package com.datastax.oss.driver.internal.core.loadbalancing.helper;
import static com.datastax.oss.driver.internal.core.time.Clock.LOG;
import com.datastax.oss.driver.api.core.config.DefaultDriverOption;
import com.datastax.oss.driver.api.core.config.DriverExecutionProfile;
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.DefaultNode;
import edu.umd.cs.findbugs.annotations.NonNull;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import net.jcip.annotations.ThreadSafe;
@ThreadSafe
public class InferringLocalDcHelper extends OptionalLocalDcHelper {
public InferringLocalDcHelper(
@NonNull InternalDriverContext context,
@NonNull DriverExecutionProfile profile,
@NonNull String logPrefix) {
super(context, profile, logPrefix);
}
@NonNull
@Override
public Optional<String> discoverLocalDc(@NonNull Map<UUID, Node> nodes) {
Optional<String> optionalLocalDc = super.discoverLocalDc(nodes);
if (optionalLocalDc.isPresent()) {
return optionalLocalDc;
}
Set<String> datacenters = new HashSet<>();
Set<DefaultNode> contactPoints = context.getMetadataManager().getContactPoints();
for (Node node : contactPoints) {
String datacenter = node.getDatacenter();
if (datacenter != null) {
datacenters.add(datacenter);
}
}
if (datacenters.size() == 1) {
String localDc = datacenters.iterator().next();
LOG.info("[{}] Inferred local DC from contact points: {}", logPrefix, localDc);
return Optional.of(localDc);
}
if (datacenters.isEmpty()) {
throw new IllegalStateException(
"The local DC could not be inferred from contact points, please set it explicitly (see "
+ DefaultDriverOption.LOAD_BALANCING_LOCAL_DATACENTER.getPath()
+ " in the config, or set it programmatically with SessionBuilder.withLocalDatacenter)");
}
throw new IllegalStateException(
String.format(
"No local DC was provided, but the contact points are from different DCs: %s; "
+ "please set the local DC explicitly (see "
+ DefaultDriverOption.LOAD_BALANCING_LOCAL_DATACENTER.getPath()
+ " in the config, or set it programmatically with SessionBuilder.withLocalDatacenter)",
formatNodesAndDcs(contactPoints)));
}
}