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