Skip to content

Commit 3181d0b

Browse files
authored
Added support for reactive service discovery
1 parent 2072314 commit 3181d0b

File tree

12 files changed

+824
-18
lines changed

12 files changed

+824
-18
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright 2019-2019 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+
* https://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.kubernetes;
18+
19+
import java.lang.annotation.Documented;
20+
import java.lang.annotation.ElementType;
21+
import java.lang.annotation.Inherited;
22+
import java.lang.annotation.Retention;
23+
import java.lang.annotation.RetentionPolicy;
24+
import java.lang.annotation.Target;
25+
26+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
27+
28+
/**
29+
* Provides a more succinct conditional <code>spring.cloud.kubernetes.enabled</code>.
30+
*
31+
* @author Tim Ysewyn
32+
* @since 2.2.0
33+
*/
34+
@Target(ElementType.TYPE)
35+
@Retention(RetentionPolicy.RUNTIME)
36+
@Documented
37+
@Inherited
38+
@ConditionalOnProperty(value = "spring.cloud.kubernetes.enabled", matchIfMissing = true)
39+
public @interface ConditionalOnKubernetesEnabled {
40+
41+
}

spring-cloud-kubernetes-core/src/main/java/org/springframework/cloud/kubernetes/KubernetesAutoConfiguration.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import org.springframework.boot.actuate.health.HealthIndicator;
3030
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
3131
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
32-
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
3332
import org.springframework.boot.context.properties.EnableConfigurationProperties;
3433
import org.springframework.context.annotation.Bean;
3534
import org.springframework.context.annotation.Configuration;
@@ -39,9 +38,10 @@
3938
*
4039
* @author Ioannis Canellos
4140
* @author Eddú Meléndez
41+
* @author Tim Ysewyn
4242
*/
4343
@Configuration
44-
@ConditionalOnProperty(value = "spring.cloud.kubernetes.enabled", matchIfMissing = true)
44+
@ConditionalOnKubernetesEnabled
4545
@EnableConfigurationProperties(KubernetesClientProperties.class)
4646
public class KubernetesAutoConfiguration {
4747

spring-cloud-kubernetes-discovery/pom.xml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,21 @@
4242
<artifactId>spring-boot-autoconfigure</artifactId>
4343
<optional>true</optional>
4444
</dependency>
45+
<dependency>
46+
<groupId>org.springframework.boot</groupId>
47+
<artifactId>spring-boot-actuator</artifactId>
48+
<optional>true</optional>
49+
</dependency>
50+
<dependency>
51+
<groupId>org.springframework.boot</groupId>
52+
<artifactId>spring-boot-starter-webflux</artifactId>
53+
<optional>true</optional>
54+
</dependency>
55+
<dependency>
56+
<groupId>org.springframework.boot</groupId>
57+
<artifactId>spring-boot-starter-webflux</artifactId>
58+
<optional>true</optional>
59+
</dependency>
4560
<dependency>
4661
<groupId>org.springframework.cloud</groupId>
4762
<artifactId>spring-cloud-commons</artifactId>
@@ -125,6 +140,11 @@
125140
<version>${spring-cloud-config.version}</version>
126141
<scope>test</scope>
127142
</dependency>
143+
<dependency>
144+
<groupId>io.projectreactor</groupId>
145+
<artifactId>reactor-test</artifactId>
146+
<scope>test</scope>
147+
</dependency>
128148
</dependencies>
129149

130150
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2019-2019 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+
* https://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.kubernetes.discovery;
18+
19+
import java.lang.annotation.Documented;
20+
import java.lang.annotation.ElementType;
21+
import java.lang.annotation.Inherited;
22+
import java.lang.annotation.Retention;
23+
import java.lang.annotation.RetentionPolicy;
24+
import java.lang.annotation.Target;
25+
26+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
27+
28+
/**
29+
* Provides a more succinct conditional
30+
* <code>spring.cloud.kubernetes.discovery.enabled</code>.
31+
*
32+
* @author Tim Ysewyn
33+
* @since 2.2.0
34+
*/
35+
@Target(ElementType.TYPE)
36+
@Retention(RetentionPolicy.RUNTIME)
37+
@Documented
38+
@Inherited
39+
@ConditionalOnProperty(value = "spring.cloud.kubernetes.discovery.enabled",
40+
matchIfMissing = true)
41+
public @interface ConditionalOnKubernetesDiscoveryEnabled {
42+
43+
}

spring-cloud-kubernetes-discovery/src/main/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryClientAutoConfiguration.java

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@
1818

1919
import io.fabric8.kubernetes.client.KubernetesClient;
2020

21+
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
2122
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
2223
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
23-
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
2424
import org.springframework.cloud.client.CommonsClientAutoConfiguration;
25+
import org.springframework.cloud.client.ConditionalOnBlockingDiscoveryEnabled;
2526
import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled;
2627
import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration;
28+
import org.springframework.cloud.kubernetes.ConditionalOnKubernetesEnabled;
29+
import org.springframework.cloud.kubernetes.KubernetesAutoConfiguration;
2730
import org.springframework.cloud.kubernetes.registry.KubernetesRegistration;
2831
import org.springframework.cloud.kubernetes.registry.KubernetesServiceRegistry;
2932
import org.springframework.context.annotation.Bean;
@@ -37,9 +40,10 @@
3740
*/
3841
@Configuration
3942
@ConditionalOnDiscoveryEnabled
40-
@ConditionalOnProperty(name = "spring.cloud.kubernetes.enabled", matchIfMissing = true)
43+
@ConditionalOnKubernetesEnabled
4144
@AutoConfigureBefore({ SimpleDiscoveryClientAutoConfiguration.class,
4245
CommonsClientAutoConfiguration.class })
46+
@AutoConfigureAfter({ KubernetesAutoConfiguration.class })
4347
public class KubernetesDiscoveryClientAutoConfiguration {
4448

4549
@Bean
@@ -72,18 +76,6 @@ public KubernetesClientServicesFunction servicesFunction(
7276
}
7377
}
7478

75-
@Bean
76-
@ConditionalOnMissingBean
77-
@ConditionalOnProperty(name = "spring.cloud.kubernetes.discovery.enabled",
78-
matchIfMissing = true)
79-
public KubernetesDiscoveryClient kubernetesDiscoveryClient(KubernetesClient client,
80-
KubernetesDiscoveryProperties properties,
81-
KubernetesClientServicesFunction kubernetesClientServicesFunction,
82-
DefaultIsServicePortSecureResolver isServicePortSecureResolver) {
83-
return new KubernetesDiscoveryClient(client, properties,
84-
kubernetesClientServicesFunction, isServicePortSecureResolver);
85-
}
86-
8779
@Bean
8880
public KubernetesServiceRegistry getServiceRegistry() {
8981
return new KubernetesServiceRegistry();
@@ -100,4 +92,21 @@ public KubernetesDiscoveryProperties getKubernetesDiscoveryProperties() {
10092
return new KubernetesDiscoveryProperties();
10193
}
10294

95+
@Configuration
96+
@ConditionalOnBlockingDiscoveryEnabled
97+
@ConditionalOnKubernetesDiscoveryEnabled
98+
public static class KubernetesDiscoveryClientConfiguration {
99+
100+
@Bean
101+
@ConditionalOnMissingBean
102+
public KubernetesDiscoveryClient kubernetesDiscoveryClient(
103+
KubernetesClient client, KubernetesDiscoveryProperties properties,
104+
KubernetesClientServicesFunction kubernetesClientServicesFunction,
105+
DefaultIsServicePortSecureResolver isServicePortSecureResolver) {
106+
return new KubernetesDiscoveryClient(client, properties,
107+
kubernetesClientServicesFunction, isServicePortSecureResolver);
108+
}
109+
110+
}
111+
103112
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright 2019-2019 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+
* https://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.kubernetes.discovery.reactive;
18+
19+
import io.fabric8.kubernetes.client.KubernetesClient;
20+
import reactor.core.publisher.Flux;
21+
import reactor.core.scheduler.Schedulers;
22+
23+
import org.springframework.cloud.client.ServiceInstance;
24+
import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient;
25+
import org.springframework.cloud.kubernetes.discovery.KubernetesClientServicesFunction;
26+
import org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryClient;
27+
import org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryProperties;
28+
import org.springframework.util.Assert;
29+
30+
/**
31+
* Kubernetes implementation of {@link ReactiveDiscoveryClient}. Currently relies on the
32+
* {@link KubernetesDiscoveryClient} for feature parity.
33+
*
34+
* @author Tim Ysewyn
35+
*/
36+
public class KubernetesReactiveDiscoveryClient implements ReactiveDiscoveryClient {
37+
38+
private final KubernetesDiscoveryClient kubernetesDiscoveryClient;
39+
40+
public KubernetesReactiveDiscoveryClient(KubernetesClient client,
41+
KubernetesDiscoveryProperties properties,
42+
KubernetesClientServicesFunction kubernetesClientServicesFunction) {
43+
this.kubernetesDiscoveryClient = new KubernetesDiscoveryClient(client, properties,
44+
kubernetesClientServicesFunction);
45+
}
46+
47+
@Override
48+
public String description() {
49+
return "Kubernetes Reactive Discovery Client";
50+
}
51+
52+
@Override
53+
public Flux<ServiceInstance> getInstances(String serviceId) {
54+
Assert.notNull(serviceId,
55+
"[Assertion failed] - the object argument must not be null");
56+
return Flux
57+
.defer(() -> Flux
58+
.fromIterable(kubernetesDiscoveryClient.getInstances(serviceId)))
59+
.subscribeOn(Schedulers.boundedElastic());
60+
}
61+
62+
@Override
63+
public Flux<String> getServices() {
64+
return Flux
65+
.defer(() -> Flux.fromIterable(kubernetesDiscoveryClient.getServices()))
66+
.subscribeOn(Schedulers.boundedElastic());
67+
}
68+
69+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Copyright 2013-2019 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+
* https://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.kubernetes.discovery.reactive;
18+
19+
import io.fabric8.kubernetes.client.KubernetesClient;
20+
21+
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
22+
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
23+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
24+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
25+
import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled;
26+
import org.springframework.cloud.client.ConditionalOnDiscoveryHealthIndicatorEnabled;
27+
import org.springframework.cloud.client.ConditionalOnReactiveDiscoveryEnabled;
28+
import org.springframework.cloud.client.ReactiveCommonsClientAutoConfiguration;
29+
import org.springframework.cloud.client.discovery.composite.reactive.ReactiveCompositeDiscoveryClientAutoConfiguration;
30+
import org.springframework.cloud.client.discovery.health.DiscoveryClientHealthIndicatorProperties;
31+
import org.springframework.cloud.client.discovery.health.reactive.ReactiveDiscoveryClientHealthIndicator;
32+
import org.springframework.cloud.client.discovery.simple.reactive.SimpleReactiveDiscoveryClientAutoConfiguration;
33+
import org.springframework.cloud.kubernetes.ConditionalOnKubernetesEnabled;
34+
import org.springframework.cloud.kubernetes.discovery.ConditionalOnKubernetesDiscoveryEnabled;
35+
import org.springframework.cloud.kubernetes.discovery.KubernetesClientServicesFunction;
36+
import org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryClientAutoConfiguration;
37+
import org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryProperties;
38+
import org.springframework.context.annotation.Bean;
39+
import org.springframework.context.annotation.Configuration;
40+
41+
/**
42+
* Auto configuration for reactive discovery client.
43+
*
44+
* @author Tim Ysewyn
45+
*/
46+
@Configuration
47+
@ConditionalOnDiscoveryEnabled
48+
@ConditionalOnReactiveDiscoveryEnabled
49+
@ConditionalOnKubernetesEnabled
50+
@ConditionalOnKubernetesDiscoveryEnabled
51+
@AutoConfigureBefore({ SimpleReactiveDiscoveryClientAutoConfiguration.class,
52+
ReactiveCommonsClientAutoConfiguration.class })
53+
@AutoConfigureAfter({ ReactiveCompositeDiscoveryClientAutoConfiguration.class,
54+
KubernetesDiscoveryClientAutoConfiguration.class })
55+
public class KubernetesReactiveDiscoveryClientAutoConfiguration {
56+
57+
@Bean
58+
@ConditionalOnMissingBean
59+
public KubernetesReactiveDiscoveryClient kubernetesReactiveDiscoveryClient(
60+
KubernetesClient client, KubernetesDiscoveryProperties properties,
61+
KubernetesClientServicesFunction kubernetesClientServicesFunction) {
62+
return new KubernetesReactiveDiscoveryClient(client, properties,
63+
kubernetesClientServicesFunction);
64+
}
65+
66+
@Bean
67+
@ConditionalOnClass(
68+
name = "org.springframework.boot.actuate.health.ReactiveHealthIndicator")
69+
@ConditionalOnDiscoveryHealthIndicatorEnabled
70+
public ReactiveDiscoveryClientHealthIndicator kubernetesReactiveDiscoveryClientHealthIndicator(
71+
KubernetesReactiveDiscoveryClient client,
72+
DiscoveryClientHealthIndicatorProperties properties) {
73+
return new ReactiveDiscoveryClientHealthIndicator(client, properties);
74+
}
75+
76+
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
22
org.springframework.cloud.kubernetes.discovery.KubernetesCatalogWatchAutoConfiguration, \
3-
org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryClientAutoConfiguration
3+
org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryClientAutoConfiguration, \
4+
org.springframework.cloud.kubernetes.discovery.reactive.KubernetesReactiveDiscoveryClientAutoConfiguration
45
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
56
org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryClientConfigClientBootstrapConfiguration

0 commit comments

Comments
 (0)