You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@servicecomb.apache.org by GitBox <gi...@apache.org> on 2018/01/09 06:54:20 UTC

[GitHub] wujimin closed pull request #492: [SCB-184]Provide starters for Spring Cloud to using service-center and config-center

wujimin closed pull request #492: [SCB-184]Provide starters for Spring Cloud to using service-center and config-center
URL: https://github.com/apache/incubator-servicecomb-java-chassis/pull/492
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/core/src/test/java/io/servicecomb/core/TestTransport.java b/core/src/test/java/io/servicecomb/core/TestTransport.java
index 4fda7c79a..d669df42e 100644
--- a/core/src/test/java/io/servicecomb/core/TestTransport.java
+++ b/core/src/test/java/io/servicecomb/core/TestTransport.java
@@ -17,14 +17,24 @@
 
 package io.servicecomb.core;
 
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.junit.Assert;
 import org.junit.Test;
 
 import io.servicecomb.core.endpoint.EndpointsCache;
+import io.servicecomb.core.transport.TransportManager;
 import io.servicecomb.serviceregistry.api.registry.Microservice;
+import io.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
+import io.servicecomb.serviceregistry.cache.CacheEndpoint;
+import io.servicecomb.serviceregistry.cache.InstanceCache;
+import io.servicecomb.serviceregistry.cache.InstanceCacheManager;
 import io.servicecomb.swagger.invocation.AsyncResponse;
+import mockit.Expectations;
+import mockit.Injectable;
 import mockit.Mocked;
 
 public class TestTransport {
@@ -69,15 +79,34 @@ public Endpoint getPublishEndpoint() throws Exception {
   }
 
   @Test
-  public void testAbstractTransport(@Mocked Microservice microservice) throws Exception {
+  public void testAbstractTransport(@Mocked Microservice microservice,
+      @Injectable InstanceCacheManager instanceCacheManager, @Injectable TransportManager transportManager,
+      @Mocked InstanceCache instanceCache, @Injectable MicroserviceInstance instance)
+      throws Exception {
+    EndpointsCache.init(instanceCacheManager, transportManager);
+    EndpointsCache oEndpointsCache = new EndpointsCache("app", "testname", "test", "rest");
 
-    EndpointsCache oEndpointsCache = new EndpointsCache("app", "testname", "test", "test");
+    List<Endpoint> endpoionts = oEndpointsCache.getLatestEndpoints();
+    Assert.assertEquals(endpoionts.size(), 0);
 
-    try {
-      List<Endpoint> endpoionts = oEndpointsCache.getLatestEndpoints();
-      Assert.assertEquals(endpoionts.size(), 0);
-    } catch (Exception e) {
-      Assert.assertEquals(null, e.getMessage());
-    }
+    Map<String, List<CacheEndpoint>> allTransportMap = new HashMap<>();
+    CacheEndpoint cacheEndpoint = new CacheEndpoint("rest://127.0.0.1:9999", instance);
+    List<CacheEndpoint> restEndpoints = new ArrayList<>();
+    restEndpoints.add(cacheEndpoint);
+    allTransportMap.put("rest", restEndpoints);
+
+    new Expectations() {
+      {
+        instanceCacheManager.getOrCreate(anyString, anyString, anyString);
+        result = instanceCache;
+        instanceCache.cacheChanged((InstanceCache) any);
+        result = true;
+        instanceCache.getOrCreateTransportMap();
+        result = allTransportMap;
+      }
+    };
+
+    endpoionts = oEndpointsCache.getLatestEndpoints();
+    Assert.assertEquals(endpoionts.size(), 1);
   }
 }
diff --git a/demo/demo-spring-boot-discovery/demo-spring-boot-zuul-proxy/src/test/resources/application.yml b/demo/demo-spring-boot-discovery/demo-spring-boot-zuul-proxy/src/test/resources/application.yml
index 2d867a7a5..ef24bce0c 100644
--- a/demo/demo-spring-boot-discovery/demo-spring-boot-zuul-proxy/src/test/resources/application.yml
+++ b/demo/demo-spring-boot-discovery/demo-spring-boot-zuul-proxy/src/test/resources/application.yml
@@ -17,16 +17,15 @@
 
 server:
   port: 0
-spring:
-  cloud:
-    cse:
-      host: 127.0.0.1
-      port: 9980
+
 zuul:
   routes:
     gateway:
       serviceId: discoveryServer
-
+discoveryServer:
+  ribbon:
+    eureka:
+      enabled: false
 hystrix:
   command:
     default:
diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/io/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java b/demo/demo-springmvc/springmvc-client/src/main/java/io/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java
index d588c22a0..7140cd617 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/java/io/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java
+++ b/demo/demo-springmvc/springmvc-client/src/main/java/io/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java
@@ -144,6 +144,8 @@ private void testFallback(RestTemplate template, String cseUrlPrefix) {
               "springmvc.codeFirst.fallbackThrowException").getMessage());
     }
 
