From a0beac65f101dc93babb8238addc81b199cd5171 Mon Sep 17 00:00:00 2001 From: Andrey G Date: Thu, 28 Nov 2024 12:54:44 +0200 Subject: [PATCH] FMWK-338 Limit lower Server version to 6.1 (#793) --- .../aerospike/convert/AerospikeConverter.java | 2 +- .../convert/AerospikeTypeAliasAccessor.java | 4 +- .../aerospike/core/AerospikeTemplate.java | 12 +- .../aerospike/core/BaseAerospikeTemplate.java | 8 +- .../core/ReactiveAerospikeTemplate.java | 14 +- .../query/AerospikeQueryCreatorUtils.java | 4 +- .../server/version/ServerVersionSupport.java | 27 +- ...activeBlockingAerospikeTestOperations.java | 20 +- .../MappingAerospikeConverterTypesTests.java | 143 +++---- ...veAerospikeTemplateDeleteRelatedTests.java | 391 ++++++++---------- .../ReactiveAerospikeTemplateInsertTests.java | 92 ++--- ...tiveAerospikeTemplateSaveRelatedTests.java | 76 ++-- .../ReactiveAerospikeTemplateUpdateTests.java | 103 +++-- .../sync/AerospikeTemplateDeleteTests.java | 294 ++++++------- .../sync/AerospikeTemplateFindAllTests.java | 7 +- ...ikeTemplateFindByQueryProjectionTests.java | 23 +- .../AerospikeTemplateFindByQueryTests.java | 23 +- .../sync/AerospikeTemplateInsertTests.java | 96 ++--- .../core/sync/AerospikeTemplateSaveTests.java | 51 +-- ...ospikeTemplateSaveWithDuplicatesTests.java | 62 ++- .../sync/AerospikeTemplateUpdateTests.java | 254 ++++++------ .../query/blocking/delete/EqualsTests.java | 7 +- .../AdditionalAerospikeTestOperations.java | 37 +- 23 files changed, 768 insertions(+), 982 deletions(-) diff --git a/src/main/java/org/springframework/data/aerospike/convert/AerospikeConverter.java b/src/main/java/org/springframework/data/aerospike/convert/AerospikeConverter.java index e88a9b751..7d366ac3d 100644 --- a/src/main/java/org/springframework/data/aerospike/convert/AerospikeConverter.java +++ b/src/main/java/org/springframework/data/aerospike/convert/AerospikeConverter.java @@ -29,7 +29,7 @@ public interface AerospikeConverter extends AerospikeReader, AerospikeWr /** * Key that identifies POJO's class. */ - String CLASS_KEY = "@_class"; + String CLASS_KEY_DEFAULT = "@_class"; /** * Access Aerospike-specific conversion service. diff --git a/src/main/java/org/springframework/data/aerospike/convert/AerospikeTypeAliasAccessor.java b/src/main/java/org/springframework/data/aerospike/convert/AerospikeTypeAliasAccessor.java index 3e7ad0a5f..f0500771c 100644 --- a/src/main/java/org/springframework/data/aerospike/convert/AerospikeTypeAliasAccessor.java +++ b/src/main/java/org/springframework/data/aerospike/convert/AerospikeTypeAliasAccessor.java @@ -20,7 +20,7 @@ import java.util.Map; -import static org.springframework.data.aerospike.convert.AerospikeConverter.CLASS_KEY; +import static org.springframework.data.aerospike.convert.AerospikeConverter.CLASS_KEY_DEFAULT; public class AerospikeTypeAliasAccessor implements TypeAliasAccessor> { @@ -31,7 +31,7 @@ public AerospikeTypeAliasAccessor(String classKey) { } public AerospikeTypeAliasAccessor() { - this.classKey = CLASS_KEY; + this.classKey = CLASS_KEY_DEFAULT; } @Override diff --git a/src/main/java/org/springframework/data/aerospike/core/AerospikeTemplate.java b/src/main/java/org/springframework/data/aerospike/core/AerospikeTemplate.java index 647728978..c585e8dd6 100644 --- a/src/main/java/org/springframework/data/aerospike/core/AerospikeTemplate.java +++ b/src/main/java/org/springframework/data/aerospike/core/AerospikeTemplate.java @@ -462,11 +462,7 @@ public void delete(Query query, Class entityClass, String setName) { List findQueryResults = find(query, entityClass, setName).filter(Objects::nonNull).toList(); if (!findQueryResults.isEmpty()) { - if (serverVersionSupport.isBatchWriteSupported()) { - deleteAll(findQueryResults); - } else { - findQueryResults.forEach(this::delete); - } + deleteAll(findQueryResults); } } @@ -492,11 +488,7 @@ public void deleteByIdsUsingQuery(Collection ids, Class entityClass, S .collect(Collectors.toUnmodifiableList()); if (!findQueryResults.isEmpty()) { - if (serverVersionSupport.isBatchWriteSupported()) { - deleteAll(findQueryResults); - } else { - findQueryResults.forEach(this::delete); - } + deleteAll(findQueryResults); } } diff --git a/src/main/java/org/springframework/data/aerospike/core/BaseAerospikeTemplate.java b/src/main/java/org/springframework/data/aerospike/core/BaseAerospikeTemplate.java index 27a5f5485..8e55774f9 100644 --- a/src/main/java/org/springframework/data/aerospike/core/BaseAerospikeTemplate.java +++ b/src/main/java/org/springframework/data/aerospike/core/BaseAerospikeTemplate.java @@ -423,7 +423,7 @@ protected Operation[] getPutAndGetHeaderOperations(AerospikeWriteData data, bool if (bins.length == 0) { throw new AerospikeException( - "Cannot put and get header on a document with no bins and \"@_class\" bin disabled."); + "Cannot put and get header on a document with no bins and class bin disabled."); } return operations(bins, Operation::put, firstlyDeleteBins ? Operation.array(Operation.delete()) : null, @@ -524,8 +524,6 @@ protected void validateGroupedKeys(GroupedKeys groupedKeys) { protected void validateForBatchWrite(Object object, String objectName) { Assert.notNull(object, objectName + " must not be null!"); - Assert.isTrue(batchWriteSupported(), "Batch write operations are supported starting with " + - "server version " + TemplateUtils.SERVER_VERSION_6); } protected boolean batchWriteSizeMatch(int batchSize, int currentSize) { @@ -536,10 +534,6 @@ protected boolean batchRecordFailed(BatchRecord batchRecord) { return batchRecord.resultCode != ResultCode.OK || batchRecord.record == null; } - protected boolean batchWriteSupported() { - return serverVersionSupport.isBatchWriteSupported(); - } - protected enum OperationType { SAVE_OPERATION("save"), INSERT_OPERATION("insert"), diff --git a/src/main/java/org/springframework/data/aerospike/core/ReactiveAerospikeTemplate.java b/src/main/java/org/springframework/data/aerospike/core/ReactiveAerospikeTemplate.java index f8f342493..d8dc9a6b0 100644 --- a/src/main/java/org/springframework/data/aerospike/core/ReactiveAerospikeTemplate.java +++ b/src/main/java/org/springframework/data/aerospike/core/ReactiveAerospikeTemplate.java @@ -450,12 +450,7 @@ public Mono delete(Query query, Class entityClass, String setName) return findQueryResults.flatMap(list -> { if (!list.isEmpty()) { - if (serverVersionSupport.isBatchWriteSupported()) { - return deleteAll(list); - } else { - list.forEach(this::delete); - return Mono.empty(); - } + return deleteAll(list); } return Mono.empty(); } @@ -484,12 +479,7 @@ public Mono deleteByIdsUsingQuery(Collection ids, Class entityCl return findQueryResults.flatMap(list -> { if (!list.isEmpty()) { - if (serverVersionSupport.isBatchWriteSupported()) { - return deleteAll(list); - } else { - list.forEach(this::delete); - return Mono.empty(); - } + return deleteAll(list); } return Mono.empty(); } diff --git a/src/main/java/org/springframework/data/aerospike/repository/query/AerospikeQueryCreatorUtils.java b/src/main/java/org/springframework/data/aerospike/repository/query/AerospikeQueryCreatorUtils.java index b2d295f5a..53a36671e 100644 --- a/src/main/java/org/springframework/data/aerospike/repository/query/AerospikeQueryCreatorUtils.java +++ b/src/main/java/org/springframework/data/aerospike/repository/query/AerospikeQueryCreatorUtils.java @@ -25,7 +25,7 @@ import java.util.stream.Stream; import static java.util.function.Predicate.not; -import static org.springframework.data.aerospike.convert.AerospikeConverter.CLASS_KEY; +import static org.springframework.data.aerospike.convert.AerospikeConverter.CLASS_KEY_DEFAULT; import static org.springframework.data.aerospike.repository.query.CriteriaDefinition.AerospikeNullQueryCriterion; import static org.springframework.data.aerospike.repository.query.CriteriaDefinition.AerospikeNullQueryCriterion.NULL_PARAM; import static org.springframework.util.ClassUtils.isAssignable; @@ -283,7 +283,7 @@ protected static boolean isAssignableValueOrConverted(Class propertyType, Obj */ protected static boolean isPojoMap(Object object, Class propertyType) { if (object instanceof TreeMap treeMap) { - Object classKey = treeMap.get(CLASS_KEY); + Object classKey = treeMap.get(CLASS_KEY_DEFAULT); return classKey != null && classKey.equals(propertyType.getName()); } return false; diff --git a/src/main/java/org/springframework/data/aerospike/server/version/ServerVersionSupport.java b/src/main/java/org/springframework/data/aerospike/server/version/ServerVersionSupport.java index 936651834..db49986ca 100644 --- a/src/main/java/org/springframework/data/aerospike/server/version/ServerVersionSupport.java +++ b/src/main/java/org/springframework/data/aerospike/server/version/ServerVersionSupport.java @@ -13,8 +13,6 @@ @Slf4j public class ServerVersionSupport { - private static final ModuleDescriptor.Version SERVER_VERSION_5_7_0_0 = ModuleDescriptor.Version.parse("5.7.0.0"); - private static final ModuleDescriptor.Version SERVER_VERSION_6_0_0_0 = ModuleDescriptor.Version.parse("6.0.0.0"); private static final ModuleDescriptor.Version SERVER_VERSION_6_1_0_0 = ModuleDescriptor.Version.parse("6.1.0.0"); private static final ModuleDescriptor.Version SERVER_VERSION_6_1_0_1 = ModuleDescriptor.Version.parse("6.1.0.1"); private static final ModuleDescriptor.Version SERVER_VERSION_6_3_0_0 = ModuleDescriptor.Version.parse("6.3.0.0"); @@ -42,22 +40,18 @@ public void scheduleServerVersionRefresh(long intervalSeconds) { private String findServerVersion() { String fullVersionString = InfoCommandUtils.request(client, client.getCluster().getRandomNode(), "version"); - String versionString = fullVersionString.substring(fullVersionString.lastIndexOf(' ') + 1); + + if (ModuleDescriptor.Version.parse(versionString).compareTo(SERVER_VERSION_6_1_0_0) < 0) { + throw new UnsupportedOperationException("Minimal supported Aerospike Server version is 6.1"); + } log.debug("Found server version {}", versionString); return versionString; } - public boolean isQueryShowSupported() { - return ModuleDescriptor.Version.parse(getServerVersion()) - .compareTo(SERVER_VERSION_5_7_0_0) >= 0; - } - - public boolean isBatchWriteSupported() { - return ModuleDescriptor.Version.parse(getServerVersion()) - .compareTo(SERVER_VERSION_6_0_0_0) >= 0; - } - + /** + * @return true if Server version is 6.1 or greater + */ public boolean isSIndexCardinalitySupported() { return ModuleDescriptor.Version.parse(getServerVersion()) .compareTo(SERVER_VERSION_6_1_0_0) >= 0; @@ -66,6 +60,8 @@ public boolean isSIndexCardinalitySupported() { /** * Since Aerospike Server ver. 6.1.0.1 attempting to create a secondary index which already exists or to drop a * non-existing secondary index returns success/OK instead of an error. + * + * @return true if Server version is 6.1.0.1 or greater */ public boolean isDropCreateBehaviorUpdated() { return ModuleDescriptor.Version.parse(getServerVersion()) @@ -74,12 +70,17 @@ public boolean isDropCreateBehaviorUpdated() { /** * Since Aerospike Server ver. 6.3.0.0 find by Collection Data Types (Collection / Map / POJO) is supported. + * + * @return true if Server version is 6.3 or greater */ public boolean isFindByCDTSupported() { return ModuleDescriptor.Version.parse(getServerVersion()) .compareTo(SERVER_VERSION_6_3_0_0) >= 0; } + /** + * @return true if Server version is 7.0 or greater + */ public boolean isServerVersionGtOrEq7() { return ModuleDescriptor.Version.parse(getServerVersion()) .compareTo(SERVER_VERSION_7_0_0_0) >= 0; diff --git a/src/test/java/org/springframework/data/aerospike/ReactiveBlockingAerospikeTestOperations.java b/src/test/java/org/springframework/data/aerospike/ReactiveBlockingAerospikeTestOperations.java index 0eda40207..6cee56bca 100644 --- a/src/test/java/org/springframework/data/aerospike/ReactiveBlockingAerospikeTestOperations.java +++ b/src/test/java/org/springframework/data/aerospike/ReactiveBlockingAerospikeTestOperations.java @@ -83,24 +83,14 @@ public List saveGeneratedPersons(int count) { } public void deleteAll(ReactiveAerospikeRepository repository, Collection entities) { - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - try { - repository.deleteAll(entities).block(); - } catch (AerospikeException.BatchRecordArray ignored) { - // KEY_NOT_FOUND ResultCode causes exception if there are no entities - } - } else { - entities.forEach(entity -> repository.delete(entity).block()); + try { + repository.deleteAll(entities).block(); + } catch (AerospikeException.BatchRecordArray ignored) { + // KEY_NOT_FOUND ResultCode causes exception if there are no entities } } public void saveAll(ReactiveAerospikeRepository repository, Collection entities) { - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - repository.saveAll(entities).blockLast(); - } else { - entities.forEach(entity -> repository.save(entity).block()); - } + repository.saveAll(entities).blockLast(); } } diff --git a/src/test/java/org/springframework/data/aerospike/convert/MappingAerospikeConverterTypesTests.java b/src/test/java/org/springframework/data/aerospike/convert/MappingAerospikeConverterTypesTests.java index 81a028670..5a77974fe 100644 --- a/src/test/java/org/springframework/data/aerospike/convert/MappingAerospikeConverterTypesTests.java +++ b/src/test/java/org/springframework/data/aerospike/convert/MappingAerospikeConverterTypesTests.java @@ -25,6 +25,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.within; +import static org.springframework.data.aerospike.convert.AerospikeConverter.CLASS_KEY_DEFAULT; import static org.springframework.data.aerospike.sample.SampleClasses.SimpleClass.SIMPLESET; import static org.springframework.data.aerospike.sample.SampleClasses.SimpleClassWithPersistenceConstructor.SIMPLESET2; import static org.springframework.data.aerospike.sample.SampleClasses.User.SIMPLESET3; @@ -50,7 +51,7 @@ void primitiveShortId(int converterOption) { DocumentWithPrimitiveShortId object = new DocumentWithPrimitiveShortId((short) 5); assertWriteAndRead(converterOption, object, "DocumentWithPrimitiveShortId", (short) 5, - new Bin("@_class", DocumentWithPrimitiveShortId.class.getName()) + new Bin(CLASS_KEY_DEFAULT, DocumentWithPrimitiveShortId.class.getName()) ); } @@ -60,7 +61,7 @@ void primitiveIntId(int converterOption) { DocumentWithPrimitiveIntId object = new DocumentWithPrimitiveIntId(5); assertWriteAndRead(converterOption, object, "DocumentWithPrimitiveIntId", 5, - new Bin("@_class", DocumentWithPrimitiveIntId.class.getName()) + new Bin(CLASS_KEY_DEFAULT, DocumentWithPrimitiveIntId.class.getName()) ); } @@ -70,7 +71,7 @@ void primitiveLongId(int converterOption) { DocumentWithPrimitiveLongId object = new DocumentWithPrimitiveLongId(5L); assertWriteAndRead(converterOption, object, "DocumentWithPrimitiveLongId", 5L, - new Bin("@_class", DocumentWithPrimitiveLongId.class.getName()) + new Bin(CLASS_KEY_DEFAULT, DocumentWithPrimitiveLongId.class.getName()) ); } @@ -80,7 +81,7 @@ void primitiveCharId(int converterOption) { DocumentWithPrimitiveCharId object = new DocumentWithPrimitiveCharId('a'); assertWriteAndRead(converterOption, object, "DocumentWithPrimitiveCharId", 'a', - new Bin("@_class", DocumentWithPrimitiveCharId.class.getName()) + new Bin(CLASS_KEY_DEFAULT, DocumentWithPrimitiveCharId.class.getName()) ); } @@ -90,7 +91,7 @@ void primitiveByteId(int converterOption) { DocumentWithPrimitiveByteId object = new DocumentWithPrimitiveByteId((byte) 100); assertWriteAndRead(converterOption, object, "DocumentWithPrimitiveByteId", - (byte) 100, new Bin("@_class", DocumentWithPrimitiveByteId.class.getName()) + (byte) 100, new Bin(CLASS_KEY_DEFAULT, DocumentWithPrimitiveByteId.class.getName()) ); } @@ -100,7 +101,7 @@ void shortId(int converterOption) { DocumentWithShortId object = DocumentWithShortId.builder().id((short) 5).build(); assertWriteAndRead(converterOption, object, "DocumentWithShortId", (short) 5, - new Bin("@_class", DocumentWithShortId.class.getName()) + new Bin(CLASS_KEY_DEFAULT, DocumentWithShortId.class.getName()) ); } @@ -110,7 +111,7 @@ void integerId(int converterOption) { DocumentWithIntegerId object = DocumentWithIntegerId.builder().id(5).build(); assertWriteAndRead(converterOption, object, "DocumentWithIntegerId", 5, - new Bin("@_class", DocumentWithIntegerId.class.getName()) + new Bin(CLASS_KEY_DEFAULT, DocumentWithIntegerId.class.getName()) ); } @@ -120,7 +121,7 @@ void longId(int converterOption) { DocumentWithLongId object = DocumentWithLongId.builder().id(5L).build(); assertWriteAndRead(converterOption, object, "DocumentWithLongId", 5L, - new Bin("@_class", DocumentWithLongId.class.getName()) + new Bin(CLASS_KEY_DEFAULT, DocumentWithLongId.class.getName()) ); } @@ -130,7 +131,7 @@ void characterId(int converterOption) { DocumentWithCharacterId object = DocumentWithCharacterId.builder().id('a').build(); assertWriteAndRead(converterOption, object, "DocumentWithCharacterId", 'a', - new Bin("@_class", DocumentWithCharacterId.class.getName()) + new Bin(CLASS_KEY_DEFAULT, DocumentWithCharacterId.class.getName()) ); } @@ -140,7 +141,7 @@ void byteId(int converterOption) { DocumentWithByteId object = DocumentWithByteId.builder().id(((byte) 100)).build(); assertWriteAndRead(converterOption, object, "DocumentWithByteId", (byte) 100, - new Bin("@_class", DocumentWithByteId.class.getName()) + new Bin(CLASS_KEY_DEFAULT, DocumentWithByteId.class.getName()) ); } @@ -150,7 +151,7 @@ void stringId(int converterOption) { DocumentWithStringId object = DocumentWithStringId.builder().id("my-amazing-string-id").build(); assertWriteAndRead(converterOption, object, "DocumentWithStringId", - "my-amazing-string-id", new Bin("@_class", DocumentWithStringId.class.getName()) + "my-amazing-string-id", new Bin(CLASS_KEY_DEFAULT, DocumentWithStringId.class.getName()) ); } @@ -162,7 +163,7 @@ void byteArrayId(int converterOption) { .build(); assertWriteAndRead(converterOption, object, "DocumentWithByteArrayId", - new byte[]{1, 0, 0, 1, 1, 1, 0, 0}, new Bin("@_class", DocumentWithByteArrayId.class.getName()) + new byte[]{1, 0, 0, 1, 1, 1, 0, 0}, new Bin(CLASS_KEY_DEFAULT, DocumentWithByteArrayId.class.getName()) ); } @@ -173,7 +174,7 @@ void setWithSimpleValue(int converterOption) { assertWriteAndRead(converterOption, object, "SetWithSimpleValue", 1L, new Bin("collectionWithSimpleValues", list(null, "a", "b", "c")), - new Bin("@_class", SetWithSimpleValue.class.getName()) + new Bin(CLASS_KEY_DEFAULT, SetWithSimpleValue.class.getName()) ); } @@ -186,7 +187,7 @@ void mapWithShortId(int converterOption) { assertWriteAndRead(converterOption, object, MapWithShortId.class.getSimpleName(), 10L, new Bin("mapWithShortId", of((short) 1, "value1", (short) 2, "value2", (short) 3, null)), - new Bin("@_class", MapWithShortId.class.getName()) + new Bin(CLASS_KEY_DEFAULT, MapWithShortId.class.getName()) ); } @@ -199,7 +200,7 @@ void mapWithIntegerId(int converterOption) { assertWriteAndRead(converterOption, object, MapWithIntegerId.class.getSimpleName(), 10L, new Bin("mapWithIntId", of(1, "value1", 2, "value2", 3, null)), - new Bin("@_class", MapWithIntegerId.class.getName()) + new Bin(CLASS_KEY_DEFAULT, MapWithIntegerId.class.getName()) ); } @@ -212,7 +213,7 @@ void mapWithLongId(int converterOption) { assertWriteAndRead(converterOption, object, MapWithLongId.class.getSimpleName(), 10L, new Bin("mapWithLongId", of(1L, "value1", 2L, "value2", 3L, null)), - new Bin("@_class", MapWithLongId.class.getName()) + new Bin(CLASS_KEY_DEFAULT, MapWithLongId.class.getName()) ); } @@ -225,7 +226,7 @@ void mapWithDoubleId(int converterOption) { assertWriteAndRead(converterOption, object, MapWithDoubleId.class.getSimpleName(), 10L, new Bin("mapWithDoubleId", of(100.25, "value1", 200.25, "value2", 300.25, null)), - new Bin("@_class", MapWithDoubleId.class.getName()) + new Bin(CLASS_KEY_DEFAULT, MapWithDoubleId.class.getName()) ); } @@ -238,7 +239,7 @@ void mapWithByteId(int converterOption) { assertWriteAndRead(converterOption, object, MapWithByteId.class.getSimpleName(), 10L, new Bin("mapWithByteId", of((byte) 100, "value1", (byte) 200, "value2", (byte) 300, null)), - new Bin("@_class", MapWithByteId.class.getName()) + new Bin(CLASS_KEY_DEFAULT, MapWithByteId.class.getName()) ); } @@ -251,7 +252,7 @@ void mapWithCharacterId(int converterOption) { assertWriteAndRead(converterOption, object, MapWithCharacterId.class.getSimpleName(), 10L, new Bin("mapWithCharacterId", of('a', "value1", 'b', "value2", 'c', null)), - new Bin("@_class", MapWithCharacterId.class.getName()) + new Bin(CLASS_KEY_DEFAULT, MapWithCharacterId.class.getName()) ); } @@ -264,7 +265,7 @@ void mapWithSimpleValue(int converterOption) { assertWriteAndRead(converterOption, object, MapWithStringValue.class.getSimpleName(), 10L, new Bin("mapWithStringValue", of("key1", "value1", "key2", "value2", "key3", null)), - new Bin("@_class", MapWithStringValue.class.getName()) + new Bin(CLASS_KEY_DEFAULT, MapWithStringValue.class.getName()) ); } @@ -283,7 +284,7 @@ void idClassConverterNotFound(int converterOption) { new Bin("counter", 1L), new Bin("@_version", 1234567890), new Bin("update", 10L), - new Bin("@_class", DocumentExampleIdClass.class.getName()) + new Bin(CLASS_KEY_DEFAULT, DocumentExampleIdClass.class.getName()) )) .isInstanceOf(org.springframework.core.convert.ConverterNotFoundException.class) .hasMessage("No converter found capable of converting from type " + @@ -299,7 +300,7 @@ void mapWithCollectionValues(int converterOption) { assertWriteAndRead(converterOption, object, MapWithCollectionValue.class.getSimpleName(), 10L, new Bin("mapWithCollectionValue", of("key1", list(), "key2", list("a", "b", "c"))), - new Bin("@_class", MapWithCollectionValue.class.getName()) + new Bin(CLASS_KEY_DEFAULT, MapWithCollectionValue.class.getName()) ); } @@ -312,11 +313,11 @@ void mapWithNonSimpleValue(int converterOption) { assertWriteAndRead(converterOption, object, MapWithGenericValue.class.getSimpleName(), 10L, new Bin("mapWithNonSimpleValue", of( - "key1", of("street", of("name", "Gogolya str.", "number", 15, "@_class", Street.class.getName()), - "apartment", 567, "@_class", Address.class.getName()), - "key2", of("street", of("name", "Shakespeare str.", "number", 40, "@_class", Street.class.getName()), - "apartment", 765, "@_class", Address.class.getName()))), - new Bin("@_class", MapWithGenericValue.class.getName()) + "key1", of("street", of("name", "Gogolya str.", "number", 15, CLASS_KEY_DEFAULT, Street.class.getName()), + "apartment", 567, CLASS_KEY_DEFAULT, Address.class.getName()), + "key2", of("street", of("name", "Shakespeare str.", "number", 40, CLASS_KEY_DEFAULT, Street.class.getName()), + "apartment", 765, CLASS_KEY_DEFAULT, Address.class.getName()))), + new Bin(CLASS_KEY_DEFAULT, MapWithGenericValue.class.getName()) ); } @@ -331,10 +332,10 @@ void listsAndMapsWithObjectValue(int converterOption) { assertWriteAndRead(converterOption, object, "CustomTypeWithListAndMap", id, new Bin("listOfObjects", list("firstItem", of("keyInList", "valueInList"), - of("street", of("name", "Gogolya str.", "number", 15, "@_class", Street.class.getName()), - "apartment", 567, "@_class", Address.class.getName()))), + of("street", of("name", "Gogolya str.", "number", 15, CLASS_KEY_DEFAULT, Street.class.getName()), + "apartment", 567, CLASS_KEY_DEFAULT, Address.class.getName()))), new Bin("mapWithObjectValue", of("map", of("key", "value"))), - new Bin("@_class", CustomTypeWithListAndMap.class.getName()) + new Bin(CLASS_KEY_DEFAULT, CustomTypeWithListAndMap.class.getName()) ); } @@ -348,13 +349,13 @@ void customTypeWithCustomType(int converterOption) { assertWriteAndRead(converterOption, object, "CustomTypeWithCustomType", id, new Bin("field", of( - "@_class", ImmutableListAndMap.class.getName(), + CLASS_KEY_DEFAULT, ImmutableListAndMap.class.getName(), "listOfObjects", list("firstItem", of("keyInList", "valueInList")), "mapWithObjectValue", of("map", of("key", "value"), - "address", of("street", of("name", "Gogolya str.", "number", 15, "@_class", Street.class.getName()), - "apartment", 567, "@_class", Address.class.getName())) + "address", of("street", of("name", "Gogolya str.", "number", 15, CLASS_KEY_DEFAULT, Street.class.getName()), + "apartment", 567, CLASS_KEY_DEFAULT, Address.class.getName())) )), - new Bin("@_class", CustomTypeWithCustomType.class.getName()) + new Bin(CLASS_KEY_DEFAULT, CustomTypeWithCustomType.class.getName()) ); } @@ -368,7 +369,7 @@ void listsAndMapsWithObjectImmutable(int converterOption) { assertWriteAndRead(converterOption, object, "CustomTypeWithListAndMapImmutable", id, new Bin("listOfObjects", list("firstItem", of("keyInList", "valueInList"))), new Bin("mapWithObjectValue", of("map", of("key", "value"))), - new Bin("@_class", CustomTypeWithListAndMapImmutable.class.getName()) + new Bin(CLASS_KEY_DEFAULT, CustomTypeWithListAndMapImmutable.class.getName()) ); } @@ -394,7 +395,7 @@ void objectWithSimpleFields(int converterOption) { new Bin("field11", (byte) 1), new Bin("field12", '3'), new Bin("field13", 'd'), - new Bin("@_class", "simpleclass") + new Bin(CLASS_KEY_DEFAULT, "simpleclass") ); } @@ -404,7 +405,7 @@ void objectWithPersistenceConstructor(int converterOption) { SimpleClassWithPersistenceConstructor object = new SimpleClassWithPersistenceConstructor(17, "abyrvalg", 13); assertWriteAndRead(converterOption, object, SIMPLESET2, 17, - new Bin("@_class", SimpleClassWithPersistenceConstructor.class.getName()), + new Bin(CLASS_KEY_DEFAULT, SimpleClassWithPersistenceConstructor.class.getName()), new Bin("field1", "abyrvalg"), new Bin("field2", 13)); } @@ -417,13 +418,13 @@ void complexClass(int converterOption) { User object = new User(10, name, address); assertWriteAndRead(converterOption, object, SIMPLESET3, 10, - new Bin("@_class", User.class.getName()), + new Bin(CLASS_KEY_DEFAULT, User.class.getName()), new Bin("name", - of("firstName", "Vasya", "lastName", "Pupkin", "@_class", Name.class.getName())), + of("firstName", "Vasya", "lastName", "Pupkin", CLASS_KEY_DEFAULT, Name.class.getName())), new Bin("address", of("street", - of("name", "Gogolya street", "number", 24, "@_class", Street.class.getName()), - "apartment", 777, "@_class", Address.class.getName())) + of("name", "Gogolya street", "number", 24, CLASS_KEY_DEFAULT, Street.class.getName()), + "apartment", 777, CLASS_KEY_DEFAULT, Address.class.getName())) ); } @@ -436,14 +437,14 @@ void setWithComplexValue(int converterOption) { Person object = new Person("kate-01", addresses); assertWriteAndRead(converterOption, object, "Person", "kate-01", - new Bin("@_class", Person.class.getName()), + new Bin(CLASS_KEY_DEFAULT, Person.class.getName()), new Bin("addresses", list( of("street", - of("name", "Southwark Street", "number", 110, "@_class", Street.class.getName()), - "apartment", 876, "@_class", Address.class.getName()), + of("name", "Southwark Street", "number", 110, CLASS_KEY_DEFAULT, Street.class.getName()), + "apartment", 876, CLASS_KEY_DEFAULT, Address.class.getName()), of("street", - of("name", "Finsbury Pavement", "number", 125, "@_class", Street.class.getName()), - "apartment", 13, "@_class", Address.class.getName()) + of("name", "Finsbury Pavement", "number", 125, CLASS_KEY_DEFAULT, Street.class.getName()), + "apartment", 13, CLASS_KEY_DEFAULT, Address.class.getName()) ))); } @@ -456,7 +457,7 @@ void enumProperties(int converterOption) { ClassWithEnumProperties object = new ClassWithEnumProperties("id", TYPES.SECOND, list, set, map); assertWriteAndRead(converterOption, object, "ClassWithEnumProperties", "id", - new Bin("@_class", ClassWithEnumProperties.class.getName()), + new Bin(CLASS_KEY_DEFAULT, ClassWithEnumProperties.class.getName()), new Bin("type", "SECOND"), new Bin("list", list("FIRST", "SECOND")), new Bin("set", list("FIRST", "SECOND", "THIRD")), @@ -471,7 +472,7 @@ void sortedMapWithSimpleValue(int converterOption) { SortedMapWithSimpleValue object = new SortedMapWithSimpleValue(id, map); assertWriteAndRead(converterOption, object, "SortedMapWithSimpleValue", id, - new Bin("@_class", SortedMapWithSimpleValue.class.getName()), + new Bin(CLASS_KEY_DEFAULT, SortedMapWithSimpleValue.class.getName()), new Bin("map", of("a", "b", "c", "d")) ); } @@ -485,7 +486,7 @@ void nestedMapsWithSimpleValue(int converterOption) { NestedMapsWithSimpleValue object = new NestedMapsWithSimpleValue(id, map); assertWriteAndRead(converterOption, object, "NestedMapsWithSimpleValue", id, - new Bin("@_class", NestedMapsWithSimpleValue.class.getName()), + new Bin(CLASS_KEY_DEFAULT, NestedMapsWithSimpleValue.class.getName()), new Bin("nestedMaps", of( "level-1", of("level-1-1", of("1", "2")), "level-2", of("level-2-2", of("1", "2")))) @@ -499,7 +500,7 @@ void genericType(int converterOption) { @SuppressWarnings("unchecked") GenericType> object = new GenericType(id, "string"); assertWriteAndRead(converterOption, object, "GenericType", id, - new Bin("@_class", GenericType.class.getName()), + new Bin(CLASS_KEY_DEFAULT, GenericType.class.getName()), new Bin("content", "string") ); } @@ -510,7 +511,7 @@ void listOfLists(int converterOption) { ListOfLists object = new ListOfLists(id, list(list("a", "b", "c"), list("d", "e"), list())); assertWriteAndRead(converterOption, object, "ListOfLists", id, - new Bin("@_class", ListOfLists.class.getName()), + new Bin(CLASS_KEY_DEFAULT, ListOfLists.class.getName()), new Bin("listOfLists", list(list("a", "b", "c"), list("d", "e"), list())) ); } @@ -522,10 +523,10 @@ void listOfMaps(int converterOption) { new Name("Nastya", "Smirnova")))); assertWriteAndRead(converterOption, object, "ListOfMaps", id, - new Bin("@_class", ListOfMaps.class.getName()), + new Bin(CLASS_KEY_DEFAULT, ListOfMaps.class.getName()), new Bin("listOfMaps", list( - of("vasya", of("firstName", "Vasya", "lastName", "Pukin", "@_class", Name.class.getName())), - of("nastya", of("firstName", "Nastya", "lastName", "Smirnova", "@_class", Name.class.getName())) + of("vasya", of("firstName", "Vasya", "lastName", "Pukin", CLASS_KEY_DEFAULT, Name.class.getName())), + of("nastya", of("firstName", "Nastya", "lastName", "Smirnova", CLASS_KEY_DEFAULT, Name.class.getName())) ))); } @@ -536,9 +537,9 @@ void containerOfCustomFieldNames(int converterOption) { , "2")); assertWriteAndRead(converterOption, object, "ContainerOfCustomFieldNames", id, - new Bin("@_class", ContainerOfCustomFieldNames.class.getName()), + new Bin(CLASS_KEY_DEFAULT, ContainerOfCustomFieldNames.class.getName()), new Bin("property", "value"), - new Bin("customFieldNames", of("property1", 1, "property2", "2", "@_class", + new Bin("customFieldNames", of("property1", 1, "property2", "2", CLASS_KEY_DEFAULT, CustomFieldNames.class.getName())) ); } @@ -549,7 +550,7 @@ void classWithComplexId(int converterOption) { ClassWithComplexId object = new ClassWithComplexId(new ComplexId(10L)); assertWriteAndRead(converterOption, object, ClassWithComplexId.class.getSimpleName(), "id::10", - new Bin("@_class", ClassWithComplexId.class.getName()) + new Bin(CLASS_KEY_DEFAULT, ClassWithComplexId.class.getName()) ); } @@ -560,9 +561,9 @@ void idFieldOfNonDocumentClass(int converterOption) { of("key", new DocumentWithLongId(45L, "v"))); assertWriteAndRead(converterOption, object, MapWithGenericValue.class.getSimpleName(), 788L, - new Bin("@_class", MapWithGenericValue.class.getName()), + new Bin(CLASS_KEY_DEFAULT, MapWithGenericValue.class.getName()), new Bin("mapWithNonSimpleValue", - of("key", of("id", 45L, "content", "v", "@_class", DocumentWithLongId.class.getName()))) + of("key", of("id", 45L, "content", "v", CLASS_KEY_DEFAULT, DocumentWithLongId.class.getName()))) ); } @@ -573,7 +574,7 @@ void objectWithByteArrayField(int converterOption) { assertWriteAndRead(converterOption, object, "DocumentWithByteArray", id, - new Bin("@_class", DocumentWithByteArray.class.getName()), + new Bin(CLASS_KEY_DEFAULT, DocumentWithByteArray.class.getName()), new Bin("array", new byte[]{1, 0, 0, 1, 1, 1, 0, 0})); } @@ -585,7 +586,7 @@ void objectWithArrayField(int converterOption) { assertWriteAndRead(converterOption, object, "DocumentWithIntArray", id, - new Bin("@_class", DocumentWithIntArray.class.getName()), + new Bin(CLASS_KEY_DEFAULT, DocumentWithIntArray.class.getName()), new Bin("array", Arrays.stream(array).boxed().toList())); } @@ -598,7 +599,7 @@ void objectWithAtomicField(int converterOption) { DocumentWithAtomicFields readDoc = readObjectAfterWriting(converterOption, object, "DocumentWithAtomicFields", id, - new Bin("@_class", DocumentWithAtomicFields.class.getName()), + new Bin(CLASS_KEY_DEFAULT, DocumentWithAtomicFields.class.getName()), new Bin("atomicInteger", AerospikeConverters.AtomicIntegerToIntegerConverter.INSTANCE.convert(atomicInteger)), new Bin("atomicLong", AerospikeConverters.AtomicLongToLongConverter.INSTANCE.convert(atomicLong))); @@ -622,7 +623,7 @@ void objectWithURLField(int converterOption) { assertWriteAndRead(converterOption, object, "DocumentWithURL", id, - new Bin("@_class", DocumentWithURL.class.getName()), + new Bin(CLASS_KEY_DEFAULT, DocumentWithURL.class.getName()), new Bin("url", AerospikeConverters.URLToStringConverter.INSTANCE.convert(url))); } @@ -634,7 +635,7 @@ void objectWithUUIDField(int converterOption) { assertWriteAndRead(converterOption, object, "DocumentWithUUID", id, - new Bin("@_class", DocumentWithUUID.class.getName()), + new Bin(CLASS_KEY_DEFAULT, DocumentWithUUID.class.getName()), new Bin("uuid", AerospikeConverters.UuidToStringConverter.INSTANCE.convert(uuid))); } @@ -646,7 +647,7 @@ void objectWithCurrencyField(int converterOption) { assertWriteAndRead(converterOption, object, "DocumentWithCurrency", id, - new Bin("@_class", DocumentWithCurrency.class.getName()), + new Bin(CLASS_KEY_DEFAULT, DocumentWithCurrency.class.getName()), new Bin("currency", AerospikeConverters.CurrencyToStringConverter.INSTANCE.convert(currency))); } @@ -658,7 +659,7 @@ void objectWithDateField(int converterOption) { assertWriteAndRead(converterOption, object, "DocumentWithDate", id, - new Bin("@_class", DocumentWithDate.class.getName()), + new Bin(CLASS_KEY_DEFAULT, DocumentWithDate.class.getName()), new Bin("date", DateConverters.DateToLongConverter.INSTANCE.convert(date))); } @@ -671,7 +672,7 @@ void objectWithCalendarField(int converterOption) { assertWriteAndRead(converterOption, object, "DocumentWithCalendar", id, - new Bin("@_class", DocumentWithCalendar.class.getName()), + new Bin(CLASS_KEY_DEFAULT, DocumentWithCalendar.class.getName()), new Bin("calendar", DateConverters.CalendarToMapConverter.INSTANCE.convert(calendar))); } @@ -688,7 +689,7 @@ void objectWithInstantField(int converterOption) { assertWriteAndRead(converterOption, object, "DocumentWithInstant", id, objectAssertFunction, - new Bin("@_class", DocumentWithInstant.class.getName()), + new Bin(CLASS_KEY_DEFAULT, DocumentWithInstant.class.getName()), new Bin("instant", DateConverters.InstantToLongConverter.INSTANCE.convert(instant))); } @@ -700,7 +701,7 @@ void objectWithDurationField(int converterOption) { assertWriteAndRead(converterOption, object, "DocumentWithDuration", id, - new Bin("@_class", DocumentWithDuration.class.getName()), + new Bin(CLASS_KEY_DEFAULT, DocumentWithDuration.class.getName()), new Bin("duration", DateConverters.DurationToStringConverter.INSTANCE.convert(duration))); } @@ -715,7 +716,7 @@ void objectWithBigDecimal(int converterOption) { assertWriteAndRead(converterOption, object, "BigDecimalContainer", id, - new Bin("@_class", BigDecimalContainer.class.getName()), + new Bin(CLASS_KEY_DEFAULT, BigDecimalContainer.class.getName()), new Bin("collection", list("988687642340235")), new Bin("value", "999999999999999999999999998746"), new Bin("map", of("big-decimal-val", "767867678687678")) @@ -728,7 +729,7 @@ void objectWithByteArrayFieldWithOneValueInData(int converterOption) { DocumentWithByteArray object = new DocumentWithByteArray(id, new byte[]{1}); assertWriteAndRead(converterOption, object, "DocumentWithByteArray", id, - new Bin("@_class", DocumentWithByteArray.class.getName()), + new Bin(CLASS_KEY_DEFAULT, DocumentWithByteArray.class.getName()), new Bin("array", new byte[]{1}) ); } diff --git a/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateDeleteRelatedTests.java b/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateDeleteRelatedTests.java index ba0c6a3fc..969082035 100644 --- a/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateDeleteRelatedTests.java +++ b/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateDeleteRelatedTests.java @@ -157,246 +157,219 @@ public void deleteByObject_shouldReturnFalseIfValueIsAbsent() { @Test public void deleteByIds_ShouldDeleteAllDocuments() { - // batch delete operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - String id1 = nextId(); - String id2 = nextId(); - reactiveTemplate.save(new SampleClasses.VersionedClass(id1, "test1")).block(); - reactiveTemplate.save(new SampleClasses.VersionedClass(id2, "test2")).block(); - - List ids = List.of(id1, id2); - reactiveTemplate.deleteByIds(ids, SampleClasses.VersionedClass.class).block(); - - List list = reactiveTemplate.findByIds(ids, - SampleClasses.VersionedClass.class).subscribeOn(Schedulers.parallel()).collectList().block(); - assertThat(list).isEmpty(); - - List persons = additionalAerospikeTestOperations.saveGeneratedPersons(101); - ids = persons.stream().map(Person::getId).toList(); - reactiveTemplate.deleteByIds(ids, Person.class).block(); - assertThat(reactiveTemplate.findByIds(ids, Person.class).collectList().block()).hasSize(0); - - List persons2 = additionalAerospikeTestOperations.saveGeneratedPersons(1001); - ids = persons2.stream().map(Person::getId).toList(); - reactiveTemplate.deleteByIds(ids, Person.class).block(); - assertThat(reactiveTemplate.findByIds(ids, Person.class).collectList().block()).hasSize(0); - } + String id1 = nextId(); + String id2 = nextId(); + reactiveTemplate.save(new SampleClasses.VersionedClass(id1, "test1")).block(); + reactiveTemplate.save(new SampleClasses.VersionedClass(id2, "test2")).block(); + + List ids = List.of(id1, id2); + reactiveTemplate.deleteByIds(ids, SampleClasses.VersionedClass.class).block(); + + List list = reactiveTemplate.findByIds(ids, + SampleClasses.VersionedClass.class).subscribeOn(Schedulers.parallel()).collectList().block(); + assertThat(list).isEmpty(); + + List persons = additionalAerospikeTestOperations.saveGeneratedPersons(101); + ids = persons.stream().map(Person::getId).toList(); + reactiveTemplate.deleteByIds(ids, Person.class).block(); + assertThat(reactiveTemplate.findByIds(ids, Person.class).collectList().block()).hasSize(0); + + List persons2 = additionalAerospikeTestOperations.saveGeneratedPersons(1001); + ids = persons2.stream().map(Person::getId).toList(); + reactiveTemplate.deleteByIds(ids, Person.class).block(); + assertThat(reactiveTemplate.findByIds(ids, Person.class).collectList().block()).hasSize(0); } @Test public void deleteByIdsWithSetName_ShouldDeleteAllDocuments() { - // batch delete operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - String id1 = nextId(); - String id2 = nextId(); - reactiveTemplate.save(new SampleClasses.DocumentWithExpiration(id1), OVERRIDE_SET_NAME).block(); - reactiveTemplate.save(new SampleClasses.DocumentWithExpiration(id2), OVERRIDE_SET_NAME).block(); - - List ids = List.of(id1, id2); - reactiveTemplate.deleteByIds(ids, OVERRIDE_SET_NAME).block(); - - List list = reactiveTemplate.findByIds(ids, - SampleClasses.DocumentWithExpiration.class, OVERRIDE_SET_NAME) - .subscribeOn(Schedulers.parallel()).collectList().block(); - assertThat(list).isEmpty(); - } + String id1 = nextId(); + String id2 = nextId(); + reactiveTemplate.save(new SampleClasses.DocumentWithExpiration(id1), OVERRIDE_SET_NAME).block(); + reactiveTemplate.save(new SampleClasses.DocumentWithExpiration(id2), OVERRIDE_SET_NAME).block(); + + List ids = List.of(id1, id2); + reactiveTemplate.deleteByIds(ids, OVERRIDE_SET_NAME).block(); + + List list = reactiveTemplate.findByIds(ids, + SampleClasses.DocumentWithExpiration.class, OVERRIDE_SET_NAME) + .subscribeOn(Schedulers.parallel()).collectList().block(); + assertThat(list).isEmpty(); } @Test public void deleteByIdsFromDifferentSets_ShouldDeleteAllDocuments() { - // batch delete operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - SampleClasses.DocumentWithExpiration entity1_1 = new SampleClasses.DocumentWithExpiration(id); - SampleClasses.DocumentWithExpiration entity1_2 = new SampleClasses.DocumentWithExpiration(nextId()); - SampleClasses.VersionedClass entity2_1 = new SampleClasses.VersionedClass(nextId(), "test1"); - SampleClasses.VersionedClass entity2_2 = new SampleClasses.VersionedClass(nextId(), "test2"); - Person entity3_1 = Person.builder().id(nextId()).firstName("Name1").build(); - Person entity3_2 = Person.builder().id(nextId()).firstName("Name2").build(); - reactiveTemplate.save(entity1_1).block(); - reactiveTemplate.save(entity1_2).block(); - reactiveTemplate.save(entity2_1).block(); - reactiveTemplate.save(entity2_2).block(); - reactiveTemplate.save(entity3_1).block(); - reactiveTemplate.save(entity3_2).block(); - - Map, Collection> entitiesKeys = Map.of( - SampleClasses.DocumentWithExpiration.class, List.of(entity1_1.getId(), entity1_2.getId()), - SampleClasses.VersionedClass.class, List.of(entity2_1.getId(), entity2_2.getId()), - Person.class, List.of(entity3_1.getId(), entity3_2.getId()) - ); - GroupedKeys groupedKeys = GroupedKeys.builder().entitiesKeys(entitiesKeys).build(); - reactiveTemplate.deleteByIds(groupedKeys).block(); - - List list1 = reactiveTemplate.findByIds( - List.of(entity1_1.getId(), entity1_2.getId()), - SampleClasses.DocumentWithExpiration.class - ).subscribeOn(Schedulers.parallel()).collectList().block(); - assertThat(list1).isEmpty(); - List list2 = reactiveTemplate.findByIds( - List.of(entity2_1.getId(), entity2_2.getId()), - SampleClasses.VersionedClass.class - ).subscribeOn(Schedulers.parallel()).collectList().block(); - assertThat(list2).isEmpty(); - List list3 = reactiveTemplate.findByIds( - List.of(entity3_1.getId(), entity3_2.getId()), - Person.class - ).subscribeOn(Schedulers.parallel()).collectList().block(); - assertThat(list3).isEmpty(); - } + SampleClasses.DocumentWithExpiration entity1_1 = new SampleClasses.DocumentWithExpiration(id); + SampleClasses.DocumentWithExpiration entity1_2 = new SampleClasses.DocumentWithExpiration(nextId()); + SampleClasses.VersionedClass entity2_1 = new SampleClasses.VersionedClass(nextId(), "test1"); + SampleClasses.VersionedClass entity2_2 = new SampleClasses.VersionedClass(nextId(), "test2"); + Person entity3_1 = Person.builder().id(nextId()).firstName("Name1").build(); + Person entity3_2 = Person.builder().id(nextId()).firstName("Name2").build(); + reactiveTemplate.save(entity1_1).block(); + reactiveTemplate.save(entity1_2).block(); + reactiveTemplate.save(entity2_1).block(); + reactiveTemplate.save(entity2_2).block(); + reactiveTemplate.save(entity3_1).block(); + reactiveTemplate.save(entity3_2).block(); + + Map, Collection> entitiesKeys = Map.of( + SampleClasses.DocumentWithExpiration.class, List.of(entity1_1.getId(), entity1_2.getId()), + SampleClasses.VersionedClass.class, List.of(entity2_1.getId(), entity2_2.getId()), + Person.class, List.of(entity3_1.getId(), entity3_2.getId()) + ); + GroupedKeys groupedKeys = GroupedKeys.builder().entitiesKeys(entitiesKeys).build(); + reactiveTemplate.deleteByIds(groupedKeys).block(); + + List list1 = reactiveTemplate.findByIds( + List.of(entity1_1.getId(), entity1_2.getId()), + SampleClasses.DocumentWithExpiration.class + ).subscribeOn(Schedulers.parallel()).collectList().block(); + assertThat(list1).isEmpty(); + List list2 = reactiveTemplate.findByIds( + List.of(entity2_1.getId(), entity2_2.getId()), + SampleClasses.VersionedClass.class + ).subscribeOn(Schedulers.parallel()).collectList().block(); + assertThat(list2).isEmpty(); + List list3 = reactiveTemplate.findByIds( + List.of(entity3_1.getId(), entity3_2.getId()), + Person.class + ).subscribeOn(Schedulers.parallel()).collectList().block(); + assertThat(list3).isEmpty(); } @Test public void deleteByIds_rejectsDuplicateIds() { - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - String id1 = nextId(); - SampleClasses.DocumentWithExpiration document1 = new SampleClasses.DocumentWithExpiration(id1); - SampleClasses.DocumentWithExpiration document2 = new SampleClasses.DocumentWithExpiration(id1); - reactiveTemplate.save(document1).block(); - reactiveTemplate.save(document2).block(); - - List ids = List.of(id1, id1); - StepVerifier.create(reactiveTemplate.deleteByIds(ids, SampleClasses.DocumentWithExpiration.class)) - .expectError(AerospikeException.BatchRecordArray.class) - .verify(); - } + String id1 = nextId(); + SampleClasses.DocumentWithExpiration document1 = new SampleClasses.DocumentWithExpiration(id1); + SampleClasses.DocumentWithExpiration document2 = new SampleClasses.DocumentWithExpiration(id1); + reactiveTemplate.save(document1).block(); + reactiveTemplate.save(document2).block(); + + List ids = List.of(id1, id1); + StepVerifier.create(reactiveTemplate.deleteByIds(ids, SampleClasses.DocumentWithExpiration.class)) + .expectError(AerospikeException.BatchRecordArray.class) + .verify(); } @Test public void deleteAll_ShouldDeleteAllDocuments() { - // batch delete operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - String id1 = nextId(); - String id2 = nextId(); - SampleClasses.DocumentWithExpiration document1 = new SampleClasses.DocumentWithExpiration(id1); - SampleClasses.DocumentWithExpiration document2 = new SampleClasses.DocumentWithExpiration(id2); - reactiveTemplate.saveAll(List.of(document1, document2)).blockLast(); - - List ids = List.of(id1, id2); - reactiveTemplate.deleteAll(List.of(document1, document2)).block(); - - List list = reactiveTemplate.findByIds(ids, - SampleClasses.VersionedClass.class).subscribeOn(Schedulers.parallel()).collectList().block(); - assertThat(list).isEmpty(); - - List persons = additionalAerospikeTestOperations.saveGeneratedPersons(101); - ids = persons.stream().map(Person::getId).toList(); - reactiveTemplate.deleteAll(persons).block(); - assertThat(reactiveTemplate.findByIds(ids, Person.class).collectList().block()).hasSize(0); - - List persons2 = additionalAerospikeTestOperations.saveGeneratedPersons(1001); - ids = persons2.stream().map(Person::getId).toList(); - reactiveTemplate.deleteAll(persons2).block(); - assertThat(reactiveTemplate.findByIds(ids, Person.class).collectList().block()).hasSize(0); - } + String id1 = nextId(); + String id2 = nextId(); + SampleClasses.DocumentWithExpiration document1 = new SampleClasses.DocumentWithExpiration(id1); + SampleClasses.DocumentWithExpiration document2 = new SampleClasses.DocumentWithExpiration(id2); + reactiveTemplate.saveAll(List.of(document1, document2)).blockLast(); + + List ids = List.of(id1, id2); + reactiveTemplate.deleteAll(List.of(document1, document2)).block(); + + List list = reactiveTemplate.findByIds(ids, + SampleClasses.VersionedClass.class).subscribeOn(Schedulers.parallel()).collectList().block(); + assertThat(list).isEmpty(); + + List persons = additionalAerospikeTestOperations.saveGeneratedPersons(101); + ids = persons.stream().map(Person::getId).toList(); + reactiveTemplate.deleteAll(persons).block(); + assertThat(reactiveTemplate.findByIds(ids, Person.class).collectList().block()).hasSize(0); + + List persons2 = additionalAerospikeTestOperations.saveGeneratedPersons(1001); + ids = persons2.stream().map(Person::getId).toList(); + reactiveTemplate.deleteAll(persons2).block(); + assertThat(reactiveTemplate.findByIds(ids, Person.class).collectList().block()).hasSize(0); } @Test public void deleteAllWithSetName_ShouldDeleteAllDocuments() { - // batch delete operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - String id1 = nextId(); - String id2 = nextId(); - SampleClasses.DocumentWithExpiration document1 = new SampleClasses.DocumentWithExpiration(id1); - SampleClasses.DocumentWithExpiration document2 = new SampleClasses.DocumentWithExpiration(id2); - reactiveTemplate.saveAll(List.of(document1, document2), OVERRIDE_SET_NAME).blockLast(); - - reactiveTemplate.deleteAll(List.of(document1, document2), OVERRIDE_SET_NAME).block(); - List ids = List.of(id1, id2); - List list = reactiveTemplate.findByIds(ids, - SampleClasses.DocumentWithExpiration.class, OVERRIDE_SET_NAME) - .subscribeOn(Schedulers.parallel()).collectList().block(); - assertThat(list).isEmpty(); - } + String id1 = nextId(); + String id2 = nextId(); + SampleClasses.DocumentWithExpiration document1 = new SampleClasses.DocumentWithExpiration(id1); + SampleClasses.DocumentWithExpiration document2 = new SampleClasses.DocumentWithExpiration(id2); + reactiveTemplate.saveAll(List.of(document1, document2), OVERRIDE_SET_NAME).blockLast(); + + reactiveTemplate.deleteAll(List.of(document1, document2), OVERRIDE_SET_NAME).block(); + List ids = List.of(id1, id2); + List list = reactiveTemplate.findByIds(ids, + SampleClasses.DocumentWithExpiration.class, OVERRIDE_SET_NAME) + .subscribeOn(Schedulers.parallel()).collectList().block(); + assertThat(list).isEmpty(); } @Test public void deleteAll_ShouldDeleteAllDocumentsBeforeGivenLastUpdateTime() { - // batch delete operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - String id1 = nextId(); - String id2 = nextId(); - SampleClasses.CollectionOfObjects document1 = new SampleClasses.CollectionOfObjects(id1, List.of("test1")); - SampleClasses.CollectionOfObjects document2 = new SampleClasses.CollectionOfObjects(id2, List.of("test2")); - - reactiveTemplate.save(document1).block(); - AwaitilityUtils.wait(1, MILLISECONDS); - - Instant lastUpdateTime = Instant.now(); - Instant inFuture = Instant.ofEpochMilli(lastUpdateTime.toEpochMilli() + 10000); - reactiveTemplate.save(document2).block(); - - // make sure document1 has lastUpdateTime less than specified millis - List resultsWithLutLtMillis = - runLastUpdateTimeQuery(lastUpdateTime.toEpochMilli(), FilterOperation.LT, - SampleClasses.CollectionOfObjects.class); - assertThat(resultsWithLutLtMillis.get(0).getId()).isEqualTo(document1.getId()); - assertThat(resultsWithLutLtMillis.get(0).getCollection().iterator().next()) - .isEqualTo(document1.getCollection().iterator().next()); - - assertThatThrownBy(() -> - reactiveTemplate.deleteAll(SampleClasses.CollectionOfObjects.class, inFuture).block()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageMatching("Last update time (.*) must be less than the current time"); - - reactiveTemplate.deleteAll(SampleClasses.CollectionOfObjects.class, lastUpdateTime).block(); - assertThat(reactiveTemplate.findByIds(List.of(id1, id2), SampleClasses.CollectionOfObjects.class) - .collectList().block()).hasSize(1); - SampleClasses.CollectionOfObjects result = reactiveTemplate.findByIds(List.of(id1, id2), - SampleClasses.CollectionOfObjects.class).collectList().block().get(0); - assertThat(result.getId()).isEqualTo(document2.getId()); - assertThat(result.getCollection().iterator().next()).isEqualTo(document2.getCollection().iterator().next()); - - List persons = additionalAerospikeTestOperations.saveGeneratedPersons(101); - AwaitilityUtils.wait(1, MILLISECONDS); - lastUpdateTime = Instant.now(); - Person newPerson = new Person(nextId(), "testFirstName"); - reactiveTemplate.save(newPerson).block(); - persons.add(newPerson); - - reactiveTemplate.deleteAll(reactiveTemplate.getSetName(Person.class), lastUpdateTime).block(); - List personsIds = persons.stream().map(Person::getId).toList(); - assertThat(reactiveTemplate.findByIds(personsIds, Person.class).collectList().block()).contains(newPerson); - - List persons2 = additionalAerospikeTestOperations.saveGeneratedPersons(1001); - reactiveTemplate.deleteAll(Person.class, lastUpdateTime) - .block(); // persons2 were saved after the given time - personsIds = persons2.stream().map(Person::getId).toList(); - assertThat(reactiveTemplate.findByIds(personsIds, Person.class).collectList().block()) - .containsExactlyInAnyOrderElementsOf(persons2); - } + String id1 = nextId(); + String id2 = nextId(); + SampleClasses.CollectionOfObjects document1 = new SampleClasses.CollectionOfObjects(id1, List.of("test1")); + SampleClasses.CollectionOfObjects document2 = new SampleClasses.CollectionOfObjects(id2, List.of("test2")); + + reactiveTemplate.save(document1).block(); + AwaitilityUtils.wait(1, MILLISECONDS); + + Instant lastUpdateTime = Instant.now(); + Instant inFuture = Instant.ofEpochMilli(lastUpdateTime.toEpochMilli() + 10000); + reactiveTemplate.save(document2).block(); + + // make sure document1 has lastUpdateTime less than specified millis + List resultsWithLutLtMillis = + runLastUpdateTimeQuery(lastUpdateTime.toEpochMilli(), FilterOperation.LT, + SampleClasses.CollectionOfObjects.class); + assertThat(resultsWithLutLtMillis.get(0).getId()).isEqualTo(document1.getId()); + assertThat(resultsWithLutLtMillis.get(0).getCollection().iterator().next()) + .isEqualTo(document1.getCollection().iterator().next()); + + assertThatThrownBy(() -> + reactiveTemplate.deleteAll(SampleClasses.CollectionOfObjects.class, inFuture).block()) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageMatching("Last update time (.*) must be less than the current time"); + + reactiveTemplate.deleteAll(SampleClasses.CollectionOfObjects.class, lastUpdateTime).block(); + assertThat(reactiveTemplate.findByIds(List.of(id1, id2), SampleClasses.CollectionOfObjects.class) + .collectList().block()).hasSize(1); + SampleClasses.CollectionOfObjects result = reactiveTemplate.findByIds(List.of(id1, id2), + SampleClasses.CollectionOfObjects.class).collectList().block().get(0); + assertThat(result.getId()).isEqualTo(document2.getId()); + assertThat(result.getCollection().iterator().next()).isEqualTo(document2.getCollection().iterator().next()); + + List persons = additionalAerospikeTestOperations.saveGeneratedPersons(101); + AwaitilityUtils.wait(1, MILLISECONDS); + lastUpdateTime = Instant.now(); + Person newPerson = new Person(nextId(), "testFirstName"); + reactiveTemplate.save(newPerson).block(); + persons.add(newPerson); + + reactiveTemplate.deleteAll(reactiveTemplate.getSetName(Person.class), lastUpdateTime).block(); + List personsIds = persons.stream().map(Person::getId).toList(); + assertThat(reactiveTemplate.findByIds(personsIds, Person.class).collectList().block()).contains(newPerson); + + List persons2 = additionalAerospikeTestOperations.saveGeneratedPersons(1001); + reactiveTemplate.deleteAll(Person.class, lastUpdateTime) + .block(); // persons2 were saved after the given time + personsIds = persons2.stream().map(Person::getId).toList(); + assertThat(reactiveTemplate.findByIds(personsIds, Person.class).collectList().block()) + .containsExactlyInAnyOrderElementsOf(persons2); } @Test public void deleteAll_rejectsDuplicateIds() { - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - String id1 = nextId(); - SampleClasses.DocumentWithExpiration document1 = new SampleClasses.DocumentWithExpiration(id1); - SampleClasses.DocumentWithExpiration document2 = new SampleClasses.DocumentWithExpiration(id1); - reactiveTemplate.saveAll(List.of(document1, document2)).blockLast(); - - StepVerifier.create(reactiveTemplate.deleteAll(List.of(document1, document2))) - .expectError(AerospikeException.BatchRecordArray.class) - .verify(); - } + String id1 = nextId(); + SampleClasses.DocumentWithExpiration document1 = new SampleClasses.DocumentWithExpiration(id1); + SampleClasses.DocumentWithExpiration document2 = new SampleClasses.DocumentWithExpiration(id1); + reactiveTemplate.saveAll(List.of(document1, document2)).blockLast(); + + StepVerifier.create(reactiveTemplate.deleteAll(List.of(document1, document2))) + .expectError(AerospikeException.BatchRecordArray.class) + .verify(); } @Test public void deleteAll_VersionsMismatch() { - // batch delete operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - String id1 = "id1"; - VersionedClass document1 = new VersionedClass(id1, "test1"); - String id2 = "id2"; - VersionedClass document2 = new VersionedClass(id2, "test2"); - reactiveTemplate.save(document1).block(); - reactiveTemplate.save(document2).block(); - - document2.setVersion(232); - assertThatThrownBy(() -> reactiveTemplate.deleteAll(List.of(document1, document2)).block()) - .isInstanceOf(OptimisticLockingFailureException.class) - .hasMessageContaining("Failed to delete the record with ID 'id2' due to versions mismatch"); - } + String id1 = "id1"; + VersionedClass document1 = new VersionedClass(id1, "test1"); + String id2 = "id2"; + VersionedClass document2 = new VersionedClass(id2, "test2"); + reactiveTemplate.save(document1).block(); + reactiveTemplate.save(document2).block(); + + document2.setVersion(232); + assertThatThrownBy(() -> reactiveTemplate.deleteAll(List.of(document1, document2)).block()) + .isInstanceOf(OptimisticLockingFailureException.class) + .hasMessageContaining("Failed to delete the record with ID 'id2' due to versions mismatch"); } } diff --git a/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateInsertTests.java b/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateInsertTests.java index 445c6856d..3d56b74e6 100644 --- a/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateInsertTests.java +++ b/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateInsertTests.java @@ -229,67 +229,59 @@ public void insertsOnlyFirstDocumentAndNextAttemptsShouldFailWithDuplicateKeyExc @Test public void insertAll_shouldInsertAllDocuments() { - if (serverVersionSupport.isBatchWriteSupported()) { - Person customer1 = new Person(nextId(), "Dave"); - Person customer2 = new Person(nextId(), "James"); - reactiveTemplate.insertAll(List.of(customer1, customer2)).blockLast(); - - Person result1 = findById(customer1.getId(), Person.class); - Person result2 = findById(customer2.getId(), Person.class); - assertThat(result1).isEqualTo(customer1); - assertThat(result2).isEqualTo(customer2); - reactiveTemplate.delete(result1).block(); // cleanup - reactiveTemplate.delete(result2).block(); // cleanup - - Iterable personsToInsert = IntStream.range(0, 101) - .mapToObj(age -> Person.builder().id(nextId()) - .firstName("Gregor") - .age(age).build()) - .collect(Collectors.toList()); - reactiveTemplate.insertAll(personsToInsert).blockLast(); - - @SuppressWarnings("CastCanBeRemovedNarrowingVariableType") - List ids = ((List) personsToInsert).stream().map(Person::getId).toList(); - List result = reactiveTemplate.findByIds(ids, Person.class).collectList().block(); - assertThat(result).hasSameElementsAs(personsToInsert); - } + Person customer1 = new Person(nextId(), "Dave"); + Person customer2 = new Person(nextId(), "James"); + reactiveTemplate.insertAll(List.of(customer1, customer2)).blockLast(); + + Person result1 = findById(customer1.getId(), Person.class); + Person result2 = findById(customer2.getId(), Person.class); + assertThat(result1).isEqualTo(customer1); + assertThat(result2).isEqualTo(customer2); + reactiveTemplate.delete(result1).block(); // cleanup + reactiveTemplate.delete(result2).block(); // cleanup + + Iterable personsToInsert = IntStream.range(0, 101) + .mapToObj(age -> Person.builder().id(nextId()) + .firstName("Gregor") + .age(age).build()) + .collect(Collectors.toList()); + reactiveTemplate.insertAll(personsToInsert).blockLast(); + + @SuppressWarnings("CastCanBeRemovedNarrowingVariableType") + List ids = ((List) personsToInsert).stream().map(Person::getId).toList(); + List result = reactiveTemplate.findByIds(ids, Person.class).collectList().block(); + assertThat(result).hasSameElementsAs(personsToInsert); } @Test public void insertAllWithSetName_shouldInsertAllDocuments() { - if (serverVersionSupport.isBatchWriteSupported()) { - Person customer1 = new Person(nextId(), "Dave"); - Person customer2 = new Person(nextId(), "James"); - reactiveTemplate.insertAll(List.of(customer1, customer2), OVERRIDE_SET_NAME).blockLast(); - - Person result1 = findById(customer1.getId(), Person.class, OVERRIDE_SET_NAME); - Person result2 = findById(customer2.getId(), Person.class, OVERRIDE_SET_NAME); - assertThat(result1).isEqualTo(customer1); - assertThat(result2).isEqualTo(customer2); - } + Person customer1 = new Person(nextId(), "Dave"); + Person customer2 = new Person(nextId(), "James"); + reactiveTemplate.insertAll(List.of(customer1, customer2), OVERRIDE_SET_NAME).blockLast(); + + Person result1 = findById(customer1.getId(), Person.class, OVERRIDE_SET_NAME); + Person result2 = findById(customer2.getId(), Person.class, OVERRIDE_SET_NAME); + assertThat(result1).isEqualTo(customer1); + assertThat(result2).isEqualTo(customer2); } @Test public void insertAll_rejectsDuplicateId() { - if (serverVersionSupport.isBatchWriteSupported()) { - Person person = new Person(id, "Amol"); - person.setAge(28); - - StepVerifier.create(reactiveTemplate.insertAll(List.of(person, person))) - .expectError(AerospikeException.BatchRecordArray.class) - .verify(); - } + Person person = new Person(id, "Amol"); + person.setAge(28); + + StepVerifier.create(reactiveTemplate.insertAll(List.of(person, person))) + .expectError(AerospikeException.BatchRecordArray.class) + .verify(); } @Test public void insertAllWithSetName_rejectsDuplicateId() { - if (serverVersionSupport.isBatchWriteSupported()) { - Person person = new Person(id, "Amol"); - person.setAge(28); - - StepVerifier.create(reactiveTemplate.insertAll(List.of(person, person), OVERRIDE_SET_NAME)) - .expectError(AerospikeException.BatchRecordArray.class) - .verify(); - } + Person person = new Person(id, "Amol"); + person.setAge(28); + + StepVerifier.create(reactiveTemplate.insertAll(List.of(person, person), OVERRIDE_SET_NAME)) + .expectError(AerospikeException.BatchRecordArray.class) + .verify(); } } diff --git a/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateSaveRelatedTests.java b/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateSaveRelatedTests.java index 6a6040179..b7cffb9be 100644 --- a/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateSaveRelatedTests.java +++ b/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateSaveRelatedTests.java @@ -252,61 +252,49 @@ public void save_rejectsNullObjectToBeSaved() { @Test public void saveAll_shouldSaveAllDocuments() { - // batch delete operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - Person customer1 = new Person(nextId(), "Dave"); - Person customer2 = new Person(nextId(), "James"); - reactiveTemplate.saveAll(List.of(customer1, customer2)).blockLast(); - - Person result1 = findById(customer1.getId(), Person.class); - Person result2 = findById(customer2.getId(), Person.class); - assertThat(result1).isEqualTo(customer1); - assertThat(result2).isEqualTo(customer2); - reactiveTemplate.delete(result1).block(); // cleanup - reactiveTemplate.delete(result2).block(); // cleanup - } + Person customer1 = new Person(nextId(), "Dave"); + Person customer2 = new Person(nextId(), "James"); + reactiveTemplate.saveAll(List.of(customer1, customer2)).blockLast(); + + Person result1 = findById(customer1.getId(), Person.class); + Person result2 = findById(customer2.getId(), Person.class); + assertThat(result1).isEqualTo(customer1); + assertThat(result2).isEqualTo(customer2); + reactiveTemplate.delete(result1).block(); // cleanup + reactiveTemplate.delete(result2).block(); // cleanup } @Test public void saveAllWithSetName_shouldSaveAllDocuments() { - // batch delete operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - Person customer1 = new Person(nextId(), "Dave"); - Person customer2 = new Person(nextId(), "James"); - reactiveTemplate.saveAll(List.of(customer1, customer2), OVERRIDE_SET_NAME).blockLast(); - - Person result1 = findById(customer1.getId(), Person.class, OVERRIDE_SET_NAME); - Person result2 = findById(customer2.getId(), Person.class, OVERRIDE_SET_NAME); - assertThat(result1).isEqualTo(customer1); - assertThat(result2).isEqualTo(customer2); - reactiveTemplate.delete(result1, OVERRIDE_SET_NAME).block(); // cleanup - reactiveTemplate.delete(result2, OVERRIDE_SET_NAME).block(); // cleanup - } + Person customer1 = new Person(nextId(), "Dave"); + Person customer2 = new Person(nextId(), "James"); + reactiveTemplate.saveAll(List.of(customer1, customer2), OVERRIDE_SET_NAME).blockLast(); + + Person result1 = findById(customer1.getId(), Person.class, OVERRIDE_SET_NAME); + Person result2 = findById(customer2.getId(), Person.class, OVERRIDE_SET_NAME); + assertThat(result1).isEqualTo(customer1); + assertThat(result2).isEqualTo(customer2); + reactiveTemplate.delete(result1, OVERRIDE_SET_NAME).block(); // cleanup + reactiveTemplate.delete(result2, OVERRIDE_SET_NAME).block(); // cleanup } @Test public void saveAll_rejectsDuplicateId() { - // batch delete operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - VersionedClass first = new VersionedClass(id, "foo"); - StepVerifier.create(reactiveTemplate.saveAll(List.of(first, first))) - .expectError(OptimisticLockingFailureException.class) - .verify(); - reactiveTemplate.delete(findById(id, VersionedClass.class)).block(); // cleanup - } + VersionedClass first = new VersionedClass(id, "foo"); + StepVerifier.create(reactiveTemplate.saveAll(List.of(first, first))) + .expectError(OptimisticLockingFailureException.class) + .verify(); + reactiveTemplate.delete(findById(id, VersionedClass.class)).block(); // cleanup } @Test public void saveAllWithSetName_rejectsDuplicateId() { - // batch delete operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - VersionedClass second = new VersionedClass(id, "foo"); - - StepVerifier.create(reactiveTemplate.saveAll(List.of(second, second), OVERRIDE_SET_NAME)) - .expectError(OptimisticLockingFailureException.class) - .verify(); - reactiveTemplate.delete(findById(id, VersionedClass.class, OVERRIDE_SET_NAME), OVERRIDE_SET_NAME) - .block(); // cleanup - } + VersionedClass second = new VersionedClass(id, "foo"); + + StepVerifier.create(reactiveTemplate.saveAll(List.of(second, second), OVERRIDE_SET_NAME)) + .expectError(OptimisticLockingFailureException.class) + .verify(); + reactiveTemplate.delete(findById(id, VersionedClass.class, OVERRIDE_SET_NAME), OVERRIDE_SET_NAME) + .block(); // cleanup } } diff --git a/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateUpdateTests.java b/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateUpdateTests.java index 624334366..76a98fb09 100644 --- a/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateUpdateTests.java +++ b/src/test/java/org/springframework/data/aerospike/core/reactive/ReactiveAerospikeTemplateUpdateTests.java @@ -368,69 +368,60 @@ public void TestAddToMapSpecifyingMapFieldOnlyWithSetName() { @Test public void updateAllIfDocumentsChanged() { - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - int age1 = 140335200; - int age2 = 177652800; - Person person1 = new Person(id, "Wolfgang", age1); - Person person2 = new Person(nextId(), "Johann", age2); - reactiveTemplate.insertAll(List.of(person1, person2)).blockLast(); - - person1.setFirstName("Wolfgang M"); - person2.setFirstName("Johann B"); - reactiveTemplate.updateAll(List.of(person1, person2)).blockLast(); - - Person result1 = reactiveTemplate.findById(person1.getId(), Person.class).block(); - Person result2 = reactiveTemplate.findById(person2.getId(), Person.class).block(); - assertThat(result1.getAge()).isEqualTo(age1); - assertThat(result1.getFirstName()).isEqualTo("Wolfgang M"); - assertThat(result2.getAge()).isEqualTo(age2); - assertThat(result2.getFirstName()).isEqualTo("Johann B"); - - List persons = additionalAerospikeTestOperations.saveGeneratedPersons(101); - Iterable personsWithUpdate = persons.stream() - .peek(person -> person.setFirstName(person.getFirstName() + "_")).toList(); - - reactiveTemplate.updateAll(personsWithUpdate).blockLast(); - personsWithUpdate.forEach(person -> - assertThat(reactiveTemplate.findById(person.getId(), Person.class).block().getFirstName() - .equals(person.getFirstName())).isTrue()); - } + int age1 = 140335200; + int age2 = 177652800; + Person person1 = new Person(id, "Wolfgang", age1); + Person person2 = new Person(nextId(), "Johann", age2); + reactiveTemplate.insertAll(List.of(person1, person2)).blockLast(); + + person1.setFirstName("Wolfgang M"); + person2.setFirstName("Johann B"); + reactiveTemplate.updateAll(List.of(person1, person2)).blockLast(); + + Person result1 = reactiveTemplate.findById(person1.getId(), Person.class).block(); + Person result2 = reactiveTemplate.findById(person2.getId(), Person.class).block(); + assertThat(result1.getAge()).isEqualTo(age1); + assertThat(result1.getFirstName()).isEqualTo("Wolfgang M"); + assertThat(result2.getAge()).isEqualTo(age2); + assertThat(result2.getFirstName()).isEqualTo("Johann B"); + + List persons = additionalAerospikeTestOperations.saveGeneratedPersons(101); + Iterable personsWithUpdate = persons.stream() + .peek(person -> person.setFirstName(person.getFirstName() + "_")).toList(); + + reactiveTemplate.updateAll(personsWithUpdate).blockLast(); + personsWithUpdate.forEach(person -> + assertThat(reactiveTemplate.findById(person.getId(), Person.class).block().getFirstName() + .equals(person.getFirstName())).isTrue()); } @Test public void updateAllShouldThrowExceptionOnUpdateForNonExistingKey() { - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - Person person1 = new Person(id, "svenfirstName", 11); - Person person2 = new Person(nextId(), "svenfirstName", 11); - Person person3 = new Person(nextId(), "svenfirstName", 11); - reactiveTemplate.save(person3).block(); - // RecordExistsAction.UPDATE_ONLY - assertThatThrownBy(() -> reactiveTemplate.updateAll(List.of(person1, person2)).blockLast()) - .isInstanceOf(AerospikeException.BatchRecordArray.class); - - assertThat(reactiveTemplate.findById(person1.getId(), Person.class).block()).isNull(); - assertThat(reactiveTemplate.findById(person2.getId(), Person.class).block()).isNull(); - assertThat(reactiveTemplate.findById(person3.getId(), Person.class).block()).isEqualTo(person3); - } + Person person1 = new Person(id, "svenfirstName", 11); + Person person2 = new Person(nextId(), "svenfirstName", 11); + Person person3 = new Person(nextId(), "svenfirstName", 11); + reactiveTemplate.save(person3).block(); + // RecordExistsAction.UPDATE_ONLY + assertThatThrownBy(() -> reactiveTemplate.updateAll(List.of(person1, person2)).blockLast()) + .isInstanceOf(AerospikeException.BatchRecordArray.class); + + assertThat(reactiveTemplate.findById(person1.getId(), Person.class).block()).isNull(); + assertThat(reactiveTemplate.findById(person2.getId(), Person.class).block()).isNull(); + assertThat(reactiveTemplate.findById(person3.getId(), Person.class).block()).isEqualTo(person3); } @Test public void updateAllIfDocumentsNotChanged() { - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - int age1 = 140335200; - int age2 = 177652800; - Person person1 = new Person(id, "Wolfgang", age1); - Person person2 = new Person(nextId(), "Johann", age2); - reactiveTemplate.insertAll(List.of(person1, person2)).blockLast(); - reactiveTemplate.updateAll(List.of(person1, person2)).blockLast(); - - Person result1 = reactiveTemplate.findById(person1.getId(), Person.class).block(); - Person result2 = reactiveTemplate.findById(person2.getId(), Person.class).block(); - assertThat(result1.getAge()).isEqualTo(age1); - assertThat(result2.getAge()).isEqualTo(age2); - } + int age1 = 140335200; + int age2 = 177652800; + Person person1 = new Person(id, "Wolfgang", age1); + Person person2 = new Person(nextId(), "Johann", age2); + reactiveTemplate.insertAll(List.of(person1, person2)).blockLast(); + reactiveTemplate.updateAll(List.of(person1, person2)).blockLast(); + + Person result1 = reactiveTemplate.findById(person1.getId(), Person.class).block(); + Person result2 = reactiveTemplate.findById(person2.getId(), Person.class).block(); + assertThat(result1.getAge()).isEqualTo(age1); + assertThat(result2.getAge()).isEqualTo(age2); } } diff --git a/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateDeleteTests.java b/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateDeleteTests.java index b6bb06a8e..d5d679f61 100644 --- a/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateDeleteTests.java +++ b/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateDeleteTests.java @@ -171,19 +171,17 @@ public void deleteById_returnsFalseIfValueIsAbsent() { @Test public void deleteByGroupedKeys() { - if (serverVersionSupport.isBatchWriteSupported()) { - List persons = additionalAerospikeTestOperations.saveGeneratedPersons(5); - List personsIds = persons.stream().map(Person::getId).toList(); - List customers = additionalAerospikeTestOperations.saveGeneratedCustomers(3); - List customersIds = customers.stream().map(Customer::getId).toList(); + List persons = additionalAerospikeTestOperations.saveGeneratedPersons(5); + List personsIds = persons.stream().map(Person::getId).toList(); + List customers = additionalAerospikeTestOperations.saveGeneratedCustomers(3); + List customersIds = customers.stream().map(Customer::getId).toList(); - GroupedKeys groupedKeys = getGroupedKeys(persons, customers); + GroupedKeys groupedKeys = getGroupedKeys(persons, customers); - template.deleteByIds(groupedKeys); + template.deleteByIds(groupedKeys); - assertThat(template.findByIds(personsIds, Person.class)).isEmpty(); - assertThat(template.findByIds(customersIds, Customer.class)).isEmpty(); - } + assertThat(template.findByIds(personsIds, Person.class)).isEmpty(); + assertThat(template.findByIds(customersIds, Customer.class)).isEmpty(); } GroupedKeys getGroupedKeys(Collection persons, Collection customers) { @@ -249,188 +247,164 @@ public void deleteByType_NullTypeThrowsException() { @Test public void deleteByIds_rejectsDuplicateIds() { - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - String id1 = nextId(); - DocumentWithExpiration document1 = new DocumentWithExpiration(id1); - DocumentWithExpiration document2 = new DocumentWithExpiration(id1); - template.save(document1); - template.save(document2); - - List ids = List.of(id1, id1); - assertThatThrownBy(() -> template.deleteByIds(ids, DocumentWithExpiration.class)) - .isInstanceOf(AerospikeException.BatchRecordArray.class) - .hasMessageContaining("Batch failed"); - } + String id1 = nextId(); + DocumentWithExpiration document1 = new DocumentWithExpiration(id1); + DocumentWithExpiration document2 = new DocumentWithExpiration(id1); + template.save(document1); + template.save(document2); + + List ids = List.of(id1, id1); + assertThatThrownBy(() -> template.deleteByIds(ids, DocumentWithExpiration.class)) + .isInstanceOf(AerospikeException.BatchRecordArray.class) + .hasMessageContaining("Batch failed"); } @Test public void deleteByIds_ShouldDeleteAllDocuments() { - // batch delete operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - String id1 = nextId(); - String id2 = nextId(); - template.save(new DocumentWithExpiration(id1)); - template.save(new DocumentWithExpiration(id2)); - - List ids = List.of(id1, id2); - template.deleteByIds(ids, DocumentWithExpiration.class); - assertThat(template.findByIds(ids, DocumentWithExpiration.class)).isEmpty(); - - List persons = additionalAerospikeTestOperations.saveGeneratedPersons(101); - ids = persons.stream().map(Person::getId).toList(); - template.deleteByIds(ids, Person.class); - assertThat(template.findByIds(ids, Person.class)).isEmpty(); - - List persons2 = additionalAerospikeTestOperations.saveGeneratedPersons(1001); - ids = persons2.stream().map(Person::getId).toList(); - template.deleteByIds(ids, Person.class); - assertThat(template.findByIds(ids, Person.class)).isEmpty(); - } + String id1 = nextId(); + String id2 = nextId(); + template.save(new DocumentWithExpiration(id1)); + template.save(new DocumentWithExpiration(id2)); + + List ids = List.of(id1, id2); + template.deleteByIds(ids, DocumentWithExpiration.class); + assertThat(template.findByIds(ids, DocumentWithExpiration.class)).isEmpty(); + + List persons = additionalAerospikeTestOperations.saveGeneratedPersons(101); + ids = persons.stream().map(Person::getId).toList(); + template.deleteByIds(ids, Person.class); + assertThat(template.findByIds(ids, Person.class)).isEmpty(); + + List persons2 = additionalAerospikeTestOperations.saveGeneratedPersons(1001); + ids = persons2.stream().map(Person::getId).toList(); + template.deleteByIds(ids, Person.class); + assertThat(template.findByIds(ids, Person.class)).isEmpty(); } @Test public void deleteByIds_ShouldDeleteAllDocumentsWithSetName() { - // batch delete operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - String id1 = nextId(); - String id2 = nextId(); - template.save(new DocumentWithExpiration(id1), OVERRIDE_SET_NAME); - template.save(new DocumentWithExpiration(id2), OVERRIDE_SET_NAME); + String id1 = nextId(); + String id2 = nextId(); + template.save(new DocumentWithExpiration(id1), OVERRIDE_SET_NAME); + template.save(new DocumentWithExpiration(id2), OVERRIDE_SET_NAME); - List ids = List.of(id1, id2); - template.deleteByIds(ids, OVERRIDE_SET_NAME); + List ids = List.of(id1, id2); + template.deleteByIds(ids, OVERRIDE_SET_NAME); - assertThat(template.findByIds(ids, DocumentWithExpiration.class, OVERRIDE_SET_NAME)).isEmpty(); - } + assertThat(template.findByIds(ids, DocumentWithExpiration.class, OVERRIDE_SET_NAME)).isEmpty(); } @Test public void deleteAll_rejectsDuplicateIds() { - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - String id1 = nextId(); - DocumentWithExpiration document1 = new DocumentWithExpiration(id1); - DocumentWithExpiration document2 = new DocumentWithExpiration(id1); - template.save(document1); - template.save(document2); - - assertThatThrownBy(() -> template.deleteAll(List.of(document1, document2))) - .isInstanceOf(AerospikeException.BatchRecordArray.class) - .hasMessageContaining("Batch failed"); - } + String id1 = nextId(); + DocumentWithExpiration document1 = new DocumentWithExpiration(id1); + DocumentWithExpiration document2 = new DocumentWithExpiration(id1); + template.save(document1); + template.save(document2); + + assertThatThrownBy(() -> template.deleteAll(List.of(document1, document2))) + .isInstanceOf(AerospikeException.BatchRecordArray.class) + .hasMessageContaining("Batch failed"); } @Test public void deleteAll_ShouldDeleteAllDocuments() { - // batch delete operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - String id1 = nextId(); - String id2 = nextId(); - DocumentWithExpiration document1 = new DocumentWithExpiration(id1); - DocumentWithExpiration document2 = new DocumentWithExpiration(id2); - template.save(document1); - template.save(document2); - - template.deleteAll(List.of(document1, document2)); - assertThat(template.findByIds(List.of(id1, id2), DocumentWithExpiration.class)).isEmpty(); - - List persons = additionalAerospikeTestOperations.saveGeneratedPersons(101); - template.deleteAll(persons); - List personsIds = persons.stream().map(Person::getId).toList(); - assertThat(template.findByIds(personsIds, Person.class)).isEmpty(); - - List persons2 = additionalAerospikeTestOperations.saveGeneratedPersons(1001); - template.deleteAll(persons2); - personsIds = persons2.stream().map(Person::getId).toList(); - assertThat(template.findByIds(personsIds, Person.class)).isEmpty(); - } + String id1 = nextId(); + String id2 = nextId(); + DocumentWithExpiration document1 = new DocumentWithExpiration(id1); + DocumentWithExpiration document2 = new DocumentWithExpiration(id2); + template.save(document1); + template.save(document2); + + template.deleteAll(List.of(document1, document2)); + assertThat(template.findByIds(List.of(id1, id2), DocumentWithExpiration.class)).isEmpty(); + + List persons = additionalAerospikeTestOperations.saveGeneratedPersons(101); + template.deleteAll(persons); + List personsIds = persons.stream().map(Person::getId).toList(); + assertThat(template.findByIds(personsIds, Person.class)).isEmpty(); + + List persons2 = additionalAerospikeTestOperations.saveGeneratedPersons(1001); + template.deleteAll(persons2); + personsIds = persons2.stream().map(Person::getId).toList(); + assertThat(template.findByIds(personsIds, Person.class)).isEmpty(); } @Test public void deleteAll_ShouldDeleteAllDocumentsWithSetName() { - // batch delete operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - String id1 = nextId(); - String id2 = nextId(); - DocumentWithExpiration document1 = new DocumentWithExpiration(id1); - DocumentWithExpiration document2 = new DocumentWithExpiration(id2); - template.saveAll(List.of(document1, document2), OVERRIDE_SET_NAME); + String id1 = nextId(); + String id2 = nextId(); + DocumentWithExpiration document1 = new DocumentWithExpiration(id1); + DocumentWithExpiration document2 = new DocumentWithExpiration(id2); + template.saveAll(List.of(document1, document2), OVERRIDE_SET_NAME); - template.deleteAll(List.of(document1, document2), OVERRIDE_SET_NAME); + template.deleteAll(List.of(document1, document2), OVERRIDE_SET_NAME); - assertThat(template.findByIds(List.of(id1, id2), DocumentWithExpiration.class, OVERRIDE_SET_NAME)).isEmpty(); - } + assertThat(template.findByIds(List.of(id1, id2), DocumentWithExpiration.class, OVERRIDE_SET_NAME)).isEmpty(); } @Test public void deleteAll_ShouldDeleteAllDocumentsBeforeGivenLastUpdateTime() { - // batch delete operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - String id1 = nextId(); - String id2 = nextId(); - CollectionOfObjects document1 = new CollectionOfObjects(id1, List.of("test1")); - CollectionOfObjects document2 = new CollectionOfObjects(id2, List.of("test2")); - - template.save(document1); - AwaitilityUtils.wait(1, MILLISECONDS); - - Instant lastUpdateTime = Instant.now(); - Instant inFuture = Instant.ofEpochMilli(lastUpdateTime.toEpochMilli() + 10000); - template.save(document2); - - // make sure document1 has lastUpdateTime less than specified millis - List resultsWithLutLtMillis = - runLastUpdateTimeQuery(lastUpdateTime.toEpochMilli(), FilterOperation.LT, CollectionOfObjects.class); - assertThat(resultsWithLutLtMillis.get(0).getId()).isEqualTo(document1.getId()); - assertThat(resultsWithLutLtMillis.get(0).getCollection().iterator().next()) - .isEqualTo(document1.getCollection().iterator().next()); - - assertThatThrownBy(() -> template.deleteAll(CollectionOfObjects.class, inFuture)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageMatching("Last update time (.*) must be less than the current time"); - - template.deleteAll(CollectionOfObjects.class, lastUpdateTime); - assertThat(template.findByIds(List.of(id1, id2), CollectionOfObjects.class)).hasSize(1); - CollectionOfObjects result = template.findByIds(List.of(id1, id2), CollectionOfObjects.class).get(0); - assertThat(result.getId()).isEqualTo(document2.getId()); - assertThat(result.getCollection().iterator().next()).isEqualTo(document2.getCollection().iterator().next()); - - List persons = additionalAerospikeTestOperations.saveGeneratedPersons(101); - AwaitilityUtils.wait(1, MILLISECONDS); - lastUpdateTime = Instant.now(); - AwaitilityUtils.wait(1, MILLISECONDS); - Person newPerson = new Person(nextId(), "testFirstName"); - template.save(newPerson); - persons.add(newPerson); - - template.deleteAll(template.getSetName(Person.class), lastUpdateTime); - List personsIds = persons.stream().map(Person::getId).toList(); - assertThat(template.findByIds(personsIds, Person.class)).contains(newPerson); - - List persons2 = additionalAerospikeTestOperations.saveGeneratedPersons(1001); - template.deleteAll(Person.class, lastUpdateTime); // persons2 were saved after the given time - personsIds = persons2.stream().map(Person::getId).toList(); - assertThat(template.findByIds(personsIds, Person.class)).containsExactlyElementsOf(persons2); - } + String id1 = nextId(); + String id2 = nextId(); + CollectionOfObjects document1 = new CollectionOfObjects(id1, List.of("test1")); + CollectionOfObjects document2 = new CollectionOfObjects(id2, List.of("test2")); + + template.save(document1); + AwaitilityUtils.wait(1, MILLISECONDS); + + Instant lastUpdateTime = Instant.now(); + Instant inFuture = Instant.ofEpochMilli(lastUpdateTime.toEpochMilli() + 10000); + template.save(document2); + + // make sure document1 has lastUpdateTime less than specified millis + List resultsWithLutLtMillis = + runLastUpdateTimeQuery(lastUpdateTime.toEpochMilli(), FilterOperation.LT, CollectionOfObjects.class); + assertThat(resultsWithLutLtMillis.get(0).getId()).isEqualTo(document1.getId()); + assertThat(resultsWithLutLtMillis.get(0).getCollection().iterator().next()) + .isEqualTo(document1.getCollection().iterator().next()); + + assertThatThrownBy(() -> template.deleteAll(CollectionOfObjects.class, inFuture)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageMatching("Last update time (.*) must be less than the current time"); + + template.deleteAll(CollectionOfObjects.class, lastUpdateTime); + assertThat(template.findByIds(List.of(id1, id2), CollectionOfObjects.class)).hasSize(1); + CollectionOfObjects result = template.findByIds(List.of(id1, id2), CollectionOfObjects.class).get(0); + assertThat(result.getId()).isEqualTo(document2.getId()); + assertThat(result.getCollection().iterator().next()).isEqualTo(document2.getCollection().iterator().next()); + + List persons = additionalAerospikeTestOperations.saveGeneratedPersons(101); + AwaitilityUtils.wait(1, MILLISECONDS); + lastUpdateTime = Instant.now(); + AwaitilityUtils.wait(1, MILLISECONDS); + Person newPerson = new Person(nextId(), "testFirstName"); + template.save(newPerson); + persons.add(newPerson); + + template.deleteAll(template.getSetName(Person.class), lastUpdateTime); + List personsIds = persons.stream().map(Person::getId).toList(); + assertThat(template.findByIds(personsIds, Person.class)).contains(newPerson); + + List persons2 = additionalAerospikeTestOperations.saveGeneratedPersons(1001); + template.deleteAll(Person.class, lastUpdateTime); // persons2 were saved after the given time + personsIds = persons2.stream().map(Person::getId).toList(); + assertThat(template.findByIds(personsIds, Person.class)).containsExactlyElementsOf(persons2); } @Test public void deleteAll_VersionsMismatch() { - // batch delete operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - String id1 = "id1"; - VersionedClass document1 = new VersionedClass(id1, "test1"); - String id2 = "id2"; - VersionedClass document2 = new VersionedClass(id2, "test2"); - template.save(document1); - template.save(document2); - - document2.setVersion(232); - assertThatThrownBy(() -> template.deleteAll(List.of(document1, document2))) - .isInstanceOf(OptimisticLockingFailureException.class) - .hasMessageContaining("Failed to delete the record with ID 'id2' due to versions mismatch"); - } + String id1 = "id1"; + VersionedClass document1 = new VersionedClass(id1, "test1"); + String id2 = "id2"; + VersionedClass document2 = new VersionedClass(id2, "test2"); + template.save(document1); + template.save(document2); + + document2.setVersion(232); + assertThatThrownBy(() -> template.deleteAll(List.of(document1, document2))) + .isInstanceOf(OptimisticLockingFailureException.class) + .hasMessageContaining("Failed to delete the record with ID 'id2' due to versions mismatch"); } @Test diff --git a/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateFindAllTests.java b/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateFindAllTests.java index a39e84eab..41f12a956 100644 --- a/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateFindAllTests.java +++ b/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateFindAllTests.java @@ -67,12 +67,7 @@ public void findAll_findNothing() { assertThat(result).isEmpty(); // bring records back - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - template.insertAll(allPersons); - } else { - allPersons.forEach(person -> template.insert(person)); - } + template.insertAll(allPersons); } @Test diff --git a/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateFindByQueryProjectionTests.java b/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateFindByQueryProjectionTests.java index 02e77fa5a..ef53fcce4 100644 --- a/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateFindByQueryProjectionTests.java +++ b/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateFindByQueryProjectionTests.java @@ -50,16 +50,8 @@ public void beforeAllSetUp() { deleteOneByOne(allPersons); deleteOneByOne(allPersons, OVERRIDE_SET_NAME); - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - template.insertAll(allPersons); - template.insertAll(allPersons, OVERRIDE_SET_NAME); - } else { - allPersons.forEach(person -> { - template.insert(person); - template.insert(person, OVERRIDE_SET_NAME); - }); - } + template.insertAll(allPersons); + template.insertAll(allPersons, OVERRIDE_SET_NAME); } @Override @@ -68,15 +60,8 @@ public void setUp() { super.setUp(); template.deleteAll(Person.class); template.deleteAll(OVERRIDE_SET_NAME); - if (serverVersionSupport.isBatchWriteSupported()) { - template.insertAll(allPersons); - template.insertAll(allPersons, OVERRIDE_SET_NAME); - } else { - allPersons.forEach(person -> { - template.insert(person); - template.insert(person, OVERRIDE_SET_NAME); - }); - } + template.insertAll(allPersons); + template.insertAll(allPersons, OVERRIDE_SET_NAME); } @AfterAll diff --git a/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateFindByQueryTests.java b/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateFindByQueryTests.java index 1060703c5..2b404d3b1 100644 --- a/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateFindByQueryTests.java +++ b/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateFindByQueryTests.java @@ -81,16 +81,9 @@ public void beforeAllSetUp() { template.deleteAll(Person.class); template.deleteAll(OVERRIDE_SET_NAME); - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - template.insertAll(allPersons); - template.insertAll(allPersons, OVERRIDE_SET_NAME); - } else { - allPersons.forEach(person -> { - template.insert(person); - template.insert(person, OVERRIDE_SET_NAME); - }); - } + template.insertAll(allPersons); + template.insertAll(allPersons, OVERRIDE_SET_NAME); + additionalAerospikeTestOperations.createIndex(Person.class, "person_first_name_index", "firstName", IndexType.STRING); } @@ -103,14 +96,8 @@ public void setUp() { @AfterAll public void afterAll() { - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - template.deleteAll(allPersons); - template.deleteAll(allPersons, OVERRIDE_SET_NAME); - } else { - deleteOneByOne(allPersons); - deleteOneByOne(allPersons, OVERRIDE_SET_NAME); - } + template.deleteAll(allPersons); + template.deleteAll(allPersons, OVERRIDE_SET_NAME); additionalAerospikeTestOperations.dropIndex(Person.class, "person_first_name_index"); } diff --git a/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateInsertTests.java b/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateInsertTests.java index 07003764a..d6fa602c2 100644 --- a/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateInsertTests.java +++ b/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateInsertTests.java @@ -239,33 +239,30 @@ public void insertsOnlyFirstDocumentAndNextAttemptsShouldFailWithDuplicateKeyExc @Test public void insertAll_insertsAllDocuments() { - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - List persons = IntStream.range(1, 10) - .mapToObj(age -> Person.builder().id(nextId()) - .firstName("Gregor") - .age(age).build()) - .collect(Collectors.toList()); - template.insertAll(persons); - - List result = template.findByIds(persons.stream().map(Person::getId) - .collect(Collectors.toList()), Person.class); - assertThat(result).hasSameElementsAs(persons); - template.deleteAll(Person.class); // cleanup - - Iterable personsToInsert = IntStream.range(0, 101) - .mapToObj(age -> Person.builder().id(nextId()) - .firstName("Gregor") - .age(age).build()) - .collect(Collectors.toList()); - template.insertAll(personsToInsert); - - @SuppressWarnings("CastCanBeRemovedNarrowingVariableType") - List ids = ((List) personsToInsert).stream().map(Person::getId) - .collect(Collectors.toList()); - result = template.findByIds(ids, Person.class); - assertThat(result).hasSameElementsAs(personsToInsert); - } + List persons = IntStream.range(1, 10) + .mapToObj(age -> Person.builder().id(nextId()) + .firstName("Gregor") + .age(age).build()) + .collect(Collectors.toList()); + template.insertAll(persons); + + List result = template.findByIds(persons.stream().map(Person::getId) + .collect(Collectors.toList()), Person.class); + assertThat(result).hasSameElementsAs(persons); + template.deleteAll(Person.class); // cleanup + + Iterable personsToInsert = IntStream.range(0, 101) + .mapToObj(age -> Person.builder().id(nextId()) + .firstName("Gregor") + .age(age).build()) + .collect(Collectors.toList()); + template.insertAll(personsToInsert); + + @SuppressWarnings("CastCanBeRemovedNarrowingVariableType") + List ids = ((List) personsToInsert).stream().map(Person::getId) + .collect(Collectors.toList()); + result = template.findByIds(ids, Person.class); + assertThat(result).hasSameElementsAs(personsToInsert); } @Test @@ -276,12 +273,7 @@ public void insertAllWithSetName_insertsAllDocuments() { .age(age).build()) .collect(Collectors.toList()); - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - template.insertAll(persons, OVERRIDE_SET_NAME); - } else { - persons.forEach(person -> template.insert(person, OVERRIDE_SET_NAME)); - } + template.insertAll(persons, OVERRIDE_SET_NAME); List result = template.findByIds(persons.stream().map(Person::getId) .collect(Collectors.toList()), Person.class, OVERRIDE_SET_NAME); @@ -291,31 +283,25 @@ public void insertAllWithSetName_insertsAllDocuments() { @Test public void insertAll_rejectsDuplicateIds() { - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - VersionedClass second = new VersionedClass("as-5440", "foo"); - assertThatThrownBy(() -> template.insertAll(List.of(second, second))) - .isInstanceOf(OptimisticLockingFailureException.class) - .hasMessageContaining("Failed to insert the record with ID 'as-5440' due to versions mismatch"); - Assertions.assertEquals(1, second.getVersion()); - } + VersionedClass second = new VersionedClass("as-5440", "foo"); + assertThatThrownBy(() -> template.insertAll(List.of(second, second))) + .isInstanceOf(OptimisticLockingFailureException.class) + .hasMessageContaining("Failed to insert the record with ID 'as-5440' due to versions mismatch"); + Assertions.assertEquals(1, second.getVersion()); } @Test public void shouldInsertAllVersionedDocuments() { - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - VersionedClass first = new VersionedClass(id, "foo"); - VersionedClass second = new VersionedClass(nextId(), "foo", 1); - VersionedClass third = new VersionedClass(nextId(), "foo", 2); - - // initially given versions are ignored - // RecordExistsAction.CREATE_ONLY is used - assertThatNoException().isThrownBy(() -> template.insertAll(List.of(first, second, third))); - - assertThat(first.getVersion() == 1).isTrue(); - assertThat(second.getVersion() == 1).isTrue(); - assertThat(third.getVersion() == 1).isTrue(); - } + VersionedClass first = new VersionedClass(id, "foo"); + VersionedClass second = new VersionedClass(nextId(), "foo", 1); + VersionedClass third = new VersionedClass(nextId(), "foo", 2); + + // initially given versions are ignored + // RecordExistsAction.CREATE_ONLY is used + assertThatNoException().isThrownBy(() -> template.insertAll(List.of(first, second, third))); + + assertThat(first.getVersion() == 1).isTrue(); + assertThat(second.getVersion() == 1).isTrue(); + assertThat(third.getVersion() == 1).isTrue(); } } diff --git a/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateSaveTests.java b/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateSaveTests.java index dbd4013e8..05fd76da5 100644 --- a/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateSaveTests.java +++ b/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateSaveTests.java @@ -333,12 +333,7 @@ public void shouldSaveAllAndSetVersion() { assertThat(second.getVersion()).isEqualTo(1); second.setVersion(second.getVersion()); - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - template.saveAll(List.of(first, second)); - } else { - List.of(first, second).forEach(document -> template.save(document)); - } + template.saveAll(List.of(first, second)); assertThat(first.getVersion()).isEqualTo(1); assertThat(second.getVersion()).isEqualTo(2); @@ -351,12 +346,7 @@ public void shouldSaveAllAndSetVersion() { public void shouldSaveAllAndSetVersionWithSetName() { VersionedClass first = new VersionedClass(id, "foo"); VersionedClass second = new VersionedClass(nextId(), "foo"); - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - template.saveAll(List.of(first, second), OVERRIDE_SET_NAME); - } else { - List.of(first, second).forEach(person -> template.save(person, OVERRIDE_SET_NAME)); - } + template.saveAll(List.of(first, second), OVERRIDE_SET_NAME); assertThat(first.getVersion()).isEqualTo(1); assertThat(second.getVersion()).isEqualTo(1); @@ -367,25 +357,22 @@ public void shouldSaveAllAndSetVersionWithSetName() { @Test public void shouldSaveAllNotVersionedDocumentsIfAlreadyExist() { - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - Person john = new Person("id1", "John"); - Person jack = new Person("id2", "Jack"); - template.save(jack); // saving non-versioned document to create a new DB record - // If an object has no version property, RecordExistsAction.UPDATE is used - // If a corresponding record does not exist it will be created, otherwise updated (an "upsert") - template.saveAll(List.of(john, jack)); - assertThat(template.findById("id1", Person.class)).isEqualTo(john); // DB record is created - assertThat(template.findById("id2", Person.class)).isEqualTo(jack); - template.delete(john); // cleanup - template.delete(jack); // cleanup - - Person person = new Person(id, "Amol"); - person.setAge(28); - template.save(person); - // If an object has no version property, RecordExistsAction.UPDATE is used - assertThatNoException().isThrownBy(() -> template.saveAll(List.of(person, person))); - template.delete(person); // cleanup - } + Person john = new Person("id1", "John"); + Person jack = new Person("id2", "Jack"); + template.save(jack); // saving non-versioned document to create a new DB record + // If an object has no version property, RecordExistsAction.UPDATE is used + // If a corresponding record does not exist it will be created, otherwise updated (an "upsert") + template.saveAll(List.of(john, jack)); + assertThat(template.findById("id1", Person.class)).isEqualTo(john); // DB record is created + assertThat(template.findById("id2", Person.class)).isEqualTo(jack); + template.delete(john); // cleanup + template.delete(jack); // cleanup + + Person person = new Person(id, "Amol"); + person.setAge(28); + template.save(person); + // If an object has no version property, RecordExistsAction.UPDATE is used + assertThatNoException().isThrownBy(() -> template.saveAll(List.of(person, person))); + template.delete(person); // cleanup } } diff --git a/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateSaveWithDuplicatesTests.java b/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateSaveWithDuplicatesTests.java index cf0a9bea9..87bf36ad2 100644 --- a/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateSaveWithDuplicatesTests.java +++ b/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateSaveWithDuplicatesTests.java @@ -47,50 +47,44 @@ public void afterAll() { @Test public void shouldSaveAllVersionedDocumentsAndSetVersionAndThrowExceptionIfDuplicatesWithinOneBatch() { - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - VersionedClass first = new VersionedClass("newId100", "foo"); - VersionedClass second = new VersionedClass("newId200", "foo"); + VersionedClass first = new VersionedClass("newId100", "foo"); + VersionedClass second = new VersionedClass("newId200", "foo"); - // The documents’ versions are equal to zero, meaning the documents have not been saved to the database yet - assertThat(first.getVersion()).isSameAs(0); - assertThat(second.getVersion()).isSameAs(0); + // The documents’ versions are equal to zero, meaning the documents have not been saved to the database yet + assertThat(first.getVersion()).isSameAs(0); + assertThat(second.getVersion()).isSameAs(0); - // An attempt to save the same versioned documents in one batch results in getting an exception - assertThatThrownBy(() -> template.saveAll(List.of(first, first, second, second))) - .isInstanceOf(OptimisticLockingFailureException.class) - .hasMessageFindingMatch("Failed to save the record with ID .* due to versions mismatch"); + // An attempt to save the same versioned documents in one batch results in getting an exception + assertThatThrownBy(() -> template.saveAll(List.of(first, first, second, second))) + .isInstanceOf(OptimisticLockingFailureException.class) + .hasMessageFindingMatch("Failed to save the record with ID .* due to versions mismatch"); - // The documents' versions get updated after they are read from the corresponding database records - assertThat(first.getVersion()).isSameAs(1); - assertThat(second.getVersion()).isSameAs(1); + // The documents' versions get updated after they are read from the corresponding database records + assertThat(first.getVersion()).isSameAs(1); + assertThat(second.getVersion()).isSameAs(1); - template.delete(first); // cleanup - template.delete(second); // cleanup - } + template.delete(first); // cleanup + template.delete(second); // cleanup } @Test public void shouldSaveAllVersionedDocumentsIfDuplicatesNotWithinOneBatch() { - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - // The same versioned documents can be saved if they are not in the same batch. - // This way, the generation counts of the corresponding database records can be used - // to update the documents’ versions each time. - VersionedClass newFirst = new VersionedClass("newId300", "foo"); - VersionedClass newSecond = new VersionedClass("newId400", "bar"); + // The same versioned documents can be saved if they are not in the same batch. + // This way, the generation counts of the corresponding database records can be used + // to update the documents’ versions each time. + VersionedClass newFirst = new VersionedClass("newId300", "foo"); + VersionedClass newSecond = new VersionedClass("newId400", "bar"); - assertThat(newFirst.getVersion()).isSameAs(0); - assertThat(newSecond.getVersion()).isSameAs(0); + assertThat(newFirst.getVersion()).isSameAs(0); + assertThat(newSecond.getVersion()).isSameAs(0); - template.saveAll(List.of(newFirst, newSecond)); - // Failed to save the record with ID 'newId2' due to versions mismatch - assertThat(newFirst.getVersion()).isSameAs(1); - assertThat(newSecond.getVersion()).isSameAs(1); + template.saveAll(List.of(newFirst, newSecond)); + // Failed to save the record with ID 'newId2' due to versions mismatch + assertThat(newFirst.getVersion()).isSameAs(1); + assertThat(newSecond.getVersion()).isSameAs(1); - template.saveAll(List.of(newFirst, newSecond)); - assertThat(newFirst.getVersion()).isSameAs(2); - assertThat(newSecond.getVersion()).isSameAs(2); - } + template.saveAll(List.of(newFirst, newSecond)); + assertThat(newFirst.getVersion()).isSameAs(2); + assertThat(newSecond.getVersion()).isSameAs(2); } } diff --git a/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateUpdateTests.java b/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateUpdateTests.java index 1482fa7c9..a68320c8a 100644 --- a/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateUpdateTests.java +++ b/src/test/java/org/springframework/data/aerospike/core/sync/AerospikeTemplateUpdateTests.java @@ -400,150 +400,138 @@ public void TestAddToMapSpecifyingMapFieldOnly() { @Test public void updateAllShouldThrowExceptionOnUpdateForNonExistingKey() { - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - // This class has a version field (class field annotated with @Version). - // The constructor does not receive the version, so it stays equal to zero - VersionedClass first = new VersionedClass("newId1", "foo"); - VersionedClass second = new VersionedClass("newId2", "bar"); - // The documents’ versions are equal to zero, meaning the documents have not been saved to the database yet - assertThat(first.getVersion() == 0).isTrue(); - assertThat(second.getVersion() == 0).isTrue(); - template.insert(first); - - // The document's version is equal to one meaning there is a corresponding DB record - assertThat(first.getVersion() == 1).isTrue(); - - // RecordExistsAction.UPDATE_ONLY - assertThatThrownBy(() -> template.updateAll(List.of(first, second))) // An attempt to update versioned - // documents without already existing DB records results in getting BatchRecordArray exception - .isInstanceOf(OptimisticLockingFailureException.class) - .hasMessageContaining("Failed to update the record with ID 'newId2' due to versions mismatch"); - assertThat(first.getVersion() == 2).isTrue(); // This document's version gets updated after it is read - // from the corresponding DB record - assertThat(second.getVersion() == 0).isTrue(); // This document's version stays equal to zero as there is - // no corresponding DB record - - assertThat(template.findById(first.getId(), VersionedClass.class)).isEqualTo(first); - assertThat(template.findById(second.getId(), VersionedClass.class)).isNull(); - - Person firstPerson = new Person("newId1", "foo"); - Person secondPerson = new Person("newId2", "bar"); // - template.insert(firstPerson); - // RecordExistsAction.UPDATE_ONLY - assertThatThrownBy(() -> template.updateAll(List.of(firstPerson, secondPerson))) - .isInstanceOf(AerospikeException.BatchRecordArray.class) - .hasMessageContaining("Batch failed"); - - assertThat(template.findById(firstPerson.getId(), Person.class)).isEqualTo(firstPerson); - assertThat(template.findById(secondPerson.getId(), Person.class)).isNull(); - } + // This class has a version field (class field annotated with @Version). + // The constructor does not receive the version, so it stays equal to zero + VersionedClass first = new VersionedClass("newId1", "foo"); + VersionedClass second = new VersionedClass("newId2", "bar"); + // The documents’ versions are equal to zero, meaning the documents have not been saved to the database yet + assertThat(first.getVersion() == 0).isTrue(); + assertThat(second.getVersion() == 0).isTrue(); + template.insert(first); + + // The document's version is equal to one meaning there is a corresponding DB record + assertThat(first.getVersion() == 1).isTrue(); + + // RecordExistsAction.UPDATE_ONLY + assertThatThrownBy(() -> template.updateAll(List.of(first, second))) // An attempt to update versioned + // documents without already existing DB records results in getting BatchRecordArray exception + .isInstanceOf(OptimisticLockingFailureException.class) + .hasMessageContaining("Failed to update the record with ID 'newId2' due to versions mismatch"); + assertThat(first.getVersion() == 2).isTrue(); // This document's version gets updated after it is read + // from the corresponding DB record + assertThat(second.getVersion() == 0).isTrue(); // This document's version stays equal to zero as there is + // no corresponding DB record + + assertThat(template.findById(first.getId(), VersionedClass.class)).isEqualTo(first); + assertThat(template.findById(second.getId(), VersionedClass.class)).isNull(); + + Person firstPerson = new Person("newId1", "foo"); + Person secondPerson = new Person("newId2", "bar"); // + template.insert(firstPerson); + // RecordExistsAction.UPDATE_ONLY + assertThatThrownBy(() -> template.updateAll(List.of(firstPerson, secondPerson))) + .isInstanceOf(AerospikeException.BatchRecordArray.class) + .hasMessageContaining("Batch failed"); + + assertThat(template.findById(firstPerson.getId(), Person.class)).isEqualTo(firstPerson); + assertThat(template.findById(secondPerson.getId(), Person.class)).isNull(); } @Test public void updateAllIfDocumentsNotChanged() { - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - int age1 = 140335200; - int age2 = 177652800; - Person person1 = new Person(id, "Wolfgang M", age1); - Person person2 = new Person(nextId(), "Johann B", age2); - template.insertAll(List.of(person1, person2)); - template.updateAll(List.of(person1, person2)); - - Person result1 = template.findById(person1.getId(), Person.class); - Person result2 = template.findById(person2.getId(), Person.class); - assertThat(result1.getAge()).isEqualTo(age1); - assertThat(result2.getAge()).isEqualTo(age2); - template.delete(result1); // cleanup - template.delete(result2); // cleanup - } + int age1 = 140335200; + int age2 = 177652800; + Person person1 = new Person(id, "Wolfgang M", age1); + Person person2 = new Person(nextId(), "Johann B", age2); + template.insertAll(List.of(person1, person2)); + template.updateAll(List.of(person1, person2)); + + Person result1 = template.findById(person1.getId(), Person.class); + Person result2 = template.findById(person2.getId(), Person.class); + assertThat(result1.getAge()).isEqualTo(age1); + assertThat(result2.getAge()).isEqualTo(age2); + template.delete(result1); // cleanup + template.delete(result2); // cleanup } @Test public void updateAllIfDocumentsChanged() { - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - int age1 = 140335200; - int age2 = 177652800; - Person person1 = new Person(id, "Wolfgang", age1); - Person person2 = new Person(nextId(), "Johann", age2); - template.insertAll(List.of(person1, person2)); - - person1.setFirstName("Wolfgang M"); - person2.setFirstName("Johann B"); - template.updateAll(List.of(person1, person2)); - - Person result1 = template.findById(person1.getId(), Person.class); - Person result2 = template.findById(person2.getId(), Person.class); - assertThat(result1.getAge()).isEqualTo(age1); - assertThat(result1.getFirstName()).isEqualTo("Wolfgang M"); - assertThat(result2.getAge()).isEqualTo(age2); - assertThat(result2.getFirstName()).isEqualTo("Johann B"); - template.delete(result1); // cleanup - template.delete(result2); // cleanup - - List persons = additionalAerospikeTestOperations.saveGeneratedPersons(101); - Iterable personsWithUpdate = persons.stream() - .peek(person -> person.setFirstName(person.getFirstName() + "_")).toList(); - template.updateAll(personsWithUpdate); - personsWithUpdate.forEach(person -> - assertThat(template.findById(person.getId(), Person.class).getFirstName() - .equals(person.getFirstName())).isTrue()); - - // This document has a version (class field annotated with @Version). - // The constructor does not receive the version parameter, so it stays equal to zero - VersionedClass first = new VersionedClass("id1", "foo"); - - // In this case non-zero versions get explicitly passed to the constructor - VersionedClass second = new VersionedClass("id2", "foo", 1); - VersionedClass third = new VersionedClass("id3", "foo", 2); - - // Insert multiple versioned documents to create new DB records - template.insertAll(List.of(first, second, third)); - - assertThat(first.getVersion() == 1).isTrue(); - // initial documents' versions are overridden by the versions from the created DB records - assertThat(second.getVersion() == 1).isTrue(); - assertThat(third.getVersion() == 1).isTrue(); - - first = new VersionedClass(first.getId(), "foobar1", first.getVersion()); - second = new VersionedClass(second.getId(), "foobar2", second.getVersion()); - third = new VersionedClass(third.getId(), "foobar3", third.getVersion()); - template.updateAll(List.of(first, second, third)); - - assertThat(template.findById(first.getId(), VersionedClass.class)).satisfies(doc -> { - assertThat(doc.getField()).isEqualTo("foobar1"); - assertThat(doc.getVersion()).isEqualTo(2); - }); - assertThat(template.findById(second.getId(), VersionedClass.class)).satisfies(doc -> { - assertThat(doc.getField()).isEqualTo("foobar2"); - assertThat(doc.getVersion()).isEqualTo(2); - }); - assertThat(template.findById(third.getId(), VersionedClass.class)).satisfies(doc -> { - assertThat(doc.getField()).isEqualTo("foobar3"); - assertThat(doc.getVersion()).isEqualTo(2); - }); - } + int age1 = 140335200; + int age2 = 177652800; + Person person1 = new Person(id, "Wolfgang", age1); + Person person2 = new Person(nextId(), "Johann", age2); + template.insertAll(List.of(person1, person2)); + + person1.setFirstName("Wolfgang M"); + person2.setFirstName("Johann B"); + template.updateAll(List.of(person1, person2)); + + Person result1 = template.findById(person1.getId(), Person.class); + Person result2 = template.findById(person2.getId(), Person.class); + assertThat(result1.getAge()).isEqualTo(age1); + assertThat(result1.getFirstName()).isEqualTo("Wolfgang M"); + assertThat(result2.getAge()).isEqualTo(age2); + assertThat(result2.getFirstName()).isEqualTo("Johann B"); + template.delete(result1); // cleanup + template.delete(result2); // cleanup + + List persons = additionalAerospikeTestOperations.saveGeneratedPersons(101); + Iterable personsWithUpdate = persons.stream() + .peek(person -> person.setFirstName(person.getFirstName() + "_")).toList(); + template.updateAll(personsWithUpdate); + personsWithUpdate.forEach(person -> + assertThat(template.findById(person.getId(), Person.class).getFirstName() + .equals(person.getFirstName())).isTrue()); + + // This document has a version (class field annotated with @Version). + // The constructor does not receive the version parameter, so it stays equal to zero + VersionedClass first = new VersionedClass("id1", "foo"); + + // In this case non-zero versions get explicitly passed to the constructor + VersionedClass second = new VersionedClass("id2", "foo", 1); + VersionedClass third = new VersionedClass("id3", "foo", 2); + + // Insert multiple versioned documents to create new DB records + template.insertAll(List.of(first, second, third)); + + assertThat(first.getVersion() == 1).isTrue(); + // initial documents' versions are overridden by the versions from the created DB records + assertThat(second.getVersion() == 1).isTrue(); + assertThat(third.getVersion() == 1).isTrue(); + + first = new VersionedClass(first.getId(), "foobar1", first.getVersion()); + second = new VersionedClass(second.getId(), "foobar2", second.getVersion()); + third = new VersionedClass(third.getId(), "foobar3", third.getVersion()); + template.updateAll(List.of(first, second, third)); + + assertThat(template.findById(first.getId(), VersionedClass.class)).satisfies(doc -> { + assertThat(doc.getField()).isEqualTo("foobar1"); + assertThat(doc.getVersion()).isEqualTo(2); + }); + assertThat(template.findById(second.getId(), VersionedClass.class)).satisfies(doc -> { + assertThat(doc.getField()).isEqualTo("foobar2"); + assertThat(doc.getVersion()).isEqualTo(2); + }); + assertThat(template.findById(third.getId(), VersionedClass.class)).satisfies(doc -> { + assertThat(doc.getField()).isEqualTo("foobar3"); + assertThat(doc.getVersion()).isEqualTo(2); + }); } @Test public void updateAllIfDocumentsNotChangedWithSetName() { - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - int age1 = 140335200; - int age2 = 177652800; - Person person1 = new Person(id, "Wolfgang", age1); - Person person2 = new Person(nextId(), "Johann", age2); - template.insertAll(List.of(person1, person2), OVERRIDE_SET_NAME); - template.updateAll(List.of(person1, person2), OVERRIDE_SET_NAME); - - Person result1 = template.findById(person1.getId(), Person.class, OVERRIDE_SET_NAME); - Person result2 = template.findById(person2.getId(), Person.class, OVERRIDE_SET_NAME); - assertThat(result1.getAge()).isEqualTo(age1); - assertThat(result2.getAge()).isEqualTo(age2); - template.delete(result1, OVERRIDE_SET_NAME); // cleanup - template.delete(result2, OVERRIDE_SET_NAME); // cleanup - } + int age1 = 140335200; + int age2 = 177652800; + Person person1 = new Person(id, "Wolfgang", age1); + Person person2 = new Person(nextId(), "Johann", age2); + template.insertAll(List.of(person1, person2), OVERRIDE_SET_NAME); + template.updateAll(List.of(person1, person2), OVERRIDE_SET_NAME); + + Person result1 = template.findById(person1.getId(), Person.class, OVERRIDE_SET_NAME); + Person result2 = template.findById(person2.getId(), Person.class, OVERRIDE_SET_NAME); + assertThat(result1.getAge()).isEqualTo(age1); + assertThat(result2.getAge()).isEqualTo(age2); + template.delete(result1, OVERRIDE_SET_NAME); // cleanup + template.delete(result2, OVERRIDE_SET_NAME); // cleanup } } diff --git a/src/test/java/org/springframework/data/aerospike/repository/query/blocking/delete/EqualsTests.java b/src/test/java/org/springframework/data/aerospike/repository/query/blocking/delete/EqualsTests.java index 907855dfd..2b7ff9214 100644 --- a/src/test/java/org/springframework/data/aerospike/repository/query/blocking/delete/EqualsTests.java +++ b/src/test/java/org/springframework/data/aerospike/repository/query/blocking/delete/EqualsTests.java @@ -85,12 +85,7 @@ void deleteAllByIds() { @Test void deleteAll() { - if (serverVersionSupport.isBatchWriteSupported()) { - // batch delete requires server ver. >= 6.0.0 - repository.deleteAll(List.of(dave, carter)); - } else { - List.of(dave, carter).forEach(repository::delete); - } + repository.deleteAll(List.of(dave, carter)); assertThat(repository.findAllById(List.of(dave.getId(), carter.getId()))).isEmpty(); // cleanup repository.save(dave); diff --git a/src/test/java/org/springframework/data/aerospike/util/AdditionalAerospikeTestOperations.java b/src/test/java/org/springframework/data/aerospike/util/AdditionalAerospikeTestOperations.java index 896901217..281428409 100644 --- a/src/test/java/org/springframework/data/aerospike/util/AdditionalAerospikeTestOperations.java +++ b/src/test/java/org/springframework/data/aerospike/util/AdditionalAerospikeTestOperations.java @@ -66,9 +66,9 @@ public void assertNoScansForSet(String setName) { @SneakyThrows public List getScans() { - String showCmd = "scan-show"; - if (serverVersionSupport.isQueryShowSupported()) { - showCmd = "query-show"; + String showCmd = "query-show"; + if (!serverVersionSupport.isSIndexCardinalitySupported()) { + throw new UnsupportedOperationException("Minimal supported Aerospike Server version is 6.1"); } Container.ExecResult execResult = aerospike.execInContainer("asinfo", "-v", showCmd); String stdout = execResult.getStdout(); @@ -87,14 +87,6 @@ private List getScanJobs(String stdout) { .build()); } - @SneakyThrows - public void killAllScans() { - Container.ExecResult execResult = aerospike.execInContainer("asinfo", "-v", "scan-abort-all:"); - assertThat(execResult.getStdout()) - .as("Scan jobs killed") - .contains("OK"); - } - public void deleteAllAndVerify(Class... entityClasses) { Arrays.asList(entityClasses).forEach(this::truncateSetOfEntityClass); Arrays.asList(entityClasses).forEach(this::awaitUntilSetIsEmpty); @@ -145,7 +137,8 @@ public void createIndex(String namespace, String setName, String indexName, Stri public void createIndex(String namespace, String setName, String indexName, String binName, IndexType indexType, IndexCollectionType indexCollectionType, CTX... ctx) { IndexCollectionType collType = indexCollectionType == null ? DEFAULT : indexCollectionType; - IndexUtils.createIndex(client, serverVersionSupport, namespace, setName, indexName, binName, indexType, collType, + IndexUtils.createIndex(client, serverVersionSupport, namespace, setName, indexName, binName, indexType, + collType, ctx); indexesRefresher.refreshIndexesCache(); } @@ -180,25 +173,15 @@ public void dropIndexes(Collection indexesToBeDropped) { } public void deleteAll(AerospikeRepository repository, Collection entities) { - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - try { - repository.deleteAll(entities); - } catch (AerospikeException.BatchRecordArray ignored) { - // KEY_NOT_FOUND ResultCode causes exception if there are no entities - } - } else { - entities.forEach(repository::delete); + try { + repository.deleteAll(entities); + } catch (AerospikeException.BatchRecordArray ignored) { + // KEY_NOT_FOUND ResultCode causes exception if there are no entities } } public void saveAll(AerospikeRepository repository, Collection entities) { - // batch write operations are supported starting with Server version 6.0+ - if (serverVersionSupport.isBatchWriteSupported()) { - repository.saveAll(entities); - } else { - entities.forEach(repository::save); - } + repository.saveAll(entities); } /**