diff --git a/docs/src/main/asciidoc/spring-cloud-commons.adoc b/docs/src/main/asciidoc/spring-cloud-commons.adoc
index 73a8c438..38fdab00 100644
--- a/docs/src/main/asciidoc/spring-cloud-commons.adoc
+++ b/docs/src/main/asciidoc/spring-cloud-commons.adoc
@@ -321,6 +321,33 @@ By default, implementations of `DiscoveryClient` will auto-register the local Sp
Commons now provides a `ServiceRegistry` interface which provides methods like `register(Registration)` and `deregister(Registration)` which allow you to provide custom registered services. `Registration` is a marker interface.
+[source,java,indent=0]
+----
+@Configuration
+@EnableDiscoveryClient(autoRegister=false)
+public class MyConfiguration {
+ private ServiceRegistry registry;
+
+ public MyConfiguration(ServiceRegistry registry) {
+ this.registry = registry;
+ }
+
+ // called via some external process, such as an event or a custom actuator endpoint
+ public void register() {
+ Registration registration = constructRegistration();
+ this.registry.register(registration);
+ }
+}
+----
+
+Each `ServiceRegistry` implementation has its own `Registry` implementation.
+
+
+==== ServiceRegistry Auto-Registration
+
+By default, the `ServiceRegistry` implementation will auto-register the running service. To disable that behavior, there are two methods. You can set `@EnableDiscoveryClient(autoRegister=false)` to permanently disable auto-registration. You can also set `spring.cloud.service-registry.auto-registration.enabled=false` to disable the behavior via configuration.
+
+
==== Service Registry Actuator Endpoint
A `/service-registry` actuator endpoint is provided by Commons. This endpoint relys on a `Registration` bean in the Spring Application Context. Calling `/service-registry/instance-status` via a GET will return the status of the `Registration`. A POST to the same endpoint with a `String` body will change the status of the current `Registration` to the new value. Please see the documentation of the `ServiceRegistry` implementation you are using for the allowed values for updating the status and the values retured for the status.
@@ -362,9 +389,10 @@ for details of how the `RestTemplate` is set up.
==== Retrying Failed Requests
A load balanced `RestTemplate` can be configured to retry failed requests.
-By default this logic is disabled, you can enable it by setting
-`spring.cloud.loadbalancer.retry.enabled=true`. The load balanced `RestTemplate` will
-honor some of the Ribbon configuration values related to retrying failed requests.
+By default this logic is disabled, you can enable it by adding link:https://github.com/spring-projects/spring-retry[Spring Retry] to your application's classpath. The load balanced `RestTemplate` will
+honor some of the Ribbon configuration values related to retrying failed requests. If
+you would like to disable the retry logic with Spring Retry on the classpath
+you can set `spring.cloud.loadbalancer.retry.enabled=false`.
The properties you can use are `client.ribbon.MaxAutoRetries`,
`client.ribbon.MaxAutoRetriesNextServer`, and `client.ribbon.OkToRetryOnAllOperations`.
See the https://github.com/Netflix/ribbon/wiki/Getting-Started#the-properties-file-sample-clientproperties[Ribbon documentation]
diff --git a/mvnw b/mvnw
index 0a7dac22..25f750cb 100755
--- a/mvnw
+++ b/mvnw
@@ -238,6 +238,14 @@ else
echo $MAVEN_ARGS | grep -q milestone && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pmilestone//')
fi
+if echo $VERSION | egrep -q 'RELEASE'; then
+ echo Activating \"central\" profile for version=\"$VERSION\"
+ echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pcentral"
+else
+ echo Deactivating \"central\" profile for version=\"$VERSION\"
+ echo $MAVEN_ARGS | grep -q central && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pcentral//')
+fi
+
exec "$JAVACMD" \
$MAVEN_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
diff --git a/mvnw.cmd b/mvnw.cmd
index fc830243..b0dc0e7e 100644
--- a/mvnw.cmd
+++ b/mvnw.cmd
@@ -1,145 +1,145 @@
-@REM ----------------------------------------------------------------------------
-@REM Licensed to the Apache Software Foundation (ASF) under one
-@REM or more contributor license agreements. See the NOTICE file
-@REM distributed with this work for additional information
-@REM regarding copyright ownership. The ASF licenses this file
-@REM to you under the Apache License, Version 2.0 (the
-@REM "License"); you may not use this file except in compliance
-@REM with the License. You may obtain a copy of the License at
-@REM
-@REM http://www.apache.org/licenses/LICENSE-2.0
-@REM
-@REM Unless required by applicable law or agreed to in writing,
-@REM software distributed under the License is distributed on an
-@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@REM KIND, either express or implied. See the License for the
-@REM specific language governing permissions and limitations
-@REM under the License.
-@REM ----------------------------------------------------------------------------
-
-@REM ----------------------------------------------------------------------------
-@REM Maven2 Start Up Batch script
-@REM
-@REM Required ENV vars:
-@REM JAVA_HOME - location of a JDK home dir
-@REM
-@REM Optional ENV vars
-@REM M2_HOME - location of maven2's installed home dir
-@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
-@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
-@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
-@REM e.g. to debug Maven itself, use
-@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
-@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
-@REM ----------------------------------------------------------------------------
-
-@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
-@echo off
-@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
-@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
-
-@REM set %HOME% to equivalent of $HOME
-if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
-
-@REM Execute a user defined script before this one
-if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
-@REM check for pre script, once with legacy .bat ending and once with .cmd ending
-if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
-if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
-:skipRcPre
-
-@setlocal
-
-set ERROR_CODE=0
-
-@REM To isolate internal variables from possible post scripts, we use another setlocal
-@setlocal
-
-@REM ==== START VALIDATION ====
-if not "%JAVA_HOME%" == "" goto OkJHome
-
-echo.
-echo Error: JAVA_HOME not found in your environment. >&2
-echo Please set the JAVA_HOME variable in your environment to match the >&2
-echo location of your Java installation. >&2
-echo.
-goto error
-
-:OkJHome
-if exist "%JAVA_HOME%\bin\java.exe" goto init
-
-echo.
-echo Error: JAVA_HOME is set to an invalid directory. >&2
-echo JAVA_HOME = "%JAVA_HOME%" >&2
-echo Please set the JAVA_HOME variable in your environment to match the >&2
-echo location of your Java installation. >&2
-echo.
-goto error
-
-@REM ==== END VALIDATION ====
-
-:init
-
-set MAVEN_CMD_LINE_ARGS=%*
-
-@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
-@REM Fallback to current working directory if not found.
-
-set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
-IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
-
-set EXEC_DIR=%CD%
-set WDIR=%EXEC_DIR%
-:findBaseDir
-IF EXIST "%WDIR%"\.mvn goto baseDirFound
-cd ..
-IF "%WDIR%"=="%CD%" goto baseDirNotFound
-set WDIR=%CD%
-goto findBaseDir
-
-:baseDirFound
-set MAVEN_PROJECTBASEDIR=%WDIR%
-cd "%EXEC_DIR%"
-goto endDetectBaseDir
-
-:baseDirNotFound
-set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
-cd "%EXEC_DIR%"
-
-:endDetectBaseDir
-
-IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
-
-@setlocal EnableExtensions EnableDelayedExpansion
-for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
-@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
-
-:endReadAdditionalConfig
-
-SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
+@REM ----------------------------------------------------------------------------
+@REM Licensed to the Apache Software Foundation (ASF) under one
+@REM or more contributor license agreements. See the NOTICE file
+@REM distributed with this work for additional information
+@REM regarding copyright ownership. The ASF licenses this file
+@REM to you under the Apache License, Version 2.0 (the
+@REM "License"); you may not use this file except in compliance
+@REM with the License. You may obtain a copy of the License at
+@REM
+@REM http://www.apache.org/licenses/LICENSE-2.0
+@REM
+@REM Unless required by applicable law or agreed to in writing,
+@REM software distributed under the License is distributed on an
+@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+@REM KIND, either express or implied. See the License for the
+@REM specific language governing permissions and limitations
+@REM under the License.
+@REM ----------------------------------------------------------------------------
+
+@REM ----------------------------------------------------------------------------
+@REM Maven2 Start Up Batch script
+@REM
+@REM Required ENV vars:
+@REM JAVA_HOME - location of a JDK home dir
+@REM
+@REM Optional ENV vars
+@REM M2_HOME - location of maven2's installed home dir
+@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
+@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
+@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
+@REM e.g. to debug Maven itself, use
+@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
+@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
+@REM ----------------------------------------------------------------------------
+
+@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
+@echo off
+@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
+@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
+
+@REM set %HOME% to equivalent of $HOME
+if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
+
+@REM Execute a user defined script before this one
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
+@REM check for pre script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
+if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
+:skipRcPre
+
+@setlocal
+
+set ERROR_CODE=0
+
+@REM To isolate internal variables from possible post scripts, we use another setlocal
+@setlocal
+
+@REM ==== START VALIDATION ====
+if not "%JAVA_HOME%" == "" goto OkJHome
+
+echo.
+echo Error: JAVA_HOME not found in your environment. >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+:OkJHome
+if exist "%JAVA_HOME%\bin\java.exe" goto init
+
+echo.
+echo Error: JAVA_HOME is set to an invalid directory. >&2
+echo JAVA_HOME = "%JAVA_HOME%" >&2
+echo Please set the JAVA_HOME variable in your environment to match the >&2
+echo location of your Java installation. >&2
+echo.
+goto error
+
+@REM ==== END VALIDATION ====
+
+:init
+
+set MAVEN_CMD_LINE_ARGS=%*
+
+@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
+@REM Fallback to current working directory if not found.
+
+set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
+IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
+
+set EXEC_DIR=%CD%
+set WDIR=%EXEC_DIR%
+:findBaseDir
+IF EXIST "%WDIR%"\.mvn goto baseDirFound
+cd ..
+IF "%WDIR%"=="%CD%" goto baseDirNotFound
+set WDIR=%CD%
+goto findBaseDir
+
+:baseDirFound
+set MAVEN_PROJECTBASEDIR=%WDIR%
+cd "%EXEC_DIR%"
+goto endDetectBaseDir
+
+:baseDirNotFound
+set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
+cd "%EXEC_DIR%"
+
+:endDetectBaseDir
+
+IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
+
+@setlocal EnableExtensions EnableDelayedExpansion
+for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
+@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
+
+:endReadAdditionalConfig
+
+SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar""
-set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
-
-%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
-if ERRORLEVEL 1 goto error
-goto end
-
-:error
-set ERROR_CODE=1
-
-:end
-@endlocal & set ERROR_CODE=%ERROR_CODE%
-
-if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
-@REM check for post script, once with legacy .bat ending and once with .cmd ending
-if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
-if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
-:skipRcPost
-
-@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
-if "%MAVEN_BATCH_PAUSE%" == "on" pause
-
-if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
-
-exit /B %ERROR_CODE%
+set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
+
+%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
+if ERRORLEVEL 1 goto error
+goto end
+
+:error
+set ERROR_CODE=1
+
+:end
+@endlocal & set ERROR_CODE=%ERROR_CODE%
+
+if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
+@REM check for post script, once with legacy .bat ending and once with .cmd ending
+if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
+if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
+:skipRcPost
+
+@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
+if "%MAVEN_BATCH_PAUSE%" == "on" pause
+
+if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
+
+exit /B %ERROR_CODE%
diff --git a/pom.xml b/pom.xml
index 4049312b..1023b238 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,23 +26,6 @@
-
- org.apache.maven.plugins
- maven-javadoc-plugin
-
-
- aggregate
-
- aggregate-jar
-
- package
- false
-
- true
-
-
-
-
org.apache.maven.plugins
maven-compiler-plugin
@@ -68,23 +51,6 @@
-
- org.apache.maven.plugins
- maven-jar-plugin
- 3.0.0
-
-
-
- test-jar
-
-
-
-
-
- **/*.properties
-
-
-
diff --git a/spring-cloud-commons/pom.xml b/spring-cloud-commons/pom.xml
index 48d2ad05..7e561f47 100644
--- a/spring-cloud-commons/pom.xml
+++ b/spring-cloud-commons/pom.xml
@@ -13,6 +13,28 @@
jar
Spring Cloud Commons
Spring Cloud Commons
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.0.0
+
+
+ test-compile
+
+ test-jar
+
+
+
+
+
+ **/*.properties
+
+
+
+
+
org.springframework.boot
diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/DiscoveryClient.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/DiscoveryClient.java
index 41f429e4..c2d553d9 100644
--- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/DiscoveryClient.java
+++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/DiscoveryClient.java
@@ -21,7 +21,7 @@ import java.util.List;
import org.springframework.cloud.client.ServiceInstance;
/**
- * DiscoveryClient represents operations commonly available to Discovery service such as
+ * DiscoveryClient represents read operations commonly available to Discovery service such as
* Netflix Eureka or consul.io
* @author Spencer Gibb
*/
diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/noop/NoopDiscoveryClient.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/noop/NoopDiscoveryClient.java
index 6c6a9bc0..351b3458 100644
--- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/noop/NoopDiscoveryClient.java
+++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/noop/NoopDiscoveryClient.java
@@ -24,8 +24,13 @@ import org.springframework.cloud.client.discovery.DiscoveryClient;
/**
* DiscoveryClient used when no implementations are found on the classpath
+ *
+ * @deprecated Use {@link org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClient instead}
+ *
* @author Dave Syer
*/
+
+@Deprecated
public class NoopDiscoveryClient implements DiscoveryClient {
private final ServiceInstance instance;
diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/noop/NoopDiscoveryClientAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/noop/NoopDiscoveryClientAutoConfiguration.java
index 424d5930..6dd788b6 100644
--- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/noop/NoopDiscoveryClientAutoConfiguration.java
+++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/noop/NoopDiscoveryClientAutoConfiguration.java
@@ -39,12 +39,17 @@ import org.springframework.core.env.Environment;
import lombok.extern.apachecommons.CommonsLog;
/**
+ *
+ * @deprecated Use
+ * {@link org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration instead}
+ *
* @author Dave Syer
*/
@Configuration
@EnableConfigurationProperties
@ConditionalOnMissingBean(DiscoveryClient.class)
@CommonsLog
+@Deprecated
public class NoopDiscoveryClientAutoConfiguration
implements ApplicationListener {
diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClient.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClient.java
new file mode 100644
index 00000000..95aa15ed
--- /dev/null
+++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClient.java
@@ -0,0 +1,50 @@
+package org.springframework.cloud.client.discovery.simple;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.cloud.client.discovery.DiscoveryClient;
+import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryProperties.SimpleServiceInstance;
+
+/**
+ * A {@link org.springframework.cloud.client.discovery.DiscoveryClient} that will use the
+ * properties file as a source of service instances
+ *
+ * @author Biju Kunjummen
+ */
+public class SimpleDiscoveryClient implements DiscoveryClient {
+
+ private SimpleDiscoveryProperties simpleDiscoveryProperties;
+
+ public SimpleDiscoveryClient(SimpleDiscoveryProperties simpleDiscoveryProperties) {
+ this.simpleDiscoveryProperties = simpleDiscoveryProperties;
+ }
+
+ @Override
+ public String description() {
+ return "Simple Discovery Client";
+ }
+
+ @Override
+ public ServiceInstance getLocalServiceInstance() {
+ return null;
+ }
+
+ @Override
+ public List getInstances(String serviceId) {
+ List serviceInstances = new ArrayList<>();
+ List serviceInstanceForService = this.simpleDiscoveryProperties
+ .getInstances().get(serviceId);
+
+ if (serviceInstanceForService != null) {
+ serviceInstances.addAll(serviceInstanceForService);
+ }
+ return serviceInstances;
+ }
+
+ @Override
+ public List getServices() {
+ return new ArrayList<>(this.simpleDiscoveryProperties.getInstances().keySet());
+ }
+}
diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientAutoConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientAutoConfiguration.java
new file mode 100644
index 00000000..9115daae
--- /dev/null
+++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientAutoConfiguration.java
@@ -0,0 +1,31 @@
+package org.springframework.cloud.client.discovery.simple;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cloud.client.discovery.DiscoveryClient;
+import org.springframework.cloud.client.discovery.noop.NoopDiscoveryClientAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * Spring Boot Auto-Configuration for Simple Properties based Discovery Client
+ *
+ * @author Biju Kunjummen
+ */
+
+@Configuration
+@ConditionalOnMissingBean(DiscoveryClient.class)
+@EnableConfigurationProperties(SimpleDiscoveryProperties.class)
+@AutoConfigureBefore(NoopDiscoveryClientAutoConfiguration.class)
+public class SimpleDiscoveryClientAutoConfiguration {
+
+ @Autowired
+ private SimpleDiscoveryProperties simpleDiscoveryProperties;
+
+ @Bean
+ public DiscoveryClient simpleDiscoveryClient() {
+ return new SimpleDiscoveryClient(simpleDiscoveryProperties);
+ }
+}
diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryProperties.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryProperties.java
new file mode 100644
index 00000000..5643edea
--- /dev/null
+++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryProperties.java
@@ -0,0 +1,85 @@
+package org.springframework.cloud.client.discovery.simple;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.cloud.client.ServiceInstance;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Properties to hold the details of a
+ * {@link org.springframework.cloud.client.discovery.DiscoveryClient} service instances
+ * for a given service
+ *
+ * @author Biju Kunjummen
+ */
+
+@ConfigurationProperties(prefix = "spring.cloud.discovery.client.simple")
+public class SimpleDiscoveryProperties {
+ private Map> instances = new HashMap<>();
+
+ public Map> getInstances() {
+ return instances;
+ }
+
+ public void setInstances(Map> instances) {
+ this.instances = instances;
+ }
+
+ public static class SimpleServiceInstance implements ServiceInstance {
+
+ private URI resolvedUri;
+ private String host;
+ private int port;
+ private boolean secure;
+
+ public SimpleServiceInstance() {
+ }
+
+ public SimpleServiceInstance(String uri) {
+ setUri(uri);
+ }
+
+ public void setUri(String uri) {
+ this.resolvedUri = URI.create(uri);
+ this.host = this.resolvedUri.getHost();
+ this.port = this.resolvedUri.getPort();
+ String scheme = this.resolvedUri.getScheme();
+ if ("https".equals(scheme)) {
+ this.secure = true;
+ }
+ }
+
+ @Override
+ public String getServiceId() {
+ return null;
+ }
+
+ @Override
+ public String getHost() {
+ return this.host;
+ }
+
+ @Override
+ public int getPort() {
+ return this.port;
+ }
+
+ @Override
+ public boolean isSecure() {
+ return this.secure;
+ }
+
+ @Override
+ public URI getUri() {
+ return this.resolvedUri;
+ }
+
+ @Override
+ public Map getMetadata() {
+ return null;
+ }
+ }
+}
diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancedRetryPolicy.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancedRetryPolicy.java
index 02ee113c..903f3e05 100644
--- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancedRetryPolicy.java
+++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancedRetryPolicy.java
@@ -49,4 +49,16 @@ public interface LoadBalancedRetryPolicy {
* @param throwable the throwable from the failed execution.
*/
public abstract void registerThrowable(LoadBalancedRetryContext context, Throwable throwable);
+
+ /**
+ * If an exception is not thrown when making a request, than this method will be
+ * called to see if the client would like to retry the request based on the status
+ * code returned. For example in CloudFoundry the router will return a 404
+ * when an app is not available. Since HTTP clients do not throw an exception when
+ * a 404 is returned than retryableStatusCode allows
+ * clients to force a retry.
+ * @param statusCode The HTTP status code.
+ * @return True if a retry should be attempted, false to just return the response
+ */
+ public boolean retryableStatusCode(int statusCode);
}
diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRetryProperties.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRetryProperties.java
index 634249c0..b750d895 100644
--- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRetryProperties.java
+++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/loadbalancer/LoadBalancerRetryProperties.java
@@ -23,7 +23,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
*/
@ConfigurationProperties("spring.cloud.loadbalancer.retry")
public class LoadBalancerRetryProperties {
- private boolean enabled = false;
+ private boolean enabled = true;
/**
* Returns true if the load balancer should retry failed requests.
diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/Registration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/Registration.java
index f9e31df1..9f3e7022 100644
--- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/Registration.java
+++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/Registration.java
@@ -1,7 +1,10 @@
package org.springframework.cloud.client.serviceregistry;
/**
+ * A marker interface used by a {@link ServiceRegistry}.
+ *
* @author Spencer Gibb
+ * @since 1.2.0
*/
public interface Registration {
diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/ServiceRegistry.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/ServiceRegistry.java
index eb3d73ee..bcd695e8 100644
--- a/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/ServiceRegistry.java
+++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/client/serviceregistry/ServiceRegistry.java
@@ -1,19 +1,48 @@
package org.springframework.cloud.client.serviceregistry;
/**
- * TODO: write javadoc
+ * Contract to register and deregister instances with a Service Registry.
+ *
* @author Spencer Gibb
+ * @since 1.2.0
*/
public interface ServiceRegistry {
+
+ /**
+ * Register the registration. Registrations typically have information about
+ * instances such as: hostname and port.
+ * @param registration the registraion
+ */
void register(R registration);
+ /**
+ * Deregister the registration.
+ * @param registration
+ */
void deregister(R registration);
+ /**
+ * Close the ServiceRegistry. This a lifecycle method.
+ */
void close();
- // TODO: return value for success?
+ /**
+ * Sets the status of the registration. The status values are determined
+ * by the individual implementations.
+ *
+ * @see org.springframework.cloud.client.serviceregistry.endpoint.ServiceRegistryEndpoint
+ * @param registration the registration to update
+ * @param status the status to set
+ */
void setStatus(R registration, String status);
- // TODO: concrete return value? Interface?
- Object getStatus(R registration);
+ /**
+ * Gets the status of a particular registration.
+ *
+ * @see org.springframework.cloud.client.serviceregistry.endpoint.ServiceRegistryEndpoint
+ * @param registration the registration to query
+ * @param the type of the status
+ * @return the status of the registration
+ */
+ T getStatus(R registration);
}
diff --git a/spring-cloud-commons/src/main/resources/META-INF/spring.factories b/spring-cloud-commons/src/main/resources/META-INF/spring.factories
index e8cf54ed..4e17ff9a 100644
--- a/spring-cloud-commons/src/main/resources/META-INF/spring.factories
+++ b/spring-cloud-commons/src/main/resources/META-INF/spring.factories
@@ -6,7 +6,8 @@ org.springframework.cloud.client.hypermedia.CloudHypermediaAutoConfiguration,\
org.springframework.cloud.client.loadbalancer.AsyncLoadBalancerAutoConfiguration,\
org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration,\
org.springframework.cloud.client.serviceregistry.ServiceRegistryAutoConfiguration,\
-org.springframework.cloud.commons.util.UtilAutoConfiguration
+org.springframework.cloud.commons.util.UtilAutoConfiguration,\
+org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration
# Environment Post Processors
diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/noop/NoopDiscoveryClientConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/DiscoveryClientAutoConfigurationDefaultTests.java
similarity index 60%
rename from spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/noop/NoopDiscoveryClientConfigurationTests.java
rename to spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/DiscoveryClientAutoConfigurationDefaultTests.java
index dfe1e1ee..b62e7aca 100644
--- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/noop/NoopDiscoveryClientConfigurationTests.java
+++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/DiscoveryClientAutoConfigurationDefaultTests.java
@@ -1,4 +1,4 @@
-package org.springframework.cloud.client.discovery.noop;
+package org.springframework.cloud.client.discovery.simple;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -10,22 +10,22 @@ import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit4.SpringRunner;
-import static org.junit.Assert.assertTrue;
+import static org.assertj.core.api.Assertions.assertThat;
/**
- * Tests if @EnableDiscoveryClient is NOT used, then NoopDiscoveryClient is created.
- * @author Spencer Gibb
+ * DiscoveryClient implementation defaults to {@link SimpleDiscoveryClient}
+ * @author Biju Kunjummen
*/
@RunWith(SpringRunner.class)
-@SpringBootTest(classes = NoopDiscoveryClientConfigurationTests.App.class)
-public class NoopDiscoveryClientConfigurationTests {
+@SpringBootTest(classes = DiscoveryClientAutoConfigurationDefaultTests.App.class)
+public class DiscoveryClientAutoConfigurationDefaultTests {
@Autowired
DiscoveryClient discoveryClient;
@Test
- public void testDiscoveryClientIsNoop() {
- assertTrue("discoveryClient is wrong instance type", discoveryClient instanceof NoopDiscoveryClient);
+ public void simpleDiscoveryClientShouldBeTheDefault() {
+ assertThat(discoveryClient).isInstanceOf(SimpleDiscoveryClient.class);
}
@EnableAutoConfiguration
diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientPropertiesMappingTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientPropertiesMappingTests.java
new file mode 100644
index 00000000..6b6b7150
--- /dev/null
+++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientPropertiesMappingTests.java
@@ -0,0 +1,88 @@
+package org.springframework.cloud.client.discovery.simple;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.cloud.client.discovery.DiscoveryClient;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.net.URI;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for mapping properties to instances in {@link SimpleDiscoveryClient}
+ *
+ * @author Biju Kunjummen
+ */
+
+@RunWith(SpringRunner.class)
+@SpringBootTest(properties = {
+ "spring.cloud.discovery.client.simple.instances.service1[0].uri=http://s1-1:8080",
+ "spring.cloud.discovery.client.simple.instances.service1[1].uri=https://s1-2:8443",
+ "spring.cloud.discovery.client.simple.instances.service2[0].uri=https://s2-1:8080",
+ "spring.cloud.discovery.client.simple.instances.service2[1].uri=https://s2-2:443" })
+public class SimpleDiscoveryClientPropertiesMappingTests {
+
+ @Autowired
+ private SimpleDiscoveryProperties props;
+
+ @Autowired
+ private DiscoveryClient discoveryClient;
+
+ @Test
+ public void propsShouldGetCleanlyMapped() {
+ assertThat(props.getInstances().size()).isEqualTo(2);
+ assertThat(props.getInstances().get("service1").size()).isEqualTo(2);
+ assertThat(props.getInstances().get("service1").get(0).getHost())
+ .isEqualTo("s1-1");
+ assertThat(props.getInstances().get("service1").get(0).getPort()).isEqualTo(8080);
+ assertThat(props.getInstances().get("service1").get(0).getUri())
+ .isEqualTo(URI.create("http://s1-1:8080"));
+ assertThat(props.getInstances().get("service1").get(0).isSecure())
+ .isEqualTo(false);
+
+ assertThat(props.getInstances().get("service2").size()).isEqualTo(2);
+ assertThat(props.getInstances().get("service2").get(0).getHost())
+ .isEqualTo("s2-1");
+ assertThat(props.getInstances().get("service2").get(0).getPort()).isEqualTo(8080);
+ assertThat(props.getInstances().get("service2").get(0).getUri())
+ .isEqualTo(URI.create("https://s2-1:8080"));
+ assertThat(props.getInstances().get("service2").get(0).isSecure())
+ .isEqualTo(true);
+ }
+
+ @Test
+ public void testDiscoveryClientShouldResolveSimpleValues() {
+ assertThat(this.discoveryClient.description())
+ .isEqualTo("Simple Discovery Client");
+ assertThat(this.discoveryClient.getInstances("service1")).hasSize(2);
+
+ ServiceInstance s1 = this.discoveryClient.getInstances("service1").get(0);
+ assertThat(s1.getHost()).isEqualTo("s1-1");
+ assertThat(s1.getPort()).isEqualTo(8080);
+ assertThat(s1.getUri()).isEqualTo(URI.create("http://s1-1:8080"));
+ assertThat(s1.isSecure()).isEqualTo(false);
+ }
+
+ @Test
+ public void testGetServices() {
+ assertThat(this.discoveryClient.getServices())
+ .containsExactlyInAnyOrder("service1", "service2");
+ }
+
+ @Test
+ public void testGetANonExistentServiceShouldReturnAnEmptyList() {
+ assertThat(this.discoveryClient.getInstances("nonexistent")).isNotNull();
+ assertThat(this.discoveryClient.getInstances("nonexistent")).isEmpty();
+ }
+
+ @Configuration
+ @EnableAutoConfiguration
+ public static class SampleConfig {
+ }
+}
diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientTests.java
new file mode 100644
index 00000000..a418901c
--- /dev/null
+++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClientTests.java
@@ -0,0 +1,47 @@
+package org.springframework.cloud.client.discovery.simple;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryProperties.SimpleServiceInstance;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author Biju Kunjummen
+ */
+public class SimpleDiscoveryClientTests {
+
+ private SimpleDiscoveryClient simpleDiscoveryClient;
+
+ @Before
+ public void setUp() {
+ SimpleDiscoveryProperties simpleDiscoveryProperties = new SimpleDiscoveryProperties();
+
+ Map> map = new HashMap<>();
+ SimpleServiceInstance service1Inst1 = new SimpleServiceInstance(
+ "http://host1:8080");
+ SimpleServiceInstance service1Inst2 = new SimpleServiceInstance(
+ "https://host2:8443");
+ map.put("service1", Arrays.asList(service1Inst1, service1Inst2));
+ simpleDiscoveryProperties.setInstances(map);
+ this.simpleDiscoveryClient = new SimpleDiscoveryClient(simpleDiscoveryProperties);
+ }
+
+ @Test
+ public void shouldBeAbleToRetrieveServiceDetailsByName() {
+ List instances = this.simpleDiscoveryClient
+ .getInstances("service1");
+ assertThat(instances.size()).isEqualTo(2);
+ assertThat(instances.get(0).getHost()).isEqualTo("host1");
+ assertThat(instances.get(0).getPort()).isEqualTo(8080);
+ assertThat(instances.get(0).getUri()).isEqualTo(URI.create("http://host1:8080"));
+ assertThat(instances.get(0).isSecure()).isEqualTo(false);
+ }
+}
diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/noop/NoopDiscoveryClientConfigurationAdditionalTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/UserDefinedDiscoveryClientOverridesDefaultsTests.java
similarity index 72%
rename from spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/noop/NoopDiscoveryClientConfigurationAdditionalTests.java
rename to spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/UserDefinedDiscoveryClientOverridesDefaultsTests.java
index ca1d3e8b..04672f17 100644
--- a/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/noop/NoopDiscoveryClientConfigurationAdditionalTests.java
+++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/client/discovery/simple/UserDefinedDiscoveryClientOverridesDefaultsTests.java
@@ -1,6 +1,4 @@
-package org.springframework.cloud.client.discovery.noop;
-
-import java.util.List;
+package org.springframework.cloud.client.discovery.simple;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -14,22 +12,26 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit4.SpringRunner;
-import static org.junit.Assert.assertFalse;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
/**
- * Tests if @EnableDiscoveryClient is NOT used, then NoopDiscoveryClient is created.
- * @author Spencer Gibb
+ * @author Biju Kunjummen
*/
@RunWith(SpringRunner.class)
-@SpringBootTest(classes = NoopDiscoveryClientConfigurationAdditionalTests.App.class)
-public class NoopDiscoveryClientConfigurationAdditionalTests {
+@SpringBootTest(classes = UserDefinedDiscoveryClientOverridesDefaultsTests.App.class)
+public class UserDefinedDiscoveryClientOverridesDefaultsTests {
@Autowired
DiscoveryClient discoveryClient;
@Test
public void testDiscoveryClientIsNotNoop() {
- assertFalse("discoveryClient is wrong instance type", discoveryClient instanceof NoopDiscoveryClient);
+ assertThat(discoveryClient).isNotInstanceOf(SimpleDiscoveryClient.class);
+
+ assertThat(discoveryClient.description())
+ .isEqualTo("user defined discovery client");
}
@EnableAutoConfiguration
@@ -41,7 +43,7 @@ public class NoopDiscoveryClientConfigurationAdditionalTests {
return new DiscoveryClient() {
@Override
public String description() {
- return null;
+ return "user defined discovery client";
}
@Override
diff --git a/spring-cloud-context/pom.xml b/spring-cloud-context/pom.xml
index cb41aa42..8d15c17b 100644
--- a/spring-cloud-context/pom.xml
+++ b/spring-cloud-context/pom.xml
@@ -59,5 +59,12 @@
spring-boot-starter-test
test
+
+ org.springframework.cloud
+ spring-cloud-commons
+ ${project.version}
+ test-jar
+ test
+
diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/RefreshAutoConfiguration.java b/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/RefreshAutoConfiguration.java
index 36ccf711..439b48fc 100644
--- a/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/RefreshAutoConfiguration.java
+++ b/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/RefreshAutoConfiguration.java
@@ -30,6 +30,7 @@ import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguratio
import org.springframework.cloud.context.environment.EnvironmentManager;
import org.springframework.cloud.context.refresh.ContextRefresher;
import org.springframework.cloud.context.scope.refresh.RefreshScope;
+import org.springframework.cloud.endpoint.event.RefreshEventListener;
import org.springframework.cloud.logging.LoggingRebinder;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
@@ -89,4 +90,10 @@ public class RefreshAutoConfiguration {
return new ContextRefresher(context, scope);
}
+ @Bean
+ public RefreshEventListener refreshEventListener(
+ ContextRefresher contextRefresher) {
+ return new RefreshEventListener(contextRefresher);
+ }
+
}
diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/RefreshEndpointAutoConfiguration.java b/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/RefreshEndpointAutoConfiguration.java
index 32c58d29..38fb06ce 100644
--- a/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/RefreshEndpointAutoConfiguration.java
+++ b/spring-cloud-context/src/main/java/org/springframework/cloud/autoconfigure/RefreshEndpointAutoConfiguration.java
@@ -16,16 +16,10 @@
package org.springframework.cloud.autoconfigure;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.actuate.autoconfigure.ConditionalOnEnabledHealthIndicator;
import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration;
import org.springframework.boot.actuate.endpoint.Endpoint;
-import org.springframework.boot.actuate.endpoint.InfoEndpoint;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@@ -34,18 +28,14 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClas
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration;
-import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder;
import org.springframework.cloud.context.refresh.ContextRefresher;
import org.springframework.cloud.context.restart.RestartEndpoint;
import org.springframework.cloud.context.scope.refresh.RefreshScope;
import org.springframework.cloud.endpoint.RefreshEndpoint;
-import org.springframework.cloud.endpoint.event.RefreshEventListener;
import org.springframework.cloud.health.RefreshScopeHealthIndicator;
-import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.integration.monitor.IntegrationMBeanExporter;
/**
@@ -119,11 +109,5 @@ public class RefreshEndpointAutoConfiguration {
return endpoint;
}
- @Bean
- public RefreshEventListener refreshEventListener(
- RefreshEndpoint refreshEndpoint) {
- return new RefreshEventListener(refreshEndpoint);
- }
-
}
}
\ No newline at end of file
diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/EncryptionBootstrapConfiguration.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/EncryptionBootstrapConfiguration.java
index 5996f263..17b53742 100644
--- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/EncryptionBootstrapConfiguration.java
+++ b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/encrypt/EncryptionBootstrapConfiguration.java
@@ -21,6 +21,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
+import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.bootstrap.encrypt.KeyProperties.KeyStore;
import org.springframework.cloud.context.encrypt.EncryptorFactory;
@@ -109,21 +110,22 @@ public class EncryptionBootstrapConfiguration {
public ConditionOutcome getMatchOutcome(ConditionContext context,
AnnotatedTypeMetadata metadata) {
Environment environment = context.getEnvironment();
- if (hasProperty(environment, "encrypt.keyStore.location")) {
- if (hasProperty(environment, "encrypt.keyStore.password")) {
+ RelaxedPropertyResolver propertyResolver = new RelaxedPropertyResolver(environment);
+ if (hasProperty(propertyResolver, environment, "encrypt.keyStore.location")) {
+ if (hasProperty(propertyResolver, environment, "encrypt.keyStore.password")) {
return ConditionOutcome.match("Keystore found in Environment");
}
return ConditionOutcome
.noMatch("Keystore found but no password in Environment");
}
- else if (hasProperty(environment, "encrypt.key")) {
+ else if (hasProperty(propertyResolver, environment, "encrypt.key")) {
return ConditionOutcome.match("Key found in Environment");
}
return ConditionOutcome.noMatch("Keystore nor key found in Environment");
}
- private boolean hasProperty(Environment environment, String key) {
- String value = environment.getProperty(key);
+ private boolean hasProperty(RelaxedPropertyResolver propertyResolver, Environment environment, String key) {
+ String value = propertyResolver.getProperty(key);
if (value == null) {
return false;
}
diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/endpoint/event/RefreshEventListener.java b/spring-cloud-context/src/main/java/org/springframework/cloud/endpoint/event/RefreshEventListener.java
index 4cda9706..16cf5e7f 100644
--- a/spring-cloud-context/src/main/java/org/springframework/cloud/endpoint/event/RefreshEventListener.java
+++ b/spring-cloud-context/src/main/java/org/springframework/cloud/endpoint/event/RefreshEventListener.java
@@ -1,25 +1,25 @@
package org.springframework.cloud.endpoint.event;
-import java.util.Arrays;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import org.springframework.boot.context.event.ApplicationReadyEvent;
-import org.springframework.cloud.endpoint.RefreshEndpoint;
+import org.springframework.cloud.context.refresh.ContextRefresher;
import org.springframework.context.event.EventListener;
import lombok.extern.apachecommons.CommonsLog;
/**
- * Calls {@link RefreshEndpoint#refresh()} when a {@link RefreshEvent} is received.
+ * Calls {@link RefreshEventListener#refresh} when a {@link RefreshEvent} is received.
* Only responds to {@link RefreshEvent} after receiving an {@link ApplicationReadyEvent} as the RefreshEvent's might come to early in the application lifecycle.
* @author Spencer Gibb
*/
@CommonsLog
public class RefreshEventListener {
- private RefreshEndpoint refresh;
+ private ContextRefresher refresh;
private AtomicBoolean ready = new AtomicBoolean(false);
- public RefreshEventListener(RefreshEndpoint refresh) {
+ public RefreshEventListener(ContextRefresher refresh) {
this.refresh = refresh;
}
@@ -32,8 +32,8 @@ public class RefreshEventListener {
public void handle(RefreshEvent event) {
if (this.ready.get()) { // don't handle events before app is ready
log.debug("Event received " + event.getEventDesc());
- String[] keys = this.refresh.refresh();
- log.info("Refresh keys changed: " + Arrays.asList(keys));
+ Set keys = this.refresh.refresh();
+ log.info("Refresh keys changed: " + keys);
}
}
}
diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/RefreshAutoConfigurationClassPathTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/RefreshAutoConfigurationClassPathTests.java
new file mode 100644
index 00000000..a6b190cb
--- /dev/null
+++ b/spring-cloud-context/src/test/java/org/springframework/cloud/autoconfigure/RefreshAutoConfigurationClassPathTests.java
@@ -0,0 +1,42 @@
+package org.springframework.cloud.autoconfigure;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.cloud.ClassPathExclusions;
+import org.springframework.cloud.FilteredClassPathRunner;
+import org.springframework.cloud.endpoint.event.RefreshEventListener;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.Configuration;
+
+import static org.junit.Assert.assertFalse;
+
+/**
+ * @author Spencer Gibb
+ */
+@RunWith(FilteredClassPathRunner.class)
+@ClassPathExclusions({"spring-boot-actuator-*.jar", "spring-boot-starter-actuator-*.jar"})
+public class RefreshAutoConfigurationClassPathTests {
+
+ @Test
+ public void refreshEventListenerCreated() {
+ try (ConfigurableApplicationContext context = getApplicationContext(
+ Config.class)) {
+ assertFalse(context.getBeansOfType(RefreshEventListener.class).isEmpty());
+ assertFalse(context.containsBean("refeshEndpoint"));
+ }
+ }
+
+ private static ConfigurableApplicationContext getApplicationContext(
+ Class> configuration, String... properties) {
+ return new SpringApplicationBuilder(configuration).web(false)
+ .properties(properties).run();
+ }
+
+ @Configuration
+ @EnableAutoConfiguration
+ static class Config {
+
+ }
+}
diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/EncryptionBootstrapConfigurationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/EncryptionBootstrapConfigurationTests.java
index 52c654ba..91d67cdc 100644
--- a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/EncryptionBootstrapConfigurationTests.java
+++ b/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/encrypt/EncryptionBootstrapConfigurationTests.java
@@ -19,6 +19,20 @@ public class EncryptionBootstrapConfigurationTests {
.run();
TextEncryptor encryptor = context.getBean(TextEncryptor.class);
assertEquals("foo", encryptor.decrypt(encryptor.encrypt("foo")));
+ context.close();
+ }
+
+ @Test
+ public void rsaKeyStoreWithRelaxedProperties() {
+ ConfigurableApplicationContext context = new SpringApplicationBuilder(
+ EncryptionBootstrapConfiguration.class).web(false).properties(
+ "encrypt.key-store.location:classpath:/server.jks",
+ "encrypt.key-store.password:letmein",
+ "encrypt.key-store.alias:mytestkey", "encrypt.key-store.secret:changeme")
+ .run();
+ TextEncryptor encryptor = context.getBean(TextEncryptor.class);
+ assertEquals("foo", encryptor.decrypt(encryptor.encrypt("foo")));
+ context.close();
}
}