Applied checkstyle and turned it on by default

This commit is contained in:
Marcin Grzejszczak
2019-02-01 12:50:02 +01:00
parent e024f6f5c2
commit ae314100f5
313 changed files with 8658 additions and 4416 deletions

View File

@@ -29,6 +29,11 @@ import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Auto-configuration for {@link ConfigurationPropertiesRebinder}.
*
* @author Dave Syer
*/
@Configuration
@ConditionalOnBean(ConfigurationPropertiesBindingPostProcessor.class)
public class ConfigurationPropertiesRebinderAutoConfiguration
@@ -50,7 +55,7 @@ public class ConfigurationPropertiesRebinderAutoConfiguration
// choice).
ConfigurationBeanFactoryMetadata metaData = this.context.getBean(
ConfigurationBeanFactoryMetadata.BEAN_NAME,
ConfigurationBeanFactoryMetadata.class);
ConfigurationBeanFactoryMetadata.class);
ConfigurationPropertiesBeans beans = new ConfigurationPropertiesBeans();
beans.setBeanMetaDataStore(metaData);
return beans;
@@ -75,11 +80,12 @@ public class ConfigurationPropertiesRebinderAutoConfiguration
if (this.context.getParent() != null) {
// TODO: make this optional? (E.g. when creating child contexts that prefer to
// be isolated.)
ConfigurationPropertiesRebinder rebinder = context
ConfigurationPropertiesRebinder rebinder = this.context
.getBean(ConfigurationPropertiesRebinder.class);
for (String name : context.getParent().getBeanDefinitionNames()) {
for (String name : this.context.getParent().getBeanDefinitionNames()) {
rebinder.rebind(name);
}
}
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2018 the original author or authors.
* Copyright 2012-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.autoconfigure;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2012-2019 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.
@@ -12,7 +12,6 @@
* 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.autoconfigure;
@@ -68,8 +67,19 @@ import org.springframework.util.StringUtils;
@AutoConfigureBefore(HibernateJpaAutoConfiguration.class)
public class RefreshAutoConfiguration {
/**
* Name of the refresh scope name.
*/
public static final String REFRESH_SCOPE_NAME = "refresh";
/**
* Name of the prefix for refresh scope.
*/
public static final String REFRESH_SCOPE_PREFIX = "spring.cloud.refresh";
/**
* Name of the enabled prefix for refresh scope.
*/
public static final String REFRESH_SCOPE_ENABLED = REFRESH_SCOPE_PREFIX + ".enabled";
@Bean
@@ -78,6 +88,24 @@ public class RefreshAutoConfiguration {
return new RefreshScope();
}
@Bean
@ConditionalOnMissingBean
public static LoggingRebinder loggingRebinder() {
return new LoggingRebinder();
}
@Bean
@ConditionalOnMissingBean
public ContextRefresher contextRefresher(ConfigurableApplicationContext context,
RefreshScope scope) {
return new ContextRefresher(context, scope);
}
@Bean
public RefreshEventListener refreshEventListener(ContextRefresher contextRefresher) {
return new RefreshEventListener(contextRefresher);
}
@Configuration
@ConditionalOnClass(name = "javax.persistence.EntityManagerFactory")
protected static class JpaInvokerConfiguration implements LoadTimeWeaverAware {
@@ -88,8 +116,8 @@ public class RefreshAutoConfiguration {
@PostConstruct
public void init() {
String cls = "org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker";
if (beanFactory.containsBean(cls)) {
beanFactory.getBean(cls);
if (this.beanFactory.containsBean(cls)) {
this.beanFactory.getBean(cls);
}
}
@@ -176,13 +204,13 @@ public class RefreshAutoConfiguration {
}
private void bindEnvironmentIfNeeded(BeanDefinitionRegistry registry) {
if (!bound) { // only bind once
if (!this.bound) { // only bind once
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
Binder.get(environment).bind("spring.cloud.refresh",
Binder.get(this.environment).bind("spring.cloud.refresh",
Bindable.ofInstance(this));
bound = true;
this.bound = true;
}
}
@@ -190,24 +218,7 @@ public class RefreshAutoConfiguration {
public void setEnvironment(Environment environment) {
this.environment = environment;
}
}
@Bean
@ConditionalOnMissingBean
public static LoggingRebinder loggingRebinder() {
return new LoggingRebinder();
}
@Bean
@ConditionalOnMissingBean
public ContextRefresher contextRefresher(ConfigurableApplicationContext context,
RefreshScope scope) {
return new ContextRefresher(context, scope);
}
@Bean
public RefreshEventListener refreshEventListener(ContextRefresher contextRefresher) {
return new RefreshEventListener(contextRefresher);
}
}

View File

@@ -45,9 +45,9 @@ import org.springframework.integration.monitor.IntegrationMBeanExporter;
* @author Venil Noronha
*/
@Configuration
@ConditionalOnClass({EndpointAutoConfiguration.class, Health.class})
@ConditionalOnClass({ EndpointAutoConfiguration.class, Health.class })
@AutoConfigureAfter({ LifecycleMvcEndpointAutoConfiguration.class,
RefreshAutoConfiguration.class})
RefreshAutoConfiguration.class })
@Import({ RestartEndpointWithIntegrationConfiguration.class,
RestartEndpointWithoutIntegrationConfiguration.class,
PauseResumeEndpointsConfiguration.class })
@@ -56,8 +56,9 @@ public class RefreshEndpointAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnEnabledHealthIndicator("refresh")
RefreshScopeHealthIndicator refreshScopeHealthIndicator(ObjectProvider<RefreshScope> scope,
ConfigurationPropertiesRebinder rebinder) {
RefreshScopeHealthIndicator refreshScopeHealthIndicator(
ObjectProvider<RefreshScope> scope,
ConfigurationPropertiesRebinder rebinder) {
return new RefreshScopeHealthIndicator(scope, rebinder);
}
@@ -74,6 +75,7 @@ public class RefreshEndpointAutoConfiguration {
}
}
}
@Configuration

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2012-2019 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.autoconfigure;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
@@ -46,7 +62,8 @@ public class WritableEnvironmentEndpointAutoConfiguration {
@ConditionalOnMissingBean
@ConditionalOnEnabledEndpoint
public WritableEnvironmentEndpoint environmentEndpoint(Environment environment) {
WritableEnvironmentEndpoint endpoint = new WritableEnvironmentEndpoint(environment);
WritableEnvironmentEndpoint endpoint = new WritableEnvironmentEndpoint(
environment);
String[] keysToSanitize = this.properties.getKeysToSanitize();
if (keysToSanitize != null) {
endpoint.setKeysToSanitize(keysToSanitize);

View File

@@ -71,10 +71,19 @@ import org.springframework.util.StringUtils;
public class BootstrapApplicationListener
implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered {
/**
* Property source name for bootstrap.
*/
public static final String BOOTSTRAP_PROPERTY_SOURCE_NAME = "bootstrap";
/**
* The default order for this listener.
*/
public static final int DEFAULT_ORDER = Ordered.HIGHEST_PRECEDENCE + 5;
/**
* The name of the default properties.
*/
public static final String DEFAULT_PROPERTIES = "defaultProperties";
private int order = DEFAULT_ORDER;
@@ -104,7 +113,8 @@ public class BootstrapApplicationListener
if (context == null) {
context = bootstrapServiceContext(environment, event.getSpringApplication(),
configName);
event.getSpringApplication().addListeners(new CloseContextOnFailureApplicationListener(context));
event.getSpringApplication()
.addListeners(new CloseContextOnFailureApplicationListener(context));
}
apply(context, event.getSpringApplication(), environment);
@@ -146,8 +156,10 @@ public class BootstrapApplicationListener
.resolvePlaceholders("${spring.cloud.bootstrap.location:}");
Map<String, Object> bootstrapMap = new HashMap<>();
bootstrapMap.put("spring.config.name", configName);
// if an app (or test) uses spring.main.web-application-type=reactive, bootstrap will fail
// force the environment to use none, because if though it is set below in the builder
// if an app (or test) uses spring.main.web-application-type=reactive, bootstrap
// will fail
// force the environment to use none, because if though it is set below in the
// builder
// the environment overrides it
bootstrapMap.put("spring.main.web-application-type", "none");
if (StringUtils.hasText(configLocation)) {
@@ -169,7 +181,7 @@ public class BootstrapApplicationListener
.registerShutdownHook(false).logStartupInfo(false)
.web(WebApplicationType.NONE);
final SpringApplication builderApplication = builder.application();
if(builderApplication.getMainApplicationClass() == null){
if (builderApplication.getMainApplicationClass() == null) {
// gh_425:
// SpringApplication cannot deduce the MainApplicationClass here
// if it is booted from SpringBootServletInitializer due to the
@@ -225,18 +237,14 @@ public class BootstrapApplicationListener
}
else {
PropertySource<?> target = environment.get(name);
if (target instanceof MapPropertySource) {
if (target instanceof MapPropertySource && target != source
&& source instanceof MapPropertySource) {
Map<String, Object> targetMap = ((MapPropertySource) target)
.getSource();
if (target != source) {
if (source instanceof MapPropertySource) {
Map<String, Object> map = ((MapPropertySource) source)
.getSource();
for (String key : map.keySet()) {
if (!target.containsProperty(key)) {
targetMap.put(key, map.get(key));
}
}
Map<String, Object> map = ((MapPropertySource) source).getSource();
for (String key : map.keySet()) {
if (!target.containsProperty(key)) {
targetMap.put(key, map.get(key));
}
}
}
@@ -303,13 +311,11 @@ public class BootstrapApplicationListener
private void addBootstrapDecryptInitializer(SpringApplication application) {
DelegatingEnvironmentDecryptApplicationInitializer decrypter = null;
for (ApplicationContextInitializer<?> initializer : application
.getInitializers()) {
if (initializer instanceof EnvironmentDecryptApplicationInitializer) {
for (ApplicationContextInitializer<?> ini : application.getInitializers()) {
if (ini instanceof EnvironmentDecryptApplicationInitializer) {
@SuppressWarnings("unchecked")
ApplicationContextInitializer<ConfigurableApplicationContext> delegate = (ApplicationContextInitializer<ConfigurableApplicationContext>) initializer;
decrypter = new DelegatingEnvironmentDecryptApplicationInitializer(
delegate);
ApplicationContextInitializer del = (ApplicationContextInitializer) ini;
decrypter = new DelegatingEnvironmentDecryptApplicationInitializer(del);
}
}
if (decrypter != null) {
@@ -327,21 +333,21 @@ public class BootstrapApplicationListener
return result;
}
public void setOrder(int order) {
this.order = order;
}
@Override
public int getOrder() {
return this.order;
}
public void setOrder(int order) {
this.order = order;
}
private static class AncestorInitializer implements
ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered {
private ConfigurableApplicationContext parent;
public AncestorInitializer(ConfigurableApplicationContext parent) {
AncestorInitializer(ConfigurableApplicationContext parent) {
this.parent = parent;
}
@@ -397,7 +403,7 @@ public class BootstrapApplicationListener
private ApplicationContextInitializer<ConfigurableApplicationContext> delegate;
public DelegatingEnvironmentDecryptApplicationInitializer(
DelegatingEnvironmentDecryptApplicationInitializer(
ApplicationContextInitializer<ConfigurableApplicationContext> delegate) {
this.delegate = delegate;
}
@@ -413,14 +419,22 @@ public class BootstrapApplicationListener
extends SystemEnvironmentPropertySource {
private final CompositePropertySource sources;
private final List<String> names = new ArrayList<>();
public ExtendedDefaultPropertySource(String name,
PropertySource<?> propertySource) {
ExtendedDefaultPropertySource(String name, PropertySource<?> propertySource) {
super(name, findMap(propertySource));
this.sources = new CompositePropertySource(name);
}
@SuppressWarnings("unchecked")
private static Map<String, Object> findMap(PropertySource<?> propertySource) {
if (propertySource instanceof MapPropertySource) {
return (Map<String, Object>) propertySource.getSource();
}
return new LinkedHashMap<String, Object>();
}
public CompositePropertySource getPropertySources() {
return this.sources;
}
@@ -461,21 +475,14 @@ public class BootstrapApplicationListener
return names.toArray(new String[0]);
}
@SuppressWarnings("unchecked")
private static Map<String, Object> findMap(PropertySource<?> propertySource) {
if (propertySource instanceof MapPropertySource) {
return (Map<String, Object>) propertySource.getSource();
}
return new LinkedHashMap<String, Object>();
}
}
private static class CloseContextOnFailureApplicationListener implements SmartApplicationListener {
private static class CloseContextOnFailureApplicationListener
implements SmartApplicationListener {
private final ConfigurableApplicationContext context;
public CloseContextOnFailureApplicationListener(ConfigurableApplicationContext context) {
CloseContextOnFailureApplicationListener(ConfigurableApplicationContext context) {
this.context = context;
}
@@ -491,6 +498,7 @@ public class BootstrapApplicationListener
}
}
}
}

View File

@@ -1,15 +1,19 @@
/*
* Copyright 2013-2014 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.
* Copyright 2012-2019 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.bootstrap;
import java.lang.annotation.Documented;
@@ -21,7 +25,7 @@ import java.lang.annotation.Target;
/**
* A marker interface used as a key in <code>META-INF/spring.factories</code>. Entries in
* the factories file are used to create the bootstrap application context.
*
*
* @author Dave Syer
*
*/
@@ -32,6 +36,7 @@ public @interface BootstrapConfiguration {
/**
* Excludes specific auto-configuration classes such that they will never be applied.
* @return classes to exclude
*/
Class<?>[] exclude() default {};

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2018 the original author or authors.
* Copyright 2013-2019 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.
@@ -39,10 +39,12 @@ import org.springframework.util.StringUtils;
/**
* This class uses {@link SpringFactoriesLoader} to load {@link BootstrapConfiguration}
* entries from {@code spring.factories}. The classes are then loaded so they can
* be sorted using {@link AnnotationAwareOrderComparator#sort(List)}.
* This class is a {@link DeferredImportSelector} so {@code @Conditional} annotations
* on imported classes are supported.
* entries from {@code spring.factories}. The classes are then loaded so they can be
* sorted using {@link AnnotationAwareOrderComparator#sort(List)}. This class is a
* {@link DeferredImportSelector} so {@code @Conditional} annotations on imported classes
* are supported.
*
* @author Spencer Gibb
*/
public class BootstrapImportSelector implements EnvironmentAware, DeferredImportSelector {
@@ -62,21 +64,21 @@ public class BootstrapImportSelector implements EnvironmentAware, DeferredImport
List<String> names = new ArrayList<>(SpringFactoriesLoader
.loadFactoryNames(BootstrapConfiguration.class, classLoader));
names.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(
environment.getProperty("spring.cloud.bootstrap.sources", ""))));
this.environment.getProperty("spring.cloud.bootstrap.sources", ""))));
List<OrderedAnnotatedElement> elements = new ArrayList<>();
for (String name : names) {
try {
elements.add(new OrderedAnnotatedElement(metadataReaderFactory, name));
} catch (IOException e) {
elements.add(
new OrderedAnnotatedElement(this.metadataReaderFactory, name));
}
catch (IOException e) {
continue;
}
}
AnnotationAwareOrderComparator.sort(elements);
String[] classNames = elements.stream()
.map(e -> e.name)
.toArray(String[]::new);
String[] classNames = elements.stream().map(e -> e.name).toArray(String[]::new);
return classNames;
}
@@ -84,17 +86,21 @@ public class BootstrapImportSelector implements EnvironmentAware, DeferredImport
class OrderedAnnotatedElement implements AnnotatedElement {
private final String name;
private Order order = null;
private Integer value;
public OrderedAnnotatedElement(MetadataReaderFactory metadataReaderFactory, String name) throws IOException {
OrderedAnnotatedElement(MetadataReaderFactory metadataReaderFactory, String name)
throws IOException {
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(name);
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
Map<String, Object> attributes = metadata.getAnnotationAttributes(Order.class.getName());
Map<String, Object> attributes = metadata
.getAnnotationAttributes(Order.class.getName());
this.name = name;
if (attributes != null && attributes.containsKey("value")) {
value = (Integer) attributes.get("value");
order = new Order() {
this.value = (Integer) attributes.get("value");
this.order = new Order() {
@Override
public Class<? extends Annotation> annotationType() {
return Order.class;
@@ -102,7 +108,7 @@ public class BootstrapImportSelector implements EnvironmentAware, DeferredImport
@Override
public int value() {
return value;
return OrderedAnnotatedElement.this.value;
}
};
}
@@ -112,14 +118,15 @@ public class BootstrapImportSelector implements EnvironmentAware, DeferredImport
@SuppressWarnings("unchecked")
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
if (annotationClass == Order.class) {
return (T) order;
return (T) this.order;
}
return null;
}
@Override
public Annotation[] getAnnotations() {
return order == null ? new Annotation[0] : new Annotation[]{order};
return this.order == null ? new Annotation[0]
: new Annotation[] { this.order };
}
@Override
@@ -129,10 +136,10 @@ public class BootstrapImportSelector implements EnvironmentAware, DeferredImport
@Override
public String toString() {
return new ToStringCreator(this)
.append("name", name)
.append("value", value)
.toString();
return new ToStringCreator(this).append("name", this.name)
.append("value", this.value).toString();
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2018 the original author or authors.
* Copyright 2013-2019 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.
@@ -19,7 +19,13 @@ package org.springframework.cloud.bootstrap;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* Configuration to import the {@link BootstrapImportSelector} configuration.
*
* @author Spencer Gibb
*/
@Configuration
@Import(BootstrapImportSelector.class)
public class BootstrapImportSelectorConfiguration {
}

View File

@@ -33,6 +33,9 @@ import org.springframework.util.ClassUtils;
public class LoggingSystemShutdownListener
implements ApplicationListener<ApplicationEnvironmentPreparedEvent>, Ordered {
/**
* Default order for the listener.
*/
public static final int DEFAULT_ORDER = BootstrapApplicationListener.DEFAULT_ORDER
+ 1;
@@ -50,13 +53,13 @@ public class LoggingSystemShutdownListener
loggingSystem.beforeInitialize();
}
public void setOrder(int order) {
this.order = order;
}
@Override
public int getOrder() {
return this.order;
}
public void setOrder(int order) {
this.order = order;
}
}

View File

@@ -61,6 +61,9 @@ import org.springframework.util.StringUtils;
public class PropertySourceBootstrapConfiguration implements
ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered {
/**
* Bootstrap property source name.
*/
public static final String BOOTSTRAP_PROPERTY_SOURCE_NAME = BootstrapApplicationListener.BOOTSTRAP_PROPERTY_SOURCE_NAME
+ "Properties";
@@ -116,7 +119,8 @@ public class PropertySourceBootstrapConfiguration implements
private void reinitializeLoggingSystem(ConfigurableEnvironment environment,
String oldLogConfig, LogFile oldLogFile) {
Map<String, Object> props = Binder.get(environment)
.bind("logging", Bindable.mapOf(String.class, Object.class)).orElseGet(Collections::emptyMap);
.bind("logging", Bindable.mapOf(String.class, Object.class))
.orElseGet(Collections::emptyMap);
if (!props.isEmpty()) {
String logConfig = environment.resolvePlaceholders("${logging.config:}");
LogFile logFile = LogFile.get(environment);
@@ -154,7 +158,8 @@ public class PropertySourceBootstrapConfiguration implements
MutablePropertySources incoming = new MutablePropertySources();
incoming.addFirst(composite);
PropertySourceBootstrapProperties remoteProperties = new PropertySourceBootstrapProperties();
Binder.get(environment(incoming)).bind("spring.cloud.config", Bindable.ofInstance(remoteProperties));
Binder.get(environment(incoming)).bind("spring.cloud.config",
Bindable.ofInstance(remoteProperties));
if (!remoteProperties.isAllowOverride() || (!remoteProperties.isOverrideNone()
&& remoteProperties.isOverrideSystemProperties())) {
propertySources.addFirst(composite);
@@ -231,7 +236,8 @@ public class PropertySourceBootstrapConfiguration implements
private String[] getProfilesForValue(Object property) {
final String value = (property == null ? null : property.toString());
return property == null ? new String[0] : StringUtils.tokenizeToStringArray(value, ",");
return property == null ? new String[0]
: StringUtils.tokenizeToStringArray(value, ",");
}
}

View File

@@ -1,7 +1,28 @@
/*
* Copyright 2012-2019 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.bootstrap.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Properties for Spring Cloud Config bootstrap.
*
* @author Dave Syer
*/
@ConfigurationProperties("spring.cloud.config")
public class PropertySourceBootstrapProperties {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2012-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.bootstrap.config;
import org.springframework.core.env.Environment;
@@ -22,7 +23,7 @@ import org.springframework.core.env.PropertySource;
* Strategy for locating (possibly remote) property sources for the Environment.
* Implementations should not fail unless they intend to prevent the application from
* starting.
*
*
* @author Dave Syer
*
*/
@@ -31,7 +32,6 @@ public interface PropertySourceLocator {
/**
* @param environment The current Environment.
* @return A PropertySource, or null if there is none.
*
* @throws IllegalStateException if there is a fail-fast condition.
*/
PropertySource<?> locate(Environment environment);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2012-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.bootstrap.encrypt;
import org.springframework.beans.factory.annotation.Autowired;
@@ -41,7 +42,7 @@ import org.springframework.util.StringUtils;
*/
@Configuration
@ConditionalOnClass({ TextEncryptor.class })
@EnableConfigurationProperties({KeyProperties.class})
@EnableConfigurationProperties({ KeyProperties.class })
public class EncryptionBootstrapConfiguration {
@Autowired(required = false)
@@ -50,10 +51,21 @@ public class EncryptionBootstrapConfiguration {
@Autowired
private KeyProperties key;
@Bean
public EnvironmentDecryptApplicationInitializer environmentDecryptApplicationListener() {
if (this.encryptor == null) {
this.encryptor = new FailsafeTextEncryptor();
}
EnvironmentDecryptApplicationInitializer listener = new EnvironmentDecryptApplicationInitializer(
this.encryptor);
listener.setFailOnError(this.key.isFailOnError());
return listener;
}
@Configuration
@Conditional(KeyCondition.class)
@ConditionalOnClass(RsaSecretEncryptor.class)
@EnableConfigurationProperties({RsaProperties.class})
@EnableConfigurationProperties({ RsaProperties.class })
protected static class RsaEncryptionConfiguration {
@Autowired
@@ -73,10 +85,10 @@ public class EncryptionBootstrapConfiguration {
keyStore.getPassword().toCharArray()).getKeyPair(
keyStore.getAlias(),
keyStore.getSecret().toCharArray()),
this.rsaProperties.getAlgorithm(), this.rsaProperties.getSalt(),
this.rsaProperties.isStrong());
}
this.rsaProperties.getAlgorithm(),
this.rsaProperties.getSalt(), this.rsaProperties.isStrong());
}
throw new IllegalStateException("Invalid keystore location");
}
@@ -101,17 +113,9 @@ public class EncryptionBootstrapConfiguration {
}
@Bean
public EnvironmentDecryptApplicationInitializer environmentDecryptApplicationListener() {
if (this.encryptor == null) {
this.encryptor = new FailsafeTextEncryptor();
}
EnvironmentDecryptApplicationInitializer listener = new EnvironmentDecryptApplicationInitializer(
this.encryptor);
listener.setFailOnError(this.key.isFailOnError());
return listener;
}
/**
* A Spring Boot condition for key encryption.
*/
public static class KeyCondition extends SpringBootCondition {
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2017 the original author or authors.
* Copyright 2012-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.bootstrap.encrypt;
import java.util.ArrayList;
@@ -52,32 +53,40 @@ import org.springframework.security.crypto.encrypt.TextEncryptor;
public class EnvironmentDecryptApplicationInitializer implements
ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered {
/**
* Name of the decrypted property source.
*/
public static final String DECRYPTED_PROPERTY_SOURCE_NAME = "decrypted";
/**
* Name of the decrypted bootstrap property source.
*/
public static final String DECRYPTED_BOOTSTRAP_PROPERTY_SOURCE_NAME = "decryptedBootstrap";
private int order = Ordered.HIGHEST_PRECEDENCE + 15;
private static final Pattern COLLECTION_PROPERTY = Pattern
.compile("(\\S+)?\\[(\\d+)\\](\\.\\S+)?");
private static Log logger = LogFactory
.getLog(EnvironmentDecryptApplicationInitializer.class);
private int order = Ordered.HIGHEST_PRECEDENCE + 15;
private TextEncryptor encryptor;
private boolean failOnError = true;
public EnvironmentDecryptApplicationInitializer(TextEncryptor encryptor) {
this.encryptor = encryptor;
}
/**
* Strategy to determine how to handle exceptions during decryption.
*
* @param failOnError The flag value (default true).
*/
public void setFailOnError(boolean failOnError) {
this.failOnError = failOnError;
}
public EnvironmentDecryptApplicationInitializer(TextEncryptor encryptor) {
this.encryptor = encryptor;
}
@Override
public int getOrder() {
return this.order;
@@ -178,9 +187,6 @@ public class EnvironmentDecryptApplicationInitializer implements
return overrides;
}
private static final Pattern COLLECTION_PROPERTY = Pattern
.compile("(\\S+)?\\[(\\d+)\\](\\.\\S+)?");
private void collectEncryptedProperties(PropertySource<?> source,
Map<String, Object> overrides) {
@@ -193,7 +199,8 @@ public class EnvironmentDecryptApplicationInitializer implements
collectEncryptedProperties(nested, overrides);
}
} else if (source instanceof EnumerablePropertySource) {
}
else if (source instanceof EnumerablePropertySource) {
Map<String, Object> otherCollectionProperties = new LinkedHashMap<>();
boolean sourceHasDecryptedCollection = false;
@@ -207,11 +214,13 @@ public class EnvironmentDecryptApplicationInitializer implements
if (COLLECTION_PROPERTY.matcher(key).matches()) {
sourceHasDecryptedCollection = true;
}
} else if (COLLECTION_PROPERTY.matcher(key).matches()) {
}
else if (COLLECTION_PROPERTY.matcher(key).matches()) {
// put non-encrypted properties so merging of index properties
// happens correctly
otherCollectionProperties.put(key, value);
} else {
}
else {
overrides.remove(key);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2012-2019 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.
@@ -13,11 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.bootstrap.encrypt;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.io.Resource;
/**
* Key encryption properties.
*
* @author Dave Syer
*/
@ConfigurationProperties("encrypt")
public class KeyProperties {
@@ -27,8 +33,8 @@ public class KeyProperties {
private String key;
/**
* A salt for the symmetric key, in the form of a hex-encoded byte array. As a stronger
* alternative, consider using a keystore.
* A salt for the symmetric key, in the form of a hex-encoded byte array. As a
* stronger alternative, consider using a keystore.
*/
private String salt = "deadbeef";
@@ -61,7 +67,7 @@ public class KeyProperties {
}
public String getSalt() {
return salt;
return this.salt;
}
public void setSalt(String salt) {
@@ -76,6 +82,9 @@ public class KeyProperties {
this.keyStore = keyStore;
}
/**
* Key store properties.
*/
public static class KeyStore {
/**
@@ -131,4 +140,5 @@ public class KeyProperties {
}
}
}

View File

@@ -1,6 +1,5 @@
package org.springframework.cloud.bootstrap.encrypt;
/*
* Copyright 2013-2018 the original author or authors.
* Copyright 2013-2019 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.
@@ -15,6 +14,8 @@ package org.springframework.cloud.bootstrap.encrypt;
* limitations under the License.
*/
package org.springframework.cloud.bootstrap.encrypt;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.security.rsa.crypto.RsaAlgorithm;
@@ -33,10 +34,10 @@ public class RsaProperties {
private RsaAlgorithm algorithm = RsaAlgorithm.DEFAULT;
/**
* Flag to indicate that "strong" AES encryption should be used internally. If
* true, then the GCM algorithm is applied to the AES encrypted bytes. Default is
* false (in which case "standard" CBC is used instead). Once it is set, do not
* change it (or existing ciphers will not be decryptable).
* Flag to indicate that "strong" AES encryption should be used internally. If true,
* then the GCM algorithm is applied to the AES encrypted bytes. Default is false (in
* which case "standard" CBC is used instead). Once it is set, do not change it (or
* existing ciphers will not be decryptable).
*/
private boolean strong = false;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2012-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.context.config.annotation;
import java.lang.annotation.Documented;
@@ -30,7 +31,7 @@ import org.springframework.context.annotation.ScopedProxyMode;
* 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
*
*/
@@ -39,8 +40,10 @@ import org.springframework.context.annotation.ScopedProxyMode;
@Scope("refresh")
@Documented
public @interface RefreshScope {
/**
* @see Scope#proxyMode()
* @return proxy mode
*/
ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2018 the original author or authors.
* Copyright 2012-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.context.encrypt;
import java.io.IOException;
@@ -67,7 +68,7 @@ public class EncryptorFactory {
throw new KeyFormatException();
}
else {
encryptor = Encryptors.text(data, salt);
encryptor = Encryptors.text(data, this.salt);
}
return encryptor;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2012-2019 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.
@@ -13,15 +13,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.context.encrypt;
/**
* Exception related to the format of key.
*
* @author Dave Syer
*/
@SuppressWarnings("serial")
public class KeyFormatException extends RuntimeException {
public KeyFormatException() {
super();
}
public KeyFormatException(Throwable t) {
super(t);
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2012-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.context.environment;
import java.util.Set;
@@ -22,7 +23,7 @@ import org.springframework.core.env.Environment;
/**
* Event published to signal a change in the {@link Environment}.
*
*
* @author Dave Syer
*
*/
@@ -45,7 +46,7 @@ public class EnvironmentChangeEvent extends ApplicationEvent {
* @return The keys.
*/
public Set<String> getKeys() {
return keys;
return this.keys;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2012-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.context.environment;
import java.util.Collections;
@@ -33,18 +34,20 @@ 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
*
*
*/
@Component
@ManagedResource
public class EnvironmentManager implements ApplicationEventPublisherAware {
private static final String MANAGER_PROPERTY_SOURCE = "manager";
private Map<String, Object> map = new LinkedHashMap<String, Object>();
private ConfigurableEnvironment environment;
private ApplicationEventPublisher publisher;
public EnvironmentManager(ConfigurableEnvironment environment) {
@@ -65,10 +68,10 @@ public class EnvironmentManager implements ApplicationEventPublisherAware {
@ManagedOperation
public Map<String, Object> reset() {
Map<String, Object> result = new LinkedHashMap<String, Object>(map);
if (!map.isEmpty()) {
map.clear();
publish(new EnvironmentChangeEvent(publisher, result.keySet()));
Map<String, Object> result = new LinkedHashMap<String, Object>(this.map);
if (!this.map.isEmpty()) {
this.map.clear();
publish(new EnvironmentChangeEvent(this.publisher, result.keySet()));
}
return result;
}
@@ -76,31 +79,33 @@ public class EnvironmentManager implements ApplicationEventPublisherAware {
@ManagedOperation
public void setProperty(String name, String value) {
if (!environment.getPropertySources().contains(MANAGER_PROPERTY_SOURCE)) {
synchronized (map) {
if (!environment.getPropertySources().contains(MANAGER_PROPERTY_SOURCE)) {
if (!this.environment.getPropertySources().contains(MANAGER_PROPERTY_SOURCE)) {
synchronized (this.map) {
if (!this.environment.getPropertySources()
.contains(MANAGER_PROPERTY_SOURCE)) {
MapPropertySource source = new MapPropertySource(
MANAGER_PROPERTY_SOURCE, map);
environment.getPropertySources().addFirst(source);
MANAGER_PROPERTY_SOURCE, this.map);
this.environment.getPropertySources().addFirst(source);
}
}
}
if (!value.equals(environment.getProperty(name))) {
map.put(name, value);
publish(new EnvironmentChangeEvent(publisher, Collections.singleton(name)));
if (!value.equals(this.environment.getProperty(name))) {
this.map.put(name, value);
publish(new EnvironmentChangeEvent(this.publisher,
Collections.singleton(name)));
}
}
@ManagedOperation
public Object getProperty(String name) {
return environment.getProperty(name);
return this.environment.getProperty(name);
}
private void publish(EnvironmentChangeEvent environmentChangeEvent) {
if (publisher != null) {
publisher.publishEvent(environmentChangeEvent);
if (this.publisher != null) {
this.publisher.publishEvent(environmentChangeEvent);
}
}

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2012-2019 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.context.environment;
import org.springframework.boot.actuate.env.EnvironmentEndpoint;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2018 the original author or authors.
* Copyright 2012-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.context.environment;
import java.util.Collections;
@@ -26,9 +27,9 @@ import org.springframework.boot.actuate.env.EnvironmentEndpointWebExtension;
/**
* MVC endpoint for the {@link EnvironmentManager}, providing a POST to /env as a simple
* way to change the Environment.
*
*
* @author Dave Syer
*
*
*/
@EndpointWebExtension(endpoint = WritableEnvironmentEndpoint.class)
public class WritableEnvironmentEndpointWebExtension
@@ -44,13 +45,13 @@ public class WritableEnvironmentEndpointWebExtension
@WriteOperation
public Object write(String name, String value) {
environment.setProperty(name, value);
this.environment.setProperty(name, value);
return Collections.singletonMap(name, value);
}
@DeleteOperation
public Map<String, Object> reset() {
return environment.reset();
return this.environment.reset();
}
public void setEnvironmentManager(EnvironmentManager environment) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2018 the original author or authors.
* Copyright 2013-2019 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.
@@ -16,29 +16,34 @@
package org.springframework.cloud.context.named;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.lang.Nullable;
import java.util.Iterator;
import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Stream;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.lang.Nullable;
/**
* Special ObjectProvider that allows the actual ObjectProvider to be resolved
* later because of the creation of the named child context.
* @param <T>
* Special ObjectProvider that allows the actual ObjectProvider to be resolved later
* because of the creation of the named child context.
*
* @param <T> - type of the provided object
*/
class ClientFactoryObjectProvider<T> implements ObjectProvider<T> {
private final NamedContextFactory clientFactory;
private final String name;
private final Class<T> type;
private ObjectProvider<T> provider;
public ClientFactoryObjectProvider(NamedContextFactory clientFactory, String name, Class<T> type) {
ClientFactoryObjectProvider(NamedContextFactory clientFactory, String name,
Class<T> type) {
this.clientFactory = clientFactory;
this.name = name;
this.type = type;
@@ -109,8 +114,9 @@ class ClientFactoryObjectProvider<T> implements ObjectProvider<T> {
@SuppressWarnings("unchecked")
private ObjectProvider<T> delegate() {
if (this.provider == null) {
provider = this.clientFactory.getProvider(name, type);
this.provider = this.clientFactory.getProvider(this.name, this.type);
}
return provider;
return this.provider;
}
}

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2012-2019 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.context.named;
import java.util.Collection;
@@ -25,18 +41,17 @@ import org.springframework.core.env.MapPropertySource;
*
* Ported from spring-cloud-netflix FeignClientFactory and SpringClientFactory
*
* @param <C> specification
* @author Spencer Gibb
* @author Dave Syer
*/
//TODO: add javadoc
// TODO: add javadoc
public abstract class NamedContextFactory<C extends NamedContextFactory.Specification>
implements DisposableBean, ApplicationContextAware {
public interface Specification {
String getName();
private final String propertySourceName;
Class<?>[] getConfiguration();
}
private final String propertyName;
private Map<String, AnnotationConfigApplicationContext> contexts = new ConcurrentHashMap<>();
@@ -45,8 +60,6 @@ public abstract class NamedContextFactory<C extends NamedContextFactory.Specific
private ApplicationContext parent;
private Class<?> defaultConfigType;
private final String propertySourceName;
private final String propertyName;
public NamedContextFactory(Class<?> defaultConfigType, String propertySourceName,
String propertyName) {
@@ -67,7 +80,7 @@ public abstract class NamedContextFactory<C extends NamedContextFactory.Specific
}
public Set<String> getContextNames() {
return new HashSet<>(contexts.keySet());
return new HashSet<>(this.contexts.keySet());
}
@Override
@@ -111,7 +124,7 @@ public abstract class NamedContextFactory<C extends NamedContextFactory.Specific
this.defaultConfigType);
context.getEnvironment().getPropertySources().addFirst(new MapPropertySource(
this.propertySourceName,
Collections.<String, Object> singletonMap(this.propertyName, name)));
Collections.<String, Object>singletonMap(this.propertyName, name)));
if (this.parent != null) {
// Uses Environment from parent as well as beans
context.setParent(this.parent);
@@ -124,7 +137,7 @@ public abstract class NamedContextFactory<C extends NamedContextFactory.Specific
protected String generateDisplayName(String name) {
return this.getClass().getSimpleName() + "-" + name;
}
public <T> T getInstance(String name, Class<T> type) {
AnnotationConfigApplicationContext context = getContext(name);
if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context,
@@ -172,4 +185,15 @@ public abstract class NamedContextFactory<C extends NamedContextFactory.Specific
return null;
}
/**
* Specification with name and configuration.
*/
public interface Specification {
String getName();
Class<?>[] getConfiguration();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2012-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.context.properties;
import java.util.HashMap;
@@ -38,8 +39,8 @@ import org.springframework.stereotype.Component;
*
*/
@Component
public class ConfigurationPropertiesBeans implements BeanPostProcessor,
ApplicationContextAware {
public class ConfigurationPropertiesBeans
implements BeanPostProcessor, ApplicationContextAware {
private ConfigurationBeanFactoryMetadata metaData;
@@ -56,12 +57,13 @@ ApplicationContextAware {
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
if (applicationContext.getAutowireCapableBeanFactory() instanceof ConfigurableListableBeanFactory) {
if (applicationContext
.getAutowireCapableBeanFactory() instanceof ConfigurableListableBeanFactory) {
this.beanFactory = (ConfigurableListableBeanFactory) applicationContext
.getAutowireCapableBeanFactory();
}
if (applicationContext.getParent() != null
&& applicationContext.getParent().getAutowireCapableBeanFactory() instanceof ConfigurableListableBeanFactory) {
if (applicationContext.getParent() != null && applicationContext.getParent()
.getAutowireCapableBeanFactory() instanceof ConfigurableListableBeanFactory) {
ConfigurableListableBeanFactory listable = (ConfigurableListableBeanFactory) applicationContext
.getParent().getAutowireCapableBeanFactory();
String[] names = listable
@@ -86,8 +88,8 @@ ApplicationContextAware {
if (isRefreshScoped(beanName)) {
return bean;
}
ConfigurationProperties annotation = AnnotationUtils.findAnnotation(
bean.getClass(), ConfigurationProperties.class);
ConfigurationProperties annotation = AnnotationUtils
.findAnnotation(bean.getClass(), ConfigurationProperties.class);
if (annotation != null) {
this.beans.put(beanName, bean);
}
@@ -105,7 +107,8 @@ ApplicationContextAware {
if (this.refreshScope == null && !this.refreshScopeInitialized) {
this.refreshScopeInitialized = true;
for (String scope : this.beanFactory.getRegisteredScopeNames()) {
if (this.beanFactory.getRegisteredScope(scope) instanceof org.springframework.cloud.context.scope.refresh.RefreshScope) {
if (this.beanFactory.getRegisteredScope(
scope) instanceof org.springframework.cloud.context.scope.refresh.RefreshScope) {
this.refreshScope = scope;
break;
}
@@ -114,9 +117,8 @@ ApplicationContextAware {
if (beanName == null || this.refreshScope == null) {
return false;
}
return this.beanFactory.containsBeanDefinition(beanName)
&& this.refreshScope.equals(this.beanFactory.getBeanDefinition(beanName)
.getScope());
return this.beanFactory.containsBeanDefinition(beanName) && this.refreshScope
.equals(this.beanFactory.getBeanDefinition(beanName).getScope());
}
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2012-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.context.properties;
import java.util.HashSet;
@@ -25,6 +26,7 @@ import org.springframework.beans.BeansException;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.cloud.util.ProxyUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
@@ -33,17 +35,15 @@ 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;
import org.springframework.cloud.util.ProxyUtils;
/**
* Listens for {@link EnvironmentChangeEvent} and rebinds beans that were bound to the
* {@link Environment} using {@link ConfigurationProperties
* <code>@ConfigurationProperties</code>}. When these beans are re-bound and
* re-initialized, the changes are available immediately to any component that is using the
* <code>@ConfigurationProperties</code> bean.
* re-initialized, the changes are available immediately to any component that is using
* the <code>@ConfigurationProperties</code> bean.
*
* @see RefreshScope for a deeper and optionally more focused refresh of bean components.
*
* @author Dave Syer
*
*/
@@ -70,7 +70,6 @@ public class ConfigurationPropertiesRebinder
/**
* A map of bean name to errors when instantiating the bean.
*
* @return The errors accumulated since the latest destroy.
*/
public Map<String, Exception> getErrors() {
@@ -97,9 +96,10 @@ public class ConfigurationPropertiesRebinder
bean = ProxyUtils.getTargetObject(bean);
}
if (bean != null) {
this.applicationContext.getAutowireCapableBeanFactory().destroyBean(bean);
this.applicationContext.getAutowireCapableBeanFactory()
.initializeBean(bean, name);
this.applicationContext.getAutowireCapableBeanFactory()
.destroyBean(bean);
this.applicationContext.getAutowireCapableBeanFactory()
.initializeBean(bean, name);
return true;
}
}
@@ -117,7 +117,7 @@ public class ConfigurationPropertiesRebinder
@ManagedAttribute
public Set<String> getBeanNames() {
return new HashSet<String>(this.beans.getBeanNames());
return new HashSet<>(this.beans.getBeanNames());
}
@Override

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2012-2019 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.context.refresh;
import java.util.ArrayList;
@@ -45,10 +61,11 @@ public class ContextRefresher {
StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME,
StandardServletEnvironment.JNDI_PROPERTY_SOURCE_NAME,
StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME,
StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME,
StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME,
"configurationProperties"));
private ConfigurableApplicationContext context;
private RefreshScope scope;
public ContextRefresher(ConfigurableApplicationContext context, RefreshScope scope) {
@@ -76,7 +93,7 @@ public class ContextRefresher {
addConfigFilesToEnvironment();
Set<String> keys = changes(before,
extract(this.context.getEnvironment().getPropertySources())).keySet();
this.context.publishEvent(new EnvironmentChangeEvent(context, keys));
this.context.publishEvent(new EnvironmentChangeEvent(this.context, keys));
return keys;
}

View File

@@ -119,33 +119,6 @@ public class RestartEndpoint implements ApplicationListener<ApplicationPreparedE
return new ResumeEndpoint();
}
@Endpoint(id = "pause")
public class PauseEndpoint {
@WriteOperation
public Boolean pause() {
if (isRunning()) {
doPause();
return true;
}
return false;
}
}
@Endpoint(id = "resume")
@ConfigurationProperties("management.endpoint.resume")
public class ResumeEndpoint {
@WriteOperation
public Boolean resume() {
if (!isRunning()) {
doResume();
return true;
}
return false;
}
}
// @ManagedOperation
public synchronized ConfigurableApplicationContext doRestart() {
if (this.context != null) {
@@ -202,17 +175,53 @@ public class RestartEndpoint implements ApplicationListener<ApplicationPreparedE
this.application.getClass().getClassLoader());
}
/**
* Pause endpoint configuration.
*/
@Endpoint(id = "pause")
public class PauseEndpoint {
@WriteOperation
public Boolean pause() {
if (isRunning()) {
doPause();
return true;
}
return false;
}
}
/**
* Resume endpoint configuration.
*/
@Endpoint(id = "resume")
@ConfigurationProperties("management.endpoint.resume")
public class ResumeEndpoint {
@WriteOperation
public Boolean resume() {
if (!isRunning()) {
doResume();
return true;
}
return false;
}
}
private class IntegrationShutdown {
private IntegrationMBeanExporter exporter;
public IntegrationShutdown(Object exporter) {
IntegrationShutdown(Object exporter) {
this.exporter = (IntegrationMBeanExporter) exporter;
}
public void stop(long timeout) {
this.exporter.stopActiveComponents(timeout);
}
}
}

View File

@@ -24,8 +24,8 @@ 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.
* A listener that stores enough information about an application, as it starts, to be
* able to restart it later if needed.
*
* @author Dave Syer
*

View File

@@ -1,14 +1,17 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2012-2019 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
* 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
* 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.
* 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.context.scope;
@@ -64,17 +67,19 @@ import org.springframework.util.StringUtils;
* </p>
*
* @author Dave Syer
*
* @since 3.1
*
*/
public class GenericScope implements Scope, BeanFactoryPostProcessor,
BeanDefinitionRegistryPostProcessor, DisposableBean {
private static final Log logger = LogFactory.getLog(GenericScope.class);
/**
* Prefix for the scoped target.
*/
public static final String SCOPED_TARGET_PREFIX = "scopedTarget.";
private static final Log logger = LogFactory.getLog(GenericScope.class);
private BeanLifecycleWrapperCache cache = new BeanLifecycleWrapperCache(
new StandardScopeCache());
@@ -90,28 +95,27 @@ public class GenericScope implements Scope, BeanFactoryPostProcessor,
private ConcurrentMap<String, ReadWriteLock> locks = new ConcurrentHashMap<>();
static RuntimeException wrapIfNecessary(Throwable throwable) {
if (throwable instanceof RuntimeException) {
return (RuntimeException) throwable;
}
if (throwable instanceof Error) {
throw (Error) throwable;
}
return new IllegalStateException(throwable);
}
/**
* Manual override for the serialization ID that will be used to identify the bean
* factory. The default is a unique key based on the bean names in the bean factory.
*
* @param id The ID to set.
*/
public void setId(String id) {
this.id = id;
}
/**
* The name of this scope. Default "generic".
*
* @param name The name value to set.
*/
public void setName(String name) {
this.name = name;
}
/**
* The cache implementation to use for bean instances in this scope.
*
* @param cache The cache to use.
*/
public void setScopeCache(ScopeCache cache) {
@@ -120,7 +124,6 @@ public class GenericScope implements Scope, BeanFactoryPostProcessor,
/**
* A map of bean name to errors when instantiating the bean.
*
* @return The errors accumulated since the latest destroy.
*/
public Map<String, Exception> getErrors() {
@@ -133,7 +136,7 @@ public class GenericScope implements Scope, BeanFactoryPostProcessor,
Collection<BeanLifecycleWrapper> wrappers = this.cache.clear();
for (BeanLifecycleWrapper wrapper : wrappers) {
try {
Lock lock = locks.get(wrapper.getName()).writeLock();
Lock lock = this.locks.get(wrapper.getName()).writeLock();
lock.lock();
try {
wrapper.destroy();
@@ -154,14 +157,13 @@ public class GenericScope implements Scope, BeanFactoryPostProcessor,
/**
* Destroys the named bean (i.e. flushes it from the cache by default).
*
* @param name The bean name to flush.
* @return True if the bean was already cached; false otherwise.
*/
protected boolean destroy(String name) {
BeanLifecycleWrapper wrapper = this.cache.remove(name);
if (wrapper != null) {
Lock lock = locks.get(wrapper.getName()).writeLock();
Lock lock = this.locks.get(wrapper.getName()).writeLock();
lock.lock();
try {
wrapper.destroy();
@@ -179,7 +181,7 @@ public class GenericScope implements Scope, BeanFactoryPostProcessor,
public Object get(String name, ObjectFactory<?> objectFactory) {
BeanLifecycleWrapper value = this.cache.put(name,
new BeanLifecycleWrapper(name, objectFactory));
locks.putIfAbsent(name, new ReentrantReadWriteLock());
this.locks.putIfAbsent(name, new ReentrantReadWriteLock());
try {
return value.getBean();
}
@@ -274,7 +276,6 @@ public class GenericScope implements Scope, BeanFactoryPostProcessor,
* IDs of the bean factories match. This method sets up the serialization ID to be
* either the ID provided to the scope instance, or if that is null, a hash of all the
* bean names.
*
* @param beanFactory The bean factory to configure.
*/
private void setSerializationId(ConfigurableListableBeanFactory beanFactory) {
@@ -303,29 +304,27 @@ public class GenericScope implements Scope, BeanFactoryPostProcessor,
}
static RuntimeException wrapIfNecessary(Throwable throwable) {
if (throwable instanceof RuntimeException) {
return (RuntimeException) throwable;
}
if (throwable instanceof Error) {
throw (Error) throwable;
}
return new IllegalStateException(throwable);
}
protected String getName() {
return this.name;
}
/**
* The name of this scope. Default "generic".
* @param name The name value to set.
*/
public void setName(String name) {
this.name = name;
}
protected ReadWriteLock getLock(String beanName) {
return locks.get(beanName);
return this.locks.get(beanName);
}
private static class BeanLifecycleWrapperCache {
private final ScopeCache cache;
public BeanLifecycleWrapperCache(ScopeCache cache) {
BeanLifecycleWrapperCache(ScopeCache cache) {
this.cache = cache;
}
@@ -362,15 +361,15 @@ public class GenericScope implements Scope, BeanFactoryPostProcessor,
*/
private static class BeanLifecycleWrapper {
private Object bean;
private Runnable callback;
private final String name;
private final ObjectFactory<?> objectFactory;
public BeanLifecycleWrapper(String name, ObjectFactory<?> objectFactory) {
private Object bean;
private Runnable callback;
BeanLifecycleWrapper(String name, ObjectFactory<?> objectFactory) {
this.name = name;
this.objectFactory = objectFactory;
}
@@ -441,11 +440,17 @@ public class GenericScope implements Scope, BeanFactoryPostProcessor,
}
/**
* A factory bean with a locked scope.
*
* @param <S> - a generic scope extension
*/
@SuppressWarnings("serial")
public static class LockedScopedProxyFactoryBean<S extends GenericScope>
extends ScopedProxyFactoryBean implements MethodInterceptor {
private final S scope;
private String targetBeanName;
public LockedScopedProxyFactoryBean(S scope) {
@@ -477,7 +482,7 @@ public class GenericScope implements Scope, BeanFactoryPostProcessor,
return invocation.proceed();
}
Object proxy = getObject();
ReadWriteLock readWriteLock = scope.getLock(this.targetBeanName);
ReadWriteLock readWriteLock = this.scope.getLock(this.targetBeanName);
if (readWriteLock == null) {
if (logger.isDebugEnabled()) {
logger.debug("For bean with name [" + this.targetBeanName
@@ -497,7 +502,8 @@ public class GenericScope implements Scope, BeanFactoryPostProcessor,
}
return invocation.proceed();
}
// see gh-349. Throw the original exception rather than the UndeclaredThrowableException
// see gh-349. Throw the original exception rather than the
// UndeclaredThrowableException
catch (UndeclaredThrowableException e) {
throw e.getUndeclaredThrowable();
}
@@ -511,6 +517,7 @@ public class GenericScope implements Scope, BeanFactoryPostProcessor,
&& method.getName().equals("getTargetObject")
&& method.getParameterTypes().length == 0;
}
}
}

View File

@@ -19,19 +19,19 @@ package org.springframework.cloud.context.scope;
import java.util.Collection;
/**
* A special-purpose cache interface specifically for the {@link GenericScope} to use to manage cached bean instances.
* Implementations generally fall into two categories: those that store values "globally" (i.e. one instance per key),
* and those that store potentially multiple instances per key based on context (e.g. via a thread local). All
* A special-purpose cache interface specifically for the {@link GenericScope} to use to
* manage cached bean instances. Implementations generally fall into two categories: those
* that store values "globally" (i.e. one instance per key), and those that store
* potentially multiple instances per key based on context (e.g. via a thread local). All
* implementations should be thread safe.
*
*
* @author Dave Syer
*
*
*/
public interface ScopeCache {
/**
* Removes the object with this name from the cache.
*
* @param name The object name.
* @return The object removed, or null if there was none.
*/
@@ -39,23 +39,20 @@ public interface ScopeCache {
/**
* Clears the cache and returns all objects in an unmodifiable collection.
*
* @return All objects stored in the cache.
*/
Collection<Object> clear();
/**
* Gets the named object from the cache.
*
* @param name The name of the object.
* @return The object with that name, or null if there is none.
*/
Object get(String name);
/**
* Put a value in the cache if the key is not already used. If one is already present with the name provided, it is
* not replaced, but is returned to the caller.
*
* Put a value in the cache if the key is not already used. If one is already present
* with the name provided, it is not replaced, but is returned to the caller.
* @param name The key.
* @param value The new candidate value.
* @return The value that is in the cache at the end of the operation.

View File

@@ -23,31 +23,31 @@ import java.util.concurrent.ConcurrentMap;
/**
* A simple cache implementation backed by a concurrent map.
*
*
* @author Dave Syer
*
*/
public class StandardScopeCache implements ScopeCache {
private final ConcurrentMap<String, Object> cache = new ConcurrentHashMap<String, Object>();
public Object remove(String name) {
return cache.remove(name);
return this.cache.remove(name);
}
public Collection<Object> clear() {
Collection<Object> values = new ArrayList<Object>(cache.values());
cache.clear();
Collection<Object> values = new ArrayList<Object>(this.cache.values());
this.cache.clear();
return values;
}
public Object get(String name) {
return cache.get(name);
return this.cache.get(name);
}
public Object put(String name, Object value) {
Object result = cache.putIfAbsent(name, value);
if (result!=null) {
Object result = this.cache.putIfAbsent(name, value);
if (result != null) {
return result;
}
return value;

View File

@@ -1,14 +1,17 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2012-2019 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
* 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
* 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.
* 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.context.scope.refresh;
@@ -64,17 +67,19 @@ import org.springframework.jmx.export.annotation.ManagedResource;
* </p>
*
* @author Dave Syer
*
* @since 3.1
*
*/
@ManagedResource
public class RefreshScope extends GenericScope
implements ApplicationContextAware, ApplicationListener<ContextRefreshedEvent>, Ordered {
public class RefreshScope extends GenericScope implements ApplicationContextAware,
ApplicationListener<ContextRefreshedEvent>, Ordered {
private ApplicationContext context;
private BeanDefinitionRegistry registry;
private boolean eager = true;
private int order = Ordered.LOWEST_PRECEDENCE - 100;
/**
@@ -96,7 +101,6 @@ public class RefreshScope extends GenericScope
/**
* Flag to determine whether all beans in refresh scope should be instantiated eagerly
* on startup. Default true.
*
* @param eager The flag to set.
*/
public void setEager(boolean eager) {
@@ -135,7 +139,8 @@ public class RefreshScope extends GenericScope
}
}
@ManagedOperation(description = "Dispose of the current instance of bean name provided and force a refresh on next method execution.")
@ManagedOperation(description = "Dispose of the current instance of bean name "
+ "provided and force a refresh on next method execution.")
public boolean refresh(String name) {
if (!name.startsWith(SCOPED_TARGET_PREFIX)) {
// User wants to refresh the bean with this name but that isn't the one in the
@@ -150,7 +155,8 @@ public class RefreshScope extends GenericScope
return false;
}
@ManagedOperation(description = "Dispose of the current instance of all beans in this scope and force a refresh on next method execution.")
@ManagedOperation(description = "Dispose of the current instance of all beans "
+ "in this scope and force a refresh on next method execution.")
public void refreshAll() {
super.destroy();
this.context.publishEvent(new RefreshScopeRefreshedEvent());

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2012-2019 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.context.scope.refresh;
import org.springframework.context.ApplicationEvent;
@@ -7,7 +23,12 @@ import org.springframework.context.ApplicationEvent;
*/
@SuppressWarnings("serial")
public class RefreshScopeRefreshedEvent extends ApplicationEvent {
/**
* Default name for the refresh scope refreshed event.
*/
public static final String DEFAULT_NAME = "__refreshAll__";
private String name;
public RefreshScopeRefreshedEvent() {
@@ -20,6 +41,7 @@ public class RefreshScopeRefreshedEvent extends ApplicationEvent {
}
public String getName() {
return name;
return this.name;
}
}

View File

@@ -25,7 +25,7 @@ import org.springframework.cloud.context.scope.ScopeCache;
/**
* @author Dave Syer
*
*
*/
public class ThreadLocalScopeCache implements ScopeCache {
@@ -36,23 +36,23 @@ public class ThreadLocalScopeCache implements ScopeCache {
};
public Object remove(String name) {
return data.get().remove(name);
return this.data.get().remove(name);
}
public Collection<Object> clear() {
ConcurrentMap<String, Object> map = data.get();
ConcurrentMap<String, Object> map = this.data.get();
Collection<Object> values = new ArrayList<Object>(map.values());
map.clear();
return values;
}
public Object get(String name) {
return data.get().get(name);
return this.data.get().get(name);
}
public Object put(String name, Object value) {
Object result = data.get().putIfAbsent(name, value);
if (result!=null) {
Object result = this.data.get().putIfAbsent(name, value);
if (result != null) {
return result;
}
return value;

View File

@@ -1,14 +1,17 @@
/*
* Copyright 2002-2009 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.
* Copyright 2012-2019 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.context.scope.thread;
@@ -16,11 +19,9 @@ package org.springframework.cloud.context.scope.thread;
import org.springframework.cloud.context.scope.GenericScope;
/**
*
* @author Dave Syer
*
* @since 3.1
*
*
*/
public class ThreadScope extends GenericScope {

View File

@@ -38,7 +38,7 @@ public class RefreshEndpoint {
@WriteOperation
public Collection<String> refresh() {
Set<String> keys = contextRefresher.refresh();
Set<String> keys = this.contextRefresher.refresh();
return keys;
}

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2012-2019 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.endpoint.event;
import org.springframework.cloud.endpoint.RefreshEndpoint;
@@ -5,12 +21,14 @@ import org.springframework.context.ApplicationEvent;
/**
* Event that triggers a call to {@link RefreshEndpoint#refresh()}.
*
* @author Spencer Gibb
*/
@SuppressWarnings("serial")
public class RefreshEvent extends ApplicationEvent {
private Object event;
private String eventDesc;
public RefreshEvent(Object source, Object event, String eventDesc) {
@@ -26,4 +44,5 @@ public class RefreshEvent extends ApplicationEvent {
public String getEventDesc() {
return this.eventDesc;
}
}

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2012-2019 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.endpoint.event;
import java.util.Set;
@@ -13,12 +29,17 @@ import org.springframework.context.event.SmartApplicationListener;
/**
* Calls {@link RefreshEventListener#refresh} when a {@link RefreshEvent} is received.
* Only responds to {@link RefreshEvent} after receiving an {@link ApplicationReadyEvent}, as the RefreshEvents might come too early in the application lifecycle.
* Only responds to {@link RefreshEvent} after receiving an {@link ApplicationReadyEvent},
* as the RefreshEvents might come too early in the application lifecycle.
*
* @author Spencer Gibb
*/
public class RefreshEventListener implements SmartApplicationListener {
private static Log log = LogFactory.getLog(RefreshEventListener.class);
private ContextRefresher refresh;
private AtomicBoolean ready = new AtomicBoolean(false);
public RefreshEventListener(ContextRefresher refresh) {
@@ -35,7 +56,8 @@ public class RefreshEventListener implements SmartApplicationListener {
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ApplicationReadyEvent) {
handle((ApplicationReadyEvent) event);
} else if (event instanceof RefreshEvent) {
}
else if (event instanceof RefreshEvent) {
handle((RefreshEvent) event);
}
}
@@ -51,4 +73,5 @@ public class RefreshEventListener implements SmartApplicationListener {
log.info("Refresh keys changed: " + keys);
}
}
}

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2012-2019 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.env;
import java.util.Collections;
@@ -10,11 +26,17 @@ import org.springframework.core.env.Environment;
/**
* @author Spencer Gibb
*/
public class EnvironmentUtils {
public final class EnvironmentUtils {
private EnvironmentUtils() {
throw new IllegalStateException("Can't instantiate a utility class");
}
public static Map<String, String> getSubProperties(Environment environment,
String keyPrefix) {
return Binder.get(environment)
.bind(keyPrefix, Bindable.mapOf(String.class, String.class))
.orElseGet(Collections::emptyMap);
}
}

View File

@@ -35,10 +35,11 @@ import org.springframework.cloud.context.scope.refresh.RefreshScope;
public class RefreshScopeHealthIndicator extends AbstractHealthIndicator {
private ObjectProvider<RefreshScope> scope;
private ConfigurationPropertiesRebinder rebinder;
public RefreshScopeHealthIndicator(ObjectProvider<RefreshScope> scope,
ConfigurationPropertiesRebinder rebinder) {
ConfigurationPropertiesRebinder rebinder) {
this.scope = scope;
this.rebinder = rebinder;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2012-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.logging;
import java.util.Collections;
@@ -64,7 +65,8 @@ public class LoggingRebinder
protected void setLogLevels(LoggingSystem system, Environment environment) {
Map<String, String> levels = Binder.get(environment)
.bind("logging.level", STRING_STRING_MAP).orElseGet(Collections::emptyMap);
.bind("logging.level", STRING_STRING_MAP)
.orElseGet(Collections::emptyMap);
for (Entry<String, String> entry : levels.entrySet()) {
setLogLevel(system, environment, entry.getKey(), entry.getValue().toString());
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2018 the original author or authors.
* Copyright 2013-2019 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.
@@ -22,7 +22,11 @@ import org.springframework.aop.support.AopUtils;
/**
* @author Ryan Baxter
*/
public class ProxyUtils {
public final class ProxyUtils {
private ProxyUtils() {
throw new IllegalStateException("Can't instantiate a utility class");
}
@SuppressWarnings("unchecked")
public static <T> T getTargetObject(Object candidate) {
@@ -36,4 +40,5 @@ public class ProxyUtils {
}
return (T) candidate;
}
}

View File

@@ -1,45 +1,47 @@
{"properties": [
{
"name": "management.health.refresh.enabled",
"type": "java.lang.Boolean",
"description": "Enable the health endpoint for the refresh scope.",
"defaultValue": true
},
{
"name": "management.endpoint.env.post.enabled",
"type": "java.lang.Boolean",
"description": "Enable changing the Environment through a POST to /env.",
"defaultValue": true
},
{
"name": "management.endpoint.refresh.enabled",
"type": "java.lang.Boolean",
"description": "Enable the /refresh endpoint to refresh configuration and re-initialize refresh scoped beans.",
"defaultValue": true
},
{
"name": "management.endpoint.restart.enabled",
"type": "java.lang.Boolean",
"description": "Enable the /restart endpoint to restart the application context.",
"defaultValue": true
},
{
"name": "management.endpoint.pause.enabled",
"type": "java.lang.Boolean",
"description": "Enable the /pause endpoint (to send Lifecycle.stop()).",
"defaultValue": true
},
{
"name": "management.endpoint.resume.enabled",
"type": "java.lang.Boolean",
"description": "Enable the /resume endpoint (to send Lifecycle.start()).",
"defaultValue": true
},
{
"name": "spring.cloud.refresh.extra-refreshable",
"type": "java.util.Set<java.lang.String>",
"description": "Additional class names for beans to post process into refresh scope.",
"defaultValue": true
}
]}
{
"properties": [
{
"name": "management.health.refresh.enabled",
"type": "java.lang.Boolean",
"description": "Enable the health endpoint for the refresh scope.",
"defaultValue": true
},
{
"name": "management.endpoint.env.post.enabled",
"type": "java.lang.Boolean",
"description": "Enable changing the Environment through a POST to /env.",
"defaultValue": true
},
{
"name": "management.endpoint.refresh.enabled",
"type": "java.lang.Boolean",
"description": "Enable the /refresh endpoint to refresh configuration and re-initialize refresh scoped beans.",
"defaultValue": true
},
{
"name": "management.endpoint.restart.enabled",
"type": "java.lang.Boolean",
"description": "Enable the /restart endpoint to restart the application context.",
"defaultValue": true
},
{
"name": "management.endpoint.pause.enabled",
"type": "java.lang.Boolean",
"description": "Enable the /pause endpoint (to send Lifecycle.stop()).",
"defaultValue": true
},
{
"name": "management.endpoint.resume.enabled",
"type": "java.lang.Boolean",
"description": "Enable the /resume endpoint (to send Lifecycle.start()).",
"defaultValue": true
},
{
"name": "spring.cloud.refresh.extra-refreshable",
"type": "java.util.Set<java.lang.String>",
"description": "Additional class names for beans to post process into refresh scope.",
"defaultValue": true
}
]
}

View File

@@ -5,13 +5,11 @@ org.springframework.cloud.autoconfigure.LifecycleMvcEndpointAutoConfiguration,\
org.springframework.cloud.autoconfigure.RefreshAutoConfiguration,\
org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration,\
org.springframework.cloud.autoconfigure.WritableEnvironmentEndpointAutoConfiguration
# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.cloud.bootstrap.BootstrapApplicationListener,\
org.springframework.cloud.bootstrap.LoggingSystemShutdownListener,\
org.springframework.cloud.context.restart.RestartListener
# Bootstrap components
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration,\

View File

@@ -5,6 +5,7 @@ import java.util.function.Function;
import org.assertj.core.util.Lists;
import org.junit.Test;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.context.restart.RestartEndpoint;
@@ -21,9 +22,20 @@ import static org.junit.Assert.assertThat;
/**
* @author Spencer Gibb
*/
//TODO: super slow. Port to @SpringBootTest
// TODO: super slow. Port to @SpringBootTest
public class LifecycleMvcAutoConfigurationTests {
private static ConfigurableApplicationContext getApplicationContext(
Class<?> configuration, String... properties) {
List<String> defaultProperties = Lists.newArrayList(properties);
defaultProperties.add("server.port=0");
defaultProperties.add("spring.jmx.default-domain=${random.uuid}");
return new SpringApplicationBuilder(configuration)
.properties(defaultProperties.toArray(new String[] {})).run();
}
@Test
public void environmentWebEndpointExtensionDisabled() {
beanNotCreated("environmentWebEndpointExtension",
@@ -45,47 +57,41 @@ public class LifecycleMvcAutoConfigurationTests {
// restartEndpoint
@Test
public void restartEndpointDisabled() {
beanNotCreated("restartEndpoint",
"management.endpoint.restart.enabled=false");
beanNotCreated("restartEndpoint", "management.endpoint.restart.enabled=false");
}
@Test
public void restartEndpointGloballyDisabled() {
beanNotCreated("restartEndpoint",
"management.endpoint.default.enabled=false");
beanNotCreated("restartEndpoint", "management.endpoint.default.enabled=false");
}
@Test
public void restartEndpointEnabled() {
beanCreatedAndEndpointEnabled("restartEndpoint", RestartEndpoint.class,
RestartEndpoint::restart,
"management.endpoint.restart.enabled=true");
RestartEndpoint::restart, "management.endpoint.restart.enabled=true");
}
// pauseEndpoint
@Test
public void pauseEndpointDisabled() {
beanNotCreated("pauseEndpoint",
"management.endpoint.pause.enabled=false");
beanNotCreated("pauseEndpoint", "management.endpoint.pause.enabled=false");
}
@Test
public void pauseEndpointRestartDisabled() {
beanNotCreated("pauseEndpoint",
"management.endpoint.restart.enabled=false",
beanNotCreated("pauseEndpoint", "management.endpoint.restart.enabled=false",
"management.endpoint.pause.enabled=true");
}
@Test
public void pauseEndpointGloballyDisabled() {
beanNotCreated("pauseEndpoint",
"management.endpoint.default.enabled=false");
beanNotCreated("pauseEndpoint", "management.endpoint.default.enabled=false");
}
@Test
public void pauseEndpointEnabled() {
beanCreatedAndEndpointEnabled("pauseEndpoint", RestartEndpoint.PauseEndpoint.class,
RestartEndpoint.PauseEndpoint::pause,
beanCreatedAndEndpointEnabled("pauseEndpoint",
RestartEndpoint.PauseEndpoint.class, RestartEndpoint.PauseEndpoint::pause,
"management.endpoint.restart.enabled=true",
"management.endpoint.pause.enabled=true");
}
@@ -93,48 +99,53 @@ public class LifecycleMvcAutoConfigurationTests {
// resumeEndpoint
@Test
public void resumeEndpointDisabled() {
beanNotCreated("resumeEndpoint",
"management.endpoint.restart.enabled=true",
beanNotCreated("resumeEndpoint", "management.endpoint.restart.enabled=true",
"management.endpoint.resume.enabled=false");
}
@Test
public void resumeEndpointRestartDisabled() {
beanNotCreated("resumeEndpoint",
"management.endpoint.restart.enabled=false",
beanNotCreated("resumeEndpoint", "management.endpoint.restart.enabled=false",
"management.endpoint.resume.enabled=true");
}
@Test
public void resumeEndpointGloballyDisabled() {
beanNotCreated("resumeEndpoint",
"management.endpoint.default.enabled=false");
beanNotCreated("resumeEndpoint", "management.endpoint.default.enabled=false");
}
@Test
public void resumeEndpointEnabled() {
beanCreatedAndEndpointEnabled("resumeEndpoint", RestartEndpoint.ResumeEndpoint.class,
beanCreatedAndEndpointEnabled("resumeEndpoint",
RestartEndpoint.ResumeEndpoint.class,
RestartEndpoint.ResumeEndpoint::resume,
"management.endpoint.restart.enabled=true",
"management.endpoint.resume.enabled=true");
}
private void beanNotCreated(String beanName, String... contextProperties) {
try (ConfigurableApplicationContext context = getApplicationContext(Config.class, contextProperties)) {
assertThat("bean was created", context.containsBeanDefinition(beanName), equalTo(false));
try (ConfigurableApplicationContext context = getApplicationContext(Config.class,
contextProperties)) {
assertThat("bean was created", context.containsBeanDefinition(beanName),
equalTo(false));
}
}
private void beanCreated(String beanName, String... contextProperties) {
try (ConfigurableApplicationContext context = getApplicationContext(Config.class, contextProperties)) {
assertThat("bean was not created", context.containsBeanDefinition(beanName), equalTo(true));
try (ConfigurableApplicationContext context = getApplicationContext(Config.class,
contextProperties)) {
assertThat("bean was not created", context.containsBeanDefinition(beanName),
equalTo(true));
}
}
@SuppressWarnings("unchecked")
private <T> void beanCreatedAndEndpointEnabled(String beanName, Class<T> type, Function<T, Object> function, String... properties) {
try (ConfigurableApplicationContext context = getApplicationContext(Config.class, properties)) {
assertThat("bean was not created", context.containsBeanDefinition(beanName), equalTo(true));
private <T> void beanCreatedAndEndpointEnabled(String beanName, Class<T> type,
Function<T, Object> function, String... properties) {
try (ConfigurableApplicationContext context = getApplicationContext(Config.class,
properties)) {
assertThat("bean was not created", context.containsBeanDefinition(beanName),
equalTo(true));
Object endpoint = context.getBean(beanName, type);
Object result = function.apply((T) endpoint);
@@ -144,19 +155,10 @@ public class LifecycleMvcAutoConfigurationTests {
}
}
private static ConfigurableApplicationContext getApplicationContext(
Class<?> configuration, String... properties) {
List<String> defaultProperties = Lists.newArrayList(properties);
defaultProperties.add("server.port=0");
defaultProperties.add("spring.jmx.default-domain=${random.uuid}");
return new SpringApplicationBuilder(configuration).properties(defaultProperties.toArray(new String[]{})).run();
}
@Configuration
@EnableAutoConfiguration
static class Config {
}
}

View File

@@ -2,6 +2,7 @@ package org.springframework.cloud.autoconfigure;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
@@ -17,26 +18,31 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Spencer Gibb
*/
@RunWith(ModifiedClassPathRunner.class)
@ClassPathExclusions({"spring-boot-actuator-*.jar", "spring-boot-starter-actuator-*.jar"})
@ClassPathExclusions({ "spring-boot-actuator-*.jar",
"spring-boot-starter-actuator-*.jar" })
public class RefreshAutoConfigurationClassPathTests {
private static ConfigurableApplicationContext getApplicationContext(
Class<?> configuration, String... properties) {
return new SpringApplicationBuilder(configuration).web(WebApplicationType.NONE)
.properties(properties).run();
}
@Test
public void refreshEventListenerCreated() {
try (ConfigurableApplicationContext context = getApplicationContext(
Config.class)) {
assertThat(context.getBeansOfType(RefreshEventListener.class)).as("RefreshEventListeners not created").isNotEmpty();
assertThat(context.containsBean("refreshEndpoint")).as("refreshEndpoint created").isFalse();
assertThat(context.getBeansOfType(RefreshEventListener.class))
.as("RefreshEventListeners not created").isNotEmpty();
assertThat(context.containsBean("refreshEndpoint"))
.as("refreshEndpoint created").isFalse();
}
}
private static ConfigurableApplicationContext getApplicationContext(
Class<?> configuration, String... properties) {
return new SpringApplicationBuilder(configuration).web(WebApplicationType.NONE).properties(properties).run();
}
@Configuration
@EnableAutoConfiguration
static class Config {
}
}

View File

@@ -19,25 +19,28 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Spencer Gibb
*/
@RunWith(ModifiedClassPathRunner.class)
@ClassPathExclusions({"spring-boot-actuator-autoconfigure-*.jar", "spring-boot-starter-actuator-*.jar"})
@ClassPathExclusions({ "spring-boot-actuator-autoconfigure-*.jar",
"spring-boot-starter-actuator-*.jar" })
public class RefreshAutoConfigurationMoreClassPathTests {
@Rule
public OutputCapture outputCapture = new OutputCapture();
@Test
public void unknownClassProtected() {
try (ConfigurableApplicationContext context = getApplicationContext(
Config.class, "debug=true")) {
String output = this.outputCapture.toString();
assertThat(output).doesNotContain("Failed to introspect annotations on [class org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration")
.doesNotContain("TypeNotPresentExceptionProxy");
}
}
private static ConfigurableApplicationContext getApplicationContext(
Class<?> configuration, String... properties) {
return new SpringApplicationBuilder(configuration).web(WebApplicationType.NONE).properties(properties).run();
return new SpringApplicationBuilder(configuration).web(WebApplicationType.NONE)
.properties(properties).run();
}
@Test
public void unknownClassProtected() {
try (ConfigurableApplicationContext context = getApplicationContext(Config.class,
"debug=true")) {
String output = this.outputCapture.toString();
assertThat(output).doesNotContain(
"Failed to introspect annotations on [class org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration")
.doesNotContain("TypeNotPresentExceptionProxy");
}
}
@Configuration
@@ -45,4 +48,5 @@ public class RefreshAutoConfigurationMoreClassPathTests {
static class Config {
}
}

View File

@@ -24,12 +24,18 @@ public class RefreshAutoConfigurationTests {
@Rule
public OutputCapture output = new OutputCapture();
private static ConfigurableApplicationContext getApplicationContext(
WebApplicationType type, Class<?> configuration, String... properties) {
return new SpringApplicationBuilder(configuration).web(type)
.properties(properties).properties("server.port=0").run();
}
@Test
public void noWarnings() {
try (ConfigurableApplicationContext context = getApplicationContext(
WebApplicationType.NONE, Config.class)) {
assertThat(context.containsBean("refreshScope")).isTrue();
assertThat(output.toString()).doesNotContain("WARN");
assertThat(this.output.toString()).doesNotContain("WARN");
}
}
@@ -63,12 +69,6 @@ public class RefreshAutoConfigurationTests {
}
}
private static ConfigurableApplicationContext getApplicationContext(
WebApplicationType type, Class<?> configuration, String... properties) {
return new SpringApplicationBuilder(configuration).web(type)
.properties(properties).properties("server.port=0").run();
}
@Configuration
@EnableAutoConfiguration(exclude = DataSourceAutoConfiguration.class)
@EnableConfigurationProperties(ConfigProps.class)
@@ -78,7 +78,9 @@ public class RefreshAutoConfigurationTests {
@ConfigurationProperties("config")
static class ConfigProps {
private String foo;
private boolean sealed;
public String getFoo() {
@@ -92,5 +94,7 @@ public class RefreshAutoConfigurationTests {
this.foo = foo;
this.sealed = true;
}
}
}

View File

@@ -2,6 +2,7 @@ package org.springframework.cloud.bootstrap;
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;
@@ -13,16 +14,15 @@ import org.springframework.test.context.junit4.SpringRunner;
import static org.junit.Assert.assertFalse;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class,
properties = "spring.cloud.bootstrap.enabled:false")
@SpringBootTest(classes = Application.class, properties = "spring.cloud.bootstrap.enabled:false")
public class BootstrapDisabledAutoConfigurationIntegrationTests {
@Autowired
private ConfigurableEnvironment environment;
@Test
public void noBootstrapProperties() {
assertFalse(environment.getPropertySources().contains("bootstrap"));
assertFalse(this.environment.getPropertySources().contains("bootstrap"));
}
@EnableAutoConfiguration

View File

@@ -3,6 +3,7 @@ package org.springframework.cloud.bootstrap;
import org.junit.Ignore;
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;
@@ -25,7 +26,7 @@ public class BootstrapOrderingAutoConfigurationIntegrationTests {
private ConfigurableEnvironment environment;
@Test
@Ignore //FIXME: spring boot 2.0.0
@Ignore // FIXME: spring boot 2.0.0
public void bootstrapPropertiesExist() {
assertTrue(this.environment.getPropertySources().contains(
PropertySourceBootstrapConfiguration.BOOTSTRAP_PROPERTY_SOURCE_NAME));

View File

@@ -7,6 +7,7 @@ import java.util.Map;
import org.junit.Ignore;
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;
@@ -25,8 +26,8 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class,
properties = { "encrypt.key:deadbeef", "spring.cloud.bootstrap.name:custom" })
@SpringBootTest(classes = Application.class, properties = { "encrypt.key:deadbeef",
"spring.cloud.bootstrap.name:custom" })
@ActiveProfiles("encrypt")
public class BootstrapOrderingCustomPropertySourceIntegrationTests {
@@ -34,7 +35,7 @@ public class BootstrapOrderingCustomPropertySourceIntegrationTests {
private ConfigurableEnvironment environment;
@Test
@Ignore //FIXME: spring boot 2.0.0
@Ignore // FIXME: spring boot 2.0.0
public void bootstrapPropertiesExist() {
assertTrue(this.environment.getPropertySources().contains(
PropertySourceBootstrapConfiguration.BOOTSTRAP_PROPERTY_SOURCE_NAME));
@@ -56,7 +57,7 @@ public class BootstrapOrderingCustomPropertySourceIntegrationTests {
protected static class PropertySourceConfiguration implements PropertySourceLocator {
public static Map<String, Object> MAP = new HashMap<String, Object>(
Collections.<String, Object> singletonMap("custom.foo",
Collections.<String, Object>singletonMap("custom.foo",
"{cipher}6154ca04d4bb6144d672c4e3d750b5147116dd381946d51fa44f8bc25dc256f4"));
@Override

View File

@@ -4,6 +4,7 @@ import org.junit.AfterClass;
import org.junit.BeforeClass;
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;
@@ -16,10 +17,12 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class,
properties = "spring.cloud.bootstrap.name:json")
@SpringBootTest(classes = Application.class, properties = "spring.cloud.bootstrap.name:json")
public class BootstrapOrderingSpringApplicationJsonIntegrationTests {
@Autowired
private ConfigurableEnvironment environment;
@BeforeClass
public static void spikeJson() {
System.setProperty("SPRING_APPLICATION_JSON", "{\"message\":\"From JSON\"}");
@@ -30,9 +33,6 @@ public class BootstrapOrderingSpringApplicationJsonIntegrationTests {
System.clearProperty("SPRING_APPLICATION_JSON");
}
@Autowired
private ConfigurableEnvironment environment;
@Test
public void bootstrapPropertiesExist() {
assertTrue(this.environment.getPropertySources()
@@ -43,6 +43,7 @@ public class BootstrapOrderingSpringApplicationJsonIntegrationTests {
@EnableAutoConfiguration
@Configuration
protected static class Application {
}
}

View File

@@ -26,6 +26,7 @@ public class BootstrapSourcesOrderingTests {
@EnableAutoConfiguration
@Configuration
protected static class Application {
}
}

View File

@@ -26,6 +26,7 @@ import java.util.Locale;
import org.junit.Assert;
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;
@@ -35,8 +36,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestApplication.class,
properties = "debug=true")
@SpringBootTest(classes = TestApplication.class, properties = "debug=true")
public class MessageSourceConfigurationTests {
@Autowired
@@ -44,7 +44,8 @@ public class MessageSourceConfigurationTests {
@Test
public void loadsMessage() {
Assert.assertEquals("Hello World!", this.messageSource.getMessage("hello.message", null, Locale.getDefault()));
Assert.assertEquals("Hello World!", this.messageSource.getMessage("hello.message",
null, Locale.getDefault()));
}
@Configuration

View File

@@ -24,15 +24,16 @@ import static org.springframework.cloud.bootstrap.TestHigherPriorityBootstrapCon
@EnableConfigurationProperties
public class TestBootstrapConfiguration {
public static List<String> fooSightings = null;
public TestBootstrapConfiguration() {
firstToBeCreated.compareAndSet(null, TestBootstrapConfiguration.class);
}
public static List<String> fooSightings = null;
@Bean
@Qualifier("foo-during-bootstrap")
public String fooDuringBootstrap(ConfigurableEnvironment environment, ApplicationEventPublisher publisher) {
public String fooDuringBootstrap(ConfigurableEnvironment environment,
ApplicationEventPublisher publisher) {
String property = environment.getProperty("test.bootstrap.foo", "undefined");
if (fooSightings != null) {

View File

@@ -12,13 +12,13 @@ import org.springframework.core.annotation.Order;
@Order(Ordered.HIGHEST_PRECEDENCE)
public class TestHigherPriorityBootstrapConfiguration {
static final AtomicReference<Class<?>> firstToBeCreated = new AtomicReference<>();
public static final AtomicInteger count = new AtomicInteger();
static final AtomicReference<Class<?>> firstToBeCreated = new AtomicReference<>();
public TestHigherPriorityBootstrapConfiguration() {
count.incrementAndGet();
firstToBeCreated.compareAndSet(null, TestHigherPriorityBootstrapConfiguration.class);
firstToBeCreated.compareAndSet(null,
TestHigherPriorityBootstrapConfiguration.class);
}
}

View File

@@ -53,13 +53,13 @@ import static org.junit.Assert.assertTrue;
*/
public class BootstrapConfigurationTests {
@Rule
public ExpectedException expected = ExpectedException.none();
private ConfigurableApplicationContext context;
private ConfigurableApplicationContext sibling;
@Rule
public ExpectedException expected = ExpectedException.none();
@After
public void close() {
// Expected.* is bound to the PropertySourceConfiguration below
@@ -111,7 +111,6 @@ public class BootstrapConfigurationTests {
/**
* Running the test from maven will start from a different directory then starting it
* from intellij
*
* @return
*/
private String getExternalProperties() {
@@ -275,10 +274,10 @@ public class BootstrapConfigurationTests {
this.context = new SpringApplicationBuilder().sources(BareConfiguration.class)
.child(BareConfiguration.class).web(WebApplicationType.NONE).run();
assertEquals(1, TestHigherPriorityBootstrapConfiguration.count.get());
assertNotNull(context.getParent());
assertEquals("bootstrap", context.getParent().getParent().getId());
assertNull(context.getParent().getParent().getParent());
assertEquals("bar", context.getEnvironment().getProperty("custom.foo"));
assertNotNull(this.context.getParent());
assertEquals("bootstrap", this.context.getParent().getParent().getId());
assertNull(this.context.getParent().getParent().getParent());
assertEquals("bar", this.context.getEnvironment().getProperty("custom.foo"));
}
@Test
@@ -294,18 +293,18 @@ public class BootstrapConfigurationTests {
.properties("spring.application.name=context")
.web(WebApplicationType.NONE).run();
assertEquals(1, TestHigherPriorityBootstrapConfiguration.count.get());
assertNotNull(context.getParent());
assertEquals("bootstrap", context.getParent().getParent().getId());
assertNull(context.getParent().getParent().getParent());
assertEquals("context", context.getEnvironment().getProperty("custom.foo"));
assertNotNull(this.context.getParent());
assertEquals("bootstrap", this.context.getParent().getParent().getId());
assertNull(this.context.getParent().getParent().getParent());
assertEquals("context", this.context.getEnvironment().getProperty("custom.foo"));
assertEquals("context",
context.getEnvironment().getProperty("spring.application.name"));
assertNotNull(sibling.getParent());
assertEquals("bootstrap", sibling.getParent().getParent().getId());
assertNull(sibling.getParent().getParent().getParent());
assertEquals("sibling", sibling.getEnvironment().getProperty("custom.foo"));
this.context.getEnvironment().getProperty("spring.application.name"));
assertNotNull(this.sibling.getParent());
assertEquals("bootstrap", this.sibling.getParent().getParent().getId());
assertNull(this.sibling.getParent().getParent().getParent());
assertEquals("sibling", this.sibling.getEnvironment().getProperty("custom.foo"));
assertEquals("sibling",
sibling.getEnvironment().getProperty("spring.application.name"));
this.sibling.getEnvironment().getProperty("spring.application.name"));
}
@Test
@@ -375,6 +374,7 @@ public class BootstrapConfigurationTests {
@Configuration
@EnableConfigurationProperties
protected static class BareConfiguration {
}
@Configuration
@@ -416,6 +416,7 @@ public class BootstrapConfigurationTests {
public void setFail(boolean fail) {
this.fail = fail;
}
}
}

View File

@@ -16,21 +16,22 @@
package org.springframework.cloud.bootstrap.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.springframework.boot.WebApplicationType.NONE;
import org.junit.Test;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.springframework.boot.WebApplicationType.NONE;
/**
* Integration tests for Bootstrap Listener's functionality of adding a bootstrap context
* as the root Application Context
*
*
* @author Biju Kunjummen
*/
public class BootstrapListenerHierarchyIntegrationTests {
@@ -88,6 +89,7 @@ public class BootstrapListenerHierarchyIntegrationTests {
@Configuration
static class BasicConfiguration {
}
@Configuration
@@ -97,5 +99,7 @@ public class BootstrapListenerHierarchyIntegrationTests {
public String rootBean() {
return "rootBean";
}
}
}
}

View File

@@ -1,7 +1,7 @@
package org.springframework.cloud.bootstrap.encrypt;
/*
* Copyright 2013-2018 the original author or authors.
* Copyright 2013-2019 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.
@@ -70,17 +70,17 @@ public class EncryptionBootstrapConfigurationTests {
context.close();
}
@Test
public void rsaProperties() {
ConfigurableApplicationContext context = new SpringApplicationBuilder(
EncryptionBootstrapConfiguration.class).web(WebApplicationType.NONE).properties(
"encrypt.key-store.location:classpath:/server.jks",
"encrypt.key-store.password:letmein",
"encrypt.key-store.alias:mytestkey", "encrypt.key-store.secret:changeme",
"encrypt.rsa.strong:true",
"encrypt.rsa.salt:foobar")
.run();
EncryptionBootstrapConfiguration.class)
.web(WebApplicationType.NONE)
.properties("encrypt.key-store.location:classpath:/server.jks",
"encrypt.key-store.password:letmein",
"encrypt.key-store.alias:mytestkey",
"encrypt.key-store.secret:changeme",
"encrypt.rsa.strong:true", "encrypt.rsa.salt:foobar")
.run();
RsaProperties properties = context.getBean(RsaProperties.class);
assertEquals("foobar", properties.getSalt());
assertTrue(properties.isStrong());
@@ -88,7 +88,6 @@ public class EncryptionBootstrapConfigurationTests {
context.close();
}
@Test
public void nonExistentKeystoreLocationShouldNotBeAllowed() {
try {
@@ -107,4 +106,5 @@ public class EncryptionBootstrapConfigurationTests {
assertThat(e).hasRootCauseInstanceOf(IllegalStateException.class);
}
}
}

View File

@@ -1,6 +1,7 @@
package org.springframework.cloud.bootstrap.encrypt;
import org.junit.Test;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -40,14 +41,17 @@ public class EncryptionIntegrationTests {
@ConfigurationProperties("foo")
protected static class PasswordProperties {
private String password;
public String getPassword() {
return password;
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
}
}

View File

@@ -15,14 +15,15 @@
*/
package org.springframework.cloud.bootstrap.encrypt;
import java.nio.charset.Charset;
import org.junit.Test;
import org.springframework.cloud.context.encrypt.EncryptorFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.crypto.encrypt.TextEncryptor;
import org.springframework.util.StreamUtils;
import java.nio.charset.Charset;
import static org.junit.Assert.assertEquals;
/**
@@ -49,4 +50,5 @@ public class EncryptorFactoryTests {
+ "MIIEowIBAAKCAQEAwClFgrRa/PUHPIJr9gvIPL6g6Rjp/TVZmVNOf2fL96DYbkj5\n";
new EncryptorFactory().create(key);
}
}
}

View File

@@ -212,4 +212,5 @@ public class EnvironmentDecryptApplicationInitializerTests {
verify(encryptor).decrypt("bar2");
verifyNoMoreInteractions(encryptor);
}
}

View File

@@ -1,6 +1,6 @@
package org.springframework.cloud.bootstrap.encrypt;
/*
* Copyright 2013-2018 the original author or authors.
* Copyright 2013-2019 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.
@@ -35,30 +35,32 @@ import static org.hamcrest.Matchers.hasSize;
* @author Ryan Baxter
*/
@RunWith(ModifiedClassPathRunner.class)
@ClassPathExclusions({"spring-security-rsa*.jar"})
@ClassPathExclusions({ "spring-security-rsa*.jar" })
public class RsaDisabledTests {
private ConfigurableApplicationContext context;
@Before
public void setUp() {
context = new SpringApplicationBuilder().web(WebApplicationType.NONE)
.sources(EncryptionBootstrapConfiguration.class).web(WebApplicationType.NONE).properties(
"encrypt.key:mykey",
"encrypt.rsa.strong:true",
"encrypt.rsa.salt:foobar").run();
this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE)
.sources(EncryptionBootstrapConfiguration.class)
.web(WebApplicationType.NONE).properties("encrypt.key:mykey",
"encrypt.rsa.strong:true", "encrypt.rsa.salt:foobar")
.run();
}
@After
public void tearDown() {
if(context != null) {
context.close();
if (this.context != null) {
this.context.close();
}
}
@Test
public void testLoadBalancedRetryFactoryBean() throws Exception {
Map<String, RsaProperties> properties = context.getBeansOfType(RsaProperties.class);
Map<String, RsaProperties> properties = this.context
.getBeansOfType(RsaProperties.class);
assertThat(properties.values(), hasSize(0));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2006-2018 the original author or authors.
* Copyright 2006-2019 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.
@@ -72,15 +72,13 @@ public class EnvironmentManagerIntegrationTests {
@Test
public void testRefresh() throws Exception {
assertEquals("Hello scope!", properties.getMessage());
assertEquals("Hello scope!", this.properties.getMessage());
String content = property("message", "Foo");
this.mvc.perform(post(BASE_PATH + "/env")
.content(content)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
this.mvc.perform(post(BASE_PATH + "/env").content(content)
.contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk())
.andExpect(content().string("{\"message\":\"Foo\"}"));
assertEquals("Foo", properties.getMessage());
assertEquals("Foo", this.properties.getMessage());
}
private String property(String name, String value) throws JsonProcessingException {
@@ -89,23 +87,21 @@ public class EnvironmentManagerIntegrationTests {
property.put("name", name);
property.put("value", value);
return mapper.writeValueAsString(property);
return this.mapper.writeValueAsString(property);
}
@Test
public void testRefreshFails() throws Exception {
try {
this.mvc.perform(post(BASE_PATH + "/env")
.content(property("delay", "foo"))
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
this.mvc.perform(post(BASE_PATH + "/env").content(property("delay", "foo"))
.contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk())
.andExpect(status().is5xxServerError());
fail("expected ServletException");
}
catch (ServletException e) {
// The underlying BindException is not handled by the dispatcher servlet
}
assertEquals(0, properties.getDelay());
assertEquals(0, this.properties.getDelay());
}
@Test
@@ -116,15 +112,15 @@ public class EnvironmentManagerIntegrationTests {
@Test
public void environmentBeansConfiguredCorrectly() {
Map<String, EnvironmentEndpoint> envbeans = this.context.getBeansOfType(EnvironmentEndpoint.class);
assertThat(envbeans).hasSize(1)
.containsKey("environmentEndpoint");
Map<String, EnvironmentEndpoint> envbeans = this.context
.getBeansOfType(EnvironmentEndpoint.class);
assertThat(envbeans).hasSize(1).containsKey("environmentEndpoint");
assertThat(envbeans.get("environmentEndpoint"))
.isInstanceOf(WritableEnvironmentEndpoint.class);
Map<String, EnvironmentEndpointWebExtension> extbeans = this.context.getBeansOfType(EnvironmentEndpointWebExtension.class);
assertThat(extbeans).hasSize(1)
.containsKey("environmentEndpointWebExtension");
Map<String, EnvironmentEndpointWebExtension> extbeans = this.context
.getBeansOfType(EnvironmentEndpointWebExtension.class);
assertThat(extbeans).hasSize(1).containsKey("environmentEndpointWebExtension");
assertThat(extbeans.get("environmentEndpointWebExtension"))
.isInstanceOf(WritableEnvironmentEndpointWebExtension.class);
}
@@ -148,7 +144,7 @@ public class EnvironmentManagerIntegrationTests {
private int delay;
public String getMessage() {
return message;
return this.message;
}
public void setMessage(String message) {
@@ -156,12 +152,13 @@ public class EnvironmentManagerIntegrationTests {
}
public int getDelay() {
return delay;
return this.delay;
}
public void setDelay(int delay) {
this.delay = delay;
}
}
}

View File

@@ -42,4 +42,4 @@ public class EnvironmentManagerTest {
assertThat(event.getKeys()).containsExactly("foo");
}
}
}

View File

@@ -35,7 +35,8 @@ public class NamedContextFactoryTests {
Bar bar = factory.getInstance("bar", Bar.class);
assertThat("bar was null", bar, is(notNullValue()));
assertThat("context names not exposed", factory.getContextNames(), hasItems("foo", "bar"));
assertThat("context names not exposed", factory.getContextNames(),
hasItems("foo", "bar"));
Bar foobar = factory.getInstance("foo", Bar.class);
assertThat("bar was not null", foobar, is(nullValue()));
@@ -60,7 +61,7 @@ public class NamedContextFactoryTests {
}
private TestSpec getSpec(String name, Class<?> configClass) {
return new TestSpec(name, new Class[]{configClass});
return new TestSpec(name, new Class[] { configClass });
}
static class TestClientFactory extends NamedContextFactory<TestSpec> {
@@ -68,9 +69,11 @@ public class NamedContextFactoryTests {
public TestClientFactory() {
super(TestSpec.class, "testfactory", "test.client.name");
}
}
static class TestSpec implements NamedContextFactory.Specification {
private String name;
private Class<?>[] configuration;
@@ -85,7 +88,7 @@ public class NamedContextFactoryTests {
@Override
public String getName() {
return name;
return this.name;
}
public void setName(String name) {
@@ -94,31 +97,43 @@ public class NamedContextFactoryTests {
@Override
public Class<?>[] getConfiguration() {
return configuration;
return this.configuration;
}
public void setConfiguration(Class<?>[] configuration) {
this.configuration = configuration;
}
}
static class BaseConfig {
@Bean
Baz baz1() {
return new Baz();
}
}
static class Baz {
}
static class Baz{}
static class FooConfig {
@Bean
Foo foo() {
return new Foo();
}
}
static class Foo {
}
static class Foo{}
static class BarConfig {
@Bean
Bar bar() {
return new Bar();
@@ -128,7 +143,11 @@ public class NamedContextFactoryTests {
Baz baz2() {
return new Baz();
}
}
static class Bar {
}
static class Bar{}
}

View File

@@ -108,6 +108,12 @@ public class ConfigurationPropertiesRebinderIntegrationTests {
assertEquals(2, this.properties.getCount());
}
interface SomeService {
void foo();
}
@Configuration
@EnableConfigurationProperties
@Import({ RefreshConfiguration.RebinderConfiguration.class,
@@ -123,27 +129,30 @@ public class ConfigurationPropertiesRebinderIntegrationTests {
@Bean
@ConfigurationProperties("some.service")
public SomeService someService() {
return ProxyFactory.getProxy(SomeService.class, (MethodInterceptor) methodInvocation -> null);
return ProxyFactory.getProxy(SomeService.class,
(MethodInterceptor) methodInvocation -> null);
}
}
interface SomeService {
void foo();
}
// Hack out a protected inner class for testing
protected static class RefreshConfiguration extends RefreshAutoConfiguration {
@Configuration
protected static class RebinderConfiguration
extends ConfigurationPropertiesRebinderAutoConfiguration {
}
}
@ConfigurationProperties
protected static class TestProperties {
private String message;
private int delay;
private int count = 0;
public int getCount() {
@@ -170,19 +179,23 @@ public class ConfigurationPropertiesRebinderIntegrationTests {
public void init() {
this.count++;
}
}
@ConfigurationProperties("config")
@ConditionalOnMissingBean(ConfigProperties.class)
public static class ConfigProperties {
private String name;
public String getName() {
return name;
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
}

View File

@@ -80,16 +80,20 @@ public class ConfigurationPropertiesRebinderLifecycleIntegrationTests {
// Hack out a protected inner class for testing
protected static class RefreshConfiguration extends RefreshAutoConfiguration {
@Configuration
protected static class RebinderConfiguration
extends ConfigurationPropertiesRebinderAutoConfiguration {
}
}
@ConfigurationProperties
protected static class TestProperties implements DisposableBean, InitializingBean {
private String message;
private int count = 0;
public int getCount() {
@@ -114,6 +118,7 @@ public class ConfigurationPropertiesRebinderLifecycleIntegrationTests {
this.message = "";
this.count++;
}
}
}

View File

@@ -15,8 +15,6 @@
*/
package org.springframework.cloud.context.properties;
import static org.junit.Assert.assertEquals;
import java.util.List;
import java.util.Map;
@@ -25,6 +23,7 @@ import javax.annotation.PostConstruct;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -42,9 +41,10 @@ import org.springframework.core.env.PropertySource;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import static org.junit.Assert.assertEquals;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestConfiguration.class,
properties = "messages=one,two")
@SpringBootTest(classes = TestConfiguration.class, properties = "messages=one,two")
public class ConfigurationPropertiesRebinderListIntegrationTests {
@Autowired
@@ -114,16 +114,20 @@ public class ConfigurationPropertiesRebinderListIntegrationTests {
// Hack out a protected inner class for testing
protected static class RefreshConfiguration extends RefreshAutoConfiguration {
@Configuration
protected static class RebinderConfiguration
extends ConfigurationPropertiesRebinderAutoConfiguration {
}
}
@ConfigurationProperties
protected static class TestProperties {
private List<String> messages;
private int count;
public List<String> getMessages() {
@@ -142,6 +146,7 @@ public class ConfigurationPropertiesRebinderListIntegrationTests {
public void init() {
this.count++;
}
}
}

View File

@@ -15,8 +15,6 @@
*/
package org.springframework.cloud.context.properties;
import static org.junit.Assert.assertEquals;
import java.util.HashMap;
import java.util.Map;
@@ -24,6 +22,7 @@ import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.aop.AopAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
@@ -41,9 +40,11 @@ import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import static org.junit.Assert.assertEquals;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestConfiguration.class,
properties = { "messages.expiry.one=168", "messages.expiry.two=76" })
@SpringBootTest(classes = TestConfiguration.class, properties = {
"messages.expiry.one=168", "messages.expiry.two=76" })
public class ConfigurationPropertiesRebinderProxyIntegrationTests {
@Autowired
@@ -81,39 +82,44 @@ public class ConfigurationPropertiesRebinderProxyIntegrationTests {
@Aspect
protected static class Interceptor {
@Before("execution(* *..TestProperties.*(..))")
public void before() {
System.err.println("Before");
}
}
// Hack out a protected inner class for testing
protected static class RefreshConfiguration extends RefreshAutoConfiguration {
@Configuration
protected static class RebinderConfiguration
extends ConfigurationPropertiesRebinderAutoConfiguration {
}
}
@ConfigurationProperties("messages")
protected static class TestProperties {
private String name;
private final Map<String, Integer> expiry = new HashMap<>();
private String name;
public Map<String, Integer> getExpiry() {
return expiry;
return this.expiry;
}
public String getName() {
return name;
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
}

View File

@@ -15,12 +15,11 @@
*/
package org.springframework.cloud.context.properties;
import static org.junit.Assert.assertEquals;
import javax.annotation.PostConstruct;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -38,6 +37,8 @@ import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import static org.junit.Assert.assertEquals;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestConfiguration.class)
public class ConfigurationPropertiesRebinderRefreshScopeIntegrationTests {
@@ -57,31 +58,31 @@ public class ConfigurationPropertiesRebinderRefreshScopeIntegrationTests {
@Test
@DirtiesContext
public void testSimpleProperties() throws Exception {
assertEquals("Hello scope!", properties.getMessage());
assertEquals("Hello scope!", this.properties.getMessage());
// Change the dynamic property source...
TestPropertyValues.of("message:Foo").applyTo(this.environment);
// ...but don't refresh, so the bean stays the same:
assertEquals("Hello scope!", properties.getMessage());
assertEquals(1, properties.getCount());
assertEquals("Hello scope!", this.properties.getMessage());
assertEquals(1, this.properties.getCount());
}
@Test
@DirtiesContext
public void testRefresh() throws Exception {
assertEquals(1, properties.getCount());
assertEquals("Hello scope!", properties.getMessage());
assertEquals(1, properties.getCount());
assertEquals(1, this.properties.getCount());
assertEquals("Hello scope!", this.properties.getMessage());
assertEquals(1, this.properties.getCount());
// Change the dynamic property source...
TestPropertyValues.of("message:Foo").applyTo(this.environment);
// ...rebind, but the bean is not re-initialized:
rebinder.rebind();
assertEquals("Hello scope!", properties.getMessage());
assertEquals(1, properties.getCount());
this.rebinder.rebind();
assertEquals("Hello scope!", this.properties.getMessage());
assertEquals(1, this.properties.getCount());
// ...and then refresh, so the bean is re-initialized:
refreshScope.refreshAll();
assertEquals("Foo", properties.getMessage());
this.refreshScope.refreshAll();
assertEquals("Foo", this.properties.getMessage());
// It's a new instance so the initialization count is 1
assertEquals(1, properties.getCount());
assertEquals(1, this.properties.getCount());
}
@Configuration
@@ -101,16 +102,19 @@ public class ConfigurationPropertiesRebinderRefreshScopeIntegrationTests {
@ConfigurationProperties
protected static class TestProperties {
private String message;
private int delay;
private int count = 0;
public int getCount() {
return count;
return this.count;
}
public String getMessage() {
return message;
return this.message;
}
public void setMessage(String message) {
@@ -118,7 +122,7 @@ public class ConfigurationPropertiesRebinderRefreshScopeIntegrationTests {
}
public int getDelay() {
return delay;
return this.delay;
}
public void setDelay(int delay) {
@@ -129,6 +133,7 @@ public class ConfigurationPropertiesRebinderRefreshScopeIntegrationTests {
public void init() {
this.count++;
}
}
}

View File

@@ -74,7 +74,7 @@ public class ContextRefresherIntegrationTests {
public void testUpdateHikari() throws Exception {
assertEquals("Hello scope!", this.properties.getMessage());
TestPropertyValues.of("spring.datasource.hikari.read-only=true")
.applyTo(environment);
.applyTo(this.environment);
// ...and then refresh, so the bean is re-initialized:
this.refresher.refresh();
assertEquals("Hello scope!", this.properties.getMessage());
@@ -84,12 +84,15 @@ public class ContextRefresherIntegrationTests {
@EnableConfigurationProperties(TestProperties.class)
@EnableAutoConfiguration
protected static class TestConfiguration {
}
@ConfigurationProperties
@ManagedResource
protected static class TestProperties {
private String message;
private int delay;
@ManagedAttribute
@@ -109,6 +112,7 @@ public class ContextRefresherIntegrationTests {
public void setDelay(int delay) {
this.delay = delay;
}
}
}

View File

@@ -9,6 +9,7 @@ import java.util.Map;
import org.junit.After;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.logging.LoggingSystem;
import org.springframework.boot.test.util.TestPropertyValues;
@@ -44,7 +45,7 @@ public class ContextRefresherTests {
List<String> names = names(context.getEnvironment().getPropertySources());
assertThat(names).doesNotContain(
"applicationConfig: [classpath:/bootstrap-refresh.properties]");
ContextRefresher refresher = new ContextRefresher(context, scope);
ContextRefresher refresher = new ContextRefresher(context, this.scope);
refresher.refresh();
names = names(context.getEnvironment().getPropertySources());
assertThat(names).contains(
@@ -67,7 +68,7 @@ public class ContextRefresherTests {
List<String> names = names(context.getEnvironment().getPropertySources());
System.err.println("***** " + context.getEnvironment().getPropertySources());
assertThat(names).doesNotContain("bootstrapProperties");
ContextRefresher refresher = new ContextRefresher(context, scope);
ContextRefresher refresher = new ContextRefresher(context, this.scope);
TestPropertyValues.of(
"spring.cloud.bootstrap.sources: org.springframework.cloud.context.refresh.ContextRefresherTests.PropertySourceConfiguration")
.applyTo(context.getEnvironment(), Type.MAP, "defaultProperties");
@@ -85,7 +86,7 @@ public class ContextRefresherTests {
ContextRefresherTests.class, "--spring.main.web-application-type=none",
"--debug=false", "--spring.main.bannerMode=OFF",
"--spring.cloud.bootstrap.name=refresh")) {
ContextRefresher refresher = new ContextRefresher(context, scope);
ContextRefresher refresher = new ContextRefresher(context, this.scope);
TestPropertyValues.of(
"spring.cloud.bootstrap.sources: org.springframework.cloud.context.refresh.ContextRefresherTests.PropertySourceConfiguration")
.applyTo(context);
@@ -111,7 +112,7 @@ public class ContextRefresherTests {
"--spring.main.bannerMode=OFF",
"--spring.cloud.bootstrap.name=refresh")) {
assertThat(system.getCount()).isEqualTo(4);
ContextRefresher refresher = new ContextRefresher(context, scope);
ContextRefresher refresher = new ContextRefresher(context, this.scope);
refresher.refresh();
assertThat(system.getCount()).isEqualTo(4);
}
@@ -122,21 +123,20 @@ public class ContextRefresherTests {
TestBootstrapConfiguration.fooSightings = new ArrayList<>();
try (ConfigurableApplicationContext context = SpringApplication.run(ContextRefresherTests.class,
"--spring.main.web-application-type=none", "--debug=false",
"--spring.main.bannerMode=OFF",
"--spring.cloud.bootstrap.name=refresh",
"--test.bootstrap.foo=bar")) {
try (ConfigurableApplicationContext context = SpringApplication.run(
ContextRefresherTests.class, "--spring.main.web-application-type=none",
"--debug=false", "--spring.main.bannerMode=OFF",
"--spring.cloud.bootstrap.name=refresh", "--test.bootstrap.foo=bar")) {
context.getEnvironment().setActiveProfiles("refresh");
ContextRefresher refresher = new ContextRefresher(context, scope);
ContextRefresher refresher = new ContextRefresher(context, this.scope);
refresher.refresh();
assertThat(TestBootstrapConfiguration.fooSightings).containsExactly("bar", "bar");
assertThat(TestBootstrapConfiguration.fooSightings).containsExactly("bar",
"bar");
}
TestBootstrapConfiguration.fooSightings = null;
}
private List<String> names(MutablePropertySources propertySources) {
List<String> list = new ArrayList<>();
for (PropertySource<?> p : propertySources) {
@@ -147,6 +147,7 @@ public class ContextRefresherTests {
@Configuration
protected static class Empty {
}
@Configuration

View File

@@ -34,36 +34,40 @@ public class RestartIntegrationTests {
private ConfigurableApplicationContext context;
public static void main(String[] args) {
SpringApplication.run(TestConfiguration.class, args);
}
@After
public void close() {
if (context != null) {
context.close();
if (this.context != null) {
this.context.close();
}
}
@Test
public void testRestartTwice() throws Exception {
context = SpringApplication.run(TestConfiguration.class,
this.context = SpringApplication.run(TestConfiguration.class,
"--management.endpoint.restart.enabled=true", "--server.port=0",
"--spring.liveBeansView.mbeanDomain=livebeans");
RestartEndpoint endpoint = context.getBean(RestartEndpoint.class);
assertNotNull(context.getParent());
assertNull(context.getParent().getParent());
context = endpoint.doRestart();
RestartEndpoint endpoint = this.context.getBean(RestartEndpoint.class);
assertNotNull(this.context.getParent());
assertNull(this.context.getParent().getParent());
this.context = endpoint.doRestart();
assertNotNull(context);
assertNotNull(context.getParent());
assertNull(context.getParent().getParent());
assertNotNull(this.context);
assertNotNull(this.context.getParent());
assertNull(this.context.getParent().getParent());
RestartEndpoint next = context.getBean(RestartEndpoint.class);
RestartEndpoint next = this.context.getBean(RestartEndpoint.class);
assertNotSame(endpoint, next);
context = next.doRestart();
this.context = next.doRestart();
assertNotNull(context);
assertNotNull(context.getParent());
assertNull(context.getParent().getParent());
assertNotNull(this.context);
assertNotNull(this.context.getParent());
assertNull(this.context.getParent().getParent());
LiveBeansView beans = new LiveBeansView();
String json = beans.getSnapshotAsJson();
@@ -71,13 +75,10 @@ public class RestartIntegrationTests {
assertThat(json).containsOnlyOnce("parent\": null");
}
public static void main(String[] args) {
SpringApplication.run(TestConfiguration.class, args);
}
@Configuration
@EnableAutoConfiguration
protected static class TestConfiguration {
}
}

View File

@@ -17,6 +17,7 @@ package org.springframework.cloud.context.scope.refresh;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.test.context.SpringBootTest;
@@ -33,15 +34,15 @@ import static org.junit.Assert.assertEquals;
@SpringBootTest(classes = TestConfiguration.class)
public class ImportRefreshScopeIntegrationTests {
@Autowired
org.springframework.cloud.context.scope.refresh.RefreshScope scope;
@Autowired
private ConfigurableListableBeanFactory beanFactory;
@Autowired
private ExampleService service;
@Autowired
org.springframework.cloud.context.scope.refresh.RefreshScope scope;
@Test
public void testSimpleProperties() throws Exception {
assertEquals("Hello scope!", this.service.getMessage());
@@ -63,6 +64,7 @@ public class ImportRefreshScopeIntegrationTests {
@Configuration
@Import({ RefreshAutoConfiguration.class, ExampleService.class })
protected static class TestConfiguration {
}
}

View File

@@ -16,17 +16,13 @@
package org.springframework.cloud.context.scope.refresh;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.aop.framework.Advised;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.DisposableBean;
@@ -46,6 +42,11 @@ import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestConfiguration.class)
public class MoreRefreshScopeIntegrationTests {
@@ -89,7 +90,8 @@ public class MoreRefreshScopeIntegrationTests {
assertEquals("Hello scope!", this.service.getMessage());
String id1 = this.service.toString();
// Change the dynamic property source...
TestPropertyValues.of("message:Foo").applyTo(this.environment, Type.MAP, "morerefreshtests");
TestPropertyValues.of("message:Foo").applyTo(this.environment, Type.MAP,
"morerefreshtests");
// ...and then refresh, so the bean is re-initialized:
this.scope.refreshAll();
String id2 = this.service.toString();
@@ -123,7 +125,6 @@ public class MoreRefreshScopeIntegrationTests {
assertEquals("Foo", this.service.getMessage());
}
public static class TestService implements InitializingBean, DisposableBean {
private static Log logger = LogFactory.getLog(TestService.class);
@@ -136,6 +137,19 @@ public class MoreRefreshScopeIntegrationTests {
private volatile long delay = 0;
public static void reset() {
initCount = 0;
destroyCount = 0;
}
public static int getInitCount() {
return initCount;
}
public static int getDestroyCount() {
return destroyCount;
}
public void setDelay(long delay) {
this.delay = delay;
}
@@ -153,24 +167,6 @@ public class MoreRefreshScopeIntegrationTests {
this.message = null;
}
public static void reset() {
initCount = 0;
destroyCount = 0;
}
public static int getInitCount() {
return initCount;
}
public static int getDestroyCount() {
return destroyCount;
}
public void setMessage(String message) {
logger.debug("Setting message: " + message);
this.message = message;
}
public String getMessage() {
logger.debug("Getting message: " + this.message);
try {
@@ -183,6 +179,11 @@ public class MoreRefreshScopeIntegrationTests {
return this.message;
}
public void setMessage(String message) {
logger.debug("Setting message: " + message);
this.message = message;
}
}
@Configuration
@@ -232,6 +233,7 @@ public class MoreRefreshScopeIntegrationTests {
public void setDelay(int delay) {
this.delay = delay;
}
}
}

View File

@@ -22,6 +22,7 @@ import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
@@ -51,9 +52,9 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ClientApp.class, properties = "management.endpoints.web.exposure.include=*", webEnvironment = RANDOM_PORT)
public class RefreshEndpointIntegrationTests {
private static final String BASE_PATH = new WebEndpointProperties().getBasePath();
@LocalServerPort
private int port;
@@ -61,9 +62,11 @@ public class RefreshEndpointIntegrationTests {
public void webAccess() throws Exception {
TestRestTemplate template = new TestRestTemplate();
template.exchange(
getUrlEncodedEntity("http://localhost:" + this.port + BASE_PATH + "/env", "message",
"Hello Dave!"), String.class);
template.postForObject("http://localhost:" + this.port + BASE_PATH + "/refresh", null, String.class);
getUrlEncodedEntity("http://localhost:" + this.port + BASE_PATH + "/env",
"message", "Hello Dave!"),
String.class);
template.postForObject("http://localhost:" + this.port + BASE_PATH + "/refresh",
null, String.class);
String message = template.getForObject("http://localhost:" + this.port + "/",
String.class);
assertEquals("Hello Dave!", message);
@@ -76,8 +79,8 @@ public class RefreshEndpointIntegrationTests {
property.put("value", value);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
RequestEntity<Map<String, String>> entity = new RequestEntity<>(
property, headers, HttpMethod.POST, new URI(uri));
RequestEntity<Map<String, String>> entity = new RequestEntity<>(property, headers,
HttpMethod.POST, new URI(uri));
return entity;
}
@@ -85,23 +88,23 @@ public class RefreshEndpointIntegrationTests {
@EnableAutoConfiguration
protected static class ClientApp {
public static void main(String[] args) {
SpringApplication.run(ClientApp.class, args);
}
@Bean
@RefreshScope
public Controller controller() {
return new Controller();
}
public static void main(String[] args) {
SpringApplication.run(ClientApp.class, args);
}
}
@RestController
protected static class Controller {
String message;
@Value("${message:Hello World!}")
public void setMessage(String message) {
this.message = message;
@@ -114,5 +117,4 @@ public class RefreshEndpointIntegrationTests {
}
}

View File

@@ -113,6 +113,7 @@ public class RefreshScopeConcurrencyTests {
private static Log logger = LogFactory.getLog(ExampleService.class);
private String message = null;
private volatile long delay = 0;
public void setDelay(long delay) {
@@ -130,11 +131,6 @@ public class RefreshScopeConcurrencyTests {
this.message = null;
}
public void setMessage(String message) {
logger.debug("Setting message: " + message);
this.message = message;
}
@Override
public String getMessage() {
logger.debug("Getting message: " + this.message);
@@ -148,6 +144,11 @@ public class RefreshScopeConcurrencyTests {
return this.message;
}
public void setMessage(String message) {
logger.debug("Setting message: " + message);
this.message = message;
}
}
@Configuration
@@ -173,7 +174,9 @@ public class RefreshScopeConcurrencyTests {
@ConfigurationProperties
@ManagedResource
protected static class TestProperties {
private String message;
private int delay;
@ManagedAttribute
@@ -193,6 +196,7 @@ public class RefreshScopeConcurrencyTests {
public void setDelay(int delay) {
this.delay = delay;
}
}
}

View File

@@ -15,9 +15,6 @@
*/
package org.springframework.cloud.context.scope.refresh;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
@@ -31,6 +28,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
@@ -51,6 +49,9 @@ import org.springframework.test.annotation.Repeat;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.ObjectUtils;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestConfiguration.class, properties = "logging.level.org.springframework.cloud.context.scope.refresh.RefreshScopeConfigurationScaleTests=DEBUG")
public class RefreshScopeConfigurationScaleTests {
@@ -58,11 +59,11 @@ public class RefreshScopeConfigurationScaleTests {
private static Log logger = LogFactory
.getLog(RefreshScopeConfigurationScaleTests.class);
private ExecutorService executor = Executors.newFixedThreadPool(8);
@Autowired
org.springframework.cloud.context.scope.refresh.RefreshScope scope;
private ExecutorService executor = Executors.newFixedThreadPool(8);
@Autowired
private ExampleService service;
@@ -74,11 +75,11 @@ public class RefreshScopeConfigurationScaleTests {
@DirtiesContext
public void testConcurrentRefresh() throws Exception {
scope.setEager(false);
this.scope.setEager(false);
// overload the thread pool and try to force Spring to create too many instances
int n = 80;
TestPropertyValues.of("message=Foo").applyTo(environment);
TestPropertyValues.of("message=Foo").applyTo(this.environment);
this.scope.refreshAll();
final CountDownLatch latch = new CountDownLatch(n);
List<Future<String>> results = new ArrayList<>();
@@ -124,6 +125,7 @@ public class RefreshScopeConfigurationScaleTests {
private static Log logger = LogFactory.getLog(ExampleService.class);
private String message = null;
private volatile long delay = 0;
public void setDelay(long delay) {
@@ -151,12 +153,6 @@ public class RefreshScopeConfigurationScaleTests {
this.message = null;
}
public void setMessage(String message) {
logger.debug("Setting message: " + ObjectUtils.getIdentityHexString(this)
+ ", " + message);
this.message = message;
}
@Override
public String getMessage() {
logger.debug("Returning message: " + ObjectUtils.getIdentityHexString(this)
@@ -164,6 +160,12 @@ public class RefreshScopeConfigurationScaleTests {
return this.message;
}
public void setMessage(String message) {
logger.debug("Setting message: " + ObjectUtils.getIdentityHexString(this)
+ ", " + message);
this.message = message;
}
}
@Configuration
@@ -191,7 +193,9 @@ public class RefreshScopeConfigurationScaleTests {
@ConfigurationProperties
protected static class TestProperties {
private String message;
private int delay;
public String getMessage() {
@@ -209,6 +213,7 @@ public class RefreshScopeConfigurationScaleTests {
public void setDelay(int delay) {
this.delay = delay;
}
}
}

View File

@@ -41,23 +41,26 @@ import static org.junit.Assert.assertEquals;
*
*/
public class RefreshScopeConfigurationTests {
private AnnotationConfigApplicationContext context;
@Rule
public ExpectedException expected = ExpectedException.none();
private AnnotationConfigApplicationContext context;
@After
public void init() {
if (context!=null) {
context.close();
if (this.context != null) {
this.context.close();
}
}
private void refresh() {
EnvironmentManager environmentManager = context.getBean(EnvironmentManager.class);
EnvironmentManager environmentManager = this.context
.getBean(EnvironmentManager.class);
environmentManager.setProperty("message", "Hello Dave!");
org.springframework.cloud.context.scope.refresh.RefreshScope scope = context.getBean(org.springframework.cloud.context.scope.refresh.RefreshScope.class);
org.springframework.cloud.context.scope.refresh.RefreshScope scope = this.context
.getBean(
org.springframework.cloud.context.scope.refresh.RefreshScope.class);
scope.refreshAll();
}
@@ -66,10 +69,13 @@ public class RefreshScopeConfigurationTests {
*/
@Test
public void configurationWithRefreshScope() throws Exception {
context = new AnnotationConfigApplicationContext(Application.class,
PropertyPlaceholderAutoConfiguration.class, RefreshAutoConfiguration.class, LifecycleMvcEndpointAutoConfiguration.class);
Application application = context.getBean(Application.class);
assertEquals("refresh", context.getBeanDefinition("scopedTarget.application").getScope());
this.context = new AnnotationConfigApplicationContext(Application.class,
PropertyPlaceholderAutoConfiguration.class,
RefreshAutoConfiguration.class,
LifecycleMvcEndpointAutoConfiguration.class);
Application application = this.context.getBean(Application.class);
assertEquals("refresh",
this.context.getBeanDefinition("scopedTarget.application").getScope());
application.hello();
refresh();
String message = application.hello();
@@ -78,9 +84,11 @@ public class RefreshScopeConfigurationTests {
@Test
public void refreshScopeOnBean() throws Exception {
context = new AnnotationConfigApplicationContext(ClientApp.class,
PropertyPlaceholderAutoConfiguration.class, RefreshAutoConfiguration.class, LifecycleMvcEndpointAutoConfiguration.class);
Controller application = context.getBean(Controller.class);
this.context = new AnnotationConfigApplicationContext(ClientApp.class,
PropertyPlaceholderAutoConfiguration.class,
RefreshAutoConfiguration.class,
LifecycleMvcEndpointAutoConfiguration.class);
Controller application = this.context.getBean(Controller.class);
application.hello();
refresh();
String message = application.hello();
@@ -89,9 +97,11 @@ public class RefreshScopeConfigurationTests {
@Test
public void refreshScopeOnNested() throws Exception {
context = new AnnotationConfigApplicationContext(NestedApp.class,
PropertyPlaceholderAutoConfiguration.class, RefreshAutoConfiguration.class, LifecycleMvcEndpointAutoConfiguration.class);
NestedController application = context.getBean(NestedController.class);
this.context = new AnnotationConfigApplicationContext(NestedApp.class,
PropertyPlaceholderAutoConfiguration.class,
RefreshAutoConfiguration.class,
LifecycleMvcEndpointAutoConfiguration.class);
NestedController application = this.context.getBean(NestedController.class);
application.hello();
refresh();
String message = application.hello();
@@ -101,7 +111,11 @@ public class RefreshScopeConfigurationTests {
// WTF? Maven can't compile without the FQN on this one (not the others).
@org.springframework.context.annotation.Configuration
protected static class NestedApp {
public static void main(String[] args) {
SpringApplication.run(ClientApp.class, args);
}
@RestController
@RefreshScope
protected static class NestedController {
@@ -111,15 +125,11 @@ public class RefreshScopeConfigurationTests {
@RequestMapping("/")
public String hello() {
return message;
return this.message;
}
}
public static void main(String[] args) {
SpringApplication.run(ClientApp.class, args);
}
}
@Configuration("application")
@@ -129,30 +139,30 @@ public class RefreshScopeConfigurationTests {
@Value("${message:Hello World!}")
String message = "Hello World";
@RequestMapping("/")
public String hello() {
return message;
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@RequestMapping("/")
public String hello() {
return this.message;
}
}
@Configuration
protected static class ClientApp {
public static void main(String[] args) {
SpringApplication.run(ClientApp.class, args);
}
@Bean
@RefreshScope
public Controller controller() {
return new Controller();
}
public static void main(String[] args) {
SpringApplication.run(ClientApp.class, args);
}
}
@RestController
@@ -164,7 +174,7 @@ public class RefreshScopeConfigurationTests {
@RequestMapping("/")
// Deliberately use package scope
String hello() {
return message;
return this.message;
}
}

View File

@@ -143,12 +143,29 @@ public class RefreshScopeIntegrationTests {
private static Log logger = LogFactory.getLog(ExampleService.class);
private volatile static int initCount = 0;
private volatile static int destroyCount = 0;
private volatile static RefreshScopeRefreshedEvent event;
private String message = null;
private volatile long delay = 0;
public static void reset() {
initCount = 0;
destroyCount = 0;
event = null;
}
public static int getInitCount() {
return initCount;
}
public static int getDestroyCount() {
return destroyCount;
}
public void setDelay(long delay) {
this.delay = delay;
}
@@ -166,25 +183,6 @@ public class RefreshScopeIntegrationTests {
this.message = null;
}
public static void reset() {
initCount = 0;
destroyCount = 0;
event = null;
}
public static int getInitCount() {
return initCount;
}
public static int getDestroyCount() {
return destroyCount;
}
public void setMessage(String message) {
logger.debug("Setting message: " + message);
this.message = message;
}
@Override
public String getMessage() {
logger.debug("Getting message: " + this.message);
@@ -198,6 +196,11 @@ public class RefreshScopeIntegrationTests {
return this.message;
}
public void setMessage(String message) {
logger.debug("Setting message: " + message);
this.message = message;
}
@Override
public String throwsException() throws ServiceException {
throw new ServiceException();
@@ -207,10 +210,13 @@ public class RefreshScopeIntegrationTests {
public void onApplicationEvent(RefreshScopeRefreshedEvent e) {
event = e;
}
}
@SuppressWarnings("serial")
public static class ServiceException extends Exception {}
public static class ServiceException extends Exception {
}
@Configuration
@EnableConfigurationProperties(TestProperties.class)
@@ -234,7 +240,9 @@ public class RefreshScopeIntegrationTests {
@ConfigurationProperties
@ManagedResource
protected static class TestProperties {
private String message;
private int delay;
@ManagedAttribute
@@ -254,6 +262,7 @@ public class RefreshScopeIntegrationTests {
public void setDelay(int delay) {
this.delay = delay;
}
}
}

View File

@@ -136,12 +136,29 @@ public class RefreshScopeLazyIntegrationTests {
private static Log logger = LogFactory.getLog(ExampleService.class);
private volatile static int initCount = 0;
private volatile static int destroyCount = 0;
private volatile static RefreshScopeRefreshedEvent event;
private String message = null;
private volatile long delay = 0;
public static void reset() {
initCount = 0;
destroyCount = 0;
event = null;
}
public static int getInitCount() {
return initCount;
}
public static int getDestroyCount() {
return destroyCount;
}
public void setDelay(long delay) {
this.delay = delay;
}
@@ -159,25 +176,6 @@ public class RefreshScopeLazyIntegrationTests {
this.message = null;
}
public static void reset() {
initCount = 0;
destroyCount = 0;
event = null;
}
public static int getInitCount() {
return initCount;
}
public static int getDestroyCount() {
return destroyCount;
}
public void setMessage(String message) {
logger.debug("Setting message: " + message);
this.message = message;
}
@Override
public String getMessage() {
logger.debug("Getting message: " + this.message);
@@ -191,10 +189,16 @@ public class RefreshScopeLazyIntegrationTests {
return this.message;
}
public void setMessage(String message) {
logger.debug("Setting message: " + message);
this.message = message;
}
@Override
public void onApplicationEvent(RefreshScopeRefreshedEvent e) {
event = e;
}
}
@Configuration
@@ -227,7 +231,9 @@ public class RefreshScopeLazyIntegrationTests {
@ConfigurationProperties
@ManagedResource
protected static class TestProperties {
private String message;
private int delay;
@ManagedAttribute
@@ -247,6 +253,7 @@ public class RefreshScopeLazyIntegrationTests {
public void setDelay(int delay) {
this.delay = delay;
}
}
}

View File

@@ -17,6 +17,7 @@ package org.springframework.cloud.context.scope.refresh;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
@@ -31,7 +32,8 @@ import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {RefreshScopeNullBeanIntegrationTests.TestConfiguration.class})
@SpringBootTest(classes = {
RefreshScopeNullBeanIntegrationTests.TestConfiguration.class })
public class RefreshScopeNullBeanIntegrationTests {
@Autowired
@@ -49,7 +51,9 @@ public class RefreshScopeNullBeanIntegrationTests {
// this.scope.refreshAll();
}
protected static class OptionalService { }
protected static class OptionalService {
}
public static class MyCustomComponent {
@@ -58,6 +62,7 @@ public class RefreshScopeNullBeanIntegrationTests {
public MyCustomComponent(OptionalService optionalService) {
this.optionalService = optionalService;
}
}
@Configuration
@@ -68,10 +73,12 @@ public class RefreshScopeNullBeanIntegrationTests {
public OptionalService service() {
return null;
}
}
@Configuration
@Import({ RefreshAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class, OptionalConfiguration.class })
@Import({ RefreshAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class,
OptionalConfiguration.class })
protected static class TestConfiguration {
@Autowired(required = false)
@@ -79,8 +86,9 @@ public class RefreshScopeNullBeanIntegrationTests {
@Bean
public MyCustomComponent myCustomComponent() {
return new MyCustomComponent(optionalService);
return new MyCustomComponent(this.optionalService);
}
}
}

View File

@@ -15,9 +15,6 @@
*/
package org.springframework.cloud.context.scope.refresh;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
@@ -31,6 +28,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
@@ -47,18 +45,22 @@ import org.springframework.test.annotation.Repeat;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.ObjectUtils;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestConfiguration.class)
// , properties="logging.level.org.springframework.cloud.context.scope.refresh.RefreshScopePureScaleTests=DEBUG")
// ,
// properties="logging.level.org.springframework.cloud.context.scope.refresh.RefreshScopePureScaleTests=DEBUG")
public class RefreshScopePureScaleTests {
private static Log logger = LogFactory.getLog(RefreshScopePureScaleTests.class);
private ExecutorService executor = Executors.newFixedThreadPool(8);
@Autowired
org.springframework.cloud.context.scope.refresh.RefreshScope scope;
private ExecutorService executor = Executors.newFixedThreadPool(8);
@Autowired
private ExampleService service;
@@ -91,7 +93,8 @@ public class RefreshScopePureScaleTests {
public void run() {
logger.debug("Refreshing.");
RefreshScopePureScaleTests.this.scope.refreshAll();
}});
}
});
}
assertTrue(latch.await(15000, TimeUnit.MILLISECONDS));
assertEquals("Foo", this.service.getMessage());
@@ -112,6 +115,7 @@ public class RefreshScopePureScaleTests {
private static Log logger = LogFactory.getLog(ExampleService.class);
private String message = null;
private volatile long delay = 0;
public void setDelay(long delay) {
@@ -120,33 +124,38 @@ public class RefreshScopePureScaleTests {
@Override
public void afterPropertiesSet() throws Exception {
logger.debug("Initializing: " + ObjectUtils.getIdentityHexString(this) + ", " + this.message);
logger.debug("Initializing: " + ObjectUtils.getIdentityHexString(this) + ", "
+ this.message);
try {
Thread.sleep(this.delay);
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
logger.debug("Initialized: " + ObjectUtils.getIdentityHexString(this) + ", " + this.message);
logger.debug("Initialized: " + ObjectUtils.getIdentityHexString(this) + ", "
+ this.message);
}
@Override
public void destroy() throws Exception {
logger.debug("Destroying message: " + ObjectUtils.getIdentityHexString(this) + ", " + this.message);
logger.debug("Destroying message: " + ObjectUtils.getIdentityHexString(this)
+ ", " + this.message);
this.message = null;
}
public void setMessage(String message) {
logger.debug("Setting message: " + ObjectUtils.getIdentityHexString(this) + ", " + message);
this.message = message;
}
@Override
public String getMessage() {
logger.debug("Returning message: " + ObjectUtils.getIdentityHexString(this) + ", " + this.message);
logger.debug("Returning message: " + ObjectUtils.getIdentityHexString(this)
+ ", " + this.message);
return this.message;
}
public void setMessage(String message) {
logger.debug("Setting message: " + ObjectUtils.getIdentityHexString(this)
+ ", " + message);
this.message = message;
}
}
@Configuration

View File

@@ -56,11 +56,11 @@ public class RefreshScopeScaleTests {
private static Log logger = LogFactory.getLog(RefreshScopeScaleTests.class);
private ExecutorService executor = Executors.newFixedThreadPool(8);
@Autowired
org.springframework.cloud.context.scope.refresh.RefreshScope scope;
private ExecutorService executor = Executors.newFixedThreadPool(8);
@Autowired
private ExampleService service;
@@ -113,10 +113,12 @@ public class RefreshScopeScaleTests {
private static Log logger = LogFactory.getLog(ExampleService.class);
private String message = null;
private volatile long delay = 0;
private static volatile int count;
private String message = null;
private volatile long delay = 0;
public void setDelay(long delay) {
this.delay = delay;
}
@@ -139,17 +141,17 @@ public class RefreshScopeScaleTests {
this.message = null;
}
public void setMessage(String message) {
logger.debug("Setting message: " + message);
this.message = message;
}
@Override
public String getMessage() {
logger.debug("Returning message: " + this.message);
return this.message;
}
public void setMessage(String message) {
logger.debug("Setting message: " + message);
this.message = message;
}
}
@Configuration
@@ -175,7 +177,9 @@ public class RefreshScopeScaleTests {
@ConfigurationProperties
@ManagedResource
protected static class TestProperties {
private String message;
private int delay;
@ManagedAttribute
@@ -195,6 +199,7 @@ public class RefreshScopeScaleTests {
public void setDelay(int delay) {
this.delay = delay;
}
}
}

View File

@@ -79,4 +79,5 @@ public class RefreshScopeSerializationTests {
protected static class TestBean {
}
}

View File

@@ -17,6 +17,7 @@ package org.springframework.cloud.context.scope.refresh;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
@@ -44,43 +45,44 @@ public class RefreshScopeWebIntegrationTests {
@Autowired
private org.springframework.cloud.context.scope.refresh.RefreshScope scope;
@Autowired
private EnvironmentManager environmentManager;
@Autowired
private Client application;
@Autowired
private ConfigurableListableBeanFactory beanFactory;
@Test
public void scopeOnBeanDefinition() throws Exception {
assertEquals("refresh", beanFactory.getBeanDefinition("scopedTarget.application").getScope());
assertEquals("refresh", this.beanFactory
.getBeanDefinition("scopedTarget.application").getScope());
}
@Test
public void beanAccess() throws Exception {
application.hello();
environmentManager.setProperty("message", "Hello Dave!");
scope.refreshAll();
String message = application.hello();
this.application.hello();
this.environmentManager.setProperty("message", "Hello Dave!");
this.scope.refreshAll();
String message = this.application.hello();
assertEquals("Hello Dave!", message);
}
@Configuration
@EnableAutoConfiguration
protected static class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
@RefreshScope
public Client application() {
return new Client();
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@@ -92,7 +94,7 @@ public class RefreshScopeWebIntegrationTests {
@RequestMapping("/")
public String hello() {
return message;
return this.message;
}
}

View File

@@ -73,7 +73,7 @@ public class RefreshEndpointTests {
.properties("spring.cloud.bootstrap.name:none").run();
RefreshScope scope = new RefreshScope();
scope.setApplicationContext(this.context);
context.getEnvironment().setActiveProfiles("local");
this.context.getEnvironment().setActiveProfiles("local");
ContextRefresher contextRefresher = new ContextRefresher(this.context, scope);
RefreshEndpoint endpoint = new RefreshEndpoint(contextRefresher);
Collection<String> keys = endpoint.refresh();
@@ -87,7 +87,7 @@ public class RefreshEndpointTests {
.properties("spring.cloud.bootstrap.name:none").run();
RefreshScope scope = new RefreshScope();
scope.setApplicationContext(this.context);
context.getEnvironment().setActiveProfiles("override");
this.context.getEnvironment().setActiveProfiles("override");
ContextRefresher contextRefresher = new ContextRefresher(this.context, scope);
RefreshEndpoint endpoint = new RefreshEndpoint(contextRefresher);
Collection<String> keys = endpoint.refresh();
@@ -148,8 +148,8 @@ public class RefreshEndpointTests {
@Test
public void shutdownHooksCleaned() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(Empty.class)
.web(WebApplicationType.NONE).bannerMode(Mode.OFF).run()) {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder(
Empty.class).web(WebApplicationType.NONE).bannerMode(Mode.OFF).run()) {
RefreshScope scope = new RefreshScope();
scope.setApplicationContext(context);
ContextRefresher contextRefresher = new ContextRefresher(context, scope);
@@ -173,8 +173,8 @@ public class RefreshEndpointTests {
@Configuration
protected static class Empty implements SmartApplicationListener {
private List<ApplicationEvent> events = new ArrayList<ApplicationEvent>();
private List<ApplicationEvent> events = new ArrayList<ApplicationEvent>();
@Override
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
@@ -184,11 +184,12 @@ public class RefreshEndpointTests {
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof EnvironmentChangeEvent ||
event instanceof RefreshScopeRefreshedEvent) {
if (event instanceof EnvironmentChangeEvent
|| event instanceof RefreshScopeRefreshedEvent) {
this.events.add(event);
}
}
}
@Component
@@ -202,4 +203,5 @@ public class RefreshEndpointTests {
}
}
}

View File

@@ -38,19 +38,20 @@ public class RefreshScopeHealthIndicatorTests {
@SuppressWarnings("unchecked")
private ObjectProvider<RefreshScope> scopeProvider = mock(ObjectProvider.class);
private ConfigurationPropertiesRebinder rebinder =
mock(ConfigurationPropertiesRebinder.class);
private ConfigurationPropertiesRebinder rebinder = mock(
ConfigurationPropertiesRebinder.class);
private RefreshScope scope = mock(RefreshScope.class);
private RefreshScopeHealthIndicator indicator = new RefreshScopeHealthIndicator(
this.scopeProvider, this.rebinder);
@Before
public void init() {
BDDMockito.willReturn(scope).given(scopeProvider).getIfAvailable();
when(this.rebinder.getErrors())
.thenReturn(Collections.emptyMap());
when(this.scope.getErrors())
.thenReturn(Collections.emptyMap());
BDDMockito.willReturn(this.scope).given(this.scopeProvider).getIfAvailable();
when(this.rebinder.getErrors()).thenReturn(Collections.emptyMap());
when(this.scope.getErrors()).thenReturn(Collections.emptyMap());
}
@Test
@@ -60,24 +61,24 @@ public class RefreshScopeHealthIndicatorTests {
@Test
public void binderError() {
when(this.rebinder.getErrors()).thenReturn(Collections
.singletonMap("foo", new RuntimeException("FOO")));
when(this.rebinder.getErrors())
.thenReturn(Collections.singletonMap("foo", new RuntimeException("FOO")));
assertEquals(Status.DOWN, this.indicator.health().getStatus());
}
@Test
public void scopeError() {
when(this.scope.getErrors()).thenReturn(Collections
.singletonMap("foo", new RuntimeException("FOO")));
when(this.scope.getErrors())
.thenReturn(Collections.singletonMap("foo", new RuntimeException("FOO")));
assertEquals(Status.DOWN, this.indicator.health().getStatus());
}
@Test
public void bothError() {
when(this.rebinder.getErrors()).thenReturn(Collections
.singletonMap("foo", new RuntimeException("FOO")));
when(this.scope.getErrors()).thenReturn(Collections
.singletonMap("bar", new RuntimeException("BAR")));
when(this.rebinder.getErrors())
.thenReturn(Collections.singletonMap("foo", new RuntimeException("FOO")));
when(this.scope.getErrors())
.thenReturn(Collections.singletonMap("bar", new RuntimeException("BAR")));
assertEquals(Status.DOWN, this.indicator.health().getStatus());
}

View File

@@ -15,9 +15,6 @@
*/
package org.springframework.cloud.logging;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.util.Collections;
import org.junit.After;
@@ -31,6 +28,9 @@ import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.core.env.StandardEnvironment;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* @author Dave Syer
*
@@ -38,6 +38,7 @@ import org.springframework.core.env.StandardEnvironment;
public class LoggingRebinderTests {
private LoggingRebinder rebinder = new LoggingRebinder();
private Logger logger = LoggerFactory.getLogger("org.springframework.web");
@After

View File

@@ -1 +1 @@
config.name: main
config.name:main

View File

@@ -1 +1 @@
foo: {cipher}e4e061f9fe39ba5b14d8012d2f17d39775606039409b71ed4be0fdd033d5324a
foo:{cipher}e4e061f9fe39ba5b14d8012d2f17d39775606039409b71ed4be0fdd033d5324a

View File

@@ -1 +1 @@
added: Hello added!
added:Hello added!

View File

@@ -1 +1 @@
message: Hello override!
message:Hello override!

View File

@@ -1,7 +1,7 @@
message: Hello scope!
delay: 0
debug: true
message:Hello scope!
delay:0
debug:true
#logging.level.org.springframework.web: DEBUG
#logging.level.org.springframework.context.annotation: DEBUG
logging.level.org.hibernate=ERROR
logging.level.com.zaxxer.hikari=ERROR
logging.level.com.zaxxer.hikari=ERROR

View File

@@ -1,2 +1,2 @@
spring.main.sources: org.springframework.cloud.context.properties.ConfigurationPropertiesRebinderIntegrationTests.ConfigProperties
config.name: parent
spring.main.sources:org.springframework.cloud.context.properties.ConfigurationPropertiesRebinderIntegrationTests.ConfigProperties
config.name:parent

View File

@@ -1 +1 @@
bar: {cipher}6154ca04d4bb6144d672c4e3d750b5147116dd381946d51fa44f8bc25dc256f4
bar:{cipher}6154ca04d4bb6144d672c4e3d750b5147116dd381946d51fa44f8bc25dc256f4

Some files were not shown because too many files have changed in this diff Show More