diff --git a/README.md b/README.md index a13c4467..2d5d3555 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +## Camunda BPM Data + +[![stable](https://img.shields.io/badge/lifecycle-STABLE-green.svg)](https://github.com/holisticon#open-source-lifecycle) [![Build Status](https://github.com/holunda-io/camunda-bpm-data/workflows/default/badge.svg)](https://github.com/holunda-io/camunda-bpm-data/actions) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.holunda.data/camunda-bpm-data/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.holunda.data/camunda-bpm-data) [![CodeCov](https://codecov.io/gh/holunda-io/camunda-bpm-data/branch/master/graph/badge.svg)](https://codecov.io/gh/holunda-io/camunda-bpm-data) @@ -5,9 +8,7 @@ [![Changes](https://img.shields.io/badge/CHANGES---yellow)](https://www.holunda.io/camunda-bpm-data/changelog) [![gitter](https://badges.gitter.im/holunda-io/camunda-bpm-data.svg)](https://gitter.im/holunda-io/camunda-bpm-data?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) -## Camunda BPM Data - -> Beautiful process data handling for Camunda BPM. +> Beautiful process data handling for Camunda Platform 7. ## Why to use this library in every Camunda project @@ -15,14 +16,14 @@ If you are a software engineer and run process automation projects in your compa based on Camunda Process Engine, you probably are familiar with process variables. Camunda offers an API to access them and thereby manipulate the state of the process execution - one of the core features during process automation. -Unfortunately, as a user of the Camunda API, you have to exactly know the variable type (so the Java class behind it). +Unfortunately, as a user of the Camunda Platform 7 API, you have to exactly know the variable type (so the Java class behind it). For example, if you store a String in a variable `"orderId"` you must extract it as a String in every piece of code. Since there is no code connection between the different code parts, but the BPMN process model orchestrates these snippets to a single process execution, it makes refactoring and testing of process automation projects error-prone and challenging. This library helps you to overcome these difficulties and make access, manipulation and testing process variables really -easy and convenient. We leverage the Camunda API and offer you not only a better API but also some [additional features](https://www.holunda.io/camunda-bpm-data/wiki/user-guide/features). +easy and convenient. We leverage the Camunda Platform 7 API and offer you not only a better API but also some [additional features](https://www.holunda.io/camunda-bpm-data/snapshot/user-guide/features.html). If you want to read more about data in Camunda processes, have a look on those articles: @@ -40,20 +41,20 @@ If you just want to start using the library, put the following dependency into y io.holunda.data camunda-bpm-data - 1.2.5 + 1.2.6 ``` If you are using Gradle Kotlin DSL add to your `build.gradle.kts`: ``` kotlin -implementation("io.holunda.data:camunda-bpm-data:1.2.5") +implementation("io.holunda.data:camunda-bpm-data:1.2.6") ``` For Gradle Groovy DSL add to your `build.gradle`: ``` groovy -implementation 'io.holunda.data:camunda-bpm-data:1.2.5' +implementation 'io.holunda.data:camunda-bpm-data:1.2.6' ``` ### Variable declaration Now your setup is completed, and you can declare your variables like this: @@ -139,7 +140,7 @@ Please put the following dependency into your `pom.xml`: io.holunda.data camunda-bpm-data-test - 1.2.2 + 1.2.6 test ``` @@ -191,23 +192,23 @@ public class ApproveOrderTaskControllerTest { ### Further documentation -For further details, please consult our [Quick Start](https://www.holunda.io/camunda-bpm-data/quick-start) -guide or have a look to our primary documentation - [the User Guide](https://www.holunda.io/camunda-bpm-data/wiki/user-guide) +For further details, please consult our [Quick Start](https://www.holunda.io/camunda-bpm-data/snapshot/quick-start) +guide or have a look to our primary documentation: [User Guide](https://www.holunda.io/camunda-bpm-data/snapshot/user-guide/motivation.html) ## Working Example We prepared some typical usage scenarios and implemented two example projects in Java and Kotlin. -See our [Examples](https://www.holunda.io/camunda-bpm-data/wiki/user-guide/examples) section for usage and configuration. +See our [Examples](https://www.holunda.io/camunda-bpm-data/snapshot/user-guide/examples.html) section for usage and configuration. ## License -[![Apache License 2](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://www.holunda.io/camunda-bpm-data/license) +[![Apache License 2](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE) This library is developed under Apache 2.0 License. ## Contribution -If you want to contribute to this project, feel free to do so. Start with [Contributing guide](http://holunda.io/camunda-bpm-data/wiki/developer-guide/contribution). +If you want to contribute to this project, feel free to do so. Start with [Contributing guide](http://holunda.io/camunda-bpm-data/snapshot/developer-guide/contribution.html). ## Maintainer diff --git a/example/coverage-report-aggregator/pom.xml b/example/coverage-report-aggregator/pom.xml index 7f00a86d..308020ca 100644 --- a/example/coverage-report-aggregator/pom.xml +++ b/example/coverage-report-aggregator/pom.xml @@ -6,7 +6,7 @@ io.holunda.data.example camunda-bpm-data-example-parent - 1.2.6 + 1.2.7 camunda-bpm-data-coverage-report diff --git a/example/example-java/pom.xml b/example/example-java/pom.xml index 9d745ce2..9d12ab4a 100644 --- a/example/example-java/pom.xml +++ b/example/example-java/pom.xml @@ -6,7 +6,7 @@ io.holunda.data.example camunda-bpm-data-example-parent - 1.2.6 + 1.2.7 camunda-bpm-data-example-java diff --git a/example/example-kotlin/pom.xml b/example/example-kotlin/pom.xml index fbdf0b1e..9b607838 100644 --- a/example/example-kotlin/pom.xml +++ b/example/example-kotlin/pom.xml @@ -6,7 +6,7 @@ io.holunda.data.example camunda-bpm-data-example-parent - 1.2.6 + 1.2.7 camunda-bpm-data-example-kotlin diff --git a/example/example-no-engine/pom.xml b/example/example-no-engine/pom.xml index 7f7818f5..5c1cc77b 100644 --- a/example/example-no-engine/pom.xml +++ b/example/example-no-engine/pom.xml @@ -6,7 +6,7 @@ io.holunda.data.example camunda-bpm-data-example-parent - 1.2.6 + 1.2.7 camunda-bpm-data-example-no-engine @@ -32,7 +32,7 @@ io.holunda.camunda-api camunda-bpm-engine-api - 7.15.0 + 7.17.0 diff --git a/example/itest/pom.xml b/example/itest/pom.xml index 76c54c57..206b9590 100644 --- a/example/itest/pom.xml +++ b/example/itest/pom.xml @@ -6,7 +6,7 @@ io.holunda.data.example camunda-bpm-data-example-parent - 1.2.6 + 1.2.7 camunda-bpm-data-integration-test diff --git a/example/pom.xml b/example/pom.xml index 939ac333..214d07e7 100644 --- a/example/pom.xml +++ b/example/pom.xml @@ -6,7 +6,7 @@ io.holunda.data camunda-bpm-data-parent - 1.2.6 + 1.2.7 io.holunda.data.example @@ -15,7 +15,7 @@ pom - 1.6.7 + 1.6.9 true true true diff --git a/example/spin-type-detector/pom.xml b/example/spin-type-detector/pom.xml index 55342e0e..132f43c2 100644 --- a/example/spin-type-detector/pom.xml +++ b/example/spin-type-detector/pom.xml @@ -6,7 +6,7 @@ io.holunda.data.example camunda-bpm-data-example-parent - 1.2.6 + 1.2.7 camunda-bpm-data-spin-type-detector diff --git a/extension/core/pom.xml b/extension/core/pom.xml index 593d3b61..09d9f026 100644 --- a/extension/core/pom.xml +++ b/extension/core/pom.xml @@ -6,7 +6,7 @@ io.holunda.data camunda-bpm-data-parent - 1.2.6 + 1.2.7 ../../pom.xml diff --git a/extension/core/src/main/java/io/holunda/camunda/bpm/data/adapter/basic/ReadAdapterLockedExternalTask.java b/extension/core/src/main/java/io/holunda/camunda/bpm/data/adapter/basic/ReadAdapterLockedExternalTask.java index ccab48c2..1455864e 100644 --- a/extension/core/src/main/java/io/holunda/camunda/bpm/data/adapter/basic/ReadAdapterLockedExternalTask.java +++ b/extension/core/src/main/java/io/holunda/camunda/bpm/data/adapter/basic/ReadAdapterLockedExternalTask.java @@ -1,7 +1,6 @@ package io.holunda.camunda.bpm.data.adapter.basic; import io.holunda.camunda.bpm.data.adapter.ReadAdapter; -import io.holunda.camunda.bpm.data.adapter.VariableNotFoundException; import org.camunda.bpm.engine.externaltask.LockedExternalTask; import java.util.Optional; @@ -14,24 +13,21 @@ @SuppressWarnings("java:S1192") public class ReadAdapterLockedExternalTask implements ReadAdapter { - private final LockedExternalTask lockedExternalTask; - private final String variableName; + private final ReadAdapter readAdapter; - public ReadAdapterLockedExternalTask(LockedExternalTask lockedExternalTask, String variableName) { - this.lockedExternalTask = lockedExternalTask; - this.variableName = variableName; + public ReadAdapterLockedExternalTask(LockedExternalTask lockedExternalTask, String variableName, Class clazz) { + readAdapter = new ReadWriteAdapterVariableMap<>(lockedExternalTask.getVariables(), variableName, clazz); } @Override public T get() { - return getOptional().orElseThrow(() -> new VariableNotFoundException("Couldn't find required variable '" + variableName + "'")); + return readAdapter.get(); } @Override @SuppressWarnings("unchecked") public Optional getOptional() { - return (Optional) Optional.ofNullable(lockedExternalTask.getVariables()) - .map(it -> it.get(variableName)); + return readAdapter.getOptional(); } @Override @@ -46,7 +42,7 @@ public Optional getLocalOptional() { @Override public T getOrDefault(T defaultValue) { - return getOptional().orElse(defaultValue); + return readAdapter.getOrDefault(defaultValue); } @Override @@ -56,7 +52,7 @@ public T getLocalOrDefault(T defaultValue) { @Override public T getOrNull() { - return getOptional().orElse(null); + return readAdapter.getOrNull(); } @Override diff --git a/extension/core/src/main/java/io/holunda/camunda/bpm/data/factory/BasicVariableFactory.java b/extension/core/src/main/java/io/holunda/camunda/bpm/data/factory/BasicVariableFactory.java index 2ba9538d..e5be4858 100644 --- a/extension/core/src/main/java/io/holunda/camunda/bpm/data/factory/BasicVariableFactory.java +++ b/extension/core/src/main/java/io/holunda/camunda/bpm/data/factory/BasicVariableFactory.java @@ -94,7 +94,7 @@ public ReadAdapter from(CaseService caseService, String caseExecutionId) { @Override public ReadAdapter from(LockedExternalTask lockedExternalTask) { - return new ReadAdapterLockedExternalTask<>(lockedExternalTask, name); + return new ReadAdapterLockedExternalTask<>(lockedExternalTask, name, clazz); } /** diff --git a/extension/core/src/test/java/io/holunda/camunda/bpm/data/reader/LockedExternalTaskReaderTest.java b/extension/core/src/test/java/io/holunda/camunda/bpm/data/reader/LockedExternalTaskReaderTest.java index e9d1b039..46b41472 100644 --- a/extension/core/src/test/java/io/holunda/camunda/bpm/data/reader/LockedExternalTaskReaderTest.java +++ b/extension/core/src/test/java/io/holunda/camunda/bpm/data/reader/LockedExternalTaskReaderTest.java @@ -10,11 +10,13 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.UUID; import static io.holunda.camunda.bpm.data.CamundaBpmData.listVariable; import static io.holunda.camunda.bpm.data.CamundaBpmData.mapVariable; import static io.holunda.camunda.bpm.data.CamundaBpmData.setVariable; import static io.holunda.camunda.bpm.data.CamundaBpmData.stringVariable; +import static io.holunda.camunda.bpm.data.CamundaBpmData.uuidVariable; import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -24,12 +26,14 @@ public class LockedExternalTaskReaderTest { - private static final VariableFactory STRING = stringVariable("myString"); - private static final VariableFactory> LIST = listVariable("myList", String.class); - private static final VariableFactory> SET = setVariable("mySet", String.class); - private static final VariableFactory> MAP = mapVariable("myMap", String.class, String.class); + private static final VariableFactory STRING_VAR = stringVariable("myString"); + private static final VariableFactory UUID_VAR = uuidVariable("myUuid"); + private static final VariableFactory> LIST_VAR = listVariable("myList", String.class); + private static final VariableFactory> SET_VAR = setVariable("mySet", String.class); + private static final VariableFactory> MAP_VAR = mapVariable("myMap", String.class, String.class); private final String stringValue = "value"; + private final UUID uuidValue = UUID.randomUUID(); private final List listValue = asList("foo", "bar"); private final Set setValue = asHashSet("foo", "bar"); private final Map mapValue = Map.of("a", "b", "c", "d"); @@ -42,66 +46,71 @@ public class LockedExternalTaskReaderTest { public void setUp() { when(externalTask.getVariables()).thenReturn( Variables - .putValue(STRING.getName(), stringValue) - .putValue(LIST.getName(), listValue) - .putValue(SET.getName(), setValue) - .putValue(MAP.getName(), mapValue) + .putValue(STRING_VAR.getName(), stringValue) + .putValue(LIST_VAR.getName(), listValue) + .putValue(SET_VAR.getName(), setValue) + .putValue(MAP_VAR.getName(), mapValue) + .putValue(UUID_VAR.getName(), uuidValue) ); } @Test public void shouldDelegateGet() { - assertThat(reader.get(STRING)).isEqualTo(stringValue); - assertThat(reader.get(LIST)).isEqualTo(listValue); - assertThat(reader.get(SET)).isEqualTo(setValue); - assertThat(reader.get(MAP)).isEqualTo(mapValue); + assertThat(reader.get(STRING_VAR)).isEqualTo(stringValue); + assertThat(reader.get(LIST_VAR)).isEqualTo(listValue); + assertThat(reader.get(SET_VAR)).isEqualTo(setValue); + assertThat(reader.get(MAP_VAR)).isEqualTo(mapValue); + assertThat(reader.get(UUID_VAR)).isEqualTo(uuidValue); + assertThat(reader.get(UUID_VAR)).isInstanceOf(UUID.class); } @Test public void shouldDelegateGetOptional() { - assertThat(reader.getOptional(STRING)).hasValue(stringValue); - assertThat(reader.getOptional(LIST)).hasValue(listValue); - assertThat(reader.getOptional(SET)).hasValue(setValue); - assertThat(reader.getOptional(MAP)).hasValue(mapValue); + assertThat(reader.getOptional(STRING_VAR)).hasValue(stringValue); + assertThat(reader.getOptional(LIST_VAR)).hasValue(listValue); + assertThat(reader.getOptional(SET_VAR)).hasValue(setValue); + assertThat(reader.getOptional(MAP_VAR)).hasValue(mapValue); + assertThat(reader.getOptional(UUID_VAR)).hasValue(uuidValue); assertThat(reader.getOptional(stringVariable("xxx"))).isEmpty(); } @Test public void shouldDelegateGetLocalOptional() { - assertThatThrownBy(() -> reader.getLocalOptional(STRING)) + assertThatThrownBy(() -> reader.getLocalOptional(STRING_VAR)) .isInstanceOf(UnsupportedOperationException.class) .hasMessage("Can't get a local variable on an external task"); } @Test public void shouldDelegateGetLocal() { - assertThatThrownBy(() -> reader.getLocal(STRING)) + assertThatThrownBy(() -> reader.getLocal(STRING_VAR)) .isInstanceOf(UnsupportedOperationException.class) .hasMessage("Can't get a local variable on an external task"); } @Test public void shouldDelegateGetOrNull() { - assertThat(reader.getOrNull(STRING)).isEqualTo(stringValue); - assertThat(reader.getOrNull(LIST)).isEqualTo(listValue); - assertThat(reader.getOrNull(SET)).isEqualTo(setValue); - assertThat(reader.getOrNull(MAP)).isEqualTo(mapValue); + assertThat(reader.getOrNull(STRING_VAR)).isEqualTo(stringValue); + assertThat(reader.getOrNull(LIST_VAR)).isEqualTo(listValue); + assertThat(reader.getOrNull(SET_VAR)).isEqualTo(setValue); + assertThat(reader.getOrNull(MAP_VAR)).isEqualTo(mapValue); + assertThat(reader.getOrNull(UUID_VAR)).isEqualTo(uuidValue); assertThat(reader.getOrNull(stringVariable("xxx"))).isNull(); } @Test public void shouldDelegateGetLocalOrNull() { - assertThatThrownBy(() -> reader.getLocalOrNull(STRING)) + assertThatThrownBy(() -> reader.getLocalOrNull(STRING_VAR)) .isInstanceOf(UnsupportedOperationException.class) .hasMessage("Can't get a local variable on an external task"); } @Test public void shouldDelegateGetOrDefault() { - assertThat(reader.getOrDefault(STRING, "default")).isEqualTo(stringValue); - assertThat(reader.getOrDefault(LIST, asList("a", "b"))).isEqualTo(listValue); - assertThat(reader.getOrDefault(SET, asHashSet("a", "b"))).isEqualTo(setValue); - assertThat(reader.getOrDefault(MAP, Map.of("a", "b", "c", "d"))).isEqualTo(mapValue); + assertThat(reader.getOrDefault(STRING_VAR, "default")).isEqualTo(stringValue); + assertThat(reader.getOrDefault(LIST_VAR, asList("a", "b"))).isEqualTo(listValue); + assertThat(reader.getOrDefault(SET_VAR, asHashSet("a", "b"))).isEqualTo(setValue); + assertThat(reader.getOrDefault(MAP_VAR, Map.of("a", "b", "c", "d"))).isEqualTo(mapValue); assertThat(reader.getOrDefault(stringVariable("xxx"), "default")).isEqualTo("default"); assertThat(reader.getOrDefault(listVariable("xxx", String.class), asList("a", "b"))).isEqualTo(asList("a", "b")); @@ -111,7 +120,7 @@ public void shouldDelegateGetOrDefault() { @Test public void shouldDelegateGetLocalOrDefault() { - assertThatThrownBy(() -> reader.getLocalOrDefault(STRING, stringValue)) + assertThatThrownBy(() -> reader.getLocalOrDefault(STRING_VAR, stringValue)) .isInstanceOf(UnsupportedOperationException.class) .hasMessage("Can't get a local variable on an external task"); } diff --git a/extension/core/src/test/kotlin/io/holunda/camunda/bpm/data/adapter/basic/ReadAdapterLockedExternalTaskTest.kt b/extension/core/src/test/kotlin/io/holunda/camunda/bpm/data/adapter/basic/ReadAdapterLockedExternalTaskTest.kt new file mode 100644 index 00000000..7fa3a259 --- /dev/null +++ b/extension/core/src/test/kotlin/io/holunda/camunda/bpm/data/adapter/basic/ReadAdapterLockedExternalTaskTest.kt @@ -0,0 +1,97 @@ +package io.holunda.camunda.bpm.data.adapter.basic + +import io.holunda.camunda.bpm.data.CamundaBpmData +import org.assertj.core.api.Assertions.assertThat +import org.camunda.bpm.engine.externaltask.LockedExternalTask +import org.camunda.bpm.engine.variable.VariableMap +import org.junit.Test +import java.util.* + +class ReadAdapterLockedExternalTaskTest { + + private val uuidVar = CamundaBpmData.uuidVariable("uuidVar") + + @Test + fun `get UUID type from variableMap directly`() { + val map = CamundaBpmData.builder() + .set(uuidVar, UUID.randomUUID()) + .build() + + assertThat(uuidVar.from(map).get()).isInstanceOf(UUID::class.java) + } + + @Test + fun `get UUID type from ExternalTask`() { + val variables = CamundaBpmData.builder() + .set(uuidVar, UUID.randomUUID()) + .build() + + val task = LockedExternalTaskFake( + id = UUID.randomUUID().toString(), + variables = variables + ) + + assertThat(task.variables).isSameAs(variables) + assertThat(uuidVar.from(task).get()).isInstanceOf(UUID::class.java) + } +} + +data class LockedExternalTaskFake( + private var id: String? = null, + private var topicName: String? = null, + private var workerId: String? = null, + private var lockExpirationTime: Date? = null, + private var processInstanceId: String? = null, + private var executionId: String? = null, + private var activityId: String? = null, + private var activityInstanceId: String? = null, + private var processDefinitionId: String? = null, + private var processDefinitionKey: String? = null, + private var processDefinitionVersionTag: String? = null, + private var retries: Int? = null, + private var errorMessage: String? = null, + private var errorDetails: String? = null, + private var variables: VariableMap? = null, + private var tenantId: String? = null, + private var priority: Long = 0, + private var businessKey: String? = null, + private var extensionProperties: Map? = null, +) : LockedExternalTask { + override fun getId() = id + + override fun getTopicName() = topicName + + override fun getWorkerId() = workerId + + override fun getLockExpirationTime() = lockExpirationTime + + override fun getProcessInstanceId() = processInstanceId + + override fun getExecutionId() = executionId + + override fun getActivityId() = activityId + + override fun getActivityInstanceId() = activityInstanceId + + override fun getProcessDefinitionId() = processDefinitionId + + override fun getProcessDefinitionKey() = processDefinitionKey + + override fun getProcessDefinitionVersionTag() = processDefinitionVersionTag + + override fun getRetries() = retries + + override fun getErrorMessage() = errorMessage + + override fun getErrorDetails() = errorDetails + + override fun getVariables() = variables + + override fun getTenantId() = tenantId + + override fun getPriority() = priority + + override fun getBusinessKey() = businessKey + + override fun getExtensionProperties() = extensionProperties +} diff --git a/extension/test/pom.xml b/extension/test/pom.xml index e25af5f0..ab339c32 100644 --- a/extension/test/pom.xml +++ b/extension/test/pom.xml @@ -6,7 +6,7 @@ io.holunda.data camunda-bpm-data-parent - 1.2.6 + 1.2.7 ../../pom.xml diff --git a/pom.xml b/pom.xml index faaf037f..22ff71e0 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ io.holunda.data camunda-bpm-data-parent - 1.2.6 + 1.2.7 ${project.artifactId} Camunda BPM Data https://github.com/holunda-io/camunda-bpm-data/ @@ -21,16 +21,16 @@ 7.16.0 7.16.2-ee - 2.6.6 + 2.6.7 2.4.21 - 1.14.0 - 14.0.0 + 1.16.0 + 15.0.0 - 1.6.20 - 1.2.0 + 1.7.0 + 1.2.2 true - 2.1.21 + 2.1.23 4.0.0 5.16.0 4.4.0 @@ -331,7 +331,7 @@ org.jetbrains.dokka dokka-maven-plugin - 1.6.10 + 1.6.21 attach-javadocs @@ -459,7 +459,7 @@ org.sonatype.plugins nexus-staging-maven-plugin - 1.6.12 + 1.6.13 default-deploy @@ -488,7 +488,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 3.0.0 + 3.1.0 enforce-maven