diff --git a/spring-cloud-zookeeper-config/src/main/java/org/springframework/cloud/zookeeper/config/ZookeeperPropertySourceLocator.java b/spring-cloud-zookeeper-config/src/main/java/org/springframework/cloud/zookeeper/config/ZookeeperPropertySourceLocator.java index 8c184acd..14e11ba5 100644 --- a/spring-cloud-zookeeper-config/src/main/java/org/springframework/cloud/zookeeper/config/ZookeeperPropertySourceLocator.java +++ b/spring-cloud-zookeeper-config/src/main/java/org/springframework/cloud/zookeeper/config/ZookeeperPropertySourceLocator.java @@ -40,24 +40,27 @@ * Client. Configuration is loaded into the Spring Environment during the special * "bootstrap" phase. Configuration is stored in the {@code /config} namespace by default. * Multiple {@code PropertySource} instances are created based on the application's name - * and the active profiles that mimicks the Spring Cloud Config order of resolving - * properties. For example, an application with the name "testApp" and with the "dev" - * profile will have the following property sources created: + * and the active profiles that mimics the Spring Cloud Config order of resolving + * properties. What's more,it supports multiple business namespaces through {@code defaultContext}. + * For example, an application with the name "testApp", and with the "dev" + * profile, with "namespace1,namespace2" defaultContext will have the following property sources + * created: * *
{@code
  * config/testApp,dev
  * config/testApp
- * config/application,dev
- * config/application
+ * config/namespace1,dev
+ * config/namespace1
+ * config/namespace2,dev
+ * config/namespace2
  * }
* - * The most specific property source is at the top, with the least specific at the bottom. - * Properties is the {@code config/application} namespace are applicable to all - * applications using zookeeper for configuration. Properties in the - * {@code config/testApp} namespace are only available to the instances of the service - * named "testApp". + * Properties in the {@code config/testApp} namespace are only available to the instances of the service + * named "testApp". If you want to share the configuration with other applications, you can configure the + * same {@code defaultContext} like "namespace1" or "namespace2". * * @author Spencer Gibb + * @author lemonJ * @since 1.0.0 */ public class ZookeeperPropertySourceLocator implements PropertySourceLocator { @@ -107,16 +110,4 @@ public PropertySource locate(Environment environment) { @PreDestroy public void destroy() { } - - private PropertySource create(String context) { - return new ZookeeperPropertySource(context, this.curator); - } - - private void addProfiles(List contexts, String baseContext, - List profiles) { - for (String profile : profiles) { - contexts.add(baseContext + this.properties.getProfileSeparator() + profile); - } - } - } diff --git a/spring-cloud-zookeeper-config/src/main/java/org/springframework/cloud/zookeeper/config/ZookeeperPropertySources.java b/spring-cloud-zookeeper-config/src/main/java/org/springframework/cloud/zookeeper/config/ZookeeperPropertySources.java index 0730ff1b..3bbe5880 100644 --- a/spring-cloud-zookeeper-config/src/main/java/org/springframework/cloud/zookeeper/config/ZookeeperPropertySources.java +++ b/spring-cloud-zookeeper-config/src/main/java/org/springframework/cloud/zookeeper/config/ZookeeperPropertySources.java @@ -16,15 +16,17 @@ package org.springframework.cloud.zookeeper.config; -import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; +import java.util.stream.Stream; import org.apache.commons.logging.Log; import org.apache.curator.framework.CuratorFramework; import org.springframework.core.style.ToStringCreator; +import org.springframework.util.StringUtils; public class ZookeeperPropertySources { private final ZookeeperConfigProperties properties; @@ -44,22 +46,23 @@ public List getAutomaticContexts(List profiles, boolean reverse) } public List generateAutomaticContexts(List profiles, boolean reverse) { - List contexts = new ArrayList<>(); String root = properties.getRoot(); - String defaultContext = root + "/" + properties.getDefaultContext(); - contexts.add(new Context(defaultContext)); - addProfiles(contexts, defaultContext, profiles); - - StringBuilder baseContext = new StringBuilder(root); - if (!properties.getName().startsWith("/")) { - baseContext.append("/"); - } - // getName() defaults to ${spring.application.name} or application - baseContext.append(properties.getName()); - contexts.add(new Context(baseContext.toString())); - addProfiles(contexts, baseContext.toString(), profiles); - + //properties.getDefaultContext() may contain some configs and the former config owns higher priority. + List defaultContextList = Arrays.stream(properties.getDefaultContext().split(properties.getProfileSeparator())).collect(Collectors.toList()); + Collections.reverse(defaultContextList); + String name = properties.getName().startsWith("/") ? properties.getName().substring(1) : properties.getName(); + defaultContextList.add(name); + + List contexts = defaultContextList.stream() + .filter(StringUtils::hasLength) + .flatMap(contextString -> { + Context context = new Context(root + "/" + contextString); + Stream profileContextStream = profiles.stream() + .map(profile -> new Context(context.getPath() + this.properties.getProfileSeparator() + profile, profile)); + return Stream.concat(Stream.of(context), profileContextStream); + } + ).distinct().collect(Collectors.toList()); if (reverse) { Collections.reverse(contexts); } diff --git a/spring-cloud-zookeeper-config/src/test/java/org/springframework/cloud/zookeeper/config/ZookeeperPropertySourceLocatorTests.java b/spring-cloud-zookeeper-config/src/test/java/org/springframework/cloud/zookeeper/config/ZookeeperPropertySourceLocatorTests.java index a4f06258..28c9b259 100644 --- a/spring-cloud-zookeeper-config/src/test/java/org/springframework/cloud/zookeeper/config/ZookeeperPropertySourceLocatorTests.java +++ b/spring-cloud-zookeeper-config/src/test/java/org/springframework/cloud/zookeeper/config/ZookeeperPropertySourceLocatorTests.java @@ -198,7 +198,8 @@ public void propertyLoadedAndUpdated() throws Exception { public void compositePropertySourceHoldsPropertySourcesInCorrectOrder() { // given - final String defaultContext = "someDefaultContext"; + final String defaultContext = "someDefaultContext1,someDefaultContext2"; + String[] defaultContextArray = defaultContext.split(","); final String someName = "someName"; final String someProfile = "someProfile"; @@ -229,8 +230,11 @@ public void compositePropertySourceHoldsPropertySourcesInCorrectOrder() { .endsWith(someName + properties.getProfileSeparator() + someProfile); assertThat(propertySources.get(1).getName()).endsWith(someName); assertThat(propertySources.get(2).getName()).endsWith( - defaultContext + properties.getProfileSeparator() + someProfile); - assertThat(propertySources.get(3).getName()).endsWith(defaultContext); + defaultContextArray[0] + properties.getProfileSeparator() + someProfile); + assertThat(propertySources.get(3).getName()).endsWith(defaultContextArray[0]); + assertThat(propertySources.get(4).getName()).endsWith( + defaultContextArray[1] + properties.getProfileSeparator() + someProfile); + assertThat(propertySources.get(5).getName()).endsWith(defaultContextArray[1]); } @Configuration