com.netflix.astyanax.impl.RingDescribeHostSupplier Maven / Gradle / Ivy
/*******************************************************************************
* Copyright 2011 Netflix
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package com.netflix.astyanax.impl;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Supplier;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.netflix.astyanax.Keyspace;
import com.netflix.astyanax.connectionpool.Host;
import com.netflix.astyanax.connectionpool.TokenRange;
import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
/**
* HostSupplier that uses existing hosts in the connection pool to execute a ring
* describe and get the entire list of hosts and their tokens from Cassandra.
*
* @author elandau
*
*/
public class RingDescribeHostSupplier implements Supplier> {
private final static Logger LOG = LoggerFactory.getLogger(RingDescribeHostSupplier.class);
private final Keyspace keyspace;
private final int defaultPort;
private final String dc;
private final String rack;
private volatile List previousHosts;
public RingDescribeHostSupplier(Keyspace keyspace, int defaultPort, String dc, String rack) {
this.keyspace = keyspace;
this.defaultPort = defaultPort;
this.dc = dc;
this.rack = rack;
}
public RingDescribeHostSupplier(Keyspace keyspace, int defaultPort, String dc) {
this(keyspace, defaultPort, dc, null);
}
public RingDescribeHostSupplier(Keyspace keyspace, int defaultPort) {
this(keyspace, defaultPort, null, null);
}
@Override
public synchronized List get() {
try {
Map ipToHost = Maps.newHashMap();
for (TokenRange range : keyspace.describeRing(dc, rack)) {
for (String endpoint : range.getEndpoints()) {
Host host = ipToHost.get(endpoint);
if (host == null) {
host = new Host(endpoint, defaultPort);
ipToHost.put(endpoint, host);
}
host.getTokenRanges().add(range);
}
}
previousHosts = Lists.newArrayList(ipToHost.values());
return previousHosts;
}
catch (ConnectionException e) {
if (previousHosts == null) {
throw new RuntimeException(e);
}
LOG.warn("Failed to get hosts from " + keyspace.getKeyspaceName() + " via ring describe. Will use previously known ring instead");
return previousHosts;
}
}
}