diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/autoconfigure/EnvironmentEndpointAutoConfiguration.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/autoconfigure/LifecycleMvcEndpointAutoConfiguration.java similarity index 91% rename from spring-cloud-config-client/src/main/java/org/springframework/cloud/autoconfigure/EnvironmentEndpointAutoConfiguration.java rename to spring-cloud-config-client/src/main/java/org/springframework/cloud/autoconfigure/LifecycleMvcEndpointAutoConfiguration.java index b1a99243..ead3ab5d 100644 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/autoconfigure/EnvironmentEndpointAutoConfiguration.java +++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/autoconfigure/LifecycleMvcEndpointAutoConfiguration.java @@ -35,6 +35,10 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** + * Autoconfiguration for some MVC endpoints governing the application context lifecycle. + * Provides restart, pause, resume, refresh (environment) and environment update + * endpoints. + * * @author Dave Syer * */ @@ -43,8 +47,9 @@ import org.springframework.context.annotation.Configuration; @ConditionalOnProperty(value = "endpoints.env.enabled", matchIfMissing = true) @ConditionalOnWebApplication @ConditionalOnBean(RestartEndpoint.class) -@AutoConfigureAfter({ WebMvcAutoConfiguration.class, EndpointAutoConfiguration.class, RefreshAutoConfiguration.class }) -public class EnvironmentEndpointAutoConfiguration { +@AutoConfigureAfter({ WebMvcAutoConfiguration.class, EndpointAutoConfiguration.class, + RefreshAutoConfiguration.class }) +public class LifecycleMvcEndpointAutoConfiguration { @Autowired private RestartEndpoint restartEndpoint; diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/autoconfigure/RefreshAutoConfiguration.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/autoconfigure/RefreshAutoConfiguration.java index ab54312f..b783898f 100644 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/autoconfigure/RefreshAutoConfiguration.java +++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/autoconfigure/RefreshAutoConfiguration.java @@ -49,6 +49,13 @@ import org.springframework.context.annotation.Configuration; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.integration.monitor.IntegrationMBeanExporter; +/** + * Autoconfiguration for the refresh scope and associated features to do with changes in + * the Environment (e.g. rebinding logger levels). + * + * @author Dave Syer + * + */ @Configuration @ConditionalOnClass(RefreshScope.class) @AutoConfigureAfter(WebMvcAutoConfiguration.class) @@ -75,16 +82,17 @@ public class RefreshAutoConfiguration { @Configuration @ConditionalOnClass(InfoEndpoint.class) @ConditionalOnBean(EndpointAutoConfiguration.class) - protected static class InfoEndpointRebinderConfiguration implements ApplicationListener { - + protected static class InfoEndpointRebinderConfiguration implements + ApplicationListener { + @Autowired private EndpointAutoConfiguration endpoints; - + @Autowired private ConfigurableEnvironment environment; - + private Map map = new LinkedHashMap(); - + @Override public void onApplicationEvent(EnvironmentChangeEvent event) { for (String key : event.getKeys()) { @@ -93,21 +101,22 @@ public class RefreshAutoConfiguration { } } } - + @Bean public InfoEndpoint infoEndpoint() throws Exception { return new InfoEndpoint(endpoints.infoEndpoint().invoke()) { @Override public Map invoke() { - Map info = new LinkedHashMap(super.invoke()); + Map info = new LinkedHashMap( + super.invoke()); info.putAll(map); return info; } }; } - + } - + @Configuration @ConditionalOnBean(ConfigurationPropertiesBindingPostProcessor.class) protected static class ConfigurationPropertiesRebinderConfiguration { @@ -135,7 +144,7 @@ public class RefreshAutoConfiguration { @ConditionalOnClass(IntegrationMBeanExporter.class) protected static class RestartEndpointWithIntegration { - @Autowired(required=false) + @Autowired(required = false) private IntegrationMBeanExporter exporter; @Bean @@ -179,7 +188,8 @@ public class RefreshAutoConfiguration { @Bean @ConditionalOnMissingBean - public RefreshEndpoint refreshEndpoint(ConfigurableApplicationContext context, RefreshScope scope) { + public RefreshEndpoint refreshEndpoint( + ConfigurableApplicationContext context, RefreshScope scope) { RefreshEndpoint endpoint = new RefreshEndpoint(context, scope); return endpoint; } diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/BootstrapConfiguration.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/BootstrapConfiguration.java index 01ac59f6..d8df65d1 100644 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/BootstrapConfiguration.java +++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/BootstrapConfiguration.java @@ -18,7 +18,13 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; - +/** + * A marker interface used as a key in META-INF/spring.factories. Entries in + * the factories file are used to create the bootstrap application context. + * + * @author Dave Syer + * + */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/Environment.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/Environment.java index 4c5a1c63..56af50c7 100644 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/Environment.java +++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/Environment.java @@ -23,6 +23,10 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; /** + * Simple plain text serializable encapsulation of a list of property sources. Basically a + * DTO for {@link org.springframework.core.env.Environment}, but also applicable outside + * the domain of a Spring application. + * * @author Dave Syer * */ diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/PropertySource.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/PropertySource.java index 05126f43..4d1d0c7e 100644 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/PropertySource.java +++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/PropertySource.java @@ -22,10 +22,10 @@ import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; /** - * @author Dave Syer - * - */ -/** + * Simple plain text serializable encapsulation of a named source of key-value pairs. + * Basically a DTO for {@link PropertySource}, but also applicable outside the domain of a + * Spring application. + * * @author Dave Syer * */ diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/config/annotation/RefreshScope.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/config/annotation/RefreshScope.java index 59315df4..42bdee75 100644 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/config/annotation/RefreshScope.java +++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/config/annotation/RefreshScope.java @@ -24,7 +24,17 @@ import java.lang.annotation.Target; import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.ScopedProxyMode; -@Target({ElementType.TYPE, ElementType.METHOD}) +/** + * Convenience annotation to put a @Bean definition in + * {@link org.springframework.cloud.context.scope.refresh.RefreshScope refresh scope}. + * Beans annotated this way can be refreshed at runtime and any components that are using + * them will get a new instance on the next method call, fully initialized and injected + * with all dependencies. + * + * @author Dave Syer + * + */ +@Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Scope("refresh") @Documented diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/environment/EnvironmentChangeEvent.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/environment/EnvironmentChangeEvent.java index c4361393..d0fb5e50 100644 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/environment/EnvironmentChangeEvent.java +++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/environment/EnvironmentChangeEvent.java @@ -18,8 +18,11 @@ package org.springframework.cloud.context.environment; import java.util.Set; import org.springframework.context.ApplicationEvent; +import org.springframework.core.env.Environment; /** + * Event published to signal a change in the {@link Environment}. + * * @author Dave Syer * */ diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/environment/EnvironmentManager.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/environment/EnvironmentManager.java index 00b969b9..91e625cf 100644 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/environment/EnvironmentManager.java +++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/environment/EnvironmentManager.java @@ -23,6 +23,7 @@ import java.util.Set; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.Environment; import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.MutablePropertySources; import org.springframework.jmx.export.annotation.ManagedOperation; @@ -30,6 +31,10 @@ import org.springframework.jmx.export.annotation.ManagedResource; import org.springframework.stereotype.Component; /** + * Entry point for making local (but volatile) changes to the {@link Environment} of a + * running application. Allows properties to be added and values changed, simply by adding + * them to a high priority property source in the existing Environment. + * * @author Dave Syer * */ @@ -48,8 +53,8 @@ public class EnvironmentManager implements ApplicationEventPublisherAware { MutablePropertySources sources = environment.getPropertySources(); if (sources.contains(MANAGER_PROPERTY_SOURCE)) { @SuppressWarnings("unchecked") - Map map = (Map) sources.get(MANAGER_PROPERTY_SOURCE) - .getSource(); + Map map = (Map) sources.get( + MANAGER_PROPERTY_SOURCE).getSource(); this.map = map; } } @@ -60,7 +65,7 @@ public class EnvironmentManager implements ApplicationEventPublisherAware { } @ManagedOperation - public Map reset() { + public Map reset() { Map result = new LinkedHashMap(map); if (!map.isEmpty()) { Set keys = map.keySet(); @@ -75,8 +80,7 @@ public class EnvironmentManager implements ApplicationEventPublisherAware { if (!environment.getPropertySources().contains(MANAGER_PROPERTY_SOURCE)) { synchronized (map) { - if (!environment.getPropertySources().contains( - MANAGER_PROPERTY_SOURCE)) { + if (!environment.getPropertySources().contains(MANAGER_PROPERTY_SOURCE)) { MapPropertySource source = new MapPropertySource( MANAGER_PROPERTY_SOURCE, map); environment.getPropertySources().addFirst(source); diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/environment/EnvironmentManagerMvcEndpoint.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/environment/EnvironmentManagerMvcEndpoint.java index 30a6d784..652b08bd 100644 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/environment/EnvironmentManagerMvcEndpoint.java +++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/environment/EnvironmentManagerMvcEndpoint.java @@ -26,6 +26,9 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; /** + * MVC endpoint for the {@link EnvironmentManager} providing a POST to /env as a simple + * way to change the Environment. + * * @author Dave Syer * */ diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinder.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinder.java index 344446b2..c0799857 100644 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinder.java +++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinder.java @@ -25,17 +25,27 @@ import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.boot.context.properties.ConfigurationBeanFactoryMetaData; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor; +import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.cloud.context.environment.EnvironmentChangeEvent; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationListener; import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.env.Environment; import org.springframework.jmx.export.annotation.ManagedAttribute; import org.springframework.jmx.export.annotation.ManagedOperation; import org.springframework.jmx.export.annotation.ManagedResource; import org.springframework.stereotype.Component; /** + * Listens for {@link EnvironmentChangeEvent} and rebinds beans that were bound to the + * {@link Environment} using {@link ConfigurationProperties + * @ConfigurationProperties}. When these beans are re-bound and + * re-initialized the changes are available immediately to any component that is using the + * @ConfigurationProperties bean. + * + * @see RefreshScope for a deeper and optionally more focused refresh of bean components + * * @author Dave Syer * */ diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/restart/RestartEndpoint.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/restart/RestartEndpoint.java index 94171a97..5c4f0e99 100644 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/restart/RestartEndpoint.java +++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/restart/RestartEndpoint.java @@ -35,7 +35,7 @@ import org.springframework.util.ClassUtils; /** * An endpoint that restarts the application context. Install as a bean and also register * a {@link RestartListener} with the {@link SpringApplication} that starts the context. - * Those two components communicate via an {@link ApplicationEvent} and set up teh state + * Those two components communicate via an {@link ApplicationEvent} and set up the state * needed to restart the context. * * @author Dave Syer diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/restart/RestartListener.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/restart/RestartListener.java index cdd25d46..4dcad0ad 100644 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/restart/RestartListener.java +++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/restart/RestartListener.java @@ -24,6 +24,9 @@ import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.context.event.SmartApplicationListener; /** + * A listener that stores enough information about an application as it starts, to be able + * to restart it later if needed. + * * @author Dave Syer * */ @@ -58,11 +61,13 @@ public class RestartListener implements SmartApplicationListener { if (context == null) { context = event.getApplicationContext(); } - } else if (input instanceof ContextRefreshedEvent) { + } + else if (input instanceof ContextRefreshedEvent) { if (context != null && input.getSource().equals(context) && event != null) { context.publishEvent(event); } - } else { + } + else { if (context != null && input.getSource().equals(context)) { context = null; } diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/restart/RestartMvcEndpoint.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/restart/RestartMvcEndpoint.java index 804a9731..ab8b32e9 100644 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/restart/RestartMvcEndpoint.java +++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/restart/RestartMvcEndpoint.java @@ -27,8 +27,10 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; - /** + * MVC endpoint to allow an application to be restarted on a POST (to /restart by + * default). + * * @author Dave Syer * */ @@ -54,17 +56,17 @@ public class RestartMvcEndpoint extends EndpointMvcAdapter { }); thread.setDaemon(false); thread.start(); - return Collections.singletonMap( - "message", "Restarting"); + return Collections.singletonMap("message", "Restarting"); } - + public MvcEndpoint getPauseEndpoint() { - return new GenericPostableMvcEndpoint(((RestartEndpoint)getDelegate()).getPauseEndpoint()); + return new GenericPostableMvcEndpoint( + ((RestartEndpoint) getDelegate()).getPauseEndpoint()); } public MvcEndpoint getResumeEndpoint() { - return new GenericPostableMvcEndpoint(((RestartEndpoint)getDelegate()).getResumeEndpoint()); + return new GenericPostableMvcEndpoint( + ((RestartEndpoint) getDelegate()).getResumeEndpoint()); } - } diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/endpoint/GenericPostableMvcEndpoint.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/endpoint/GenericPostableMvcEndpoint.java index 2ef3447f..b9547e03 100644 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/endpoint/GenericPostableMvcEndpoint.java +++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/endpoint/GenericPostableMvcEndpoint.java @@ -26,6 +26,13 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; +/** + * A convenient base class for MVC endpoints that accept a POST (instead of the default + * GET). + * + * @author Dave Syer + * + */ public class GenericPostableMvcEndpoint extends EndpointMvcAdapter { public GenericPostableMvcEndpoint(Endpoint delegate) { diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/logging/LoggingRebinder.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/logging/LoggingRebinder.java index 4d309d9c..b67cdb40 100644 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/logging/LoggingRebinder.java +++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/logging/LoggingRebinder.java @@ -29,11 +29,14 @@ import org.springframework.context.EnvironmentAware; import org.springframework.core.env.Environment; /** + * Listener that looks for {@link EnvironmentChangeEvent} and rebinds logger levels if any + * changed. + * * @author Dave Syer * */ -public class LoggingRebinder implements - ApplicationListener, EnvironmentAware { +public class LoggingRebinder implements ApplicationListener, + EnvironmentAware { private final Log logger = LogFactory.getLog(getClass()); @@ -49,8 +52,7 @@ public class LoggingRebinder implements if (environment == null) { return; } - LoggingSystem system = LoggingSystem.get(LoggingSystem.class - .getClassLoader()); + LoggingSystem system = LoggingSystem.get(LoggingSystem.class.getClassLoader()); setLogLevels(system, environment); } diff --git a/spring-cloud-config-client/src/main/resources/META-INF/spring.factories b/spring-cloud-config-client/src/main/resources/META-INF/spring.factories index b6359593..9d136e43 100644 --- a/spring-cloud-config-client/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-config-client/src/main/resources/META-INF/spring.factories @@ -1,7 +1,7 @@ # Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.cloud.autoconfigure.RefreshAutoConfiguration,\ -org.springframework.cloud.autoconfigure.EnvironmentEndpointAutoConfiguration,\ +org.springframework.cloud.autoconfigure.LifecycleMvcEndpointAutoConfiguration,\ org.springframework.cloud.autoconfigure.ConfigClientAutoConfiguration # Application Listeners