Skip to content

Commit 04d34a8

Browse files
jahstreettolbertam
authored andcommitted
JAVA-3168 Copy node info for contact points on initial node refresh only from first match by endpoint
patch by Alex Sasnouskikh; reviewed by Andy Tolbert and Alexandre Dura for JAVA-3168
1 parent 2e0c44c commit 04d34a8

File tree

2 files changed

+54
-16
lines changed

2 files changed

+54
-16
lines changed

core/src/main/java/com/datastax/oss/driver/internal/core/metadata/InitialNodeListRefresh.java

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,16 @@
1818
package com.datastax.oss.driver.internal.core.metadata;
1919

2020
import com.datastax.oss.driver.api.core.metadata.EndPoint;
21-
import com.datastax.oss.driver.api.core.metadata.Node;
2221
import com.datastax.oss.driver.internal.core.context.InternalDriverContext;
2322
import com.datastax.oss.driver.internal.core.metadata.token.TokenFactory;
2423
import com.datastax.oss.driver.internal.core.metadata.token.TokenFactoryRegistry;
2524
import com.datastax.oss.driver.shaded.guava.common.annotations.VisibleForTesting;
2625
import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList;
2726
import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap;
27+
import java.util.ArrayList;
2828
import java.util.HashMap;
29+
import java.util.HashSet;
30+
import java.util.List;
2931
import java.util.Map;
3032
import java.util.Set;
3133
import java.util.UUID;
@@ -63,22 +65,31 @@ public Result compute(
6365
TokenFactory tokenFactory = null;
6466

6567
Map<UUID, DefaultNode> newNodes = new HashMap<>();
68+
// Contact point nodes don't have host ID as well as other info yet, so we fill them with node
69+
// info found on first match by endpoint
70+
Set<EndPoint> matchedContactPoints = new HashSet<>();
71+
List<DefaultNode> addedNodes = new ArrayList<>();
6672

6773
for (NodeInfo nodeInfo : nodeInfos) {
6874
UUID hostId = nodeInfo.getHostId();
6975
if (newNodes.containsKey(hostId)) {
7076
LOG.warn(
7177
"[{}] Found duplicate entries with host_id {} in system.peers, "
72-
+ "keeping only the first one",
78+
+ "keeping only the first one {}",
7379
logPrefix,
74-
hostId);
80+
hostId,
81+
newNodes.get(hostId));
7582
} else {
7683
EndPoint endPoint = nodeInfo.getEndPoint();
77-
DefaultNode node = findIn(contactPoints, endPoint);
78-
if (node == null) {
84+
DefaultNode contactPointNode = findContactPointNode(endPoint);
85+
DefaultNode node;
86+
if (contactPointNode == null || matchedContactPoints.contains(endPoint)) {
7987
node = new DefaultNode(endPoint, context);
88+
addedNodes.add(node);
8089
LOG.debug("[{}] Adding new node {}", logPrefix, node);
8190
} else {
91+
matchedContactPoints.add(contactPointNode.getEndPoint());
92+
node = contactPointNode;
8293
LOG.debug("[{}] Copying contact point {}", logPrefix, node);
8394
}
8495
if (tokenMapEnabled && tokenFactory == null && nodeInfo.getPartitioner() != null) {
@@ -90,14 +101,11 @@ public Result compute(
90101
}
91102

92103
ImmutableList.Builder<Object> eventsBuilder = ImmutableList.builder();
93-
94-
for (DefaultNode newNode : newNodes.values()) {
95-
if (findIn(contactPoints, newNode.getEndPoint()) == null) {
96-
eventsBuilder.add(NodeStateEvent.added(newNode));
97-
}
104+
for (DefaultNode addedNode : addedNodes) {
105+
eventsBuilder.add(NodeStateEvent.added(addedNode));
98106
}
99107
for (DefaultNode contactPoint : contactPoints) {
100-
if (findIn(newNodes.values(), contactPoint.getEndPoint()) == null) {
108+
if (!matchedContactPoints.contains(contactPoint.getEndPoint())) {
101109
eventsBuilder.add(NodeStateEvent.removed(contactPoint));
102110
}
103111
}
@@ -108,10 +116,10 @@ public Result compute(
108116
eventsBuilder.build());
109117
}
110118

111-
private DefaultNode findIn(Iterable<? extends Node> nodes, EndPoint endPoint) {
112-
for (Node node : nodes) {
119+
private DefaultNode findContactPointNode(EndPoint endPoint) {
120+
for (DefaultNode node : contactPoints) {
113121
if (node.getEndPoint().equals(endPoint)) {
114-
return (DefaultNode) node;
122+
return node;
115123
}
116124
}
117125
return null;

core/src/test/java/com/datastax/oss/driver/internal/core/metadata/InitialNodeListRefreshTest.java

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ public class InitialNodeListRefreshTest {
4848
private UUID hostId1;
4949
private UUID hostId2;
5050
private UUID hostId3;
51+
private UUID hostId4;
52+
private UUID hostId5;
5153

5254
@Before
5355
public void setup() {
@@ -61,10 +63,12 @@ public void setup() {
6163
hostId1 = UUID.randomUUID();
6264
hostId2 = UUID.randomUUID();
6365
hostId3 = UUID.randomUUID();
66+
hostId4 = UUID.randomUUID();
67+
hostId5 = UUID.randomUUID();
6468
}
6569

6670
@Test
67-
public void should_copy_contact_points() {
71+
public void should_copy_contact_points_on_first_endpoint_match_only() {
6872
// Given
6973
Iterable<NodeInfo> newInfos =
7074
ImmutableList.of(
@@ -76,6 +80,17 @@ public void should_copy_contact_points() {
7680
DefaultNodeInfo.builder()
7781
.withEndPoint(contactPoint2.getEndPoint())
7882
.withHostId(hostId2)
83+
.build(),
84+
DefaultNodeInfo.builder().withEndPoint(endPoint3).withHostId(hostId3).build(),
85+
DefaultNodeInfo.builder()
86+
// address translator can translate node addresses to the same endpoints
87+
.withEndPoint(contactPoint2.getEndPoint())
88+
.withHostId(hostId4)
89+
.build(),
90+
DefaultNodeInfo.builder()
91+
// address translator can translate node addresses to the same endpoints
92+
.withEndPoint(endPoint3)
93+
.withHostId(hostId5)
7994
.build());
8095
InitialNodeListRefresh refresh =
8196
new InitialNodeListRefresh(newInfos, ImmutableSet.of(contactPoint1, contactPoint2));
@@ -86,11 +101,26 @@ public void should_copy_contact_points() {
86101
// Then
87102
// contact points have been copied to the metadata, and completed with missing information
88103
Map<UUID, Node> newNodes = result.newMetadata.getNodes();
89-
assertThat(newNodes).containsOnlyKeys(hostId1, hostId2);
104+
assertThat(newNodes).containsOnlyKeys(hostId1, hostId2, hostId3, hostId4, hostId5);
90105
assertThat(newNodes.get(hostId1)).isEqualTo(contactPoint1);
91106
assertThat(contactPoint1.getHostId()).isEqualTo(hostId1);
92107
assertThat(newNodes.get(hostId2)).isEqualTo(contactPoint2);
93108
assertThat(contactPoint2.getHostId()).isEqualTo(hostId2);
109+
// And
110+
// node has been added for the new endpoint
111+
assertThat(newNodes.get(hostId3).getEndPoint()).isEqualTo(endPoint3);
112+
assertThat(newNodes.get(hostId3).getHostId()).isEqualTo(hostId3);
113+
// And
114+
// nodes have been added for duplicated endpoints
115+
assertThat(newNodes.get(hostId4).getEndPoint()).isEqualTo(contactPoint2.getEndPoint());
116+
assertThat(newNodes.get(hostId4).getHostId()).isEqualTo(hostId4);
117+
assertThat(newNodes.get(hostId5).getEndPoint()).isEqualTo(endPoint3);
118+
assertThat(newNodes.get(hostId5).getHostId()).isEqualTo(hostId5);
119+
assertThat(result.events)
120+
.containsExactlyInAnyOrder(
121+
NodeStateEvent.added((DefaultNode) newNodes.get(hostId3)),
122+
NodeStateEvent.added((DefaultNode) newNodes.get(hostId4)),
123+
NodeStateEvent.added((DefaultNode) newNodes.get(hostId5)));
94124
}
95125

96126
@Test

0 commit comments

Comments
 (0)