diff --git a/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/ConditionalOnSelectiveNamespacesMissing.java b/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/ConditionalOnSelectiveNamespacesMissing.java deleted file mode 100644 index 2cf3c18c38..0000000000 --- a/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/ConditionalOnSelectiveNamespacesMissing.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2013-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.kubernetes.client.discovery; - -import java.util.Set; - -import org.apache.commons.logging.LogFactory; - -import org.springframework.boot.context.properties.bind.Bindable; -import org.springframework.boot.context.properties.bind.Binder; -import org.springframework.context.annotation.ConditionContext; -import org.springframework.context.annotation.ConfigurationCondition; -import org.springframework.core.log.LogAccessor; -import org.springframework.core.type.AnnotatedTypeMetadata; - -/** - * Conditional that checks if our discovery is _not_ based on selective namespaces, i.e.: - * 'spring.cloud.kubernetes.discovery.namespaces' is not set. - * - * @author wind57 - */ -final class ConditionalOnSelectiveNamespacesMissing implements ConfigurationCondition { - - private static final LogAccessor LOG = new LogAccessor( - LogFactory.getLog(ConditionalOnSelectiveNamespacesMissing.class)); - - @Override - public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { - - Set selectiveNamespaces = Binder.get(context.getEnvironment()) - .bind("spring.cloud.kubernetes.discovery.namespaces", Bindable.setOf(String.class)) - .orElse(Set.of()); - boolean selectiveNamespacesMissing = selectiveNamespaces.isEmpty(); - if (selectiveNamespacesMissing) { - LOG.debug(() -> "selective namespaces not present"); - } - else { - LOG.debug(() -> "found selective namespaces : " + selectiveNamespaces.stream().sorted().toList()); - } - return selectiveNamespacesMissing; - } - - @Override - public ConfigurationPhase getConfigurationPhase() { - return ConfigurationPhase.REGISTER_BEAN; - } - -} diff --git a/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/ConditionalOnSelectiveNamespacesPresent.java b/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/ConditionalOnSelectiveNamespacesPresent.java deleted file mode 100644 index 75a660bc26..0000000000 --- a/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/ConditionalOnSelectiveNamespacesPresent.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2013-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.kubernetes.client.discovery; - -import java.util.Set; - -import org.apache.commons.logging.LogFactory; - -import org.springframework.boot.context.properties.bind.Bindable; -import org.springframework.boot.context.properties.bind.Binder; -import org.springframework.context.annotation.ConditionContext; -import org.springframework.context.annotation.ConfigurationCondition; -import org.springframework.core.log.LogAccessor; -import org.springframework.core.type.AnnotatedTypeMetadata; - -/** - * Conditional that checks if our discovery is based on selective namespaces, i.e.: - * 'spring.cloud.kubernetes.discovery.namespaces' is set. - * - * @author wind57 - */ -final class ConditionalOnSelectiveNamespacesPresent implements ConfigurationCondition { - - private static final LogAccessor LOG = new LogAccessor( - LogFactory.getLog(ConditionalOnSelectiveNamespacesPresent.class)); - - @Override - public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { - - Set selectiveNamespaces = Binder.get(context.getEnvironment()) - .bind("spring.cloud.kubernetes.discovery.namespaces", Bindable.setOf(String.class)) - .orElse(Set.of()); - boolean selectiveNamespacesPresent = !selectiveNamespaces.isEmpty(); - if (selectiveNamespacesPresent) { - LOG.debug(() -> "found selective namespaces : " + selectiveNamespaces.stream().sorted().toList()); - } - else { - LOG.debug(() -> "selective namespaces not present"); - } - return selectiveNamespacesPresent; - } - - @Override - public ConfigurationCondition.ConfigurationPhase getConfigurationPhase() { - return ConfigurationPhase.REGISTER_BEAN; - } - -} diff --git a/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerAutoConfiguration.java b/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerAutoConfiguration.java index 761b233d13..8ea470fa0c 100644 --- a/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerAutoConfiguration.java +++ b/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerAutoConfiguration.java @@ -16,6 +16,9 @@ package org.springframework.cloud.kubernetes.client.discovery; +import java.util.ArrayList; +import java.util.List; + import io.kubernetes.client.informer.SharedIndexInformer; import io.kubernetes.client.informer.SharedInformerFactory; import io.kubernetes.client.informer.cache.Lister; @@ -37,21 +40,21 @@ import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration; import org.springframework.cloud.kubernetes.client.KubernetesClientAutoConfiguration; import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider; -import org.springframework.cloud.kubernetes.commons.config.NamespaceResolutionFailedException; import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryProperties; import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryPropertiesAutoConfiguration; import org.springframework.cloud.kubernetes.commons.discovery.conditionals.ConditionalOnBlockingOrReactiveDiscoveryEnabled; import org.springframework.cloud.kubernetes.commons.discovery.conditionals.ConditionalOnKubernetesDiscoveryEnabled; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.core.log.LogAccessor; import static io.kubernetes.client.util.Namespaces.NAMESPACE_ALL; -import static io.kubernetes.client.util.Namespaces.NAMESPACE_DEFAULT; import static org.springframework.cloud.kubernetes.client.KubernetesClientUtils.getApplicationNamespace; /** + * This one uses: 'ConditionalOnBlockingOrReactiveDiscoveryEnabled' because beans it + * contains are specific to both clients. + * * @author wind57 */ @Configuration(proxyBeanMethods = false) @@ -59,7 +62,6 @@ @ConditionalOnKubernetesDiscoveryEnabled @ConditionalOnBlockingOrReactiveDiscoveryEnabled @ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES) -@Conditional(ConditionalOnSelectiveNamespacesMissing.class) @AutoConfigureBefore({ SimpleDiscoveryClientAutoConfiguration.class, CommonsClientAutoConfiguration.class }) @AutoConfigureAfter({ KubernetesClientAutoConfiguration.class, KubernetesDiscoveryPropertiesAutoConfiguration.class }) final class KubernetesClientInformerAutoConfiguration { @@ -67,71 +69,112 @@ final class KubernetesClientInformerAutoConfiguration { private static final LogAccessor LOG = new LogAccessor( LogFactory.getLog(KubernetesClientInformerAutoConfiguration.class)); + // we rely on the order of namespaces to enable listers, as such provide a bean of + // namespaces as a list, instead of the incoming Set. @Bean - @ConditionalOnMissingBean - SharedInformerFactory sharedInformerFactory(ApiClient client) { - LOG.debug(() -> "registering sharedInformerFactory for non-selective namespaces"); - return new SharedInformerFactory(client); - } + List k8sClientDiscoveryNamespaces(KubernetesDiscoveryProperties properties, + KubernetesNamespaceProvider provider) { - @Bean - String kubernetesClientNamespace(KubernetesDiscoveryProperties properties, KubernetesNamespaceProvider provider) { - String namespace; if (properties.allNamespaces()) { - namespace = NAMESPACE_ALL; LOG.debug(() -> "serviceSharedInformer will use all-namespaces"); + return List.of(NAMESPACE_ALL); } - else { - try { - namespace = getApplicationNamespace(null, "kubernetes client discovery", provider); - } - catch (NamespaceResolutionFailedException ex) { - LOG.warn(() -> "failed to resolve namespace, defaulting to :" + NAMESPACE_DEFAULT - + ". This will fail in a future release."); - namespace = NAMESPACE_DEFAULT; - } - LOG.debug("serviceSharedInformer will use namespace : " + namespace); + + if (properties.namespaces() != null && !properties.namespaces().isEmpty()) { + List selectiveNamespaces = properties.namespaces().stream().sorted().toList(); + LOG.debug(() -> "serviceSharedInformers will use selective namespaces : " + selectiveNamespaces); + return selectiveNamespaces; } - return namespace; + String namespace = getApplicationNamespace(null, "kubernetes client discovery", provider); + LOG.debug(() -> "using namespace : " + namespace); + return List.of(namespace); } @Bean - @ConditionalOnMissingBean(value = V1Service.class, parameterizedContainer = SharedIndexInformer.class) - SharedIndexInformer servicesSharedIndexInformer(SharedInformerFactory sharedInformerFactory, - ApiClient apiClient, String kubernetesClientNamespace) { - - GenericKubernetesApi servicesApi = new GenericKubernetesApi<>(V1Service.class, - V1ServiceList.class, "", "v1", "services", apiClient); + @ConditionalOnMissingBean(value = SharedInformerFactory.class, parameterizedContainer = List.class) + List sharedInformerFactories(ApiClient apiClient, List selectiveNamespaces) { - return sharedInformerFactory.sharedIndexInformerFor(servicesApi, V1Service.class, 0L, - kubernetesClientNamespace); + int howManyNamespaces = selectiveNamespaces.size(); + List sharedInformerFactories = new ArrayList<>(howManyNamespaces); + for (int i = 0; i < howManyNamespaces; ++i) { + sharedInformerFactories.add(new SharedInformerFactory(apiClient)); + } + return sharedInformerFactories; } @Bean - @ConditionalOnMissingBean(value = V1Endpoints.class, parameterizedContainer = SharedIndexInformer.class) - SharedIndexInformer endpointsSharedIndexInformer(SharedInformerFactory sharedInformerFactory, - ApiClient apiClient, String kubernetesClientNamespace) { + @ConditionalOnMissingBean(value = V1Service.class, + parameterizedContainer = { List.class, SharedIndexInformer.class }) + List> serviceSharedIndexInformers( + List sharedInformerFactories, List selectiveNamespaces, + ApiClient apiClient) { + + int howManyNamespaces = selectiveNamespaces.size(); + List> serviceSharedIndexedInformers = new ArrayList<>(howManyNamespaces); + for (int i = 0; i < howManyNamespaces; ++i) { + GenericKubernetesApi servicesApi = new GenericKubernetesApi<>(V1Service.class, + V1ServiceList.class, "", "v1", "services", apiClient); + SharedIndexInformer sharedIndexInformer = sharedInformerFactories.get(i) + .sharedIndexInformerFor(servicesApi, V1Service.class, 0L, selectiveNamespaces.get(i)); + serviceSharedIndexedInformers.add(sharedIndexInformer); + } + return serviceSharedIndexedInformers; + } - GenericKubernetesApi servicesApi = new GenericKubernetesApi<>(V1Endpoints.class, - V1EndpointsList.class, "", "v1", "endpoints", apiClient); + @Bean + @ConditionalOnMissingBean(value = V1Service.class, parameterizedContainer = { List.class, Lister.class }) + List> serviceListers(List selectiveNamespaces, + List> serviceSharedIndexInformers) { + + int howManyNamespaces = selectiveNamespaces.size(); + List> serviceListers = new ArrayList<>(howManyNamespaces); + + for (int i = 0; i < howManyNamespaces; ++i) { + String namespace = selectiveNamespaces.get(i); + Lister lister = new Lister<>(serviceSharedIndexInformers.get(i).getIndexer(), namespace); + LOG.debug(() -> "registering lister (for services) in namespace : " + namespace); + serviceListers.add(lister); + } - return sharedInformerFactory.sharedIndexInformerFor(servicesApi, V1Endpoints.class, 0L, - kubernetesClientNamespace); + return serviceListers; } @Bean - @ConditionalOnMissingBean(value = V1Service.class, parameterizedContainer = Lister.class) - Lister servicesLister(SharedIndexInformer servicesSharedIndexInformer, - String kubernetesClientNamespace) { - return new Lister<>(servicesSharedIndexInformer.getIndexer(), kubernetesClientNamespace); + @ConditionalOnMissingBean(value = V1Endpoints.class, + parameterizedContainer = { List.class, SharedIndexInformer.class }) + List> endpointsSharedIndexInformers( + List sharedInformerFactories, List selectiveNamespaces, + ApiClient apiClient) { + + int howManyNamespaces = selectiveNamespaces.size(); + List> endpointsSharedIndexedInformers = new ArrayList<>(howManyNamespaces); + for (int i = 0; i < howManyNamespaces; ++i) { + GenericKubernetesApi endpointsApi = new GenericKubernetesApi<>( + V1Endpoints.class, V1EndpointsList.class, "", "v1", "endpoints", apiClient); + SharedIndexInformer sharedIndexInformer = sharedInformerFactories.get(i) + .sharedIndexInformerFor(endpointsApi, V1Endpoints.class, 0L, selectiveNamespaces.get(i)); + endpointsSharedIndexedInformers.add(sharedIndexInformer); + } + return endpointsSharedIndexedInformers; } @Bean - @ConditionalOnMissingBean(value = V1Endpoints.class, parameterizedContainer = Lister.class) - Lister endpointsLister(SharedIndexInformer endpointsSharedIndexInformer, - String kubernetesClientNamespace) { - return new Lister<>(endpointsSharedIndexInformer.getIndexer(), kubernetesClientNamespace); + @ConditionalOnMissingBean(value = V1Endpoints.class, parameterizedContainer = { List.class, Lister.class }) + List> endpointsListers(List selectiveNamespaces, + List> serviceSharedIndexInformers) { + + int howManyNamespaces = selectiveNamespaces.size(); + List> endpointsListers = new ArrayList<>(howManyNamespaces); + + for (int i = 0; i < howManyNamespaces; ++i) { + String namespace = selectiveNamespaces.get(i); + Lister lister = new Lister<>(serviceSharedIndexInformers.get(i).getIndexer()); + LOG.debug(() -> "registering lister (for endpoints) in namespace : " + namespace); + endpointsListers.add(lister); + } + + return endpointsListers; } } diff --git a/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerDiscoveryClientAutoConfiguration.java b/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerDiscoveryClientAutoConfiguration.java index 69f2686233..4dda10ced4 100644 --- a/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerDiscoveryClientAutoConfiguration.java +++ b/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerDiscoveryClientAutoConfiguration.java @@ -25,6 +25,7 @@ import io.kubernetes.client.openapi.apis.CoreV1Api; import io.kubernetes.client.openapi.models.V1Endpoints; import io.kubernetes.client.openapi.models.V1Service; +import org.apache.commons.logging.LogFactory; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureBefore; @@ -32,14 +33,16 @@ import org.springframework.cloud.client.CommonsClientAutoConfiguration; import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration; import org.springframework.cloud.kubernetes.client.KubernetesClientAutoConfiguration; -import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryClientHealthConfiguration; +import org.springframework.cloud.kubernetes.commons.PodUtils; +import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryClientHealthIndicatorInitializer; import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryProperties; import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryPropertiesAutoConfiguration; import org.springframework.cloud.kubernetes.commons.discovery.conditionals.ConditionalOnSpringCloudKubernetesBlockingDiscovery; +import org.springframework.cloud.kubernetes.commons.discovery.conditionals.ConditionalOnSpringCloudKubernetesBlockingDiscoveryHealthInitializer; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; +import org.springframework.core.log.LogAccessor; /** * @author wind57 @@ -48,29 +51,15 @@ @ConditionalOnSpringCloudKubernetesBlockingDiscovery @AutoConfigureBefore({ SimpleDiscoveryClientAutoConfiguration.class, CommonsClientAutoConfiguration.class }) @AutoConfigureAfter({ KubernetesClientAutoConfiguration.class, KubernetesDiscoveryPropertiesAutoConfiguration.class, - KubernetesClientInformerAutoConfiguration.class, - KubernetesClientInformerSelectiveNamespacesAutoConfiguration.class, KubernetesClientDiscoveryClientSpelAutoConfiguration.class }) -@Import(KubernetesDiscoveryClientHealthConfiguration.class) final class KubernetesClientInformerDiscoveryClientAutoConfiguration { - @Bean - @ConditionalOnMissingBean - @Conditional(ConditionalOnSelectiveNamespacesMissing.class) - KubernetesClientInformerDiscoveryClient kubernetesClientInformerDiscoveryClient( - SharedInformerFactory sharedInformerFactory, Lister serviceLister, - Lister endpointsLister, SharedInformer serviceInformer, - SharedInformer endpointsInformer, KubernetesDiscoveryProperties properties, - CoreV1Api coreV1Api, Predicate predicate) { - return new KubernetesClientInformerDiscoveryClient(List.of(sharedInformerFactory), List.of(serviceLister), - List.of(endpointsLister), List.of(serviceInformer), List.of(endpointsInformer), properties, coreV1Api, - predicate); - } + private static final LogAccessor LOG = new LogAccessor( + LogFactory.getLog(KubernetesClientInformerDiscoveryClientAutoConfiguration.class)); @Bean @ConditionalOnMissingBean - @Conditional(ConditionalOnSelectiveNamespacesPresent.class) - KubernetesClientInformerDiscoveryClient selectiveNamespacesKubernetesInformerDiscoveryClient( + KubernetesClientInformerDiscoveryClient kubernetesClientInformerDiscoveryClient( List sharedInformerFactories, List> serviceListers, List> endpointsListers, List> serviceInformers, List> endpointsInformers, KubernetesDiscoveryProperties properties, @@ -79,4 +68,12 @@ KubernetesClientInformerDiscoveryClient selectiveNamespacesKubernetesInformerDis serviceInformers, endpointsInformers, properties, coreV1Api, predicate); } + @Bean + @ConditionalOnSpringCloudKubernetesBlockingDiscoveryHealthInitializer + KubernetesDiscoveryClientHealthIndicatorInitializer indicatorInitializer( + ApplicationEventPublisher applicationEventPublisher, PodUtils podUtils) { + LOG.debug(() -> "Will publish InstanceRegisteredEvent from blocking implementation"); + return new KubernetesDiscoveryClientHealthIndicatorInitializer(podUtils, applicationEventPublisher); + } + } diff --git a/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerReactiveDiscoveryClientAutoConfiguration.java b/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerReactiveDiscoveryClientAutoConfiguration.java index 603e6a4b63..70666fca0f 100644 --- a/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerReactiveDiscoveryClientAutoConfiguration.java +++ b/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerReactiveDiscoveryClientAutoConfiguration.java @@ -43,7 +43,6 @@ import org.springframework.cloud.kubernetes.commons.discovery.conditionals.ConditionalOnSpringCloudKubernetesReactiveDiscoveryHealthInitializer; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.core.log.LogAccessor; @@ -56,14 +55,33 @@ @AutoConfigureBefore({ SimpleReactiveDiscoveryClientAutoConfiguration.class, ReactiveCommonsClientAutoConfiguration.class }) @AutoConfigureAfter({ ReactiveCompositeDiscoveryClientAutoConfiguration.class, - KubernetesDiscoveryPropertiesAutoConfiguration.class, KubernetesClientInformerAutoConfiguration.class, - KubernetesClientInformerSelectiveNamespacesAutoConfiguration.class, + KubernetesDiscoveryPropertiesAutoConfiguration.class, KubernetesClientDiscoveryClientSpelAutoConfiguration.class }) final class KubernetesClientInformerReactiveDiscoveryClientAutoConfiguration { private static final LogAccessor LOG = new LogAccessor( LogFactory.getLog(KubernetesClientInformerReactiveDiscoveryClientAutoConfiguration.class)); + // in case blocking is disabled + @Bean + @ConditionalOnMissingBean + KubernetesClientInformerDiscoveryClient kubernetesClientInformerDiscoveryClientForReactiveImplementation( + List sharedInformerFactories, List> serviceListers, + List> endpointsListers, List> serviceInformers, + List> endpointsInformers, KubernetesDiscoveryProperties properties, + CoreV1Api coreV1Api, Predicate predicate) { + + return new KubernetesClientInformerDiscoveryClient(sharedInformerFactories, serviceListers, endpointsListers, + serviceInformers, endpointsInformers, properties, coreV1Api, predicate); + } + + @Bean + @ConditionalOnMissingBean + KubernetesClientInformerReactiveDiscoveryClient kubernetesClientReactiveDiscoveryClient( + KubernetesClientInformerDiscoveryClient kubernetesClientInformerDiscoveryClient) { + return new KubernetesClientInformerReactiveDiscoveryClient(kubernetesClientInformerDiscoveryClient); + } + /** * Post an event so that health indicator is initialized. */ @@ -86,36 +104,4 @@ ReactiveDiscoveryClientHealthIndicator kubernetesReactiveDiscoveryClientHealthIn return new ReactiveDiscoveryClientHealthIndicator(client, properties); } - @Bean - @ConditionalOnMissingBean - KubernetesClientInformerReactiveDiscoveryClient kubernetesClientReactiveDiscoveryClient( - KubernetesClientInformerDiscoveryClient kubernetesClientInformerDiscoveryClient) { - return new KubernetesClientInformerReactiveDiscoveryClient(kubernetesClientInformerDiscoveryClient); - } - - @Bean - @ConditionalOnMissingBean - @Conditional(ConditionalOnSelectiveNamespacesMissing.class) - KubernetesClientInformerDiscoveryClient kubernetesClientInformerDiscoveryClient( - SharedInformerFactory sharedInformerFactory, Lister serviceLister, - Lister endpointsLister, SharedInformer serviceInformer, - SharedInformer endpointsInformer, KubernetesDiscoveryProperties properties, - CoreV1Api coreV1Api, Predicate predicate) { - return new KubernetesClientInformerDiscoveryClient(List.of(sharedInformerFactory), List.of(serviceLister), - List.of(endpointsLister), List.of(serviceInformer), List.of(endpointsInformer), properties, coreV1Api, - predicate); - } - - @Bean - @ConditionalOnMissingBean - @Conditional(ConditionalOnSelectiveNamespacesPresent.class) - KubernetesClientInformerDiscoveryClient selectiveNamespacesKubernetesClientInformerDiscoveryClient( - List sharedInformerFactories, List> serviceListers, - List> endpointsListers, List> serviceInformers, - List> endpointsInformers, KubernetesDiscoveryProperties properties, - CoreV1Api coreV1Api, Predicate predicate) { - return new KubernetesClientInformerDiscoveryClient(sharedInformerFactories, serviceListers, endpointsListers, - serviceInformers, endpointsInformers, properties, coreV1Api, predicate); - } - } diff --git a/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerSelectiveNamespacesAutoConfiguration.java b/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerSelectiveNamespacesAutoConfiguration.java deleted file mode 100644 index 3cf938e9c5..0000000000 --- a/spring-cloud-kubernetes-client-discovery/src/main/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerSelectiveNamespacesAutoConfiguration.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright 2013-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.kubernetes.client.discovery; - -import java.util.ArrayList; -import java.util.List; - -import io.kubernetes.client.informer.SharedIndexInformer; -import io.kubernetes.client.informer.SharedInformerFactory; -import io.kubernetes.client.informer.cache.Lister; -import io.kubernetes.client.openapi.ApiClient; -import io.kubernetes.client.openapi.models.V1Endpoints; -import io.kubernetes.client.openapi.models.V1EndpointsList; -import io.kubernetes.client.openapi.models.V1Service; -import io.kubernetes.client.openapi.models.V1ServiceList; -import io.kubernetes.client.util.generic.GenericKubernetesApi; -import org.apache.commons.logging.LogFactory; - -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnCloudPlatform; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.cloud.CloudPlatform; -import org.springframework.cloud.client.CommonsClientAutoConfiguration; -import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled; -import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration; -import org.springframework.cloud.kubernetes.client.KubernetesClientAutoConfiguration; -import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryProperties; -import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryPropertiesAutoConfiguration; -import org.springframework.cloud.kubernetes.commons.discovery.conditionals.ConditionalOnBlockingOrReactiveDiscoveryEnabled; -import org.springframework.cloud.kubernetes.commons.discovery.conditionals.ConditionalOnKubernetesDiscoveryEnabled; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.log.LogAccessor; - -/** - * Auto-configuration to be used when "spring.cloud.kubernetes.discovery.namespaces" is - * defined. - * - * @author wind57 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnDiscoveryEnabled -@ConditionalOnKubernetesDiscoveryEnabled -@ConditionalOnBlockingOrReactiveDiscoveryEnabled -@Conditional(ConditionalOnSelectiveNamespacesPresent.class) -@ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES) -@AutoConfigureBefore({ SimpleDiscoveryClientAutoConfiguration.class, CommonsClientAutoConfiguration.class }) -@AutoConfigureAfter({ KubernetesClientAutoConfiguration.class, KubernetesDiscoveryPropertiesAutoConfiguration.class }) -final class KubernetesClientInformerSelectiveNamespacesAutoConfiguration { - - private static final LogAccessor LOG = new LogAccessor( - LogFactory.getLog(KubernetesClientInformerSelectiveNamespacesAutoConfiguration.class)); - - // we rely on the order of namespaces to enable listers, as such provide a bean of - // namespaces as a list, instead of the incoming Set. - @Bean - List selectiveNamespaces(KubernetesDiscoveryProperties properties) { - List selectiveNamespaces = properties.namespaces().stream().sorted().toList(); - LOG.debug(() -> "using selective namespaces : " + selectiveNamespaces); - return selectiveNamespaces; - } - - @Bean - @ConditionalOnMissingBean(value = SharedInformerFactory.class, parameterizedContainer = List.class) - List sharedInformerFactories(ApiClient apiClient, List selectiveNamespaces) { - - int howManyNamespaces = selectiveNamespaces.size(); - List sharedInformerFactories = new ArrayList<>(howManyNamespaces); - for (int i = 0; i < howManyNamespaces; ++i) { - sharedInformerFactories.add(new SharedInformerFactory(apiClient)); - } - return sharedInformerFactories; - } - - @Bean - @ConditionalOnMissingBean(value = V1Service.class, - parameterizedContainer = { List.class, SharedIndexInformer.class }) - List> serviceSharedIndexInformers( - List sharedInformerFactories, List selectiveNamespaces, - ApiClient apiClient) { - - int howManyNamespaces = selectiveNamespaces.size(); - List> serviceSharedIndexedInformers = new ArrayList<>(howManyNamespaces); - for (int i = 0; i < howManyNamespaces; ++i) { - GenericKubernetesApi servicesApi = new GenericKubernetesApi<>(V1Service.class, - V1ServiceList.class, "", "v1", "services", apiClient); - SharedIndexInformer sharedIndexInformer = sharedInformerFactories.get(i) - .sharedIndexInformerFor(servicesApi, V1Service.class, 0L, selectiveNamespaces.get(i)); - serviceSharedIndexedInformers.add(sharedIndexInformer); - } - return serviceSharedIndexedInformers; - } - - @Bean - @ConditionalOnMissingBean(value = V1Service.class, parameterizedContainer = { List.class, Lister.class }) - List> serviceListers(List selectiveNamespaces, - List> serviceSharedIndexInformers) { - - int howManyNamespaces = selectiveNamespaces.size(); - List> serviceListers = new ArrayList<>(howManyNamespaces); - - for (int i = 0; i < howManyNamespaces; ++i) { - String namespace = selectiveNamespaces.get(i); - Lister lister = new Lister<>(serviceSharedIndexInformers.get(i).getIndexer(), namespace); - LOG.debug(() -> "registering lister (for services) in namespace : " + namespace); - serviceListers.add(lister); - } - - return serviceListers; - } - - @Bean - @ConditionalOnMissingBean(value = V1Endpoints.class, - parameterizedContainer = { List.class, SharedIndexInformer.class }) - List> endpointsSharedIndexInformers( - List sharedInformerFactories, List selectiveNamespaces, - ApiClient apiClient) { - - int howManyNamespaces = selectiveNamespaces.size(); - List> endpointsSharedIndexedInformers = new ArrayList<>(howManyNamespaces); - for (int i = 0; i < howManyNamespaces; ++i) { - GenericKubernetesApi endpointsApi = new GenericKubernetesApi<>( - V1Endpoints.class, V1EndpointsList.class, "", "v1", "endpoints", apiClient); - SharedIndexInformer sharedIndexInformer = sharedInformerFactories.get(i) - .sharedIndexInformerFor(endpointsApi, V1Endpoints.class, 0L, selectiveNamespaces.get(i)); - endpointsSharedIndexedInformers.add(sharedIndexInformer); - } - return endpointsSharedIndexedInformers; - } - - @Bean - @ConditionalOnMissingBean(value = V1Endpoints.class, parameterizedContainer = { List.class, Lister.class }) - List> endpointsListers(List selectiveNamespaces, - List> serviceSharedIndexInformers) { - - int howManyNamespaces = selectiveNamespaces.size(); - List> endpointsListers = new ArrayList<>(howManyNamespaces); - - for (int i = 0; i < howManyNamespaces; ++i) { - String namespace = selectiveNamespaces.get(i); - Lister lister = new Lister<>(serviceSharedIndexInformers.get(i).getIndexer()); - LOG.debug(() -> "registering lister (for endpoints) in namespace : " + namespace); - endpointsListers.add(lister); - } - - return endpointsListers; - } - -} diff --git a/spring-cloud-kubernetes-client-discovery/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-cloud-kubernetes-client-discovery/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 9d49cea85f..3527902071 100644 --- a/spring-cloud-kubernetes-client-discovery/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/spring-cloud-kubernetes-client-discovery/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -2,5 +2,4 @@ org.springframework.cloud.kubernetes.client.discovery.KubernetesClientCatalogWat org.springframework.cloud.kubernetes.client.discovery.KubernetesClientInformerDiscoveryClientAutoConfiguration org.springframework.cloud.kubernetes.client.discovery.KubernetesClientInformerAutoConfiguration org.springframework.cloud.kubernetes.client.discovery.KubernetesClientInformerReactiveDiscoveryClientAutoConfiguration -org.springframework.cloud.kubernetes.client.discovery.KubernetesClientInformerSelectiveNamespacesAutoConfiguration org.springframework.cloud.kubernetes.client.discovery.KubernetesClientDiscoveryClientSpelAutoConfiguration diff --git a/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/ConditionalOnSelectiveNamespacesDisabledTests.java b/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/ConditionalOnSelectiveNamespacesDisabledTests.java deleted file mode 100644 index 7a316b20c6..0000000000 --- a/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/ConditionalOnSelectiveNamespacesDisabledTests.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2013-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.kubernetes.client.discovery; - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -import org.springframework.context.annotation.ConditionContext; -import org.springframework.mock.env.MockEnvironment; - -/** - * @author wind57 - */ - -class ConditionalOnSelectiveNamespacesDisabledTests { - - private static final ConditionalOnSelectiveNamespacesMissing TO_TEST = new ConditionalOnSelectiveNamespacesMissing(); - - private static final ConditionContext CONDITION_CONTEXT = Mockito.mock(ConditionContext.class); - - @Test - void testSelectiveNamespacesNotPresent() { - MockEnvironment environment = new MockEnvironment(); - Mockito.when(CONDITION_CONTEXT.getEnvironment()).thenReturn(environment); - boolean result = TO_TEST.matches(CONDITION_CONTEXT, null); - Assertions.assertThat(result).isTrue(); - } - - @Test - void testSelectiveNamespacesPresentEmpty() { - MockEnvironment environment = new MockEnvironment(); - environment.setProperty("spring.cloud.kubernetes.discovery.namespaces", ""); - Mockito.when(CONDITION_CONTEXT.getEnvironment()).thenReturn(environment); - boolean result = TO_TEST.matches(CONDITION_CONTEXT, null); - Assertions.assertThat(result).isTrue(); - } - - @Test - void testSelectiveNamespacesPresentNonEmpty() { - MockEnvironment environment = new MockEnvironment(); - environment.setProperty("spring.cloud.kubernetes.discovery.namespaces", "default"); - Mockito.when(CONDITION_CONTEXT.getEnvironment()).thenReturn(environment); - boolean result = TO_TEST.matches(CONDITION_CONTEXT, null); - Assertions.assertThat(result).isFalse(); - } - -} diff --git a/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/ConditionalOnSelectiveNamespacesEnabledTests.java b/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/ConditionalOnSelectiveNamespacesEnabledTests.java deleted file mode 100644 index ae7e347f19..0000000000 --- a/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/ConditionalOnSelectiveNamespacesEnabledTests.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2013-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.kubernetes.client.discovery; - -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -import org.springframework.context.annotation.ConditionContext; -import org.springframework.mock.env.MockEnvironment; - -/** - * @author wind57 - */ -class ConditionalOnSelectiveNamespacesEnabledTests { - - private static final ConditionalOnSelectiveNamespacesPresent TO_TEST = new ConditionalOnSelectiveNamespacesPresent(); - - private static final ConditionContext CONDITION_CONTEXT = Mockito.mock(ConditionContext.class); - - @Test - void testSelectiveNamespacesNotPresent() { - MockEnvironment environment = new MockEnvironment(); - Mockito.when(CONDITION_CONTEXT.getEnvironment()).thenReturn(environment); - boolean result = TO_TEST.matches(CONDITION_CONTEXT, null); - Assertions.assertThat(result).isFalse(); - } - - @Test - void testSelectiveNamespacesPresentEmpty() { - MockEnvironment environment = new MockEnvironment(); - environment.setProperty("spring.cloud.kubernetes.discovery.namespaces", ""); - Mockito.when(CONDITION_CONTEXT.getEnvironment()).thenReturn(environment); - boolean result = TO_TEST.matches(CONDITION_CONTEXT, null); - Assertions.assertThat(result).isFalse(); - } - - @Test - void testSelectiveNamespacesPresentNonEmpty() { - MockEnvironment environment = new MockEnvironment(); - environment.setProperty("spring.cloud.kubernetes.discovery.namespaces", "default"); - Mockito.when(CONDITION_CONTEXT.getEnvironment()).thenReturn(environment); - boolean result = TO_TEST.matches(CONDITION_CONTEXT, null); - Assertions.assertThat(result).isTrue(); - } - -} diff --git a/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerDiscoveryClientAutoConfigurationApplicationContextTests.java b/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerDiscoveryClientAutoConfigurationApplicationContextTests.java index 556ae38ce6..2608fc71e2 100644 --- a/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerDiscoveryClientAutoConfigurationApplicationContextTests.java +++ b/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerDiscoveryClientAutoConfigurationApplicationContextTests.java @@ -29,7 +29,10 @@ import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.cloud.client.discovery.health.reactive.ReactiveDiscoveryClientHealthIndicator; +import org.springframework.cloud.client.discovery.simple.reactive.SimpleReactiveDiscoveryClientAutoConfiguration; +import org.springframework.cloud.commons.util.UtilAutoConfiguration; import org.springframework.cloud.kubernetes.client.KubernetesClientAutoConfiguration; +import org.springframework.cloud.kubernetes.commons.KubernetesCommonsAutoConfiguration; import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryClientHealthIndicatorInitializer; import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryPropertiesAutoConfiguration; import org.springframework.cloud.kubernetes.integration.tests.commons.Commons; @@ -38,10 +41,8 @@ import org.springframework.context.annotation.Primary; import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.cloud.kubernetes.client.discovery.TestUtils.assertNonSelectiveNamespacesBeansMissing; -import static org.springframework.cloud.kubernetes.client.discovery.TestUtils.assertNonSelectiveNamespacesBeansPresent; -import static org.springframework.cloud.kubernetes.client.discovery.TestUtils.assertSelectiveNamespacesBeansMissing; -import static org.springframework.cloud.kubernetes.client.discovery.TestUtils.assertSelectiveNamespacesBeansPresent; +import static org.springframework.cloud.kubernetes.client.discovery.TestUtils.assertInformerBeansMissing; +import static org.springframework.cloud.kubernetes.client.discovery.TestUtils.assertInformerBeansPresent; /** * Test various conditionals for @@ -62,16 +63,20 @@ static void afterAll() { @Test void discoveryEnabledDefault() { - setup("spring.main.cloud-platform=KUBERNETES", "spring.cloud.config.enabled=false"); + setup("spring.main.cloud-platform=KUBERNETES", "spring.cloud.config.enabled=false", + "spring.cloud.kubernetes.client.namespace=default"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).doesNotHaveBean(KubernetesClientInformerReactiveDiscoveryClient.class); + assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); - assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); + assertThat(context).getBeans(KubernetesDiscoveryClientHealthIndicatorInitializer.class).hasSize(2); + assertThat(context).getBeans(ReactiveDiscoveryClientHealthIndicator.class).hasSize(2); + // ours + assertThat(context).hasBean("kubernetesReactiveDiscoveryClientHealthIndicator"); + // from commons, not ours + assertThat(context).hasBean("simpleReactiveDiscoveryClientHealthIndicator"); - assertNonSelectiveNamespacesBeansPresent(context); - assertSelectiveNamespacesBeansMissing(context); + assertInformerBeansPresent(context, 1); }); } @@ -81,29 +86,36 @@ void discoveryEnabledDefaultWithSelectiveNamespaces() { "spring.cloud.kubernetes.discovery.namespaces=a,b,c"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).doesNotHaveBean(KubernetesClientInformerReactiveDiscoveryClient.class); + assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); - assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); + assertThat(context).getBeans(KubernetesDiscoveryClientHealthIndicatorInitializer.class).hasSize(2); + assertThat(context).getBeans(ReactiveDiscoveryClientHealthIndicator.class).hasSize(2); + // ours + assertThat(context).hasBean("kubernetesReactiveDiscoveryClientHealthIndicator"); + // from commons, not ours + assertThat(context).hasBean("simpleReactiveDiscoveryClientHealthIndicator"); - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansPresent(context, 3); + // 3 namespaces + assertInformerBeansPresent(context, 3); }); } @Test void discoveryEnabled() { setup("spring.main.cloud-platform=KUBERNETES", "spring.cloud.config.enabled=false", - "spring.cloud.discovery.enabled=true"); + "spring.cloud.discovery.enabled=true", "spring.cloud.kubernetes.client.namespace=default"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).doesNotHaveBean(KubernetesClientInformerReactiveDiscoveryClient.class); + assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); - assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); + assertThat(context).getBeans(KubernetesDiscoveryClientHealthIndicatorInitializer.class).hasSize(2); + assertThat(context).getBeans(ReactiveDiscoveryClientHealthIndicator.class).hasSize(2); + // ours + assertThat(context).hasBean("kubernetesReactiveDiscoveryClientHealthIndicator"); + // from commons, not ours + assertThat(context).hasBean("simpleReactiveDiscoveryClientHealthIndicator"); - assertNonSelectiveNamespacesBeansPresent(context); - assertSelectiveNamespacesBeansMissing(context); + assertInformerBeansPresent(context, 1); }); } @@ -113,13 +125,16 @@ void discoveryEnabledWithSelectiveNamespaces() { "spring.cloud.discovery.enabled=true", "spring.cloud.kubernetes.discovery.namespaces=a,b"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).doesNotHaveBean(KubernetesClientInformerReactiveDiscoveryClient.class); - - assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); - - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansPresent(context, 2); + assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); + + assertThat(context).getBeans(KubernetesDiscoveryClientHealthIndicatorInitializer.class).hasSize(2); + // reactive only present + assertThat(context).hasBean("reactiveIndicatorInitializer"); + assertThat(context).getBeans(ReactiveDiscoveryClientHealthIndicator.class).hasSize(2); + // ours + assertThat(context).hasBean("kubernetesReactiveDiscoveryClientHealthIndicator"); + // from commons, not ours + assertThat(context).hasBean("simpleReactiveDiscoveryClientHealthIndicator"); }); } @@ -134,8 +149,7 @@ void discoveryDisabled() { assertThat(context).doesNotHaveBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansMissing(context); + assertInformerBeansMissing(context); }); } @@ -150,24 +164,22 @@ void discoveryDisabledWithSelectiveNamespaces() { assertThat(context).doesNotHaveBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansMissing(context); + assertInformerBeansMissing(context); }); } @Test void kubernetesDiscoveryEnabled() { setup("spring.main.cloud-platform=KUBERNETES", "spring.cloud.config.enabled=false", - "spring.cloud.kubernetes.discovery.enabled=true"); + "spring.cloud.kubernetes.discovery.enabled=true", "spring.cloud.kubernetes.client.namespace=default"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).doesNotHaveBean(KubernetesClientInformerReactiveDiscoveryClient.class); + assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); - assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); + assertThat(context).getBeans(KubernetesDiscoveryClientHealthIndicatorInitializer.class).hasSize(2); + assertThat(context).getBeans(ReactiveDiscoveryClientHealthIndicator.class).hasSize(2); - assertNonSelectiveNamespacesBeansPresent(context); - assertSelectiveNamespacesBeansMissing(context); + assertInformerBeansPresent(context, 1); }); } @@ -178,13 +190,16 @@ void kubernetesDiscoveryEnabledWithSelectiveNamespaces() { "spring.cloud.kubernetes.discovery.namespaces=a,b,c,d"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).doesNotHaveBean(KubernetesClientInformerReactiveDiscoveryClient.class); + assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); - assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); + assertThat(context).getBeans(KubernetesDiscoveryClientHealthIndicatorInitializer.class).hasSize(2); + assertThat(context).getBeans(ReactiveDiscoveryClientHealthIndicator.class).hasSize(2); + // ours + assertThat(context).hasBean("kubernetesReactiveDiscoveryClientHealthIndicator"); + // from commons, not ours + assertThat(context).hasBean("simpleReactiveDiscoveryClientHealthIndicator"); - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansPresent(context, 4); + assertInformerBeansPresent(context, 4); }); } @@ -197,10 +212,11 @@ void kubernetesDiscoveryDisabled() { assertThat(context).doesNotHaveBean(KubernetesClientInformerReactiveDiscoveryClient.class); assertThat(context).doesNotHaveBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); + assertThat(context).hasSingleBean(ReactiveDiscoveryClientHealthIndicator.class); + // not ours, but form commons + assertThat(context).hasBean("simpleReactiveDiscoveryClientHealthIndicator"); - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansMissing(context); + assertInformerBeansMissing(context); }); } @@ -214,26 +230,29 @@ void kubernetesDiscoveryDisabledWithSelectiveNamespaces() { assertThat(context).doesNotHaveBean(KubernetesClientInformerReactiveDiscoveryClient.class); assertThat(context).doesNotHaveBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); + // simpleReactiveDiscoveryClientHealthIndicator + assertThat(context).hasSingleBean(ReactiveDiscoveryClientHealthIndicator.class); - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansMissing(context); + assertInformerBeansMissing(context); }); } @Test void kubernetesDiscoveryBlockingEnabled() { setup("spring.main.cloud-platform=KUBERNETES", "spring.cloud.config.enabled=false", - "spring.cloud.discovery.blocking.enabled=true"); + "spring.cloud.discovery.blocking.enabled=true", "spring.cloud.kubernetes.client.namespace=default"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).doesNotHaveBean(KubernetesClientInformerReactiveDiscoveryClient.class); + assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); - assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); + assertThat(context).getBeans(KubernetesDiscoveryClientHealthIndicatorInitializer.class).hasSize(2); + assertThat(context).getBeans(ReactiveDiscoveryClientHealthIndicator.class).hasSize(2); + // ours + assertThat(context).hasBean("kubernetesReactiveDiscoveryClientHealthIndicator"); + // from commons, not ours + assertThat(context).hasBean("simpleReactiveDiscoveryClientHealthIndicator"); - assertNonSelectiveNamespacesBeansPresent(context); - assertSelectiveNamespacesBeansMissing(context); + assertInformerBeansPresent(context, 1); }); } @@ -243,29 +262,37 @@ void kubernetesDiscoveryBlockingEnabledWithSelectiveNamespaces() { "spring.cloud.discovery.blocking.enabled=true", "spring.cloud.kubernetes.discovery.namespaces=a"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).doesNotHaveBean(KubernetesClientInformerReactiveDiscoveryClient.class); + assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); - assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); + assertThat(context).getBeans(KubernetesDiscoveryClientHealthIndicatorInitializer.class).hasSize(2); + assertThat(context).getBeans(ReactiveDiscoveryClientHealthIndicator.class).hasSize(2); + // ours + assertThat(context).hasBean("kubernetesReactiveDiscoveryClientHealthIndicator"); + // from commons, not ours + assertThat(context).hasBean("simpleReactiveDiscoveryClientHealthIndicator"); - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansPresent(context, 1); + assertInformerBeansPresent(context, 1); }); } @Test void kubernetesDiscoveryBlockingDisabled() { setup("spring.main.cloud-platform=KUBERNETES", "spring.cloud.config.enabled=false", - "spring.cloud.discovery.blocking.enabled=false"); + "spring.cloud.discovery.blocking.enabled=false", "spring.cloud.kubernetes.client.namespace=default"); applicationContextRunner.run(context -> { - assertThat(context).doesNotHaveBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).doesNotHaveBean(KubernetesClientInformerReactiveDiscoveryClient.class); + assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); + // only the implementation for the reactive + assertThat(context).hasBean("kubernetesClientInformerDiscoveryClientForReactiveImplementation"); + assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); - assertThat(context).doesNotHaveBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); + assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); + assertThat(context).getBeans(ReactiveDiscoveryClientHealthIndicator.class).hasSize(2); + // ours + assertThat(context).hasBean("kubernetesReactiveDiscoveryClientHealthIndicator"); + // from commons, not ours + assertThat(context).hasBean("simpleReactiveDiscoveryClientHealthIndicator"); - assertNonSelectiveNamespacesBeansPresent(context); - assertSelectiveNamespacesBeansMissing(context); + assertInformerBeansPresent(context, 1); }); } @@ -274,30 +301,39 @@ void kubernetesDiscoveryBlockingDisabledWithSelectiveNamespaces() { setup("spring.main.cloud-platform=KUBERNETES", "spring.cloud.config.enabled=false", "spring.cloud.discovery.blocking.enabled=false", "spring.cloud.kubernetes.discovery.namespaces=a,b"); applicationContextRunner.run(context -> { - assertThat(context).doesNotHaveBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).doesNotHaveBean(KubernetesClientInformerReactiveDiscoveryClient.class); + assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); + // only the implementation for the reactive + assertThat(context).hasBean("kubernetesClientInformerDiscoveryClientForReactiveImplementation"); + assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); - assertThat(context).doesNotHaveBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); + assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); + assertThat(context).getBeans(ReactiveDiscoveryClientHealthIndicator.class).hasSize(2); + // ours + assertThat(context).hasBean("kubernetesReactiveDiscoveryClientHealthIndicator"); + // from commons, not ours + assertThat(context).hasBean("simpleReactiveDiscoveryClientHealthIndicator"); - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansPresent(context, 2); + assertInformerBeansPresent(context, 2); }); } @Test void kubernetesDiscoveryHealthIndicatorEnabled() { setup("spring.main.cloud-platform=KUBERNETES", "spring.cloud.config.enabled=false", - "spring.cloud.discovery.client.health-indicator.enabled=true"); + "spring.cloud.discovery.client.health-indicator.enabled=true", + "spring.cloud.kubernetes.client.namespace=default"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).doesNotHaveBean(KubernetesClientInformerReactiveDiscoveryClient.class); + assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); - assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); + assertThat(context).getBeans(KubernetesDiscoveryClientHealthIndicatorInitializer.class).hasSize(2); + assertThat(context).getBeans(ReactiveDiscoveryClientHealthIndicator.class).hasSize(2); + // ours + assertThat(context).hasBean("kubernetesReactiveDiscoveryClientHealthIndicator"); + // from commons, not ours + assertThat(context).hasBean("simpleReactiveDiscoveryClientHealthIndicator"); - assertNonSelectiveNamespacesBeansPresent(context); - assertSelectiveNamespacesBeansMissing(context); + assertInformerBeansPresent(context, 1); }); } @@ -308,29 +344,32 @@ void kubernetesDiscoveryHealthIndicatorEnabledWithSelectiveNamespaces() { "spring.cloud.kubernetes.discovery.namespaces=b"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).doesNotHaveBean(KubernetesClientInformerReactiveDiscoveryClient.class); + assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); - assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); + assertThat(context).getBeans(KubernetesDiscoveryClientHealthIndicatorInitializer.class).hasSize(2); + assertThat(context).getBeans(ReactiveDiscoveryClientHealthIndicator.class).hasSize(2); + // ours + assertThat(context).hasBean("kubernetesReactiveDiscoveryClientHealthIndicator"); + // from commons, not ours + assertThat(context).hasBean("simpleReactiveDiscoveryClientHealthIndicator"); - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansPresent(context, 1); + assertInformerBeansPresent(context, 1); }); } @Test void kubernetesDiscoveryHealthIndicatorDisabled() { setup("spring.main.cloud-platform=KUBERNETES", "spring.cloud.config.enabled=false", - "spring.cloud.discovery.client.health-indicator.enabled=false"); + "spring.cloud.discovery.client.health-indicator.enabled=false", + "spring.cloud.kubernetes.client.namespace=default"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).doesNotHaveBean(KubernetesClientInformerReactiveDiscoveryClient.class); + assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); assertThat(context).doesNotHaveBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); - assertNonSelectiveNamespacesBeansPresent(context); - assertSelectiveNamespacesBeansMissing(context); + assertInformerBeansPresent(context, 1); }); } @@ -341,29 +380,34 @@ void kubernetesDiscoveryHealthIndicatorDisabledWithSelectiveNamespaces() { "spring.cloud.kubernetes.discovery.namespaces=b"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).doesNotHaveBean(KubernetesClientInformerReactiveDiscoveryClient.class); + assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); assertThat(context).doesNotHaveBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansPresent(context, 1); + assertInformerBeansPresent(context, 1); }); } @Test void kubernetesDiscoveryHealthIndicatorEnabledHealthIndicatorMissing() { setupWithFilteredClassLoader(HealthIndicator.class, "spring.main.cloud-platform=KUBERNETES", - "spring.cloud.config.enabled=false", "spring.cloud.discovery.client.health-indicator.enabled=true"); + "spring.cloud.config.enabled=false", "spring.cloud.discovery.client.health-indicator.enabled=true", + "spring.cloud.kubernetes.client.namespace=default"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).doesNotHaveBean(KubernetesClientInformerReactiveDiscoveryClient.class); - - assertThat(context).doesNotHaveBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); + assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); - assertNonSelectiveNamespacesBeansPresent(context); - assertSelectiveNamespacesBeansMissing(context); + assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); + // reactive only present + assertThat(context).hasBean("reactiveIndicatorInitializer"); + assertThat(context).getBeans(ReactiveDiscoveryClientHealthIndicator.class).hasSize(2); + // ours + assertThat(context).hasBean("kubernetesReactiveDiscoveryClientHealthIndicator"); + // from commons, not ours + assertThat(context).hasBean("simpleReactiveDiscoveryClientHealthIndicator"); + + assertInformerBeansPresent(context, 1); }); } @@ -374,13 +418,17 @@ void kubernetesDiscoveryHealthIndicatorEnabledHealthIndicatorMissingWithSelectiv "spring.cloud.kubernetes.discovery.namespaces=a,b,c,d,e"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).doesNotHaveBean(KubernetesClientInformerReactiveDiscoveryClient.class); + assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); - assertThat(context).doesNotHaveBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); - - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansPresent(context, 5); + assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); + assertThat(context).hasBean("reactiveIndicatorInitializer"); + assertThat(context).getBeans(ReactiveDiscoveryClientHealthIndicator.class).hasSize(2); + // ours + assertThat(context).hasBean("kubernetesReactiveDiscoveryClientHealthIndicator"); + // from commons, not ours + assertThat(context).hasBean("simpleReactiveDiscoveryClientHealthIndicator"); + + assertInformerBeansPresent(context, 5); }); } @@ -390,7 +438,7 @@ void kubernetesDiscoveryHealthIndicatorEnabledHealthIndicatorMissingWithSelectiv @Test void reactiveDisabled() { setup("spring.main.cloud-platform=KUBERNETES", "spring.cloud.config.enabled=false", - "spring.cloud.discovery.reactive.enabled=false"); + "spring.cloud.discovery.reactive.enabled=false", "spring.cloud.kubernetes.client.namespace=default"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); assertThat(context).doesNotHaveBean(KubernetesClientInformerReactiveDiscoveryClient.class); @@ -398,8 +446,7 @@ void reactiveDisabled() { assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); - assertNonSelectiveNamespacesBeansPresent(context); - assertSelectiveNamespacesBeansMissing(context); + assertInformerBeansPresent(context, 1); }); } @@ -418,31 +465,37 @@ void reactiveDisabledWithSelectiveNamespaces() { assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansPresent(context, 5); + assertInformerBeansPresent(context, 5); }); } private void setup(String... properties) { applicationContextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(KubernetesClientInformerDiscoveryClientAutoConfiguration.class, - KubernetesClientAutoConfiguration.class, KubernetesDiscoveryPropertiesAutoConfiguration.class, + .withConfiguration(AutoConfigurations.of( + KubernetesClientInformerReactiveDiscoveryClientAutoConfiguration.class, + KubernetesClientAutoConfiguration.class, SimpleReactiveDiscoveryClientAutoConfiguration.class, + UtilAutoConfiguration.class, KubernetesDiscoveryPropertiesAutoConfiguration.class, KubernetesClientInformerAutoConfiguration.class, - KubernetesClientInformerSelectiveNamespacesAutoConfiguration.class, + KubernetesClientInformerDiscoveryClientAutoConfiguration.class, + KubernetesCommonsAutoConfiguration.class, KubernetesClientDiscoveryClientSpelAutoConfiguration.class)) - .withUserConfiguration(ApiClientConfig.class) + .withUserConfiguration( + KubernetesClientInformerDiscoveryClientAutoConfigurationApplicationContextTests.ApiClientConfig.class) .withPropertyValues(properties); } private void setupWithFilteredClassLoader(Class cls, String... properties) { applicationContextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(KubernetesClientInformerDiscoveryClientAutoConfiguration.class, - KubernetesClientAutoConfiguration.class, KubernetesDiscoveryPropertiesAutoConfiguration.class, - KubernetesClientInformerAutoConfiguration.class, - KubernetesClientInformerSelectiveNamespacesAutoConfiguration.class, + .withConfiguration(AutoConfigurations.of( + KubernetesClientInformerReactiveDiscoveryClientAutoConfiguration.class, + KubernetesClientAutoConfiguration.class, SimpleReactiveDiscoveryClientAutoConfiguration.class, + UtilAutoConfiguration.class, KubernetesDiscoveryPropertiesAutoConfiguration.class, + KubernetesCommonsAutoConfiguration.class, KubernetesClientInformerAutoConfiguration.class, + KubernetesClientInformerDiscoveryClientAutoConfiguration.class, KubernetesClientDiscoveryClientSpelAutoConfiguration.class)) + .withUserConfiguration( + KubernetesClientInformerDiscoveryClientAutoConfigurationApplicationContextTests.ApiClientConfig.class) .withClassLoader(new FilteredClassLoader(cls)) - .withUserConfiguration(ApiClientConfig.class) .withPropertyValues(properties); } diff --git a/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerReactiveDiscoveryClientAutoConfigurationApplicationContextTests.java b/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerReactiveDiscoveryClientAutoConfigurationApplicationContextTests.java index 4a3ce1920e..b416b6db0b 100644 --- a/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerReactiveDiscoveryClientAutoConfigurationApplicationContextTests.java +++ b/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerReactiveDiscoveryClientAutoConfigurationApplicationContextTests.java @@ -40,10 +40,8 @@ import org.springframework.context.annotation.Primary; import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.cloud.kubernetes.client.discovery.TestUtils.assertNonSelectiveNamespacesBeansMissing; -import static org.springframework.cloud.kubernetes.client.discovery.TestUtils.assertNonSelectiveNamespacesBeansPresent; -import static org.springframework.cloud.kubernetes.client.discovery.TestUtils.assertSelectiveNamespacesBeansMissing; -import static org.springframework.cloud.kubernetes.client.discovery.TestUtils.assertSelectiveNamespacesBeansPresent; +import static org.springframework.cloud.kubernetes.client.discovery.TestUtils.assertInformerBeansMissing; +import static org.springframework.cloud.kubernetes.client.discovery.TestUtils.assertInformerBeansPresent; /** * Test various conditionals for @@ -64,19 +62,17 @@ static void afterAll() { @Test void discoveryEnabledDefault() { - setup("spring.main.cloud-platform=KUBERNETES", "spring.cloud.config.enabled=false"); + setup("spring.main.cloud-platform=KUBERNETES", "spring.cloud.config.enabled=false", + "spring.cloud.kubernetes.client.namespace=default"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).hasBean("kubernetesClientInformerDiscoveryClient"); assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); // simple from commons and ours assertThat(context).getBeans(ReactiveDiscoveryClientHealthIndicator.class).hasSize(2); - assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).hasBean("reactiveIndicatorInitializer"); + assertThat(context).getBeans(KubernetesDiscoveryClientHealthIndicatorInitializer.class).hasSize(2); - assertNonSelectiveNamespacesBeansPresent(context); - assertSelectiveNamespacesBeansMissing(context); + assertInformerBeansPresent(context, 1); }); } @@ -86,35 +82,29 @@ void discoveryEnabledDefaultWithSelectiveNamespaces() { "spring.cloud.kubernetes.discovery.namespaces=a,b,c"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).hasBean("selectiveNamespacesKubernetesClientInformerDiscoveryClient"); assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); // simple from commons and ours assertThat(context).getBeans(ReactiveDiscoveryClientHealthIndicator.class).hasSize(2); - assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).hasBean("reactiveIndicatorInitializer"); + assertThat(context).getBeans(KubernetesDiscoveryClientHealthIndicatorInitializer.class).hasSize(2); - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansPresent(context, 3); + assertInformerBeansPresent(context, 3); }); } @Test void discoveryEnabled() { setup("spring.main.cloud-platform=KUBERNETES", "spring.cloud.config.enabled=false", - "spring.cloud.discovery.enabled=true"); + "spring.cloud.discovery.enabled=true", "spring.cloud.kubernetes.client.namespace=default"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).hasBean("kubernetesClientInformerDiscoveryClient"); assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); // simple from commons and ours assertThat(context).getBeans(ReactiveDiscoveryClientHealthIndicator.class).hasSize(2); - assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).hasBean("reactiveIndicatorInitializer"); + assertThat(context).getBeans(KubernetesDiscoveryClientHealthIndicatorInitializer.class).hasSize(2); - assertNonSelectiveNamespacesBeansPresent(context); - assertSelectiveNamespacesBeansMissing(context); + assertInformerBeansPresent(context, 1); }); } @@ -124,16 +114,13 @@ void discoveryEnabledWithSelectiveNamespaces() { "spring.cloud.discovery.enabled=true", "spring.cloud.kubernetes.discovery.namespaces=a,b,c"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).hasBean("selectiveNamespacesKubernetesClientInformerDiscoveryClient"); assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); // simple from commons and ours assertThat(context).getBeans(ReactiveDiscoveryClientHealthIndicator.class).hasSize(2); - assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).hasBean("reactiveIndicatorInitializer"); + assertThat(context).getBeans(KubernetesDiscoveryClientHealthIndicatorInitializer.class).hasSize(2); - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansPresent(context, 3); + assertInformerBeansPresent(context, 3); }); } @@ -148,8 +135,7 @@ void discoveryDisabled() { assertThat(context).doesNotHaveBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansMissing(context); + assertInformerBeansMissing(context); }); } @@ -164,27 +150,23 @@ void discoveryDisabledWithSelectiveNamespaces() { assertThat(context).doesNotHaveBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansMissing(context); + assertInformerBeansMissing(context); }); } @Test void kubernetesDiscoveryEnabled() { setup("spring.main.cloud-platform=KUBERNETES", "spring.cloud.config.enabled=false", - "spring.cloud.kubernetes.discovery.enabled=true"); + "spring.cloud.kubernetes.discovery.enabled=true", "spring.cloud.kubernetes.client.namespace=default"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).hasBean("kubernetesClientInformerDiscoveryClient"); assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); // simple from commons and ours assertThat(context).getBeans(ReactiveDiscoveryClientHealthIndicator.class).hasSize(2); - assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).hasBean("reactiveIndicatorInitializer"); + assertThat(context).getBeans(KubernetesDiscoveryClientHealthIndicatorInitializer.class).hasSize(2); - assertNonSelectiveNamespacesBeansPresent(context); - assertSelectiveNamespacesBeansMissing(context); + assertInformerBeansPresent(context, 1); }); } @@ -194,16 +176,13 @@ void kubernetesDiscoveryEnabledWithSelectiveNamespaces() { "spring.cloud.kubernetes.discovery.enabled=true", "spring.cloud.kubernetes.discovery.namespaces=a,b"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).hasBean("selectiveNamespacesKubernetesClientInformerDiscoveryClient"); assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); // simple from commons and ours assertThat(context).getBeans(ReactiveDiscoveryClientHealthIndicator.class).hasSize(2); - assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).hasBean("reactiveIndicatorInitializer"); + assertThat(context).getBeans(KubernetesDiscoveryClientHealthIndicatorInitializer.class).hasSize(2); - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansPresent(context, 2); + assertInformerBeansPresent(context, 2); }); } @@ -219,8 +198,7 @@ void kubernetesDiscoveryDisabled() { // only "simple" one from commons, as ours is not picked up assertThat(context).hasSingleBean(ReactiveDiscoveryClientHealthIndicator.class); - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansMissing(context); + assertInformerBeansMissing(context); }); } @@ -236,27 +214,24 @@ void kubernetesDiscoveryDisabledWithSelectiveNamespaces() { // only "simple" one from commons, as ours is not picked up assertThat(context).hasSingleBean(ReactiveDiscoveryClientHealthIndicator.class); - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansMissing(context); + // we don't read the KubernetesClientInformerAutoConfiguration + assertInformerBeansMissing(context); }); } @Test void kubernetesReactiveDiscoveryEnabled() { setup("spring.main.cloud-platform=KUBERNETES", "spring.cloud.config.enabled=false", - "spring.cloud.discovery.reactive.enabled=true"); + "spring.cloud.discovery.reactive.enabled=true", "spring.cloud.kubernetes.client.namespace=default"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).hasBean("kubernetesClientInformerDiscoveryClient"); assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); // simple from commons and ours assertThat(context).getBeans(ReactiveDiscoveryClientHealthIndicator.class).hasSize(2); - assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).hasBean("reactiveIndicatorInitializer"); + assertThat(context).getBeans(KubernetesDiscoveryClientHealthIndicatorInitializer.class).hasSize(2); - assertNonSelectiveNamespacesBeansPresent(context); - assertSelectiveNamespacesBeansMissing(context); + assertInformerBeansPresent(context, 1); }); } @@ -266,32 +241,28 @@ void kubernetesReactiveDiscoveryEnabledWithSelectiveNamespaces() { "spring.cloud.discovery.reactive.enabled=true", "spring.cloud.kubernetes.discovery.namespaces=a,b"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).hasBean("selectiveNamespacesKubernetesClientInformerDiscoveryClient"); assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); // simple from commons and ours assertThat(context).getBeans(ReactiveDiscoveryClientHealthIndicator.class).hasSize(2); - assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).hasBean("reactiveIndicatorInitializer"); + assertThat(context).getBeans(KubernetesDiscoveryClientHealthIndicatorInitializer.class).hasSize(2); - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansPresent(context, 2); + assertInformerBeansPresent(context, 2); }); } @Test void kubernetesReactiveDiscoveryDisabled() { setup("spring.main.cloud-platform=KUBERNETES", "spring.cloud.config.enabled=false", - "spring.cloud.discovery.reactive.enabled=false"); + "spring.cloud.discovery.reactive.enabled=false", "spring.cloud.kubernetes.client.namespace=default"); applicationContextRunner.run(context -> { - assertThat(context).doesNotHaveBean(KubernetesClientInformerDiscoveryClient.class); + assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); assertThat(context).doesNotHaveBean(KubernetesClientInformerReactiveDiscoveryClient.class); assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); - assertThat(context).doesNotHaveBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); + assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertNonSelectiveNamespacesBeansPresent(context); - assertSelectiveNamespacesBeansMissing(context); + assertInformerBeansPresent(context, 1); }); } @@ -300,14 +271,13 @@ void kubernetesReactiveDiscoveryDisabledWithSelectiveNamespaces() { setup("spring.main.cloud-platform=KUBERNETES", "spring.cloud.config.enabled=false", "spring.cloud.discovery.reactive.enabled=false", "spring.cloud.kubernetes.discovery.namespaces=a,b"); applicationContextRunner.run(context -> { - assertThat(context).doesNotHaveBean(KubernetesClientInformerDiscoveryClient.class); + assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); assertThat(context).doesNotHaveBean(KubernetesClientInformerReactiveDiscoveryClient.class); assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); - assertThat(context).doesNotHaveBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); + assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansPresent(context, 2); + assertInformerBeansPresent(context, 2); }); } @@ -317,19 +287,18 @@ void kubernetesReactiveDiscoveryDisabledWithSelectiveNamespaces() { @Test void blockingDisabled() { setup("spring.main.cloud-platform=KUBERNETES", "spring.cloud.config.enabled=false", - "spring.cloud.discovery.blocking.enabled=false"); + "spring.cloud.discovery.blocking.enabled=false", "spring.cloud.kubernetes.client.namespace=default"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).hasBean("kubernetesClientInformerDiscoveryClient"); + // only the implementation for the reactive + assertThat(context).hasBean("kubernetesClientInformerDiscoveryClientForReactiveImplementation"); assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); // simple from commons and ours assertThat(context).getBeans(ReactiveDiscoveryClientHealthIndicator.class).hasSize(2); assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertThat(context).hasBean("reactiveIndicatorInitializer"); - assertNonSelectiveNamespacesBeansPresent(context); - assertSelectiveNamespacesBeansMissing(context); + assertInformerBeansPresent(context, 1); }); } @@ -342,7 +311,8 @@ void blockingDisabledWithSelectiveNamespaces() { "spring.cloud.discovery.blocking.enabled=false", "spring.cloud.kubernetes.discovery.namespaces=a,b"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).hasBean("selectiveNamespacesKubernetesClientInformerDiscoveryClient"); + // only the implementation for the reactive + assertThat(context).hasBean("kubernetesClientInformerDiscoveryClientForReactiveImplementation"); assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); // simple from commons and ours @@ -350,25 +320,23 @@ void blockingDisabledWithSelectiveNamespaces() { assertThat(context).hasSingleBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); assertThat(context).hasBean("reactiveIndicatorInitializer"); - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansPresent(context, 2); + assertInformerBeansPresent(context, 2); }); } @Test void healthDisabled() { setup("spring.main.cloud-platform=KUBERNETES", "spring.cloud.config.enabled=false", - "spring.cloud.discovery.client.health-indicator.enabled=false"); + "spring.cloud.discovery.client.health-indicator.enabled=false", + "spring.cloud.kubernetes.client.namespace=default"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).hasBean("kubernetesClientInformerDiscoveryClient"); assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); assertThat(context).doesNotHaveBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertNonSelectiveNamespacesBeansPresent(context); - assertSelectiveNamespacesBeansMissing(context); + assertInformerBeansPresent(context, 1); }); } @@ -379,14 +347,12 @@ void healthDisabledWithSelectiveNamespaces() { "spring.cloud.kubernetes.discovery.namespaces=a,b"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).hasBean("selectiveNamespacesKubernetesClientInformerDiscoveryClient"); assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); assertThat(context).doesNotHaveBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansPresent(context, 2); + assertInformerBeansPresent(context, 2); }); } @@ -394,17 +360,16 @@ void healthDisabledWithSelectiveNamespaces() { void healthEnabledClassNotPresent() { setupWithFilteredClassLoader("org.springframework.boot.health.contributor.ReactiveHealthIndicator", "spring.main.cloud-platform=KUBERNETES", "spring.cloud.config.enabled=false", - "spring.cloud.discovery.client.health-indicator.enabled=false"); + "spring.cloud.discovery.client.health-indicator.enabled=false", + "spring.cloud.kubernetes.client.namespace=default"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).hasBean("kubernetesClientInformerDiscoveryClient"); assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); assertThat(context).doesNotHaveBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertNonSelectiveNamespacesBeansPresent(context); - assertSelectiveNamespacesBeansMissing(context); + assertInformerBeansPresent(context, 1); }); } @@ -416,14 +381,12 @@ void healthEnabledClassNotPresentWithSelectiveNamespaces() { "spring.cloud.kubernetes.discovery.namespaces=a,b"); applicationContextRunner.run(context -> { assertThat(context).hasSingleBean(KubernetesClientInformerDiscoveryClient.class); - assertThat(context).hasBean("selectiveNamespacesKubernetesClientInformerDiscoveryClient"); assertThat(context).hasSingleBean(KubernetesClientInformerReactiveDiscoveryClient.class); assertThat(context).doesNotHaveBean(ReactiveDiscoveryClientHealthIndicator.class); assertThat(context).doesNotHaveBean(KubernetesDiscoveryClientHealthIndicatorInitializer.class); - assertNonSelectiveNamespacesBeansMissing(context); - assertSelectiveNamespacesBeansPresent(context, 2); + assertInformerBeansPresent(context, 2); }); } @@ -433,8 +396,9 @@ private void setup(String... properties) { KubernetesClientInformerReactiveDiscoveryClientAutoConfiguration.class, KubernetesClientAutoConfiguration.class, SimpleReactiveDiscoveryClientAutoConfiguration.class, UtilAutoConfiguration.class, KubernetesDiscoveryPropertiesAutoConfiguration.class, - KubernetesClientInformerSelectiveNamespacesAutoConfiguration.class, - KubernetesCommonsAutoConfiguration.class, KubernetesClientInformerAutoConfiguration.class, + KubernetesClientInformerAutoConfiguration.class, + KubernetesClientInformerDiscoveryClientAutoConfiguration.class, + KubernetesCommonsAutoConfiguration.class, KubernetesClientDiscoveryClientSpelAutoConfiguration.class)) .withUserConfiguration(ApiClientConfig.class) .withPropertyValues(properties); @@ -446,8 +410,8 @@ private void setupWithFilteredClassLoader(String name, String... properties) { KubernetesClientInformerReactiveDiscoveryClientAutoConfiguration.class, KubernetesClientAutoConfiguration.class, SimpleReactiveDiscoveryClientAutoConfiguration.class, UtilAutoConfiguration.class, KubernetesDiscoveryPropertiesAutoConfiguration.class, - KubernetesClientInformerSelectiveNamespacesAutoConfiguration.class, KubernetesCommonsAutoConfiguration.class, KubernetesClientInformerAutoConfiguration.class, + KubernetesClientInformerDiscoveryClientAutoConfiguration.class, KubernetesClientDiscoveryClientSpelAutoConfiguration.class)) .withUserConfiguration(ApiClientConfig.class) .withClassLoader(new FilteredClassLoader(name)) diff --git a/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerSelectiveNamespacesAutoConfigurationTests.java b/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerSelectiveNamespacesAutoConfigurationTests.java deleted file mode 100644 index 2406a6d425..0000000000 --- a/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/KubernetesClientInformerSelectiveNamespacesAutoConfigurationTests.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2019-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.kubernetes.client.discovery; - -import java.util.List; -import java.util.Set; - -import io.kubernetes.client.openapi.ApiClient; -import org.assertj.core.api.Assertions; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mockito; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.boot.test.system.CapturedOutput; -import org.springframework.boot.test.system.OutputCaptureExtension; -import org.springframework.cloud.kubernetes.commons.discovery.KubernetesDiscoveryProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author wind57 - */ -@ExtendWith(OutputCaptureExtension.class) -class KubernetesClientInformerSelectiveNamespacesAutoConfigurationTests { - - private static final String NAMESPACE_A = "a"; - - private static final String NAMESPACE_B = "b"; - - private static final String NAMESPACE_C = "c"; - - private static final String NAMESPACE_D = "d"; - - @Test - void testBeansCreates(CapturedOutput output) { - - new ApplicationContextRunner() - .withPropertyValues("spring.cloud.discovery.enabled=true", "spring.cloud.kubernetes.discovery.enabled=true", - "spring.cloud.kubernetes.discovery.namespaces[0]=" + NAMESPACE_A, - "spring.cloud.kubernetes.discovery.namespaces[1]=" + NAMESPACE_B, - "spring.main.cloud-platform=kubernetes") - .withConfiguration( - AutoConfigurations.of(KubernetesClientInformerSelectiveNamespacesAutoConfiguration.class)) - .withUserConfiguration(Config.class) - .run(context -> { - assertThat(context.getBean("selectiveNamespaces")).isNotNull(); - - @SuppressWarnings("unchecked") - Set selectiveNamespaces = context.getBean("selectiveNamespaces", Set.class); - Assertions.assertThat(selectiveNamespaces).isEqualTo(Set.of("a", "b")); - - @SuppressWarnings("unchecked") - Set namespaces = context.getBean("namespaces", Set.class); - Assertions.assertThat(namespaces).isEqualTo(Set.of("c", "d")); - }); - - assertThat(output.getOut().contains("registering lister (for services) in namespace : " + NAMESPACE_A)) - .isTrue(); - assertThat(output.getOut().contains("registering lister (for services) in namespace : " + NAMESPACE_B)) - .isTrue(); - - assertThat(output.getOut().contains("registering lister (for services) in namespace : " + NAMESPACE_C)) - .isFalse(); - assertThat(output.getOut().contains("registering lister (for services) in namespace : " + NAMESPACE_D)) - .isFalse(); - - assertThat(output.getOut().contains("registering lister (for endpoints) in namespace : " + NAMESPACE_A)) - .isTrue(); - assertThat(output.getOut().contains("registering lister (for endpoints) in namespace : " + NAMESPACE_B)) - .isTrue(); - - assertThat(output.getOut().contains("registering lister (for endpoints) in namespace : " + NAMESPACE_C)) - .isFalse(); - assertThat(output.getOut().contains("registering lister (for endpoints) in namespace : " + NAMESPACE_D)) - .isFalse(); - } - - @Configuration - @EnableConfigurationProperties(KubernetesDiscoveryProperties.class) - static class Config { - - @Bean - ApiClient apiClient() { - return Mockito.mock(ApiClient.class); - } - - @Bean - List namespaces() { - return List.of(NAMESPACE_C, NAMESPACE_D); - } - - } - -} diff --git a/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/TestUtils.java b/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/TestUtils.java index 3dd479c40d..4bde1419f3 100644 --- a/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/TestUtils.java +++ b/spring-cloud-kubernetes-client-discovery/src/test/java/org/springframework/cloud/kubernetes/client/discovery/TestUtils.java @@ -35,41 +35,14 @@ * * @author wind57 */ -public final class TestUtils { +final class TestUtils { private TestUtils() { } - public static void assertSelectiveNamespacesBeansMissing(AssertableApplicationContext context) { - String[] sharedInformerFactoriesBeanName = context - .getBeanNamesForType(ResolvableType.forType(new ParameterizedTypeReference>() { - })); - assertThat(sharedInformerFactoriesBeanName).isEmpty(); - - String[] serviceSharedIndexInformersBeanName = context.getBeanNamesForType( - ResolvableType.forType(new ParameterizedTypeReference>>() { - })); - assertThat(serviceSharedIndexInformersBeanName).isEmpty(); - - String[] endpointsSharedIndexInformersBeanName = context.getBeanNamesForType( - ResolvableType.forType(new ParameterizedTypeReference>>() { - })); - assertThat(endpointsSharedIndexInformersBeanName).isEmpty(); - - String[] serviceListersBeanName = context - .getBeanNamesForType(ResolvableType.forType(new ParameterizedTypeReference>>() { - })); - assertThat(serviceListersBeanName).isEmpty(); - - String[] endpointsListersBeanName = context - .getBeanNamesForType(ResolvableType.forType(new ParameterizedTypeReference>>() { - })); - assertThat(endpointsListersBeanName).isEmpty(); - } - @SuppressWarnings("unchecked") - public static void assertSelectiveNamespacesBeansPresent(AssertableApplicationContext context, int times) { + static void assertInformerBeansPresent(AssertableApplicationContext context, int times) { String sharedInformerFactoriesBeanName = context .getBeanNamesForType(ResolvableType.forType(new ParameterizedTypeReference>() { }))[0]; @@ -105,57 +78,31 @@ public static void assertSelectiveNamespacesBeansPresent(AssertableApplicationCo assertThat(endpointsListers.size()).isEqualTo(times); } - @SuppressWarnings("unchecked") - public static void assertNonSelectiveNamespacesBeansPresent(AssertableApplicationContext context) { - assertThat(context).hasSingleBean(SharedInformerFactory.class); - - String serviceSharedIndexInformerBeanName = context.getBeanNamesForType( - ResolvableType.forType(new ParameterizedTypeReference>() { - }))[0]; - SharedIndexInformer serviceSharedIndexInformer = (SharedIndexInformer) context - .getBean(serviceSharedIndexInformerBeanName); - assertThat(serviceSharedIndexInformer).isNotNull(); - - String endpointSharedIndexInformerBeanName = context.getBeanNamesForType( - ResolvableType.forType(new ParameterizedTypeReference>() { - }))[0]; - SharedIndexInformer endpointsSharedIndexInformer = (SharedIndexInformer) context - .getBean(endpointSharedIndexInformerBeanName); - assertThat(endpointsSharedIndexInformer).isNotNull(); - - String serviceListerBeanName = context - .getBeanNamesForType(ResolvableType.forType(new ParameterizedTypeReference>() { - }))[0]; - Lister serviceLister = (Lister) context.getBean(serviceListerBeanName); - assertThat(serviceLister).isNotNull(); - - String endpointsListerBeanName = context - .getBeanNamesForType(ResolvableType.forType(new ParameterizedTypeReference>() { - }))[0]; - Lister endpointsLister = (Lister) context.getBean(endpointsListerBeanName); - assertThat(endpointsLister).isNotNull(); - } + static void assertInformerBeansMissing(AssertableApplicationContext context) { + String[] sharedInformerFactoriesBeanName = context + .getBeanNamesForType(ResolvableType.forType(new ParameterizedTypeReference>() { + })); + assertThat(sharedInformerFactoriesBeanName).isEmpty(); - public static void assertNonSelectiveNamespacesBeansMissing(AssertableApplicationContext context) { - String[] serviceSharedIndexInformerBeanName = context.getBeanNamesForType( - ResolvableType.forType(new ParameterizedTypeReference>() { + String[] serviceSharedIndexInformersBeanName = context.getBeanNamesForType( + ResolvableType.forType(new ParameterizedTypeReference>>() { })); - assertThat(serviceSharedIndexInformerBeanName).isEmpty(); + assertThat(serviceSharedIndexInformersBeanName).isEmpty(); - String[] endpointSharedIndexInformerBeanName = context.getBeanNamesForType( - ResolvableType.forType(new ParameterizedTypeReference>() { + String[] endpointsSharedIndexInformersBeanName = context.getBeanNamesForType( + ResolvableType.forType(new ParameterizedTypeReference>>() { })); - assertThat(endpointSharedIndexInformerBeanName).isEmpty(); + assertThat(endpointsSharedIndexInformersBeanName).isEmpty(); - String[] serviceListerBeanName = context - .getBeanNamesForType(ResolvableType.forType(new ParameterizedTypeReference>() { + String[] serviceListersBeanName = context + .getBeanNamesForType(ResolvableType.forType(new ParameterizedTypeReference>>() { })); - assertThat(serviceListerBeanName).isEmpty(); + assertThat(serviceListersBeanName).isEmpty(); - String[] endpointsListerBeanName = context - .getBeanNamesForType(ResolvableType.forType(new ParameterizedTypeReference>() { + String[] endpointsListersBeanName = context + .getBeanNamesForType(ResolvableType.forType(new ParameterizedTypeReference>>() { })); - assertThat(endpointsListerBeanName).isEmpty(); + assertThat(endpointsListersBeanName).isEmpty(); } } diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/discovery/KubernetesDiscoveryClientHealthConfiguration.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/discovery/KubernetesDiscoveryClientHealthConfiguration.java deleted file mode 100644 index 3b7770a580..0000000000 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/discovery/KubernetesDiscoveryClientHealthConfiguration.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2019-present the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.kubernetes.commons.discovery; - -import org.apache.commons.logging.LogFactory; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.health.contributor.HealthIndicator; -import org.springframework.cloud.client.ConditionalOnDiscoveryHealthIndicatorEnabled; -import org.springframework.cloud.kubernetes.commons.PodUtils; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.log.LogAccessor; - -/** - * @author wind57 - */ -@Configuration -public class KubernetesDiscoveryClientHealthConfiguration { - - private static final LogAccessor LOG = new LogAccessor( - LogFactory.getLog(KubernetesDiscoveryClientHealthConfiguration.class)); - - @Bean - @ConditionalOnClass({ HealthIndicator.class }) - @ConditionalOnDiscoveryHealthIndicatorEnabled - public KubernetesDiscoveryClientHealthIndicatorInitializer indicatorInitializer( - ApplicationEventPublisher applicationEventPublisher, PodUtils podUtils) { - - LOG.debug(() -> "Will publish InstanceRegisteredEvent from blocking implementation"); - return new KubernetesDiscoveryClientHealthIndicatorInitializer(podUtils, applicationEventPublisher); - } - -} diff --git a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientDiscoverySimpleIT.java b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientDiscoverySimpleIT.java index 202de24ba8..bc673b2bda 100644 --- a/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientDiscoverySimpleIT.java +++ b/spring-cloud-kubernetes-integration-tests/spring-cloud-kubernetes-k8s-client-discovery/src/test/java/org/springframework/cloud/kubernetes/k8s/client/discovery/KubernetesClientDiscoverySimpleIT.java @@ -89,7 +89,7 @@ void test(CapturedOutput output) throws Exception { K3S.execInContainer("sh", "-c", "kubectl annotate pods " + both[1].split("/")[1] + " custom-annotation=custom-annotation-value"); - assertLogStatement(output, "using selective namespaces : [default]"); + assertLogStatement(output, "serviceSharedInformers will use selective namespaces : [default]"); List services = discoveryClient.getServices(); List instances = discoveryClient.getInstances("busybox-service");