diff --git a/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/Fabric8KubernetesDiscoveryClientUtils.java b/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/Fabric8KubernetesDiscoveryClientUtils.java index ab5a98d8..93777104 100644 --- a/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/Fabric8KubernetesDiscoveryClientUtils.java +++ b/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/Fabric8KubernetesDiscoveryClientUtils.java @@ -222,26 +222,31 @@ final class Fabric8KubernetesDiscoveryClientUtils { // see https://github.com/spring-cloud/spring-cloud-kubernetes/issues/1182 on why this // is needed - static List withFilter(List initial, KubernetesDiscoveryProperties properties, + static List withFilter(List endpoints, KubernetesDiscoveryProperties properties, KubernetesClient client, Predicate filter) { if (properties.filter() == null || properties.filter().isBlank()) { LOG.debug(() -> "filter not present"); - return initial; + return endpoints; } List result = new ArrayList<>(); // group by namespace in order to make a single API call per namespace when // retrieving services - Map> byNamespace = initial.stream() + Map> endpointsByNamespace = endpoints.stream() .collect(Collectors.groupingBy(x -> x.getMetadata().getNamespace())); - for (Map.Entry> entry : byNamespace.entrySet()) { - Set withFilter = client.services().inNamespace(entry.getKey()).list().getItems().stream() + for (Map.Entry> entry : endpointsByNamespace.entrySet()) { + // get all services in the namespace that match the filter + Set filteredServiceNames = client.services().inNamespace(entry.getKey()).list().getItems().stream() .filter(filter).map(service -> service.getMetadata().getName()).collect(Collectors.toSet()); - result.addAll( - entry.getValue().stream().filter(x -> withFilter.contains(x.getMetadata().getName())).toList()); + // in the previous step we might have taken "too many" services, so in the + // next one take only those that have a matching endpoints, by name. + // This way we only get the endpoints that have a matching service with an + // applied filter, it's like we filtered endpoints by that filter. + result.addAll(entry.getValue().stream() + .filter(endpoint -> filteredServiceNames.contains(endpoint.getMetadata().getName())).toList()); } diff --git a/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClient.java b/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClient.java index 1fb12e94..031cdc6f 100644 --- a/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClient.java +++ b/spring-cloud-kubernetes-fabric8-discovery/src/main/java/org/springframework/cloud/kubernetes/fabric8/discovery/KubernetesDiscoveryClient.java @@ -109,6 +109,7 @@ public class KubernetesDiscoveryClient implements DiscoveryClient, EnvironmentAw List instances = new ArrayList<>(); for (EndpointSubsetNS es : subsetsNS) { + // subsetsNS are only those that matched the serviceId instances.addAll(getNamespaceServiceInstances(es, serviceId)); }