// Path: spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/serviceregistry/EurekaAutoServiceRegistration.java
// public class EurekaAutoServiceRegistration
// 		implements AutoServiceRegistration, SmartLifecycle, Ordered, SmartApplicationListener {
// 
// 	private static final Log log = LogFactory.getLog(EurekaAutoServiceRegistration.class);
// 
// 	private AtomicBoolean running = new AtomicBoolean(false);
// 
// 	private int order = 0;
// 
// 	private AtomicInteger port = new AtomicInteger(0);
// 
// 	private ApplicationContext context;
// 
// 	private EurekaServiceRegistry serviceRegistry;
// 
// 	private EurekaRegistration registration;
// 
// 	public EurekaAutoServiceRegistration(ApplicationContext context, EurekaServiceRegistry serviceRegistry,
// 			EurekaRegistration registration) {
// 		this.context = context;
// 		this.serviceRegistry = serviceRegistry;
// 		this.registration = registration;
// 	}
// 
// 	@Override
// 	public void start() {
// 		// only set the port if the nonSecurePort or securePort is 0 and this.port != 0
// 		if (this.port.get() != 0) {
// 			if (this.registration.getNonSecurePort() == 0) {
// 				this.registration.setNonSecurePort(this.port.get());
// 			}
// 
// 			if (this.registration.getSecurePort() == 0 && this.registration.isSecure()) {
// 				this.registration.setSecurePort(this.port.get());
// 			}
// 		}
// 
// 		// only initialize if nonSecurePort is greater than 0 and it isn't already running
// 		// because of containerPortInitializer below
// 		if (!this.running.get() && this.registration.getNonSecurePort() > 0) {
// 
// 			this.serviceRegistry.register(this.registration);
// 
// 			this.context.publishEvent(new InstanceRegisteredEvent<>(this, this.registration.getInstanceConfig()));
// 			this.running.set(true);
// 		}
// 	}
// 
// 	@Override
// 	public void stop() {
// 		this.serviceRegistry.deregister(this.registration);
// 		this.running.set(false);
// 	}
// 
// 	@Override
// 	public boolean isRunning() {
// 		return this.running.get();
// 	}
// 
// 	@Override
// 	public int getPhase() {
// 		return 0;
// 	}
// 
// 	@Override
// 	public boolean isAutoStartup() {
// 		return true;
// 	}
// 
// 	@Override
// 	public void stop(Runnable callback) {
// 		stop();
// 		callback.run();
// 	}
// 
// 	@Override
// 	public int getOrder() {
// 		return this.order;
// 	}
// 
// 	@Override
// 	public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
// 		return WebServerInitializedEvent.class.isAssignableFrom(eventType)
// 				|| ContextClosedEvent.class.isAssignableFrom(eventType);
// 	}
// 
// 	@Override
// 	public void onApplicationEvent(ApplicationEvent event) {
// 		if (event instanceof WebServerInitializedEvent) {
// 			onApplicationEvent((WebServerInitializedEvent) event);
// 		}
// 		else if (event instanceof ContextClosedEvent) {
// 			onApplicationEvent((ContextClosedEvent) event);
// 		}
// 	}
// 
// 	public void onApplicationEvent(WebServerInitializedEvent event) {
// 		// TODO: take SSL into account
// 		String contextName = event.getApplicationContext().getServerNamespace();
// 		if (contextName == null || !contextName.equals("management")) {
// 			int localPort = event.getWebServer().getPort();
// 			if (this.port.get() == 0) {
// 				log.info("Updating port to " + localPort);
// 				this.port.compareAndSet(0, localPort);
// 				start();
// 			}
// 		}
// 	}
// 
// 	public void onApplicationEvent(ContextClosedEvent event) {
// 		if (event.getApplicationContext() == context) {
// 			stop();
// 		}
// 	}
// 
// }


