diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 5990cfd94..e7a32bdbd 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -13,10 +13,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Set up JDK
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: 17
@@ -35,7 +35,7 @@ jobs:
run: ./mvnw integration-test failsafe:verify -Pitest -B -T4
- name: Upload coverage information
- uses: codecov/codecov-action@v3
+ uses: codecov/codecov-action@v4
with:
token: "${{ secrets.CODECOV_TOKEN }}"
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index bece96d6f..78df248a4 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -25,18 +25,6 @@ jobs:
# install pip=>20.1 to use "pip cache dir"
python3 -m pip install --upgrade pip
-# - name: Get pip cache dir
-# id: pip-cache
-# run: echo "::set-output name=dir::$(pip cache dir)"
-#
-# - name: Cache dependencies
-# uses: actions/cache@v3
-# with:
-# path: ${{ steps.pip-cache.outputs.dir }}
-# key: ${{ runner.os }}-pip-${{ hashFiles('./docs/requirements.txt') }}
-# restore-keys: |
-# ${{ runner.os }}-pip-
-
- name: Install dependencies
run: python3 -m pip install -r ./docs/requirements.txt
diff --git a/.github/workflows/release-notes.yml b/.github/workflows/release-notes.yml
index ff2ec246c..a3d8fbf44 100644
--- a/.github/workflows/release-notes.yml
+++ b/.github/workflows/release-notes.yml
@@ -9,6 +9,7 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@master
+
- name: Create Release Notes Markdown
uses: docker://decathlon/release-notes-generator-action:3.1.5
env:
@@ -21,6 +22,7 @@ jobs:
echo "RELEASE_NOTES_FILE=$RELEASE_NOTES_FILE" >> $GITHUB_ENV
VERSION=$(echo ${{ github.event.milestone.title }} | cut -d' ' -f2)
echo "VERSION=$VERSION" >> $GITHUB_ENV
+
- name: Create a Draft Release Notes on GitHub
id: create_release
uses: actions/create-release@v1
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 5a45fe6a9..a623e5dfc 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -12,11 +12,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
# Setup JDK and Maven
- name: Set up JDK 17
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v4
with:
java-version: 17
distribution: 'zulu'
@@ -51,7 +51,7 @@ jobs:
OSS_CENTRAL_PASSWORD: "${{ secrets.SONATYPE_PASSWORD }}"
- name: Upload coverage information to CodeCov
- uses: codecov/codecov-action@v3
+ uses: codecov/codecov-action@v4
with:
token: "${{ secrets.CODECOV_TOKEN }}"
diff --git a/bom/datapool-dependencies/pom.xml b/bom/datapool-dependencies/pom.xml
index 40528bd36..6a16e02dc 100644
--- a/bom/datapool-dependencies/pom.xml
+++ b/bom/datapool-dependencies/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-parent
- 4.1.4
+ 4.1.5
../parent/pom.xml
diff --git a/bom/parent/pom.xml b/bom/parent/pom.xml
index ecc3b34cb..b776aec02 100644
--- a/bom/parent/pom.xml
+++ b/bom/parent/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-root
- 4.1.4
+ 4.1.5
../../pom.xml
@@ -19,14 +19,14 @@
3.1.5
- 7.20.0
+ 7.21.0
4.9.4
4.9.0
- 2.0.0
+ 2.1.0
- 4.2.0
- 5.2.1
+ 4.2.1
+ 5.3.1
1.3.1
1.3.1.0
@@ -311,7 +311,7 @@
org.jacoco
jacoco-maven-plugin
- 0.8.11
+ 0.8.12
pre-unit-test
@@ -372,7 +372,7 @@
org.apache.maven.plugins
maven-compiler-plugin
- 3.12.1
+ 3.13.0
UTF-8
@@ -420,7 +420,7 @@
org.apache.maven.plugins
maven-jar-plugin
- 3.3.0
+ 3.4.1
@@ -565,7 +565,7 @@
org.jetbrains.dokka
dokka-maven-plugin
- 1.9.10
+ 1.9.20
attach-javadocs
@@ -581,7 +581,7 @@
org.codehaus.mojo
build-helper-maven-plugin
- 3.5.0
+ 3.6.0
generate-sources
@@ -601,7 +601,7 @@
org.apache.maven.plugins
maven-source-plugin
- 3.3.0
+ 3.3.1
attach-sources
@@ -620,7 +620,7 @@
maven-install-plugin
- 3.1.1
+ 3.1.2
diff --git a/bom/taskpool-dependencies/pom.xml b/bom/taskpool-dependencies/pom.xml
index 9a011b103..aabbc4875 100644
--- a/bom/taskpool-dependencies/pom.xml
+++ b/bom/taskpool-dependencies/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-parent
- 4.1.4
+ 4.1.5
../parent/pom.xml
diff --git a/core/bus-jackson/pom.xml b/core/bus-jackson/pom.xml
index f6f428fbe..bbb0ca60c 100755
--- a/core/bus-jackson/pom.xml
+++ b/core/bus-jackson/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-parent
- 4.1.4
+ 4.1.5
../../bom/parent/pom.xml
diff --git a/core/bus-jackson/src/main/kotlin/io/holunda/polyflow/bus/jackson/JsonAutoDetectAnyVisibility.kt b/core/bus-jackson/src/main/kotlin/io/holunda/polyflow/bus/jackson/JsonAutoDetectAnyVisibility.kt
new file mode 100644
index 000000000..fc79c2fb9
--- /dev/null
+++ b/core/bus-jackson/src/main/kotlin/io/holunda/polyflow/bus/jackson/JsonAutoDetectAnyVisibility.kt
@@ -0,0 +1,9 @@
+package io.holunda.polyflow.bus.jackson
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect
+
+/**
+ * Allow serialization of all fields. (Also private fields!)
+ */
+@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
+class JsonAutoDetectAnyVisibility
diff --git a/core/datapool/datapool-api/pom.xml b/core/datapool/datapool-api/pom.xml
index 5d7a669f9..f14a7909e 100755
--- a/core/datapool/datapool-api/pom.xml
+++ b/core/datapool/datapool-api/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-datapool-parent
- 4.1.4
+ 4.1.5
polyflow-datapool-api
diff --git a/core/datapool/datapool-core/pom.xml b/core/datapool/datapool-core/pom.xml
index 661917e5d..dcbaa5ab4 100644
--- a/core/datapool/datapool-core/pom.xml
+++ b/core/datapool/datapool-core/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-datapool-parent
- 4.1.4
+ 4.1.5
polyflow-datapool-core
@@ -40,12 +40,11 @@
dom4j
2.1.4
-
io.holunda.polyflow
polyflow-bus-jackson
- test
+
org.springframework.boot
spring-boot-starter-test
diff --git a/core/datapool/datapool-core/src/main/kotlin/io/holunda/polyflow/datapool/core/DataPoolCoreAxonConfiguration.kt b/core/datapool/datapool-core/src/main/kotlin/io/holunda/polyflow/datapool/core/DataPoolCoreAxonConfiguration.kt
index d1acd8734..a3f6fd958 100755
--- a/core/datapool/datapool-core/src/main/kotlin/io/holunda/polyflow/datapool/core/DataPoolCoreAxonConfiguration.kt
+++ b/core/datapool/datapool-core/src/main/kotlin/io/holunda/polyflow/datapool/core/DataPoolCoreAxonConfiguration.kt
@@ -1,5 +1,7 @@
package io.holunda.polyflow.datapool.core
+import com.fasterxml.jackson.databind.ObjectMapper
+import io.holunda.polyflow.bus.jackson.JsonAutoDetectAnyVisibility
import io.holunda.polyflow.datapool.core.business.CreateOrUpdateCommandHandler
import io.holunda.polyflow.datapool.core.business.DataEntryAggregate
import io.holunda.polyflow.datapool.core.business.upcaster.DataEntryCreatedEventUpcaster
@@ -13,6 +15,7 @@ import org.axonframework.eventsourcing.SnapshotTriggerDefinition
import org.axonframework.eventsourcing.Snapshotter
import org.axonframework.eventsourcing.eventstore.EventStore
import org.axonframework.messaging.annotation.ParameterResolverFactory
+import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.context.annotation.Bean
@@ -98,5 +101,15 @@ class DataPoolCoreAxonConfiguration {
*/
@Bean(DATA_ENTRY_CACHE)
fun dataEntryCache(): Cache = WeakReferenceCache()
+
+ @Autowired
+ fun configureJackson(objectMapper: ObjectMapper) {
+ objectMapper.configurePolyflowJacksonObjectMapperForDatapool()
+ }
+}
+
+fun ObjectMapper.configurePolyflowJacksonObjectMapperForDatapool(): ObjectMapper {
+ addMixIn(DataEntryAggregate::class.java, JsonAutoDetectAnyVisibility::class.java)
+ return this
}
diff --git a/core/datapool/datapool-core/src/test/kotlin/io/holunda/polyflow/datapool/core/business/DataEntryAggregateTest.kt b/core/datapool/datapool-core/src/test/kotlin/io/holunda/polyflow/datapool/core/business/DataEntryAggregateTest.kt
index 262004518..2f6d34f81 100644
--- a/core/datapool/datapool-core/src/test/kotlin/io/holunda/polyflow/datapool/core/business/DataEntryAggregateTest.kt
+++ b/core/datapool/datapool-core/src/test/kotlin/io/holunda/polyflow/datapool/core/business/DataEntryAggregateTest.kt
@@ -1,7 +1,13 @@
package io.holunda.polyflow.datapool.core.business
+import com.fasterxml.jackson.databind.ObjectMapper
import io.holunda.camunda.taskpool.api.business.*
+import io.holunda.polyflow.bus.jackson.JsonAutoDetectAnyVisibility
+import io.holunda.polyflow.bus.jackson.configurePolyflowJacksonObjectMapper
import io.holunda.polyflow.datapool.core.DeletionStrategy
+import io.holunda.polyflow.datapool.core.configurePolyflowJacksonObjectMapperForDatapool
+import org.assertj.core.api.Assertions
+import org.assertj.core.api.Assertions.assertThat
import org.axonframework.eventsourcing.AggregateDeletedException
import org.axonframework.test.aggregate.AggregateTestFixture
import org.camunda.bpm.engine.variable.Variables
@@ -353,5 +359,53 @@ class DataEntryAggregateTest {
)
}
+ @Test
+ fun `should serialize and deserialize an empty aggregate`() {
+ // GIVEN an object mapper and an empty aggregate
+ val objectMapper = ObjectMapper().configurePolyflowJacksonObjectMapper()
+ val dataEntryAggregate = DataEntryAggregate()
+
+ // WHEN we serialize and deserialize it
+ val serializedObj = objectMapper.writeValueAsString(dataEntryAggregate)
+ objectMapper.readValue(serializedObj, DataEntryAggregate::class.java)
+ // THEN no problem should occur
+ }
+
+ @Test
+ fun `should serialize and deserialize an aggregate with data`() {
+ // GIVEN an object mapper and a filled aggregate
+ val objectMapper = ObjectMapper()
+ .configurePolyflowJacksonObjectMapper()
+ .configurePolyflowJacksonObjectMapperForDatapool()
+
+ val dataEntryAggregate = DataEntryAggregate().apply {
+ on(
+ DataEntryCreatedEvent(
+ entryId = UUID.randomUUID().toString(),
+ entryType = "io.holunda.My",
+ name = "Some name",
+ type = "Another",
+ applicationName = "Different application",
+ )
+ )
+ }
+ val dataIdentityValue = dataEntryAggregate.getDataIdentityValueForTest()
+
+ // WHEN we serialize and deserialize it
+ val serializedObj = objectMapper.writeValueAsString(dataEntryAggregate)
+ val deserializedObj = objectMapper.readValue(serializedObj, DataEntryAggregate::class.java)
+
+ // THEN no problem should occur
+ assertThat(deserializedObj.getDataIdentityValueForTest()).isEqualTo(dataIdentityValue)
+ }
+
+}
+
+private fun DataEntryAggregate.getDataIdentityValueForTest(): String? {
+ return javaClass.getDeclaredField("dataIdentity").let {
+ it.isAccessible = true
+ val value = it.get(this) as String?
+ return@let value
+ }
}
diff --git a/core/datapool/datapool-event/pom.xml b/core/datapool/datapool-event/pom.xml
index 3688e0fda..b08a6b98b 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
- 4.1.4
+ 4.1.5
polyflow-datapool-event
diff --git a/core/datapool/pom.xml b/core/datapool/pom.xml
index 6bffafc10..9f663ca3c 100755
--- a/core/datapool/pom.xml
+++ b/core/datapool/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-parent
- 4.1.4
+ 4.1.5
../../bom/parent/pom.xml
diff --git a/core/spring-utils/pom.xml b/core/spring-utils/pom.xml
index 3af7ae9f2..57602cef2 100755
--- a/core/spring-utils/pom.xml
+++ b/core/spring-utils/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-parent
- 4.1.4
+ 4.1.5
../../bom/parent/pom.xml
diff --git a/core/taskpool/pom.xml b/core/taskpool/pom.xml
index a69b6e362..69037f002 100755
--- a/core/taskpool/pom.xml
+++ b/core/taskpool/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-parent
- 4.1.4
+ 4.1.5
../../bom/parent/pom.xml
diff --git a/core/taskpool/taskpool-api/pom.xml b/core/taskpool/taskpool-api/pom.xml
index 0d905573f..49bd0b6ff 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
- 4.1.4
+ 4.1.5
polyflow-taskpool-api
diff --git a/core/taskpool/taskpool-core/pom.xml b/core/taskpool/taskpool-core/pom.xml
index a03337f06..96e51aeac 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
- 4.1.4
+ 4.1.5
polyflow-taskpool-core
diff --git a/core/taskpool/taskpool-core/src/main/kotlin/io/holunda/polyflow/taskpool/core/JacksonExtensions.kt b/core/taskpool/taskpool-core/src/main/kotlin/io/holunda/polyflow/taskpool/core/JacksonExtensions.kt
deleted file mode 100644
index 090af6d87..000000000
--- a/core/taskpool/taskpool-core/src/main/kotlin/io/holunda/polyflow/taskpool/core/JacksonExtensions.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package io.holunda.polyflow.taskpool.core
-
-import com.fasterxml.jackson.databind.ObjectMapper
-import io.holunda.polyflow.bus.jackson.configurePolyflowJacksonObjectMapper
-
-/**
- * Configures object mapper.
- */
-@Deprecated(
- replaceWith = ReplaceWith("io.holunda.polyflow.bus.jackson.configurePolyflowJacksonObjectMapper()"),
- message = "Moved to separate artifact polyflow-bus-jackson"
-)
-fun ObjectMapper.configureTaskpoolJacksonObjectMapper(): ObjectMapper = configurePolyflowJacksonObjectMapper()
diff --git a/core/taskpool/taskpool-core/src/main/kotlin/io/holunda/polyflow/taskpool/core/TaskPoolCoreConfiguration.kt b/core/taskpool/taskpool-core/src/main/kotlin/io/holunda/polyflow/taskpool/core/TaskPoolCoreConfiguration.kt
index 6b31cffed..5fe428ddc 100755
--- a/core/taskpool/taskpool-core/src/main/kotlin/io/holunda/polyflow/taskpool/core/TaskPoolCoreConfiguration.kt
+++ b/core/taskpool/taskpool-core/src/main/kotlin/io/holunda/polyflow/taskpool/core/TaskPoolCoreConfiguration.kt
@@ -1,13 +1,18 @@
package io.holunda.polyflow.taskpool.core
+import com.fasterxml.jackson.databind.ObjectMapper
+import io.holunda.polyflow.bus.jackson.JsonAutoDetectAnyVisibility
import io.holunda.polyflow.taskpool.core.process.ProcessDefinitionAggregate
import io.holunda.polyflow.taskpool.core.process.ProcessInstanceAggregate
import io.holunda.polyflow.taskpool.core.task.TaskAggregate
+import org.axonframework.common.caching.Cache
+import org.axonframework.common.caching.WeakReferenceCache
import org.axonframework.eventsourcing.EventSourcingRepository
import org.axonframework.eventsourcing.eventstore.EventStore
import org.axonframework.messaging.annotation.ParameterResolverFactory
import org.axonframework.modelling.command.Aggregate
import org.axonframework.modelling.command.AggregateNotFoundException
+import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
@@ -22,6 +27,7 @@ class TaskPoolCoreConfiguration {
companion object {
const val TASK_AGGREGATE_REPOSITORY = "taskAggregateRepository"
+ const val TASK_CACHE = "taskCache"
const val PROCESS_DEFINITION_AGGREGATE_REPOSITORY = "processDefinitionAggregateRepository"
const val PROCESS_INSTANCE_AGGREGATE_REPOSITORY = "processInstanceAggregateRepository"
}
@@ -62,6 +68,16 @@ class TaskPoolCoreConfiguration {
.build()
}
+ @Autowired
+ fun configureJackson(objectMapper: ObjectMapper) {
+ objectMapper.configurePolyflowJacksonObjectMapperForTaskPool()
+ }
+
+ /**
+ * Use weak reference cache.
+ */
+ @Bean(TASK_CACHE)
+ fun taskCache(): Cache = WeakReferenceCache()
}
/**
@@ -89,3 +105,8 @@ fun Optional.ifPresentOrElse(presentConsumer: (T) -> Unit, missingCallbac
}
}
+fun ObjectMapper.configurePolyflowJacksonObjectMapperForTaskPool(): ObjectMapper {
+ addMixIn(TaskAggregate::class.java, JsonAutoDetectAnyVisibility::class.java)
+ return this
+}
+
diff --git a/core/taskpool/taskpool-core/src/main/kotlin/io/holunda/polyflow/taskpool/core/process/ProcessInstanceVariablesChangeHandler.kt b/core/taskpool/taskpool-core/src/main/kotlin/io/holunda/polyflow/taskpool/core/process/ProcessInstanceVariablesChangeHandler.kt
index b5cfb745c..aa15b0904 100644
--- a/core/taskpool/taskpool-core/src/main/kotlin/io/holunda/polyflow/taskpool/core/process/ProcessInstanceVariablesChangeHandler.kt
+++ b/core/taskpool/taskpool-core/src/main/kotlin/io/holunda/polyflow/taskpool/core/process/ProcessInstanceVariablesChangeHandler.kt
@@ -7,7 +7,7 @@ import org.springframework.context.annotation.Lazy
import org.springframework.stereotype.Component
/**
- * This handler makes sure that an update of variables can be send without a create of the process instance..
+ * This handler makes sure that an update of variables can be sent without a create of the process instance.
*/
@Component
class ProcessInstanceVariablesChangeHandler(
diff --git a/core/taskpool/taskpool-core/src/main/kotlin/io/holunda/polyflow/taskpool/core/task/TaskAggregate.kt b/core/taskpool/taskpool-core/src/main/kotlin/io/holunda/polyflow/taskpool/core/task/TaskAggregate.kt
index b7554eaa2..087d1d4cf 100755
--- a/core/taskpool/taskpool-core/src/main/kotlin/io/holunda/polyflow/taskpool/core/task/TaskAggregate.kt
+++ b/core/taskpool/taskpool-core/src/main/kotlin/io/holunda/polyflow/taskpool/core/task/TaskAggregate.kt
@@ -15,7 +15,10 @@ import org.axonframework.spring.stereotype.Aggregate
/**
* Main representation of the tasks available in the system.
*/
-@Aggregate(repository = TaskPoolCoreConfiguration.TASK_AGGREGATE_REPOSITORY)
+@Aggregate(
+ repository = TaskPoolCoreConfiguration.TASK_AGGREGATE_REPOSITORY,
+ cache = TaskPoolCoreConfiguration.TASK_CACHE,
+)
class TaskAggregate() {
companion object : KLogging()
diff --git a/core/taskpool/taskpool-event/pom.xml b/core/taskpool/taskpool-event/pom.xml
index 2331d8823..98afc50d6 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
- 4.1.4
+ 4.1.5
polyflow-taskpool-event
diff --git a/docs/examples/scenarios/single-node.md b/docs/examples/scenarios/single-node.md
index 2eb909af7..9f852cb42 100644
--- a/docs/examples/scenarios/single-node.md
+++ b/docs/examples/scenarios/single-node.md
@@ -16,7 +16,7 @@ Before you begin, please build the entire project with `./mvnw clean install` fr
### Start
The demo application consists of one Maven module which can be started by running from command line in
-the `examples/scenarios/single-node` directory using Maven. Alternatively you can start the packaged application using:
+the `examples/scenarios/single-node-jpa` directory using Maven. Alternatively you can start the packaged application using:
```bash
java -jar target/*.jar
@@ -24,6 +24,6 @@ java -jar target/*.jar
## Useful URLs
-* [http://localhost:8080/taskpool/](http://localhost:8080/polyflow/)
+* [http://localhost:8080/polyflow/](http://localhost:8080/polyflow/)
* [http://localhost:8080/swagger-ui/](http://localhost:8080/swagger-ui/)
* [http://localhost:8080/camunda/app/tasklist/default/](http://localhost:8080/camunda/app/tasklist/default/)
diff --git a/integration/camunda-bpm/engine-client/pom.xml b/integration/camunda-bpm/engine-client/pom.xml
index 17e931e5d..025f5a3aa 100644
--- a/integration/camunda-bpm/engine-client/pom.xml
+++ b/integration/camunda-bpm/engine-client/pom.xml
@@ -5,7 +5,7 @@
io.holunda.polyflow
polyflow-integration-camunda-bpm-engine-parent
- 4.1.4
+ 4.1.5
polyflow-camunda-bpm-engine-client
diff --git a/integration/camunda-bpm/pom.xml b/integration/camunda-bpm/pom.xml
index 70e873fd1..293013459 100644
--- a/integration/camunda-bpm/pom.xml
+++ b/integration/camunda-bpm/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-parent
- 4.1.4
+ 4.1.5
../../bom/parent/pom.xml
@@ -15,9 +15,9 @@
pom
- 7.20.0
+ 7.21.0
${camunda-bpm.version}
- 7.20.0
+ 7.21.0
diff --git a/integration/camunda-bpm/springboot-autoconfigure/pom.xml b/integration/camunda-bpm/springboot-autoconfigure/pom.xml
index b98124970..2931fd03c 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
- 4.1.4
+ 4.1.5
polyflow-camunda-bpm-springboot-autoconfigure
diff --git a/integration/camunda-bpm/springboot-starter/pom.xml b/integration/camunda-bpm/springboot-starter/pom.xml
index 4bc0ce3a7..d3934a85c 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
- 4.1.4
+ 4.1.5
polyflow-camunda-bpm-springboot-starter
diff --git a/integration/camunda-bpm/taskpool-collector/pom.xml b/integration/camunda-bpm/taskpool-collector/pom.xml
index 4370c2de7..5e10c70c6 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
- 4.1.4
+ 4.1.5
polyflow-camunda-bpm-taskpool-collector
diff --git a/integration/camunda-bpm/taskpool-job-sender/pom.xml b/integration/camunda-bpm/taskpool-job-sender/pom.xml
index 33e7607c7..b4dec28f5 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
- 4.1.4
+ 4.1.5
polyflow-camunda-bpm-taskpool-job-sender
diff --git a/integration/common/datapool-sender/pom.xml b/integration/common/datapool-sender/pom.xml
index 548d9dbbf..b036d438d 100755
--- a/integration/common/datapool-sender/pom.xml
+++ b/integration/common/datapool-sender/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-integration-common-parent
- 4.1.4
+ 4.1.5
polyflow-datapool-sender
diff --git a/integration/common/pom.xml b/integration/common/pom.xml
index 1e8219e8d..e495bf72d 100755
--- a/integration/common/pom.xml
+++ b/integration/common/pom.xml
@@ -6,7 +6,7 @@
io.holunda.polyflow
polyflow-parent
- 4.1.4
+ 4.1.5
../../bom/parent/pom.xml
diff --git a/integration/common/tasklist-url-resolver/pom.xml b/integration/common/tasklist-url-resolver/pom.xml
index edec9d1d2..12fb3a55c 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
- 4.1.4
+ 4.1.5
polyflow-tasklist-url-resolver
diff --git a/integration/common/taskpool-sender/pom.xml b/integration/common/taskpool-sender/pom.xml
index 4add0f46b..5d0a674fb 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
- 4.1.4
+ 4.1.5
polyflow-taskpool-sender
diff --git a/integration/common/variable-serializer/pom.xml b/integration/common/variable-serializer/pom.xml
index 3e31e3ca2..73f98c4d5 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
- 4.1.4
+ 4.1.5
polyflow-variable-serializer
diff --git a/integration/common/variable-serializer/src/main/kotlin/VariableSerializer.kt b/integration/common/variable-serializer/src/main/kotlin/VariableSerializer.kt
index 4f20dab4d..e02c34eca 100644
--- a/integration/common/variable-serializer/src/main/kotlin/VariableSerializer.kt
+++ b/integration/common/variable-serializer/src/main/kotlin/VariableSerializer.kt
@@ -40,19 +40,22 @@ typealias JsonPathFilterFunction = (path: String) -> Boolean
/**
- * Converts a deep map structure representing the payload into a map of one level keyed by the JSON path and valued by the value.
- * The map might contain primitive types or maps as value.
+ * Converts a deep list of pairs representing the payload into a list of pairs of one level keyed by the JSON path and
+ * valued by the value. A map structure is not sufficient because there can be multiple (different) values for the same
+ * path. For example a pair with a list value of (customer, [foo, bar]) would be converted to the two pairs
+ * (customer, foo) and (customer, bar).
+ * Note: The initial map might contain primitive types, maps or lists as values.
* @param limit limit of levels to convert. Defaults to -1 meaning there is no limit.
* @param filters filter object to identify properties to include into the result.
*/
-fun VariableMap.toJsonPathsWithValues(limit: Int = -1, filters: List> = emptyList()): Map {
- val pathsWithValues: List> = this.entries.map {
- it.toJsonPathWithValue(prefix = "", limit = limit, filter = filters).toMap().toMutableMap()
- }
- return pathsWithValues.reduceOrNull { result, memberList -> result.apply { putAll(memberList) } }?.toMap() ?: mapOf()
+fun VariableMap.toJsonPathsWithValues(limit: Int = -1, filters: List> = emptyList()): Set> {
+ return this.entries
+ .map { it.toPair() }
+ .map { it.toJsonPathWithValue(prefix = "", limit = limit, filter = filters) }
+ .flatten().toSet()
}
-internal fun MutableMap.MutableEntry.toJsonPathWithValue(
+internal fun Pair.toJsonPathWithValue(
prefix: String = "",
limit: Int = -1,
filter: List>
@@ -64,12 +67,12 @@ internal fun MutableMap.MutableEntry.toJsonPathWithValue(
}
// compose the path key
val key = if (prefix == "") {
- this.key
+ this.first
} else {
- "$prefix.${this.key}"
+ "$prefix.${this.first}"
}
- val value = this.value
+ val value = this.second
return if (value != null && value.isPrimitiveType()) {
// check the filters
@@ -86,7 +89,12 @@ internal fun MutableMap.MutableEntry.toJsonPathWithValue(
listOf(key to value)
} else if (value is Map<*, *>) {
@Suppress("UNCHECKED_CAST")
- (value as Map).toMutableMap().entries.map { it.toJsonPathWithValue(key, limit, filter) }.flatten()
+ (value as Map).entries
+ .map { it.toPair() }
+ .map { it.toJsonPathWithValue(key, limit, filter) }
+ .flatten()
+ } else if (value is List<*>) {
+ value.map { (key to it).toJsonPathWithValue(prefix, limit, filter) }.flatten()
} else {
// ignore complex objects
listOf()
diff --git a/integration/common/variable-serializer/src/test/kotlin/JsonPathWithValueTest.kt b/integration/common/variable-serializer/src/test/kotlin/JsonPathWithValueTest.kt
index 5aa7661b6..d7a5e94fd 100644
--- a/integration/common/variable-serializer/src/test/kotlin/JsonPathWithValueTest.kt
+++ b/integration/common/variable-serializer/src/test/kotlin/JsonPathWithValueTest.kt
@@ -41,10 +41,10 @@ internal class JsonPathWithValueTest {
val result = payload.toJsonPathsWithValues(limit = -1)
- assertThat(result.keys).containsExactlyInAnyOrderElementsOf(payload.keys)
+ assertThat(result.keys()).containsExactlyInAnyOrderElementsOf(payload.keys)
payload.entries.forEach {
- assertThat(result).containsKey(it.key)
- assertThat(result[it.key]).isEqualTo(it.value)
+ assertThat(result.keys()).contains(it.key)
+ assertThat(result.first { entry -> entry.first == it.key }.second).isEqualTo(it.value)
}
}
@@ -72,7 +72,7 @@ internal class JsonPathWithValueTest {
val result = deep.toJsonPathsWithValues(limit = -1)
- assertThat(result.keys).containsExactlyInAnyOrderElementsOf(
+ assertThat(result.keys()).containsExactlyInAnyOrderElementsOf(
flat.keys.plus(
listOf(
"key-map.child1",
@@ -82,13 +82,13 @@ internal class JsonPathWithValueTest {
)
)
flat.entries.forEach {
- assertThat(result).containsKey(it.key)
- assertThat(result[it.key]).isEqualTo(it.value)
+ assertThat(result.keys()).contains(it.key)
+ assertThat(result.first { entry -> entry.first == it.key }.second).isEqualTo(it.value)
}
- assertThat(result["key-map.child1"]).isEqualTo("string")
- assertThat(result["key-map.child2.grand-child1"]).isEqualTo("grand-child-value")
- assertThat(result["key-map.child2.grand-child2"]).isEqualTo(451.01F)
+ assertThat(result).contains("key-map.child1" to "string")
+ assertThat(result).contains("key-map.child2.grand-child1" to "grand-child-value")
+ assertThat(result).contains("key-map.child2.grand-child2" to 451.01F)
}
@Test
@@ -115,7 +115,7 @@ internal class JsonPathWithValueTest {
val result = deep.toJsonPathsWithValues(limit = 1)
- assertThat(result.keys).containsExactlyInAnyOrderElementsOf(
+ assertThat(result.keys()).containsExactlyInAnyOrderElementsOf(
flat.keys.plus(
listOf(
"key-map.child1"
@@ -123,11 +123,11 @@ internal class JsonPathWithValueTest {
)
)
flat.entries.forEach {
- assertThat(result).containsKey(it.key)
- assertThat(result[it.key]).isEqualTo(it.value)
+ assertThat(result.keys()).contains(it.key)
+ assertThat(result).contains(it.key to it.value)
}
- assertThat(result["key-map.child1"]).isEqualTo("string")
- assertThat(result["key-map.child2"]).isNull()
+ assertThat(result).contains("key-map.child1" to "string")
+ assertThat(result.keys()).doesNotContain("key-map.child2")
}
@Test
@@ -145,7 +145,7 @@ internal class JsonPathWithValueTest {
put("key", "value")
put("to-ignore", "should not be there")
}
- assertThat(payload.toJsonPathsWithValues(filters = listOf(eqExclude("to-ignore")))).containsOnlyKeys("key")
+ assertThat(payload.toJsonPathsWithValues(filters = listOf(eqExclude("to-ignore"))).keys()).containsOnly("key")
}
@@ -155,7 +155,7 @@ internal class JsonPathWithValueTest {
put("key", "value")
put("to-ignore", "should not be there")
}
- assertThat(payload.toJsonPathsWithValues(filters = listOf(eqInclude("key")))).containsOnlyKeys("key")
+ assertThat(payload.toJsonPathsWithValues(filters = listOf(eqInclude("key"))).keys()).containsOnly("key")
}
@Test
@@ -172,8 +172,8 @@ internal class JsonPathWithValueTest {
eqInclude("include2"),
eqExclude("to-ignore")
)
- )
- ).containsOnlyKeys("include1", "include2")
+ ).keys()
+ ).containsOnly("include1", "include2")
}
@Test
@@ -188,8 +188,8 @@ internal class JsonPathWithValueTest {
eqInclude("include1.key"),
eqInclude("include2"),
)
- )
- ).containsOnlyKeys("include1.key", "include2")
+ ).keys()
+ ).containsOnly("include1.key", "include2")
}
@@ -199,7 +199,7 @@ internal class JsonPathWithValueTest {
put("key", "value")
put("other", "value2")
}
- assertThat(payload.toJsonPathsWithValues(filters = listOf(all()))).containsOnlyKeys("key", "other")
+ assertThat(payload.toJsonPathsWithValues(filters = listOf(all())).keys()).containsOnly("key", "other")
}
@Test
@@ -211,4 +211,46 @@ internal class JsonPathWithValueTest {
assertThat(payload.toJsonPathsWithValues(filters = listOf(none()))).isEmpty()
}
+ @Test
+ fun `should map list to multiple pairs`() {
+ val payload = createVariables().apply {
+ put("multiple", listOf("value-1", "value-2"))
+ }
+
+ val result = payload.toJsonPathsWithValues()
+
+ assertThat(result).hasSize(2)
+ assertThat(result).contains("multiple" to "value-1")
+ assertThat(result).contains("multiple" to "value-2")
+ }
+
+ @Test
+ fun `should map list of lists`() {
+ val payload = createVariables().apply {
+ put("multiple", listOf(listOf("value-1", "value-2"), listOf("value-3", "value-4")))
+ }
+ val result = payload.toJsonPathsWithValues()
+
+ assertThat(result).hasSize(4)
+ assertThat(result).contains("multiple" to "value-1")
+ assertThat(result).contains("multiple" to "value-2")
+ assertThat(result).contains("multiple" to "value-3")
+ assertThat(result).contains("multiple" to "value-4")
+ }
+
+ @Test
+ fun `should map list of maps`() {
+ val payload = createVariables().apply {
+ put("multiple", listOf(mapOf("deepKey1" to "value-1"), mapOf("deepKey2" to "value-2")))
+ }
+ val result = payload.toJsonPathsWithValues()
+
+ assertThat(result).hasSize(2)
+ assertThat(result).contains("multiple.deepKey1" to "value-1")
+ assertThat(result).contains("multiple.deepKey2" to "value-2")
+ }
+}
+
+internal fun Set>.keys(): List {
+ return this.map { it.first }
}
diff --git a/integration/common/variable-serializer/src/test/kotlin/VariableSerializerTest.kt b/integration/common/variable-serializer/src/test/kotlin/VariableSerializerTest.kt
index f636d14c9..9d423d687 100755
--- a/integration/common/variable-serializer/src/test/kotlin/VariableSerializerTest.kt
+++ b/integration/common/variable-serializer/src/test/kotlin/VariableSerializerTest.kt
@@ -124,4 +124,15 @@ class VariableSerializerTest {
val elements = expectedPojoMap[Pojo1::anotherKey.name] as List