diff --git a/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/ZookeeperDiscoveryClientConfiguration.java b/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/ZookeeperDiscoveryClientConfiguration.java index bfcbe3f3..ac27dc5b 100644 --- a/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/ZookeeperDiscoveryClientConfiguration.java +++ b/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/ZookeeperDiscoveryClientConfiguration.java @@ -49,20 +49,20 @@ public class ZookeeperDiscoveryClientConfiguration { private CuratorFramework curator; @Bean - public ZookeeperDiscoveryProperties zookeeperDiscoveryProperties() { - return new ZookeeperDiscoveryProperties(); + public ZookeeperDiscoveryProperties zookeeperDiscoveryProperties(InetUtils inetUtils) { + return new ZookeeperDiscoveryProperties(inetUtils); } @Bean @ConditionalOnMissingBean - public ZookeeperServiceDiscovery zookeeperServiceDiscovery(InetUtils inetUtils) { - return new ZookeeperServiceDiscovery(this.curator, zookeeperDiscoveryProperties(), - instanceSerializer(), inetUtils); + public ZookeeperServiceDiscovery zookeeperServiceDiscovery(ZookeeperDiscoveryProperties zookeeperDiscoveryProperties, InstanceSerializer instanceSerializer) { + return new ZookeeperServiceDiscovery(this.curator, zookeeperDiscoveryProperties, + instanceSerializer); } @Bean - public ZookeeperLifecycle zookeeperLifecycle(ZookeeperServiceDiscovery zookeeperServiceDiscovery) { - return new ZookeeperLifecycle(zookeeperDiscoveryProperties(), zookeeperServiceDiscovery); + public ZookeeperLifecycle zookeeperLifecycle(ZookeeperServiceDiscovery zookeeperServiceDiscovery, ZookeeperDiscoveryProperties zookeeperDiscoveryProperties) { + return new ZookeeperLifecycle(zookeeperDiscoveryProperties, zookeeperServiceDiscovery); } @Bean @@ -94,8 +94,8 @@ public class ZookeeperDiscoveryClientConfiguration { } @Bean - public ZookeeperServiceWatch zookeeperServiceWatch() { - return new ZookeeperServiceWatch(this.curator, zookeeperDiscoveryProperties()); + public ZookeeperServiceWatch zookeeperServiceWatch(ZookeeperDiscoveryProperties zookeeperDiscoveryProperties) { + return new ZookeeperServiceWatch(this.curator, zookeeperDiscoveryProperties); } } diff --git a/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/ZookeeperDiscoveryProperties.java b/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/ZookeeperDiscoveryProperties.java index 8b3b2a10..dca5e332 100644 --- a/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/ZookeeperDiscoveryProperties.java +++ b/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/ZookeeperDiscoveryProperties.java @@ -20,6 +20,7 @@ import java.util.HashMap; import java.util.Map; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.commons.util.InetUtils; /** * Properties related to Zookeeper's Service Discovery. @@ -29,6 +30,9 @@ import org.springframework.boot.context.properties.ConfigurationProperties; */ @ConfigurationProperties("spring.cloud.zookeeper.discovery") public class ZookeeperDiscoveryProperties { + + private InetUtils.HostInfo hostInfo; + private boolean enabled = true; /** @@ -47,12 +51,28 @@ public class ZookeeperDiscoveryProperties { */ private String instanceHost; + /** Port to register the service under (defaults to listening port) */ + private Integer instancePort; + + /** + * Register as a service in zookeeper. + */ + private boolean register = true; + /** * Gets the metadata name/value pairs associated with this instance. This information * is sent to zookeeper and can be used by other instances. */ private Map metadata = new HashMap<>(); + @SuppressWarnings("unused") + private ZookeeperDiscoveryProperties() {} + + public ZookeeperDiscoveryProperties(InetUtils inetUtils) { + this.hostInfo = inetUtils.findFirstNonLoopbackHostInfo(); + this.instanceHost = this.hostInfo.getIpAddress(); + } + public boolean isEnabled() { return this.enabled; } @@ -83,6 +103,7 @@ public class ZookeeperDiscoveryProperties { public void setInstanceHost(String instanceHost) { this.instanceHost = instanceHost; + this.hostInfo.override = true; } public Map getMetadata() { @@ -93,13 +114,31 @@ public class ZookeeperDiscoveryProperties { this.metadata = metadata; } + public boolean isRegister() { + return this.register; + } + + public void setRegister(boolean register) { + this.register = register; + } + + public Integer getInstancePort() { + return this.instancePort; + } + + public void setInstancePort(Integer instancePort) { + this.instancePort = instancePort; + } + @Override public String toString() { return "ZookeeperDiscoveryProperties{" + "enabled=" + this.enabled + ", root='" + this.root + '\'' + ", uriSpec='" + this.uriSpec + '\'' + ", instanceHost='" + this.instanceHost + '\'' + + ", instancePort='" + this.instancePort + '\'' + ", metadata=" + this.metadata + + ", register=" + this.register + '}'; } } diff --git a/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/ZookeeperLifecycle.java b/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/ZookeeperLifecycle.java index 369b8b27..daf3e7af 100644 --- a/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/ZookeeperLifecycle.java +++ b/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/ZookeeperLifecycle.java @@ -16,6 +16,8 @@ package org.springframework.cloud.zookeeper.discovery; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.springframework.cloud.client.discovery.AbstractDiscoveryLifecycle; import org.springframework.util.ReflectionUtils; @@ -28,6 +30,8 @@ import org.springframework.util.ReflectionUtils; */ public class ZookeeperLifecycle extends AbstractDiscoveryLifecycle { + private static final Log log = LogFactory.getLog(ZookeeperLifecycle.class); + private ZookeeperDiscoveryProperties properties; private ZookeeperServiceDiscovery serviceDiscovery; @@ -35,10 +39,18 @@ public class ZookeeperLifecycle extends AbstractDiscoveryLifecycle { ZookeeperServiceDiscovery serviceDiscovery) { this.properties = properties; this.serviceDiscovery = serviceDiscovery; + if (this.properties.getInstancePort() != null) { + this.serviceDiscovery.setPort(this.properties.getInstancePort()); + this.serviceDiscovery.build(); + } } @Override protected void register() { + if (!this.properties.isRegister()) { + log.debug("Registration disabled."); + return; + } try { this.serviceDiscovery.getServiceDiscovery().start(); } @@ -51,6 +63,9 @@ public class ZookeeperLifecycle extends AbstractDiscoveryLifecycle { @Override protected void deregister() { + if (!this.properties.isRegister()) { + return; + } try { this.serviceDiscovery.getServiceDiscovery().unregisterService( this.serviceDiscovery.getServiceInstance()); diff --git a/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/ZookeeperServiceDiscovery.java b/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/ZookeeperServiceDiscovery.java index 7002c704..11c6fa31 100644 --- a/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/ZookeeperServiceDiscovery.java +++ b/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/ZookeeperServiceDiscovery.java @@ -28,10 +28,10 @@ import org.apache.curator.x.discovery.UriSpec; import org.apache.curator.x.discovery.details.InstanceSerializer; import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Value; -import org.springframework.cloud.commons.util.InetUtils; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.util.ReflectionUtils; +import org.springframework.util.StringUtils; /** * Service discovery for Zookeeper that sets up {@link ServiceDiscovery} @@ -48,8 +48,6 @@ public class ZookeeperServiceDiscovery implements ApplicationContextAware { private InstanceSerializer instanceSerializer; - private InetUtils inetUtils; - private ApplicationContext context; private AtomicBoolean built = new AtomicBoolean(false); @@ -65,11 +63,10 @@ public class ZookeeperServiceDiscovery implements ApplicationContextAware { public ZookeeperServiceDiscovery(CuratorFramework curator, ZookeeperDiscoveryProperties properties, - InstanceSerializer instanceSerializer, InetUtils inetUtils) { + InstanceSerializer instanceSerializer) { this.curator = curator; this.properties = properties; this.instanceSerializer = instanceSerializer; - this.inetUtils = inetUtils; } public int getPort() { @@ -98,8 +95,10 @@ public class ZookeeperServiceDiscovery implements ApplicationContextAware { if (this.port.get() <= 0) { throw new IllegalStateException("Cannot create instance whose port is not greater than 0"); } - String host = this.properties.getInstanceHost() == null ? getIpAddress() : - this.properties.getInstanceHost(); + String host = this.properties.getInstanceHost(); + if (!StringUtils.hasText(host)) { + throw new IllegalStateException("instanceHost must not be empty"); + } UriSpec uriSpec = new UriSpec(this.properties.getUriSpec()); configureServiceInstance(this.serviceInstance, this.appName, this.context, this.port, host, uriSpec); @@ -149,10 +148,6 @@ public class ZookeeperServiceDiscovery implements ApplicationContextAware { // @formatter:on } - public String getIpAddress() { - return this.inetUtils.findFirstNonLoopbackAddress().getHostAddress(); - } - protected AtomicReference> getServiceDiscoveryRef() { return this.serviceDiscovery; } diff --git a/spring-cloud-zookeeper-discovery/src/test/groovy/org/springframework/cloud/zookeeper/discovery/CustomZookeeperServiceDiscovery.groovy b/spring-cloud-zookeeper-discovery/src/test/groovy/org/springframework/cloud/zookeeper/discovery/CustomZookeeperServiceDiscovery.groovy index ef990c25..0af34b48 100644 --- a/spring-cloud-zookeeper-discovery/src/test/groovy/org/springframework/cloud/zookeeper/discovery/CustomZookeeperServiceDiscovery.groovy +++ b/spring-cloud-zookeeper-discovery/src/test/groovy/org/springframework/cloud/zookeeper/discovery/CustomZookeeperServiceDiscovery.groovy @@ -6,8 +6,6 @@ import org.apache.curator.framework.CuratorFramework import org.apache.curator.x.discovery.ServiceDiscoveryBuilder import org.apache.curator.x.discovery.ServiceInstance import org.apache.curator.x.discovery.UriSpec -import org.springframework.cloud.commons.util.InetUtils -import org.springframework.cloud.commons.util.InetUtilsProperties class CustomZookeeperServiceDiscovery extends ZookeeperServiceDiscovery { @@ -15,7 +13,7 @@ class CustomZookeeperServiceDiscovery extends ZookeeperServiceDiscovery { private final String basePath CustomZookeeperServiceDiscovery(String applicationName, String basePath, CuratorFramework curator) { - super(curator, null, null, new InetUtils(new InetUtilsProperties())) + super(curator, null, null) this.applicationName = applicationName this.basePath = basePath build() diff --git a/spring-cloud-zookeeper-discovery/src/test/groovy/org/springframework/cloud/zookeeper/discovery/ZookeeperLifecycleRegistrationDisabledTests.java b/spring-cloud-zookeeper-discovery/src/test/groovy/org/springframework/cloud/zookeeper/discovery/ZookeeperLifecycleRegistrationDisabledTests.java new file mode 100644 index 00000000..4e2d1c4a --- /dev/null +++ b/spring-cloud-zookeeper-discovery/src/test/groovy/org/springframework/cloud/zookeeper/discovery/ZookeeperLifecycleRegistrationDisabledTests.java @@ -0,0 +1,75 @@ +/* + * 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; + +import java.io.IOException; +import java.util.List; + +import org.apache.curator.test.TestingServer; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.boot.test.WebIntegrationTest; +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.zookeeper.ZookeeperAutoConfiguration; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import static org.junit.Assert.assertTrue; + +/** + * @author Spencer Gibb + */ +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = ZookeeperLifecycleRegistrationDisabledTests.TestPropsConfig.class) +@WebIntegrationTest(value = { "spring.application.name=myTestNotRegisteredService", + "spring.cloud.zookeeper.discovery.register=false"}, randomPort = true) +public class ZookeeperLifecycleRegistrationDisabledTests { + + static TestingServer testingServer; + + @BeforeClass + public static void before() throws Exception { + testingServer = new TestingServer(2181); + } + + @AfterClass + public static void clean() throws IOException { + testingServer.close(); + } + + @Autowired + private ZookeeperDiscoveryClient client; + + @Test + public void contextLoads() { + List instances = client.getInstances("myTestNotRegisteredService"); + assertTrue("service was registered", instances.isEmpty()); + } + + @Configuration + @EnableAutoConfiguration + @Import({ ZookeeperAutoConfiguration.class, ZookeeperDiscoveryClientConfiguration.class }) + static class TestPropsConfig { + + } +} \ No newline at end of file