import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaAutoServiceRegistration;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.netflix.appinfo.HealthCheckHandler;
import com.netflix.discovery.EurekaClient;
import com.netflix.discovery.EurekaClientConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.health.SimpleStatusAggregator;
import org.springframework.boot.actuate.health.StatusAggregator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.ConditionalOnBlockingDiscoveryEnabled;
import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled;
import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent;
	@Bean
	@ConditionalOnMissingBean
	public EurekaDiscoveryClient discoveryClient(EurekaClient client, EurekaClientConfig clientConfig) {
		return new EurekaDiscoveryClient(client, clientConfig);
	}

	@Configuration(proxyBeanMethods = false)
	@ConditionalOnProperty(value = "eureka.client.healthcheck.enabled", matchIfMissing = false)
	protected static class EurekaHealthCheckHandlerConfiguration {

		@Autowired(required = false)
		private StatusAggregator statusAggregator = new SimpleStatusAggregator();

		@Bean
		@ConditionalOnMissingBean(HealthCheckHandler.class)
		public EurekaHealthCheckHandler eurekaHealthCheckHandler() {
			return new EurekaHealthCheckHandler(this.statusAggregator);
		}

	}

	@Configuration(proxyBeanMethods = false)
	@ConditionalOnClass(RefreshScopeRefreshedEvent.class)
	protected static class EurekaClientConfigurationRefresher
			implements ApplicationListener<RefreshScopeRefreshedEvent> {

		@Autowired(required = false)
		private EurekaClient eurekaClient;

		@Autowired(required = false)
// Path: spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/serviceregistry/EurekaAutoServiceRegistration.java
// public class EurekaAutoServiceRegistration
// 		implements AutoServiceRegistration, SmartLifecycle, Ordered, SmartApplicationListener {
// 
// 	private static final Log log = LogFactory.getLog(EurekaAutoServiceRegistration.class);
// 
// 	private AtomicBoolean running = new AtomicBoolean(false);
// 
// 	private int order = 0;
// 
// 	private AtomicInteger port = new AtomicInteger(0);
// 
// 	private ApplicationContext context;
// 
// 	private EurekaServiceRegistry serviceRegistry;
// 
// 	private EurekaRegistration registration;
// 
// 	public EurekaAutoServiceRegistration(ApplicationContext context, EurekaServiceRegistry serviceRegistry,
// 			EurekaRegistration registration) {
// 		this.context = context;
// 		this.serviceRegistry = serviceRegistry;
// 		this.registration = registration;
// 	}
// 
// 	@Override
// 	public void start() {
// 		// only set the port if the nonSecurePort or securePort is 0 and this.port != 0
// 		if (this.port.get() != 0) {
// 			if (this.registration.getNonSecurePort() == 0) {
// 				this.registration.setNonSecurePort(this.port.get());
// 			}
// 
// 			if (this.registration.getSecurePort() == 0 && this.registration.isSecure()) {
// 				this.registration.setSecurePort(this.port.get());
// 			}
// 		}
// 
// 		// only initialize if nonSecurePort is greater than 0 and it isn't already running
// 		// because of containerPortInitializer below
// 		if (!this.running.get() && this.registration.getNonSecurePort() > 0) {
// 
// 			this.serviceRegistry.register(this.registration);
// 
// 			this.context.publishEvent(new InstanceRegisteredEvent<>(this, this.registration.getInstanceConfig()));
// 			this.running.set(true);
// 		}
// 	}
// 
// 	@Override
// 	public void stop() {
// 		this.serviceRegistry.deregister(this.registration);
// 		this.running.set(false);
// 	}
// 
// 	@Override
// 	public boolean isRunning() {
// 		return this.running.get();
// 	}
// 
// 	@Override
// 	public int getPhase() {
// 		return 0;
// 	}
// 
// 	@Override
// 	public boolean isAutoStartup() {
// 		return true;
// 	}
// 
// 	@Override
// 	public void stop(Runnable callback) {
// 		stop();
// 		callback.run();
// 	}
// 
// 	@Override
// 	public int getOrder() {
// 		return this.order;
// 	}
// 
// 	@Override
// 	public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
// 		return WebServerInitializedEvent.class.isAssignableFrom(eventType)
// 				|| ContextClosedEvent.class.isAssignableFrom(eventType);
// 	}
// 
// 	@Override
// 	public void onApplicationEvent(ApplicationEvent event) {
// 		if (event instanceof WebServerInitializedEvent) {
// 			onApplicationEvent((WebServerInitializedEvent) event);
// 		}
// 		else if (event instanceof ContextClosedEvent) {
// 			onApplicationEvent((ContextClosedEvent) event);
// 		}
// 	}
// 
// 	public void onApplicationEvent(WebServerInitializedEvent event) {
// 		// TODO: take SSL into account
// 		String contextName = event.getApplicationContext().getServerNamespace();
// 		if (contextName == null || !contextName.equals("management")) {
// 			int localPort = event.getWebServer().getPort();
// 			if (this.port.get() == 0) {
// 				log.info("Updating port to " + localPort);
// 				this.port.compareAndSet(0, localPort);
// 				start();
// 			}
// 		}
// 	}
// 
// 	public void onApplicationEvent(ContextClosedEvent event) {
// 		if (event.getApplicationContext() == context) {
// 			stop();
// 		}
// 	}
// 
// }


// Path: spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClientConfiguration.java
import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaAutoServiceRegistration;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.netflix.appinfo.HealthCheckHandler;
import com.netflix.discovery.EurekaClient;
import com.netflix.discovery.EurekaClientConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.health.SimpleStatusAggregator;
import org.springframework.boot.actuate.health.StatusAggregator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.ConditionalOnBlockingDiscoveryEnabled;
import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled;
import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent;

	@Bean
	@ConditionalOnMissingBean
	public EurekaDiscoveryClient discoveryClient(EurekaClient client, EurekaClientConfig clientConfig) {
		return new EurekaDiscoveryClient(client, clientConfig);
	}

	@Configuration(proxyBeanMethods = false)
	@ConditionalOnProperty(value = "eureka.client.healthcheck.enabled", matchIfMissing = false)
	protected static class EurekaHealthCheckHandlerConfiguration {

		@Autowired(required = false)
		private StatusAggregator statusAggregator = new SimpleStatusAggregator();

		@Bean
		@ConditionalOnMissingBean(HealthCheckHandler.class)
		public EurekaHealthCheckHandler eurekaHealthCheckHandler() {
			return new EurekaHealthCheckHandler(this.statusAggregator);
		}

	}

	@Configuration(proxyBeanMethods = false)
	@ConditionalOnClass(RefreshScopeRefreshedEvent.class)
	protected static class EurekaClientConfigurationRefresher
			implements ApplicationListener<RefreshScopeRefreshedEvent> {

		@Autowired(required = false)
		private EurekaClient eurekaClient;

		@Autowired(required = false)
		private EurekaAutoServiceRegistration autoRegistration;