content: /*
   * Copyright 2010-2025 Hyland Software, Inc. and its affiliates.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.activiti.engine.test.api.event;
  
  import static java.util.Collections.singletonMap;
  import static org.assertj.core.api.Assertions.assertThat;
  
  import com.fasterxml.jackson.core.JsonParseException;
  import com.fasterxml.jackson.core.type.TypeReference;
  import com.fasterxml.jackson.databind.JsonMappingException;
  import com.fasterxml.jackson.databind.ObjectMapper;
  import java.io.IOException;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  import org.activiti.engine.delegate.event.ActivitiEventType;
  import org.activiti.engine.event.EventLogEntry;
  import org.activiti.engine.impl.event.logger.EventLogger;
  import org.activiti.engine.impl.event.logger.handler.Fields;
  import org.activiti.engine.impl.identity.Authentication;
  import org.activiti.engine.impl.test.PluggableActivitiTestCase;
  import org.activiti.engine.runtime.ProcessInstance;
  import org.activiti.engine.task.Task;
  import org.activiti.engine.test.Deployment;
  
  /**
   */
  public class DatabaseEventLoggerTest extends PluggableActivitiTestCase {
  
      protected EventLogger databaseEventLogger;
  
      protected ObjectMapper objectMapper = new ObjectMapper();
  
      @Override
      protected void setUp() throws Exception {
          super.setUp();
  
          // Database event logger setup
          databaseEventLogger = new EventLogger(
              processEngineConfiguration.getClock(),
              processEngineConfiguration.getObjectMapper()
          );
          runtimeService.addEventListener(databaseEventLogger);
      }
  
      @Override
      protected void tearDown() throws Exception {
          // Database event logger teardown
          runtimeService.removeEventListener(databaseEventLogger);
  
          super.tearDown();
      }
  
      @Deployment(resources = { "org/activiti/engine/test/api/event/DatabaseEventLoggerProcess.bpmn20.xml" })
      public void testDatabaseEvents() throws IOException {
          String testTenant = "testTenant";
  
          String deploymentId = repositoryService
              .createDeployment()
              .addClasspathResource("org/activiti/engine/test/api/event/DatabaseEventLoggerProcess.bpmn20.xml")
              .tenantId(testTenant)
              .deploy()
              .getId();
  
          // Run process to gather data
          ProcessInstance processInstance = runtimeService.startProcessInstanceByKeyAndTenantId(
              "DatabaseEventLoggerProcess",
              singletonMap("testVar", "helloWorld"),
              testTenant
          );
  
          // Verify event log entries
          List<EventLogEntry> eventLogEntries = managementService.getEventLogEntries(null, null);
  
          String processDefinitionId = processInstance.getProcessDefinitionId();
          Iterator<EventLogEntry> iterator = eventLogEntries.iterator();
          while (iterator.hasNext()) {
              EventLogEntry entry = iterator.next();
              if (entry.getProcessDefinitionId() != null && !entry.getProcessDefinitionId().equals(processDefinitionId)) {
                  iterator.remove();
              }
          }
  
          assertThat(eventLogEntries).hasSize(15);
  
          long lastLogNr = -1;
          for (int i = 0; i < eventLogEntries.size(); i++) {
              EventLogEntry entry = eventLogEntries.get(i);
  
              if (i == 0) {
                  assertThat(entry.getType()).isNotNull();
                  assertThat(entry.getType()).isEqualTo(ActivitiEventType.VARIABLE_CREATED.name());
                  assertThat(entry.getProcessDefinitionId()).isNotNull();
                  assertThat(entry.getProcessInstanceId()).isNotNull();
                  assertThat(entry.getTimeStamp()).isNotNull();
                  assertThat(entry.getTaskId()).isNull();
  
                  Map<String, Object> data = objectMapper.readValue(
                      entry.getData(),
                      new TypeReference<HashMap<String, Object>>() {}
                  );
                  assertThat(data.get(Fields.PROCESS_DEFINITION_ID)).isNotNull();
                  assertThat(data.get(Fields.PROCESS_INSTANCE_ID)).isNotNull();
                  assertThat(data.get(Fields.VALUE_STRING)).isNotNull();
                  assertThat(data.get(Fields.TENANT_ID)).isEqualTo(testTenant);
              }
  
              // process instance start
              if (i == 1) {
                  assertThat(entry.getType()).isNotNull();
                  assertThat(entry.getType()).isEqualTo("PROCESSINSTANCE_START");
                  assertThat(entry.getProcessDefinitionId()).isNotNull();
                  assertThat(entry.getProcessInstanceId()).isNotNull();
                  assertThat(entry.getTimeStamp()).isNotNull();
                  assertThat(entry.getExecutionId()).isNull();
                  assertThat(entry.getTaskId()).isNull();
  
                  Map<String, Object> data = objectMapper.readValue(
                      entry.getData(),
                      new TypeReference<HashMap<String, Object>>() {}
                  );
                  assertThat(data.get(Fields.ID)).isNotNull();
                  assertThat(data.get(Fields.PROCESS_DEFINITION_ID)).isNotNull();
                  assertThat(data.get(Fields.TENANT_ID)).isNotNull();
                  assertThat(data.get(Fields.TENANT_ID)).isEqualTo(testTenant);
  
                  Map<String, Object> variableMap = (Map<String, Object>) data.get(Fields.VARIABLES);
                  assertThat(variableMap).hasSize(1);
                  assertThat(variableMap.get("testVar")).isEqualTo("helloWorld");
  
                  assertThat(data.containsKey(Fields.NAME)).isFalse();
                  assertThat(data.containsKey(Fields.BUSINESS_KEY)).isFalse();
              }
  
              // Activity started
              if (i == 2 || i == 5 || i == 9 || i == 12) {
                  assertThat(entry.getType()).isNotNull();
                  assertThat(entry.getType()).isEqualTo(ActivitiEventType.ACTIVITY_STARTED.name());
                  assertThat(entry.getProcessDefinitionId()).isNotNull();
                  assertThat(entry.getProcessInstanceId()).isNotNull();
                  assertThat(entry.getTimeStamp()).isNotNull();
                  assertThat(entry.getExecutionId()).isNotNull();
                  assertThat(entry.getTaskId()).isNull();
  
                  Map<String, Object> data = objectMapper.readValue(
                      entry.getData(),
                      new TypeReference<HashMap<String, Object>>() {}
                  );
                  assertThat(data.get(Fields.ACTIVITY_ID)).isNotNull();
                  assertThat(data.get(Fields.PROCESS_DEFINITION_ID)).isNotNull();
                  assertThat(data.get(Fields.PROCESS_INSTANCE_ID)).isNotNull();
                  assertThat(data.get(Fields.EXECUTION_ID)).isNotNull();
                  assertThat(data.get(Fields.ACTIVITY_TYPE)).isNotNull();
                  assertThat(data.get(Fields.TENANT_ID)).isEqualTo(testTenant);
              }
  
              // Leaving start
              if (i == 3) {
                  assertThat(entry.getType()).isNotNull();
                  assertThat(entry.getType()).isEqualTo(ActivitiEventType.ACTIVITY_COMPLETED.name());
                  assertThat(entry.getProcessDefinitionId()).isNotNull();
                  assertThat(entry.getProcessInstanceId()).isNotNull();
                  assertThat(entry.getTimeStamp()).isNotNull();
                  assertThat(entry.getExecutionId()).isNotNull();
                  assertThat(entry.getTaskId()).isNull();
  
                  Map<String, Object> data = objectMapper.readValue(
                      entry.getData(),
                      new TypeReference<HashMap<String, Object>>() {}
                  );
                  assertThat(data.get(Fields.ACTIVITY_ID)).isNotNull();
                  assertThat(data.get(Fields.ACTIVITY_ID)).isEqualTo("startEvent1");
                  assertThat(data.get(Fields.PROCESS_DEFINITION_ID)).isNotNull();
                  assertThat(data.get(Fields.PROCESS_INSTANCE_ID)).isNotNull();
                  assertThat(data.get(Fields.EXECUTION_ID)).isNotNull();
                  assertThat(data.get(Fields.ACTIVITY_TYPE)).isNotNull();
                  assertThat(data.get(Fields.TENANT_ID)).isEqualTo(testTenant);
              }
  
              // Sequence flow taken
              if (i == 4 || i == 7 || i == 8) {
                  assertThat(entry.getType()).isNotNull();
                  assertThat(entry.getType()).isEqualTo(ActivitiEventType.SEQUENCEFLOW_TAKEN.name());
                  assertThat(entry.getProcessDefinitionId()).isNotNull();
                  assertThat(entry.getProcessInstanceId()).isNotNull();
                  assertThat(entry.getTimeStamp()).isNotNull();
                  assertThat(entry.getExecutionId()).isNotNull();
                  assertThat(entry.getTaskId()).isNull();
  
                  Map<String, Object> data = objectMapper.readValue(
                      entry.getData(),
                      new TypeReference<HashMap<String, Object>>() {}
                  );
                  assertThat(data.get(Fields.ID)).isNotNull();
                  assertThat(data.get(Fields.SOURCE_ACTIVITY_ID)).isNotNull();
                  assertThat(data.get(Fields.SOURCE_ACTIVITY_NAME)).isNotNull();
                  assertThat(data.get(Fields.SOURCE_ACTIVITY_TYPE)).isNotNull();
                  assertThat(data.get(Fields.TENANT_ID)).isEqualTo(testTenant);
              }
  
              // Leaving parallel gateway
              if (i == 6) {
                  assertThat(entry.getType()).isNotNull();
                  assertThat(entry.getType()).isEqualTo(ActivitiEventType.ACTIVITY_COMPLETED.name());
                  assertThat(entry.getProcessDefinitionId()).isNotNull();
                  assertThat(entry.getProcessInstanceId()).isNotNull();
                  assertThat(entry.getTimeStamp()).isNotNull();
                  assertThat(entry.getExecutionId()).isNotNull();
                  assertThat(entry.getTaskId()).isNull();
  
                  Map<String, Object> data = objectMapper.readValue(
                      entry.getData(),
                      new TypeReference<HashMap<String, Object>>() {}
                  );
                  assertThat(data.get(Fields.ACTIVITY_ID)).isNotNull();
                  assertThat(data.get(Fields.PROCESS_DEFINITION_ID)).isNotNull();
                  assertThat(data.get(Fields.PROCESS_INSTANCE_ID)).isNotNull();
                  assertThat(data.get(Fields.EXECUTION_ID)).isNotNull();
                  assertThat(data.get(Fields.ACTIVITY_TYPE)).isNotNull();
                  assertThat(data.get(Fields.TENANT_ID)).isEqualTo(testTenant);
              }
  
              // Tasks
              if (i == 11 || i == 14) {
                  assertThat(entry.getType()).isNotNull();
                  assertThat(entry.getType()).isEqualTo(ActivitiEventType.TASK_ASSIGNED.name());
                  assertThat(entry.getTimeStamp()).isNotNull();
                  assertThat(entry.getProcessDefinitionId()).isNotNull();
                  assertThat(entry.getProcessInstanceId()).isNotNull();
                  assertThat(entry.getExecutionId()).isNotNull();
                  assertThat(entry.getTaskId()).isNotNull();
  
                  Map<String, Object> data = objectMapper.readValue(
                      entry.getData(),
                      new TypeReference<HashMap<String, Object>>() {}
                  );
                  assertThat(data.get(Fields.ID)).isNotNull();
                  assertThat(data.get(Fields.NAME)).isNotNull();
                  assertThat(data.get(Fields.ASSIGNEE)).isNotNull();
                  assertThat(data.get(Fields.CREATE_TIME)).isNotNull();
                  assertThat(data.get(Fields.PRIORITY)).isNotNull();
                  assertThat(data.get(Fields.PROCESS_DEFINITION_ID)).isNotNull();
                  assertThat(data.get(Fields.EXECUTION_ID)).isNotNull();
                  assertThat(data.get(Fields.TENANT_ID)).isNotNull();
  
                  assertThat(data.containsKey(Fields.DESCRIPTION)).isFalse();
                  assertThat(data.containsKey(Fields.CATEGORY)).isFalse();
                  assertThat(data.containsKey(Fields.OWNER)).isFalse();
                  assertThat(data.containsKey(Fields.DUE_DATE)).isFalse();
                  assertThat(data.containsKey(Fields.FORM_KEY)).isFalse();
                  assertThat(data.containsKey(Fields.USER_ID)).isFalse();
  
                  assertThat(data.get(Fields.TENANT_ID)).isEqualTo(testTenant);
              }
  
              if (i == 10 || i == 13) {
                  assertThat(entry.getType()).isNotNull();
                  assertThat(entry.getType()).isEqualTo(ActivitiEventType.TASK_CREATED.name());
                  assertThat(entry.getTimeStamp()).isNotNull();
                  assertThat(entry.getProcessDefinitionId()).isNotNull();
                  assertThat(entry.getProcessInstanceId()).isNotNull();
                  assertThat(entry.getExecutionId()).isNotNull();
                  assertThat(entry.getTaskId()).isNotNull();
  
                  Map<String, Object> data = objectMapper.readValue(
                      entry.getData(),
                      new TypeReference<HashMap<String, Object>>() {}
                  );
                  assertThat(data.get(Fields.ID)).isNotNull();
                  assertThat(data.get(Fields.NAME)).isNotNull();
                  assertThat(data.get(Fields.ASSIGNEE)).isNotNull();
                  assertThat(data.get(Fields.CREATE_TIME)).isNotNull();
                  assertThat(data.get(Fields.PRIORITY)).isNotNull();
                  assertThat(data.get(Fields.PROCESS_DEFINITION_ID)).isNotNull();
                  assertThat(data.get(Fields.EXECUTION_ID)).isNotNull();
                  assertThat(data.get(Fields.TENANT_ID)).isNotNull();
  
                  assertThat(data.containsKey(Fields.DESCRIPTION)).isFalse();
                  assertThat(data.containsKey(Fields.CATEGORY)).isFalse();
                  assertThat(data.containsKey(Fields.OWNER)).isFalse();
                  assertThat(data.containsKey(Fields.DUE_DATE)).isFalse();
                  assertThat(data.containsKey(Fields.FORM_KEY)).isFalse();
                  assertThat(data.containsKey(Fields.USER_ID)).isFalse();
  
                  assertThat(data.get(Fields.TENANT_ID)).isEqualTo(testTenant);
              }
  
              lastLogNr = entry.getLogNumber();
          }
  
          // Completing two tasks
          for (Task task : taskService.createTaskQuery().list()) {
              Authentication.setAuthenticatedUserId(task.getAssignee());
              taskService.complete(task.getId(), singletonMap("test", "test"));
              Authentication.setAuthenticatedUserId(null);
          }
  
          // Verify events
          eventLogEntries = managementService.getEventLogEntries(lastLogNr, 100L);
          assertThat(eventLogEntries).hasSize(17);
  
          for (int i = 0; i < eventLogEntries.size(); i++) {
              EventLogEntry entry = eventLogEntries.get(i);
  
              // Task completion
              if (i == 1 || i == 6) {
                  assertThat(entry.getType()).isNotNull();
                  assertThat(entry.getType()).isEqualTo(ActivitiEventType.TASK_COMPLETED.name());
                  assertThat(entry.getProcessDefinitionId()).isNotNull();
                  assertThat(entry.getProcessInstanceId()).isNotNull();
                  assertThat(entry.getExecutionId()).isNotNull();
                  assertThat(entry.getTaskId()).isNotNull();
  
                  Map<String, Object> data = objectMapper.readValue(
                      entry.getData(),
                      new TypeReference<HashMap<String, Object>>() {}
                  );
                  assertThat(data.get(Fields.ID)).isNotNull();
                  assertThat(data.get(Fields.NAME)).isNotNull();
                  assertThat(data.get(Fields.ASSIGNEE)).isNotNull();
                  assertThat(data.get(Fields.CREATE_TIME)).isNotNull();
                  assertThat(data.get(Fields.PRIORITY)).isNotNull();
                  assertThat(data.get(Fields.PROCESS_DEFINITION_ID)).isNotNull();
                  assertThat(data.get(Fields.EXECUTION_ID)).isNotNull();
                  assertThat(data.get(Fields.TENANT_ID)).isNotNull();
                  assertThat(data.get(Fields.USER_ID)).isNotNull();
  
                  Map<String, Object> variableMap = (Map<String, Object>) data.get(Fields.VARIABLES);
                  assertThat(variableMap).hasSize(1);
                  assertThat(variableMap.get("test")).isEqualTo("test");
  
                  assertThat(data.containsKey(Fields.DESCRIPTION)).isFalse();
                  assertThat(data.containsKey(Fields.CATEGORY)).isFalse();
                  assertThat(data.containsKey(Fields.OWNER)).isFalse();
                  assertThat(data.containsKey(Fields.DUE_DATE)).isFalse();
                  assertThat(data.containsKey(Fields.FORM_KEY)).isFalse();
  
                  assertThat(data.get(Fields.TENANT_ID)).isEqualTo(testTenant);
              }
  
              // Activity Completed
              if (i == 2 || i == 7 || i == 10 || i == 13) {
                  assertThat(entry.getType()).isNotNull();
                  assertThat(entry.getType()).isEqualTo(ActivitiEventType.ACTIVITY_COMPLETED.name());
                  assertThat(entry.getProcessDefinitionId()).isNotNull();
                  assertThat(entry.getProcessInstanceId()).isNotNull();
                  assertThat(entry.getTimeStamp()).isNotNull();
                  assertThat(entry.getExecutionId()).isNotNull();
                  assertThat(entry.getTaskId()).isNull();
  
                  Map<String, Object> data = objectMapper.readValue(
                      entry.getData(),
                      new TypeReference<HashMap<String, Object>>() {}
                  );
                  assertThat(data.get(Fields.ACTIVITY_ID)).isNotNull();
                  assertThat(data.get(Fields.PROCESS_DEFINITION_ID)).isNotNull();
                  assertThat(data.get(Fields.PROCESS_INSTANCE_ID)).isNotNull();
                  assertThat(data.get(Fields.EXECUTION_ID)).isNotNull();
                  assertThat(data.get(Fields.ACTIVITY_TYPE)).isNotNull();
                  assertThat(data.get(Fields.BEHAVIOR_CLASS)).isNotNull();
  
                  assertThat(data.get(Fields.TENANT_ID)).isEqualTo(testTenant);
  
                  if (i == 2) {
                      assertThat(data.get(Fields.ACTIVITY_TYPE)).isEqualTo("userTask");
                  } else if (i == 7) {
                      assertThat(data.get(Fields.ACTIVITY_TYPE)).isEqualTo("userTask");
                  } else if (i == 10) {
                      assertThat(data.get(Fields.ACTIVITY_TYPE)).isEqualTo("parallelGateway");
                  } else if (i == 13) {
                      assertThat(data.get(Fields.ACTIVITY_TYPE)).isEqualTo("endEvent");
                  }
              }
  
              // Sequence flow taken
              if (i == 3 || i == 8 || i == 11) {
                  assertThat(entry.getType()).isNotNull();
                  assertThat(ActivitiEventType.SEQUENCEFLOW_TAKEN.name()).isEqualTo(entry.getType());
                  assertThat(entry.getProcessDefinitionId()).isNotNull();
                  assertThat(entry.getProcessInstanceId()).isNotNull();
                  assertThat(entry.getTimeStamp()).isNotNull();
                  assertThat(entry.getExecutionId()).isNotNull();
                  assertThat(entry.getTaskId()).isNull();
  
                  Map<String, Object> data = objectMapper.readValue(
                      entry.getData(),
                      new TypeReference<HashMap<String, Object>>() {}
                  );
                  assertThat(data.get(Fields.ID)).isNotNull();
                  assertThat(data.get(Fields.SOURCE_ACTIVITY_ID)).isNotNull();
                  assertThat(data.get(Fields.SOURCE_ACTIVITY_TYPE)).isNotNull();
                  assertThat(data.get(Fields.SOURCE_ACTIVITY_BEHAVIOR_CLASS)).isNotNull();
                  assertThat(data.get(Fields.TARGET_ACTIVITY_ID)).isNotNull();
                  assertThat(data.get(Fields.TARGET_ACTIVITY_TYPE)).isNotNull();
                  assertThat(data.get(Fields.TARGET_ACTIVITY_BEHAVIOR_CLASS)).isNotNull();
  
                  assertThat(data.get(Fields.TENANT_ID)).isEqualTo(testTenant);
              }
  
              if (i == 14 || i == 15) {
                  assertThat(entry.getType()).isNotNull();
                  assertThat(entry.getType()).isEqualTo("VARIABLE_DELETED");
                  assertThat(entry.getProcessDefinitionId()).isNotNull();
                  assertThat(entry.getProcessInstanceId()).isNotNull();
                  assertThat(entry.getTimeStamp()).isNotNull();
                  assertThat(entry.getExecutionId()).isNotNull();
                  assertThat(entry.getTaskId()).isNull();
              }
  
              if (i == 16) {
                  assertThat(entry.getType()).isNotNull();
                  assertThat(entry.getType()).isEqualTo("PROCESSINSTANCE_END");
                  assertThat(entry.getProcessDefinitionId()).isNotNull();
                  assertThat(entry.getProcessInstanceId()).isNotNull();
                  assertThat(entry.getTimeStamp()).isNotNull();
                  assertThat(entry.getExecutionId()).isNull();
                  assertThat(entry.getTaskId()).isNull();
  
                  Map<String, Object> data = objectMapper.readValue(
                      entry.getData(),
                      new TypeReference<HashMap<String, Object>>() {}
                  );
                  assertThat(data.get(Fields.ID)).isNotNull();
                  assertThat(data.get(Fields.PROCESS_DEFINITION_ID)).isNotNull();
                  assertThat(data.get(Fields.TENANT_ID)).isNotNull();
  
                  assertThat(data.containsKey(Fields.NAME)).isFalse();
                  assertThat(data.containsKey(Fields.BUSINESS_KEY)).isFalse();
  
                  assertThat(data.get(Fields.TENANT_ID)).isEqualTo(testTenant);
              }
          }
  
          // Cleanup
          for (EventLogEntry eventLogEntry : managementService.getEventLogEntries(null, null)) {
              managementService.deleteEventLogEntry(eventLogEntry.getLogNumber());
          }
  
          repositoryService.deleteDeployment(deploymentId, true);
      }
  
      public void testDatabaseEventsNoTenant() throws IOException {
          String deploymentId = repositoryService
              .createDeployment()
              .addClasspathResource("org/activiti/engine/test/api/event/DatabaseEventLoggerProcess.bpmn20.xml")
              .deploy()
              .getId();
  
          // Run process to gather data
          ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(
              "DatabaseEventLoggerProcess",
              singletonMap("testVar", "helloWorld")
          );
  
          // Verify event log entries
          List<EventLogEntry> eventLogEntries = managementService.getEventLogEntries(null, null);
  
          String processDefinitionId = processInstance.getProcessDefinitionId();
          Iterator<EventLogEntry> iterator = eventLogEntries.iterator();
          while (iterator.hasNext()) {
              EventLogEntry entry = iterator.next();
              if (entry.getProcessDefinitionId() != null && !entry.getProcessDefinitionId().equals(processDefinitionId)) {
                  iterator.remove();
              }
          }
  
          assertThat(eventLogEntries).hasSize(15);
  
          for (int i = 0; i < eventLogEntries.size(); i++) {
              EventLogEntry entry = eventLogEntries.get(i);
  
              if (i == 0) {
                  assertThat(ActivitiEventType.VARIABLE_CREATED.name()).isEqualTo(entry.getType());
                  Map<String, Object> data = objectMapper.readValue(
                      entry.getData(),
                      new TypeReference<HashMap<String, Object>>() {}
                  );
                  assertThat(data.get(Fields.TENANT_ID)).isNull();
              }
  
              // process instance start
              if (i == 1) {
                  assertThat(entry.getType()).isEqualTo("PROCESSINSTANCE_START");
                  Map<String, Object> data = objectMapper.readValue(
                      entry.getData(),
                      new TypeReference<HashMap<String, Object>>() {}
                  );
                  assertThat(data.get(Fields.TENANT_ID)).isNull();
              }
  
              // Activity started
              if (i == 2 || i == 5 || i == 9 || i == 12) {
                  assertThat(ActivitiEventType.ACTIVITY_STARTED.name()).isEqualTo(entry.getType());
                  Map<String, Object> data = objectMapper.readValue(
                      entry.getData(),
                      new TypeReference<HashMap<String, Object>>() {}
                  );
                  assertThat(data.get(Fields.TENANT_ID)).isNull();
              }
  
              // Leaving start
              if (i == 3) {
                  assertThat(ActivitiEventType.ACTIVITY_COMPLETED.name()).isEqualTo(entry.getType());
                  Map<String, Object> data = objectMapper.readValue(
                      entry.getData(),
                      new TypeReference<HashMap<String, Object>>() {}
                  );
                  assertThat(data.get(Fields.TENANT_ID)).isNull();
              }
  
              // Sequence flow taken
              if (i == 4 || i == 7 || i == 8) {
                  assertThat(ActivitiEventType.SEQUENCEFLOW_TAKEN.name()).isEqualTo(entry.getType());
                  Map<String, Object> data = objectMapper.readValue(
                      entry.getData(),
                      new TypeReference<HashMap<String, Object>>() {}
                  );
                  assertThat(data.get(Fields.TENANT_ID)).isNull();
              }
  
              // Leaving parallel gateway
              if (i == 6) {
                  assertThat(ActivitiEventType.ACTIVITY_COMPLETED.name()).isEqualTo(entry.getType());
                  Map<String, Object> data = objectMapper.readValue(
                      entry.getData(),
                      new TypeReference<HashMap<String, Object>>() {}
                  );
                  assertThat(data.get(Fields.TENANT_ID)).isNull();
              }
  
              // Tasks
              if (i == 11 || i == 14) {
                  assertThat(ActivitiEventType.TASK_ASSIGNED.name()).isEqualTo(entry.getType());
                  Map<String, Object> data = objectMapper.readValue(
                      entry.getData(),
                      new TypeReference<HashMap<String, Object>>() {}
                  );
                  assertThat(data.get(Fields.TENANT_ID)).isNull();
              }
  
              if (i == 10 || i == 13) {
                  assertThat(ActivitiEventType.TASK_CREATED.name()).isEqualTo(entry.getType());
                  Map<String, Object> data = objectMapper.readValue(
                      entry.getData(),
                      new TypeReference<HashMap<String, Object>>() {}
                  );
                  assertThat(data.get(Fields.TENANT_ID)).isNull();
              }
          }
  
          repositoryService.deleteDeployment(deploymentId, true);
  
          // Cleanup
          for (EventLogEntry eventLogEntry : managementService.getEventLogEntries(null, null)) {
              managementService.deleteEventLogEntry(eventLogEntry.getLogNumber());
          }
      }
  
      public void testStandaloneTaskEvents() throws JsonParseException, JsonMappingException, IOException {
          Task task = taskService.newTask();
          task.setAssignee("kermit");
          task.setTenantId("myTenant");
          taskService.saveTask(task);
  
          taskService.setAssignee(task.getId(), "gonzo");
  
          task = taskService.createTaskQuery().taskId(task.getId()).singleResult();
          task.setAssignee("kermit");
          taskService.saveTask(task);
  
          List<EventLogEntry> events = managementService.getEventLogEntries(null, null);
          assertThat(events).hasSize(4);
          assertThat(events.get(0).getType()).isEqualTo("TASK_CREATED");
          assertThat(events.get(1).getType()).isEqualTo("TASK_ASSIGNED");
          assertThat(events.get(2).getType()).isEqualTo("TASK_ASSIGNED");
          assertThat(events.get(3).getType()).isEqualTo("TASK_ASSIGNED");
  
          for (EventLogEntry eventLogEntry : events) {
              Map<String, Object> data = objectMapper.readValue(
                  eventLogEntry.getData(),
                  new TypeReference<HashMap<String, Object>>() {}
              );
              assertThat(data.get(Fields.TENANT_ID)).isEqualTo("myTenant");
          }
  
          // Cleanup
          taskService.deleteTask(task.getId(), true);
          for (EventLogEntry eventLogEntry : managementService.getEventLogEntries(null, null)) {
              managementService.deleteEventLogEntry(eventLogEntry.getLogNumber());
          }
      }
  }
  