Skip to content

Commit 7cd5146

Browse files
committed
fix
Signed-off-by: wind57 <[email protected]>
1 parent b5e1513 commit 7cd5146

File tree

12 files changed

+147
-129
lines changed

12 files changed

+147
-129
lines changed

spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/catalog/KubernetesEndpointSlicesCatalogWatch.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.Collections;
2121
import java.util.List;
2222
import java.util.Map;
23+
import java.util.Objects;
2324
import java.util.function.Function;
2425
import java.util.stream.Stream;
2526

@@ -73,13 +74,18 @@ else if (!context.properties().namespaces().isEmpty()) {
7374
endpointSlices = namespacedEndpointSlices(api, namespace, context.properties().serviceLabels());
7475
}
7576

77+
return generateState(endpointSlices);
78+
79+
}
80+
81+
List<EndpointNameAndNamespace> generateState(List<V1EndpointSlice> endpointSlices) {
7682
Stream<V1ObjectReference> references = endpointSlices.stream()
7783
.map(V1EndpointSlice::getEndpoints)
84+
.filter(Objects::nonNull)
7885
.flatMap(List::stream)
7986
.map(V1Endpoint::getTargetRef);
8087

8188
return KubernetesCatalogWatchContext.state(references);
82-
8389
}
8490

