Skip to content

Commit 8c58a0b

Browse files
Merge pull request spring-projects#412 from OlgaMaciaszek/spring-projectsgh-304-add-discovery-clients-order-support
Gh 304 add discovery clients order support
2 parents 1d64629 + e115562 commit 8c58a0b

File tree

8 files changed

+291
-48
lines changed

8 files changed

+291
-48
lines changed

docs/src/main/asciidoc/spring-cloud-commons.adoc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,17 @@ To disable it, set `spring.cloud.discovery.client.health-indicator.enabled=false
254254
To disable the description field of the `DiscoveryClientHealthIndicator`, set `spring.cloud.discovery.client.health-indicator.include-description=false`.
255255
Otherwise, it can bubble up as the `description` of the rolled up `HealthIndicator`.
256256

257+
==== Ordering `DiscoveryClient` instances
258+
`DiscoveryClient` interface extends `Ordered`. This is useful when using multiple discovery
259+
clients, as it allows you to define the order of the returned discovery clients, similar to
260+
how you can order the beans loaded by a Spring application. By default, the order of any `DiscoveryClient` is set to
261+
`0`. If you want to set a different order for your custom `DiscoveryClient` implementations, you just need to override
262+
the `getOrder()` method so that it returns the value that is suitable for your setup. Apart from this, you can use
263+
properties to set the order of the `DiscoveryClient`
264+
implementations provided by Spring Cloud, among others `ConsulDiscoveryClient`, `EurekaDiscoveryClient` and
265+
`ZookeeperDiscoveryClient`. In order to do it, you just need to set the
266+
`spring.cloud.{clientIdentifier}.discovery.order` (or `eureka.client.order` for Eureka) property to the desired value.
267+
257268
=== ServiceRegistry
258269

259270
Commons now provides a `ServiceRegistry` interface that provides methods such as `register(Registration)` and `deregister(Registration)`, which let you provide custom registered services.

spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/DiscoveryClient.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2013-2015 the original author or authors.
2+
* Copyright 2013-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,22 +19,29 @@
1919
import java.util.List;
2020

2121
import org.springframework.cloud.client.ServiceInstance;
22+
import org.springframework.core.Ordered;
2223

2324
/**
2425
* Represents read operations commonly available to discovery services such as Netflix
2526
* Eureka or consul.io.
27+
*
2628
* @author Spencer Gibb
29+
* @author Olga Maciaszek-Sharma
2730
*/
28-
public interface DiscoveryClient {
31+
public interface DiscoveryClient extends Ordered {
32+
33+
int DEFAULT_ORDER = 0;
2934

3035
/**
3136
* A human-readable description of the implementation, used in HealthIndicator.
37+
*
3238
* @return The description.
3339
*/
3440
String description();
3541

3642
/**
3743
* Gets all ServiceInstances associated with a particular serviceId.
44+
*
3845
* @param serviceId The serviceId to query.
3946
* @return A List of ServiceInstance.
4047
*/
@@ -45,4 +52,13 @@ public interface DiscoveryClient {
4552
*/
4653
List<String> getServices();
4754

55+
/**
56+
* Default implementation for getting order of discovery clients.
57+
*
58+
* @return order
59+
*/
60+
@Override
61+
default int getOrder() {
62+
return DEFAULT_ORDER;
63+
}
4864
}

spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/composite/CompositeDiscoveryClient.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/*
2+
* Copyright 2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
117
package org.springframework.cloud.client.discovery.composite;
218

319
import java.util.ArrayList;
@@ -7,18 +23,21 @@
723

824
import org.springframework.cloud.client.ServiceInstance;
925
import org.springframework.cloud.client.discovery.DiscoveryClient;
26+
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
1027

1128
/**
1229
* A {@link DiscoveryClient} that is composed of other discovery clients and delegates
1330
* calls to each of them in order.
1431
*
1532
* @author Biju Kunjummen
33+
* @author Olga Maciaszek-Sharma
1634
*/
1735
public class CompositeDiscoveryClient implements DiscoveryClient {
1836

1937
private final List<DiscoveryClient> discoveryClients;
2038

2139
public CompositeDiscoveryClient(List<DiscoveryClient> discoveryClients) {
40+
AnnotationAwareOrderComparator.sort(discoveryClients);
2241
this.discoveryClients = discoveryClients;
2342
}
2443

spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryClient.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/*
2+
* Copyright 2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
117
package org.springframework.cloud.client.discovery.simple;
218

319
import java.util.ArrayList;
@@ -12,6 +28,7 @@
1228
* properties file as a source of service instances.
1329
*
1430
* @author Biju Kunjummen
31+
* @author Olga Maciaszek-Sharma
1532
*/
1633
public class SimpleDiscoveryClient implements DiscoveryClient {
1734

@@ -42,4 +59,9 @@ public List<ServiceInstance> getInstances(String serviceId) {
4259
public List<String> getServices() {
4360
return new ArrayList<>(this.simpleDiscoveryProperties.getInstances().keySet());
4461
}
62+
63+
@Override
64+
public int getOrder() {
65+
return this.simpleDiscoveryProperties.getOrder();
66+
}
4567
}

spring-cloud-commons/src/main/java/org/springframework/cloud/client/discovery/simple/SimpleDiscoveryProperties.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/*
2+
* Copyright 2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
117
package org.springframework.cloud.client.discovery.simple;
218

319
import java.net.URI;
@@ -10,13 +26,18 @@
1026

1127
import org.springframework.boot.context.properties.ConfigurationProperties;
1228
import org.springframework.cloud.client.ServiceInstance;
29+
import org.springframework.cloud.client.discovery.DiscoveryClient;
1330

1431
/**
1532
* Properties to hold the details of a
1633
* {@link org.springframework.cloud.client.discovery.DiscoveryClient} service instances
1734
* for a given service.
35+
* It also holds the user-configurable order that will be used to establish the
36+
* precedence of this client in the list of clients
37+
* used by {@link org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClient}.
1838
*
1939
* @author Biju Kunjummen
40+
* @author Olga Maciaszek-Sharma
2041
*/
2142

2243
@ConfigurationProperties(prefix = "spring.cloud.discovery.client.simple")
@@ -30,6 +51,8 @@ public class SimpleDiscoveryProperties {
3051
*/
3152
private SimpleServiceInstance local = new SimpleServiceInstance();
3253

54+
private int order = DiscoveryClient.DEFAULT_ORDER;
55+
3356
public Map<String, List<SimpleServiceInstance>> getInstances() {
3457
return this.instances;
3558
}
@@ -42,6 +65,14 @@ public SimpleServiceInstance getLocal() {
4265
return this.local;
4366
}
4467

68+
public int getOrder() {
69+
return this.order;
70+
}
71+
72+
public void setOrder(int order) {
73+
this.order = order;
74+
}
75+
4576
@PostConstruct
4677
public void init() {
4778
for (String key : this.instances.keySet()) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Copyright 2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cloud.client.discovery.composite;
18+
19+
import java.util.List;
20+
21+
import org.junit.Test;
22+
import org.junit.runner.RunWith;
23+
24+
import org.springframework.beans.factory.annotation.Autowired;
25+
import org.springframework.boot.test.context.SpringBootTest;
26+
import org.springframework.cloud.client.ServiceInstance;
27+
import org.springframework.cloud.client.discovery.DiscoveryClient;
28+
import org.springframework.test.context.junit4.SpringRunner;
29+
30+
import static org.assertj.core.api.Assertions.assertThat;
31+
import static org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientTestsConfig.CUSTOM_DISCOVERY_CLIENT;
32+
import static org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientTestsConfig.CUSTOM_SERVICE_ID;
33+
import static org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientTestsConfig.DEFAULT_ORDER_DISCOVERY_CLIENT;
34+
import static org.springframework.cloud.client.discovery.composite.CompositeDiscoveryClientTestsConfig.FOURTH_DISCOVERY_CLIENT;
35+
36+
/**
37+
* Tests for the support of ordered {@link DiscoveryClient} instances in {@link CompositeDiscoveryClient}
38+
*
39+
* @author Olga Maciaszek-Sharma
40+
*/
41+
@RunWith(SpringRunner.class)
42+
@SpringBootTest(properties = "spring.cloud.discovery.client.simple.order:2", classes = {
43+
CompositeDiscoveryClientTestsConfig.class})
44+
public class CompositeDiscoveryClientOrderTest {
45+
46+
@Autowired
47+
DiscoveryClient discoveryClient;
48+
49+
@Test
50+
public void shouldGetOrderedDiscoveryClients() {
51+
// when:
52+
List<DiscoveryClient> discoveryClients = ((CompositeDiscoveryClient) this.discoveryClient)
53+
.getDiscoveryClients();
54+
55+
// then:
56+
assertThat(discoveryClients.get(0).description())
57+
.isEqualTo(CUSTOM_DISCOVERY_CLIENT);
58+
assertThat(discoveryClients.get(1).description())
59+
.isEqualTo(DEFAULT_ORDER_DISCOVERY_CLIENT);
60+
assertThat(discoveryClients.get(2).description())
61+
.isEqualTo("Simple Discovery Client");
62+
assertThat(discoveryClients.get(3).description())
63+
.isEqualTo(FOURTH_DISCOVERY_CLIENT);
64+
}
65+
66+
@Test
67+
public void shouldOnlyReturnServiceInstancesForTheHighestPrecedenceDiscoveryClient() {
68+
// when:
69+
List<ServiceInstance> serviceInstances = this.discoveryClient
70+
.getInstances(CUSTOM_SERVICE_ID);
71+
72+
// then:
73+
assertThat(serviceInstances).hasSize(1);
74+
assertThat(serviceInstances.get(0).getPort()).isEqualTo(123);
75+
}
76+
}

0 commit comments

Comments
 (0)