All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.netflix.evcache.pool.eureka.EurekaNodeListProvider Maven / Gradle / Ivy
package com.netflix.evcache.pool.eureka;
import com.google.common.net.InetAddresses;
import com.netflix.appinfo.AmazonInfo;
import com.netflix.appinfo.ApplicationInfoManager;
import com.netflix.appinfo.DataCenterInfo;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
import com.netflix.archaius.api.Property;
import com.netflix.archaius.api.PropertyRepository;
import com.netflix.discovery.EurekaClient;
import com.netflix.discovery.shared.Application;
import com.netflix.evcache.metrics.EVCacheMetricsFactory;
import com.netflix.evcache.pool.EVCacheClientPool;
import com.netflix.evcache.pool.EVCacheNodeList;
import com.netflix.evcache.pool.EVCacheServerGroupConfig;
import com.netflix.evcache.pool.ServerGroup;
import com.netflix.spectator.api.BasicTag;
import com.netflix.spectator.api.Tag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class EurekaNodeListProvider implements EVCacheNodeList {
private static final Logger log = LoggerFactory.getLogger(EurekaNodeListProvider.class);
private final EurekaClient _eurekaClient;
private PropertyRepository props;
private final ApplicationInfoManager applicationInfoManager;
@SuppressWarnings("rawtypes") // Archaius2 PropertyRepository does not support ParameterizedTypes
private Property ignoreHosts = null;
public EurekaNodeListProvider(ApplicationInfoManager applicationInfoManager, EurekaClient eurekaClient, PropertyRepository props) {
this.applicationInfoManager = applicationInfoManager;
this._eurekaClient = eurekaClient;
this.props = props;
}
/*
* (non-Javadoc)
*
* @see com.netflix.evcache.pool.EVCacheNodeList#discoverInstances()
*/
@Override
public Map discoverInstances(String _appName) throws IOException {
final Property ignoreAppEurekaStatus = props.get("evcache.ignoreAppEurekaStatus", Boolean.class).orElse(false);
if (ignoreAppEurekaStatus.get())
log.info("Not going to consider the eureka status of the application, to initialize evcache client.");
if (!ignoreAppEurekaStatus.get() && (applicationInfoManager.getInfo().getStatus() == InstanceStatus.DOWN)) {
log.info("Not initializing evcache client as application eureka status is DOWN. " +
"One can override this behavior by setting evcache.ignoreAppEurekaStatus property to true, scoped to your application.");
return Collections. emptyMap();
}
/* Get a list of EVCACHE instances from the DiscoveryManager */
final Application app = _eurekaClient.getApplication(_appName);
if (app == null) return Collections. emptyMap();
final List appInstances = app.getInstances();
final Map instancesSpecific = new HashMap();
/* Iterate all the discovered instances to find usable ones */
for (InstanceInfo iInfo : appInstances) {
final DataCenterInfo dcInfo = iInfo.getDataCenterInfo();
if (dcInfo == null) {
if (log.isErrorEnabled()) log.error("Data Center Info is null for appName - " + _appName);
continue;
}
/* Only AWS instances are usable; bypass all others */
if (DataCenterInfo.Name.Amazon != dcInfo.getName() || !(dcInfo instanceof AmazonInfo)) {
log.error("This is not an AWSDataCenter. You will not be able to use Discovery Nodelist Provider. Cannot proceed. " +
"DataCenterInfo : {}; appName - {}. Please use SimpleNodeList provider and specify the server groups manually.",
dcInfo, _appName);
continue;
}
final AmazonInfo amznInfo = (AmazonInfo) dcInfo;
// We checked above if this instance is Amazon so no need to do a instanceof check
final String zone = amznInfo.get(AmazonInfo.MetaDataKey.availabilityZone);
if(zone == null) {
final List tagList = new ArrayList(3);
EVCacheMetricsFactory.getInstance().addAppNameTags(tagList, _appName);
tagList.add(new BasicTag(EVCacheMetricsFactory.CONFIG_NAME, EVCacheMetricsFactory.NULL_ZONE));
EVCacheMetricsFactory.getInstance().increment(EVCacheMetricsFactory.CONFIG, tagList);
continue;
}
final String asgName = iInfo.getASGName();
if(asgName == null) {
final List tagList = new ArrayList(3);
EVCacheMetricsFactory.getInstance().addAppNameTags(tagList, _appName);
tagList.add(new BasicTag(EVCacheMetricsFactory.CONFIG_NAME, EVCacheMetricsFactory.NULL_SERVERGROUP));
EVCacheMetricsFactory.getInstance().increment(EVCacheMetricsFactory.CONFIG, tagList);
continue;
}
final Property asgEnabled = props.get(asgName + ".enabled", Boolean.class).orElse(true);
if (!asgEnabled.get()) {
if(log.isDebugEnabled()) log.debug("ASG " + asgName + " is disabled so ignoring it");
continue;
}
final Map metaInfo = iInfo.getMetadata();
final int evcachePort = Integer.parseInt((metaInfo != null && metaInfo.containsKey("evcache.port")) ?
metaInfo.get("evcache.port") : EVCacheClientPool.DEFAULT_PORT);
int port = evcachePort;
final Property isSecure = props.get(asgName + ".use.secure", Boolean.class)
.orElseGet(_appName + ".use.secure")
.orElseGet("evcache.use.secure")
.orElse(false);
if(isSecure.get()) {
port = Integer.parseInt((metaInfo != null && metaInfo.containsKey("evcache.secure.port")) ?
metaInfo.get("evcache.secure.port") : EVCacheClientPool.DEFAULT_SECURE_PORT);
}
final ServerGroup serverGroup = new ServerGroup(zone, asgName);
final Set instances;
final EVCacheServerGroupConfig config;
if (instancesSpecific.containsKey(serverGroup)) {
config = instancesSpecific.get(serverGroup);
instances = config.getInetSocketAddress();
} else {
instances = new HashSet();
config = new EVCacheServerGroupConfig(serverGroup, instances);
instancesSpecific.put(serverGroup, config);
//EVCacheMetricsFactory.getInstance().getRegistry().gauge(EVCacheMetricsFactory.getInstance().getRegistry().createId(_appName + "-port", "ServerGroup", asgName, "APP", _appName), Long.valueOf(port));
}
/* Don't try to use downed instances */
final InstanceStatus status = iInfo.getStatus();
if (status == null || InstanceStatus.OUT_OF_SERVICE == status || InstanceStatus.DOWN == status) {
if (log.isDebugEnabled()) log.debug("The Status of the instance in Discovery is " + status + ". App Name : " + _appName + "; Zone : " + zone
+ "; Host : " + iInfo.getHostName() + "; Instance Id - " + iInfo.getId());
continue;
}
final InstanceInfo myInfo = applicationInfoManager.getInfo();
final DataCenterInfo myDC = myInfo.getDataCenterInfo();
final AmazonInfo myAmznDC = (myDC instanceof AmazonInfo) ? (AmazonInfo) myDC : null;
final String myInstanceId = myInfo.getInstanceId();
final String myIp = myInfo.getIPAddr();
final String myPublicHostName = (myAmznDC != null) ? myAmznDC.get(AmazonInfo.MetaDataKey.publicHostname) : null;
boolean isInCloud = false;
if (myPublicHostName != null) {
isInCloud = myPublicHostName.startsWith("ec2");
}
if (!isInCloud) {
if (myAmznDC != null && myAmznDC.get(AmazonInfo.MetaDataKey.vpcId) != null) {
isInCloud = true;
} else {
if (myIp.equals(myInstanceId)) {
isInCloud = false;
}
}
}
final String myZone = (myAmznDC != null) ? myAmznDC.get(AmazonInfo.MetaDataKey.availabilityZone) : null;
final String myRegion = (myZone != null) ? myZone.substring(0, myZone.length() - 1) : null;
final String region = (zone != null) ? zone.substring(0, zone.length() - 1) : null;
final String host = amznInfo.get(AmazonInfo.MetaDataKey.publicHostname);
InetSocketAddress address = null;
final String vpcId = amznInfo.get(AmazonInfo.MetaDataKey.vpcId);
final String localIp = amznInfo.get(AmazonInfo.MetaDataKey.localIpv4);
if (log.isDebugEnabled()) log.debug("myZone - " + myZone + "; zone : " + zone + "; myRegion : " + myRegion + "; region : " + region + "; host : " + host + "; vpcId : " + vpcId);
if(ignoreHosts == null) ignoreHosts = props.get(_appName + ".ignore.hosts", Set.class).orElse(Collections.emptySet());
if(localIp != null && ignoreHosts.get().contains(localIp)) continue;
if(host != null && ignoreHosts.get().contains(host)) continue;
if (vpcId != null) {
final InetAddress add = InetAddresses.forString(localIp);
final InetAddress inetAddress = InetAddress.getByAddress(localIp, add.getAddress());
address = new InetSocketAddress(inetAddress, port);
if (log.isDebugEnabled()) log.debug("VPC : localIp - " + localIp + " ; add : " + add + "; inetAddress : " + inetAddress + "; address - " + address
+ "; App Name : " + _appName + "; Zone : " + zone + "; myZone - " + myZone + "; Host : " + iInfo.getHostName() + "; Instance Id - " + iInfo.getId());
} else {
if(host != null && host.startsWith("ec2")) {
final InetAddress inetAddress = (localIp != null) ? InetAddress.getByAddress(host, InetAddresses.forString(localIp).getAddress()) : InetAddress.getByName(host);
address = new InetSocketAddress(inetAddress, port);
if (log.isDebugEnabled()) log.debug("myZone - " + myZone + ". host : " + host
+ "; inetAddress : " + inetAddress + "; address - " + address + "; App Name : " + _appName
+ "; Zone : " + zone + "; Host : " + iInfo.getHostName() + "; Instance Id - " + iInfo.getId());
} else {
final String ipToUse = (isInCloud) ? localIp : amznInfo.get(AmazonInfo.MetaDataKey.publicIpv4);
final InetAddress add = InetAddresses.forString(ipToUse);
final InetAddress inetAddress = InetAddress.getByAddress(ipToUse, add.getAddress());
address = new InetSocketAddress(inetAddress, port);
if (log.isDebugEnabled()) log.debug("CLASSIC : IPToUse - " + ipToUse + " ; add : " + add + "; inetAddress : " + inetAddress + "; address - " + address
+ "; App Name : " + _appName + "; Zone : " + zone + "; myZone - " + myZone + "; Host : " + iInfo.getHostName() + "; Instance Id - " + iInfo.getId());
}
}
instances.add(address);
}
return instancesSpecific;
}
}