Merge branch 'master' into 2.0.x

# Conflicts:
#	docs/pom.xml
#	pom.xml
#	spring-cloud-commons-dependencies/pom.xml
#	spring-cloud-commons/pom.xml
#	spring-cloud-context/pom.xml
#	spring-cloud-starter/pom.xml
This commit is contained in:
Spencer Gibb
2017-04-06 21:43:05 -06:00
27 changed files with 671 additions and 233 deletions

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}

View File

@@ -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<String> keys = this.refresh.refresh();
log.info("Refresh keys changed: " + keys);
}
}
}

View File

@@ -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 {
}
}

View File

@@ -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();
}
}