8591
private List<V1EndpointSlice> endpointSlices(DiscoveryV1Api api, Map<String, String> labels) {

spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/catalog/KubernetesEndpointsCatalogWatch.java

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -72,16 +72,21 @@ else if (!context.properties().namespaces().isEmpty()) {
7272
endpoints = namespacedEndpoints(coreV1Api, namespace, context.properties().serviceLabels());
7373
}
7474

75-
/**
76-
* <pre>
77-
* - An "V1Endpoints" holds a List of V1EndpointSubset.
78-
* - A single V1EndpointSubset holds a List of V1EndpointAddress
79-
*
80-
* - (The union of all V1EndpointSubsets is the Set of all V1Endpoints)
81-
* - Set of V1Endpoints is the cartesian product of :
82-
* V1EndpointSubset::getAddresses and V1EndpointSubset::getPorts (each is a List)
83-
* </pre>
84-
*/
75+
return generateState(endpoints);
76+
77+
}
78+
79+
/**
80+
* <pre>
81+
* - An "V1Endpoints" holds a List of V1EndpointSubset.
82+
* - A single V1EndpointSubset holds a List of V1EndpointAddress
83+
*
84+
* - (The union of all V1EndpointSubsets is the Set of all V1Endpoints)
85+
* - Set of V1Endpoints is the cartesian product of :
86+
* V1EndpointSubset::getAddresses and V1EndpointSubset::getPorts (each is a List)
87+
* </pre>
88+
*/
89+
List<EndpointNameAndNamespace> generateState(List<V1Endpoints> endpoints) {
8590
Stream<V1ObjectReference> references = endpoints.stream()
8691
.map(V1Endpoints::getSubsets)
8792
.filter(Objects::nonNull)
@@ -92,7 +97,6 @@ else if (!context.properties().namespaces().isEmpty()) {
9297
.map(V1EndpointAddress::getTargetRef);
9398

9499
return KubernetesCatalogWatchContext.state(references);
95-
96100
}
97101

98102
private List<V1Endpoints> endpoints(CoreV1Api client, Map<String, String> labels) {

spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/catalog/KubernetesCatalogWatchEndpointSlicesTests.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import com.github.tomakehurst.wiremock.client.WireMock;
2626
import io.kubernetes.client.openapi.ApiClient;
2727
import io.kubernetes.client.openapi.JSON;
28+
import io.kubernetes.client.openapi.models.V1EndpointSlice;
29+
import io.kubernetes.client.openapi.models.V1EndpointSliceList;
2830
import io.kubernetes.client.util.ClientBuilder;
2931
import org.junit.jupiter.api.AfterAll;
3032
import org.junit.jupiter.api.AfterEach;
@@ -38,6 +40,7 @@
3840
import static com.github.tomakehurst.wiremock.client.WireMock.get;
3941
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
4042
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
43+
import static org.assertj.core.api.Assertions.assertThat;
4144

4245
/**
4346
* Test cases for the Endpoint Slices support
@@ -191,4 +194,36 @@ void testInOneNamespaceWithDoubleLabel() {
191194
invokeAndAssert(watch, List.of(new EndpointNameAndNamespace("a", "b")));
192195
}
193196

197+
@Test
198+
@Override
199+
void testWithoutSubsetsOrEndpoints() {
200+
201+
// even though we set Endpoints here to null, when
202+
// deserializing, it will be an empty List.
203+
// I'm going to leave the test here in case the client changes in this regard.
204+
// 'generateStateEndpointsWithoutEndpoints' test covers the null Subsets anyway
205+
V1EndpointSliceList endpointSlices = endpointSlicesNoEndpoints();
206+
207+
stubFor(get("/apis/discovery.k8s.io/v1/namespaces/b/endpointslices?labelSelector=key%3Dvalue%2Ckey1%3Dvalue1")
208+
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(endpointSlices))));
209+
// otherwise the stub might fail
210+
LinkedHashMap<String, String> map = new LinkedHashMap<>();
211+
map.put("key", "value");
212+
map.put("key1", "value1");
213+
KubernetesCatalogWatch watch = createWatcherInSpecificNamespaceWithLabels("b", map, null, apiClient,
214+
USE_ENDPOINT_SLICES);
215+
216+
invokeAndAssert(watch, List.of());
217+
}
218+
219+
@Test
220+
void generateStateEndpointsWithoutEndpoints() {
221+
222+
KubernetesEndpointSlicesCatalogWatch catalogWatch = new KubernetesEndpointSlicesCatalogWatch();
223+
List<V1EndpointSlice> endpointSlicesNoEndpoints = endpointSlicesNoEndpoints().getItems();
224+
225+
// even if Endpoints are missing, we do not fail
226+
assertThat(catalogWatch.generateState(endpointSlicesNoEndpoints)).isEmpty();
227+
}
228+
194229
}

spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/catalog/KubernetesCatalogWatchEndpointsTests.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.github.tomakehurst.wiremock.client.WireMock;
2626
import io.kubernetes.client.openapi.JSON;
2727
import io.kubernetes.client.openapi.apis.CoreV1Api;
28+
import io.kubernetes.client.openapi.models.V1Endpoints;
2829
import io.kubernetes.client.util.ClientBuilder;
2930
import org.junit.jupiter.api.AfterAll;
3031
import org.junit.jupiter.api.AfterEach;
@@ -38,6 +39,7 @@
3839
import static com.github.tomakehurst.wiremock.client.WireMock.get;
3940
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
4041
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
42+
import static org.assertj.core.api.Assertions.assertThat;
4143

4244
/**
4345
* Test cases for the Endpoints support
@@ -191,4 +193,30 @@ void testInOneNamespaceWithDoubleLabel() {
191193
invokeAndAssert(watch, List.of(new EndpointNameAndNamespace("a", "b")));
192194
}
193195

196+
@Test
197+
@Override
198+
void testWithoutSubsetsOrEndpoints() {
199+
stubFor(get("/api/v1/namespaces/b/endpoints?labelSelector=key%3Dvalue%2Ckey1%3Dvalue1")
200+
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(endpointsNoSubsets()))));
201+
// otherwise the stub might fail
202+
LinkedHashMap<String, String> map = new LinkedHashMap<>();
203+
map.put("key", "value");
204+
map.put("key1", "value1");
205+
KubernetesCatalogWatch watch = createWatcherInSpecificNamespaceWithLabels("b", map, coreV1Api, null,
206+
USE_ENDPOINT_SLICES);
207+
208+
invokeAndAssert(watch, List.of());
209+
}
210+
211+
@Test
212+
void generateStateEndpointsWithoutSubsets() {
213+
214+
KubernetesEndpointsCatalogWatch catalogWatch = new KubernetesEndpointsCatalogWatch();
215+
List<V1Endpoints> endpoints = endpointsNoSubsets().getItems();
216+
217+
// we do not fail, even if Subsets are not present
218+
List<EndpointNameAndNamespace> result = catalogWatch.generateState(endpoints);
219+
assertThat(result).isEmpty();
220+
}
221+
194222
}

spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/catalog/KubernetesEndpointsAndEndpointSlicesTests.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import io.kubernetes.client.openapi.ApiClient;
2424
import io.kubernetes.client.openapi.apis.CoreV1Api;
25+
import io.kubernetes.client.openapi.models.V1Endpoint;
2526
import io.kubernetes.client.openapi.models.V1EndpointAddressBuilder;
2627
import io.kubernetes.client.openapi.models.V1EndpointBuilder;
2728
import io.kubernetes.client.openapi.models.V1EndpointSliceBuilder;
@@ -104,6 +105,8 @@ abstract class KubernetesEndpointsAndEndpointSlicesTests {
104105
*/
105106
abstract void testInOneNamespaceWithDoubleLabel();
106107

108+
abstract void testWithoutSubsetsOrEndpoints();
109+
107110
KubernetesCatalogWatch createWatcherInAllNamespacesWithLabels(Map<String, String> labels, Set<String> namespaces,
108111
CoreV1Api coreV1Api, ApiClient apiClient, boolean endpointSlices) {
109112

@@ -174,6 +177,12 @@ V1EndpointsList endpoints(String name, String namespace) {
174177
.build();
175178
}
176179

180+
V1EndpointsList endpointsNoSubsets() {
181+
return new V1EndpointsListBuilder().addToItems(new V1EndpointsBuilder().build())
182+
.withKind("EndpointsList")
183+
.build();
184+
}
185+
177186
V1EndpointSliceList endpointSlices(String name, String namespace) {
178187
return new V1EndpointSliceListBuilder()
179188
.addToItems(new V1EndpointSliceBuilder().addToEndpoints(new V1EndpointBuilder()
@@ -182,6 +191,13 @@ V1EndpointSliceList endpointSlices(String name, String namespace) {
182191
.build();
183192
}
184193

194+
V1EndpointSliceList endpointSlicesNoEndpoints() {
195+
List<V1Endpoint> endpoints = null;
196+
return new V1EndpointSliceListBuilder().withKind("V1EndpointSliceList")
197+
.addToItems(new V1EndpointSliceBuilder().withEndpoints(endpoints).build())
198+
.build();
199+
}
200+
185201
static void invokeAndAssert(KubernetesCatalogWatch watch, List<EndpointNameAndNamespace> state) {
186202
watch.catalogServicesWatch();
187203

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,14 @@ else if (!context.properties().namespaces().isEmpty()) {
7373
endpointSlices = endpointSlices(context, namespace, client);
7474
}
7575

76-
return state(endpointSlices);
76+
return generateState(endpointSlices);
7777
}
7878

7979
/**
8080
* This one is visible for testing, especially since fabric8 mock client will save
8181
* null subsets as empty lists, thus blocking some unit test.
8282
*/
83-
List<EndpointNameAndNamespace> state(List<EndpointSlice> endpointSlices) {
83+
List<EndpointNameAndNamespace> generateState(List<EndpointSlice> endpointSlices) {
8484
Stream<ObjectReference> references = endpointSlices.stream()
8585
.map(EndpointSlice::getEndpoints)
8686
.filter(Objects::nonNull)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public List<EndpointNameAndNamespace> apply(Fabric8CatalogWatchContext context)
4444
List<Endpoints> endpoints = endpoints(context.properties(), context.kubernetesClient(),
4545
context.namespaceProvider(), "catalog-watcher", null, ALWAYS_TRUE);
4646

47-
return state(endpoints);
47+
return generateState(endpoints);
4848
}
4949

5050
/**
@@ -60,7 +60,7 @@ public List<EndpointNameAndNamespace> apply(Fabric8CatalogWatchContext context)
6060
* EndpointSubset::getAddresses and EndpointSubset::getPorts (each is a List)
6161
* </pre>
6262
*/
63-
List<EndpointNameAndNamespace> state(List<Endpoints> endpoints) {
63+
List<EndpointNameAndNamespace> generateState(List<Endpoints> endpoints) {
6464
Stream<ObjectReference> references = endpoints.stream()
6565
.map(Endpoints::getSubsets)
6666
.filter(Objects::nonNull)

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

Lines changed: 0 additions & 54 deletions
This file was deleted.

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,7 @@ void endpoints(String namespace, Map<String, String> labels, String podName) {
319319
mockClient().endpoints().inNamespace(namespace).resource(endpoints).create();
320320
}
321321

322-
void endpointsWithoutSubsets(String namespace, Map<String, String> labels, String podName) {
322+
Endpoints endpointsWithoutSubsets(String namespace, Map<String, String> labels, String podName) {
323323

324324
// though we set it to null here, the mock client when creating it
325325
// will set it to an empty list. I will keep it like this, may be client changes
@@ -331,6 +331,7 @@ void endpointsWithoutSubsets(String namespace, Map<String, String> labels, Strin
331331
.withSubsets(endpointSubsets)
332332
.build();
333333
mockClient().endpoints().inNamespace(namespace).resource(endpoints).create();
334+
return endpoints;
334335
}
335336

336337
void service(String namespace, Map<String, String> labels, String podName) {
@@ -359,7 +360,7 @@ static void endpointSlice(String namespace, Map<String, String> labels, String p
359360

360361
}
361362

362-
static void endpointSliceWithoutEndpoints(String namespace, Map<String, String> labels, String podName) {
363+
static EndpointSlice endpointSliceWithoutEndpoints(String namespace, Map<String, String> labels, String podName) {
363364

364365
List<Endpoint> endpoints = null;
365366

@@ -372,6 +373,7 @@ static void endpointSliceWithoutEndpoints(String namespace, Map<String, String>
372373
.build();
373374

374375
mockClient().discovery().v1().endpointSlices().inNamespace(namespace).resource(slice).create();
376+
return slice;
375377

376378
}
377379

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

Lines changed: 0 additions & 57 deletions
This file was deleted.

0 commit comments

Comments
 (0)