Skip to content

Commit 2267db7

Browse files
committed
wip
Signed-off-by: wind57 <[email protected]>
1 parent c069fa9 commit 2267db7

File tree

6 files changed

+228
-55
lines changed

6 files changed

+228
-55
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Copyright 2013-present 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.util.Arrays;
20+
import java.util.List;
21+
import java.util.Set;
22+
import java.util.stream.Collectors;
23+
24+
import org.springframework.cloud.client.ServiceInstance;
25+
import org.springframework.cloud.client.discovery.DiscoveryClient;
26+
import org.springframework.cloud.kubernetes.commons.discovery.DefaultKubernetesServiceInstance;
27+
import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryProperties;
28+
import org.springframework.cloud.kubernetes.commons.discovery.Service;
29+
import org.springframework.util.StringUtils;
30+
import org.springframework.web.client.RestTemplate;
31+
32+
abstract class KubernetesAbstractBlockingDiscoveryClient implements DiscoveryClient {
33+
34+
private final RestTemplate rest;
35+
36+
private final boolean emptyNamespaces;
37+
38+
private final Set<String> namespaces;
39+
40+
private final String discoveryServerUrl;
41+
42+
KubernetesAbstractBlockingDiscoveryClient(RestTemplate rest, KubernetesDiscoveryProperties kubernetesDiscoveryProperties) {
43+
if (!StringUtils.hasText(kubernetesDiscoveryProperties.discoveryServerUrl())) {
44+
throw new DiscoveryServerUrlInvalidException();
45+
}
46+
this.rest = rest;
47+
this.emptyNamespaces = kubernetesDiscoveryProperties.namespaces().isEmpty();
48+
this.namespaces = kubernetesDiscoveryProperties.namespaces();
49+
this.discoveryServerUrl = kubernetesDiscoveryProperties.discoveryServerUrl();
50+
}
51+
52+
@Override
53+
public List<String> getServices() {
54+
Service[] services = rest.getForEntity(discoveryServerUrl + "/apps", Service[].class).getBody();
55+
if (services != null && services.length > 0) {
56+
return Arrays.stream(services).filter(this::matchNamespaces).map(Service::name).toList();
57+
}
58+
return List.of();
59+
}
60+
61+
@Override
62+
public List<ServiceInstance> getInstances(String serviceId) {
63+
DefaultKubernetesServiceInstance[] responseBody = rest
64+
.getForEntity(discoveryServerUrl + "/apps/" + serviceId, DefaultKubernetesServiceInstance[].class)
65+
.getBody();
66+
if (responseBody != null && responseBody.length > 0) {
67+
return Arrays.stream(responseBody).filter(this::matchNamespaces).collect(Collectors.toList());
68+
}
69+
return List.of();
70+
}
71+
72+
@Override
73+
public abstract String description();
74+
75+
private boolean matchNamespaces(DefaultKubernetesServiceInstance kubernetesServiceInstance) {
76+
return emptyNamespaces || namespaces.contains(kubernetesServiceInstance.getNamespace());
77+
}
78+
79+
private boolean matchNamespaces(Service service) {
80+
return service.serviceInstances().isEmpty()
81+
|| service.serviceInstances().stream().anyMatch(this::matchNamespaces);
82+
}
83+
84+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright 2013-present 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+
/**
20+
* @author wind57
21+
*/
22+
abstract class KubernetesAbstractReactiveDiscoveryClient {
23+
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright 2013-present 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.util.List;
20+
21+
import org.springframework.cache.annotation.Cacheable;
22+
import org.springframework.cloud.client.ServiceInstance;
23+
import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryProperties;
24+
import org.springframework.web.client.RestTemplate;
25+
26+
/**
27+
* @author wind57
28+
*/
29+
class KubernetesCacheableDiscoveryClient extends KubernetesAbstractBlockingDiscoveryClient {
30+
31+
KubernetesCacheableDiscoveryClient(RestTemplate rest, KubernetesDiscoveryProperties kubernetesDiscoveryProperties) {
32+
super(rest, kubernetesDiscoveryProperties);
33+
}
34+
35+
@Override
36+
@Cacheable("k8s-blocking-discovery-services")
37+
public List<String> getServices() {
38+
return super.getServices();
39+
}
40+
41+
@Override
42+
@Cacheable("k8s-blocking-discovery-instances")
43+
public List<ServiceInstance> getInstances(String serviceId) {
44+
return super.getInstances(serviceId);
45+
}
46+
47+
@Override
48+
public String description() {
49+
return "Kubernetes Cacheable Discovery Client";
50+
}
51+
}

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

Lines changed: 2 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -16,74 +16,21 @@
1616

1717
package org.springframework.cloud.kubernetes.discovery;
1818

19-
import java.util.Arrays;
20-
import java.util.List;
21-
import java.util.Set;
22-
import java.util.stream.Collectors;
23-
24-
import org.springframework.cloud.client.ServiceInstance;
25-
import org.springframework.cloud.client.discovery.DiscoveryClient;
26-
import org.springframework.cloud.kubernetes.commons.discovery.DefaultKubernetesServiceInstance;
2719
import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryProperties;
28-
import org.springframework.cloud.kubernetes.commons.discovery.Service;
29-
import org.springframework.util.StringUtils;
3020
import org.springframework.web.client.RestTemplate;
3121

3222
/**
3323
* @author Ryan Baxter
3424
*/
35-
public class KubernetesDiscoveryClient implements DiscoveryClient {
36-
37-
private final RestTemplate rest;
38-
39-
private final boolean emptyNamespaces;
40-
41-
private final Set<String> namespaces;
42-
43-
private final String discoveryServerUrl;
25+
final class KubernetesDiscoveryClient extends KubernetesAbstractBlockingDiscoveryClient {
4426

4527
KubernetesDiscoveryClient(RestTemplate rest, KubernetesDiscoveryProperties kubernetesDiscoveryProperties) {
46-
if (!StringUtils.hasText(kubernetesDiscoveryProperties.discoveryServerUrl())) {
47-
throw new DiscoveryServerUrlInvalidException();
48-
}
49-
this.rest = rest;
50-
this.emptyNamespaces = kubernetesDiscoveryProperties.namespaces().isEmpty();
51-
this.namespaces = kubernetesDiscoveryProperties.namespaces();
52-
this.discoveryServerUrl = kubernetesDiscoveryProperties.discoveryServerUrl();
28+
super(rest, kubernetesDiscoveryProperties);
5329
}
5430

5531
@Override
5632
public String description() {
5733
return "Kubernetes Discovery Client";
5834
}
5935

60-
@Override
61-
public List<ServiceInstance> getInstances(String serviceId) {
62-
DefaultKubernetesServiceInstance[] responseBody = rest
63-
.getForEntity(discoveryServerUrl + "/apps/" + serviceId, DefaultKubernetesServiceInstance[].class)
64-
.getBody();
65-
if (responseBody != null && responseBody.length > 0) {
66-
return Arrays.stream(responseBody).filter(this::matchNamespaces).collect(Collectors.toList());
67-
}
68-
return List.of();
69-
}
70-
71-
@Override
72-
public List<String> getServices() {
73-
Service[] services = rest.getForEntity(discoveryServerUrl + "/apps", Service[].class).getBody();
74-
if (services != null && services.length > 0) {
75-
return Arrays.stream(services).filter(this::matchNamespaces).map(Service::name).toList();
76-
}
77-
return List.of();
78-
}
79-
80-
private boolean matchNamespaces(DefaultKubernetesServiceInstance kubernetesServiceInstance) {
81-
return emptyNamespaces || namespaces.contains(kubernetesServiceInstance.getNamespace());
82-
}
83-
84-
private boolean matchNamespaces(Service service) {
85-
return service.serviceInstances().isEmpty()
86-
|| service.serviceInstances().stream().anyMatch(this::matchNamespaces);
87-
}
88-
8936
}

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import org.springframework.cloud.kubernetes.commons.PodUtils;
2424
import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryClientHealthIndicatorInitializer;
2525
import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryProperties;
26+
import org.springframework.cloud.kubernetes.commons.discovery.conditionals.ConditionalOnDiscoveryCacheableBlockingDisabled;
27+
import org.springframework.cloud.kubernetes.commons.discovery.conditionals.ConditionalOnDiscoveryCacheableBlockingEnabled;
2628
import org.springframework.cloud.kubernetes.commons.discovery.conditionals.ConditionalOnSpringCloudKubernetesBlockingDiscovery;
2729
import org.springframework.cloud.kubernetes.commons.discovery.conditionals.ConditionalOnSpringCloudKubernetesBlockingDiscoveryHealthInitializer;
2830
import org.springframework.context.ApplicationEventPublisher;
@@ -46,11 +48,20 @@ RestTemplateBuilder restTemplateBuilder() {
4648

4749
@Bean
4850
@ConditionalOnMissingBean
51+
@ConditionalOnDiscoveryCacheableBlockingDisabled
4952
KubernetesDiscoveryClient kubernetesDiscoveryClient(RestTemplateBuilder restTemplateBuilder,
5053
KubernetesDiscoveryProperties properties) {
5154
return new KubernetesDiscoveryClient(restTemplateBuilder.build(), properties);
5255
}
5356

57+
@Bean
58+
@ConditionalOnMissingBean
59+
@ConditionalOnDiscoveryCacheableBlockingEnabled
60+
KubernetesCacheableDiscoveryClient kubernetesCacheableDiscoveryClient(RestTemplateBuilder restTemplateBuilder,
61+
KubernetesDiscoveryProperties properties) {
62+
return new KubernetesCacheableDiscoveryClient(restTemplateBuilder.build(), properties);
63+
}
64+
5465
@Bean
5566
@ConditionalOnMissingBean
5667
PodUtils<?> kubernetesDiscoveryPodUtils() {

spring-cloud-kubernetes-discovery/src/test/java/org/springframework/cloud/kubernetes/discovery/KubernetesDiscoveryAutoConfigurationTests.java

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,62 @@ void testFor1426Issue() {
266266
});
267267
}
268268

269+
/**
270+
* <pre>
271+
* - no property related to cacheable in the blocking implementation is set, as such:
272+
* - KubernetesDiscoveryClient is present
273+
* - KubernetesCacheableDiscoveryClient is not present
274+
* </pre>
275+
*/
276+
@Test
277+
void blockingCacheableDefault() {
278+
setupWithFilteredClassLoader(null,
279+
"spring.main.cloud-platform=KUBERNETES", "spring.cloud.config.enabled=false",
280+
"spring.cloud.kubernetes.discovery.discovery-server-url=http://k8sdiscoveryserver");
281+
applicationContextRunner.run(context -> {
282+
assertThat(context).hasSingleBean(KubernetesDiscoveryClient.class);
283+
assertThat(context).doesNotHaveBean(KubernetesCacheableDiscoveryClient.class);
284+
});
285+
}
286+
287+
/**
288+
* <pre>
289+
* - cacheable in the blocking implementation = false, as such:
290+
* - KubernetesDiscoveryClient is present
291+
* - KubernetesCacheableDiscoveryClient is not present
292+
* </pre>
293+
*/
294+
@Test
295+
void blockingCacheableDisabled() {
296+
setupWithFilteredClassLoader(null,
297+
"spring.main.cloud-platform=KUBERNETES", "spring.cloud.config.enabled=false",
298+
"spring.cloud.kubernetes.discovery.cacheable.blocking.enabled=false",
299+
"spring.cloud.kubernetes.discovery.discovery-server-url=http://k8sdiscoveryserver");
300+
applicationContextRunner.run(context -> {
301+
assertThat(context).hasSingleBean(KubernetesDiscoveryClient.class);
302+
assertThat(context).doesNotHaveBean(KubernetesCacheableDiscoveryClient.class);
303+
});
304+
}
305+
306+
/**
307+
* <pre>
308+
* - cacheable in the blocking implementation = true, as such:
309+
* - KubernetesDiscoveryClient is not present
310+
* - KubernetesCacheableDiscoveryClient is present
311+
* </pre>
312+
*/
313+
@Test
314+
void blockingCacheableEnabled() {
315+
setupWithFilteredClassLoader(null,
316+
"spring.main.cloud-platform=KUBERNETES", "spring.cloud.config.enabled=false",
317+
"spring.cloud.kubernetes.discovery.cacheable.blocking.enabled=true",
318+
"spring.cloud.kubernetes.discovery.discovery-server-url=http://k8sdiscoveryserver");
319+
applicationContextRunner.run(context -> {
320+
assertThat(context).doesNotHaveBean(KubernetesDiscoveryClient.class);
321+
assertThat(context).hasSingleBean(KubernetesCacheableDiscoveryClient.class);
322+
});
323+
}
324+
269325
private ApplicationContextRunner applicationContextRunner;
270326

271327
private void setupWithFilteredClassLoader(Class<?> cls, String... properties) {

0 commit comments

Comments
 (0)