+    result = template.getForObject(cseUrlPrefix + "/fallback/fromcache/hello", String.class);
+    TestMgr.check(result, "hello");
     result = template.getForObject(cseUrlPrefix + "/fallback/fromcache/hello", String.class);
     TestMgr.check(result, "hello");
     result = template.getForObject(cseUrlPrefix + "/fallback/fromcache/throwexception", String.class);
diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/io/servicecomb/demo/springmvc/client/SpringmvcClient.java b/demo/demo-springmvc/springmvc-client/src/main/java/io/servicecomb/demo/springmvc/client/SpringmvcClient.java
index 7a7a1aacc..bd2343374 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/java/io/servicecomb/demo/springmvc/client/SpringmvcClient.java
+++ b/demo/demo-springmvc/springmvc-client/src/main/java/io/servicecomb/demo/springmvc/client/SpringmvcClient.java
@@ -51,7 +51,6 @@
   private static MetricsPublisher metricsPublisher;
 
   public static void main(String[] args) throws Exception {
-    templateUrlWithServiceName.setRequestFactory(new UrlWithServiceNameClientHttpRequestFactory());
     Log4jUtils.init();
     BeanUtils.init();
 
@@ -61,6 +60,7 @@ public static void main(String[] args) throws Exception {
   }
 
   public static void run() throws Exception {
+    templateUrlWithServiceName.setRequestFactory(new UrlWithServiceNameClientHttpRequestFactory());
     restTemplate = RestTemplateBuilder.create();
     controller = BeanUtils.getBean("controller");
     metricsPublisher = BeanUtils.getBean("metricsPublisher");
diff --git a/handlers/handler-loadbalance/src/main/java/io/servicecomb/loadbalance/ServerListCache.java b/handlers/handler-loadbalance/src/main/java/io/servicecomb/loadbalance/ServerListCache.java
deleted file mode 100644
index cb035ea3b..000000000
--- a/handlers/handler-loadbalance/src/main/java/io/servicecomb/loadbalance/ServerListCache.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 io.servicecomb.loadbalance;
-
-import com.netflix.loadbalancer.Server;
-
-import io.servicecomb.core.Transport;
-import io.servicecomb.core.endpoint.AbstractEndpointsCache;
-import io.servicecomb.serviceregistry.cache.CacheEndpoint;
-
-public class ServerListCache extends AbstractEndpointsCache<Server> {
-
-  public ServerListCache(String appId, String microserviceName, String microserviceVersionRule,
-      String transportName) {
-    super(appId, microserviceName, microserviceVersionRule, transportName);
-  }
-
-  @Override
-  protected Server createEndpoint(Transport transport, CacheEndpoint cacheEndpoint) {
-    return new CseServer(transport, cacheEndpoint);
-  }
-}
diff --git a/handlers/handler-loadbalance/src/test/java/io/servicecomb/loadbalance/TestServerListCache.java b/handlers/handler-loadbalance/src/test/java/io/servicecomb/loadbalance/TestServerListCache.java
deleted file mode 100644
index 8b896503b..000000000
--- a/handlers/handler-loadbalance/src/test/java/io/servicecomb/loadbalance/TestServerListCache.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 io.servicecomb.loadbalance;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import com.netflix.loadbalancer.Server;
-
-import io.servicecomb.core.Transport;
-import io.servicecomb.serviceregistry.cache.CacheEndpoint;
-import io.servicecomb.serviceregistry.cache.InstanceCache;
-import io.servicecomb.serviceregistry.cache.InstanceCacheManager;
-import mockit.Mock;
-import mockit.MockUp;
-
-public class TestServerListCache {
-
-  private ServerListCache instance = null;
-
-  private Transport transport = null;
-
-  private void mockTestCases() {
-    new MockUp<InstanceCacheManager>() {
-      @Mock
-      public InstanceCache getOrCreate(String appId, String microserviceName, String microserviceVersionRule) {
-        return null;
-      }
-    };
-
-    transport = Mockito.mock(Transport.class);
-  }
-
-  @Before
-  public void setUp() throws Exception {
-    mockTestCases();
-    instance = new ServerListCache("appId", "microserviceName", "microserviceVersionRule", "transportName");
-  }
-
-  @After
-  public void tearDown() throws Exception {
-    instance = null;
-  }
-
-  @Test
-  public void testServerListCache() {
-    Assert.assertNotNull(instance);
-  }
-
-  @Test
-  public void testCreateEndpointTransportString() {
-    Server server = instance.createEndpoint(transport, new CacheEndpoint("stringAddress", null));
-    Assert.assertNotNull(server);
-  }
-}
diff --git a/spring-boot-starter/spring-boot-starter-discovery/pom.xml b/spring-boot-starter/spring-boot-starter-discovery/pom.xml
index 7a3030f35..df6c9ff1b 100644
--- a/spring-boot-starter/spring-boot-starter-discovery/pom.xml
+++ b/spring-boot-starter/spring-boot-starter-discovery/pom.xml
@@ -26,10 +26,6 @@
 	<artifactId>spring-boot-starter-discovery</artifactId>
 
 	<dependencies>
-		<dependency>
-			<groupId>org.apache.tomcat.embed</groupId>
-			<artifactId>tomcat-embed-logging-juli</artifactId>
-		</dependency>
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
 			<artifactId>spring-boot-starter</artifactId>
@@ -76,39 +72,7 @@
 		</dependency>
 		<dependency>
 			<groupId>io.servicecomb</groupId>
-			<artifactId>common-rest</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>io.servicecomb</groupId>
-			<artifactId>java-chassis-core</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>io.servicecomb</groupId>
-			<artifactId>provider-pojo</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>io.servicecomb</groupId>
-			<artifactId>provider-rest-common</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>io.servicecomb</groupId>
-			<artifactId>provider-jaxrs</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>io.servicecomb</groupId>
-			<artifactId>provider-springmvc</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>io.servicecomb</groupId>
-			<artifactId>transport-rest-client</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>io.servicecomb</groupId>
-			<artifactId>transport-rest-servlet</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>io.servicecomb</groupId>
-			<artifactId>handler-loadbalance</artifactId>
+			<artifactId>service-registry</artifactId>
 		</dependency>
 	</dependencies>
 </project>
diff --git a/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseDiscoveryClient.java b/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseDiscoveryClient.java
index 9a63edaa9..28b68f353 100644
--- a/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseDiscoveryClient.java
+++ b/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseDiscoveryClient.java
@@ -18,25 +18,25 @@
 
 import java.util.ArrayList;
 import java.util.List;
-
-import javax.inject.Inject;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.springframework.cloud.client.DefaultServiceInstance;
 import org.springframework.cloud.client.ServiceInstance;
 import org.springframework.cloud.client.discovery.DiscoveryClient;
 
-import io.servicecomb.core.provider.consumer.ConsumerProviderManager;
-import io.servicecomb.core.provider.consumer.ReferenceConfig;
+import io.servicecomb.foundation.common.cache.VersionedCache;
 import io.servicecomb.foundation.common.net.URIEndpointObject;
 import io.servicecomb.serviceregistry.RegistryUtils;
 import io.servicecomb.serviceregistry.api.registry.Microservice;
 import io.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
 import io.servicecomb.serviceregistry.client.ServiceRegistryClient;
+import io.servicecomb.serviceregistry.definition.DefinitionConst;
+import io.servicecomb.serviceregistry.discovery.DiscoveryContext;
+import io.servicecomb.serviceregistry.discovery.DiscoveryTree;
 
 public class CseDiscoveryClient implements DiscoveryClient {
-
-  @Inject
-  private ConsumerProviderManager consumerProviderManager;
+  private Map<String, DiscoveryTree> discoveryTrees = new ConcurrentHashMap<>();
 
   @Override
   public String description() {
@@ -45,21 +45,21 @@ public String description() {
 
   @Override
   public List<ServiceInstance> getInstances(final String serviceId) {
-    List<ServiceInstance> instances = new ArrayList<>();
-    ServiceRegistryClient client = RegistryUtils.getServiceRegistryClient();
-    String appId = RegistryUtils.getAppId();
-    ReferenceConfig referenceConfig = consumerProviderManager.getReferenceConfig(serviceId);
-    String versionRule = referenceConfig.getMicroserviceVersionRule();
-    String cseServiceID = client.getMicroserviceId(appId, serviceId, versionRule);
-    List<MicroserviceInstance> cseServices = client.getMicroserviceInstance(cseServiceID, cseServiceID);
-    if (null != cseServices && !cseServices.isEmpty()) {
-      for (MicroserviceInstance instance : cseServices) {
-        List<String> eps = instance.getEndpoints();
-        for (String ep : eps) {
-          URIEndpointObject uri = new URIEndpointObject(ep);
-          instances.add(new DefaultServiceInstance(instance.getServiceId(), uri.getHostOrIp(),
-              uri.getPort(), false));
-        }
+    DiscoveryContext context = new DiscoveryContext();
+    context.setInputParameters(serviceId);
+    DiscoveryTree discoveryTree = discoveryTrees.computeIfAbsent(serviceId, key -> {
+      return new DiscoveryTree();
+    });
+    VersionedCache serversVersionedCache = discoveryTree.discovery(context,
+        RegistryUtils.getAppId(),
+        serviceId,
+        DefinitionConst.VERSION_RULE_ALL);
+    Map<String, MicroserviceInstance> servers = serversVersionedCache.data();
+    List<ServiceInstance> instances = new ArrayList<>(servers.size());
+    for (MicroserviceInstance s : servers.values()) {
+      for (String endpoint : s.getEndpoints()) {
+        URIEndpointObject uri = new URIEndpointObject(endpoint);
+        instances.add(new DefaultServiceInstance(serviceId, uri.getHostOrIp(), uri.getPort(), uri.isSslEnabled()));
       }
     }
     return instances;
diff --git a/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseDiscoveryClientConfiguration.java b/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseDiscoveryClientConfiguration.java
index e8768b072..19b38b784 100644
--- a/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseDiscoveryClientConfiguration.java
+++ b/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseDiscoveryClientConfiguration.java
@@ -17,33 +17,17 @@
 package io.servicecomb.springboot.starter.discovery;
 
 import org.springframework.boot.autoconfigure.AutoConfigureBefore;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
 import org.springframework.cloud.client.discovery.DiscoveryClient;
 import org.springframework.cloud.client.discovery.noop.NoopDiscoveryClientAutoConfiguration;
-import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Primary;
-
-import io.servicecomb.core.provider.consumer.ConsumerProviderManager;
+import org.springframework.core.annotation.Order;
 
 @AutoConfigureBefore(NoopDiscoveryClientAutoConfiguration.class)
 @Configuration
 public class CseDiscoveryClientConfiguration {
-
-  @Bean
-  public CseDiscoveryProperties cseDiscoveryProperties() {
-    return new CseDiscoveryProperties();
-  }
-
-  @Bean
-  @ConditionalOnBean(ZuulProperties.class)
-  public CseRoutesProperties cseRoutesProperties(ConsumerProviderManager manager) {
-    return new CseRoutesProperties(manager);
-  }
-
   @Bean
-  @Primary
+  @Order(5000)
   public DiscoveryClient cseDiscoveryClient() {
     return new CseDiscoveryClient();
   }
diff --git a/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseDiscoveryProperties.java b/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseDiscoveryProperties.java
deleted file mode 100644
index 96773f81b..000000000
--- a/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseDiscoveryProperties.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 io.servicecomb.springboot.starter.discovery;
-
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-@ConfigurationProperties("spring.cloud.cse")
-public class CseDiscoveryProperties {
-
-  /** Hostname to use when accessing server */
-  private String host;
-
-  /** Port to register the service under (defaults to listening port) */
-  private String port;
-
-  public CseDiscoveryProperties() {
-  }
-
-  public String getHost() {
-    return host;
-  }
-
-  public void setHost(String host) {
-    this.host = host;
-  }
-
-  public String getPort() {
-    return port;
-  }
-
-  public void setPort(String port) {
-    this.port = port;
-  }
-}
diff --git a/spring-boot-starter/spring-boot-starter-discovery/src/main/java/ribbon/io/servicecomb/springboot/starter/discovery/CseRibbonClientConfiguration.java b/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseRibbonClientConfiguration.java
similarity index 80%
rename from spring-boot-starter/spring-boot-starter-discovery/src/main/java/ribbon/io/servicecomb/springboot/starter/discovery/CseRibbonClientConfiguration.java
rename to spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseRibbonClientConfiguration.java
index cffa70c21..fabb086c7 100644
--- a/spring-boot-starter/spring-boot-starter-discovery/src/main/java/ribbon/io/servicecomb/springboot/starter/discovery/CseRibbonClientConfiguration.java
+++ b/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseRibbonClientConfiguration.java
@@ -1,51 +1,45 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 ribbon.io.servicecomb.springboot.starter.discovery;
-
-import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
-import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import com.netflix.client.config.IClientConfig;
-import com.netflix.loadbalancer.Server;
-import com.netflix.loadbalancer.ServerList;
-
-import io.servicecomb.springboot.starter.discovery.CseRoutesProperties;
-import io.servicecomb.springboot.starter.discovery.ServiceCombServerList;
-
-/**
- * Custom {@link org.springframework.cloud.netflix.ribbon.RibbonClient} configuration must not be
- * scanned by spring.
- *
- * @see <a href="http://cloud.spring.io/spring-cloud-static/Camden.SR4/#_customizing_the_ribbon_client">
- * Customizing the Ribbon Client </a>
- */
-@Configuration
-@ConditionalOnBean(ZuulProperties.class)
-public class CseRibbonClientConfiguration {
-
-  @Bean
-  ServerList<Server> ribbonServerList(
-      IClientConfig config,
-      CseRoutesProperties cseRoutesProperties) {
-
-    ServiceCombServerList serverList = new ServiceCombServerList(cseRoutesProperties);
-    serverList.initWithNiwsConfig(config);
-    return serverList;
-  }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 io.servicecomb.springboot.starter.discovery;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration;
+import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import com.netflix.client.config.IClientConfig;
+import com.netflix.loadbalancer.Server;
+import com.netflix.loadbalancer.ServerList;
+
+/**
+ * Custom {@link org.springframework.cloud.netflix.ribbon.RibbonClient} configuration must not be
+ * scanned by spring.
+ *
+ * @see <a href="http://cloud.spring.io/spring-cloud-static/Camden.SR4/#_customizing_the_ribbon_client">
+ * Customizing the Ribbon Client </a>
+ */
+public class CseRibbonClientConfiguration {
+  @Bean
+  public ServerList<Server> ribbonServerList(
+      IClientConfig config) {
+    ServiceCombServerList serverList = new ServiceCombServerList();
+    serverList.initWithNiwsConfig(config);
+    return serverList;
+  }
+}
diff --git a/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/RibbonCseAutoConfiguration.java b/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseRibbonConfiguration.java
similarity index 92%
rename from spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/RibbonCseAutoConfiguration.java
rename to spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseRibbonConfiguration.java
index ba92c70cc..deb06d142 100644
--- a/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/RibbonCseAutoConfiguration.java
+++ b/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseRibbonConfiguration.java
@@ -1,36 +1,34 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 io.servicecomb.springboot.starter.discovery;
-
-import org.springframework.boot.autoconfigure.AutoConfigureAfter;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
-import org.springframework.cloud.netflix.ribbon.RibbonClients;
-import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
-import org.springframework.context.annotation.Configuration;
-
-import ribbon.io.servicecomb.springboot.starter.discovery.CseRibbonClientConfiguration;
-
-@Configuration
-@EnableConfigurationProperties
-@ConditionalOnBean(SpringClientFactory.class)
-@AutoConfigureAfter(RibbonAutoConfiguration.class)
-@RibbonClients(defaultConfiguration = CseRibbonClientConfiguration.class)
-public class RibbonCseAutoConfiguration {
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 io.servicecomb.springboot.starter.discovery;
+
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
+import org.springframework.cloud.netflix.ribbon.RibbonClients;
+import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@EnableConfigurationProperties
+@ConditionalOnBean(SpringClientFactory.class)
+@AutoConfigureAfter(RibbonAutoConfiguration.class)
+@RibbonClients(defaultConfiguration = CseRibbonClientConfiguration.class)
+public class CseRibbonConfiguration {
+
+}
diff --git a/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseRoutesProperties.java b/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseRoutesProperties.java
deleted file mode 100644
index 15db9b2b8..000000000
--- a/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseRoutesProperties.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 io.servicecomb.springboot.starter.discovery;
-
-import org.springframework.beans.factory.annotation.Autowired;
-
-import io.servicecomb.core.provider.consumer.ConsumerProviderManager;
-import io.servicecomb.core.provider.consumer.ReferenceConfig;
-import io.servicecomb.serviceregistry.RegistryUtils;
-
-public final class CseRoutesProperties {
-
-  private final ConsumerProviderManager consumerProviderManager;
-
-  @Autowired
-  CseRoutesProperties(ConsumerProviderManager consumerProviderManager) {
-    this.consumerProviderManager = consumerProviderManager;
-  }
-
-  String getVersionRule(String serviceName) {
-    ReferenceConfig referenceConfig = consumerProviderManager.getReferenceConfig(serviceName);
-    return referenceConfig.getMicroserviceVersionRule();
-  }
-
-  String getAppID() {
-    return RegistryUtils.getAppId();
-  }
-}
diff --git a/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseServerListCacheWrapper.java b/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseServerListCacheWrapper.java
deleted file mode 100644
index 73f2c9dd8..000000000
--- a/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseServerListCacheWrapper.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 io.servicecomb.springboot.starter.discovery;
-
-import com.netflix.loadbalancer.Server;
-
-import io.servicecomb.core.Transport;
-import io.servicecomb.loadbalance.ServerListCache;
-import io.servicecomb.serviceregistry.cache.CacheEndpoint;
-
-public class CseServerListCacheWrapper extends ServerListCache {
-
-  public CseServerListCacheWrapper(String appId, String microserviceName, String microserviceVersionRule,
-      String transportName) {
-    super(appId, microserviceName, microserviceVersionRule, transportName);
-  }
-
-  @Override
-  protected Server createEndpoint(Transport transport, CacheEndpoint cacheEndpoint) {
-    return new CseServerWrapper(transport, cacheEndpoint);
-  }
-}
diff --git a/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseServerWrapper.java b/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseServerWrapper.java
deleted file mode 100644
index b3d7c6caa..000000000
--- a/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/CseServerWrapper.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 io.servicecomb.springboot.starter.discovery;
-
-import io.servicecomb.core.Transport;
-import io.servicecomb.foundation.common.net.URIEndpointObject;
-import io.servicecomb.loadbalance.CseServer;
-import io.servicecomb.serviceregistry.cache.CacheEndpoint;
-
-public class CseServerWrapper extends CseServer {
-
-  public CseServerWrapper(Transport transport, CacheEndpoint cacheEndpoint) {
-    super(transport, cacheEndpoint);
-  }
-
-  // used in LoadBalancerContext
-  public String getHost() {
-    URIEndpointObject host = (URIEndpointObject) getEndpoint().getAddress();
-    return host.getHostOrIp();
-  }
-
-  public int getPort() {
-    URIEndpointObject host = (URIEndpointObject) getEndpoint().getAddress();
-    return host.getPort();
-  }
-}
diff --git a/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/ServiceCombDiscoveryException.java b/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/ServiceCombDiscoveryException.java
deleted file mode 100644
index 4848513d5..000000000
--- a/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/ServiceCombDiscoveryException.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 io.servicecomb.springboot.starter.discovery;
-
-public class ServiceCombDiscoveryException extends RuntimeException {
-  private static final long serialVersionUID = 3806741463767943277L;
-
-  public ServiceCombDiscoveryException(String message) {
-    super(message);
-  }
-}
diff --git a/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/ServiceCombServerList.java b/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/ServiceCombServerList.java
index 74f0ba554..5edb8e5e2 100644
--- a/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/ServiceCombServerList.java
+++ b/spring-boot-starter/spring-boot-starter-discovery/src/main/java/io/servicecomb/springboot/starter/discovery/ServiceCombServerList.java
@@ -16,65 +16,57 @@
  */
 package io.servicecomb.springboot.starter.discovery;
 
+import java.util.ArrayList;
 import java.util.List;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import java.util.Map;
 
 import com.netflix.client.config.IClientConfig;
 import com.netflix.loadbalancer.AbstractServerList;
 import com.netflix.loadbalancer.Server;
 
-import io.servicecomb.loadbalance.ServerListCache;
+import io.servicecomb.foundation.common.cache.VersionedCache;
+import io.servicecomb.foundation.common.net.URIEndpointObject;
+import io.servicecomb.serviceregistry.RegistryUtils;
+import io.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
+import io.servicecomb.serviceregistry.definition.DefinitionConst;
+import io.servicecomb.serviceregistry.discovery.DiscoveryContext;
+import io.servicecomb.serviceregistry.discovery.DiscoveryTree;
 
 public class ServiceCombServerList extends AbstractServerList<Server> {
 
-  private static final Logger logger = LoggerFactory.getLogger(ServiceCombServerList.class);
-
-  private final CseRoutesProperties config;
-
-  private ServerListCache serverListCache;
+  private DiscoveryTree discoveryTree = new DiscoveryTree();
 
   private String serviceId;
 
-  public ServiceCombServerList(CseRoutesProperties config) {
-    this.config = config;
+  public ServiceCombServerList() {
   }
 
   @Override
   public List<Server> getInitialListOfServers() {
-    return servers();
+    DiscoveryContext context = new DiscoveryContext();
+    context.setInputParameters(serviceId);
+    VersionedCache serversVersionedCache = discoveryTree.discovery(context,
+        RegistryUtils.getAppId(),
+        serviceId,
+        DefinitionConst.VERSION_RULE_ALL);
+    Map<String, MicroserviceInstance> servers = serversVersionedCache.data();
+    List<Server> instances = new ArrayList<>(servers.size());
+    for (MicroserviceInstance s : servers.values()) {
+      for (String endpoint : s.getEndpoints()) {
+        URIEndpointObject uri = new URIEndpointObject(endpoint);
+        instances.add(new Server(uri.getHostOrIp(), uri.getPort()));
+      }
+    }
+    return instances;
   }
 
   @Override
   public List<Server> getUpdatedListOfServers() {
-    return servers();
-  }
-
-  private List<Server> servers() {
-    if (serverListCache == null) {
-      throw new ServiceCombDiscoveryException("Service list is not initialized");
-    }
-
-    logger.info("Looking for service with app id: {}, service id: {}, version rule: {}",
-        config.getAppID(),
-        serviceId,
-        config.getVersionRule(serviceId));
-
-    List<Server> endpoints = serverListCache.getLatestEndpoints();
-
-    logger.info("Found service endpoints {}", endpoints);
-    return endpoints;
+    return getInitialListOfServers();
   }
 
   @Override
   public void initWithNiwsConfig(IClientConfig iClientConfig) {
-    serviceId = iClientConfig.getClientName();
-
-    serverListCache = new CseServerListCacheWrapper(
-        config.getAppID(),
-        serviceId,
-        config.getVersionRule(serviceId),
-        "rest");
+    this.serviceId = iClientConfig.getClientName();
   }
 }
diff --git a/spring-boot-starter/spring-boot-starter-discovery/src/main/resources/META-INF/spring.factories b/spring-boot-starter/spring-boot-starter-discovery/src/main/resources/META-INF/spring.factories
index 6f7488c07..f0f56122c 100644
--- a/spring-boot-starter/spring-boot-starter-discovery/src/main/resources/META-INF/spring.factories
+++ b/spring-boot-starter/spring-boot-starter-discovery/src/main/resources/META-INF/spring.factories
@@ -17,4 +17,8 @@
 
 io.servicecomb.springboot.starter.provider.EnableServiceComb=\
   io.servicecomb.springboot.starter.discovery.CseDiscoveryClientConfiguration,\
-  io.servicecomb.springboot.starter.discovery.RibbonCseAutoConfiguration
+  io.servicecomb.springboot.starter.discovery.CseRibbonConfiguration
+org.springframework.cloud.client.discovery.EnableDiscoveryClient=\
+  io.servicecomb.springboot.starter.discovery.CseDiscoveryClientConfiguration
+org.springframework.cloud.netflix.ribbon.RibbonClient=\
+  io.servicecomb.springboot.starter.discovery.CseRibbonConfiguration
\ No newline at end of file
diff --git a/spring-boot-starter/spring-boot-starter-discovery/src/test/java/io/servicecomb/springboot/starter/discovery/ServiceCombServerListTest.java b/spring-boot-starter/spring-boot-starter-discovery/src/test/java/io/servicecomb/springboot/starter/discovery/ServiceCombServerListTest.java
deleted file mode 100644
index 47c96505b..000000000
--- a/spring-boot-starter/spring-boot-starter-discovery/src/test/java/io/servicecomb/springboot/starter/discovery/ServiceCombServerListTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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 io.servicecomb.springboot.starter.discovery;
-
-import static com.seanyinx.github.unit.scaffolding.AssertUtils.expectFailing;
-import static io.servicecomb.core.Const.DEFAULT_VERSION_RULE;
-import static org.hamcrest.core.Is.is;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.seanyinx.github.unit.scaffolding.Randomness;
-
-import io.servicecomb.core.provider.consumer.ConsumerProviderManager;
-import io.servicecomb.core.provider.consumer.ReferenceConfig;
-
-public class ServiceCombServerListTest {
-
-  private final ReferenceConfig referenceConfig = mock(ReferenceConfig.class);
-
-  private final ConsumerProviderManager manager = mock(ConsumerProviderManager.class);
-
-  private final CseRoutesProperties properties = new CseRoutesProperties(manager);
-
-  private final ServiceCombServerList serverList = new ServiceCombServerList(properties);
-
-  private String serviceId = Randomness.uniquify("serviceId");
-
-  @Before
-  public void setUp() throws Exception {
-    when(manager.getReferenceConfig(serviceId)).thenReturn(referenceConfig);
-    when(referenceConfig.getMicroserviceVersionRule()).thenReturn(DEFAULT_VERSION_RULE);
-  }
-
-  @Test
-  public void blowsUpWhenServerListNotInitialized() {
-    try {
-      serverList.getInitialListOfServers();
-      expectFailing(ServiceCombDiscoveryException.class);
-    } catch (ServiceCombDiscoveryException e) {
-      Assert.assertThat(e.getMessage(), is("Service list is not initialized"));
-    }
-  }
-}
diff --git a/spring-boot-starter/spring-boot-starter-discovery/src/test/java/io/servicecomb/springboot/starter/discovery/TestCseDiscoveryClient.java b/spring-boot-starter/spring-boot-starter-discovery/src/test/java/io/servicecomb/springboot/starter/discovery/TestCseDiscoveryClient.java
new file mode 100644
index 000000000..c932e0486
--- /dev/null
+++ b/spring-boot-starter/spring-boot-starter-discovery/src/test/java/io/servicecomb/springboot/starter/discovery/TestCseDiscoveryClient.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 io.servicecomb.springboot.starter.discovery;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.springframework.cloud.client.discovery.DiscoveryClient;
+
+import io.servicecomb.serviceregistry.RegistryUtils;
+import io.servicecomb.serviceregistry.api.registry.Microservice;
+import io.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
+import io.servicecomb.serviceregistry.client.ServiceRegistryClient;
+import io.servicecomb.serviceregistry.discovery.DiscoveryContext;
+import io.servicecomb.serviceregistry.discovery.DiscoveryTree;
+import io.servicecomb.serviceregistry.discovery.DiscoveryTreeNode;
+import mockit.Expectations;
+import mockit.Injectable;
+import mockit.Mocked;
+
+public class TestCseDiscoveryClient {
+  @Test
+  public void testCseDiscoveryClient(@Mocked RegistryUtils registryUtils,
+      @Injectable ServiceRegistryClient serviceRegistryClient,
+      @Mocked DiscoveryTree discoveryTree,
+      @Injectable DiscoveryTreeNode versionedCache) {
+    List<Microservice> microserviceList = new ArrayList<>();
+    Microservice service1 = new Microservice();
+    service1.setServiceName("service1");
+    microserviceList.add(service1);
+    Microservice server2 = new Microservice();
+    microserviceList.add(server2);
+    server2.setServiceName("server2");
+
+    Map<String, MicroserviceInstance> servers = new HashMap<>();
+    List<String> endpoints = new ArrayList<>();
+    endpoints.add("rest://localhost:3333");
+    endpoints.add("rest://localhost:4444");
+    MicroserviceInstance instance1 = new MicroserviceInstance();
+    instance1.setServiceId("service1");
+    instance1.setInstanceId("service1-instance1");
+    instance1.setEndpoints(endpoints);
+    servers.put("service1-instance1", instance1);
+
+    new Expectations() {
+      {
+        RegistryUtils.getServiceRegistryClient();
+        result = serviceRegistryClient;
+        serviceRegistryClient.getAllMicroservices();
+        result = microserviceList;
+        discoveryTree.discovery((DiscoveryContext) any, anyString, anyString, anyString);
+        result = versionedCache;
+        versionedCache.data();
+        result = servers;
+      }
+    };
+
+    DiscoveryClient client = new CseDiscoveryClient();
+    Assert.assertEquals("Spring Cloud CSE Discovery Client", client.description());
+    Assert.assertEquals(null, client.getLocalServiceInstance());
+    Assert.assertEquals(2, client.getServices().size());
+    Assert.assertEquals("server2", client.getServices().get(1));
+    Assert.assertEquals(2, client.getInstances("service1-instance1").size());
+    Assert.assertEquals(4444, client.getInstances("service1-instance1").get(1).getPort());
+  }
+}
diff --git a/spring-boot-starter/spring-boot-starter-discovery/src/test/java/io/servicecomb/springboot/starter/discovery/TestCseDiscoveryClientConfiguration.java b/spring-boot-starter/spring-boot-starter-discovery/src/test/java/io/servicecomb/springboot/starter/discovery/TestCseDiscoveryClientConfiguration.java
new file mode 100644
index 000000000..947106fab
--- /dev/null
+++ b/spring-boot-starter/spring-boot-starter-discovery/src/test/java/io/servicecomb/springboot/starter/discovery/TestCseDiscoveryClientConfiguration.java
@@ -0,0 +1,12 @@
+package io.servicecomb.springboot.starter.discovery;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestCseDiscoveryClientConfiguration {
+  @Test
+  public void testCseDiscoveryClientConfiguration() {
+    CseDiscoveryClientConfiguration discoveryClientConfiguration = new CseDiscoveryClientConfiguration();
+    Assert.assertTrue(discoveryClientConfiguration.cseDiscoveryClient() instanceof CseDiscoveryClient);
+  }
+}
diff --git a/spring-boot-starter/spring-boot-starter-discovery/src/test/java/io/servicecomb/springboot/starter/discovery/TestCseRibbonClientConfiguration.java b/spring-boot-starter/spring-boot-starter-discovery/src/test/java/io/servicecomb/springboot/starter/discovery/TestCseRibbonClientConfiguration.java
new file mode 100644
index 000000000..4b2ba69bd
--- /dev/null
+++ b/spring-boot-starter/spring-boot-starter-discovery/src/test/java/io/servicecomb/springboot/starter/discovery/TestCseRibbonClientConfiguration.java
@@ -0,0 +1,16 @@
+package io.servicecomb.springboot.starter.discovery;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.netflix.client.config.IClientConfig;
+
+import mockit.Injectable;
+
+public class TestCseRibbonClientConfiguration {
+  @Test
+  public void testCseRibbonClientConfiguration(@Injectable IClientConfig clientConfig) {
+    CseRibbonClientConfiguration config = new CseRibbonClientConfiguration();
+    Assert.assertTrue(config.ribbonServerList(clientConfig) instanceof ServiceCombServerList);
+  }
+}
diff --git a/spring-boot-starter/spring-boot-starter-discovery/src/test/java/io/servicecomb/springboot/starter/discovery/TestServiceCombServerList.java b/spring-boot-starter/spring-boot-starter-discovery/src/test/java/io/servicecomb/springboot/starter/discovery/TestServiceCombServerList.java
new file mode 100644
index 000000000..124ad232a
--- /dev/null
+++ b/spring-boot-starter/spring-boot-starter-discovery/src/test/java/io/servicecomb/springboot/starter/discovery/TestServiceCombServerList.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 io.servicecomb.springboot.starter.discovery;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.netflix.client.config.IClientConfig;
+import com.netflix.loadbalancer.Server;
+
+import io.servicecomb.serviceregistry.RegistryUtils;
+import io.servicecomb.serviceregistry.api.registry.MicroserviceInstance;
+import io.servicecomb.serviceregistry.discovery.DiscoveryContext;
+import io.servicecomb.serviceregistry.discovery.DiscoveryTree;
+import io.servicecomb.serviceregistry.discovery.DiscoveryTreeNode;
+import mockit.Expectations;
+import mockit.Injectable;
+import mockit.Mocked;
+
+public class TestServiceCombServerList {
+  @Test
+  public void testServiceCombServerList(@Injectable IClientConfig iClientConfig,
+      @Mocked RegistryUtils registryUtils,
+      @Mocked DiscoveryTree discoveryTree,
+      @Injectable DiscoveryTreeNode versionedCache) {
+    Map<String, MicroserviceInstance> servers = new HashMap<>();
+    List<String> endpoints = new ArrayList<>();
+    endpoints.add("rest://localhost:3333");
+    endpoints.add("rest://localhost:4444");
+    MicroserviceInstance instance1 = new MicroserviceInstance();
+    instance1.setServiceId("service1");
+    instance1.setInstanceId("service1-instance1");
+    instance1.setEndpoints(endpoints);
+    servers.put("service1-instance1", instance1);
+
+    new Expectations() {
+      {
+        iClientConfig.getClientName();
+        result = "serviceId1";
+
+        RegistryUtils.getAppId();
+        result = "app";
+        discoveryTree.discovery((DiscoveryContext) any, anyString, anyString, anyString);
+        result = versionedCache;
+        versionedCache.data();
+        result = servers;
+      }
+    };
+
+    ServiceCombServerList list = new ServiceCombServerList();
+    list.initWithNiwsConfig(iClientConfig);
+    List<Server> serverList = list.getInitialListOfServers();
+    Assert.assertEquals(2, serverList.size());
+    Assert.assertEquals(4444, serverList.get(1).getPort());
+    Assert.assertEquals(serverList.size(), list.getUpdatedListOfServers().size());
+  }
+}


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services