All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.netflix.nfsidecar.supplier.EurekaHostSupplier Maven / Gradle / Ivy

package com.netflix.nfsidecar.supplier;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.netflix.appinfo.AmazonInfo;
import com.netflix.appinfo.AmazonInfo.MetaDataKey;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.astyanax.connectionpool.Host;
import com.netflix.discovery.DiscoveryClient;
import com.netflix.discovery.shared.Application;

/**
 * Use Eureka to provide a list of Cassandra hosts that contain the complete
 * Dynomite topology.
 *
 * EurekaHostsSupplier provides a {@code Supplier>} via the
 * {DiscoveryManager} (i.e. the Eureka client).
 *
 * Note that the class needs the Eureka application name to discover all
 * instances for that application.
 */
@Singleton
public class EurekaHostSupplier implements HostSupplier {

    private static final Logger LOG = LoggerFactory.getLogger(EurekaHostSupplier.class);

    // Eureka client
    private final DiscoveryClient discoveryClient;

    @Inject
    public EurekaHostSupplier(DiscoveryClient discoveryClient) {
        this.discoveryClient = discoveryClient;
    }

    /**
     * Get a list of Cassandra hosts that contain the complete Dynomite
     * topology.
     *
     * @param clusterName
     *            name of the Dynomite cluster
     * @return a Supplier that returns a list of Cassandra hosts
     */
    @Override
    public Supplier> getSupplier(final String clusterName) {
        return new Supplier>() {

            @Override
            public List get() {

                if (discoveryClient == null) {
                    LOG.error("Eureka DiscoveryClient cannot be null");
                    throw new RuntimeException("EurekaHostsSupplier needs a non-null DiscoveryClient");
                }

                LOG.debug("Fetching instance list for app: " + clusterName);

                Application app = discoveryClient.getApplication(clusterName.toUpperCase());
                List hosts = new ArrayList();

                if (app == null) {
                    LOG.warn("Cluster '{}' not found in Eureka", clusterName);
                    return hosts;
                }

                List ins = app.getInstances();

                if (ins == null || ins.isEmpty()) {
                    LOG.warn("Cluster '{}' found in Eureka but has no instances", clusterName);
                    return hosts;
                }

                hosts = Lists
                        .newArrayList(Collections2.transform(Collections2.filter(ins, new Predicate() {
                            @Override
                            public boolean apply(InstanceInfo input) {
                                return input.getStatus() == InstanceInfo.InstanceStatus.UP;
                            }
                        }), new Function() {
                            @Override
                            public Host apply(InstanceInfo info) {
                                String[] parts = StringUtils.split(StringUtils.split(info.getHostName(), ".")[0], '-');

                                Host host = new Host(info.getHostName(), info.getPort())
                                        .addAlternateIpAddress(StringUtils
                                                .join(new String[] { parts[1], parts[2], parts[3], parts[4] }, "."))
                                        .addAlternateIpAddress(info.getIPAddr()).setId(info.getId());

                                try {
                                    if (info.getDataCenterInfo() instanceof AmazonInfo) {
                                        AmazonInfo amazonInfo = (AmazonInfo) info.getDataCenterInfo();
                                        host.setRack(amazonInfo.get(MetaDataKey.availabilityZone));
                                    }
                                } catch (Throwable t) {
                                    LOG.error("Error getting rack for host " + host.getName(), t);
                                }

                                return host;
                            }
                        }));

                LOG.debug("Found hosts in Eureka. Num hosts: " + hosts.size());

                return hosts;
            }
        };
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy