Added an option to use SC-Zookeeper in a non-web app
without this change when you don't use web environment then your context fails to start
with this change we allow users to use sc-zookeeper as a clients without the need to register in SC-Zookeeper
fixes #91
This commit is contained in:
committed by
Dave Syer
parent
358f9a9df0
commit
1b44ab895f
@@ -95,11 +95,11 @@ a modified file in the correct place. Just commit it and push the change.
|
||||
If you don't have an IDE preference we would recommend that you use
|
||||
http://www.springsource.com/developer/sts[Spring Tools Suite] or
|
||||
http://eclipse.org[Eclipse] when working with the code. We use the
|
||||
http://eclipse.org/m2e/[m2eclipe] eclipse plugin for maven support. Other IDEs and tools
|
||||
http://eclipse.org/m2e/[m2eclipse] eclipse plugin for maven support. Other IDEs and tools
|
||||
should also work without issue as long as they use Maven 3.3.3 or better.
|
||||
|
||||
==== Importing into eclipse with m2eclipse
|
||||
We recommend the http://eclipse.org/m2e/[m2eclipe] eclipse plugin when working with
|
||||
We recommend the http://eclipse.org/m2e/[m2eclipse] eclipse plugin when working with
|
||||
eclipse. If you don't already have m2eclipse installed it is available from the "eclipse
|
||||
marketplace".
|
||||
|
||||
|
||||
@@ -84,6 +84,9 @@ public class ZookeeperDiscoveryClient implements DiscoveryClient {
|
||||
public List<org.springframework.cloud.client.ServiceInstance> getInstances(
|
||||
final String serviceId) {
|
||||
try {
|
||||
if (this.serviceDiscovery.getServiceDiscovery() == null) {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
String serviceIdToQuery = getServiceIdToQuery(serviceId);
|
||||
Collection<ServiceInstance<ZookeeperInstance>> zkInstances = this.serviceDiscovery
|
||||
.getServiceDiscovery().queryForInstances(serviceIdToQuery);
|
||||
|
||||
@@ -43,6 +43,7 @@ public class ZookeeperLifecycle extends AbstractDiscoveryLifecycle {
|
||||
this.serviceDiscovery.setPort(this.properties.getInstancePort());
|
||||
this.serviceDiscovery.build();
|
||||
}
|
||||
this.serviceDiscovery.buildServiceDiscovery();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -91,6 +92,7 @@ public class ZookeeperLifecycle extends AbstractDiscoveryLifecycle {
|
||||
protected void setConfiguredPort(int port) {
|
||||
this.serviceDiscovery.setPort(port);
|
||||
this.serviceDiscovery.build();
|
||||
this.serviceDiscovery.buildServiceDiscovery();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -21,14 +21,14 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.AbstractServerList;
|
||||
|
||||
import org.apache.curator.x.discovery.ServiceDiscovery;
|
||||
import org.apache.curator.x.discovery.ServiceInstance;
|
||||
import org.springframework.cloud.zookeeper.discovery.dependency.ZookeeperDependencies;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.AbstractServerList;
|
||||
|
||||
import static org.springframework.util.ReflectionUtils.rethrowRuntimeException;
|
||||
|
||||
/**
|
||||
@@ -76,6 +76,9 @@ public class ZookeeperServerList extends AbstractServerList<ZookeeperServer> {
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<ZookeeperServer> getServers() {
|
||||
try {
|
||||
if (this.serviceDiscovery == null) {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
Collection<ServiceInstance<ZookeeperInstance>> instances = this.serviceDiscovery
|
||||
.queryForInstances(this.serviceId);
|
||||
if (instances == null || instances.isEmpty()) {
|
||||
|
||||
@@ -90,9 +90,13 @@ public class ZookeeperServiceDiscovery implements ApplicationContextAware {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds Service Instance - needs to be used when you want to register your application
|
||||
* in Zookeeper
|
||||
*/
|
||||
public void build() {
|
||||
if (this.built.compareAndSet(false, true)) {
|
||||
if (this.port.get() <= 0) {
|
||||
if (this.port.get() <= 0 && this.properties.isRegister()) {
|
||||
throw new IllegalStateException("Cannot create instance whose port is not greater than 0");
|
||||
}
|
||||
String host = this.properties.getInstanceHost();
|
||||
@@ -100,13 +104,22 @@ public class ZookeeperServiceDiscovery implements ApplicationContextAware {
|
||||
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);
|
||||
configureServiceDiscovery(this.serviceDiscovery, this.curator, this.properties,
|
||||
this.instanceSerializer, this.serviceInstance);
|
||||
if (this.properties.isRegister()) {
|
||||
configureServiceInstance(this.serviceInstance, this.appName,
|
||||
this.context, this.port, host, uriSpec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds Service Discovery - needs to be used if you want to use Zookeeper as a client application.
|
||||
* You don't have to register in Zookeeper to use Service Discovery.
|
||||
*/
|
||||
public void buildServiceDiscovery() {
|
||||
configureServiceDiscovery(this.serviceDiscovery, this.curator, this.properties,
|
||||
this.instanceSerializer, this.serviceInstance);
|
||||
}
|
||||
|
||||
/**
|
||||
* One can override this method to provide custom way of registering a service
|
||||
* instance (e.g. when no payload is required).
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
package org.springframework.cloud.zookeeper.discovery.issues.issue91;
|
||||
|
||||
import org.apache.curator.test.TestingServer;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.actuate.autoconfigure.EndpointMBeanExportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.util.SocketUtils;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import com.jayway.awaitility.Awaitility;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public class Issue91Tests {
|
||||
|
||||
TestingServer server;
|
||||
String connectionString;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
this.server = new TestingServer(SocketUtils.findAvailableTcpPort());
|
||||
this.connectionString = "--spring.cloud.zookeeper.connectString=" + this.server.getConnectString();
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanup() throws Exception {
|
||||
this.server.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_work_when_using_web_client_without_the_web_environment()
|
||||
throws Exception {
|
||||
SpringApplication producerApp = new SpringApplication(HelloProducer.class);
|
||||
producerApp.setWebEnvironment(true);
|
||||
SpringApplication clientApplication = new SpringApplication(HelloClient.class);
|
||||
clientApplication.setWebEnvironment(false);
|
||||
|
||||
try (ConfigurableApplicationContext producerContext = producerApp.run(this.connectionString, "--server.port=0",
|
||||
"--spring.application.name=hello-world")) {
|
||||
try (final ConfigurableApplicationContext context = clientApplication.run(this.connectionString,
|
||||
"--spring.cloud.zookeeper.discovery.register=false")) {
|
||||
Awaitility.await().until(new Runnable() {
|
||||
@Override public void run() {
|
||||
try {
|
||||
HelloClient bean = context.getBean(HelloClient.class);
|
||||
then(bean.discoveryClient.getServices()).isNotEmpty();
|
||||
then(bean.discoveryClient.getInstances("hello-world")).isNotEmpty();
|
||||
String string = bean.restTemplate.getForObject("http://hello-world/", String.class);
|
||||
then(string).isEqualTo("foo");
|
||||
} catch (IllegalStateException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration(exclude = {EndpointMBeanExportAutoConfiguration.class,
|
||||
JmxAutoConfiguration.class})
|
||||
@EnableDiscoveryClient
|
||||
@Configuration
|
||||
class HelloClient {
|
||||
@LoadBalanced @Bean RestTemplate restTemplate() {
|
||||
return new RestTemplate();
|
||||
}
|
||||
|
||||
@Autowired DiscoveryClient discoveryClient;
|
||||
|
||||
@Autowired RestTemplate restTemplate;
|
||||
}
|
||||
|
||||
@EnableAutoConfiguration(exclude = {EndpointMBeanExportAutoConfiguration.class,
|
||||
JmxAutoConfiguration.class})
|
||||
@EnableDiscoveryClient
|
||||
@RestController
|
||||
class HelloProducer {
|
||||
|
||||
@RequestMapping("/")
|
||||
public String foo() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user