|
14 | 14 |
|
15 | 15 | import static org.assertj.core.api.Assertions.assertThat; |
16 | 16 |
|
| 17 | +import java.util.Date; |
17 | 18 | import java.util.concurrent.atomic.AtomicInteger; |
| 19 | +import java.util.concurrent.atomic.AtomicReference; |
18 | 20 |
|
19 | 21 | import org.flowable.common.engine.impl.cfg.TransactionContext; |
20 | 22 | import org.flowable.common.engine.impl.interceptor.CommandContext; |
21 | 23 | import org.flowable.engine.impl.context.Context; |
| 24 | +import org.flowable.engine.impl.persistence.entity.ExecutionEntity; |
22 | 25 | import org.flowable.engine.impl.test.JobTestHelper; |
23 | 26 | import org.flowable.engine.impl.test.PluggableFlowableTestCase; |
24 | 27 | import org.flowable.engine.impl.util.CommandContextUtil; |
| 28 | +import org.flowable.engine.runtime.ProcessInstance; |
| 29 | +import org.flowable.engine.test.Deployment; |
25 | 30 | import org.flowable.job.api.Job; |
26 | 31 | import org.flowable.job.service.JobService; |
27 | 32 | import org.flowable.job.service.impl.nontx.NonTransactionalJobHandler; |
28 | 33 | import org.flowable.job.service.impl.persistence.entity.JobEntity; |
| 34 | +import org.flowable.task.api.Task; |
29 | 35 | import org.junit.jupiter.api.AfterEach; |
30 | 36 | import org.junit.jupiter.api.BeforeEach; |
31 | 37 | import org.junit.jupiter.api.Test; |
@@ -83,6 +89,54 @@ public void testJobExecutedWithoutTransaction() { |
83 | 89 | assertThat(nonTransactionalTestJobHandler.nonTransactionalCounter).hasValue(1); |
84 | 90 | } |
85 | 91 |
|
| 92 | + @Test |
| 93 | + @Deployment(resources = "org/flowable/engine/test/api/oneTaskProcess.bpmn20.xml") |
| 94 | + public void testAsyncExclusiveJob() { |
| 95 | + ProcessInstance processInstance = runtimeService.createProcessInstanceBuilder() |
| 96 | + .processDefinitionKey("oneTaskProcess") |
| 97 | + .start(); |
| 98 | + Task task = taskService.createTaskQuery() |
| 99 | + .processInstanceId(processInstance.getId()) |
| 100 | + .singleResult(); |
| 101 | + managementService.executeCommand(commandContext -> { |
| 102 | + JobService jobService = CommandContextUtil.getJobService(); |
| 103 | + JobEntity job = jobService.createJob(); |
| 104 | + job.setProcessInstanceId(processInstance.getId()); |
| 105 | + job.setExecutionId(task.getExecutionId()); |
| 106 | + job.setJobHandlerType(nonTransactionalTestJobHandler.getType()); |
| 107 | + job.setJobHandlerConfiguration("myTest"); |
| 108 | + jobService.createAsyncJob(job, true); |
| 109 | + jobService.scheduleAsyncJob(job); |
| 110 | + return null; |
| 111 | + }); |
| 112 | + |
| 113 | + AtomicReference<String> processLockOwner = new AtomicReference<>(); |
| 114 | + AtomicReference<Date> processLockTime = new AtomicReference<>(); |
| 115 | + nonTransactionalTestJobHandler.nonTransactionalRunnable = () -> { |
| 116 | + ExecutionEntity executionEntity = (ExecutionEntity) runtimeService.createProcessInstanceQuery() |
| 117 | + .processInstanceId(processInstance.getId()) |
| 118 | + .singleResult(); |
| 119 | + processLockOwner.set(executionEntity.getLockOwner()); |
| 120 | + processLockTime.set(executionEntity.getLockTime()); |
| 121 | + }; |
| 122 | + |
| 123 | + JobTestHelper.waitForJobExecutorOnCondition(processEngineConfiguration, 10000L, 20L, |
| 124 | + () -> managementService.createJobQuery().count() == 0); |
| 125 | + |
| 126 | + assertThat(processLockOwner).hasValue(processEngineConfiguration.getAsyncExecutor().getLockOwner()); |
| 127 | + assertThat(processLockTime).doesNotHaveNullValue(); |
| 128 | + |
| 129 | + managementService.executeCommand(commandContext -> { |
| 130 | + ExecutionEntity executionEntity = (ExecutionEntity) runtimeService.createProcessInstanceQuery() |
| 131 | + .processInstanceId(processInstance.getId()) |
| 132 | + .singleResult(); |
| 133 | + |
| 134 | + assertThat(executionEntity.getLockOwner()).isNull(); |
| 135 | + assertThat(executionEntity.getLockTime()).isNull(); |
| 136 | + return null; |
| 137 | + }); |
| 138 | + } |
| 139 | + |
86 | 140 | @Test |
87 | 141 | public void testJobExecutedWithoutTransactionThrowsException() { |
88 | 142 | managementService.executeCommand(commandContext -> { |
@@ -125,6 +179,8 @@ public static class NonTransactionalTestJobHandler implements NonTransactionalJo |
125 | 179 | protected AtomicInteger withoutTransactionCounter = new AtomicInteger(0); |
126 | 180 | protected AtomicInteger nonTransactionalCounter = new AtomicInteger(0); |
127 | 181 |
|
| 182 | + protected Runnable nonTransactionalRunnable; |
| 183 | + |
128 | 184 | protected String jobConfiguration; |
129 | 185 | protected String nonTransactionalOutput; |
130 | 186 |
|
@@ -154,6 +210,9 @@ public String executeNonTransactionally(JobEntity job, String configuration) { |
154 | 210 | } |
155 | 211 |
|
156 | 212 | this.jobConfiguration = job.getJobHandlerConfiguration(); |
| 213 | + if (nonTransactionalRunnable != null) { |
| 214 | + nonTransactionalRunnable.run(); |
| 215 | + } |
157 | 216 | return jobConfiguration; |
158 | 217 |
|
159 | 218 | } |
@@ -189,6 +248,7 @@ public String getJobConfiguration() { |
189 | 248 | } |
190 | 249 |
|
191 | 250 | public void reset() { |
| 251 | + this.nonTransactionalRunnable = null; |
192 | 252 | this.counter.set(0); |
193 | 253 | this.withCommandContext.set(0); |
194 | 254 | this.withoutCommandContext.set(0); |
|
0 commit comments