package com.datastax.oss.driver.internal.core.metadata;
import com.datastax.oss.driver.api.core.metadata.EndPoint;
import com.datastax.oss.driver.api.core.metadata.Node;
import com.datastax.oss.driver.internal.core.context.InternalDriverContext;
import com.datastax.oss.driver.internal.core.metadata.token.DefaultTokenMap;
import com.datastax.oss.driver.internal.core.metadata.token.TokenFactory;
import com.datastax.oss.driver.internal.core.metadata.token.TokenFactoryRegistry;
import com.datastax.oss.driver.shaded.guava.common.annotations.VisibleForTesting;
import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList;
import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap;
import java.util.Set;
import java.util.UUID;
import net.jcip.annotations.ThreadSafe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ThreadSafe
class InitialNodeListRefresh extends NodesRefresh {
private static final Logger LOG = LoggerFactory.getLogger(InitialNodeListRefresh.class);
@VisibleForTesting final Iterable<NodeInfo> nodeInfos;
@VisibleForTesting final Set<DefaultNode> contactPoints;
InitialNodeListRefresh(Iterable<NodeInfo> nodeInfos, Set<DefaultNode> contactPoints) {
this.nodeInfos = nodeInfos;
this.contactPoints = contactPoints;
}
@Override
public Result compute(
DefaultMetadata oldMetadata, boolean tokenMapEnabled, InternalDriverContext context) {
String logPrefix = context.getSessionName();
TokenFactoryRegistry tokenFactoryRegistry = context.getTokenFactoryRegistry();
assert oldMetadata.getNodes().isEmpty();
TokenFactory tokenFactory =
oldMetadata.getTokenMap().map(m -> ((DefaultTokenMap) m).getTokenFactory()).orElse(null);
boolean tokensChanged = false;
ImmutableMap.Builder<UUID, DefaultNode> newNodesBuilder = ImmutableMap.builder();
for (NodeInfo nodeInfo : nodeInfos) {
EndPoint endPoint = nodeInfo.getEndPoint();
DefaultNode node = findIn(contactPoints, endPoint);
if (node == null) {
node = new DefaultNode(endPoint, context);
LOG.debug("[{}] Adding new node {}", logPrefix, node);
} else {
LOG.debug("[{}] Copying contact point {}", logPrefix, node);
}
if (tokenFactory == null && nodeInfo.getPartitioner() != null) {
tokenFactory = tokenFactoryRegistry.tokenFactoryFor(nodeInfo.getPartitioner());
}
tokensChanged |= copyInfos(nodeInfo, node, tokenFactory, context);
newNodesBuilder.put(node.getHostId(), node);
}
ImmutableMap<UUID, DefaultNode> newNodes = newNodesBuilder.build();
ImmutableList.Builder<Object> eventsBuilder = ImmutableList.builder();
for (DefaultNode newNode : newNodes.values()) {
if (findIn(contactPoints, newNode.getEndPoint()) == null) {
eventsBuilder.add(NodeStateEvent.added(newNode));
}
}
for (DefaultNode contactPoint : contactPoints) {
if (findIn(newNodes.values(), contactPoint.getEndPoint()) == null) {
eventsBuilder.add(NodeStateEvent.removed(contactPoint));
}
}
return new Result(
oldMetadata.withNodes(
ImmutableMap.copyOf(newNodes), tokenMapEnabled, tokensChanged, tokenFactory, context),
eventsBuilder.build());
}
private DefaultNode findIn(Iterable<? extends Node> nodes, EndPoint endPoint) {
for (Node node : nodes) {
if (node.getEndPoint().equals(endPoint)) {
return (DefaultNode) node;
}
}
return null;
}
}