├── .codacy.yaml
├── .editorconfig
├── .github
├── ISSUE_TEMPLATE.md
├── ISSUE_TEMPLATE
│ ├── 1_bug_report.md
│ └── 2_feature_request.md
├── dependabot.yml
├── release-notes.yml
└── workflows
│ ├── ci.yml
│ ├── codacy.yml
│ ├── docs.yml
│ ├── release-notes.yml
│ └── release.yml
├── .gitignore
├── .mvn
└── wrapper
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── LICENSE
├── README.md
├── SECURITY.md
├── bom
├── datapool-dependencies
│ └── pom.xml
├── parent
│ └── pom.xml
└── taskpool-dependencies
│ └── pom.xml
├── codecov.yml
├── core
├── bus-jackson
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── kotlin
│ │ │ └── io
│ │ │ │ └── holunda
│ │ │ │ └── polyflow
│ │ │ │ └── bus
│ │ │ │ └── jackson
│ │ │ │ ├── DataEntryStateTypeMappingModule.kt
│ │ │ │ ├── JacksonExtensions.kt
│ │ │ │ ├── JsonAutoDetectAnyVisibility.kt
│ │ │ │ ├── KotlinTypeInfo.kt
│ │ │ │ ├── VariableMapTypeMappingModule.kt
│ │ │ │ └── config
│ │ │ │ └── FallbackPayloadObjectMapperAutoConfiguration.kt
│ │ └── resources
│ │ │ └── META-INF
│ │ │ └── spring
│ │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports
│ │ └── test
│ │ └── kotlin
│ │ └── io
│ │ └── holunda
│ │ └── polyflow
│ │ ├── bus
│ │ └── jackson
│ │ │ ├── CreateTaskCommandSerializationTest.kt
│ │ │ ├── DataEntryCommandsSerializationTest.kt
│ │ │ └── DeserializersTest.kt
│ │ └── view
│ │ └── query
│ │ ├── data
│ │ └── DataEntryQueriesDeserializationTest.kt
│ │ ├── process
│ │ ├── ProcessDefinitionQueriesDeserializationTest.kt
│ │ ├── ProcessInstanceQueriesDeserializationTest.kt
│ │ └── variable
│ │ │ └── ProcessInstanceQueriesDeserializationTest.kt
│ │ └── task
│ │ └── TaskQueriesDeserializationTest.kt
├── datapool
│ ├── datapool-api
│ │ ├── pom.xml
│ │ └── src
│ │ │ ├── main
│ │ │ └── kotlin
│ │ │ │ └── io
│ │ │ │ └── holunda
│ │ │ │ └── camunda
│ │ │ │ └── taskpool
│ │ │ │ └── api
│ │ │ │ └── business
│ │ │ │ ├── AuthorizationChange.kt
│ │ │ │ ├── DataEntryChange.kt
│ │ │ │ ├── DataEntryCommands.kt
│ │ │ │ ├── DataEntryState.kt
│ │ │ │ ├── DataIdentity.kt
│ │ │ │ ├── Modification.kt
│ │ │ │ ├── ProcessingType.kt
│ │ │ │ ├── WithCorrelations.kt
│ │ │ │ └── WithPayload.kt
│ │ │ └── test
│ │ │ └── kotlin
│ │ │ └── io
│ │ │ └── holunda
│ │ │ └── camunda
│ │ │ └── taskpool
│ │ │ └── api
│ │ │ └── business
│ │ │ └── ProcessingTypeTest.kt
│ ├── datapool-core
│ │ ├── pom.xml
│ │ └── src
│ │ │ ├── main
│ │ │ └── kotlin
│ │ │ │ └── io
│ │ │ │ └── holunda
│ │ │ │ └── polyflow
│ │ │ │ └── datapool
│ │ │ │ ├── Helpers.kt
│ │ │ │ └── core
│ │ │ │ ├── DataPoolCoreAxonConfiguration.kt
│ │ │ │ ├── DataPoolCoreConfiguration.kt
│ │ │ │ ├── DataPoolProperties.kt
│ │ │ │ ├── DeletionStrategy.kt
│ │ │ │ ├── DeletionStrategyValue.kt
│ │ │ │ ├── EnablePolyflowDataPool.kt
│ │ │ │ ├── business
│ │ │ │ ├── CreateOrUpdateCommandHandler.kt
│ │ │ │ ├── DataEntryAggregate.kt
│ │ │ │ └── upcaster
│ │ │ │ │ ├── DataEntryEventUpcaster.kt
│ │ │ │ │ └── DatapoolEventUpcasters.kt
│ │ │ │ └── repository
│ │ │ │ ├── FirstEventOnlyEventSourcingRepository.kt
│ │ │ │ └── FirstEventOnlyEventSourcingRepositoryBuilder.kt
│ │ │ └── test
│ │ │ ├── kotlin
│ │ │ └── io
│ │ │ │ └── holunda
│ │ │ │ └── polyflow
│ │ │ │ └── datapool
│ │ │ │ └── core
│ │ │ │ ├── DataPoolCoreDeletionStrategyConfigurationTest.kt
│ │ │ │ ├── business
│ │ │ │ ├── DataEntryAggregateFirstEventOnlyEventSourcingRepositoryITest.kt
│ │ │ │ ├── DataEntryAggregateTest.kt
│ │ │ │ ├── repository
│ │ │ │ │ └── FirstEventOnlyEventSourcingRepositoryBuilderTest.kt
│ │ │ │ └── upcaster
│ │ │ │ │ └── DataEntryCreatedEventUpcasterTest.kt
│ │ │ │ └── itest
│ │ │ │ └── TestApplication.kt
│ │ │ └── resources
│ │ │ ├── application-itest-first-event-only.yml
│ │ │ ├── banner.txt
│ │ │ ├── db
│ │ │ └── migrations
│ │ │ │ ├── V0_0_1__axon.sql
│ │ │ │ ├── V0_0_2__axon_dlq.sql
│ │ │ │ └── V0_0_3__axon_sequence_per_table.sql
│ │ │ └── logback.xml
│ ├── datapool-event
│ │ ├── pom.xml
│ │ └── src
│ │ │ ├── main
│ │ │ └── kotlin
│ │ │ │ └── io
│ │ │ │ └── holunda
│ │ │ │ └── camunda
│ │ │ │ └── taskpool
│ │ │ │ └── api
│ │ │ │ └── business
│ │ │ │ ├── BusinessEvents.kt
│ │ │ │ └── Mappers.kt
│ │ │ └── test
│ │ │ └── kotlin
│ │ │ └── io
│ │ │ └── holunda
│ │ │ └── camunda
│ │ │ └── taskpool
│ │ │ └── api
│ │ │ └── business
│ │ │ └── MappersTest.kt
│ └── pom.xml
├── spring-utils
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ └── kotlin
│ │ │ └── io
│ │ │ └── holunda
│ │ │ └── polyflow
│ │ │ └── spring
│ │ │ └── ApplicationNameBeanPostProcessor.kt
│ │ └── test
│ │ └── kotlin
│ │ └── io
│ │ └── holunda
│ │ └── polyflow
│ │ ├── datapool
│ │ └── DataEntrySenderProperties.kt
│ │ └── spring
│ │ └── ApplicationNameBeanPostProcessorTest.kt
└── taskpool
│ ├── pom.xml
│ ├── taskpool-api
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ └── kotlin
│ │ │ └── io
│ │ │ └── holunda
│ │ │ └── camunda
│ │ │ └── taskpool
│ │ │ └── api
│ │ │ ├── process
│ │ │ ├── definition
│ │ │ │ └── ProcessDefinitionCommand.kt
│ │ │ ├── instance
│ │ │ │ └── ProcessInstanceCommand.kt
│ │ │ └── variable
│ │ │ │ ├── ProcessVariableCommands.kt
│ │ │ │ └── ProcessVariableValue.kt
│ │ │ └── task
│ │ │ ├── CamundaTaskEventType.kt
│ │ │ ├── EngineTaskCommand.kt
│ │ │ ├── EngineTaskCommandFilter.kt
│ │ │ ├── EngineTaskCommandSorter.kt
│ │ │ ├── EngineTaskCommands.kt
│ │ │ ├── InteractionTaskCommand.kt
│ │ │ ├── InteractionTaskCommands.kt
│ │ │ ├── SourceReference.kt
│ │ │ ├── TaskIdentity.kt
│ │ │ ├── TaskIdentityWithPayloadAndCorrelations.kt
│ │ │ ├── WithFormKey.kt
│ │ │ ├── WithPayload.kt
│ │ │ └── WithTaskId.kt
│ │ └── test
│ │ └── kotlin
│ │ └── io
│ │ └── holunda
│ │ └── polyflow
│ │ └── taskpool
│ │ └── sender
│ │ └── CommandSorterTest.kt
│ ├── taskpool-core
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ └── kotlin
│ │ │ └── io
│ │ │ └── holunda
│ │ │ └── polyflow
│ │ │ └── taskpool
│ │ │ └── core
│ │ │ ├── EnableTaskPool.kt
│ │ │ ├── TaskPoolCoreConfiguration.kt
│ │ │ ├── process
│ │ │ ├── ProcessDefinitionAggregate.kt
│ │ │ ├── ProcessDefinitionRegisterCommandHandler.kt
│ │ │ ├── ProcessInstanceAggregate.kt
│ │ │ └── ProcessInstanceVariablesChangeHandler.kt
│ │ │ └── task
│ │ │ ├── ExternalCommandHandler.kt
│ │ │ ├── TaskAggregate.kt
│ │ │ └── TaskAggregateEngineTaskCommandFilter.kt
│ │ └── test
│ │ ├── kotlin
│ │ └── io
│ │ │ └── holunda
│ │ │ └── polyflow
│ │ │ └── taskpool
│ │ │ └── core
│ │ │ ├── TestApplication.kt
│ │ │ ├── process
│ │ │ ├── ProcessDefinitionHandlerAggregateITest.kt
│ │ │ ├── ProcessInstanceAggregateTest.kt
│ │ │ └── ProcessInstanceVariableChangeAggregateITest.kt
│ │ │ └── task
│ │ │ ├── TaskAggregateClaimTest.kt
│ │ │ ├── TaskAggregateDeferTest.kt
│ │ │ ├── TaskAggregateEngineCommandTest.kt
│ │ │ ├── TaskAssignmentChangeTest.kt
│ │ │ ├── TaskAttributeUpdateTest.kt
│ │ │ ├── TaskHandlerAggregateITest.kt
│ │ │ └── TaskMarkToBeCompletedTest.kt
│ │ └── resources
│ │ ├── application-itest.yml
│ │ ├── banner.txt
│ │ ├── db
│ │ └── migrations
│ │ │ ├── V0_0_1__axon.sql
│ │ │ ├── V0_0_2__axon_dlq.sql
│ │ │ └── V0_0_3__axon_sequence_per_table.sql
│ │ └── logback.xml
│ └── taskpool-event
│ ├── pom.xml
│ └── src
│ ├── main
│ └── kotlin
│ │ └── io
│ │ └── holunda
│ │ └── camunda
│ │ └── taskpool
│ │ ├── api
│ │ ├── process
│ │ │ ├── definition
│ │ │ │ └── ProcessDefinitionEvents.kt
│ │ │ ├── instance
│ │ │ │ └── ProcessInstanceEvents.kt
│ │ │ └── variable
│ │ │ │ └── ProcessVariableEvents.kt
│ │ └── task
│ │ │ └── TaskEvents.kt
│ │ ├── mapper
│ │ ├── process
│ │ │ ├── ProcessDefinitionMapper.kt
│ │ │ └── ProcessInstanceMapper.kt
│ │ └── task
│ │ │ ├── TaskEventMappers.kt
│ │ │ └── TaskFactoryMethods.kt
│ │ ├── model
│ │ └── Task.kt
│ │ └── upcast
│ │ ├── AnnotatedEventUpcaster.kt
│ │ ├── AnnotationBasedSingleEventUpcaster.kt
│ │ ├── RepresentationContentType.kt
│ │ ├── TaskpoolEventUpcasters.kt
│ │ ├── definition
│ │ └── ProcessDefinitionEventUpcasters.kt
│ │ └── task
│ │ ├── TaskAttributeUpdatedEngineEvent4To5Upcaster.kt
│ │ └── TaskEventEventUpcasterForPatchingSourceRefernce.kt
│ └── test
│ └── kotlin
│ └── io
│ └── holunda
│ └── camunda
│ └── taskpool
│ └── upcast
│ ├── ProcessDefinitionUpcasterTest.kt
│ ├── TaskEventSourceReferenceUpcasterTest.kt
│ └── TaskUpdateEventPayloadAndCorrelationUpcasterTest.kt
├── detekt.yml
├── docs
├── CNAME
├── assets
│ └── img
│ │ ├── bg.svg
│ │ └── logo-negative.svg
├── developer-guide
│ ├── contribution.md
│ └── project-setup.md
├── examples
│ ├── example-approval.md
│ ├── example-components
│ │ ├── index.md
│ │ ├── pa-backend.md
│ │ ├── pa-frontend.md
│ │ ├── pp-backend.md
│ │ ├── pp-frontend.md
│ │ └── user-management.md
│ ├── index.md
│ └── scenarios
│ │ ├── distributed-axon-server-local.md
│ │ ├── distributed-axon-server.md
│ │ ├── distributed-with-kafka.md
│ │ ├── index.md
│ │ └── single-node.md
├── getting-started
│ └── index.md
├── img
│ ├── Negative@2x.png
│ ├── Positive@2x.png
│ ├── api.graphml
│ ├── architecture-collector.graphml
│ ├── architecture-collector.png
│ ├── collector-building-blocks.graphml
│ ├── collector-building-blocks.png
│ ├── deployment-axon-server-events-only.graphml
│ ├── deployment-axon-server-events-only.png
│ ├── deployment-axon-server.graphml
│ ├── deployment-axon-server.png
│ ├── deployment-messaging.graphml
│ ├── deployment-messaging.png
│ ├── deployment-single.graphml
│ ├── deployment-single.png
│ ├── example_amend_request.png
│ ├── example_approve_request.png
│ ├── example_archive_business_object.png
│ ├── example_archive_completed.png
│ ├── example_start_form.png
│ ├── example_tasklist_approve_data.png
│ ├── example_tasklist_approve_description.png
│ ├── favicon.ico
│ ├── favicon.png
│ ├── polyflow-65x61.png
│ ├── polyflow-hero-530x406.png
│ ├── process-platform-architecture.graphml
│ ├── process-platform-architecture.png
│ ├── process_approve_request.png
│ ├── scenario_kafka_messaging_overview.png
│ ├── scenario_kafka_messaging_tx_view.png
│ ├── scenario_kafka_to_tasklist_detail.png
│ ├── scenario_process_application_to_kafka_detail.png
│ ├── tasklist-angular-classic.png
│ └── tasklist-angular-data.png
├── index.md
├── introduction
│ ├── concepts.md
│ ├── deployment.md
│ ├── features.md
│ ├── index.md
│ └── solution-architecture.md
├── migration-guide
│ └── index.md
├── reference-guide
│ ├── components
│ │ ├── camunda-interaction-client.md
│ │ ├── camunda-starter.md
│ │ ├── camunda-taskpool-collector.md
│ │ ├── common-datapool-sender.md
│ │ ├── common-taskpool-sender.md
│ │ ├── core-datapool.md
│ │ ├── core-taskpool.md
│ │ ├── index.md
│ │ ├── other-bus-jackson.md
│ │ ├── other-tasklist-url-resolver.md
│ │ ├── other-variable-serializer.md
│ │ ├── view-api-client.md
│ │ ├── view-api.md
│ │ ├── view-form-url-resolver.md
│ │ ├── view-jpa.md
│ │ ├── view-mongo.md
│ │ └── view-simple.md
│ ├── configuration
│ │ ├── core-datapool-aggregate-tuning.md
│ │ ├── index.md
│ │ ├── local-core-deployment.md
│ │ ├── persistence.md
│ │ └── view-mongo.md
│ └── index.md
├── requirements.txt
└── stylesheets
│ └── extra.css
├── integration
├── camunda-bpm
│ ├── engine-client
│ │ ├── pom.xml
│ │ └── src
│ │ │ ├── main
│ │ │ ├── kotlin
│ │ │ │ └── io
│ │ │ │ │ └── holunda
│ │ │ │ │ └── polyflow
│ │ │ │ │ └── client
│ │ │ │ │ └── camunda
│ │ │ │ │ ├── CamundaEngineClientAutoConfiguration.kt
│ │ │ │ │ ├── CamundaEngineClientProperties.kt
│ │ │ │ │ ├── EnableCamundaEngineClient.kt
│ │ │ │ │ ├── process
│ │ │ │ │ └── ProcessStarter.kt
│ │ │ │ │ └── task
│ │ │ │ │ └── TaskEventHandlers.kt
│ │ │ └── resources
│ │ │ │ └── META-INF
│ │ │ │ └── spring
│ │ │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports
│ │ │ └── test
│ │ │ ├── kotlin
│ │ │ └── io
│ │ │ │ └── holunda
│ │ │ │ └── polyflow
│ │ │ │ └── client
│ │ │ │ └── camunda
│ │ │ │ ├── CamundaEngineClientPropertiesExtendedTest.kt
│ │ │ │ ├── CamundaEngineClientPropertiesITest.kt
│ │ │ │ ├── CamundaEngineClientPropertiesTestApplication.kt
│ │ │ │ ├── process
│ │ │ │ └── ProcessStarterTest.kt
│ │ │ │ └── task
│ │ │ │ └── TaskEventHandlerTest.kt
│ │ │ └── resources
│ │ │ ├── application-properties-itest.yaml
│ │ │ ├── banner.txt
│ │ │ └── logback.xml
│ ├── pom.xml
│ ├── springboot-autoconfigure
│ │ ├── pom.xml
│ │ └── src
│ │ │ ├── main
│ │ │ └── kotlin
│ │ │ │ └── io
│ │ │ │ └── holunda
│ │ │ │ └── polyflow
│ │ │ │ └── taskpool
│ │ │ │ ├── EnableTaskpoolEngineSupport.kt
│ │ │ │ └── TaskpoolEngineSupportConfiguration.kt
│ │ │ └── test
│ │ │ ├── kotlin
│ │ │ └── io
│ │ │ │ └── holunda
│ │ │ │ └── polyflow
│ │ │ │ └── taskpool
│ │ │ │ └── TaskpoolEngineSupportConfigurationITest.kt
│ │ │ └── resources
│ │ │ ├── application.yml
│ │ │ ├── banner.txt
│ │ │ └── logback.xml
│ ├── springboot-starter
│ │ ├── pom.xml
│ │ └── src
│ │ │ ├── main
│ │ │ └── resources
│ │ │ │ └── META-INF
│ │ │ │ └── spring
│ │ │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports
│ │ │ └── test
│ │ │ ├── kotlin
│ │ │ └── TaskpoolStarterITest.kt
│ │ │ └── resources
│ │ │ ├── application.yml
│ │ │ └── banner.txt
│ ├── taskpool-collector
│ │ ├── pom.xml
│ │ └── src
│ │ │ ├── main
│ │ │ ├── kotlin
│ │ │ │ └── io
│ │ │ │ │ └── holunda
│ │ │ │ │ └── polyflow
│ │ │ │ │ └── taskpool
│ │ │ │ │ ├── CamundaEngineExtensions.kt
│ │ │ │ │ ├── DelegateTaskExtensions.kt
│ │ │ │ │ ├── EnableCamundaTaskpoolCollector.kt
│ │ │ │ │ ├── HistoricProcessInstanceEventExtensions.kt
│ │ │ │ │ ├── HistoricScopeInstanceEventExtensions.kt
│ │ │ │ │ ├── HistoricVariableInstanceExtensions.kt
│ │ │ │ │ ├── ProcessDefinitionEntityExtensions.kt
│ │ │ │ │ ├── TaskEntityExtensions.kt
│ │ │ │ │ ├── VariableMapExtensions.kt
│ │ │ │ │ └── collector
│ │ │ │ │ ├── CamundaTaskpoolCollectorConfiguration.kt
│ │ │ │ │ ├── CamundaTaskpoolCollectorProperties.kt
│ │ │ │ │ ├── FallbackProcessVariablesCorrelatorConfiguration.kt
│ │ │ │ │ ├── FallbackProcessVariablesFilterConfiguration.kt
│ │ │ │ │ ├── process
│ │ │ │ │ ├── definition
│ │ │ │ │ │ ├── ProcessDefinitionCollectorConfiguration.kt
│ │ │ │ │ │ ├── ProcessDefinitionProcessor.kt
│ │ │ │ │ │ ├── ProcessDefinitionService.kt
│ │ │ │ │ │ ├── RefreshProcessDefinitionRegistrationParseListener.kt
│ │ │ │ │ │ └── RefreshProcessDefinitionsEventingJobHandler.kt
│ │ │ │ │ ├── instance
│ │ │ │ │ │ ├── ProcessInstanceCollectorConfiguration.kt
│ │ │ │ │ │ ├── ProcessInstanceEventCollectorService.kt
│ │ │ │ │ │ └── ProcessInstanceProcessor.kt
│ │ │ │ │ └── variable
│ │ │ │ │ │ ├── ProcessVariableCollectorConfiguration.kt
│ │ │ │ │ │ ├── ProcessVariableEventCollectorService.kt
│ │ │ │ │ │ └── ProcessVariableProcessor.kt
│ │ │ │ │ └── task
│ │ │ │ │ ├── BuiltInPublishDelegateParseListener.kt
│ │ │ │ │ ├── TaskAssigner.kt
│ │ │ │ │ ├── TaskCollectorConfiguration.kt
│ │ │ │ │ ├── TaskCommandProcessor.kt
│ │ │ │ │ ├── TaskEventCollectorService.kt
│ │ │ │ │ ├── TaskServiceCollectorService.kt
│ │ │ │ │ ├── TaskVariableLoader.kt
│ │ │ │ │ ├── VariablesEnricher.kt
│ │ │ │ │ ├── assigner
│ │ │ │ │ ├── EmptyTaskAssigner.kt
│ │ │ │ │ ├── ProcessVariableChangeAssigningService.kt
│ │ │ │ │ ├── ProcessVariableTaskAssignerMapping.kt
│ │ │ │ │ └── ProcessVariablesTaskAssigner.kt
│ │ │ │ │ └── enricher
│ │ │ │ │ ├── EmptyTaskCommandEnricher.kt
│ │ │ │ │ ├── ProcessVariableCorrelation.kt
│ │ │ │ │ ├── ProcessVariableFilter.kt
│ │ │ │ │ ├── ProcessVariablesCorrelator.kt
│ │ │ │ │ ├── ProcessVariablesFilter.kt
│ │ │ │ │ ├── ProcessVariablesTaskCommandEnricher.kt
│ │ │ │ │ ├── ProcessVariablesTaskCommandEnricherFilter.kt
│ │ │ │ │ └── VariableFilter.kt
│ │ │ └── resources
│ │ │ │ └── META-INF
│ │ │ │ └── spring
│ │ │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports
│ │ │ └── test
│ │ │ ├── kotlin
│ │ │ └── io
│ │ │ │ └── holunda
│ │ │ │ └── polyflow
│ │ │ │ └── taskpool
│ │ │ │ ├── collector
│ │ │ │ ├── properties
│ │ │ │ │ ├── CamundaTaskpoolCollectorPropertiesExtendedTest.kt
│ │ │ │ │ └── CamundaTaskpoolCollectorPropertiesITest.kt
│ │ │ │ └── task
│ │ │ │ │ └── enricher
│ │ │ │ │ ├── ProcessVariablesCorrelatorTest.kt
│ │ │ │ │ └── ProcessVariablesFilterTest.kt
│ │ │ │ └── itest
│ │ │ │ ├── JacksonDataFormatConfigurator.kt
│ │ │ │ ├── TestDriver.kt
│ │ │ │ ├── tx
│ │ │ │ ├── ProcessDefinitionServiceITest.kt
│ │ │ │ └── TaskCollectorITest.kt
│ │ │ │ └── txjob
│ │ │ │ └── TaskTxJobSenderITest.kt
│ │ │ └── resources
│ │ │ ├── META-INF
│ │ │ └── services
│ │ │ │ └── org.camunda.spin.spi.DataFormatConfigurator
│ │ │ ├── application-collector-tx-itest.yml
│ │ │ ├── application-properties-itest.yml
│ │ │ ├── application-txjob-sender-itest.yml
│ │ │ ├── banner.txt
│ │ │ ├── db
│ │ │ └── migrations
│ │ │ │ └── h2-postgresql
│ │ │ │ ├── V0_0_1__postgres_engine_7.21.0.sql
│ │ │ │ ├── V0_0_2__postgres_identity_7.21.0.sql
│ │ │ │ └── V0_0_3__postgres_engine_7.21_to_7.22.sql
│ │ │ ├── itest
│ │ │ └── message_start_event.bpmn
│ │ │ └── logback.xml
│ └── taskpool-job-sender
│ │ ├── pom.xml
│ │ └── src
│ │ ├── main
│ │ ├── kotlin
│ │ │ └── io
│ │ │ │ └── holunda
│ │ │ │ └── polyflow
│ │ │ │ └── taskpool
│ │ │ │ └── sender
│ │ │ │ ├── CamundaJobSenderConfiguration.kt
│ │ │ │ ├── EngineTaskCommandsSendingJobHandler.kt
│ │ │ │ ├── EngineTaskCommandsSendingJobHandlerConfiguration.kt
│ │ │ │ └── TxAwareAccumulatingCamundaJobEngineTaskCommandSender.kt
│ │ └── resources
│ │ │ └── META-INF
│ │ │ └── spring
│ │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports
│ │ └── test
│ │ └── kotlin
│ │ └── io
│ │ └── holunda
│ │ └── polyflow
│ │ └── taskpool
│ │ └── sender
│ │ ├── EngineTaskCommandsByteSerializationTest.kt
│ │ ├── EngineTaskCommandsSendingJobHandlerConfigurationTest.kt
│ │ └── TestObjectFactory.kt
└── common
│ ├── datapool-sender
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ └── kotlin
│ │ │ └── io
│ │ │ └── holunda
│ │ │ └── polyflow
│ │ │ └── datapool
│ │ │ ├── DataEntrySenderConfiguration.kt
│ │ │ ├── DataEntrySenderProperties.kt
│ │ │ ├── DataEntrySenderType.kt
│ │ │ ├── DataPoolSenderProperties.kt
│ │ │ ├── EnableDataEntrySender.kt
│ │ │ ├── projector
│ │ │ ├── DataEntryProjectionSupplier.kt
│ │ │ └── DataEntryProjector.kt
│ │ │ └── sender
│ │ │ ├── AbstractDataEntryCommandSender.kt
│ │ │ ├── AbstractTxAwareAccumulatingDataEntryCommandSender.kt
│ │ │ ├── DataEntryCommandSender.kt
│ │ │ ├── DirectTxAwareAccumulatingDataEntryCommandSender.kt
│ │ │ ├── SimpleDataEntryCommandSender.kt
│ │ │ └── gateway
│ │ │ ├── AxonCommandListGateway.kt
│ │ │ ├── CommandListGateway.kt
│ │ │ ├── LoggingDataEntryCommandErrorHandler.kt
│ │ │ └── LoggingDataEntryCommandSuccessHandler.kt
│ │ └── test
│ │ ├── kotlin
│ │ └── io
│ │ │ └── holunda
│ │ │ └── polyflow
│ │ │ └── datapool
│ │ │ ├── DataEntryDataPoolSenderPropertiesExtendedTest.kt
│ │ │ ├── DataEntryDataPoolSenderPropertiesITest.kt
│ │ │ └── PropertiesTestApplication.kt
│ │ └── resources
│ │ ├── application-properties-itest.yml
│ │ ├── banner.txt
│ │ └── logback.xml
│ ├── pom.xml
│ ├── tasklist-url-resolver
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── kotlin
│ │ │ └── io
│ │ │ │ └── holunda
│ │ │ │ └── polyflow
│ │ │ │ └── urlresolver
│ │ │ │ ├── FallbackTasklistUrlResolverAutoConfiguration.kt
│ │ │ │ ├── TasklistUrlProperties.kt
│ │ │ │ └── TasklistUrlResolver.kt
│ │ └── resources
│ │ │ └── META-INF
│ │ │ └── spring
│ │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports
│ │ └── test
│ │ ├── kotlin
│ │ └── io
│ │ │ └── holunda
│ │ │ └── polyflow
│ │ │ └── urlresolver
│ │ │ ├── DataEntrySenderPropertiesExtendedTest.kt
│ │ │ ├── DataEntrySenderPropertiesITest.kt
│ │ │ └── PropertiesTestApplication.kt
│ │ └── resources
│ │ ├── banner.txt
│ │ └── logback.xml
│ ├── taskpool-sender
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ └── kotlin
│ │ │ └── io
│ │ │ └── holunda
│ │ │ └── polyflow
│ │ │ └── taskpool
│ │ │ ├── EnableTaskpoolSender.kt
│ │ │ ├── JacksonExtensions.kt
│ │ │ ├── ProcessInstanceValueExtensions.kt
│ │ │ └── sender
│ │ │ ├── GenericTaskPublisher.kt
│ │ │ ├── SenderConfiguration.kt
│ │ │ ├── SenderProperties.kt
│ │ │ ├── api
│ │ │ └── Task.kt
│ │ │ ├── gateway
│ │ │ ├── AxonCommandListGateway.kt
│ │ │ ├── CommandListGateway.kt
│ │ │ ├── LoggingTaskCommandErrorHandler.kt
│ │ │ └── LoggingTaskCommandSuccessHandler.kt
│ │ │ ├── process
│ │ │ ├── definition
│ │ │ │ ├── ProcessDefinitionCommandSender.kt
│ │ │ │ └── SimpleProcessDefinitionCommandSender.kt
│ │ │ ├── instance
│ │ │ │ ├── ProcessInstanceCommandSender.kt
│ │ │ │ └── SimpleProcessInstanceCommandSender.kt
│ │ │ └── variable
│ │ │ │ ├── ProcessVariableCommandSender.kt
│ │ │ │ ├── SimpleProcessVariableCommandSender.kt
│ │ │ │ ├── SingleProcessVariableCommands.kt
│ │ │ │ └── TxAwareAccumulatingProcessVariableCommandSender.kt
│ │ │ └── task
│ │ │ ├── AbstractTxAwareAccumulatingEngineTaskCommandSender.kt
│ │ │ ├── DirectTxAwareAccumulatingEngineTaskCommandSender.kt
│ │ │ ├── EngineTaskCommandSender.kt
│ │ │ ├── SimpleEngineTaskCommandSender.kt
│ │ │ └── accumulator
│ │ │ ├── CommandAccumulator.kt
│ │ │ ├── EngineTaskCommandIntentDetector.kt
│ │ │ ├── EngineTaskCommandProjectionErrorDetector.kt
│ │ │ ├── ProjectingCommandAccumulator.kt
│ │ │ ├── SimpleEngineTaskCommandIntentDetector.kt
│ │ │ ├── SortingCommandAccumulator.kt
│ │ │ └── projectProperties.kt
│ │ └── test
│ │ ├── kotlin
│ │ └── io
│ │ │ └── holunda
│ │ │ └── polyflow
│ │ │ └── taskpool
│ │ │ └── sender
│ │ │ ├── PropertiesTestApplication.kt
│ │ │ ├── SenderPropertiesExtendedTest.kt
│ │ │ ├── SenderPropertiesITest.kt
│ │ │ ├── gateway
│ │ │ └── AxonCommandListGatewayTest.kt
│ │ │ ├── process
│ │ │ └── variable
│ │ │ │ └── SimpleProcessVariableTest.kt
│ │ │ └── task
│ │ │ └── accumulator
│ │ │ ├── CommandAccumulatorTest.kt
│ │ │ ├── EngineTaskCommandIntentDetectorTest.kt
│ │ │ └── ProjectPropertiesTest.kt
│ │ └── resources
│ │ ├── banner.txt
│ │ └── logback.xml
│ └── variable-serializer
│ ├── pom.xml
│ └── src
│ ├── main
│ └── kotlin
│ │ ├── PathFilter.kt
│ │ └── VariableSerializer.kt
│ └── test
│ └── kotlin
│ ├── JsonPathWithValueTest.kt
│ ├── TestFixtures.kt
│ └── VariableSerializerTest.kt
├── mkdocs.yml
├── mvnw
├── mvnw.cmd
├── pom.xml
└── view
├── form-url-resolver
├── pom.xml
└── src
│ ├── main
│ └── kotlin
│ │ └── io
│ │ └── holunda
│ │ └── polyflow
│ │ └── urlresolver
│ │ ├── EnablePropertyBasedFormUrlResolver.kt
│ │ ├── FormUrlResolverProperties.kt
│ │ ├── PropertyBasedFormUrlResolver.kt
│ │ └── PropertyBasedFormUrlResolverConfiguration.kt
│ └── test
│ ├── kotlin
│ └── io
│ │ └── holunda
│ │ └── polyflow
│ │ └── urlresolver
│ │ └── FormUrlResolverTest.kt
│ └── resources
│ └── form-url-properties.yml
├── jpa
├── pom.xml
└── src
│ ├── main
│ └── kotlin
│ │ └── io
│ │ └── holunda
│ │ └── polyflow
│ │ └── view
│ │ └── jpa
│ │ ├── CountByApplication.kt
│ │ ├── EnablePolyflowJpaView.kt
│ │ ├── JpaPolyflowViewDataEntryService.kt
│ │ ├── JpaPolyflowViewProcessDefinitionService.kt
│ │ ├── JpaPolyflowViewProcessInstanceService.kt
│ │ ├── JpaPolyflowViewTaskService.kt
│ │ ├── PolyflowJpaViewConfiguration.kt
│ │ ├── PolyflowJpaViewProperties.kt
│ │ ├── SpecificationExt.kt
│ │ ├── auth
│ │ ├── AuthorizationPrincipal.kt
│ │ └── AuthorizationPrincipalType.kt
│ │ ├── data
│ │ ├── ConverterExt.kt
│ │ ├── DataEntryEntity.kt
│ │ ├── DataEntryEventHandler.kt
│ │ ├── DataEntryId.kt
│ │ ├── DataEntryPayloadAttributeEntity.kt
│ │ ├── DataEntryPayloadAttributeEntityId.kt
│ │ ├── DataEntryRepository.kt
│ │ ├── DataEntryStateEmbeddable.kt
│ │ └── ProtocolElement.kt
│ │ ├── payload
│ │ └── PayloadAttribute.kt
│ │ ├── process
│ │ ├── ConverterExt.kt
│ │ ├── ProcessDefinitionEntity.kt
│ │ ├── ProcessDefinitionRepository.kt
│ │ ├── ProcessInstanceEntity.kt
│ │ ├── ProcessInstanceRepository.kt
│ │ └── SourceReferenceEmbeddable.kt
│ │ ├── task
│ │ ├── ConverterExt.kt
│ │ ├── TaskAndDataEntryPayloadAttributeEntity.kt
│ │ ├── TaskAndDataEntryPayloadAttributeEntityId.kt
│ │ ├── TaskEntity.kt
│ │ └── TaskRepository.kt
│ │ └── update
│ │ └── QueryEmitterExt.kt
│ ├── sql
│ └── persistence.xml
│ └── test
│ ├── kotlin
│ └── io
│ │ └── holunda
│ │ └── polyflow
│ │ └── view
│ │ └── jpa
│ │ ├── JpaPolyflowViewServiceDataEntryCorrelationITest.kt
│ │ ├── JpaPolyflowViewServiceDataEntryITest.kt
│ │ ├── JpaPolyflowViewServiceDataEntryRevisionSupportITest.kt
│ │ ├── JpaPolyflowViewServiceProcessDefinitionITest.kt
│ │ ├── JpaPolyflowViewServiceProcessInstanceITest.kt
│ │ ├── JpaPolyflowViewServiceTaskITest.kt
│ │ ├── SpecificationTest.kt
│ │ ├── TestFixtures.kt
│ │ ├── auth
│ │ └── AuthorizationPrincipalTest.kt
│ │ ├── data
│ │ ├── ConverterExtKtTest.kt
│ │ ├── DataEntryIdTest.kt
│ │ └── DataEntryRepositoryITest.kt
│ │ ├── itest
│ │ ├── FixedH2Dialect.kt
│ │ ├── MockQueryEmitterConfiguration.kt
│ │ ├── NoToastPostgresSQLDialect.kt
│ │ ├── ObjectMapperConfiguration.kt
│ │ ├── TestApplication.kt
│ │ └── TestApplicationDataJpa.kt
│ │ ├── process
│ │ ├── ProcessDefinitionRepositoryITest.kt
│ │ └── ProcessInstanceRepositoryITest.kt
│ │ └── task
│ │ ├── ConverterExtKtTest.kt
│ │ ├── TaskEntityTest.kt
│ │ └── TaskRepositoryITest.kt
│ └── resources
│ ├── application-itest-tc-mariadb.yaml
│ ├── application-itest.yaml
│ ├── banner.txt
│ ├── db
│ └── migrations
│ │ ├── h2-postgresql
│ │ ├── V0_0_10__axon_sequences_per_table.sql
│ │ ├── V0_0_11__jpa_view_correlation_payload.sql
│ │ ├── V0_0_12__jpa_plf_data_entry_correlations.sql
│ │ ├── V0_0_1__postgres_engine_7.21.0.sql
│ │ ├── V0_0_2__postgres_identity_7.21.0.sql
│ │ ├── V0_0_3__admin.sql
│ │ ├── V0_0_4__tasklist_filters.sql
│ │ ├── V0_0_5__axon.sql
│ │ ├── V0_0_6__request.sql
│ │ ├── V0_0_7__jpa_view.sql
│ │ ├── V0_0_8__axon_dlq.sql
│ │ └── V0_0_9__polyflow_deleted.sql
│ │ └── mariadb
│ │ ├── V0_0_10__jpa_view_correlation_payload.sql
│ │ ├── V0_0_11__jpa_plf_data_entry_correlations.sql
│ │ ├── V0_0_1__mariadb_engine_7.21.0.sql
│ │ ├── V0_0_2__mariadb_identity_7.21.0.sql
│ │ ├── V0_0_3__admin.sql
│ │ ├── V0_0_4__tasklist_filters.sql
│ │ ├── V0_0_5__axon.sql
│ │ ├── V0_0_6__request.sql
│ │ ├── V0_0_7__jpa_view.sql
│ │ ├── V0_0_8__axon_dlq.sql
│ │ └── V0_0_9__axon_sequences_per_table.sql
│ └── logback.xml
├── mongo
├── pom.xml
└── src
│ ├── main
│ └── kotlin
│ │ └── io
│ │ └── holunda
│ │ └── polyflow
│ │ └── view
│ │ └── mongo
│ │ ├── ChangeStreamOptionsSupport.kt
│ │ ├── Converters.kt
│ │ ├── EnableTaskPoolMongoView.kt
│ │ ├── MongoViewService.kt
│ │ ├── TaskPoolMongoViewConfiguration.kt
│ │ ├── TaskPoolMongoViewProperties.kt
│ │ ├── data
│ │ ├── DataEntryChangeTracker.kt
│ │ ├── DataEntryDocument.kt
│ │ ├── DataEntryRepository.kt
│ │ ├── DataEntryUpdateRepository.kt
│ │ ├── DataEntryUpdateRepositoryImpl.kt
│ │ └── ProtocolElement.kt
│ │ ├── process
│ │ ├── ProcessDefinitionDocument.kt
│ │ ├── ProcessDefinitionMongoService.kt
│ │ └── ProcessDefinitionRepository.kt
│ │ ├── task
│ │ ├── ReferenceDocument.kt
│ │ ├── TaskChangeTracker.kt
│ │ ├── TaskCountByApplicationRepositoryExtension.kt
│ │ ├── TaskDocument.kt
│ │ ├── TaskRepository.kt
│ │ ├── TaskRepositoryExtension.kt
│ │ ├── TaskRepositoryExtensionImpl.kt
│ │ ├── TaskUpdatesExtension.kt
│ │ ├── TaskWithDataEntriesDocument.kt
│ │ ├── TaskWithDataEntriesRepository.kt
│ │ ├── TaskWithDataEntriesRepositoryExtension.kt
│ │ └── TaskWithDataEntriesRepositoryExtensionImpl.kt
│ │ └── util
│ │ └── CronTriggerWithJitter.kt
│ └── test
│ ├── kotlin
│ └── io
│ │ └── holunda
│ │ └── polyflow
│ │ └── view
│ │ └── mongo
│ │ ├── TaskPoolMongoTestContext.kt
│ │ ├── data
│ │ └── DataEntryConverterTest.kt
│ │ ├── service
│ │ ├── PolyflowMongoServiceChangeStreamChangeTrackingITest.kt
│ │ ├── PolyflowMongoServiceEventHandlerChangeTrackingITest.kt
│ │ ├── PolyflowMongoServiceRetryTest.kt
│ │ ├── PolyflowMongoServiceSortTest.kt
│ │ ├── PolyflowMongoServiceTestBase.kt
│ │ ├── PolyflowStages.kt
│ │ └── TaskChangeTrackerTest.kt
│ │ └── task
│ │ ├── TaskDocumentBuilder.kt
│ │ └── TaskRepositoryExtensionImplITest.kt
│ └── resources
│ ├── application-itest-replicated.yml
│ ├── application-itest-standalone.yml
│ ├── banner.txt
│ └── logback.xml
├── pom.xml
├── simple
├── pom.xml
└── src
│ ├── main
│ └── kotlin
│ │ └── io
│ │ └── holunda
│ │ └── polyflow
│ │ └── view
│ │ └── simple
│ │ ├── EnablePolyflowSimpleView.kt
│ │ ├── TaskPoolSimpleViewConfiguration.kt
│ │ └── service
│ │ ├── Converters.kt
│ │ ├── RevisionSupport.kt
│ │ ├── SimpleDataEntryService.kt
│ │ ├── SimpleProcessDefinitionService.kt
│ │ ├── SimpleProcessInstanceService.kt
│ │ ├── SimpleProcessVariableService.kt
│ │ ├── SimpleServiceViewProcessingGroup.kt
│ │ └── SimpleTaskPoolService.kt
│ └── test
│ ├── kotlin
│ └── io
│ │ └── holunda
│ │ └── polyflow
│ │ └── view
│ │ ├── TaskWithDataEntriesCorrelationTest.kt
│ │ └── simple
│ │ └── service
│ │ ├── ConvertersKtTest.kt
│ │ ├── DataPoolServiceTest.kt
│ │ ├── DataPoolStages.kt
│ │ ├── SimpleDataEntryServiceTest.kt
│ │ ├── SimpleTaskPoolServicePerformanceTest.kt
│ │ ├── SimpleTaskPoolServiceTest.kt
│ │ ├── TaskPoolStages.kt
│ │ ├── TestDataEntry.kt
│ │ └── TestTaskData.kt
│ └── resources
│ └── logback.xml
├── view-api-client
├── pom.xml
└── src
│ └── main
│ └── kotlin
│ ├── DataEntryQueryClient.kt
│ ├── ProcessDefinitionQueryClient.kt
│ ├── ProcessInstanceQueryClient.kt
│ ├── ProcessVariableQueryClient.kt
│ ├── QueryGatewayExt.kt
│ └── TaskQueryClient.kt
└── view-api
├── pom.xml
└── src
├── main
└── kotlin
│ ├── ComponentLike.kt
│ ├── DataEntry.kt
│ ├── Extensions.kt
│ ├── FormUrlResolver.kt
│ ├── ProcessDefinition.kt
│ ├── ProcessInstance.kt
│ ├── ProcessInstanceState.kt
│ ├── ProcessVariable.kt
│ ├── ProtocolEntry.kt
│ ├── Task.kt
│ ├── TaskWithDataEntries.kt
│ ├── auth
│ ├── User.kt
│ └── UserService.kt
│ ├── filter
│ └── Filter.kt
│ ├── query
│ ├── FilterQuery.kt
│ ├── PageableSortableQuery.kt
│ ├── QueryResult.kt
│ ├── data
│ │ ├── DataEntriesForDataEntryTypeQuery.kt
│ │ ├── DataEntriesForUserQuery.kt
│ │ ├── DataEntriesQuery.kt
│ │ ├── DataEntriesQueryResult.kt
│ │ ├── DataEntryApi.kt
│ │ ├── DataEntryForIdentityQuery.kt
│ │ ├── QueryDataIdentity.kt
│ │ └── ReactiveDataEntryApi.kt
│ ├── process
│ │ ├── ProcessDefinitionApi.kt
│ │ ├── ProcessDefinitionsStartableByUserQuery.kt
│ │ ├── ProcessInstanceApi.kt
│ │ ├── ProcessInstanceQueryResult.kt
│ │ ├── ProcessInstancesByStateQuery.kt
│ │ ├── ReactiveProcessDefinitionApi.kt
│ │ └── variable
│ │ │ ├── ProcessVariableApi.kt
│ │ │ ├── ProcessVariableFilter.kt
│ │ │ ├── ProcessVariableQueryResult.kt
│ │ │ ├── ProcessVariablesForInstanceQuery.kt
│ │ │ └── filter
│ │ │ ├── ProcessVariableFilterExactlyOne.kt
│ │ │ └── ProcessVariableFilterOneOf.kt
│ └── task
│ │ ├── AllTasksQuery.kt
│ │ ├── AllTasksWithDataEntriesQuery.kt
│ │ ├── ApplicationWithTaskCount.kt
│ │ ├── PageableSortableFilteredTaskQuery.kt
│ │ ├── ReactiveTaskApi.kt
│ │ ├── TaskApi.kt
│ │ ├── TaskAttributeNamesQuery.kt
│ │ ├── TaskAttributeNamesQueryResult.kt
│ │ ├── TaskAttributeValuesQuery.kt
│ │ ├── TaskAttributeValuesQueryResult.kt
│ │ ├── TaskCountByApplicationQuery.kt
│ │ ├── TaskForIdQuery.kt
│ │ ├── TaskQueryResult.kt
│ │ ├── TaskWithDataEntriesForIdQuery.kt
│ │ ├── TasksForApplicationQuery.kt
│ │ ├── TasksForCandidateUserAndGroupQuery.kt
│ │ ├── TasksForGroupQuery.kt
│ │ ├── TasksForUserQuery.kt
│ │ ├── TasksWithDataEntriesForGroupQuery.kt
│ │ ├── TasksWithDataEntriesForUserQuery.kt
│ │ └── TasksWithDataEntriesQueryResult.kt
│ └── sort
│ ├── DataEntryComparator.kt
│ ├── Sorter.kt
│ ├── TaskComparator.kt
│ └── TasksWithDataEntriesComparator.kt
└── test
└── kotlin
├── DataEntryTest.kt
├── ExtensionsTest.kt
├── TaskTest.kt
├── filter
└── FilterTest.kt
├── query
├── PageableSortableQueryTest.kt
├── data
│ ├── DataEntriesForUserQueryTest.kt
│ ├── DataEntriesQueryTest.kt
│ └── DataEntryForIdentityQueryTest.kt
├── process
│ ├── ProcessDefinitionsStartableByUserQueryTest.kt
│ └── ProcessInstanceByStateQueryTest.kt
└── task
│ ├── AllTasksQueryTest.kt
│ ├── TaskForIdQueryTest.kt
│ ├── TaskWithDataEntriesForGroupQueryTest.kt
│ ├── TaskWithDataEntriesForIdQueryTest.kt
│ ├── TaskWithDataEntriesForUserQueryTest.kt
│ ├── TasksForApplicationQueryTest.kt
│ ├── TasksForGroupQueryTest.kt
│ └── TasksForUserQueryTest.kt
└── sort
└── ComparatorTest.kt
/.codacy.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | engines:
3 | duplications:
4 | exclude_paths:
5 | - "**/src/test/kotlin/**"
6 | exclude_paths:
7 | - "README.md"
8 | - ".github/**"
9 | - "docs/**"
10 | - "**.sql"
11 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # http://editorconfig.org
4 |
5 | root = true
6 |
7 | [*]
8 | # We recommend you to keep these unchanged
9 | end_of_line = lf
10 | insert_final_newline = true
11 | charset = utf-8
12 | trim_trailing_whitespace = true
13 | max_line_length = 160
14 |
15 | # camunda uses 2 spaces for indention
16 | indent_style = space
17 | indent_size = 2
18 |
19 | # in markdown, we might want trailing whitespaces
20 | [*.md]
21 | trim_trailing_whitespace = false
22 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | Please use one of the following templates:
2 |
3 | https://github.com/holunda-io/camunda-bpm-taskpool/issues/new/choose
4 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/1_bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 'Bug report'
3 | about: 'Report a bug in camunda-bpm-taskpool'
4 | title:
5 | labels: 'type: bug :bug:'
6 | assignees:
7 |
8 | ---
9 |
10 | ### Steps to reproduce
11 |
12 | * camunda-bpm-taskpool version:
13 | * Camunda BPM version:
14 | * JDK version:
15 | * Operating system:
16 | * Complete executable reproducer: (e.g. GitHub Repo)
17 | * Steps: (what exactly are you doing with the above reproducer?)
18 |
19 | ### Expected behaviour
20 |
21 | ### Actual behaviour
22 |
23 | (In case of exceptions provide full stack trace)
24 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/2_feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 'Feature request'
3 | about: 'Suggest a feature for camunda-bpm-taskpool'
4 | title:
5 | labels: 'type: enhancement'
6 | assignees:
7 |
8 | ---
9 |
10 | ### Scenario
11 |
12 | * camunda-bpm-taskpool version:
13 | * Camunda BPM version:
14 | * Description of your use case: (detailed description or executable reproducer, e.g. GitHub repo)
15 |
16 | ### Current Behaviour
17 |
18 | ### Wanted Behaviour
19 |
20 | ### Possible Workarounds
21 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: maven
4 | directory: "/"
5 | schedule:
6 | interval: "daily"
7 | open-pull-requests-limit: 19
8 | labels:
9 | - "Type: dependencies"
10 | - package-ecosystem: "github-actions"
11 | directory: "/"
12 | schedule:
13 | interval: "daily"
14 | labels:
15 | - "Type: dependencies"
16 |
--------------------------------------------------------------------------------
/.github/release-notes.yml:
--------------------------------------------------------------------------------
1 | changelog:
2 | sections:
3 | - title: ":rocket: Enhancements & Features"
4 | labels: [ "Type: enhancement", "Type: documentation", "Type: example" ]
5 | - title: ":zap: Breaking Changes"
6 | labels: [ "Type: breaking" ]
7 | - title: ":bug: Bug Fixes"
8 | labels: [ "Type: bug" ]
9 | - title: ":hammer_and_wrench: Chore"
10 | labels: [ "Type: dependencies" ]
11 | issues:
12 | exclude:
13 | labels: [ "Type: Incorrect Repository", "Type: question" ]
14 | contributors:
15 | exclude:
16 | names: [ "dependabot[bot]", "codacy-badger" ]
17 |
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.9.2/apache-maven-3.9.2-bin.zip
2 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Supported Versions
4 |
5 | Use this section to tell people about which versions of your project are
6 | currently being supported with security updates.
7 |
8 | | Version | Supported |
9 | | ------- | ------------------ |
10 | | 5.1.x | :white_check_mark: |
11 | | 5.0.x | :x: |
12 | | 4.0.x | :white_check_mark: |
13 | | < 4.0 | :x: |
14 |
15 | ## Reporting a Vulnerability
16 |
17 | Use this section to tell people how to report a vulnerability.
18 |
19 | Tell them where to go, how often they can expect to get an update on a
20 | reported vulnerability, what to expect if the vulnerability is accepted or
21 | declined, etc.
22 |
--------------------------------------------------------------------------------
/core/bus-jackson/src/main/kotlin/io/holunda/polyflow/bus/jackson/DataEntryStateTypeMappingModule.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.bus.jackson
2 |
3 | import com.fasterxml.jackson.databind.module.SimpleModule
4 | import io.holunda.camunda.taskpool.api.business.DataEntryState
5 | import io.holunda.camunda.taskpool.api.business.DataEntryStateImpl
6 |
7 | /**
8 | * Module to map data entry state.
9 | */
10 | class DataEntryStateTypeMappingModule: SimpleModule() {
11 | init {
12 | addAbstractTypeMapping(DataEntryState::class.java, DataEntryStateImpl::class.java)
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/core/bus-jackson/src/main/kotlin/io/holunda/polyflow/bus/jackson/JsonAutoDetectAnyVisibility.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.bus.jackson
2 |
3 | import com.fasterxml.jackson.annotation.JsonAutoDetect
4 |
5 | /**
6 | * Allow serialization of all fields. (Also private fields!)
7 | */
8 | @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
9 | class JsonAutoDetectAnyVisibility
10 |
--------------------------------------------------------------------------------
/core/bus-jackson/src/main/kotlin/io/holunda/polyflow/bus/jackson/KotlinTypeInfo.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.bus.jackson
2 |
3 | import com.fasterxml.jackson.annotation.JsonTypeInfo
4 |
5 | /**
6 | * Type info for all classes using inheritance.
7 | */
8 | @JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, property = "@class", include = JsonTypeInfo.As.PROPERTY)
9 | class KotlinTypeInfo
10 |
--------------------------------------------------------------------------------
/core/bus-jackson/src/main/kotlin/io/holunda/polyflow/bus/jackson/VariableMapTypeMappingModule.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.bus.jackson
2 |
3 | import com.fasterxml.jackson.databind.module.SimpleModule
4 | import org.camunda.bpm.engine.variable.VariableMap
5 | import org.camunda.bpm.engine.variable.impl.VariableMapImpl
6 |
7 | /**
8 | * Module to map camunda variable impl.
9 | */
10 | class VariableMapTypeMappingModule : SimpleModule() {
11 | init {
12 | addAbstractTypeMapping(VariableMap::class.java, VariableMapImpl::class.java)
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/core/bus-jackson/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports:
--------------------------------------------------------------------------------
1 | io.holunda.polyflow.bus.jackson.config.FallbackPayloadObjectMapperAutoConfiguration
2 |
--------------------------------------------------------------------------------
/core/datapool/datapool-api/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 |
7 | io.holunda.polyflow
8 | polyflow-datapool-parent
9 | 4.4.1-SNAPSHOT
10 |
11 |
12 | polyflow-datapool-api
13 | core/datapool/${project.artifactId}
14 |
15 |
16 |
17 | org.axonframework
18 | axon-modelling
19 |
20 |
21 | org.camunda.commons
22 | camunda-commons-typed-values
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/core/datapool/datapool-api/src/main/kotlin/io/holunda/camunda/taskpool/api/business/DataEntryState.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.camunda.taskpool.api.business
2 |
3 | /**
4 | * Compound processing state.
5 | */
6 | interface DataEntryState {
7 | /**
8 | * State type.
9 | */
10 | val processingType: ProcessingType
11 | /**
12 | * Carrying business-relevant state label.
13 | */
14 | val state: String?
15 | }
16 |
17 | /**
18 | * Simple implementation of compound entry state.
19 | */
20 | data class DataEntryStateImpl(
21 | override val processingType: ProcessingType = ProcessingType.UNDEFINED,
22 | override val state: String = ""
23 | ) : DataEntryState
24 |
--------------------------------------------------------------------------------
/core/datapool/datapool-api/src/main/kotlin/io/holunda/camunda/taskpool/api/business/DataIdentity.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.camunda.taskpool.api.business
2 |
3 | /**
4 | * Represents an identity of a data entry.
5 | */
6 | interface DataIdentity {
7 | /**
8 | * String representation of an entry.
9 | */
10 | val entryType: EntryType
11 | /**
12 | * String representation of an entry.
13 | */
14 | val entryId: EntryId
15 |
16 | /**
17 | * Retrieves the identity as a string.
18 | */
19 | fun asString() = dataIdentityString(entryType = entryType, entryId = entryId)
20 | }
21 | /**
22 | * Id of business entry.
23 | */
24 | typealias EntryId = String
25 |
26 | /**
27 | * Type of business entry.
28 | */
29 | typealias EntryType = String
30 |
31 | /**
32 | * Separator.
33 | */
34 | const val DATA_IDENTITY_SEPARATOR = "#"
35 |
36 | /**
37 | * Constructs the data identity.
38 | */
39 | fun dataIdentityString(entryType: EntryType, entryId: EntryId) = "$entryType$DATA_IDENTITY_SEPARATOR$entryId"
40 |
--------------------------------------------------------------------------------
/core/datapool/datapool-api/src/main/kotlin/io/holunda/camunda/taskpool/api/business/Modification.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.camunda.taskpool.api.business
2 |
3 | import java.time.OffsetDateTime
4 |
5 | /**
6 | * Represents the auditable reason for data entry modification.
7 | */
8 | data class Modification(
9 | /**
10 | * Time of update
11 | */
12 | val time: OffsetDateTime = OffsetDateTime.now(),
13 | /**
14 | * Username of the user who updated the business entry.
15 | */
16 | val username: String? = null,
17 | /**
18 | * Log entry for the update.
19 | */
20 | val log: String? = null,
21 |
22 | /**
23 | * Log entry details.
24 | */
25 | val logNotes: String? = null
26 | ) {
27 | companion object {
28 | /**
29 | * No modification null-object.
30 | */
31 | val NONE = Modification()
32 |
33 | /**
34 | * Modification executed now.
35 | */
36 | fun now() = Modification(time = OffsetDateTime.now())
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/core/datapool/datapool-api/src/main/kotlin/io/holunda/camunda/taskpool/api/business/ProcessingType.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.camunda.taskpool.api.business
2 |
3 | /**
4 | * State type of processing.
5 | */
6 | enum class ProcessingType {
7 | /**
8 | * Before processing.
9 | */
10 | PRELIMINARY,
11 | /**
12 | * During processing.
13 | */
14 | IN_PROGRESS,
15 | /**
16 | * Process has finished the work on business entry with success.
17 | */
18 | COMPLETED,
19 | /**
20 | * Process has failed to finish the work on business entry with success.
21 | */
22 | CANCELLED,
23 | /**
24 | * Undefined status.
25 | */
26 | UNDEFINED,
27 | /**
28 | * Data entry is deleted.
29 | */
30 | DELETED;
31 |
32 | /**
33 | * Factory method.
34 | */
35 | fun of(state: String = "") = DataEntryStateImpl(processingType = this, state = state)
36 | }
37 |
--------------------------------------------------------------------------------
/core/datapool/datapool-api/src/main/kotlin/io/holunda/camunda/taskpool/api/business/WithPayload.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.camunda.taskpool.api.business
2 |
3 | import org.camunda.bpm.engine.variable.VariableMap
4 |
5 | /**
6 | * Represents data payload.
7 | */
8 | interface WithPayload {
9 | /**
10 | * Payload.
11 | */
12 | val payload: VariableMap
13 | }
14 |
--------------------------------------------------------------------------------
/core/datapool/datapool-api/src/test/kotlin/io/holunda/camunda/taskpool/api/business/ProcessingTypeTest.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.camunda.taskpool.api.business
2 |
3 | import org.assertj.core.api.Assertions.assertThat
4 | import org.junit.jupiter.api.Test
5 |
6 | internal class ProcessingTypeTest {
7 |
8 | @Test
9 | fun `creates processing type`() {
10 | assertThat(ProcessingType.PRELIMINARY.of("draft")).isEqualTo(DataEntryStateImpl(processingType = ProcessingType.PRELIMINARY, state = "draft"))
11 | assertThat(ProcessingType.IN_PROGRESS.of("doing")).isEqualTo(DataEntryStateImpl(processingType = ProcessingType.IN_PROGRESS, state = "doing"))
12 | assertThat(ProcessingType.COMPLETED.of("done")).isEqualTo(DataEntryStateImpl(processingType = ProcessingType.COMPLETED, state = "done"))
13 | assertThat(ProcessingType.DELETED.of("thrashed")).isEqualTo(DataEntryStateImpl(processingType = ProcessingType.DELETED, state = "thrashed"))
14 | assertThat(ProcessingType.CANCELLED.of("rejected")).isEqualTo(DataEntryStateImpl(processingType = ProcessingType.CANCELLED, state = "rejected"))
15 | assertThat(ProcessingType.UNDEFINED.of("custom")).isEqualTo(DataEntryStateImpl(processingType = ProcessingType.UNDEFINED, state = "custom"))
16 | }
17 | }
--------------------------------------------------------------------------------
/core/datapool/datapool-core/src/main/kotlin/io/holunda/polyflow/datapool/Helpers.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.datapool
2 |
3 | import java.util.*
4 |
5 | /**
6 | * Allows to call a consumer if the element is present or call another callback, if the element is missing.
7 | * @param presentConsumer consumer the is called if the element is there.
8 | * @param missingCallback callback called if the element is missing.
9 | */
10 | fun Optional.ifPresentOrElse(presentConsumer: (T) -> Unit, missingCallback: () -> Unit) {
11 | if (this.isPresent) {
12 | presentConsumer(this.get())
13 | } else {
14 | missingCallback()
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/core/datapool/datapool-core/src/main/kotlin/io/holunda/polyflow/datapool/core/DataPoolProperties.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.datapool.core
2 |
3 | import org.axonframework.eventsourcing.EventSourcingRepository
4 | import org.springframework.boot.context.properties.ConfigurationProperties
5 |
6 | /**
7 | * Properties effecting data pool command model.
8 | */
9 | @ConfigurationProperties(prefix = "polyflow.core.data-entry")
10 | data class DataPoolProperties(
11 | /**
12 | * How many events lead to a snapshot of data entries. Check the [eventSourcingRepositoryType] property.
13 | */
14 | val snapshotThreshold: Int = 5,
15 |
16 | /**
17 | * Specifies the full-qualified class name of the event sourced repository used to load data entry aggregates.
18 | * Defaults to [org.axonframework.eventsourcing.EventSourcingRepository].
19 | * Consider to use [io.holunda.polyflow.datapool.core.repository.FirstEventOnlyEventSourcingRepository] if you want to load the aggregate with first event only.
20 | */
21 | val eventSourcingRepositoryType: String = EventSourcingRepository::class.java.canonicalName,
22 |
23 | /**
24 | * Specifies the deletion strategy for data entries.
25 | */
26 | val deletionStrategy: DeletionStrategyValue? = DeletionStrategyValue.lax
27 | )
28 |
--------------------------------------------------------------------------------
/core/datapool/datapool-core/src/main/kotlin/io/holunda/polyflow/datapool/core/DeletionStrategy.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.datapool.core
2 |
3 | /**
4 | * Describes how deleted data entries should be handled.
5 | */
6 | interface DeletionStrategy {
7 | /**
8 | * If set to true, the update event sent to the aggregate will result in AggregateDeletedException.
9 | * If set to false, the update of deleted data entry will undelete it and update the properties.
10 | */
11 | fun strictMode(): Boolean
12 | }
--------------------------------------------------------------------------------
/core/datapool/datapool-core/src/main/kotlin/io/holunda/polyflow/datapool/core/DeletionStrategyValue.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.datapool.core
2 |
3 | /**
4 | * Different deletion strategies.
5 | */
6 | enum class DeletionStrategyValue {
7 | /**
8 | * Allow updates after deletes.
9 | */
10 | strict,
11 |
12 | /**
13 | * Enforces errors on any operation after deletion.
14 | */
15 | lax
16 | }
17 |
--------------------------------------------------------------------------------
/core/datapool/datapool-core/src/main/kotlin/io/holunda/polyflow/datapool/core/EnablePolyflowDataPool.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.datapool.core
2 |
3 | import org.springframework.context.annotation.Import
4 |
5 | /**
6 | * Starts data pool component.
7 | */
8 | @MustBeDocumented
9 | @Import(
10 | DataPoolCoreConfiguration::class,
11 | DataPoolCoreAxonConfiguration::class
12 | )
13 | annotation class EnablePolyflowDataPool
14 |
--------------------------------------------------------------------------------
/core/datapool/datapool-core/src/test/kotlin/io/holunda/polyflow/datapool/core/business/repository/FirstEventOnlyEventSourcingRepositoryBuilderTest.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.datapool.core.business.repository
2 |
3 | import io.holunda.polyflow.datapool.core.business.DataEntryAggregate
4 | import io.holunda.polyflow.datapool.core.repository.FirstEventOnlyEventSourcingRepositoryBuilder
5 | import org.assertj.core.api.Assertions.assertThat
6 | import org.axonframework.eventsourcing.NoSnapshotTriggerDefinition
7 | import org.axonframework.eventsourcing.eventstore.EventStore
8 | import org.junit.jupiter.api.Test
9 | import org.mockito.kotlin.mock
10 |
11 | internal class FirstEventOnlyEventSourcingRepositoryBuilderTest {
12 |
13 | private val eventStore: EventStore = mock()
14 |
15 | @Test
16 | fun `should construct the builder with defaults`() {
17 | val builder = FirstEventOnlyEventSourcingRepositoryBuilder(DataEntryAggregate::class.java).eventStore(eventStore)
18 |
19 | assertThat(builder.internalEventStore()).isEqualTo(eventStore)
20 | assertThat(builder.internalSnapshotTriggerDefinition()).isEqualTo(NoSnapshotTriggerDefinition.INSTANCE)
21 | assertThat(builder.internalRepositoryProvider()).isNull()
22 | assertThat(builder.internalEventStreamFilter()).isNull()
23 | }
24 | }
--------------------------------------------------------------------------------
/core/datapool/datapool-core/src/test/kotlin/io/holunda/polyflow/datapool/core/itest/TestApplication.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.datapool.core.itest
2 |
3 | import com.thoughtworks.xstream.XStream
4 | import com.thoughtworks.xstream.security.AnyTypePermission
5 | import io.holunda.polyflow.datapool.core.EnablePolyflowDataPool
6 | import org.axonframework.eventsourcing.eventstore.inmemory.InMemoryEventStorageEngine
7 | import org.axonframework.serialization.Serializer
8 | import org.axonframework.serialization.xml.XStreamSerializer
9 | import org.springframework.beans.factory.annotation.Qualifier
10 | import org.springframework.boot.autoconfigure.SpringBootApplication
11 | import org.springframework.context.annotation.Bean
12 |
13 | @SpringBootApplication
14 | @EnablePolyflowDataPool
15 | class TestApplication {
16 | @Bean
17 | @Qualifier("eventSerializer")
18 | fun myEventSerializerForProcess(): Serializer = XStreamSerializer.builder().xStream(XStream().apply { addPermission(AnyTypePermission.ANY) }).build()
19 |
20 | @Bean
21 | fun inMemoryStorageEngine() = InMemoryEventStorageEngine()
22 | }
23 |
--------------------------------------------------------------------------------
/core/datapool/datapool-core/src/test/resources/application-itest-first-event-only.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: taskpool-core-itest
4 | datasource:
5 | url: jdbc:h2:mem:itest;
6 | username: sa
7 | password:
8 | jpa:
9 | generate-ddl: false
10 | hibernate.ddl-auto: validate
11 | show-sql: false
12 | open-in-view: false
13 | flyway:
14 | enabled: true
15 | locations: "classpath:db/migrations"
16 |
17 | polyflow:
18 | core:
19 | data-entry:
20 | event-sourcing-repository-type: io.holunda.polyflow.datapool.core.repository.FirstEventOnlyEventSourcingRepository
21 |
22 | logging.level:
23 | io.holunda.polyflow:
24 | datapool:
25 | core:
26 | business:
27 | DataEntryAggregate: DEBUG
28 | CreateOrUpdateCommandHandler: TRACE
29 |
--------------------------------------------------------------------------------
/core/datapool/datapool-core/src/test/resources/banner.txt:
--------------------------------------------------------------------------------
1 | -------------------------------------------------------------------------------
2 | I-Test Datapool Core
3 | -------------------------------------------------------------------------------
4 |
--------------------------------------------------------------------------------
/core/datapool/datapool-core/src/test/resources/db/migrations/V0_0_2__axon_dlq.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE dead_letter_entry (
2 | dead_letter_id VARCHAR(255) NOT NULL,
3 | cause_message VARCHAR(255),
4 | cause_type VARCHAR(255),
5 | diagnostics BLOB,
6 | enqueued_at TIMESTAMP NOT NULL,
7 | last_touched TIMESTAMP,
8 | aggregate_identifier VARCHAR(255),
9 | event_identifier VARCHAR(255) NOT NULL,
10 | message_type VARCHAR(255) NOT NULL,
11 | meta_data BLOB,
12 | payload BLOB NOT NULL,
13 | payload_revision VARCHAR(255),
14 | payload_type VARCHAR(255) NOT NULL,
15 | sequence_number INT8,
16 | time_stamp VARCHAR(255) NOT NULL,
17 | token BLOB,
18 | token_type VARCHAR(255),
19 | type VARCHAR(255),
20 | processing_group VARCHAR(255) NOT NULL,
21 | processing_started TIMESTAMP,
22 | sequence_identifier VARCHAR(255) NOT NULL,
23 | sequence_index INT8 NOT NULL,
24 | PRIMARY KEY (dead_letter_id)
25 | );
--------------------------------------------------------------------------------
/core/datapool/datapool-core/src/test/resources/db/migrations/V0_0_3__axon_sequence_per_table.sql:
--------------------------------------------------------------------------------
1 | drop SEQUENCE hibernate_sequence;
2 | create sequence association_value_entry_seq start with 1 increment by 50;
3 | create sequence domain_event_entry_seq start with 1 increment by 50;
4 |
--------------------------------------------------------------------------------
/core/datapool/datapool-core/src/test/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/core/datapool/datapool-event/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 |
7 | io.holunda.polyflow
8 | polyflow-datapool-parent
9 | 4.4.1-SNAPSHOT
10 |
11 |
12 | polyflow-datapool-event
13 | core/datapool/${project.artifactId}
14 |
15 |
16 |
17 | ${project.parent.groupId}
18 | polyflow-datapool-api
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/core/spring-utils/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 |
7 | io.holunda.polyflow
8 | polyflow-parent
9 | 4.4.1-SNAPSHOT
10 | ../../bom/parent/pom.xml
11 |
12 |
13 | polyflow-spring-utils
14 | core/spring-utils/${project.artifactId}
15 |
16 |
17 |
18 |
19 | org.springframework.boot
20 | spring-boot-starter
21 | provided
22 |
23 |
24 | org.springframework.boot
25 | spring-boot-test
26 | test
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/core/spring-utils/src/test/kotlin/io/holunda/polyflow/datapool/DataEntrySenderProperties.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.datapool
2 |
3 | import io.holunda.polyflow.spring.ApplicationNameBeanPostProcessor
4 | import org.springframework.boot.context.properties.ConfigurationProperties
5 |
6 | @ConfigurationProperties(prefix = "polyflow.test")
7 | data class DataEntrySenderProperties(var applicationName: String = ApplicationNameBeanPostProcessor.UNSET_APPLICATION_NAME)
8 |
--------------------------------------------------------------------------------
/core/taskpool/taskpool-api/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 |
7 | io.holunda.polyflow
8 | polyflow-taskpool-parent
9 | 4.4.1-SNAPSHOT
10 |
11 |
12 | polyflow-taskpool-api
13 | core/taskpool/${project.artifactId}
14 |
15 |
16 |
17 | io.holunda.polyflow
18 | polyflow-datapool-api
19 |
20 |
21 | org.axonframework
22 | axon-messaging
23 |
24 |
25 | org.camunda.commons
26 | camunda-commons-typed-values
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/core/taskpool/taskpool-api/src/main/kotlin/io/holunda/camunda/taskpool/api/process/definition/ProcessDefinitionCommand.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.camunda.taskpool.api.process.definition
2 |
3 | import io.holunda.camunda.taskpool.api.task.WithFormKey
4 | import org.axonframework.modelling.command.TargetAggregateIdentifier
5 |
6 | /**
7 | * Any command about process definition should implement this interface.
8 | */
9 | interface ProcessDefinitionCommand {
10 | val processDefinitionId: String
11 | }
12 |
13 | /**
14 | * Informs about a process definition deployed in the engine.
15 | */
16 | data class RegisterProcessDefinitionCommand(
17 |
18 | @TargetAggregateIdentifier
19 | override val processDefinitionId: String,
20 | val processDefinitionKey: String,
21 | val processDefinitionVersion: Int,
22 |
23 | val applicationName: String,
24 | val processName: String,
25 | val processVersionTag: String?,
26 | val processDescription: String?,
27 | override val formKey: String?,
28 | val startableFromTasklist: Boolean,
29 | val candidateStarterUsers: Set,
30 | val candidateStarterGroups: Set
31 | ) : ProcessDefinitionCommand, WithFormKey
32 |
--------------------------------------------------------------------------------
/core/taskpool/taskpool-api/src/main/kotlin/io/holunda/camunda/taskpool/api/task/CamundaTaskEventType.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.camunda.taskpool.api.task
2 |
3 | /**
4 | * Identifies camunda task event.
5 | */
6 | interface CamundaTaskEventType {
7 | /**
8 | * Event classification.
9 | */
10 | val eventName: String
11 |
12 | companion object {
13 | const val CREATE = "create"
14 | const val ASSIGN = "assignment"
15 | const val DELETE = "delete"
16 | const val COMPLETE = "complete"
17 | const val ATTRIBUTES = "attribute-update"
18 | const val ATTRIBUTES_LISTENER_UPDATE = "attribute-listener-update"
19 | const val CANDIDATE_GROUP_ADD = "candidate-group-add"
20 | const val CANDIDATE_GROUP_DELETE = "candidate-group-delete"
21 | const val CANDIDATE_USER_ADD = "candidate-user-add"
22 | const val CANDIDATE_USER_DELETE = "candidate-user-delete"
23 | const val BATCH = "batch"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/core/taskpool/taskpool-api/src/main/kotlin/io/holunda/camunda/taskpool/api/task/EngineTaskCommand.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.camunda.taskpool.api.task
2 |
3 | /**
4 | * Task command received from the Camunda Engine.
5 | */
6 | interface EngineTaskCommand : WithTaskId, CamundaTaskEventType {
7 | /**
8 | * Used to order commands before sending in case multiple events are received from the engine for the same task in the same transaction.
9 | * Commands with lower order value are sent before commands with higher order value.
10 | */
11 | val order: Int
12 | }
13 |
14 |
15 |
--------------------------------------------------------------------------------
/core/taskpool/taskpool-api/src/main/kotlin/io/holunda/camunda/taskpool/api/task/EngineTaskCommandFilter.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.camunda.taskpool.api.task
2 |
3 | import java.util.function.Predicate
4 |
5 | /**
6 | * Filter for task commands.
7 | */
8 | interface EngineTaskCommandFilter : Predicate {
9 | /**
10 | * Tests if the task command should be sent.
11 | * @param engineTaskCommand commend to test.
12 | * @return true, if command should be emitted. Defaults to false.
13 | */
14 | override fun test(engineTaskCommand: EngineTaskCommand): Boolean = false
15 | }
16 |
--------------------------------------------------------------------------------
/core/taskpool/taskpool-api/src/main/kotlin/io/holunda/camunda/taskpool/api/task/EngineTaskCommandSorter.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.camunda.taskpool.api.task
2 |
3 | /**
4 | * Create can carry almost everything of changes.
5 | */
6 | const val ORDER_TASK_CREATION = -3
7 |
8 | /**
9 | * Complete can carry assignee.
10 | */
11 | const val ORDER_TASK_COMPLETION = -2
12 | const val ORDER_TASK_DELETION = -1
13 | const val ORDER_TASK_ASSIGNMENT = 0
14 | const val ORDER_TASK_CANDIDATES_UPDATE = 1
15 | const val ORDER_TASK_ATTRIBUTE_UPDATE = 2
16 | const val ORDER_TASK_BATCH = 100
17 |
18 | /**
19 | * Special command that is never an intent, but is used for enrichment of other commands.
20 | */
21 | const val ORDER_TASK_HISTORIC_ATTRIBUTE_UPDATE = 10
22 |
23 |
24 | /**
25 | * Provides an ordering for EngineTaskCommand based on their order property.
26 | * This is used to determine the intent of the command batch.
27 | */
28 | class EngineTaskCommandSorter : Comparator {
29 |
30 | override fun compare(command: EngineTaskCommand, otherCommand: EngineTaskCommand): Int {
31 |
32 | // EngineTaskCommand with lower order value comes first
33 | return command.order.compareTo(otherCommand.order)
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/core/taskpool/taskpool-api/src/main/kotlin/io/holunda/camunda/taskpool/api/task/InteractionTaskCommand.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.camunda.taskpool.api.task
2 |
3 | /**
4 | * Task command caused by user or system interaction with a task.
5 | */
6 | interface InteractionTaskCommand : TaskIdentity
7 |
--------------------------------------------------------------------------------
/core/taskpool/taskpool-api/src/main/kotlin/io/holunda/camunda/taskpool/api/task/TaskIdentity.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.camunda.taskpool.api.task
2 |
3 | /**
4 | * Task identity.
5 | */
6 | interface TaskIdentity : WithTaskId {
7 | /**
8 | * Task definition key.
9 | */
10 | val taskDefinitionKey: String
11 | /**
12 | * Task source reference.
13 | */
14 | val sourceReference: SourceReference
15 | }
16 |
--------------------------------------------------------------------------------
/core/taskpool/taskpool-api/src/main/kotlin/io/holunda/camunda/taskpool/api/task/TaskIdentityWithPayloadAndCorrelations.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.camunda.taskpool.api.task
2 |
3 | import io.holunda.camunda.taskpool.api.business.WithCorrelations
4 |
5 | /**
6 | * Task identity which can be enriched with payload and correlations.
7 | */
8 | interface TaskIdentityWithPayloadAndCorrelations : TaskIdentity, WithPayload, WithCorrelations {
9 | /**
10 | * Flag, indicating if the enrichment has been performed. The payload is only then taken into account.
11 | */
12 | var enriched: Boolean
13 | }
14 |
--------------------------------------------------------------------------------
/core/taskpool/taskpool-api/src/main/kotlin/io/holunda/camunda/taskpool/api/task/WithFormKey.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.camunda.taskpool.api.task
2 |
3 | /**
4 | * Identifies elements with form key.
5 | */
6 | interface WithFormKey {
7 | /**
8 | * Optional form key.
9 | */
10 | val formKey: String?
11 | }
12 |
--------------------------------------------------------------------------------
/core/taskpool/taskpool-api/src/main/kotlin/io/holunda/camunda/taskpool/api/task/WithPayload.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.camunda.taskpool.api.task
2 |
3 | import org.camunda.bpm.engine.variable.VariableMap
4 |
5 | /**
6 | * Represents task payload.
7 | */
8 | interface WithPayload {
9 | /**
10 | * Payload.
11 | */
12 | val payload: VariableMap
13 | /**
14 | * Business key.
15 | */
16 | val businessKey: String?
17 | }
18 |
--------------------------------------------------------------------------------
/core/taskpool/taskpool-api/src/main/kotlin/io/holunda/camunda/taskpool/api/task/WithTaskId.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.camunda.taskpool.api.task
2 |
3 | /**
4 | * Identifies the fact that the task id is present.
5 | * This is a minimum requirement for the task to be identified.
6 | */
7 | interface WithTaskId {
8 | /**
9 | * Task id.
10 | */
11 | val id: String
12 | }
13 |
--------------------------------------------------------------------------------
/core/taskpool/taskpool-core/src/main/kotlin/io/holunda/polyflow/taskpool/core/EnableTaskPool.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.core
2 |
3 | import org.springframework.context.annotation.Import
4 |
5 | /**
6 | * Starts task pool component.
7 | */
8 | @MustBeDocumented
9 | @Import(TaskPoolCoreConfiguration::class)
10 | annotation class EnablePolyflowTaskPool
11 |
--------------------------------------------------------------------------------
/core/taskpool/taskpool-core/src/main/kotlin/io/holunda/polyflow/taskpool/core/process/ProcessDefinitionRegisterCommandHandler.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.core.process
2 |
3 | import io.holunda.camunda.taskpool.api.process.definition.RegisterProcessDefinitionCommand
4 | import org.axonframework.commandhandling.CommandHandler
5 | import org.axonframework.eventsourcing.EventSourcingRepository
6 | import org.springframework.context.annotation.Lazy
7 | import org.springframework.stereotype.Component
8 |
9 | /**
10 | * Handler allowing to register existing definition multiple times.
11 | */
12 | @Component
13 | class ProcessDefinitionRegisterCommandHandler(
14 | @Lazy
15 | val eventSourcingRepository: EventSourcingRepository
16 | ) {
17 |
18 | /**
19 | * Submits a register definition command to an existing aggregate or a new aggregate.
20 | */
21 | @CommandHandler
22 | fun register(command: RegisterProcessDefinitionCommand) {
23 | eventSourcingRepository.loadOrCreate(command.processDefinitionId) { ProcessDefinitionAggregate() }
24 | .execute { it.handle(command) }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/core/taskpool/taskpool-core/src/main/kotlin/io/holunda/polyflow/taskpool/core/process/ProcessInstanceVariablesChangeHandler.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.core.process
2 |
3 | import io.holunda.camunda.taskpool.api.process.variable.ChangeProcessVariablesForExecutionCommand
4 | import org.axonframework.commandhandling.CommandHandler
5 | import org.axonframework.eventsourcing.EventSourcingRepository
6 | import org.springframework.context.annotation.Lazy
7 | import org.springframework.stereotype.Component
8 |
9 | /**
10 | * This handler makes sure that an update of variables can be sent without a create of the process instance.
11 | */
12 | @Component
13 | class ProcessInstanceVariablesChangeHandler(
14 | @Lazy
15 | val eventSourcingRepository: EventSourcingRepository
16 | ) {
17 |
18 | /**
19 | * Update variables on existing instance aggregate or create a new one, if missed.
20 | */
21 | @CommandHandler
22 | fun update(command: ChangeProcessVariablesForExecutionCommand) {
23 | eventSourcingRepository.loadOrCreate(command.sourceReference.instanceId) { ProcessInstanceAggregate() }
24 | .execute { it.changeVariables(command) }
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/core/taskpool/taskpool-core/src/main/kotlin/io/holunda/polyflow/taskpool/core/task/ExternalCommandHandler.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.core.task
2 |
3 | import io.holunda.camunda.taskpool.api.task.CreateTaskCommand
4 | import org.axonframework.commandhandling.CommandHandler
5 | import org.axonframework.eventsourcing.EventSourcingRepository
6 | import org.axonframework.messaging.MetaData
7 | import org.springframework.context.annotation.Lazy
8 | import org.springframework.stereotype.Component
9 |
10 | /**
11 | * Handler allowing to re-submit a create command for already existing task.
12 | */
13 | @Component
14 | class ExternalCommandHandler(
15 | @Lazy
16 | val eventSourcingRepository: EventSourcingRepository
17 | ) {
18 |
19 | /**
20 | * Create a new aggregate (default) or load existing and replay the creation command if already there.
21 | */
22 | @CommandHandler
23 | fun create(command: CreateTaskCommand, metadata: MetaData) {
24 | eventSourcingRepository.loadOrCreate(command.id) { TaskAggregate() }
25 | .execute { it.handle(command, metadata) }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/core/taskpool/taskpool-core/src/test/kotlin/io/holunda/polyflow/taskpool/core/TestApplication.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.core
2 |
3 | import com.thoughtworks.xstream.XStream
4 | import com.thoughtworks.xstream.security.AnyTypePermission
5 | import org.axonframework.eventsourcing.eventstore.inmemory.InMemoryEventStorageEngine
6 | import org.axonframework.serialization.Serializer
7 | import org.axonframework.serialization.xml.XStreamSerializer
8 | import org.springframework.beans.factory.annotation.Qualifier
9 | import org.springframework.boot.autoconfigure.SpringBootApplication
10 | import org.springframework.context.annotation.Bean
11 |
12 | @SpringBootApplication
13 | @EnablePolyflowTaskPool
14 | class TestApplication {
15 | @Bean
16 | @Qualifier("eventSerializer")
17 | fun myEventSerializerForProcess(): Serializer = XStreamSerializer.builder().xStream(XStream().apply { addPermission(AnyTypePermission.ANY) }).build()
18 |
19 | @Bean
20 | fun inMemoryEventStoreEngine() = InMemoryEventStorageEngine()
21 | }
22 |
--------------------------------------------------------------------------------
/core/taskpool/taskpool-core/src/test/resources/application-itest.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: taskpool-core-itest
4 | datasource:
5 | url: jdbc:h2:mem:itest;
6 | username: sa
7 | password:
8 | jpa:
9 | generate-ddl: false
10 | hibernate.ddl-auto: validate
11 | show-sql: false
12 | open-in-view: false
13 | flyway:
14 | enabled: true
15 | locations: "classpath:db/migrations"
16 |
--------------------------------------------------------------------------------
/core/taskpool/taskpool-core/src/test/resources/banner.txt:
--------------------------------------------------------------------------------
1 | -------------------------------------------------------------------------------
2 | I-Test Taskpool Core
3 | -------------------------------------------------------------------------------
4 |
--------------------------------------------------------------------------------
/core/taskpool/taskpool-core/src/test/resources/db/migrations/V0_0_2__axon_dlq.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE dead_letter_entry (
2 | dead_letter_id VARCHAR(255) NOT NULL,
3 | cause_message VARCHAR(255),
4 | cause_type VARCHAR(255),
5 | diagnostics BLOB,
6 | enqueued_at TIMESTAMP NOT NULL,
7 | last_touched TIMESTAMP,
8 | aggregate_identifier VARCHAR(255),
9 | event_identifier VARCHAR(255) NOT NULL,
10 | message_type VARCHAR(255) NOT NULL,
11 | meta_data BLOB,
12 | payload BLOB NOT NULL,
13 | payload_revision VARCHAR(255),
14 | payload_type VARCHAR(255) NOT NULL,
15 | sequence_number INT8,
16 | time_stamp VARCHAR(255) NOT NULL,
17 | token BLOB,
18 | token_type VARCHAR(255),
19 | type VARCHAR(255),
20 | processing_group VARCHAR(255) NOT NULL,
21 | processing_started TIMESTAMP,
22 | sequence_identifier VARCHAR(255) NOT NULL,
23 | sequence_index INT8 NOT NULL,
24 | PRIMARY KEY (dead_letter_id)
25 | );
--------------------------------------------------------------------------------
/core/taskpool/taskpool-core/src/test/resources/db/migrations/V0_0_3__axon_sequence_per_table.sql:
--------------------------------------------------------------------------------
1 | drop SEQUENCE hibernate_sequence;
2 | create sequence association_value_entry_seq start with 1 increment by 50;
3 | create sequence domain_event_entry_seq start with 1 increment by 50;
4 |
--------------------------------------------------------------------------------
/core/taskpool/taskpool-core/src/test/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/core/taskpool/taskpool-event/src/main/kotlin/io/holunda/camunda/taskpool/api/process/definition/ProcessDefinitionEvents.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.camunda.taskpool.api.process.definition
2 |
3 | import org.axonframework.serialization.Revision
4 |
5 | /**
6 | * Event sent after a new process has been deployed.
7 | */
8 | @Revision("1")
9 | data class ProcessDefinitionRegisteredEvent(
10 | val processDefinitionId: String,
11 | val processDefinitionKey: String,
12 | val processDefinitionVersion: Int,
13 | val applicationName: String,
14 | val processName: String,
15 | val processVersionTag: String?,
16 | val processDescription: String?,
17 | val formKey: String?,
18 | val startableFromTasklist: Boolean,
19 | val candidateStarterUsers: Set = setOf(),
20 | val candidateStarterGroups: Set = setOf()
21 | )
22 |
--------------------------------------------------------------------------------
/core/taskpool/taskpool-event/src/main/kotlin/io/holunda/camunda/taskpool/api/process/variable/ProcessVariableEvents.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.camunda.taskpool.api.process.variable
2 |
3 | import io.holunda.camunda.taskpool.api.task.SourceReference
4 | import org.axonframework.serialization.Revision
5 |
6 | /**
7 | * Variable has been changed.
8 | */
9 | @Revision("1")
10 | data class ProcessVariablesChangedEvent(
11 | val sourceReference: SourceReference,
12 | val variableChanges: List
13 | )
14 |
--------------------------------------------------------------------------------
/core/taskpool/taskpool-event/src/main/kotlin/io/holunda/camunda/taskpool/mapper/process/ProcessDefinitionMapper.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.camunda.taskpool.mapper.process
2 |
3 | import io.holunda.camunda.taskpool.api.process.definition.ProcessDefinitionRegisteredEvent
4 | import io.holunda.camunda.taskpool.api.process.definition.RegisterProcessDefinitionCommand
5 |
6 | /**
7 | * Maps command to event.
8 | */
9 | fun RegisterProcessDefinitionCommand.registerEvent(): ProcessDefinitionRegisteredEvent =
10 | ProcessDefinitionRegisteredEvent(
11 | processDefinitionId = this.processDefinitionId,
12 | processDefinitionKey = this.processDefinitionKey,
13 | processDefinitionVersion = this.processDefinitionVersion,
14 | processDescription = this.processDescription,
15 | processName = this.processName,
16 | processVersionTag = this.processVersionTag,
17 | applicationName = this.applicationName,
18 | candidateStarterGroups = this.candidateStarterGroups,
19 | candidateStarterUsers = this.candidateStarterUsers,
20 | formKey = this.formKey,
21 | startableFromTasklist = this.startableFromTasklist
22 | )
--------------------------------------------------------------------------------
/core/taskpool/taskpool-event/src/main/kotlin/io/holunda/camunda/taskpool/upcast/AnnotatedEventUpcaster.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.camunda.taskpool.upcast
2 |
3 | /**
4 | * Marks a single event upcaster.
5 | */
6 | @Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE)
7 | @MustBeDocumented
8 | annotation class AnnotatedEventUpcaster(
9 | /**
10 | * Target class type name.
11 | */
12 | val targetClassTypeName: String,
13 | /**
14 | * Target revision, defaults to reserved value [NULL_VALUE] to indicate null
.
15 | */
16 | val revision: String = NULL_VALUE,
17 |
18 | /**
19 | * Representation content type.
20 | */
21 | val representationContentType: RepresentationContentType = RepresentationContentType.XML
22 | ) {
23 | companion object {
24 | const val NULL_VALUE = "SINGLE_EVENT_UPCASTER_NULL_VALUE"
25 | }
26 | }
--------------------------------------------------------------------------------
/core/taskpool/taskpool-event/src/main/kotlin/io/holunda/camunda/taskpool/upcast/RepresentationContentType.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.camunda.taskpool.upcast
2 |
3 | /**
4 | * Supported content types for this upcaster.
5 | */
6 | enum class RepresentationContentType {
7 | JSON, XML
8 | }
--------------------------------------------------------------------------------
/detekt.yml:
--------------------------------------------------------------------------------
1 | #
2 | # see https://github.com/arturbosch/detekt/blob/master/detekt-cli/src/main/resources/default-detekt-config.yml
3 | #
4 | comments:
5 | active: true
6 | excludes: [ "**/test/**","**/*Test.kt","*/src/test/kotlin/**/*.kt","**/*Stages.kt","**/*ITest.kt" ]
7 | CommentOverPrivateFunction:
8 | active: false
9 | CommentOverPrivateProperty:
10 | active: false
11 | EndOfSentenceFormat:
12 | active: false
13 | endOfSentenceFormat: ([.?!][ \t\n\r\f<])|([.?!:]$)
14 | UndocumentedPublicClass:
15 | active: true
16 | searchInNestedClass: true
17 | searchInInnerClass: true
18 | searchInInnerObject: true
19 | searchInInnerInterface: true
20 | UndocumentedPublicFunction:
21 | active: true
22 |
23 | performance:
24 | active: true
25 | SpreadOperator:
26 | active: false
27 |
--------------------------------------------------------------------------------
/docs/CNAME:
--------------------------------------------------------------------------------
1 | www.holunda.io
2 |
--------------------------------------------------------------------------------
/docs/developer-guide/contribution.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Contribution
3 | ---
4 |
5 | There are several ways in which you may contribute to this project.
6 |
7 | * [File issues](https://github.com/holunda-io/camunda-bpm-taskpool/issues)
8 | * Submit a pull requests
9 |
10 | ## Found a bug or missing feature?
11 |
12 | Please [file an issue](https://github.com/holunda-io/camunda-bpm-taskpool/issues) in our
13 | issue tracking system.
14 |
15 | ## Submit a Pull Request
16 |
17 | If you found a solution to an [open issue](https://github.com/holunda-io/camunda-bpm-taskpool/issues)
18 | and implemented it, we would be happy to add your contribution in the code base. For doing so,
19 | please create a pull request. Prior to that, please make sure you:
20 |
21 | - rebase against the `develop` branch
22 | - stick to project coding conventions
23 | - added test cases for the problem you are solving
24 | - added docs, describing the change
25 | - generally comply with codacy report
26 |
--------------------------------------------------------------------------------
/docs/examples/example-components/pa-backend.md:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | title: Process Application Backend
4 | ---
5 |
6 | The process application backend is implementing the process described in the [Example application](../example-application/).
7 | It demonstrates a typical three-tier application, following the Boundary-Control-Entity pattern.
8 |
9 | ## Boundary Tier
10 | The REST API is defined using OpenAPI specification and is implemented by Spring MVC controllers. It defines of four
11 | logical parts:
12 |
13 | - Environment Controller
14 | - Request Controller
15 | - Approve Task Controller
16 | - Amend Task Controller
17 |
18 | ## Control Tier
19 | The control tier is implemented using stateless Spring Beans and orchestrated by the Camunda BPM Process.
20 | Typical `JavaDelegate` and `ExecutionListener` are used as a glue layer. Business services of this layer are
21 | responsible for the integration with `Datapool Components` to reflect the status of the `Request` business entity.
22 | The Camunda BPM Engine is configured to use the `TaskCollector` to integrate with remaining components of
23 | the `camunda-bpm-taskpool`.
24 |
25 | ## Entity Tier
26 | The entity tier is implemented using Spring Data JPA, using Hibernate entities. Application data and process engine data is stored using a RDBMS.
27 |
--------------------------------------------------------------------------------
/docs/examples/example-components/pa-frontend.md:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | title: Process Application Frontend
4 | ---
5 |
6 | The process application frontend is implementing the user task forms and business object views for the
7 | example application. It is built as a typical Angular Single Page Application (SPA) and provides
8 | views for both user tasks and the business objects. It communicates with process application backend via
9 | REST API, defined in the latter.
10 |
11 | The user primarily interacts with the process platform which seamlessly integrates with the process applications.
12 | Usually, it provides integration points for user-task embedding / UI-composition. Unfortunately,
13 | this topic strongly depends on the frontend technology and is not a subject we want to demonstrate
14 | in this example. For simplicity, we built a very simple example, skipping the UI composition / integration entirely.
15 |
16 | The navigation between the process platform and process application is just as simple as a full page
17 | navigation of a hyperlink.
18 |
--------------------------------------------------------------------------------
/docs/examples/example-components/pp-backend.md:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | title: Process Platform Backend
4 | ---
5 |
6 | The purpose of the example process platform backend is to demonstrate how __process agnostic__ parts of the
7 | process solution can be implemented.
8 |
--------------------------------------------------------------------------------
/docs/examples/example-components/user-management.md:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | title: User Management
4 | ---
5 |
6 | Usually, a central user management like a Single-Sign-On (SSO) is a part deployed into the process application
7 | landscape. This is responsible for authentication and authorization of the user and is required to control the
8 | role-based access to user tasks.
9 |
10 | In our example application, we __disable any security checks__ to avoid the unneeded complexity. In doing so, we
11 | implemented a trivial user store holding some pre-defined users used in example components and allow to simply
12 | switch users from the frontend by choosing a different user from the drop-down list.
13 |
14 | It is integrated with the example frontends by passing around the user id along with the requests and provide a way
15 | to resolve the user by that id. Technically speaking, the user id can be used to retrieve the permissions of the user
16 | and check them in the backend.
17 |
--------------------------------------------------------------------------------
/docs/examples/index.md:
--------------------------------------------------------------------------------
1 | We provide the following examples to demonstrate the features of Polyflow:
2 |
3 | - [Example Approval](example-approval.md)
--------------------------------------------------------------------------------
/docs/examples/scenarios/single-node.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Scenario for running on a single node
3 | ---
4 |
5 | This example demonstrates the usage of the Camunda BPM Taskpool deployed in one single node and is built as a SpringBoot application
6 | described in the [Deployment](../../introduction/deployment.md) section.
7 |
8 | ### System Requirements
9 |
10 | * JDK 11
11 |
12 | ### Preparations
13 |
14 | Before you begin, please build the entire project with `./mvnw clean install` from the command line in the project root directory.
15 |
16 | ### Start
17 |
18 | The demo application consists of one Maven module which can be started by running from command line in
19 | the `examples/scenarios/single-node-jpa` directory using Maven. Alternatively you can start the packaged application using:
20 |
21 | ```bash
22 | java -jar target/*.jar
23 | ```
24 |
25 | ## Useful URLs
26 |
27 | * [http://localhost:8080/polyflow/](http://localhost:8080/polyflow/)
28 | * [http://localhost:8080/swagger-ui/](http://localhost:8080/swagger-ui/)
29 | * [http://localhost:8080/camunda/app/tasklist/default/](http://localhost:8080/camunda/app/tasklist/default/)
30 |
--------------------------------------------------------------------------------
/docs/img/Negative@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/Negative@2x.png
--------------------------------------------------------------------------------
/docs/img/Positive@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/Positive@2x.png
--------------------------------------------------------------------------------
/docs/img/architecture-collector.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/architecture-collector.png
--------------------------------------------------------------------------------
/docs/img/collector-building-blocks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/collector-building-blocks.png
--------------------------------------------------------------------------------
/docs/img/deployment-axon-server-events-only.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/deployment-axon-server-events-only.png
--------------------------------------------------------------------------------
/docs/img/deployment-axon-server.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/deployment-axon-server.png
--------------------------------------------------------------------------------
/docs/img/deployment-messaging.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/deployment-messaging.png
--------------------------------------------------------------------------------
/docs/img/deployment-single.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/deployment-single.png
--------------------------------------------------------------------------------
/docs/img/example_amend_request.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/example_amend_request.png
--------------------------------------------------------------------------------
/docs/img/example_approve_request.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/example_approve_request.png
--------------------------------------------------------------------------------
/docs/img/example_archive_business_object.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/example_archive_business_object.png
--------------------------------------------------------------------------------
/docs/img/example_archive_completed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/example_archive_completed.png
--------------------------------------------------------------------------------
/docs/img/example_start_form.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/example_start_form.png
--------------------------------------------------------------------------------
/docs/img/example_tasklist_approve_data.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/example_tasklist_approve_data.png
--------------------------------------------------------------------------------
/docs/img/example_tasklist_approve_description.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/example_tasklist_approve_description.png
--------------------------------------------------------------------------------
/docs/img/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/favicon.ico
--------------------------------------------------------------------------------
/docs/img/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/favicon.png
--------------------------------------------------------------------------------
/docs/img/polyflow-65x61.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/polyflow-65x61.png
--------------------------------------------------------------------------------
/docs/img/polyflow-hero-530x406.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/polyflow-hero-530x406.png
--------------------------------------------------------------------------------
/docs/img/process-platform-architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/process-platform-architecture.png
--------------------------------------------------------------------------------
/docs/img/process_approve_request.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/process_approve_request.png
--------------------------------------------------------------------------------
/docs/img/scenario_kafka_messaging_overview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/scenario_kafka_messaging_overview.png
--------------------------------------------------------------------------------
/docs/img/scenario_kafka_messaging_tx_view.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/scenario_kafka_messaging_tx_view.png
--------------------------------------------------------------------------------
/docs/img/scenario_kafka_to_tasklist_detail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/scenario_kafka_to_tasklist_detail.png
--------------------------------------------------------------------------------
/docs/img/scenario_process_application_to_kafka_detail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/scenario_process_application_to_kafka_detail.png
--------------------------------------------------------------------------------
/docs/img/tasklist-angular-classic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/tasklist-angular-classic.png
--------------------------------------------------------------------------------
/docs/img/tasklist-angular-data.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/holunda-io/camunda-bpm-taskpool/01eff184afcf3b1de13483a2172ddfae69c88438/docs/img/tasklist-angular-data.png
--------------------------------------------------------------------------------
/docs/migration-guide/index.md:
--------------------------------------------------------------------------------
1 | This guide contains hints for upgrading to newer versions whenever there are breaking changes.
2 |
3 | ## Migrating to 4.x
4 |
5 | Version 4.x upgrades the Spring Boot dependency from 2.x to 3.x, which also requires upgrading Camunda to >=7.20 and Axon to >=4.7. It also means that Hibernate 6 is used now,
6 | which changes the way database sequences are created for sequence generators.
7 |
8 | Axon uses sequence generators for its tables and thus if you come from an older Hibernate version, you probably have a sequence called `hibernate_sequence` in your database.
9 | You can either create separate sequences per table and take care to have them start at the right value (recommended in
10 | the [Axon migration guide](https://docs.axoniq.io/reference-guide/axon-framework/upgrading-to-4-7#step-3-1)) or set the JPA property `hibernate.id.db_structure_naming_strategy`
11 | to `legacy` to restore the old behavior. In the Spring application properties, you would have to set this property:
12 |
13 | ```properties
14 | spring.jpa.properties.hibernate.id.db_structure_naming_strategy=legacy
15 | ```
16 |
--------------------------------------------------------------------------------
/docs/reference-guide/components/camunda-interaction-client.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Camunda Engine Interaction Client
3 | pageId: engine-interaction-client
4 | ---
5 |
6 | ## Camunda Engine Interaction Client
7 |
8 |
9 | ### Purpose
10 |
11 | This component performs changes delivered by Camunda Interaction Events on Camunda BPM engine.
12 | The following Camunda Interaction Events are supported:
13 |
14 | * Claim User Task
15 | * Unclaim User Task
16 | * Defer User Task
17 | * Undefer User Task
18 | * Complete User Task
19 |
20 | ### Usage and configuration
21 |
22 | To use Camunda Engine Interaction Client please add the following artifact to your classpath:
23 |
24 | ```xml
25 |
26 | io.holunda.polyflow
27 | polyflow-camunda-bpm-engine-client
28 |
29 | ```
30 |
31 | In your `application.yml` configure the application name of your process engine, to receive commands:
32 |
33 | ```yml
34 | polyflow:
35 | integration:
36 | client:
37 | camunda:
38 | application-name: my-process-application # defaults to ${spring.application.name}
39 | ```
40 |
--------------------------------------------------------------------------------
/docs/reference-guide/components/camunda-starter.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Camunda Engine Taskpool Support SpringBoot Starter
3 | pageId: engine-starter
4 | ---
5 |
6 | ### Purpose
7 |
8 | The Polyflow Camunda Platform 7 SpringBoot Starter is a convenience module providing a single
9 | module dependency to be included in the process application. It includes all process application
10 | modules and provides meaningful defaults for their options.
11 |
12 | ### Configuration
13 |
14 | In order to enable the starter, please put the following dependency on your class path:
15 |
16 | ```xml
17 |
18 | io.holunda.polyflow
19 | polyflow-camunda-bpm-springboot-starter
20 |
21 | ```
22 |
23 | The included `TaskpoolEngineSupportConfiguration` is a SpringBoot AutoConfiguration that configures the required components.
24 | If you want to configure it manually, please add the `@EnableTaskpoolEngineSupport` annotation on any `@Configuration` annotated
25 | class of your SpringBoot application.
26 |
27 | The `@EnableTaskpoolEngineSupport` annotation has the same effect as the following block of annotations:
28 |
29 | ```java
30 | @EnableCamundaTaskpoolCollector
31 | @EnableDataEntrySender
32 | public class MyApplication {
33 | //...
34 | }
35 | ```
36 |
--------------------------------------------------------------------------------
/docs/reference-guide/components/core-taskpool.md:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | title: Taskpool Core
4 | pageId: core-taskpool
5 |
6 | ---
7 | ### Purpose
8 |
9 | The component is responsible for maintaining and storing the consistent state of the taskpool
10 | core concepts:
11 |
12 | * Task (represents a user task instance)
13 | * Process Definition (represents a process definition)
14 |
15 | The component receives all commands and emits events, if changes are performed on underlying entities.
16 | The event stream is used to store all changes (purely event-sourced) and should be used by all other
17 | parties interested in changes.
18 |
--------------------------------------------------------------------------------
/docs/reference-guide/components/other-variable-serializer.md:
--------------------------------------------------------------------------------
1 | ### Purpose
2 |
3 | Provides shared code configuring the variable serializer.
4 |
5 |
6 |
--------------------------------------------------------------------------------
/docs/reference-guide/components/view-api-client.md:
--------------------------------------------------------------------------------
1 | ## Purpose
2 |
3 | The Polyflow View API Client is a client for the users of the task-pool and the data-pool query API. It provides simple components which can be used
4 | in order to query the configured views. By doing so, it defines an easy-to-use API for **callers**.
5 |
6 | ## Usage
7 |
8 | Please put the following component to you class path:
9 |
10 | ```xml
11 |
12 | io.holunda.polyflow
13 | polyflow-view-api-client
14 |
15 | ```
16 |
17 | The components available are:
18 |
19 | * `io.holunda.polyflow.view.DataEntryQueryClient`
20 | * `io.holunda.polyflow.view.ProcessDefinitionQueryClient`
21 | * `io.holunda.polyflow.view.ProcessInstanceQueryClient`
22 | * `io.holunda.polyflow.view.ProcessVariableQueryClient`
23 | * `io.holunda.polyflow.view.TaskQueryClient`
24 |
25 | To initialize the client, you need to pass the `queryGateway` to it:
26 |
27 | ```kotlin
28 | @Bean
29 | fun myTaskClient(queryGateway: QueryGateway) = TaskQueryClient(queryGateway)
30 |
31 | ```
32 |
33 | If you are using Kotlin, you might like the extension functions of the `QueryGateway` provided by `io.holunda.polyflow.view.QueryGatewayExt` object.
34 |
--------------------------------------------------------------------------------
/docs/reference-guide/configuration/index.md:
--------------------------------------------------------------------------------
1 | This is a root of configuration reference guide.
2 |
3 | Here are some dedicated articles:
4 |
5 | * [Persistence configuration](persistence.md)
6 | * [Mongo DB View configuration](view-mongo.md)
7 | * [Datapool Aggregate Tuning](core-datapool-aggregate-tuning.md)
8 | * [Deployment of Polyflow Core inside Process applications](local-core-deployment.md)
9 |
--------------------------------------------------------------------------------
/docs/reference-guide/configuration/persistence.md:
--------------------------------------------------------------------------------
1 | ## Persistence
2 |
3 | If you use relational databases for your Event Store of the [DataPool](../components/core-datapool.md) or [TaskPool](../components/core-taskpool.md) or your view,
4 | using the [JPA View](../components/view-jpa.md), Axon Framework, used as a component of Polyflow will detect and autoconfigure itself. Especially, if you use
5 | Spring Data JPA or Spring JDBC, Axon auto-configuration will try to reuse it.
6 |
7 | If you are using `@EntityScan` annotation, you need to add Axon entities to the scan. To do so, please the following code on top of a class marked with `@Configuration`.
8 |
9 | ```kotlin
10 | @Configuration
11 | @EntityScan(
12 | basePackageClasses = [
13 | TokenEntry::class, DomainEventEntry::class, SagaEntry::class
14 | ]
15 | )
16 | class MyConfiguration
17 | ```
18 |
--------------------------------------------------------------------------------
/docs/reference-guide/index.md:
--------------------------------------------------------------------------------
1 | This reference guide is a primary source of information in order to understand how Polyflow components are used and how to configure them.
2 | It is divided into tow major sections:
3 |
4 | * [Components](components)
5 | * [Configuration](configuration)
6 |
7 |
8 |
--------------------------------------------------------------------------------
/docs/requirements.txt:
--------------------------------------------------------------------------------
1 | mkdocs
2 | mkdocs-git-committers-plugin
3 | mkdocs-material
4 | mike
5 | mkdocs-git-revision-date-localized-plugin
6 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/engine-client/src/main/kotlin/io/holunda/polyflow/client/camunda/CamundaEngineClientAutoConfiguration.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.client.camunda
2 |
3 | import io.holunda.polyflow.spring.ApplicationNameBeanPostProcessor
4 | import org.camunda.bpm.spring.boot.starter.CamundaBpmAutoConfiguration
5 | import org.springframework.boot.autoconfigure.AutoConfigureAfter
6 | import org.springframework.boot.context.properties.EnableConfigurationProperties
7 | import org.springframework.context.annotation.ComponentScan
8 | import org.springframework.context.annotation.Import
9 |
10 | /**
11 | * Engine client configuration enabling the event handling of interaction commands.
12 | */
13 | @ComponentScan
14 | @AutoConfigureAfter(CamundaBpmAutoConfiguration::class)
15 | @EnableConfigurationProperties(CamundaEngineClientProperties::class)
16 | @Import(ApplicationNameBeanPostProcessor::class)
17 | class CamundaEngineClientAutoConfiguration
18 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/engine-client/src/main/kotlin/io/holunda/polyflow/client/camunda/CamundaEngineClientProperties.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.client.camunda
2 |
3 | import io.holunda.polyflow.spring.ApplicationNameBeanPostProcessor.Companion.UNSET_APPLICATION_NAME
4 | import org.springframework.boot.context.properties.ConfigurationProperties
5 |
6 | /**
7 | * Properties to configure Camunda to receive interaction commands via Axon.
8 | */
9 | @ConfigurationProperties("polyflow.integration.client.camunda")
10 | data class CamundaEngineClientProperties(
11 |
12 | /**
13 | * Denotes the (logical) name of the process application.
14 | * As Default, spring.application.name will be used
15 | */
16 | // The default is set by ApplicationNameBeanPostProcessor
17 | var applicationName: String = UNSET_APPLICATION_NAME
18 | )
19 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/engine-client/src/main/kotlin/io/holunda/polyflow/client/camunda/EnableCamundaEngineClient.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.client.camunda
2 |
3 | import org.springframework.context.annotation.Import
4 |
5 | /**
6 | * Starts camunda client component accepting interaction commands.
7 | */
8 | @MustBeDocumented
9 | @Import(CamundaEngineClientAutoConfiguration::class)
10 | annotation class EnableCamundaEngineClient
11 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/engine-client/src/main/kotlin/io/holunda/polyflow/client/camunda/process/ProcessStarter.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.client.camunda.process
2 |
3 | import org.camunda.bpm.engine.RuntimeService
4 | import org.camunda.bpm.engine.variable.VariableMap
5 | import org.springframework.stereotype.Component
6 |
7 | /**
8 | * Starts process.
9 | */
10 | @Component
11 | class ProcessStarter(private val runtimeService: RuntimeService) {
12 |
13 | /**
14 | * Starts process.
15 | * @param processDefinitionKey definition key.
16 | * @param payload variables.
17 | * @param businessKey optional business key.
18 | * @return process instance id.
19 | */
20 | fun startProcess(
21 | processDefinitionKey: String,
22 | payload: VariableMap,
23 | businessKey: String?
24 | ): String {
25 | val instance = if (businessKey != null) {
26 | runtimeService.startProcessInstanceByKey(processDefinitionKey, businessKey, payload)
27 | } else {
28 | runtimeService.startProcessInstanceByKey(processDefinitionKey, payload)
29 | }
30 | return instance.processInstanceId
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/engine-client/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports:
--------------------------------------------------------------------------------
1 | io.holunda.polyflow.client.camunda.CamundaEngineClientAutoConfiguration
2 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/engine-client/src/test/kotlin/io/holunda/polyflow/client/camunda/CamundaEngineClientPropertiesITest.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.client.camunda
2 |
3 | import org.assertj.core.api.Assertions.assertThat
4 | import org.camunda.bpm.engine.RuntimeService
5 | import org.camunda.bpm.engine.TaskService
6 | import org.junit.jupiter.api.Test
7 | import org.springframework.beans.factory.annotation.Autowired
8 | import org.springframework.boot.test.context.SpringBootTest
9 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment.MOCK
10 | import org.springframework.boot.test.mock.mockito.MockBean
11 | import org.springframework.test.context.ActiveProfiles
12 |
13 | @SpringBootTest(classes = [CamundaEngineClientPropertiesTestApplication::class], webEnvironment = MOCK)
14 | @ActiveProfiles("properties-itest")
15 | class CamundaEngineClientPropertiesITest {
16 |
17 | @MockBean
18 | lateinit var runtimeService: RuntimeService
19 |
20 | @MockBean
21 | lateinit var taskService: TaskService
22 |
23 | @Autowired
24 | lateinit var props: CamundaEngineClientProperties
25 |
26 | @Test
27 | fun test_properties() {
28 | assertThat(props.applicationName).isEqualTo("Foo")
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/engine-client/src/test/kotlin/io/holunda/polyflow/client/camunda/CamundaEngineClientPropertiesTestApplication.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.client.camunda
2 |
3 | import org.springframework.boot.autoconfigure.SpringBootApplication
4 | import org.springframework.boot.context.properties.EnableConfigurationProperties
5 |
6 | @SpringBootApplication
7 | @EnableConfigurationProperties(CamundaEngineClientProperties::class)
8 | class CamundaEngineClientPropertiesTestApplication
9 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/engine-client/src/test/resources/application-properties-itest.yaml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: Foo
4 |
5 | axon:
6 | axonserver:
7 | enabled: false
8 |
9 | camunda:
10 | bpm:
11 | enabled: false
12 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/engine-client/src/test/resources/banner.txt:
--------------------------------------------------------------------------------
1 | -------------------------------------------------------------------------------
2 | I-Test using SpringBoot: ${spring-boot.version}, Camunda ${camunda.bpm.version}
3 | -------------------------------------------------------------------------------
4 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/engine-client/src/test/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/springboot-autoconfigure/src/main/kotlin/io/holunda/polyflow/taskpool/EnableTaskpoolEngineSupport.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool
2 |
3 | import org.springframework.context.annotation.Import
4 |
5 | /**
6 | * Put this annotation on your process application configuration to enable
7 | * defaults of task pool engine components.
8 | */
9 | @MustBeDocumented
10 | @Import(TaskpoolEngineSupportConfiguration::class)
11 | annotation class EnableTaskpoolEngineSupport
12 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/springboot-autoconfigure/src/main/kotlin/io/holunda/polyflow/taskpool/TaskpoolEngineSupportConfiguration.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool
2 |
3 | import io.holunda.polyflow.datapool.EnableDataEntrySender
4 | import org.springframework.context.annotation.Configuration
5 |
6 | /**
7 | * Configuration enabling engine components.
8 | */
9 | @EnableCamundaTaskpoolCollector
10 | @EnableDataEntrySender
11 | class TaskpoolEngineSupportConfiguration
12 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/springboot-autoconfigure/src/test/resources/application.yml:
--------------------------------------------------------------------------------
1 | camunda:
2 | bpm:
3 | eventing:
4 | task: false
5 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/springboot-autoconfigure/src/test/resources/banner.txt:
--------------------------------------------------------------------------------
1 | -------------------------------------------------------------------------------
2 | I-Test using SpringBoot: ${spring-boot.version}, Camunda ${camunda.bpm.version}
3 | -------------------------------------------------------------------------------
4 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/springboot-autoconfigure/src/test/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/springboot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports:
--------------------------------------------------------------------------------
1 | io.holunda.polyflow.taskpool.collector.CamundaTaskpoolCollectorConfiguration
2 | io.holunda.polyflow.taskpool.sender.SenderConfiguration
3 | io.holunda.polyflow.datapool.DataEntrySenderConfiguration
4 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/springboot-starter/src/test/resources/application.yml:
--------------------------------------------------------------------------------
1 | camunda:
2 | bpm:
3 | eventing:
4 | task: false
5 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/springboot-starter/src/test/resources/banner.txt:
--------------------------------------------------------------------------------
1 | -------------------------------------------------------------------------------
2 | I-Test using SpringBoot: ${spring-boot.version}, Camunda ${camunda.bpm.version}
3 | -------------------------------------------------------------------------------
4 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/CamundaEngineExtensions.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool
2 |
3 | import org.camunda.bpm.engine.context.ProcessEngineContext
4 | import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl
5 | import org.camunda.bpm.engine.impl.interceptor.Command
6 | import org.camunda.bpm.engine.impl.persistence.entity.IdentityLinkEntity
7 | import org.camunda.bpm.engine.impl.persistence.entity.ProcessDefinitionEntity
8 |
9 | /**
10 | * Runs a command in command context.
11 | */
12 | fun ProcessEngineConfigurationImpl.executeInCommandContext(command: Command): T {
13 | return this.commandExecutorTxRequired.execute(command)
14 | }
15 | /**
16 | * Execute call in a process engine context.
17 | * @param newContext if set to true, the new context is created.
18 | * @param call function to be called inside the process engine context.
19 | * @return T return value of the function.
20 | */
21 | fun callInProcessEngineContext(newContext: Boolean, call: () -> T): T {
22 | return if (newContext) {
23 | try {
24 | ProcessEngineContext.requiresNew();
25 | call.invoke()
26 | } finally {
27 | ProcessEngineContext.clear();
28 | }
29 | } else {
30 | call.invoke()
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/EnableCamundaTaskpoolCollector.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool
2 |
3 | import io.holunda.polyflow.taskpool.collector.CamundaTaskpoolCollectorConfiguration
4 | import org.springframework.context.annotation.Import
5 |
6 | /**
7 | * Enables the task collector, which listens to Camunda Spring Events and performs, collecting, enriching and sending
8 | * of taskpool commands to Task Pool Core.
9 | */
10 | @MustBeDocumented
11 | @Import(CamundaTaskpoolCollectorConfiguration::class)
12 | @EnableTaskpoolSender
13 | annotation class EnableCamundaTaskpoolCollector
14 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/VariableMapExtensions.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool
2 |
3 | import org.camunda.bpm.engine.variable.VariableMap
4 | import org.camunda.bpm.engine.variable.Variables
5 |
6 | /**
7 | * Add all elements from one variable map to another.
8 | * @param source source of the variables.
9 | */
10 | fun VariableMap.putAllTyped(source: VariableMap) {
11 | source.keys.forEach {
12 | this.putValueTyped(it, source.getValueTyped(it))
13 | }
14 | }
15 |
16 | /**
17 | * Filters keys by a predicate.
18 | * @param predicate filter function.
19 | * @return new variable map containing only entries for which the keys are matching the filter function.
20 | */
21 | inline fun VariableMap.filterKeys(predicate: (String) -> Boolean): VariableMap {
22 | val result = Variables.createVariables()
23 | for (entry in this) {
24 | if (predicate(entry.key)) {
25 | result[entry.key] = entry.value
26 | }
27 | }
28 | return result
29 | }
30 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/collector/FallbackProcessVariablesCorrelatorConfiguration.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.collector
2 |
3 | import io.holunda.polyflow.taskpool.collector.task.enricher.ProcessVariablesCorrelator
4 | import org.camunda.bpm.spring.boot.starter.CamundaBpmAutoConfiguration
5 | import org.springframework.boot.autoconfigure.AutoConfigureAfter
6 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
7 | import org.springframework.context.annotation.Bean
8 | import org.springframework.context.annotation.Configuration
9 |
10 | /**
11 | * Configures fallback if no process variable correlator is defined.
12 | * No @Configuration required.
13 | * Configuration used via auto-configuration.
14 | */
15 | @ConditionalOnMissingBean(ProcessVariablesCorrelator::class)
16 | class FallbackProcessVariablesCorrelatorConfiguration {
17 | /**
18 | * Empty correlator.
19 | */
20 | @Bean
21 | fun processVariablesCorrelatorFallback(): ProcessVariablesCorrelator = ProcessVariablesCorrelator()
22 | }
23 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/collector/FallbackProcessVariablesFilterConfiguration.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.collector
2 |
3 | import io.holunda.polyflow.taskpool.collector.task.enricher.ProcessVariablesFilter
4 | import org.camunda.bpm.spring.boot.starter.CamundaBpmAutoConfiguration
5 | import org.springframework.boot.autoconfigure.AutoConfigureAfter
6 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
7 | import org.springframework.context.annotation.Bean
8 | import org.springframework.context.annotation.Configuration
9 |
10 | /**
11 | * Configures fallback if no process variable filter is defined.
12 | * No @Configuration required.
13 | * Configuration used via auto-configuration.
14 | */
15 | @ConditionalOnMissingBean(ProcessVariablesFilter::class)
16 | class FallbackProcessVariablesFilterConfiguration {
17 | /**
18 | * Empty process variable filter.
19 | */
20 | @Bean
21 | fun processVariablesFilterFallback(): ProcessVariablesFilter = ProcessVariablesFilter()
22 | }
23 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/collector/process/definition/ProcessDefinitionProcessor.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.collector.process.definition
2 |
3 | import io.github.oshai.kotlinlogging.KotlinLogging
4 | import io.holunda.camunda.taskpool.api.process.definition.ProcessDefinitionCommand
5 | import io.holunda.polyflow.taskpool.sender.process.definition.ProcessDefinitionCommandSender
6 | import org.springframework.context.event.EventListener
7 |
8 | private val logger = KotlinLogging.logger {}
9 |
10 | /**
11 | * Processes commands sent via Spring Eventing and delegates them to taskpool command sender.
12 | */
13 | class ProcessDefinitionProcessor(
14 | private val processDefinitionCommandSender: ProcessDefinitionCommandSender
15 | ) {
16 |
17 | /**
18 | * Receives the process definition command and pass it over to the sender.
19 | * @param command process definition command, delivered by Spring eventing.
20 | */
21 | @EventListener
22 | fun process(command: ProcessDefinitionCommand) {
23 | if (logger.isTraceEnabled()) {
24 | logger.trace { "COLLECTOR-005: Sending process definition command: $command" }
25 | }
26 | processDefinitionCommandSender.send(command)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/collector/process/definition/RefreshProcessDefinitionRegistrationParseListener.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.collector.process.definition
2 |
3 | import io.holunda.polyflow.taskpool.executeInCommandContext
4 | import org.camunda.bpm.engine.impl.bpmn.parser.AbstractBpmnParseListener
5 | import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl
6 | import org.camunda.bpm.engine.impl.persistence.entity.ProcessDefinitionEntity
7 | import org.camunda.bpm.engine.impl.util.xml.Element
8 |
9 | /**
10 | * Parse listener that starts a refresh process definition job on every new process parse (deployment).
11 | */
12 | class RefreshProcessDefinitionRegistrationParseListener(
13 | private val processEngineConfiguration: ProcessEngineConfigurationImpl
14 | ) : AbstractBpmnParseListener() {
15 |
16 | override fun parseProcess(processElement: Element, processDefinition: ProcessDefinitionEntity) {
17 | // create job / send command to job executor
18 | // to handle this deployment asynchronous.
19 | processEngineConfiguration.executeInCommandContext(RefreshProcessDefinitionsJobCommand(processDefinitionKey = processDefinition.key))
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/collector/process/instance/ProcessInstanceProcessor.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.collector.process.instance
2 |
3 | import io.github.oshai.kotlinlogging.KotlinLogging
4 | import io.holunda.camunda.taskpool.api.process.instance.ProcessInstanceCommand
5 | import io.holunda.polyflow.taskpool.sender.process.instance.ProcessInstanceCommandSender
6 | import org.springframework.context.event.EventListener
7 |
8 | private val logger = KotlinLogging.logger {}
9 |
10 | /**
11 | * Default process instance processor.
12 | */
13 | class ProcessInstanceProcessor(
14 | private val processInstanceCommandSender: ProcessInstanceCommandSender
15 | ) {
16 |
17 | /**
18 | * Reacts on incoming process instance commands.
19 | * @param command command about process instance to send.
20 | */
21 | @EventListener
22 | fun process(command: ProcessInstanceCommand) {
23 | if (logger.isTraceEnabled()) {
24 | logger.trace { "COLLECTOR-006: Sending process instance command: $command" }
25 | }
26 | processInstanceCommandSender.send(command)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/collector/task/TaskAssigner.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.collector.task
2 |
3 | import io.holunda.camunda.taskpool.api.task.EngineTaskCommand
4 |
5 | /**
6 | * Hook for assignment changes.
7 | */
8 | interface TaskAssigner {
9 | /**
10 | * Sets assignment of a task command.
11 | * @param command task command
12 | * @return command with modified assignment information.
13 | */
14 | fun setAssignment(command: EngineTaskCommand): EngineTaskCommand
15 | }
16 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/collector/task/VariablesEnricher.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.collector.task
2 |
3 | import io.holunda.camunda.taskpool.api.task.TaskIdentityWithPayloadAndCorrelations
4 |
5 | /**
6 | * Enriches commands with payload.
7 | */
8 | interface VariablesEnricher {
9 | /**
10 | * Enriches command with payload and correlations.
11 | */
12 | fun enrich(command: T): T
13 | }
14 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/collector/task/assigner/EmptyTaskAssigner.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.collector.task.assigner
2 |
3 | import io.holunda.camunda.taskpool.api.task.EngineTaskCommand
4 | import io.holunda.polyflow.taskpool.collector.task.TaskAssigner
5 |
6 | /**
7 | * No-op task assigner changing nothing.
8 | */
9 | class EmptyTaskAssigner : TaskAssigner {
10 | override fun setAssignment(command: EngineTaskCommand): EngineTaskCommand = command
11 | }
12 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/collector/task/enricher/EmptyTaskCommandEnricher.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.collector.task.enricher
2 |
3 | import io.holunda.camunda.taskpool.api.task.TaskIdentityWithPayloadAndCorrelations
4 | import io.holunda.polyflow.taskpool.collector.task.VariablesEnricher
5 |
6 |
7 | /**
8 | * Empty implementation without any enrichment. Used for compliance of the commands.
9 | */
10 | class EmptyTaskCommandEnricher : VariablesEnricher {
11 | override fun enrich(command: T): T = command.apply { enriched = true }
12 | }
13 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/collector/task/enricher/ProcessVariableCorrelation.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.collector.task.enricher
2 |
3 | import io.holunda.camunda.taskpool.api.business.EntryType
4 |
5 | /**
6 | * Describes correlation between data entries for a business process definition.
7 | * @param processDefinitionKey process definition key.
8 | * @param correlations a map from task definition key to correlation map (variableName, entryType).
9 | * @param globalCorrelations a global (per-process) correlation map (variableName, entryType).
10 | */
11 | data class ProcessVariableCorrelation(
12 | val processDefinitionKey: ProcessDefinitionKey,
13 | val correlations: Map>,
14 | val globalCorrelations: Map = emptyMap()
15 | )
16 |
17 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/collector/task/enricher/ProcessVariableFilter.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.collector.task.enricher
2 |
3 | /**
4 | * This filter allows to either explicitly include (whitelist) or exclude (blacklist) process variables for all user tasks of a certain
5 | * process (if a process definition key is given), or for all user tasks of all processes (if no process definition key is given).
6 | * If a differentiation between individual user tasks of a process is required, use a {@link TaskVariableFilter} instead.
7 | */
8 | data class ProcessVariableFilter(
9 | override val processDefinitionKey: ProcessDefinitionKey?,
10 | val filterType: FilterType,
11 | val processVariables: List = emptyList()
12 | ) : VariableFilter {
13 |
14 | constructor(filterType: FilterType, processVariables: List) : this(null, filterType, processVariables)
15 |
16 | override fun filter(taskDefinitionKey: TaskDefinitionKey, variableName: VariableName): Boolean {
17 | return (filterType == FilterType.INCLUDE) == processVariables.contains(variableName)
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/taskpool-collector/src/main/kotlin/io/holunda/polyflow/taskpool/collector/task/enricher/VariableFilter.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.collector.task.enricher
2 |
3 | /**
4 | * To be implemented by classes that filter process variables. Used during enrichment to decide which process variables are added to a task's payload.
5 | */
6 | interface VariableFilter {
7 |
8 | val processDefinitionKey: ProcessDefinitionKey?
9 |
10 | /**
11 | * Returns whether the process variable with the given name shall be contained in the payload of the given task.
12 | * @param taskDefinitionKey the key of the task to be enriched
13 | * @param variableName the name of the process variable
14 | */
15 | fun filter(taskDefinitionKey: TaskDefinitionKey, variableName: VariableName): Boolean
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/taskpool-collector/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports:
--------------------------------------------------------------------------------
1 | io.holunda.polyflow.taskpool.collector.FallbackProcessVariablesCorrelatorConfiguration
2 | io.holunda.polyflow.taskpool.collector.FallbackProcessVariablesFilterConfiguration
3 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/taskpool-collector/src/test/kotlin/io/holunda/polyflow/taskpool/itest/JacksonDataFormatConfigurator.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.itest
2 |
3 | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
4 | import com.fasterxml.jackson.module.kotlin.KotlinModule
5 | import org.camunda.spin.impl.json.jackson.format.JacksonJsonDataFormat
6 | import org.camunda.spin.spi.DataFormatConfigurator
7 |
8 | class JacksonDataFormatConfigurator : DataFormatConfigurator {
9 |
10 | override fun configure(dataFormat: JacksonJsonDataFormat) {
11 | val objectMapper = dataFormat.objectMapper
12 | objectMapper.registerModule(KotlinModule.Builder().build())
13 | objectMapper.registerModule(JavaTimeModule())
14 | }
15 |
16 | override fun getDataFormatClass(): Class {
17 | return JacksonJsonDataFormat::class.java
18 | }
19 | }
--------------------------------------------------------------------------------
/integration/camunda-bpm/taskpool-collector/src/test/resources/META-INF/services/org.camunda.spin.spi.DataFormatConfigurator:
--------------------------------------------------------------------------------
1 | io.holunda.polyflow.taskpool.itest.JacksonDataFormatConfigurator
2 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/taskpool-collector/src/test/resources/application-properties-itest.yml:
--------------------------------------------------------------------------------
1 | #
2 | # I-Test properties justifying that no properties are needed to start Spring Boot with Camunda Task Pool collector.
3 | #
4 | spring:
5 | application:
6 | name: Foo
7 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/taskpool-collector/src/test/resources/banner.txt:
--------------------------------------------------------------------------------
1 | -------------------------------------------------------------------------------
2 | I-Test using SpringBoot: ${spring-boot.version}, Camunda ${camunda.bpm.version}
3 | -------------------------------------------------------------------------------
4 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/taskpool-collector/src/test/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/taskpool-job-sender/src/main/kotlin/io/holunda/polyflow/taskpool/sender/EngineTaskCommandsSendingJobHandlerConfiguration.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.sender
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper
4 | import com.fasterxml.jackson.module.kotlin.readValue
5 | import org.camunda.bpm.engine.impl.jobexecutor.JobHandlerConfiguration
6 |
7 | /**
8 | * Configuration for a job handler sending commands to Taskpool Core.
9 | * @param taskId for what task id we are sending commands
10 | * @param commandByteArrayId reference to the resource entity in ACT_GE_BYTEARRAY storing byte serialized JSON of List.
11 | */
12 | data class EngineTaskCommandsSendingJobHandlerConfiguration(
13 | val taskId: String,
14 | val commandByteArrayId: String
15 | ) : JobHandlerConfiguration {
16 |
17 | companion object {
18 | /**
19 | * Reconstructs the configuration from JSON String.
20 | */
21 | fun fromCanonicalString(value: String, objectMapper: ObjectMapper): EngineTaskCommandsSendingJobHandlerConfiguration {
22 | return objectMapper.readValue(value)
23 | }
24 | }
25 |
26 | // will never be used.
27 | override fun toCanonicalString(): String = throw UnsupportedOperationException()
28 | }
--------------------------------------------------------------------------------
/integration/camunda-bpm/taskpool-job-sender/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports:
--------------------------------------------------------------------------------
1 | io.holunda.polyflow.taskpool.sender.CamundaJobSenderConfiguration
2 |
--------------------------------------------------------------------------------
/integration/camunda-bpm/taskpool-job-sender/src/test/kotlin/io/holunda/polyflow/taskpool/sender/EngineTaskCommandsSendingJobHandlerConfigurationTest.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.sender
2 |
3 | import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
4 | import com.fasterxml.jackson.module.kotlin.readValue
5 | import org.assertj.core.api.Assertions.assertThat
6 | import org.junit.jupiter.api.Test
7 |
8 | class EngineTaskCommandsSendingJobHandlerConfigurationTest {
9 |
10 | private val objectMapper = jacksonObjectMapper()
11 |
12 | @Test
13 | fun `serializes configuration`() {
14 | val config = EngineTaskCommandsSendingJobHandlerConfiguration(
15 | taskId = "4711",
16 | commandByteArrayId = "0815"
17 | )
18 |
19 | val json = objectMapper.writeValueAsString(config)
20 | assertThat(json).isEqualTo("""{"taskId":"4711","commandByteArrayId":"0815"}""")
21 |
22 | val back: EngineTaskCommandsSendingJobHandlerConfiguration = objectMapper.readValue(json)
23 | assertThat(back).isEqualTo(config)
24 | }
25 | }
--------------------------------------------------------------------------------
/integration/common/datapool-sender/src/main/kotlin/io/holunda/polyflow/datapool/DataEntrySenderType.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.datapool
2 |
3 | /**
4 | * Data entry sender type.
5 | */
6 | enum class DataEntrySenderType {
7 | /**
8 | * Provided implementation.
9 | */
10 | simple,
11 |
12 | /**
13 | * Sender using Tx synchronization sending commands directly.
14 | */
15 | tx,
16 |
17 | /**
18 | * Custom = user-defined.
19 | */
20 | custom
21 | }
22 |
--------------------------------------------------------------------------------
/integration/common/datapool-sender/src/main/kotlin/io/holunda/polyflow/datapool/DataPoolSenderProperties.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.datapool
2 |
3 | import org.springframework.boot.context.properties.ConfigurationProperties
4 | import org.springframework.boot.context.properties.NestedConfigurationProperty
5 |
6 | /**
7 | * Holder for the enabled flag and the reference to the relevant [DataPoolSenderProperties].
8 | * The name is special in order to avoid name clashing with taskpool sender properties.
9 | */
10 | @ConfigurationProperties(prefix = "polyflow.integration.sender")
11 | data class DataPoolSenderProperties(
12 | /**
13 | * Global value to control the command gateway.
14 | */
15 | val enabled: Boolean = true,
16 |
17 | /**
18 | * Data entry properties.
19 | */
20 | @NestedConfigurationProperty
21 | val dataEntry: DataEntrySenderProperties = DataEntrySenderProperties(),
22 | )
23 |
--------------------------------------------------------------------------------
/integration/common/datapool-sender/src/main/kotlin/io/holunda/polyflow/datapool/EnableDataEntrySender.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.datapool
2 |
3 | import org.springframework.context.annotation.Import
4 |
5 | /**
6 | * Enables the data entry sender.
7 | */
8 | @MustBeDocumented
9 | @Import(DataEntrySenderConfiguration::class)
10 | annotation class EnableDataEntrySender
11 |
--------------------------------------------------------------------------------
/integration/common/datapool-sender/src/main/kotlin/io/holunda/polyflow/datapool/projector/DataEntryProjector.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.datapool.projector
2 |
3 | import io.holunda.camunda.taskpool.api.business.EntryType
4 | import org.springframework.stereotype.Component
5 |
6 | /**
7 | * Component responsible for retrieving property projectors for given entry types.
8 | */
9 | class DataEntryProjector(private val suppliers: List) {
10 | /**
11 | * Retrieve a list of projection suppliers for a given entry type.
12 | * @return a projection supplier if registered for this entry type, or null.
13 | */
14 | fun getProjection(entryType: EntryType): DataEntryProjectionSupplier? = suppliers.find { it.entryType == entryType }
15 | }
16 |
--------------------------------------------------------------------------------
/integration/common/datapool-sender/src/main/kotlin/io/holunda/polyflow/datapool/sender/SimpleDataEntryCommandSender.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.datapool.sender
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper
4 | import io.holunda.polyflow.datapool.DataEntrySenderProperties
5 | import io.holunda.polyflow.datapool.projector.DataEntryProjector
6 | import io.holunda.polyflow.datapool.sender.gateway.CommandListGateway
7 | import org.axonframework.commandhandling.CommandMessage
8 |
9 | /**
10 | * Sends commands using the gateway.
11 | */
12 | class SimpleDataEntryCommandSender(
13 | private val commandListGateway: CommandListGateway,
14 | properties: DataEntrySenderProperties,
15 | dataEntryProjector: DataEntryProjector,
16 | objectMapper: ObjectMapper
17 | ) : AbstractDataEntryCommandSender(properties, dataEntryProjector, objectMapper) {
18 |
19 | override fun send(command: CommandMessage) {
20 | if (properties.enabled) {
21 | commandListGateway.sendToGateway(listOf(command))
22 | } else {
23 | DataEntryCommandSender.logger.debug { "SENDER-104: Data entry sending is disabled by property. Would have sent $command." }
24 | }
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/integration/common/datapool-sender/src/main/kotlin/io/holunda/polyflow/datapool/sender/gateway/CommandListGateway.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.datapool.sender.gateway
2 |
3 | import org.axonframework.commandhandling.CommandResultMessage
4 | import java.util.function.BiFunction
5 |
6 | /**
7 | * Defines a gateway proxy, for sending commands.
8 | */
9 | interface CommandListGateway {
10 |
11 | /**
12 | * Sends a list of commands to gateway.
13 | */
14 | fun sendToGateway(commands: List)
15 |
16 | }
17 |
18 | /**
19 | * Handler for command errors.
20 | */
21 | interface CommandErrorHandler : BiFunction, Unit>
22 |
23 | /**
24 | * Handler for command results.
25 | */
26 | interface CommandSuccessHandler : BiFunction, Unit>
27 |
--------------------------------------------------------------------------------
/integration/common/datapool-sender/src/main/kotlin/io/holunda/polyflow/datapool/sender/gateway/LoggingDataEntryCommandErrorHandler.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.datapool.sender.gateway
2 |
3 | import io.github.oshai.kotlinlogging.KLogger
4 | import org.axonframework.commandhandling.CommandResultMessage
5 | import org.slf4j.Logger
6 |
7 | /**
8 | * Error handler, logging the error.
9 | */
10 | open class LoggingDataEntryCommandErrorHandler(private val logger: KLogger) : CommandErrorHandler {
11 |
12 | override fun apply(commandMessage: Any, commandResultMessage: CommandResultMessage) {
13 | logger.error(commandResultMessage.exceptionResult()) { "${"SENDER-103: Sending command $commandMessage resulted in error"}" }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/integration/common/datapool-sender/src/main/kotlin/io/holunda/polyflow/datapool/sender/gateway/LoggingDataEntryCommandSuccessHandler.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.datapool.sender.gateway
2 |
3 | import io.github.oshai.kotlinlogging.KLogger
4 | import org.axonframework.commandhandling.CommandResultMessage
5 | import org.slf4j.Logger
6 |
7 | /**
8 | * Logs success.
9 | */
10 | open class LoggingDataEntryCommandSuccessHandler(private val logger: KLogger) : CommandSuccessHandler {
11 |
12 | override fun apply(commandMessage: Any, commandResultMessage: CommandResultMessage) {
13 | if (logger.isDebugEnabled()) {
14 | logger.debug { "SENDER-102: Successfully submitted command $commandMessage" }
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/integration/common/datapool-sender/src/test/kotlin/io/holunda/polyflow/datapool/DataEntryDataPoolSenderPropertiesITest.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.datapool
2 |
3 | import org.assertj.core.api.Assertions.assertThat
4 | import org.junit.jupiter.api.Test
5 | import org.junit.jupiter.api.extension.ExtendWith
6 | import org.springframework.beans.factory.annotation.Autowired
7 | import org.springframework.boot.test.context.SpringBootTest
8 | import org.springframework.context.annotation.PropertySource
9 | import org.springframework.test.context.ActiveProfiles
10 | import org.springframework.test.context.junit.jupiter.SpringExtension
11 |
12 | @ExtendWith(SpringExtension::class)
13 | @SpringBootTest(classes = [PropertiesTestApplication::class], webEnvironment = SpringBootTest.WebEnvironment.MOCK)
14 | @ActiveProfiles("properties-itest")
15 | @PropertySource
16 | class DataEntryDataPoolSenderPropertiesITest {
17 |
18 | @Autowired
19 | lateinit var props: DataEntrySenderProperties
20 |
21 | @Test
22 | fun `should use defaults without properties in yaml`() {
23 | assertThat(props.applicationName).isEqualTo("Foo")
24 | assertThat(props.enabled).isFalse
25 | assertThat(props.type).isEqualTo(DataEntrySenderType.simple)
26 | assertThat(props.sendWithinTransaction).isFalse()
27 | }
28 | }
29 |
30 |
--------------------------------------------------------------------------------
/integration/common/datapool-sender/src/test/kotlin/io/holunda/polyflow/datapool/PropertiesTestApplication.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.datapool
2 |
3 | import io.holunda.polyflow.spring.ApplicationNameBeanPostProcessor
4 | import org.springframework.boot.autoconfigure.SpringBootApplication
5 | import org.springframework.boot.context.properties.EnableConfigurationProperties
6 | import org.springframework.context.annotation.Import
7 |
8 | @SpringBootApplication
9 | @EnableConfigurationProperties(DataEntrySenderProperties::class)
10 | @Import(ApplicationNameBeanPostProcessor::class)
11 | class PropertiesTestApplication
12 |
--------------------------------------------------------------------------------
/integration/common/datapool-sender/src/test/resources/application-properties-itest.yml:
--------------------------------------------------------------------------------
1 | #
2 | # I-Test properties justifying that no properties are needed to start Spring Boot with Camunda Task Pool collector.
3 | #
4 | spring:
5 | application:
6 | name: Foo
7 |
--------------------------------------------------------------------------------
/integration/common/datapool-sender/src/test/resources/banner.txt:
--------------------------------------------------------------------------------
1 | -------------------------------------------------------------------------------
2 | I-Test using SpringBoot: ${spring-boot.version}
3 | -------------------------------------------------------------------------------
4 |
--------------------------------------------------------------------------------
/integration/common/datapool-sender/src/test/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/integration/common/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 |
7 | io.holunda.polyflow
8 | polyflow-parent
9 | 4.4.1-SNAPSHOT
10 | ../../bom/parent/pom.xml
11 |
12 |
13 | polyflow-integration-common-parent
14 | POM: integration/${project.artifactId}
15 | pom
16 |
17 |
18 | datapool-sender
19 | tasklist-url-resolver
20 | taskpool-sender
21 | variable-serializer
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/integration/common/tasklist-url-resolver/src/main/kotlin/io/holunda/polyflow/urlresolver/FallbackTasklistUrlResolverAutoConfiguration.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.urlresolver
2 |
3 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
4 | import org.springframework.boot.context.properties.EnableConfigurationProperties
5 | import org.springframework.context.annotation.Bean
6 |
7 |
8 | /**
9 | * No @Configuration required.
10 | * Configuration used via auto-configuration.
11 | */
12 | @EnableConfigurationProperties(TasklistUrlProperties::class)
13 | class FallbackTasklistUrlResolverAutoConfiguration {
14 |
15 | /**
16 | * Property-based Tasklist URL resolver.
17 | */
18 | @Bean
19 | @ConditionalOnMissingBean(TasklistUrlResolver::class)
20 | fun propertyBasedTasklistUrlResolver(properties: TasklistUrlProperties): TasklistUrlResolver {
21 | return if (properties.tasklistUrl == null) {
22 | throw IllegalStateException("Either set polyflow.integration.tasklist.tasklist-url property or provide own implementation of TasklistUrlResolver")
23 | } else {
24 | object : TasklistUrlResolver {
25 | override fun getTasklistUrl(): String = properties.tasklistUrl
26 | }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/integration/common/tasklist-url-resolver/src/main/kotlin/io/holunda/polyflow/urlresolver/TasklistUrlProperties.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.urlresolver
2 |
3 | import org.springframework.boot.context.properties.ConfigurationProperties
4 |
5 | /**
6 | * Configuration properties for task list URL.
7 | */
8 | @ConfigurationProperties(prefix = "polyflow.integration.tasklist")
9 | data class TasklistUrlProperties(
10 | /**
11 | * URL of the task list.
12 | */
13 | val tasklistUrl: String? = null
14 | )
15 |
--------------------------------------------------------------------------------
/integration/common/tasklist-url-resolver/src/main/kotlin/io/holunda/polyflow/urlresolver/TasklistUrlResolver.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.urlresolver
2 |
3 | /**
4 | * Resolver for tasklist URL.
5 | */
6 | interface TasklistUrlResolver {
7 | /**
8 | * Retrieves the URL of the task list application.
9 | * @return task list URL
10 | */
11 | fun getTasklistUrl() : String
12 | }
13 |
--------------------------------------------------------------------------------
/integration/common/tasklist-url-resolver/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports:
--------------------------------------------------------------------------------
1 | io.holunda.polyflow.urlresolver.FallbackTasklistUrlResolverAutoConfiguration
2 |
--------------------------------------------------------------------------------
/integration/common/tasklist-url-resolver/src/test/kotlin/io/holunda/polyflow/urlresolver/DataEntrySenderPropertiesITest.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.urlresolver
2 |
3 | import org.assertj.core.api.Assertions.assertThat
4 | import org.junit.jupiter.api.Test
5 | import org.junit.jupiter.api.extension.ExtendWith
6 | import org.springframework.beans.factory.annotation.Autowired
7 | import org.springframework.boot.test.context.SpringBootTest
8 | import org.springframework.context.annotation.PropertySource
9 | import org.springframework.test.context.ActiveProfiles
10 | import org.springframework.test.context.junit.jupiter.SpringExtension
11 |
12 | @ExtendWith(SpringExtension::class)
13 | @SpringBootTest(classes = [PropertiesTestApplication::class], webEnvironment = SpringBootTest.WebEnvironment.MOCK)
14 | @ActiveProfiles("properties-itest")
15 | @PropertySource
16 | class DataEntrySenderPropertiesITest {
17 |
18 | @Autowired
19 | lateinit var props: TasklistUrlProperties
20 |
21 | @Test
22 | fun `should use defaults without properties in yaml`() {
23 | assertThat(props.tasklistUrl).isNull()
24 | }
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/integration/common/tasklist-url-resolver/src/test/kotlin/io/holunda/polyflow/urlresolver/PropertiesTestApplication.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.urlresolver
2 |
3 | import org.mockito.kotlin.mock
4 | import org.springframework.boot.autoconfigure.SpringBootApplication
5 | import org.springframework.boot.context.properties.EnableConfigurationProperties
6 | import org.springframework.context.annotation.Bean
7 |
8 | @SpringBootApplication
9 | @EnableConfigurationProperties(TasklistUrlProperties::class)
10 | class PropertiesTestApplication {
11 |
12 | @Bean
13 | fun ownResolver(): TasklistUrlResolver = mock()
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/integration/common/tasklist-url-resolver/src/test/resources/banner.txt:
--------------------------------------------------------------------------------
1 | -------------------------------------------------------------------------------
2 | I-Test using SpringBoot: ${spring-boot.version}
3 | -------------------------------------------------------------------------------
4 |
--------------------------------------------------------------------------------
/integration/common/tasklist-url-resolver/src/test/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/integration/common/taskpool-sender/src/main/kotlin/io/holunda/polyflow/taskpool/EnableTaskpoolSender.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool
2 |
3 | import io.holunda.polyflow.taskpool.sender.SenderConfiguration
4 | import org.springframework.context.annotation.Import
5 |
6 | /**
7 | * Enables the taskpool sender.
8 | */
9 | @MustBeDocumented
10 | @Import(SenderConfiguration::class)
11 | annotation class EnableTaskpoolSender
12 |
--------------------------------------------------------------------------------
/integration/common/taskpool-sender/src/main/kotlin/io/holunda/polyflow/taskpool/JacksonExtensions.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper
4 | import io.holunda.polyflow.bus.jackson.configurePolyflowJacksonObjectMapper
5 |
6 | /**
7 | * Configures object mapper.
8 | */
9 | @Deprecated(
10 | replaceWith = ReplaceWith("io.holunda.polyflow.bus.jackson.configurePolyflowJacksonObjectMapper()"),
11 | message = "Moved to separate artifact polyflow-bus-jackson to centralize the creation"
12 | )
13 | fun ObjectMapper.configureTaskpoolJacksonObjectMapper(): ObjectMapper = configurePolyflowJacksonObjectMapper()
14 |
--------------------------------------------------------------------------------
/integration/common/taskpool-sender/src/main/kotlin/io/holunda/polyflow/taskpool/ProcessInstanceValueExtensions.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool
2 |
3 | import com.fasterxml.jackson.databind.ObjectMapper
4 | import io.holunda.camunda.taskpool.api.process.variable.ObjectProcessVariableValue
5 | import io.holunda.camunda.taskpool.api.process.variable.PrimitiveProcessVariableValue
6 | import io.holunda.camunda.taskpool.api.process.variable.ProcessVariableValue
7 | import io.holunda.camunda.taskpool.api.process.variable.TypedValueProcessVariableValue
8 | import io.holunda.camunda.variable.serializer.serialize
9 |
10 | /**
11 | * Serialize process variable.
12 | */
13 | fun ProcessVariableValue.serialize(objectMapper: ObjectMapper): ProcessVariableValue =
14 | if (this is TypedValueProcessVariableValue) {
15 | if (this.value.type.isPrimitiveValueType) {
16 | PrimitiveProcessVariableValue(this.value.value)
17 | } else {
18 | ObjectProcessVariableValue(serialize(this.value.value, objectMapper))
19 | }
20 | } else {
21 | this
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/integration/common/taskpool-sender/src/main/kotlin/io/holunda/polyflow/taskpool/sender/gateway/CommandListGateway.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.sender.gateway
2 |
3 | import org.axonframework.commandhandling.CommandResultMessage
4 | import java.util.function.BiFunction
5 |
6 | /**
7 | * Defines a gateway proxy, for sending commands.
8 | */
9 | interface CommandListGateway {
10 |
11 | /**
12 | * Sends a list of commands to gateway.
13 | */
14 | fun sendToGateway(commands: List)
15 |
16 | }
17 |
18 | /**
19 | * Handler for command errors.
20 | */
21 | interface CommandErrorHandler : BiFunction, Unit>
22 |
23 | /**
24 | * Handler for command results.
25 | */
26 | interface CommandSuccessHandler : BiFunction, Unit>
27 |
--------------------------------------------------------------------------------
/integration/common/taskpool-sender/src/main/kotlin/io/holunda/polyflow/taskpool/sender/gateway/LoggingTaskCommandErrorHandler.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.sender.gateway
2 |
3 | import io.github.oshai.kotlinlogging.KLogger
4 | import org.axonframework.commandhandling.CommandResultMessage
5 |
6 | /**
7 | * Error handler, logging the error.
8 | */
9 | open class LoggingTaskCommandErrorHandler(private val logger: KLogger) : CommandErrorHandler {
10 |
11 | override fun apply(commandMessage: Any, commandResultMessage: CommandResultMessage) {
12 | logger.error(commandResultMessage.exceptionResult()) { "SENDER-003: Sending command $commandMessage resulted in error" }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/integration/common/taskpool-sender/src/main/kotlin/io/holunda/polyflow/taskpool/sender/gateway/LoggingTaskCommandSuccessHandler.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.sender.gateway
2 |
3 | import io.github.oshai.kotlinlogging.KLogger
4 | import org.axonframework.commandhandling.CommandResultMessage
5 |
6 | /**
7 | * Logs success.
8 | */
9 | open class LoggingTaskCommandSuccessHandler(private val logger: KLogger) : CommandSuccessHandler {
10 |
11 | override fun apply(commandMessage: Any, commandResultMessage: CommandResultMessage) {
12 | if (logger.isDebugEnabled()) {
13 | logger.debug { "SENDER-002: Successfully submitted command $commandMessage" }
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/integration/common/taskpool-sender/src/main/kotlin/io/holunda/polyflow/taskpool/sender/process/definition/ProcessDefinitionCommandSender.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.sender.process.definition
2 |
3 | import io.holunda.camunda.taskpool.api.process.definition.ProcessDefinitionCommand
4 |
5 | /**
6 | * Sender for process definitions.
7 | */
8 | interface ProcessDefinitionCommandSender {
9 |
10 | /**
11 | * Sends a process definition command.
12 | * @param command command to send.
13 | */
14 | fun send(command: ProcessDefinitionCommand)
15 | }
16 |
--------------------------------------------------------------------------------
/integration/common/taskpool-sender/src/main/kotlin/io/holunda/polyflow/taskpool/sender/process/definition/SimpleProcessDefinitionCommandSender.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.sender.process.definition
2 |
3 | import io.github.oshai.kotlinlogging.KotlinLogging
4 | import io.holunda.camunda.taskpool.api.process.definition.ProcessDefinitionCommand
5 | import io.holunda.polyflow.taskpool.sender.SenderProperties
6 | import io.holunda.polyflow.taskpool.sender.gateway.CommandListGateway
7 |
8 | private val logger = KotlinLogging.logger {}
9 |
10 | /**
11 | * Simple sender for process definition commands
12 | */
13 | internal class SimpleProcessDefinitionCommandSender(
14 | private val commandListGateway: CommandListGateway,
15 | private val senderProperties: SenderProperties
16 | ) : ProcessDefinitionCommandSender {
17 |
18 | override fun send(command: ProcessDefinitionCommand) {
19 | if (senderProperties.enabled && senderProperties.processDefinition.enabled) {
20 | commandListGateway.sendToGateway(listOf(command))
21 | } else {
22 | logger.debug { "SENDER-007: Process definition sending is disabled by property. Would have sent $command." }
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/integration/common/taskpool-sender/src/main/kotlin/io/holunda/polyflow/taskpool/sender/process/instance/ProcessInstanceCommandSender.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.sender.process.instance
2 |
3 | import io.holunda.camunda.taskpool.api.process.instance.ProcessInstanceCommand
4 |
5 | /**
6 | * Sender for process instances.
7 | */
8 | interface ProcessInstanceCommandSender {
9 |
10 | /**
11 | * Sends a process instance command.
12 | * @param command command to send.
13 | */
14 | fun send(command: ProcessInstanceCommand)
15 | }
16 |
--------------------------------------------------------------------------------
/integration/common/taskpool-sender/src/main/kotlin/io/holunda/polyflow/taskpool/sender/process/instance/SimpleProcessInstanceCommandSender.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.sender.process.instance
2 |
3 | import io.github.oshai.kotlinlogging.KotlinLogging
4 | import io.holunda.camunda.taskpool.api.process.instance.ProcessInstanceCommand
5 | import io.holunda.polyflow.taskpool.sender.SenderProperties
6 | import io.holunda.polyflow.taskpool.sender.gateway.CommandListGateway
7 |
8 | private val logger = KotlinLogging.logger {}
9 |
10 | /**
11 | * Simple sender for process definition commands
12 | */
13 | internal class SimpleProcessInstanceCommandSender(
14 | private val commandListGateway: CommandListGateway,
15 | private val senderProperties: SenderProperties
16 | ) : ProcessInstanceCommandSender {
17 |
18 | override fun send(command: ProcessInstanceCommand) {
19 | if (senderProperties.enabled && senderProperties.processInstance.enabled) {
20 | commandListGateway.sendToGateway(listOf(command))
21 | } else {
22 | logger.debug { "SENDER-008: Process instance sending is disabled by property. Would have sent $command." }
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/integration/common/taskpool-sender/src/main/kotlin/io/holunda/polyflow/taskpool/sender/process/variable/ProcessVariableCommandSender.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.sender.process.variable
2 |
3 | /**
4 | * Sender for process variables.
5 | */
6 | interface ProcessVariableCommandSender {
7 | /**
8 | * Sends a process variable command.
9 | * @param command command to send.
10 | */
11 | fun send(command: SingleProcessVariableCommand)
12 | }
13 |
--------------------------------------------------------------------------------
/integration/common/taskpool-sender/src/main/kotlin/io/holunda/polyflow/taskpool/sender/task/EngineTaskCommandSender.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.sender.task
2 |
3 | import io.holunda.camunda.taskpool.api.task.EngineTaskCommand
4 |
5 | /**
6 | * Interface for beans sending task commands.
7 | */
8 | interface EngineTaskCommandSender {
9 | /**
10 | * Sends the command to core and enriches it, if possible.
11 | */
12 | fun send(command: EngineTaskCommand)
13 | }
14 |
--------------------------------------------------------------------------------
/integration/common/taskpool-sender/src/main/kotlin/io/holunda/polyflow/taskpool/sender/task/SimpleEngineTaskCommandSender.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.sender.task
2 |
3 | import io.github.oshai.kotlinlogging.KotlinLogging
4 | import io.holunda.camunda.taskpool.api.task.EngineTaskCommand
5 | import io.holunda.polyflow.taskpool.sender.SenderProperties
6 | import io.holunda.polyflow.taskpool.sender.gateway.CommandListGateway
7 |
8 | private val logger = KotlinLogging.logger {}
9 |
10 | /**
11 | * Sends commands using the gateway.
12 | */
13 | class SimpleEngineTaskCommandSender(
14 | private val commandListGateway: CommandListGateway,
15 | private val senderProperties: SenderProperties
16 | ) : EngineTaskCommandSender {
17 |
18 | override fun send(command: EngineTaskCommand) {
19 | if (senderProperties.task.enabled) {
20 | commandListGateway.sendToGateway(listOf(command))
21 | } else {
22 | logger.debug { "SENDER-004: Process task sending is disabled by property. Would have sent $command." }
23 | }
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/integration/common/taskpool-sender/src/main/kotlin/io/holunda/polyflow/taskpool/sender/task/accumulator/CommandAccumulator.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.sender.task.accumulator
2 |
3 | import io.holunda.camunda.taskpool.api.task.EngineTaskCommand
4 |
5 | /**
6 | * Accumulator is responsible for transforming (and evtl. reducing) the number of commands being sent,
7 | * by accumulating information from several commands into one.
8 | */
9 | typealias EngineTaskCommandAccumulator = (List) -> List
10 |
--------------------------------------------------------------------------------
/integration/common/taskpool-sender/src/main/kotlin/io/holunda/polyflow/taskpool/sender/task/accumulator/EngineTaskCommandIntentDetector.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.sender.task.accumulator
2 |
3 | import io.holunda.camunda.taskpool.api.task.EngineTaskCommand
4 |
5 | /**
6 | * Detects intents of task command lists.
7 | */
8 | interface EngineTaskCommandIntentDetector {
9 |
10 | /**
11 | * Detects intents from a list of tasks commands collected for a single user task id.
12 | * @param engineTaskCommands commands collected from the engine.
13 | * @return list of intents. Every intent is a list of corresponding task commands sorted in a way, that the intended command is the first element in the list.
14 | */
15 | fun detectIntents(engineTaskCommands: List): List>
16 | }
--------------------------------------------------------------------------------
/integration/common/taskpool-sender/src/main/kotlin/io/holunda/polyflow/taskpool/sender/task/accumulator/EngineTaskCommandProjectionErrorDetector.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.sender.task.accumulator
2 |
3 | import io.holunda.camunda.taskpool.api.task.*
4 |
5 | /**
6 | * Due to Camunda event handling implementation eventing might be slightly strange.
7 | * Ignore error reporting if:
8 | * - to any original (intent) the detail is UpdateAttributesHistoricTaskCommand
9 | * - to any original except create the detail is AddCandidateUsersCommand, DeleteCandidateUsersCommand, since the detail should be detected as primary intent
10 | */
11 | object EngineTaskCommandProjectionErrorDetector : ProjectionErrorDetector {
12 |
13 | override fun shouldReportError(original: Any, detail: Any): Boolean {
14 | return when {
15 | original !is CreateTaskCommand && detail is AddCandidateUsersCommand -> false
16 | original !is CreateTaskCommand && detail is DeleteCandidateUsersCommand -> false
17 | detail is UpdateAttributesHistoricTaskCommand -> false
18 | else -> true
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/integration/common/taskpool-sender/src/main/kotlin/io/holunda/polyflow/taskpool/sender/task/accumulator/SortingCommandAccumulator.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.sender.task.accumulator
2 |
3 | import io.holunda.camunda.taskpool.api.task.EngineTaskCommand
4 | import io.holunda.camunda.taskpool.api.task.EngineTaskCommandSorter
5 |
6 | /**
7 | * Sorts commands by their order id
8 | */
9 | class SortingCommandAccumulator : EngineTaskCommandAccumulator {
10 | override fun invoke(taskCommands: List) = taskCommands.sortedWith(EngineTaskCommandSorter())
11 | }
12 |
--------------------------------------------------------------------------------
/integration/common/taskpool-sender/src/test/kotlin/io/holunda/polyflow/taskpool/sender/PropertiesTestApplication.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.taskpool.sender
2 |
3 | import org.springframework.boot.autoconfigure.SpringBootApplication
4 | import org.springframework.boot.context.properties.EnableConfigurationProperties
5 |
6 | @SpringBootApplication
7 | @EnableConfigurationProperties(SenderProperties::class)
8 | class PropertiesTestApplication
9 |
--------------------------------------------------------------------------------
/integration/common/taskpool-sender/src/test/resources/banner.txt:
--------------------------------------------------------------------------------
1 | -------------------------------------------------------------------------------
2 | I-Test using SpringBoot: ${spring-boot.version}
3 | -------------------------------------------------------------------------------
4 |
--------------------------------------------------------------------------------
/integration/common/taskpool-sender/src/test/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/integration/common/variable-serializer/src/test/kotlin/TestFixtures.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.variable.serializer
2 |
3 | import java.time.Instant
4 | import java.time.OffsetDateTime
5 |
6 | data class Pojo1(
7 | val key: String,
8 | val anotherKey: List
9 | )
10 |
11 | data class Pojo2(
12 | val keyZUZUZ: String,
13 | var children: List = listOf()
14 | )
15 |
16 | data class Pojo3(
17 | val key: String,
18 | val anotherKey: Int
19 | )
20 |
21 | data class Pojo4(
22 | val key: String,
23 | val anotherKey: List
24 | )
25 |
26 | data class Pojo5(
27 | val key: String,
28 | val ts: Instant,
29 | val date: OffsetDateTime
30 | )
31 |
--------------------------------------------------------------------------------
/view/form-url-resolver/src/main/kotlin/io/holunda/polyflow/urlresolver/EnablePropertyBasedFormUrlResolver.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.urlresolver
2 |
3 | import org.springframework.context.annotation.Import
4 |
5 | /**
6 | * Annotation to enable property-based form url resolver component.
7 | */
8 | @MustBeDocumented
9 | @Import(PropertyBasedFormUrlResolverConfiguration::class)
10 | annotation class EnablePropertyBasedFormUrlResolver
11 |
--------------------------------------------------------------------------------
/view/form-url-resolver/src/test/resources/form-url-properties.yml:
--------------------------------------------------------------------------------
1 | polyflow:
2 | integration:
3 | form-url-resolver:
4 | defaultTaskTemplate: "/forms/${formKey}/${id}"
5 | defaultApplicationTemplate: "http://localhost:8080/${applicatioName}"
6 | defaultProcessTemplate: "/${processDefinitionKey}/${formKey}"
7 | applications:
8 | - app1:
9 | url: "http://app1.server.io/app"
10 | tasks:
11 | - task1: "/forms/task1/foo/${id}"
12 | - task2: "/bar/2/foo/${id}"
13 | processes:
14 | - process1: "/proc-1/start"
15 | - process2: "/proc/2/begin"
16 | - app2:
17 | url: "http://foo.app2.com"
18 | tasks:
19 | - otherTask1: "/views/task1/${id}"
20 | - otherTask2: "/other/2/foo/${id}"
21 |
--------------------------------------------------------------------------------
/view/jpa/src/main/kotlin/io/holunda/polyflow/view/jpa/CountByApplication.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.jpa
2 |
3 | /**
4 | * Helper multi-valued class to support count by application name queries.
5 | */
6 | data class CountByApplication(
7 | /**
8 | * application name (grouping criteria).
9 | */
10 | val applicationName: String,
11 | /**
12 | * Count.
13 | */
14 | val count: Long
15 | )
16 |
--------------------------------------------------------------------------------
/view/jpa/src/main/kotlin/io/holunda/polyflow/view/jpa/EnablePolyflowJpaView.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.jpa
2 |
3 | import org.springframework.context.annotation.Import
4 |
5 | /**
6 | * Enables polyflow projection using RDMBS via JPA as persistence.
7 | */
8 | @MustBeDocumented
9 | @Import(PolyflowJpaViewConfiguration::class)
10 | annotation class EnablePolyflowJpaView
11 |
--------------------------------------------------------------------------------
/view/jpa/src/main/kotlin/io/holunda/polyflow/view/jpa/auth/AuthorizationPrincipal.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.jpa.auth
2 |
3 | /**
4 | * DTO representing authorized user or group.
5 | */
6 | data class AuthorizationPrincipal(
7 | val name: String,
8 | val type: AuthorizationPrincipalType
9 | ) {
10 | companion object {
11 | /**
12 | * Factory method to construct principal out of string.
13 | */
14 | operator fun invoke(auth: String) = auth.split(":").let {
15 | require(it.size >= 2) { "Illegal auth format, expecting :, received '$auth'" }
16 | AuthorizationPrincipal(type = AuthorizationPrincipalType.valueOf(it[0]), name = it.subList(1, it.size).joinToString(":"))
17 | }
18 |
19 | /**
20 | * Constructor for the group principal.
21 | */
22 | fun group(name: String): AuthorizationPrincipal = AuthorizationPrincipal(name = name, type = AuthorizationPrincipalType.GROUP)
23 | /**
24 | * Constructor for the user principal.
25 | */
26 | fun user(name: String): AuthorizationPrincipal = AuthorizationPrincipal(name = name, type = AuthorizationPrincipalType.USER)
27 | }
28 |
29 | override fun toString(): String = "$type:$name"
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/view/jpa/src/main/kotlin/io/holunda/polyflow/view/jpa/auth/AuthorizationPrincipalType.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.jpa.auth
2 |
3 | /**
4 | * Authorization principal type.
5 | */
6 | enum class AuthorizationPrincipalType {
7 | GROUP,
8 | USER
9 | }
10 |
--------------------------------------------------------------------------------
/view/jpa/src/main/kotlin/io/holunda/polyflow/view/jpa/data/DataEntryEventHandler.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.jpa.data
2 |
3 | import io.holunda.camunda.taskpool.api.business.DataEntryAnonymizedEvent
4 | import io.holunda.camunda.taskpool.api.business.DataEntryCreatedEvent
5 | import io.holunda.camunda.taskpool.api.business.DataEntryDeletedEvent
6 | import io.holunda.camunda.taskpool.api.business.DataEntryUpdatedEvent
7 | import org.axonframework.messaging.MetaData
8 | import java.time.Instant
9 |
10 | /**
11 | * Interface for receiving all data entry relevant events.
12 | */
13 | interface DataEntryEventHandler {
14 |
15 | /**
16 | * Data entry created.
17 | */
18 | fun on(event: DataEntryCreatedEvent, metaData: MetaData, eventTimestamp: Instant)
19 |
20 | /**
21 | * Data entry updated.
22 | */
23 | fun on(event: DataEntryUpdatedEvent, metaData: MetaData, eventTimestamp: Instant)
24 |
25 | /**
26 | * Data entry deleted.
27 | */
28 | fun on(event: DataEntryDeletedEvent, metaData: MetaData)
29 |
30 | /**
31 | * Data entry anonymized.
32 | */
33 | fun on(event: DataEntryAnonymizedEvent, metaData: MetaData)
34 | }
35 |
--------------------------------------------------------------------------------
/view/jpa/src/main/kotlin/io/holunda/polyflow/view/jpa/data/DataEntryPayloadAttributeEntity.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.jpa.data
2 |
3 | import jakarta.persistence.EmbeddedId
4 | import jakarta.persistence.Entity
5 | import jakarta.persistence.Table
6 | import org.hibernate.annotations.Immutable
7 |
8 | /**
9 | * Entity that holds the combined payload attributes of the correlated DataEntries.
10 | */
11 | @Entity
12 | @Immutable
13 | @Table(name = "PLF_VIEW_DATA_ENTRY_PAYLOAD")
14 | class DataEntryPayloadAttributeEntity(
15 | @EmbeddedId
16 | var id: DataEntryPayloadAttributeEntityId,
17 | ) {
18 | constructor(entryType: String, entryId: String, path: String, value: String) : this(
19 | DataEntryPayloadAttributeEntityId(
20 | entryType = entryType,
21 | entryId = entryId,
22 | path = path,
23 | value = value
24 | )
25 | )
26 |
27 | override fun toString(): String = "DataEntryPayloadAttributeEntity(id=$id)"
28 | }
29 |
30 |
--------------------------------------------------------------------------------
/view/jpa/src/main/kotlin/io/holunda/polyflow/view/jpa/data/DataEntryStateEmbeddable.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.jpa.data
2 |
3 | import io.holunda.camunda.taskpool.api.business.DataEntryState
4 | import jakarta.persistence.Column
5 | import jakarta.persistence.Embeddable
6 | import java.io.Serializable
7 |
8 | /**
9 | * Represents stat of data entry.
10 | */
11 | @Embeddable
12 | class DataEntryStateEmbeddable(
13 | @Column(name = "PROCESSING_TYPE", length = 64, nullable = false)
14 | var processingType: String,
15 | @Column(name = "STATE", length = 64, nullable = false)
16 | var state: String
17 | ) : Serializable {
18 | companion object {
19 | /**
20 | * Factory method.
21 | */
22 | operator fun invoke(state: DataEntryState): DataEntryStateEmbeddable =
23 | DataEntryStateEmbeddable(processingType = state.processingType.name, state = state.state ?: "")
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/view/jpa/src/main/kotlin/io/holunda/polyflow/view/jpa/process/ProcessDefinitionRepository.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.jpa.process
2 |
3 | import io.holunda.polyflow.view.jpa.auth.AuthorizationPrincipal
4 | import io.holunda.polyflow.view.jpa.composeOr
5 | import org.springframework.data.jpa.domain.Specification
6 | import org.springframework.data.jpa.repository.JpaSpecificationExecutor
7 | import org.springframework.data.repository.CrudRepository
8 |
9 | /**
10 | * Spring Data JPA for Process definitions.
11 | */
12 | interface ProcessDefinitionRepository : CrudRepository, JpaSpecificationExecutor {
13 | companion object {
14 |
15 | /**
16 | * Specification for checking authorization of multiple principals.
17 | */
18 | fun isStarterAuthorizedFor(principals: Collection): Specification =
19 | composeOr(principals.map { principal ->
20 | Specification { processDefinition, _, builder ->
21 | builder.isMember(
22 | "${principal.type}:${principal.name}",
23 | processDefinition.get>(ProcessDefinitionEntity::authorizedStarterPrincipals.name)
24 | )
25 | }
26 | })
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/view/jpa/src/main/kotlin/io/holunda/polyflow/view/jpa/process/ProcessInstanceRepository.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.jpa.process
2 |
3 | import io.holunda.polyflow.view.ProcessInstanceState
4 | import io.holunda.polyflow.view.jpa.composeOr
5 | import org.springframework.data.jpa.domain.Specification
6 | import org.springframework.data.jpa.repository.JpaSpecificationExecutor
7 | import org.springframework.data.repository.CrudRepository
8 |
9 | /**
10 | * Repository for process instances.
11 | */
12 | interface ProcessInstanceRepository : CrudRepository, JpaSpecificationExecutor {
13 |
14 | companion object {
15 | /**
16 | * Checks if the instance has one of provided states.
17 | */
18 | fun hasStates(processInstanceStates: Set): Specification =
19 | composeOr(processInstanceStates.map { state ->
20 | Specification { instance, _, builder ->
21 | builder.equal(
22 | instance.get(ProcessInstanceEntity::state.name),
23 | state
24 | )
25 | }
26 | })
27 |
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/view/jpa/src/main/kotlin/io/holunda/polyflow/view/jpa/task/TaskAndDataEntryPayloadAttributeEntity.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.jpa.task
2 |
3 | import jakarta.persistence.EmbeddedId
4 | import jakarta.persistence.Entity
5 | import jakarta.persistence.Table
6 |
7 | @Entity
8 | @Table(name = "PLF_VIEW_TASK_AND_DATA_ENTRY_PAYLOAD")
9 | class TaskAndDataEntryPayloadAttributeEntity(
10 | @EmbeddedId
11 | var id: TaskAndDataEntryPayloadAttributeEntityId
12 | ) {
13 | constructor(taskId: String, path: String, value: String) : this(
14 | TaskAndDataEntryPayloadAttributeEntityId(
15 | taskId,
16 | path,
17 | value
18 | )
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/view/jpa/src/sql/persistence.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
13 | io.holunda.polyflow.view.jpa.data.DataEntryEntity
14 | io.holunda.polyflow.view.jpa.data.ProtocolElement
15 | io.holunda.polyflow.view.jpa.process.ProcessDefinitionEntity
16 | io.holunda.polyflow.view.jpa.process.ProcessInstanceEntity
17 | io.holunda.polyflow.view.jpa.task.TaskEntity
18 |
19 |
20 |
--------------------------------------------------------------------------------
/view/jpa/src/test/kotlin/io/holunda/polyflow/view/jpa/data/DataEntryIdTest.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.jpa.data
2 |
3 | import org.assertj.core.api.Assertions.assertThat
4 | import org.assertj.core.api.Assertions.assertThatThrownBy
5 | import org.junit.jupiter.api.Test
6 |
7 | internal class DataEntryIdTest {
8 |
9 | @Test
10 | fun `should construct data entry id `() {
11 | val id = DataEntryId("type:id")
12 | assertThat(id).isEqualTo(DataEntryId(entryType = "type", entryId = "id"))
13 | }
14 |
15 | @Test
16 | fun `should construct data entry id with id containing a colon`() {
17 | val id = DataEntryId("type:id:k")
18 | assertThat(id).isEqualTo(DataEntryId(entryType = "type", entryId = "id:k"))
19 | }
20 |
21 |
22 | @Test
23 | fun `should not construct data entry id`() {
24 | assertThatThrownBy { DataEntryId("bad string") }.hasMessage("Illegal identity format, expecting :, received 'bad string'")
25 | }
26 |
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/view/jpa/src/test/kotlin/io/holunda/polyflow/view/jpa/itest/FixedH2Dialect.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.jpa.itest
2 |
3 | import org.hibernate.boot.model.TypeContributions
4 | import org.hibernate.dialect.H2Dialect
5 | import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo
6 | import org.hibernate.service.ServiceRegistry
7 | import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl
8 | import java.sql.Types
9 |
10 | @Suppress("unused") // used in application-itest.yaml
11 | class FixedH2Dialect(info: DialectResolutionInfo) : H2Dialect(info) {
12 | override fun registerColumnTypes(typeContributions: TypeContributions, serviceRegistry: ServiceRegistry) {
13 | super.registerColumnTypes(typeContributions, serviceRegistry)
14 | val ddlTypeRegistry = typeContributions.typeConfiguration.ddlTypeRegistry
15 | ddlTypeRegistry.addDescriptor(DdlTypeImpl(Types.BLOB, "bytea", this))
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/view/jpa/src/test/kotlin/io/holunda/polyflow/view/jpa/itest/MockQueryEmitterConfiguration.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.jpa.itest
2 |
3 | import org.axonframework.queryhandling.QueryUpdateEmitter
4 | import org.mockito.Mockito
5 | import org.springframework.context.annotation.Bean
6 | import org.springframework.context.annotation.Configuration
7 | import org.springframework.context.annotation.Primary
8 | import org.springframework.context.annotation.Profile
9 |
10 | @Configuration
11 | @Profile("mock-query-emitter")
12 | class MockQueryEmitterConfiguration {
13 |
14 | @Bean
15 | @Primary
16 | fun mockingQueryUpdateEmitter(): QueryUpdateEmitter = Mockito.mock(QueryUpdateEmitter::class.java)
17 | }
18 |
--------------------------------------------------------------------------------
/view/jpa/src/test/kotlin/io/holunda/polyflow/view/jpa/itest/ObjectMapperConfiguration.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.jpa.itest
2 |
3 | import com.fasterxml.jackson.databind.SerializationFeature
4 | import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
5 | import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
6 | import org.springframework.context.annotation.Bean
7 | import org.springframework.context.annotation.Configuration
8 | import java.text.SimpleDateFormat
9 |
10 | @Configuration
11 | class ObjectMapperConfiguration {
12 | @Bean
13 | fun objectMapper() = jacksonObjectMapper().apply {
14 | dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'")
15 | registerModule(JavaTimeModule())
16 | configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
17 | configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false)
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/view/jpa/src/test/kotlin/io/holunda/polyflow/view/jpa/itest/TestApplicationDataJpa.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.jpa.itest
2 |
3 | import org.springframework.boot.autoconfigure.SpringBootApplication
4 | import org.springframework.context.annotation.ComponentScan
5 | import org.springframework.context.annotation.Import
6 |
7 | @SpringBootApplication
8 | @Import(value = [ObjectMapperConfiguration::class, MockQueryEmitterConfiguration::class])
9 | @ComponentScan(basePackages = ["io.holunda.polyflow.view.jpa"])
10 | class TestApplicationDataJpa
11 |
--------------------------------------------------------------------------------
/view/jpa/src/test/kotlin/io/holunda/polyflow/view/jpa/task/TaskEntityTest.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.jpa.task
2 |
3 | import io.holunda.polyflow.view.jpa.emptyTask
4 | import org.assertj.core.api.Assertions.assertThat
5 | import org.junit.jupiter.api.Test
6 | import java.time.Instant
7 |
8 | internal class TaskEntityTest {
9 |
10 | @Test
11 | fun `test toString`() {
12 | val now = Instant.now()
13 | val task = emptyTask().apply {
14 | taskId = "id-123"
15 | taskDefinitionKey = "def-098"
16 | name = "name"
17 | createdDate = now
18 | }
19 | assertThat(task.toString()).isEqualTo("Task[taskId=id-123, taskDefinitionKey=def-098, name=name, created=$now]")
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/view/jpa/src/test/resources/application-itest-tc-mariadb.yaml:
--------------------------------------------------------------------------------
1 | spring:
2 | jpa:
3 | open-in-view: true # disable JPA warning
4 | show-sql: false
5 | database-platform: org.hibernate.dialect.MariaDBDialect
6 | generate-ddl: false
7 | hibernate.ddl-auto: none
8 | datasource:
9 | url: jdbc:tc:mariadb:10.11:///testDb
10 | username: sa
11 | password: sa
12 | flyway:
13 | enabled: true
14 | locations: "classpath:db/migrations/mariadb"
15 |
16 | polyflow:
17 | view:
18 | jpa:
19 | stored-items: TASK, DATA_ENTRY, PROCESS_INSTANCE, PROCESS_DEFINITION
20 |
21 | logging:
22 | level:
23 | root: INFO
24 | org.springframework: INFO
25 | org.axonframework: INFO
26 | org.hibernate.type: INFO # activate this and generic ROOT logger to see SQL and binding
27 | io.holixon.axon.gateway.query: INFO
28 | io.holunda.polyflow.view.jpa: INFO
29 |
30 | axon:
31 | axonserver:
32 | enabled: false
33 | eventhandling:
34 | processors:
35 | [io.holunda.polyflow.view.jpa.service.data]:
36 | mode: subscribing
37 | source: eventBus
38 |
39 |
--------------------------------------------------------------------------------
/view/jpa/src/test/resources/banner.txt:
--------------------------------------------------------------------------------
1 | ===============================================================================
2 | JPA View I-Test, using SpringBoot ${spring-boot.formatted-version}
3 | ===============================================================================
4 |
--------------------------------------------------------------------------------
/view/jpa/src/test/resources/db/migrations/h2-postgresql/V0_0_10__axon_sequences_per_table.sql:
--------------------------------------------------------------------------------
1 | DROP SEQUENCE hibernate_sequence;
2 |
3 | CREATE SEQUENCE association_value_entry_seq START WITH 1 INCREMENT BY 50;
4 |
5 | CREATE SEQUENCE domain_event_entry_seq START WITH 1 INCREMENT BY 50;
6 |
--------------------------------------------------------------------------------
/view/jpa/src/test/resources/db/migrations/h2-postgresql/V0_0_11__jpa_view_correlation_payload.sql:
--------------------------------------------------------------------------------
1 | create view PLF_VIEW_TASK_AND_DATA_ENTRY_PAYLOAD as
2 | ((select pc.TASK_ID, dea.PATH, dea.VALUE
3 | from PLF_TASK_CORRELATIONS pc
4 | join PLF_DATA_ENTRY_PAYLOAD_ATTRIBUTES dea on pc.ENTRY_ID = dea.ENTRY_ID and pc.ENTRY_TYPE = dea.ENTRY_TYPE)
5 | union
6 | select * from PLF_TASK_PAYLOAD_ATTRIBUTES);
7 |
--------------------------------------------------------------------------------
/view/jpa/src/test/resources/db/migrations/h2-postgresql/V0_0_12__jpa_plf_data_entry_correlations.sql:
--------------------------------------------------------------------------------
1 | create table PLF_DATA_ENTRY_CORRELATIONS
2 | (
3 | OWNING_ENTRY_TYPE varchar(255) not null,
4 | OWNING_ENTRY_ID varchar(64) not null,
5 | ENTRY_TYPE varchar(255) not null,
6 | ENTRY_ID varchar(64) not null,
7 | primary key (OWNING_ENTRY_TYPE, OWNING_ENTRY_ID, ENTRY_TYPE, ENTRY_ID)
8 | );
9 |
10 | create view PLF_VIEW_DATA_ENTRY_PAYLOAD as
11 | (
12 | select *
13 | from PLF_DATA_ENTRY_PAYLOAD_ATTRIBUTES
14 | union
15 | (select ec.OWNING_ENTRY_ID as ENTRY_ID,
16 | ec.OWNING_ENTRY_TYPE as ENTRY_TYPE,
17 | ep.path as PATH,
18 | ep.value as VALUE
19 | from PLF_DATA_ENTRY_CORRELATIONS ec
20 | join PLF_DATA_ENTRY_PAYLOAD_ATTRIBUTES ep
21 | on
22 | ec.ENTRY_ID = ep.ENTRY_ID and ec.ENTRY_TYPE = ep.ENTRY_TYPE)
23 | );
24 |
--------------------------------------------------------------------------------
/view/jpa/src/test/resources/db/migrations/h2-postgresql/V0_0_4__tasklist_filters.sql:
--------------------------------------------------------------------------------
1 | -- All tasks excludes just for admin
2 | INSERT INTO ACT_RU_FILTER (ID_, REV_, RESOURCE_TYPE_, NAME_, OWNER_, QUERY_, PROPERTIES_)
3 | VALUES ('F000', 1, 'Task', 'All Tasks', 'admin', '{}',
4 | '{"showUndefinedVariable":false,"description":"All tasks (for admin use only!)","refresh":true,"priority":0}');
5 |
6 | INSERT INTO ACT_RU_AUTHORIZATION (ID_, REV_, TYPE_, GROUP_ID_, USER_ID_, RESOURCE_TYPE_, RESOURCE_ID_, PERMS_)
7 | VALUES ('A20', 1, 1, null, 'admin', 5, 'F000', 2147483647);
8 |
--------------------------------------------------------------------------------
/view/jpa/src/test/resources/db/migrations/h2-postgresql/V0_0_6__request.sql:
--------------------------------------------------------------------------------
1 | create table APP_APPROVAL_REQUEST
2 | (
3 | id varchar(255) not null,
4 | amount decimal(10, 2),
5 | applicant varchar(255),
6 | currency varchar(255),
7 | subject varchar(255),
8 | primary key (id)
9 | );
10 |
--------------------------------------------------------------------------------
/view/jpa/src/test/resources/db/migrations/h2-postgresql/V0_0_8__axon_dlq.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE dead_letter_entry
2 | (
3 | dead_letter_id VARCHAR(255) NOT NULL,
4 | cause_message VARCHAR(255),
5 | cause_type VARCHAR(255),
6 | diagnostics BYTEA,
7 | enqueued_at TIMESTAMP NOT NULL,
8 | last_touched TIMESTAMP,
9 | aggregate_identifier VARCHAR(255),
10 | event_identifier VARCHAR(255) NOT NULL,
11 | message_type VARCHAR(255) NOT NULL,
12 | meta_data BYTEA,
13 | payload BYTEA NOT NULL,
14 | payload_revision VARCHAR(255),
15 | payload_type VARCHAR(255) NOT NULL,
16 | sequence_number INT8,
17 | time_stamp VARCHAR(255) NOT NULL,
18 | token BYTEA,
19 | token_type VARCHAR(255),
20 | type VARCHAR(255),
21 | processing_group VARCHAR(255) NOT NULL,
22 | processing_started TIMESTAMP,
23 | sequence_identifier VARCHAR(255) NOT NULL,
24 | sequence_index INT8 NOT NULL,
25 | PRIMARY KEY (dead_letter_id)
26 | );
27 |
--------------------------------------------------------------------------------
/view/jpa/src/test/resources/db/migrations/h2-postgresql/V0_0_9__polyflow_deleted.sql:
--------------------------------------------------------------------------------
1 | ALTER TABLE plf_data_entry
2 | ADD date_deleted timestamp;
3 |
--------------------------------------------------------------------------------
/view/jpa/src/test/resources/db/migrations/mariadb/V0_0_10__jpa_view_correlation_payload.sql:
--------------------------------------------------------------------------------
1 | create view plf_view_task_and_data_entry_payload as
2 | ((select pc.task_id, dea.path, dea.value
3 | from plf_task_correlations pc
4 | join plf_data_entry_payload_attributes dea on pc.entry_id = dea.entry_id and pc.entry_type = dea.entry_type)
5 | union
6 | select * from plf_task_payload_attributes);
7 |
--------------------------------------------------------------------------------
/view/jpa/src/test/resources/db/migrations/mariadb/V0_0_11__jpa_plf_data_entry_correlations.sql:
--------------------------------------------------------------------------------
1 | create table plf_data_entry_correlations
2 | (
3 | owning_entry_type varchar(255) not null,
4 | owning_entry_id varchar(64) not null,
5 | entry_type varchar(255) not null,
6 | entry_id varchar(64) not null,
7 | primary key (owning_entry_type, owning_entry_id, entry_type, entry_id)
8 | );
9 |
10 | create view plf_view_data_entry_payload as
11 | (
12 | select *
13 | from plf_data_entry_payload_attributes
14 | union
15 | (select ec.owning_entry_id as ENTRY_ID,
16 | ec.owning_entry_type as ENTRY_TYPE,
17 | ep.path as PATH,
18 | ep.value as VALUE
19 | from plf_data_entry_correlations ec
20 | join plf_data_entry_payload_attributes ep
21 | on
22 | ec.entry_id = ep.entry_id and ec.entry_type = ep.entry_type)
23 | );
24 |
--------------------------------------------------------------------------------
/view/jpa/src/test/resources/db/migrations/mariadb/V0_0_4__tasklist_filters.sql:
--------------------------------------------------------------------------------
1 | -- All tasks excludes just for admin
2 | INSERT INTO ACT_RU_FILTER (ID_, REV_, RESOURCE_TYPE_, NAME_, OWNER_, QUERY_, PROPERTIES_)
3 | VALUES ('F000', 1, 'Task', 'All Tasks', 'admin', '{}',
4 | '{"showUndefinedVariable":false,"description":"All tasks (for admin use only!)","refresh":true,"priority":0}');
5 |
6 | INSERT INTO ACT_RU_AUTHORIZATION (ID_, REV_, TYPE_, GROUP_ID_, USER_ID_, RESOURCE_TYPE_, RESOURCE_ID_, PERMS_)
7 | VALUES ('A20', 1, 1, null, 'admin', 5, 'F000', 2147483647);
8 |
--------------------------------------------------------------------------------
/view/jpa/src/test/resources/db/migrations/mariadb/V0_0_6__request.sql:
--------------------------------------------------------------------------------
1 | create table APP_APPROVAL_REQUEST
2 | (
3 | id varchar(255) not null,
4 | amount decimal(10, 2),
5 | applicant varchar(255),
6 | currency varchar(255),
7 | subject varchar(255),
8 | primary key (id)
9 | );
10 |
--------------------------------------------------------------------------------
/view/jpa/src/test/resources/db/migrations/mariadb/V0_0_8__axon_dlq.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE dead_letter_entry
2 | (
3 | dead_letter_id VARCHAR(255) NOT NULL,
4 | cause_message VARCHAR(255),
5 | cause_type VARCHAR(255),
6 | diagnostics LONGBLOB,
7 | enqueued_at TIMESTAMP NOT NULL,
8 | last_touched TIMESTAMP,
9 | aggregate_identifier VARCHAR(255),
10 | event_identifier VARCHAR(255) NOT NULL,
11 | message_type VARCHAR(255) NOT NULL,
12 | meta_data LONGBLOB,
13 | payload LONGBLOB NOT NULL,
14 | payload_revision VARCHAR(255),
15 | payload_type VARCHAR(255) NOT NULL,
16 | sequence_number INT8,
17 | time_stamp VARCHAR(255) NOT NULL,
18 | token LONGBLOB,
19 | token_type VARCHAR(255),
20 | type VARCHAR(255),
21 | processing_group VARCHAR(255) NOT NULL,
22 | processing_started TIMESTAMP,
23 | sequence_identifier VARCHAR(255) NOT NULL,
24 | sequence_index INT8 NOT NULL,
25 | PRIMARY KEY (dead_letter_id)
26 | );
27 |
--------------------------------------------------------------------------------
/view/jpa/src/test/resources/db/migrations/mariadb/V0_0_9__axon_sequences_per_table.sql:
--------------------------------------------------------------------------------
1 | DROP SEQUENCE hibernate_sequence;
2 |
3 | CREATE SEQUENCE association_value_entry_seq START WITH 1 INCREMENT BY 50;
4 |
5 | CREATE SEQUENCE domain_event_entry_seq START WITH 1 INCREMENT BY 50;
6 |
--------------------------------------------------------------------------------
/view/jpa/src/test/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/view/mongo/src/main/kotlin/io/holunda/polyflow/view/mongo/ChangeStreamOptionsSupport.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.mongo
2 |
3 | import com.mongodb.client.model.changestream.OperationType
4 | import org.bson.BsonValue
5 | import org.springframework.data.mongodb.core.ChangeStreamOptions
6 | import org.springframework.data.mongodb.core.aggregation.Aggregation
7 | import org.springframework.data.mongodb.core.query.Criteria
8 |
9 | /**
10 | * Create change stream options, compatible with Cosmos DB.
11 | * Includes resume token, if it is not null.
12 | */
13 | fun BsonValue?.changeStreamOptions(): ChangeStreamOptions {
14 | return ChangeStreamOptions
15 | .builder()
16 | .filter(
17 | Aggregation.newAggregation(
18 | Aggregation.match(Criteria.where("operationType").`in`(OperationType.INSERT.value, OperationType.UPDATE.value, OperationType.REPLACE.value)),
19 | Aggregation.project("fullDocument")
20 | )
21 | ).let { builder ->
22 | if (this != null) {
23 | builder.resumeToken(this)
24 | } else {
25 | builder
26 | }
27 | }.build()
28 | }
29 |
--------------------------------------------------------------------------------
/view/mongo/src/main/kotlin/io/holunda/polyflow/view/mongo/EnableTaskPoolMongoView.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.mongo
2 |
3 | import org.springframework.context.annotation.Import
4 |
5 | /**
6 | * Enables polyflow projection using Mongo DB as persistence.
7 | */
8 | @MustBeDocumented
9 | @Deprecated(message = "Please use EnablePolyflowMongoView instead", replaceWith = ReplaceWith("EnablePolyflowMongoView"))
10 | @Import(TaskPoolMongoViewConfiguration::class)
11 | annotation class EnableTaskPoolMongoView
12 |
13 | /**
14 | * Enables polyflow projection using Mongo DB as persistence.
15 | */
16 | @MustBeDocumented
17 | @Import(TaskPoolMongoViewConfiguration::class)
18 | annotation class EnablePolyflowMongoView
19 |
--------------------------------------------------------------------------------
/view/mongo/src/main/kotlin/io/holunda/polyflow/view/mongo/data/DataEntryUpdateRepository.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.mongo.data
2 |
3 | import org.bson.BsonValue
4 | import org.springframework.data.mongodb.core.ChangeStreamEvent
5 | import reactor.core.publisher.Flux
6 |
7 | /**
8 | * Repository for retrieving change updates.
9 | */
10 | interface DataEntryUpdateRepository {
11 | /**
12 | * Retrieves change stream of data entry updates.
13 | * @param resumeToken resume token showing current position.
14 | * @return change event stream.
15 | */
16 | fun getDataEntryUpdates(resumeToken: BsonValue?): Flux>
17 | }
18 |
--------------------------------------------------------------------------------
/view/mongo/src/main/kotlin/io/holunda/polyflow/view/mongo/data/DataEntryUpdateRepositoryImpl.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.mongo.data
2 |
3 | import io.holunda.polyflow.view.mongo.changeStreamOptions
4 | import org.bson.BsonValue
5 | import org.springframework.data.mongodb.core.ChangeStreamEvent
6 | import org.springframework.data.mongodb.core.ReactiveMongoTemplate
7 | import reactor.core.publisher.Flux
8 |
9 | /**
10 | * Implementation of the change stream based on Mongo template.
11 | */
12 | open class DataEntryUpdateRepositoryImpl(
13 | private val mongoTemplate: ReactiveMongoTemplate
14 | ) : DataEntryUpdateRepository {
15 | override fun getDataEntryUpdates(resumeToken: BsonValue?): Flux> {
16 | return mongoTemplate.changeStream(DataEntryDocument.COLLECTION, resumeToken.changeStreamOptions(), DataEntryDocument::class.java)
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/view/mongo/src/main/kotlin/io/holunda/polyflow/view/mongo/process/ProcessDefinitionRepository.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.mongo.process
2 |
3 | import org.springframework.data.mongodb.repository.Query
4 | import org.springframework.data.mongodb.repository.ReactiveMongoRepository
5 | import org.springframework.data.repository.query.Param
6 | import org.springframework.stereotype.Repository
7 | import reactor.core.publisher.Flux
8 |
9 |
10 | /**
11 | * Repository for process definitions.
12 | */
13 | @Repository
14 | interface ProcessDefinitionRepository : ReactiveMongoRepository {
15 |
16 | /**
17 | * Find all for given user.
18 | */
19 | @Query("{ \$or: [ { 'candidateStarterUsers' : ?0 }, { 'candidateStarterGroups' : ?1} ] }")
20 | fun findAllForUser(@Param("username") username: String, @Param("groupNames") groupNames: Set): Flux
21 |
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/view/mongo/src/main/kotlin/io/holunda/polyflow/view/mongo/task/TaskCountByApplicationRepositoryExtension.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.mongo.task
2 |
3 | import io.holunda.polyflow.view.query.task.ApplicationWithTaskCount
4 | import reactor.core.publisher.Flux
5 | import reactor.core.publisher.Mono
6 |
7 | /**
8 | * Counts tasks.
9 | */
10 | interface TaskCountByApplicationRepositoryExtension {
11 | /**
12 | * Retrieves counts grouped by application names.
13 | */
14 | fun findTaskCountsByApplication(): Flux
15 |
16 | /**
17 | * Retrieves a count of tasks for given application.
18 | */
19 | fun findTaskCountForApplication(applicationName: String): Mono
20 |
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/view/mongo/src/main/kotlin/io/holunda/polyflow/view/mongo/task/TaskRepositoryExtension.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.mongo.task
2 |
3 | import org.springframework.data.domain.Pageable
4 | import reactor.core.publisher.Flux
5 |
6 | /**
7 | * Extension to allow single type for implementation.
8 | */
9 | interface TaskRepositoryExtension : TaskCountByApplicationRepositoryExtension, TaskUpdatesExtension {
10 | /**
11 | * Find tasks visible to the user or one of the groups, optionally restricted by business key and priority.
12 | *
13 | * @param username user's name
14 | * @param groupNames user's groups
15 | * @param businessKey Business Key to restrict.
16 | * @param priorities Priorities to restrict.
17 | * If non-null and non-empty, any of the contained priorities must match.
18 | * @param pageable defines sorting and paging requirements.
19 | * @return Flux of matching documents.
20 | */
21 | fun findForUser(
22 | username: String,
23 | groupNames: Collection,
24 | businessKey: String?,
25 | priorities: Collection?,
26 | pageable: Pageable?
27 | ): Flux
28 | }
29 |
--------------------------------------------------------------------------------
/view/mongo/src/main/kotlin/io/holunda/polyflow/view/mongo/task/TaskUpdatesExtension.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.mongo.task
2 |
3 | import org.bson.BsonValue
4 | import org.springframework.data.mongodb.core.ChangeStreamEvent
5 | import reactor.core.publisher.Flux
6 |
7 | /**
8 | * Task updates.
9 | */
10 | interface TaskUpdatesExtension {
11 | /**
12 | * Retrieves a task updates flux.
13 | */
14 | fun getTaskUpdates(resumeToken: BsonValue? = null): Flux>
15 | }
16 |
--------------------------------------------------------------------------------
/view/mongo/src/main/kotlin/io/holunda/polyflow/view/mongo/task/TaskWithDataEntriesRepository.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.mongo.task
2 |
3 | import org.springframework.data.mongodb.repository.ReactiveMongoRepository
4 | import org.springframework.stereotype.Repository
5 |
6 |
7 | /**
8 | * Reactive mongo repository for tasks with data entries.
9 | */
10 | @Repository
11 | interface TaskWithDataEntriesRepository : TaskWithDataEntriesRepositoryExtension, ReactiveMongoRepository
12 |
13 |
--------------------------------------------------------------------------------
/view/mongo/src/main/kotlin/io/holunda/polyflow/view/mongo/task/TaskWithDataEntriesRepositoryExtension.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.mongo.task
2 |
3 | import io.holunda.polyflow.view.auth.User
4 | import io.holunda.polyflow.view.filter.Criterion
5 | import org.springframework.data.domain.Pageable
6 | import reactor.core.publisher.Flux
7 |
8 |
9 | /**
10 | * Repository extension.
11 | */
12 | interface TaskWithDataEntriesRepositoryExtension {
13 |
14 | /**
15 | * Find all tasks with data entries matching specified filter.
16 | */
17 | fun findAllFilteredForUser(user: User, criteria: List, pageable: Pageable? = null): Flux
18 | }
19 |
--------------------------------------------------------------------------------
/view/mongo/src/test/resources/application-itest-replicated.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | data:
3 | mongodb:
4 | uri: mongodb://127.0.0.1:27017/?replicaSet=repembedded
5 |
--------------------------------------------------------------------------------
/view/mongo/src/test/resources/application-itest-standalone.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | data:
3 | mongodb:
4 | uri: mongodb://127.0.0.1:27017
5 |
--------------------------------------------------------------------------------
/view/mongo/src/test/resources/banner.txt:
--------------------------------------------------------------------------------
1 | -------------------------------------------------------------------------------
2 | Mongo ITEST
3 | -------------------------------------------------------------------------------
4 |
--------------------------------------------------------------------------------
/view/mongo/src/test/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/view/simple/src/main/kotlin/io/holunda/polyflow/view/simple/EnablePolyflowSimpleView.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.simple
2 |
3 | import org.springframework.context.annotation.Import
4 |
5 |
6 | /**
7 | * Enables simple (in-memory) polyflow view.
8 | */
9 | @MustBeDocumented
10 | @Import(TaskPoolSimpleViewConfiguration::class)
11 | annotation class EnablePolyflowSimpleView
12 |
--------------------------------------------------------------------------------
/view/simple/src/main/kotlin/io/holunda/polyflow/view/simple/service/SimpleServiceViewProcessingGroup.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.simple.service
2 |
3 | import io.github.oshai.kotlinlogging.KotlinLogging
4 | import org.axonframework.config.EventProcessingConfiguration
5 | import org.axonframework.eventhandling.TrackingEventProcessor
6 | import org.springframework.stereotype.Component
7 |
8 | private val logger = KotlinLogging.logger {}
9 |
10 | /**
11 | * Component responsible for offering replay functionality of the processor.
12 | */
13 | @Component
14 | class SimpleServiceViewProcessingGroup(
15 | private val configuration: EventProcessingConfiguration
16 | ) {
17 |
18 | companion object {
19 | const val PROCESSING_GROUP = "io.holunda.polyflow.view.simple"
20 | }
21 |
22 | /**
23 | * Configure to run a event replay to fill the simple task view with events on start-up.
24 | */
25 | fun restore() {
26 | this.configuration
27 | .eventProcessorByProcessingGroup(PROCESSING_GROUP, TrackingEventProcessor::class.java)
28 | .ifPresent {
29 | logger.info { "VIEW-SIMPLE-002: Starting simple view event replay." }
30 | it.shutDown()
31 | it.resetTokens()
32 | it.start()
33 | }
34 | }
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/view/simple/src/test/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/view/view-api-client/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 |
7 | io.holunda.polyflow
8 | polyflow-view-parent
9 | 4.4.1-SNAPSHOT
10 |
11 |
12 | polyflow-view-api-client
13 | core/view/${project.artifactId}
14 |
15 |
16 |
17 | io.holunda.polyflow
18 | polyflow-view-api
19 |
20 |
21 |
22 |
23 |
24 |
25 | org.apache.maven.plugins
26 | maven-surefire-plugin
27 |
28 | false
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/view/view-api-client/src/main/kotlin/ProcessDefinitionQueryClient.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view
2 |
3 | import io.holunda.polyflow.view.query.process.ProcessDefinitionsStartableByUserQuery
4 | import io.holunda.polyflow.view.query.task.*
5 | import org.axonframework.messaging.responsetypes.ResponseTypes
6 | import org.axonframework.queryhandling.QueryGateway
7 | import java.util.concurrent.CompletableFuture
8 |
9 | /**
10 | * Client encapsulating the correct query types (including response types)
11 | */
12 | open class ProcessDefinitionQueryClient(
13 | private val queryGateway: QueryGateway
14 | ) {
15 |
16 | /**
17 | * @see io.holunda.polyflow.view.query.process.ProcessDefinitionApi.query
18 | * @see io.holunda.polyflow.view.query.process.ProcessDefinitionsStartableByUserQuery
19 | */
20 | fun query(query: ProcessDefinitionsStartableByUserQuery): CompletableFuture> =
21 | queryGateway.query(
22 | query,
23 | ResponseTypes.multipleInstancesOf(ProcessDefinition::class.java)
24 | )
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/view/view-api/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 |
7 | io.holunda.polyflow
8 | polyflow-view-parent
9 | 4.4.1-SNAPSHOT
10 |
11 |
12 | polyflow-view-api
13 | core/view/${project.artifactId}
14 |
15 |
16 |
17 | io.holunda.polyflow
18 | polyflow-taskpool-event
19 |
20 |
21 | io.holunda.polyflow
22 | polyflow-datapool-event
23 |
24 |
25 | io.holixon.axon.gateway
26 | axon-gateway-extension
27 |
28 |
29 | org.springframework
30 | spring-core
31 | provided
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/ComponentLike.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view
2 |
3 | /**
4 | * Marker annotation to open the classes in Kotlin.
5 | */
6 | @MustBeDocumented
7 | @Target(AnnotationTarget.CLASS, AnnotationTarget.ANNOTATION_CLASS)
8 | annotation class ComponentLike
9 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/FormUrlResolver.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view
2 |
3 | /**
4 | * Facility to resolve URLs of forms.
5 | */
6 | interface FormUrlResolver {
7 | /**
8 | * Creates a complete URL to call the tasks form e.g. from the task list
9 | */
10 | fun resolveUrl(task: Task): String
11 | /**
12 | * Creates a complete URL to call the start forms.
13 | */
14 | fun resolveUrl(processDefinition: ProcessDefinition): String
15 | /**
16 | * Creates a complete
17 | */
18 | fun resolveUrl(dataEntry: DataEntry): String
19 | }
20 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/ProcessDefinition.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view
2 |
3 | /**
4 | * Represents a deployed process definition.
5 | */
6 | data class ProcessDefinition(
7 | val processDefinitionId: String,
8 | val processDefinitionKey: String,
9 | val processDefinitionVersion: Int,
10 |
11 | val applicationName: String,
12 | val processName: String,
13 | val processVersionTag: String? = null,
14 | val processDescription: String? = null,
15 | val formKey: String? = null,
16 | val startableFromTasklist: Boolean = true,
17 | val candidateStarterUsers: Set = setOf(),
18 | val candidateStarterGroups: Set = setOf()
19 | )
20 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/ProcessInstanceState.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view
2 |
3 | /**
4 | * Process instance state.
5 | */
6 | enum class ProcessInstanceState {
7 | /**
8 | * Process is running.
9 | */
10 | RUNNING,
11 |
12 | /**
13 | * Process is finished.
14 | */
15 | FINISHED,
16 |
17 | /**
18 | * Process is cancelled.
19 | */
20 | CANCELLED,
21 |
22 | /**
23 | * Process is suspended.
24 | */
25 | SUSPENDED
26 | }
27 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/ProcessVariable.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view
2 |
3 | import io.holunda.camunda.taskpool.api.process.variable.ProcessVariableValue
4 | import io.holunda.camunda.taskpool.api.task.SourceReference
5 |
6 | /**
7 | * Represents a process variable.
8 | */
9 | data class ProcessVariable(
10 | val variableName: String,
11 | val variableInstanceId: String,
12 | val sourceReference: SourceReference,
13 | val scopeActivityInstanceId: String,
14 | val value: ProcessVariableValue
15 | )
16 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/ProtocolEntry.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view
2 |
3 | import io.holunda.camunda.taskpool.api.business.DataEntryState
4 | import java.time.Instant
5 | import java.util.*
6 |
7 | /**
8 | * Represents a protocol entry.
9 | */
10 | data class ProtocolEntry(
11 | val time: Instant,
12 | val state: DataEntryState,
13 | val username: String?,
14 | val logMessage: String?,
15 | val logDetails: String?
16 | )
17 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/auth/User.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.auth
2 |
3 | /**
4 | * Simple user abstraction.
5 | * @param username username of the user.
6 | * @param groups set of group names assigned to the user.
7 | */
8 | data class User(
9 | val username: String,
10 | val groups: Set
11 | )
12 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/auth/UserService.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.auth
2 |
3 | /**
4 | * Simple integration hook into auth of the final system.
5 | */
6 | interface UserService {
7 |
8 | /**
9 | * Retrieves a user for given user identifier.
10 | * [userIdentifier] a token or a key identifying the user.
11 | * @return User
12 | * @throws UnknownUserException if user not found.
13 | */
14 | @Throws(UnknownUserException::class)
15 | fun getUser(userIdentifier: String): User
16 |
17 | }
18 |
19 | /**
20 | * Is thrown if the user is not known in the system.
21 | */
22 | class UnknownUserException(reason: String) : IllegalArgumentException(reason)
23 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/FilterQuery.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query
2 |
3 | /**
4 | * Query using a filter function.
5 | */
6 | interface FilterQuery {
7 | /**
8 | * Applies the filter.
9 | * @param element element to check.
10 | * @return true, if the element is included into the result.
11 | */
12 | fun applyFilter(element: T): Boolean
13 | }
14 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/data/DataEntriesForDataEntryTypeQuery.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.data
2 |
3 | import io.holunda.camunda.taskpool.api.business.EntryType
4 | import io.holunda.polyflow.view.DataEntry
5 | import io.holunda.polyflow.view.query.FilterQuery
6 | import io.holunda.polyflow.view.query.PageableSortableQuery
7 |
8 | /**
9 | * Query by entry type.
10 | * @param entryType type of data entry.
11 | * @param page current page, zero-based index.
12 | * @param size page size
13 | */
14 | data class DataEntriesForDataEntryTypeQuery(
15 | val entryType: EntryType,
16 | override val page: Int = 0,
17 | override val size: Int = Int.MAX_VALUE,
18 | override val sort: List = listOf()
19 | ) : FilterQuery, PageableSortableQuery {
20 |
21 | @Deprecated("Please use other constructor setting sort as List")
22 | constructor(entryType: EntryType, page: Int = 0, size: Int = Int.MAX_VALUE, sort: String?) : this(
23 | entryType = entryType,
24 | page = page,
25 | size = size,
26 | sort = if (sort.isNullOrBlank()) {
27 | listOf()
28 | } else {
29 | listOf(sort)
30 | },
31 | )
32 |
33 | override fun applyFilter(element: DataEntry) = element.entryType == this.entryType
34 | }
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/data/DataEntriesQueryResult.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.data
2 |
3 | import io.holunda.polyflow.view.DataEntry
4 | import io.holunda.polyflow.view.query.PageableSortableQuery
5 | import io.holunda.polyflow.view.query.QueryResult
6 |
7 | /**
8 | * Results of a query for multiple data entries.
9 | */
10 | data class DataEntriesQueryResult(
11 | override val elements: List,
12 | override val totalElementCount: Int = elements.size
13 | ) : QueryResult(elements = elements, totalElementCount = totalElementCount) {
14 |
15 | override fun slice(query: PageableSortableQuery) = this.copy(elements = super.slice(query).elements)
16 | }
17 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/data/DataEntryForIdentityQuery.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.data
2 |
3 | import io.holunda.camunda.taskpool.api.business.DataIdentity
4 | import io.holunda.camunda.taskpool.api.business.EntryId
5 | import io.holunda.camunda.taskpool.api.business.EntryType
6 | import io.holunda.polyflow.view.DataEntry
7 | import io.holunda.polyflow.view.query.FilterQuery
8 |
9 | /**
10 | * Query for entry type and optional id.
11 | * @param entryType type of the data entry.
12 | * @param entryId id of the data entry.
13 | */
14 | data class DataEntryForIdentityQuery(
15 | val entryType: EntryType,
16 | val entryId: EntryId,
17 | ) : FilterQuery {
18 |
19 | /**
20 | * Additional convenience constructor.
21 | */
22 | constructor(
23 | identity: DataIdentity
24 | ) : this(
25 | entryType = identity.entryType,
26 | entryId = identity.entryId,
27 | )
28 |
29 | override fun applyFilter(element: DataEntry) = element.entryType == this.entryType && element.entryId == this.entryId
30 | }
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/data/QueryDataIdentity.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.data
2 |
3 | import io.holunda.camunda.taskpool.api.business.DataIdentity
4 | import io.holunda.camunda.taskpool.api.business.EntryId
5 | import io.holunda.camunda.taskpool.api.business.EntryType
6 |
7 | /**
8 | * Identity used in queries.
9 | */
10 | data class QueryDataIdentity(
11 | override val entryType: EntryType,
12 | override val entryId: EntryId
13 | ) : DataIdentity
14 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/process/ProcessDefinitionApi.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.process
2 |
3 | import io.holunda.polyflow.view.ProcessDefinition
4 |
5 | /**
6 | * Queries for process definitions.
7 | */
8 | interface ProcessDefinitionApi {
9 |
10 | /**
11 | * Query for process definitions startable by user.
12 | * @param query query object.
13 | * @return list of process definitions.
14 | */
15 | fun query(query: ProcessDefinitionsStartableByUserQuery): List
16 | }
17 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/process/ProcessDefinitionsStartableByUserQuery.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.process
2 |
3 | import io.holunda.polyflow.view.ProcessDefinition
4 | import io.holunda.polyflow.view.auth.User
5 | import io.holunda.polyflow.view.query.FilterQuery
6 |
7 | /**
8 | * Query for startable processes by given user.
9 | * @param user user with groups accessing the startable processes.
10 | */
11 | data class ProcessDefinitionsStartableByUserQuery(
12 | val user: User
13 | ) : FilterQuery {
14 |
15 | override fun applyFilter(element: ProcessDefinition) =
16 | // start-able
17 | element.startableFromTasklist &&
18 | // candidate user
19 | (element.candidateStarterUsers.contains(this.user.username)
20 | // candidate groups
21 | || (element.candidateStarterGroups.any { candidateGroup -> this.user.groups.contains(candidateGroup) }))
22 | }
23 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/process/ProcessInstanceApi.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.process
2 |
3 | import org.axonframework.queryhandling.QueryResponseMessage
4 |
5 | /**
6 | * Process instance API.
7 | */
8 | interface ProcessInstanceApi {
9 |
10 | /**
11 | * Query for process instances.
12 | * @param query query object.
13 | * @return list of process instances.
14 | */
15 | fun query(query: ProcessInstancesByStateQuery): QueryResponseMessage
16 | }
17 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/process/ProcessInstanceQueryResult.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.process
2 |
3 | import io.holunda.polyflow.view.ProcessInstance
4 | import io.holunda.polyflow.view.query.PageableSortableQuery
5 | import io.holunda.polyflow.view.query.QueryResult
6 |
7 | /**
8 | * Result for process instance queries.
9 | */
10 | data class ProcessInstanceQueryResult(
11 | override val elements: List
12 | ) : QueryResult(elements = elements) {
13 | override fun slice(query: PageableSortableQuery) = this.copy(elements = super.slice(query).elements)
14 | }
15 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/process/ProcessInstancesByStateQuery.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.process
2 |
3 | import io.holunda.polyflow.view.ProcessInstance
4 | import io.holunda.polyflow.view.ProcessInstanceState
5 | import io.holunda.polyflow.view.query.FilterQuery
6 |
7 | /**
8 | * Query for process instance matching the provided states.
9 | */
10 | data class ProcessInstancesByStateQuery(
11 | val states: Set
12 | ) : FilterQuery {
13 | override fun applyFilter(element: ProcessInstance): Boolean = states.contains(element = element.state)
14 | }
15 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/process/ReactiveProcessDefinitionApi.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.process
2 |
3 | import io.holunda.polyflow.view.ProcessDefinition
4 | import org.axonframework.messaging.MetaData
5 | import java.util.concurrent.CompletableFuture
6 |
7 | /**
8 | * Reactive API for process definitions.
9 | * @see ProcessDefinitionApi
10 | * For the client, there is no difference in definition of the query, but the implementer has a different method to reflect the reactive nature.
11 | */
12 | interface ReactiveProcessDefinitionApi {
13 |
14 | /**
15 | * Query for startable process definitions.
16 | * @param query query object.
17 | * @param metaData query metaData, may be empty.
18 | * @return observable list of process definitions.
19 | */
20 | fun query(query: ProcessDefinitionsStartableByUserQuery, metaData: MetaData = MetaData.emptyInstance()): CompletableFuture>
21 | }
22 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/process/variable/ProcessVariableApi.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.process.variable
2 |
3 | import org.axonframework.queryhandling.QueryResponseMessage
4 |
5 | /**
6 | * Process variable API.
7 | */
8 | interface ProcessVariableApi {
9 |
10 | /**
11 | * Query for process variables.
12 | */
13 | fun query(query: ProcessVariablesForInstanceQuery): QueryResponseMessage
14 | }
15 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/process/variable/ProcessVariableFilter.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.process.variable
2 |
3 | import io.holunda.polyflow.view.ProcessVariable
4 | import java.util.function.Function
5 |
6 | /**
7 | * Process variable filter
8 | */
9 | interface ProcessVariableFilter : Function {
10 | val type: ProcessVariableFilterType
11 | }
12 |
13 | /**
14 | * Filter type.
15 | */
16 | enum class ProcessVariableFilterType {
17 | /**
18 | * Include variables.
19 | */
20 | INCLUDE,
21 |
22 | /**
23 | * Exclude variables.
24 | */
25 | EXCLUDE
26 | }
27 |
28 |
29 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/process/variable/ProcessVariableQueryResult.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.process.variable
2 |
3 | import io.holunda.polyflow.view.ProcessVariable
4 |
5 | /**
6 | * Response of the process variable query.
7 | */
8 | data class ProcessVariableQueryResult(
9 | val variables: List
10 | )
11 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/process/variable/ProcessVariablesForInstanceQuery.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.process.variable
2 |
3 | import io.holunda.polyflow.view.ProcessVariable
4 | import io.holunda.polyflow.view.query.FilterQuery
5 |
6 | /**
7 | * Query for variables of given process instance.
8 | * @param processInstanceId process instance id to query for.
9 | * @param variableFilter
10 | */
11 | data class ProcessVariablesForInstanceQuery(
12 | val processInstanceId: String,
13 | val variableFilter: List
14 | ) : FilterQuery {
15 |
16 | override fun applyFilter(element: ProcessVariable): Boolean =
17 | element.sourceReference.instanceId == processInstanceId
18 | && (variableFilter.isEmpty() || variableFilter.any { filter -> filter.apply(element) })
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/process/variable/filter/ProcessVariableFilterExactlyOne.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.process.variable.filter
2 |
3 | import io.holunda.polyflow.view.ProcessVariable
4 | import io.holunda.polyflow.view.query.process.variable.ProcessVariableFilter
5 | import io.holunda.polyflow.view.query.process.variable.ProcessVariableFilterType
6 |
7 | /**
8 | * Filter to query for exactly one variable.
9 | */
10 | data class ProcessVariableFilterExactlyOne(
11 | val processVariableName: String
12 | ) : ProcessVariableFilter {
13 |
14 | override val type: ProcessVariableFilterType = ProcessVariableFilterType.INCLUDE
15 | override fun apply(variable: ProcessVariable): Boolean = processVariableName == variable.variableName
16 | }
17 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/process/variable/filter/ProcessVariableFilterOneOf.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.process.variable.filter
2 |
3 | import io.holunda.polyflow.view.ProcessVariable
4 | import io.holunda.polyflow.view.query.process.variable.ProcessVariableFilter
5 | import io.holunda.polyflow.view.query.process.variable.ProcessVariableFilterType
6 |
7 | /**
8 | * Filter to query for a list of variables. Every variable present in the list matches the filter.
9 | */
10 | data class ProcessVariableFilterOneOf(
11 | val processVariableNames: Set
12 | ) : ProcessVariableFilter {
13 |
14 | init {
15 | require(processVariableNames.isNotEmpty()) { "You must specify at least one variable for this filter." }
16 | }
17 |
18 | override val type: ProcessVariableFilterType = ProcessVariableFilterType.INCLUDE
19 | override fun apply(variable: ProcessVariable): Boolean = processVariableNames.contains(variable.variableName)
20 | }
21 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/task/AllTasksQuery.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.task
2 |
3 | import io.holunda.polyflow.view.Task
4 |
5 | /**
6 | * Query for all tasks.
7 | * @param page - page to read, zero-based index.
8 | * @param size - size of the page
9 | * @param sort - optional attribute to sort by.
10 | * @param filters - the filters to further filter down the tasks.
11 | */
12 | data class AllTasksQuery(
13 | override val page: Int = 0,
14 | override val size: Int = Int.MAX_VALUE,
15 | override val sort: List = listOf(),
16 | override val filters: List = listOf()
17 | ) : PageableSortableFilteredTaskQuery {
18 |
19 | @Deprecated("Please use other constructor setting sort as List")
20 | constructor(page: Int = 0, size: Int = Int.MAX_VALUE, sort: String?, filters: List = listOf()): this(
21 | page = page,
22 | size = size,
23 | sort = if (sort.isNullOrBlank()) {
24 | listOf()
25 | } else {
26 | listOf(sort)
27 | },
28 | filters = filters
29 | )
30 |
31 | override fun applyFilter(element: Task): Boolean = true
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/task/ApplicationWithTaskCount.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.task
2 |
3 | /**
4 | * Information about amount of tasks per application.
5 | */
6 | data class ApplicationWithTaskCount(
7 | val application: String,
8 | val taskCount: Int
9 | )
10 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/task/PageableSortableFilteredTaskQuery.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.task
2 |
3 | import io.holunda.polyflow.view.Task
4 | import io.holunda.polyflow.view.query.FilterQuery
5 | import io.holunda.polyflow.view.query.PageableSortableQuery
6 |
7 | /**
8 | * Pageable and sortable task query containing filters.
9 | */
10 | interface PageableSortableFilteredTaskQuery : FilterQuery, PageableSortableQuery {
11 | val filters: List
12 | }
13 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/task/TaskAttributeNamesQuery.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.task
2 |
3 | import io.holunda.polyflow.view.Task
4 | import io.holunda.polyflow.view.auth.User
5 | import io.holunda.polyflow.view.query.FilterQuery
6 | import io.holunda.polyflow.view.query.PageableSortableQuery
7 |
8 | /**
9 | * Query for tasks attribute names.
10 | * @param user - the user with groups accessing the tasks. If non is passed, all task attributes will be queried.
11 | * @param assignedToMeOnly flag indicating if the resulting tasks must be assigned to the user only.
12 | */
13 | data class TaskAttributeNamesQuery(
14 | val user: User?,
15 | val assignedToMeOnly: Boolean = false,
16 | ) : FilterQuery {
17 |
18 | override fun applyFilter(element: Task): Boolean = true
19 |
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/task/TaskAttributeNamesQueryResult.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.task
2 |
3 | import io.holunda.polyflow.view.query.PageableSortableQuery
4 | import io.holunda.polyflow.view.query.QueryResult
5 |
6 | /**
7 | * Result of query for multiple task attributes.
8 | */
9 | data class TaskAttributeNamesQueryResult(
10 | override val elements: List,
11 | override val totalElementCount: Int = elements.size
12 | ) : QueryResult(elements = elements, totalElementCount = totalElementCount) {
13 | override fun slice(query: PageableSortableQuery) = this.copy(elements = super.slice(query).elements)
14 | }
15 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/task/TaskAttributeValuesQueryResult.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.task
2 |
3 | import io.holunda.polyflow.view.Task
4 | import io.holunda.polyflow.view.query.PageableSortableQuery
5 | import io.holunda.polyflow.view.query.QueryResult
6 |
7 | /**
8 | * Result of query for multiple task attributes.
9 | */
10 | data class TaskAttributeValuesQueryResult(
11 | override val elements: List,
12 | override val totalElementCount: Int = elements.size
13 | ) : QueryResult(elements = elements, totalElementCount = totalElementCount) {
14 | override fun slice(query: PageableSortableQuery) = this.copy(elements = super.slice(query).elements)
15 | }
16 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/task/TaskCountByApplicationQuery.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.task
2 |
3 | /**
4 | * Query for amount of tasks for every application.
5 | */
6 | class TaskCountByApplicationQuery {
7 |
8 | /*
9 | * This is a marker class. All instances should be equal.
10 | */
11 | override fun equals(other: Any?): Boolean {
12 | return (other is TaskCountByApplicationQuery)
13 | }
14 |
15 | /*
16 | * This is a marker class. All instances should be equal.
17 | */
18 | override fun hashCode(): Int {
19 | return 1329081230;
20 | }
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/task/TaskForIdQuery.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.task
2 |
3 | import io.holunda.polyflow.view.Task
4 | import io.holunda.polyflow.view.query.FilterQuery
5 |
6 | /**
7 | * Query for task with a given id.
8 | * @param id task id.
9 | */
10 | data class TaskForIdQuery(val id: String) : FilterQuery {
11 | override fun applyFilter(element: Task): Boolean = element.id == id
12 | }
13 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/task/TaskQueryResult.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.task
2 |
3 | import io.holunda.polyflow.view.Task
4 | import io.holunda.polyflow.view.query.PageableSortableQuery
5 | import io.holunda.polyflow.view.query.QueryResult
6 |
7 | /**
8 | * Result of query for multiple tasks.
9 | */
10 | data class TaskQueryResult(
11 | override val elements: List,
12 | override val totalElementCount: Int = elements.size
13 | ) : QueryResult(elements = elements, totalElementCount = totalElementCount) {
14 | override fun slice(query: PageableSortableQuery) = this.copy(elements = super.slice(query).elements)
15 | }
16 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/task/TaskWithDataEntriesForIdQuery.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.task
2 |
3 | import io.holunda.polyflow.view.TaskWithDataEntries
4 | import io.holunda.polyflow.view.query.FilterQuery
5 |
6 |
7 | /**
8 | * Query for task with given id with correlated data entries.
9 | * @param id task id.
10 | */
11 | data class TaskWithDataEntriesForIdQuery(val id: String) : FilterQuery {
12 | override fun applyFilter(element: TaskWithDataEntries): Boolean = TaskForIdQuery(id).applyFilter(element.task)
13 | }
14 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/task/TasksForApplicationQuery.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.task
2 |
3 | import io.holunda.polyflow.view.Task
4 | import io.holunda.polyflow.view.query.FilterQuery
5 |
6 | /**
7 | * Query for task of a certain process application.
8 | * @param applicationName the name of the process application.
9 | */
10 | data class TasksForApplicationQuery(val applicationName: String) : FilterQuery {
11 | override fun applyFilter(element: Task): Boolean = element.sourceReference.applicationName == applicationName
12 | }
13 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/query/task/TasksWithDataEntriesQueryResult.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.task
2 |
3 | import io.holunda.polyflow.view.TaskWithDataEntries
4 | import io.holunda.polyflow.view.query.PageableSortableQuery
5 | import io.holunda.polyflow.view.query.QueryResult
6 |
7 | /**
8 | * Result for query for multiple tasks with data entries.
9 | */
10 | data class TasksWithDataEntriesQueryResult(
11 | override val elements: List,
12 | override val totalElementCount: Int = elements.size
13 | ) : QueryResult(elements = elements, totalElementCount = totalElementCount) {
14 | override fun slice(query: PageableSortableQuery) = this.copy(elements = super.slice(query).elements)
15 | }
16 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/sort/DataEntryComparator.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.sort
2 |
3 | import io.holunda.polyflow.view.DataEntry
4 | import io.holunda.polyflow.view.filter.extractValue
5 | import java.lang.reflect.Field
6 | import java.util.Comparator
7 | import javax.xml.datatype.DatatypeConstants
8 |
9 |
10 | /**
11 | * Comparator of data entries to be used in a sort.
12 | */
13 | data class DataEntryComparator(
14 | private val fieldSort: Pair
15 | ) : Comparator {
16 |
17 | override fun compare(o1: DataEntry, o2: DataEntry): Int {
18 | return try {
19 |
20 | val v1 = extractValue(o1, this.fieldSort.first)
21 | val v2 = extractValue(o2, this.fieldSort.first)
22 |
23 | when (findCompareMode(v1, v2)) {
24 | CompareMode.DEFAULT -> compareActual(fieldSort, v1, v2)
25 | CompareMode.LESS_THAN -> -1 * this.fieldSort.second.modifier
26 | CompareMode.GREATER_THAN -> 1 * this.fieldSort.second.modifier
27 | CompareMode.EQUAL -> 0 * this.fieldSort.second.modifier
28 | }
29 | } catch (e: Exception) {
30 | DatatypeConstants.LESSER
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/sort/TaskComparator.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.sort
2 |
3 | import io.holunda.polyflow.view.Task
4 | import io.holunda.polyflow.view.TaskWithDataEntries
5 | import io.holunda.polyflow.view.filter.extractValue
6 | import java.lang.reflect.Field
7 | import javax.xml.datatype.DatatypeConstants.LESSER
8 |
9 | /**
10 | * Comparator for Tasks with Data Entries
11 | */
12 | data class TaskComparator(
13 | private val fieldSort: Pair
14 | ) : Comparator {
15 | override fun compare(o1: Task, o2: Task): Int {
16 | return try {
17 |
18 | val v1 = extractValue(o1, this.fieldSort.first)
19 | val v2 = extractValue(o2, this.fieldSort.first)
20 |
21 | when (findCompareMode(v1, v2)) {
22 | CompareMode.DEFAULT -> compareActual(fieldSort, v1, v2)
23 | CompareMode.LESS_THAN -> -1 * this.fieldSort.second.modifier
24 | CompareMode.GREATER_THAN -> 1 * this.fieldSort.second.modifier
25 | CompareMode.EQUAL -> 0 * this.fieldSort.second.modifier
26 | }
27 | } catch (e: Exception) {
28 | LESSER
29 | }
30 | }
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/view/view-api/src/main/kotlin/sort/TasksWithDataEntriesComparator.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.sort
2 |
3 | import io.holunda.polyflow.view.TaskWithDataEntries
4 | import io.holunda.polyflow.view.filter.extractValue
5 | import java.lang.reflect.Field
6 | import javax.xml.datatype.DatatypeConstants.LESSER
7 |
8 | /**
9 | * Comparator for Tasks with Data Entries
10 | */
11 | data class TasksWithDataEntriesComparator(
12 | private val fieldSort: Pair
13 | ) : Comparator {
14 | override fun compare(o1: TaskWithDataEntries, o2: TaskWithDataEntries): Int {
15 | return try {
16 |
17 | val v1 = extractValue(o1.task, this.fieldSort.first)
18 | val v2 = extractValue(o2.task, this.fieldSort.first)
19 |
20 | when (findCompareMode(v1, v2)) {
21 | CompareMode.DEFAULT -> compareActual(fieldSort, v1, v2)
22 | CompareMode.LESS_THAN -> -1 * this.fieldSort.second.modifier
23 | CompareMode.GREATER_THAN -> 1 * this.fieldSort.second.modifier
24 | CompareMode.EQUAL -> 0 * this.fieldSort.second.modifier
25 | }
26 | } catch (e: Exception) {
27 | LESSER
28 | }
29 | }
30 | }
31 |
32 |
--------------------------------------------------------------------------------
/view/view-api/src/test/kotlin/DataEntryTest.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view
2 |
3 | import org.assertj.core.api.Assertions.assertThat
4 | import org.junit.jupiter.api.Test
5 |
6 | class DataEntryTest {
7 |
8 | @Test
9 | fun `has identity`() {
10 | assertThat(DataEntry(
11 | entryType = "type",
12 | entryId = "foo",
13 | name = "some",
14 | applicationName = "app1",
15 | type = "myType"
16 | ).identity).isEqualTo("type#foo")
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/view/view-api/src/test/kotlin/query/data/DataEntryForIdentityQueryTest.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.data
2 |
3 | import io.holunda.polyflow.view.DataEntry
4 | import org.assertj.core.api.Assertions.assertThat
5 | import org.junit.jupiter.api.Test
6 |
7 | internal class DataEntryForIdentityQueryTest {
8 |
9 | private val dataEntry = DataEntry(
10 | entryType = "io.type",
11 | entryId = "0239480234",
12 | type = "data entry",
13 | applicationName = "test-application",
14 | name = "Data Entry for case 4711",
15 | )
16 |
17 | @Test
18 | fun `should filter by identity`() {
19 | assertThat(DataEntryForIdentityQuery(entryType = "io.type", entryId = "0239480234").applyFilter(dataEntry)).isTrue
20 | assertThat(DataEntryForIdentityQuery(entryType = "other.type", entryId = "0239480234").applyFilter(dataEntry)).isFalse
21 | assertThat(DataEntryForIdentityQuery(entryType = "io.type", entryId = "other-id").applyFilter(dataEntry)).isFalse
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/view/view-api/src/test/kotlin/query/process/ProcessInstanceByStateQueryTest.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.process
2 |
3 | import io.holunda.camunda.taskpool.api.task.ProcessReference
4 | import io.holunda.polyflow.view.ProcessInstance
5 | import io.holunda.polyflow.view.ProcessInstanceState
6 | import org.assertj.core.api.Assertions.assertThat
7 | import org.junit.jupiter.api.Test
8 |
9 | internal class ProcessInstanceByStateQueryTest {
10 |
11 | private val processInstance = ProcessInstance(
12 | processInstanceId = "9034278213",
13 | sourceReference = ProcessReference(
14 | instanceId = "instance-id",
15 | executionId = "exec-id",
16 | definitionId = "def-id",
17 | definitionKey = "def-key",
18 | name = "process name",
19 | applicationName = "test-application"
20 | ),
21 | state = ProcessInstanceState.RUNNING
22 | )
23 |
24 | @Test
25 | fun `should filter by state`() {
26 | assertThat(ProcessInstancesByStateQuery(states = setOf(ProcessInstanceState.RUNNING)).applyFilter(processInstance)).isTrue
27 | assertThat(ProcessInstancesByStateQuery(states = setOf(ProcessInstanceState.FINISHED)).applyFilter(processInstance)).isFalse
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/view/view-api/src/test/kotlin/query/task/AllTasksQueryTest.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.task
2 |
3 | import io.holunda.camunda.taskpool.api.task.ProcessReference
4 | import io.holunda.polyflow.view.Task
5 | import io.holunda.polyflow.view.auth.User
6 | import org.assertj.core.api.Assertions.assertThat
7 | import org.junit.jupiter.api.Test
8 |
9 | class AllTasksQueryTest {
10 | private val task = Task(
11 | id = "923847239",
12 | sourceReference = ProcessReference(
13 | instanceId = "instance-id",
14 | executionId = "exec-id",
15 | definitionId = "def-id",
16 | definitionKey = "def-key",
17 | name = "process name",
18 | applicationName = "test-application"
19 | ),
20 | name = "task 1",
21 | description = "description",
22 | taskDefinitionKey = "task-def",
23 | candidateUsers = setOf("kermit"),
24 | assignee = "piggy",
25 | candidateGroups = setOf("muppets"),
26 | )
27 |
28 | @Test
29 | fun `should always return true`() {
30 | assertThat(AllTasksQuery().applyFilter(task)).isTrue
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/view/view-api/src/test/kotlin/query/task/TaskForIdQueryTest.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.task
2 |
3 | import io.holunda.camunda.taskpool.api.task.ProcessReference
4 | import io.holunda.polyflow.view.Task
5 | import org.assertj.core.api.Assertions.assertThat
6 | import org.junit.jupiter.api.Test
7 |
8 | class TaskForIdQueryTest {
9 | private val task = Task(
10 | id = "923847239",
11 | sourceReference = ProcessReference(
12 | instanceId = "instance-id",
13 | executionId = "exec-id",
14 | definitionId = "def-id",
15 | definitionKey = "def-key",
16 | name = "process name",
17 | applicationName = "test-application"
18 | ),
19 | taskDefinitionKey = "task-def"
20 | )
21 |
22 | @Test
23 | fun `should filter by id`() {
24 | assertThat(TaskForIdQuery(id = "923847239").applyFilter(task)).isTrue
25 | assertThat(TaskForIdQuery(id = "other-id").applyFilter(task)).isFalse
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/view/view-api/src/test/kotlin/query/task/TasksForApplicationQueryTest.kt:
--------------------------------------------------------------------------------
1 | package io.holunda.polyflow.view.query.task
2 |
3 | import io.holunda.camunda.taskpool.api.task.ProcessReference
4 | import io.holunda.polyflow.view.Task
5 | import org.assertj.core.api.Assertions.assertThat
6 | import org.junit.jupiter.api.Test
7 |
8 | class TasksForApplicationQueryTest {
9 | private val task = Task(
10 | id = "923847239",
11 | sourceReference = ProcessReference(
12 | instanceId = "instance-id",
13 | executionId = "exec-id",
14 | definitionId = "def-id",
15 | definitionKey = "def-key",
16 | name = "process name",
17 | applicationName = "test-application"
18 | ),
19 | taskDefinitionKey = "task-def"
20 | )
21 |
22 | @Test
23 | fun `should filter by application`() {
24 | assertThat(TasksForApplicationQuery(applicationName = "test-application").applyFilter(task)).isTrue
25 | assertThat(TasksForApplicationQuery(applicationName = "other-application").applyFilter(task)).isFalse
26 | }
27 | }
28 |
--------------------------------------------------------------------------------