diff --git a/bom/datapool-dependencies/pom.xml b/bom/datapool-dependencies/pom.xml
index 575eea33c..c1ba60a5a 100644
--- a/bom/datapool-dependencies/pom.xml
+++ b/bom/datapool-dependencies/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-parent
- 3.10.0
+ 3.11.0
../parent/pom.xml
diff --git a/bom/parent/pom.xml b/bom/parent/pom.xml
index fa47fa2ec..57bcfb24c 100644
--- a/bom/parent/pom.xml
+++ b/bom/parent/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-root
- 3.10.0
+ 3.11.0
../../pom.xml
@@ -18,7 +18,7 @@
https://github.com/holunda-io/camunda-bpm-taskpool/
- 2.7.10
+ 2.7.11
7.18.0
4.6.6
@@ -306,7 +306,7 @@
org.jacoco
jacoco-maven-plugin
- 0.8.9
+ 0.8.10
pre-unit-test
diff --git a/bom/taskpool-dependencies/pom.xml b/bom/taskpool-dependencies/pom.xml
index 510e10b40..d3fcda32b 100644
--- a/bom/taskpool-dependencies/pom.xml
+++ b/bom/taskpool-dependencies/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-parent
- 3.10.0
+ 3.11.0
../parent/pom.xml
diff --git a/core/bus-jackson/pom.xml b/core/bus-jackson/pom.xml
index 14804e34a..89b778c9c 100755
--- a/core/bus-jackson/pom.xml
+++ b/core/bus-jackson/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-parent
- 3.10.0
+ 3.11.0
../../bom/parent/pom.xml
diff --git a/core/datapool/datapool-api/pom.xml b/core/datapool/datapool-api/pom.xml
index fe8de1bf8..6249d1d95 100755
--- a/core/datapool/datapool-api/pom.xml
+++ b/core/datapool/datapool-api/pom.xml
@@ -5,7 +5,7 @@
io.holunda.polyflow
polyflow-datapool-parent
- 3.10.0
+ 3.11.0
polyflow-datapool-api
diff --git a/core/datapool/datapool-core/pom.xml b/core/datapool/datapool-core/pom.xml
index 6fa36ea98..fb4d96fbe 100644
--- a/core/datapool/datapool-core/pom.xml
+++ b/core/datapool/datapool-core/pom.xml
@@ -5,7 +5,7 @@
io.holunda.polyflow
polyflow-datapool-parent
- 3.10.0
+ 3.11.0
polyflow-datapool-core
diff --git a/core/datapool/datapool-event/pom.xml b/core/datapool/datapool-event/pom.xml
index b515de624..28694e943 100755
--- a/core/datapool/datapool-event/pom.xml
+++ b/core/datapool/datapool-event/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-datapool-parent
- 3.10.0
+ 3.11.0
polyflow-datapool-event
diff --git a/core/datapool/pom.xml b/core/datapool/pom.xml
index 6da49f0e0..4c2952aa1 100755
--- a/core/datapool/pom.xml
+++ b/core/datapool/pom.xml
@@ -5,7 +5,7 @@
io.holunda.polyflow
polyflow-parent
- 3.10.0
+ 3.11.0
../../bom/parent/pom.xml
diff --git a/core/taskpool/pom.xml b/core/taskpool/pom.xml
index 03cd53162..6e98e9ab9 100755
--- a/core/taskpool/pom.xml
+++ b/core/taskpool/pom.xml
@@ -5,7 +5,7 @@
io.holunda.polyflow
polyflow-parent
- 3.10.0
+ 3.11.0
../../bom/parent/pom.xml
diff --git a/core/taskpool/taskpool-api/pom.xml b/core/taskpool/taskpool-api/pom.xml
index c53613086..606a1b419 100755
--- a/core/taskpool/taskpool-api/pom.xml
+++ b/core/taskpool/taskpool-api/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-taskpool-parent
- 3.10.0
+ 3.11.0
polyflow-taskpool-api
diff --git a/core/taskpool/taskpool-core/pom.xml b/core/taskpool/taskpool-core/pom.xml
index 301875e58..e4967e766 100755
--- a/core/taskpool/taskpool-core/pom.xml
+++ b/core/taskpool/taskpool-core/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-taskpool-parent
- 3.10.0
+ 3.11.0
polyflow-taskpool-core
diff --git a/core/taskpool/taskpool-event/pom.xml b/core/taskpool/taskpool-event/pom.xml
index ec871c1e2..2cb5b179f 100644
--- a/core/taskpool/taskpool-event/pom.xml
+++ b/core/taskpool/taskpool-event/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-taskpool-parent
- 3.10.0
+ 3.11.0
polyflow-taskpool-event
diff --git a/docs/reference-guide/components/camunda-taskpool-collector.md b/docs/reference-guide/components/camunda-taskpool-collector.md
index dc1224a9e..1923afb12 100644
--- a/docs/reference-guide/components/camunda-taskpool-collector.md
+++ b/docs/reference-guide/components/camunda-taskpool-collector.md
@@ -15,7 +15,7 @@ received from Camunda BPM Engine (from delegate event listener or from history e
which is passed over to the Taskpool Collector using internal **Spring eventing** mechanism. The Taskpool
Collector converts the series of such events into a Taskpool Command - an entity carrying an intent
of change inside the Taskpool core. Please note that _event_ has another meaning in CQRS/ES systems
-and other components of the Taskpool, but in the context of Taskpool collector an event always originates from
+and other components of the Taskpool, but in the context of Taskpool Collector an event always originates from
Spring eventing.
### Features
@@ -25,6 +25,7 @@ Spring eventing.
- Collection of process variable change events
- Collection of task events and history events
- Creation of task engine commands
+- Collection of tasks assignment information
- Enrichment of task engine commands with process variables
- Attachment of correlation information to task engine commands
- Transmission of commands to Axon command bus
@@ -55,7 +56,7 @@ In order to enable collector component, include the Maven dependency to your pro
```
-Then activate the Taskpool collector by providing the annotation on any Spring Configuration:
+Then activate the Taskpool Collector by providing the annotation on any Spring Configuration:
```java
@Configuration
@@ -68,7 +69,7 @@ class MyProcessApplicationConfiguration {
### Event collection
-Taskpool Collector registers Spring Event Listener to the following events, fired by Camunda Eventing Engine Plugin:
+By default, Taskpool Collector registers Spring Event Listener to the following events, fired by Camunda Eventing Engine Plugin:
* `DelegateTask` events:
** create
@@ -86,6 +87,22 @@ The events are transformed into corresponding commands and passed over to the pr
is fired using custom listeners only and polyflow components don't rely on that but rather on own implementation of built-in (unskippable) listeners.
For this purpose, it is important to disable Camunda Platform custom listeners by setting `camunda.bpm.eventing.task` property to `false`.
+During collection of task information, you can control which listeners are registered. By default, all listeners are considered but you can change
+this behaviour by setting values of two properties:
+
+```yaml
+
+polyflow:
+ integration:
+ collector:
+ camunda:
+ task:
+ excludedTaskEventNames: assignment, delete
+ excludedHistoryEventNames: add-identity-link, delete-identity-link
+```
+This particular setting is helpful, if you want to disable assignment in the engine entirely and want to provide you own custom task assignment algorithm or
+use assignment based on process variables (see below for more details).
+
### Task commands enrichment
Alongside with attributes received from the Camunda BPM engine, the engine task commands
@@ -126,7 +143,7 @@ A `VariableFilter` can be of the following type:
Here is an example, how the process variable filter can configure the enrichment:
```java
- @Configuration
+@Configuration
public class MyTaskCollectorConfiguration {
@Bean
@@ -168,6 +185,12 @@ public class MyTaskCollectorConfiguration {
If you want to implement a custom enrichment, please provide your own implementation of the interface `VariablesEnricher`
(register a Spring Component of the type) and set the property `polyflow.integration.collector.camunda.task.enricher.type` to `custom`.
+!!! warning
+ Avoid using a classic Camunda `TaskListener` which modifies process variables on task creation, since changes of those
+ listeners can't be used during task enrichment. A proper way to modify instance or task variables is to implement an ordered Spring
+ `EventListener` listening on `DelegateTask`, put it before the enricher by providing `@Order(TaskEventCollectorService.ORDER - 80)` and scope the event listener to
+ the task of your interest using condition: `@EventListener(condition = "#delegateTask.taskDefinitionKey.equals('my-task-key') && #delegateTask.eventName.equals('create')")`
+
### Data Correlation
Apart from task payload attached by the enricher, the so-called _Correlation_ with data entries can
@@ -251,11 +274,11 @@ and the process reaches the task `task_approve_request`, the task will get the f
### Task Assignment
-User task assignment is a core functionality for every process application fostering task oriented work. By default, Taskpool Collector uses
+User task assignment is a core functionality for every process application fostering task-oriented work. By default, Taskpool Collector uses
information from Camunda User Task and maps that one-to-one to properties of the user task commands. The task attribute
`assignee`, `candidateUsers` and `candidateGroups` are mapped to the corresponding attributes automatically.
-To control the task assignment mode you can configure taskpool collector using application properties. The property
+To control the task assignment mode you can configure Taskpool Collector using application properties. The property
`polyflow.integration.collector.camunda.task.assigner.type` has the following values:
* `no`: No additional assignment takes place, the Camunda task attributes are used (default)
diff --git a/integration/camunda-bpm/engine-client/pom.xml b/integration/camunda-bpm/engine-client/pom.xml
index 434fde71d..0c25a9f1b 100644
--- a/integration/camunda-bpm/engine-client/pom.xml
+++ b/integration/camunda-bpm/engine-client/pom.xml
@@ -4,7 +4,7 @@
io.holunda.polyflow
polyflow-integration-camunda-bpm-engine-parent
- 3.10.0
+ 3.11.0
polyflow-camunda-bpm-engine-client
diff --git a/integration/camunda-bpm/pom.xml b/integration/camunda-bpm/pom.xml
index 5fd83dcc6..36609fc99 100644
--- a/integration/camunda-bpm/pom.xml
+++ b/integration/camunda-bpm/pom.xml
@@ -5,7 +5,7 @@
io.holunda.polyflow
polyflow-parent
- 3.10.0
+ 3.11.0
../../bom/parent/pom.xml
diff --git a/integration/camunda-bpm/springboot-autoconfigure/pom.xml b/integration/camunda-bpm/springboot-autoconfigure/pom.xml
index 540959ed4..63d44081e 100755
--- a/integration/camunda-bpm/springboot-autoconfigure/pom.xml
+++ b/integration/camunda-bpm/springboot-autoconfigure/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-integration-camunda-bpm-engine-parent
- 3.10.0
+ 3.11.0
polyflow-camunda-bpm-springboot-autoconfigure
diff --git a/integration/camunda-bpm/springboot-starter/pom.xml b/integration/camunda-bpm/springboot-starter/pom.xml
index e9af668f2..f6083f6e4 100755
--- a/integration/camunda-bpm/springboot-starter/pom.xml
+++ b/integration/camunda-bpm/springboot-starter/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-integration-camunda-bpm-engine-parent
- 3.10.0
+ 3.11.0
polyflow-camunda-bpm-springboot-starter
diff --git a/integration/camunda-bpm/taskpool-collector/pom.xml b/integration/camunda-bpm/taskpool-collector/pom.xml
index d75cfa45b..80dfc615b 100755
--- a/integration/camunda-bpm/taskpool-collector/pom.xml
+++ b/integration/camunda-bpm/taskpool-collector/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-integration-camunda-bpm-engine-parent
- 3.10.0
+ 3.11.0
polyflow-camunda-bpm-taskpool-collector
diff --git a/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/collector/CamundaTaskpoolCollectorProperties.kt b/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/collector/CamundaTaskpoolCollectorProperties.kt
index 8a930f719..c0a696ce7 100755
--- a/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/collector/CamundaTaskpoolCollectorProperties.kt
+++ b/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/collector/CamundaTaskpoolCollectorProperties.kt
@@ -1,6 +1,7 @@
package io.holunda.polyflow.taskpool.collector
import io.holunda.polyflow.taskpool.collector.task.assigner.ProcessVariableTaskAssignerMapping
+import org.camunda.bpm.engine.delegate.TaskListener
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.context.properties.ConstructorBinding
@@ -69,9 +70,33 @@ data class CamundaTaskCollectorProperties(
* Properties of task importer.
*/
@NestedConfigurationProperty
- val importer: TaskImporterProperties = TaskImporterProperties()
+ val importer: TaskImporterProperties = TaskImporterProperties(),
-)
+ /**
+ * List of task events to be excluded from collector. Defaults to empty list, so all events are collected.
+ * Possible values are constants defined in [TaskListener].
+ */
+ val excludedTaskEventNames: List = listOf(),
+
+ /**
+ * List of history events to restrict (HistoricTaskInstanceEventEntity, HistoricIdentityLinkLogEventEntity). Defaults to empty list, so all events are collected.
+ * Possible values are constants defined in [HistoryEventTypes] + "update".
+ */
+ val excludedHistoryEventNames: List = listOf()
+) {
+ /**
+ * Determines if the provided event name should be collected.
+ * @param eventName event name to check.
+ * @return true if not excluded.
+ */
+ fun collectTaskEvent(eventName: String): Boolean = !excludedTaskEventNames.contains(eventName)
+ /**
+ * Determines if the provided event name should be collected.
+ * @param eventName event name to check.
+ * @return true if not excluded.
+ */
+ fun collectHistoryEvent(eventName: String): Boolean = !excludedHistoryEventNames.contains(eventName)
+}
/**
* Process variable properties.
diff --git a/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/collector/task/TaskCollectorConfiguration.kt b/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/collector/task/TaskCollectorConfiguration.kt
index 5b4fc1342..9434e7272 100644
--- a/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/collector/task/TaskCollectorConfiguration.kt
+++ b/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/collector/task/TaskCollectorConfiguration.kt
@@ -114,7 +114,7 @@ class TaskCollectorConfiguration(
/**
* Constructs the task collector service responsible for collecting Camunda Spring events and building commands out of them.
*/
- @Bean
+ @Bean(TaskEventCollectorService.NAME)
fun taskEventCollectorService(repositoryService: RepositoryService) = TaskEventCollectorService(
camundaTaskpoolCollectorProperties = camundaTaskpoolCollectorProperties,
repositoryService = repositoryService
diff --git a/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/collector/task/TaskEventCollectorService.kt b/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/collector/task/TaskEventCollectorService.kt
index 5d08ccdc0..5a9b208f0 100755
--- a/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/collector/task/TaskEventCollectorService.kt
+++ b/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/collector/task/TaskEventCollectorService.kt
@@ -17,12 +17,13 @@ import org.springframework.core.annotation.Order
* Collects Camunda events and Camunda historic events (event listener order is {@link TaskEventCollectorService#ORDER}) and emits Commands
*/
class TaskEventCollectorService(
- private val camundaTaskpoolCollectorProperties: CamundaTaskpoolCollectorProperties,
+ val camundaTaskpoolCollectorProperties: CamundaTaskpoolCollectorProperties, // must not be private to access in conditions of event handlers
private val repositoryService: RepositoryService
) {
companion object : KLogging() {
+ const val NAME = "taskEventCollectorService"
// high order to be later than all other listeners and work on changed entity
const val ORDER = Integer.MAX_VALUE - 100
}
@@ -46,7 +47,7 @@ class TaskEventCollectorService(
* Fires create command.
*/
@Order(ORDER)
- @EventListener(condition = "#task.eventName.equals('create')")
+ @EventListener(condition = "#task.eventName.equals('create') && @taskEventCollectorService.camundaTaskpoolCollectorProperties.task.collectTaskEvent('create')")
fun create(task: DelegateTask): CreateTaskCommand =
CreateTaskCommand(
id = task.id,
@@ -70,7 +71,7 @@ class TaskEventCollectorService(
* Fires complete.
*/
@Order(ORDER)
- @EventListener(condition = "#task.eventName.equals('complete')")
+ @EventListener(condition = "#task.eventName.equals('complete') && @taskEventCollectorService.camundaTaskpoolCollectorProperties.task.collectTaskEvent('complete')")
fun complete(task: DelegateTask): CompleteTaskCommand =
CompleteTaskCommand(
id = task.id,
@@ -81,17 +82,18 @@ class TaskEventCollectorService(
* Fires assign command.
*/
@Order(ORDER)
- @EventListener(condition = "#task.eventName.equals('assignment')")
+ @EventListener(condition = "#task.eventName.equals('assignment') && @taskEventCollectorService.camundaTaskpoolCollectorProperties.task.collectTaskEvent('assignment')")
fun assign(task: DelegateTask) {
// this method is intentionally empty to demonstrate that the assign event is captured.
// we hence rely on historic identity link events to capture assignment via API and via listeners more accurately.
+ // see implementation below
}
/**
* Fires delete command.
*/
@Order(ORDER)
- @EventListener(condition = "#task.eventName.equals('delete')")
+ @EventListener(condition = "#task.eventName.equals('delete') && @taskEventCollectorService.camundaTaskpoolCollectorProperties.task.collectTaskEvent('delete')")
fun delete(task: DelegateTask): DeleteTaskCommand =
DeleteTaskCommand(
id = task.id,
@@ -103,7 +105,7 @@ class TaskEventCollectorService(
* Fires update command.
*/
@Order(ORDER)
- @EventListener(condition = "#task.eventName.equals('update')")
+ @EventListener(condition = "#task.eventName.equals('update') && @taskEventCollectorService.camundaTaskpoolCollectorProperties.task.collectTaskEvent('update')")
fun update(task: DelegateTask): UpdateAttributeTaskCommand? =
if (task is TaskEntity) {
if (task.isAssigneeChange()) {
@@ -122,10 +124,9 @@ class TaskEventCollectorService(
* into the original intent.
*/
@Order(ORDER)
- @EventListener
- fun update(changeEvent: HistoricTaskInstanceEventEntity): UpdateAttributesHistoricTaskCommand? =
- when (changeEvent.eventType) {
- "update" -> UpdateAttributesHistoricTaskCommand(
+ @EventListener(condition = "#changeEvent.eventType.equals('update') && @taskEventCollectorService.camundaTaskpoolCollectorProperties.task.collectHistoryEvent('update')")
+ fun update(changeEvent: HistoricTaskInstanceEventEntity): UpdateAttributesHistoricTaskCommand =
+ UpdateAttributesHistoricTaskCommand(
id = changeEvent.taskId,
description = changeEvent.description,
dueDate = changeEvent.dueDate,
@@ -137,15 +138,12 @@ class TaskEventCollectorService(
sourceReference = changeEvent.sourceReference(repositoryService, camundaTaskpoolCollectorProperties.applicationName)
)
- else -> null
- }
-
/**
* Fires update assignment historic command.
* This is the only way to detect changes of identity links (candidate user/group change and remove).
*/
@Order(ORDER)
- @EventListener
+ @EventListener(condition = "@taskEventCollectorService.camundaTaskpoolCollectorProperties.task.collectHistoryEvent('add-identity-link') || @taskEventCollectorService.camundaTaskpoolCollectorProperties.task.collectHistoryEvent('delete-identity-link')")
fun update(changeEvent: HistoricIdentityLinkLogEventEntity): Any? =
when {
// user assignment. Is needed because the assignment out of a listener is undetected otherwise.
diff --git a/integration/camunda-bpm/taskpool-collector/src/test/kotlin/io/holunda/polyflow/taskpool/collector/properties/CamundaTaskpoolCollectorPropertiesExtendedTest.kt b/integration/camunda-bpm/taskpool-collector/src/test/kotlin/io/holunda/polyflow/taskpool/collector/properties/CamundaTaskpoolCollectorPropertiesExtendedTest.kt
index 458d2bd46..d0f1ba439 100644
--- a/integration/camunda-bpm/taskpool-collector/src/test/kotlin/io/holunda/polyflow/taskpool/collector/properties/CamundaTaskpoolCollectorPropertiesExtendedTest.kt
+++ b/integration/camunda-bpm/taskpool-collector/src/test/kotlin/io/holunda/polyflow/taskpool/collector/properties/CamundaTaskpoolCollectorPropertiesExtendedTest.kt
@@ -83,6 +83,31 @@ internal class CamundaTaskpoolCollectorPropertiesExtendedTest {
}
}
+ @Test
+ fun `loads properties configuration to ignore listeners`() {
+ contextRunner
+ .withUserConfiguration(TestMockConfiguration::class.java)
+ .withUserConfiguration(AdditionalMockConfiguration::class.java)
+ .withPropertyValues(
+ "spring.application.name=my-test-application",
+ "camunda.bpm.eventing.task=false",
+ "polyflow.integration.collector.camunda.task.enabled=true",
+ "polyflow.integration.collector.camunda.task.enricher.type=custom",
+ "polyflow.integration.collector.camunda.task.excluded-task-event-names=assignment",
+ "polyflow.integration.collector.camunda.task.excluded-history-event-names=add-identity-link,delete-identity-link",
+ ).run {
+
+ assertThat(it.getBean(CamundaTaskpoolCollectorProperties::class.java)).isNotNull
+ val props: CamundaTaskpoolCollectorProperties = it.getBean(CamundaTaskpoolCollectorProperties::class.java)
+
+ assertThat(props.task.enabled).isTrue
+ assertThat(props.task.collectTaskEvent("assignment")).isFalse()
+ assertThat(props.task.collectHistoryEvent("add-identity-link")).isFalse()
+ assertThat(props.task.collectHistoryEvent("delete-identity-link")).isFalse()
+ }
+ }
+
+
/**
* Config class without configuration annotation not to confuse others.
*/
diff --git a/integration/camunda-bpm/taskpool-collector/src/test/kotlin/io/holunda/polyflow/taskpool/itest/TestDriver.kt b/integration/camunda-bpm/taskpool-collector/src/test/kotlin/io/holunda/polyflow/taskpool/itest/TestDriver.kt
index e6f6e4870..7b35e6ff1 100644
--- a/integration/camunda-bpm/taskpool-collector/src/test/kotlin/io/holunda/polyflow/taskpool/itest/TestDriver.kt
+++ b/integration/camunda-bpm/taskpool-collector/src/test/kotlin/io/holunda/polyflow/taskpool/itest/TestDriver.kt
@@ -145,8 +145,8 @@ class TestDriver(
}
- fun assertProcessInstanceWaitsInUserTask(instance: ProcessInstance) {
- BpmnAwareTests.assertThat(instance).isWaitingAt(TASK_DEFINITION_KEY)
+ fun assertProcessInstanceWaitsInUserTask(instance: ProcessInstance, taskDefinitionKey: String = TASK_DEFINITION_KEY) {
+ BpmnAwareTests.assertThat(instance).isWaitingAt(taskDefinitionKey)
}
/*
diff --git a/integration/camunda-bpm/taskpool-collector/src/test/kotlin/io/holunda/polyflow/taskpool/itest/tx/TaskCollectorITest.kt b/integration/camunda-bpm/taskpool-collector/src/test/kotlin/io/holunda/polyflow/taskpool/itest/tx/TaskCollectorITest.kt
index 92dbec1d0..963bf20f6 100644
--- a/integration/camunda-bpm/taskpool-collector/src/test/kotlin/io/holunda/polyflow/taskpool/itest/tx/TaskCollectorITest.kt
+++ b/integration/camunda-bpm/taskpool-collector/src/test/kotlin/io/holunda/polyflow/taskpool/itest/tx/TaskCollectorITest.kt
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.module.kotlin.convertValue
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import io.holunda.camunda.taskpool.api.task.*
import io.holunda.polyflow.taskpool.EnableCamundaTaskpoolCollector
+import io.holunda.polyflow.taskpool.collector.task.TaskEventCollectorService
import io.holunda.polyflow.taskpool.itest.TestDriver
import io.holunda.polyflow.taskpool.itest.TestDriver.Companion.DEFAULT_VARIABLES
import io.holunda.polyflow.taskpool.itest.TestDriver.Companion.createTaskCommand
@@ -17,6 +18,7 @@ import org.axonframework.commandhandling.gateway.CommandGateway
import org.camunda.bpm.engine.RepositoryService
import org.camunda.bpm.engine.RuntimeService
import org.camunda.bpm.engine.TaskService
+import org.camunda.bpm.engine.delegate.DelegateTask
import org.camunda.bpm.engine.delegate.TaskListener
import org.camunda.bpm.engine.impl.interceptor.Command
import org.camunda.bpm.engine.impl.interceptor.CommandExecutor
@@ -32,6 +34,8 @@ import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.mock.mockito.MockBean
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Primary
+import org.springframework.context.event.EventListener
+import org.springframework.core.annotation.Order
import org.springframework.test.annotation.DirtiesContext
import org.springframework.test.context.ActiveProfiles
import java.time.Instant.now
@@ -647,6 +651,43 @@ internal class TaskCollectorITest {
}
+ /**
+ * The process is started and waits in a user task. The user task has a task listener that changes some local process variables on create.
+ * The create command should contain the local variables.
+ */
+ @Test
+ fun `updates variables with create listener implemented as spring event handler`() {
+
+ // deploy
+ driver.deployProcess(
+ createUserTaskProcess(
+ taskDefinitionKey = "eventing",
+ taskListeners = listOf(
+ "create" to "#{setTaskLocalVariables}" // this one will be ignored, since it is invoked after enrichment
+ )
+ )
+ )
+
+
+ // start
+ val instance = driver.startProcessInstance(variables = Variables.createVariables().putValue("overriddenVariable", "global-value"))
+ driver.assertProcessInstanceWaitsInUserTask(instance, "eventing")
+
+ val createCommand = createTaskCommand(
+ variables = Variables.createVariables()
+ .putValue("taskLocalOnlyVariable", "only-value-by-event-handler")
+ .putValue("overriddenVariable", "local-value-by-event-handler")
+ )
+
+
+ waitAtMost(3, TimeUnit.SECONDS).untilAsserted {
+ verify(commandListGateway).sendToGateway(
+ listOf(createCommand)
+ )
+ }
+
+ verifyNoMoreInteractions(commandListGateway)
+ }
/**
* Internal test application.
@@ -694,6 +735,26 @@ internal class TaskCollectorITest {
delegateTask.dueDate = TestDriver.NOW
delegateTask.followUpDate = TestDriver.NOW
}
+
+ /**
+ * A task listener that sets some local variables.
+ */
+ @Order(TaskEventCollectorService.ORDER - 80)
+ @EventListener(condition = "#delegateTask.taskDefinitionKey.equals('eventing') && #delegateTask.eventName.equals('create')")
+ fun setTaskLocalVariables(delegateTask: DelegateTask) {
+ delegateTask.setVariableLocal("taskLocalOnlyVariable", "only-value-by-event-handler")
+ delegateTask.setVariableLocal("overriddenVariable", "local-value-by-event-handler")
+ }
+
+
+ /**
+ * A task listener that sets some local variables.
+ */
+ @Bean
+ fun setTaskLocalVariables() = TaskListener { delegateTask ->
+ delegateTask.setVariableLocal("taskLocalOnlyVariable", "only-value")
+ delegateTask.setVariableLocal("overriddenVariable", "local-value")
+ }
}
}
diff --git a/integration/camunda-bpm/taskpool-collector/src/test/kotlin/io/holunda/polyflow/taskpool/itest/txjob/TaskTxJobSenderITest.kt b/integration/camunda-bpm/taskpool-collector/src/test/kotlin/io/holunda/polyflow/taskpool/itest/txjob/TaskTxJobSenderITest.kt
index bd5b4d011..eeddff42d 100644
--- a/integration/camunda-bpm/taskpool-collector/src/test/kotlin/io/holunda/polyflow/taskpool/itest/txjob/TaskTxJobSenderITest.kt
+++ b/integration/camunda-bpm/taskpool-collector/src/test/kotlin/io/holunda/polyflow/taskpool/itest/txjob/TaskTxJobSenderITest.kt
@@ -7,17 +7,16 @@ import io.holunda.polyflow.taskpool.itest.TestDriver
import io.holunda.polyflow.taskpool.itest.TestDriver.Companion.createUserTaskProcess
import io.holunda.polyflow.taskpool.sender.gateway.CommandListGateway
import org.assertj.core.api.Assertions
+import org.awaitility.Awaitility
import org.axonframework.commandhandling.gateway.CommandGateway
import org.camunda.bpm.engine.ManagementService
import org.camunda.bpm.engine.RepositoryService
import org.camunda.bpm.engine.RuntimeService
-import org.camunda.bpm.engine.TaskService
-import org.camunda.bpm.engine.impl.interceptor.Command
-import org.camunda.bpm.engine.impl.interceptor.CommandExecutor
+import org.camunda.bpm.engine.delegate.TaskListener
+import org.camunda.bpm.engine.impl.persistence.entity.MessageEntity
import org.camunda.bpm.engine.test.assertions.bpmn.BpmnAwareTests.*
+import org.camunda.bpm.engine.variable.Variables
import org.camunda.bpm.spring.boot.starter.annotation.EnableProcessApplication
-import org.junit.After
-import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test
@@ -30,20 +29,20 @@ import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.mock.mockito.MockBean
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Primary
-import org.springframework.test.annotation.Commit
import org.springframework.test.annotation.DirtiesContext
-import org.springframework.test.annotation.Rollback
import org.springframework.test.context.ActiveProfiles
-import org.springframework.test.context.transaction.AfterTransaction
+import org.springframework.transaction.annotation.Propagation
import org.springframework.transaction.annotation.Transactional
-import org.springframework.transaction.support.TransactionSynchronization
+import org.springframework.transaction.support.TransactionTemplate
import java.util.*
+import java.util.concurrent.TimeUnit
-@Disabled("Understand how to test this")
@SpringBootTest(classes = [TaskTxJobSenderITest.TaskTxJobSenderTestApplication::class], webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@ActiveProfiles("txjob-sender-itest")
@DirtiesContext
+@Transactional
+@Disabled("This test sometimes fails because it can't create a new TX (Entity Manager is closed).")
internal class TaskTxJobSenderITest {
@MockBean
@@ -59,63 +58,111 @@ internal class TaskTxJobSenderITest {
lateinit var managementService: ManagementService
@Autowired
- lateinit var taskServiceService: TaskService
-
-
- @Autowired
- lateinit var commandExecutor: CommandExecutor
+ lateinit var txTemplate: TransactionTemplate
+ lateinit var createCommand: CreateTaskCommand
private val driver: TestDriver by lazy {
TestDriver(repositoryService, runtimeService)
}
-
@BeforeEach
- fun `start process and create user task`() {
-
+ fun `setup tx template`() {
+ txTemplate.propagationBehavior = Propagation.REQUIRES_NEW.value()
}
@Test
- @Transactional
- @Commit
fun `creates task in process`() {
- // deploy
- driver.deployProcess(
- createUserTaskProcess()
- )
-// commandExecutor.execute {
-// Command {
- // start
- val instance = driver.startProcessInstance()
- // instance is started
- assertThat(instance).isStarted
- // user task
- driver.assertProcessInstanceWaitsInUserTask(instance)
-// }
-// }
+ doInTransaction {
+ // deploy
+ driver.deployProcess(
+ createUserTaskProcess()
+ )
+ // start
+ val instance = driver.startProcessInstance()
+ // instance is started
+ assertThat(instance).isStarted
+ // user task
+ driver.assertProcessInstanceWaitsInUserTask(instance)
- /*
+ verifyNoMoreInteractions(commandListGateway)
+
+ createCommand = TestDriver.createTaskCommand()
+ }
+
+ assertAndExecuteCommandSendingJob()
+
+ verify(commandListGateway).sendToGateway(
+ listOf(createCommand)
+ )
+ }
- val createCommand = createTaskCommand(
- candidateUsers = setOf("piggy"),
- candidateGroups = setOf("muppetshow"),
+ /**
+ * The process is started and waits in a user task. The user task has a task listener that changes some local process variables on create.
+ * The create command should contain the local variables.
+ */
+ @Test
+ @Disabled("Find out why the local listener update always gt into the next TX and how to deal with it")
+ fun `updates variables with create listener`() {
+
+ doInTransaction {
+ // deploy
+ driver.deployProcess(
+ createUserTaskProcess(
+ taskListeners = listOf(
+ "create" to "#{setTaskLocalVariables}"
+ )
)
- */
+ )
+
+ // start
+ val instance = driver.startProcessInstance(variables = Variables.createVariables().putValue("overriddenVariable", "global-value"))
+ driver.assertProcessInstanceWaitsInUserTask(instance)
+
+ verifyNoMoreInteractions(commandListGateway)
+ createCommand = TestDriver.createTaskCommand(
+ variables = Variables.createVariables()
+ .putValue("taskLocalOnlyVariable", "only-value")
+ .putValue("overriddenVariable", "local-value")
+ )
+ }
- verifyNoMoreInteractions(commandListGateway)
+ assertAndExecuteCommandSendingJob()
+
+ verify(commandListGateway).sendToGateway(
+ listOf(createCommand)
+ )
}
- @AfterTransaction
- fun `after all`() {
- val jobs = managementService.createJobQuery().list()
- Assertions.assertThat(jobs).hasSize(1)
+ private fun assertAndExecuteCommandSendingJob() {
+ doInTransaction {
+ val jobs = managementService.createJobQuery().list()
+ Assertions.assertThat(jobs).hasSize(1)
+ Assertions.assertThat(jobs[0]).isInstanceOf(MessageEntity::class.java)
+ Assertions.assertThat((jobs[0] as MessageEntity).jobHandlerType).isEqualTo("polyflow-engine-task-command-sending")
+
+ Awaitility.waitAtMost(3, TimeUnit.SECONDS).untilAsserted {
+ try {
+ execute(jobs[0])
+ } catch (e: Exception) {
+ // brute force preventing Optimistic locking exception, IllegalStateException (job doesn't exist)
+ }
+ Assertions.assertThat(managementService.createJobQuery().count()).isEqualTo(0)
+ }
+ }
}
+ private fun doInTransaction(operation: Runnable) {
+ txTemplate.execute {
+ operation.run()
+ null
+ }
+
+ }
@SpringBootApplication
@EnableProcessApplication
@@ -126,5 +173,15 @@ internal class TaskTxJobSenderITest {
@Bean
@Primary
fun testTxJobAxonCommandGateway(): CommandGateway = mock()
+
+ /**
+ * A task listener that sets some local variables.
+ */
+ @Bean
+ fun setTaskLocalVariables() = TaskListener { delegateTask ->
+ delegateTask.setVariableLocal("taskLocalOnlyVariable", "only-value")
+ delegateTask.setVariableLocal("overriddenVariable", "local-value")
+ }
+
}
}
diff --git a/integration/camunda-bpm/taskpool-collector/src/test/resources/application-txjob-sender-itest.yml b/integration/camunda-bpm/taskpool-collector/src/test/resources/application-txjob-sender-itest.yml
index 6c3a453c9..2b0e97a03 100644
--- a/integration/camunda-bpm/taskpool-collector/src/test/resources/application-txjob-sender-itest.yml
+++ b/integration/camunda-bpm/taskpool-collector/src/test/resources/application-txjob-sender-itest.yml
@@ -1,5 +1,5 @@
spring:
- application.name: txjob-sender-test
+ application.name: collector-test
jpa:
open-in-view: true # disable JPA warning
show-sql: true
@@ -17,7 +17,16 @@ camunda:
polyflow:
integration:
+ collector:
+ camunda:
+ task:
+ enabled: true
+ process-instance:
+ enabled: false
+ process-definition:
+ enabled: false
sender:
task:
type: txjob
send-within-transaction: true
+
diff --git a/integration/camunda-bpm/taskpool-job-sender/pom.xml b/integration/camunda-bpm/taskpool-job-sender/pom.xml
index f5ee9f19f..f6f7b48d1 100755
--- a/integration/camunda-bpm/taskpool-job-sender/pom.xml
+++ b/integration/camunda-bpm/taskpool-job-sender/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-integration-camunda-bpm-engine-parent
- 3.10.0
+ 3.11.0
polyflow-camunda-bpm-taskpool-job-sender
diff --git a/integration/common/datapool-sender/pom.xml b/integration/common/datapool-sender/pom.xml
index 06f83b9f7..dc304de41 100755
--- a/integration/common/datapool-sender/pom.xml
+++ b/integration/common/datapool-sender/pom.xml
@@ -5,7 +5,7 @@
io.holunda.polyflow
polyflow-integration-common-parent
- 3.10.0
+ 3.11.0
polyflow-datapool-sender
diff --git a/integration/common/pom.xml b/integration/common/pom.xml
index acce6c5aa..20bc0ed7d 100755
--- a/integration/common/pom.xml
+++ b/integration/common/pom.xml
@@ -5,7 +5,7 @@
io.holunda.polyflow
polyflow-parent
- 3.10.0
+ 3.11.0
../../bom/parent/pom.xml
diff --git a/integration/common/tasklist-url-resolver/pom.xml b/integration/common/tasklist-url-resolver/pom.xml
index 92158c1a1..c625b9d1a 100644
--- a/integration/common/tasklist-url-resolver/pom.xml
+++ b/integration/common/tasklist-url-resolver/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-integration-common-parent
- 3.10.0
+ 3.11.0
polyflow-tasklist-url-resolver
diff --git a/integration/common/taskpool-sender/pom.xml b/integration/common/taskpool-sender/pom.xml
index 1d06c591f..10cadc2ad 100755
--- a/integration/common/taskpool-sender/pom.xml
+++ b/integration/common/taskpool-sender/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-integration-common-parent
- 3.10.0
+ 3.11.0
polyflow-taskpool-sender
diff --git a/integration/common/variable-serializer/pom.xml b/integration/common/variable-serializer/pom.xml
index 6a5fc6579..e81865208 100755
--- a/integration/common/variable-serializer/pom.xml
+++ b/integration/common/variable-serializer/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-integration-common-parent
- 3.10.0
+ 3.11.0
polyflow-variable-serializer
diff --git a/pom.xml b/pom.xml
index e95b93f2b..27b13a831 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
io.holunda.polyflow
polyflow-root
- 3.10.0
+ 3.11.0
pom
POM: ${project.artifactId}
@@ -20,7 +20,7 @@
${java.version}
${java.version}
- 1.8.20
+ 1.8.21
${java.version}
true
3.0.5
diff --git a/view/form-url-resolver/pom.xml b/view/form-url-resolver/pom.xml
index d08aeeb3b..a3db7b34c 100644
--- a/view/form-url-resolver/pom.xml
+++ b/view/form-url-resolver/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-view-parent
- 3.10.0
+ 3.11.0
polyflow-form-url-resolver
diff --git a/view/jpa/pom.xml b/view/jpa/pom.xml
index 5527fefe7..e21baaff1 100644
--- a/view/jpa/pom.xml
+++ b/view/jpa/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-view-parent
- 3.10.0
+ 3.11.0
polyflow-view-jpa
diff --git a/view/mongo/pom.xml b/view/mongo/pom.xml
index 40d451fb5..ba510a6e4 100755
--- a/view/mongo/pom.xml
+++ b/view/mongo/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-view-parent
- 3.10.0
+ 3.11.0
polyflow-view-mongo
diff --git a/view/pom.xml b/view/pom.xml
index a7e7ca730..672ff531c 100644
--- a/view/pom.xml
+++ b/view/pom.xml
@@ -5,7 +5,7 @@
io.holunda.polyflow
polyflow-parent
- 3.10.0
+ 3.11.0
../bom/parent/pom.xml
diff --git a/view/simple/pom.xml b/view/simple/pom.xml
index 2a7cdaf54..254c8ee36 100755
--- a/view/simple/pom.xml
+++ b/view/simple/pom.xml
@@ -5,7 +5,7 @@
io.holunda.polyflow
polyflow-view-parent
- 3.10.0
+ 3.11.0
polyflow-view-simple
diff --git a/view/view-api-client/pom.xml b/view/view-api-client/pom.xml
index 6314f3e87..773d04061 100755
--- a/view/view-api-client/pom.xml
+++ b/view/view-api-client/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-view-parent
- 3.10.0
+ 3.11.0
polyflow-view-api-client
diff --git a/view/view-api/pom.xml b/view/view-api/pom.xml
index a71bc672b..eb717e0d5 100755
--- a/view/view-api/pom.xml
+++ b/view/view-api/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-view-parent
- 3.10.0
+ 3.11.0
polyflow-view-api