diff --git a/Guardfile b/Guardfile
new file mode 100644
index 00000000..826e7679
--- /dev/null
+++ b/Guardfile
@@ -0,0 +1,11 @@
+require 'asciidoctor'
+require 'erb'
+
+options = {:mkdirs => true, :safe => :unsafe, :attributes => 'linkcss'}
+
+guard 'shell' do
+ watch(/^[A-Za-z].*\.adoc$/) {|m|
+ Asciidoctor.render_file('src/main/adoc/README.adoc', options.merge(:to_file => './README.md'))
+ Asciidoctor.render_file('src/main/adoc/spring-cloud-netflix.adoc', options.merge(:to_dir => 'target/docs'))
+ }
+end
diff --git a/spring-cloud-netflix-core/pom.xml b/spring-cloud-netflix-core/pom.xml
index e04889a5..91e7bb5b 100644
--- a/spring-cloud-netflix-core/pom.xml
+++ b/spring-cloud-netflix-core/pom.xml
@@ -108,6 +108,11 @@
spring-boot-starter-test
test
+
+ org.neo4j
+ neo4j-cypher-compiler-2.1
+ 2.1.2
+
diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientConfiguration.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientConfiguration.java
index f9eb86f7..62909820 100644
--- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientConfiguration.java
+++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka/EurekaClientConfiguration.java
@@ -25,6 +25,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.netflix.servo.ServoMetricReader;
import org.springframework.context.ApplicationListener;
@@ -34,7 +35,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
-import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.Ordered;
import com.netflix.appinfo.ApplicationInfoManager;
@@ -54,8 +54,7 @@ import com.netflix.discovery.EurekaClientConfig;
EurekaInstanceConfigBean.class })
@ConditionalOnClass(EurekaClientConfig.class)
@ConditionalOnExpression("${eureka.client.enabled:true}")
-public class EurekaClientConfiguration implements
- ApplicationListener, SmartLifecycle, Ordered {
+public class EurekaClientConfiguration implements SmartLifecycle, Ordered {
private static final Logger logger = LoggerFactory
.getLogger(EurekaClientConfiguration.class);
@@ -64,19 +63,14 @@ public class EurekaClientConfiguration implements
private int order = 0;
+ private int port = 0;
+
@Autowired
private EurekaClientConfigBean clientConfig;
@Autowired
private EurekaInstanceConfigBean instanceConfig;
- @Override
- public void onApplicationEvent(ContextRefreshedEvent event) {
- logger.info("Registering application {} with eureka with status UP",
- instanceConfig.getAppname());
- ApplicationInfoManager.getInstance().setInstanceStatus(InstanceStatus.UP);
- }
-
@PreDestroy
public void close() {
logger.info("Removing application {} from eureka", instanceConfig.getAppname());
@@ -85,11 +79,20 @@ public class EurekaClientConfiguration implements
@Override
public void start() {
- DiscoveryManager.getInstance().initComponent(instanceConfig, clientConfig);
+ if (port != 0) {
+ instanceConfig.setNonSecurePort(port);
+ DiscoveryManager.getInstance().initComponent(instanceConfig, clientConfig);
+ logger.info("Registering application {} with eureka with status UP",
+ instanceConfig.getAppname());
+ ApplicationInfoManager.getInstance().setInstanceStatus(InstanceStatus.UP);
+ }
}
@Override
public void stop() {
+ logger.info("Unregistering application {} with eureka with status OUT_OF_SERVICE",
+ instanceConfig.getAppname());
+ ApplicationInfoManager.getInstance().setInstanceStatus(InstanceStatus.OUT_OF_SERVICE);
running = false;
}
@@ -134,4 +137,18 @@ public class EurekaClientConfiguration implements
new ServoMetricReader(server), config);
}
+ @Bean
+ protected ApplicationListener containerPortInitializer() {
+ return new ApplicationListener() {
+
+ @Override
+ public void onApplicationEvent(EmbeddedServletContainerInitializedEvent event) {
+ // TODO: take SSL into account when Spring Boot 1.2 is available
+ EurekaClientConfiguration.this.port = event.getEmbeddedServletContainer()
+ .getPort();
+ EurekaClientConfiguration.this.start();
+ }
+ };
+ }
+
}
diff --git a/src/main/adoc/spring-cloud-netflix.adoc b/src/main/adoc/spring-cloud-netflix.adoc
new file mode 100644
index 00000000..5d55f739
--- /dev/null
+++ b/src/main/adoc/spring-cloud-netflix.adoc
@@ -0,0 +1,80 @@
+= Spring Cloud Netflix
+
+This project provides Netflix OSS integrations for Spring Boot apps through autoconfiguration
+and binding to the Spring Environment and other Spring programming model idioms.
+
+== Service Discovery: Eureka Clients
+
+Example eureka client:
+
+```
+@Configuration
+@ComponentScan
+@EnableAutoConfiguration
+@EnableEurekaClient
+@RestController
+public class Application {
+
+ @RequestMapping("/")
+ public String home() {
+ return "Hello world";
+ }
+
+ public static void main(String[] args) {
+ new SpringApplicationBuilder(Application.class).web(true).run(args);
+ }
+
+}
+
+```
+
+(i.e. utterly normal Spring Boot app). Configuration is required to locate the Eureka server. Example:
+
+```
+eureka:
+ client:
+ serviceUrl:
+ defaultZone: http://localhost:8080/v2/
+ default.defaultZone: http://localhost:8080/v2/
+```
+
+The default application name, virtual host and non-secure port are taken from the `Environment` is
+`${spring.application.name}`, `${spring.application.name}.mydomain.net` and `${server.port}` respectively.
+
+== Service Discovery: Eureka Server
+
+Example eureka server:
+
+```
+@Configuration
+@EnableAutoConfiguration
+@EnableEurekaServer
+public class Application {
+
+ public static void main(String[] args) {
+ new SpringApplicationBuilder(Application.class).web(true).run(args);
+ }
+
+}
+
+```
+
+The server has a home page with a UI, and HTTP API endpoints per the
+normal Eureka functionality under `/v2/*`.
+
+Eureka (apache -> tomcat) see https://github.com/cfregly/fluxcapacitor/wiki/NetflixOSS-FAQ#eureka-service-discovery-load-balancer[flux capacitor] and https://groups.google.com/forum/?fromgroups#!topic/eureka_netflix/g3p2r7gHnN0[google group discussion].
+
+== Circuit Breaker: Hystrix Clients
+
+== Circuit Breaker: Hystrix Dashboard
+
+=== Turbine
+
+== Declarative REST Client: Feign
+
+== Client Side Load Balancer: Ribbon
+
+== External Configuration: Archaius
+
+== Router and Filter: Zuul
+