diff --git a/benchmarks/pom.xml b/benchmarks/pom.xml
index e79957d8c..cb4b52b73 100644
--- a/benchmarks/pom.xml
+++ b/benchmarks/pom.xml
@@ -6,7 +6,7 @@
com.aerospike
aerospike-parent
- 8.1.3
+ 8.1.4
aerospike-benchmarks
jar
diff --git a/client/pom.xml b/client/pom.xml
index 65008b3ef..dfe67163a 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -6,7 +6,7 @@
com.aerospike
aerospike-parent
- 8.1.3
+ 8.1.4
aerospike-client-jdk8
jar
diff --git a/client/src/com/aerospike/client/ResultCode.java b/client/src/com/aerospike/client/ResultCode.java
index cdf1d8341..54a3ce096 100644
--- a/client/src/com/aerospike/client/ResultCode.java
+++ b/client/src/com/aerospike/client/ResultCode.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2023 Aerospike, Inc.
+ * Copyright 2012-2024 Aerospike, Inc.
*
* Portions may be licensed to Aerospike, Inc. under one or more contributor
* license agreements WHICH ARE COMPATIBLE WITH THE APACHE LICENSE, VERSION 2.0.
@@ -233,6 +233,11 @@ public final class ResultCode {
*/
public static final int LOST_CONFLICT = 28;
+ /**
+ * Write can't complete until XDR finishes shipping.
+ */
+ public static final int XDR_KEY_BUSY = 32;
+
/**
* There are no more records left for query.
*/
@@ -582,6 +587,9 @@ public static String getResultString(int resultCode) {
case LOST_CONFLICT:
return "Transaction failed due to conflict with XDR";
+ case XDR_KEY_BUSY:
+ return "Write can't complete until XDR finishes shipping";
+
case QUERY_END:
return "Query end";
diff --git a/client/src/com/aerospike/client/cluster/Cluster.java b/client/src/com/aerospike/client/cluster/Cluster.java
index 7bb55ad3d..10e601a4c 100644
--- a/client/src/com/aerospike/client/cluster/Cluster.java
+++ b/client/src/com/aerospike/client/cluster/Cluster.java
@@ -569,11 +569,11 @@ private final void tend(boolean failIfNotConnected, boolean isInit) {
}
// Handle nodes changes determined from refreshes.
- ArrayList removeList = findNodesToRemove(peers.refreshCount);
+ findNodesToRemove(peers);
// Remove nodes in a batch.
- if (removeList.size() > 0) {
- removeNodes(removeList);
+ if (peers.removeList.size() > 0) {
+ removeNodes(peers.removeList);
}
}
@@ -762,8 +762,9 @@ protected Node createNode(NodeValidator nv) {
return node;
}
- private final ArrayList findNodesToRemove(int refreshCount) {
- ArrayList removeList = new ArrayList();
+ private final void findNodesToRemove(Peers peers) {
+ int refreshCount = peers.refreshCount;
+ ArrayList removeList = peers.removeList;
for (Node node : nodes) {
if (! node.isActive()) {
@@ -797,7 +798,6 @@ private final ArrayList findNodesToRemove(int refreshCount) {
}
}
}
- return removeList;
}
private final boolean findNodeInPartitionMap(Node filter) {
diff --git a/client/src/com/aerospike/client/cluster/Node.java b/client/src/com/aerospike/client/cluster/Node.java
index e1d30a3f4..8fa6be5a7 100644
--- a/client/src/com/aerospike/client/cluster/Node.java
+++ b/client/src/com/aerospike/client/cluster/Node.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2023 Aerospike, Inc.
+ * Copyright 2012-2024 Aerospike, Inc.
*
* Portions may be licensed to Aerospike, Inc. under one or more contributor
* license agreements WHICH ARE COMPATIBLE WITH THE APACHE LICENSE, VERSION 2.0.
@@ -426,7 +426,7 @@ protected final void refreshPeers(Peers peers) {
boolean peersValidated = true;
for (Peer peer : peers.peers) {
- if (findPeerNode(cluster, peers, peer.nodeName)) {
+ if (findPeerNode(cluster, peers, peer)) {
// Node already exists. Do not even try to connect to hosts.
continue;
}
@@ -450,19 +450,16 @@ protected final void refreshPeers(Peers peers) {
if (Log.warnEnabled()) {
Log.warn("Peer node " + peer.nodeName + " is different than actual node " + nv.name + " for host " + host);
}
-
- if (findPeerNode(cluster, peers, nv.name)) {
- // Node already exists. Do not even try to connect to hosts.
- nv.primaryConn.close();
- nodeValidated = true;
- break;
- }
}
// Create new node.
Node node = cluster.createNode(nv);
peers.nodes.put(nv.name, node);
- nodeValidated = true;
+ nodeValidated = true;
+
+ if (peer.replaceNode != null) {
+ peers.removeList.add(peer.replaceNode);
+ }
break;
}
catch (Throwable e) {
@@ -490,20 +487,37 @@ protected final void refreshPeers(Peers peers) {
}
}
- private static boolean findPeerNode(Cluster cluster, Peers peers, String nodeName) {
+ private static boolean findPeerNode(Cluster cluster, Peers peers, Peer peer) {
// Check global node map for existing cluster.
- Node node = cluster.nodesMap.get(nodeName);
+ Node node = cluster.nodesMap.get(peer.nodeName);
if (node != null) {
- node.referenceCount++;
- return true;
+ // Node name found.
+ if (node.failures <= 0 || node.address.getAddress().isLoopbackAddress()) {
+ // If the node does not have cluster tend errors or is localhost,
+ // reject new peer as the IP address does not need to change.
+ node.referenceCount++;
+ return true;
+ }
+
+ // Match peer hosts with the node host.
+ for (Host h : peer.hosts) {
+ if (h.equals(node.host)) {
+ // Main node host is also the same as one of the peer hosts.
+ // Peer should not be added.
+ node.referenceCount++;
+ return true;
+ }
+ }
+ peer.replaceNode = node;
}
// Check local node map for this tend iteration.
- node = peers.nodes.get(nodeName);
+ node = peers.nodes.get(peer.nodeName);
if (node != null) {
node.referenceCount++;
+ peer.replaceNode = null;
return true;
}
return false;
diff --git a/client/src/com/aerospike/client/cluster/Peer.java b/client/src/com/aerospike/client/cluster/Peer.java
index 05ab16a1d..83712a5a8 100644
--- a/client/src/com/aerospike/client/cluster/Peer.java
+++ b/client/src/com/aerospike/client/cluster/Peer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2021 Aerospike, Inc.
+ * Copyright 2012-2024 Aerospike, Inc.
*
* Portions may be licensed to Aerospike, Inc. under one or more contributor
* license agreements WHICH ARE COMPATIBLE WITH THE APACHE LICENSE, VERSION 2.0.
@@ -24,4 +24,5 @@ public final class Peer {
String nodeName;
String tlsName;
List hosts;
+ Node replaceNode;
}
diff --git a/client/src/com/aerospike/client/cluster/Peers.java b/client/src/com/aerospike/client/cluster/Peers.java
index bd28255d1..9c38f8a49 100644
--- a/client/src/com/aerospike/client/cluster/Peers.java
+++ b/client/src/com/aerospike/client/cluster/Peers.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2022 Aerospike, Inc.
+ * Copyright 2012-2024 Aerospike, Inc.
*
* Portions may be licensed to Aerospike, Inc. under one or more contributor
* license agreements WHICH ARE COMPATIBLE WITH THE APACHE LICENSE, VERSION 2.0.
@@ -26,6 +26,7 @@
public final class Peers {
public final ArrayList peers;
public final HashMap nodes;
+ public final ArrayList removeList;
private final HashSet invalidHosts;
public int refreshCount;
public boolean genChanged;
@@ -33,6 +34,7 @@ public final class Peers {
public Peers(int peerCapacity) {
peers = new ArrayList(peerCapacity);
nodes = new HashMap(16);
+ removeList = new ArrayList();
invalidHosts = new HashSet(8);
}
diff --git a/client/src/com/aerospike/client/command/RegisterCommand.java b/client/src/com/aerospike/client/command/RegisterCommand.java
index b5b8b30c7..d55c7389b 100644
--- a/client/src/com/aerospike/client/command/RegisterCommand.java
+++ b/client/src/com/aerospike/client/command/RegisterCommand.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2023 Aerospike, Inc.
+ * Copyright 2012-2024 Aerospike, Inc.
*
* Portions may be licensed to Aerospike, Inc. under one or more contributor
* license agreements WHICH ARE COMPATIBLE WITH THE APACHE LICENSE, VERSION 2.0.
@@ -55,11 +55,23 @@ public static RegisterTask register(Cluster cluster, Policy policy, byte[] bytes
String file = null;
String line = null;
String message = null;
+ String messageNew = null;
+ int errorCode = 0;
while (parser.next()) {
String name = parser.getName();
-
- if (name.equals("error")) {
+
+ if (name.startsWith("ERROR")) {
+ // New error format: ERROR::;file=;line=;message=
+ int idx = name.indexOf(';');
+ String s = (idx > 0)? name.substring(0, idx) : name;
+ Info.Error ie = new Info.Error(s);
+ messageNew = ie.message;
+ errorCode = ie.code;
+ file = parser.getValue();
+ }
+ else if (name.equals("error")) {
+ // Old error format: error=;file=;line=;message=
error = parser.getValue();
}
else if (name.equals("file")) {
@@ -72,8 +84,15 @@ else if (name.equals("message")) {
message = parser.getStringBase64();
}
}
-
- if (error != null) {
+
+ if (errorCode != 0) {
+ throw new AerospikeException(errorCode, "Registration failed: " + System.lineSeparator() +
+ "File: " + file + System.lineSeparator() +
+ "Line: " + line + System.lineSeparator() +
+ "Message: " + messageNew + ". " + message
+ );
+ }
+ else if (error != null) {
throw new AerospikeException("Registration failed: " + error + System.lineSeparator() +
"File: " + file + System.lineSeparator() +
"Line: " + line + System.lineSeparator() +
diff --git a/examples/pom.xml b/examples/pom.xml
index 21ced4a1f..fad839b13 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -6,7 +6,7 @@
com.aerospike
aerospike-parent
- 8.1.3
+ 8.1.4
aerospike-examples
jar
diff --git a/pom.xml b/pom.xml
index 03d679aaf..359cdd7f7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
com.aerospike
aerospike-parent
aerospike-parent
- 8.1.3
+ 8.1.4
pom
https://github.com/aerospike/aerospike-client-java
@@ -39,12 +39,12 @@
2.18.1
3.2.0
- 4.1.111.Final
+ 4.1.112.Final
2.0.62.Final
- 1.59.0
+ 1.65.1
3.0.1
0.4
- 1.8.0
+ 1.9.0
4.13.1
diff --git a/proxy/pom.xml b/proxy/pom.xml
index 8e8ebd270..9be7dce26 100644
--- a/proxy/pom.xml
+++ b/proxy/pom.xml
@@ -6,7 +6,7 @@
com.aerospike
aerospike-parent
- 8.1.3
+ 8.1.4
aerospike-proxy-client
jar
diff --git a/test/pom.xml b/test/pom.xml
index ac86ff071..1ed1b89a9 100644
--- a/test/pom.xml
+++ b/test/pom.xml
@@ -6,7 +6,7 @@
com.aerospike
aerospike-parent
- 8.1.3
+ 8.1.4
aerospike-client-test
jar