diff --git a/pom.xml b/pom.xml
index dfaf06c7..75ed6d55 100644
--- a/pom.xml
+++ b/pom.xml
@@ -205,6 +205,13 @@
pom
import
+
+ org.springframework.cloud
+ spring-cloud-config-dependencies
+ ${spring-cloud-config.version}
+ pom
+ import
+
org.springframework.cloud
spring-cloud-openfeign-dependencies
@@ -212,6 +219,11 @@
pom
import
+
+ org.springframework.cloud
+ spring-cloud-test-support
+ ${spring-cloud-commons.version}
+
@@ -219,6 +231,7 @@
2.17
2.0.0.BUILD-SNAPSHOT
2.0.0.BUILD-SNAPSHOT
+ 2.0.0.BUILD-SNAPSHOT
2.0.0.BUILD-SNAPSHOT
2.0.0.BUILD-SNAPSHOT
diff --git a/spring-cloud-zookeeper-discovery/pom.xml b/spring-cloud-zookeeper-discovery/pom.xml
index 36d8de9b..eb6f2a51 100644
--- a/spring-cloud-zookeeper-discovery/pom.xml
+++ b/spring-cloud-zookeeper-discovery/pom.xml
@@ -108,6 +108,16 @@
spring-boot-autoconfigure-processor
true
+
+ org.springframework.cloud
+ spring-cloud-config-client
+ true
+
+
+ org.springframework.cloud
+ spring-cloud-config-server
+ true
+
org.springframework.boot
spring-boot-starter-web
@@ -118,6 +128,11 @@
spring-boot-starter-test
test
+
+ org.springframework.cloud
+ spring-cloud-test-support
+ test
+
commons-configuration
commons-configuration
diff --git a/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/configclient/ZookeeperConfigServerAutoConfiguration.java b/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/configclient/ZookeeperConfigServerAutoConfiguration.java
new file mode 100644
index 00000000..821a21b3
--- /dev/null
+++ b/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/configclient/ZookeeperConfigServerAutoConfiguration.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2013-2016 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.zookeeper.discovery.configclient;
+
+import javax.annotation.PostConstruct;
+
+import org.apache.curator.framework.CuratorFramework;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cloud.config.server.config.ConfigServerProperties;
+import org.springframework.cloud.zookeeper.discovery.ZookeeperDiscoveryProperties;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.util.StringUtils;
+
+/**
+ * Extra configuration for config server if it happens to be registered with Zookeeper.
+ *
+ * @author Dave Syer
+ */
+@Configuration
+@EnableConfigurationProperties
+@ConditionalOnClass({ ZookeeperDiscoveryProperties.class, CuratorFramework.class,
+ ConfigServerProperties.class })
+public class ZookeeperConfigServerAutoConfiguration {
+
+ @Autowired(required = false)
+ private ZookeeperDiscoveryProperties properties;
+
+ @Autowired(required = false)
+ private ConfigServerProperties server;
+
+ @PostConstruct
+ public void init() {
+ if (this.properties == null || this.server == null) {
+ return;
+ }
+ String prefix = this.server.getPrefix();
+ if (StringUtils.hasText(prefix)) {
+ this.properties.getMetadata().put("configPath", prefix);
+ }
+ }
+
+}
diff --git a/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/configclient/ZookeeperDiscoveryClientConfigServiceBootstrapConfiguration.java b/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/configclient/ZookeeperDiscoveryClientConfigServiceBootstrapConfiguration.java
new file mode 100644
index 00000000..0ff259b0
--- /dev/null
+++ b/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/configclient/ZookeeperDiscoveryClientConfigServiceBootstrapConfiguration.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2013-2016 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.zookeeper.discovery.configclient;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.cloud.commons.util.InetUtils;
+import org.springframework.cloud.config.client.ConfigServicePropertySourceLocator;
+import org.springframework.cloud.zookeeper.ZookeeperAutoConfiguration;
+import org.springframework.cloud.zookeeper.discovery.ZookeeperDiscoveryAutoConfiguration;
+import org.springframework.cloud.zookeeper.discovery.ZookeeperDiscoveryClientConfiguration;
+import org.springframework.cloud.zookeeper.discovery.ZookeeperDiscoveryProperties;
+import org.springframework.cloud.zookeeper.support.CuratorServiceDiscoveryAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.core.annotation.Order;
+
+/**
+ * Helper for config client that wants to lookup the config server via discovery.
+ *
+ * @author Spencer Gibb
+ */
+@ConditionalOnClass(ConfigServicePropertySourceLocator.class)
+@ConditionalOnProperty(value = "spring.cloud.config.discovery.enabled", matchIfMissing = false)
+@Configuration
+@Import({ ZookeeperAutoConfiguration.class, ZookeeperDiscoveryClientConfiguration.class,
+ CuratorServiceDiscoveryAutoConfiguration.class, ZookeeperDiscoveryAutoConfiguration.class})
+@Order(0)
+public class ZookeeperDiscoveryClientConfigServiceBootstrapConfiguration {
+
+ @Bean
+ public ZookeeperDiscoveryProperties zookeeperDiscoveryProperties(InetUtils inetUtils) {
+ ZookeeperDiscoveryProperties properties = new ZookeeperDiscoveryProperties(inetUtils);
+ // for bootstrap, registration is not needed, just discovery client
+ properties.setRegister(false);
+ return properties;
+ }
+}
diff --git a/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/serviceregistry/ZookeeperAutoServiceRegistration.java b/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/serviceregistry/ZookeeperAutoServiceRegistration.java
index 785012c0..8dd157f5 100644
--- a/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/serviceregistry/ZookeeperAutoServiceRegistration.java
+++ b/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/serviceregistry/ZookeeperAutoServiceRegistration.java
@@ -19,6 +19,7 @@ package org.springframework.cloud.zookeeper.serviceregistry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration;
+import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties;
import org.springframework.cloud.zookeeper.discovery.ZookeeperDiscoveryProperties;
/**
@@ -38,7 +39,14 @@ public class ZookeeperAutoServiceRegistration extends AbstractAutoServiceRegistr
public ZookeeperAutoServiceRegistration(ZookeeperServiceRegistry registry,
ZookeeperRegistration registration,
ZookeeperDiscoveryProperties properties) {
- super(registry);
+ this(registry, registration, properties, null);
+ }
+
+ public ZookeeperAutoServiceRegistration(ZookeeperServiceRegistry registry,
+ ZookeeperRegistration registration,
+ ZookeeperDiscoveryProperties properties,
+ AutoServiceRegistrationProperties arProperties) {
+ super(registry, arProperties);
this.registration = registration;
this.properties = properties;
if (this.properties.getInstancePort() != null) {
diff --git a/spring-cloud-zookeeper-discovery/src/main/resources/META-INF/spring.factories b/spring-cloud-zookeeper-discovery/src/main/resources/META-INF/spring.factories
index 7f8ed4a1..b53623ba 100644
--- a/spring-cloud-zookeeper-discovery/src/main/resources/META-INF/spring.factories
+++ b/spring-cloud-zookeeper-discovery/src/main/resources/META-INF/spring.factories
@@ -15,3 +15,7 @@ org.springframework.cloud.zookeeper.discovery.ZookeeperDiscoveryClientConfigurat
# Environment Post Processors
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.cloud.zookeeper.discovery.dependency.DependencyEnvironmentPostProcessor
+
+
+org.springframework.cloud.bootstrap.BootstrapConfiguration=\
+org.springframework.cloud.zookeeper.discovery.configclient.ZookeeperDiscoveryClientConfigServiceBootstrapConfiguration
diff --git a/spring-cloud-zookeeper-discovery/src/test/java/org/springframework/cloud/zookeeper/discovery/configclient/DiscoveryClientConfigServiceAutoConfigurationTests.java b/spring-cloud-zookeeper-discovery/src/test/java/org/springframework/cloud/zookeeper/discovery/configclient/DiscoveryClientConfigServiceAutoConfigurationTests.java
new file mode 100644
index 00000000..fdd20262
--- /dev/null
+++ b/spring-cloud-zookeeper-discovery/src/test/java/org/springframework/cloud/zookeeper/discovery/configclient/DiscoveryClientConfigServiceAutoConfigurationTests.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2013-2016 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.zookeeper.discovery.configclient;
+
+import java.util.Arrays;
+
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
+import org.springframework.boot.test.util.TestPropertyValues;
+import org.springframework.cloud.client.DefaultServiceInstance;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.cloud.commons.util.UtilAutoConfiguration;
+import org.springframework.cloud.config.client.ConfigClientProperties;
+import org.springframework.cloud.config.client.DiscoveryClientConfigServiceBootstrapConfiguration;
+import org.springframework.cloud.test.ClassPathExclusions;
+import org.springframework.cloud.test.ModifiedClassPathRunner;
+import org.springframework.cloud.zookeeper.ZookeeperAutoConfiguration;
+import org.springframework.cloud.zookeeper.discovery.ZookeeperDiscoveryClient;
+import org.springframework.cloud.zookeeper.discovery.ZookeeperDiscoveryClientConfiguration;
+import org.springframework.cloud.zookeeper.discovery.ZookeeperDiscoveryProperties;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+/**
+ * @author Dave Syer
+ */
+@RunWith(ModifiedClassPathRunner.class)
+@ClassPathExclusions({ "spring-retry-*.jar", "spring-boot-starter-aop-*.jar" })
+public class DiscoveryClientConfigServiceAutoConfigurationTests {
+
+ private AnnotationConfigApplicationContext context;
+
+ @After
+ public void close() {
+ if (this.context != null) {
+ if (this.context.getParent() != null) {
+ ((AnnotationConfigApplicationContext) this.context.getParent()).close();
+ }
+ this.context.close();
+ }
+ }
+
+ @Test
+ public void onWhenRequested() {
+ setup("server.port=7000", "spring.cloud.config.discovery.enabled=true",
+ "spring.cloud.zookeeper.discovery.instance-port:7001",
+ "spring.cloud.zookeeper.discovery.instance-host:foo",
+ "spring.cloud.config.discovery.service-id:configserver");
+ assertEquals( 1, this.context
+ .getBeanNamesForType(ZookeeperConfigServerAutoConfiguration.class).length);
+ ZookeeperDiscoveryClient client = this.context.getParent().getBean(
+ ZookeeperDiscoveryClient.class);
+ verify(client, atLeast(2)).getInstances("configserver");
+ ConfigClientProperties locator = this.context
+ .getBean(ConfigClientProperties.class);
+ assertEquals("http://foo:7001/", locator.getUri()[0]);
+ }
+
+ private void setup(String... env) {
+ AnnotationConfigApplicationContext parent = new AnnotationConfigApplicationContext();
+ TestPropertyValues.of(env).applyTo(parent);
+ parent.register(UtilAutoConfiguration.class,
+ PropertyPlaceholderAutoConfiguration.class, EnvironmentKnobbler.class,
+ ZookeeperDiscoveryClientConfigServiceBootstrapConfiguration.class,
+ DiscoveryClientConfigServiceBootstrapConfiguration.class,
+ ConfigClientProperties.class);
+ parent.refresh();
+ this.context = new AnnotationConfigApplicationContext();
+ this.context.setParent(parent);
+ this.context.register(PropertyPlaceholderAutoConfiguration.class,
+ ZookeeperConfigServerAutoConfiguration.class, ZookeeperAutoConfiguration.class,
+ ZookeeperDiscoveryClientConfiguration.class);
+ this.context.refresh();
+ }
+
+ @Configuration
+ protected static class EnvironmentKnobbler {
+
+ @Bean
+ public ZookeeperDiscoveryClient zookeeperDiscoveryClient(
+ ZookeeperDiscoveryProperties properties) {
+ ZookeeperDiscoveryClient client = mock(ZookeeperDiscoveryClient.class);
+ ServiceInstance instance = new DefaultServiceInstance("configserver",
+ properties.getInstanceHost(), properties.getInstancePort(), false);
+ given(client.getInstances("configserver"))
+ .willReturn(Arrays.asList(instance));
+ return client;
+ }
+
+ }
+
+}
diff --git a/spring-cloud-zookeeper-discovery/src/test/java/org/springframework/cloud/zookeeper/discovery/configclient/ZookeeperConfigServerAutoConfigurationTests.java b/spring-cloud-zookeeper-discovery/src/test/java/org/springframework/cloud/zookeeper/discovery/configclient/ZookeeperConfigServerAutoConfigurationTests.java
new file mode 100644
index 00000000..f8c37237
--- /dev/null
+++ b/spring-cloud-zookeeper-discovery/src/test/java/org/springframework/cloud/zookeeper/discovery/configclient/ZookeeperConfigServerAutoConfigurationTests.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2013-2016 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.zookeeper.discovery.configclient;
+
+import org.junit.After;
+import org.junit.Test;
+
+import org.springframework.boot.WebApplicationType;
+import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.cloud.config.server.config.ConfigServerProperties;
+import org.springframework.cloud.zookeeper.discovery.ZookeeperDiscoveryProperties;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author Dave Syer
+ */
+public class ZookeeperConfigServerAutoConfigurationTests {
+
+ private ConfigurableApplicationContext context;
+
+ @After
+ public void close() {
+ if (this.context != null) {
+ this.context.close();
+ }
+ }
+
+ @Test
+ public void offByDefault() {
+ this.context = new AnnotationConfigApplicationContext(
+ ZookeeperConfigServerAutoConfiguration.class);
+ assertEquals(0,
+ this.context.getBeanNamesForType(ZookeeperDiscoveryProperties.class).length);
+ }
+
+ @Test
+ public void onWhenRequested() {
+ setup("spring.cloud.config.server.prefix=/config");
+ assertEquals(1,
+ this.context.getBeanNamesForType(ZookeeperDiscoveryProperties.class).length);
+ ZookeeperDiscoveryProperties properties = this.context.getBean(ZookeeperDiscoveryProperties.class);
+ assertThat(properties.getMetadata()).containsEntry("configPath", "/config");
+ }
+
+ private void setup(String... env) {
+ this.context = new SpringApplicationBuilder(
+ PropertyPlaceholderAutoConfiguration.class,
+ ZookeeperConfigServerAutoConfiguration.class,
+ ConfigServerProperties.class, ZookeeperDiscoveryProperties.class)
+ .web(WebApplicationType.NONE)
+ .properties(env).run();
+ }
+
+}