diff --git a/pom.xml b/pom.xml
index 227ba871..9fe85de7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,7 +24,7 @@
${basedir}
4.0.27.Final
2.7.3
- 1.1.5.BUILD-SNAPSHOT
+ 1.2.0.BUILD-SNAPSHOT
1.2.2.BUILD-SNAPSHOT
Brooklyn.BUILD-SNAPSHOT
diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/CloudEurekaClient.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/CloudEurekaClient.java
index 4338c1f9..3bb72451 100644
--- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/CloudEurekaClient.java
+++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/CloudEurekaClient.java
@@ -16,16 +16,24 @@
package org.springframework.cloud.netflix.eureka;
+import java.lang.reflect.Field;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
-import lombok.extern.apachecommons.CommonsLog;
-
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
-import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.util.ReflectionUtils;
import com.netflix.appinfo.ApplicationInfoManager;
+import com.netflix.appinfo.InstanceInfo;
+import com.netflix.appinfo.InstanceInfo.InstanceStatus;
import com.netflix.discovery.DiscoveryClient;
import com.netflix.discovery.EurekaClientConfig;
+import com.netflix.discovery.shared.transport.EurekaHttpClient;
+
+import lombok.extern.apachecommons.CommonsLog;
/**
* Subclass of {@link DiscoveryClient} that sends a {@link HeartbeatEvent} when
@@ -34,22 +42,55 @@ import com.netflix.discovery.EurekaClientConfig;
*/
@CommonsLog
public class CloudEurekaClient extends DiscoveryClient {
+ private static final Log log = LogFactory.getLog(EurekaServiceRegistry.class);
private final AtomicLong cacheRefreshedCount = new AtomicLong(0);
- private ApplicationContext context;
+ private ApplicationEventPublisher publisher;
+ private Field eurekaTransportField;
+ private ApplicationInfoManager applicationInfoManager;
+ private AtomicReference eurekaHttpClient = new AtomicReference<>();
public CloudEurekaClient(ApplicationInfoManager applicationInfoManager,
- EurekaClientConfig config, ApplicationContext context) {
- this(applicationInfoManager, config, null, context);
+ EurekaClientConfig config, ApplicationEventPublisher publisher) {
+ this(applicationInfoManager, config, null, publisher);
}
public CloudEurekaClient(ApplicationInfoManager applicationInfoManager,
EurekaClientConfig config,
DiscoveryClientOptionalArgs args,
- ApplicationContext context) {
+ ApplicationEventPublisher publisher) {
super(applicationInfoManager, config, args);
- this.context = context;
+ this.applicationInfoManager = applicationInfoManager;
+ this.publisher = publisher;
+ this.eurekaTransportField = ReflectionUtils.findField(DiscoveryClient.class, "eurekaTransport");
+ ReflectionUtils.makeAccessible(this.eurekaTransportField);
+ }
+
+ public ApplicationInfoManager getApplicationInfoManager() {
+ return applicationInfoManager;
+ }
+
+ public void cancelOverrideStatus(InstanceInfo info) {
+ getEurekaHttpClient().deleteStatusOverride(info.getAppName(), info.getId(), info);
+ }
+
+ EurekaHttpClient getEurekaHttpClient() {
+ if (this.eurekaHttpClient.get() == null) {
+ try {
+ Object eurekaTransport = this.eurekaTransportField.get(this);
+ Field registrationClientField = ReflectionUtils.findField(eurekaTransport.getClass(), "registrationClient");
+ ReflectionUtils.makeAccessible(registrationClientField);
+ this.eurekaHttpClient.compareAndSet(null, (EurekaHttpClient) registrationClientField.get(eurekaTransport));
+ } catch (IllegalAccessException e) {
+ log.error("error getting EurekaHttpClient", e);
+ }
+ }
+ return this.eurekaHttpClient.get();
+ }
+
+ public void setStatus(InstanceStatus newStatus, InstanceInfo info) {
+ getEurekaHttpClient().statusUpdate(info.getAppName(), info.getId(), newStatus, info);
}
@Override
@@ -57,7 +98,7 @@ public class CloudEurekaClient extends DiscoveryClient {
if (this.cacheRefreshedCount != null) { //might be called during construction and will be null
long newCount = this.cacheRefreshedCount.incrementAndGet();
log.trace("onCacheRefreshed called with count: " + newCount);
- this.context.publishEvent(new HeartbeatEvent(this, newCount));
+ this.publisher.publishEvent(new HeartbeatEvent(this, newCount));
}
}
}
diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java
index 46b0f1fd..230fbe1f 100644
--- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java
+++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java
@@ -52,6 +52,7 @@ import org.springframework.util.StringUtils;
import com.netflix.appinfo.ApplicationInfoManager;
import com.netflix.appinfo.EurekaInstanceConfig;
+import com.netflix.appinfo.HealthCheckHandler;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.DiscoveryClient.DiscoveryClientOptionalArgs;
import com.netflix.discovery.EurekaClient;
@@ -76,16 +77,19 @@ import static org.springframework.cloud.commons.util.IdUtils.getDefaultInstanceI
public class EurekaClientAutoConfiguration {
@Value("${server.port:${SERVER_PORT:${PORT:8080}}}")
- int nonSecurePort;
+ private int nonSecurePort;
@Value("${management.port:${MANAGEMENT_PORT:${server.port:${SERVER_PORT:${PORT:8080}}}}}")
- int managementPort;
+ private int managementPort;
@Value("${eureka.instance.hostname:${EUREKA_INSTANCE_HOSTNAME:}}")
- String hostname;
+ private String hostname;
@Autowired
- ConfigurableEnvironment env;
+ private ConfigurableEnvironment env;
+
+ @Autowired(required = false)
+ private HealthCheckHandler healthCheckHandler;
@Bean
public HasFeatures eurekaFeature() {
@@ -145,6 +149,20 @@ public class EurekaClientAutoConfiguration {
return new EurekaDiscoveryClient(config, client);
}
+ @Bean
+ public EurekaServiceRegistry eurekaServiceRegistry() {
+ return new EurekaServiceRegistry();
+ }
+
+ @Bean
+ public EurekaRegistration eurekaRegistration(EurekaClient eurekaClient, CloudEurekaInstanceConfig instanceConfig, ApplicationInfoManager applicationInfoManager) {
+ return EurekaRegistration.builder(instanceConfig)
+ .with(applicationInfoManager)
+ .with(eurekaClient)
+ .with(healthCheckHandler)
+ .build();
+ }
+
@Bean
@ConditionalOnMissingBean(value = DiscoveryClientOptionalArgs.class, search = SearchStrategy.CURRENT)
public MutableDiscoveryClientOptionalArgs discoveryClientOptionalArgs() {
diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClientConfiguration.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClientConfiguration.java
index ff9c4d74..7a8e795e 100644
--- a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClientConfiguration.java
+++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaDiscoveryClientConfiguration.java
@@ -22,9 +22,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.endpoint.Endpoint;
import org.springframework.boot.actuate.health.HealthAggregator;
-import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.OrderedHealthAggregator;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -40,10 +38,8 @@ import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.Ordered;
-import com.netflix.appinfo.ApplicationInfoManager;
import com.netflix.appinfo.EurekaInstanceConfig;
import com.netflix.appinfo.HealthCheckHandler;
-import com.netflix.appinfo.InstanceInfo.InstanceStatus;
import com.netflix.discovery.EurekaClient;
import com.netflix.discovery.EurekaClientConfig;
@@ -68,69 +64,36 @@ public class EurekaDiscoveryClientConfiguration implements SmartLifecycle, Order
private AtomicInteger port = new AtomicInteger(0);
- @Autowired
- private CloudEurekaInstanceConfig instanceConfig;
-
- @Autowired(required = false)
- private HealthCheckHandler healthCheckHandler;
-
@Autowired
private ApplicationContext context;
@Autowired
- private ApplicationInfoManager applicationInfoManager;
+ private EurekaServiceRegistry serviceRegistry;
@Autowired
- private EurekaClient eurekaClient;
+ private EurekaRegistration registration;
@Override
public void start() {
// only set the port if the nonSecurePort is 0 and this.port != 0
- if (this.port.get() != 0 && this.instanceConfig.getNonSecurePort() == 0) {
- this.instanceConfig.setNonSecurePort(this.port.get());
+ if (this.port.get() != 0 && this.registration.getNonSecurePort() == 0) {
+ this.registration.setNonSecurePort(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.instanceConfig.getNonSecurePort() > 0) {
+ if (!this.running.get() && this.registration.getNonSecurePort() > 0) {
- maybeInitializeClient();
+ this.serviceRegistry.register(this.registration);
- if (log.isInfoEnabled()) {
- log.info("Registering application " + this.instanceConfig.getAppname()
- + " with eureka with status "
- + this.instanceConfig.getInitialStatus());
- }
-
- this.applicationInfoManager
- .setInstanceStatus(this.instanceConfig.getInitialStatus());
-
- if (this.healthCheckHandler != null) {
- this.eurekaClient.registerHealthCheck(this.healthCheckHandler);
- }
this.context.publishEvent(
- new InstanceRegisteredEvent<>(this, this.instanceConfig));
+ new InstanceRegisteredEvent<>(this, this.registration.getInstanceConfig()));
this.running.set(true);
}
}
-
- private void maybeInitializeClient() {
- // force initialization of possibly scoped proxies
- this.applicationInfoManager.getInfo();
- this.eurekaClient.getApplications();
- }
-
@Override
public void stop() {
- if (this.applicationInfoManager.getInfo() != null) {
-
- if (log.isInfoEnabled()) {
- log.info("Unregistering application " + this.instanceConfig.getAppname()
- + " with eureka with status DOWN");
- }
-
- this.applicationInfoManager.setInstanceStatus(InstanceStatus.DOWN);
- }
+ this.serviceRegistry.deregister(this.registration);
this.running.set(false);
}
@@ -189,7 +152,6 @@ public class EurekaDiscoveryClientConfiguration implements SmartLifecycle, Order
public void onApplicationEvent(ContextClosedEvent event) {
// register in case meta data changed
stop();
- this.eurekaClient.shutdown();
}
@Configuration
diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaRegistration.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaRegistration.java
new file mode 100644
index 00000000..11a3f7d4
--- /dev/null
+++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaRegistration.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2013-2016 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.springframework.cloud.netflix.eureka;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.aop.framework.Advised;
+import org.springframework.aop.support.AopUtils;
+import org.springframework.cloud.client.serviceregistry.Registration;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.util.Assert;
+
+import com.netflix.appinfo.ApplicationInfoManager;
+import com.netflix.appinfo.HealthCheckHandler;
+import com.netflix.appinfo.InstanceInfo;
+import com.netflix.discovery.EurekaClient;
+import com.netflix.discovery.EurekaClientConfig;
+
+/**
+ * @author Spencer Gibb
+ */
+public class EurekaRegistration implements Registration {
+ private static final Log log = LogFactory.getLog(EurekaRegistration.class);
+
+ private final EurekaClient eurekaClient;
+ private final AtomicReference cloudEurekaClient = new AtomicReference<>();
+ private final CloudEurekaInstanceConfig instanceConfig;
+ private final ApplicationInfoManager applicationInfoManager;
+ private HealthCheckHandler healthCheckHandler;
+
+ private EurekaRegistration(CloudEurekaInstanceConfig instanceConfig, EurekaClient eurekaClient, ApplicationInfoManager applicationInfoManager, HealthCheckHandler healthCheckHandler) {
+ this.eurekaClient = eurekaClient;
+ this.instanceConfig = instanceConfig;
+ this.applicationInfoManager = applicationInfoManager;
+ this.healthCheckHandler = healthCheckHandler;
+ }
+
+ public static Builder builder(CloudEurekaInstanceConfig instanceConfig) {
+ return new Builder(instanceConfig);
+ }
+
+ public static class Builder {
+ private final CloudEurekaInstanceConfig instanceConfig;
+ private ApplicationInfoManager applicationInfoManager;
+ private EurekaClient eurekaClient;
+ private HealthCheckHandler healthCheckHandler;
+
+ private EurekaClientConfig clientConfig;
+ private ApplicationEventPublisher publisher;
+
+ Builder(CloudEurekaInstanceConfig instanceConfig) {
+ this.instanceConfig = instanceConfig;
+ }
+
+ public Builder with(ApplicationInfoManager applicationInfoManager) {
+ this.applicationInfoManager = applicationInfoManager;
+ return this;
+ }
+
+ public Builder with(EurekaClient eurekaClient) {
+ this.eurekaClient = eurekaClient;
+ return this;
+ }
+
+ public Builder with(HealthCheckHandler healthCheckHandler) {
+ this.healthCheckHandler = healthCheckHandler;
+ return this;
+ }
+
+ public Builder with(EurekaClientConfig clientConfig, ApplicationEventPublisher publisher) {
+ this.clientConfig = clientConfig;
+ this.publisher = publisher;
+ return this;
+ }
+
+ public EurekaRegistration build() {
+ Assert.notNull(instanceConfig, "instanceConfig may not be null");
+
+ if (this.applicationInfoManager == null) {
+ InstanceInfo instanceInfo = new InstanceInfoFactory().create(this.instanceConfig);
+ this.applicationInfoManager = new ApplicationInfoManager(this.instanceConfig, instanceInfo);
+ }
+ if (this.eurekaClient == null) {
+ Assert.notNull(this.clientConfig, "if eurekaClient is null, EurekaClientConfig may not be null");
+ Assert.notNull(this.publisher, "if eurekaClient is null, ApplicationEventPublisher may not be null");
+
+ this.eurekaClient = new CloudEurekaClient(this.applicationInfoManager, this.clientConfig, this.publisher);
+ }
+ return new EurekaRegistration(instanceConfig, eurekaClient, applicationInfoManager, healthCheckHandler);
+ }
+
+ }
+
+ public CloudEurekaClient getEurekaClient() {
+ if (this.cloudEurekaClient.get() == null) {
+ try {
+ this.cloudEurekaClient.compareAndSet(null, getTargetObject(eurekaClient, CloudEurekaClient.class));
+ } catch (Exception e) {
+ log.error("error getting CloudEurekaClient", e);
+ }
+ }
+ return this.cloudEurekaClient.get();
+ }
+
+ @SuppressWarnings({"unchecked"})
+ protected T getTargetObject(Object proxy, Class targetClass) throws Exception {
+ if (AopUtils.isJdkDynamicProxy(proxy)) {
+ return (T) ((Advised) proxy).getTargetSource().getTarget();
+ } else {
+ return (T) proxy; // expected to be cglib proxy then, which is simply a specialized class
+ }
+ }
+
+ public CloudEurekaInstanceConfig getInstanceConfig() {
+ return instanceConfig;
+ }
+
+ public ApplicationInfoManager getApplicationInfoManager() {
+ return applicationInfoManager;
+ }
+
+ public HealthCheckHandler getHealthCheckHandler() {
+ return healthCheckHandler;
+ }
+
+ public void setHealthCheckHandler(HealthCheckHandler healthCheckHandler) {
+ this.healthCheckHandler = healthCheckHandler;
+ }
+
+ public void setNonSecurePort(int port) {
+ this.instanceConfig.setNonSecurePort(port);
+ }
+
+ public int getNonSecurePort() {
+ return this.instanceConfig.getNonSecurePort();
+ }
+}
diff --git a/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaServiceRegistry.java b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaServiceRegistry.java
new file mode 100644
index 00000000..8e72d655
--- /dev/null
+++ b/spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/EurekaServiceRegistry.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2013-2016 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.springframework.cloud.netflix.eureka;
+
+import java.util.HashMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.cloud.client.serviceregistry.AutoServiceRegistration;
+import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
+
+import com.netflix.appinfo.InstanceInfo;
+
+/**
+ * @author Spencer Gibb
+ */
+public class EurekaServiceRegistry implements ServiceRegistry, AutoServiceRegistration {
+
+ private static final Log log = LogFactory.getLog(EurekaServiceRegistry.class);
+
+ @Override
+ public void register(EurekaRegistration reg) {
+ maybeInitializeClient(reg);
+
+ if (log.isInfoEnabled()) {
+ log.info("Registering application " + reg.getInstanceConfig().getAppname()
+ + " with eureka with status "
+ + reg.getInstanceConfig().getInitialStatus());
+ }
+
+ reg.getApplicationInfoManager()
+ .setInstanceStatus(reg.getInstanceConfig().getInitialStatus());
+
+ if (reg.getHealthCheckHandler() != null) {
+ reg.getEurekaClient().registerHealthCheck(reg.getHealthCheckHandler());
+ }
+ }
+
+ private void maybeInitializeClient(EurekaRegistration reg) {
+ // force initialization of possibly scoped proxies
+ reg.getApplicationInfoManager().getInfo();
+ reg.getEurekaClient().getApplications();
+ }
+
+ @Override
+ public void deregister(EurekaRegistration reg) {
+ if (reg.getApplicationInfoManager().getInfo() != null) {
+
+ if (log.isInfoEnabled()) {
+ log.info("Unregistering application " + reg.getInstanceConfig().getAppname()
+ + " with eureka with status DOWN");
+ }
+
+ reg.getApplicationInfoManager().setInstanceStatus(InstanceInfo.InstanceStatus.DOWN);
+
+ //TODO: on deregister or on context shutdown
+ reg.getEurekaClient().shutdown();
+ }
+ }
+
+ @Override
+ public void setStatus(EurekaRegistration registration, String status) {
+ InstanceInfo info = registration.getApplicationInfoManager().getInfo();
+
+ //TODO: howto deal with delete properly?
+ if ("RESET_OVERRIDE".equalsIgnoreCase(status)) {
+ registration.getEurekaClient().cancelOverrideStatus(info);
+ return;
+ }
+
+ //TODO: howto deal with status types across discovery systems?
+ InstanceInfo.InstanceStatus newStatus = InstanceInfo.InstanceStatus.toEnum(status);
+ registration.getEurekaClient().setStatus(newStatus, info);
+ }
+
+ @Override
+ public Object getStatus(EurekaRegistration registration) {
+ HashMap status = new HashMap<>();
+
+ InstanceInfo info = registration.getApplicationInfoManager().getInfo();
+ status.put("status", info.getStatus().toString());
+ status.put("overriddenStatus", info.getOverriddenStatus().toString());
+
+ return status;
+ }
+
+ public void close() {
+ }
+
+}
diff --git a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/sample/EurekaSampleApplication.java b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/sample/EurekaSampleApplication.java
index fbf931fe..21567e2b 100644
--- a/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/sample/EurekaSampleApplication.java
+++ b/spring-cloud-netflix-eureka-client/src/test/java/org/springframework/cloud/netflix/eureka/sample/EurekaSampleApplication.java
@@ -16,30 +16,59 @@
package org.springframework.cloud.netflix.eureka.sample;
+import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.metrics.repository.InMemoryMetricRepository;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.discovery.DiscoveryClient;
+import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent;
+import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
+import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
+import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean;
+import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
+import org.springframework.cloud.netflix.eureka.EurekaRegistration;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
+import org.springframework.context.event.EventListener;
import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.netflix.appinfo.HealthCheckHandler;
import com.netflix.appinfo.InstanceInfo;
+import java.io.Closeable;
+import java.io.IOException;
+
+import static org.springframework.web.bind.annotation.RequestMethod.POST;
+
@Configuration
@ComponentScan
@EnableAutoConfiguration
@RestController
@EnableEurekaClient
-public class EurekaSampleApplication {
+public class EurekaSampleApplication implements ApplicationContextAware, Closeable {
+
+ @Autowired
+ private DiscoveryClient discoveryClient;
+
+ @Autowired
+ private ServiceRegistry serviceRegistry;
+
+ @Autowired
+ private InetUtils inetUtils;
@Autowired
- DiscoveryClient discoveryClient;
+ private EurekaClientConfigBean clientConfig;
+
+ private ApplicationContext context;
+
+ private EurekaRegistration registration;
@Bean
public InMemoryMetricRepository inMemoryMetricRepository() {
@@ -62,8 +91,43 @@ public class EurekaSampleApplication {
return "Hello world "+discoveryClient.getLocalServiceInstance().getUri();
}
+ @Override
+ public void setApplicationContext(ApplicationContext context) throws BeansException {
+ this.context = context;
+ }
+
public static void main(String[] args) {
new SpringApplicationBuilder(EurekaSampleApplication.class).web(true).run(args);
}
+ @RequestMapping(path = "/register", method = POST)
+ public String register() {
+ EurekaInstanceConfigBean config = new EurekaInstanceConfigBean(inetUtils);
+ String appname = "customapp";
+ config.setIpAddress("127.0.0.1");
+ config.setHostname("localhost");
+ config.setAppname(appname);
+ config.setVirtualHostName(appname);
+ config.setSecureVirtualHostName(appname);
+ config.setNonSecurePort(4444);
+ config.setInstanceId("127.0.0.1:customapp:4444");
+
+ this.registration = EurekaRegistration.builder(config)
+ .with(this.clientConfig, this.context)
+ .build();
+
+ this.serviceRegistry.register(this.registration);
+ return config.getInstanceId();
+ }
+
+ @RequestMapping(path = "/deregister", method = POST)
+ public String deregister() {
+ this.serviceRegistry.deregister(this.registration);
+ return "deregister";
+ }
+
+ @Override
+ public void close() throws IOException {
+ deregister();
+ }
}