diff --git a/pom.xml b/pom.xml index 474def963..5e1deca02 100644 --- a/pom.xml +++ b/pom.xml @@ -31,8 +31,9 @@ 4.1.2 3.3.0 1.6 - 7.2.1 - 7.1.0 + 8.1.2 + 8.1.2 + 8.1.2 3.6.1 3.1.6 2.12.7 @@ -194,14 +195,19 @@ com.aerospike - aerospike-client - ${aerospike-client} + aerospike-client-jdk8 + ${aerospike-client-jdk8} com.aerospike aerospike-reactor-client ${aerospike-reactor-client} + + com.aerospike + aerospike-proxy-client + ${aerospike-proxy-client} + joda-time joda-time @@ -248,12 +254,15 @@ com.aerospike - aerospike-client + aerospike-client-jdk8 com.aerospike aerospike-reactor-client - true + + + com.aerospike + aerospike-proxy-client com.esotericsoftware @@ -273,6 +282,26 @@ lombok provided + + io.netty + netty-transport + ${netty.version} + + + io.netty + netty-handler + ${netty.version} + + + io.netty + netty-transport-native-epoll + ${netty.version} + + + io.netty + netty-transport-native-kqueue + ${netty.version} + io.projectreactor @@ -302,7 +331,6 @@ org.awaitility awaitility ${awaitility} - test ch.qos.logback @@ -322,30 +350,6 @@ ${hibernate.validator} test - - io.netty - netty-transport - ${netty.version} - test - - - io.netty - netty-handler - ${netty.version} - test - - - io.netty - netty-transport-native-epoll - ${netty.version} - test - - - io.netty - netty-transport-native-kqueue - ${netty.version} - test - diff --git a/src/main/asciidoc/reference/aerospike-reactive-repositories.adoc b/src/main/asciidoc/reference/aerospike-reactive-repositories.adoc index a2fad131f..8013baace 100644 --- a/src/main/asciidoc/reference/aerospike-reactive-repositories.adoc +++ b/src/main/asciidoc/reference/aerospike-reactive-repositories.adoc @@ -55,7 +55,10 @@ public interface ReactivePersonRepository extends ReactiveAerospikeRepository Utils.getObjectsCount(node, namespace, setName)) + .mapToLong(node -> Utils.getObjectsCount(client, node, namespace, setName)) .sum(); return (nodes.length > 1) ? (totalObjects / replicationFactor) : totalObjects; @@ -1308,7 +1308,8 @@ public boolean indexExists(String indexName) { try { Node[] nodes = client.getNodes(); for (Node node : nodes) { - String response = Info.request(node, "sindex-exists:ns=" + namespace + ";indexname=" + indexName); + String response = sendInfoCommand(client, node, + "sindex-exists:ns=" + namespace + ";indexname=" + indexName); if (response == null) throw new AerospikeException("Null node response"); if (response.equalsIgnoreCase("true")) { 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 f4229c009..d6028d903 100644 --- a/src/main/java/org/springframework/data/aerospike/core/ReactiveAerospikeTemplate.java +++ b/src/main/java/org/springframework/data/aerospike/core/ReactiveAerospikeTemplate.java @@ -15,8 +15,15 @@ */ package org.springframework.data.aerospike.core; +import com.aerospike.client.AerospikeException; +import com.aerospike.client.BatchRecord; +import com.aerospike.client.BatchResults; +import com.aerospike.client.Bin; +import com.aerospike.client.Key; +import com.aerospike.client.Operation; import com.aerospike.client.Record; -import com.aerospike.client.*; +import com.aerospike.client.ResultCode; +import com.aerospike.client.Value; import com.aerospike.client.cdt.CTX; import com.aerospike.client.cluster.Node; import com.aerospike.client.policy.BatchPolicy; @@ -77,6 +84,7 @@ import static org.springframework.data.aerospike.core.TemplateUtils.getIdValue; import static org.springframework.data.aerospike.query.QualifierUtils.getIdQualifier; import static org.springframework.data.aerospike.query.QualifierUtils.queryCriteriaIsNotNull; +import static org.springframework.data.aerospike.util.InfoCommandUtils.sendInfoCommand; /** * Primary implementation of {@link ReactiveAerospikeOperations}. @@ -1082,10 +1090,10 @@ public Mono count(String setName) { private long countSet(String setName) { Node[] nodes = reactorClient.getAerospikeClient().getNodes(); - int replicationFactor = Utils.getReplicationFactor(nodes, namespace); + int replicationFactor = Utils.getReplicationFactor(reactorClient.getAerospikeClient(), nodes, namespace); long totalObjects = Arrays.stream(nodes) - .mapToLong(node -> Utils.getObjectsCount(node, namespace, setName)) + .mapToLong(node -> Utils.getObjectsCount(reactorClient.getAerospikeClient(), node, namespace, setName)) .sum(); return (nodes.length > 1) ? (totalObjects / replicationFactor) : totalObjects; @@ -1191,8 +1199,8 @@ public Mono indexExists(String indexName) { try { Node[] nodes = reactorClient.getAerospikeClient().getNodes(); for (Node node : nodes) { - String response = Info.request(reactorClient.getAerospikeClient().getInfoPolicyDefault(), - node, "sindex-exists:ns=" + namespace + ";indexname=" + indexName); + String response = sendInfoCommand(reactorClient.getAerospikeClient(), node, + "sindex-exists:ns=" + namespace + ";indexname=" + indexName); if (response == null) throw new AerospikeException("Null node response"); if (response.equalsIgnoreCase("true")) { diff --git a/src/main/java/org/springframework/data/aerospike/query/cache/IndexRefresher.java b/src/main/java/org/springframework/data/aerospike/query/cache/IndexRefresher.java index 0919bd604..99ceaa163 100644 --- a/src/main/java/org/springframework/data/aerospike/query/cache/IndexRefresher.java +++ b/src/main/java/org/springframework/data/aerospike/query/cache/IndexRefresher.java @@ -16,7 +16,6 @@ package org.springframework.data.aerospike.query.cache; import com.aerospike.client.IAerospikeClient; -import com.aerospike.client.Info; import com.aerospike.client.cluster.Node; import com.aerospike.client.policy.InfoPolicy; import org.slf4j.Logger; @@ -29,6 +28,8 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import static org.springframework.data.aerospike.util.InfoCommandUtils.sendInfoCommand; + /** * @author Anastasiia Smirnova */ @@ -65,7 +66,7 @@ public void refreshIndexes() { .filter(Node::isActive) .findAny() // we do want to send info request to the random node (sending request to the first node may // lead to uneven request distribution) - .map(node -> Info.request(infoPolicy, node, indexOperations.buildGetIndexesCommand())) + .map(node -> sendInfoCommand(client, infoPolicy, node, indexOperations.buildGetIndexesCommand())) .map(response -> { IndexesInfo indexesInfo = indexOperations.parseIndexesInfo(response); indexOperations.enrichIndexesWithCardinality(client, indexesInfo.indexes, serverVersionSupport); diff --git a/src/main/java/org/springframework/data/aerospike/query/cache/InternalIndexOperations.java b/src/main/java/org/springframework/data/aerospike/query/cache/InternalIndexOperations.java index 42d0ca7ea..64649d910 100644 --- a/src/main/java/org/springframework/data/aerospike/query/cache/InternalIndexOperations.java +++ b/src/main/java/org/springframework/data/aerospike/query/cache/InternalIndexOperations.java @@ -16,7 +16,6 @@ package org.springframework.data.aerospike.query.cache; import com.aerospike.client.IAerospikeClient; -import com.aerospike.client.Info; import lombok.extern.slf4j.Slf4j; import org.springframework.data.aerospike.query.model.Index; import org.springframework.data.aerospike.query.model.IndexKey; @@ -30,6 +29,7 @@ import static java.util.stream.Collectors.collectingAndThen; import static java.util.stream.Collectors.toMap; +import static org.springframework.data.aerospike.util.InfoCommandUtils.sendInfoCommand; /** * Internal index related operations used by ReactorIndexRefresher and IndexRefresher. @@ -41,7 +41,6 @@ public class InternalIndexOperations { // Base64 will return index context as a base64 response private static final String SINDEX_WITH_BASE64 = "sindex-list:;b64=true"; - private final IndexInfoParser indexInfoParser; public InternalIndexOperations(IndexInfoParser indexInfoParser) { @@ -81,7 +80,7 @@ public int getIndexBinValuesRatio(IAerospikeClient client, ServerVersionSupport String namespace, String indexName) { if (serverVersionSupport.isSIndexCardinalitySupported()) { try { - String indexStatData = Info.request(client.getInfoPolicyDefault(), client.getCluster().getRandomNode(), + String indexStatData = sendInfoCommand(client, client.getCluster().getRandomNode(), String.format("sindex-stat:ns=%s;indexname=%s", namespace, indexName)); return Integer.parseInt( 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 99e026ea8..f78c15001 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 @@ -1,7 +1,6 @@ package org.springframework.data.aerospike.server.version; import com.aerospike.client.IAerospikeClient; -import com.aerospike.client.Info; import lombok.Getter; import lombok.extern.slf4j.Slf4j; @@ -10,6 +9,8 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import static org.springframework.data.aerospike.util.InfoCommandUtils.sendInfoCommand; + @Slf4j public class ServerVersionSupport { @@ -40,9 +41,10 @@ public void scheduleServerVersionRefresh(long intervalSeconds) { } private String findServerVersion() { - String versionString = Info.request(client.getInfoPolicyDefault(), - client.getCluster().getRandomNode(), "version"); - versionString = versionString.substring(versionString.lastIndexOf(' ') + 1); + String fullVersionString = sendInfoCommand(client, client.getCluster().getRandomNode(), + "version"); + + String versionString = fullVersionString.substring(fullVersionString.lastIndexOf(' ') + 1); log.debug("Found server version {}", versionString); return versionString; } diff --git a/src/main/java/org/springframework/data/aerospike/util/InfoCommandUtils.java b/src/main/java/org/springframework/data/aerospike/util/InfoCommandUtils.java new file mode 100644 index 000000000..852bb4dfc --- /dev/null +++ b/src/main/java/org/springframework/data/aerospike/util/InfoCommandUtils.java @@ -0,0 +1,124 @@ +package org.springframework.data.aerospike.util; + +import com.aerospike.client.AerospikeException; +import com.aerospike.client.IAerospikeClient; +import com.aerospike.client.cluster.Node; +import com.aerospike.client.listener.InfoListener; +import com.aerospike.client.policy.InfoPolicy; +import lombok.extern.slf4j.Slf4j; + +import java.util.Map; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +@Slf4j +public class InfoCommandUtils { + + public static String sendInfoCommand(IAerospikeClient client, Node node, String command) { + return sendInfoCommand(client, client.getInfoPolicyDefault(), node, command); + } + + public static String sendInfoCommand(IAerospikeClient client, InfoPolicy infoPolicy, Node node, String command) { + InfoListenerWithStringValue listener = new InfoListenerWithStringValue() { + + volatile String stringValue = ""; + volatile String infoCommand = ""; + volatile boolean isComplete = false; + volatile AerospikeException exception; + + @Override + public synchronized String getStringValue() { + return stringValue; + } + + @Override + public synchronized boolean isComplete() { + return isComplete; + } + + @Override + public synchronized AerospikeException getException() { + return exception; + } + + @Override + public synchronized String getInfoCommand() { + return infoCommand; + } + + @Override + public void onSuccess(Map map) { + stringValue = map.get(command); + isComplete = true; + } + + @Override + public void onFailure(AerospikeException ae) { + exception = ae; + infoCommand = command; + isComplete = true; + } + }; + + client.info(client.getCluster().eventLoops.next(), listener, infoPolicy, node, command); + waitForCompletionOrTimeout(listener); + failIfExceptionFound(listener); + + return listener.getStringValue() == null ? "" : listener.getStringValue(); + } + + private static void failIfExceptionFound(InfoListenerWithStringValue listener) { + if (listener.getException() != null) { + throw new AerospikeException(String.format("Info command %s failed", listener.getInfoCommand()), + listener.getException()); + } + } + + private static void waitForCompletionOrTimeout(InfoListenerWithStringValue listener) { + // Create a CountDownLatch with initial count 1 + CountDownLatch latch = new CountDownLatch(1); + + // Start a separate thread to wait for isComplete() + Thread waitingThread = getWaitingThread(listener, latch); + + try { + // Wait for completion or timeout + boolean timeoutOver = latch.await(1, TimeUnit.SECONDS); // timeout is 1 second + if (!timeoutOver) { + waitingThread.interrupt(); // Interrupt waiting thread if timeout occurs + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); // Interrupted + log.error("Interrupted while waiting for info command to complete"); + } + } + + private static Thread getWaitingThread(InfoListenerWithStringValue listener, CountDownLatch latch) { + Thread waitingThread = new Thread(() -> { + while (!listener.isComplete()) { + try { + //noinspection ResultOfMethodCallIgnored + latch.await(1, TimeUnit.MILLISECONDS); // Wait briefly before re-checking + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return; // Interrupted, exit thread + } + } + latch.countDown(); // Release latch when isComplete() is true + }); + waitingThread.start(); + return waitingThread; + } + + interface InfoListenerWithStringValue extends InfoListener { + + String getStringValue(); + + @SuppressWarnings("BooleanMethodIsAlwaysInverted") + boolean isComplete(); + + AerospikeException getException(); + + String getInfoCommand(); + } +} diff --git a/src/main/java/org/springframework/data/aerospike/util/InfoResponseUtils.java b/src/main/java/org/springframework/data/aerospike/util/InfoResponseUtils.java index 6a69989fe..9725f004b 100644 --- a/src/main/java/org/springframework/data/aerospike/util/InfoResponseUtils.java +++ b/src/main/java/org/springframework/data/aerospike/util/InfoResponseUtils.java @@ -43,19 +43,19 @@ public static T getPropertyFromResponse(String response, String propertyName .findFirst() .map(objectsStr -> objectsStr.split("=")) .orElseThrow(() -> new IllegalStateException( - "Failed to parse server response. Could not to find property: " + propertyName + " in response: " + - response)); + String.format("Failed to parse server response. Cannot find property '%s' in response '%s'", + propertyName, response))); if (keyValuePair.length != 2) { - throw new IllegalStateException("Failed to parse server response. Expected property: " + propertyName + - " to have length 2 in response: " + response); + throw new IllegalStateException(String.format("Failed to parse server response. Expected property '%s' " + + "to have length 2 in response '%s'", propertyName, response)); } String valueStr = keyValuePair[1]; try { return mapper.apply(valueStr); } catch (Exception e) { - throw new IllegalStateException( - "Failed to parse value: " + valueStr + " for property: " + propertyName + " in response: " + response); + throw new IllegalStateException(String.format("Failed to parse value '%s' for property '%s' " + + "in response '%s'", valueStr, propertyName, response)); } } } diff --git a/src/main/java/org/springframework/data/aerospike/util/Utils.java b/src/main/java/org/springframework/data/aerospike/util/Utils.java index 943f7f6c2..35f92876b 100644 --- a/src/main/java/org/springframework/data/aerospike/util/Utils.java +++ b/src/main/java/org/springframework/data/aerospike/util/Utils.java @@ -57,6 +57,7 @@ import static com.aerospike.client.command.ParticleType.LIST; import static com.aerospike.client.command.ParticleType.MAP; import static com.aerospike.client.command.ParticleType.STRING; +import static org.springframework.data.aerospike.util.InfoCommandUtils.sendInfoCommand; import static org.springframework.util.ClassUtils.isPrimitiveOrWrapper; import static org.springframework.util.StringUtils.hasLength; @@ -86,10 +87,10 @@ public static String[] infoAll(IAerospikeClient client, return messages; } - public static int getReplicationFactor(Node[] nodes, String namespace) { + public static int getReplicationFactor(IAerospikeClient client, Node[] nodes, String namespace) { Node randomNode = getRandomNode(nodes); - - String response = Info.request(randomNode, "get-config:context=namespace;id=" + namespace); + String response = sendInfoCommand(client, randomNode, "get-config:context=namespace;id=" + namespace + ); if (response.equalsIgnoreCase("ns_type=unknown")) { throw new InvalidDataAccessResourceUsageException("Namespace: " + namespace + " does not exist"); } @@ -111,8 +112,8 @@ public static Node getRandomNode(Node[] nodes) { throw new AerospikeException.InvalidNode("Command failed because no active nodes found."); } - public static long getObjectsCount(Node node, String namespace, String setName) { - String infoString = Info.request(node, "sets/" + namespace + "/" + setName); + public static long getObjectsCount(IAerospikeClient client, Node node, String namespace, String setName) { + String infoString = sendInfoCommand(client, node, "sets/" + namespace + "/" + setName); if (infoString.isEmpty()) { // set is not present return 0L; } diff --git a/src/test/java/org/springframework/data/aerospike/config/ReactiveTestConfig.java b/src/test/java/org/springframework/data/aerospike/config/ReactiveTestConfig.java index aae6b04e3..e357b7f27 100644 --- a/src/test/java/org/springframework/data/aerospike/config/ReactiveTestConfig.java +++ b/src/test/java/org/springframework/data/aerospike/config/ReactiveTestConfig.java @@ -1,15 +1,6 @@ package org.springframework.data.aerospike.config; import com.aerospike.client.IAerospikeClient; -import com.aerospike.client.async.EventLoops; -import com.aerospike.client.async.EventPolicy; -import com.aerospike.client.async.NettyEventLoops; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.epoll.Epoll; -import io.netty.channel.epoll.EpollEventLoopGroup; -import io.netty.channel.kqueue.KQueue; -import io.netty.channel.kqueue.KQueueEventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.core.env.Environment; @@ -25,7 +16,6 @@ import java.util.Arrays; import java.util.List; -import java.util.Locale; /** * @author Peter Milne @@ -45,26 +35,6 @@ protected List customConverters() { ); } - @Override - protected EventLoops eventLoops() { - int nThreads = Math.max(2, Runtime.getRuntime().availableProcessors() * 2); - String os = System.getProperty("os.name").toLowerCase(Locale.ENGLISH); - - EventLoopGroup eventLoopGroup; - if (os.contains("nux") && Epoll.isAvailable()) { - eventLoopGroup = new EpollEventLoopGroup(nThreads); - } else if (os.contains("mac") && KQueue.isAvailable()) { - eventLoopGroup = new KQueueEventLoopGroup(nThreads); - } else { - eventLoopGroup = new NioEventLoopGroup(nThreads); - } - - EventPolicy eventPolicy = new EventPolicy(); - eventPolicy.maxCommandsInProcess = 40; - eventPolicy.maxCommandsInQueue = 1024; - return new NettyEventLoops(eventPolicy, eventLoopGroup); - } - @Bean public AdditionalAerospikeTestOperations aerospikeOperations(ReactiveAerospikeTemplate template, IAerospikeClient client, diff --git a/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateDeleteTests.java b/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateDeleteTests.java index d9235af04..f1f711394 100644 --- a/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateDeleteTests.java +++ b/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateDeleteTests.java @@ -255,7 +255,7 @@ public void deleteByIds_rejectsDuplicateIds() { List ids = List.of(id1, id1); assertThatThrownBy(() -> template.deleteByIds(ids, DocumentWithExpiration.class)) .isInstanceOf(AerospikeException.BatchRecordArray.class) - .hasMessageContaining("Errors during batch delete"); + .hasMessageContaining("Batch failed"); } } @@ -312,7 +312,7 @@ public void deleteAll_rejectsDuplicateIds() { assertThatThrownBy(() -> template.deleteAll(List.of(document1, document2))) .isInstanceOf(AerospikeException.BatchRecordArray.class) - .hasMessageContaining("Errors during batch delete"); + .hasMessageContaining("Batch failed"); } } diff --git a/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateUpdateTests.java b/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateUpdateTests.java index c17f6d776..d26d81950 100644 --- a/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateUpdateTests.java +++ b/src/test/java/org/springframework/data/aerospike/core/AerospikeTemplateUpdateTests.java @@ -433,7 +433,7 @@ public void updateAllShouldThrowExceptionOnUpdateForNonExistingKey() { // RecordExistsAction.UPDATE_ONLY assertThatThrownBy(() -> template.updateAll(List.of(firstPerson, secondPerson))) .isInstanceOf(AerospikeException.BatchRecordArray.class) - .hasMessageContaining("Errors during batch update"); + .hasMessageContaining("Batch failed"); assertThat(template.findById(firstPerson.getId(), Person.class)).isEqualTo(firstPerson); assertThat(template.findById(secondPerson.getId(), Person.class)).isNull(); diff --git a/src/test/java/org/springframework/data/aerospike/repository/query/blocking/noindex/findBy/NotEqualTests.java b/src/test/java/org/springframework/data/aerospike/repository/query/blocking/noindex/findBy/NotEqualTests.java index 4e88bc188..024d1e854 100644 --- a/src/test/java/org/springframework/data/aerospike/repository/query/blocking/noindex/findBy/NotEqualTests.java +++ b/src/test/java/org/springframework/data/aerospike/repository/query/blocking/noindex/findBy/NotEqualTests.java @@ -52,6 +52,15 @@ void findByNestedSimplePropertyNotEqual() { TestUtils.setFriendsToNull(repository, oliver, dave, carter); } + @Test + void findByNestedSimplePropertyNotEqual_ZipCode() { + assertThat(carter.getAddress().getZipCode()).isEqualTo("C0124"); + assertThat(dave.getAddress().getZipCode()).isEqualTo("C0123"); + // find all records where address' zipCode is not C0123 or C0125, and all without address.zipCode + assertThat(repository.findByAddressZipCodeIsNot("C0123")) + .containsOnly(donny, oliver, alicia, boyd, stefan, leroi, leroi2, matias, douglas, carter); + } + @Test void findByNestedSimplePropertyNotEqual_NegativeTest() { assertThatThrownBy(() -> negativeTestsRepository.findByFriendAddressZipCodeIsNot()) diff --git a/src/test/java/org/springframework/data/aerospike/util/IndexUtils.java b/src/test/java/org/springframework/data/aerospike/util/IndexUtils.java index 945a3daac..584802174 100644 --- a/src/test/java/org/springframework/data/aerospike/util/IndexUtils.java +++ b/src/test/java/org/springframework/data/aerospike/util/IndexUtils.java @@ -2,7 +2,6 @@ import com.aerospike.client.AerospikeException; import com.aerospike.client.IAerospikeClient; -import com.aerospike.client.Info; import com.aerospike.client.ResultCode; import com.aerospike.client.cdt.CTX; import com.aerospike.client.cluster.Node; @@ -18,6 +17,8 @@ import java.util.function.Supplier; import java.util.stream.Collectors; +import static org.springframework.data.aerospike.util.InfoCommandUtils.sendInfoCommand; + public class IndexUtils { static void dropIndex(IAerospikeClient client, ServerVersionSupport serverVersionSupport, String namespace, @@ -45,8 +46,8 @@ static void createIndex(IAerospikeClient client, ServerVersionSupport serverVers public static List getIndexes(IAerospikeClient client, String namespace, IndexInfoParser indexInfoParser) { Node node = client.getCluster().getRandomNode(); - String response = Info.request(client.getInfoPolicyDefault(), - node, "sindex-list:ns=" + namespace + ";b64=true"); + String response = sendInfoCommand(client, node, "sindex-list:ns=" + namespace + ";b64=true" + ); return Arrays.stream(response.split(";")) .map(indexInfoParser::parse) .collect(Collectors.toList()); @@ -58,8 +59,8 @@ public static List getIndexes(IAerospikeClient client, String namespace, */ public static boolean indexExists(IAerospikeClient client, String namespace, String indexName) { Node node = client.getCluster().getRandomNode(); - String response = Info.request(client.getInfoPolicyDefault(), - node, "sindex/" + namespace + '/' + indexName); + String response = sendInfoCommand(client, node, "sindex/" + namespace + '/' + indexName + ); return !response.startsWith("FAIL:201"); } diff --git a/src/test/java/org/springframework/data/aerospike/util/InfoResponseUtilsTests.java b/src/test/java/org/springframework/data/aerospike/util/InfoResponseUtilsTests.java index 4925965b2..5e031fe25 100644 --- a/src/test/java/org/springframework/data/aerospike/util/InfoResponseUtilsTests.java +++ b/src/test/java/org/springframework/data/aerospike/util/InfoResponseUtilsTests.java @@ -57,7 +57,7 @@ void propertyInvalidTypeInResponse() { assertThatThrownBy(() -> InfoResponseUtils.getPropertyFromConfigResponse(response, "replication-factor", Integer::parseInt)) .isInstanceOf(IllegalStateException.class) - .hasMessageStartingWith("Failed to parse value: factor for property: replication-factor"); + .hasMessageStartingWith("Failed to parse value 'factor' for property 'replication-factor' in response"); } @Test @@ -67,8 +67,8 @@ void propertyInvalidFormatInResponse() { assertThatThrownBy(() -> InfoResponseUtils.getPropertyFromConfigResponse(response, "replication-factor", Integer::parseInt)) .isInstanceOf(IllegalStateException.class) - .hasMessageStartingWith("Failed to parse server response. Expected property: replication-factor to have " + - "length 2 in response"); + .hasMessageStartingWith("Failed to parse server response. Expected property 'replication-factor' " + + "to have length 2 in response"); } @Test @@ -78,8 +78,8 @@ void missingPropertyInResponse() { assertThatThrownBy(() -> InfoResponseUtils.getPropertyFromConfigResponse(response, "replication-factor", Integer::parseInt)) .isInstanceOf(IllegalStateException.class) - .hasMessageStartingWith("Failed to parse server response. Could not to find property: replication-factor " + - "in response"); + .hasMessageStartingWith("Failed to parse server response. Cannot find property 'replication-factor' in " + + "response"); } @Test @@ -89,7 +89,7 @@ void emptyResponse() { assertThatThrownBy(() -> InfoResponseUtils.getPropertyFromConfigResponse(response, "replication-factor", Integer::parseInt)) .isInstanceOf(IllegalStateException.class) - .hasMessageStartingWith("Failed to parse server response. Could not to find property: replication-factor " + - "in response"); + .hasMessageStartingWith("Failed to parse server response. Cannot find property " + + "'replication-factor' in response ''"); } }