diff --git a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/composite/CompositeUtils.java b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/composite/CompositeUtils.java index 26d3a130..1f6879e4 100644 --- a/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/composite/CompositeUtils.java +++ b/spring-cloud-config-server/src/main/java/org/springframework/cloud/config/server/composite/CompositeUtils.java @@ -18,13 +18,15 @@ package org.springframework.cloud.config.server.composite; import java.lang.reflect.AnnotatedType; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Map; import java.util.Optional; +import java.util.stream.Collectors; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.boot.context.properties.bind.Binder; import org.springframework.cloud.config.server.environment.EnvironmentRepositoryFactory; import org.springframework.core.env.Environment; import org.springframework.core.type.MethodMetadata; @@ -34,26 +36,42 @@ import org.springframework.core.type.MethodMetadata; */ public class CompositeUtils { + /** + * Returns list of values of the `type` field from the `spring.cloud.config.server.composite` collection. + */ public static List getCompositeTypeList(Environment environment) { - List repoTypes = new ArrayList<>(); - for (int i = 0; i < Integer.MAX_VALUE; i++) { - String property = String.format("spring.cloud.config.server.composite[%d].type", i); - String type = environment.getProperty(property); - if (type != null) { - repoTypes.add(type); - continue; - } - break; - } - return repoTypes; + return Binder.get(environment) + .bind("spring.cloud.config.server", CompositeConfig.class) + .get().getComposite().stream() + .map(map -> (String)map.get("type")) + .collect(Collectors.toList()); } + static class CompositeConfig { + List> composite; + + public List> getComposite() { + return composite; + } + + public void setComposite(List> composite) { + this.composite = composite; + } + } + + /** + * Given a type of EnvironmentRepository (git, svn, native, etc...) returns the name of the factory bean. + * See {@link #getCompositeTypeList(Environment)} + */ public static String getFactoryName(String type, ConfigurableListableBeanFactory beanFactory) { String[] factoryNames = BeanFactoryUtils .beanNamesForTypeIncludingAncestors(beanFactory, EnvironmentRepositoryFactory.class, true, false); return Arrays.stream(factoryNames).filter(n -> n.startsWith(type)).findFirst().orElse(null); } + /** + * Given a Factory Name return the generic type parameters of the factory (The actual repository class, and its properties class)o + */ public static Type[] getEnvironmentRepositoryFactoryTypeParams(ConfigurableListableBeanFactory beanFactory, String factoryName) { MethodMetadata methodMetadata = (MethodMetadata) beanFactory.getBeanDefinition(factoryName).getSource(); Class factoryClass = null; diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/AdhocTestSuite.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/AdhocTestSuite.java index 47c4bc9a..98a06fd9 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/AdhocTestSuite.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/AdhocTestSuite.java @@ -103,7 +103,7 @@ import org.springframework.cloud.config.server.ssh.SshUriPropertyProcessorTest; SshUriPropertyProcessorTest.class, PropertyBasedSshSessionFactoryTest.class, SshPropertyValidatorTest.class, - CompositeConfigServerIntegrationTests.class, + CompositeIntegrationTests.class, SubversionConfigServerIntegrationTests.class, ConfigServerHealthIndicatorTests.class, CustomCompositeEnvironmentRepositoryTests.class, diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/CompositeConfigServerIntegrationTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/CompositeIntegrationTests.java similarity index 96% rename from spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/CompositeConfigServerIntegrationTests.java rename to spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/CompositeIntegrationTests.java index 343fc9f0..2339742c 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/CompositeConfigServerIntegrationTests.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/CompositeIntegrationTests.java @@ -34,7 +34,7 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen * @author Ryan Baxter * @author Dylan Roberts */ -public class CompositeConfigServerIntegrationTests { +public class CompositeIntegrationTests { @RunWith(SpringRunner.class) @SpringBootTest(classes = ConfigServerApplication.class, properties = { "spring.config.name:compositeconfigserver", @@ -44,7 +44,7 @@ public class CompositeConfigServerIntegrationTests { "spring.cloud.config.server.git.order:1"}, webEnvironment = RANDOM_PORT) @ActiveProfiles({ "test", "git", "subversion" }) - public static class StaticConfigCompositeConfigServerIntegrationTests { + public static class StaticTests { @LocalServerPort private int port; @@ -94,7 +94,7 @@ public class CompositeConfigServerIntegrationTests { }, webEnvironment = RANDOM_PORT) @ActiveProfiles({ "test", "composite"}) - public static class ListConfigCompositeConfigServerIntegrationTests { + public static class ListTests { @LocalServerPort private int port; diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/composite/CompositUtilsTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/composite/CompositUtilsTests.java new file mode 100644 index 00000000..1f1365d4 --- /dev/null +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/composite/CompositUtilsTests.java @@ -0,0 +1,51 @@ +package org.springframework.cloud.config.server.composite; + +import java.util.List; + +import org.junit.Rule; +import org.junit.Test; + +import org.junit.rules.ExpectedException; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.cloud.config.server.ConfigServerApplication; + +import static org.assertj.core.api.Assertions.assertThat; + +public class CompositUtilsTests { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void getCompositeTypeListWorks() { + new WebApplicationContextRunner() + .withUserConfiguration(ConfigServerApplication.class) + .withPropertyValues("spring.profiles.active:test,composite", + "spring.config.name:compositeconfigserver", + "spring.cloud.config.server.composite[0].uri:file:./target/repos/config-repo", + "spring.cloud.config.server.composite[0].type:git", + "spring.cloud.config.server.composite[1].uri:file:///./target/repos/svn-config-repo", + "spring.cloud.config.server.composite[1].type:svn") + .run(context -> { + List types = CompositeUtils.getCompositeTypeList(context.getEnvironment()); + assertThat(types).containsExactly("git", "svn"); + }); + } + + @Test + public void getCompositeTypeListFails() { + thrown.expect(IllegalStateException.class); + + new WebApplicationContextRunner() + .withUserConfiguration(ConfigServerApplication.class) + .withPropertyValues("spring.profiles.active:test,composite", + "spring.config.name:compositeconfigserver", + "spring.cloud.config.server.composite[0].uri:file:./target/repos/config-repo", + "spring.cloud.config.server.composite[0].type:git", + "spring.cloud.config.server.composite[2].uri:file:///./target/repos/svn-config-repo", + "spring.cloud.config.server.composite[2].type:svn") + .run(context -> { + CompositeUtils.getCompositeTypeList(context.getEnvironment()); + }); + } +} diff --git a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/config/CustomCompositeEnvironmentRepositoryTests.java b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/config/CustomCompositeEnvironmentRepositoryTests.java index 194f76b8..6881d05c 100644 --- a/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/config/CustomCompositeEnvironmentRepositoryTests.java +++ b/spring-cloud-config-server/src/test/java/org/springframework/cloud/config/server/config/CustomCompositeEnvironmentRepositoryTests.java @@ -52,13 +52,13 @@ public class CustomCompositeEnvironmentRepositoryTests { @RunWith(SpringRunner.class) @SpringBootTest(classes = CustomCompositeEnvironmentRepositoryTests - .StaticConfigCustomCompositeEnvironmentRepositoryTests.TestApplication.class, properties = { + .StaticTests.Config.class, properties = { "spring.config.name:compositeconfigserver", "spring.cloud.config.server.git.uri:file:./target/repos/config-repo", "spring.cloud.config.server.git.order:1" }, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ActiveProfiles({"test", "git"}) @DirtiesContext - public static class StaticConfigCustomCompositeEnvironmentRepositoryTests { + public static class StaticTests { @LocalServerPort private int port; @@ -82,7 +82,7 @@ public class CustomCompositeEnvironmentRepositoryTests { @Configuration @EnableAutoConfiguration @EnableConfigServer - protected static class TestApplication { + protected static class Config { @Bean public EnvironmentRepository environmentRepository() { @@ -98,7 +98,7 @@ public class CustomCompositeEnvironmentRepositoryTests { @RunWith(SpringRunner.class) @SpringBootTest(classes = CustomCompositeEnvironmentRepositoryTests - .ListConfigCustomCompositeEnvironmentRepositoryTests.TestApplication.class, properties = { + .ListTests.Config.class, properties = { "spring.config.name:compositeconfigserver", "spring.cloud.config.server.composite[0].type:git", "spring.cloud.config.server.composite[0].uri:file:./target/repos/config-repo", @@ -107,7 +107,7 @@ public class CustomCompositeEnvironmentRepositoryTests { }, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ActiveProfiles({"test", "composite"}) @DirtiesContext - public static class ListConfigCustomCompositeEnvironmentRepositoryTests { + public static class ListTests { @LocalServerPort private int port; @@ -130,7 +130,7 @@ public class CustomCompositeEnvironmentRepositoryTests { @Configuration @EnableAutoConfiguration @EnableConfigServer - protected static class TestApplication { + protected static class Config { @Bean public CustomEnvironmentRepositoryFactory customEnvironmentRepositoryFactory(ConfigurableEnvironment environment)