diff --git a/.github/workflows/ci-pipeline.yml b/.github/workflows/ci-pipeline.yml index 4d5bf1b..1e7208c 100644 --- a/.github/workflows/ci-pipeline.yml +++ b/.github/workflows/ci-pipeline.yml @@ -26,7 +26,7 @@ jobs: - name: Set up Java environment uses: actions/setup-java@v1 with: - java-version: 11 + java-version: 17 gpg-private-key: ${{ secrets.MAVEN_CENTRAL_GPG_SIGNING_KEY_SEC }} gpg-passphrase: MAVEN_CENTRAL_GPG_PASSPHRASE - name: Build diff --git a/.mvn/jvm.config b/.mvn/jvm.config new file mode 100644 index 0000000..61a567f --- /dev/null +++ b/.mvn/jvm.config @@ -0,0 +1,5 @@ +--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED +--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED diff --git a/eze/pom.xml b/eze/pom.xml index 7e4a558..8a757dd 100644 --- a/eze/pom.xml +++ b/eze/pom.xml @@ -1,5 +1,7 @@ - + 4.0.0 eze @@ -23,6 +25,11 @@ zeebe-workflow-engine + + io.camunda + zeebe-db + + io.camunda zeebe-util @@ -195,10 +202,10 @@ org.jetbrains.kotlin kotlin-stdlib - - - - + + + + org.jetbrains.kotlin kotlin-reflect diff --git a/eze/src/main/kotlin/org/camunda/community/eze/db/EzeDbColumnFamily.kt b/eze/src/main/kotlin/org/camunda/community/eze/db/EzeDbColumnFamily.kt index 95af106..7600095 100644 --- a/eze/src/main/kotlin/org/camunda/community/eze/db/EzeDbColumnFamily.kt +++ b/eze/src/main/kotlin/org/camunda/community/eze/db/EzeDbColumnFamily.kt @@ -37,7 +37,25 @@ class EzeDbColumnFamily, } } - override fun put(key: KeyType, value: ValueType) { + override fun insert(key: KeyType, value: ValueType) { + if (exists(key)) { + throw IllegalStateException("An entry with the key $key already exists.") + } + put(key, value) + } + + override fun update(key: KeyType, value: ValueType) { + if (!exists(key)) { + throw IllegalStateException("An entry with the key $key doesn't exist.") + } + put(key, value) + } + + override fun upsert(key: KeyType, value: ValueType) { + put(key, value) + } + + private fun put(key: KeyType, value: ValueType) { ensureInOpenTransaction( context ) { transaction -> @@ -53,6 +71,7 @@ class EzeDbColumnFamily, } } + override fun get(key: KeyType): ValueType? { columnFamilyContext.writeKey(key) val valueBuffer: DirectBuffer? = getValue(context, columnFamilyContext) @@ -103,7 +122,18 @@ class EzeDbColumnFamily, whileEqualPrefix(context, keyPrefix, visitor) } - override fun delete(key: KeyType) { + override fun deleteExisting(key: KeyType) { + if (!exists(key)) { + throw IllegalStateException("An entry with the key $key doesn't exist.") + } + delete(key) + } + + override fun deleteIfExists(key: KeyType) { + delete(key) + } + + private fun delete(key: KeyType) { columnFamilyContext.writeKey(key) ensureInOpenTransaction( context diff --git a/eze/src/test/kotlin/org/camunda/community/eze/db/ColumnFamilyTest.java b/eze/src/test/kotlin/org/camunda/community/eze/db/ColumnFamilyTest.java index e6f1f14..2f4878d 100644 --- a/eze/src/test/kotlin/org/camunda/community/eze/db/ColumnFamilyTest.java +++ b/eze/src/test/kotlin/org/camunda/community/eze/db/ColumnFamilyTest.java @@ -8,6 +8,8 @@ package org.camunda.community.eze.db; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import io.camunda.zeebe.db.ColumnFamily; import io.camunda.zeebe.db.ZeebeDb; @@ -45,13 +47,13 @@ public void setup() throws Exception { } @Test - public void shouldPutValue() { + public void shouldInsertValue() { // given key.wrapLong(1213); value.wrapLong(255); // when - columnFamily.put(key, value); + columnFamily.insert(key, value); value.wrapLong(221); // then @@ -64,6 +66,81 @@ public void shouldPutValue() { assertThat(value.getValue()).isEqualTo(255); } + @Test + public void shouldNotInsertIfExist() { + // given + key.wrapLong(1); + value.wrapLong(10); + + columnFamily.insert(key, value); + + // when/then + assertThatThrownBy(() -> columnFamily.insert(key, value)) + .isInstanceOf(IllegalStateException.class); + } + + @Test + public void shouldUpdateValue() { + // given + key.wrapLong(1213); + value.wrapLong(255); + columnFamily.insert(key, value); + + // when + value.wrapLong(256); + columnFamily.update(key, value); + + // then + final DbLong zbLong = columnFamily.get(key); + + assertThat(zbLong).isNotNull(); + assertThat(zbLong.getValue()).isEqualTo(256); + } + + @Test + public void shouldNotUpdateIfNotExist() { + // given + key.wrapLong(1); + value.wrapLong(10); + + // when/then + assertThatThrownBy(() -> columnFamily.update(key, value)) + .isInstanceOf(IllegalStateException.class); + } + + @Test + public void shouldUpsertIfExist() { + // given + key.wrapLong(1); + value.wrapLong(10); + + columnFamily.insert(key, value); + + // when + value.wrapLong(11); + columnFamily.upsert(key, value); + + // then + final var persistedValue = columnFamily.get(key); + + assertThat(persistedValue.getValue()).isEqualTo(11); + } + + @Test + public void shouldUpsertIfNotExist() { + // given + key.wrapLong(1); + value.wrapLong(10); + + // when + columnFamily.upsert(key, value); + + // then + final var persistedValue = columnFamily.get(key); + + assertThat(persistedValue.getValue()).isEqualTo(10); + } + @Test public void shouldReturnNullIfNotExist() { // given @@ -149,12 +226,12 @@ public void shouldNotExist() { } @Test - public void shouldDelete() { + public void shouldDeleteExisting() { // given putKeyValuePair(1213, 255); // when - columnFamily.delete(key); + columnFamily.deleteExisting(key); // then final boolean exists = columnFamily.exists(key); @@ -164,6 +241,44 @@ public void shouldDelete() { assertThat(zbLong).isNull(); } + @Test + public void shouldNotDeleteExistingIfNotExist() { + // given + key.wrapLong(1); + value.wrapLong(10); + + // when/then + assertThatThrownBy(() -> columnFamily.deleteExisting(key)) + .isInstanceOf(IllegalStateException.class); + } + + @Test + public void shouldDeleteIfExists() { + // given + key.wrapLong(1); + value.wrapLong(10); + + columnFamily.insert(key, value); + + // when + columnFamily.deleteIfExists(key); + + // then + final var persistedValue = columnFamily.get(key); + + assertThat(persistedValue).isNull(); + } + + @Test + public void shouldIgnoreDeleteIfNotExist() { + // given + key.wrapLong(1); + value.wrapLong(10); + + // when/then + assertThatCode(() -> columnFamily.deleteIfExists(key)).doesNotThrowAnyException(); + } + @Test public void shouldNotDeleteDifferentKey() { // given @@ -171,7 +286,7 @@ public void shouldNotDeleteDifferentKey() { // when key.wrapLong(700); - columnFamily.delete(key); + columnFamily.deleteIfExists(key); // then key.wrapLong(1213); @@ -235,7 +350,7 @@ public void shouldDeleteOnForeachPair() { // when columnFamily.forEach( (key, value) -> { - columnFamily.delete(key); + columnFamily.deleteIfExists(key); }); final List keys = new ArrayList<>(); @@ -302,7 +417,7 @@ public void shouldDeleteWhileTrue() { // when columnFamily.whileTrue( (key, value) -> { - columnFamily.delete(key); + columnFamily.deleteIfExists(key); return key.getValue() != 4567; }); @@ -326,13 +441,13 @@ public void shouldCheckIfEmpty() { putKeyValuePair(1, 10); assertThat(columnFamily.isEmpty()).isFalse(); - columnFamily.delete(key); + columnFamily.deleteIfExists(key); assertThat(columnFamily.isEmpty()).isTrue(); } private void putKeyValuePair(final int key, final int value) { this.key.wrapLong(key); this.value.wrapLong(value); - columnFamily.put(this.key, this.value); + columnFamily.upsert(this.key, this.value); } } diff --git a/eze/src/test/kotlin/org/camunda/community/eze/db/DbStringColumnFamilyTest.java b/eze/src/test/kotlin/org/camunda/community/eze/db/DbStringColumnFamilyTest.java index ea28187..d1ed188 100644 --- a/eze/src/test/kotlin/org/camunda/community/eze/db/DbStringColumnFamilyTest.java +++ b/eze/src/test/kotlin/org/camunda/community/eze/db/DbStringColumnFamilyTest.java @@ -46,13 +46,13 @@ public void setup() throws Exception { } @Test - public void shouldPutValue() { + public void shouldInsertValue() { // given key.wrapString("foo"); value.wrapString("baring"); // when - columnFamily.put(key, value); + columnFamily.insert(key, value); value.wrapString("yes"); // then @@ -230,6 +230,6 @@ public void shouldThrowExceptionOnMultipleNestedWhileEqualPrefix() { private void putKeyValuePair(final String key, final String value) { this.key.wrapString(key); this.value.wrapString(value); - columnFamily.put(this.key, this.value); + columnFamily.upsert(this.key, this.value); } } diff --git a/eze/src/test/kotlin/org/camunda/community/eze/db/DbTransactionTest.java b/eze/src/test/kotlin/org/camunda/community/eze/db/DbTransactionTest.java index 4d89d76..f721d2a 100644 --- a/eze/src/test/kotlin/org/camunda/community/eze/db/DbTransactionTest.java +++ b/eze/src/test/kotlin/org/camunda/community/eze/db/DbTransactionTest.java @@ -79,9 +79,9 @@ public void shouldUseTransaction() { // when transactionContext.runInTransaction( () -> { - oneColumnFamily.put(oneKey, oneValue); - twoColumnFamily.put(twoKey, twoValue); - threeColumnFamily.put(threeKey, threeValue); + oneColumnFamily.upsert(oneKey, oneValue); + twoColumnFamily.upsert(twoKey, twoValue); + threeColumnFamily.upsert(threeKey, threeValue); }); // then @@ -98,7 +98,7 @@ public void shouldNotGetPreviousValue() { transactionContext.runInTransaction( () -> { - oneColumnFamily.put(oneKey, oneValue); + oneColumnFamily.upsert(oneKey, oneValue); oneColumnFamily.get(oneKey); oneKey.wrapLong(-1); @@ -125,9 +125,9 @@ public void shouldStartNewTransaction() throws Exception { final ZeebeDbTransaction transaction = transactionContext.getCurrentTransaction(); transaction.run( () -> { - oneColumnFamily.put(oneKey, oneValue); - twoColumnFamily.put(twoKey, twoValue); - threeColumnFamily.put(threeKey, threeValue); + oneColumnFamily.upsert(oneKey, oneValue); + twoColumnFamily.upsert(twoKey, twoValue); + threeColumnFamily.upsert(threeKey, threeValue); }); // when @@ -154,9 +154,9 @@ public void shouldAccessOnOpenTransaction() throws Exception { final ZeebeDbTransaction transaction = transactionContext.getCurrentTransaction(); transaction.run( () -> { - oneColumnFamily.put(oneKey, oneValue); - twoColumnFamily.put(twoKey, twoValue); - threeColumnFamily.put(threeKey, threeValue); + oneColumnFamily.upsert(oneKey, oneValue); + twoColumnFamily.upsert(twoKey, twoValue); + threeColumnFamily.upsert(threeKey, threeValue); }); // when @@ -204,15 +204,15 @@ public void shouldNotReopenTransactionWithOperations() { final ZeebeDbTransaction sameTransaction = transactionContext.getCurrentTransaction(); sameTransaction.run( () -> { - oneColumnFamily.put(oneKey, oneValue); - twoColumnFamily.put(twoKey, twoValue); - threeColumnFamily.put(threeKey, threeValue); + oneColumnFamily.upsert(oneKey, oneValue); + twoColumnFamily.upsert(twoKey, twoValue); + threeColumnFamily.upsert(threeKey, threeValue); }); sameTransaction.commit(); // then it is committed but available in this transaction assertThat(oneColumnFamily.exists(oneKey)).isTrue(); - oneColumnFamily.delete(oneKey); + oneColumnFamily.deleteIfExists(oneKey); assertThat(twoColumnFamily.exists(twoKey)).isTrue(); assertThat(threeColumnFamily.exists(threeKey)).isTrue(); @@ -239,9 +239,9 @@ public void shouldRollbackTransaction() throws Exception { final ZeebeDbTransaction transaction = transactionContext.getCurrentTransaction(); transaction.run( () -> { - oneColumnFamily.put(oneKey, oneValue); - twoColumnFamily.put(twoKey, twoValue); - threeColumnFamily.put(threeKey, threeValue); + oneColumnFamily.upsert(oneKey, oneValue); + twoColumnFamily.upsert(twoKey, twoValue); + threeColumnFamily.upsert(threeKey, threeValue); }); // when @@ -263,7 +263,7 @@ public void shouldGetValueInTransaction() { // when transactionContext.runInTransaction( () -> { - oneColumnFamily.put(oneKey, oneValue); + oneColumnFamily.upsert(oneKey, oneValue); final DbLong value = oneColumnFamily.get(oneKey); actualValue.set(value.getValue()); }); @@ -279,7 +279,7 @@ public void shouldFindValueInTransaction() { final Map actualValues = new HashMap<>(); oneKey.wrapLong(1); oneValue.wrapLong(-1); - oneColumnFamily.put(oneKey, oneValue); + oneColumnFamily.upsert(oneKey, oneValue); // when transactionContext.runInTransaction( @@ -287,12 +287,12 @@ public void shouldFindValueInTransaction() { // update value oneKey.wrapLong(1); oneValue.wrapLong(-2); - oneColumnFamily.put(oneKey, oneValue); + oneColumnFamily.upsert(oneKey, oneValue); // create new key-value pair oneKey.wrapLong(2); oneValue.wrapLong(-3); - oneColumnFamily.put(oneKey, oneValue); + oneColumnFamily.upsert(oneKey, oneValue); actualValues.put(oneKey.getValue(), oneColumnFamily.get(oneKey).getValue()); oneKey.wrapLong(1); @@ -313,11 +313,11 @@ public void shouldIterateAndFindValuesInTransaction() { oneKey.wrapLong(1); oneValue.wrapLong(-1); - oneColumnFamily.put(oneKey, oneValue); + oneColumnFamily.upsert(oneKey, oneValue); oneKey.wrapLong(2); oneValue.wrapLong(-2); - oneColumnFamily.put(oneKey, oneValue); + oneColumnFamily.upsert(oneKey, oneValue); // when transactionContext.runInTransaction( @@ -325,12 +325,12 @@ public void shouldIterateAndFindValuesInTransaction() { // update old value oneKey.wrapLong(2); oneValue.wrapLong(-5); - oneColumnFamily.put(oneKey, oneValue); + oneColumnFamily.upsert(oneKey, oneValue); // create new key-value pair oneKey.wrapLong(3); oneValue.wrapLong(-3); - oneColumnFamily.put(oneKey, oneValue); + oneColumnFamily.upsert(oneKey, oneValue); oneColumnFamily.forEach((k, v) -> actualValues.put(k.getValue(), v.getValue())); }); @@ -348,15 +348,15 @@ public void shouldIterateAndDeleteInTransaction() { // given oneKey.wrapLong(1); oneValue.wrapLong(-1); - oneColumnFamily.put(oneKey, oneValue); + oneColumnFamily.upsert(oneKey, oneValue); oneKey.wrapLong(2); oneValue.wrapLong(-2); - oneColumnFamily.put(oneKey, oneValue); + oneColumnFamily.upsert(oneKey, oneValue); // when transactionContext.runInTransaction( - () -> oneColumnFamily.forEach((k, v) -> oneColumnFamily.delete(k))); + () -> oneColumnFamily.forEach((k, v) -> oneColumnFamily.deleteIfExists(k))); // then assertThat(oneColumnFamily.exists(oneKey)).isFalse(); @@ -370,15 +370,15 @@ public void shouldEndInSameTransaction() { final AtomicLong actualValue = new AtomicLong(0); oneKey.wrapLong(1); oneValue.wrapLong(-1); - oneColumnFamily.put(oneKey, oneValue); + oneColumnFamily.upsert(oneKey, oneValue); twoValue.wrapLong(192313); // when - oneColumnFamily.put(oneKey, oneValue); + oneColumnFamily.upsert(oneKey, oneValue); transactionContext.runInTransaction( () -> { - transactionContext.runInTransaction(() -> oneColumnFamily.put(oneKey, twoValue)); + transactionContext.runInTransaction(() -> oneColumnFamily.upsert(oneKey, twoValue)); final DbLong value = oneColumnFamily.get(oneKey); actualValue.set(value.getValue()); }); @@ -396,24 +396,24 @@ public void shouldWriteAndDeleteInTransaction() { twoKey.wrapLong(52000); twoValue.wrapLong(192313); - twoColumnFamily.put(twoKey, twoValue); + twoColumnFamily.upsert(twoKey, twoValue); threeKey.wrapLong(Short.MAX_VALUE); threeValue.wrapLong(Integer.MAX_VALUE); - threeColumnFamily.put(threeKey, threeValue); + threeColumnFamily.upsert(threeKey, threeValue); // when transactionContext.runInTransaction( () -> { // create - oneColumnFamily.put(oneKey, oneValue); + oneColumnFamily.upsert(oneKey, oneValue); // delete - twoColumnFamily.delete(twoKey); + twoColumnFamily.deleteIfExists(twoKey); // update threeValue.wrapLong(Integer.MIN_VALUE); - threeColumnFamily.put(threeKey, threeValue); + threeColumnFamily.upsert(threeKey, threeValue); }); // then @@ -436,10 +436,10 @@ public void shouldWriteAndDeleteSameKeyValuePairInTransaction() { transactionContext.runInTransaction( () -> { // create - oneColumnFamily.put(oneKey, oneValue); + oneColumnFamily.upsert(oneKey, oneValue); // delete - oneColumnFamily.delete(oneKey); + oneColumnFamily.deleteIfExists(oneKey); }); // then @@ -454,7 +454,7 @@ public void shouldNotCommitOnError() { twoKey.wrapLong(52000); twoValue.wrapLong(192313); - twoColumnFamily.put(twoKey, twoValue); + twoColumnFamily.upsert(twoKey, twoValue); threeKey.wrapLong(Short.MAX_VALUE); threeValue.wrapLong(Integer.MAX_VALUE); @@ -464,9 +464,9 @@ public void shouldNotCommitOnError() { try { transactionContext.runInTransaction( () -> { - oneColumnFamily.put(oneKey, oneValue); - twoColumnFamily.delete(twoKey); - threeColumnFamily.put(threeKey, threeValue); + oneColumnFamily.upsert(oneKey, oneValue); + twoColumnFamily.deleteIfExists(twoKey); + threeColumnFamily.upsert(threeKey, threeValue); throw new RuntimeException(); }); } catch (final Exception e) { @@ -484,15 +484,15 @@ public void shouldWriteKeyAfterDeletion() { // given oneKey.wrapLong(1); oneValue.wrapLong(-1); - oneColumnFamily.put(oneKey, oneValue); + oneColumnFamily.upsert(oneKey, oneValue); // when assertThat(oneColumnFamily.get(oneKey).getValue()).isEqualTo(-1); transactionContext.runInTransaction( () -> { - oneColumnFamily.delete(oneKey); + oneColumnFamily.deleteIfExists(oneKey); oneValue.wrapLong(-2); - oneColumnFamily.put(oneKey, oneValue); + oneColumnFamily.upsert(oneKey, oneValue); }); // then diff --git a/pom.xml b/pom.xml index 298f7f0..f6ed0ca 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,7 @@ - + 4.0.0 eze-root @@ -11,7 +13,7 @@ org.camunda.community community-hub-release-parent 1.2.2 - + @@ -40,11 +42,11 @@ licenses/COPYING-HEADER.txt UTF-8 - 11 + 17 3.0 1.6.21 - 1.3.6 + 8.0.2 4.1.77.Final 5.8.2 @@ -81,6 +83,36 @@ pom + + io.camunda + zeebe-workflow-engine + ${zeebe.version} + + + + io.camunda + zeebe-util + ${zeebe.version} + + + + io.camunda + zeebe-logstreams + ${zeebe.version} + + + + io.camunda + zeebe-test-util + ${zeebe.version} + + + + io.camunda + zeebe-db + ${zeebe.version} + + io.netty netty-bom @@ -257,6 +289,26 @@ agrona ${agrona.version} + + + + org.camunda.feel + feel-engine + 1.14.2 + + + + org.apache.commons + commons-lang3 + 3.11 + + + + org.awaitility + awaitility + ${awaitility.version} + + @@ -279,7 +331,7 @@ 3.0.0 - +