package com.netflix.appinfo;
import javax.inject.Inject;
import javax.inject.Singleton;
import com.netflix.discovery.CommonConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.netflix.appinfo.AmazonInfo.MetaDataKey;
import com.netflix.archaius.api.Config;
/**
* When running in EC2 add the following override binding.
*
* bind(EurekaInstanceConfig.class).to(KaryonEc2EurekaInstanceConfig.class);
*
*
* @author elandau
*
*/
@Singleton
public class Ec2EurekaArchaius2InstanceConfig extends EurekaArchaius2InstanceConfig implements RefreshableInstanceConfig {
private static final Logger LOG = LoggerFactory.getLogger(Ec2EurekaArchaius2InstanceConfig.class);
private static final String[] DEFAULT_AWS_ADDRESS_RESOLUTION_ORDER = new String[] {
MetaDataKey.publicHostname.name(),
MetaDataKey.localIpv4.name()
};
private final AmazonInfoConfig amazonInfoConfig;
private final RefreshableAmazonInfoProvider amazonInfoHolder;
@Inject
public Ec2EurekaArchaius2InstanceConfig(Config configInstance, AmazonInfoConfig amazonInfoConfig) {
this(configInstance, amazonInfoConfig, CommonConstants.DEFAULT_CONFIG_NAMESPACE);
}
/* visible for testing */ Ec2EurekaArchaius2InstanceConfig(Config configInstance, AmazonInfo info) {
this(configInstance, new Archaius2AmazonInfoConfig(configInstance), CommonConstants.DEFAULT_CONFIG_NAMESPACE, info, false);
}
public Ec2EurekaArchaius2InstanceConfig(Config configInstance, AmazonInfoConfig amazonInfoConfig, String namespace) {
this(configInstance, amazonInfoConfig, namespace, null, true);
}
/* visible for testing */ Ec2EurekaArchaius2InstanceConfig(Config configInstance,
AmazonInfoConfig amazonInfoConfig,
String namespace,
AmazonInfo initialInfo,
boolean eagerInit) {
super(configInstance, namespace);
this.amazonInfoConfig = amazonInfoConfig;
if (eagerInit) {
RefreshableAmazonInfoProvider.FallbackAddressProvider fallbackAddressProvider =
new RefreshableAmazonInfoProvider.FallbackAddressProvider() {
@Override
public String getFallbackIp() {
return Ec2EurekaArchaius2InstanceConfig.super.getIpAddress();
}
@Override
public String getFallbackHostname() {
return Ec2EurekaArchaius2InstanceConfig.super.getHostName(false);
}
};
this.amazonInfoHolder = new RefreshableAmazonInfoProvider(amazonInfoConfig, fallbackAddressProvider);
} else {
this.amazonInfoHolder = new RefreshableAmazonInfoProvider(initialInfo, amazonInfoConfig);
}
}
@Override
public String getHostName(boolean refresh) {
if (refresh) {
amazonInfoHolder.refresh();
}
return amazonInfoHolder.get().get(MetaDataKey.publicHostname);
}
@Override
public DataCenterInfo getDataCenterInfo() {
return amazonInfoHolder.get();
}
@Override
public String[] getDefaultAddressResolutionOrder() {
String[] order = super.getDefaultAddressResolutionOrder();
return (order.length == 0) ? DEFAULT_AWS_ADDRESS_RESOLUTION_ORDER : order;
}
/**
* @deprecated 2016-09-07
*
* Refresh instance info - currently only used when in AWS cloud
* as a public ip can change whenever an EIP is associated or dissociated.
*/
@Deprecated
public synchronized void refreshAmazonInfo() {
amazonInfoHolder.refresh();
}
@Override
public String resolveDefaultAddress(boolean refresh) {
// In this method invocation data center info will be refreshed.
String result = getHostName(refresh);
for (String name : getDefaultAddressResolutionOrder()) {
try {
AmazonInfo.MetaDataKey key = AmazonInfo.MetaDataKey.valueOf(name);
String address = amazonInfoHolder.get().get(key);
if (address != null && !address.isEmpty()) {
result = address;
break;
}
} catch (Exception e) {
LOG.error("failed to resolve default address for key {}, skipping", name, e);
}
}
return result;
}
}