diff --git a/pom.xml b/pom.xml index dee59b32..744eb3d9 100644 --- a/pom.xml +++ b/pom.xml @@ -41,11 +41,6 @@ spring-cloud-config-server 1.0.1.BUILD-SNAPSHOT - - org.springframework.security - spring-security-rsa - 1.0.0.RELEASE - org.eclipse.jgit org.eclipse.jgit diff --git a/spring-cloud-config-client/pom.xml b/spring-cloud-config-client/pom.xml index 552e18e0..f77a276c 100644 --- a/spring-cloud-config-client/pom.xml +++ b/spring-cloud-config-client/pom.xml @@ -22,44 +22,28 @@ - - org.springframework.boot - spring-boot-starter-test - test - org.springframework.boot spring-boot-starter - org.springframework.boot - spring-boot-starter-aop - true + org.springframework.cloud + spring-cloud-commons - org.springframework.security - spring-security-crypto - - - org.springframework.security - spring-security-rsa - true - - - org.springframework.boot - spring-boot-starter-web - true - - - org.springframework.integration - spring-integration-jmx - true + org.springframework + spring-web org.springframework.boot spring-boot-starter-actuator true + + org.springframework.boot + spring-boot-starter-test + test + diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/autoconfigure/LifecycleMvcEndpointAutoConfiguration.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/autoconfigure/LifecycleMvcEndpointAutoConfiguration.java deleted file mode 100644 index ead3ab5d..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/autoconfigure/LifecycleMvcEndpointAutoConfiguration.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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. - */ -package org.springframework.cloud.autoconfigure; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration; -import org.springframework.boot.actuate.endpoint.EnvironmentEndpoint; -import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; -import org.springframework.cloud.config.client.RefreshEndpoint; -import org.springframework.cloud.context.environment.EnvironmentManager; -import org.springframework.cloud.context.environment.EnvironmentManagerMvcEndpoint; -import org.springframework.cloud.context.restart.RestartEndpoint; -import org.springframework.cloud.context.restart.RestartMvcEndpoint; -import org.springframework.cloud.endpoint.GenericPostableMvcEndpoint; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Autoconfiguration for some MVC endpoints governing the application context lifecycle. - * Provides restart, pause, resume, refresh (environment) and environment update - * endpoints. - * - * @author Dave Syer - * - */ -@Configuration -@ConditionalOnClass(EnvironmentEndpoint.class) -@ConditionalOnProperty(value = "endpoints.env.enabled", matchIfMissing = true) -@ConditionalOnWebApplication -@ConditionalOnBean(RestartEndpoint.class) -@AutoConfigureAfter({ WebMvcAutoConfiguration.class, EndpointAutoConfiguration.class, - RefreshAutoConfiguration.class }) -public class LifecycleMvcEndpointAutoConfiguration { - - @Autowired - private RestartEndpoint restartEndpoint; - - @Bean - @ConditionalOnBean(EnvironmentEndpoint.class) - public EnvironmentManagerMvcEndpoint environmentManagerEndpoint( - EnvironmentEndpoint delegate, EnvironmentManager environment) { - return new EnvironmentManagerMvcEndpoint(delegate, environment); - } - - @Bean - @ConditionalOnBean(RefreshEndpoint.class) - public MvcEndpoint refreshMvcEndpoint(RefreshEndpoint endpoint) { - return new GenericPostableMvcEndpoint(endpoint); - } - - @Bean - public RestartMvcEndpoint restartMvcEndpoint() { - return new RestartMvcEndpoint(restartEndpoint); - } - - @Bean - public MvcEndpoint pauseMvcEndpoint(RestartMvcEndpoint restartEndpoint) { - return restartEndpoint.getPauseEndpoint(); - } - - @Bean - public MvcEndpoint resumeMvcEndpoint(RestartMvcEndpoint restartEndpoint) { - return restartEndpoint.getResumeEndpoint(); - } - -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/autoconfigure/RefreshAutoConfiguration.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/autoconfigure/RefreshAutoConfiguration.java deleted file mode 100644 index fcd25c15..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/autoconfigure/RefreshAutoConfiguration.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * 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. - * - */ - -package org.springframework.cloud.autoconfigure; - -import java.util.LinkedHashMap; -import java.util.Map; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.actuate.autoconfigure.EndpointAutoConfiguration; -import org.springframework.boot.actuate.endpoint.Endpoint; -import org.springframework.boot.actuate.endpoint.InfoEndpoint; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationBeanFactoryMetaData; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor; -import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessorRegistrar; -import org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration; -import org.springframework.cloud.config.client.RefreshEndpoint; -import org.springframework.cloud.context.environment.EnvironmentChangeEvent; -import org.springframework.cloud.context.environment.EnvironmentManager; -import org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder; -import org.springframework.cloud.context.restart.RestartEndpoint; -import org.springframework.cloud.context.scope.refresh.RefreshScope; -import org.springframework.cloud.logging.LoggingRebinder; -import org.springframework.context.ApplicationListener; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.integration.monitor.IntegrationMBeanExporter; - -/** - * Autoconfiguration for the refresh scope and associated features to do with changes in - * the Environment (e.g. rebinding logger levels). - * - * @author Dave Syer - * - */ -@Configuration -@ConditionalOnClass(RefreshScope.class) -@AutoConfigureAfter(WebMvcAutoConfiguration.class) -public class RefreshAutoConfiguration { - - @Bean - @ConditionalOnMissingBean - public static RefreshScope refreshScope() { - return new RefreshScope(); - } - - @Bean - @ConditionalOnMissingBean - public static LoggingRebinder loggingRebinder() { - return new LoggingRebinder(); - } - - @Bean - @ConditionalOnMissingBean - public EnvironmentManager environmentManager(ConfigurableEnvironment environment) { - return new EnvironmentManager(environment); - } - - @Configuration - @ConditionalOnClass(InfoEndpoint.class) - @ConditionalOnBean(EndpointAutoConfiguration.class) - protected static class InfoEndpointRebinderConfiguration implements - ApplicationListener { - - @Autowired - private EndpointAutoConfiguration endpoints; - - @Autowired - private ConfigurableEnvironment environment; - - private Map map = new LinkedHashMap(); - - @Override - public void onApplicationEvent(EnvironmentChangeEvent event) { - for (String key : event.getKeys()) { - if (key.startsWith("info.")) { - map.put(key.substring("info.".length()), environment.getProperty(key)); - } - } - } - - @Bean - public InfoEndpoint infoEndpoint() throws Exception { - return new InfoEndpoint(endpoints.infoEndpoint().invoke()) { - @Override - public Map invoke() { - Map info = new LinkedHashMap( - super.invoke()); - info.putAll(map); - return info; - } - }; - } - - } - - @Configuration - @ConditionalOnBean(ConfigurationPropertiesBindingPostProcessor.class) - protected static class ConfigurationPropertiesRebinderConfiguration implements - BeanFactoryAware { - - private BeanFactory context; - - @Override - public void setBeanFactory(BeanFactory applicationContext) throws BeansException { - context = applicationContext; - } - - @Bean - @ConditionalOnMissingBean - public ConfigurationPropertiesRebinder configurationPropertiesRebinder() { - // Since this is a BeanPostProcessor we have to be super careful not to cause - // a cascade of bean instantiation. Knowing the *name* of the beans we need is - // super optimal, but a little brittle (unfortunately we have no choice). - ConfigurationPropertiesBindingPostProcessor binder = context - .getBean( - ConfigurationPropertiesBindingPostProcessorRegistrar.BINDER_BEAN_NAME, - ConfigurationPropertiesBindingPostProcessor.class); - ConfigurationBeanFactoryMetaData metaData = context.getBean( - ConfigurationPropertiesBindingPostProcessorRegistrar.BINDER_BEAN_NAME - + ".store", ConfigurationBeanFactoryMetaData.class); - ConfigurationPropertiesRebinder rebinder = new ConfigurationPropertiesRebinder( - binder); - rebinder.setBeanMetaDataStore(metaData); - return rebinder; - } - } - - @ConditionalOnClass(Endpoint.class) - protected static class RefreshEndpointsConfiguration { - - @ConditionalOnClass(IntegrationMBeanExporter.class) - protected static class RestartEndpointWithIntegration { - - @Autowired(required = false) - private IntegrationMBeanExporter exporter; - - @Bean - @ConditionalOnMissingBean - public RestartEndpoint restartEndpoint() { - RestartEndpoint endpoint = new RestartEndpoint(); - if (exporter != null) { - endpoint.setIntegrationMBeanExporter(exporter); - } - return endpoint; - } - - } - - @ConditionalOnMissingClass(name = "org.springframework.integration.monitor.IntegrationMBeanExporter") - protected static class RestartEndpointWithoutIntegration { - - @Bean - @ConditionalOnMissingBean - public RestartEndpoint restartEndpoint() { - return new RestartEndpoint(); - } - } - - @Bean - @ConfigurationProperties("endpoints.pause") - public Endpoint pauseEndpoint(RestartEndpoint restartEndpoint) { - return restartEndpoint.getPauseEndpoint(); - } - - @Bean - @ConfigurationProperties("endpoints.resume") - public Endpoint resumeEndpoint(RestartEndpoint restartEndpoint) { - return restartEndpoint.getResumeEndpoint(); - } - - @Configuration - @ConditionalOnProperty(value = "endpoints.refresh.enabled", matchIfMissing = true) - @ConditionalOnBean(PropertySourceBootstrapConfiguration.class) - protected static class RefreshEndpointConfiguration { - - @Bean - @ConditionalOnMissingBean - public RefreshEndpoint refreshEndpoint( - ConfigurableApplicationContext context, RefreshScope scope) { - RefreshEndpoint endpoint = new RefreshEndpoint(context, scope); - return endpoint; - } - - } - - } -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/BootstrapApplicationListener.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/BootstrapApplicationListener.java deleted file mode 100644 index 39e0d553..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/BootstrapApplicationListener.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * 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. - */ - -package org.springframework.cloud.bootstrap; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.springframework.beans.factory.ListableBeanFactory; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.builder.ParentContextApplicationContextInitializer; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.ApplicationListener; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.AnnotationAwareOrderComparator; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.PropertySource; -import org.springframework.core.env.StandardEnvironment; -import org.springframework.core.io.support.SpringFactoriesLoader; -import org.springframework.util.ClassUtils; -import org.springframework.util.StringUtils; - -/** - * A listener that prepares a SpringApplication (e.g. populating its Environment) by - * delegating to {@link ApplicationContextInitializer} beans in a separate bootstrap - * context. The bootstrap context is a SpringApplication created from sources defined in - * spring.factories as {@link BootstrapConfiguration}, and initialized with external - * config taken from "bootstrap.properties" (or yml), instead of the normal - * "application.properties". - * - * @author Dave Syer - * - */ -public class BootstrapApplicationListener implements - ApplicationListener, Ordered { - - public static final String BOOTSTRAP_PROPERTY_SOURCE_NAME = "bootstrap"; - - public static final int DEFAULT_ORDER = Ordered.HIGHEST_PRECEDENCE + 5; - - private int order = DEFAULT_ORDER; - - @Override - public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) { - ConfigurableEnvironment environment = event.getEnvironment(); - if (!environment.getProperty("spring.cloud.bootstrap.enabled", Boolean.class, - true)) { - return; - } - // don't listen to events in a bootstrap context - if (environment.getPropertySources().contains("bootstrapInProgress")) { - return; - } - ConfigurableApplicationContext context = bootstrapServiceContext(environment, - event.getSpringApplication()); - apply(context, event.getSpringApplication(), environment); - } - - private ConfigurableApplicationContext bootstrapServiceContext( - ConfigurableEnvironment environment, final SpringApplication application) { - StandardEnvironment bootstrapEnvironment = new StandardEnvironment(); - MutablePropertySources bootstrapProperties = bootstrapEnvironment - .getPropertySources(); - for (PropertySource source : bootstrapProperties) { - bootstrapProperties.remove(source.getName()); - } - String configName = environment - .resolvePlaceholders("${spring.cloud.bootstrap.name:bootstrap}"); - String configLocation = environment - .resolvePlaceholders("${spring.cloud.bootstrap.location:}"); - Map bootstrapMap = new HashMap<>(); - bootstrapMap.put("spring.config.name", configName); - if (StringUtils.hasText(configLocation)) { - bootstrapMap.put("spring.config.location", configLocation); - } - bootstrapProperties.addFirst(new MapPropertySource( - BOOTSTRAP_PROPERTY_SOURCE_NAME, bootstrapMap)); - bootstrapProperties.addFirst(new MapPropertySource("bootstrapInProgress", - Collections. emptyMap())); - for (PropertySource source : environment.getPropertySources()) { - bootstrapProperties.addLast(source); - } - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - // Use names and ensure unique to protect against duplicates - List names = SpringFactoriesLoader.loadFactoryNames( - BootstrapConfiguration.class, classLoader); - // TODO: is it possible or sensible to share a ResourceLoader? - SpringApplicationBuilder builder = new SpringApplicationBuilder() - .profiles(environment.getActiveProfiles()).showBanner(false) - .environment(bootstrapEnvironment) - .properties("spring.application.name:" + configName).web(false); - List> sources = new ArrayList<>(); - for (String name : names) { - Class cls = ClassUtils.resolveClassName(name, null); - try { - cls.getDeclaredAnnotations(); - } - catch (Exception e) { - continue; - } - sources.add(cls); - } - builder.sources(sources.toArray(new Class[sources.size()])); - final ConfigurableApplicationContext context = builder.run(); - // Make the bootstrap context a parent of the app context - addAncestorInitializer(application, context); - bootstrapProperties.remove("bootstrapInProgress"); - return context; - } - - private void addAncestorInitializer(SpringApplication application, - ConfigurableApplicationContext context) { - boolean installed = false; - for (ApplicationContextInitializer initializer : application.getInitializers()) { - if (initializer instanceof AncestorInitializer) { - installed = true; - // New parent - ((AncestorInitializer) initializer).setParent(context); - } - } - if (!installed) { - application.addInitializers(new AncestorInitializer(context)); - } - - } - - private void apply(ConfigurableApplicationContext context, - SpringApplication application, ConfigurableEnvironment environment) { - @SuppressWarnings("rawtypes") - List initializers = getOrderedBeansOfType(context, - ApplicationContextInitializer.class); - application.addInitializers(initializers - .toArray(new ApplicationContextInitializer[initializers.size()])); - } - - private List getOrderedBeansOfType(ListableBeanFactory context, Class type) { - List result = new ArrayList(); - for (String name : context.getBeanNamesForType(type)) { - result.add(context.getBean(name, type)); - } - AnnotationAwareOrderComparator.sort(result); - return result; - } - - public void setOrder(int order) { - this.order = order; - } - - @Override - public int getOrder() { - return this.order; - } - - private static class AncestorInitializer implements - ApplicationContextInitializer, Ordered { - - private ConfigurableApplicationContext parent; - - public AncestorInitializer(ConfigurableApplicationContext parent) { - this.parent = parent; - } - - public void setParent(ConfigurableApplicationContext parent) { - this.parent = parent; - } - - @Override - public int getOrder() { - // Need to run not too late (so not unordered), so that, for instance, the - // ContextIdApplicationContextInitializer runs later and picks up the merged - // Environment. Also not too early so that other initializers can pick up the - // parent (especially the Environment). - return Ordered.HIGHEST_PRECEDENCE + 10; - } - - @Override - public void initialize(ConfigurableApplicationContext context) { - preemptMerge( - context.getEnvironment().getPropertySources(), - new MapPropertySource(BOOTSTRAP_PROPERTY_SOURCE_NAME, Collections - . emptyMap())); - while (context.getParent() != null && context.getParent() != context) { - context = (ConfigurableApplicationContext) context.getParent(); - } - new ParentContextApplicationContextInitializer(parent).initialize(context); - } - - private void preemptMerge(MutablePropertySources propertySources, - PropertySource propertySource) { - if (propertySource != null - && !propertySources.contains(propertySource.getName())) { - propertySources.addFirst(propertySource); - } - } - } -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/BootstrapConfiguration.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/BootstrapConfiguration.java deleted file mode 100644 index d8df65d1..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/BootstrapConfiguration.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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. - */ -package org.springframework.cloud.bootstrap; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * A marker interface used as a key in META-INF/spring.factories. Entries in - * the factories file are used to create the bootstrap application context. - * - * @author Dave Syer - * - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@Documented -public @interface BootstrapConfiguration { - - /** - * Exclude specific auto-configuration classes such that they will never be applied. - */ - Class[] exclude() default {}; - -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceBootstrapConfiguration.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceBootstrapConfiguration.java deleted file mode 100644 index 7baeb44d..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceBootstrapConfiguration.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * 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. - */ - -package org.springframework.cloud.bootstrap.config; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.bind.PropertySourcesPropertyValues; -import org.springframework.boot.bind.RelaxedDataBinder; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.bootstrap.BootstrapApplicationListener; -import org.springframework.cloud.config.client.ConfigClientProperties; -import org.springframework.cloud.config.client.ConfigServicePropertySourceLocator; -import org.springframework.cloud.config.client.PropertySourceLocator; -import org.springframework.cloud.context.environment.EnvironmentChangeEvent; -import org.springframework.cloud.logging.LoggingRebinder; -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.AnnotationAwareOrderComparator; -import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.PropertySource; -import org.springframework.core.env.StandardEnvironment; - -/** - * @author Dave Syer - * - */ -@Configuration -@EnableConfigurationProperties(PropertySourceBootstrapProperties.class) -public class PropertySourceBootstrapConfiguration implements - ApplicationContextInitializer { - - private static final String BOOTSTRAP_PROPERTY_SOURCE_NAME = BootstrapApplicationListener.BOOTSTRAP_PROPERTY_SOURCE_NAME; - - private static Log logger = LogFactory - .getLog(PropertySourceBootstrapConfiguration.class); - - @Autowired(required = false) - private List propertySourceLocators = new ArrayList<>(); - - @Autowired - private PropertySourceBootstrapProperties properties; - - public void setPropertySourceLocators( - Collection propertySourceLocators) { - this.propertySourceLocators = new ArrayList<>(propertySourceLocators); - } - - @Override - public void initialize(ConfigurableApplicationContext applicationContext) { - CompositePropertySource composite = new CompositePropertySource( - BOOTSTRAP_PROPERTY_SOURCE_NAME); - AnnotationAwareOrderComparator.sort(propertySourceLocators); - boolean empty = true; - for (PropertySourceLocator locator : propertySourceLocators) { - PropertySource source = null; - source = locator.locate(applicationContext.getEnvironment()); - if (source == null) { - continue; - } - logger.info("Located property source: " + source); - composite.addPropertySource(source); - empty = false; - } - if (!empty) { - MutablePropertySources propertySources = applicationContext.getEnvironment() - .getPropertySources(); - if (propertySources.contains(BOOTSTRAP_PROPERTY_SOURCE_NAME)) { - propertySources.remove(BOOTSTRAP_PROPERTY_SOURCE_NAME); - } - insertPropertySources(propertySources, composite); - setLogLevels(applicationContext.getEnvironment()); - } - } - - private void setLogLevels(ConfigurableEnvironment environment) { - LoggingRebinder rebinder = new LoggingRebinder(); - rebinder.setEnvironment(environment); - // We can't fire the event in the ApplicationContext here (too early), but we can - // create our own listener and poke it (it doesn't need the key changes) - rebinder.onApplicationEvent(new EnvironmentChangeEvent(Collections - . emptySet())); - } - - private void insertPropertySources(MutablePropertySources propertySources, - CompositePropertySource composite) { - MutablePropertySources incoming = new MutablePropertySources(); - incoming.addFirst(composite); - PropertySourceBootstrapProperties remoteProperties = new PropertySourceBootstrapProperties(); - new RelaxedDataBinder(remoteProperties, "spring.cloud.config") - .bind(new PropertySourcesPropertyValues(incoming)); - if (!remoteProperties.isAllowOverride() - || remoteProperties.isOverrideSystemProperties()) { - propertySources.addFirst(composite); - return; - } - if (propertySources - .contains(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME)) { - propertySources.addAfter( - StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, - composite); - } - else { - propertySources.addLast(composite); - } - } - - @Configuration - protected static class PropertySourceLocatorConfiguration { - - @Autowired - private ConfigurableEnvironment environment; - - @Bean - public ConfigClientProperties configClientProperties() { - ConfigClientProperties client = new ConfigClientProperties(environment); - return client; - } - - @Bean - @ConditionalOnProperty(value = "spring.cloud.config.enabled", matchIfMissing = true) - public ConfigServicePropertySourceLocator configServicePropertySource() { - ConfigServicePropertySourceLocator locator = new ConfigServicePropertySourceLocator( - configClientProperties()); - return locator; - } - - } - -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceBootstrapProperties.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceBootstrapProperties.java deleted file mode 100644 index cfe2692b..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceBootstrapProperties.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.springframework.cloud.bootstrap.config; - -import org.springframework.boot.context.properties.ConfigurationProperties; - -@ConfigurationProperties("spring.cloud.config") -public class PropertySourceBootstrapProperties { - - /** - * Flag to indicate that the external properties should override system properties. - * Default true. - */ - private boolean overrideSystemProperties = true; - - /** - * Flag to indicate that {@link #isSystemPropertiesOverride() - * systemPropertiesOverride} can be used. Set to false to prevent users from changing - * the default accidentally. Default true. - */ - private boolean allowOverride = true; - - public boolean isOverrideSystemProperties() { - return overrideSystemProperties; - } - - public void setOverrideSystemProperties(boolean overrideSystemProperties) { - this.overrideSystemProperties = overrideSystemProperties; - } - - public boolean isAllowOverride() { - return allowOverride; - } - - public void setAllowOverride(boolean allowOverride) { - this.allowOverride = allowOverride; - } - -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/encrypt/EncryptionBootstrapConfiguration.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/encrypt/EncryptionBootstrapConfiguration.java deleted file mode 100644 index fde82d58..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/encrypt/EncryptionBootstrapConfiguration.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * 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. - */ -package org.springframework.cloud.bootstrap.encrypt; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionOutcome; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; -import org.springframework.boot.autoconfigure.condition.SpringBootCondition; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.bootstrap.encrypt.KeyProperties.KeyStore; -import org.springframework.cloud.config.encrypt.EncryptorFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ConditionContext; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.Environment; -import org.springframework.core.type.AnnotatedTypeMetadata; -import org.springframework.security.crypto.encrypt.TextEncryptor; -import org.springframework.security.rsa.crypto.KeyStoreKeyFactory; -import org.springframework.security.rsa.crypto.RsaSecretEncryptor; -import org.springframework.util.StringUtils; - -/** - * @author Dave Syer - * - */ -@Configuration -@ConditionalOnClass({ TextEncryptor.class, RsaSecretEncryptor.class }) -@EnableConfigurationProperties(KeyProperties.class) -public class EncryptionBootstrapConfiguration { - - @Autowired(required = false) - private TextEncryptor encryptor; - - @Autowired - private KeyProperties key; - - @Configuration - @Conditional(KeyCondition.class) - @ConditionalOnClass(RsaSecretEncryptor.class) - protected static class RsaEncryptionConfiguration { - - @Autowired - private KeyProperties key; - - @Bean - @ConditionalOnMissingBean(TextEncryptor.class) - public TextEncryptor textEncryptor() { - KeyStore keyStore = key.getKeyStore(); - if (keyStore.getLocation() != null && keyStore.getLocation().exists()) { - return new RsaSecretEncryptor( - new KeyStoreKeyFactory(keyStore.getLocation(), keyStore - .getPassword().toCharArray()).getKeyPair( - keyStore.getAlias(), keyStore.getSecret().toCharArray())); - } - return new EncryptorFactory().create(key.getKey()); - } - - } - - @Configuration - @Conditional(KeyCondition.class) - @ConditionalOnMissingClass(name = "org.springframework.security.rsa.crypto.RsaSecretEncryptor") - protected static class VanillaEncryptionConfiguration { - - @Autowired - private KeyProperties key; - - @Bean - @ConditionalOnMissingBean(TextEncryptor.class) - public TextEncryptor textEncryptor() { - return new EncryptorFactory().create(key.getKey()); - } - - } - - @Bean - public EnvironmentDecryptApplicationInitializer environmentDecryptApplicationListener() { - if (encryptor == null) { - encryptor = new FailsafeTextEncryptor(); - } - EnvironmentDecryptApplicationInitializer listener = new EnvironmentDecryptApplicationInitializer( - encryptor); - listener.setFailOnError(key.isFailOnError()); - return listener; - } - - public static class KeyCondition extends SpringBootCondition { - - @Override - public ConditionOutcome getMatchOutcome(ConditionContext context, - AnnotatedTypeMetadata metadata) { - Environment environment = context.getEnvironment(); - if (hasProperty(environment, "encrypt.keyStore.location")) { - if (hasProperty(environment, "encrypt.keyStore.password")) { - return ConditionOutcome.match("Keystore found in Environment"); - } - return ConditionOutcome - .noMatch("Keystore found but no password in Environment"); - } - else if (hasProperty(environment, "encrypt.key")) { - return ConditionOutcome.match("Key found in Environment"); - } - return ConditionOutcome.noMatch("Keystore nor key found in Environment"); - } - - private boolean hasProperty(Environment environment, String key) { - String value = environment.getProperty(key); - if (value == null) { - return false; - } - return StringUtils.hasText(environment.resolvePlaceholders(value)); - } - - } - - /** - * TextEncryptor that just fails, so that users don't get a false sense of security - * adding ciphers to config files and not getting them decrypted. - * - * @author Dave Syer - * - */ - protected static class FailsafeTextEncryptor implements TextEncryptor { - - @Override - public String encrypt(String text) { - throw new UnsupportedOperationException( - "No encryption for FailsafeTextEncryptor. Did you configure the keystore correctly?"); - } - - @Override - public String decrypt(String encryptedText) { - throw new UnsupportedOperationException( - "No decryption for FailsafeTextEncryptor. Did you configure the keystore correctly?"); - } - - } - -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/encrypt/EnvironmentDecryptApplicationInitializer.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/encrypt/EnvironmentDecryptApplicationInitializer.java deleted file mode 100644 index 163e71d8..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/encrypt/EnvironmentDecryptApplicationInitializer.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * 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. - */ -package org.springframework.cloud.bootstrap.encrypt; - -import java.util.LinkedHashMap; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.core.Ordered; -import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.EnumerablePropertySource; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.PropertySource; -import org.springframework.security.crypto.encrypt.TextEncryptor; - -/** - * @author Dave Syer - * - */ -public class EnvironmentDecryptApplicationInitializer implements - ApplicationContextInitializer, Ordered { - - 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; - } - - @Override - public int getOrder() { - return order; - } - - @Override - public void initialize(ConfigurableApplicationContext applicationContext) { - - ConfigurableEnvironment environment = applicationContext.getEnvironment(); - Map overrides = new LinkedHashMap(); - for (PropertySource source : environment.getPropertySources()) { - decrypt(source, overrides); - } - if (!overrides.isEmpty()) { - environment.getPropertySources().addFirst( - new MapPropertySource("decrypted", overrides)); - } - } - - private void decrypt(PropertySource source, Map overrides) { - - if (source instanceof EnumerablePropertySource) { - - EnumerablePropertySource enumerable = (EnumerablePropertySource) source; - for (String key : enumerable.getPropertyNames()) { - String value = source.getProperty(key).toString(); - if (value.startsWith("{cipher}")) { - value = value.substring("{cipher}".length()); - try { - value = encryptor.decrypt(value); - if (logger.isDebugEnabled()) { - logger.debug("Decrypted: key=" + key); - } - } - catch (Exception e) { - String message = "Cannot decrypt: key=" + key; - if (failOnError) { - throw new IllegalStateException(message, e); - } - if (logger.isDebugEnabled()) { - logger.warn(message, e); - } - else { - logger.warn(message); - } - // Set value to empty to avoid making a password out of the - // cipher text - value = ""; - } - overrides.put(key, value); - } - } - - } - else if (source instanceof CompositePropertySource) { - - for (PropertySource nested : ((CompositePropertySource) source) - .getPropertySources()) { - decrypt(nested, overrides); - } - - } - - } - -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/encrypt/KeyProperties.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/encrypt/KeyProperties.java deleted file mode 100644 index d3d3b11e..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/bootstrap/encrypt/KeyProperties.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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. - */ -package org.springframework.cloud.bootstrap.encrypt; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.core.io.Resource; - -@ConfigurationProperties("encrypt") -public class KeyProperties { - - private String key; - - private boolean failOnError = true; - - private KeyProperties.KeyStore keyStore = new KeyStore(); - - public boolean isFailOnError() { - return failOnError; - } - - public void setFailOnError(boolean failOnError) { - this.failOnError = failOnError; - } - - public String getKey() { - return key; - } - - public void setKey(String key) { - this.key = key; - } - - public KeyStore getKeyStore() { - return keyStore; - } - - public void setKeyStore(KeyProperties.KeyStore keyStore) { - this.keyStore = keyStore; - } - - public static class KeyStore { - - private Resource location; - private String password; - private String alias; - private String secret; - - public String getAlias() { - return alias; - } - - public void setAlias(String alias) { - this.alias = alias; - } - - public Resource getLocation() { - return location; - } - - public void setLocation(Resource location) { - this.location = location; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public String getSecret() { - return secret==null ? password : secret; - } - - public void setSecret(String secret) { - this.secret = secret; - } - - } -} \ No newline at end of file diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/autoconfigure/ConfigClientAutoConfiguration.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigClientAutoConfiguration.java similarity index 74% rename from spring-cloud-config-client/src/main/java/org/springframework/cloud/autoconfigure/ConfigClientAutoConfiguration.java rename to spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigClientAutoConfiguration.java index af9b97a5..07489935 100644 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/autoconfigure/ConfigClientAutoConfiguration.java +++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigClientAutoConfiguration.java @@ -13,16 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.cloud.autoconfigure; +package org.springframework.cloud.config.client; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.cloud.config.client.ConfigClientProperties; -import org.springframework.cloud.config.client.ConfigServerHealthIndicator; -import org.springframework.cloud.config.client.ConfigServicePropertySourceLocator; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -33,7 +30,7 @@ import org.springframework.core.env.Environment; * bound to it. It won't be available in time for autowiring into the bootstrap context, * but the values in this properties object will be the same as the ones used to bind to * the config server, if there is one. - * + * * @author Dave Syer * */ @@ -43,9 +40,11 @@ public class ConfigClientAutoConfiguration { @Bean public ConfigClientProperties configClientProperties(Environment environment, ApplicationContext context) { - if (context.getParent()!=null && BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context.getParent(), - ConfigClientProperties.class).length > 0) { - return BeanFactoryUtils.beanOfType(context.getParent(), ConfigClientProperties.class); + if (context.getParent() != null + && BeanFactoryUtils.beanNamesForTypeIncludingAncestors( + context.getParent(), ConfigClientProperties.class).length > 0) { + return BeanFactoryUtils.beanOfType(context.getParent(), + ConfigClientProperties.class); } ConfigClientProperties client = new ConfigClientProperties(environment); return client; @@ -57,10 +56,11 @@ public class ConfigClientAutoConfiguration { @ConditionalOnProperty(value = "spring.cloud.config.enabled", matchIfMissing = true) protected static class ConfigServerHealthIndicatorConfiguration { - @Bean - public ConfigServerHealthIndicator configServerHealthIndicator(ConfigServicePropertySourceLocator locator) { - return new ConfigServerHealthIndicator(locator); - } + @Bean + public ConfigServerHealthIndicator configServerHealthIndicator( + ConfigServicePropertySourceLocator locator) { + return new ConfigServerHealthIndicator(locator); + } } } diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigServiceBootstrapConfiguration.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigServiceBootstrapConfiguration.java new file mode 100644 index 00000000..a064fbf0 --- /dev/null +++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigServiceBootstrapConfiguration.java @@ -0,0 +1,51 @@ +/* + * 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. + */ + +package org.springframework.cloud.config.client; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.env.ConfigurableEnvironment; + +/** + * @author Dave Syer + * + */ +@Configuration +@EnableConfigurationProperties +public class ConfigServiceBootstrapConfiguration { + + @Autowired + private ConfigurableEnvironment environment; + + @Bean + public ConfigClientProperties configClientProperties() { + ConfigClientProperties client = new ConfigClientProperties(this.environment); + return client; + } + + @Bean + @ConditionalOnProperty(value = "spring.cloud.config.enabled", matchIfMissing = true) + public ConfigServicePropertySourceLocator configServicePropertySource() { + ConfigServicePropertySourceLocator locator = new ConfigServicePropertySourceLocator( + configClientProperties()); + return locator; + } + +} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigServicePropertySourceLocator.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigServicePropertySourceLocator.java index 86550eb8..3d860f2f 100644 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigServicePropertySourceLocator.java +++ b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigServicePropertySourceLocator.java @@ -22,6 +22,7 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.cloud.bootstrap.config.PropertySourceLocator; import org.springframework.cloud.config.environment.Environment; import org.springframework.cloud.config.environment.PropertySource; import org.springframework.core.annotation.Order; @@ -34,7 +35,6 @@ import org.springframework.http.MediaType; import org.springframework.http.client.ClientHttpRequestExecution; import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.http.client.ClientHttpResponse; -import org.springframework.security.crypto.codec.Base64; import org.springframework.web.client.HttpServerErrorException; import org.springframework.web.client.RestTemplate; @@ -136,3 +136,634 @@ public class ConfigServicePropertySourceLocator implements PropertySourceLocator } } + +/** + * Base64 encoder which is a reduced version of Robert Harder's public domain + * implementation (version 2.3.7). See http://iharder.net/base64 for more information. + *

+ * For internal use only. + * + * @author Luke Taylor + * @since 3.0 + */ +final class Base64 { + + /** No options specified. Value is zero. */ + public final static int NO_OPTIONS = 0; + + /** Specify encoding in first bit. Value is one. */ + public final static int ENCODE = 1; + + /** Specify decoding in first bit. Value is zero. */ + public final static int DECODE = 0; + + /** Do break lines when encoding. Value is 8. */ + public final static int DO_BREAK_LINES = 8; + + /** + * Encode using Base64-like encoding that is URL- and Filename-safe as described in + * Section 4 of RFC3548: http://www.faqs + * .org/rfcs/rfc3548.html. It is important to note that data encoded this way is + * not officially valid Base64, or at the very least should not be called + * Base64 without also specifying that is was encoded using the URL- and Filename-safe + * dialect. + */ + public final static int URL_SAFE = 16; + + /** + * Encode using the special "ordered" dialect of Base64 described here: http://www.faqs.org/qa/rfcc-1940.html. + */ + public final static int ORDERED = 32; + + /** Maximum line length (76) of Base64 output. */ + private final static int MAX_LINE_LENGTH = 76; + + /** The equals sign (=) as a byte. */ + private final static byte EQUALS_SIGN = (byte) '='; + + /** The new line character (\n) as a byte. */ + private final static byte NEW_LINE = (byte) '\n'; + + private final static byte WHITE_SPACE_ENC = -5; // Indicates white space in encoding + private final static byte EQUALS_SIGN_ENC = -1; // Indicates equals sign in encoding + + /* ******** S T A N D A R D B A S E 6 4 A L P H A B E T ******** */ + + /** The 64 valid Base64 values. */ + /* Host platform me be something funny like EBCDIC, so we hardcode these values. */ + private final static byte[] _STANDARD_ALPHABET = { (byte) 'A', (byte) 'B', + (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G', (byte) 'H', + (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N', + (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', + (byte) 'U', (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', + (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', + (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l', + (byte) 'm', (byte) 'n', (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', + (byte) 's', (byte) 't', (byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', + (byte) 'y', (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3', + (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', + (byte) '+', (byte) '/' }; + + /** + * Translates a Base64 value to either its 6-bit reconstruction value or a negative + * number indicating some other meaning. + **/ + private final static byte[] _STANDARD_DECODABET = { -9, -9, -9, -9, -9, -9, -9, -9, + -9, // Decimal 0 - 8 + -5, -5, // Whitespace: Tab and Linefeed + -9, -9, // Decimal 11 - 12 + -5, // Whitespace: Carriage Return + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26 + -9, -9, -9, -9, -9, // Decimal 27 - 31 + -5, // Whitespace: Space + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42 + 62, // Plus sign at decimal 43 + -9, -9, -9, // Decimal 44 - 46 + 63, // Slash at decimal 47 + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine + -9, -9, -9, // Decimal 58 - 60 + -1, // Equals sign at decimal 61 + -9, -9, -9, // Decimal 62 - 64 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N' + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z' + -9, -9, -9, -9, -9, -9, // Decimal 91 - 96 + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm' + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z' + -9, -9, -9, -9, -9 // Decimal 123 - 127 + , -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 128 - 139 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 140 - 152 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 153 - 165 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 166 - 178 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 179 - 191 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 192 - 204 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 205 - 217 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 218 - 230 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 231 - 243 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9 // Decimal 244 - 255 + }; + + /* ******** U R L S A F E B A S E 6 4 A L P H A B E T ******** */ + + /** + * Used in the URL- and Filename-safe dialect described in Section 4 of RFC3548: http://www.faqs.org/rfcs/rfc3548.html. + * Notice that the last two bytes become "hyphen" and "underscore" instead of "plus" + * and "slash." + */ + private final static byte[] _URL_SAFE_ALPHABET = { (byte) 'A', (byte) 'B', + (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G', (byte) 'H', + (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N', + (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', + (byte) 'U', (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', + (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', + (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l', + (byte) 'm', (byte) 'n', (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', + (byte) 's', (byte) 't', (byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', + (byte) 'y', (byte) 'z', (byte) '0', (byte) '1', (byte) '2', (byte) '3', + (byte) '4', (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9', + (byte) '-', (byte) '_' }; + + /** + * Used in decoding URL- and Filename-safe dialects of Base64. + */ + private final static byte[] _URL_SAFE_DECODABET = { -9, -9, -9, -9, -9, -9, -9, -9, + -9, // Decimal 0 - 8 + -5, -5, // Whitespace: Tab and Linefeed + -9, -9, // Decimal 11 - 12 + -5, // Whitespace: Carriage Return + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26 + -9, -9, -9, -9, -9, // Decimal 27 - 31 + -5, // Whitespace: Space + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42 + -9, // Plus sign at decimal 43 + -9, // Decimal 44 + 62, // Minus sign at decimal 45 + -9, // Decimal 46 + -9, // Slash at decimal 47 + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine + -9, -9, -9, // Decimal 58 - 60 + -1, // Equals sign at decimal 61 + -9, -9, -9, // Decimal 62 - 64 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N' + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z' + -9, -9, -9, -9, // Decimal 91 - 94 + 63, // Underscore at decimal 95 + -9, // Decimal 96 + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm' + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z' + -9, -9, -9, -9, -9 // Decimal 123 - 127 + , -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 128 - 139 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 140 - 152 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 153 - 165 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 166 - 178 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 179 - 191 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 192 - 204 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 205 - 217 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 218 - 230 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 231 - 243 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9 // Decimal 244 - 255 + }; + + /* ******** O R D E R E D B A S E 6 4 A L P H A B E T ******** */ + + /** + * I don't get the point of this technique, but someone requested it, and it is + * described here: http://www.faqs.org/ + * qa/rfcc-1940.html. + */ + private final static byte[] _ORDERED_ALPHABET = { (byte) '-', (byte) '0', (byte) '1', + (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7', + (byte) '8', (byte) '9', (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', + (byte) 'E', (byte) 'F', (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', + (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P', + (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', (byte) 'V', + (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', (byte) '_', (byte) 'a', + (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', (byte) 'g', + (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l', (byte) 'm', + (byte) 'n', (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', + (byte) 't', (byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', + (byte) 'z' }; + + /** + * Used in decoding the "ordered" dialect of Base64. + */ + private final static byte[] _ORDERED_DECODABET = { -9, -9, -9, -9, -9, -9, -9, -9, + -9, // Decimal 0 - 8 + -5, -5, // Whitespace: Tab and Linefeed + -9, -9, // Decimal 11 - 12 + -5, // Whitespace: Carriage Return + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26 + -9, -9, -9, -9, -9, // Decimal 27 - 31 + -5, // Whitespace: Space + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42 + -9, // Plus sign at decimal 43 + -9, // Decimal 44 + 0, // Minus sign at decimal 45 + -9, // Decimal 46 + -9, // Slash at decimal 47 + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, // Numbers zero through nine + -9, -9, -9, // Decimal 58 - 60 + -1, // Equals sign at decimal 61 + -9, -9, -9, // Decimal 62 - 64 + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, // Letters 'A' through 'M' + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, // Letters 'N' through 'Z' + -9, -9, -9, -9, // Decimal 91 - 94 + 37, // Underscore at decimal 95 + -9, // Decimal 96 + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, // Letters 'a' through 'm' + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // Letters 'n' through 'z' + -9, -9, -9, -9, -9 // Decimal 123 - 127 + , -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 128 - 139 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 140 - 152 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 153 - 165 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 166 - 178 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 179 - 191 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 192 - 204 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 205 - 217 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 218 - 230 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 231 - 243 + -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9 // Decimal 244 - 255 + }; + + public static byte[] decode(byte[] bytes) { + return decode(bytes, 0, bytes.length, NO_OPTIONS); + } + + public static byte[] encode(byte[] bytes) { + return encodeBytesToBytes(bytes, 0, bytes.length, NO_OPTIONS); + } + + public static boolean isBase64(byte[] bytes) { + try { + decode(bytes); + } + catch (InvalidBase64CharacterException e) { + return false; + } + return true; + } + + /** + * Returns one of the _SOMETHING_ALPHABET byte arrays depending on the options + * specified. It's possible, though silly, to specify ORDERED and URLSAFE in + * which case one of them will be picked, though there is no guarantee as to which one + * will be picked. + */ + private static byte[] getAlphabet(int options) { + if ((options & URL_SAFE) == URL_SAFE) { + return _URL_SAFE_ALPHABET; + } + else if ((options & ORDERED) == ORDERED) { + return _ORDERED_ALPHABET; + } + else { + return _STANDARD_ALPHABET; + } + } + + /** + * Returns one of the _SOMETHING_DECODABET byte arrays depending on the options + * specified. It's possible, though silly, to specify ORDERED and URL_SAFE in which + * case one of them will be picked, though there is no guarantee as to which one will + * be picked. + */ + private static byte[] getDecodabet(int options) { + if ((options & URL_SAFE) == URL_SAFE) { + return _URL_SAFE_DECODABET; + } + else if ((options & ORDERED) == ORDERED) { + return _ORDERED_DECODABET; + } + else { + return _STANDARD_DECODABET; + } + } + + /* ******** E N C O D I N G M E T H O D S ******** */ + + /** + *

+ * Encodes up to three bytes of the array source and writes the resulting + * four Base64 bytes to destination. The source and destination arrays can + * be manipulated anywhere along their length by specifying srcOffset and + * destOffset. This method does not check to make sure your arrays are + * large enough to accomodate srcOffset + 3 for the source array + * or destOffset + 4 for the destination array. The actual + * number of significant bytes in your array is given by numSigBytes. + *

+ *

+ * This is the lowest level of the encoding methods with all possible parameters. + *

+ * + * @param source the array to convert + * @param srcOffset the index where conversion begins + * @param numSigBytes the number of significant bytes in your array + * @param destination the array to hold the conversion + * @param destOffset the index where output will be put + * @return the destination array + * @since 1.3 + */ + private static byte[] encode3to4(byte[] source, int srcOffset, int numSigBytes, + byte[] destination, int destOffset, int options) { + + byte[] ALPHABET = getAlphabet(options); + + // 1 2 3 + // 01234567890123456789012345678901 Bit position + // --------000000001111111122222222 Array position from threeBytes + // --------| || || || | Six bit groups to index ALPHABET + // >>18 >>12 >> 6 >> 0 Right shift necessary + // 0x3f 0x3f 0x3f Additional AND + + // Create buffer with zero-padding if there are only one or two + // significant bytes passed in the array. + // We have to shift left 24 in order to flush out the 1's that appear + // when Java treats a value as negative that is cast from a byte to an int. + int inBuff = (numSigBytes > 0 ? ((source[srcOffset] << 24) >>> 8) : 0) + | (numSigBytes > 1 ? ((source[srcOffset + 1] << 24) >>> 16) : 0) + | (numSigBytes > 2 ? ((source[srcOffset + 2] << 24) >>> 24) : 0); + + switch (numSigBytes) { + case 3: + destination[destOffset] = ALPHABET[(inBuff >>> 18)]; + destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f]; + destination[destOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3f]; + destination[destOffset + 3] = ALPHABET[(inBuff) & 0x3f]; + return destination; + + case 2: + destination[destOffset] = ALPHABET[(inBuff >>> 18)]; + destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f]; + destination[destOffset + 2] = ALPHABET[(inBuff >>> 6) & 0x3f]; + destination[destOffset + 3] = EQUALS_SIGN; + return destination; + + case 1: + destination[destOffset] = ALPHABET[(inBuff >>> 18)]; + destination[destOffset + 1] = ALPHABET[(inBuff >>> 12) & 0x3f]; + destination[destOffset + 2] = EQUALS_SIGN; + destination[destOffset + 3] = EQUALS_SIGN; + return destination; + + default: + return destination; + } + } + + /** + * + * @param source The data to convert + * @param off Offset in array where conversion should begin + * @param len Length of data to convert + * @param options Specified options + * @return The Base64-encoded data as a String + * @see Base64#DO_BREAK_LINES + * @throws java.io.IOException if there is an error + * @throws NullPointerException if source array is null + * @throws IllegalArgumentException if source array, offset, or length are invalid + * @since 2.3.1 + */ + private static byte[] encodeBytesToBytes(byte[] source, int off, int len, int options) { + + if (source == null) { + throw new NullPointerException("Cannot serialize a null array."); + } // end if: null + + if (off < 0) { + throw new IllegalArgumentException("Cannot have negative offset: " + off); + } // end if: off < 0 + + if (len < 0) { + throw new IllegalArgumentException("Cannot have length offset: " + len); + } // end if: len < 0 + + if (off + len > source.length) { + throw new IllegalArgumentException(String.format( + "Cannot have offset of %d and length of %d with array of length %d", + off, len, source.length)); + } // end if: off < 0 + + boolean breakLines = (options & DO_BREAK_LINES) > 0; + + // int len43 = len * 4 / 3; + // byte[] outBuff = new byte[ ( len43 ) // Main 4:3 + // + ( (len % 3) > 0 ? 4 : 0 ) // Account for padding + // + (breakLines ? ( len43 / MAX_LINE_LENGTH ) : 0) ]; // New lines + // Try to determine more precisely how big the array needs to be. + // If we get it right, we don't have to do an array copy, and + // we save a bunch of memory. + int encLen = (len / 3) * 4 + (len % 3 > 0 ? 4 : 0); // Bytes needed for actual + // encoding + if (breakLines) { + encLen += encLen / MAX_LINE_LENGTH; // Plus extra newline characters + } + byte[] outBuff = new byte[encLen]; + + int d = 0; + int e = 0; + int len2 = len - 2; + int lineLength = 0; + for (; d < len2; d += 3, e += 4) { + encode3to4(source, d + off, 3, outBuff, e, options); + + lineLength += 4; + if (breakLines && lineLength >= MAX_LINE_LENGTH) { + outBuff[e + 4] = NEW_LINE; + e++; + lineLength = 0; + } // end if: end of line + } // en dfor: each piece of array + + if (d < len) { + encode3to4(source, d + off, len - d, outBuff, e, options); + e += 4; + } // end if: some padding needed + + // Only resize array if we didn't guess it right. + if (e <= outBuff.length - 1) { + byte[] finalOut = new byte[e]; + System.arraycopy(outBuff, 0, finalOut, 0, e); + // System.err.println("Having to resize array from " + outBuff.length + " to " + // + e ); + return finalOut; + } + else { + // System.err.println("No need to resize array."); + return outBuff; + } + } + + /* ******** D E C O D I N G M E T H O D S ******** */ + + /** + * Decodes four bytes from array source and writes the resulting bytes (up + * to three of them) to destination. The source and destination arrays can + * be manipulated anywhere along their length by specifying srcOffset and + * destOffset. This method does not check to make sure your arrays are + * large enough to accomodate srcOffset + 4 for the source array + * or destOffset + 3 for the destination array. This method + * returns the actual number of bytes that were converted from the Base64 encoding. + *

+ * This is the lowest level of the decoding methods with all possible parameters. + *

+ * + * + * @param source the array to convert + * @param srcOffset the index where conversion begins + * @param destination the array to hold the conversion + * @param destOffset the index where output will be put + * @param options alphabet type is pulled from this (standard, url-safe, ordered) + * @return the number of decoded bytes converted + * @throws NullPointerException if source or destination arrays are null + * @throws IllegalArgumentException if srcOffset or destOffset are invalid or there is + * not enough room in the array. + * @since 1.3 + */ + private static int decode4to3(final byte[] source, final int srcOffset, + final byte[] destination, final int destOffset, final int options) { + + // Lots of error checking and exception throwing + if (source == null) { + throw new NullPointerException("Source array was null."); + } // end if + if (destination == null) { + throw new NullPointerException("Destination array was null."); + } // end if + if (srcOffset < 0 || srcOffset + 3 >= source.length) { + throw new IllegalArgumentException( + String.format( + "Source array with length %d cannot have offset of %d and still process four bytes.", + source.length, srcOffset)); + } // end if + if (destOffset < 0 || destOffset + 2 >= destination.length) { + throw new IllegalArgumentException( + String.format( + "Destination array with length %d cannot have offset of %d and still store three bytes.", + destination.length, destOffset)); + } // end if + + byte[] DECODABET = getDecodabet(options); + + // Example: Dk== + if (source[srcOffset + 2] == EQUALS_SIGN) { + // Two ways to do the same thing. Don't know which way I like best. + // int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) + // | ( ( DECODABET[ source[ srcOffset + 1] ] << 24 ) >>> 12 ); + int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18) + | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12); + + destination[destOffset] = (byte) (outBuff >>> 16); + return 1; + } + + // Example: DkL= + else if (source[srcOffset + 3] == EQUALS_SIGN) { + // Two ways to do the same thing. Don't know which way I like best. + // int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) + // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) + // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ); + int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18) + | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12) + | ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6); + + destination[destOffset] = (byte) (outBuff >>> 16); + destination[destOffset + 1] = (byte) (outBuff >>> 8); + return 2; + } + + // Example: DkLE + else { + // Two ways to do the same thing. Don't know which way I like best. + // int outBuff = ( ( DECODABET[ source[ srcOffset ] ] << 24 ) >>> 6 ) + // | ( ( DECODABET[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) + // | ( ( DECODABET[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ) + // | ( ( DECODABET[ source[ srcOffset + 3 ] ] << 24 ) >>> 24 ); + int outBuff = ((DECODABET[source[srcOffset]] & 0xFF) << 18) + | ((DECODABET[source[srcOffset + 1]] & 0xFF) << 12) + | ((DECODABET[source[srcOffset + 2]] & 0xFF) << 6) + | ((DECODABET[source[srcOffset + 3]] & 0xFF)); + + destination[destOffset] = (byte) (outBuff >> 16); + destination[destOffset + 1] = (byte) (outBuff >> 8); + destination[destOffset + 2] = (byte) (outBuff); + + return 3; + } + } + + /** + * Low-level access to decoding ASCII characters in the form of a byte array. + * Ignores GUNZIP option, if it's set. This is not generally a + * recommended method, although it is used internally as part of the decoding process. + * Special case: if len = 0, an empty array is returned. Still, if you need more speed + * and reduced memory footprint (and aren't gzipping), consider this method. + * + * @param source The Base64 encoded data + * @param off The offset of where to begin decoding + * @param len The length of characters to decode + * @param options Can specify options such as alphabet type to use + * @return decoded data + * @throws IllegalArgumentException If bogus characters exist in source data + */ + private static byte[] decode(final byte[] source, final int off, final int len, + final int options) { + + // Lots of error checking and exception throwing + if (source == null) { + throw new NullPointerException("Cannot decode null source array."); + } // end if + if (off < 0 || off + len > source.length) { + throw new IllegalArgumentException( + String.format( + "Source array with length %d cannot have offset of %d and process %d bytes.", + source.length, off, len)); + } // end if + + if (len == 0) { + return new byte[0]; + } + else if (len < 4) { + throw new IllegalArgumentException( + "Base64-encoded string must have at least four characters, but length specified was " + + len); + } // end if + + byte[] DECODABET = getDecodabet(options); + + int len34 = len * 3 / 4; // Estimate on array size + byte[] outBuff = new byte[len34]; // Upper limit on size of output + int outBuffPosn = 0; // Keep track of where we're writing + + byte[] b4 = new byte[4]; // Four byte buffer from source, eliminating white space + int b4Posn = 0; // Keep track of four byte input buffer + int i = 0; // Source array counter + byte sbiDecode = 0; // Special value from DECODABET + + for (i = off; i < off + len; i++) { // Loop through source + + sbiDecode = DECODABET[source[i] & 0xFF]; + + // White space, Equals sign, or legit Base64 character + // Note the values such as -5 and -9 in the + // DECODABETs at the top of the file. + if (sbiDecode >= WHITE_SPACE_ENC) { + if (sbiDecode >= EQUALS_SIGN_ENC) { + b4[b4Posn++] = source[i]; // Save non-whitespace + if (b4Posn > 3) { // Time to decode? + outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, options); + b4Posn = 0; + + // If that was the equals sign, break out of 'for' loop + if (source[i] == EQUALS_SIGN) { + break; + } + } + } + } + else { + // There's a bad input character in the Base64 stream. + throw new InvalidBase64CharacterException(String.format( + "Bad Base64 input character decimal %d in array position %d", + ((int) source[i]) & 0xFF, i)); + } + } + + byte[] out = new byte[outBuffPosn]; + System.arraycopy(outBuff, 0, out, 0, outBuffPosn); + return out; + } +} + +@SuppressWarnings("serial") +class InvalidBase64CharacterException extends IllegalArgumentException { + + InvalidBase64CharacterException(String message) { + super(message); + } +} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/PropertySourceLocator.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/PropertySourceLocator.java deleted file mode 100644 index a04be177..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/PropertySourceLocator.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - */ -package org.springframework.cloud.config.client; - -import org.springframework.core.env.Environment; -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 - * - */ -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); - -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/RefreshEndpoint.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/RefreshEndpoint.java deleted file mode 100644 index 9a44c781..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/RefreshEndpoint.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * 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. - */ - -package org.springframework.cloud.config.client; - -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.springframework.boot.actuate.endpoint.AbstractEndpoint; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.cloud.context.environment.EnvironmentChangeEvent; -import org.springframework.cloud.context.scope.refresh.RefreshScope; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.EnumerablePropertySource; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.PropertySource; -import org.springframework.core.env.StandardEnvironment; -import org.springframework.jmx.export.annotation.ManagedOperation; -import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.web.context.support.StandardServletEnvironment; - -/** - * @author Dave Syer - * - */ -@ConfigurationProperties(prefix = "endpoints.refresh", ignoreUnknownFields = false) -@ManagedResource -public class RefreshEndpoint extends AbstractEndpoint> { - - private Set standardSources = new HashSet(Arrays.asList( - StandardEnvironment.SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, - StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, - StandardServletEnvironment.JNDI_PROPERTY_SOURCE_NAME, - StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME, - StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME)); - - private ConfigurableApplicationContext context; - - private RefreshScope scope; - - public RefreshEndpoint(ConfigurableApplicationContext context, RefreshScope scope) { - super("refresh"); - this.context = context; - this.scope = scope; - } - - @ManagedOperation - public synchronized String[] refresh() { - Map before = extract(context.getEnvironment().getPropertySources()); - addConfigFilesToEnvironment(); - Set keys = changes(before, - extract(context.getEnvironment().getPropertySources())).keySet(); - scope.refreshAll(); - if (keys.isEmpty()) { - return new String[0]; - } - context.publishEvent(new EnvironmentChangeEvent(keys)); - return keys.toArray(new String[keys.size()]); - } - - private void addConfigFilesToEnvironment() { - ConfigurableApplicationContext capture = new SpringApplicationBuilder(Empty.class).showBanner( - false).web(false).environment(context.getEnvironment()).run(); - MutablePropertySources target = context.getEnvironment().getPropertySources(); - for (PropertySource source : capture.getEnvironment().getPropertySources()) { - String name = source.getName(); - if (!standardSources.contains(name)) { - if (target.contains(name)) { - target.replace(name, source); - } else { - if (target.contains("defaultProperties")) { - target.addBefore("defaultProperties", source); - } else { - target.addLast(source); - } - } - } - } - } - - @Override - public Collection invoke() { - return Arrays.asList(refresh()); - } - - private Map changes(Map before, - Map after) { - Map result = new HashMap(); - for (String key : before.keySet()) { - if (!after.containsKey(key)) { - result.put(key, null); - } else if (!equal(before.get(key), after.get(key))) { - result.put(key, after.get(key)); - } - } - for (String key : after.keySet()) { - if (!before.containsKey(key)) { - result.put(key, after.get(key)); - } - } - return result; - } - - private boolean equal(Object one, Object two) { - if (one == null && two == null) { - return true; - } - if (one == null || two == null) { - return false; - } - return one.equals(two); - } - - private Map extract(MutablePropertySources propertySources) { - Map result = new HashMap(); - for (PropertySource parent : propertySources) { - if (!standardSources.contains(parent.getName())) { - extract(parent, result); - } - } - return result; - } - - private void extract(PropertySource parent, Map result) { - if (parent instanceof CompositePropertySource) { - try { - for (PropertySource source : ((CompositePropertySource) parent).getPropertySources()) { - extract(source, result); - } - } catch (Exception e) { - return; - } - } else if (parent instanceof EnumerablePropertySource) { - for (String key : ((EnumerablePropertySource) parent).getPropertyNames()) { - result.put(key, parent.getProperty(key)); - } - } - } - - @Configuration - protected static class Empty { - - } - -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/encrypt/EncryptorFactory.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/encrypt/EncryptorFactory.java deleted file mode 100644 index cf35be66..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/encrypt/EncryptorFactory.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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. - */ -package org.springframework.cloud.config.encrypt; - -import org.springframework.security.crypto.encrypt.Encryptors; -import org.springframework.security.crypto.encrypt.TextEncryptor; -import org.springframework.security.rsa.crypto.RsaSecretEncryptor; - -/** - * @author Dave Syer - * - */ -public class EncryptorFactory { - - // TODO: expose as config property - private static final String SALT = "deadbeef"; - - public TextEncryptor create(String data) { - - TextEncryptor encryptor; - if (data.contains("RSA PRIVATE KEY")) { - - try { - encryptor = new RsaSecretEncryptor(data); - } - catch (IllegalArgumentException e) { - throw new KeyFormatException(); - } - - } - else if (data.startsWith("ssh-rsa") || data.contains("RSA PUBLIC KEY")) { - throw new KeyFormatException(); - } - else { - encryptor = Encryptors.text(data, SALT); - } - - return encryptor; - } - -} - - diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/encrypt/KeyFormatException.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/encrypt/KeyFormatException.java deleted file mode 100644 index d1f0c557..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/encrypt/KeyFormatException.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ -package org.springframework.cloud.config.encrypt; - -@SuppressWarnings("serial") -public class KeyFormatException extends RuntimeException { -} \ No newline at end of file diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/config/BeanLifecycleDecorator.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/config/BeanLifecycleDecorator.java deleted file mode 100644 index 1488d095..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/config/BeanLifecycleDecorator.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2002-2011 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.config; - - -/** - * A helper interface providing optional decoration of bean instances and their - * destruction callbacks. Users can supply custom implementations of this - * strategy if they want tighter control over method invocation on the bean or - * its destruction callback. - * - * @param - * the type of auxiliary context object that can be passed between - * methods. Implementations can choose what type of data to supply as - * it is passed around unchanged by the caller. - * - * @author Dave Syer - * - */ -public interface BeanLifecycleDecorator { - - /** - * Optionally decorate and provide a new instance of a compatible bean for - * the caller to use instead of the input. - * - * @param bean - * the bean to optionally decorate - * @param context - * the context as created by - * {@link #decorateDestructionCallback(Runnable)} - * @return the replacement bean for the caller to use - */ - Object decorateBean(Object bean, Context context); - - /** - * Optionally decorate the destruction callback provided, and also return - * some context that can be used later by the - * {@link #decorateBean(Object, Context)} method. - * - * @param callback - * the destruction callback that will be used by the container - * @return a context wrapper - */ - Context decorateDestructionCallback(Runnable callback); - - static class Context { - - private final T auxiliary; - private final Runnable callback; - - public Context(Runnable callback, T auxiliary) { - this.callback = callback; - this.auxiliary = auxiliary; - } - - public Runnable getCallback() { - return callback; - } - - public T getAuxiliary() { - return auxiliary; - } - - } - -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/config/StandardBeanLifecycleDecorator.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/config/StandardBeanLifecycleDecorator.java deleted file mode 100644 index 32736f61..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/config/StandardBeanLifecycleDecorator.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2002-2011 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.config; - -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; - -import org.aopalliance.intercept.MethodInterceptor; -import org.aopalliance.intercept.MethodInvocation; -import org.springframework.aop.framework.ProxyFactory; - -/** - * A {@link BeanLifecycleDecorator} that tries to protect against concurrent access to a bean during its own destruction. - * A read-write lock is used, and method access is protected using the read lock, while the destruction callback is - * protected more strictly with the write lock. In this way concurrent access is possible to the bean as long as it is - * not being destroyed, in which case only one thread has access. If the bean has no destruction callback the lock and - * associated proxies are never created. - * - * @author Dave Syer - * - */ -public class StandardBeanLifecycleDecorator implements BeanLifecycleDecorator { - - private final boolean proxyTargetClass; - - public StandardBeanLifecycleDecorator(boolean proxyTargetClass) { - this.proxyTargetClass = proxyTargetClass; - } - - public Object decorateBean(Object bean, Context context) { - if (context != null) { - bean = getDisposalLockProxy(bean, context.getAuxiliary().readLock()); - } - return bean; - } - - public Context decorateDestructionCallback(final Runnable callback) { - if (callback == null) { - return null; - } - final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(); - return new Context(new Runnable() { - public void run() { - Lock lock = readWriteLock.writeLock(); - lock.lock(); - try { - callback.run(); - } finally { - lock.unlock(); - } - } - }, readWriteLock); - } - - /** - * Apply a lock (preferably a read lock allowing multiple concurrent access) to the bean. Callers should replace the - * bean input with the output. - * - * @param bean the bean to lock - * @param lock the lock to apply - * @return a proxy that locks while its methods are executed - */ - private Object getDisposalLockProxy(Object bean, final Lock lock) { - ProxyFactory factory = new ProxyFactory(bean); - factory.setProxyTargetClass(proxyTargetClass); - factory.addAdvice(new MethodInterceptor() { - public Object invoke(MethodInvocation invocation) throws Throwable { - lock.lock(); - try { - return invocation.proceed(); - } finally { - lock.unlock(); - } - } - }); - return factory.getProxy(); - } - -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/config/annotation/RefreshScope.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/config/annotation/RefreshScope.java deleted file mode 100644 index d46daa24..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/config/annotation/RefreshScope.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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. - */ -package org.springframework.cloud.context.config.annotation; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.context.annotation.Scope; -import org.springframework.context.annotation.ScopedProxyMode; - -/** - * Convenience annotation to put a @Bean definition in - * {@link org.springframework.cloud.context.scope.refresh.RefreshScope refresh scope}. - * Beans annotated this way can be refreshed at runtime and any components that are using - * them will get a new instance on the next method call, fully initialized and injected - * with all dependencies. - * - * @author Dave Syer - * - */ -@Target({ ElementType.TYPE, ElementType.METHOD }) -@Retention(RetentionPolicy.RUNTIME) -@Scope("refresh") -@Documented -public @interface RefreshScope { - /** - * @see Scope#proxyMode() - */ - ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS; - -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/environment/EnvironmentChangeEvent.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/environment/EnvironmentChangeEvent.java deleted file mode 100644 index d0fb5e50..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/environment/EnvironmentChangeEvent.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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. - */ -package org.springframework.cloud.context.environment; - -import java.util.Set; - -import org.springframework.context.ApplicationEvent; -import org.springframework.core.env.Environment; - -/** - * Event published to signal a change in the {@link Environment}. - * - * @author Dave Syer - * - */ -@SuppressWarnings("serial") -public class EnvironmentChangeEvent extends ApplicationEvent { - - private Set keys; - - public EnvironmentChangeEvent(Set keys) { - super(keys); - this.keys = keys; - } - - /** - * @return the keys - */ - public Set getKeys() { - return keys; - } - -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/environment/EnvironmentManager.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/environment/EnvironmentManager.java deleted file mode 100644 index 91e625cf..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/environment/EnvironmentManager.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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. - */ -package org.springframework.cloud.context.environment; - -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; - -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.ApplicationEventPublisherAware; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.Environment; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.jmx.export.annotation.ManagedOperation; -import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.stereotype.Component; - -/** - * Entry point for making local (but volatile) changes to the {@link Environment} of a - * running application. Allows properties to be added and values changed, simply by adding - * them to a high priority property source in the existing Environment. - * - * @author Dave Syer - * - */ -@Component -@ManagedResource -public class EnvironmentManager implements ApplicationEventPublisherAware { - - private static final String MANAGER_PROPERTY_SOURCE = "manager"; - private Map map = new LinkedHashMap(); - - private ConfigurableEnvironment environment; - private ApplicationEventPublisher publisher; - - public EnvironmentManager(ConfigurableEnvironment environment) { - this.environment = environment; - MutablePropertySources sources = environment.getPropertySources(); - if (sources.contains(MANAGER_PROPERTY_SOURCE)) { - @SuppressWarnings("unchecked") - Map map = (Map) sources.get( - MANAGER_PROPERTY_SOURCE).getSource(); - this.map = map; - } - } - - @Override - public void setApplicationEventPublisher(ApplicationEventPublisher publisher) { - this.publisher = publisher; - } - - @ManagedOperation - public Map reset() { - Map result = new LinkedHashMap(map); - if (!map.isEmpty()) { - Set keys = map.keySet(); - map.clear(); - publish(new EnvironmentChangeEvent(keys)); - } - return result; - } - - @ManagedOperation - public void setProperty(String name, String value) { - - if (!environment.getPropertySources().contains(MANAGER_PROPERTY_SOURCE)) { - synchronized (map) { - if (!environment.getPropertySources().contains(MANAGER_PROPERTY_SOURCE)) { - MapPropertySource source = new MapPropertySource( - MANAGER_PROPERTY_SOURCE, map); - environment.getPropertySources().addFirst(source); - } - } - } - - if (!value.equals(environment.getProperty(name))) { - map.put(name, value); - publish(new EnvironmentChangeEvent(Collections.singleton(name))); - } - - } - - @ManagedOperation - public Object getProperty(String name) { - return environment.getProperty(name); - } - - private void publish(EnvironmentChangeEvent environmentChangeEvent) { - if (publisher != null) { - publisher.publishEvent(environmentChangeEvent); - } - } - -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/environment/EnvironmentManagerMvcEndpoint.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/environment/EnvironmentManagerMvcEndpoint.java deleted file mode 100644 index 652b08bd..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/environment/EnvironmentManagerMvcEndpoint.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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. - */ -package org.springframework.cloud.context.environment; - -import java.util.Map; - -import org.springframework.boot.actuate.endpoint.Endpoint; -import org.springframework.boot.actuate.endpoint.EnvironmentEndpoint; -import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; - -/** - * MVC endpoint for the {@link EnvironmentManager} providing a POST to /env as a simple - * way to change the Environment. - * - * @author Dave Syer - * - */ -public class EnvironmentManagerMvcEndpoint implements MvcEndpoint { - - private EnvironmentManager environment; - private EnvironmentEndpoint delegate; - - public EnvironmentManagerMvcEndpoint(EnvironmentEndpoint delegate, - EnvironmentManager enviroment) { - this.delegate = delegate; - environment = enviroment; - } - - @RequestMapping(value = "", method = RequestMethod.POST) - @ResponseBody - public Object value(@RequestParam Map params) { - for (String name : params.keySet()) { - environment.setProperty(name, params.get(name)); - } - return params; - } - - @RequestMapping(value = "reset", method = RequestMethod.POST) - @ResponseBody - public Map reset() { - return environment.reset(); - } - - public void setEnvironmentManager(EnvironmentManager environment) { - this.environment = environment; - } - - @Override - public String getPath() { - return "/" + this.delegate.getId(); - } - - @Override - public boolean isSensitive() { - return this.delegate.isSensitive(); - } - - @Override - @SuppressWarnings("rawtypes") - public Class getEndpointType() { - return this.delegate.getClass(); - } -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinder.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinder.java deleted file mode 100644 index c0799857..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinder.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * 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. - */ -package org.springframework.cloud.context.properties; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.boot.context.properties.ConfigurationBeanFactoryMetaData; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.cloud.context.environment.EnvironmentChangeEvent; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.context.ApplicationListener; -import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.core.env.Environment; -import org.springframework.jmx.export.annotation.ManagedAttribute; -import org.springframework.jmx.export.annotation.ManagedOperation; -import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.stereotype.Component; - -/** - * Listens for {@link EnvironmentChangeEvent} and rebinds beans that were bound to the - * {@link Environment} using {@link ConfigurationProperties - * @ConfigurationProperties}. When these beans are re-bound and - * re-initialized the changes are available immediately to any component that is using the - * @ConfigurationProperties bean. - * - * @see RefreshScope for a deeper and optionally more focused refresh of bean components - * - * @author Dave Syer - * - */ -@Component -@ManagedResource -public class ConfigurationPropertiesRebinder implements BeanPostProcessor, - ApplicationListener, ApplicationContextAware { - - private ConfigurationBeanFactoryMetaData metaData; - - private ConfigurationPropertiesBindingPostProcessor binder; - - public ConfigurationPropertiesRebinder( - ConfigurationPropertiesBindingPostProcessor binder) { - this.binder = binder; - } - - private Map beans = new HashMap(); - - private ApplicationContext applicationContext; - - @Override - public void setApplicationContext(ApplicationContext applicationContext) - throws BeansException { - this.applicationContext = applicationContext; - } - - /** - * @param beans the bean meta data to set - */ - public void setBeanMetaDataStore(ConfigurationBeanFactoryMetaData beans) { - this.metaData = beans; - } - - @Override - public Object postProcessBeforeInitialization(Object bean, String beanName) - throws BeansException { - ConfigurationProperties annotation = AnnotationUtils.findAnnotation( - bean.getClass(), ConfigurationProperties.class); - if (annotation != null) { - beans.put(beanName, bean); - } - else if (metaData != null) { - annotation = this.metaData.findFactoryAnnotation(beanName, - ConfigurationProperties.class); - if (annotation != null) { - beans.put(beanName, bean); - } - } - return bean; - } - - @Override - public Object postProcessAfterInitialization(Object bean, String beanName) - throws BeansException { - return bean; - } - - @ManagedOperation - public void rebind() { - for (String name : beans.keySet()) { - rebind(name); - } - } - - @ManagedOperation - public void rebind(String name) { - binder.postProcessBeforeInitialization(beans.get(name), name); - if (applicationContext != null) { - applicationContext.getAutowireCapableBeanFactory().initializeBean( - beans.get(name), name); - } - } - - @ManagedAttribute - public Set getBeanNames() { - return new HashSet(beans.keySet()); - } - - @Override - public void onApplicationEvent(EnvironmentChangeEvent event) { - rebind(); - } - -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/restart/RestartEndpoint.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/restart/RestartEndpoint.java deleted file mode 100644 index 5c4f0e99..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/restart/RestartEndpoint.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * 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. - */ - -package org.springframework.cloud.context.restart; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.actuate.endpoint.AbstractEndpoint; -import org.springframework.boot.actuate.endpoint.Endpoint; -import org.springframework.boot.context.event.ApplicationPreparedEvent; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationListener; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.integration.monitor.IntegrationMBeanExporter; -import org.springframework.jmx.export.annotation.ManagedAttribute; -import org.springframework.jmx.export.annotation.ManagedOperation; -import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.util.ClassUtils; - -/** - * An endpoint that restarts the application context. Install as a bean and also register - * a {@link RestartListener} with the {@link SpringApplication} that starts the context. - * Those two components communicate via an {@link ApplicationEvent} and set up the state - * needed to restart the context. - * - * @author Dave Syer - * - */ -@ConfigurationProperties("endpoints.restart") -@ManagedResource -public class RestartEndpoint extends AbstractEndpoint implements - ApplicationListener { - - private static Log logger = LogFactory.getLog(RestartEndpoint.class); - - public RestartEndpoint() { - super("restart", true, false); - } - - private ConfigurableApplicationContext context; - - private SpringApplication application; - - private String[] args; - - private ApplicationPreparedEvent event; - - private IntegrationShutdown integrationShutdown; - - private long timeout; - - @ManagedAttribute - public long getTimeout() { - return timeout; - } - - public void setTimeout(long timeout) { - this.timeout = timeout; - } - - public void setIntegrationMBeanExporter(Object exporter) { - if (exporter != null) { - this.integrationShutdown = new IntegrationShutdown(exporter); - } - } - - @Override - public void onApplicationEvent(ApplicationPreparedEvent input) { - event = (ApplicationPreparedEvent) input; - if (context == null) { - context = event.getApplicationContext(); - args = event.getArgs(); - application = event.getSpringApplication(); - } - } - - @Override - public Boolean invoke() { - try { - restart(); - logger.info("Restarted"); - return true; - } catch (Exception e) { - if (logger.isDebugEnabled()) { - logger.info("Could not restart", e); - } else { - logger.info("Could not restart: " + e.getMessage()); - } - return false; - } - } - - public Endpoint getPauseEndpoint() { - return new PauseEndpoint(); - } - - public Endpoint getResumeEndpoint() { - return new ResumeEndpoint(); - } - - private class PauseEndpoint extends AbstractEndpoint { - - public PauseEndpoint() { - super("pause", true, true); - } - - @Override - public Boolean invoke() { - if (isRunning()) { - pause(); - return true; - } - return false; - } - } - - private class ResumeEndpoint extends AbstractEndpoint { - - public ResumeEndpoint() { - super("resume", true, true); - } - - @Override - public Boolean invoke() { - if (!isRunning()) { - resume(); - return true; - } - return false; - } - } - - @ManagedOperation - public synchronized ConfigurableApplicationContext restart() { - if (context != null) { - if (integrationShutdown != null) { - integrationShutdown.stop(timeout); - } - application.setEnvironment(context.getEnvironment()); - context.close(); - // If running in a webapp then the context classloader is probably going to - // die so we need to revert to a safe place before starting again - overrideClassLoaderForRestart(); - context = application.run(args); - } - return context; - } - - @ManagedAttribute - public boolean isRunning() { - if (context != null) { - return context.isRunning(); - } - return false; - } - - @ManagedOperation - public synchronized void pause() { - if (context != null) { - context.stop(); - } - } - - @ManagedOperation - public synchronized void resume() { - if (context != null) { - context.start(); - } - } - - private void overrideClassLoaderForRestart() { - ClassUtils.overrideThreadContextClassLoader(application.getClass().getClassLoader()); - } - - private class IntegrationShutdown { - - private IntegrationMBeanExporter exporter; - - public IntegrationShutdown(Object exporter) { - this.exporter = (IntegrationMBeanExporter) exporter; - } - - public void stop(long timeout) { - exporter.stopActiveComponents(timeout); - } - } - -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/restart/RestartListener.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/restart/RestartListener.java deleted file mode 100644 index 4dcad0ad..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/restart/RestartListener.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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. - */ - -package org.springframework.cloud.context.restart; - -import org.springframework.boot.context.event.ApplicationPreparedEvent; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.event.ContextClosedEvent; -import org.springframework.context.event.ContextRefreshedEvent; -import org.springframework.context.event.SmartApplicationListener; - -/** - * A listener that stores enough information about an application as it starts, to be able - * to restart it later if needed. - * - * @author Dave Syer - * - */ -public class RestartListener implements SmartApplicationListener { - - private ConfigurableApplicationContext context; - - private ApplicationPreparedEvent event; - - @Override - public int getOrder() { - return 0; - } - - @Override - public boolean supportsEventType(Class eventType) { - return ApplicationPreparedEvent.class.isAssignableFrom(eventType) - || ContextRefreshedEvent.class.isAssignableFrom(eventType) - || ContextClosedEvent.class.isAssignableFrom(eventType); - - } - - @Override - public boolean supportsSourceType(Class sourceType) { - return true; - } - - @Override - public void onApplicationEvent(ApplicationEvent input) { - if (input instanceof ApplicationPreparedEvent) { - event = (ApplicationPreparedEvent) input; - if (context == null) { - context = event.getApplicationContext(); - } - } - else if (input instanceof ContextRefreshedEvent) { - if (context != null && input.getSource().equals(context) && event != null) { - context.publishEvent(event); - } - } - else { - if (context != null && input.getSource().equals(context)) { - context = null; - } - } - } - -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/restart/RestartMvcEndpoint.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/restart/RestartMvcEndpoint.java deleted file mode 100644 index ab8b32e9..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/restart/RestartMvcEndpoint.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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. - */ -package org.springframework.cloud.context.restart; - -import java.util.Collections; -import java.util.Map; - -import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter; -import org.springframework.boot.actuate.endpoint.mvc.MvcEndpoint; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.cloud.endpoint.GenericPostableMvcEndpoint; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; - -/** - * MVC endpoint to allow an application to be restarted on a POST (to /restart by - * default). - * - * @author Dave Syer - * - */ -public class RestartMvcEndpoint extends EndpointMvcAdapter { - - public RestartMvcEndpoint(RestartEndpoint delegate) { - super(delegate); - } - - @RequestMapping(method = RequestMethod.POST) - @ResponseBody - @Override - public Object invoke() { - if (!getDelegate().isEnabled()) { - return new ResponseEntity>(Collections.singletonMap( - "message", "This endpoint is disabled"), HttpStatus.NOT_FOUND); - } - Thread thread = new Thread(new Runnable() { - @Override - public void run() { - RestartMvcEndpoint.super.invoke(); - } - }); - thread.setDaemon(false); - thread.start(); - return Collections.singletonMap("message", "Restarting"); - } - - public MvcEndpoint getPauseEndpoint() { - return new GenericPostableMvcEndpoint( - ((RestartEndpoint) getDelegate()).getPauseEndpoint()); - } - - public MvcEndpoint getResumeEndpoint() { - return new GenericPostableMvcEndpoint( - ((RestartEndpoint) getDelegate()).getResumeEndpoint()); - } - -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/scope/GenericScope.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/scope/GenericScope.java deleted file mode 100644 index b28c72fe..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/scope/GenericScope.java +++ /dev/null @@ -1,354 +0,0 @@ -/* - * 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. - */ - -package org.springframework.cloud.context.scope; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.UUID; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.ObjectFactory; -import org.springframework.beans.factory.config.BeanFactoryPostProcessor; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.config.Scope; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; -import org.springframework.cloud.context.config.BeanLifecycleDecorator; -import org.springframework.cloud.context.config.BeanLifecycleDecorator.Context; -import org.springframework.cloud.context.config.StandardBeanLifecycleDecorator; -import org.springframework.expression.Expression; -import org.springframework.expression.ExpressionParser; -import org.springframework.expression.ParseException; -import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.expression.spel.support.StandardEvaluationContext; -import org.springframework.util.StringUtils; - -/** - *

- * A generic Scope implementation. - *

- * - * @author Dave Syer - * - * @since 3.1 - * - */ -public class GenericScope implements Scope, BeanFactoryPostProcessor, DisposableBean { - - private static final Log logger = LogFactory.getLog(GenericScope.class); - - public static final String SCOPED_TARGET_PREFIX = "scopedTarget."; - - private BeanLifecycleWrapperCache cache = new BeanLifecycleWrapperCache( - new StandardScopeCache()); - - private String name = "generic"; - - private boolean proxyTargetClass = true; - - private ConfigurableListableBeanFactory beanFactory; - - private StandardEvaluationContext evaluationContext; - - private String id; - - private BeanLifecycleDecorator lifecycle; - - /** - * 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 "refresh". - * - * @param name the name value to set - */ - public void setName(String name) { - this.name = name; - } - - /** - * Flag to indicate that proxies should be created for the concrete type, not just the - * interfaces, of the scoped beans. - * - * @param proxyTargetClass the flag value to set - */ - public void setProxyTargetClass(boolean proxyTargetClass) { - this.proxyTargetClass = proxyTargetClass; - } - - /** - * The cache implementation to use for bean instances in this scope. - * - * @param cache the cache to use - */ - public void setScopeCache(ScopeCache cache) { - this.cache = new BeanLifecycleWrapperCache(cache); - } - - /** - * Helper to manage the creation and destruction of beans. - * - * @param lifecycle the bean lifecycle to set - */ - public void setBeanLifecycleManager(BeanLifecycleDecorator lifecycle) { - this.lifecycle = lifecycle; - } - - public void destroy() { - List errors = new ArrayList(); - Collection wrappers = cache.clear(); - for (BeanLifecycleWrapper wrapper : wrappers) { - try { - wrapper.destroy(); - } - catch (RuntimeException e) { - errors.add(e); - } - } - if (!errors.isEmpty()) { - throw wrapIfNecessary(errors.get(0)); - } - } - - protected void destroy(String name) { - BeanLifecycleWrapper wrapper = cache.remove(name); - if (wrapper != null) { - wrapper.destroy(); - } - } - - public Object get(String name, ObjectFactory objectFactory) { - if (lifecycle == null) { - lifecycle = new StandardBeanLifecycleDecorator(proxyTargetClass); - } - BeanLifecycleWrapper value = cache.put(name, new BeanLifecycleWrapper(name, - objectFactory, lifecycle)); - return value.getBean(); - } - - public String getConversationId() { - return name; - } - - public void registerDestructionCallback(String name, Runnable callback) { - BeanLifecycleWrapper value = cache.get(name); - if (value == null) { - return; - } - value.setDestroyCallback(callback); - } - - public Object remove(String name) { - BeanLifecycleWrapper value = cache.remove(name); - if (value == null) { - return null; - } - // Someone might have added another object with the same key, but we - // keep the method contract by removing the - // value we found anyway - return value.getBean(); - } - - public Object resolveContextualObject(String key) { - Expression expression = parseExpression(key); - return expression.getValue(evaluationContext, beanFactory); - } - - private Expression parseExpression(String input) { - if (StringUtils.hasText(input)) { - ExpressionParser parser = new SpelExpressionParser(); - try { - return parser.parseExpression(input); - } - catch (ParseException e) { - throw new IllegalArgumentException("Cannot parse expression: " + input, e); - } - - } - else { - return null; - } - } - - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) - throws BeansException { - beanFactory.registerScope(name, this); - setSerializationId(beanFactory); - } - - /** - * If the bean factory is a DefaultListableBeanFactory then it can serialize scoped - * beans and deserialize them in another context (even in another JVM), as long as the - * 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) { - - if (beanFactory instanceof DefaultListableBeanFactory) { - - String id = this.id; - if (id == null) { - String names = Arrays.asList(beanFactory.getBeanDefinitionNames()) - .toString(); - logger.debug("Generating bean factory id from names: " + names); - id = UUID.nameUUIDFromBytes(names.getBytes()).toString(); - } - - logger.info("BeanFactory id=" + id); - ((DefaultListableBeanFactory) beanFactory).setSerializationId(id); - - } - else { - logger.warn("BeanFactory was not a DefaultListableBeanFactory, so RefreshScope beans " - + "cannot be serialized reliably and passed to a remote JVM."); - } - - } - - static RuntimeException wrapIfNecessary(Throwable throwable) { - if (throwable instanceof RuntimeException) { - return (RuntimeException) throwable; - } - if (throwable instanceof Error) { - throw (Error) throwable; - } - return new IllegalStateException(throwable); - } - - private static class BeanLifecycleWrapperCache { - - private final ScopeCache cache; - - public BeanLifecycleWrapperCache(ScopeCache cache) { - this.cache = cache; - } - - public BeanLifecycleWrapper remove(String name) { - return (BeanLifecycleWrapper) cache.remove(name); - } - - public Collection clear() { - Collection values = cache.clear(); - Collection wrappers = new LinkedHashSet(); - for (Object object : values) { - wrappers.add((BeanLifecycleWrapper) object); - } - return wrappers; - } - - public BeanLifecycleWrapper get(String name) { - return (BeanLifecycleWrapper) cache.get(name); - } - - public BeanLifecycleWrapper put(String name, BeanLifecycleWrapper value) { - return (BeanLifecycleWrapper) cache.put(name, (Object) value); - } - - } - - /** - * Wrapper for a bean instance and any destruction callback (DisposableBean etc.) that - * is registered for it. Also decorates the bean to optionally guard it from - * concurrent access (for instance). - * - * @author Dave Syer - * - */ - private static class BeanLifecycleWrapper { - - private Object bean; - - private Context context; - - private final String name; - - @SuppressWarnings("rawtypes") - private final BeanLifecycleDecorator lifecycle; - - private final ObjectFactory objectFactory; - - @SuppressWarnings("rawtypes") - public BeanLifecycleWrapper(String name, ObjectFactory objectFactory, - BeanLifecycleDecorator lifecycle) { - this.name = name; - this.objectFactory = objectFactory; - this.lifecycle = lifecycle; - } - - public void setDestroyCallback(Runnable callback) { - this.context = lifecycle.decorateDestructionCallback(callback); - } - - @SuppressWarnings("unchecked") - public Object getBean() { - if (bean == null) { - bean = lifecycle.decorateBean(objectFactory.getObject(), context); - } - return bean; - } - - public void destroy() { - if (context == null) { - return; - } - Runnable callback = context.getCallback(); - if (callback != null) { - callback.run(); - } - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - BeanLifecycleWrapper other = (BeanLifecycleWrapper) obj; - if (name == null) { - if (other.name != null) - return false; - } - else if (!name.equals(other.name)) - return false; - return true; - } - - } - -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/scope/ScopeCache.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/scope/ScopeCache.java deleted file mode 100644 index 1be557c0..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/scope/ScopeCache.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2002-2011 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; - -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 - * implementations should be thread safe. - * - * @author Dave Syer - * - */ -public interface ScopeCache { - - /** - * Remove the object with this name from the cache. - * - * @param name the object name - * @return the object removed or null if there was none - */ - Object remove(String name); - - /** - * Clear the cache and return all objects in an unmodifiable collection. - * - * @return all objects stored in the cache - */ - Collection clear(); - - /** - * Get 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. - * - * @param name the key - * @param value the new candidate value - * @return the value that is in the cache at the end of the operation - */ - Object put(String name, Object value); - -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/scope/StandardScopeCache.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/scope/StandardScopeCache.java deleted file mode 100644 index e3591a0d..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/scope/StandardScopeCache.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2002-2011 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; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.concurrent.ConcurrentHashMap; -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 cache = new ConcurrentHashMap(); - - public Object remove(String name) { - return cache.remove(name); - } - - public Collection clear() { - Collection values = new ArrayList(cache.values()); - cache.clear(); - return values; - } - - public Object get(String name) { - return cache.get(name); - } - - public Object put(String name, Object value) { - Object result = cache.putIfAbsent(name, value); - if (result!=null) { - return result; - } - return value; - } - -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/scope/refresh/RefreshScope.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/scope/refresh/RefreshScope.java deleted file mode 100644 index 953e5103..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/scope/refresh/RefreshScope.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * 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. - */ - -package org.springframework.cloud.context.scope.refresh; - -import java.io.Serializable; - -import org.springframework.beans.BeansException; -import org.springframework.cloud.context.scope.GenericScope; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationContextAware; -import org.springframework.jmx.export.annotation.ManagedOperation; -import org.springframework.jmx.export.annotation.ManagedResource; - -/** - *

- * A Scope implementation that allows for beans to be refreshed dynamically at runtime (see {@link #refresh(String)} and - * {@link #refreshAll()}). If a bean is refreshed then the next time the bean is accessed (i.e. a method is executed) a - * new instance is created. All lifecycle methods are applied to the bean instances, so any destruction callbacks that - * were registered in the bean factory are called when it is refreshed, and then the initialization callbacks are - * invoked as normal when the new instance is created. A new bean instance is created from the original bean definition, - * so any externalized content (property placeholders or expressions in string literals) is re-evaluated when it is - * created. - *

- * - *

- * Note that all beans in this scope are only initialized when first accessed, so the scope forces lazy - * initialization semantics. The implementation involves creating a proxy for every bean in the scope, so there is a - * flag {@link #setProxyTargetClass(boolean) proxyTargetClass} which controls the proxy creation, defaulting to JDK - * dynamic proxies and therefore only exposing the interfaces implemented by a bean. If callers need access to other - * methods then the flag needs to be set (and CGLib present on the classpath). Because this scope automatically proxies - * all its beans, there is no need to add <aop:auto-proxy/> to any bean definitions. - *

- * - *

- * The scoped proxy approach adopted here has a side benefit that bean instances are automatically {@link Serializable}, - * and can be sent across the wire as long as the receiver has an identical application context on the other side. To - * ensure that the two contexts agree that they are identical they have to have the same serialization id. One will be - * generated automatically by default from the bean names, so two contexts with the same bean names are by default able - * to exchange beans by name. If you need to override the default id then provide an explicit {@link #setId(String) id} - * when the Scope is declared. - *

- * - * @author Dave Syer - * - * @since 3.1 - * - */ -@ManagedResource -public class RefreshScope extends GenericScope implements ApplicationContextAware { - - private ApplicationContext context; - - /** - * Create a scope instance and give it the default name: "refresh". - */ - public RefreshScope() { - super(); - super.setName("refresh"); - } - - @ManagedOperation(description = "Dispose of the current instance of bean name provided and force a refresh on next method execution.") - public void 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 cache... - name = SCOPED_TARGET_PREFIX + name; - } - // Ensure lifecycle is finished if bean was disposable - super.destroy(name); - context.publishEvent(new RefreshScopeRefreshedEvent(name)); - } - - @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(); - context.publishEvent(new RefreshScopeRefreshedEvent()); - } - - @Override - public void setApplicationContext(ApplicationContext context) throws BeansException { - this.context = context; - } -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/scope/refresh/RefreshScopeRefreshedEvent.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/scope/refresh/RefreshScopeRefreshedEvent.java deleted file mode 100644 index 0216108d..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/scope/refresh/RefreshScopeRefreshedEvent.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.springframework.cloud.context.scope.refresh; - -import org.springframework.context.ApplicationEvent; - -/** - * @author Spencer Gibb - */ -@SuppressWarnings("serial") -public class RefreshScopeRefreshedEvent extends ApplicationEvent { - public static final String DEFAULT_NAME = "__refreshAll__"; - private String name; - - public RefreshScopeRefreshedEvent() { - this(DEFAULT_NAME); - } - - public RefreshScopeRefreshedEvent(String name) { - super(name); - this.name = name; - } - - public String getName() { - return name; - } -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/scope/thread/ThreadLocalScopeCache.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/scope/thread/ThreadLocalScopeCache.java deleted file mode 100644 index c140d63d..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/scope/thread/ThreadLocalScopeCache.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2002-2011 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; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -import org.springframework.cloud.context.scope.ScopeCache; - -/** - * @author Dave Syer - * - */ -public class ThreadLocalScopeCache implements ScopeCache { - - private ThreadLocal> data = new ThreadLocal>() { - protected ConcurrentMap initialValue() { - return new ConcurrentHashMap(); - } - }; - - public Object remove(String name) { - return data.get().remove(name); - } - - public Collection clear() { - ConcurrentMap map = data.get(); - Collection values = new ArrayList(map.values()); - map.clear(); - return values; - } - - public Object get(String name) { - return data.get().get(name); - } - - public Object put(String name, Object value) { - Object result = data.get().putIfAbsent(name, value); - if (result!=null) { - return result; - } - return value; - } - -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/scope/thread/ThreadScope.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/scope/thread/ThreadScope.java deleted file mode 100644 index 8637cd2b..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/context/scope/thread/ThreadScope.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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. - */ - -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 { - - /** - * Create a scope instance and give it the default name: "thread". - */ - public ThreadScope() { - super(); - super.setName("thread"); - super.setScopeCache(new ThreadLocalScopeCache()); - } - -} diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/endpoint/GenericPostableMvcEndpoint.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/endpoint/GenericPostableMvcEndpoint.java deleted file mode 100644 index b9547e03..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/endpoint/GenericPostableMvcEndpoint.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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. - */ -package org.springframework.cloud.endpoint; - -import java.util.Collections; -import java.util.Map; - -import org.springframework.boot.actuate.endpoint.Endpoint; -import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; - -/** - * A convenient base class for MVC endpoints that accept a POST (instead of the default - * GET). - * - * @author Dave Syer - * - */ -public class GenericPostableMvcEndpoint extends EndpointMvcAdapter { - - public GenericPostableMvcEndpoint(Endpoint delegate) { - super(delegate); - } - - @RequestMapping(method = RequestMethod.POST) - @ResponseBody - @Override - public Object invoke() { - if (!getDelegate().isEnabled()) { - return new ResponseEntity>(Collections.singletonMap( - "message", "This endpoint is disabled"), HttpStatus.NOT_FOUND); - } - return super.invoke(); - } - -} \ No newline at end of file diff --git a/spring-cloud-config-client/src/main/java/org/springframework/cloud/logging/LoggingRebinder.java b/spring-cloud-config-client/src/main/java/org/springframework/cloud/logging/LoggingRebinder.java deleted file mode 100644 index b67cdb40..00000000 --- a/spring-cloud-config-client/src/main/java/org/springframework/cloud/logging/LoggingRebinder.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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. - */ -package org.springframework.cloud.logging; - -import java.util.Map; -import java.util.Map.Entry; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.springframework.boot.bind.RelaxedPropertyResolver; -import org.springframework.boot.logging.LogLevel; -import org.springframework.boot.logging.LoggingSystem; -import org.springframework.cloud.context.environment.EnvironmentChangeEvent; -import org.springframework.context.ApplicationListener; -import org.springframework.context.EnvironmentAware; -import org.springframework.core.env.Environment; - -/** - * Listener that looks for {@link EnvironmentChangeEvent} and rebinds logger levels if any - * changed. - * - * @author Dave Syer - * - */ -public class LoggingRebinder implements ApplicationListener, - EnvironmentAware { - - private final Log logger = LogFactory.getLog(getClass()); - - private Environment environment; - - @Override - public void setEnvironment(Environment environment) { - this.environment = environment; - } - - @Override - public void onApplicationEvent(EnvironmentChangeEvent event) { - if (environment == null) { - return; - } - LoggingSystem system = LoggingSystem.get(LoggingSystem.class.getClassLoader()); - setLogLevels(system, environment); - } - - protected void setLogLevels(LoggingSystem system, Environment environment) { - Map levels = new RelaxedPropertyResolver(environment) - .getSubProperties("logging.level."); - for (Entry entry : levels.entrySet()) { - setLogLevel(system, environment, entry.getKey(), entry.getValue().toString()); - } - } - - private void setLogLevel(LoggingSystem system, Environment environment, String name, - String level) { - try { - if (name.equalsIgnoreCase("root")) { - name = null; - } - level = environment.resolvePlaceholders(level); - system.setLogLevel(name, LogLevel.valueOf(level)); - } - catch (RuntimeException ex) { - this.logger.error("Cannot set level: " + level + " for '" + name + "'"); - } - } - -} diff --git a/spring-cloud-config-client/src/main/resources/META-INF/spring.factories b/spring-cloud-config-client/src/main/resources/META-INF/spring.factories index 9d136e43..8f2ccf02 100644 --- a/spring-cloud-config-client/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-config-client/src/main/resources/META-INF/spring.factories @@ -1,16 +1,7 @@ # Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.springframework.cloud.autoconfigure.RefreshAutoConfiguration,\ -org.springframework.cloud.autoconfigure.LifecycleMvcEndpointAutoConfiguration,\ -org.springframework.cloud.autoconfigure.ConfigClientAutoConfiguration - -# Application Listeners -org.springframework.context.ApplicationListener=\ -org.springframework.cloud.bootstrap.BootstrapApplicationListener,\ -org.springframework.cloud.context.restart.RestartListener +org.springframework.cloud.config.client.ConfigClientAutoConfiguration # Bootstrap components org.springframework.cloud.bootstrap.BootstrapConfiguration=\ -org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration,\ -org.springframework.cloud.bootstrap.encrypt.EncryptionBootstrapConfiguration,\ -org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration \ No newline at end of file +org.springframework.cloud.config.client.ConfigServiceBootstrapConfiguration \ No newline at end of file diff --git a/spring-cloud-config-client/src/test/java/org/springframework/cloud/autoconfigure/ConfigClientAutoConfigurationTests.java b/spring-cloud-config-client/src/test/java/org/springframework/cloud/autoconfigure/ConfigClientAutoConfigurationTests.java index a6129a17..47cb5240 100644 --- a/spring-cloud-config-client/src/test/java/org/springframework/cloud/autoconfigure/ConfigClientAutoConfigurationTests.java +++ b/spring-cloud-config-client/src/test/java/org/springframework/cloud/autoconfigure/ConfigClientAutoConfigurationTests.java @@ -5,9 +5,8 @@ import static org.junit.Assert.assertEquals; import org.junit.Test; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration; +import org.springframework.cloud.config.client.ConfigClientAutoConfiguration; import org.springframework.cloud.config.client.ConfigClientProperties; -import org.springframework.cloud.config.client.ConfigServerHealthIndicator; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; @@ -31,16 +30,4 @@ public class ConfigClientAutoConfigurationTests { context.close(); } - @Test - public void withHealthIndicator() { - ConfigurableApplicationContext context = new SpringApplicationBuilder( - PropertySourceBootstrapConfiguration.class) - .child(ConfigClientAutoConfiguration.class).web(false).run(); - assertEquals(1, BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context, - ConfigClientProperties.class).length); - assertEquals(1, BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context, - ConfigServerHealthIndicator.class).length); - context.close(); - } - } diff --git a/spring-cloud-config-client/src/test/java/org/springframework/cloud/autoconfigure/ConfigServerBootstrapConfigurationTests.java b/spring-cloud-config-client/src/test/java/org/springframework/cloud/autoconfigure/ConfigServerBootstrapConfigurationTests.java new file mode 100644 index 00000000..7fa45273 --- /dev/null +++ b/spring-cloud-config-client/src/test/java/org/springframework/cloud/autoconfigure/ConfigServerBootstrapConfigurationTests.java @@ -0,0 +1,29 @@ +package org.springframework.cloud.autoconfigure; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.springframework.beans.factory.BeanFactoryUtils; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration; +import org.springframework.cloud.config.client.ConfigClientAutoConfiguration; +import org.springframework.cloud.config.client.ConfigClientProperties; +import org.springframework.cloud.config.client.ConfigServerHealthIndicator; +import org.springframework.cloud.config.client.ConfigServiceBootstrapConfiguration; +import org.springframework.context.ConfigurableApplicationContext; + +public class ConfigServerBootstrapConfigurationTests { + + @Test + public void withHealthIndicator() { + ConfigurableApplicationContext context = new SpringApplicationBuilder( + PropertySourceBootstrapConfiguration.class, ConfigServiceBootstrapConfiguration.class) + .child(ConfigClientAutoConfiguration.class).web(false).run(); + assertEquals(1, BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context, + ConfigClientProperties.class).length); + assertEquals(1, BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context, + ConfigServerHealthIndicator.class).length); + context.close(); + } + +} diff --git a/spring-cloud-config-client/src/test/java/org/springframework/cloud/bootstrap/BootstrapDisabledAutoConfigurationIntegrationTests.java b/spring-cloud-config-client/src/test/java/org/springframework/cloud/bootstrap/BootstrapDisabledAutoConfigurationIntegrationTests.java deleted file mode 100644 index 0a11c681..00000000 --- a/spring-cloud-config-client/src/test/java/org/springframework/cloud/bootstrap/BootstrapDisabledAutoConfigurationIntegrationTests.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.springframework.cloud.bootstrap; - -import static org.junit.Assert.assertFalse; - -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.IntegrationTest; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.cloud.bootstrap.BootstrapDisabledAutoConfigurationIntegrationTests.Application; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes = Application.class) -@IntegrationTest("spring.cloud.bootstrap.enabled:false") -public class BootstrapDisabledAutoConfigurationIntegrationTests { - - @Autowired - private ConfigurableEnvironment environment; - - @Test - public void noBootstrapProperties() { - assertFalse(environment.getPropertySources().contains("bootstrap")); - } - - @EnableAutoConfiguration - @Configuration - protected static class Application { - - } - -} diff --git a/spring-cloud-config-client/src/test/java/org/springframework/cloud/bootstrap/BootstrapOrderingAutoConfigurationIntegrationTests.java b/spring-cloud-config-client/src/test/java/org/springframework/cloud/bootstrap/BootstrapOrderingAutoConfigurationIntegrationTests.java deleted file mode 100644 index 74a4a66c..00000000 --- a/spring-cloud-config-client/src/test/java/org/springframework/cloud/bootstrap/BootstrapOrderingAutoConfigurationIntegrationTests.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.springframework.cloud.bootstrap; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -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.IntegrationTest; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.cloud.bootstrap.BootstrapOrderingAutoConfigurationIntegrationTests.Application; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes = Application.class) -@IntegrationTest("encrypt.key:deadbeef") -@ActiveProfiles("encrypt") -public class BootstrapOrderingAutoConfigurationIntegrationTests { - - @Autowired - private ConfigurableEnvironment environment; - - @Test - public void bootstrapPropertiesExist() { - assertTrue(environment.getPropertySources().contains("bootstrap")); - } - - @Test - public void normalPropertiesDecrypted() { - assertEquals("foo", environment.resolvePlaceholders("${foo}")); - } - - @Test - public void bootstrapPropertiesDecrypted() { - assertEquals("bar", environment.resolvePlaceholders("${bar}")); - } - - @EnableAutoConfiguration - @Configuration - protected static class Application { - - } - -} diff --git a/spring-cloud-config-client/src/test/java/org/springframework/cloud/bootstrap/config/BootstrapConfigurationTests.java b/spring-cloud-config-client/src/test/java/org/springframework/cloud/bootstrap/config/BootstrapConfigurationTests.java deleted file mode 100644 index 49e86987..00000000 --- a/spring-cloud-config-client/src/test/java/org/springframework/cloud/bootstrap/config/BootstrapConfigurationTests.java +++ /dev/null @@ -1,320 +0,0 @@ -/* - * 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. - */ - -package org.springframework.cloud.bootstrap.config; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.junit.After; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.config.client.ConfigClientProperties; -import org.springframework.cloud.config.client.PropertySourceLocator; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.Environment; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.PropertySource; -import org.springframework.core.env.StandardEnvironment; - -/** - * @author Dave Syer - * - */ -public class BootstrapConfigurationTests { - - private ConfigurableApplicationContext context; - - @Rule - public ExpectedException expected = ExpectedException.none(); - - @After - public void close() { - // Expected.* is bound to the PropertySourceConfiguration below - System.clearProperty("expected.name"); - System.clearProperty("expected.fail"); - // Used to test system properties override - System.clearProperty("bootstrap.foo"); - PropertySourceConfiguration.MAP.clear(); - if (context != null) { - context.close(); - } - } - - @Test - public void pickupExternalBootstrapProperties() { - String externalPropertiesPath = getExternalProperties(); - - context = new SpringApplicationBuilder().web(false) - .sources(BareConfiguration.class) - .properties("spring.cloud.bootstrap.location:" + externalPropertiesPath) - .run(); - assertEquals("externalPropertiesInfoName", - context.getEnvironment().getProperty("info.name")); - assertTrue(context.getEnvironment().getPropertySources().contains("bootstrap")); - assertNotNull(context.getBean(ConfigClientProperties.class)); - } - - /** - * Running the test from maven will start from a different directory then starting it - * from intellij - * - * @return - */ - private String getExternalProperties() { - String externalPropertiesPath = ""; - File externalProperties = new File( - "src/test/resources/external-properties/bootstrap.properties"); - if (externalProperties.exists()) { - externalPropertiesPath = externalProperties.getAbsolutePath(); - } - else { - externalProperties = new File( - "spring-cloud-config-client/src/test/resources/external-properties/bootstrap.properties"); - externalPropertiesPath = externalProperties.getAbsolutePath(); - } - return externalPropertiesPath; - } - - @Test - public void picksUpAdditionalPropertySource() { - PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar"); - System.setProperty("expected.name", "bootstrap"); - context = new SpringApplicationBuilder().web(false) - .sources(BareConfiguration.class).run(); - assertEquals("bar", context.getEnvironment().getProperty("bootstrap.foo")); - assertTrue(context.getEnvironment().getPropertySources().contains("bootstrap")); - assertNotNull(context.getBean(ConfigClientProperties.class)); - } - - @Test - public void failsOnPropertySource() { - System.setProperty("expected.fail", "true"); - expected.expectMessage("Planned"); - context = new SpringApplicationBuilder().web(false) - .sources(BareConfiguration.class).run(); - } - - @Test - public void overrideSystemPropertySourceByDefault() { - PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar"); - System.setProperty("bootstrap.foo", "system"); - context = new SpringApplicationBuilder().web(false) - .sources(BareConfiguration.class).run(); - assertEquals("bar", context.getEnvironment().getProperty("bootstrap.foo")); - } - - @Test - public void systemPropertyOverrideFalse() { - PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar"); - PropertySourceConfiguration.MAP.put( - "spring.cloud.config.overrideSystemProperties", "false"); - System.setProperty("bootstrap.foo", "system"); - context = new SpringApplicationBuilder().web(false) - .sources(BareConfiguration.class).run(); - assertEquals("system", context.getEnvironment().getProperty("bootstrap.foo")); - } - - @Test - public void systemPropertyOverrideWhenOverrideDisallowed() { - PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar"); - PropertySourceConfiguration.MAP.put( - "spring.cloud.config.overrideSystemProperties", "false"); - // If spring.cloud.config.allowOverride=false is in the remote property sources - // with sufficiently high priority it always wins. Admins can enforce it by adding - // their own remote property source. - PropertySourceConfiguration.MAP.put("spring.cloud.config.allowOverride", "false"); - System.setProperty("bootstrap.foo", "system"); - context = new SpringApplicationBuilder().web(false) - .sources(BareConfiguration.class).run(); - assertEquals("bar", context.getEnvironment().getProperty("bootstrap.foo")); - } - - @Test - public void applicationNameInBootstrapAndMain() { - System.setProperty("expected.name", "main"); - context = new SpringApplicationBuilder() - .web(false) - .properties("spring.cloud.bootstrap.name:other", - "spring.config.name:plain").sources(BareConfiguration.class) - .run(); - assertEquals("app", - context.getEnvironment().getProperty("spring.application.name")); - // The parent is called "main" because spring.application.name is specified in - // other.properties (the bootstrap properties) - assertEquals( - "main", - context.getParent().getEnvironment() - .getProperty("spring.application.name")); - // The bootstrap context has a different "bootstrap" property source - assertNotSame(context.getEnvironment().getPropertySources().get("bootstrap"), - ((ConfigurableEnvironment) context.getParent().getEnvironment()) - .getPropertySources().get("bootstrap")); - assertEquals("app", context.getId()); - } - - @Test - public void applicationNameNotInBootstrap() { - System.setProperty("expected.name", "main"); - context = new SpringApplicationBuilder() - .web(false) - .properties("spring.cloud.bootstrap.name:application", - "spring.config.name:other").sources(BareConfiguration.class) - .run(); - assertEquals("main", - context.getEnvironment().getProperty("spring.application.name")); - // The parent is called "application" because spring.application.name is not - // defined in the bootstrap properties - assertEquals( - "application", - context.getParent().getEnvironment() - .getProperty("spring.application.name")); - } - - @Test - public void applicationNameOnlyInBootstrap() { - System.setProperty("expected.name", "main"); - context = new SpringApplicationBuilder().web(false) - .properties("spring.cloud.bootstrap.name:other") - .sources(BareConfiguration.class).run(); - // The main context is called "main" because spring.application.name is specified - // in other.properties (and not in the main config file) - assertEquals("main", - context.getEnvironment().getProperty("spring.application.name")); - // The parent is called "main" because spring.application.name is specified in - // other.properties (the bootstrap properties this time) - assertEquals( - "main", - context.getParent().getEnvironment() - .getProperty("spring.application.name")); - assertEquals("main", context.getId()); - } - - @Test - public void environmentEnrichedOnceWhenSharedWithChildContext() { - PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar"); - context = new SpringApplicationBuilder().sources(BareConfiguration.class) - .environment(new StandardEnvironment()).child(BareConfiguration.class) - .web(false).run(); - assertEquals("bar", context.getEnvironment().getProperty("bootstrap.foo")); - assertEquals(context.getEnvironment(), context.getParent().getEnvironment()); - MutablePropertySources sources = context.getEnvironment().getPropertySources(); - PropertySource bootstrap = sources.get("bootstrap"); - assertNotNull(bootstrap); - assertEquals(0, sources.precedenceOf(bootstrap)); - } - - @Test - public void environmentEnrichedInParentContext() { - PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar"); - context = new SpringApplicationBuilder().sources(BareConfiguration.class) - .child(BareConfiguration.class).web(false).run(); - assertEquals("bar", context.getEnvironment().getProperty("bootstrap.foo")); - assertNotSame(context.getEnvironment(), context.getParent().getEnvironment()); - assertTrue(context.getEnvironment().getPropertySources().contains("bootstrap")); - assertTrue(((ConfigurableEnvironment) context.getParent().getEnvironment()) - .getPropertySources().contains("bootstrap")); - } - - @Test - public void differentProfileInChild() { - PropertySourceConfiguration.MAP.put("bootstrap.foo", "bar"); - // Profiles are always merged with the child - ConfigurableApplicationContext parent = new SpringApplicationBuilder() - .sources(BareConfiguration.class).profiles("parent").web(false).run(); - context = new SpringApplicationBuilder(BareConfiguration.class).profiles("child") - .parent(parent).web(false).run(); - assertNotSame(context.getEnvironment(), context.getParent().getEnvironment()); - // The ApplicationContext merges profiles (profiles and property sources), see - // AbstractEnvironment.merge() - assertTrue(this.context.getEnvironment().acceptsProfiles("child", "parent")); - // But the parent is not a child - assertFalse(this.context.getParent().getEnvironment().acceptsProfiles("child")); - assertTrue(this.context.getParent().getEnvironment().acceptsProfiles("parent")); - assertTrue(((ConfigurableEnvironment) context.getParent().getEnvironment()) - .getPropertySources().contains("bootstrap")); - assertEquals("bar", context.getEnvironment().getProperty("bootstrap.foo")); - // The "bootstrap" property source is not shared now, but it has the same - // properties in it because they are pulled from the PropertySourceConfiguration - // below - assertEquals("bar", - context.getParent().getEnvironment().getProperty("bootstrap.foo")); - // The parent property source is there in the child because they are both in the - // "parent" profile (by virtue of the merge in AbstractEnvironment) - assertEquals("parent", context.getEnvironment().getProperty("info.name")); - } - - @Configuration - @EnableConfigurationProperties(ConfigClientProperties.class) - protected static class BareConfiguration { - } - - @Configuration - @ConfigurationProperties("expected") - // This is added to bootstrap context as a source in bootstrap.properties - protected static class PropertySourceConfiguration implements PropertySourceLocator { - - public static Map MAP = new HashMap( - Collections. singletonMap("bootstrap.foo", "bar")); - - private String name; - - private boolean fail = false; - - @Override - public PropertySource locate(Environment environment) { - if (name != null) { - assertEquals(name, environment.getProperty("spring.application.name")); - } - if (fail) { - throw new RuntimeException("Planned"); - } - return new MapPropertySource("testBootstrap", MAP); - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public boolean isFail() { - return fail; - } - - public void setFail(boolean fail) { - this.fail = fail; - } - } - -} diff --git a/spring-cloud-config-client/src/test/java/org/springframework/cloud/bootstrap/encrypt/EncryptionBootstrapConfigurationTests.java b/spring-cloud-config-client/src/test/java/org/springframework/cloud/bootstrap/encrypt/EncryptionBootstrapConfigurationTests.java deleted file mode 100644 index 52c654ba..00000000 --- a/spring-cloud-config-client/src/test/java/org/springframework/cloud/bootstrap/encrypt/EncryptionBootstrapConfigurationTests.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.springframework.cloud.bootstrap.encrypt; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; -import org.springframework.boot.builder.SpringApplicationBuilder; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.security.crypto.encrypt.TextEncryptor; - -public class EncryptionBootstrapConfigurationTests { - - @Test - public void rsaKeyStore() { - ConfigurableApplicationContext context = new SpringApplicationBuilder( - EncryptionBootstrapConfiguration.class).web(false).properties( - "encrypt.keyStore.location:classpath:/server.jks", - "encrypt.keyStore.password:letmein", - "encrypt.keyStore.alias:mytestkey", "encrypt.keyStore.secret:changeme") - .run(); - TextEncryptor encryptor = context.getBean(TextEncryptor.class); - assertEquals("foo", encryptor.decrypt(encryptor.encrypt("foo"))); - } - -} diff --git a/spring-cloud-config-client/src/test/java/org/springframework/cloud/bootstrap/encrypt/EnvironmentDecryptApplicationListenerTests.java b/spring-cloud-config-client/src/test/java/org/springframework/cloud/bootstrap/encrypt/EnvironmentDecryptApplicationListenerTests.java deleted file mode 100644 index d9fb86ab..00000000 --- a/spring-cloud-config-client/src/test/java/org/springframework/cloud/bootstrap/encrypt/EnvironmentDecryptApplicationListenerTests.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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. - */ -package org.springframework.cloud.bootstrap.encrypt; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; -import org.springframework.boot.test.EnvironmentTestUtils; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.security.crypto.encrypt.Encryptors; - -/** - * @author Dave Syer - * - */ -public class EnvironmentDecryptApplicationListenerTests { - - private EnvironmentDecryptApplicationInitializer listener = new EnvironmentDecryptApplicationInitializer(Encryptors.noOpText()); - - @Test - public void decryptCipherKey() { - ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(); - EnvironmentTestUtils.addEnvironment(context, "foo: {cipher}bar"); - listener.initialize(context); - assertEquals("bar", context.getEnvironment().getProperty("foo")); - } - - @Test(expected=IllegalStateException.class) - public void errorOnDecrypt() { - listener = new EnvironmentDecryptApplicationInitializer(Encryptors.text("deadbeef", "AFFE37")); - ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(); - EnvironmentTestUtils.addEnvironment(context, "foo: {cipher}bar"); - listener.initialize(context); - assertEquals("bar", context.getEnvironment().getProperty("foo")); - } - - @Test - public void errorOnDecryptWithEmpty() { - listener = new EnvironmentDecryptApplicationInitializer(Encryptors.text("deadbeef", "AFFE37")); - listener.setFailOnError(false); - ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(); - EnvironmentTestUtils.addEnvironment(context, "foo: {cipher}bar"); - listener.initialize(context); - // Empty is safest fallback for undecryptable cipher - assertEquals("", context.getEnvironment().getProperty("foo")); - } - -} diff --git a/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/environment/EnvironmentManagerIntegrationTests.java b/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/environment/EnvironmentManagerIntegrationTests.java deleted file mode 100644 index d2f6f61b..00000000 --- a/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/environment/EnvironmentManagerIntegrationTests.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2006-2007 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import javax.servlet.ServletException; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.cloud.context.environment.EnvironmentManagerIntegrationTests.TestConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; -import org.springframework.web.context.WebApplicationContext; - -@SpringApplicationConfiguration(classes = TestConfiguration.class) -@RunWith(SpringJUnit4ClassRunner.class) -@WebAppConfiguration -public class EnvironmentManagerIntegrationTests { - - @Autowired - private TestProperties properties; - - @Autowired - private WebApplicationContext context; - - private MockMvc mvc; - - @Before - public void setUp() { - this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build(); - } - - @Test - public void testRefresh() throws Exception { - assertEquals("Hello scope!", properties.getMessage()); - // Change the dynamic property source... - this.mvc.perform(post("/env").param("message", "Foo")).andExpect(status().isOk()).andExpect( - content().string("{\"message\":\"Foo\"}")); - assertEquals("Foo", properties.getMessage()); - } - - @Test - public void testRefreshFails() throws Exception { - try { - this.mvc.perform(post("/env").param("delay", "foo")).andExpect( - status().is5xxServerError()); - fail("expected ServletException"); - } catch (ServletException e) { - // The underlying BindException is not handled by the dispatcher servlet - } - assertEquals(0, properties.getDelay()); - } - - public static void main(String[] args) { - SpringApplication.run(TestConfiguration.class, args); - } - - @Configuration - @EnableAutoConfiguration - protected static class TestConfiguration { - - @Bean - protected TestProperties properties() { - return new TestProperties(); - } - - } - - @ConfigurationProperties - protected static class TestProperties { - - private String message; - - private int delay; - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public int getDelay() { - return delay; - } - - public void setDelay(int delay) { - this.delay = delay; - } - } - -} diff --git a/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinderIntegrationTests.java b/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinderIntegrationTests.java deleted file mode 100644 index f7ec3697..00000000 --- a/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/properties/ConfigurationPropertiesRebinderIntegrationTests.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2006-2007 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.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.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.EnvironmentTestUtils; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.context.properties.ConfigurationPropertiesRebinderIntegrationTests.TestConfiguration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -@SpringApplicationConfiguration(classes=TestConfiguration.class) -@RunWith(SpringJUnit4ClassRunner.class) -public class ConfigurationPropertiesRebinderIntegrationTests { - - @Autowired - private TestProperties properties; - - @Autowired - private ConfigurationPropertiesRebinder rebinder; - - @Autowired - private ConfigurableEnvironment environment; - - @Test - @DirtiesContext - public void testSimpleProperties() throws Exception { - assertEquals("Hello scope!", properties.getMessage()); - // Change the dynamic property source... - EnvironmentTestUtils.addEnvironment(environment, "message:Foo"); - // ...but don't refresh, so the bean stays the same: - assertEquals("Hello scope!", properties.getMessage()); - assertEquals(1, properties.getCount()); - } - - @Test - @DirtiesContext - public void testRefresh() throws Exception { - assertEquals(1, properties.getCount()); - assertEquals("Hello scope!", properties.getMessage()); - // Change the dynamic property source... - EnvironmentTestUtils.addEnvironment(environment, "message:Foo"); - // ...and then refresh, so the bean is re-initialized: - rebinder.rebind(); - assertEquals("Foo", properties.getMessage()); - assertEquals(2, properties.getCount()); - } - - @Configuration - @EnableConfigurationProperties - @Import({RefreshAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class}) - protected static class TestConfiguration { - - @Bean - protected TestProperties properties() { - return new TestProperties(); - } - - } - - @ConfigurationProperties - protected static class TestProperties { - private String message; - private int delay; - private int count = 0; - public int getCount() { - return count; - } - public String getMessage() { - return message; - } - public void setMessage(String message) { - this.message = message; - } - public int getDelay() { - return delay; - } - public void setDelay(int delay) { - this.delay = delay; - } - @PostConstruct - public void init() { - this.count ++; - } - } - -} diff --git a/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/restart/RestartIntegrationTests.java b/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/restart/RestartIntegrationTests.java deleted file mode 100644 index 139d584b..00000000 --- a/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/restart/RestartIntegrationTests.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2006-2007 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.restart; - -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.assertNull; - -import org.junit.After; -import org.junit.Test; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Configuration; - -public class RestartIntegrationTests { - - private ConfigurableApplicationContext context; - - @After - public void close() { - if (context != null) { - context.close(); - } - } - - @Test - public void testRestartTwice() throws Exception { - - context = SpringApplication.run(TestConfiguration.class, "--endpoints.restart.enabled=true", "--server.port=0"); - RestartEndpoint endpoint = context.getBean(RestartEndpoint.class); - assertNotNull(context.getParent()); - assertNull(context.getParent().getParent()); - context = endpoint.restart(); - - assertNotNull(context); - assertNotNull(context.getParent()); - assertNull(context.getParent().getParent()); - - RestartEndpoint next = context.getBean(RestartEndpoint.class); - assertNotSame(endpoint, next); - context = next.restart(); - - assertNotNull(context); - assertNotNull(context.getParent()); - assertNull(context.getParent().getParent()); - - } - - public static void main(String[] args) { - SpringApplication.run(TestConfiguration.class, args); - } - - @Configuration - @EnableAutoConfiguration - protected static class TestConfiguration { - } - -} diff --git a/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/scope/refresh/ImportRefreshScopeIntegrationTests.java b/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/scope/refresh/ImportRefreshScopeIntegrationTests.java deleted file mode 100644 index 76cb9a74..00000000 --- a/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/scope/refresh/ImportRefreshScopeIntegrationTests.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2006-2007 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 static org.junit.Assert.assertEquals; - -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.SpringApplicationConfiguration; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.cloud.context.scope.refresh.ImportRefreshScopeIntegrationTests.TestConfiguration; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -@SpringApplicationConfiguration(classes = TestConfiguration.class) -@RunWith(SpringJUnit4ClassRunner.class) -public class ImportRefreshScopeIntegrationTests { - - @Autowired - private ConfigurableListableBeanFactory beanFactory; - - @Autowired - private ExampleService service; - - @Autowired - private org.springframework.cloud.context.scope.refresh.RefreshScope scope; - - @Test - public void testSimpleProperties() throws Exception { - assertEquals("Hello scope!", service.getMessage()); - assertEquals("refresh", beanFactory.getBeanDefinition("scopedTarget.service").getScope()); - assertEquals("Hello scope!", service.getMessage()); - } - - @Configuration("service") - @RefreshScope - public static class ExampleService { - - public String getMessage() { - return "Hello scope!"; - } - - } - - @Configuration - @Import({ RefreshAutoConfiguration.class, ExampleService.class }) - protected static class TestConfiguration { - } - -} diff --git a/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/scope/refresh/MoreRefreshScopeIntegrationTests.java b/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/scope/refresh/MoreRefreshScopeIntegrationTests.java deleted file mode 100644 index b4d54305..00000000 --- a/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/scope/refresh/MoreRefreshScopeIntegrationTests.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright 2006-2007 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 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.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; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.EnvironmentTestUtils; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.jmx.export.annotation.ManagedAttribute; -import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.cloud.context.scope.refresh.MoreRefreshScopeIntegrationTests.TestConfiguration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -@SpringApplicationConfiguration(classes = TestConfiguration.class) -@RunWith(SpringJUnit4ClassRunner.class) -public class MoreRefreshScopeIntegrationTests { - - @Autowired - private TestService service; - - @Autowired - private TestProperties properties; - - @Autowired - private org.springframework.cloud.context.scope.refresh.RefreshScope scope; - - @Autowired - private ConfigurableEnvironment environment; - - @Before - public void init() { - TestService.reset(); - } - - @Test - @DirtiesContext - public void testSimpleProperties() throws Exception { - assertEquals("Hello scope!", service.getMessage()); - assertTrue(service instanceof Advised); - // Change the dynamic property source... - EnvironmentTestUtils.addEnvironment(environment, "message:Foo"); - // ...but don't refresh, so the bean stays the same: - assertEquals("Hello scope!", service.getMessage()); - assertEquals(1, TestService.getInitCount()); - assertEquals(0, TestService.getDestroyCount()); - } - - @Test - @DirtiesContext - public void testRefresh() throws Exception { - assertEquals("Hello scope!", service.getMessage()); - String id1 = service.toString(); - // Change the dynamic property source... - EnvironmentTestUtils.addEnvironment(environment, "message:Foo"); - // ...and then refresh, so the bean is re-initialized: - scope.refreshAll(); - String id2 = service.toString(); - assertEquals("Foo", service.getMessage()); - assertEquals(2, TestService.getInitCount()); - assertEquals(1, TestService.getDestroyCount()); - assertNotSame(id1, id2); - } - - @Test - @DirtiesContext - public void testRefreshFails() throws Exception { - assertEquals("Hello scope!", service.getMessage()); - // Change the dynamic property source... - EnvironmentTestUtils.addEnvironment(environment, "message:Foo", "delay:foo"); - // ...and then refresh, so the bean is re-initialized: - scope.refreshAll(); - try { - // If a refresh fails (e.g. a binding error in this case) the application is - // basically hosed. - assertEquals("Hello scope!", service.getMessage()); - fail("expected BeanCreationException"); - } catch (BeanCreationException e) { - } - // But we can fix it by fixing the binding error: - EnvironmentTestUtils.addEnvironment(environment, "delay:0"); - // ...and then refresh, so the bean is re-initialized: - scope.refreshAll(); - assertEquals("Foo", service.getMessage()); - } - - public static class TestService implements InitializingBean, DisposableBean { - - private static Log logger = LogFactory.getLog(TestService.class); - - private volatile static int initCount = 0; - - private volatile static int destroyCount = 0; - - private String message = null; - - private volatile long delay = 0; - - public void setDelay(long delay) { - this.delay = delay; - } - - public void afterPropertiesSet() throws Exception { - logger.debug("Initializing message: " + message); - initCount++; - } - - public void destroy() throws Exception { - logger.debug("Destroying message: " + message); - destroyCount++; - 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: " + message); - try { - Thread.sleep(delay); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - logger.info("Returning message: " + message); - return message; - } - - } - - @Configuration - @EnableConfigurationProperties - @Import({ RefreshAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) - protected static class TestConfiguration { - - @Bean - @RefreshScope - protected TestProperties properties() { - return new TestProperties(); - } - - @Bean - @RefreshScope - public TestService service() { - TestService service = new TestService(); - service.setMessage(properties().getMessage()); - service.setDelay(properties().getDelay()); - return service; - } - - } - - @ConfigurationProperties - @ManagedResource - protected static class TestProperties { - - private String message; - - private int delay; - - @ManagedAttribute - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - @ManagedAttribute - public int getDelay() { - return delay; - } - - public void setDelay(int delay) { - this.delay = delay; - } - } - -} diff --git a/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshEndpointIntegrationTests.java b/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshEndpointIntegrationTests.java deleted file mode 100644 index ec321706..00000000 --- a/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshEndpointIntegrationTests.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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. - */ -package org.springframework.cloud.context.scope.refresh; - -import static org.junit.Assert.assertEquals; - -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Arrays; -import java.util.Collections; - -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.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.IntegrationTest; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.boot.test.TestRestTemplate; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.cloud.context.scope.refresh.RefreshEndpointIntegrationTests.ClientApp; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.MediaType; -import org.springframework.http.RequestEntity; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.util.LinkedMultiValueMap; -import org.springframework.util.MultiValueMap; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * @author Dave Syer - * - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes = ClientApp.class) -@IntegrationTest("server.port:0") -@WebAppConfiguration -public class RefreshEndpointIntegrationTests { - - @Value("${local.server.port}") - private int port; - - @Test - public void webAccess() throws Exception { - TestRestTemplate template = new TestRestTemplate(); - template.exchange( - getUrlEncodedEntity("http://localhost:" + port + "/env", "message", - "Hello Dave!"), String.class); - template.postForObject("http://localhost:" + port + "/refresh", "", String.class); - String message = template.getForObject("http://localhost:" + port + "/", - String.class); - assertEquals("Hello Dave!", message); - } - - private RequestEntity getUrlEncodedEntity(String uri, String key, String value) - throws URISyntaxException { - MultiValueMap env = new LinkedMultiValueMap( - Collections.singletonMap("message", Arrays.asList("Hello Dave!"))); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); - RequestEntity> entity = new RequestEntity>( - env, headers, HttpMethod.POST, new URI(uri)); - return entity; - } - - @Configuration - @EnableAutoConfiguration - protected static class ClientApp { - - @Bean - @RefreshScope - public Controller controller() { - return new Controller(); - } - - public static void main(String[] args) { - SpringApplication.run(ClientApp.class, args); - } - - } - - @RestController - protected static class Controller { - - @Value("${message:Hello World!}") - String message; - - @RequestMapping("/") - public String hello() { - return message; - } - - } - - -} diff --git a/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeConcurrencyTests.java b/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeConcurrencyTests.java deleted file mode 100644 index 1aef5713..00000000 --- a/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeConcurrencyTests.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2006-2007 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 static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.util.concurrent.Callable; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - -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; -import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.jmx.export.annotation.ManagedAttribute; -import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.cloud.context.scope.refresh.RefreshScopeConcurrencyTests.TestConfiguration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.annotation.Repeat; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -@SpringApplicationConfiguration(classes=TestConfiguration.class) -@RunWith(SpringJUnit4ClassRunner.class) -public class RefreshScopeConcurrencyTests { - - private static Log logger = LogFactory.getLog(RefreshScopeConcurrencyTests.class); - - private ExecutorService executor = Executors.newSingleThreadExecutor(); - - @Autowired - private Service service; - - @Autowired - private TestProperties properties; - - @Autowired - private org.springframework.cloud.context.scope.refresh.RefreshScope scope; - - @Test - @Repeat(10) - @DirtiesContext - public void testConcurrentRefresh() throws Exception { - - assertEquals("Hello scope!", service.getMessage()); - properties.setMessage("Foo"); - properties.setDelay(500); - final CountDownLatch latch = new CountDownLatch(1); - Future result = executor.submit(new Callable() { - public String call() throws Exception { - logger.debug("Background started."); - try { - return service.getMessage(); - } finally { - latch.countDown(); - logger.debug("Background done."); - } - } - }); - assertTrue(latch.await(1500, TimeUnit.MILLISECONDS)); - logger.info("Refreshing"); - scope.refreshAll(); - assertEquals("Foo", service.getMessage()); - /* - * This is the most important assertion: we don't want a null value because that means the bean was destroyed - * and not re-initialized before we accessed it. - */ - assertNotNull(result.get()); - assertEquals("Hello scope!", result.get()); - } - - public static interface Service { - - String getMessage(); - - } - - public static class ExampleService implements Service, InitializingBean, DisposableBean { - - private static Log logger = LogFactory.getLog(ExampleService.class); - - private String message = null; - private volatile long delay = 0; - - public void setDelay(long delay) { - this.delay = delay; - } - - public void afterPropertiesSet() throws Exception { - logger.debug("Initializing message: " + message); - } - - public void destroy() throws Exception { - logger.debug("Destroying message: " + message); - message = null; - } - - public void setMessage(String message) { - logger.debug("Setting message: " + message); - this.message = message; - } - - public String getMessage() { - logger.debug("Getting message: " + message); - try { - Thread.sleep(delay); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - logger.info("Returning message: " + message); - return message; - } - - } - - @Configuration - @EnableConfigurationProperties(TestProperties.class) - @Import({RefreshAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class}) - protected static class TestConfiguration { - - @Autowired - private TestProperties properties; - - @Bean - @RefreshScope - public ExampleService service() { - ExampleService service = new ExampleService(); - service.setMessage(properties.getMessage()); - service.setDelay(properties.getDelay()); - return service; - } - - } - - @ConfigurationProperties - @ManagedResource - protected static class TestProperties { - private String message; - private int delay; - @ManagedAttribute - public String getMessage() { - return message; - } - public void setMessage(String message) { - this.message = message; - } - @ManagedAttribute - public int getDelay() { - return delay; - } - public void setDelay(int delay) { - this.delay = delay; - } - } - -} diff --git a/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeConfigurationTests.java b/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeConfigurationTests.java deleted file mode 100644 index b94f6cbc..00000000 --- a/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeConfigurationTests.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * 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. - */ -package org.springframework.cloud.context.scope.refresh; - -import static org.junit.Assert.assertEquals; - -import org.junit.After; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.cloud.context.environment.EnvironmentManager; -import org.springframework.cloud.context.scope.refresh.RefreshScopeConfigurationTests.NestedApp.NestedController; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * @author Dave Syer - * - */ -public class RefreshScopeConfigurationTests { - - private AnnotationConfigApplicationContext context; - - @Rule - public ExpectedException expected = ExpectedException.none(); - - @After - public void init() { - if (context!=null) { - context.close(); - } - } - - private void refresh() { - EnvironmentManager environmentManager = 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); - scope.refreshAll(); - } - - /** - * See gh-43 - */ - @Test - public void configurationWithRefreshScope() throws Exception { - context = new AnnotationConfigApplicationContext(Application.class, - PropertyPlaceholderAutoConfiguration.class, RefreshAutoConfiguration.class); - Application application = context.getBean(Application.class); - assertEquals("refresh", context.getBeanDefinition("scopedTarget.application").getScope()); - application.hello(); - refresh(); - String message = application.hello(); - assertEquals("Hello Dave!", message); - } - - @Test - public void refreshScopeOnBean() throws Exception { - context = new AnnotationConfigApplicationContext(ClientApp.class, - PropertyPlaceholderAutoConfiguration.class, RefreshAutoConfiguration.class); - Controller application = context.getBean(Controller.class); - application.hello(); - refresh(); - String message = application.hello(); - assertEquals("Hello Dave!", message); - } - - @Test - public void refreshScopeOnNested() throws Exception { - context = new AnnotationConfigApplicationContext(NestedApp.class, - PropertyPlaceholderAutoConfiguration.class, RefreshAutoConfiguration.class); - NestedController application = context.getBean(NestedController.class); - application.hello(); - refresh(); - String message = application.hello(); - assertEquals("Hello Dave!", message); - } - - // WTF? Maven can't compile without the FQN on this one (not the others). - @org.springframework.context.annotation.Configuration - protected static class NestedApp { - - @RestController - @RefreshScope - protected static class NestedController { - - @Value("${message:Hello World!}") - String message; - - @RequestMapping("/") - public String hello() { - return message; - } - - } - - public static void main(String[] args) { - SpringApplication.run(ClientApp.class, args); - } - - } - - @Configuration("application") - @RefreshScope - protected static class Application { - - @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); - } - - } - - @Configuration - protected static class ClientApp { - - @Bean - @RefreshScope - public Controller controller() { - return new Controller(); - } - - public static void main(String[] args) { - SpringApplication.run(ClientApp.class, args); - } - - } - - @RestController - protected static class Controller { - - @Value("${message:Hello World!}") - String message; - - @RequestMapping("/") - public String hello() { - return message; - } - - } - -} diff --git a/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeIntegrationTests.java b/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeIntegrationTests.java deleted file mode 100644 index e540a779..00000000 --- a/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeIntegrationTests.java +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright 2006-2007 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.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.aop.framework.Advised; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.cloud.context.scope.GenericScope; -import org.springframework.cloud.context.scope.refresh.RefreshScopeIntegrationTests.TestConfiguration; -import org.springframework.context.ApplicationListener; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.jmx.export.annotation.ManagedAttribute; -import org.springframework.jmx.export.annotation.ManagedResource; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.junit.Assert.*; - -@SpringApplicationConfiguration(classes = TestConfiguration.class) -@RunWith(SpringJUnit4ClassRunner.class) -public class RefreshScopeIntegrationTests { - - @Autowired - private Service service; - - @Autowired - private TestProperties properties; - - @Autowired - private org.springframework.cloud.context.scope.refresh.RefreshScope scope; - - @Before - public void init() { - ExampleService.reset(); - } - - @Test - @DirtiesContext - public void testSimpleProperties() throws Exception { - assertEquals("Hello scope!", service.getMessage()); - assertTrue(service instanceof Advised); - // Change the dynamic property source... - properties.setMessage("Foo"); - // ...but don't refresh, so the bean stays the same: - assertEquals("Hello scope!", service.getMessage()); - assertEquals(1, ExampleService.getInitCount()); - assertEquals(0, ExampleService.getDestroyCount()); - } - - @Test - @DirtiesContext - public void testRefresh() throws Exception { - assertEquals("Hello scope!", service.getMessage()); - String id1 = service.toString(); - // Change the dynamic property source... - properties.setMessage("Foo"); - // ...and then refresh, so the bean is re-initialized: - scope.refreshAll(); - String id2 = service.toString(); - assertEquals("Foo", service.getMessage()); - assertEquals(2, ExampleService.getInitCount()); - assertEquals(1, ExampleService.getDestroyCount()); - assertNotSame(id1, id2); - assertNotNull(ExampleService.event); - assertEquals(RefreshScopeRefreshedEvent.DEFAULT_NAME, - ExampleService.event.getName()); - } - - @Test - @DirtiesContext - public void testRefreshBean() throws Exception { - assertEquals("Hello scope!", service.getMessage()); - String id1 = service.toString(); - // Change the dynamic property source... - properties.setMessage("Foo"); - // ...and then refresh, so the bean is re-initialized: - scope.refresh("service"); - String id2 = service.toString(); - assertEquals("Foo", service.getMessage()); - assertEquals(2, ExampleService.getInitCount()); - assertEquals(1, ExampleService.getDestroyCount()); - assertNotSame(id1, id2); - assertNotNull(ExampleService.event); - assertEquals(GenericScope.SCOPED_TARGET_PREFIX + "service", - ExampleService.event.getName()); - } - - public static interface Service { - - String getMessage(); - - } - - public static class ExampleService implements Service, InitializingBean, - DisposableBean, ApplicationListener { - - 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 void setDelay(long delay) { - this.delay = delay; - } - - public void afterPropertiesSet() throws Exception { - logger.debug("Initializing message: " + message); - initCount++; - } - - public void destroy() throws Exception { - logger.debug("Destroying message: " + message); - destroyCount++; - 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; - } - - public String getMessage() { - logger.debug("Getting message: " + message); - try { - Thread.sleep(delay); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - logger.info("Returning message: " + message); - return message; - } - - @Override - public void onApplicationEvent(RefreshScopeRefreshedEvent e) { - event = e; - } - } - - @Configuration - @EnableConfigurationProperties(TestProperties.class) - @Import({ RefreshAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class }) - protected static class TestConfiguration { - - @Autowired - private TestProperties properties; - - @Bean - @RefreshScope - public ExampleService service() { - ExampleService service = new ExampleService(); - service.setMessage(properties.getMessage()); - service.setDelay(properties.getDelay()); - return service; - } - - } - - @ConfigurationProperties - @ManagedResource - protected static class TestProperties { - private String message; - private int delay; - - @ManagedAttribute - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - @ManagedAttribute - public int getDelay() { - return delay; - } - - public void setDelay(int delay) { - this.delay = delay; - } - } - -} diff --git a/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeWebIntegrationTests.java b/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeWebIntegrationTests.java deleted file mode 100644 index 8bce8fa3..00000000 --- a/spring-cloud-config-client/src/test/java/org/springframework/cloud/context/scope/refresh/RefreshScopeWebIntegrationTests.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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. - */ -package org.springframework.cloud.context.scope.refresh; - -import static org.junit.Assert.assertEquals; - -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; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.cloud.context.environment.EnvironmentManager; -import org.springframework.cloud.context.scope.refresh.RefreshScopeWebIntegrationTests.Application; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * @author Dave Syer - * - */ -@RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes = Application.class) -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()); - } - - @Test - public void beanAccess() throws Exception { - application.hello(); - environmentManager.setProperty("message", "Hello Dave!"); - scope.refreshAll(); - String message = application.hello(); - assertEquals("Hello Dave!", message); - } - - @Configuration - @EnableAutoConfiguration - protected static class Application { - - @Bean - @RefreshScope - public Client application() { - return new Client(); - } - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } - - } - - @RestController - protected static class Client { - - @Value("${message:Hello World!}") - String message; - - @RequestMapping("/") - public String hello() { - return message; - } - - } - -} diff --git a/spring-cloud-config-client/src/test/java/org/springframework/cloud/logging/LoggingRebinderTests.java b/spring-cloud-config-client/src/test/java/org/springframework/cloud/logging/LoggingRebinderTests.java deleted file mode 100644 index c8b1e14d..00000000 --- a/spring-cloud-config-client/src/test/java/org/springframework/cloud/logging/LoggingRebinderTests.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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. - */ -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; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.boot.logging.LogLevel; -import org.springframework.boot.logging.LoggingSystem; -import org.springframework.boot.test.EnvironmentTestUtils; -import org.springframework.core.env.StandardEnvironment; -import org.springframework.cloud.context.environment.EnvironmentChangeEvent; - -/** - * @author Dave Syer - * - */ -public class LoggingRebinderTests { - - private LoggingRebinder rebinder = new LoggingRebinder(); - private Logger logger = LoggerFactory.getLogger("org.springframework.web"); - - @After - public void reset() { - LoggingSystem.get(getClass().getClassLoader()).setLogLevel("org.springframework.web", LogLevel.INFO); - } - - @Test - public void logLevelsChanged() { - assertFalse(logger.isTraceEnabled()); - StandardEnvironment environment = new StandardEnvironment(); - EnvironmentTestUtils.addEnvironment(environment, "logging.level.org.springframework.web=TRACE"); - rebinder.setEnvironment(environment); - rebinder.onApplicationEvent(new EnvironmentChangeEvent(Collections.singleton("logging.level.org.springframework.web"))); - assertTrue(logger.isTraceEnabled()); - } - -} diff --git a/spring-cloud-config-client/src/test/resources/application-encrypt.properties b/spring-cloud-config-client/src/test/resources/application-encrypt.properties deleted file mode 100644 index b1329f64..00000000 --- a/spring-cloud-config-client/src/test/resources/application-encrypt.properties +++ /dev/null @@ -1 +0,0 @@ -foo: {cipher}e4e061f9fe39ba5b14d8012d2f17d39775606039409b71ed4be0fdd033d5324a diff --git a/spring-cloud-config-client/src/test/resources/application.properties b/spring-cloud-config-client/src/test/resources/application.properties deleted file mode 100644 index 961e7d22..00000000 --- a/spring-cloud-config-client/src/test/resources/application.properties +++ /dev/null @@ -1,5 +0,0 @@ -message: Hello scope! -delay: 0 -debug: true -#logging.level.org.springframework.web: DEBUG -#logging.level.org.springframework.context.annotation: DEBUG \ No newline at end of file diff --git a/spring-cloud-config-client/src/test/resources/bootstrap-encrypt.properties b/spring-cloud-config-client/src/test/resources/bootstrap-encrypt.properties deleted file mode 100644 index 3035e009..00000000 --- a/spring-cloud-config-client/src/test/resources/bootstrap-encrypt.properties +++ /dev/null @@ -1 +0,0 @@ -bar: {cipher}6154ca04d4bb6144d672c4e3d750b5147116dd381946d51fa44f8bc25dc256f4 \ No newline at end of file diff --git a/spring-cloud-config-client/src/test/resources/bootstrap-parent.properties b/spring-cloud-config-client/src/test/resources/bootstrap-parent.properties deleted file mode 100644 index 0c36bbdd..00000000 --- a/spring-cloud-config-client/src/test/resources/bootstrap-parent.properties +++ /dev/null @@ -1 +0,0 @@ -info.name: parent \ No newline at end of file diff --git a/spring-cloud-config-client/src/test/resources/bootstrap.properties b/spring-cloud-config-client/src/test/resources/bootstrap.properties deleted file mode 100644 index 9ec10bf9..00000000 --- a/spring-cloud-config-client/src/test/resources/bootstrap.properties +++ /dev/null @@ -1,2 +0,0 @@ -spring.main.sources: org.springframework.cloud.bootstrap.config.BootstrapConfigurationTests.PropertySourceConfiguration -info.name: child diff --git a/spring-cloud-config-client/src/test/resources/external-properties/bootstrap.properties b/spring-cloud-config-client/src/test/resources/external-properties/bootstrap.properties deleted file mode 100644 index 925265df..00000000 --- a/spring-cloud-config-client/src/test/resources/external-properties/bootstrap.properties +++ /dev/null @@ -1 +0,0 @@ -info.name: externalPropertiesInfoName \ No newline at end of file diff --git a/spring-cloud-config-client/src/test/resources/other.properties b/spring-cloud-config-client/src/test/resources/other.properties deleted file mode 100644 index dc756282..00000000 --- a/spring-cloud-config-client/src/test/resources/other.properties +++ /dev/null @@ -1 +0,0 @@ -spring.application.name: main \ No newline at end of file diff --git a/spring-cloud-config-client/src/test/resources/plain.properties b/spring-cloud-config-client/src/test/resources/plain.properties deleted file mode 100644 index aa8f5408..00000000 --- a/spring-cloud-config-client/src/test/resources/plain.properties +++ /dev/null @@ -1 +0,0 @@ -spring.application.name: app diff --git a/spring-cloud-config-client/src/test/resources/server.jks b/spring-cloud-config-client/src/test/resources/server.jks deleted file mode 100644 index 560be5fe..00000000 Binary files a/spring-cloud-config-client/src/test/resources/server.jks and /dev/null differ diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/EncryptionController.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/EncryptionController.java index 4cbcf4ef..fa8f7138 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/EncryptionController.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/EncryptionController.java @@ -29,10 +29,10 @@ import java.util.Map.Entry; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cloud.config.encrypt.EncryptorFactory; -import org.springframework.cloud.config.encrypt.KeyFormatException; import org.springframework.cloud.config.environment.Environment; import org.springframework.cloud.config.environment.PropertySource; +import org.springframework.cloud.context.encrypt.EncryptorFactory; +import org.springframework.cloud.context.encrypt.KeyFormatException; import org.springframework.core.io.ByteArrayResource; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/EnvironmentRepositoryPropertySourceLocator.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/EnvironmentRepositoryPropertySourceLocator.java index a02d1018..cb995295 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/EnvironmentRepositoryPropertySourceLocator.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/EnvironmentRepositoryPropertySourceLocator.java @@ -17,7 +17,7 @@ package org.springframework.cloud.config.server; import java.util.Map; -import org.springframework.cloud.config.client.PropertySourceLocator; +import org.springframework.cloud.bootstrap.config.PropertySourceLocator; import org.springframework.cloud.config.environment.PropertySource; import org.springframework.core.env.CompositePropertySource; import org.springframework.core.env.Environment; diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/EncryptionControllerTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/EncryptionControllerTests.java index 79df7396..dab9283b 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/EncryptionControllerTests.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/EncryptionControllerTests.java @@ -22,12 +22,12 @@ import static org.junit.Assert.assertTrue; import java.util.Collections; import org.junit.Test; -import org.springframework.cloud.config.encrypt.KeyFormatException; import org.springframework.cloud.config.environment.Environment; import org.springframework.cloud.config.environment.PropertySource; import org.springframework.cloud.config.server.EncryptionController; import org.springframework.cloud.config.server.InvalidCipherException; import org.springframework.cloud.config.server.KeyNotInstalledException; +import org.springframework.cloud.context.encrypt.KeyFormatException; import org.springframework.http.MediaType; import org.springframework.security.rsa.crypto.RsaSecretEncryptor;