diff --git a/engine-rest/engine-rest-openapi/src/main/templates/models/org/camunda/bpm/engine/rest/dto/history/SetRemovalTimeToHistoricProcessInstancesDto.ftl b/engine-rest/engine-rest-openapi/src/main/templates/models/org/camunda/bpm/engine/rest/dto/history/SetRemovalTimeToHistoricProcessInstancesDto.ftl index ab200741c11..6c35353eab1 100644 --- a/engine-rest/engine-rest-openapi/src/main/templates/models/org/camunda/bpm/engine/rest/dto/history/SetRemovalTimeToHistoricProcessInstancesDto.ftl +++ b/engine-rest/engine-rest-openapi/src/main/templates/models/org/camunda/bpm/engine/rest/dto/history/SetRemovalTimeToHistoricProcessInstancesDto.ftl @@ -16,9 +16,28 @@ <@lib.property name = "hierarchical" type = "boolean" - last = true desc = "Sets the removal time to all historic process instances in the hierarchy. Value may only be `true`, as `false` is the default behavior."/> + <@lib.property + name = "updateInChunks" + type = "boolean" + desc = "Handles removal time updates in chunks, taking into account the defined size in + `removalTimeUpdateChunkSize` in the process engine configuration. The size of the + chunks can also be overridden per call with the `updateChunkSize` parameter. + Enabling this option can lead to multiple executions of the resulting jobs, preventing + the database transaction from timing out by limiting the number of rows to update. + Value may only be `true`, as `false` is the default behavior."/> + + <@lib.property + name = "updateChunkSize" + type = "integer" + format = "int32" + last = true + desc = "Defines the size of the chunks in which removal time updates are processed. + The value must be a positive integer between `1` and `500`. This only has an + effect if `updateInChunks` is set to `true`. If undefined, the operation uses the + `removalTimeUpdateChunkSize` defined in the process engine configuration."/> + \ No newline at end of file diff --git a/engine-rest/engine-rest-openapi/src/main/templates/paths/history/process-instance/set-removal-time/post.ftl b/engine-rest/engine-rest-openapi/src/main/templates/paths/history/process-instance/set-removal-time/post.ftl index a4ce0715dbe..07c4c8bbfa8 100644 --- a/engine-rest/engine-rest-openapi/src/main/templates/paths/history/process-instance/set-removal-time/post.ftl +++ b/engine-rest/engine-rest-openapi/src/main/templates/paths/history/process-instance/set-removal-time/post.ftl @@ -26,6 +26,22 @@ "b4d2ad94-7240-11e9-98b7-be5e0f7575b7" ] } + }', + '"example-2": { + "summary": "POST `/history/process-instance/set-removal-time`", + "value": { + "absoluteRemovalTime": "2019-05-05T11:56:24.725+0200", + "hierarchical": true, + "updateInChunks": true, + "updateChunkSize": 300, + "historicProcessInstanceQuery": { + "unfinished": true + }, + "historicProcessInstanceIds": [ + "b4d2ad98-7240-11e9-98b7-be5e0f7575b7", + "b4d2ad94-7240-11e9-98b7-be5e0f7575b7" + ] + } }' ] /> "responses" : { diff --git a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/dto/history/batch/removaltime/SetRemovalTimeToHistoricProcessInstancesDto.java b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/dto/history/batch/removaltime/SetRemovalTimeToHistoricProcessInstancesDto.java index 223a10eefd2..d7045a24a01 100644 --- a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/dto/history/batch/removaltime/SetRemovalTimeToHistoricProcessInstancesDto.java +++ b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/dto/history/batch/removaltime/SetRemovalTimeToHistoricProcessInstancesDto.java @@ -26,6 +26,8 @@ public class SetRemovalTimeToHistoricProcessInstancesDto extends AbstractSetRemo protected String[] historicProcessInstanceIds; protected HistoricProcessInstanceQueryDto historicProcessInstanceQuery; protected boolean hierarchical; + protected boolean updateInChunks; + protected Integer updateChunkSize; public String[] getHistoricProcessInstanceIds() { return historicProcessInstanceIds; @@ -51,4 +53,19 @@ public void setHierarchical(boolean hierarchical) { this.hierarchical = hierarchical; } + public boolean isUpdateInChunks() { + return updateInChunks; + } + + public void setUpdateInChunks(boolean updateInChunks) { + this.updateInChunks = updateInChunks; + } + + public Integer getUpdateChunkSize() { + return updateChunkSize; + } + + public void setUpdateChunkSize(Integer updateChunkSize) { + this.updateChunkSize = updateChunkSize; + } } diff --git a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/impl/history/HistoricProcessInstanceRestServiceImpl.java b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/impl/history/HistoricProcessInstanceRestServiceImpl.java index 26fbeaf3bc5..7beda5c8211 100644 --- a/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/impl/history/HistoricProcessInstanceRestServiceImpl.java +++ b/engine-rest/engine-rest/src/main/java/org/camunda/bpm/engine/rest/impl/history/HistoricProcessInstanceRestServiceImpl.java @@ -194,6 +194,15 @@ public BatchDto setRemovalTimeAsync(SetRemovalTimeToHistoricProcessInstancesDto } + if (dto.isUpdateInChunks()) { + builder.updateInChunks(); + } + + Integer chunkSize = dto.getUpdateChunkSize(); + if (chunkSize != null) { + builder.chunkSize(chunkSize); + } + Batch batch = builder.executeAsync(); return BatchDto.fromBatch(batch); } diff --git a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/history/HistoricProcessInstanceRestServiceInteractionTest.java b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/history/HistoricProcessInstanceRestServiceInteractionTest.java index ee3e52ab1c7..35741eeb572 100644 --- a/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/history/HistoricProcessInstanceRestServiceInteractionTest.java +++ b/engine-rest/engine-rest/src/test/java/org/camunda/bpm/engine/rest/history/HistoricProcessInstanceRestServiceInteractionTest.java @@ -16,8 +16,35 @@ */ package org.camunda.bpm.engine.rest.history; +import static io.restassured.RestAssured.given; +import static io.restassured.path.json.JsonPath.from; +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.RETURNS_DEEP_STUBS; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + import io.restassured.http.ContentType; import io.restassured.response.Response; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.ws.rs.core.Response.Status; import org.camunda.bpm.engine.AuthorizationException; import org.camunda.bpm.engine.BadUserRequestException; import org.camunda.bpm.engine.HistoryService; @@ -42,39 +69,11 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; -import javax.ws.rs.core.Response.Status; -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static io.restassured.RestAssured.given; -import static io.restassured.path.json.JsonPath.from; -import static org.assertj.core.api.Assertions.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.equalTo; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.mockito.Mockito.*; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.anyList; -import static org.mockito.Mockito.anyString; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.RETURNS_DEEP_STUBS; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - public class HistoricProcessInstanceRestServiceInteractionTest extends AbstractRestServiceTest { @ClassRule public static TestContainerRule rule = new TestContainerRule(); - + protected static final String DELETE_REASON = "deleteReason"; protected static final String TEST_DELETE_REASON = "test"; protected static final String FAIL_IF_NOT_EXISTS = "failIfNotExists"; @@ -183,7 +182,7 @@ public void testDeleteNonExistingProcessInstanceIfExists() { given().pathParam("id", MockProvider.EXAMPLE_PROCESS_INSTANCE_ID).queryParam("failIfNotExists", false) .then().expect().statusCode(Status.NO_CONTENT.getStatusCode()) .when().delete(HISTORIC_SINGLE_PROCESS_INSTANCE_URL); - + verify(historyServiceMock).deleteHistoricProcessInstanceIfExists(MockProvider.EXAMPLE_PROCESS_INSTANCE_ID); } @@ -263,7 +262,7 @@ public void testDeleteAsyncWithBadRequestQuery() { .statusCode(Status.BAD_REQUEST.getStatusCode()) .when().post(DELETE_HISTORIC_PROCESS_INSTANCES_ASYNC_URL); } - + @Test public void testDeleteAllVariablesByProcessInstanceId() { given() @@ -275,12 +274,12 @@ public void testDeleteAllVariablesByProcessInstanceId() { verify(historyServiceMock).deleteHistoricVariableInstancesByProcessInstanceId(EXAMPLE_PROCESS_INSTANCE_ID); } - + @Test public void testDeleteAllVariablesForNonExistingProcessInstance() { doThrow(new NotFoundException("No historic process instance found with id: 'NON_EXISTING_ID'")) .when(historyServiceMock).deleteHistoricVariableInstancesByProcessInstanceId("NON_EXISTING_ID"); - + given() .pathParam("id", "NON_EXISTING_ID") .expect() @@ -385,7 +384,7 @@ public void shouldSetRemovalTime_Absolute() { } @Test - public void shouldNotSetRemovalTime_Absolute() { + public void shouldSetRemovalTime_AbsoluteNoTime() { SetRemovalTimeSelectModeForHistoricProcessInstancesBuilder builderMock = mock(SetRemovalTimeSelectModeForHistoricProcessInstancesBuilder.class, RETURNS_DEEP_STUBS); @@ -413,7 +412,7 @@ public void shouldNotSetRemovalTime_Absolute() { } @Test - public void shouldClearRemovalTime() { + public void shouldSetRemovalTime_ClearTime() { SetRemovalTimeSelectModeForHistoricProcessInstancesBuilder builderMock = mock(SetRemovalTimeSelectModeForHistoricProcessInstancesBuilder.class, RETURNS_DEEP_STUBS); @@ -464,7 +463,7 @@ public void shouldSetRemovalTime_Response() { } @Test - public void shouldSetRemovalTime_ThrowBadUserException() { + public void shouldSetRemovalTime_FailBadUserRequest() { SetRemovalTimeSelectModeForHistoricProcessInstancesBuilder builderMock = mock(SetRemovalTimeSelectModeForHistoricProcessInstancesBuilder.class, RETURNS_DEEP_STUBS); @@ -481,6 +480,70 @@ public void shouldSetRemovalTime_ThrowBadUserException() { .post(SET_REMOVAL_TIME_HISTORIC_PROCESS_INSTANCES_ASYNC_URL); } + @Test + public void shouldSetRemovalTime_InChunks() { + SetRemovalTimeSelectModeForHistoricProcessInstancesBuilder builderMock = + mock(SetRemovalTimeSelectModeForHistoricProcessInstancesBuilder.class, RETURNS_DEEP_STUBS); + + when(historyServiceMock.setRemovalTimeToHistoricProcessInstances()) + .thenReturn(builderMock); + + Map payload = new HashMap<>(); + payload.put("historicProcessInstanceIds", Collections.singletonList(EXAMPLE_PROCESS_INSTANCE_ID)); + payload.put("clearedRemovalTime", true); + payload.put("updateInChunks", true); + + given() + .contentType(ContentType.JSON) + .body(payload) + .then() + .expect().statusCode(Status.OK.getStatusCode()) + .when() + .post(SET_REMOVAL_TIME_HISTORIC_PROCESS_INSTANCES_ASYNC_URL); + + SetRemovalTimeSelectModeForHistoricProcessInstancesBuilder builder = + historyServiceMock.setRemovalTimeToHistoricProcessInstances(); + + verify(builder).clearedRemovalTime(); + verify(builder).byIds(EXAMPLE_PROCESS_INSTANCE_ID); + verify(builder).byQuery(null); + verify(builder).updateInChunks(); + verify(builder).executeAsync(); + verifyNoMoreInteractions(builder); + } + + @Test + public void shouldSetRemovalTime_ChunkSize() { + SetRemovalTimeSelectModeForHistoricProcessInstancesBuilder builderMock = + mock(SetRemovalTimeSelectModeForHistoricProcessInstancesBuilder.class, RETURNS_DEEP_STUBS); + + when(historyServiceMock.setRemovalTimeToHistoricProcessInstances()) + .thenReturn(builderMock); + + Map payload = new HashMap<>(); + payload.put("historicProcessInstanceIds", Collections.singletonList(EXAMPLE_PROCESS_INSTANCE_ID)); + payload.put("clearedRemovalTime", true); + payload.put("updateChunkSize", 20); + + given() + .contentType(ContentType.JSON) + .body(payload) + .then() + .expect().statusCode(Status.OK.getStatusCode()) + .when() + .post(SET_REMOVAL_TIME_HISTORIC_PROCESS_INSTANCES_ASYNC_URL); + + SetRemovalTimeSelectModeForHistoricProcessInstancesBuilder builder = + historyServiceMock.setRemovalTimeToHistoricProcessInstances(); + + verify(builder).clearedRemovalTime(); + verify(builder).byIds(EXAMPLE_PROCESS_INSTANCE_ID); + verify(builder).byQuery(null); + verify(builder).chunkSize(20); + verify(builder).executeAsync(); + verifyNoMoreInteractions(builder); + } + @Test public void testOrQuery() { // given diff --git a/engine/src/main/java/org/camunda/bpm/engine/history/SetRemovalTimeToHistoricProcessInstancesBuilder.java b/engine/src/main/java/org/camunda/bpm/engine/history/SetRemovalTimeToHistoricProcessInstancesBuilder.java index 1bb121cdc85..1148b3c8d95 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/history/SetRemovalTimeToHistoricProcessInstancesBuilder.java +++ b/engine/src/main/java/org/camunda/bpm/engine/history/SetRemovalTimeToHistoricProcessInstancesBuilder.java @@ -22,6 +22,7 @@ import org.camunda.bpm.engine.authorization.Permissions; import org.camunda.bpm.engine.authorization.Resources; import org.camunda.bpm.engine.batch.Batch; +import org.camunda.bpm.engine.impl.batch.removaltime.ProcessSetRemovalTimeJobHandler; /** * Fluent builder to set the removal time to historic process instances and @@ -59,6 +60,36 @@ public interface SetRemovalTimeToHistoricProcessInstancesBuilder { */ SetRemovalTimeToHistoricProcessInstancesBuilder hierarchical(); + /** + * Handles removal time updates in chunks, taking into account the defined + * size in {@code removalTimeUpdateChunkSize} in the process engine + * configuration. The size of the chunks can also be overridden per call with + * the {@link #chunkSize(int)} option. Enabling this option can lead to + * multiple executions of the resulting jobs, preventing the database + * transaction from timing out by limiting the number of rows to update. + * + * @since 7.20 + * + * @return the builder. + */ + SetRemovalTimeToHistoricProcessInstancesBuilder updateInChunks(); + + /** + * Defines the size of the chunks in which removal time updates are processed. + * The value must be a positive integer value that doesn't exceed the + * {@link ProcessSetRemovalTimeJobHandler#MAX_CHUNK_SIZE}. + * + * Only has an effect if {@link #updateInChunks()} is invoked as well. + * + * If undefined, the operation uses the `removalTimeUpdateChunkSize` defined + * in the process engine configuration. + * + * @since 7.20 + * + * @return the builder. + */ + SetRemovalTimeToHistoricProcessInstancesBuilder chunkSize(int chunkSize); + /** * Sets the removal time asynchronously as batch. The returned batch can be used to * track the progress of setting a removal time. diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/batch/AbstractBatchJobHandler.java b/engine/src/main/java/org/camunda/bpm/engine/impl/batch/AbstractBatchJobHandler.java index 67d677afbd1..1272ca59427 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/batch/AbstractBatchJobHandler.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/batch/AbstractBatchJobHandler.java @@ -16,6 +16,12 @@ */ package org.camunda.bpm.engine.impl.batch; +import com.google.gson.JsonElement; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl; import org.camunda.bpm.engine.impl.context.Context; import org.camunda.bpm.engine.impl.db.DbEntity; import org.camunda.bpm.engine.impl.db.entitymanager.OptimisticLockingListener; @@ -32,11 +38,6 @@ import org.camunda.bpm.engine.impl.persistence.entity.MessageEntity; import org.camunda.bpm.engine.impl.util.ClockUtil; import org.camunda.bpm.engine.impl.util.JsonUtil; -import com.google.gson.JsonElement; - -import java.util.Date; -import java.util.Iterator; -import java.util.List; /** * Common methods for batch job handlers based on list of ids, providing serialization, configuration instantiation, etc. @@ -45,6 +46,7 @@ */ public abstract class AbstractBatchJobHandler implements BatchJobHandler, OptimisticLockingListener { + @Override public abstract JobDeclaration getJobDeclaration(); @Override @@ -114,8 +116,6 @@ public final void execute(final BatchJobConfiguration configuration, } executeHandler(batchConfiguration, execution, commandContext, tenantId); - - commandContext.getByteArrayManager().delete(byteArray); } protected abstract void executeHandler(final T configuration, @@ -251,4 +251,16 @@ public OptimisticLockingResult failedOperation(final DbOperation operation) { return OptimisticLockingResult.THROW; } + @Override + public int calculateInvocationsPerBatchJob(String batchType, T configuration) { + ProcessEngineConfigurationImpl engineConfig = Context.getProcessEngineConfiguration(); + Map invocationsPerBatchJobByBatchType = engineConfig.getInvocationsPerBatchJobByBatchType(); + Integer invocationCount = invocationsPerBatchJobByBatchType.get(batchType); + if (invocationCount != null) { + return invocationCount; + } else { + return engineConfig.getInvocationsPerBatchJob(); + } + } + } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/batch/BatchJobDeclaration.java b/engine/src/main/java/org/camunda/bpm/engine/impl/batch/BatchJobDeclaration.java index 3b118a0596d..0ed69084992 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/batch/BatchJobDeclaration.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/batch/BatchJobDeclaration.java @@ -51,10 +51,17 @@ protected String resolveJobDefinitionId(BatchJobContext context) { return context.getBatch().getBatchJobDefinitionId(); } + @Override public ParameterValueProvider getJobPriorityProvider() { long batchJobPriority = Context.getProcessEngineConfiguration() .getBatchJobPriority(); return new ConstantValueProvider(batchJobPriority); } + @Override + public MessageEntity reconfigure(BatchJobContext context, MessageEntity job) { + super.reconfigure(context, job); + job.setJobHandlerConfiguration(new BatchJobConfiguration(context.getConfiguration().getId())); + return job; + } } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/batch/BatchJobHandler.java b/engine/src/main/java/org/camunda/bpm/engine/impl/batch/BatchJobHandler.java index 9688870db4d..ef59d4abdd0 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/batch/BatchJobHandler.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/batch/BatchJobHandler.java @@ -66,4 +66,17 @@ public interface BatchJobHandler extends JobHandler { */ void deleteJobs(BatchEntity batch); + /** + * Determine the number of invocations ber patch job. This can be defined by + * the related batch job handler specifically or otherwise taken from the + * engine configuration. + * + * @param batchType + * the batch's type to help determine any engine configuration + * related to it + * @param configuration + * the configuration object + * @return the number of invocations ber patch job + */ + int calculateInvocationsPerBatchJob(String batchType, T configuration); } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/batch/builder/BatchBuilder.java b/engine/src/main/java/org/camunda/bpm/engine/impl/batch/builder/BatchBuilder.java index 57c720d9093..3e6aaaee075 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/batch/builder/BatchBuilder.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/batch/builder/BatchBuilder.java @@ -16,6 +16,8 @@ */ package org.camunda.bpm.engine.impl.batch.builder; +import java.util.List; +import java.util.Map; import org.camunda.bpm.engine.ProcessEngineException; import org.camunda.bpm.engine.authorization.Permission; import org.camunda.bpm.engine.batch.Batch; @@ -27,9 +29,6 @@ import org.camunda.bpm.engine.impl.jobexecutor.JobHandler; import org.camunda.bpm.engine.impl.util.ClockUtil; -import java.util.List; -import java.util.Map; - public class BatchBuilder { protected CommandContext commandContext; @@ -130,7 +129,7 @@ protected BatchEntity configure(BatchEntity batch) { String type = jobHandler.getType(); batch.setType(type); - int invocationPerBatchJobCount = calculateInvocationsPerBatchJob(type); + int invocationPerBatchJobCount = jobHandler.calculateInvocationsPerBatchJob(type, config); batch.setInvocationsPerBatchJob(invocationPerBatchJobCount); batch.setTenantId(tenantId); @@ -207,21 +206,4 @@ protected int calculateTotalJobs(int instanceCount, int invocationPerBatchJobCou return (instanceCount / invocationPerBatchJobCount) + 1; } - protected int calculateInvocationsPerBatchJob(String batchType) { - ProcessEngineConfigurationImpl engineConfig = commandContext.getProcessEngineConfiguration(); - - Map invocationsPerBatchJobByBatchType = - engineConfig.getInvocationsPerBatchJobByBatchType(); - - Integer invocationCount = invocationsPerBatchJobByBatchType.get(batchType); - - if (invocationCount != null) { - return invocationCount; - - } else { - return engineConfig.getInvocationsPerBatchJob(); - - } - } - } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/batch/removaltime/ProcessSetRemovalTimeJobHandler.java b/engine/src/main/java/org/camunda/bpm/engine/impl/batch/removaltime/ProcessSetRemovalTimeJobHandler.java index 03119a9277b..4bdef7556ab 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/batch/removaltime/ProcessSetRemovalTimeJobHandler.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/batch/removaltime/ProcessSetRemovalTimeJobHandler.java @@ -16,11 +16,24 @@ */ package org.camunda.bpm.engine.impl.batch.removaltime; +import static org.camunda.bpm.engine.ProcessEngineConfiguration.HISTORY_REMOVAL_TIME_STRATEGY_END; +import static org.camunda.bpm.engine.ProcessEngineConfiguration.HISTORY_REMOVAL_TIME_STRATEGY_START; + +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Set; import org.camunda.bpm.engine.batch.Batch; import org.camunda.bpm.engine.impl.batch.AbstractBatchJobHandler; import org.camunda.bpm.engine.impl.batch.BatchJobContext; import org.camunda.bpm.engine.impl.batch.BatchJobDeclaration; +import org.camunda.bpm.engine.impl.cfg.TransactionListener; +import org.camunda.bpm.engine.impl.cfg.TransactionState; +import org.camunda.bpm.engine.impl.db.DbEntity; +import org.camunda.bpm.engine.impl.db.entitymanager.operation.DbOperation; import org.camunda.bpm.engine.impl.interceptor.CommandContext; +import org.camunda.bpm.engine.impl.interceptor.CommandExecutor; import org.camunda.bpm.engine.impl.jobexecutor.JobDeclaration; import org.camunda.bpm.engine.impl.persistence.entity.ByteArrayEntity; import org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity; @@ -28,80 +41,95 @@ import org.camunda.bpm.engine.impl.persistence.entity.MessageEntity; import org.camunda.bpm.engine.repository.ProcessDefinition; -import java.util.Date; -import java.util.List; - -import static org.camunda.bpm.engine.ProcessEngineConfiguration.HISTORY_REMOVAL_TIME_STRATEGY_END; -import static org.camunda.bpm.engine.ProcessEngineConfiguration.HISTORY_REMOVAL_TIME_STRATEGY_START; - /** * @author Tassilo Weidner */ public class ProcessSetRemovalTimeJobHandler extends AbstractBatchJobHandler { public static final BatchJobDeclaration JOB_DECLARATION = new BatchJobDeclaration(Batch.TYPE_PROCESS_SET_REMOVAL_TIME); + public static final int MAX_CHUNK_SIZE = 500; - public void executeHandler(SetRemovalTimeBatchConfiguration batchConfiguration, + @Override + public void executeHandler(SetRemovalTimeBatchConfiguration configuration, ExecutionEntity execution, CommandContext commandContext, String tenantId) { + if (configuration.isUpdateInChunks()) { + // only one instance allowed if enabled, see #calculateInvocationsPerBatchJob + String instanceId = configuration.getIds().get(0); + Set entities = configuration.getEntities(); + Integer chunkSize = getUpdateChunkSize(configuration, commandContext); + Map, DbOperation> operations = addRemovalTimeToInstance(instanceId, configuration, + chunkSize, entities, commandContext); + MessageEntity currentJob = (MessageEntity) commandContext.getCurrentJob(); + registerTransactionHandler(configuration, operations, chunkSize, currentJob, commandContext); + currentJob.setRepeat("true"); + } else { + configuration.getIds().forEach(id -> + addRemovalTimeToInstance(id, configuration, null, Collections.emptySet(), commandContext)); + } + } - for (String instanceId : batchConfiguration.getIds()) { - - HistoricProcessInstanceEntity instance = findProcessInstanceById(instanceId, commandContext); - - if (instance != null) { - if (batchConfiguration.isHierarchical() && hasHierarchy(instance)) { - String rootProcessInstanceId = instance.getRootProcessInstanceId(); - - HistoricProcessInstanceEntity rootInstance = findProcessInstanceById(rootProcessInstanceId, commandContext); - Date removalTime = getOrCalculateRemovalTime(batchConfiguration, rootInstance, commandContext); - - addRemovalTimeToHierarchy(rootProcessInstanceId, removalTime, commandContext); - - } else { - Date removalTime = getOrCalculateRemovalTime(batchConfiguration, instance, commandContext); - - if (removalTime != instance.getRemovalTime()) { - addRemovalTime(instanceId, removalTime, commandContext); - - } + protected Map, DbOperation> addRemovalTimeToInstance(String instanceId, + SetRemovalTimeBatchConfiguration configuration, + Integer batchSize, + Set entities, + CommandContext commandContext) { + HistoricProcessInstanceEntity instance = findProcessInstanceById(instanceId, commandContext); + if (instance != null) { + if (configuration.isHierarchical() && hasHierarchy(instance)) { + String rootProcessInstanceId = instance.getRootProcessInstanceId(); + HistoricProcessInstanceEntity rootInstance = findProcessInstanceById(rootProcessInstanceId, commandContext); + Date removalTime = getOrCalculateRemovalTime(configuration, rootInstance, commandContext); + return addRemovalTimeToHierarchy(rootProcessInstanceId, removalTime, batchSize, entities, commandContext); + } else { + Date removalTime = getOrCalculateRemovalTime(configuration, instance, commandContext); + if (removalTime != instance.getRemovalTime()) { + return addRemovalTime(instanceId, removalTime, batchSize, entities, commandContext); } } } + return null; } - protected Date getOrCalculateRemovalTime(SetRemovalTimeBatchConfiguration batchConfiguration, HistoricProcessInstanceEntity instance, CommandContext commandContext) { - if (batchConfiguration.hasRemovalTime()) { - return batchConfiguration.getRemovalTime(); - + protected Date getOrCalculateRemovalTime(SetRemovalTimeBatchConfiguration configuration, + HistoricProcessInstanceEntity instance, + CommandContext commandContext) { + if (configuration.hasRemovalTime()) { + return configuration.getRemovalTime(); } else if (hasBaseTime(instance, commandContext)) { return calculateRemovalTime(instance, commandContext); - } else { return null; - } } - protected void addRemovalTimeToHierarchy(String rootProcessInstanceId, Date removalTime, CommandContext commandContext) { - commandContext.getHistoricProcessInstanceManager() - .addRemovalTimeToProcessInstancesByRootProcessInstanceId(rootProcessInstanceId, removalTime); - + protected Map, DbOperation> addRemovalTimeToHierarchy(String rootProcessInstanceId, + Date removalTime, + Integer batchSize, + Set entities, + CommandContext commandContext) { + Map, DbOperation> operations = commandContext.getHistoricProcessInstanceManager() + .addRemovalTimeToProcessInstancesByRootProcessInstanceId(rootProcessInstanceId, removalTime, batchSize, entities); if (isDmnEnabled(commandContext)) { - commandContext.getHistoricDecisionInstanceManager() - .addRemovalTimeToDecisionsByRootProcessInstanceId(rootProcessInstanceId, removalTime); + operations.putAll(commandContext.getHistoricDecisionInstanceManager() + .addRemovalTimeToDecisionsByRootProcessInstanceId(rootProcessInstanceId, removalTime, batchSize, entities)); } + return operations; } - protected void addRemovalTime(String instanceId, Date removalTime, CommandContext commandContext) { - commandContext.getHistoricProcessInstanceManager() - .addRemovalTimeById(instanceId, removalTime); - + protected Map, DbOperation> addRemovalTime(String instanceId, + Date removalTime, + Integer batchSize, + Set entities, + CommandContext commandContext) { + Map, DbOperation> operations = commandContext.getHistoricProcessInstanceManager() + .addRemovalTimeById(instanceId, removalTime, batchSize, entities); if (isDmnEnabled(commandContext)) { - commandContext.getHistoricDecisionInstanceManager() - .addRemovalTimeToDecisionsByProcessInstanceId(instanceId, removalTime); + operations.putAll(commandContext.getHistoricDecisionInstanceManager() + .addRemovalTimeToDecisionsByProcessInstanceId(instanceId, removalTime, batchSize, entities)); } + return operations; } protected boolean hasBaseTime(HistoricProcessInstanceEntity instance, CommandContext commandContext) { @@ -157,23 +185,63 @@ protected HistoricProcessInstanceEntity findProcessInstanceById(String instanceI .findHistoricProcessInstance(instanceId); } + protected void registerTransactionHandler(SetRemovalTimeBatchConfiguration configuration, + Map, DbOperation> operations, + Integer chunkSize, + MessageEntity currentJob, + CommandContext commandContext) { + CommandExecutor newCommandExecutor = commandContext.getProcessEngineConfiguration().getCommandExecutorTxRequiresNew(); + TransactionListener transactionResulthandler = createTransactionHandler(configuration, operations, chunkSize, + currentJob, newCommandExecutor); + commandContext.getTransactionContext().addTransactionListener(TransactionState.COMMITTED, transactionResulthandler); + } + + protected int getUpdateChunkSize(SetRemovalTimeBatchConfiguration configuration, CommandContext commandContext) { + return configuration.getChunkSize() == null + ? commandContext.getProcessEngineConfiguration().getRemovalTimeUpdateChunkSize() + : configuration.getChunkSize(); + } + + protected TransactionListener createTransactionHandler(SetRemovalTimeBatchConfiguration configuration, + Map, DbOperation> operations, + Integer chunkSize, + MessageEntity currentJob, + CommandExecutor newCommandExecutor) { + return new ProcessSetRemovalTimeResultHandler(configuration, chunkSize, newCommandExecutor, this, + currentJob.getId(), operations); + } + + @Override public JobDeclaration getJobDeclaration() { return JOB_DECLARATION; } - protected SetRemovalTimeBatchConfiguration createJobConfiguration(SetRemovalTimeBatchConfiguration configuration, List processInstanceIds) { + @Override + protected SetRemovalTimeBatchConfiguration createJobConfiguration(SetRemovalTimeBatchConfiguration configuration, + List processInstanceIds) { return new SetRemovalTimeBatchConfiguration(processInstanceIds) .setRemovalTime(configuration.getRemovalTime()) .setHasRemovalTime(configuration.hasRemovalTime()) - .setHierarchical(configuration.isHierarchical()); + .setHierarchical(configuration.isHierarchical()) + .setUpdateInChunks(configuration.isUpdateInChunks()) + .setChunkSize(configuration.getChunkSize()); } + @Override protected SetRemovalTimeJsonConverter getJsonConverterInstance() { return SetRemovalTimeJsonConverter.INSTANCE; } + @Override + public int calculateInvocationsPerBatchJob(String batchType, SetRemovalTimeBatchConfiguration configuration) { + if (configuration.isUpdateInChunks()) { + return 1; + } + return super.calculateInvocationsPerBatchJob(batchType, configuration); + } + + @Override public String getType() { return Batch.TYPE_PROCESS_SET_REMOVAL_TIME; } - } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/batch/removaltime/ProcessSetRemovalTimeResultHandler.java b/engine/src/main/java/org/camunda/bpm/engine/impl/batch/removaltime/ProcessSetRemovalTimeResultHandler.java new file mode 100644 index 00000000000..7389584c5b4 --- /dev/null +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/batch/removaltime/ProcessSetRemovalTimeResultHandler.java @@ -0,0 +1,97 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; 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.camunda.bpm.engine.impl.batch.removaltime; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import org.camunda.bpm.engine.impl.batch.BatchJobContext; +import org.camunda.bpm.engine.impl.cfg.TransactionListener; +import org.camunda.bpm.engine.impl.db.DbEntity; +import org.camunda.bpm.engine.impl.db.entitymanager.operation.DbOperation; +import org.camunda.bpm.engine.impl.history.event.HistoricProcessInstanceEventEntity; +import org.camunda.bpm.engine.impl.interceptor.CommandContext; +import org.camunda.bpm.engine.impl.interceptor.CommandExecutor; +import org.camunda.bpm.engine.impl.persistence.entity.ByteArrayEntity; +import org.camunda.bpm.engine.impl.persistence.entity.JobEntity; +import org.camunda.bpm.engine.impl.persistence.entity.MessageEntity; +import org.camunda.bpm.engine.impl.util.ClockUtil; + +public class ProcessSetRemovalTimeResultHandler implements TransactionListener { + + protected SetRemovalTimeBatchConfiguration batchJobConfiguration; + protected Integer chunkSize; + protected CommandExecutor commandExecutor; + protected ProcessSetRemovalTimeJobHandler jobHandler; + protected String jobId; + protected Map, DbOperation> operations; + + public ProcessSetRemovalTimeResultHandler(SetRemovalTimeBatchConfiguration batchJobConfiguration, + Integer chunkSize, + CommandExecutor commandExecutor, + ProcessSetRemovalTimeJobHandler jobHandler, + String jobId, + Map, DbOperation> operations) { + this.batchJobConfiguration = batchJobConfiguration; + this.chunkSize = chunkSize; + this.commandExecutor = commandExecutor; + this.jobHandler = jobHandler; + this.jobId = jobId; + this.operations = operations; + } + + @Override + public void execute(CommandContext commandContext) { + // use the new command executor since the command context might already have been closed/finished + commandExecutor.execute(context -> { + JobEntity job = context.getJobManager().findJobById(jobId); + Set entitiesToUpdate = getEntitiesToUpdate(operations, chunkSize); + if (entitiesToUpdate.isEmpty() && !operations.containsKey(HistoricProcessInstanceEventEntity.class)) { + // update the process instance last to avoid orphans + entitiesToUpdate = new HashSet<>(); + entitiesToUpdate.add(HistoricProcessInstanceEventEntity.class.getName()); + } + if (entitiesToUpdate.isEmpty()) { + job.delete(true); + } else { + // save batch job configuration + batchJobConfiguration.setEntities(entitiesToUpdate); + ByteArrayEntity newConfiguration = saveConfiguration(batchJobConfiguration, context); + BatchJobContext newBatchContext = new BatchJobContext(null, newConfiguration); + ProcessSetRemovalTimeJobHandler.JOB_DECLARATION.reconfigure(newBatchContext, (MessageEntity) job); + // reschedule job + context.getJobManager().reschedule(job, ClockUtil.getCurrentTime()); + } + return null; + }); + } + + protected ByteArrayEntity saveConfiguration(SetRemovalTimeBatchConfiguration configuration, CommandContext context) { + ByteArrayEntity configurationEntity = new ByteArrayEntity(); + configurationEntity.setBytes(jobHandler.writeConfiguration(configuration)); + context.getByteArrayManager().insert(configurationEntity); + return configurationEntity; + } + + protected static Set getEntitiesToUpdate(Map, DbOperation> operations, int chunkSize) { + return operations.entrySet().stream() + .filter(op -> op.getValue().getRowsAffected() == chunkSize) + .map(op -> op.getKey().getName()) + .collect(Collectors.toSet()); + } +} diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/batch/removaltime/SetRemovalTimeBatchConfiguration.java b/engine/src/main/java/org/camunda/bpm/engine/impl/batch/removaltime/SetRemovalTimeBatchConfiguration.java index fbb59a17306..ea7ca7bad41 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/batch/removaltime/SetRemovalTimeBatchConfiguration.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/batch/removaltime/SetRemovalTimeBatchConfiguration.java @@ -18,7 +18,7 @@ import java.util.Date; import java.util.List; - +import java.util.Set; import org.camunda.bpm.engine.impl.batch.BatchConfiguration; import org.camunda.bpm.engine.impl.batch.DeploymentMappings; @@ -30,6 +30,9 @@ public class SetRemovalTimeBatchConfiguration extends BatchConfiguration { protected Date removalTime; protected boolean hasRemovalTime; protected boolean isHierarchical; + protected boolean updateInChunks; + protected Integer chunkSize; + protected Set entities; public SetRemovalTimeBatchConfiguration(List ids) { this(ids, null); @@ -66,4 +69,31 @@ public SetRemovalTimeBatchConfiguration setHierarchical(boolean hierarchical) { return this; } + public boolean isUpdateInChunks() { + return updateInChunks; + } + + public SetRemovalTimeBatchConfiguration setUpdateInChunks(boolean updateInChunks) { + this.updateInChunks = updateInChunks; + return this; + } + + public Integer getChunkSize() { + return chunkSize; + } + + public SetRemovalTimeBatchConfiguration setChunkSize(Integer chunkSize) { + this.chunkSize = chunkSize; + return this; + } + + public Set getEntities() { + return entities; + } + + public SetRemovalTimeBatchConfiguration setEntities(Set entities) { + this.entities = entities; + return this; + } + } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/batch/removaltime/SetRemovalTimeJsonConverter.java b/engine/src/main/java/org/camunda/bpm/engine/impl/batch/removaltime/SetRemovalTimeJsonConverter.java index afd8c5c161c..9665bfc3f27 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/batch/removaltime/SetRemovalTimeJsonConverter.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/batch/removaltime/SetRemovalTimeJsonConverter.java @@ -17,15 +17,16 @@ package org.camunda.bpm.engine.impl.batch.removaltime; import com.google.gson.JsonObject; - +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import org.camunda.bpm.engine.impl.batch.AbstractBatchConfigurationObjectConverter; import org.camunda.bpm.engine.impl.batch.DeploymentMappingJsonConverter; import org.camunda.bpm.engine.impl.batch.DeploymentMappings; import org.camunda.bpm.engine.impl.util.JsonUtil; -import java.util.Date; -import java.util.List; - /** * @author Tassilo Weidner */ @@ -39,6 +40,9 @@ public class SetRemovalTimeJsonConverter protected static final String REMOVAL_TIME = "removalTime"; protected static final String HAS_REMOVAL_TIME = "hasRemovalTime"; protected static final String IS_HIERARCHICAL = "isHierarchical"; + protected static final String UPDATE_IN_CHUNKS = "updateInChunks"; + protected static final String CHUNK_SIZE = "chunkSize"; + protected static final String ENTITIES = "entities"; @Override public JsonObject writeConfiguration(SetRemovalTimeBatchConfiguration configuration) { @@ -49,6 +53,11 @@ public JsonObject writeConfiguration(SetRemovalTimeBatchConfiguration configurat JsonUtil.addDateField(json, REMOVAL_TIME, configuration.getRemovalTime()); JsonUtil.addField(json, HAS_REMOVAL_TIME, configuration.hasRemovalTime()); JsonUtil.addField(json, IS_HIERARCHICAL, configuration.isHierarchical()); + JsonUtil.addField(json, UPDATE_IN_CHUNKS, configuration.isUpdateInChunks()); + JsonUtil.addField(json, CHUNK_SIZE, configuration.getChunkSize()); + if (configuration.getEntities() != null) { + JsonUtil.addListField(json, ENTITIES, new ArrayList<>(configuration.getEntities())); + } return json; } @@ -59,7 +68,7 @@ public SetRemovalTimeBatchConfiguration readConfiguration(JsonObject jsonObject) long removalTimeMills = JsonUtil.getLong(jsonObject, REMOVAL_TIME); Date removalTime = removalTimeMills > 0 ? new Date(removalTimeMills) : null; - List instanceIds = JsonUtil.asStringList(JsonUtil.getArray(jsonObject, IDS)); + List instanceIds = JsonUtil.asStringList(JsonUtil.getArray(jsonObject, IDS)); DeploymentMappings mappings = JsonUtil.asList(JsonUtil.getArray(jsonObject, ID_MAPPINGS), DeploymentMappingJsonConverter.INSTANCE, DeploymentMappings::new); @@ -68,10 +77,22 @@ public SetRemovalTimeBatchConfiguration readConfiguration(JsonObject jsonObject) boolean isHierarchical = JsonUtil.getBoolean(jsonObject, IS_HIERARCHICAL); + boolean updateInChunks = JsonUtil.getBoolean(jsonObject, UPDATE_IN_CHUNKS); + + Integer chunkSize = jsonObject.has(CHUNK_SIZE)? JsonUtil.getInt(jsonObject, CHUNK_SIZE) : null; + + Set entities = null; + if (jsonObject.has(ENTITIES)) { + entities = new HashSet<>(JsonUtil.asStringList(JsonUtil.getArray(jsonObject, ENTITIES))); + } + return new SetRemovalTimeBatchConfiguration(instanceIds, mappings) .setRemovalTime(removalTime) .setHasRemovalTime(hasRemovalTime) - .setHierarchical(isHierarchical); + .setHierarchical(isHierarchical) + .setUpdateInChunks(updateInChunks) + .setChunkSize(chunkSize) + .setEntities(entities); } } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/ProcessEngineConfigurationImpl.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/ProcessEngineConfigurationImpl.java index 389c22a13b3..fbbb3c98fa7 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/ProcessEngineConfigurationImpl.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cfg/ProcessEngineConfigurationImpl.java @@ -1063,6 +1063,11 @@ public abstract class ProcessEngineConfigurationImpl extends ProcessEngineConfig /** Controls whether the time cycle is re-evaluated when due. */ protected boolean reevaluateTimeCycleWhenDue = false; + /** + * Size of batch in which removal time data will be updated. {@link ProcessSetRemovalTimeJobHandler#MAX_CHUNK_SIZE} must be respected. + */ + protected int removalTimeUpdateChunkSize = 500; + /** * @return {@code true} if the exception code feature is disabled and vice-versa. */ @@ -1475,7 +1480,7 @@ protected void initIncidentHandlers() { // batch /////////////////////////////////////////////////////////////////////// - protected void initBatchHandlers() { + public void initBatchHandlers() { if (batchHandlers == null) { batchHandlers = new HashMap<>(); @@ -1527,6 +1532,11 @@ protected void initBatchHandlers() { batchHandlers.put(customBatchJobHandler.getType(), customBatchJobHandler); } } + + if (removalTimeUpdateChunkSize > ProcessSetRemovalTimeJobHandler.MAX_CHUNK_SIZE || removalTimeUpdateChunkSize <= 0) { + throw LOG.invalidPropertyValue("removalTimeUpdateChunkSize", String.valueOf(removalTimeUpdateChunkSize), + String.format("value for chunk size should be between 1 and %s", ProcessSetRemovalTimeJobHandler.MAX_CHUNK_SIZE)); + } } // command executors //////////////////////////////////////////////////////// @@ -1895,6 +1905,9 @@ public static void initSqlSessionFactoryProperties(Properties properties, String properties.put("distinct", DbSqlSessionFactory.databaseSpecificDistinct.get(databaseType)); properties.put("numericCast", DbSqlSessionFactory.databaseSpecificNumericCast.get(databaseType)); + properties.put("limitBeforeInUpdate", DbSqlSessionFactory.databaseSpecificLimitBeforeInUpdate.get(databaseType)); + properties.put("limitAfterInUpdate", DbSqlSessionFactory.databaseSpecificLimitAfterInUpdate.get(databaseType)); + properties.put("countDistinctBeforeStart", DbSqlSessionFactory.databaseSpecificCountDistinctBeforeStart.get(databaseType)); properties.put("countDistinctBeforeEnd", DbSqlSessionFactory.databaseSpecificCountDistinctBeforeEnd.get(databaseType)); properties.put("countDistinctAfterEnd", DbSqlSessionFactory.databaseSpecificCountDistinctAfterEnd.get(databaseType)); @@ -5351,6 +5364,15 @@ public ProcessEngineConfigurationImpl setReevaluateTimeCycleWhenDue(boolean reev return this; } + public int getRemovalTimeUpdateChunkSize() { + return removalTimeUpdateChunkSize; + } + + public ProcessEngineConfigurationImpl setRemovalTimeUpdateChunkSize(int removalTimeUpdateChunkSize) { + this.removalTimeUpdateChunkSize = removalTimeUpdateChunkSize; + return this; + } + protected CrdbTransactionRetryInterceptor getCrdbRetryInterceptor() { return new CrdbTransactionRetryInterceptor(commandRetries); } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/batch/removaltime/SetRemovalTimeToHistoricProcessInstancesCmd.java b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/batch/removaltime/SetRemovalTimeToHistoricProcessInstancesCmd.java index 77792efb1c7..1ce9090a3ec 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/batch/removaltime/SetRemovalTimeToHistoricProcessInstancesCmd.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/cmd/batch/removaltime/SetRemovalTimeToHistoricProcessInstancesCmd.java @@ -16,15 +16,21 @@ */ package org.camunda.bpm.engine.impl.cmd.batch.removaltime; +import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotEmpty; +import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; import org.camunda.bpm.engine.BadUserRequestException; import org.camunda.bpm.engine.authorization.BatchPermissions; import org.camunda.bpm.engine.batch.Batch; import org.camunda.bpm.engine.history.HistoricProcessInstanceQuery; import org.camunda.bpm.engine.history.UserOperationLogEntry; -import org.camunda.bpm.engine.impl.batch.builder.BatchBuilder; import org.camunda.bpm.engine.impl.HistoricProcessInstanceQueryImpl; import org.camunda.bpm.engine.impl.batch.BatchConfiguration; import org.camunda.bpm.engine.impl.batch.BatchElementConfiguration; +import org.camunda.bpm.engine.impl.batch.builder.BatchBuilder; import org.camunda.bpm.engine.impl.batch.removaltime.SetRemovalTimeBatchConfiguration; import org.camunda.bpm.engine.impl.history.SetRemovalTimeToHistoricProcessInstancesBuilderImpl; import org.camunda.bpm.engine.impl.history.SetRemovalTimeToHistoricProcessInstancesBuilderImpl.Mode; @@ -33,13 +39,6 @@ import org.camunda.bpm.engine.impl.persistence.entity.PropertyChange; import org.camunda.bpm.engine.impl.util.CollectionUtil; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; - -import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotEmpty; -import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNotNull; - /** * @author Tassilo Weidner */ @@ -90,7 +89,9 @@ protected BatchConfiguration getConfiguration(BatchElementConfiguration elementC return new SetRemovalTimeBatchConfiguration(elementConfiguration.getIds(), elementConfiguration.getMappings()) .setHierarchical(builder.isHierarchical()) .setHasRemovalTime(hasRemovalTime()) - .setRemovalTime(builder.getRemovalTime()); + .setRemovalTime(builder.getRemovalTime()) + .setUpdateInChunks(builder.isUpdateInChunks()) + .setChunkSize(builder.getChunkSize()); } protected boolean hasRemovalTime() { @@ -105,6 +106,8 @@ protected void writeUserOperationLog(CommandContext commandContext, int numInsta propertyChanges.add(new PropertyChange("hierarchical", null, builder.isHierarchical())); propertyChanges.add(new PropertyChange("nrOfInstances", null, numInstances)); propertyChanges.add(new PropertyChange("async", null, true)); + propertyChanges.add(new PropertyChange("updateInChunks", null, builder.isUpdateInChunks())); + propertyChanges.add(new PropertyChange("chunkSize", null, builder.getChunkSize())); commandContext.getOperationLogManager() .logProcessInstanceOperation(UserOperationLogEntry.OPERATION_TYPE_SET_REMOVAL_TIME, propertyChanges); diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/db/entitymanager/DbEntityManager.java b/engine/src/main/java/org/camunda/bpm/engine/impl/db/entitymanager/DbEntityManager.java index f1cc5cd1026..89d5f5d4550 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/db/entitymanager/DbEntityManager.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/db/entitymanager/DbEntityManager.java @@ -583,8 +583,8 @@ public void update(Class entityType, String statement, Objec * @param statement * @param parameter */ - public void updatePreserveOrder(Class entityType, String statement, Object parameter) { - performBulkOperationPreserveOrder(entityType, statement, parameter, UPDATE_BULK); + public DbOperation updatePreserveOrder(Class entityType, String statement, Object parameter) { + return performBulkOperationPreserveOrder(entityType, statement, parameter, UPDATE_BULK); } public void delete(Class entityType, String statement, Object parameter) { diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/db/sql/DbSqlSessionFactory.java b/engine/src/main/java/org/camunda/bpm/engine/impl/db/sql/DbSqlSessionFactory.java index ce98cc7ad3e..a1ed07f2797 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/db/sql/DbSqlSessionFactory.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/db/sql/DbSqlSessionFactory.java @@ -21,7 +21,6 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; - import org.apache.ibatis.session.SqlSessionFactory; import org.camunda.bpm.engine.impl.cfg.IdGenerator; import org.camunda.bpm.engine.impl.db.DbEntity; @@ -57,6 +56,9 @@ public class DbSqlSessionFactory implements SessionFactory { public static final Map databaseSpecificLimitBetweenStatements = new HashMap<>(); public static final Map databaseSpecificLimitBetweenFilterStatements = new HashMap<>(); public static final Map databaseSpecificLimitBetweenAcquisitionStatements = new HashMap<>(); + // limit before and after for update queries + public static final Map databaseSpecificLimitBeforeInUpdate = new HashMap<>(); + public static final Map databaseSpecificLimitAfterInUpdate = new HashMap<>(); // count distinct statements public static final Map databaseSpecificCountDistinctBeforeStart = new HashMap<>(); public static final Map databaseSpecificCountDistinctBeforeEnd = new HashMap<>(); @@ -94,11 +96,11 @@ public class DbSqlSessionFactory implements SessionFactory { public static final Map databaseSpecificDaysComparator = new HashMap<>(); public static final Map databaseSpecificCollationForCaseSensitivity = new HashMap<>(); - + public static final Map databaseSpecificAuthJoinStart = new HashMap<>(); public static final Map databaseSpecificAuthJoinEnd = new HashMap<>(); public static final Map databaseSpecificAuthJoinSeparator = new HashMap<>(); - + public static final Map databaseSpecificAuth1JoinStart = new HashMap<>(); public static final Map databaseSpecificAuth1JoinEnd = new HashMap<>(); public static final Map databaseSpecificAuth1JoinSeparator = new HashMap<>(); @@ -118,7 +120,7 @@ public class DbSqlSessionFactory implements SessionFactory { String defaultDistinctCountBeforeStart = "select count(distinct"; String defaultDistinctCountBeforeEnd = ")"; String defaultDistinctCountAfterEnd = ""; - + String defaultAuthOnStart = "IN ("; String defaultAuthOnEnd = ")"; String defaultAuthOnSeparator = ","; @@ -134,6 +136,8 @@ public class DbSqlSessionFactory implements SessionFactory { databaseSpecificLimitBetweenStatements.put(H2, ""); databaseSpecificLimitBetweenFilterStatements.put(H2, ""); databaseSpecificLimitBetweenAcquisitionStatements.put(H2, ""); + databaseSpecificLimitBeforeInUpdate.put(H2, ""); + databaseSpecificLimitAfterInUpdate.put(H2, ""); databaseSpecificOrderByStatements.put(H2, defaultOrderBy); databaseSpecificLimitBeforeNativeQueryStatements.put(H2, ""); databaseSpecificDistinct.put(H2, "distinct"); @@ -160,11 +164,11 @@ public class DbSqlSessionFactory implements SessionFactory { databaseSpecificDaysComparator.put(H2, "DATEDIFF(DAY, ${date}, #{currentTimestamp}) >= ${days}"); databaseSpecificCollationForCaseSensitivity.put(H2, ""); - + databaseSpecificAuthJoinStart.put(H2, defaultAuthOnStart); databaseSpecificAuthJoinEnd.put(H2, defaultAuthOnEnd); databaseSpecificAuthJoinSeparator.put(H2, defaultAuthOnSeparator); - + databaseSpecificAuth1JoinStart.put(H2, defaultAuthOnStart); databaseSpecificAuth1JoinEnd.put(H2, defaultAuthOnEnd); databaseSpecificAuth1JoinSeparator.put(H2, defaultAuthOnSeparator); @@ -196,6 +200,8 @@ public class DbSqlSessionFactory implements SessionFactory { databaseSpecificLimitBetweenStatements.put(mysqlLikeDatabase, ""); databaseSpecificLimitBetweenFilterStatements.put(mysqlLikeDatabase, ""); databaseSpecificLimitBetweenAcquisitionStatements.put(mysqlLikeDatabase, ""); + databaseSpecificLimitBeforeInUpdate.put(mysqlLikeDatabase, "INNER JOIN ( SELECT ID_ FROM "); + databaseSpecificLimitAfterInUpdate.put(mysqlLikeDatabase, databaseSpecificLimitAfterWithoutOffsetStatements.get(mysqlLikeDatabase) + ") tmp USING (ID_)"); databaseSpecificOrderByStatements.put(mysqlLikeDatabase, defaultOrderBy); databaseSpecificLimitBeforeNativeQueryStatements.put(mysqlLikeDatabase, ""); databaseSpecificDistinct.put(mysqlLikeDatabase, "distinct"); @@ -222,11 +228,11 @@ public class DbSqlSessionFactory implements SessionFactory { databaseSpecificDaysComparator.put(mysqlLikeDatabase, "DATEDIFF(#{currentTimestamp}, ${date}) >= ${days}"); databaseSpecificCollationForCaseSensitivity.put(mysqlLikeDatabase, ""); - + databaseSpecificAuthJoinStart.put(mysqlLikeDatabase, "="); databaseSpecificAuthJoinEnd.put(mysqlLikeDatabase, ""); databaseSpecificAuthJoinSeparator.put(mysqlLikeDatabase, "OR AUTH.RESOURCE_ID_ ="); - + databaseSpecificAuth1JoinStart.put(mysqlLikeDatabase, "="); databaseSpecificAuth1JoinEnd.put(mysqlLikeDatabase, ""); databaseSpecificAuth1JoinSeparator.put(mysqlLikeDatabase, "OR AUTH1.RESOURCE_ID_ ="); @@ -271,6 +277,48 @@ public class DbSqlSessionFactory implements SessionFactory { // related to CAM-12070 addDatabaseSpecificStatement(mysqlLikeDatabase, "updateByteArraysByBatchId", "updateByteArraysByBatchId_mysql"); + // related to https://github.com/camunda/camunda-bpm-platform/issues/3064 + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateAttachmentsByRootProcessInstanceId", "updateAttachmentsByRootProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateAttachmentsByProcessInstanceId", "updateAttachmentsByProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateAuthorizationsByRootProcessInstanceId", "updateAuthorizationsByRootProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateAuthorizationsByProcessInstanceId", "updateAuthorizationsByProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateCommentsByRootProcessInstanceId", "updateCommentsByRootProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateCommentsByProcessInstanceId", "updateCommentsByProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateHistoricActivityInstancesByRootProcessInstanceId", "updateHistoricActivityInstancesByRootProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateHistoricActivityInstancesByProcessInstanceId", "updateHistoricActivityInstancesByProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateHistoricDecisionInputInstancesByRootProcessInstanceId", "updateHistoricDecisionInputInstancesByRootProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateHistoricDecisionInputInstancesByProcessInstanceId", "updateHistoricDecisionInputInstancesByProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateHistoricDecisionInstancesByRootProcessInstanceId", "updateHistoricDecisionInstancesByRootProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateHistoricDecisionInstancesByProcessInstanceId", "updateHistoricDecisionInstancesByProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateHistoricDecisionOutputInstancesByRootProcessInstanceId", "updateHistoricDecisionOutputInstancesByRootProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateHistoricDecisionOutputInstancesByProcessInstanceId", "updateHistoricDecisionOutputInstancesByProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateHistoricDetailsByRootProcessInstanceId", "updateHistoricDetailsByRootProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateHistoricDetailsByProcessInstanceId", "updateHistoricDetailsByProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateJobLogByRootProcessInstanceId", "updateJobLogByRootProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateJobLogByProcessInstanceId", "updateJobLogByProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateHistoricProcessInstanceEventsByRootProcessInstanceId", "updateHistoricProcessInstanceEventsByRootProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateHistoricProcessInstanceByProcessInstanceId", "updateHistoricProcessInstanceByProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateHistoricTaskInstancesByRootProcessInstanceId", "updateHistoricTaskInstancesByRootProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateHistoricTaskInstancesByProcessInstanceId", "updateHistoricTaskInstancesByProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateHistoricVariableInstancesByRootProcessInstanceId", "updateHistoricVariableInstancesByRootProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateHistoricVariableInstancesByProcessInstanceId", "updateHistoricVariableInstancesByProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateByteArraysByRootProcessInstanceId", "updateByteArraysByRootProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateVariableByteArraysByProcessInstanceId", "updateVariableByteArraysByProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateDecisionInputsByteArraysByProcessInstanceId", "updateDecisionInputsByteArraysByProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateDecisionOutputsByteArraysByProcessInstanceId", "updateDecisionOutputsByteArraysByProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateJobLogByteArraysByProcessInstanceId", "updateJobLogByteArraysByProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateExternalTaskLogByteArraysByProcessInstanceId", "updateExternalTaskLogByteArraysByProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateAttachmentByteArraysByProcessInstanceId", "updateAttachmentByteArraysByProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateExternalTaskLogByRootProcessInstanceId", "updateExternalTaskLogByRootProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateExternalTaskLogByProcessInstanceId", "updateExternalTaskLogByProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateIdentityLinkLogByRootProcessInstanceId", "updateIdentityLinkLogByRootProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateIdentityLinkLogByProcessInstanceId", "updateIdentityLinkLogByProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateHistoricIncidentsByRootProcessInstanceId", "updateHistoricIncidentsByRootProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateHistoricIncidentsByProcessInstanceId", "updateHistoricIncidentsByProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateUserOperationLogByRootProcessInstanceId", "updateUserOperationLogByRootProcessInstanceId_mysql"); + addDatabaseSpecificStatement(mysqlLikeDatabase, "updateUserOperationLogByProcessInstanceId", "updateUserOperationLogByProcessInstanceId_mysql"); + + constants = new HashMap<>(); constants.put("constant.event", "'event'"); constants.put("constant.op_message", "CONCAT(NEW_VALUE_, '_|_', PROPERTY_)"); @@ -294,10 +342,12 @@ public class DbSqlSessionFactory implements SessionFactory { optimizeDatabaseSpecificLimitAfterWithoutOffsetStatements.put(postgresLikeDatabase, "LIMIT #{maxResults}"); databaseSpecificLimitBeforeWithoutOffsetStatements.put(postgresLikeDatabase, ""); databaseSpecificLimitAfterWithoutOffsetStatements.put(postgresLikeDatabase, "LIMIT #{maxResults}"); - databaseSpecificInnerLimitAfterStatements.put(postgresLikeDatabase, databaseSpecificLimitAfterStatements.get(POSTGRES)); + databaseSpecificInnerLimitAfterStatements.put(postgresLikeDatabase, databaseSpecificLimitAfterStatements.get(postgresLikeDatabase)); databaseSpecificLimitBetweenStatements.put(postgresLikeDatabase, ""); databaseSpecificLimitBetweenFilterStatements.put(postgresLikeDatabase, ""); databaseSpecificLimitBetweenAcquisitionStatements.put(postgresLikeDatabase, ""); + databaseSpecificLimitBeforeInUpdate.put(postgresLikeDatabase, "WHERE ID_ IN (SELECT ID_ FROM "); + databaseSpecificLimitAfterInUpdate.put(postgresLikeDatabase, databaseSpecificLimitAfterWithoutOffsetStatements.get(postgresLikeDatabase) + ")"); databaseSpecificOrderByStatements.put(postgresLikeDatabase, defaultOrderBy); databaseSpecificLimitBeforeNativeQueryStatements.put(postgresLikeDatabase, ""); databaseSpecificDistinct.put(postgresLikeDatabase, "distinct"); @@ -321,11 +371,11 @@ public class DbSqlSessionFactory implements SessionFactory { databaseSpecificIfNull.put(postgresLikeDatabase, "COALESCE"); databaseSpecificCollationForCaseSensitivity.put(postgresLikeDatabase, ""); - + databaseSpecificAuthJoinStart.put(postgresLikeDatabase, defaultAuthOnStart); databaseSpecificAuthJoinEnd.put(postgresLikeDatabase, defaultAuthOnEnd); databaseSpecificAuthJoinSeparator.put(postgresLikeDatabase, defaultAuthOnSeparator); - + databaseSpecificAuth1JoinStart.put(postgresLikeDatabase, defaultAuthOnStart); databaseSpecificAuth1JoinEnd.put(postgresLikeDatabase, defaultAuthOnEnd); databaseSpecificAuth1JoinSeparator.put(postgresLikeDatabase, defaultAuthOnSeparator); @@ -375,6 +425,48 @@ public class DbSqlSessionFactory implements SessionFactory { addDatabaseSpecificStatement(postgresLikeDatabase, "deleteAuthorizationsByRemovalTime", "deleteAuthorizationsByRemovalTime_postgres_or_db2"); addDatabaseSpecificStatement(postgresLikeDatabase, "deleteTaskMetricsByRemovalTime", "deleteTaskMetricsByRemovalTime_postgres_or_db2"); + // related to https://github.com/camunda/camunda-bpm-platform/issues/3064 + addDatabaseSpecificStatement(postgresLikeDatabase, "updateAttachmentsByRootProcessInstanceId", "updateAttachmentsByRootProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateAttachmentsByProcessInstanceId", "updateAttachmentsByProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateAuthorizationsByRootProcessInstanceId", "updateAuthorizationsByRootProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateAuthorizationsByProcessInstanceId", "updateAuthorizationsByProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateCommentsByRootProcessInstanceId", "updateCommentsByRootProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateCommentsByProcessInstanceId", "updateCommentsByProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateHistoricActivityInstancesByRootProcessInstanceId", "updateHistoricActivityInstancesByRootProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateHistoricActivityInstancesByProcessInstanceId", "updateHistoricActivityInstancesByProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateHistoricDecisionInputInstancesByRootProcessInstanceId", "updateHistoricDecisionInputInstancesByRootProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateHistoricDecisionInputInstancesByProcessInstanceId", "updateHistoricDecisionInputInstancesByProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateHistoricDecisionInstancesByRootProcessInstanceId", "updateHistoricDecisionInstancesByRootProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateHistoricDecisionInstancesByProcessInstanceId", "updateHistoricDecisionInstancesByProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateHistoricDecisionOutputInstancesByRootProcessInstanceId", "updateHistoricDecisionOutputInstancesByRootProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateHistoricDecisionOutputInstancesByProcessInstanceId", "updateHistoricDecisionOutputInstancesByProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateHistoricDetailsByRootProcessInstanceId", "updateHistoricDetailsByRootProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateHistoricDetailsByProcessInstanceId", "updateHistoricDetailsByProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateJobLogByRootProcessInstanceId", "updateJobLogByRootProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateJobLogByProcessInstanceId", "updateJobLogByProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateHistoricProcessInstanceEventsByRootProcessInstanceId", "updateHistoricProcessInstanceEventsByRootProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateHistoricProcessInstanceByProcessInstanceId", "updateHistoricProcessInstanceByProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateHistoricTaskInstancesByRootProcessInstanceId", "updateHistoricTaskInstancesByRootProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateHistoricTaskInstancesByProcessInstanceId", "updateHistoricTaskInstancesByProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateHistoricVariableInstancesByRootProcessInstanceId", "updateHistoricVariableInstancesByRootProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateHistoricVariableInstancesByProcessInstanceId", "updateHistoricVariableInstancesByProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateByteArraysByRootProcessInstanceId", "updateByteArraysByRootProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateVariableByteArraysByProcessInstanceId", "updateVariableByteArraysByProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateDecisionInputsByteArraysByProcessInstanceId", "updateDecisionInputsByteArraysByProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateDecisionOutputsByteArraysByProcessInstanceId", "updateDecisionOutputsByteArraysByProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateJobLogByteArraysByProcessInstanceId", "updateJobLogByteArraysByProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateExternalTaskLogByteArraysByProcessInstanceId", "updateExternalTaskLogByteArraysByProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateAttachmentByteArraysByProcessInstanceId", "updateAttachmentByteArraysByProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateExternalTaskLogByRootProcessInstanceId", "updateExternalTaskLogByRootProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateExternalTaskLogByProcessInstanceId", "updateExternalTaskLogByProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateIdentityLinkLogByRootProcessInstanceId", "updateIdentityLinkLogByRootProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateIdentityLinkLogByProcessInstanceId", "updateIdentityLinkLogByProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateHistoricIncidentsByRootProcessInstanceId", "updateHistoricIncidentsByRootProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateHistoricIncidentsByProcessInstanceId", "updateHistoricIncidentsByProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateUserOperationLogByRootProcessInstanceId", "updateUserOperationLogByRootProcessInstanceId_postgres"); + addDatabaseSpecificStatement(postgresLikeDatabase, "updateUserOperationLogByProcessInstanceId", "updateUserOperationLogByProcessInstanceId_postgres"); + + constants = new HashMap<>(); constants.put("constant.event", "'event'"); constants.put("constant.op_message", "NEW_VALUE_ || '_|_' || PROPERTY_"); @@ -407,6 +499,8 @@ public class DbSqlSessionFactory implements SessionFactory { databaseSpecificLimitBetweenStatements.put(ORACLE, ""); databaseSpecificLimitBetweenFilterStatements.put(ORACLE, ""); databaseSpecificLimitBetweenAcquisitionStatements.put(ORACLE, ""); + databaseSpecificLimitBeforeInUpdate.put(ORACLE, ""); + databaseSpecificLimitAfterInUpdate.put(ORACLE, ""); databaseSpecificOrderByStatements.put(ORACLE, defaultOrderBy); databaseSpecificLimitBeforeNativeQueryStatements.put(ORACLE, ""); databaseSpecificDistinct.put(ORACLE, "distinct"); @@ -433,11 +527,11 @@ public class DbSqlSessionFactory implements SessionFactory { databaseSpecificDaysComparator.put(ORACLE, "${date} <= #{currentTimestamp} - ${days}"); databaseSpecificCollationForCaseSensitivity.put(ORACLE, ""); - + databaseSpecificAuthJoinStart.put(ORACLE, defaultAuthOnStart); databaseSpecificAuthJoinEnd.put(ORACLE, defaultAuthOnEnd); databaseSpecificAuthJoinSeparator.put(ORACLE, defaultAuthOnSeparator); - + databaseSpecificAuth1JoinStart.put(ORACLE, defaultAuthOnStart); databaseSpecificAuth1JoinEnd.put(ORACLE, defaultAuthOnEnd); databaseSpecificAuth1JoinSeparator.put(ORACLE, defaultAuthOnSeparator); @@ -496,6 +590,8 @@ public class DbSqlSessionFactory implements SessionFactory { databaseSpecificLimitBetweenFilterStatements.put(DB2, db2LimitBetweenWithoutColumns + "RES.ID_, RES.REV_, RES.RESOURCE_TYPE_, RES.NAME_, RES.OWNER_ "); databaseSpecificLimitBetweenAcquisitionStatements.put(DB2, db2LimitBetweenWithoutColumns + "RES.ID_, RES.REV_, RES.TYPE_, RES.LOCK_EXP_TIME_, RES.LOCK_OWNER_, RES.EXCLUSIVE_, RES.PROCESS_INSTANCE_ID_, RES.DUEDATE_, RES.PRIORITY_ "); + databaseSpecificLimitBeforeInUpdate.put(DB2, ""); + databaseSpecificLimitAfterInUpdate.put(DB2, ""); databaseSpecificLimitBeforeWithoutOffsetStatements.put(DB2, ""); databaseSpecificLimitAfterWithoutOffsetStatements.put(DB2, "FETCH FIRST ${maxResults} ROWS ONLY"); databaseSpecificOrderByStatements.put(DB2, defaultOrderBy); @@ -524,11 +620,11 @@ public class DbSqlSessionFactory implements SessionFactory { databaseSpecificDaysComparator.put(DB2, "${date} + ${days} DAYS <= #{currentTimestamp}"); databaseSpecificCollationForCaseSensitivity.put(DB2, ""); - + databaseSpecificAuthJoinStart.put(DB2, defaultAuthOnStart); databaseSpecificAuthJoinEnd.put(DB2, defaultAuthOnEnd); databaseSpecificAuthJoinSeparator.put(DB2, defaultAuthOnSeparator); - + databaseSpecificAuth1JoinStart.put(DB2, defaultAuthOnStart); databaseSpecificAuth1JoinEnd.put(DB2, defaultAuthOnEnd); databaseSpecificAuth1JoinSeparator.put(DB2, defaultAuthOnSeparator); @@ -590,6 +686,8 @@ public class DbSqlSessionFactory implements SessionFactory { databaseSpecificLimitBetweenFilterStatements.put(MSSQL, ""); databaseSpecificLimitBetweenAcquisitionStatements.put(MSSQL, mssqlLimitBetweenWithoutColumns + "RES.ID_, RES.REV_, RES.TYPE_, RES.LOCK_EXP_TIME_, RES.LOCK_OWNER_, RES.EXCLUSIVE_, RES.PROCESS_INSTANCE_ID_, RES.DUEDATE_, RES.PRIORITY_ "); + databaseSpecificLimitBeforeInUpdate.put(MSSQL, ""); + databaseSpecificLimitAfterInUpdate.put(MSSQL, ""); databaseSpecificLimitBeforeWithoutOffsetStatements.put(MSSQL, "TOP (#{maxResults})"); databaseSpecificLimitAfterWithoutOffsetStatements.put(MSSQL, ""); databaseSpecificOrderByStatements.put(MSSQL, ""); @@ -618,11 +716,11 @@ public class DbSqlSessionFactory implements SessionFactory { databaseSpecificDaysComparator.put(MSSQL, "DATEDIFF(DAY, ${date}, #{currentTimestamp}) >= ${days}"); databaseSpecificCollationForCaseSensitivity.put(MSSQL, "COLLATE Latin1_General_CS_AS"); - + databaseSpecificAuthJoinStart.put(MSSQL, defaultAuthOnStart); databaseSpecificAuthJoinEnd.put(MSSQL, defaultAuthOnEnd); databaseSpecificAuthJoinSeparator.put(MSSQL, defaultAuthOnSeparator); - + databaseSpecificAuth1JoinStart.put(MSSQL, defaultAuthOnStart); databaseSpecificAuth1JoinEnd.put(MSSQL, defaultAuthOnEnd); databaseSpecificAuth1JoinSeparator.put(MSSQL, defaultAuthOnSeparator); @@ -743,10 +841,12 @@ public DbSqlSessionFactory(boolean jdbcBatchProcessing) { this.jdbcBatchProcessing = jdbcBatchProcessing; } + @Override public Class< ? > getSessionType() { return DbSqlSession.class; } + @Override public Session openSession() { return jdbcBatchProcessing ? new BatchDbSqlSession(this) : new SimpleDbSqlSession(this); } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/history/SetRemovalTimeToHistoricProcessInstancesBuilderImpl.java b/engine/src/main/java/org/camunda/bpm/engine/impl/history/SetRemovalTimeToHistoricProcessInstancesBuilderImpl.java index c25a60c823b..a556aa431e8 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/history/SetRemovalTimeToHistoricProcessInstancesBuilderImpl.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/history/SetRemovalTimeToHistoricProcessInstancesBuilderImpl.java @@ -16,20 +16,20 @@ */ package org.camunda.bpm.engine.impl.history; +import static org.camunda.bpm.engine.impl.util.EnsureUtil.ensureNull; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; import org.camunda.bpm.engine.BadUserRequestException; import org.camunda.bpm.engine.batch.Batch; import org.camunda.bpm.engine.history.HistoricProcessInstanceQuery; import org.camunda.bpm.engine.history.SetRemovalTimeSelectModeForHistoricProcessInstancesBuilder; import org.camunda.bpm.engine.history.SetRemovalTimeToHistoricProcessInstancesBuilder; +import org.camunda.bpm.engine.impl.batch.removaltime.ProcessSetRemovalTimeJobHandler; import org.camunda.bpm.engine.impl.cmd.batch.removaltime.SetRemovalTimeToHistoricProcessInstancesCmd; import org.camunda.bpm.engine.impl.interceptor.CommandExecutor; -import java.util.Arrays; -import java.util.Date; -import java.util.List; - -import static org.camunda.bpm.engine.impl.util.EnsureUtil.*; - /** * @author Tassilo Weidner */ @@ -40,6 +40,8 @@ public class SetRemovalTimeToHistoricProcessInstancesBuilderImpl implements SetR protected Date removalTime; protected Mode mode = null; protected boolean isHierarchical; + protected boolean updateInChunks; + protected Integer chunkSize; protected CommandExecutor commandExecutor; @@ -47,16 +49,19 @@ public SetRemovalTimeToHistoricProcessInstancesBuilderImpl(CommandExecutor comma this.commandExecutor = commandExecutor; } + @Override public SetRemovalTimeToHistoricProcessInstancesBuilder byQuery(HistoricProcessInstanceQuery query) { this.query = query; return this; } + @Override public SetRemovalTimeToHistoricProcessInstancesBuilder byIds(String... ids) { this.ids = ids != null ? Arrays.asList(ids) : null; return this; } + @Override public SetRemovalTimeToHistoricProcessInstancesBuilder absoluteRemovalTime(Date removalTime) { ensureNull(BadUserRequestException.class, "The removal time modes are mutually exclusive","mode", mode); @@ -73,6 +78,7 @@ public SetRemovalTimeToHistoricProcessInstancesBuilder calculatedRemovalTime() { return this; } + @Override public SetRemovalTimeToHistoricProcessInstancesBuilder clearedRemovalTime() { ensureNull(BadUserRequestException.class, "The removal time modes are mutually exclusive","mode", mode); @@ -80,11 +86,30 @@ public SetRemovalTimeToHistoricProcessInstancesBuilder clearedRemovalTime() { return this; } + @Override public SetRemovalTimeToHistoricProcessInstancesBuilder hierarchical() { isHierarchical = true; return this; } + @Override + public SetRemovalTimeToHistoricProcessInstancesBuilder updateInChunks() { + updateInChunks = true; + return this; + } + + @Override + public SetRemovalTimeToHistoricProcessInstancesBuilder chunkSize(int chunkSize) { + if (chunkSize > ProcessSetRemovalTimeJobHandler.MAX_CHUNK_SIZE || chunkSize <= 0) { + throw new BadUserRequestException(String.format("The value for chunk size should be between 1 and %s", + ProcessSetRemovalTimeJobHandler.MAX_CHUNK_SIZE)); + } + + this.chunkSize = chunkSize; + return this; + } + + @Override public Batch executeAsync() { return commandExecutor.execute(new SetRemovalTimeToHistoricProcessInstancesCmd(this)); } @@ -105,15 +130,22 @@ public Mode getMode() { return mode; } + public boolean isHierarchical() { + return isHierarchical; + } + + public boolean isUpdateInChunks() { + return updateInChunks; + } + + public Integer getChunkSize() { + return chunkSize; + } + public static enum Mode { CALCULATED_REMOVAL_TIME, ABSOLUTE_REMOVAL_TIME, CLEARED_REMOVAL_TIME; } - - public boolean isHierarchical() { - return isHierarchical; - } - } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/history/event/HistoricDecisionInstanceManager.java b/engine/src/main/java/org/camunda/bpm/engine/impl/history/event/HistoricDecisionInstanceManager.java index 5c96c3d23a7..8465c55d411 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/history/event/HistoricDecisionInstanceManager.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/history/event/HistoricDecisionInstanceManager.java @@ -16,11 +16,19 @@ */ package org.camunda.bpm.engine.impl.history.event; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; import org.camunda.bpm.engine.authorization.Resources; +import org.camunda.bpm.engine.history.CleanableHistoricDecisionInstanceReportResult; import org.camunda.bpm.engine.history.HistoricDecisionInputInstance; import org.camunda.bpm.engine.history.HistoricDecisionInstance; import org.camunda.bpm.engine.history.HistoricDecisionOutputInstance; -import org.camunda.bpm.engine.history.CleanableHistoricDecisionInstanceReportResult; import org.camunda.bpm.engine.impl.CleanableHistoricDecisionInstanceReportImpl; import org.camunda.bpm.engine.impl.HistoricDecisionInstanceQueryImpl; import org.camunda.bpm.engine.impl.Page; @@ -33,15 +41,6 @@ import org.camunda.bpm.engine.impl.util.ImmutablePair; import org.camunda.bpm.engine.impl.variable.serializer.AbstractTypedValueSerializer; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - /** * Data base operations for {@link HistoricDecisionInstanceEntity}. * @@ -169,7 +168,7 @@ public List findHistoricDecisionInstanceIdsForCleanup(Integer batchSize, parameters.put("minuteTo", minuteTo); } ListQueryParameterObject parameterObject = new ListQueryParameterObject(parameters, 0, batchSize); - return (List) getDbEntityManager().selectList("selectHistoricDecisionInstanceIdsForCleanup", parameterObject); + return getDbEntityManager().selectList("selectHistoricDecisionInstanceIdsForCleanup", parameterObject); } protected void appendHistoricDecisionInputInstances(Map decisionInstancesById, HistoricDecisionInstanceQueryImpl query) { @@ -304,33 +303,69 @@ public long findCleanableHistoricDecisionInstancesReportCountByCriteria(Cleanabl } public void addRemovalTimeToDecisionsByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime) { + addRemovalTimeToDecisionsByRootProcessInstanceId(rootProcessInstanceId, removalTime, null, Collections.emptySet()); + } + + public Map, DbOperation> addRemovalTimeToDecisionsByRootProcessInstanceId(String rootProcessInstanceId, + Date removalTime, + Integer batchSize, + Set entities) { + Map, DbOperation> updateOperations = new HashMap<>(); + Map parameters = new HashMap<>(); parameters.put("rootProcessInstanceId", rootProcessInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() - .updatePreserveOrder(HistoricDecisionInstanceEntity.class, "updateHistoricDecisionInstancesByRootProcessInstanceId", parameters); + if (isPerformUpdate(entities, HistoricDecisionInstanceEntity.class)) { + addOperation(getDbEntityManager().updatePreserveOrder(HistoricDecisionInstanceEntity.class, + "updateHistoricDecisionInstancesByRootProcessInstanceId", parameters), updateOperations); + } - getDbEntityManager() - .updatePreserveOrder(HistoricDecisionInputInstanceEntity.class, "updateHistoricDecisionInputInstancesByRootProcessInstanceId", parameters); + if (isPerformUpdate(entities, HistoricDecisionInputInstanceEntity.class)) { + addOperation(getDbEntityManager().updatePreserveOrder(HistoricDecisionInputInstanceEntity.class, + "updateHistoricDecisionInputInstancesByRootProcessInstanceId", parameters), updateOperations); + } - getDbEntityManager() - .updatePreserveOrder(HistoricDecisionOutputInstanceEntity.class, "updateHistoricDecisionOutputInstancesByRootProcessInstanceId", parameters); + if (isPerformUpdate(entities, HistoricDecisionOutputInstanceEntity.class)) { + addOperation(getDbEntityManager().updatePreserveOrder(HistoricDecisionOutputInstanceEntity.class, + "updateHistoricDecisionOutputInstancesByRootProcessInstanceId", parameters), updateOperations); + } + + return updateOperations; } public void addRemovalTimeToDecisionsByProcessInstanceId(String processInstanceId, Date removalTime) { + addRemovalTimeToDecisionsByProcessInstanceId(processInstanceId, removalTime, null, Collections.emptySet()); + } + + public Map, DbOperation> addRemovalTimeToDecisionsByProcessInstanceId(String processInstanceId, + Date removalTime, + Integer batchSize, + Set entities) { + Map, DbOperation> updateOperations = new HashMap<>(); + Map parameters = new HashMap<>(); parameters.put("processInstanceId", processInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() - .updatePreserveOrder(HistoricDecisionInstanceEntity.class, "updateHistoricDecisionInstancesByProcessInstanceId", parameters); + if (isPerformUpdate(entities, HistoricDecisionInstanceEntity.class)) { + addOperation(getDbEntityManager().updatePreserveOrder(HistoricDecisionInstanceEntity.class, + "updateHistoricDecisionInstancesByProcessInstanceId", parameters), updateOperations); + } - getDbEntityManager() - .updatePreserveOrder(HistoricDecisionInputInstanceEntity.class, "updateHistoricDecisionInputInstancesByProcessInstanceId", parameters); + if (isPerformUpdate(entities, HistoricDecisionInputInstanceEntity.class)) { + addOperation(getDbEntityManager().updatePreserveOrder(HistoricDecisionInputInstanceEntity.class, + "updateHistoricDecisionInputInstancesByProcessInstanceId", parameters), updateOperations); + } - getDbEntityManager() - .updatePreserveOrder(HistoricDecisionOutputInstanceEntity.class, "updateHistoricDecisionOutputInstancesByProcessInstanceId", parameters); + if (isPerformUpdate(entities, HistoricDecisionOutputInstanceEntity.class)) { + addOperation(getDbEntityManager().updatePreserveOrder(HistoricDecisionOutputInstanceEntity.class, + "updateHistoricDecisionOutputInstancesByProcessInstanceId", parameters), updateOperations); + } + + return updateOperations; } public void addRemovalTimeToDecisionsByRootDecisionInstanceId(String rootInstanceId, Date removalTime) { diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/AbstractHistoricManager.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/AbstractHistoricManager.java index e111fb9baa7..f4fe8dbcf84 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/AbstractHistoricManager.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/AbstractHistoricManager.java @@ -16,9 +16,14 @@ */ package org.camunda.bpm.engine.impl.persistence; +import java.util.Collection; +import java.util.Map; +import java.util.Set; import org.camunda.bpm.engine.impl.ProcessEngineLogger; import org.camunda.bpm.engine.impl.context.Context; +import org.camunda.bpm.engine.impl.db.DbEntity; import org.camunda.bpm.engine.impl.db.EnginePersistenceLogger; +import org.camunda.bpm.engine.impl.db.entitymanager.operation.DbOperation; import org.camunda.bpm.engine.impl.history.HistoryLevel; @@ -47,4 +52,20 @@ public boolean isHistoryEnabled() { public boolean isHistoryLevelFullEnabled() { return isHistoryLevelFullEnabled; } + + protected static boolean isPerformUpdate(Set entities, Class entityClass) { + return entities == null || entities.isEmpty() || entities.contains(entityClass.getName()); + } + + protected static boolean isPerformUpdateOnly(Set entities, Class entityClass) { + return entities != null && entities.size() == 1 && entities.contains(entityClass.getName()); + } + + protected static void addOperation(DbOperation operation, Map, DbOperation> operations) { + operations.put(operation.getEntityType(), operation); + } + + protected static void addOperation(Collection newOperations, Map, DbOperation> operations) { + newOperations.forEach(operation -> operations.put(operation.getEntityType(), operation)); + } } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/AttachmentManager.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/AttachmentManager.java index 9b5de8fb3b5..1e895b1365c 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/AttachmentManager.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/AttachmentManager.java @@ -20,7 +20,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; - import org.camunda.bpm.engine.impl.db.ListQueryParameterObject; import org.camunda.bpm.engine.impl.db.entitymanager.operation.DbOperation; import org.camunda.bpm.engine.impl.persistence.AbstractHistoricManager; @@ -44,21 +43,23 @@ public List findAttachmentsByTaskId(String taskId) { return getDbEntityManager().selectList("selectAttachmentsByTaskId", taskId); } - public void addRemovalTimeToAttachmentsByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime) { + public DbOperation addRemovalTimeToAttachmentsByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("rootProcessInstanceId", rootProcessInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(AttachmentEntity.class, "updateAttachmentsByRootProcessInstanceId", parameters); } - public void addRemovalTimeToAttachmentsByProcessInstanceId(String processInstanceId, Date removalTime) { + public DbOperation addRemovalTimeToAttachmentsByProcessInstanceId(String processInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("processInstanceId", processInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(AttachmentEntity.class, "updateAttachmentsByProcessInstanceId", parameters); } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/AuthorizationManager.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/AuthorizationManager.java index 0326570e627..29a1c3a246e 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/AuthorizationManager.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/AuthorizationManager.java @@ -25,17 +25,18 @@ import static org.camunda.bpm.engine.authorization.Permissions.UPDATE; import static org.camunda.bpm.engine.authorization.Permissions.UPDATE_INSTANCE; import static org.camunda.bpm.engine.authorization.ProcessDefinitionPermissions.READ_INSTANCE_VARIABLE; -import static org.camunda.bpm.engine.authorization.Resources.HISTORIC_PROCESS_INSTANCE; -import static org.camunda.bpm.engine.authorization.Resources.HISTORIC_TASK; -import static org.camunda.bpm.engine.authorization.TaskPermissions.READ_VARIABLE; import static org.camunda.bpm.engine.authorization.Resources.AUTHORIZATION; import static org.camunda.bpm.engine.authorization.Resources.BATCH; import static org.camunda.bpm.engine.authorization.Resources.DECISION_DEFINITION; import static org.camunda.bpm.engine.authorization.Resources.DECISION_REQUIREMENTS_DEFINITION; import static org.camunda.bpm.engine.authorization.Resources.DEPLOYMENT; +import static org.camunda.bpm.engine.authorization.Resources.HISTORIC_PROCESS_INSTANCE; +import static org.camunda.bpm.engine.authorization.Resources.HISTORIC_TASK; import static org.camunda.bpm.engine.authorization.Resources.PROCESS_DEFINITION; import static org.camunda.bpm.engine.authorization.Resources.PROCESS_INSTANCE; import static org.camunda.bpm.engine.authorization.Resources.TASK; +import static org.camunda.bpm.engine.authorization.TaskPermissions.READ_VARIABLE; + import java.util.ArrayList; import java.util.Arrays; import java.util.Date; @@ -46,7 +47,6 @@ import java.util.Objects; import java.util.Set; import java.util.function.Consumer; - import org.camunda.bpm.engine.AuthorizationException; import org.camunda.bpm.engine.ProcessEngineConfiguration; import org.camunda.bpm.engine.authorization.Authorization; @@ -84,7 +84,6 @@ import org.camunda.bpm.engine.impl.TaskQueryImpl; import org.camunda.bpm.engine.impl.UserOperationLogQueryImpl; import org.camunda.bpm.engine.impl.VariableInstanceQueryImpl; - import org.camunda.bpm.engine.impl.batch.BatchQueryImpl; import org.camunda.bpm.engine.impl.batch.BatchStatisticsQueryImpl; import org.camunda.bpm.engine.impl.batch.history.HistoricBatchQueryImpl; @@ -1167,24 +1166,26 @@ protected boolean isHistoricInstancePermissionsEnabled() { return Context.getProcessEngineConfiguration().isEnableHistoricInstancePermissions(); } - public void addRemovalTimeToAuthorizationsByRootProcessInstanceId(String rootProcessInstanceId, - Date removalTime) { + public DbOperation addRemovalTimeToAuthorizationsByRootProcessInstanceId(String rootProcessInstanceId, + Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("rootProcessInstanceId", rootProcessInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(AuthorizationEntity.class, "updateAuthorizationsByRootProcessInstanceId", parameters); } - public void addRemovalTimeToAuthorizationsByProcessInstanceId(String processInstanceId, - Date removalTime) { + public DbOperation addRemovalTimeToAuthorizationsByProcessInstanceId(String processInstanceId, + Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("processInstanceId", processInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(AuthorizationEntity.class, "updateAuthorizationsByProcessInstanceId", parameters); } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/ByteArrayManager.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/ByteArrayManager.java index 9e1f3cfced1..76db7bfccf5 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/ByteArrayManager.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/ByteArrayManager.java @@ -16,10 +16,11 @@ */ package org.camunda.bpm.engine.impl.persistence.entity; +import java.util.ArrayList; import java.util.Date; import java.util.HashMap; +import java.util.List; import java.util.Map; - import org.camunda.bpm.engine.impl.db.ListQueryParameterObject; import org.camunda.bpm.engine.impl.db.entitymanager.operation.DbOperation; import org.camunda.bpm.engine.impl.persistence.AbstractManager; @@ -45,35 +46,39 @@ public void insertByteArray(ByteArrayEntity arr) { getDbEntityManager().insert(arr); } - public void addRemovalTimeToByteArraysByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime) { + public DbOperation addRemovalTimeToByteArraysByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("rootProcessInstanceId", rootProcessInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(ByteArrayEntity.class, "updateByteArraysByRootProcessInstanceId", parameters); } - public void addRemovalTimeToByteArraysByProcessInstanceId(String processInstanceId, Date removalTime) { + public List addRemovalTimeToByteArraysByProcessInstanceId(String processInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("processInstanceId", processInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); // Make individual statements for each entity type that references byte arrays. // This can lead to query plans that involve less aggressive locking by databases (e.g. DB2). // See CAM-10360 for reference. - getDbEntityManager() - .updatePreserveOrder(ByteArrayEntity.class, "updateVariableByteArraysByProcessInstanceId", parameters); - getDbEntityManager() - .updatePreserveOrder(ByteArrayEntity.class, "updateDecisionInputsByteArraysByProcessInstanceId", parameters); - getDbEntityManager() - .updatePreserveOrder(ByteArrayEntity.class, "updateDecisionOutputsByteArraysByProcessInstanceId", parameters); - getDbEntityManager() - .updatePreserveOrder(ByteArrayEntity.class, "updateJobLogByteArraysByProcessInstanceId", parameters); - getDbEntityManager() - .updatePreserveOrder(ByteArrayEntity.class, "updateExternalTaskLogByteArraysByProcessInstanceId", parameters); - getDbEntityManager() - .updatePreserveOrder(ByteArrayEntity.class, "updateAttachmentByteArraysByProcessInstanceId", parameters); + List operations = new ArrayList<>(); + operations.add(getDbEntityManager() + .updatePreserveOrder(ByteArrayEntity.class, "updateVariableByteArraysByProcessInstanceId", parameters)); + operations.add(getDbEntityManager() + .updatePreserveOrder(ByteArrayEntity.class, "updateDecisionInputsByteArraysByProcessInstanceId", parameters)); + operations.add(getDbEntityManager() + .updatePreserveOrder(ByteArrayEntity.class, "updateDecisionOutputsByteArraysByProcessInstanceId", parameters)); + operations.add(getDbEntityManager() + .updatePreserveOrder(ByteArrayEntity.class, "updateJobLogByteArraysByProcessInstanceId", parameters)); + operations.add(getDbEntityManager() + .updatePreserveOrder(ByteArrayEntity.class, "updateExternalTaskLogByteArraysByProcessInstanceId", parameters)); + operations.add(getDbEntityManager() + .updatePreserveOrder(ByteArrayEntity.class, "updateAttachmentByteArraysByProcessInstanceId", parameters)); + return operations; } public DbOperation deleteByteArraysByRemovalTime(Date removalTime, int minuteFrom, int minuteTo, int batchSize) { diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentManager.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentManager.java index 885058b8b94..42e6fa8b27f 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentManager.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/CommentManager.java @@ -20,12 +20,11 @@ import java.util.HashMap; import java.util.List; import java.util.Map; - import org.camunda.bpm.engine.impl.Direction; import org.camunda.bpm.engine.impl.QueryOrderingProperty; import org.camunda.bpm.engine.impl.QueryPropertyImpl; -import org.camunda.bpm.engine.impl.db.ListQueryParameterObject; import org.camunda.bpm.engine.impl.db.DbEntity; +import org.camunda.bpm.engine.impl.db.ListQueryParameterObject; import org.camunda.bpm.engine.impl.db.entitymanager.operation.DbOperation; import org.camunda.bpm.engine.impl.persistence.AbstractHistoricManager; import org.camunda.bpm.engine.task.Comment; @@ -37,11 +36,13 @@ */ public class CommentManager extends AbstractHistoricManager { + @Override public void delete(DbEntity dbEntity) { checkHistoryEnabled(); super.delete(dbEntity); } + @Override public void insert(DbEntity dbEntity) { checkHistoryEnabled(); super.insert(dbEntity); @@ -107,21 +108,23 @@ public CommentEntity findCommentByTaskIdAndCommentId(String taskId, String comme return (CommentEntity) getDbEntityManager().selectOne("selectCommentByTaskIdAndCommentId", parameters); } - public void addRemovalTimeToCommentsByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime) { + public DbOperation addRemovalTimeToCommentsByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("rootProcessInstanceId", rootProcessInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(CommentEntity.class, "updateCommentsByRootProcessInstanceId", parameters); } - public void addRemovalTimeToCommentsByProcessInstanceId(String processInstanceId, Date removalTime) { + public DbOperation addRemovalTimeToCommentsByProcessInstanceId(String processInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("processInstanceId", processInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(CommentEntity.class, "updateCommentsByProcessInstanceId", parameters); } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/EverLivingJobEntity.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/EverLivingJobEntity.java index 156002c38b7..9f1ae32686b 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/EverLivingJobEntity.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/EverLivingJobEntity.java @@ -19,8 +19,6 @@ import org.camunda.bpm.engine.impl.ProcessEngineLogger; import org.camunda.bpm.engine.impl.db.EnginePersistenceLogger; import org.camunda.bpm.engine.impl.interceptor.CommandContext; -import org.camunda.bpm.engine.impl.jobexecutor.JobHandler; -import org.camunda.bpm.engine.impl.jobexecutor.historycleanup.HistoryCleanupHelper; /** * JobEntity for ever living job, which can be rescheduled and executed again. @@ -35,6 +33,7 @@ public class EverLivingJobEntity extends JobEntity { public static final String TYPE = "ever-living"; + @Override public String getType() { return TYPE; } @@ -48,30 +47,7 @@ protected void postExecute(CommandContext commandContext) { @Override public void init(CommandContext commandContext) { - init(commandContext, false); - } - - public void init(CommandContext commandContext, boolean shouldResetLock) { - // clean additional data related to this job - JobHandler jobHandler = getJobHandler(); - if (jobHandler != null) { - jobHandler.onDelete(getJobHandlerConfiguration(), this); - } - - //cancel the retries -> will resolve job incident if present - int retries = HistoryCleanupHelper.getMaxRetries(); - setRetries(retries); - - //delete the job's exception byte array and exception message - if (exceptionByteArrayId != null) { - clearFailedJobException(); - } - - //clean the lock information - if (shouldResetLock) { - setLockOwner(null); - setLockExpirationTime(null); - } + init(commandContext, false, true); } @Override diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricActivityInstanceManager.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricActivityInstanceManager.java index 5d9215ff340..a818c24d73a 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricActivityInstanceManager.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricActivityInstanceManager.java @@ -20,7 +20,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; - import org.camunda.bpm.engine.history.HistoricActivityInstance; import org.camunda.bpm.engine.impl.HistoricActivityInstanceQueryImpl; import org.camunda.bpm.engine.impl.Page; @@ -76,21 +75,23 @@ protected void configureQuery(HistoricActivityInstanceQueryImpl query) { getTenantManager().configureQuery(query); } - public void addRemovalTimeToActivityInstancesByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime) { + public DbOperation addRemovalTimeToActivityInstancesByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("rootProcessInstanceId", rootProcessInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(HistoricActivityInstanceEventEntity.class, "updateHistoricActivityInstancesByRootProcessInstanceId", parameters); } - public void addRemovalTimeToActivityInstancesByProcessInstanceId(String processInstanceId, Date removalTime) { + public DbOperation addRemovalTimeToActivityInstancesByProcessInstanceId(String processInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("processInstanceId", processInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(HistoricActivityInstanceEventEntity.class, "updateHistoricActivityInstancesByProcessInstanceId", parameters); } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricDetailManager.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricDetailManager.java index c51c383f3cd..653e5c27002 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricDetailManager.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricDetailManager.java @@ -20,7 +20,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; - import org.camunda.bpm.engine.history.HistoricDetail; import org.camunda.bpm.engine.impl.HistoricDetailQueryImpl; import org.camunda.bpm.engine.impl.Page; @@ -57,7 +56,7 @@ public void deleteHistoricDetailsByTaskCaseInstanceIds(List historicCase parameters.put("taskCaseInstanceIds", historicCaseInstanceIds); deleteHistoricDetails(parameters); } - + public void deleteHistoricDetailsByVariableInstanceId(String historicVariableInstanceId) { Map parameters = new HashMap(); parameters.put("variableInstanceId", historicVariableInstanceId); @@ -111,21 +110,23 @@ protected void configureQuery(HistoricDetailQueryImpl query) { getTenantManager().configureQuery(query); } - public void addRemovalTimeToDetailsByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime) { + public DbOperation addRemovalTimeToDetailsByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("rootProcessInstanceId", rootProcessInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(HistoricDetailEventEntity.class, "updateHistoricDetailsByRootProcessInstanceId", parameters); } - public void addRemovalTimeToDetailsByProcessInstanceId(String processInstanceId, Date removalTime) { + public DbOperation addRemovalTimeToDetailsByProcessInstanceId(String processInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("processInstanceId", processInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(HistoricDetailEventEntity.class, "updateHistoricDetailsByProcessInstanceId", parameters); } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricExternalTaskLogManager.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricExternalTaskLogManager.java index eaec96255dc..f25f5956c3d 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricExternalTaskLogManager.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricExternalTaskLogManager.java @@ -16,6 +16,10 @@ */ package org.camunda.bpm.engine.impl.persistence.entity; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import org.camunda.bpm.engine.externaltask.ExternalTask; import org.camunda.bpm.engine.history.HistoricExternalTaskLog; import org.camunda.bpm.engine.impl.HistoricExternalTaskLogQueryImpl; @@ -25,16 +29,15 @@ import org.camunda.bpm.engine.impl.db.ListQueryParameterObject; import org.camunda.bpm.engine.impl.db.entitymanager.operation.DbOperation; import org.camunda.bpm.engine.impl.history.HistoryLevel; -import org.camunda.bpm.engine.impl.history.event.*; +import org.camunda.bpm.engine.impl.history.event.HistoricExternalTaskLogEntity; +import org.camunda.bpm.engine.impl.history.event.HistoryEvent; +import org.camunda.bpm.engine.impl.history.event.HistoryEventProcessor; +import org.camunda.bpm.engine.impl.history.event.HistoryEventType; +import org.camunda.bpm.engine.impl.history.event.HistoryEventTypes; import org.camunda.bpm.engine.impl.history.producer.HistoryEventProducer; import org.camunda.bpm.engine.impl.persistence.AbstractManager; import org.camunda.bpm.engine.impl.util.EnsureUtil; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - public class HistoricExternalTaskLogManager extends AbstractManager { @@ -57,21 +60,23 @@ public long findHistoricExternalTaskLogsCountByQueryCriteria(HistoricExternalTas // update /////////////////////////////////////////////////////////////////// - public void addRemovalTimeToExternalTaskLogByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime) { + public DbOperation addRemovalTimeToExternalTaskLogByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("rootProcessInstanceId", rootProcessInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(HistoricExternalTaskLogEntity.class, "updateExternalTaskLogByRootProcessInstanceId", parameters); } - public void addRemovalTimeToExternalTaskLogByProcessInstanceId(String processInstanceId, Date removalTime) { + public DbOperation addRemovalTimeToExternalTaskLogByProcessInstanceId(String processInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("processInstanceId", processInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(HistoricExternalTaskLogEntity.class, "updateExternalTaskLogByProcessInstanceId", parameters); } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricIdentityLinkLogManager.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricIdentityLinkLogManager.java index 5cb3320a200..2fc1b61c08b 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricIdentityLinkLogManager.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricIdentityLinkLogManager.java @@ -20,7 +20,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; - import org.camunda.bpm.engine.history.HistoricIdentityLinkLog; import org.camunda.bpm.engine.impl.HistoricIdentityLinkLogQueryImpl; import org.camunda.bpm.engine.impl.Page; @@ -49,21 +48,23 @@ public List findHistoricIdentityLinkLogByQueryCriteria( return getDbEntityManager().selectList("selectHistoricIdentityLinkByQueryCriteria", query, page); } - public void addRemovalTimeToIdentityLinkLogByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime) { + public DbOperation addRemovalTimeToIdentityLinkLogByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("rootProcessInstanceId", rootProcessInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(HistoricIdentityLinkLogEventEntity.class, "updateIdentityLinkLogByRootProcessInstanceId", parameters); } - public void addRemovalTimeToIdentityLinkLogByProcessInstanceId(String processInstanceId, Date removalTime) { + public DbOperation addRemovalTimeToIdentityLinkLogByProcessInstanceId(String processInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("processInstanceId", processInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(HistoricIdentityLinkLogEventEntity.class, "updateIdentityLinkLogByProcessInstanceId", parameters); } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricIncidentManager.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricIncidentManager.java index 9540271cbbb..476a3057818 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricIncidentManager.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricIncidentManager.java @@ -20,7 +20,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; - import org.camunda.bpm.engine.history.HistoricIncident; import org.camunda.bpm.engine.impl.HistoricIncidentQueryImpl; import org.camunda.bpm.engine.impl.Page; @@ -53,21 +52,23 @@ public List findHistoricIncidentByQueryCriteria(HistoricIncide return getDbEntityManager().selectList("selectHistoricIncidentByQueryCriteria", query, page); } - public void addRemovalTimeToIncidentsByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime) { + public DbOperation addRemovalTimeToIncidentsByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("rootProcessInstanceId", rootProcessInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(HistoricIncidentEventEntity.class, "updateHistoricIncidentsByRootProcessInstanceId", parameters); } - public void addRemovalTimeToIncidentsByProcessInstanceId(String processInstanceId, Date removalTime) { + public DbOperation addRemovalTimeToIncidentsByProcessInstanceId(String processInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("processInstanceId", processInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(HistoricIncidentEventEntity.class, "updateHistoricIncidentsByProcessInstanceId", parameters); } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricJobLogManager.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricJobLogManager.java index 2e08a7a6793..95b967e15f9 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricJobLogManager.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricJobLogManager.java @@ -20,7 +20,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; - import org.camunda.bpm.engine.history.HistoricJobLog; import org.camunda.bpm.engine.impl.HistoricJobLogQueryImpl; import org.camunda.bpm.engine.impl.Page; @@ -68,21 +67,23 @@ public long findHistoricJobLogsCountByQueryCriteria(HistoricJobLogQueryImpl quer // update /////////////////////////////////////////////////////////////////// - public void addRemovalTimeToJobLogByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime) { + public DbOperation addRemovalTimeToJobLogByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("rootProcessInstanceId", rootProcessInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(HistoricJobLogEventEntity.class, "updateJobLogByRootProcessInstanceId", parameters); } - public void addRemovalTimeToJobLogByProcessInstanceId(String processInstanceId, Date removalTime) { + public DbOperation addRemovalTimeToJobLogByProcessInstanceId(String processInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("processInstanceId", processInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(HistoricJobLogEventEntity.class, "updateJobLogByProcessInstanceId", parameters); } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricProcessInstanceManager.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricProcessInstanceManager.java index f1618009ff8..48bfa8d9729 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricProcessInstanceManager.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricProcessInstanceManager.java @@ -21,6 +21,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import org.camunda.bpm.engine.authorization.Resources; import org.camunda.bpm.engine.history.CleanableHistoricProcessInstanceReportResult; import org.camunda.bpm.engine.history.HistoricProcessInstance; @@ -32,7 +33,14 @@ import org.camunda.bpm.engine.impl.db.ListQueryParameterObject; import org.camunda.bpm.engine.impl.db.entitymanager.operation.DbOperation; import org.camunda.bpm.engine.impl.db.sql.DbSqlSessionFactory; +import org.camunda.bpm.engine.impl.history.event.HistoricActivityInstanceEventEntity; +import org.camunda.bpm.engine.impl.history.event.HistoricDetailEventEntity; +import org.camunda.bpm.engine.impl.history.event.HistoricExternalTaskLogEntity; +import org.camunda.bpm.engine.impl.history.event.HistoricIdentityLinkLogEventEntity; +import org.camunda.bpm.engine.impl.history.event.HistoricIncidentEventEntity; import org.camunda.bpm.engine.impl.history.event.HistoricProcessInstanceEventEntity; +import org.camunda.bpm.engine.impl.history.event.HistoricTaskInstanceEventEntity; +import org.camunda.bpm.engine.impl.history.event.UserOperationLogEntryEventEntity; import org.camunda.bpm.engine.impl.interceptor.CommandContext; import org.camunda.bpm.engine.impl.persistence.AbstractHistoricManager; import org.camunda.bpm.engine.impl.util.ClockUtil; @@ -72,7 +80,7 @@ public void deleteHistoricProcessInstanceByProcessDefinitionId(String processDef public void deleteHistoricProcessInstanceByIds(List processInstanceIds) { if (isHistoryEnabled()) { - CommandContext commandContext = Context.getCommandContext(); + CommandContext commandContext = getCommandContext(); // break down parameter list to not hit query parameter limitations List> partitions = CollectionUtil.partition(processInstanceIds, DbSqlSessionFactory.MAXIMUM_NUMBER_PARAMS); @@ -119,11 +127,6 @@ public long findHistoricProcessInstanceCountByNativeQuery(Map pa return (Long) getDbEntityManager().selectOne("selectHistoricProcessInstanceCountByNativeQuery", parameterMap); } - protected void configureQuery(HistoricProcessInstanceQueryImpl query) { - getAuthorizationManager().configureHistoricProcessInstanceQuery(query); - getTenantManager().configureQuery(query); - } - @SuppressWarnings("unchecked") public List findHistoricProcessInstanceIdsForCleanup(Integer batchSize, int minuteFrom, int minuteTo) { Map parameters = new HashMap<>(); @@ -166,111 +169,212 @@ public long findCleanableHistoricProcessInstancesReportCountByCriteria(Cleanable } public void addRemovalTimeToProcessInstancesByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime) { - CommandContext commandContext = Context.getCommandContext(); + addRemovalTimeToProcessInstancesByRootProcessInstanceId(rootProcessInstanceId, removalTime, null, Collections.emptySet()); + } - commandContext.getHistoricActivityInstanceManager() - .addRemovalTimeToActivityInstancesByRootProcessInstanceId(rootProcessInstanceId, removalTime); + public Map, DbOperation> addRemovalTimeToProcessInstancesByRootProcessInstanceId( + String rootProcessInstanceId, + Date removalTime, + Integer batchSize, + Set entities) { - commandContext.getHistoricTaskInstanceManager() - .addRemovalTimeToTaskInstancesByRootProcessInstanceId(rootProcessInstanceId, removalTime); + Map, DbOperation> updateOperations = new HashMap<>(); + CommandContext commandContext = getCommandContext(); - commandContext.getHistoricVariableInstanceManager() - .addRemovalTimeToVariableInstancesByRootProcessInstanceId(rootProcessInstanceId, removalTime); + if (isPerformUpdate(entities, HistoricActivityInstanceEventEntity.class)) { + addOperation(commandContext.getHistoricActivityInstanceManager() + .addRemovalTimeToActivityInstancesByRootProcessInstanceId(rootProcessInstanceId, removalTime, batchSize), + updateOperations); + } + + if (isPerformUpdate(entities, HistoricTaskInstanceEventEntity.class)) { + addOperation(commandContext.getHistoricTaskInstanceManager() + .addRemovalTimeToTaskInstancesByRootProcessInstanceId(rootProcessInstanceId, removalTime, batchSize), + updateOperations); + } - commandContext.getHistoricDetailManager() - .addRemovalTimeToDetailsByRootProcessInstanceId(rootProcessInstanceId, removalTime); + if (isPerformUpdate(entities, HistoricVariableInstanceEntity.class)) { + addOperation(commandContext.getHistoricVariableInstanceManager() + .addRemovalTimeToVariableInstancesByRootProcessInstanceId(rootProcessInstanceId, removalTime, batchSize), + updateOperations); + } + + if (isPerformUpdate(entities, HistoricDetailEventEntity.class)) { + addOperation(commandContext.getHistoricDetailManager() + .addRemovalTimeToDetailsByRootProcessInstanceId(rootProcessInstanceId, removalTime, batchSize), + updateOperations); + } - commandContext.getHistoricIncidentManager() - .addRemovalTimeToIncidentsByRootProcessInstanceId(rootProcessInstanceId, removalTime); + if (isPerformUpdate(entities, HistoricIncidentEventEntity.class)) { + addOperation(commandContext.getHistoricIncidentManager() + .addRemovalTimeToIncidentsByRootProcessInstanceId(rootProcessInstanceId, removalTime, batchSize), + updateOperations); + } - commandContext.getHistoricExternalTaskLogManager() - .addRemovalTimeToExternalTaskLogByRootProcessInstanceId(rootProcessInstanceId, removalTime); + if (isPerformUpdate(entities, HistoricExternalTaskLogEntity.class)) { + addOperation(commandContext.getHistoricExternalTaskLogManager() + .addRemovalTimeToExternalTaskLogByRootProcessInstanceId(rootProcessInstanceId, removalTime, batchSize), + updateOperations); + } - commandContext.getHistoricJobLogManager() - .addRemovalTimeToJobLogByRootProcessInstanceId(rootProcessInstanceId, removalTime); + if (isPerformUpdate(entities, HistoricJobLogEventEntity.class)) { + addOperation(commandContext.getHistoricJobLogManager() + .addRemovalTimeToJobLogByRootProcessInstanceId(rootProcessInstanceId, removalTime, batchSize), + updateOperations); + } - commandContext.getOperationLogManager() - .addRemovalTimeToUserOperationLogByRootProcessInstanceId(rootProcessInstanceId, removalTime); + if (isPerformUpdate(entities, UserOperationLogEntryEventEntity.class)) { + addOperation(commandContext.getOperationLogManager() + .addRemovalTimeToUserOperationLogByRootProcessInstanceId(rootProcessInstanceId, removalTime, batchSize), + updateOperations); + } - commandContext.getHistoricIdentityLinkManager() - .addRemovalTimeToIdentityLinkLogByRootProcessInstanceId(rootProcessInstanceId, removalTime); + if (isPerformUpdate(entities, HistoricIdentityLinkLogEventEntity.class)) { + addOperation(commandContext.getHistoricIdentityLinkManager() + .addRemovalTimeToIdentityLinkLogByRootProcessInstanceId(rootProcessInstanceId, removalTime, batchSize), + updateOperations); + } - commandContext.getCommentManager() - .addRemovalTimeToCommentsByRootProcessInstanceId(rootProcessInstanceId, removalTime); + if (isPerformUpdate(entities, CommentEntity.class)) { + addOperation(commandContext.getCommentManager() + .addRemovalTimeToCommentsByRootProcessInstanceId(rootProcessInstanceId, removalTime, batchSize), + updateOperations); + } - commandContext.getAttachmentManager() - .addRemovalTimeToAttachmentsByRootProcessInstanceId(rootProcessInstanceId, removalTime); + if (isPerformUpdate(entities, AttachmentEntity.class)) { + addOperation(commandContext.getAttachmentManager() + .addRemovalTimeToAttachmentsByRootProcessInstanceId(rootProcessInstanceId, removalTime, batchSize), + updateOperations); + } - commandContext.getByteArrayManager() - .addRemovalTimeToByteArraysByRootProcessInstanceId(rootProcessInstanceId, removalTime); + if (isPerformUpdate(entities, ByteArrayEntity.class)) { + addOperation(commandContext.getByteArrayManager() + .addRemovalTimeToByteArraysByRootProcessInstanceId(rootProcessInstanceId, removalTime, batchSize), + updateOperations); + } - if (isEnableHistoricInstancePermissions()) { - commandContext.getAuthorizationManager() - .addRemovalTimeToAuthorizationsByRootProcessInstanceId(rootProcessInstanceId, removalTime); + if (isEnableHistoricInstancePermissions() && isPerformUpdate(entities, AuthorizationEntity.class)) { + addOperation(commandContext.getAuthorizationManager() + .addRemovalTimeToAuthorizationsByRootProcessInstanceId(rootProcessInstanceId, removalTime, batchSize), + updateOperations); } - Map parameters = new HashMap<>(); - parameters.put("rootProcessInstanceId", rootProcessInstanceId); - parameters.put("removalTime", removalTime); + if (batchSize == null || isPerformUpdateOnly(entities, HistoricProcessInstanceEventEntity.class)) { + // update process instance last if updated in batches to avoid orphans + Map parameters = new HashMap<>(); + parameters.put("rootProcessInstanceId", rootProcessInstanceId); + parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); + + addOperation(getDbEntityManager().updatePreserveOrder(HistoricProcessInstanceEventEntity.class, + "updateHistoricProcessInstanceEventsByRootProcessInstanceId", parameters), updateOperations); + } - getDbEntityManager() - .updatePreserveOrder(HistoricProcessInstanceEventEntity.class, "updateHistoricProcessInstanceEventsByRootProcessInstanceId", parameters); + return updateOperations; } - public void addRemovalTimeById(String processInstanceId, Date removalTime) { - CommandContext commandContext = Context.getCommandContext(); + public Map, DbOperation> addRemovalTimeById(String processInstanceId, + Date removalTime, + Integer batchSize, + Set entities) { - commandContext.getHistoricActivityInstanceManager() - .addRemovalTimeToActivityInstancesByProcessInstanceId(processInstanceId, removalTime); + Map, DbOperation> updateOperations = new HashMap<>(); + CommandContext commandContext = getCommandContext(); - commandContext.getHistoricTaskInstanceManager() - .addRemovalTimeToTaskInstancesByProcessInstanceId(processInstanceId, removalTime); + if (isPerformUpdate(entities, HistoricActivityInstanceEventEntity.class)) { + addOperation(commandContext.getHistoricActivityInstanceManager() + .addRemovalTimeToActivityInstancesByProcessInstanceId(processInstanceId, removalTime, batchSize), + updateOperations); + } - commandContext.getHistoricVariableInstanceManager() - .addRemovalTimeToVariableInstancesByProcessInstanceId(processInstanceId, removalTime); + if (isPerformUpdate(entities, HistoricTaskInstanceEventEntity.class)) { + addOperation(commandContext.getHistoricTaskInstanceManager() + .addRemovalTimeToTaskInstancesByProcessInstanceId(processInstanceId, removalTime, batchSize), + updateOperations); + } - commandContext.getHistoricDetailManager() - .addRemovalTimeToDetailsByProcessInstanceId(processInstanceId, removalTime); + if (isPerformUpdate(entities, HistoricVariableInstanceEntity.class)) { + addOperation(commandContext.getHistoricVariableInstanceManager() + .addRemovalTimeToVariableInstancesByProcessInstanceId(processInstanceId, removalTime, batchSize), + updateOperations); + } - commandContext.getHistoricIncidentManager() - .addRemovalTimeToIncidentsByProcessInstanceId(processInstanceId, removalTime); + if (isPerformUpdate(entities, HistoricDetailEventEntity.class)) { + addOperation(commandContext.getHistoricDetailManager() + .addRemovalTimeToDetailsByProcessInstanceId(processInstanceId, removalTime, batchSize), + updateOperations); + } - commandContext.getHistoricExternalTaskLogManager() - .addRemovalTimeToExternalTaskLogByProcessInstanceId(processInstanceId, removalTime); + if (isPerformUpdate(entities, HistoricIncidentEventEntity.class)) { + addOperation(commandContext.getHistoricIncidentManager() + .addRemovalTimeToIncidentsByProcessInstanceId(processInstanceId, removalTime, batchSize), + updateOperations); + } - commandContext.getHistoricJobLogManager() - .addRemovalTimeToJobLogByProcessInstanceId(processInstanceId, removalTime); + if (isPerformUpdate(entities, HistoricExternalTaskLogEntity.class)) { + addOperation(commandContext.getHistoricExternalTaskLogManager() + .addRemovalTimeToExternalTaskLogByProcessInstanceId(processInstanceId, removalTime, batchSize), + updateOperations); + } - commandContext.getOperationLogManager() - .addRemovalTimeToUserOperationLogByProcessInstanceId(processInstanceId, removalTime); + if (isPerformUpdate(entities, HistoricJobLogEventEntity.class)) { + addOperation(commandContext.getHistoricJobLogManager() + .addRemovalTimeToJobLogByProcessInstanceId(processInstanceId, removalTime, batchSize), + updateOperations); + } - commandContext.getHistoricIdentityLinkManager() - .addRemovalTimeToIdentityLinkLogByProcessInstanceId(processInstanceId, removalTime); + if (isPerformUpdate(entities, UserOperationLogEntryEventEntity.class)) { + addOperation(commandContext.getOperationLogManager() + .addRemovalTimeToUserOperationLogByProcessInstanceId(processInstanceId, removalTime, batchSize), + updateOperations); + } - commandContext.getCommentManager() - .addRemovalTimeToCommentsByProcessInstanceId(processInstanceId, removalTime); + if (isPerformUpdate(entities, HistoricIdentityLinkLogEventEntity.class)) { + addOperation(commandContext.getHistoricIdentityLinkManager() + .addRemovalTimeToIdentityLinkLogByProcessInstanceId(processInstanceId, removalTime, batchSize), + updateOperations); + } - commandContext.getAttachmentManager() - .addRemovalTimeToAttachmentsByProcessInstanceId(processInstanceId, removalTime); + if (isPerformUpdate(entities, CommentEntity.class)) { + addOperation(commandContext.getCommentManager() + .addRemovalTimeToCommentsByProcessInstanceId(processInstanceId, removalTime, batchSize), + updateOperations); + } - commandContext.getByteArrayManager() - .addRemovalTimeToByteArraysByProcessInstanceId(processInstanceId, removalTime); + if (isPerformUpdate(entities, AttachmentEntity.class)) { + addOperation(commandContext.getAttachmentManager() + .addRemovalTimeToAttachmentsByProcessInstanceId(processInstanceId, removalTime, batchSize), + updateOperations); + } - if (isEnableHistoricInstancePermissions()) { - commandContext.getAuthorizationManager() - .addRemovalTimeToAuthorizationsByProcessInstanceId(processInstanceId, removalTime); + if (isPerformUpdate(entities, ByteArrayEntity.class)) { + addOperation(commandContext.getByteArrayManager() + .addRemovalTimeToByteArraysByProcessInstanceId(processInstanceId, removalTime, batchSize), + updateOperations); } - Map parameters = new HashMap<>(); - parameters.put("processInstanceId", processInstanceId); - parameters.put("removalTime", removalTime); + if (isEnableHistoricInstancePermissions() && isPerformUpdate(entities, AuthorizationEntity.class)) { + addOperation(commandContext.getAuthorizationManager() + .addRemovalTimeToAuthorizationsByProcessInstanceId(processInstanceId, removalTime, batchSize), + updateOperations); + } + + if (batchSize == null || isPerformUpdateOnly(entities, HistoricProcessInstanceEventEntity.class)) { + // update process instance last if updated in batches to avoid orphans + Map parameters = new HashMap<>(); + parameters.put("processInstanceId", processInstanceId); + parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() - .updatePreserveOrder(HistoricProcessInstanceEventEntity.class, "updateHistoricProcessInstanceByProcessInstanceId", parameters); + addOperation(getDbEntityManager().updatePreserveOrder(HistoricProcessInstanceEventEntity.class, + "updateHistoricProcessInstanceByProcessInstanceId", parameters), updateOperations); + } + + return updateOperations; } public Map, DbOperation> deleteHistoricProcessInstancesByRemovalTime(Date removalTime, int minuteFrom, int minuteTo, int batchSize) { - CommandContext commandContext = Context.getCommandContext(); + CommandContext commandContext = getCommandContext(); Map, DbOperation> deleteOperations = new HashMap<>(); @@ -356,9 +460,13 @@ public Map, DbOperation> deleteHistoricProcessInstance return deleteOperations; } - protected boolean isEnableHistoricInstancePermissions() { + protected void configureQuery(HistoricProcessInstanceQueryImpl query) { + getAuthorizationManager().configureHistoricProcessInstanceQuery(query); + getTenantManager().configureQuery(query); + } + + protected static boolean isEnableHistoricInstancePermissions() { return Context.getProcessEngineConfiguration() .isEnableHistoricInstancePermissions(); } - } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricTaskInstanceManager.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricTaskInstanceManager.java index 695dad1ddaf..c8cc2cce8e9 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricTaskInstanceManager.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricTaskInstanceManager.java @@ -23,7 +23,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; - import org.camunda.bpm.engine.authorization.Resources; import org.camunda.bpm.engine.history.HistoricTaskInstance; import org.camunda.bpm.engine.impl.HistoricTaskInstanceQueryImpl; @@ -184,21 +183,23 @@ public HistoryEvent createHistoryEvent(HistoryEventProducer producer) { } } - public void addRemovalTimeToTaskInstancesByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime) { + public DbOperation addRemovalTimeToTaskInstancesByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("rootProcessInstanceId", rootProcessInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(HistoricTaskInstanceEventEntity.class, "updateHistoricTaskInstancesByRootProcessInstanceId", parameters); } - public void addRemovalTimeToTaskInstancesByProcessInstanceId(String processInstanceId, Date removalTime) { + public DbOperation addRemovalTimeToTaskInstancesByProcessInstanceId(String processInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("processInstanceId", processInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(HistoricTaskInstanceEventEntity.class, "updateHistoricTaskInstancesByProcessInstanceId", parameters); } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricVariableInstanceManager.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricVariableInstanceManager.java index 66530eeb196..f2fc4635817 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricVariableInstanceManager.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/HistoricVariableInstanceManager.java @@ -22,7 +22,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; - import org.camunda.bpm.engine.history.HistoricVariableInstance; import org.camunda.bpm.engine.history.HistoricVariableInstanceQuery; import org.camunda.bpm.engine.impl.HistoricVariableInstanceQueryImpl; @@ -45,7 +44,7 @@ public void deleteHistoricVariableInstanceByVariableInstanceId(String historicVa } } } - + public void deleteHistoricVariableInstanceByProcessInstanceIds(List historicProcessInstanceIds) { Map parameters = new HashMap(); parameters.put("processInstanceIds", historicProcessInstanceIds); @@ -137,21 +136,23 @@ public void deleteHistoricVariableInstancesByTaskId(String taskId) { } } - public void addRemovalTimeToVariableInstancesByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime) { + public DbOperation addRemovalTimeToVariableInstancesByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("rootProcessInstanceId", rootProcessInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(HistoricVariableInstanceEntity.class, "updateHistoricVariableInstancesByRootProcessInstanceId", parameters); } - public void addRemovalTimeToVariableInstancesByProcessInstanceId(String processInstanceId, Date removalTime) { + public DbOperation addRemovalTimeToVariableInstancesByProcessInstanceId(String processInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("processInstanceId", processInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(HistoricVariableInstanceEntity.class, "updateHistoricVariableInstancesByProcessInstanceId", parameters); } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/JobEntity.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/JobEntity.java index 27ad8b9eb26..adc6112533f 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/JobEntity.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/JobEntity.java @@ -28,7 +28,6 @@ import java.util.List; import java.util.Map; import java.util.Set; - import org.camunda.bpm.engine.impl.ProcessEngineLogger; import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl; import org.camunda.bpm.engine.impl.context.Context; @@ -43,6 +42,7 @@ import org.camunda.bpm.engine.impl.jobexecutor.DefaultJobPriorityProvider; import org.camunda.bpm.engine.impl.jobexecutor.JobHandler; import org.camunda.bpm.engine.impl.jobexecutor.JobHandlerConfiguration; +import org.camunda.bpm.engine.impl.jobexecutor.historycleanup.HistoryCleanupHelper; import org.camunda.bpm.engine.impl.pvm.process.ProcessDefinitionImpl; import org.camunda.bpm.engine.impl.util.ExceptionUtil; import org.camunda.bpm.engine.impl.util.StringUtil; @@ -148,6 +148,31 @@ public void init(CommandContext commandContext) { // nothing to do } + public void init(CommandContext commandContext, boolean shouldResetLock, boolean shouldCallDeleteHandler) { + if (shouldCallDeleteHandler) { + // clean additional data related to this job + JobHandler jobHandler = getJobHandler(); + if (jobHandler != null) { + jobHandler.onDelete(getJobHandlerConfiguration(), this); + } + } + + // cancel the retries -> will resolve job incident if present + int retries = HistoryCleanupHelper.getMaxRetries(); + setRetries(retries); + + // delete the job's exception byte array and exception message + if (exceptionByteArrayId != null) { + clearFailedJobException(); + } + + // clean the lock information + if (shouldResetLock) { + setLockOwner(null); + setLockExpirationTime(null); + } + } + public void insert() { CommandContext commandContext = Context.getCommandContext(); @@ -669,6 +694,7 @@ public void setLastFailureLogId(String lastFailureLogId) { this.lastFailureLogId = lastFailureLogId; } + @Override public String getFailedActivityId() { return failedActivityId; } diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/JobManager.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/JobManager.java index b0803469e10..93850c9923a 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/JobManager.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/JobManager.java @@ -27,7 +27,6 @@ import java.util.List; import java.util.Map; import java.util.Set; - import org.camunda.bpm.engine.impl.Direction; import org.camunda.bpm.engine.impl.JobQueryImpl; import org.camunda.bpm.engine.impl.JobQueryProperty; @@ -116,10 +115,12 @@ public void schedule(TimerEntity timer) { } public void reschedule(JobEntity jobEntity, Date newDuedate) { - ((EverLivingJobEntity)jobEntity).init(Context.getCommandContext(), true); - jobEntity.setSuspensionState(SuspensionState.ACTIVE.getStateCode()); - jobEntity.setDuedate(newDuedate); - hintJobExecutorIfNeeded(jobEntity, newDuedate); + if (jobEntity instanceof EverLivingJobEntity || jobEntity instanceof MessageEntity) { + jobEntity.init(Context.getCommandContext(), true, false); + jobEntity.setSuspensionState(SuspensionState.ACTIVE.getStateCode()); + jobEntity.setDuedate(newDuedate); + hintJobExecutorIfNeeded(jobEntity, newDuedate); + } } private void hintJobExecutorIfNeeded(JobEntity jobEntity, Date duedate) { diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/MessageEntity.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/MessageEntity.java index 151b2f7a898..f0c35460d41 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/MessageEntity.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/MessageEntity.java @@ -16,11 +16,14 @@ */ package org.camunda.bpm.engine.impl.persistence.entity; +import org.camunda.bpm.engine.impl.ProcessEngineLogger; +import org.camunda.bpm.engine.impl.db.EnginePersistenceLogger; +import org.camunda.bpm.engine.impl.interceptor.CommandContext; import org.camunda.bpm.engine.impl.jobexecutor.MessageJobDeclaration; /** - * NOTE: instances of Messge Entity should be created via {@link MessageJobDeclaration}. + * NOTE: instances of Message Entity should be created via {@link MessageJobDeclaration}. * * @author Tom Baeyens */ @@ -30,6 +33,8 @@ public class MessageEntity extends JobEntity { private static final long serialVersionUID = 1L; + private final static EnginePersistenceLogger LOG = ProcessEngineLogger.PERSISTENCE_LOGGER; + private String repeat = null; public String getRepeat() { @@ -39,10 +44,28 @@ public void setRepeat(String repeat) { this.repeat = repeat; } + @Override public String getType() { return TYPE; } + @Override + protected void postExecute(CommandContext commandContext) { + LOG.debugJobExecuted(this); + if (repeat != null && !repeat.isEmpty()) { + init(commandContext, false, true); + } else { + delete(true); + } + commandContext.getHistoricJobLogManager().fireJobSuccessfulEvent(this); + } + + @Override + public void init(CommandContext commandContext, boolean shouldResetLock, boolean shouldCallDeleteHandler) { + super.init(commandContext, shouldResetLock, shouldCallDeleteHandler); + repeat = null; + } + @Override public String toString() { return this.getClass().getSimpleName() diff --git a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/UserOperationLogManager.java b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/UserOperationLogManager.java index edf28e6b5c1..3d47d89b431 100644 --- a/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/UserOperationLogManager.java +++ b/engine/src/main/java/org/camunda/bpm/engine/impl/persistence/entity/UserOperationLogManager.java @@ -23,7 +23,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; - import org.camunda.bpm.engine.EntityTypes; import org.camunda.bpm.engine.authorization.Permission; import org.camunda.bpm.engine.authorization.Permissions; @@ -80,21 +79,23 @@ public List findOperationLogEntriesByQueryCriteria(UserOp return getDbEntityManager().selectList("selectUserOperationLogEntriesByQueryCriteria", query, page); } - public void addRemovalTimeToUserOperationLogByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime) { + public DbOperation addRemovalTimeToUserOperationLogByRootProcessInstanceId(String rootProcessInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("rootProcessInstanceId", rootProcessInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(UserOperationLogEntryEventEntity.class, "updateUserOperationLogByRootProcessInstanceId", parameters); } - public void addRemovalTimeToUserOperationLogByProcessInstanceId(String processInstanceId, Date removalTime) { + public DbOperation addRemovalTimeToUserOperationLogByProcessInstanceId(String processInstanceId, Date removalTime, Integer batchSize) { Map parameters = new HashMap<>(); parameters.put("processInstanceId", processInstanceId); parameters.put("removalTime", removalTime); + parameters.put("maxResults", batchSize); - getDbEntityManager() + return getDbEntityManager() .updatePreserveOrder(UserOperationLogEntryEventEntity.class, "updateUserOperationLogByProcessInstanceId", parameters); } diff --git a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Attachment.xml b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Attachment.xml index 060ce172990..8b4d1bb8381 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Attachment.xml +++ b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Attachment.xml @@ -45,7 +45,8 @@ - update ${prefix}ACT_HI_ATTACHMENT + update + ${prefix}ACT_HI_ATTACHMENT set REV_ = #{revisionNext, jdbcType=INTEGER}, NAME_ = #{name, jdbcType=VARCHAR}, @@ -56,43 +57,153 @@ + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_ATTACHMENT set + REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_ATTACHMENT set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_ATTACHMENT + + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_HI_ATTACHMENT + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_ATTACHMENT + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_ATTACHMENT RES WITH (FORCESEEK) where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_ATTACHMENT + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + where (PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + or TASK_ID_ in ( + SELECT ID_ + FROM ${prefix}ACT_HI_TASKINST + WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + )) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_ATTACHMENT set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} - where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_ATTACHMENT + + where (PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} or TASK_ID_ in ( SELECT ID_ FROM ${prefix}ACT_HI_TASKINST WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} - ) + )) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_HI_ATTACHMENT + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_ATTACHMENT + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + + where (PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + or TASK_ID_ in ( + SELECT ID_ + FROM ${prefix}ACT_HI_TASKINST + WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + )) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_ATTACHMENT RES WITH (FORCESEEK) - where RES.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + where (RES.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} or RES.TASK_ID_ in ( SELECT ID_ FROM ${prefix}ACT_HI_TASKINST WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} - ) + )) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + diff --git a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Authorization.xml b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Authorization.xml index 1102fe3b0e6..7cfccfcdf86 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Authorization.xml +++ b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Authorization.xml @@ -68,50 +68,168 @@ + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_RU_AUTHORIZATION set + REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_RU_AUTHORIZATION set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_RU_AUTHORIZATION + + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_RU_AUTHORIZATION + + + ${limitBeforeInUpdate} ${prefix}ACT_RU_AUTHORIZATION + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_RU_AUTHORIZATION RES WITH (FORCESEEK) where RES.ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_RU_AUTHORIZATION set + REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where + + (RESOURCE_ID_ IN ( + SELECT ID_ + FROM ${prefix}ACT_HI_TASKINST + WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + ) + + or RESOURCE_ID_ = #{processInstanceId, jdbcType=VARCHAR}) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_RU_AUTHORIZATION set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_RU_AUTHORIZATION + + + where + + (RESOURCE_ID_ IN ( + SELECT ID_ + FROM ${prefix}ACT_HI_TASKINST + WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + ) + + or RESOURCE_ID_ = #{processInstanceId, jdbcType=VARCHAR}) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_RU_AUTHORIZATION + + + ${limitBeforeInUpdate} ${prefix}ACT_RU_AUTHORIZATION + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where - RESOURCE_ID_ IN ( + (RESOURCE_ID_ IN ( SELECT ID_ FROM ${prefix}ACT_HI_TASKINST WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} ) - or RESOURCE_ID_ = #{processInstanceId, jdbcType=VARCHAR} + or RESOURCE_ID_ = #{processInstanceId, jdbcType=VARCHAR}) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_RU_AUTHORIZATION RES WITH (FORCESEEK) where - RES.RESOURCE_ID_ IN ( + (RES.RESOURCE_ID_ IN ( SELECT ID_ FROM ${prefix}ACT_HI_TASKINST WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} ) - or RES.RESOURCE_ID_ = #{processInstanceId, jdbcType=VARCHAR} + or RES.RESOURCE_ID_ = #{processInstanceId, jdbcType=VARCHAR}) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + diff --git a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Comment.xml b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Comment.xml index b7ba6bd9d44..d24345f9219 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Comment.xml +++ b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/Comment.xml @@ -62,43 +62,153 @@ + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_COMMENT set + REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_COMMENT set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_COMMENT + + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_HI_COMMENT + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_COMMENT + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_COMMENT RES WITH (FORCESEEK) where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_COMMENT + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + where (PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + or TASK_ID_ in ( + SELECT ID_ + FROM ${prefix}ACT_HI_TASKINST + WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + )) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_COMMENT set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} - where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_COMMENT + + where (PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} or TASK_ID_ in ( SELECT ID_ FROM ${prefix}ACT_HI_TASKINST WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} - ) + )) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_HI_COMMENT + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_COMMENT + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + + where (PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + or TASK_ID_ in ( + SELECT ID_ + FROM ${prefix}ACT_HI_TASKINST + WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + )) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_COMMENT RES WITH (FORCESEEK) - where RES.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + where (RES.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} or RES.TASK_ID_ in ( SELECT ID_ FROM ${prefix}ACT_HI_TASKINST WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} - ) + )) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + diff --git a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricActivityInstance.xml b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricActivityInstance.xml index f740bcea939..2e9b1d27f34 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricActivityInstance.xml +++ b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricActivityInstance.xml @@ -102,33 +102,132 @@ - update ${prefix}ACT_HI_ACTINST set + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_ACTINST set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + + update ${prefix}ACT_HI_ACTINST set + REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_ACTINST + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_HI_ACTINST + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_ACTINST + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_ACTINST RES WITH (FORCESEEK) where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + - update ${prefix}ACT_HI_ACTINST + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_ACTINST set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + + update ${prefix}ACT_HI_ACTINST + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_ACTINST + + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_HI_ACTINST + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_ACTINST + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_ACTINST RES WITH (FORCESEEK) where RES.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + diff --git a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricDecisionInputInstance.xml b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricDecisionInputInstance.xml index d9b3cd33b24..ee13505f270 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricDecisionInputInstance.xml +++ b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricDecisionInputInstance.xml @@ -60,34 +60,138 @@ + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_DEC_IN set + REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_DEC_IN set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_DEC_IN + + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_HI_DEC_IN + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_DEC_IN + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_DEC_IN RES WITH (FORCESEEK) where RES.ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_DEC_IN + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + where DEC_INST_ID_ IN ( + SELECT ID_ + FROM ${prefix}ACT_HI_DECINST + WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=TIMESTAMP} + ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_DEC_IN set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_DEC_IN + where DEC_INST_ID_ IN ( SELECT ID_ FROM ${prefix}ACT_HI_DECINST WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=TIMESTAMP} ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_HI_DEC_IN + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_DEC_IN + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + + where DEC_INST_ID_ IN ( + SELECT ID_ + FROM ${prefix}ACT_HI_DECINST + WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=TIMESTAMP} + ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} from ${prefix}ACT_HI_DEC_IN RES WITH (FORCESEEK) where RES.DEC_INST_ID_ IN ( @@ -95,6 +199,10 @@ FROM ${prefix}ACT_HI_DECINST WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=TIMESTAMP} ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_DECINST set + REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_DECINST set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_DECINST + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_HI_DECINST + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_DECINST + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_DECINST RES WITH (FORCESEEK) where RES.ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_DECINST + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_DECINST set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_DECINST + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_HI_DECINST + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_DECINST + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_DECINST RES WITH (FORCESEEK) where RES.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_DEC_OUT set + REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_DEC_OUT set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_DEC_OUT + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_HI_DEC_OUT + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_DEC_OUT + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_DEC_OUT RES WITH (FORCESEEK) where RES.ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_DEC_OUT + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + where DEC_INST_ID_ IN ( + SELECT ID_ + FROM ${prefix}ACT_HI_DECINST + WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=TIMESTAMP} + ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_DEC_OUT set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_DEC_OUT + + where DEC_INST_ID_ IN ( + SELECT ID_ + FROM ${prefix}ACT_HI_DECINST + WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=TIMESTAMP} + ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_HI_DEC_OUT + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_DEC_OUT + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where DEC_INST_ID_ IN ( SELECT ID_ FROM ${prefix}ACT_HI_DECINST WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=TIMESTAMP} ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_DEC_OUT RES WITH (FORCESEEK) where RES.DEC_INST_ID_ IN ( @@ -102,6 +206,10 @@ FROM ${prefix}ACT_HI_DECINST WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=TIMESTAMP} ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_DETAIL set + REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_DETAIL set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_DETAIL + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_HI_DETAIL + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_DETAIL + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_DETAIL RES WITH (FORCESEEK) where RES.ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_DETAIL + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_DETAIL set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_DETAIL + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_HI_DETAIL + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_DETAIL + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_DETAIL RES WITH (FORCESEEK) where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + diff --git a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricExternalTaskLog.xml b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricExternalTaskLog.xml index 3b513ecc452..07063a5e709 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricExternalTaskLog.xml +++ b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricExternalTaskLog.xml @@ -71,50 +71,137 @@ + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_EXT_TASK_LOG set + REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_EXT_TASK_LOG set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_EXT_TASK_LOG + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_EXT_TASK_LOG RES WITH (FORCESEEK) where RES.ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + - update ${prefix}ACT_HI_EXT_TASK_LOG set - REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}, - TIMESTAMP_ = TIMESTAMP_ + update ${prefix}ACT_HI_EXT_TASK_LOG + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_EXT_TASK_LOG + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}, + TIMESTAMP_ = TIMESTAMP_ + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}, + TIMESTAMP_ = TIMESTAMP_ + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_EXT_TASK_LOG + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_EXT_TASK_LOG set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_EXT_TASK_LOG + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_EXT_TASK_LOG RES WITH (FORCESEEK) where RES.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + update ${prefix}ACT_HI_EXT_TASK_LOG - set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}, - TIMESTAMP_ = TIMESTAMP_ + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_EXT_TASK_LOG + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}, + TIMESTAMP_ = TIMESTAMP_ + + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}, + TIMESTAMP_ = TIMESTAMP_ + diff --git a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricIdentityLinkLog.xml b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricIdentityLinkLog.xml index 78fada8c62d..fd9cf07e0a0 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricIdentityLinkLog.xml +++ b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricIdentityLinkLog.xml @@ -58,43 +58,117 @@ + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_IDENTITYLINK set + REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_IDENTITYLINK set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_IDENTITYLINK + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_IDENTITYLINK RES WITH (FORCESEEK) where RES.ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + - update ${prefix}ACT_HI_IDENTITYLINK set - REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}, - TIMESTAMP_ = TIMESTAMP_ + update ${prefix}ACT_HI_IDENTITYLINK + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_IDENTITYLINK + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}, + TIMESTAMP_ = TIMESTAMP_ + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}, + TIMESTAMP_ = TIMESTAMP_ + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_IDENTITYLINK + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + where TASK_ID_ IN ( + SELECT ID_ + FROM ${prefix}ACT_HI_TASKINST + WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_IDENTITYLINK set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_IDENTITYLINK + where TASK_ID_ IN ( SELECT ID_ FROM ${prefix}ACT_HI_TASKINST WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_IDENTITYLINK RES WITH (FORCESEEK) where RES.TASK_ID_ IN ( @@ -102,18 +176,35 @@ FROM ${prefix}ACT_HI_TASKINST WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + update ${prefix}ACT_HI_IDENTITYLINK - set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}, - TIMESTAMP_ = TIMESTAMP_ + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_IDENTITYLINK + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}, + TIMESTAMP_ = TIMESTAMP_ + + where TASK_ID_ IN ( SELECT ID_ FROM ${prefix}ACT_HI_TASKINST WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}, + TIMESTAMP_ = TIMESTAMP_ + diff --git a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricIncident.xml b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricIncident.xml index 0fbdd3a03e3..61c6cd2f0e8 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricIncident.xml +++ b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricIncident.xml @@ -107,50 +107,137 @@ + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_INCIDENT set + REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_INCIDENT set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_INCIDENT + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_INCIDENT RES WITH (FORCESEEK) where RES.ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + - update ${prefix}ACT_HI_INCIDENT set - REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}, - CREATE_TIME_ = CREATE_TIME_ + update ${prefix}ACT_HI_INCIDENT + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_INCIDENT + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}, + CREATE_TIME_ = CREATE_TIME_ + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}, + CREATE_TIME_ = CREATE_TIME_ + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_INCIDENT + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_INCIDENT set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_INCIDENT + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_INCIDENT RES WITH (FORCESEEK) where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + update ${prefix}ACT_HI_INCIDENT - set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}, - CREATE_TIME_ = CREATE_TIME_ + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_INCIDENT + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}, + CREATE_TIME_ = CREATE_TIME_ + + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}, + CREATE_TIME_ = CREATE_TIME_ + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_JOB_LOG set + REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_JOB_LOG set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_JOB_LOG + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_HI_JOB_LOG + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_JOB_LOG + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_JOB_LOG RES WITH (FORCESEEK) where RES.ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_JOB_LOG + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + where PROCESS_INSTANCE_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_JOB_LOG set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_JOB_LOG + where PROCESS_INSTANCE_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_HI_JOB_LOG + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_JOB_LOG + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + + where PROCESS_INSTANCE_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_JOB_LOG RES WITH (FORCESEEK) where RES.PROCESS_INSTANCE_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_PROCINST set + REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_PROCINST set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_PROCINST + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + update ${prefix}ACT_HI_PROCINST + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_PROCINST + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_PROCINST RES WITH (FORCESEEK) where RES.ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_PROCINST + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_PROCINST set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_PROCINST + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_HI_PROCINST + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_PROCINST + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_PROCINST RES WITH (FORCESEEK) where RES.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + diff --git a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricTaskInstance.xml b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricTaskInstance.xml index 34f58b65e9a..27db576f706 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricTaskInstance.xml +++ b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricTaskInstance.xml @@ -110,33 +110,133 @@ + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_TASKINST set + REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_TASKINST set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_TASKINST + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_HI_TASKINST + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_TASKINST + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_TASKINST RES WITH (FORCESEEK) where RES.ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_TASKINST + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_TASKINST set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_TASKINST + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_HI_TASKINST + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_TASKINST + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_TASKINST RES WITH (FORCESEEK) where RES.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + diff --git a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricVariableInstance.xml b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricVariableInstance.xml index 35469d56802..062e2836b40 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricVariableInstance.xml +++ b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/HistoricVariableInstance.xml @@ -98,33 +98,133 @@ + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_VARINST set + REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_VARINST set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_VARINST + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_HI_VARINST + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_VARINST + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_VARINST RES WITH (FORCESEEK) where RES.ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_VARINST + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_VARINST set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_VARINST + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_HI_VARINST + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_VARINST + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_VARINST RES WITH (FORCESEEK) where RES.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + diff --git a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/UserOperationLogEntry.xml b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/UserOperationLogEntry.xml index fdcb1c1446f..825851d65f2 100644 --- a/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/UserOperationLogEntry.xml +++ b/engine/src/main/resources/org/camunda/bpm/engine/impl/mapping/entity/UserOperationLogEntry.xml @@ -87,50 +87,137 @@ + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_OP_LOG set + REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_OP_LOG set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_OP_LOG + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + - update RES set - RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} - FROM ${prefix}ACT_HI_OP_LOG RES WITH (FORCESEEK) + update + + ${limitBeforeWithoutOffset} + + RES set + RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + FROM ${prefix}ACT_HI_OP_LOG RES WITH (FORCESEEK) where RES.ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + - update ${prefix}ACT_HI_OP_LOG set - REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}, - TIMESTAMP_ = TIMESTAMP_ + update ${prefix}ACT_HI_OP_LOG + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_OP_LOG + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}, + TIMESTAMP_ = TIMESTAMP_ + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}, + TIMESTAMP_ = TIMESTAMP_ + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_HI_OP_LOG + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_HI_OP_LOG set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_HI_OP_LOG + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_HI_OP_LOG RES WITH (FORCESEEK) where RES.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + update ${prefix}ACT_HI_OP_LOG - set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}, - TIMESTAMP_ = TIMESTAMP_ + + + ${limitBeforeInUpdate} ${prefix}ACT_HI_OP_LOG + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}, + TIMESTAMP_ = TIMESTAMP_ + + where PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP}, + TIMESTAMP_ = TIMESTAMP_ + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_GE_BYTEARRAY set + REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_GE_BYTEARRAY set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_GE_BYTEARRAY + + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_GE_BYTEARRAY + + + ${limitBeforeInUpdate} ${prefix}ACT_GE_BYTEARRAY + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_GE_BYTEARRAY RES WITH (FORCESEEK) where RES.ROOT_PROC_INST_ID_ = #{rootProcessInstanceId, jdbcType=VARCHAR} + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_GE_BYTEARRAY + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + where ID_ IN ( + + SELECT BYTEARRAY_ID_ + FROM ${prefix}ACT_HI_VARINST + WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_GE_BYTEARRAY set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_GE_BYTEARRAY + + where ID_ IN ( + + SELECT BYTEARRAY_ID_ + FROM ${prefix}ACT_HI_VARINST + WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_GE_BYTEARRAY + + + ${limitBeforeInUpdate} ${prefix}ACT_GE_BYTEARRAY + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where ID_ IN ( SELECT BYTEARRAY_ID_ FROM ${prefix}ACT_HI_VARINST WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_GE_BYTEARRAY RES WITH (FORCESEEK) where RES.ID_ IN ( @@ -538,12 +644,41 @@ FROM ${prefix}ACT_HI_VARINST WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_GE_BYTEARRAY + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + where ID_ IN ( + + SELECT BYTEARRAY_ID_ + FROM ${prefix}ACT_HI_DEC_IN I + INNER JOIN ${prefix}ACT_HI_DECINST D + ON I.DEC_INST_ID_ = D.ID_ + WHERE D.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_GE_BYTEARRAY set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_GE_BYTEARRAY + where ID_ IN ( SELECT BYTEARRAY_ID_ @@ -552,11 +687,45 @@ ON I.DEC_INST_ID_ = D.ID_ WHERE D.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_GE_BYTEARRAY + + + ${limitBeforeInUpdate} ${prefix}ACT_GE_BYTEARRAY + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + + where ID_ IN ( + + SELECT BYTEARRAY_ID_ + FROM ${prefix}ACT_HI_DEC_IN I + INNER JOIN ${prefix}ACT_HI_DECINST D + ON I.DEC_INST_ID_ = D.ID_ + WHERE D.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_GE_BYTEARRAY RES WITH (FORCESEEK) where RES.ID_ IN ( @@ -567,12 +736,41 @@ ON I.DEC_INST_ID_ = D.ID_ WHERE D.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_GE_BYTEARRAY + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + where ID_ IN ( + + SELECT BYTEARRAY_ID_ + FROM ${prefix}ACT_HI_DEC_OUT O + INNER JOIN ${prefix}ACT_HI_DECINST D + ON O.DEC_INST_ID_ = D.ID_ + WHERE D.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_GE_BYTEARRAY set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_GE_BYTEARRAY + where ID_ IN ( SELECT BYTEARRAY_ID_ @@ -581,11 +779,45 @@ ON O.DEC_INST_ID_ = D.ID_ WHERE D.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_GE_BYTEARRAY + + + ${limitBeforeInUpdate} ${prefix}ACT_GE_BYTEARRAY + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + + where ID_ IN ( + + SELECT BYTEARRAY_ID_ + FROM ${prefix}ACT_HI_DEC_OUT O + INNER JOIN ${prefix}ACT_HI_DECINST D + ON O.DEC_INST_ID_ = D.ID_ + WHERE D.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_GE_BYTEARRAY RES WITH (FORCESEEK) where RES.ID_ IN ( @@ -596,23 +828,82 @@ ON O.DEC_INST_ID_ = D.ID_ WHERE D.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_GE_BYTEARRAY + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + where ID_ IN ( + + SELECT JOB_EXCEPTION_STACK_ID_ + FROM ${prefix}ACT_HI_JOB_LOG + WHERE PROCESS_INSTANCE_ID_ = #{processInstanceId, jdbcType=VARCHAR} + ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_GE_BYTEARRAY set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_GE_BYTEARRAY + where ID_ IN ( SELECT JOB_EXCEPTION_STACK_ID_ FROM ${prefix}ACT_HI_JOB_LOG WHERE PROCESS_INSTANCE_ID_ = #{processInstanceId, jdbcType=VARCHAR} ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_GE_BYTEARRAY + + + ${limitBeforeInUpdate} ${prefix}ACT_GE_BYTEARRAY + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + + where ID_ IN ( + + SELECT JOB_EXCEPTION_STACK_ID_ + FROM ${prefix}ACT_HI_JOB_LOG + WHERE PROCESS_INSTANCE_ID_ = #{processInstanceId, jdbcType=VARCHAR} + ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_GE_BYTEARRAY RES WITH (FORCESEEK) where RES.ID_ IN ( @@ -621,23 +912,82 @@ FROM ${prefix}ACT_HI_JOB_LOG WHERE PROCESS_INSTANCE_ID_ = #{processInstanceId, jdbcType=VARCHAR} ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_GE_BYTEARRAY + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + where ID_ IN ( + + SELECT ERROR_DETAILS_ID_ + FROM ${prefix}ACT_HI_EXT_TASK_LOG + WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_GE_BYTEARRAY set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_GE_BYTEARRAY + where ID_ IN ( SELECT ERROR_DETAILS_ID_ FROM ${prefix}ACT_HI_EXT_TASK_LOG WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_GE_BYTEARRAY + + + ${limitBeforeInUpdate} ${prefix}ACT_GE_BYTEARRAY + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + + where ID_ IN ( + + SELECT ERROR_DETAILS_ID_ + FROM ${prefix}ACT_HI_EXT_TASK_LOG + WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_GE_BYTEARRAY RES WITH (FORCESEEK) where RES.ID_ IN ( @@ -646,12 +996,66 @@ FROM ${prefix}ACT_HI_EXT_TASK_LOG WHERE PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + update + + ${limitBeforeWithoutOffset} + + ${prefix}ACT_GE_BYTEARRAY + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + where ID_ IN ( + + SELECT CONTENT_ID_ + FROM ${prefix}ACT_HI_ATTACHMENT A + LEFT JOIN ${prefix}ACT_HI_TASKINST T ON A.TASK_ID_ = T.ID_ + WHERE A.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + OR T.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + + + + update ${prefix}ACT_GE_BYTEARRAY set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + ${limitBeforeInUpdate} ${prefix}ACT_GE_BYTEARRAY + + where ID_ IN ( + + SELECT CONTENT_ID_ + FROM ${prefix}ACT_HI_ATTACHMENT A + LEFT JOIN ${prefix}ACT_HI_TASKINST T ON A.TASK_ID_ = T.ID_ + WHERE A.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + OR T.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} + ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + + + + + update ${prefix}ACT_GE_BYTEARRAY + + + ${limitBeforeInUpdate} ${prefix}ACT_GE_BYTEARRAY + + + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + + where ID_ IN ( SELECT CONTENT_ID_ @@ -660,11 +1064,20 @@ WHERE A.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} OR T.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterInUpdate} + set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} + - update RES set + update + + ${limitBeforeWithoutOffset} + + RES set RES.REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} FROM ${prefix}ACT_GE_BYTEARRAY RES WITH (FORCESEEK) where RES.ID_ IN ( @@ -675,11 +1088,16 @@ WHERE A.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} OR T.PROC_INST_ID_ = #{processInstanceId, jdbcType=VARCHAR} ) + + and (REMOVAL_TIME_ is null or REMOVAL_TIME_ != #{removalTime, jdbcType=TIMESTAMP}) + ${limitAfterWithoutOffset} + - update ${prefix}ACT_GE_BYTEARRAY + update + ${prefix}ACT_GE_BYTEARRAY set REMOVAL_TIME_ = #{removalTime, jdbcType=TIMESTAMP} where ID_ IN ( diff --git a/engine/src/test/java/org/camunda/bpm/engine/test/api/history/removaltime/batch/BatchSetRemovalTimeInChunksTest.java b/engine/src/test/java/org/camunda/bpm/engine/test/api/history/removaltime/batch/BatchSetRemovalTimeInChunksTest.java new file mode 100644 index 00000000000..01c21ceed1f --- /dev/null +++ b/engine/src/test/java/org/camunda/bpm/engine/test/api/history/removaltime/batch/BatchSetRemovalTimeInChunksTest.java @@ -0,0 +1,2574 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; 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.camunda.bpm.engine.test.api.history.removaltime.batch; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.Assertions.tuple; +import static org.camunda.bpm.engine.ProcessEngineConfiguration.HISTORY_FULL; +import static org.camunda.bpm.engine.test.api.history.removaltime.batch.helper.BatchSetRemovalTimeRule.addDays; + +import java.io.ByteArrayInputStream; +import java.util.Date; +import java.util.List; +import org.camunda.bpm.engine.AuthorizationService; +import org.camunda.bpm.engine.BadUserRequestException; +import org.camunda.bpm.engine.DecisionService; +import org.camunda.bpm.engine.ExternalTaskService; +import org.camunda.bpm.engine.HistoryService; +import org.camunda.bpm.engine.IdentityService; +import org.camunda.bpm.engine.ManagementService; +import org.camunda.bpm.engine.ProcessEngineException; +import org.camunda.bpm.engine.RuntimeService; +import org.camunda.bpm.engine.TaskService; +import org.camunda.bpm.engine.authorization.Authorization; +import org.camunda.bpm.engine.authorization.AuthorizationQuery; +import org.camunda.bpm.engine.authorization.Resources; +import org.camunda.bpm.engine.batch.Batch; +import org.camunda.bpm.engine.history.HistoricActivityInstance; +import org.camunda.bpm.engine.history.HistoricDecisionInputInstance; +import org.camunda.bpm.engine.history.HistoricDecisionInstance; +import org.camunda.bpm.engine.history.HistoricDecisionOutputInstance; +import org.camunda.bpm.engine.history.HistoricDetail; +import org.camunda.bpm.engine.history.HistoricExternalTaskLog; +import org.camunda.bpm.engine.history.HistoricIdentityLinkLog; +import org.camunda.bpm.engine.history.HistoricIncident; +import org.camunda.bpm.engine.history.HistoricJobLog; +import org.camunda.bpm.engine.history.HistoricProcessInstance; +import org.camunda.bpm.engine.history.HistoricProcessInstanceQuery; +import org.camunda.bpm.engine.history.HistoricTaskInstance; +import org.camunda.bpm.engine.history.HistoricVariableInstance; +import org.camunda.bpm.engine.history.SetRemovalTimeSelectModeForHistoricProcessInstancesBuilder; +import org.camunda.bpm.engine.history.UserOperationLogEntry; +import org.camunda.bpm.engine.impl.batch.removaltime.ProcessSetRemovalTimeJobHandler; +import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl; +import org.camunda.bpm.engine.impl.history.event.HistoricDecisionInputInstanceEntity; +import org.camunda.bpm.engine.impl.history.event.HistoricDecisionOutputInstanceEntity; +import org.camunda.bpm.engine.impl.history.event.HistoricExternalTaskLogEntity; +import org.camunda.bpm.engine.impl.persistence.entity.AttachmentEntity; +import org.camunda.bpm.engine.impl.persistence.entity.ByteArrayEntity; +import org.camunda.bpm.engine.impl.persistence.entity.HistoricJobLogEventEntity; +import org.camunda.bpm.engine.impl.persistence.entity.HistoricVariableInstanceEntity; +import org.camunda.bpm.engine.impl.util.ClockUtil; +import org.camunda.bpm.engine.task.Attachment; +import org.camunda.bpm.engine.task.Comment; +import org.camunda.bpm.engine.task.Task; +import org.camunda.bpm.engine.test.Deployment; +import org.camunda.bpm.engine.test.ProcessEngineRule; +import org.camunda.bpm.engine.test.RequiredHistoryLevel; +import org.camunda.bpm.engine.test.api.history.removaltime.batch.helper.BatchSetRemovalTimeRule; +import org.camunda.bpm.engine.test.api.history.removaltime.batch.helper.BatchSetRemovalTimeRule.TestProcessBuilder; +import org.camunda.bpm.engine.test.dmn.businessruletask.TestPojo; +import org.camunda.bpm.engine.test.util.ProcessEngineTestRule; +import org.camunda.bpm.engine.test.util.ProvidedProcessEngineRule; +import org.camunda.bpm.engine.variable.Variables; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.RuleChain; + +@RequiredHistoryLevel(HISTORY_FULL) +public class BatchSetRemovalTimeInChunksTest { + + protected ProcessEngineRule engineRule = new ProvidedProcessEngineRule(); + protected ProcessEngineTestRule engineTestRule = new ProcessEngineTestRule(engineRule); + protected BatchSetRemovalTimeRule testRule = new BatchSetRemovalTimeRule(engineRule, engineTestRule); + + @Rule + public RuleChain ruleChain = RuleChain.outerRule(engineRule).around(engineTestRule).around(testRule); + + protected final Date REMOVAL_TIME = testRule.REMOVAL_TIME; + + protected final Date CREATE_TIME = new Date(1363608000000L); + + protected final Date CURRENT_DATE = testRule.CURRENT_DATE; + + protected ProcessEngineConfigurationImpl engineConfiguration; + protected RuntimeService runtimeService; + protected DecisionService decisionService; + protected HistoryService historyService; + protected ManagementService managementService; + protected TaskService taskService; + protected IdentityService identityService; + protected ExternalTaskService externalTaskService; + protected AuthorizationService authorizationService; + protected int defaultMaxUpdateRows; + protected int defaultInvocationsPerBatchJob; + + @Before + public void setup() { + engineConfiguration = engineRule.getProcessEngineConfiguration(); + + defaultMaxUpdateRows = engineConfiguration.getRemovalTimeUpdateChunkSize(); + defaultInvocationsPerBatchJob = engineConfiguration.getInvocationsPerBatchJob(); + engineConfiguration.setRemovalTimeUpdateChunkSize(1); + + runtimeService = engineRule.getRuntimeService(); + decisionService = engineRule.getDecisionService(); + historyService = engineRule.getHistoryService(); + managementService = engineRule.getManagementService(); + taskService = engineRule.getTaskService(); + identityService = engineRule.getIdentityService(); + externalTaskService = engineRule.getExternalTaskService(); + authorizationService = engineRule.getAuthorizationService(); + } + + @After + public void tearDown() { + engineConfiguration.setRemovalTimeUpdateChunkSize(defaultMaxUpdateRows); + engineConfiguration.setInvocationsPerBatchJob(defaultInvocationsPerBatchJob); + } + + @Test + public void shouldRescheduleRemovalTimeJob() { + // given + testRule.process().serviceTask().serviceTask().userTask().deploy().start(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + Batch batch = historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync(); + testRule.executeSeedJobs(batch, true); + // first execution updating one row per table + testRule.getExecutionJobs(batch).forEach(job -> managementService.executeJob(job.getId())); + + // when second execution updating one row per table + testRule.getExecutionJobs(batch).forEach(job -> managementService.executeJob(job.getId())); + + // then more executions exist + assertThat(testRule.getExecutionJobs(batch)).isNotEmpty(); + } + + @Test + public void shouldUseCustomChunkSize() { + // given + testRule.process().serviceTask().serviceTask().userTask().deploy().start(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + Batch batch = historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .chunkSize(100) // data updated in one chunk + .executeAsync(); + testRule.executeSeedJobs(batch, true); + // first execution updating all but the process instance + testRule.getExecutionJobs(batch).forEach(job -> managementService.executeJob(job.getId())); + + // when second execution updating process instance + testRule.getExecutionJobs(batch).forEach(job -> managementService.executeJob(job.getId())); + + // then no more jobs exist + assertThat(testRule.getExecutionJobs(batch)).isEmpty(); + } + + @Test + public void shouldUpdateProcessInstanceLast() { + // given + testRule.process().serviceTask().serviceTask().userTask().deploy().start(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + Batch batch = historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .chunkSize(100) // most data updated in one chunk + .executeAsync(); + testRule.executeSeedJobs(batch, true); + // first execution updating all but the process instance + testRule.getExecutionJobs(batch).forEach(job -> managementService.executeJob(job.getId())); + + HistoricProcessInstance historicProcessInstance = query.singleResult(); + + // assume + assertThat(historicProcessInstance.getRemovalTime()).isNull(); + + // when second execution updating process instance + testRule.getExecutionJobs(batch).forEach(job -> managementService.executeJob(job.getId())); + + // then + historicProcessInstance = query.singleResult(); + + assertThat(testRule.getExecutionJobs(batch)).isEmpty(); + assertThat(historicProcessInstance.getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + @Test + public void shouldUpdateProcessInstanceLast_Hierarchical() { + // given + testRule.process().call().userTask().deploy().start(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + Batch batch = historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .hierarchical() + .updateInChunks() + .chunkSize(100) // most data updated in one chunk + .executeAsync(); + testRule.executeSeedJobs(batch, true); + // first execution updating all but the process instance + testRule.getExecutionJobs(batch).forEach(job -> managementService.executeJob(job.getId())); + + List historicProcessInstances = historyService.createHistoricProcessInstanceQuery().list(); + + // assume + assertThat(historicProcessInstances.get(0).getRemovalTime()).isNull(); + assertThat(historicProcessInstances.get(1).getRemovalTime()).isNull(); + + // when second execution updating process instance + testRule.getExecutionJobs(batch).forEach(job -> managementService.executeJob(job.getId())); + + // then + historicProcessInstances = historyService.createHistoricProcessInstanceQuery().list(); + + assertThat(testRule.getExecutionJobs(batch)).isEmpty(); + assertThat(historicProcessInstances.get(0).getRemovalTime()).isEqualTo(REMOVAL_TIME); + assertThat(historicProcessInstances.get(1).getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + @Test + public void shouldCreateOneRemovalTimeJobPerProcessInstance() { + // given + engineConfiguration.setInvocationsPerBatchJob(3); + + TestProcessBuilder process = testRule.process().userTask().deploy(); + process.start(); + process.start(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + Batch batch = historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync(); + + // when + testRule.executeSeedJobs(batch, true); + + // then + assertThat(testRule.getExecutionJobs(batch)).hasSize(2); + } + + @Test + public void shouldRejectChunkSize_Zero() { + // given + engineConfiguration.setRemovalTimeUpdateChunkSize(0); + + // when + assertThatThrownBy(() -> engineConfiguration.initBatchHandlers()) + + // then + .isInstanceOf(ProcessEngineException.class) + .hasMessageContaining("chunk size should be between 1 and"); + } + + @Test + public void shouldRejectChunkSize_Negative() { + // given + engineConfiguration.setRemovalTimeUpdateChunkSize(-5); + + // when + assertThatThrownBy(() -> engineConfiguration.initBatchHandlers()) + + // then + .isInstanceOf(ProcessEngineException.class) + .hasMessageContaining("chunk size should be between 1 and"); + } + + @Test + public void shouldRejectChunkSize_ExceedingLimit() { + // given + engineConfiguration.setRemovalTimeUpdateChunkSize(ProcessSetRemovalTimeJobHandler.MAX_CHUNK_SIZE + 5); + + // when + assertThatThrownBy(() -> engineConfiguration.initBatchHandlers()) + + // then + .isInstanceOf(ProcessEngineException.class) + .hasMessageContaining("chunk size should be between 1 and"); + } + + @Test + public void shouldRejectCustomChunkSize_Zero() { + // given + final SetRemovalTimeSelectModeForHistoricProcessInstancesBuilder builder = + historyService.setRemovalTimeToHistoricProcessInstances(); + + // when + assertThatThrownBy(() -> builder.chunkSize(0)) + + // then + .isInstanceOf(BadUserRequestException.class) + .hasMessageContaining("chunk size should be between 1 and"); + } + + @Test + public void shouldRejectCustomChunkSize_Negative() { + // given + final SetRemovalTimeSelectModeForHistoricProcessInstancesBuilder builder = + historyService.setRemovalTimeToHistoricProcessInstances(); + + // when + assertThatThrownBy(() -> builder.chunkSize(-3)) + + // then + .isInstanceOf(BadUserRequestException.class) + .hasMessageContaining("chunk size should be between 1 and"); + } + + @Test + public void shouldRejectCustomChunkSize_ExceedingLimit() { + // given + final SetRemovalTimeSelectModeForHistoricProcessInstancesBuilder builder = + historyService.setRemovalTimeToHistoricProcessInstances(); + + // when + assertThatThrownBy(() -> builder.chunkSize(ProcessSetRemovalTimeJobHandler.MAX_CHUNK_SIZE + 1)) + + // then + .isInstanceOf(BadUserRequestException.class) + .hasMessageContaining("chunk size should be between 1 and"); + } + + // NON-HIERARCHICAL TEST CASES + + @Test + @Deployment(resources = { + "org/camunda/bpm/engine/test/dmn/deployment/drdDish.dmn11.xml" + }) + public void shouldSetRemovalTime_DecisionInstance() { + // given + testRule.process().ruleTask("dish-decision").deploy().startWithVariables( + Variables.createVariables() + .putValue("temperature", 32) + .putValue("dayType", "Weekend") + ); + + List historicDecisionInstances = historyService.createHistoricDecisionInstanceQuery().list(); + + // then + assertThat(historicDecisionInstances.get(0).getRemovalTime()).isNull(); + assertThat(historicDecisionInstances.get(1).getRemovalTime()).isNull(); + assertThat(historicDecisionInstances.get(2).getRemovalTime()).isNull(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + historicDecisionInstances = historyService.createHistoricDecisionInstanceQuery().list(); + + // then + assertThat(historicDecisionInstances.get(0).getRemovalTime()).isEqualTo(REMOVAL_TIME); + assertThat(historicDecisionInstances.get(1).getRemovalTime()).isEqualTo(REMOVAL_TIME); + assertThat(historicDecisionInstances.get(2).getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + @Test + @Deployment(resources = { + "org/camunda/bpm/engine/test/dmn/deployment/drdDish.dmn11.xml" + }) + public void shouldSetRemovalTime_DecisionInputInstance() { + // given + testRule.process().ruleTask("dish-decision").deploy().startWithVariables( + Variables.createVariables() + .putValue("temperature", 32) + .putValue("dayType", "Weekend") + ); + + HistoricDecisionInstance historicDecisionInstance = historyService.createHistoricDecisionInstanceQuery() + .rootDecisionInstancesOnly() + .includeInputs() + .singleResult(); + + List historicDecisionInputInstances = historicDecisionInstance.getInputs(); + + // then + assertThat(historicDecisionInputInstances.get(0).getRemovalTime()).isNull(); + assertThat(historicDecisionInputInstances.get(1).getRemovalTime()).isNull(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + historicDecisionInstance = historyService.createHistoricDecisionInstanceQuery() + .rootDecisionInstancesOnly() + .includeInputs() + .singleResult(); + + historicDecisionInputInstances = historicDecisionInstance.getInputs(); + + // then + assertThat(historicDecisionInputInstances.get(0).getRemovalTime()).isEqualTo(REMOVAL_TIME); + assertThat(historicDecisionInputInstances.get(1).getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + @Test + @Deployment(resources = { + "org/camunda/bpm/engine/test/dmn/deployment/drdDish.dmn11.xml" + }) + public void shouldSetRemovalTime_DecisionOutputInstance() { + // given + testRule.process().ruleTask("dish-decision").deploy().startWithVariables( + Variables.createVariables() + .putValue("temperature", 32) + .putValue("dayType", "Weekend") + ); + + HistoricDecisionInstance historicDecisionInstance = historyService.createHistoricDecisionInstanceQuery() + .rootDecisionInstancesOnly() + .includeOutputs() + .singleResult(); + + List historicDecisionOutputInstances = historicDecisionInstance.getOutputs(); + + // then + assertThat(historicDecisionOutputInstances.get(0).getRemovalTime()).isNull(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + historicDecisionInstance = historyService.createHistoricDecisionInstanceQuery() + .rootDecisionInstancesOnly() + .includeOutputs() + .singleResult(); + + historicDecisionOutputInstances = historicDecisionInstance.getOutputs(); + + // then + assertThat(historicDecisionOutputInstances.get(0).getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + @Test + public void shouldSetRemovalTime_ProcessInstance() { + // given + testRule.process().userTask().deploy().start(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().singleResult(); + + // assume + assertThat(historicProcessInstance.getRemovalTime()).isNull(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + historicProcessInstance = historyService.createHistoricProcessInstanceQuery().singleResult(); + + // then + assertThat(historicProcessInstance.getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + @Test + public void shouldSetRemovalTime_ActivityInstance() { + // given + testRule.process().userTask().deploy().start(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + HistoricActivityInstance historicActivityInstance = historyService.createHistoricActivityInstanceQuery() + .activityName("userTask") + .singleResult(); + + // then + assertThat(historicActivityInstance.getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + @Test + public void shouldSetRemovalTime_TaskInstance() { + // given + testRule.process().userTask().deploy().start(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().singleResult(); + + // then + assertThat(historicTaskInstance.getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + @Test + public void shouldSetRemovalTime_HistoricTaskInstanceAuthorization() { + // given + testRule.getProcessEngineConfiguration() + .setEnableHistoricInstancePermissions(true); + + testRule.enableAuth(); + testRule.process().userTask().deploy().start(); + testRule.disableAuth(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + Authorization authorization = + authorizationService.createAuthorizationQuery() + .resourceType(Resources.HISTORIC_TASK) + .singleResult(); + + // then + assertThat(authorization.getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + @Test + public void shouldNotSetRemovalTime_HistoricTaskInstancePermissionsDisabled() { + // given + testRule.getProcessEngineConfiguration() + .setEnableHistoricInstancePermissions(true); + + testRule.enableAuth(); + testRule.process().userTask().deploy().start(); + testRule.disableAuth(); + + testRule.getProcessEngineConfiguration() + .setEnableHistoricInstancePermissions(false); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + Authorization authorization = + authorizationService.createAuthorizationQuery() + .resourceType(Resources.HISTORIC_TASK) + .singleResult(); + + // then + assertThat(authorization.getRemovalTime()).isNull(); + } + + @Test + public void shouldSetRemovalTime_HistoricProcessInstanceAuthorization() { + // given + testRule.getProcessEngineConfiguration() + .setEnableHistoricInstancePermissions(true); + + String processInstanceId = testRule.process().userTask().deploy().start(); + + Authorization authorization = + authorizationService.createNewAuthorization(Authorization.AUTH_TYPE_GRANT); + authorization.setResource(Resources.HISTORIC_PROCESS_INSTANCE); + authorization.setResourceId(processInstanceId); + authorization.setUserId("foo"); + + authorizationService.saveAuthorization(authorization); + + // assume + AuthorizationQuery authQuery = authorizationService.createAuthorizationQuery() + .resourceType(Resources.HISTORIC_PROCESS_INSTANCE); + + assertThat(authQuery.list()) + .extracting("removalTime", "resourceId", "rootProcessInstanceId") + .containsExactly(tuple(null, processInstanceId, processInstanceId)); + + // when + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + // then + authQuery = authorizationService.createAuthorizationQuery() + .resourceType(Resources.HISTORIC_PROCESS_INSTANCE); + + assertThat(authQuery.list()) + .extracting("removalTime", "resourceId", "rootProcessInstanceId") + .containsExactly(tuple(REMOVAL_TIME, processInstanceId, processInstanceId)); + } + + @Test + public void shouldNotSetRemovalTime_HistoricProcessInstancePermissionsDisabled() { + // given + testRule.getProcessEngineConfiguration() + .setEnableHistoricInstancePermissions(false); + + String processInstanceId = testRule.process().userTask().deploy().start(); + + Authorization authorization = + authorizationService.createNewAuthorization(Authorization.AUTH_TYPE_GRANT); + authorization.setResource(Resources.HISTORIC_PROCESS_INSTANCE); + authorization.setResourceId(processInstanceId); + authorization.setUserId("foo"); + + authorizationService.saveAuthorization(authorization); + + // assume + AuthorizationQuery authQuery = authorizationService.createAuthorizationQuery() + .resourceType(Resources.HISTORIC_PROCESS_INSTANCE); + + assertThat(authQuery.list()) + .extracting("removalTime", "resourceId", "rootProcessInstanceId") + .containsExactly(tuple(null, processInstanceId, processInstanceId)); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + // then + authQuery = authorizationService.createAuthorizationQuery() + .resourceType(Resources.HISTORIC_PROCESS_INSTANCE); + + assertThat(authQuery.list()) + .extracting("removalTime", "resourceId", "rootProcessInstanceId") + .containsExactly(tuple(null, processInstanceId, processInstanceId)); + } + + @Test + public void shouldSetRemovalTime_VariableInstance() { + // given + testRule.process().userTask().deploy() + .startWithVariables( + Variables.createVariables() + .putValue("aVariableName", "aVariableValue")); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + HistoricVariableInstance historicVariableInstance = historyService.createHistoricVariableInstanceQuery().singleResult(); + + // then + assertThat(historicVariableInstance.getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + @Test + public void shouldSetRemovalTime_Detail() { + // given + testRule.process().userTask().deploy() + .startWithVariables( + Variables.createVariables() + .putValue("aVariableName", "aVariableValue")); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + HistoricDetail historicDetail = historyService.createHistoricDetailQuery().singleResult(); + + // then + assertThat(historicDetail.getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + @Test + public void shouldSetRemovalTime_ExternalTaskLog() { + // given + testRule.process().externalTask().deploy().start(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + HistoricExternalTaskLog historicExternalTaskLog = historyService.createHistoricExternalTaskLogQuery().singleResult(); + + // assume + assertThat(historicExternalTaskLog.getRemovalTime()).isNull(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + historicExternalTaskLog = historyService.createHistoricExternalTaskLogQuery().singleResult(); + + // then + assertThat(historicExternalTaskLog.getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + /** + * See https://app.camunda.com/jira/browse/CAM-10172 + */ + @Test + public void shouldSetRemovalTime_ExternalTaskLog_WithPreservedCreateTime() { + // given + ClockUtil.setCurrentTime(CREATE_TIME); + + testRule.process().externalTask().deploy().start(); + + HistoricExternalTaskLog historicExternalTaskLog = historyService.createHistoricExternalTaskLogQuery().singleResult(); + + // assume + assertThat(historicExternalTaskLog.getTimestamp()).isEqualTo(CREATE_TIME); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + historicExternalTaskLog = historyService.createHistoricExternalTaskLogQuery().singleResult(); + + // then + assertThat(historicExternalTaskLog.getTimestamp()).isEqualTo(CREATE_TIME); + } + + @Test + public void shouldSetRemovalTime_JobLog() { + // given + String processInstanceId = testRule.process().async().userTask().deploy().start(); + + HistoricJobLog job = historyService.createHistoricJobLogQuery() + .processInstanceId(processInstanceId) + .singleResult(); + + // assume + assertThat(job.getRemovalTime()).isNull(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + job = historyService.createHistoricJobLogQuery() + .processInstanceId(processInstanceId) + .singleResult(); + + // then + assertThat(job.getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + @Test + public void shouldSetRemovalTime_Incident() { + // given + testRule.process().async().userTask().deploy().start(); + + String jobId = managementService.createJobQuery().singleResult().getId(); + + managementService.setJobRetries(jobId, 0); + + HistoricIncident historicIncident = historyService.createHistoricIncidentQuery().singleResult(); + + // assume + assertThat(historicIncident.getRemovalTime()).isNull(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + historicIncident = historyService.createHistoricIncidentQuery().singleResult(); + + // then + assertThat(historicIncident.getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + /** + * See https://app.camunda.com/jira/browse/CAM-10172 + */ + @Test + public void shouldSetRemovalTime_Incident_WithPreservedCreateTime() { + // given + ClockUtil.setCurrentTime(CREATE_TIME); + + testRule.process().async().userTask().deploy().start(); + + String jobId = managementService.createJobQuery().singleResult().getId(); + + managementService.setJobRetries(jobId, 0); + + HistoricIncident historicIncident = historyService.createHistoricIncidentQuery().singleResult(); + + // assume + assertThat(historicIncident.getCreateTime()).isEqualTo(CREATE_TIME); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + historicIncident = historyService.createHistoricIncidentQuery().singleResult(); + + // then + assertThat(historicIncident.getCreateTime()).isEqualTo(CREATE_TIME); + } + + @Test + public void shouldSetRemovalTime_OperationLog() { + // given + String processInstanceId = testRule.process().async().userTask().deploy().start(); + + identityService.setAuthenticatedUserId("aUserId"); + runtimeService.suspendProcessInstanceById(processInstanceId); + identityService.clearAuthentication(); + + UserOperationLogEntry userOperationLog = historyService.createUserOperationLogQuery().singleResult(); + + // assume + assertThat(userOperationLog.getRemovalTime()).isNull(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + userOperationLog = historyService.createUserOperationLogQuery().singleResult(); + + // then + assertThat(userOperationLog.getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + /** + * See https://app.camunda.com/jira/browse/CAM-10172 + */ + @Test + public void shouldSetRemovalTime_OperationLog_WithPreservedTimestamp() { + // given + ClockUtil.setCurrentTime(CREATE_TIME); + + String processInstanceId = testRule.process().async().userTask().deploy().start(); + + identityService.setAuthenticatedUserId("aUserId"); + runtimeService.suspendProcessInstanceById(processInstanceId); + identityService.clearAuthentication(); + + UserOperationLogEntry userOperationLog = historyService.createUserOperationLogQuery().singleResult(); + + // assume + assertThat(userOperationLog.getTimestamp()).isEqualTo(CREATE_TIME); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + userOperationLog = historyService.createUserOperationLogQuery().singleResult(); + + // then + assertThat(userOperationLog.getTimestamp()).isEqualTo(CREATE_TIME); + } + + @Test + public void shouldSetRemovalTime_IdentityLinkLog() { + // given + testRule.process().userTask().deploy().start(); + + HistoricIdentityLinkLog identityLinkLog = historyService.createHistoricIdentityLinkLogQuery().singleResult(); + + // assume + assertThat(identityLinkLog.getRemovalTime()).isNull(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + identityLinkLog = historyService.createHistoricIdentityLinkLogQuery().singleResult(); + + // then + assertThat(identityLinkLog.getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + /** + * See https://app.camunda.com/jira/browse/CAM-10172 + */ + @Test + public void shouldSetRemovalTime_IdentityLinkLog_WithPreservedTime() { + // given + ClockUtil.setCurrentTime(CREATE_TIME); + + testRule.process().userTask().deploy().start(); + + HistoricIdentityLinkLog identityLinkLog = historyService.createHistoricIdentityLinkLogQuery().singleResult(); + + // assume + assertThat(identityLinkLog.getTime()).isEqualTo(CREATE_TIME); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + identityLinkLog = historyService.createHistoricIdentityLinkLogQuery().singleResult(); + + // then + assertThat(identityLinkLog.getTime()).isEqualTo(CREATE_TIME); + } + + @Test + public void shouldNotSetUnaffectedRemovalTime_IdentityLinkLog() { + // given + TestProcessBuilder testProcessBuilder = testRule.process().userTask().deploy(); + + String instance1 = testProcessBuilder.start(); + String instance2 = testProcessBuilder.start(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query.processInstanceId(instance1)) + .updateInChunks() + .executeAsync() + ); + + Task task2 = taskService.createTaskQuery().processInstanceId(instance2).singleResult(); + + HistoricIdentityLinkLog identityLinkLog = historyService.createHistoricIdentityLinkLogQuery() + .taskId(task2.getId()).singleResult(); + + // then + assertThat(identityLinkLog.getRemovalTime()).isNull(); + } + + @Test + public void shouldSetRemovalTime_CommentByTaskId() { + // given + testRule.process().userTask().deploy().start(); + + String taskId = historyService.createHistoricTaskInstanceQuery() + .taskName("userTask") + .singleResult() + .getId(); + + taskService.createComment(taskId, null, "aComment"); + + Comment comment = taskService.getTaskComments(taskId).get(0); + + // assume + assertThat(comment.getRemovalTime()).isNull(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + comment = taskService.getTaskComments(taskId).get(0); + + // then + assertThat(comment.getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + @Test + public void shouldSetRemovalTime_CommentByProcessInstanceId() { + // given + String processInstanceId = testRule.process().userTask().deploy().start(); + + taskService.createComment(null, processInstanceId, "aComment"); + + Comment comment = taskService.getProcessInstanceComments(processInstanceId).get(0); + + // assume + assertThat(comment.getRemovalTime()).isNull(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + comment = taskService.getProcessInstanceComments(processInstanceId).get(0); + + // then + assertThat(comment.getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + @Test + public void shouldSetRemovalTime_AttachmentByTaskId() { + // given + testRule.process().userTask().deploy().start(); + + String taskId = historyService.createHistoricTaskInstanceQuery() + .taskName("userTask") + .singleResult() + .getId(); + + Attachment attachment = taskService.createAttachment(null, taskId, + null, null, null, "http://camunda.com"); + + // assume + assertThat(attachment.getRemovalTime()).isNull(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + attachment = taskService.getTaskAttachments(taskId).get(0); + + // then + assertThat(attachment.getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + @Test + public void shouldSetRemovalTime_AttachmentByProcessInstanceId() { + // given + String processInstanceId = testRule.process().userTask().deploy().start(); + + Attachment attachment = taskService.createAttachment(null, null, + processInstanceId, null, null, "http://camunda.com"); + + // assume + assertThat(attachment.getRemovalTime()).isNull(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + attachment = taskService.getProcessInstanceAttachments(processInstanceId).get(0); + + // then + assertThat(attachment.getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + @Test + public void shouldSetRemovalTime_ByteArray_AttachmentByTaskId() { + // given + testRule.process().userTask().deploy().start(); + + String taskId = historyService.createHistoricTaskInstanceQuery() + .taskName("userTask") + .singleResult() + .getId(); + + AttachmentEntity attachment = (AttachmentEntity) taskService.createAttachment(null, taskId, + null, null, null, new ByteArrayInputStream("".getBytes())); + + ByteArrayEntity byteArrayEntity = testRule.findByteArrayById(attachment.getContentId()); + + // assume + assertThat(byteArrayEntity.getRemovalTime()).isNull(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + byteArrayEntity = testRule.findByteArrayById(attachment.getContentId()); + + // then + assertThat(byteArrayEntity.getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + @Test + public void shouldSetRemovalTime_ByteArray_AttachmentByProcessInstanceId() { + // given + String processInstanceId = testRule.process().userTask().deploy().start(); + + AttachmentEntity attachment = (AttachmentEntity) taskService.createAttachment(null, null, + processInstanceId, null, null, new ByteArrayInputStream("".getBytes())); + + String byteArrayId = attachment.getContentId(); + + ByteArrayEntity byteArrayEntity = testRule.findByteArrayById(byteArrayId); + + // assume + assertThat(byteArrayEntity.getRemovalTime()).isNull(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + byteArrayEntity = testRule.findByteArrayById(byteArrayId); + + // then + assertThat(byteArrayEntity.getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + @Test + public void shouldSetRemovalTime_ByteArray_Variable() { + // given + testRule.process().userTask().deploy() + .startWithVariables( + Variables.createVariables() + .putValue("aVariableName", + Variables.fileValue("file.xml") + .file("".getBytes()))); + + HistoricVariableInstance historicVariableInstance = historyService.createHistoricVariableInstanceQuery().singleResult(); + + String byteArrayId = ((HistoricVariableInstanceEntity) historicVariableInstance).getByteArrayId(); + + ByteArrayEntity byteArrayEntity = testRule.findByteArrayById(byteArrayId); + + // assume + assertThat(byteArrayEntity.getRemovalTime()).isNull(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + byteArrayEntity = testRule.findByteArrayById(byteArrayId); + + // then + assertThat(byteArrayEntity.getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + @Test + public void shouldSetRemovalTime_ByteArray_JobLog() { + // given + testRule.process().async().scriptTask().deploy().start(); + + String jobId = managementService.createJobQuery().singleResult().getId(); + + try { + managementService.executeJob(jobId); + + } catch (Exception ignored) { } + + HistoricJobLog historicJobLog = historyService.createHistoricJobLogQuery() + .failureLog() + .singleResult(); + + String byteArrayId = ((HistoricJobLogEventEntity) historicJobLog).getExceptionByteArrayId(); + + ByteArrayEntity byteArrayEntity = testRule.findByteArrayById(byteArrayId); + + // assume + assertThat(byteArrayEntity.getRemovalTime()).isNull(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + byteArrayEntity = testRule.findByteArrayById(byteArrayId); + + // then + assertThat(byteArrayEntity.getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + @Test + public void shouldSetRemovalTime_ByteArray_ExternalTaskLog() { + // given + testRule.process().externalTask().deploy().start(); + + String externalTaskId = externalTaskService.fetchAndLock(1, "aWorkerId") + .topic("aTopicName", Integer.MAX_VALUE) + .execute() + .get(0) + .getId(); + + externalTaskService.handleFailure(externalTaskId, "aWorkerId", + null, "errorDetails", 5, 3000L); + + HistoricExternalTaskLog externalTaskLog = historyService.createHistoricExternalTaskLogQuery() + .failureLog() + .singleResult(); + + String byteArrayId = ((HistoricExternalTaskLogEntity) externalTaskLog).getErrorDetailsByteArrayId(); + + ByteArrayEntity byteArrayEntity = testRule.findByteArrayById(byteArrayId); + + // assume + assertThat(byteArrayEntity.getRemovalTime()).isNull(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + byteArrayEntity = testRule.findByteArrayById(byteArrayId); + + // then + assertThat(byteArrayEntity.getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + @Test + @Deployment(resources = { + "org/camunda/bpm/engine/test/api/history/testDmnWithPojo.dmn11.xml" + }) + public void shouldSetRemovalTime_ByteArray_DecisionInputInstance() { + // given + testRule.process().ruleTask("testDecision").deploy().startWithVariables( + Variables.createVariables() + .putValue("pojo", new TestPojo("okay", 13.37)) + ); + + HistoricDecisionInstance historicDecisionInstance = historyService.createHistoricDecisionInstanceQuery() + .rootDecisionInstancesOnly() + .includeInputs() + .singleResult(); + + String byteArrayId = ((HistoricDecisionInputInstanceEntity) historicDecisionInstance.getInputs().get(0)) + .getByteArrayValueId(); + + ByteArrayEntity byteArrayEntity = testRule.findByteArrayById(byteArrayId); + + // assume + assertThat(byteArrayEntity.getRemovalTime()).isNull(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + byteArrayEntity = testRule.findByteArrayById(byteArrayId); + + // then + assertThat(byteArrayEntity.getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + @Test + @Deployment(resources = { + "org/camunda/bpm/engine/test/api/history/testDmnWithPojo.dmn11.xml" + }) + public void shouldSetRemovalTime_ByteArray_DecisionOutputInstance() { + // given + testRule.process().ruleTask("testDecision").deploy().startWithVariables( + Variables.createVariables() + .putValue("pojo", new TestPojo("okay", 13.37)) + ); + + HistoricDecisionInstance historicDecisionInstance = historyService.createHistoricDecisionInstanceQuery() + .rootDecisionInstancesOnly() + .includeOutputs() + .singleResult(); + + String byteArrayId = ((HistoricDecisionOutputInstanceEntity) historicDecisionInstance.getOutputs().get(0)) + .getByteArrayValueId(); + + ByteArrayEntity byteArrayEntity = testRule.findByteArrayById(byteArrayId); + + // assume + assertThat(byteArrayEntity.getRemovalTime()).isNull(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .absoluteRemovalTime(REMOVAL_TIME) + .byQuery(query) + .updateInChunks() + .executeAsync() + ); + + byteArrayEntity = testRule.findByteArrayById(byteArrayId); + + // then + assertThat(byteArrayEntity.getRemovalTime()).isEqualTo(REMOVAL_TIME); + } + + // HIERARCHICAL TEST CASES + + @Test + @Deployment(resources = { + "org/camunda/bpm/engine/test/dmn/deployment/drdDish.dmn11.xml" + }) + public void shouldSetRemovalTime_DecisionInstance_Hierarchical() { + // given + testRule.process() + .call() + .passVars("temperature", "dayType") + .ruleTask("dish-decision") + .userTask() + .deploy() + .startWithVariables( + Variables.createVariables() + .putValue("temperature", 32) + .putValue("dayType", "Weekend") + ); + + List historicDecisionInstances = historyService.createHistoricDecisionInstanceQuery().list(); + + // assume + assertThat(historicDecisionInstances.get(0).getRemovalTime()).isNull(); + assertThat(historicDecisionInstances.get(1).getRemovalTime()).isNull(); + assertThat(historicDecisionInstances.get(2).getRemovalTime()).isNull(); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + historicDecisionInstances = historyService.createHistoricDecisionInstanceQuery().list(); + + // then + assertThat(historicDecisionInstances.get(0).getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + assertThat(historicDecisionInstances.get(1).getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + assertThat(historicDecisionInstances.get(2).getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } + + @Test + @Deployment(resources = { + "org/camunda/bpm/engine/test/dmn/deployment/drdDish.dmn11.xml" + }) + public void shouldSetRemovalTime_DecisionInputInstance_Hierarchical() { + // given + testRule.process() + .call() + .passVars("temperature", "dayType") + .ruleTask("dish-decision") + .userTask() + .deploy() + .startWithVariables( + Variables.createVariables() + .putValue("temperature", 32) + .putValue("dayType", "Weekend") + ); + + HistoricDecisionInstance historicDecisionInstance = historyService.createHistoricDecisionInstanceQuery() + .rootDecisionInstancesOnly() + .includeInputs() + .singleResult(); + + List historicDecisionInputInstances = historicDecisionInstance.getInputs(); + + // assume + assertThat(historicDecisionInputInstances.get(0).getRemovalTime()).isNull(); + assertThat(historicDecisionInputInstances.get(1).getRemovalTime()).isNull(); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + historicDecisionInstance = historyService.createHistoricDecisionInstanceQuery() + .rootDecisionInstancesOnly() + .includeInputs() + .singleResult(); + + historicDecisionInputInstances = historicDecisionInstance.getInputs(); + + // then + assertThat(historicDecisionInputInstances.get(0).getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + assertThat(historicDecisionInputInstances.get(1).getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } + + @Test + @Deployment(resources = { + "org/camunda/bpm/engine/test/dmn/deployment/drdDish.dmn11.xml" + }) + public void shouldSetRemovalTime_DecisionOutputInstance_Hierarchical() { + // given + testRule.process() + .call() + .passVars("temperature", "dayType") + .ruleTask("dish-decision") + .userTask() + .deploy() + .startWithVariables( + Variables.createVariables() + .putValue("temperature", 32) + .putValue("dayType", "Weekend") + ); + + HistoricDecisionInstance historicDecisionInstance = historyService.createHistoricDecisionInstanceQuery() + .rootDecisionInstancesOnly() + .includeOutputs() + .singleResult(); + + List historicDecisionOutputInstances = historicDecisionInstance.getOutputs(); + + // assume + assertThat(historicDecisionOutputInstances.get(0).getRemovalTime()).isNull(); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + historicDecisionInstance = historyService.createHistoricDecisionInstanceQuery() + .rootDecisionInstancesOnly() + .includeOutputs() + .singleResult(); + + historicDecisionOutputInstances = historicDecisionInstance.getOutputs(); + + // then + assertThat(historicDecisionOutputInstances.get(0).getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } + + @Test + public void shouldSetRemovalTime_ProcessInstance_Hierarchical() { + // given + testRule.process().call().userTask().deploy().start(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + List historicProcessInstances = historyService.createHistoricProcessInstanceQuery().rootProcessInstances().list(); + + // assume + assertThat(historicProcessInstances.get(0).getRemovalTime()).isNull(); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + historicProcessInstances = historyService.createHistoricProcessInstanceQuery().list(); + + // then + assertThat(historicProcessInstances.get(0).getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + assertThat(historicProcessInstances.get(1).getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } + + @Test + public void shouldSetRemovalTime_ActivityInstance_Hierarchical() { + // given + testRule.process().call().userTask().deploy().start(); + + HistoricActivityInstance historicActivityInstance = historyService.createHistoricActivityInstanceQuery() + .activityName("userTask") + .singleResult(); + + // assume + assertThat(historicActivityInstance.getRemovalTime()).isNull(); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + historicActivityInstance = historyService.createHistoricActivityInstanceQuery() + .activityName("userTask") + .singleResult(); + + // then + assertThat(historicActivityInstance.getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } + + @Test + public void shouldSetRemovalTime_TaskInstance_Hierarchical() { + // given + testRule.process().call().userTask().deploy().start(); + + HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().singleResult(); + + // assume + assertThat(historicTaskInstance.getRemovalTime()).isNull(); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + historicTaskInstance = historyService.createHistoricTaskInstanceQuery().singleResult(); + + // then + assertThat(historicTaskInstance.getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } + + @Test + public void shouldSetRemovalTime_HistoricTaskInstanceAuthorization_Hierarchical() { + // given + testRule.getProcessEngineConfiguration() + .setEnableHistoricInstancePermissions(true); + + testRule.enableAuth(); + testRule.process().call().userTask().deploy().start(); + testRule.disableAuth(); + + HistoricTaskInstance historicTaskInstance = + historyService.createHistoricTaskInstanceQuery().singleResult(); + + // assume + assertThat(historicTaskInstance.getRemovalTime()).isNull(); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + HistoricProcessInstanceQuery query = + historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + Authorization authorization = + authorizationService.createAuthorizationQuery() + .resourceType(Resources.HISTORIC_TASK) + .singleResult(); + + // then + assertThat(authorization.getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } + + @Test + public void shouldNotSetRemovalTime_HistoricTaskInstancePermissionsDisabled_Hierarchical() { + // given + testRule.getProcessEngineConfiguration() + .setEnableHistoricInstancePermissions(true); + + testRule.enableAuth(); + testRule.process().call().userTask().deploy().start(); + testRule.disableAuth(); + + testRule.getProcessEngineConfiguration() + .setEnableHistoricInstancePermissions(false); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + HistoricProcessInstanceQuery query = + historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + Authorization authorization = + authorizationService.createAuthorizationQuery() + .resourceType(Resources.HISTORIC_TASK) + .singleResult(); + + // then + assertThat(authorization.getRemovalTime()).isNull(); + } + + @Test + public void shouldSetRemovalTime_HistoricProcessInstanceAuthorization_Hierarchical() { + // given + testRule.getProcessEngineConfiguration() + .setEnableHistoricInstancePermissions(true); + + String rootProcessInstanceId = testRule.process().call().userTask().deploy().start(); + + Authorization authorization = + authorizationService.createNewAuthorization(Authorization.AUTH_TYPE_GRANT); + authorization.setResource(Resources.HISTORIC_PROCESS_INSTANCE); + + String processInstanceId = historyService.createHistoricProcessInstanceQuery() + .activeActivityIdIn("userTask") + .singleResult() + .getId(); + + authorization.setResourceId(processInstanceId); + authorization.setUserId("foo"); + + authorizationService.saveAuthorization(authorization); + + // assume + AuthorizationQuery authQuery = authorizationService.createAuthorizationQuery() + .resourceType(Resources.HISTORIC_PROCESS_INSTANCE); + + assertThat(authQuery.list()) + .extracting("removalTime", "resourceId", "rootProcessInstanceId") + .containsExactly(tuple(null, processInstanceId, rootProcessInstanceId)); + + // when + testRule.updateHistoryTimeToLive("rootProcess", 5); + + HistoricProcessInstanceQuery query = + historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + // then + authQuery = authorizationService.createAuthorizationQuery() + .resourceType(Resources.HISTORIC_PROCESS_INSTANCE); + + Date removalTime = addDays(CURRENT_DATE, 5); + assertThat(authQuery.list()) + .extracting("removalTime", "resourceId", "rootProcessInstanceId") + .containsExactly(tuple(removalTime, processInstanceId, rootProcessInstanceId)); + } + + @Test + public void shouldNotSetRemovalTime_HistoricProcessInstancePermissionsDisabled_Hierarchical() { + // given + testRule.getProcessEngineConfiguration() + .setEnableHistoricInstancePermissions(false); + + String rootProcessInstanceId = testRule.process().call().userTask().deploy().start(); + + Authorization authorization = + authorizationService.createNewAuthorization(Authorization.AUTH_TYPE_GRANT); + authorization.setResource(Resources.HISTORIC_PROCESS_INSTANCE); + + String processInstanceId = historyService.createHistoricProcessInstanceQuery() + .activeActivityIdIn("userTask") + .singleResult() + .getId(); + + authorization.setResourceId(processInstanceId); + authorization.setUserId("foo"); + + authorizationService.saveAuthorization(authorization); + + // assume + AuthorizationQuery authQuery = authorizationService.createAuthorizationQuery() + .resourceType(Resources.HISTORIC_PROCESS_INSTANCE); + + assertThat(authQuery.list()) + .extracting("removalTime", "resourceId", "rootProcessInstanceId") + .containsExactly(tuple(null, processInstanceId, rootProcessInstanceId)); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + // when + HistoricProcessInstanceQuery query = + historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + // then + authQuery = authorizationService.createAuthorizationQuery() + .resourceType(Resources.HISTORIC_PROCESS_INSTANCE); + + assertThat(authQuery.list()) + .extracting("removalTime", "resourceId", "rootProcessInstanceId") + .containsExactly(tuple(null, processInstanceId, rootProcessInstanceId)); + } + + @Test + public void shouldSetRemovalTime_VariableInstance_Hierarchical() { + // given + testRule.process().call().userTask().deploy() + .startWithVariables( + Variables.createVariables() + .putValue("aVariableName", "aVariableValue")); + + HistoricVariableInstance historicVariableInstance = historyService.createHistoricVariableInstanceQuery().singleResult(); + + // assume + assertThat(historicVariableInstance.getRemovalTime()).isNull(); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + historicVariableInstance = historyService.createHistoricVariableInstanceQuery().singleResult(); + + // then + assertThat(historicVariableInstance.getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } + + @Test + public void shouldSetRemovalTime_Detail_Hierarchical() { + // given + testRule.process().call().userTask().deploy() + .startWithVariables( + Variables.createVariables() + .putValue("aVariableName", "aVariableValue")); + + HistoricDetail historicDetail = historyService.createHistoricDetailQuery().singleResult(); + + // assume + assertThat(historicDetail.getRemovalTime()).isNull(); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + historicDetail = historyService.createHistoricDetailQuery().singleResult(); + + // then + assertThat(historicDetail.getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } + + @Test + public void shouldSetRemovalTime_ExternalTaskLog_Hierarchical() { + // given + testRule.process().call().externalTask().deploy().start(); + + HistoricExternalTaskLog historicExternalTaskLog = historyService.createHistoricExternalTaskLogQuery().singleResult(); + + // assume + assertThat(historicExternalTaskLog.getRemovalTime()).isNull(); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + historicExternalTaskLog = historyService.createHistoricExternalTaskLogQuery().singleResult(); + + // then + assertThat(historicExternalTaskLog.getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } + + @Test + public void shouldSetRemovalTime_JobLog_Hierarchical() { + // given + testRule.process().call().async().userTask().deploy().start(); + + HistoricJobLog job = historyService.createHistoricJobLogQuery() + .processDefinitionKey("process") + .singleResult(); + + // assume + assertThat(job.getRemovalTime()).isNull(); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + job = historyService.createHistoricJobLogQuery() + .processDefinitionKey("process") + .singleResult(); + + // then + assertThat(job.getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } + + @Test + public void shouldSetRemovalTime_Incident_Hierarchical() { + // given + String rootProcessInstanceId = testRule.process().call().async().userTask().deploy().start(); + + String jobId = managementService.createJobQuery().singleResult().getId(); + + managementService.setJobRetries(jobId, 0); + + String leafProcessInstanceId = historyService.createHistoricProcessInstanceQuery() + .superProcessInstanceId(rootProcessInstanceId) + .singleResult() + .getId(); + + HistoricIncident historicIncident = historyService.createHistoricIncidentQuery() + .processInstanceId(leafProcessInstanceId) + .singleResult(); + + // assume + assertThat(historicIncident.getRemovalTime()).isNull(); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + historicIncident = historyService.createHistoricIncidentQuery() + .processInstanceId(leafProcessInstanceId) + .singleResult(); + + // then + assertThat(historicIncident.getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } + + @Test + public void shouldSetRemovalTime_OperationLog_Hierarchical() { + // given + String processInstanceId = testRule.process().call().async().userTask().deploy().start(); + + identityService.setAuthenticatedUserId("aUserId"); + runtimeService.suspendProcessInstanceById(processInstanceId); + identityService.clearAuthentication(); + + UserOperationLogEntry userOperationLog = historyService.createUserOperationLogQuery().singleResult(); + + // assume + assertThat(userOperationLog.getRemovalTime()).isNull(); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + userOperationLog = historyService.createUserOperationLogQuery().singleResult(); + + // then + assertThat(userOperationLog.getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } + + @Test + public void shouldSetRemovalTime_IdentityLinkLog_Hierarchical() { + // given + testRule.process().call().userTask().deploy().start(); + + HistoricIdentityLinkLog identityLinkLog = historyService.createHistoricIdentityLinkLogQuery().singleResult(); + + // assume + assertThat(identityLinkLog.getRemovalTime()).isNull(); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + identityLinkLog = historyService.createHistoricIdentityLinkLogQuery().singleResult(); + + // then + assertThat(identityLinkLog.getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } + + @Test + public void shouldSetRemovalTime_CommentByTaskId_Hierarchical() { + // given + testRule.process().call().userTask().deploy().start(); + + String taskId = historyService.createHistoricTaskInstanceQuery() + .taskName("userTask") + .singleResult() + .getId(); + + taskService.createComment(taskId, null, "aComment"); + + Comment comment = taskService.getTaskComments(taskId).get(0); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + // assume + assertThat(comment.getRemovalTime()).isNull(); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + comment = taskService.getTaskComments(taskId).get(0); + + // then + assertThat(comment.getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } + + @Test + public void shouldSetRemovalTime_CommentByProcessInstanceId_Hierarchical() { + // given + String processInstanceId = testRule.process().call().userTask().deploy().start(); + + taskService.createComment(null, processInstanceId, "aComment"); + + Comment comment = taskService.getProcessInstanceComments(processInstanceId).get(0); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + // assume + assertThat(comment.getRemovalTime()).isNull(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + comment = taskService.getProcessInstanceComments(processInstanceId).get(0); + + // then + assertThat(comment.getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } + + @Test + public void shouldSetRemovalTime_AttachmentByTaskId_Hierarchical() { + // given + testRule.process().call().userTask().deploy().start(); + + String taskId = historyService.createHistoricTaskInstanceQuery() + .taskName("userTask") + .singleResult() + .getId(); + + Attachment attachment = taskService.createAttachment(null, taskId, + null, null, null, "http://camunda.com"); + + // assume + assertThat(attachment.getRemovalTime()).isNull(); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + attachment = taskService.getTaskAttachments(taskId).get(0); + + // then + assertThat(attachment.getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } + + @Test + public void shouldSetRemovalTime_AttachmentByProcessInstanceId_Hierarchical() { + // given + String processInstanceId = testRule.process().call().userTask().deploy().start(); + + Attachment attachment = taskService.createAttachment(null, null, + processInstanceId, null, null, "http://camunda.com"); + + // assume + assertThat(attachment.getRemovalTime()).isNull(); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + attachment = taskService.getProcessInstanceAttachments(processInstanceId).get(0); + + // then + assertThat(attachment.getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } + + @Test + public void shouldSetRemovalTime_ByteArray_AttachmentByTaskId_Hierarchical() { + // given + testRule.process().call().userTask().deploy().start(); + + String taskId = historyService.createHistoricTaskInstanceQuery() + .taskName("userTask") + .singleResult() + .getId(); + + AttachmentEntity attachment = (AttachmentEntity) taskService.createAttachment(null, taskId, + null, null, null, new ByteArrayInputStream("".getBytes())); + + ByteArrayEntity byteArrayEntity = testRule.findByteArrayById(attachment.getContentId()); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + // assume + assertThat(byteArrayEntity.getRemovalTime()).isNull(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + byteArrayEntity = testRule.findByteArrayById(attachment.getContentId()); + + // then + assertThat(byteArrayEntity.getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } + + @Test + public void shouldSetRemovalTime_ByteArray_AttachmentByProcessInstanceId_Hierarchical() { + // given + String processInstanceId = testRule.process().call().userTask().deploy().start(); + + AttachmentEntity attachment = (AttachmentEntity) taskService.createAttachment(null, null, + processInstanceId, null, null, new ByteArrayInputStream("".getBytes())); + + String byteArrayId = attachment.getContentId(); + + ByteArrayEntity byteArrayEntity = testRule.findByteArrayById(byteArrayId); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + // assume + assertThat(byteArrayEntity.getRemovalTime()).isNull(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + byteArrayEntity = testRule.findByteArrayById(byteArrayId); + + // then + assertThat(byteArrayEntity.getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } + + @Test + public void shouldSetRemovalTime_ByteArray_Variable_Hierarchical() { + // given + testRule.process().call().userTask().deploy() + .startWithVariables( + Variables.createVariables() + .putValue("aVariableName", + Variables.fileValue("file.xml") + .file("".getBytes()))); + + HistoricVariableInstance historicVariableInstance = historyService.createHistoricVariableInstanceQuery().singleResult(); + + String byteArrayId = ((HistoricVariableInstanceEntity) historicVariableInstance).getByteArrayId(); + + ByteArrayEntity byteArrayEntity = testRule.findByteArrayById(byteArrayId); + + // assume + assertThat(byteArrayEntity.getRemovalTime()).isNull(); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + byteArrayEntity = testRule.findByteArrayById(byteArrayId); + + // then + assertThat(byteArrayEntity.getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } + + @Test + public void shouldSetRemovalTime_ByteArray_JobLog_Hierarchical() { + // given + testRule.process().call().async().scriptTask().deploy().start(); + + String jobId = managementService.createJobQuery().singleResult().getId(); + + try { + managementService.executeJob(jobId); + + } catch (Exception ignored) { } + + HistoricJobLog historicJobLog = historyService.createHistoricJobLogQuery() + .failureLog() + .singleResult(); + + String byteArrayId = ((HistoricJobLogEventEntity) historicJobLog).getExceptionByteArrayId(); + + ByteArrayEntity byteArrayEntity = testRule.findByteArrayById(byteArrayId); + + // assume + assertThat(byteArrayEntity.getRemovalTime()).isNull(); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + byteArrayEntity = testRule.findByteArrayById(byteArrayId); + + // then + assertThat(byteArrayEntity.getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } + + @Test + public void shouldSetRemovalTime_ByteArray_ExternalTaskLog_Hierarchical() { + // given + testRule.process().call().externalTask().deploy().start(); + + String externalTaskId = externalTaskService.fetchAndLock(1, "aWorkerId") + .topic("aTopicName", Integer.MAX_VALUE) + .execute() + .get(0) + .getId(); + + externalTaskService.handleFailure(externalTaskId, "aWorkerId", + null, "errorDetails", 5, 3000L); + + HistoricExternalTaskLog externalTaskLog = historyService.createHistoricExternalTaskLogQuery() + .failureLog() + .singleResult(); + + String byteArrayId = ((HistoricExternalTaskLogEntity) externalTaskLog).getErrorDetailsByteArrayId(); + + ByteArrayEntity byteArrayEntity = testRule.findByteArrayById(byteArrayId); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + // assume + assertThat(byteArrayEntity.getRemovalTime()).isNull(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + byteArrayEntity = testRule.findByteArrayById(byteArrayId); + + // then + assertThat(byteArrayEntity.getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } + + @Test + @Deployment(resources = { + "org/camunda/bpm/engine/test/api/history/testDmnWithPojo.dmn11.xml" + }) + public void shouldSetRemovalTime_ByteArray_DecisionInputInstance_Hierarchical() { + // given + testRule.process() + .call() + .passVars("pojo") + .ruleTask("testDecision") + .userTask() + .deploy() + .startWithVariables( + Variables.createVariables() + .putValue("pojo", new TestPojo("okay", 13.37)) + ); + + HistoricDecisionInstance historicDecisionInstance = historyService.createHistoricDecisionInstanceQuery() + .rootDecisionInstancesOnly() + .includeInputs() + .singleResult(); + + String byteArrayId = ((HistoricDecisionInputInstanceEntity) historicDecisionInstance.getInputs().get(0)) + .getByteArrayValueId(); + + ByteArrayEntity byteArrayEntity = testRule.findByteArrayById(byteArrayId); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + // assume + assertThat(byteArrayEntity.getRemovalTime()).isNull(); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + byteArrayEntity = testRule.findByteArrayById(byteArrayId); + + // then + assertThat(byteArrayEntity.getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } + + @Test + @Deployment(resources = { + "org/camunda/bpm/engine/test/api/history/testDmnWithPojo.dmn11.xml" + }) + public void shouldSetRemovalTime_ByteArray_DecisionOutputInstance_Hierarchical() { + // given + testRule.process() + .call() + .passVars("pojo") + .ruleTask("testDecision") + .userTask() + .deploy() + .startWithVariables( + Variables.createVariables() + .putValue("pojo", new TestPojo("okay", 13.37)) + ); + + HistoricDecisionInstance historicDecisionInstance = historyService.createHistoricDecisionInstanceQuery() + .rootDecisionInstancesOnly() + .includeOutputs() + .singleResult(); + + String byteArrayId = ((HistoricDecisionOutputInstanceEntity) historicDecisionInstance.getOutputs().get(0)) + .getByteArrayValueId(); + + ByteArrayEntity byteArrayEntity = testRule.findByteArrayById(byteArrayId); + + // assume + assertThat(byteArrayEntity.getRemovalTime()).isNull(); + + testRule.updateHistoryTimeToLive("rootProcess", 5); + + HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().rootProcessInstances(); + + // when + testRule.syncExec( + historyService.setRemovalTimeToHistoricProcessInstances() + .calculatedRemovalTime() + .byQuery(query) + .hierarchical() + .updateInChunks() + .executeAsync() + ); + + byteArrayEntity = testRule.findByteArrayById(byteArrayId); + + // then + assertThat(byteArrayEntity.getRemovalTime()).isEqualTo(addDays(CURRENT_DATE, 5)); + } +} diff --git a/engine/src/test/java/org/camunda/bpm/engine/test/api/history/removaltime/batch/BatchSetRemovalTimeTest.java b/engine/src/test/java/org/camunda/bpm/engine/test/api/history/removaltime/batch/BatchSetRemovalTimeTest.java index bfb92453219..b66c814280b 100644 --- a/engine/src/test/java/org/camunda/bpm/engine/test/api/history/removaltime/batch/BatchSetRemovalTimeTest.java +++ b/engine/src/test/java/org/camunda/bpm/engine/test/api/history/removaltime/batch/BatchSetRemovalTimeTest.java @@ -30,7 +30,6 @@ import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; - import org.camunda.bpm.engine.BadUserRequestException; import org.camunda.bpm.engine.DecisionService; import org.camunda.bpm.engine.HistoryService; @@ -389,10 +388,10 @@ public void shouldSetRemovalTimeForBatch_MultipleInvocationsPerBatchJob() { .setInvocationsPerBatchJob(2); String processInstanceIdOne = testRule.process().userTask().deploy().start(); - Batch batchOne = historyService.deleteHistoricProcessInstancesAsync(Collections.singletonList(processInstanceIdOne), ""); + historyService.deleteHistoricProcessInstancesAsync(Collections.singletonList(processInstanceIdOne), ""); String processInstanceIdTwo = testRule.process().userTask().deploy().start(); - Batch batchTwo = historyService.deleteHistoricProcessInstancesAsync(Collections.singletonList(processInstanceIdTwo), ""); + historyService.deleteHistoricProcessInstancesAsync(Collections.singletonList(processInstanceIdTwo), ""); List historicBatches = historyService.createHistoricBatchQuery() .type(Batch.TYPE_HISTORIC_PROCESS_INSTANCE_DELETION) @@ -501,10 +500,10 @@ public void shouldSetRemovalTimeForBatch_SingleInvocationPerBatchJob() { .setInvocationsPerBatchJob(1); String processInstanceIdOne = testRule.process().userTask().deploy().start(); - Batch batchOne = historyService.deleteHistoricProcessInstancesAsync(Collections.singletonList(processInstanceIdOne), ""); + historyService.deleteHistoricProcessInstancesAsync(Collections.singletonList(processInstanceIdOne), ""); String processInstanceIdTwo = testRule.process().userTask().deploy().start(); - Batch batchTwo = historyService.deleteHistoricProcessInstancesAsync(Collections.singletonList(processInstanceIdTwo), ""); + historyService.deleteHistoricProcessInstancesAsync(Collections.singletonList(processInstanceIdTwo), ""); List historicBatches = historyService.createHistoricBatchQuery() .type(Batch.TYPE_HISTORIC_PROCESS_INSTANCE_DELETION) @@ -1007,7 +1006,7 @@ public void shouldSetRemovalTimeForStandaloneDecision_BaseTimeStart() { public void shouldSetRemovalTimeForBatch_BaseTimeStart() { // given String processInstanceId = testRule.process().serviceTask().deploy().start(); - Batch batch = historyService.deleteHistoricProcessInstancesAsync(Collections.singletonList(processInstanceId), ""); + historyService.deleteHistoricProcessInstancesAsync(Collections.singletonList(processInstanceId), ""); HistoricBatch historicBatch = historyService.createHistoricBatchQuery() .type(Batch.TYPE_HISTORIC_PROCESS_INSTANCE_DELETION) @@ -1188,7 +1187,7 @@ public void shouldNotSetRemovalTimeForBatch_BaseTimeEnd() { .setHistoryRemovalTimeStrategy(HISTORY_REMOVAL_TIME_STRATEGY_END); String processInstanceId = testRule.process().serviceTask().deploy().start(); - Batch batch = historyService.deleteHistoricProcessInstancesAsync(Collections.singletonList(processInstanceId), ""); + historyService.deleteHistoricProcessInstancesAsync(Collections.singletonList(processInstanceId), ""); HistoricBatch historicBatch = historyService.createHistoricBatchQuery() .type(Batch.TYPE_HISTORIC_PROCESS_INSTANCE_DELETION) @@ -1227,7 +1226,7 @@ public void shouldClearRemovalTimeForBatch_BaseTimeEnd() { configuration.initHistoryCleanup(); String processInstanceId = testRule.process().serviceTask().deploy().start(); - Batch batch = historyService.deleteHistoricProcessInstancesAsync(Collections.singletonList(processInstanceId), ""); + historyService.deleteHistoricProcessInstancesAsync(Collections.singletonList(processInstanceId), ""); HistoricBatch historicBatch = historyService.createHistoricBatchQuery() .type(Batch.TYPE_HISTORIC_PROCESS_INSTANCE_DELETION) @@ -1602,7 +1601,7 @@ public void shouldSetRemovalTimeForBatch_Null() { configuration.initHistoryCleanup(); String processInstanceId = testRule.process().serviceTask().deploy().start(); - Batch batch = historyService.deleteHistoricProcessInstancesAsync(Collections.singletonList(processInstanceId), ""); + historyService.deleteHistoricProcessInstancesAsync(Collections.singletonList(processInstanceId), ""); HistoricBatch historicBatch = historyService.createHistoricBatchQuery() .type(Batch.TYPE_HISTORIC_PROCESS_INSTANCE_DELETION) @@ -1778,7 +1777,7 @@ public void shouldSetRemovalTimeForStandaloneDecision_Absolute() { public void shouldSetRemovalTimeForBatch_Absolute() { // given String processInstanceId = testRule.process().serviceTask().deploy().start(); - Batch batch = historyService.deleteHistoricProcessInstancesAsync(Collections.singletonList(processInstanceId), ""); + historyService.deleteHistoricProcessInstancesAsync(Collections.singletonList(processInstanceId), ""); HistoricBatch historicBatch = historyService.createHistoricBatchQuery() .type(Batch.TYPE_HISTORIC_PROCESS_INSTANCE_DELETION) @@ -2059,8 +2058,8 @@ public void shouldSetRemovalTimeForBatch_ByIds() { // given String processInstanceId = testRule.process().serviceTask().deploy().start(); - Batch batchOne = historyService.deleteHistoricProcessInstancesAsync(Collections.singletonList(processInstanceId), ""); - Batch batchTwo = historyService.deleteHistoricProcessInstancesAsync(Collections.singletonList(processInstanceId), ""); + historyService.deleteHistoricProcessInstancesAsync(Collections.singletonList(processInstanceId), ""); + historyService.deleteHistoricProcessInstancesAsync(Collections.singletonList(processInstanceId), ""); List historicBatches = historyService.createHistoricBatchQuery() .type(Batch.TYPE_HISTORIC_PROCESS_INSTANCE_DELETION) diff --git a/engine/src/test/java/org/camunda/bpm/engine/test/api/history/removaltime/batch/BatchSetRemovalTimeUserOperationLogTest.java b/engine/src/test/java/org/camunda/bpm/engine/test/api/history/removaltime/batch/BatchSetRemovalTimeUserOperationLogTest.java index 805b5eccd59..c68df2d6b8f 100644 --- a/engine/src/test/java/org/camunda/bpm/engine/test/api/history/removaltime/batch/BatchSetRemovalTimeUserOperationLogTest.java +++ b/engine/src/test/java/org/camunda/bpm/engine/test/api/history/removaltime/batch/BatchSetRemovalTimeUserOperationLogTest.java @@ -23,7 +23,6 @@ import java.util.Collections; import java.util.Date; import java.util.List; - import org.camunda.bpm.engine.DecisionService; import org.camunda.bpm.engine.HistoryService; import org.camunda.bpm.engine.IdentityService; @@ -114,7 +113,7 @@ public void shouldWriteUserOperationLogForProcessInstances() { List userOperationLogEntries = historyService.createUserOperationLogQuery().list(); // then - assertProperties(userOperationLogEntries, "mode", "removalTime", "hierarchical", "nrOfInstances", "async"); + assertProperties(userOperationLogEntries, "mode", "removalTime", "hierarchical", "nrOfInstances", "async", "updateInChunks", "chunkSize"); assertOperationType(userOperationLogEntries, "SetRemovalTime"); assertCategory(userOperationLogEntries, "Operator"); assertEntityType(userOperationLogEntries, "ProcessInstance"); @@ -316,6 +315,105 @@ public void shouldWriteUserOperationLogForProcessInstances_HierarchicalFalse() { assertThat(userOperationLogEntry.getNewValue()).isEqualTo("false"); } + @Test + public void shouldWriteUserOperationLogForProcessInstances_UpdateInChunksTrue() { + // given + testRule.process().serviceTask().deploy().start(); + + identityService.setAuthenticatedUserId("aUserId"); + + HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery(); + + // when + historyService.setRemovalTimeToHistoricProcessInstances() + .clearedRemovalTime() + .byQuery(historicProcessInstanceQuery) + .updateInChunks() + .executeAsync(); + + UserOperationLogEntry userOperationLogEntry = historyService.createUserOperationLogQuery() + .property("updateInChunks") + .singleResult(); + + // then + assertThat(userOperationLogEntry.getOrgValue()).isNull(); + assertThat(userOperationLogEntry.getNewValue()).isEqualTo("true"); + } + + @Test + public void shouldWriteUserOperationLogForProcessInstances_UpdateInChunksFalse() { + // given + testRule.process().serviceTask().deploy().start(); + + identityService.setAuthenticatedUserId("aUserId"); + + HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery(); + + // when + historyService.setRemovalTimeToHistoricProcessInstances() + .clearedRemovalTime() + .byQuery(historicProcessInstanceQuery) + .executeAsync(); + + UserOperationLogEntry userOperationLogEntry = historyService.createUserOperationLogQuery() + .property("updateInChunks") + .singleResult(); + + // then + assertThat(userOperationLogEntry.getOrgValue()).isNull(); + assertThat(userOperationLogEntry.getNewValue()).isEqualTo("false"); + } + + @Test + public void shouldWriteUserOperationLogForProcessInstances_ChunkSize() { + // given + testRule.process().serviceTask().deploy().start(); + + identityService.setAuthenticatedUserId("aUserId"); + + HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery(); + + // when + historyService.setRemovalTimeToHistoricProcessInstances() + .clearedRemovalTime() + .byQuery(historicProcessInstanceQuery) + .updateInChunks() + .chunkSize(12) + .executeAsync(); + + UserOperationLogEntry userOperationLogEntry = historyService.createUserOperationLogQuery() + .property("chunkSize") + .singleResult(); + + // then + assertThat(userOperationLogEntry.getOrgValue()).isNull(); + assertThat(userOperationLogEntry.getNewValue()).isEqualTo("12"); + } + + @Test + public void shouldWriteUserOperationLogForProcessInstances_ChunkSizeNull() { + // given + testRule.process().serviceTask().deploy().start(); + + identityService.setAuthenticatedUserId("aUserId"); + + HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery(); + + // when + historyService.setRemovalTimeToHistoricProcessInstances() + .clearedRemovalTime() + .byQuery(historicProcessInstanceQuery) + .executeAsync(); + + UserOperationLogEntry userOperationLogEntry = historyService.createUserOperationLogQuery() + .property("chunkSize") + .singleResult(); + + // then + assertThat(userOperationLogEntry.getOrgValue()).isNull(); + assertThat(userOperationLogEntry.getNewValue()).isNull(); + } + @Test @Deployment(resources = { "org/camunda/bpm/engine/test/dmn/deployment/drdDish.dmn11.xml" @@ -738,7 +836,7 @@ protected void assertProperties(List userOperationLogEntr assertThat(userOperationLogEntries.size()).isEqualTo(expectedProperties.length); assertThat(userOperationLogEntries) - .extracting("property") + .extracting("property", String.class) .containsExactlyInAnyOrder(expectedProperties); } diff --git a/engine/src/test/java/org/camunda/bpm/engine/test/api/history/removaltime/batch/helper/BatchSetRemovalTimeRule.java b/engine/src/test/java/org/camunda/bpm/engine/test/api/history/removaltime/batch/helper/BatchSetRemovalTimeRule.java index 052b198c66d..32cf927df9b 100644 --- a/engine/src/test/java/org/camunda/bpm/engine/test/api/history/removaltime/batch/helper/BatchSetRemovalTimeRule.java +++ b/engine/src/test/java/org/camunda/bpm/engine/test/api/history/removaltime/batch/helper/BatchSetRemovalTimeRule.java @@ -16,22 +16,16 @@ */ package org.camunda.bpm.engine.test.api.history.removaltime.batch.helper; -import java.util.ArrayList; import java.util.Calendar; import java.util.Date; -import java.util.List; import java.util.Map; - import org.camunda.bpm.dmn.engine.impl.DefaultDmnEngineConfiguration; import org.camunda.bpm.engine.ProcessEngineConfiguration; -import org.camunda.bpm.engine.batch.Batch; -import org.camunda.bpm.engine.batch.history.HistoricBatch; import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl; import org.camunda.bpm.engine.impl.history.DefaultHistoryRemovalTimeProvider; import org.camunda.bpm.engine.impl.interceptor.CommandExecutor; import org.camunda.bpm.engine.impl.persistence.entity.ByteArrayEntity; import org.camunda.bpm.engine.impl.util.ClockUtil; -import org.camunda.bpm.engine.runtime.Job; import org.camunda.bpm.engine.test.ProcessEngineRule; import org.camunda.bpm.engine.test.api.resources.GetByteArrayCommand; import org.camunda.bpm.engine.test.bpmn.async.FailingExecutionListener; @@ -43,7 +37,6 @@ import org.camunda.bpm.model.bpmn.builder.CallActivityBuilder; import org.camunda.bpm.model.bpmn.builder.ProcessBuilder; import org.camunda.bpm.model.bpmn.builder.StartEventBuilder; -import org.junit.rules.TestWatcher; import org.junit.runner.Description; /** @@ -58,6 +51,7 @@ public BatchSetRemovalTimeRule(ProcessEngineRule engineRule, ProcessEngineTestRu super(engineRule, engineTestRule); } + @Override protected void starting(Description description) { getProcessEngineConfiguration() .setHistoryRemovalTimeProvider(new DefaultHistoryRemovalTimeProvider()) @@ -76,6 +70,7 @@ protected void starting(Description description) { super.starting(description); } + @Override protected void finished(Description description) { super.finished(description); @@ -106,6 +101,7 @@ protected void finished(Description description) { getProcessEngineConfiguration().setAuthorizationEnabled(false); } + @Override public void clearDatabase() { super.clearDatabase(); clearAuthorization(); diff --git a/engine/src/test/java/org/camunda/bpm/engine/test/util/BatchRule.java b/engine/src/test/java/org/camunda/bpm/engine/test/util/BatchRule.java index 1e38e0ed3f4..13c8122793b 100644 --- a/engine/src/test/java/org/camunda/bpm/engine/test/util/BatchRule.java +++ b/engine/src/test/java/org/camunda/bpm/engine/test/util/BatchRule.java @@ -16,6 +16,10 @@ */ package org.camunda.bpm.engine.test.util; +import static org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl.DEFAULT_INVOCATIONS_PER_BATCH_JOB; + +import java.util.ArrayList; +import java.util.List; import org.camunda.bpm.engine.batch.Batch; import org.camunda.bpm.engine.batch.history.HistoricBatch; import org.camunda.bpm.engine.impl.util.ClockUtil; @@ -24,11 +28,6 @@ import org.junit.rules.TestWatcher; import org.junit.runner.Description; -import java.util.ArrayList; -import java.util.List; - -import static org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl.DEFAULT_INVOCATIONS_PER_BATCH_JOB; - public class BatchRule extends TestWatcher { protected ProcessEngineRule engineRule; @@ -39,6 +38,7 @@ public BatchRule(ProcessEngineRule engineRule, ProcessEngineTestRule engineTestR this.engineTestRule = engineTestRule; } + @Override protected void finished(Description description) { engineRule.getProcessEngineConfiguration() .setInvocationsPerBatchJob(DEFAULT_INVOCATIONS_PER_BATCH_JOB); @@ -54,10 +54,16 @@ public void clearDatabase() { HistoricBatch historicBatch = engineRule.getHistoryService().createHistoricBatchQuery() .batchId(batchId) .singleResult(); - if (historicBatch != null) { engineRule.getHistoryService().deleteHistoricBatch(historicBatch.getId()); } + + Batch batch = engineRule.getManagementService().createBatchQuery() + .batchId(batchId) + .singleResult(); + if (batch != null) { + engineRule.getManagementService().deleteBatch(batchId, true); + } } } } @@ -74,8 +80,11 @@ public void syncExec(Batch batch, boolean isClear) { executeSeedJobs(batch); List jobs = getExecutionJobs(batch); - for (Job job : jobs) { - engineRule.getManagementService().executeJob(job.getId()); + while (!jobs.isEmpty()) { + for (Job job : jobs) { + engineRule.getManagementService().executeJob(job.getId()); + } + jobs = getExecutionJobs(batch); } engineRule.getManagementService().executeJob( @@ -83,6 +92,13 @@ public void syncExec(Batch batch, boolean isClear) { } public void executeSeedJobs(Batch batch) { + executeSeedJobs(batch, false); + } + + public void executeSeedJobs(Batch batch, boolean cleanUp) { + if (cleanUp) { + batchIds.add(batch.getId()); + } while (getSeedJob(batch) != null) { engineRule.getManagementService().executeJob(getSeedJob(batch).getId()); } diff --git a/qa/test-db-instance-migration/test-fixture-719/src/main/java/org/camunda/bpm/qa/upgrade/TestFixture.java b/qa/test-db-instance-migration/test-fixture-719/src/main/java/org/camunda/bpm/qa/upgrade/TestFixture.java index 78a1ba230db..e6c29e833b5 100644 --- a/qa/test-db-instance-migration/test-fixture-719/src/main/java/org/camunda/bpm/qa/upgrade/TestFixture.java +++ b/qa/test-db-instance-migration/test-fixture-719/src/main/java/org/camunda/bpm/qa/upgrade/TestFixture.java @@ -19,6 +19,7 @@ import org.camunda.bpm.engine.ProcessEngine; import org.camunda.bpm.engine.ProcessEngineConfiguration; import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl; +import org.camunda.bpm.qa.upgrade.batch.SetRemovalTimeToProcessInstanceScenario; import org.camunda.bpm.qa.upgrade.httl.EnforceHistoryTimeToLiveScenario; import org.camunda.bpm.qa.upgrade.variables.JpaVariableScenario; @@ -40,6 +41,7 @@ public static void main(String... args) { // example scenario setup runner.setupScenarios(JpaVariableScenario.class); runner.setupScenarios(EnforceHistoryTimeToLiveScenario.class); + runner.setupScenarios(SetRemovalTimeToProcessInstanceScenario.class); processEngine.close(); } diff --git a/qa/test-db-instance-migration/test-fixture-719/src/main/java/org/camunda/bpm/qa/upgrade/batch/SetRemovalTimeToProcessInstanceScenario.java b/qa/test-db-instance-migration/test-fixture-719/src/main/java/org/camunda/bpm/qa/upgrade/batch/SetRemovalTimeToProcessInstanceScenario.java new file mode 100644 index 00000000000..f6dcd5246cc --- /dev/null +++ b/qa/test-db-instance-migration/test-fixture-719/src/main/java/org/camunda/bpm/qa/upgrade/batch/SetRemovalTimeToProcessInstanceScenario.java @@ -0,0 +1,58 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; 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.camunda.bpm.qa.upgrade.batch; + +import java.util.Date; +import org.camunda.bpm.engine.HistoryService; +import org.camunda.bpm.engine.ManagementService; +import org.camunda.bpm.engine.RepositoryService; +import org.camunda.bpm.engine.RuntimeService; +import org.camunda.bpm.engine.batch.Batch; +import org.camunda.bpm.engine.repository.ProcessDefinition; +import org.camunda.bpm.engine.test.Deployment; +import org.camunda.bpm.qa.upgrade.DescribesScenario; +import org.camunda.bpm.qa.upgrade.ScenarioSetup; + +public class SetRemovalTimeToProcessInstanceScenario { + + @Deployment + public static String deployOneTask() { + return "org/camunda/bpm/qa/upgrade/batch/SetRemovalTimeToProcessInstanceScenario.oneTaskProcess.bpmn20.xml"; + } + + @DescribesScenario("createSetRetriesBatch") + public static ScenarioSetup createSetRemovalTimeBatch() { + return (engine, scenarioName) -> { + // services + RuntimeService runtimeService = engine.getRuntimeService(); + HistoryService historyService = engine.getHistoryService(); + RepositoryService repositoryService = engine.getRepositoryService(); + ManagementService managementService = engine.getManagementService(); + + // definition + ProcessDefinition definition = repositoryService.createProcessDefinitionQuery() + .processDefinitionKey("createProcessForSetRemovalTimeBatch_719").singleResult(); + + // create set removal time batch + Date removalTime = new Date(1363609000000L); + String processInstanceId = runtimeService.startProcessInstanceByKey(definition.getKey()).getId(); + Batch batch = historyService.setRemovalTimeToHistoricProcessInstances().absoluteRemovalTime(removalTime).byIds(processInstanceId).executeAsync(); + managementService.setProperty("SetRemovalTimeToProcessInstanceTest.batchId", batch.getId()); + managementService.setProperty("SetRemovalTimeToProcessInstanceTest.processInstanceId", processInstanceId); + }; + } +} diff --git a/qa/test-db-instance-migration/test-fixture-719/src/main/resources/org/camunda/bpm/qa/upgrade/batch/SetRemovalTimeToProcessInstanceScenario.oneTaskProcess.bpmn20.xml b/qa/test-db-instance-migration/test-fixture-719/src/main/resources/org/camunda/bpm/qa/upgrade/batch/SetRemovalTimeToProcessInstanceScenario.oneTaskProcess.bpmn20.xml new file mode 100644 index 00000000000..35d4898b1b9 --- /dev/null +++ b/qa/test-db-instance-migration/test-fixture-719/src/main/resources/org/camunda/bpm/qa/upgrade/batch/SetRemovalTimeToProcessInstanceScenario.oneTaskProcess.bpmn20.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + PT4H + + + + + + + \ No newline at end of file diff --git a/qa/test-db-instance-migration/test-migration/src/test/java/org/camunda/bpm/qa/upgrade/scenarios7200/batch/SetRemovalTimeToProcessInstanceTest.java b/qa/test-db-instance-migration/test-migration/src/test/java/org/camunda/bpm/qa/upgrade/scenarios7200/batch/SetRemovalTimeToProcessInstanceTest.java new file mode 100644 index 00000000000..489199527b3 --- /dev/null +++ b/qa/test-db-instance-migration/test-migration/src/test/java/org/camunda/bpm/qa/upgrade/scenarios7200/batch/SetRemovalTimeToProcessInstanceTest.java @@ -0,0 +1,90 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; 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.camunda.bpm.qa.upgrade.scenarios7200.batch; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Date; +import java.util.List; +import java.util.Map; +import org.camunda.bpm.engine.HistoryService; +import org.camunda.bpm.engine.ManagementService; +import org.camunda.bpm.engine.RuntimeService; +import org.camunda.bpm.engine.batch.Batch; +import org.camunda.bpm.engine.history.HistoricActivityInstance; +import org.camunda.bpm.engine.runtime.Job; +import org.camunda.bpm.qa.upgrade.Origin; +import org.camunda.bpm.qa.upgrade.ScenarioUnderTest; +import org.camunda.bpm.qa.upgrade.UpgradeTestRule; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ScenarioUnderTest("SetRemovalTimeToProcessInstanceScenario") +@Origin("7.19.0") +public class SetRemovalTimeToProcessInstanceTest { + + Logger LOG = LoggerFactory.getLogger(SetRemovalTimeToProcessInstanceTest.class); + + @Rule + public UpgradeTestRule engineRule = new UpgradeTestRule(); + + HistoryService historyService; + ManagementService managementService; + RuntimeService runtimeService; + + @Before + public void assignServices() { + historyService = engineRule.getHistoryService(); + managementService = engineRule.getManagementService(); + runtimeService = engineRule.getRuntimeService(); + } + + @Test + @ScenarioUnderTest("runBatchJob.1") + public void shouldRunBatchJobOnce() { + // given + Map properties = managementService.getProperties(); + String batchId = properties.get("SetRemovalTimeToProcessInstanceTest.batchId"); + String processInstanceId = properties.get("SetRemovalTimeToProcessInstanceTest.processInstanceId"); + Date removalTime = new Date(1363609000000L); + + Batch batch = managementService.createBatchQuery().batchId(batchId).singleResult(); + String seedJobDefinitionId = batch.getSeedJobDefinitionId(); + Job seedJob = managementService.createJobQuery().jobDefinitionId(seedJobDefinitionId).singleResult(); + + managementService.executeJob(seedJob.getId()); + List batchJobs = managementService.createJobQuery() + .jobDefinitionId(batch.getBatchJobDefinitionId()) + .list(); + + // when + batchJobs.forEach(job -> managementService.executeJob(job.getId())); + + // then + HistoricActivityInstance historicActivityInstance = historyService.createHistoricActivityInstanceQuery() + .activityId("userTask") + .processInstanceId(processInstanceId) + .singleResult(); + assertThat(historicActivityInstance.getRemovalTime()).isEqualTo(removalTime); + + assertThat(managementService.createJobQuery().jobDefinitionId(batch.getBatchJobDefinitionId()).count()).isEqualTo(0); + } + +} diff --git a/qa/test-db-instance-migration/test-migration/src/test/java/org/camunda/bpm/qa/upgrade/scenarios7190/variables/JPAVariableTest.java b/qa/test-db-instance-migration/test-migration/src/test/java/org/camunda/bpm/qa/upgrade/scenarios7200/variables/JPAVariableTest.java similarity index 97% rename from qa/test-db-instance-migration/test-migration/src/test/java/org/camunda/bpm/qa/upgrade/scenarios7190/variables/JPAVariableTest.java rename to qa/test-db-instance-migration/test-migration/src/test/java/org/camunda/bpm/qa/upgrade/scenarios7200/variables/JPAVariableTest.java index cc460e9a907..dd05f72f0c5 100644 --- a/qa/test-db-instance-migration/test-migration/src/test/java/org/camunda/bpm/qa/upgrade/scenarios7190/variables/JPAVariableTest.java +++ b/qa/test-db-instance-migration/test-migration/src/test/java/org/camunda/bpm/qa/upgrade/scenarios7200/variables/JPAVariableTest.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.camunda.bpm.qa.upgrade.scenarios7190.variables; +package org.camunda.bpm.qa.upgrade.scenarios7200.variables; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; diff --git a/qa/test-db-rolling-update/rolling-update-util/src/main/java/org/camunda/bpm/qa/rolling/update/TestFixture.java b/qa/test-db-rolling-update/rolling-update-util/src/main/java/org/camunda/bpm/qa/rolling/update/TestFixture.java index bb34b3e6a32..83521ddc060 100644 --- a/qa/test-db-rolling-update/rolling-update-util/src/main/java/org/camunda/bpm/qa/rolling/update/TestFixture.java +++ b/qa/test-db-rolling-update/rolling-update-util/src/main/java/org/camunda/bpm/qa/rolling/update/TestFixture.java @@ -22,6 +22,7 @@ import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl; import org.camunda.bpm.qa.rolling.update.scenarios.DeploymentWhichShouldBeDeletedScenario; import org.camunda.bpm.qa.rolling.update.scenarios.authorization.AuthorizationScenario; +import org.camunda.bpm.qa.rolling.update.scenarios.batch.SetRemovalTimeToProcessInstanceScenario; import org.camunda.bpm.qa.rolling.update.scenarios.callactivity.ProcessWithCallActivityScenario; import org.camunda.bpm.qa.rolling.update.scenarios.cleanup.HistoryCleanupScenario; import org.camunda.bpm.qa.rolling.update.scenarios.eventSubProcess.ProcessWithEventSubProcessScenario; @@ -82,6 +83,7 @@ public static void main(String[] args) { if (RollingUpdateConstants.NEW_ENGINE_TAG.equals(currentFixtureTag)) { // create data with new engine runner.setupScenarios(HistoryCleanupScenario.class); runner.setupScenarios(EmptyStringVariableScenario.class); + runner.setupScenarios(SetRemovalTimeToProcessInstanceScenario.class); } processEngine.close(); diff --git a/qa/test-db-rolling-update/rolling-update-util/src/main/java/org/camunda/bpm/qa/rolling/update/scenarios/batch/SetRemovalTimeToProcessInstanceScenario.java b/qa/test-db-rolling-update/rolling-update-util/src/main/java/org/camunda/bpm/qa/rolling/update/scenarios/batch/SetRemovalTimeToProcessInstanceScenario.java new file mode 100644 index 00000000000..5b5e6e89128 --- /dev/null +++ b/qa/test-db-rolling-update/rolling-update-util/src/main/java/org/camunda/bpm/qa/rolling/update/scenarios/batch/SetRemovalTimeToProcessInstanceScenario.java @@ -0,0 +1,69 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; 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.camunda.bpm.qa.rolling.update.scenarios.batch; + +import java.util.Date; +import org.camunda.bpm.engine.ProcessEngine; +import org.camunda.bpm.engine.batch.Batch; +import org.camunda.bpm.engine.runtime.Job; +import org.camunda.bpm.engine.test.Deployment; +import org.camunda.bpm.qa.upgrade.DescribesScenario; +import org.camunda.bpm.qa.upgrade.ScenarioSetup; +import org.camunda.bpm.qa.upgrade.Times; + +public class SetRemovalTimeToProcessInstanceScenario { + + public static final String PROCESS_DEF_KEY = "oneTaskProcess"; + + @Deployment + public static String deploy() { + return "org/camunda/bpm/qa/rolling/update/oneTaskProcess.bpmn20.xml"; + } + + @DescribesScenario("createSetRemovalTimeToProcessInstanceBatch") + @Times(1) + public static ScenarioSetup createBatch() { + return new ScenarioSetup() { + @Override + public void execute(ProcessEngine engine, String scenarioName) { + Date removalTime = new Date(1363609000000L); + String processInstanceId = engine.getRuntimeService().startProcessInstanceByKey(PROCESS_DEF_KEY, "SetRemovalTimeToProcessInstance.batch").getId(); + Batch batch = engine.getHistoryService().setRemovalTimeToHistoricProcessInstances().absoluteRemovalTime(removalTime).byIds(processInstanceId).executeAsync(); + engine.getManagementService().setProperty("SetRemovalTimeToProcessInstance.batch.batchId", batch.getId()); + } + }; + } + + @DescribesScenario("createSetRemovalTimeToProcessInstanceBatchJob") + @Times(1) + public static ScenarioSetup createBatchJob() { + return new ScenarioSetup() { + @Override + public void execute(ProcessEngine engine, String scenarioName) { + Date removalTime = new Date(1363609000000L); + String processInstanceId = engine.getRuntimeService().startProcessInstanceByKey(PROCESS_DEF_KEY, "SetRemovalTimeToProcessInstance.batchJob").getId(); + Batch batch = engine.getHistoryService().setRemovalTimeToHistoricProcessInstances().absoluteRemovalTime(removalTime).byIds(processInstanceId).executeAsync(); + String seedJobDefinitionId = batch.getSeedJobDefinitionId(); + Job seedJob = engine.getManagementService().createJobQuery().jobDefinitionId(seedJobDefinitionId).singleResult(); + + engine.getManagementService().executeJob(seedJob.getId()); + engine.getManagementService().setProperty("SetRemovalTimeToProcessInstance.batchJob.batchId", batch.getId()); + } + }; + } + +} diff --git a/qa/test-db-rolling-update/test-old-engine/src/test/java/org/camunda/bpm/qa/rolling/update/batch/SetRemovalTimeToProcessInstanceTest.java b/qa/test-db-rolling-update/test-old-engine/src/test/java/org/camunda/bpm/qa/rolling/update/batch/SetRemovalTimeToProcessInstanceTest.java new file mode 100644 index 00000000000..701092f7fd9 --- /dev/null +++ b/qa/test-db-rolling-update/test-old-engine/src/test/java/org/camunda/bpm/qa/rolling/update/batch/SetRemovalTimeToProcessInstanceTest.java @@ -0,0 +1,104 @@ +/* + * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH + * under one or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information regarding copyright + * ownership. Camunda licenses this file to you under the Apache License, + * Version 2.0; 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.camunda.bpm.qa.rolling.update.batch; + +import static org.junit.Assert.assertEquals; + +import java.util.Date; +import java.util.List; +import org.camunda.bpm.engine.ManagementService; +import org.camunda.bpm.engine.RuntimeService; +import org.camunda.bpm.engine.batch.Batch; +import org.camunda.bpm.engine.history.HistoricActivityInstance; +import org.camunda.bpm.engine.runtime.Job; +import org.camunda.bpm.qa.rolling.update.AbstractRollingUpdateTestCase; +import org.camunda.bpm.qa.rolling.update.RollingUpdateConstants; +import org.camunda.bpm.qa.upgrade.ScenarioUnderTest; +import org.junit.Before; +import org.junit.Test; + +@ScenarioUnderTest("SetRemovalTimeToProcessInstanceScenario") +public class SetRemovalTimeToProcessInstanceTest extends AbstractRollingUpdateTestCase { + + protected ManagementService managementService; + protected RuntimeService runtimeService; + + @Before + public void setUp() { + managementService = rule.getManagementService(); + runtimeService = rule.getRuntimeService(); + } + + @Test + @ScenarioUnderTest("createSetRemovalTimeToProcessInstanceBatch.1") + public void shouldCompleteBatch() { + if (RollingUpdateConstants.OLD_ENGINE_TAG.equals(rule.getTag())) { // test cleanup with old engine + Date removalTime = new Date(1363609000000L); + + String processInstanceId = runtimeService.createProcessInstanceQuery().processInstanceBusinessKey("SetRemovalTimeToProcessInstance.batch").singleResult().getId(); + String batchId = managementService.getProperties().get("SetRemovalTimeToProcessInstance.batch.batchId"); + Batch batch = managementService.createBatchQuery().batchId(batchId).singleResult(); + String seedJobDefinitionId = batch.getSeedJobDefinitionId(); + Job seedJob = managementService.createJobQuery().jobDefinitionId(seedJobDefinitionId).singleResult(); + + managementService.executeJob(seedJob.getId()); + List batchJobs = managementService.createJobQuery() + .jobDefinitionId(batch.getBatchJobDefinitionId()) + .list(); + + // when + batchJobs.forEach(job -> managementService.executeJob(job.getId())); + + // then + HistoricActivityInstance historicActivityInstance = rule.getHistoryService().createHistoricActivityInstanceQuery() + .activityId("theTask") + .processInstanceId(processInstanceId) + .singleResult(); + assertEquals(removalTime, historicActivityInstance.getRemovalTime()); + + assertEquals(0, managementService.createJobQuery().jobDefinitionId(batch.getBatchJobDefinitionId()).count()); + } + } + + @Test + @ScenarioUnderTest("createSetRemovalTimeToProcessInstanceBatchJob.1") + public void testCompleteBatchKJob() { + if (RollingUpdateConstants.OLD_ENGINE_TAG.equals(rule.getTag())) { // test cleanup with old engine + Date removalTime = new Date(1363609000000L); + + String processInstanceId = runtimeService.createProcessInstanceQuery().processInstanceBusinessKey("SetRemovalTimeToProcessInstance.batchJob").singleResult().getId(); + String batchId = managementService.getProperties().get("SetRemovalTimeToProcessInstance.batchJob.batchId"); + Batch batch = managementService.createBatchQuery().batchId(batchId).singleResult(); + List batchJobs = managementService.createJobQuery() + .jobDefinitionId(batch.getBatchJobDefinitionId()) + .list(); + + // when + batchJobs.forEach(job -> managementService.executeJob(job.getId())); + + // then + HistoricActivityInstance historicActivityInstance = rule.getHistoryService().createHistoricActivityInstanceQuery() + .activityId("theTask") + .processInstanceId(processInstanceId) + .singleResult(); + assertEquals(removalTime, historicActivityInstance.getRemovalTime()); + + assertEquals(0, managementService.createJobQuery().jobDefinitionId(batch.getBatchJobDefinitionId()).count()); + } + } + +}