
org.refcodes.rest.ext.eureka.EurekaRegistrySidecarImpl Maven / Gradle / Ivy
// /////////////////////////////////////////////////////////////////////////////
// REFCODES.ORG
// /////////////////////////////////////////////////////////////////////////////
// This code is copyright (c) by Siegfried Steiner, Munich, Germany and licensed
// under the following (see "http://en.wikipedia.org/wiki/Multi-licensing")
// licenses:
// -----------------------------------------------------------------------------
// GNU General Public License, v3.0 ("http://www.gnu.org/licenses/gpl-3.0.html")
// -----------------------------------------------------------------------------
// Apache License, v2.0 ("http://www.apache.org/licenses/LICENSE-2.0")
// -----------------------------------------------------------------------------
// Please contact the copyright holding author(s) of the software artifacts in
// question for licensing issues not being covered by the above listed licenses,
// also regarding commercial licensing models or regarding the compatibility
// with other open source licenses.
// /////////////////////////////////////////////////////////////////////////////
package org.refcodes.rest.ext.eureka;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import org.refcodes.component.InitializeException;
import org.refcodes.component.LifeCycleStatus;
import org.refcodes.component.OpenException;
import org.refcodes.component.PauseException;
import org.refcodes.component.ResumeException;
import org.refcodes.component.StartException;
import org.refcodes.component.StopException;
import org.refcodes.data.Scheme;
import org.refcodes.exception.ExceptionUtility;
import org.refcodes.logger.RuntimeLogger;
import org.refcodes.logger.RuntimeLoggerFactorySingleton;
import org.refcodes.net.HttpResponseException;
import org.refcodes.net.HttpStatusException;
import org.refcodes.net.IpAddress;
import org.refcodes.net.MediaType;
import org.refcodes.net.Url;
import org.refcodes.net.UrlBuilderImpl;
import org.refcodes.net.UrlImpl;
import org.refcodes.rest.AbstractHttpRegistrySidecar;
import org.refcodes.rest.HttpRegistrySidecar;
import org.refcodes.rest.HttpRestClient;
import org.refcodes.rest.HttpRestClientImpl;
import org.refcodes.rest.HttpServerDescriptor;
import org.refcodes.rest.RestRequestBuilder;
import org.refcodes.rest.RestResponse;
import org.refcodes.runtime.SystemUtility;
import org.refcodes.security.TrustStoreDescriptor;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.util.EC2MetadataUtils;
import com.amazonaws.util.EC2MetadataUtils.NetworkInterface;
/**
* The {@link EurekaRegistrySidecarImpl} provides you with a library for
* registering your web-services at Eureka service registry and discovery.
*/
public class EurekaRegistrySidecarImpl extends AbstractHttpRegistrySidecar implements EurekaRegistrySidecar {
private static RuntimeLogger LOGGER = RuntimeLoggerFactorySingleton.createRuntimeLogger();
// /////////////////////////////////////////////////////////////////////////
// STATICS:
// /////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////
// CONSTANTS:
// /////////////////////////////////////////////////////////////////////////
private static final String DEFAULT_PING_PATH = "/ping";
private static final String DEFAULT_HOME_PATH = "/home";
private static final String DEFAULT_STATUS_PATH = "/status";
// /////////////////////////////////////////////////////////////////////////
// VARIABLES:
// /////////////////////////////////////////////////////////////////////////
private ExecutorService _executorService;
private Timer _scheduler;
private EurekaDataCenterType _dataCenterType;
private String _statusPath;
private String _homePath;
private int _port = -1;
private Scheme _scheme = null;
private String _protocol = null;
// /////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS:
// /////////////////////////////////////////////////////////////////////////
/**
* @param aExecutorService An executor service to be used when creating
* {@link Thread}s.
*/
public EurekaRegistrySidecarImpl( ExecutorService aExecutorService ) {
_executorService = aExecutorService;
}
// /////////////////////////////////////////////////////////////////////////
// INJECTION:
// /////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////
// LIFECYCLE:
// /////////////////////////////////////////////////////////////////////////
/**
* {@inheritDoc}
*/
@Override
public synchronized void initialize( EurekaServerDescriptor aServerDescriptor, Url aRegistryUrl, TrustStoreDescriptor aStoreDescriptor ) throws InitializeException {
super.initialize();
aRegistryUrl = toHttpRegistryUrl( aRegistryUrl, this );
aStoreDescriptor = toTrustStoreDescriptor( aStoreDescriptor, this );
aServerDescriptor = toHttpServerDescriptor( aServerDescriptor, this );
try {
doRegister( EurekaServiceStatus.STARTING );
}
catch ( Exception e ) {
_lifeCycleAutomaton.setLifeCycleStatus( LifeCycleStatus.ERROR );
throw new InitializeException( ExceptionUtility.toMessage( e ), e );
}
}
/**
* {@inheritDoc}
*/
@Override
public synchronized void start() throws StartException {
try {
super.start();
doStatusUpdate( EurekaServiceStatus.UP );
_scheduler = new Timer( true );
_scheduler.schedule( new HeartBeatDaemon( this, _executorService ), EurekaLoopSleepTime.REGISTRY_SERVICE_HEARBEAT.getMillis(), EurekaLoopSleepTime.REGISTRY_SERVICE_HEARBEAT.getMillis() );
}
catch ( Exception e ) {
_lifeCycleAutomaton.setLifeCycleStatus( LifeCycleStatus.ERROR );
throw new StartException( ExceptionUtility.toMessage( e ), e );
}
}
/**
* {@inheritDoc}
*/
@Override
public synchronized void pause() throws PauseException {
super.pause();
try {
doStatusUpdate( EurekaServiceStatus.DOWN );
}
catch ( Exception e ) {
_lifeCycleAutomaton.setLifeCycleStatus( LifeCycleStatus.ERROR );
throw new PauseException( ExceptionUtility.toMessage( e ), e );
}
}
/**
* {@inheritDoc}
*/
@Override
public synchronized void resume() throws ResumeException {
super.resume();
try {
doStatusUpdate( EurekaServiceStatus.UP );
}
catch ( Exception e ) {
_lifeCycleAutomaton.setLifeCycleStatus( LifeCycleStatus.ERROR );
throw new ResumeException( ExceptionUtility.toMessage( e ), e );
}
}
/**
* {@inheritDoc}
*/
@Override
public synchronized void stop() throws StopException {
super.stop();
try {
_scheduler.cancel();
doStatusUpdate( EurekaServiceStatus.OUT_OF_SERVICE );
}
catch ( Exception e ) {
_lifeCycleAutomaton.setLifeCycleStatus( LifeCycleStatus.ERROR );
throw new StopException( ExceptionUtility.toMessage( e ), e );
}
}
/**
* {@inheritDoc}
*/
@Override
public synchronized void destroy() {
super.destroy();
try {
_scheduler.cancel();
doDeregister();
}
catch ( Exception e ) {
LOGGER.warn( ExceptionUtility.toMessage( e ), e );
_lifeCycleAutomaton.setLifeCycleStatus( LifeCycleStatus.ERROR );
}
}
// /////////////////////////////////////////////////////////////////////////
// METHODS:
// /////////////////////////////////////////////////////////////////////////
/**
* {@inheritDoc}
*/
@Override
public void setPort( int aPort ) {
_port = aPort;
}
/**
* {@inheritDoc}
*/
@Override
public int getPort() {
return _port;
}
/**
* {@inheritDoc}
*/
@Override
public String toProtocol() {
if ( _scheme != null ) {
return _scheme.toProtocol();
}
return _protocol;
}
/**
* {@inheritDoc}
*/
@Override
public void setProtocol( String aProtocol ) {
Scheme theScheme = Scheme.fromProtocol( aProtocol );
if ( theScheme != null ) {
_scheme = theScheme;
_protocol = null;
}
else {
_protocol = aProtocol;
_scheme = null;
}
}
/**
* {@inheritDoc}
*/
@Override
public void setScheme( Scheme aScheme ) {
_scheme = aScheme;
_protocol = null;
}
/**
* {@inheritDoc}
*/
@Override
public Scheme getScheme() {
return _scheme;
}
/**
* {@inheritDoc}
*/
@Override
public String getHomePath() {
return _homePath;
}
/**
* {@inheritDoc}
*/
@Override
public void setHomePath( String aHomePath ) {
_homePath = aHomePath;
}
/**
* {@inheritDoc}
*/
@Override
public String getStatusPath() {
return _statusPath;
}
/**
* {@inheritDoc}
*/
@Override
public void setStatusPath( String aStatusPath ) {
_statusPath = aStatusPath;
}
/**
* {@inheritDoc}
*/
@Override
public EurekaDataCenterType getEurekaDataCenterType() {
return _dataCenterType;
}
/**
* {@inheritDoc}
*/
@Override
public void setEurekaDataCenterType( EurekaDataCenterType aDataCenterType ) {
_dataCenterType = aDataCenterType;
}
// /////////////////////////////////////////////////////////////////////////
// TWEAKS:
// /////////////////////////////////////////////////////////////////////////
/**
* {@inheritDoc}
*/
@Override
public EurekaServerDescriptor toHttpServerDescriptor( String aAlias, String aInstanceId, Scheme aScheme, String aHost, String aVirtualHost, int[] aIpAddress, int aPort, String aPingPath, String aStatusPath, String aHomePath, EurekaDataCenterType aDataCenterType ) {
return toHttpServerDescriptor( aAlias, aInstanceId, aScheme, aHost, aVirtualHost, aIpAddress, aPort, aPingPath, aStatusPath, aHomePath, aDataCenterType, this );
}
/**
* Attention: This method is package local! As it does some well known casts
* which are not obvious from the method signature!
*
* !!! ONLY INTENDED TO BE USED BY THE MAINTAINER OF THIS CLASS !!!
*
* Prepares the {@link HttpServerDescriptor} by creating it from this
* instance's state and the provided arguments. The provided arguments can
* modify theinstance's state. The {@link HttpServerDescriptor} as finally
* used is returned. You may modify this context and use it after
* modification to initialize the server via
* {@link HttpRegistrySidecar#initialize(HttpServerDescriptor, Url)} or
* {@link HttpRegistrySidecar#initialize(HttpServerDescriptor, Url, TrustStoreDescriptor)}.
*
* @param aAlias The name ("alias") which identifies the server in the
* registry.
* @param aInstanceId The ID for the instance when being registered at the
* service registry. If omitted, then the host name is used.
* @param aScheme The {@link Scheme} to which this server is being attached
* (HTTP or HTTPS).
* @param aHost The host name to be used to address this server. If omitted,
* then the system's host name should be used.
* @param aVirtualHost The virtual host name to be used for resolving.
* @param aIpAddress The IP-Address identifying the host.
* @param aPort The port of your service being registered. Make sure, you do
* not
* @param aPingPath The path to use as health-check end-point by this
* server.
* @param aStatusPath The path to use as status-page end-point by this
* server.
* @param aHomePath The path to use as home-page end-point by this server.
* @param aDataCenterType The data center type to be used.
*
* @param aRegistryService The service which's state is to be used.
*
* @return The {@link HttpServerDescriptor} as would be used when
* initializing this instance via
* {@link HttpRegistrySidecar#initialize()}
*/
static EurekaServerDescriptor toHttpServerDescriptor( String aAlias, String aInstanceId, Scheme aScheme, String aHost, String aVirtualHost, int[] aIpAddress, int aPort, String aPingPath, String aStatusPath, String aHomePath, EurekaDataCenterType aDataCenterType, EurekaRegistry> aRegistryService ) {
try {
aHost = toHost( aHost, aRegistryService );
}
catch ( UnknownHostException e ) {
LOGGER.warn( "Unable to determine host as of <" + e.getClass().getName() + ">: " + ExceptionUtility.toMessage( e ) );
}
try {
aIpAddress = toIpAddress( aIpAddress, aRegistryService );
}
catch ( IOException e ) {
LOGGER.warn( "Unable to determine host as of <" + e.getClass().getName() + ">: " + ExceptionUtility.toMessage( e ) );
}
aPort = toPort( aPort, (PortProperty) aRegistryService );
aScheme = toScheme( aScheme, (SchemeProperty) aRegistryService );
aAlias = toAlias( aAlias, aRegistryService );
aVirtualHost = toVirtualHost( aVirtualHost, aRegistryService );
aDataCenterType = toDataCenterType( aDataCenterType, aRegistryService );
aInstanceId = toInstanceId( aInstanceId, aHost, aRegistryService );
EurekaServerDescriptor theServerDescriptor = new EurekaServerDescriptorImpl();
aPingPath = toPingPath( aPingPath, DEFAULT_PING_PATH, aRegistryService );
Url thePingUrl = new UrlImpl( aScheme, aHost, ((PortProperty) aRegistryService).getPort(), aPingPath );
theServerDescriptor.setPingUrl( thePingUrl );
aHomePath = toHomePath( aHomePath, DEFAULT_HOME_PATH, aRegistryService );
Url theHomeUrl = new UrlImpl( aScheme, aHost, ((PortProperty) aRegistryService).getPort(), aHomePath );
theServerDescriptor.setHomeUrl( theHomeUrl );
aStatusPath = toStatusPath( aStatusPath, DEFAULT_STATUS_PATH, aRegistryService );
Url theStatusUrl = new UrlImpl( aScheme, aHost, ((PortProperty) aRegistryService).getPort(), aStatusPath );
theServerDescriptor.setStatusUrl( theStatusUrl );
theServerDescriptor.setHost( aInstanceId ); // Host := instance!
theServerDescriptor.setAlias( aAlias );
theServerDescriptor.setPort( aPort );
theServerDescriptor.setIpAddress( aIpAddress );
theServerDescriptor.setLeaseEvictionDurationInSecs( 30 );
theServerDescriptor.setVirtualHost( aVirtualHost );
AmazonMetaData theMetaData = toAmazonMetaData();
if ( theMetaData != null ) {
theServerDescriptor.setAmazonMetaData( theMetaData );
}
if ( aDataCenterType == null ) {
aDataCenterType = theMetaData != null ? EurekaDataCenterType.AMAZON : EurekaDataCenterType.MY_OWN;
}
theServerDescriptor.setEurekaDataCenterType( aDataCenterType );
// Meta-Data |-->
theServerDescriptor.putMetaData( "host", aHost );
theServerDescriptor.putMetaData( "uname", SystemUtility.getUname() );
theServerDescriptor.putMetaData( "ipAddress", IpAddress.toString( aIpAddress ) );
// Meta-Data <--|
return theServerDescriptor;
}
// /////////////////////////////////////////////////////////////////////////
// HOOKS:
// /////////////////////////////////////////////////////////////////////////
/**
* Resolves the property from the provided value and the provided property
* and sets the property in case the provided value is not null.
*
* @param aHomePath The value to be used when not null.
* @param aDefaultHomePath The value to be used when instance ID is null.
* @param aProperty The property to be used when the value is null and which
* is to be set when the value is not null.
*
* @return The value when not null, else the value of the provided property.
*/
protected static String toHomePath( String aHomePath, String aDefaultHomePath, HomePathProperty aProperty ) {
if ( aHomePath != null ) {
aProperty.setHomePath( aHomePath );
}
else {
aHomePath = aProperty.getHomePath();
if ( aHomePath == null ) {
aHomePath = aDefaultHomePath;
aProperty.setHomePath( aHomePath );
}
}
return aHomePath;
}
/**
* Resolves the property from the provided value and the provided property
* and sets the property in case the provided value is not null.
*
* @param aStatusPath The value to be used when not null.
* @param aDefaultStatusPath The value to be used when instance ID is null.
* @param aProperty The property to be used when the value is null and which
* is to be set when the value is not null.
*
* @return The value when not null, else the value of the provided property.
*/
protected static String toStatusPath( String aStatusPath, String aDefaultStatusPath, StatusPathProperty aProperty ) {
if ( aStatusPath != null ) {
aProperty.setStatusPath( aStatusPath );
}
else {
aStatusPath = aProperty.getStatusPath();
if ( aStatusPath == null ) {
aStatusPath = aDefaultStatusPath;
aProperty.setStatusPath( aStatusPath );
}
}
return aStatusPath;
}
/**
* Resolves the property from the provided value and the provided property
* and sets the property in case the provided value is not null.
*
* @param aInstanceId The value to be used when not null.
* @param aHost The value to be used when instance ID is null.
* @param aProperty The property to be used when the value is null and which
* is to be set when the value is not null.
*
* @return The value when not null, else the value of the provided property.
*/
protected static String toInstanceId( String aInstanceId, String aHost, InstanceIdProperty aProperty ) {
if ( aInstanceId != null ) {
aProperty.setInstanceId( aInstanceId );
}
else {
aInstanceId = aProperty.getInstanceId();
if ( aInstanceId == null ) {
try {
String theInstanceId = EC2MetadataUtils.getInstanceId();
if ( theInstanceId != null && theInstanceId.length() != 0 ) {
aInstanceId = theInstanceId;
aProperty.setInstanceId( aInstanceId );
}
}
catch ( Throwable ignore ) { /* ignore */ }
if ( aInstanceId == null ) {
aInstanceId = aHost;
aProperty.setInstanceId( aInstanceId );
}
}
}
return aInstanceId;
}
/**
* Registers the given service at Eureka.
*
* @param aServiceStatus The {@link EurekaServiceStatus} to be set.
* @throws HttpStatusException Thrown in case a HTTP response was of an
* erroneous status.
* @throws OpenException Thrown in case opening or accessing an open line
* (connection, junction, link) caused problems.
*/
protected void doRegister( EurekaServiceStatus aServiceStatus ) throws HttpStatusException, OpenException {
doRegister( aServiceStatus, this, _executorService );
}
/**
* Registers the given service at Eureka.
*
* @param aServiceStatus The {@link EurekaServiceStatus} to be set.
* @param aRegistryService The registry service to be used for registering.
* @param aExecutorService The {@link ExecutorService} used to create
* threads.
* @throws HttpStatusException Thrown in case a HTTP response was of an
* erroneous status.
* @throws OpenException Thrown in case opening or accessing an open line
* (connection, junction, link) caused problems.
*/
protected static void doRegister( EurekaServiceStatus aServiceStatus, EurekaRegistry> aRegistryService, ExecutorService aExecutorService ) throws HttpStatusException, OpenException {
Url theRegistryUrl = new UrlImpl( aRegistryService.getHttpRegistryUrl(), aRegistryService.getHttpServerDescriptor().getAlias() );
HttpRestClient theRestClient = new HttpRestClientImpl( aExecutorService );
theRestClient.open( aRegistryService.getTrustStoreDescriptor() );
RestRequestBuilder theBuilder = theRestClient.buildPost( theRegistryUrl );
aRegistryService.getHttpServerDescriptor().put( "instance/status", aServiceStatus != null ? aServiceStatus.name() : EurekaServiceStatus.UNKNOWN.name() );
theBuilder.setRequest( aRegistryService.getHttpServerDescriptor() );
theBuilder.getHeaderFields().putContentType( MediaType.APPLICATION_XML );
LOGGER.info( "Registering status <" + aServiceStatus + "> at <" + aRegistryService.getHttpRegistryUrl().toHttpUrl() + "> Eureka service registry for app-ID <" + aRegistryService.getHttpServerDescriptor().getAlias() + "> with instance-ID <" + aRegistryService.getHttpServerDescriptor().getHost() + "> ..." );
RestResponse theResponse = theBuilder.toRestResponse();
if ( theResponse.getHttpStatusCode().isErrorStatus() ) {
throw theResponse.getHttpStatusCode().toHttpStatusException( "Cannot register service with alias <" + aRegistryService.getHttpServerDescriptor().getAlias() + "> with service registry <" + aRegistryService.getHttpRegistryUrl().toHttpUrl() + "> due to HTTP-Status-Code " + theResponse.getHttpStatusCode() + " <" + theResponse.getHttpStatusCode().getStatusCode() + ">: " + theResponse.getHttpBody() );
}
}
/**
* Does a Eureka status update for the given service.
*
* @param aServiceStatus The {@link EurekaServiceStatus} to be set.
* @throws HttpStatusException Thrown in case a HTTP response was of an
* erroneous status.
* @throws OpenException Thrown in case opening or accessing an open line
* (connection, junction, link) caused problems.
* @throws UnknownHostException Thrown in case the targeted host is unknown.
*/
protected void doStatusUpdate( EurekaServiceStatus aServiceStatus ) throws OpenException, UnknownHostException, HttpStatusException {
doStatusUpdate( aServiceStatus, this, _executorService );
}
/**
* Does a Eureka status update for the given service.
*
* @param aServiceStatus The {@link EurekaServiceStatus} to be set.
* @param aRegistryService The registry service to be used for registering.
* @param aExecutorService The {@link ExecutorService} used to create
* threads.
* @throws HttpStatusException Thrown in case a HTTP response was of an
* erroneous status.
* @throws OpenException Thrown in case opening or accessing an open line
* (connection, junction, link) caused problems.
* @throws UnknownHostException Thrown in case the targeted host is unknown.
*/
protected static void doStatusUpdate( EurekaServiceStatus aServiceStatus, EurekaRegistry> aRegistryService, ExecutorService aExecutorService ) throws OpenException, UnknownHostException, HttpStatusException {
Url theRegistryUrl = new UrlBuilderImpl( aRegistryService.getHttpRegistryUrl(), aRegistryService.getAlias(), aRegistryService.getInstanceId(), "status" );
theRegistryUrl.getQueryFields().put( "value", aServiceStatus.name() );
HttpRestClient theRestClient = new HttpRestClientImpl( aExecutorService );
theRestClient.open( aRegistryService.getTrustStoreDescriptor() );
LOGGER.info( "Status update <" + aServiceStatus + "> at <" + theRegistryUrl.toHttpUrl() + "> Eureka service registry for app-ID <" + aRegistryService.getAlias() + "> with instance-ID <" + aRegistryService.getInstanceId() + "> ..." );
RestResponse theResponse;
theResponse = theRestClient.doPut( theRegistryUrl );
if ( theResponse.getHttpStatusCode().isErrorStatus() ) {
throw theResponse.getHttpStatusCode().toHttpStatusException( "Cannot register service with alias <" + aRegistryService.getAlias() + "> with service registry <" + aRegistryService.getHttpRegistryUrl().toHttpUrl() + "> due to HTTP-Status-Code " + theResponse.getHttpStatusCode() + " <" + theResponse.getHttpStatusCode().getStatusCode() + ">: " + theResponse.getHttpBody() );
}
}
/**
* Unregisters the given service at Eureka.
*
* @throws HttpStatusException Thrown in case a HTTP response was of an
* erroneous status.t
* @throws OpenException Thrown in case opening or accessing an open line
* (connection, junction, link) caused problems.
*/
protected void doDeregister() throws OpenException, HttpStatusException {
doDeregister( this, _executorService );
}
/**
* Unregisters the given service at Eureka.
*
* @param aRegistryService The registry service to be used for registering.
* @param aExecutorService The {@link ExecutorService} used to create
* threads.
* @throws HttpStatusException Thrown in case a HTTP response was of an
* erroneous status.t
* @throws OpenException Thrown in case opening or accessing an open line
* (connection, junction, link) caused problems.
*/
protected static void doDeregister( EurekaRegistry> aRegistryService, ExecutorService aExecutorService ) throws OpenException, HttpStatusException {
Url theRegistryUrl = new UrlImpl( aRegistryService.getHttpRegistryUrl(), aRegistryService.getAlias(), aRegistryService.getInstanceId() );
HttpRestClient theRestClient = new HttpRestClientImpl( aExecutorService );
theRestClient.open( aRegistryService.getTrustStoreDescriptor() );
RestResponse theResponse;
LOGGER.info( "Derigstering at <" + aRegistryService.getHttpRegistryUrl().toHttpUrl() + "> Eureka service registry for app-ID <" + aRegistryService.getAlias() + "> with instance-ID <" + aRegistryService.getInstanceId() + "> ..." );
theResponse = theRestClient.doDelete( theRegistryUrl );
if ( theResponse.getHttpStatusCode().isErrorStatus() ) {
throw theResponse.getHttpStatusCode().toHttpStatusException( "Cannot register service with alias <" + aRegistryService.getAlias() + "> with service registry <" + aRegistryService.getHttpRegistryUrl().toHttpUrl() + "> due to HTTP-Status-Code " + theResponse.getHttpStatusCode() + " <" + theResponse.getHttpStatusCode().getStatusCode() + ">: " + theResponse.getHttpBody() );
}
}
/**
* Resolves the property from the provided value and the provided property
* and sets the property in case the provided value is not null.
*
* @param aRegistryUrl The value to be used when not null.
* @param aProperty The property to be used when the value is null and which
* is to be set when the value is not null.
*
* @return The value when not null, else the value of the provided property.
*/
protected static Url toHttpRegistryUrl( Url aRegistryUrl, HttpRegistryUrlProperty aProperty ) {
aRegistryUrl = AbstractHttpRegistrySidecar.toHttpRegistryUrl( aRegistryUrl, aProperty );
if ( aRegistryUrl != null && aRegistryUrl.getPath() == null ) {
aRegistryUrl = new UrlImpl( aRegistryUrl, EUREKA_BASE_PATH );
aProperty.setHttpRegistryUrl( aRegistryUrl );
}
return aRegistryUrl;
}
/**
* Resolves the property from the provided value and the provided property
* and sets the property in case the provided value is not null.
*
* @param aDataCenterType The value to be used when not null.
* @param aProperty The property to be used when the value is null and which
* is to be set when the value is not null.
*
* @return The value when not null, else the value of the provided property.
*/
protected static EurekaDataCenterType toDataCenterType( EurekaDataCenterType aDataCenterType, EurekaDataCenterTypeProperty aProperty ) {
if ( aDataCenterType != null ) {
aProperty.setEurekaDataCenterType( aDataCenterType );
}
else {
aDataCenterType = aProperty.getEurekaDataCenterType();
}
return aDataCenterType;
}
/**
* Constructs the Amazon Meta-Data from the Machine's network and AWS
* settings.
*
* @return The according Amazon Meta-Data.
*/
protected static AmazonMetaData toAmazonMetaData() {
AmazonMetaData theMetaData = null;
try {
Region theRegion = Regions.getCurrentRegion();
if ( theRegion != null ) {
theMetaData = new AmazonMetaDataImpl();
theMetaData.setAmiId( EC2MetadataUtils.getAmiId() );
String theAmiLaunchIndex = EC2MetadataUtils.getAmiLaunchIndex();
Integer theLaunchIndex = 0;
if ( theAmiLaunchIndex != null ) {
theLaunchIndex = Integer.valueOf( theAmiLaunchIndex );
theMetaData.setAmiLaunchIndex( theLaunchIndex );
}
theMetaData.setAmiManifestPath( EC2MetadataUtils.getAmiManifestPath() );
theMetaData.setAvailabilityZone( EC2MetadataUtils.getAvailabilityZone() );
theMetaData.setInstanceId( EC2MetadataUtils.getInstanceId() );
theMetaData.setInstanceType( EC2MetadataUtils.getInstanceType() );
theMetaData.setLocalHostName( EC2MetadataUtils.getLocalHostName() );
// Too much information |-->
List theInterfaces = EC2MetadataUtils.getNetworkInterfaces();
if ( theInterfaces != null ) {
List eLocalIPv4s = null;
List ePublicIPv4s = null;
String ePublicHostName = null;
for ( NetworkInterface eInterface : theInterfaces ) {
if ( eLocalIPv4s == null || eLocalIPv4s.size() == 0 ) {
eLocalIPv4s = eInterface.getLocalIPv4s();
if ( eLocalIPv4s != null && eLocalIPv4s.size() != 0 ) {
theMetaData.setLocalIpv4( eLocalIPv4s.get( 0 ) );
}
}
if ( ePublicHostName == null || ePublicHostName.length() == 0 ) {
ePublicHostName = eInterface.getPublicHostname();
if ( ePublicHostName != null && ePublicHostName.length() != 0 ) {
theMetaData.setPublicHostname( ePublicHostName );
}
}
if ( ePublicIPv4s == null || ePublicIPv4s.size() == 0 ) {
ePublicIPv4s = eInterface.getPublicIPv4s();
if ( ePublicIPv4s != null && ePublicIPv4s.size() != 0 ) {
theMetaData.setPublicIpv4( ePublicIPv4s.get( 0 ) );
}
}
}
}
// Too much information <--|
}
}
catch ( Throwable ignore ) { /* ignore */ }
return theMetaData;
}
// /////////////////////////////////////////////////////////////////////////
// HELPER:
// /////////////////////////////////////////////////////////////////////////
// /////////////////////////////////////////////////////////////////////////
// INNER CLASSES:
// /////////////////////////////////////////////////////////////////////////
public static class HeartBeatDaemon extends TimerTask {
private HttpRestClient _client;
private EurekaRegistry> _registry;
public HeartBeatDaemon( EurekaRegistry> aRegistry, ExecutorService aExecutorService ) {
_client = new HttpRestClientImpl( aExecutorService ).withTrustStoreDescriptor( aRegistry.getTrustStoreDescriptor() );
_registry = aRegistry;
}
/**
* {@inheritDoc}
*/
@Override
public void run() {
if ( _registry.isRunning() ) {
UrlImpl theUrl = new UrlImpl( _registry.getHttpRegistryUrl(), _registry.getAlias(), _registry.getInstanceId() );
LOGGER.debug( "Sending heartbeat to <" + theUrl.toHttpUrl() + ">..." );
try {
RestResponse theResponse = _client.doPut( theUrl );
if ( theResponse.getHttpStatusCode().isErrorStatus() ) {
LOGGER.warn( "Received HTTP status code <" + theResponse.getHttpStatusCode().getStatusCode() + "> (" + theResponse.getHttpStatusCode() + ") send heartbeat to URL <" + theUrl.toHttpUrl() + ">: " + theResponse.getHttpBody() );
}
}
catch ( HttpResponseException e ) {
LOGGER.warn( "Unable to send heartbeat to URL <" + theUrl.toHttpUrl() + ">: " + e.getMessage(), e );
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy