diff --git a/pom.xml b/pom.xml index 3f1b7e71..e16f5324 100644 --- a/pom.xml +++ b/pom.xml @@ -132,6 +132,11 @@ spring-cloud-netflix-core ${spring-cloud-netflix.version} + + org.springframework.cloud + spring-cloud-starter-feign + ${spring-cloud-netflix.version} + org.apache.curator curator-framework @@ -227,6 +232,12 @@ 2.4.4 test + + com.netflix.feign + feign-core + 8.7.1 + test + diff --git a/spring-cloud-zookeeper-discovery/pom.xml b/spring-cloud-zookeeper-discovery/pom.xml index 45ae2430..d9130517 100644 --- a/spring-cloud-zookeeper-discovery/pom.xml +++ b/spring-cloud-zookeeper-discovery/pom.xml @@ -145,6 +145,16 @@ test 1.53 + + com.netflix.feign + feign-core + test + + + org.springframework.cloud + spring-cloud-starter-feign + test + diff --git a/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/ZookeeperServerList.java b/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/ZookeeperServerList.java index 835d7b07..6ecf9d23 100644 --- a/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/ZookeeperServerList.java +++ b/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/ZookeeperServerList.java @@ -21,6 +21,7 @@ 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 java.util.ArrayList; import java.util.Collection; @@ -48,7 +49,12 @@ public class ZookeeperServerList extends AbstractServerList { } public void initFromDependencies(IClientConfig clientConfig, ZookeeperDependencies zookeeperDependencies) { - this.serviceId = zookeeperDependencies.getPathForAlias(clientConfig.getClientName()); + this.serviceId = getServiceIdFromDepsOrClientName(clientConfig, zookeeperDependencies); + } + + private String getServiceIdFromDepsOrClientName(IClientConfig clientConfig, ZookeeperDependencies zookeeperDependencies) { + String serviceIdFromDeps = zookeeperDependencies.getPathForAlias(clientConfig.getClientName()); + return StringUtils.hasText(serviceIdFromDeps) ? serviceIdFromDeps : clientConfig.getClientName(); } @Override diff --git a/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/dependency/ZookeeperDependencies.java b/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/dependency/ZookeeperDependencies.java index f52c69f8..f938f52e 100644 --- a/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/dependency/ZookeeperDependencies.java +++ b/spring-cloud-zookeeper-discovery/src/main/java/org/springframework/cloud/zookeeper/discovery/dependency/ZookeeperDependencies.java @@ -52,8 +52,6 @@ public class ZookeeperDependencies { @NoArgsConstructor public static class ZookeeperDependency { - private String id; - private String path; private LoadBalancerType loadBalancerType = LoadBalancerType.ROUND_ROBIN; diff --git a/spring-cloud-zookeeper-discovery/src/test/groovy/org/springframework/cloud/zookeeper/discovery/ZookeeperDiscoveryISpec.groovy b/spring-cloud-zookeeper-discovery/src/test/groovy/org/springframework/cloud/zookeeper/discovery/ZookeeperDiscoveryISpec.groovy index 66142596..6638e999 100644 --- a/spring-cloud-zookeeper-discovery/src/test/groovy/org/springframework/cloud/zookeeper/discovery/ZookeeperDiscoveryISpec.groovy +++ b/spring-cloud-zookeeper-discovery/src/test/groovy/org/springframework/cloud/zookeeper/discovery/ZookeeperDiscoveryISpec.groovy @@ -25,26 +25,34 @@ import org.springframework.cloud.client.ServiceInstance import org.springframework.cloud.client.discovery.DiscoveryClient import org.springframework.cloud.client.discovery.EnableDiscoveryClient import org.springframework.cloud.client.loadbalancer.LoadBalanced +import org.springframework.cloud.netflix.feign.EnableFeignClients +import org.springframework.cloud.netflix.feign.FeignClient import org.springframework.cloud.zookeeper.common.CommonTestConfig import org.springframework.cloud.zookeeper.common.TestRibbonClient import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.context.annotation.Import import org.springframework.context.annotation.Profile +import org.springframework.stereotype.Controller import org.springframework.test.context.ActiveProfiles import org.springframework.test.context.ContextConfiguration +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RequestMethod import org.springframework.web.client.RestTemplate import spock.lang.Specification +import spock.util.concurrent.PollingConditions @ContextConfiguration(classes = Config, loader = SpringApplicationContextLoader) @ActiveProfiles('ribbon') @WebIntegrationTest(randomPort = true) -class ZookeeperDiscoveryISpec extends Specification { +class ZookeeperDiscoveryISpec extends Specification implements PollingUtils { @Autowired TestRibbonClient testRibbonClient @Autowired DiscoveryClient discoveryClient @Autowired ZookeeperServiceDiscovery serviceDiscovery @Value('${spring.application.name}') String springAppName + @Autowired IdUsingFeignClient idUsingFeignClient + PollingConditions conditions = new PollingConditions() def 'should find the app by its name via Ribbon'() { @@ -60,6 +68,13 @@ class ZookeeperDiscoveryISpec extends Specification { 'UP' == registeredServiceStatus(instance) } + def 'should find an instance using feign via service id'() { + expect: + conditions.eventually willPass { + assert idUsingFeignClient.beans + } + } + private String registeredServiceStatusViaServiceName() { return new JsonSlurper().parseText(testRibbonClient.thisHealthCheck()).status } @@ -73,10 +88,17 @@ class ZookeeperDiscoveryISpec extends Specification { serviceDiscovery.serviceInstance.address == discoveryClient.localServiceInstance.host } + @FeignClient("ribbonApp") + public static interface IdUsingFeignClient { + @RequestMapping(method = RequestMethod.GET, value = "/beans") + String getBeans(); + } + @Configuration @EnableAutoConfiguration @Import(CommonTestConfig) @EnableDiscoveryClient + @EnableFeignClients @Profile('ribbon') static class Config { @@ -86,4 +108,13 @@ class ZookeeperDiscoveryISpec extends Specification { return new TestRibbonClient(restTemplate, springAppName) } } + + @Controller + @Profile('ribbon') + class PingController { + + @RequestMapping('/ping') String ping() { + return 'pong' + } + } } diff --git a/spring-cloud-zookeeper-discovery/src/test/groovy/org/springframework/cloud/zookeeper/discovery/dependency/ZookeeperDependenciesSpec.groovy b/spring-cloud-zookeeper-discovery/src/test/groovy/org/springframework/cloud/zookeeper/discovery/dependency/ZookeeperDependenciesSpec.groovy index f0a90f68..a4e5e9c4 100644 --- a/spring-cloud-zookeeper-discovery/src/test/groovy/org/springframework/cloud/zookeeper/discovery/dependency/ZookeeperDependenciesSpec.groovy +++ b/spring-cloud-zookeeper-discovery/src/test/groovy/org/springframework/cloud/zookeeper/discovery/dependency/ZookeeperDependenciesSpec.groovy @@ -22,7 +22,6 @@ import spock.lang.Unroll class ZookeeperDependenciesSpec extends Specification { private static final ZookeeperDependencies.ZookeeperDependency EXPECTED_DEPENDENCY = new ZookeeperDependencies.ZookeeperDependency( - 'id', 'path', LoadBalancerType.RANDOM, 'contentTypeTemplate', diff --git a/spring-cloud-zookeeper-discovery/src/test/groovy/org/springframework/cloud/zookeeper/discovery/dependency/ZookeeperDiscoveryWithDependenciesISpec.groovy b/spring-cloud-zookeeper-discovery/src/test/groovy/org/springframework/cloud/zookeeper/discovery/dependency/ZookeeperDiscoveryWithDependenciesISpec.groovy index 3bdfab9e..867ee181 100644 --- a/spring-cloud-zookeeper-discovery/src/test/groovy/org/springframework/cloud/zookeeper/discovery/dependency/ZookeeperDiscoveryWithDependenciesISpec.groovy +++ b/spring-cloud-zookeeper-discovery/src/test/groovy/org/springframework/cloud/zookeeper/discovery/dependency/ZookeeperDiscoveryWithDependenciesISpec.groovy @@ -14,7 +14,6 @@ * limitations under the License. */ package org.springframework.cloud.zookeeper.discovery.dependency - import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.autoconfigure.EnableAutoConfiguration import org.springframework.boot.test.SpringApplicationContextLoader @@ -23,6 +22,8 @@ import org.springframework.cloud.client.ServiceInstance import org.springframework.cloud.client.discovery.DiscoveryClient import org.springframework.cloud.client.discovery.EnableDiscoveryClient import org.springframework.cloud.client.loadbalancer.LoadBalanced +import org.springframework.cloud.netflix.feign.EnableFeignClients +import org.springframework.cloud.netflix.feign.FeignClient import org.springframework.cloud.zookeeper.common.CommonTestConfig import org.springframework.cloud.zookeeper.common.TestRibbonClient import org.springframework.cloud.zookeeper.discovery.PollingUtils @@ -34,6 +35,7 @@ import org.springframework.stereotype.Controller import org.springframework.test.context.ActiveProfiles import org.springframework.test.context.ContextConfiguration import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RequestMethod import org.springframework.web.client.RestTemplate import spock.lang.Specification import spock.util.concurrent.PollingConditions @@ -45,11 +47,9 @@ class ZookeeperDiscoveryWithDependenciesISpec extends Specification implements P @Autowired TestRibbonClient testRibbonClient @Autowired DiscoveryClient discoveryClient - PollingConditions conditions - - def setup() { - conditions = new PollingConditions() - } + @Autowired AliasUsingFeignClient aliasUsingFeignClient + @Autowired IdUsingFeignClient idUsingFeignClient + PollingConditions conditions = new PollingConditions() def 'should find an instance via path when alias is not found'() { expect: @@ -58,6 +58,13 @@ class ZookeeperDiscoveryWithDependenciesISpec extends Specification implements P } } + def 'should find an instance using feign via serviceID when alias is not found'() { + expect: + conditions.eventually willPass { + assert idUsingFeignClient.beans + } + } + def 'should find a collaborator via Ribbon by using its alias from dependencies'() { expect: conditions.eventually willPass { @@ -65,6 +72,13 @@ class ZookeeperDiscoveryWithDependenciesISpec extends Specification implements P } } + def 'should find a collaborator using feign by using its alias from dependencies'() { + expect: + conditions.eventually willPass { + assert aliasUsingFeignClient.beans + } + } + def 'should find a collaborator via discovery client'() { given: List instances = discoveryClient.getInstances('someAlias') @@ -87,6 +101,7 @@ class ZookeeperDiscoveryWithDependenciesISpec extends Specification implements P @EnableAutoConfiguration @Import(CommonTestConfig) @EnableDiscoveryClient + @EnableFeignClients @Profile('dependencies') static class Config { @@ -97,6 +112,18 @@ class ZookeeperDiscoveryWithDependenciesISpec extends Specification implements P } + @FeignClient("someAlias") + public static interface AliasUsingFeignClient { + @RequestMapping(method = RequestMethod.GET, value = "/beans") + String getBeans(); + } + + @FeignClient("nameWithoutAlias") + public static interface IdUsingFeignClient { + @RequestMapping(method = RequestMethod.GET, value = "/beans") + String getBeans(); + } + @Controller @Profile('dependencies') class PingController { @@ -105,4 +132,5 @@ class ZookeeperDiscoveryWithDependenciesISpec extends Specification implements P return 'pong' } } + } \ No newline at end of file