diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/BootstrapPropertySource.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/BootstrapPropertySource.java index 91a9b7fd..848cd3df 100644 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/BootstrapPropertySource.java +++ b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/BootstrapPropertySource.java @@ -27,13 +27,15 @@ import org.springframework.util.StringUtils; import static org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration.BOOTSTRAP_PROPERTY_SOURCE_NAME; /** + * Enumerable wrapper for a property source. + * * @author Ryan Baxter */ public class BootstrapPropertySource extends EnumerablePropertySource { - private PropertySource delegate; + private EnumerablePropertySource delegate; - public BootstrapPropertySource(PropertySource delegate) { + public BootstrapPropertySource(EnumerablePropertySource delegate) { super(BOOTSTRAP_PROPERTY_SOURCE_NAME + "-" + delegate.getName(), delegate.getSource()); this.delegate = delegate; @@ -47,13 +49,7 @@ public class BootstrapPropertySource extends EnumerablePropertySource { @Override public String[] getPropertyNames() { Set names = new LinkedHashSet<>(); - if (!(this.delegate instanceof EnumerablePropertySource)) { - throw new IllegalStateException( - "Failed to enumerate property names due to non-enumerable property source: " - + this.delegate); - } - names.addAll(Arrays.asList( - ((EnumerablePropertySource) this.delegate).getPropertyNames())); + names.addAll(Arrays.asList(this.delegate.getPropertyNames())); return StringUtils.toStringArray(names); } diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceBootstrapConfiguration.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceBootstrapConfiguration.java index 5beb754b..c7ab224a 100644 --- a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceBootstrapConfiguration.java +++ b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/PropertySourceBootstrapConfiguration.java @@ -45,6 +45,7 @@ import org.springframework.core.Ordered; import org.springframework.core.annotation.AnnotationAwareOrderComparator; import org.springframework.core.env.CompositePropertySource; import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.EnumerablePropertySource; import org.springframework.core.env.Environment; import org.springframework.core.env.MutablePropertySources; import org.springframework.core.env.PropertySource; @@ -100,7 +101,13 @@ public class PropertySourceBootstrapConfiguration implements } List> sourceList = new ArrayList<>(); for (PropertySource p : source) { - sourceList.add(new BootstrapPropertySource<>(p)); + if (p instanceof EnumerablePropertySource) { + EnumerablePropertySource enumerable = (EnumerablePropertySource) p; + sourceList.add(new BootstrapPropertySource<>(enumerable)); + } + else { + sourceList.add(new SimpleBootstrapPropertySource(p)); + } } logger.info("Located property source: " + sourceList); composite.addAll(sourceList); diff --git a/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/SimpleBootstrapPropertySource.java b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/SimpleBootstrapPropertySource.java new file mode 100644 index 00000000..1f702999 --- /dev/null +++ b/spring-cloud-context/src/main/java/org/springframework/cloud/bootstrap/config/SimpleBootstrapPropertySource.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-2020 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 + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.bootstrap.config; + +import org.springframework.core.env.PropertySource; + +import static org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration.BOOTSTRAP_PROPERTY_SOURCE_NAME; + +/** + * Simple, non-enumerable PropertySource wrapper. + * @author Ryan Baxter + */ +public class SimpleBootstrapPropertySource extends PropertySource { + + private PropertySource delegate; + + public SimpleBootstrapPropertySource(PropertySource delegate) { + super(BOOTSTRAP_PROPERTY_SOURCE_NAME + "-" + delegate.getName(), + delegate.getSource()); + this.delegate = delegate; + } + + @Override + public Object getProperty(String name) { + return this.delegate.getProperty(name); + } + + public PropertySource getDelegate() { + return delegate; + } + +} diff --git a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/config/BootstrapConfigurationTests.java b/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/config/BootstrapConfigurationTests.java index aec2909a..2cdea8d5 100644 --- a/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/config/BootstrapConfigurationTests.java +++ b/spring-cloud-context/src/test/java/org/springframework/cloud/bootstrap/config/BootstrapConfigurationTests.java @@ -416,12 +416,37 @@ public class BootstrapConfigurationTests { .isEqualTo("Hello added!"); } + @Test + public void nonEnumerablePropertySourceWorks() { + this.context = new SpringApplicationBuilder().web(WebApplicationType.NONE) + .sources(BareConfiguration.class) + .properties("spring.cloud.bootstrap.name=nonenumerable").run(); + then(this.context.getEnvironment().getProperty("foo")).isEqualTo("bar"); + } + @Configuration(proxyBeanMethods = false) @EnableConfigurationProperties protected static class BareConfiguration { } + @Configuration(proxyBeanMethods = false) + // This is added to bootstrap context as a source in bootstrap.properties + protected static class SimplePropertySourceConfiguration + implements PropertySourceLocator { + + @Override + public PropertySource locate(Environment environment) { + return new PropertySource("testBootstrapSimple", this) { + @Override + public Object getProperty(String name) { + return ("foo".equals(name)) ? "bar" : null; + } + }; + } + + } + @Configuration(proxyBeanMethods = false) @ConfigurationProperties("expected") // This is added to bootstrap context as a source in bootstrap.properties diff --git a/spring-cloud-context/src/test/resources/nonenumerable.properties b/spring-cloud-context/src/test/resources/nonenumerable.properties new file mode 100644 index 00000000..ffc4f272 --- /dev/null +++ b/spring-cloud-context/src/test/resources/nonenumerable.properties @@ -0,0 +1 @@ +spring.main.sources:org.springframework.cloud.bootstrap.config.BootstrapConfigurationTests.PropertySourceConfiguration,org.springframework.cloud.bootstrap.config.BootstrapConfigurationTests.SimplePropertySourceConfiguration