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-core/pom.xml b/core/datapool/datapool-core/pom.xml index a38ace6c2..6eca08da9 100644 --- a/core/datapool/datapool-core/pom.xml +++ b/core/datapool/datapool-core/pom.xml @@ -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/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()