Use ConfigData To Load Configuration From Kubernetes Instead Of Bootstrap (#1002)

* Use ConfigData to load configuration instead of bootstrap

Co-authored-by: wind57 <eugen.rabii@gmail.com>
This commit is contained in:
Ryan Baxter
2022-05-18 15:48:36 -04:00
committed by GitHub
parent 56fbef5fa6
commit 74a1c9ba2a
153 changed files with 4570 additions and 619 deletions

View File

@@ -14,10 +14,11 @@ that setting via `spring.main.cloud-platform`.
For example, if you need to test some features, but do not want to deploy to a cluster, it is enough to set the:
`spring.main.cloud-platform=KUBERNETES`. This will make `spring-cloud-kubernetes` act as-if it is deployed in a real cluster.
Be aware that when `spring-cloud-kubernetes-config` is on the classpath, `spring.main.cloud-platform` should be set in `bootstrap.{properties|yml}`
(or the profile specific one), otherwise it should be in `application.{properties|yml}` (or the profile specific one).
Also note that these properties: `spring.cloud.kubernetes.config.enabled` and `spring.cloud.kubernetes.secrets.enabled`
only take effect when set in `bootstrap.{properties|yml}`.
NOTE: If you have `spring-cloud-bootstrap-starter` on your classpath or are setting `spring.cloud.bootstrap.enabled=true` then
you will have to set `spring.main.cloud-platform` should be set in `bootstrap.{properties|yml}`
(or the profile specific one). Also note that these properties: `spring.cloud.kubernetes.config.enabled` and `spring.cloud.kubernetes.secrets.enabled`
will only take effect when set in `bootstrap.{properties|yml}` when you have `spring-cloud-bootstrap-starter` on your classpath or are setting `spring.cloud.bootstrap.enabled=true`.
=== Breaking Changes In 3.0.x

View File

@@ -5,18 +5,27 @@ an `application-profile.properties` or `application-profile.yaml` file that cont
application or Spring Boot starters. You can override these properties by specifying system properties or environment
variables.
To enable this functionality you need to set `spring.config.import=kubernetes:` in your application's configuration properties.
Currently you can not specify a ConfigMap or Secret to load using `spring.config.import`, by default Spring Cloud Kubernetes
will load a ConfigMap and/or Secret based on the `spring.application.name` property. If `spring.application.name` is not set it will
load a ConfigMap and/or Secret with the name `application`.
If you would like to load Kubernetes `PropertySource`s during the bootstrap phase like it worked prior to the 3.0.x release
you can either add `spring-cloud-starter-bootstrap` to your application's classpath or set `spring.cloud.bootstrap.enabled=true`
as an environment variable.
[[configmap-propertysource]]
=== Using a `ConfigMap` `PropertySource`
Kubernetes provides a resource named https://kubernetes.io/docs/user-guide/configmap/[`ConfigMap`] to externalize the
parameters to pass to your application in the form of key-value pairs or embedded `application.properties` or `application.yaml` files.
The link:https://github.com/spring-cloud/spring-cloud-kubernetes/tree/master/spring-cloud-kubernetes-fabric8-config[Spring Cloud Kubernetes Config] project makes Kubernetes `ConfigMap` instances available
during application bootstrapping and triggers hot reloading of beans or Spring context when changes are detected on
during application startup and triggers hot reloading of beans or Spring context when changes are detected on
observed `ConfigMap` instances.
The default behavior is to create a `Fabric8ConfigMapPropertySource` based on a Kubernetes `ConfigMap` that has a `metadata.name` value of either the name of
your Spring application (as defined by its `spring.application.name` property) or a custom name defined within the
`bootstrap.properties` file under the following key: `spring.cloud.kubernetes.config.name`.
`application.properties` file under the following key: `spring.cloud.kubernetes.config.name`.
However, more advanced configuration is possible where you can use multiple `ConfigMap` instances.
The `spring.cloud.kubernetes.config.sources` list makes this possible.
@@ -239,8 +248,8 @@ data:
====
To tell Spring Boot which `profile` should be enabled at bootstrap, you can pass `SPRING_PROFILES_ACTIVE` environment variable.
To do so, you can launch your Spring Boot application with an environment variable that you can define it in the PodSpec at the container specification.
To tell Spring Boot which `profile` should be enabled see the https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.profiles[Spring Boot documentation].
One option for activating a specific profile when deploying to Kubernetes is to launch your Spring Boot application with an environment variable that you can define in the PodSpec at the container specification.
Deployment resource file, as follows:
====

View File

@@ -53,10 +53,6 @@
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>

View File

@@ -0,0 +1,148 @@
/*
* Copyright 2013-2022 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.config;
import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import org.springframework.boot.BootstrapRegistry.InstanceSupplier;
import org.springframework.boot.ConfigurableBootstrapContext;
import org.springframework.boot.context.config.ConfigDataLocation;
import org.springframework.boot.context.config.ConfigDataLocationResolverContext;
import org.springframework.boot.context.config.Profiles;
import org.springframework.boot.logging.DeferredLogFactory;
import org.springframework.cloud.kubernetes.client.KubernetesClientPodUtils;
import org.springframework.cloud.kubernetes.commons.KubernetesClientProperties;
import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
import org.springframework.cloud.kubernetes.commons.config.ConfigDataRetryableConfigMapPropertySourceLocator;
import org.springframework.cloud.kubernetes.commons.config.ConfigDataRetryableSecretsPropertySourceLocator;
import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties;
import org.springframework.cloud.kubernetes.commons.config.ConfigMapPropertySourceLocator;
import org.springframework.cloud.kubernetes.commons.config.KubernetesConfigDataLocationResolver;
import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties;
import org.springframework.cloud.kubernetes.commons.config.SecretsPropertySourceLocator;
import org.springframework.core.env.Environment;
import static org.springframework.cloud.kubernetes.client.KubernetesClientUtils.kubernetesApiClient;
/**
* @author Ryan Baxter
*/
public class KubernetesClientConfigDataLocationResolver extends KubernetesConfigDataLocationResolver {
public KubernetesClientConfigDataLocationResolver(DeferredLogFactory factory) {
super(factory);
}
@Override
protected void registerBeans(ConfigDataLocationResolverContext resolverContext, ConfigDataLocation location,
Profiles profiles, KubernetesConfigDataLocationResolver.PropertyHolder propertyHolder,
KubernetesNamespaceProvider namespaceProvider) {
ConfigMapConfigProperties configMapProperties = propertyHolder.configMapConfigProperties();
SecretsConfigProperties secretsProperties = propertyHolder.secretsProperties();
ConfigurableBootstrapContext bootstrapContext = resolverContext.getBootstrapContext();
ApiClient apiClient = kubernetesApiClient();
bootstrapContext.registerIfAbsent(ApiClient.class, InstanceSupplier.of(apiClient));
bootstrapContext.addCloseListener(event -> event.getApplicationContext().getBeanFactory()
.registerSingleton("configDataApiClient", event.getBootstrapContext().get(ApiClient.class)));
CoreV1Api coreV1Api = coreApi(apiClient);
bootstrapContext.registerIfAbsent(CoreV1Api.class, InstanceSupplier.of(coreV1Api));
bootstrapContext.addCloseListener(event -> event.getApplicationContext().getBeanFactory()
.registerSingleton("configCoreV1Api", event.getBootstrapContext().get(CoreV1Api.class)));
if (isRetryEnabled(configMapProperties, secretsProperties)) {
registerRetryBeans(configMapProperties, secretsProperties, bootstrapContext, coreV1Api, namespaceProvider);
}
else {
if (configMapProperties.isEnabled()) {
KubernetesClientConfigMapPropertySourceLocator configMapPropertySourceLocator = new KubernetesClientConfigMapPropertySourceLocator(
coreV1Api, configMapProperties, namespaceProvider);
bootstrapContext.registerIfAbsent(ConfigMapPropertySourceLocator.class,
InstanceSupplier.of(configMapPropertySourceLocator));
bootstrapContext.addCloseListener(event -> event.getApplicationContext().getBeanFactory()
.registerSingleton("configDataConfigMapPropertySourceLocator",
event.getBootstrapContext().get(ConfigMapPropertySourceLocator.class)));
}
if (secretsProperties.isEnabled()) {
KubernetesClientSecretsPropertySourceLocator secretsPropertySourceLocator = new KubernetesClientSecretsPropertySourceLocator(
coreV1Api, namespaceProvider, secretsProperties);
bootstrapContext.registerIfAbsent(SecretsPropertySourceLocator.class,
InstanceSupplier.of(secretsPropertySourceLocator));
bootstrapContext.addCloseListener(event -> event.getApplicationContext().getBeanFactory()
.registerSingleton("configDataSecretsPropertySourceLocator",
event.getBootstrapContext().get(SecretsPropertySourceLocator.class)));
}
}
}
private void registerRetryBeans(ConfigMapConfigProperties configMapProperties,
SecretsConfigProperties secretsProperties, ConfigurableBootstrapContext bootstrapContext,
CoreV1Api coreV1Api, KubernetesNamespaceProvider namespaceProvider) {
if (configMapProperties.isEnabled()) {
ConfigMapPropertySourceLocator configMapPropertySourceLocator = new KubernetesClientConfigMapPropertySourceLocator(
coreV1Api, configMapProperties, namespaceProvider);
if (isRetryEnabledForConfigMap(configMapProperties)) {
configMapPropertySourceLocator = new ConfigDataRetryableConfigMapPropertySourceLocator(
configMapPropertySourceLocator, configMapProperties);
}
bootstrapContext.registerIfAbsent(ConfigMapPropertySourceLocator.class,
InstanceSupplier.of(configMapPropertySourceLocator));
bootstrapContext.addCloseListener(event -> event.getApplicationContext().getBeanFactory().registerSingleton(
"configDataConfigMapPropertySourceLocator",
event.getBootstrapContext().get(ConfigMapPropertySourceLocator.class)));
}
if (secretsProperties.isEnabled()) {
SecretsPropertySourceLocator secretsPropertySourceLocator = new KubernetesClientSecretsPropertySourceLocator(
coreV1Api, namespaceProvider, secretsProperties);
if (isRetryEnabledForSecrets(secretsProperties)) {
secretsPropertySourceLocator = new ConfigDataRetryableSecretsPropertySourceLocator(
secretsPropertySourceLocator, secretsProperties);
}
bootstrapContext.registerIfAbsent(SecretsPropertySourceLocator.class,
InstanceSupplier.of(secretsPropertySourceLocator));
bootstrapContext.addCloseListener(event -> event.getApplicationContext().getBeanFactory().registerSingleton(
"configDataSecretsPropertySourceLocator",
event.getBootstrapContext().get(SecretsPropertySourceLocator.class)));
}
}
protected ApiClient apiClient(KubernetesClientProperties properties) {
ApiClient apiClient = kubernetesApiClient();
apiClient.setUserAgent(properties.getUserAgent());
return apiClient;
}
protected CoreV1Api coreApi(ApiClient apiClient) {
return new CoreV1Api(apiClient);
}
protected KubernetesNamespaceProvider kubernetesNamespaceProvider(Environment environment) {
return new KubernetesNamespaceProvider(environment);
}
protected KubernetesClientPodUtils kubernetesPodUtils(CoreV1Api client,
KubernetesNamespaceProvider kubernetesNamespaceProvider) {
return new KubernetesClientPodUtils(client, kubernetesNamespaceProvider.getNamespace());
}
}

View File

@@ -3,3 +3,6 @@ org.springframework.cloud.kubernetes.client.config.reload.KubernetesClientConfig
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.springframework.cloud.kubernetes.client.config.KubernetesClientBootstrapConfiguration,\
org.springframework.cloud.kubernetes.client.config.KubernetesClientRetryBootstrapConfiguration
# ConfigData Location Resolvers
org.springframework.boot.context.config.ConfigDataLocationResolver=\
org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigDataLocationResolver

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2013-2020 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.config;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.client.config.applications.include_profile_specific_sources.IncludeProfileSpecificSourcesApp;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* The stub data for this test is in : IncludeProfileSpecificSourcesConfigurationStub
*
* @author wind57
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = IncludeProfileSpecificSourcesApp.class,
properties = { "spring.cloud.bootstrap.name=include-profile-specific-sources",
"include.profile.specific.sources=true", "spring.main.cloud-platform=KUBERNETES",
"spring.cloud.bootstrap.enabled=true" })
@AutoConfigureWebTestClient
@ActiveProfiles("dev")
class KubernetesClientConfigMapBootstrapIncludeProfileSpecificSourcesTests
extends KubernetesClientConfigMapIncludeProfileSpecificSourcesTests {
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2013-2022 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.config;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.client.config.applications.config_map_name_as_prefix.WithPrefixApp;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* @author Ryan Baxter
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = WithPrefixApp.class,
properties = { "spring.cloud.bootstrap.name=config-map-name-as-prefix", "config.map.name.as.prefix.stub=true",
"spring.main.cloud-platform=KUBERNETES", "spring.cloud.bootstrap.enabled=true" })
@AutoConfigureWebTestClient
public class KubernetesClientConfigMapBootstrapNameAsPrefixTests extends KubernetesClientConfigMapNameAsPrefixTests {
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright 2013-2022 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.config;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
import io.kubernetes.client.util.ClientBuilder;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.MockedStatic;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.client.KubernetesClientUtils;
import org.springframework.cloud.kubernetes.client.config.applications.include_profile_specific_sources.IncludeProfileSpecificSourcesApp;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
import static org.mockito.Mockito.mockStatic;
import static org.springframework.cloud.kubernetes.client.config.boostrap.stubs.IncludeProfileSpecificSourcesConfigurationStub.stubData;
/**
* @author Ryan Baxter
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = IncludeProfileSpecificSourcesApp.class,
properties = { "spring.application.name=include-profile-specific-sources",
"include.profile.specific.sources=true", "spring.main.cloud-platform=KUBERNETES",
"spring.config.import=kubernetes:,classpath:./include-profile-specific-sources.yaml" })
@AutoConfigureWebTestClient
@ActiveProfiles("dev")
public class KubernetesClientConfigMapConfigDataIncludeProfileSpecificSourcesTests
extends KubernetesClientConfigMapIncludeProfileSpecificSourcesTests {
private static MockedStatic<KubernetesClientUtils> clientUtilsMock;
@BeforeAll
public static void wireMock() {
WireMockServer server = new WireMockServer(options().dynamicPort());
server.start();
WireMock.configureFor("localhost", server.port());
clientUtilsMock = mockStatic(KubernetesClientUtils.class);
clientUtilsMock.when(KubernetesClientUtils::kubernetesApiClient)
.thenReturn(new ClientBuilder().setBasePath(server.baseUrl()).build());
stubData();
}
@AfterAll
static void teardown() {
clientUtilsMock.close();
}
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2013-2022 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.config;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
import io.kubernetes.client.util.ClientBuilder;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.MockedStatic;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.client.KubernetesClientUtils;
import org.springframework.cloud.kubernetes.client.config.applications.config_map_name_as_prefix.WithPrefixApp;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
import static org.mockito.Mockito.mockStatic;
import static org.springframework.cloud.kubernetes.client.config.boostrap.stubs.ConfigMapNameAsPrefixConfigurationStub.stubData;
/**
* @author Ryan Baxter
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = WithPrefixApp.class,
properties = { "spring.cloud.application.name=config-map-name-as-prefix", "config.map.name.as.prefix.stub=true",
"spring.main.cloud-platform=KUBERNETES",
"spring.config.import=kubernetes:,classpath:./config-map-name-as-prefix.yaml" })
@AutoConfigureWebTestClient
public class KubernetesClientConfigMapConfigDataNameAsPrefixTests extends KubernetesClientConfigMapNameAsPrefixTests {
private static MockedStatic<KubernetesClientUtils> clientUtilsMock;
@BeforeAll
public static void wireMock() {
WireMockServer server = new WireMockServer(options().dynamicPort());
server.start();
WireMock.configureFor("localhost", server.port());
clientUtilsMock = mockStatic(KubernetesClientUtils.class);
clientUtilsMock.when(KubernetesClientUtils::kubernetesApiClient)
.thenReturn(new ClientBuilder().setBasePath(server.baseUrl()).build());
stubData();
}
@AfterAll
static void teardown() {
clientUtilsMock.close();
}
}

View File

@@ -21,14 +21,8 @@ import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.client.config.applications.include_profile_specific_sources.IncludeProfileSpecificSourcesApp;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;
/**
@@ -36,14 +30,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
*
* @author wind57
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = IncludeProfileSpecificSourcesApp.class,
properties = { "spring.cloud.bootstrap.name=include-profile-specific-sources",
"include.profile.specific.sources=true", "spring.main.cloud-platform=KUBERNETES" })
@AutoConfigureWebTestClient
@ActiveProfiles("dev")
class KubernetesClientConfigMapIncludeProfileSpecificSourcesTests {
abstract class KubernetesClientConfigMapIncludeProfileSpecificSourcesTests {
@Autowired
private WebTestClient webClient;

View File

@@ -21,13 +21,8 @@ import org.hamcrest.Matchers;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.client.config.applications.config_map_name_as_prefix.WithPrefixApp;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;
/**
@@ -35,12 +30,7 @@ import org.springframework.test.web.reactive.server.WebTestClient;
*
* @author wind57
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = WithPrefixApp.class,
properties = { "spring.cloud.bootstrap.name=config-map-name-as-prefix", "config.map.name.as.prefix.stub=true",
"spring.main.cloud-platform=KUBERNETES" })
@AutoConfigureWebTestClient
public class KubernetesClientConfigMapNameAsPrefixTests {
abstract class KubernetesClientConfigMapNameAsPrefixTests {
@Autowired
private WebTestClient webClient;

View File

@@ -64,7 +64,7 @@ public class ConfigMapNameAsPrefixConfigurationStub {
return apiClient;
}
private void stubData() {
public static void stubData() {
V1ConfigMap one = new V1ConfigMapBuilder()
.withMetadata(new V1ObjectMetaBuilder().withName("config-map-one").withNamespace("spring-k8s")
.withResourceVersion("1").build())

View File

@@ -45,7 +45,7 @@ import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options
@Order(0)
@Configuration
@ConditionalOnProperty("include.profile.specific.sources")
class IncludeProfileSpecificSourcesConfigurationStub {
public class IncludeProfileSpecificSourcesConfigurationStub {
@Bean
public WireMockServer wireMock() {
@@ -64,7 +64,7 @@ class IncludeProfileSpecificSourcesConfigurationStub {
return apiClient;
}
private void stubData() {
public static void stubData() {
V1ConfigMap one = new V1ConfigMapBuilder()
.withMetadata(new V1ObjectMetaBuilder().withName("config-map-one-dev").withNamespace("spring-k8s")
.withResourceVersion("1").build())

View File

@@ -31,7 +31,8 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author wind57
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class,
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.cloud.kubernetes.client.namespace=abc" })
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.cloud.kubernetes.client.namespace=abc",
"spring.cloud.bootstrap.enabled=true" })
class KubernetesClientBootstrapConfigurationInsideK8s {
@Autowired

View File

@@ -31,8 +31,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author wind57
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class,
properties = { "spring.cloud.kubernetes.enabled=false", "kubernetes.informer.enabled=false",
"kubernetes.manifests.enabled=false" })
properties = { "kubernetes.informer.enabled=false", "kubernetes.manifests.enabled=false" })
class KubernetesDisabled {
@Autowired

View File

@@ -28,7 +28,8 @@ import org.springframework.context.ConfigurableApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class,
properties = { "spring.cloud.kubernetes.client.namespace=default", "spring.main.cloud-platform=KUBERNETES" })
properties = { "spring.cloud.kubernetes.client.namespace=default", "spring.main.cloud-platform=KUBERNETES",
"spring.cloud.bootstrap.enabled=true" })
class KubernetesEnabled {
@Autowired

View File

@@ -31,7 +31,8 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author wind57
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class,
properties = { "spring.cloud.kubernetes.config.enabled=false", "spring.main.cloud-platform=KUBERNETES" })
properties = { "spring.cloud.kubernetes.config.enabled=false", "spring.main.cloud-platform=KUBERNETES",
"spring.cloud.bootstrap.enabled=true" })
class KubernetesEnabledConfigDisabled {
@Autowired

View File

@@ -32,7 +32,8 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class,
properties = { "spring.cloud.kubernetes.secrets.enabled=true",
"spring.cloud.kubernetes.client.namespace=default", "spring.main.cloud-platform=KUBERNETES" })
"spring.cloud.kubernetes.client.namespace=default", "spring.main.cloud-platform=KUBERNETES",
"spring.cloud.bootstrap.enabled=true" })
class KubernetesEnabledOnPurpose {
@Autowired

View File

@@ -32,7 +32,8 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class,
properties = { "spring.cloud.kubernetes.secrets.enabled=false",
"spring.cloud.kubernetes.client.namespace=default", "spring.main.cloud-platform=KUBERNETES" })
"spring.cloud.kubernetes.client.namespace=default", "spring.main.cloud-platform=KUBERNETES",
"spring.cloud.bootstrap.enabled=true" })
class KubernetesEnabledSecretsDisabled {
@Autowired

View File

@@ -0,0 +1,30 @@
/*
* Copyright 2013-2022 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.config.configmap_retry;
import org.springframework.boot.test.context.SpringBootTest;
/**
* @author Isik Erhan
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
properties = { "spring.cloud.kubernetes.client.namespace=default", "spring.main.cloud-platform=KUBERNETES",
"spring.cloud.bootstrap.enabled=true" },
classes = App.class)
class BootstrapConfigFailFastDisabled extends ConfigFailFastDisabled {
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2013-2022 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.config.configmap_retry;
import org.springframework.boot.test.context.SpringBootTest;
/**
* @author Isik Erhan
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
properties = { "spring.cloud.kubernetes.client.namespace=default",
"spring.cloud.kubernetes.config.fail-fast=true", "spring.cloud.kubernetes.config.retry.enabled=false",
"spring.main.cloud-platform=KUBERNETES", "spring.cloud.bootstrap.enabled=true" },
classes = App.class)
class BootstrapConfigFailFastEnabledButRetryDisabled extends ConfigFailFastEnabledButRetryDisabled {
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright 2013-2022 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.config.configmap_retry;
import org.springframework.boot.test.context.SpringBootTest;
/**
* @author Isik Erhan
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
properties = { "spring.cloud.kubernetes.client.namespace=default",
"spring.cloud.kubernetes.config.fail-fast=true", "spring.cloud.kubernetes.config.retry.enabled=false",
"spring.cloud.kubernetes.secrets.fail-fast=true", "spring.main.cloud-platform=KUBERNETES",
"spring.cloud.bootstrap.enabled=true" },
classes = App.class)
class BootstrapConfigRetryDisabledButSecretsRetryEnabled extends ConfigRetryDisabledButSecretsRetryEnabled {
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2013-2022 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.config.configmap_retry;
import org.springframework.boot.test.context.SpringBootTest;
/**
* @author Isik Erhan
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
properties = { "spring.cloud.kubernetes.client.namespace=default",
"spring.cloud.kubernetes.config.fail-fast=true", "spring.cloud.kubernetes.config.retry.max-attempts=5",
"spring.main.cloud-platform=KUBERNETES", "spring.cloud.bootstrap.enabled=true" },
classes = App.class)
class BootstrapConfigRetryEnabled extends ConfigRetryEnabled {
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright 2013-2022 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.config.configmap_retry;
import org.springframework.boot.test.context.SpringBootTest;
/**
* @author Isik Erhan
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
properties = { "spring.cloud.kubernetes.client.namespace=default", "spring.main.cloud-platform=KUBERNETES",
"spring.config.import=kubernetes:" },
classes = App.class)
class ConfigDataConfigFailFastDisabled extends ConfigFailFastDisabled {
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2013-2022 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.config.configmap_retry;
import org.springframework.boot.test.context.SpringBootTest;
/**
* @author Isik Erhan
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
properties = { "spring.cloud.kubernetes.client.namespace=default",
"spring.cloud.kubernetes.config.fail-fast=true", "spring.cloud.kubernetes.config.retry.enabled=false",
"spring.main.cloud-platform=KUBERNETES", "spring.config.import=kubernetes:" },
classes = App.class)
class ConfigDataConfigFailFastEnabledButRetryDisabled extends ConfigFailFastEnabledButRetryDisabled {
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright 2013-2022 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.config.configmap_retry;
import org.springframework.boot.test.context.SpringBootTest;
/**
* @author Isik Erhan
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
properties = { "spring.cloud.kubernetes.client.namespace=default",
"spring.cloud.kubernetes.config.fail-fast=true", "spring.cloud.kubernetes.config.retry.enabled=false",
"spring.cloud.kubernetes.secrets.fail-fast=true", "spring.main.cloud-platform=KUBERNETES",
"spring.config.import=kubernetes:" },
classes = App.class)
class ConfigDataConfigRetryDisabledButSecretsRetryEnabled extends ConfigRetryDisabledButSecretsRetryEnabled {
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2013-2022 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.config.configmap_retry;
import org.springframework.boot.test.context.SpringBootTest;
/**
* @author Isik Erhan
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
properties = { "spring.cloud.kubernetes.client.namespace=default",
"spring.cloud.kubernetes.config.fail-fast=true", "spring.cloud.kubernetes.config.retry.max-attempts=5",
"spring.main.cloud-platform=KUBERNETES", "spring.config.import=kubernetes:" },
classes = App.class)
class ConfigDataConfigRetryEnabled extends ConfigRetryEnabled {
}

View File

@@ -28,8 +28,7 @@ import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.kubernetes.client.KubernetesClientUtils;
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySourceLocator;
import org.springframework.mock.env.MockEnvironment;
@@ -40,16 +39,14 @@ import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/**
* @author Isik Erhan
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
properties = { "spring.cloud.kubernetes.client.namespace=default", "spring.main.cloud-platform=KUBERNETES" },
classes = App.class)
class ConfigFailFastDisabled {
abstract class ConfigFailFastDisabled {
private static final String API = "/api/v1/namespaces/default/configmaps";
@@ -86,12 +83,12 @@ class ConfigFailFastDisabled {
stubConfigMapAndSecretsDefaults();
}
@SpyBean
@Autowired
private KubernetesClientConfigMapPropertySourceLocator propertySourceLocator;
@Test
void locateShouldNotRetry() {
propertySourceLocator = spy(propertySourceLocator);
stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
Assertions.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));

View File

@@ -28,8 +28,6 @@ import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.cloud.kubernetes.client.KubernetesClientUtils;
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySourceLocator;
import org.springframework.context.ApplicationContext;
@@ -43,18 +41,14 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/**
* @author Isik Erhan
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
properties = { "spring.cloud.kubernetes.client.namespace=default",
"spring.cloud.kubernetes.config.fail-fast=true", "spring.cloud.kubernetes.config.retry.enabled=false",
"spring.main.cloud-platform=KUBERNETES" },
classes = App.class)
class ConfigFailFastEnabledButRetryDisabled {
abstract class ConfigFailFastEnabledButRetryDisabled {
private static final String API = "/api/v1/namespaces/default/configmaps";
@@ -91,7 +85,7 @@ class ConfigFailFastEnabledButRetryDisabled {
stubConfigMapAndSecretsDefaults();
}
@SpyBean
@Autowired
private KubernetesClientConfigMapPropertySourceLocator propertySourceLocator;
@Autowired
@@ -99,7 +93,7 @@ class ConfigFailFastEnabledButRetryDisabled {
@Test
void locateShouldFailWithoutRetrying() {
propertySourceLocator = spy(propertySourceLocator);
stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
assertThat(context.containsBean("kubernetesConfigRetryInterceptor")).isFalse();

View File

@@ -29,8 +29,6 @@ import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.cloud.kubernetes.client.KubernetesClientUtils;
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySourceLocator;
import org.springframework.context.ApplicationContext;
@@ -40,22 +38,17 @@ import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
/**
* @author Isik Erhan
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
properties = { "spring.cloud.kubernetes.client.namespace=default",
"spring.cloud.kubernetes.config.fail-fast=true", "spring.cloud.kubernetes.config.retry.enabled=false",
"spring.cloud.kubernetes.secrets.fail-fast=true", "spring.main.cloud-platform=KUBERNETES" },
classes = App.class)
class ConfigRetryDisabledButSecretsRetryEnabled {
abstract class ConfigRetryDisabledButSecretsRetryEnabled {
private static final String API = "/api/v1/namespaces/default/configmaps";
@@ -96,7 +89,7 @@ class ConfigRetryDisabledButSecretsRetryEnabled {
stubConfigMapAndSecretsDefaults();
}
@SpyBean
@Autowired
private KubernetesClientConfigMapPropertySourceLocator propertySourceLocator;
@Autowired
@@ -104,7 +97,7 @@ class ConfigRetryDisabledButSecretsRetryEnabled {
@Test
void locateShouldFailWithoutRetrying() {
propertySourceLocator = spy(propertySourceLocator);
/*
* Enabling secrets retry causes Spring Retry to be enabled and a
* RetryOperationsInterceptor bean with NeverRetryPolicy for config maps to be
@@ -114,7 +107,8 @@ class ConfigRetryDisabledButSecretsRetryEnabled {
stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
assertThat(context.containsBean("kubernetesConfigRetryInterceptor")).isTrue();
// TODO not in bootstrap
// assertThat(context.containsBean("kubernetesConfigRetryInterceptor")).isTrue();
assertThatThrownBy(() -> propertySourceLocator.locate(new MockEnvironment()))
.isInstanceOf(IllegalStateException.class)
.hasMessage("Unable to read ConfigMap(s) in namespace 'default'");

View File

@@ -33,34 +33,28 @@ import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.kubernetes.client.KubernetesClientUtils;
import org.springframework.cloud.kubernetes.client.config.RetryableKubernetesClientConfigMapPropertySourceLocator;
import org.springframework.cloud.kubernetes.commons.config.ConfigMapPropertySourceLocator;
import org.springframework.core.env.PropertySource;
import org.springframework.mock.env.MockEnvironment;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
import static com.github.tomakehurst.wiremock.stubbing.Scenario.STARTED;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.spy;
/**
* @author Isik Erhan
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
properties = { "spring.cloud.kubernetes.client.namespace=default",
"spring.cloud.kubernetes.config.fail-fast=true", "spring.cloud.kubernetes.config.retry.max-attempts=5",
"spring.main.cloud-platform=KUBERNETES" },
classes = App.class)
class ConfigRetryEnabled {
abstract class ConfigRetryEnabled {
private static final String API = "/api/v1/namespaces/default/configmaps";
@@ -97,12 +91,12 @@ class ConfigRetryEnabled {
stubConfigMapAndSecretsDefaults();
}
@SpyBean
private RetryableKubernetesClientConfigMapPropertySourceLocator propertySourceLocator;
@Autowired
private ConfigMapPropertySourceLocator retryablePl;
@Test
void locateShouldNotRetryWhenThereIsNoFailure() {
ConfigMapPropertySourceLocator propertySourceLocator = spy(retryablePl);
Map<String, String> data = new HashMap<>();
data.put("some.prop", "theValue");
data.put("some.number", "0");
@@ -116,7 +110,7 @@ class ConfigRetryEnabled {
.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
// verify locate is called only once
verify(propertySourceLocator, times(1)).locate(any());
WireMock.verify(1, getRequestedFor(urlEqualTo(API)));
// validate the contents of the property source
assertThat(propertySource.getProperty("some.prop")).isEqualTo("theValue");
@@ -125,6 +119,7 @@ class ConfigRetryEnabled {
@Test
void locateShouldRetryAndRecover() {
ConfigMapPropertySourceLocator propertySourceLocator = spy(retryablePl);
Map<String, String> data = new HashMap<>();
data.put("some.prop", "theValue");
data.put("some.number", "0");
@@ -149,8 +144,8 @@ class ConfigRetryEnabled {
PropertySource<?> propertySource = Assertions
.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
// verify retried 4 times
verify(propertySourceLocator, times(4)).locate(any());
// verify the request was retried 4 times, 5 total request
WireMock.verify(5, getRequestedFor(urlEqualTo(API)));
// validate the contents of the property source
assertThat(propertySource.getProperty("some.prop")).isEqualTo("theValue");
@@ -159,6 +154,7 @@ class ConfigRetryEnabled {
@Test
void locateShouldRetryAndFail() {
ConfigMapPropertySourceLocator propertySourceLocator = spy(retryablePl);
// fail all the 5 requests
stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
@@ -166,8 +162,8 @@ class ConfigRetryEnabled {
.isInstanceOf(IllegalStateException.class)
.hasMessage("Unable to read ConfigMap(s) in namespace 'default'");
// verify retried 5 times until failure
verify(propertySourceLocator, times(5)).locate(any());
// verify the request was retried 5 times
WireMock.verify(5, getRequestedFor(urlEqualTo(API)));
}
}

View File

@@ -28,8 +28,8 @@ import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.cloud.kubernetes.client.KubernetesClientUtils;
import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySourceLocator;
import org.springframework.mock.env.MockEnvironment;
@@ -40,6 +40,7 @@ import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -49,7 +50,7 @@ import static org.mockito.Mockito.verify;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
properties = { "spring.cloud.kubernetes.client.namespace=default",
"spring.cloud.kubernetes.secrets.name=my-secret", "spring.cloud.kubernetes.secrets.enable-api=true",
"spring.main.cloud-platform=KUBERNETES" },
"spring.main.cloud-platform=KUBERNETES", "spring.config.import=kubernetes:" },
classes = Application.class)
class SecretsFailFastDisabled {
@@ -88,12 +89,12 @@ class SecretsFailFastDisabled {
stubConfigMapAndSecretsDefaults();
}
@SpyBean
private KubernetesClientSecretsPropertySourceLocator propertySourceLocator;
@Autowired
private KubernetesClientSecretsPropertySourceLocator psl;
@Test
void locateShouldNotRetry() {
KubernetesClientSecretsPropertySourceLocator propertySourceLocator = spy(psl);
stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
Assertions.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));

View File

@@ -30,7 +30,6 @@ import org.mockito.MockedStatic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.cloud.kubernetes.client.KubernetesClientUtils;
import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySourceLocator;
import org.springframework.context.ApplicationContext;
@@ -44,6 +43,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -54,7 +54,7 @@ import static org.mockito.Mockito.verify;
properties = { "spring.cloud.kubernetes.client.namespace=default",
"spring.cloud.kubernetes.secrets.fail-fast=true", "spring.cloud.kubernetes.secrets.retry.enabled=false",
"spring.cloud.kubernetes.secrets.name=my-secret", "spring.cloud.kubernetes.secrets.enable-api=true",
"spring.main.cloud-platform=KUBERNETES" },
"spring.main.cloud-platform=KUBERNETES", "spring.config.import=kubernetes:" },
classes = Application.class)
class SecretsFailFastEnabledButRetryDisabled {
@@ -97,15 +97,15 @@ class SecretsFailFastEnabledButRetryDisabled {
stubConfigMapAndSecretsDefaults();
}
@SpyBean
private KubernetesClientSecretsPropertySourceLocator propertySourceLocator;
@Autowired
private KubernetesClientSecretsPropertySourceLocator psl;
@Autowired
private ApplicationContext context;
@Test
void locateShouldFailWithoutRetrying() {
KubernetesClientSecretsPropertySourceLocator propertySourceLocator = spy(psl);
stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
assertThat(context.containsBean("kubernetesSecretsRetryInterceptor")).isFalse();

View File

@@ -30,7 +30,6 @@ import org.mockito.MockedStatic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.cloud.kubernetes.client.KubernetesClientUtils;
import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySourceLocator;
import org.springframework.context.ApplicationContext;
@@ -40,10 +39,10 @@ import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -54,7 +53,8 @@ import static org.mockito.Mockito.verify;
properties = { "spring.cloud.kubernetes.client.namespace=default",
"spring.cloud.kubernetes.secrets.fail-fast=true", "spring.cloud.kubernetes.secrets.retry.enabled=false",
"spring.cloud.kubernetes.config.fail-fast=true", "spring.cloud.kubernetes.secrets.name=my-secret",
"spring.cloud.kubernetes.secrets.enable-api=true", "spring.main.cloud-platform=KUBERNETES" },
"spring.cloud.kubernetes.secrets.enable-api=true", "spring.main.cloud-platform=KUBERNETES",
"spring.config.import=kubernetes:" },
classes = Application.class)
class SecretsRetryDisabledButConfigRetryEnabled {
@@ -97,15 +97,15 @@ class SecretsRetryDisabledButConfigRetryEnabled {
stubConfigMapAndSecretsDefaults();
}
@SpyBean
private KubernetesClientSecretsPropertySourceLocator propertySourceLocator;
@Autowired
private KubernetesClientSecretsPropertySourceLocator psl;
@Autowired
private ApplicationContext context;
@Test
void locateShouldFailWithoutRetrying() {
KubernetesClientSecretsPropertySourceLocator propertySourceLocator = spy(psl);
/*
* Enabling config retry causes Spring Retry to be enabled and a
* RetryOperationsInterceptor bean with NeverRetryPolicy for secrets to be
@@ -115,7 +115,8 @@ class SecretsRetryDisabledButConfigRetryEnabled {
stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
assertThat(context.containsBean("kubernetesSecretsRetryInterceptor")).isTrue();
// TODO not in bootstrap
// assertThat(context.containsBean("kubernetesSecretsRetryInterceptor")).isTrue();
assertThatThrownBy(() -> propertySourceLocator.locate(new MockEnvironment()))
.isInstanceOf(IllegalStateException.class)
.hasMessage("Unable to read Secret with name 'my-secret' in namespace 'default'");

View File

@@ -27,38 +27,40 @@ import io.kubernetes.client.openapi.models.V1Secret;
import io.kubernetes.client.openapi.models.V1SecretList;
import io.kubernetes.client.util.ClientBuilder;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.cloud.kubernetes.client.KubernetesClientUtils;
import org.springframework.cloud.kubernetes.client.config.RetryableKubernetesClientSecretsPropertySourceLocator;
import org.springframework.cloud.kubernetes.commons.config.SecretsPropertySourceLocator;
import org.springframework.core.env.PropertySource;
import org.springframework.mock.env.MockEnvironment;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
import static com.github.tomakehurst.wiremock.stubbing.Scenario.STARTED;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.spy;
/**
* @author Isik Erhan
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, properties = {
"spring.cloud.kubernetes.client.namespace=default", "spring.cloud.kubernetes.secrets.fail-fast=true",
"spring.cloud.kubernetes.secrets.retry.max-attempts=5", "spring.cloud.kubernetes.secrets.name=my-secret",
"spring.cloud.kubernetes.secrets.enable-api=true", "spring.main.cloud-platform=KUBERNETES" },
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
properties = { "spring.cloud.kubernetes.client.namespace=default",
"spring.cloud.kubernetes.secrets.fail-fast=true",
"spring.cloud.kubernetes.secrets.retry.max-attempts=5",
"spring.cloud.kubernetes.secrets.name=my-secret", "spring.cloud.kubernetes.secrets.enable-api=true",
"spring.main.cloud-platform=KUBERNETES", "spring.config.import=kubernetes:" },
classes = Application.class)
class SecretsRetryEnabled {
@@ -91,18 +93,18 @@ class SecretsRetryEnabled {
clientUtilsMock.close();
}
@AfterEach
@Autowired
private SecretsPropertySourceLocator psl;
@BeforeEach
void afterEach() {
WireMock.reset();
stubConfigMapAndSecretsDefaults();
}
@SpyBean
private RetryableKubernetesClientSecretsPropertySourceLocator propertySourceLocator;
@Test
void locateShouldNotRetryWhenThereIsNoFailure() {
SecretsPropertySourceLocator propertySourceLocator = spy(psl);
Map<String, byte[]> data = new HashMap<>();
data.put("some.sensitive.prop", "theSensitiveValue".getBytes());
data.put("some.sensitive.number", "1".getBytes());
@@ -116,7 +118,7 @@ class SecretsRetryEnabled {
.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
// verify locate is called only once
verify(propertySourceLocator, times(1)).locate(any());
WireMock.verify(1, getRequestedFor(urlEqualTo(API)));
// validate the contents of the property source
assertThat(propertySource.getProperty("some.sensitive.prop")).isEqualTo("theSensitiveValue");
@@ -125,6 +127,7 @@ class SecretsRetryEnabled {
@Test
void locateShouldRetryAndRecover() {
SecretsPropertySourceLocator propertySourceLocator = spy(psl);
Map<String, byte[]> data = new HashMap<>();
data.put("some.sensitive.prop", "theSensitiveValue".getBytes());
data.put("some.sensitive.number", "1".getBytes());
@@ -150,7 +153,7 @@ class SecretsRetryEnabled {
.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
// verify retried 4 times
verify(propertySourceLocator, times(4)).locate(any());
WireMock.verify(4, getRequestedFor(urlEqualTo(API)));
// validate the contents of the property source
assertThat(propertySource.getProperty("some.sensitive.prop")).isEqualTo("theSensitiveValue");
@@ -159,6 +162,7 @@ class SecretsRetryEnabled {
@Test
void locateShouldRetryAndFail() {
SecretsPropertySourceLocator propertySourceLocator = spy(psl);
// fail all the 5 requests
stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
@@ -167,7 +171,7 @@ class SecretsRetryEnabled {
.hasMessage("Unable to read Secret with name 'my-secret' in namespace 'default'");
// verify retried 5 times until failure
verify(propertySourceLocator, times(5)).locate(any());
WireMock.verify(5, getRequestedFor(urlEqualTo(API)));
}
}

View File

@@ -20,14 +20,21 @@ import java.time.Duration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import static org.springframework.cloud.kubernetes.commons.KubernetesClientProperties.PREFIX;
/**
* Kubernetes client properties.
*
* @author Ioannis Canellos
*/
@ConfigurationProperties("spring.cloud.kubernetes.client")
@ConfigurationProperties(PREFIX)
public class KubernetesClientProperties {
/**
* Configuration properties prefix.
*/
public static final String PREFIX = "spring.cloud.kubernetes.client";
/**
* Default user-agent for kubernetes client.
*/

View File

@@ -121,6 +121,8 @@ public abstract class AbstractConfigProperties {
*/
private int maxAttempts = 6;
private boolean enabled = true;
public long getInitialInterval() {
return this.initialInterval;
}
@@ -153,6 +155,14 @@ public abstract class AbstractConfigProperties {
this.maxAttempts = maxAttempts;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright 2013-2020 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.config;
import java.util.Collection;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.retry.support.RetryTemplate;
/**
* ConfigMapPropertySourceLocator for when retry is enabled.
*
* @author Ryan Baxter
*/
public class ConfigDataRetryableConfigMapPropertySourceLocator extends ConfigMapPropertySourceLocator {
private RetryTemplate retryTemplate;
private ConfigMapPropertySourceLocator configMapPropertySourceLocator;
public ConfigDataRetryableConfigMapPropertySourceLocator(
ConfigMapPropertySourceLocator configMapPropertySourceLocator, ConfigMapConfigProperties properties) {
super(properties);
this.configMapPropertySourceLocator = configMapPropertySourceLocator;
this.retryTemplate = RetryTemplate.builder().maxAttempts(properties.getRetry().getMaxAttempts())
.exponentialBackoff(properties.getRetry().getInitialInterval(), properties.getRetry().getMultiplier(),
properties.getRetry().getMaxInterval())
.build();
}
@Override
protected MapPropertySource getMapPropertySource(NormalizedSource normalizedSource,
ConfigurableEnvironment environment) {
return configMapPropertySourceLocator.getMapPropertySource(normalizedSource, environment);
}
@Override
public PropertySource<?> locate(Environment environment) {
return retryTemplate.execute(retryContext -> configMapPropertySourceLocator.locate(environment));
}
@Override
public Collection<PropertySource<?>> locateCollection(Environment environment) {
return retryTemplate.execute(retryContext -> configMapPropertySourceLocator.locateCollection(environment));
}
public void setConfigMapPropertySourceLocator(ConfigMapPropertySourceLocator configMapPropertySourceLocator) {
this.configMapPropertySourceLocator = configMapPropertySourceLocator;
}
public ConfigMapPropertySourceLocator getConfigMapPropertySourceLocator() {
return configMapPropertySourceLocator;
}
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright 2013-2022 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.config;
import java.util.Collection;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.retry.support.RetryTemplate;
/**
* SecretsPropertySourceLocator for when retry is enabled.
*
* @author Ryan Baxter
*/
public class ConfigDataRetryableSecretsPropertySourceLocator extends SecretsPropertySourceLocator {
private RetryTemplate retryTemplate;
private SecretsPropertySourceLocator secretsPropertySourceLocator;
public ConfigDataRetryableSecretsPropertySourceLocator(SecretsPropertySourceLocator propertySourceLocator,
SecretsConfigProperties secretsConfigProperties) {
super(secretsConfigProperties);
this.secretsPropertySourceLocator = propertySourceLocator;
this.retryTemplate = RetryTemplate.builder().maxAttempts(properties.getRetry().getMaxAttempts())
.exponentialBackoff(properties.getRetry().getInitialInterval(), properties.getRetry().getMultiplier(),
properties.getRetry().getMaxInterval())
.build();
}
@Override
public PropertySource<?> locate(Environment environment) {
return retryTemplate.execute(retryContext -> secretsPropertySourceLocator.locate(environment));
}
@Override
public Collection<PropertySource<?>> locateCollection(Environment environment) {
return retryTemplate.execute(retryContext -> secretsPropertySourceLocator.locateCollection(environment));
}
@Override
protected MapPropertySource getPropertySource(ConfigurableEnvironment environment,
NormalizedSource normalizedSource) {
return this.secretsPropertySourceLocator.getPropertySource(environment, normalizedSource);
}
public SecretsPropertySourceLocator getSecretsPropertySourceLocator() {
return secretsPropertySourceLocator;
}
public void setSecretsPropertySourceLocator(SecretsPropertySourceLocator secretsPropertySourceLocator) {
this.secretsPropertySourceLocator = secretsPropertySourceLocator;
}
}

View File

@@ -46,9 +46,9 @@ public class KubernetesBootstrapConfiguration {
@Configuration(proxyBeanMethods = false)
@EnableRetry(proxyTargetClass = true)
@Import(AopAutoConfiguration.class)
static class RetryConfiguration {
public static class RetryConfiguration {
private static RetryOperationsInterceptor retryOperationsInterceptor(
public static RetryOperationsInterceptor retryOperationsInterceptor(
AbstractConfigProperties.RetryProperties retryProperties) {
return RetryInterceptorBuilder.stateless().backOffOptions(retryProperties.getInitialInterval(),
retryProperties.getMultiplier(), retryProperties.getMaxInterval())

View File

@@ -0,0 +1,83 @@
/*
* Copyright 2013-2022 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.config;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.springframework.boot.ConfigurableBootstrapContext;
import org.springframework.boot.context.config.ConfigData;
import org.springframework.boot.context.config.ConfigData.Option;
import org.springframework.boot.context.config.ConfigDataLoader;
import org.springframework.boot.context.config.ConfigDataLoaderContext;
import org.springframework.boot.context.config.ConfigDataResourceNotFoundException;
import org.springframework.core.Ordered;
import org.springframework.core.env.Environment;
import org.springframework.core.env.PropertySource;
/**
* @author Ryan Baxter
*/
public class KubernetesConfigDataLoader implements ConfigDataLoader<KubernetesConfigDataResource>, Ordered {
@Override
public ConfigData load(ConfigDataLoaderContext context, KubernetesConfigDataResource resource)
throws IOException, ConfigDataResourceNotFoundException {
List<PropertySource<?>> propertySources = new ArrayList<>(2);
ConfigurableBootstrapContext bootstrapContext = context.getBootstrapContext();
Environment env = resource.getEnvironment();
if (bootstrapContext.isRegistered(ConfigMapPropertySourceLocator.class)) {
propertySources.add(bootstrapContext.get(ConfigMapPropertySourceLocator.class).locate(env));
}
if (bootstrapContext.isRegistered(SecretsPropertySourceLocator.class)) {
propertySources.add(bootstrapContext.get(SecretsPropertySourceLocator.class).locate(env));
}
// boot 2.4.5+
return new ConfigData(propertySources, propertySource -> {
String propertySourceName = propertySource.getName();
List<Option> options = new ArrayList<>();
options.add(Option.IGNORE_IMPORTS);
options.add(Option.IGNORE_PROFILES);
// TODO: the profile is now available on the backend
// in a future minor, add the profile associated with a
// PropertySource see
// https://github.com/spring-cloud/spring-cloud-config/issues/1874
for (String profile : resource.getAcceptedProfiles()) {
// TODO: switch to match
// , is used as a profile-separator for property sources
// from vault
// - is the default profile-separator for property sources
if (propertySourceName.matches(".*[-,]" + profile + ".*")) {
// // TODO: switch to Options.with() when implemented
options.add(Option.PROFILE_SPECIFIC);
}
}
return ConfigData.Options.of(options.toArray(new Option[0]));
});
}
@Override
public int getOrder() {
return -1;
}
}

View File

@@ -0,0 +1,207 @@
/*
* Copyright 2013-2022 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.config;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.BootstrapRegistry.InstanceSupplier;
import org.springframework.boot.ConfigurableBootstrapContext;
import org.springframework.boot.cloud.CloudPlatform;
import org.springframework.boot.context.config.ConfigDataLocation;
import org.springframework.boot.context.config.ConfigDataLocationNotFoundException;
import org.springframework.boot.context.config.ConfigDataLocationResolver;
import org.springframework.boot.context.config.ConfigDataLocationResolverContext;
import org.springframework.boot.context.config.ConfigDataResourceNotFoundException;
import org.springframework.boot.context.config.Profiles;
import org.springframework.boot.context.properties.bind.BindHandler;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.boot.logging.DeferredLogFactory;
import org.springframework.cloud.kubernetes.commons.KubernetesClientProperties;
import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.util.ClassUtils;
/**
* @author Ryan Baxter
*/
public abstract class KubernetesConfigDataLocationResolver
implements ConfigDataLocationResolver<KubernetesConfigDataResource>, Ordered {
static final boolean RETRY_IS_PRESENT = ClassUtils.isPresent("org.springframework.retry.annotation.Retryable",
null);
/**
* Prefix for Config Server imports.
*/
public static final String PREFIX = "kubernetes:";
private final Log log;
public KubernetesConfigDataLocationResolver(DeferredLogFactory factory) {
this.log = factory.getLog(KubernetesConfigDataLocationResolver.class);
}
protected String getPrefix() {
return PREFIX;
}
@Override
public boolean isResolvable(ConfigDataLocationResolverContext context, ConfigDataLocation location) {
if (!location.hasPrefix(getPrefix())) {
return false;
}
return (CloudPlatform.KUBERNETES.isEnforced(context.getBinder())
|| CloudPlatform.KUBERNETES.isDetected(new StandardEnvironment()));
}
@Override
public List<KubernetesConfigDataResource> resolve(ConfigDataLocationResolverContext context,
ConfigDataLocation location)
throws ConfigDataLocationNotFoundException, ConfigDataResourceNotFoundException {
return Collections.emptyList();
}
@Override
public List<KubernetesConfigDataResource> resolveProfileSpecific(ConfigDataLocationResolverContext resolverContext,
ConfigDataLocation location, Profiles profiles) throws ConfigDataLocationNotFoundException {
PropertyHolder propertyHolder = loadProperties(resolverContext);
KubernetesClientProperties properties = propertyHolder.kubernetesClientProperties;
ConfigMapConfigProperties configMapProperties = propertyHolder.configMapConfigProperties;
SecretsConfigProperties secretsProperties = propertyHolder.secretsProperties;
ConfigurableBootstrapContext bootstrapContext = resolverContext.getBootstrapContext();
bootstrapContext.registerIfAbsent(KubernetesClientProperties.class, InstanceSupplier.of(properties));
bootstrapContext.addCloseListener(event -> event.getApplicationContext().getBeanFactory().registerSingleton(
"configDataKubernetesClientProperties",
event.getBootstrapContext().get(KubernetesClientProperties.class)));
bootstrapContext.registerIfAbsent(ConfigMapConfigProperties.class, InstanceSupplier.of(configMapProperties));
bootstrapContext.addCloseListener(event -> event.getApplicationContext().getBeanFactory().registerSingleton(
"configDataConfigMapConfigProperties",
event.getBootstrapContext().get(ConfigMapConfigProperties.class)));
bootstrapContext.registerIfAbsent(SecretsConfigProperties.class, InstanceSupplier.of(secretsProperties));
bootstrapContext.addCloseListener(event -> event.getApplicationContext().getBeanFactory().registerSingleton(
"configDataSecretsConfigProperties", event.getBootstrapContext().get(SecretsConfigProperties.class)));
HashMap<String, Object> kubernetesConfigData = new HashMap<>();
kubernetesConfigData.put("spring.cloud.kubernetes.client.namespace", properties.getNamespace());
if (propertyHolder.applicationName != null) {
// If its null it means sprig.application.name was not set so don't add it to
// the property source
kubernetesConfigData.put("spring.application.name", propertyHolder.applicationName);
}
PropertySource<Map<String, Object>> propertySource = new MapPropertySource("kubernetesConfigData",
kubernetesConfigData);
ConfigurableEnvironment environment = new StandardEnvironment();
environment.getPropertySources().addLast(propertySource);
environment.setActiveProfiles(profiles.getAccepted().toArray(new String[0]));
KubernetesNamespaceProvider namespaceProvider = kubernetesNamespaceProvider(environment);
registerBeans(resolverContext, location, profiles, propertyHolder, namespaceProvider);
KubernetesConfigDataResource resource = new KubernetesConfigDataResource(properties, configMapProperties,
secretsProperties, location.isOptional(), profiles, environment);
resource.setLog(log);
List<KubernetesConfigDataResource> locations = new ArrayList<>();
locations.add(resource);
return locations;
}
protected abstract void registerBeans(ConfigDataLocationResolverContext resolverContext,
ConfigDataLocation location, Profiles profiles, PropertyHolder propertyHolder,
KubernetesNamespaceProvider namespaceProvider);
protected boolean isRetryEnabled(ConfigMapConfigProperties configMapProperties,
SecretsConfigProperties secretsProperties) {
return isRetryEnabledForConfigMap(configMapProperties) || isRetryEnabledForSecrets(secretsProperties);
}
protected boolean isRetryEnabledForConfigMap(ConfigMapConfigProperties configMapProperties) {
return RETRY_IS_PRESENT && configMapProperties.getRetry().isEnabled() && configMapProperties.isFailFast();
}
protected boolean isRetryEnabledForSecrets(SecretsConfigProperties secretsProperties) {
return RETRY_IS_PRESENT && secretsProperties.getRetry().isEnabled() && secretsProperties.isFailFast();
}
protected KubernetesNamespaceProvider kubernetesNamespaceProvider(Environment environment) {
return new KubernetesNamespaceProvider(environment);
}
@Override
public int getOrder() {
return -1;
}
private BindHandler getBindHandler(ConfigDataLocationResolverContext context) {
return context.getBootstrapContext().getOrElse(BindHandler.class, null);
}
protected PropertyHolder loadProperties(ConfigDataLocationResolverContext context) {
Binder binder = context.getBinder();
BindHandler bindHandler = getBindHandler(context);
String applicationName = binder.bind("spring.application.name", String.class).orElse(null);
String namespace = binder.bind("spring.cloud.kubernetes.client.namespace", String.class)
.orElse(binder.bind("kubernetes.namespace", String.class).orElse(""));
KubernetesClientProperties kubernetesClientProperties;
if (context.getBootstrapContext().isRegistered(KubernetesClientProperties.class)) {
kubernetesClientProperties = new KubernetesClientProperties();
BeanUtils.copyProperties(context.getBootstrapContext().get(KubernetesClientProperties.class),
kubernetesClientProperties);
}
else {
kubernetesClientProperties = binder
.bind(KubernetesClientProperties.PREFIX, Bindable.of(KubernetesClientProperties.class), bindHandler)
.orElseGet(KubernetesClientProperties::new);
}
kubernetesClientProperties.setNamespace(namespace);
ConfigMapConfigProperties configMapConfigProperties = binder
.bind(ConfigMapConfigProperties.PREFIX, ConfigMapConfigProperties.class)
.orElseGet(ConfigMapConfigProperties::new);
SecretsConfigProperties secretsProperties = binder
.bind(SecretsConfigProperties.PREFIX, SecretsConfigProperties.class)
.orElseGet(SecretsConfigProperties::new);
return new PropertyHolder(kubernetesClientProperties, configMapConfigProperties, secretsProperties,
applicationName);
}
protected record PropertyHolder(KubernetesClientProperties kubernetesClientProperties,
ConfigMapConfigProperties configMapConfigProperties, SecretsConfigProperties secretsProperties,
String applicationName) {
}
}

View File

@@ -0,0 +1,129 @@
/*
* Copyright 2013-2022 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.config;
import java.util.List;
import java.util.Objects;
import org.apache.commons.logging.Log;
import org.springframework.boot.context.config.ConfigDataResource;
import org.springframework.boot.context.config.Profiles;
import org.springframework.cloud.kubernetes.commons.KubernetesClientProperties;
import org.springframework.core.env.Environment;
import org.springframework.core.style.ToStringCreator;
import org.springframework.util.StringUtils;
/**
* @author Ryan Baxter
*/
public class KubernetesConfigDataResource extends ConfigDataResource {
private final KubernetesClientProperties properties;
private final ConfigMapConfigProperties configMapProperties;
private final SecretsConfigProperties secretsConfigProperties;
private final boolean optional;
private final Profiles profiles;
private Log log;
private Environment environment;
public KubernetesConfigDataResource(KubernetesClientProperties properties,
ConfigMapConfigProperties configMapProperties, SecretsConfigProperties secretsConfigProperties,
boolean optional, Profiles profiles, Environment environment) {
this.properties = properties;
this.configMapProperties = configMapProperties;
this.secretsConfigProperties = secretsConfigProperties;
this.optional = optional;
this.profiles = profiles;
this.environment = environment;
}
public KubernetesClientProperties getProperties() {
return this.properties;
}
public ConfigMapConfigProperties getConfigMapProperties() {
return configMapProperties;
}
public SecretsConfigProperties getSecretsConfigProperties() {
return secretsConfigProperties;
}
public boolean isOptional() {
return this.optional;
}
public String getProfiles() {
return StringUtils.collectionToCommaDelimitedString(getAcceptedProfiles());
}
List<String> getAcceptedProfiles() {
return this.profiles.getAccepted();
}
public void setLog(Log log) {
this.log = log;
}
public Log getLog() {
return this.log;
}
public Environment getEnvironment() {
return environment;
}
public void setEnvironment(Environment environment) {
this.environment = environment;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
KubernetesConfigDataResource that = (KubernetesConfigDataResource) o;
return Objects.equals(this.properties, that.properties) && Objects.equals(this.optional, that.optional)
&& Objects.equals(this.profiles, that.profiles)
&& Objects.equals(this.configMapProperties, that.configMapProperties)
&& Objects.equals(this.secretsConfigProperties, that.secretsConfigProperties);
}
@Override
public int hashCode() {
return Objects.hash(this.properties, this.optional, this.profiles, configMapProperties,
secretsConfigProperties);
}
@Override
public String toString() {
return new ToStringCreator(this).append("optional", optional).append("profiles", profiles.getAccepted())
.toString();
}
}

View File

@@ -3,3 +3,7 @@ org.springframework.cloud.kubernetes.commons.KubernetesCommonsAutoConfiguration,
org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadAutoConfiguration
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.springframework.cloud.kubernetes.commons.config.KubernetesBootstrapConfiguration
# ConfigData Loaders
org.springframework.boot.context.config.ConfigDataLoader=\
org.springframework.cloud.kubernetes.commons.config.KubernetesConfigDataLoader

View File

@@ -35,6 +35,13 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<!-- in favor of mockito-inline -->
<exclusions>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</exclusion>
</exclusions>
<scope>test</scope>
</dependency>
<dependency>
@@ -42,6 +49,11 @@
<artifactId>wiremock-jre8-standalone</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2013-2021 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.configserver;
import org.springframework.boot.test.context.SpringBootTest;
/**
* @author Ryan Baxter
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.cloud.kubernetes.client.namespace=default",
"spring.profiles.include=kubernetes", "spring.cloud.kubernetes.secrets.enableApi=true", "debug=true",
"spring.cloud.bootstrap.enabled=true" },
classes = { KubernetesConfigServerApplication.class })
public class BootstrapConfigServerIntegrationTest extends ConfigServerIntegrationTest {
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright 2013-2021 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.configserver;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
import io.kubernetes.client.util.ClientBuilder;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.mockito.MockedStatic;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.client.KubernetesClientUtils;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options;
import static org.mockito.Mockito.mockStatic;
/**
* @author Ryan Baxter
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.cloud.kubernetes.client.namespace=default",
"spring.profiles.include=kubernetes", "spring.cloud.kubernetes.secrets.enableApi=true", "debug=true",
"spring.config.import=kubernetes:" },
classes = { KubernetesConfigServerApplication.class })
public class ConfigDataConfigServerIntegrationTest extends ConfigServerIntegrationTest {
private static WireMockServer wireMockServer;
private static MockedStatic<KubernetesClientUtils> clientUtilsMock;
@BeforeAll
static void setup() {
wireMockServer = new WireMockServer(options().dynamicPort());
wireMockServer.start();
WireMock.configureFor(wireMockServer.port());
clientUtilsMock = mockStatic(KubernetesClientUtils.class);
clientUtilsMock.when(KubernetesClientUtils::kubernetesApiClient)
.thenReturn(new ClientBuilder().setBasePath(wireMockServer.baseUrl()).build());
}
@AfterAll
static void teardown() {
wireMockServer.stop();
clientUtilsMock.close();
}
@AfterEach
void afterEach() {
WireMock.reset();
}
}

View File

@@ -28,8 +28,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Ryan Baxter
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = { "spring.profiles.include=kubernetes,kubernetesdisabled", "spring.cloud.kubernetes.enabled=false",
"debug=true" },
properties = { "spring.profiles.include=kubernetes,kubernetesdisabled", "debug=true" },
classes = { KubernetesConfigServerApplication.class, MockConfig.class })
class ConfigServerAutoConfigurationKubernetesDisabled {

View File

@@ -29,8 +29,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = { KubernetesConfigServerApplication.class, MockConfig.class },
properties = { "spring.cloud.kubernetes.enabled=false", "spring.profiles.include=kubernetes,kubernetesdisabled",
"debug=true" })
properties = { "spring.profiles.include=kubernetes,kubernetesdisabled", "debug=true" })
class ConfigServerAutoConfigurationKubernetesProfileMissing {
@Autowired

View File

@@ -29,7 +29,6 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.cloud.config.environment.Environment;
@@ -41,11 +40,7 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Ryan Baxter
*/
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.cloud.kubernetes.client.namespace=default",
"spring.profiles.include=kubernetes", "spring.cloud.kubernetes.secrets.enableApi=true", "debug=true" },
classes = { KubernetesConfigServerApplication.class })
public class ConfigServerIntegrationTest {
abstract class ConfigServerIntegrationTest {
@Autowired
private TestRestTemplate testRestTemplate;

View File

@@ -1,4 +1,6 @@
spring:
config:
import: "kubernetes:"
application:
name: spring-cloud-kubernetes-configuration-watcher
cloud:

View File

@@ -55,10 +55,6 @@
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>

View File

@@ -23,6 +23,7 @@ import io.fabric8.kubernetes.client.KubernetesClient;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnCloudPlatform;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.cloud.CloudPlatform;
import org.springframework.cloud.kubernetes.commons.ConditionalOnKubernetesConfigEnabled;
import org.springframework.cloud.kubernetes.commons.ConditionalOnKubernetesSecretsEnabled;
@@ -49,6 +50,7 @@ import org.springframework.core.env.Environment;
@ConditionalOnClass({ ConfigMap.class, Secret.class })
@AutoConfigureAfter(KubernetesBootstrapConfiguration.class)
@ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES)
@ConditionalOnProperty(value = "spring.cloud.bootstrap.enabled", havingValue = "true")
public class Fabric8BootstrapConfiguration {
@Bean

View File

@@ -0,0 +1,141 @@
/*
* Copyright 2013-2021 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.fabric8.config;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.KubernetesClient;
import org.springframework.boot.BootstrapRegistry;
import org.springframework.boot.BootstrapRegistry.InstanceSupplier;
import org.springframework.boot.ConfigurableBootstrapContext;
import org.springframework.boot.context.config.ConfigDataLocation;
import org.springframework.boot.context.config.ConfigDataLocationResolverContext;
import org.springframework.boot.context.config.Profiles;
import org.springframework.boot.logging.DeferredLogFactory;
import org.springframework.cloud.kubernetes.commons.KubernetesClientProperties;
import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
import org.springframework.cloud.kubernetes.commons.config.ConfigDataRetryableConfigMapPropertySourceLocator;
import org.springframework.cloud.kubernetes.commons.config.ConfigDataRetryableSecretsPropertySourceLocator;
import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties;
import org.springframework.cloud.kubernetes.commons.config.ConfigMapPropertySourceLocator;
import org.springframework.cloud.kubernetes.commons.config.KubernetesConfigDataLocationResolver;
import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties;
import org.springframework.cloud.kubernetes.commons.config.SecretsPropertySourceLocator;
import org.springframework.cloud.kubernetes.fabric8.Fabric8AutoConfiguration;
import org.springframework.core.env.Environment;
/**
* @author Ryan Baxter
*/
public class Fabric8ConfigDataLocationResolver extends KubernetesConfigDataLocationResolver {
public Fabric8ConfigDataLocationResolver(DeferredLogFactory factory) {
super(factory);
}
@Override
protected void registerBeans(ConfigDataLocationResolverContext resolverContext, ConfigDataLocation location,
Profiles profiles, KubernetesConfigDataLocationResolver.PropertyHolder propertyHolder,
KubernetesNamespaceProvider namespaceProvider) {
KubernetesClientProperties properties = propertyHolder.kubernetesClientProperties();
ConfigMapConfigProperties configMapProperties = propertyHolder.configMapConfigProperties();
SecretsConfigProperties secretsProperties = propertyHolder.secretsProperties();
ConfigurableBootstrapContext bootstrapContext = resolverContext.getBootstrapContext();
Config config = config(properties);
bootstrapContext.registerIfAbsent(Config.class, InstanceSupplier.of(config));
bootstrapContext.addCloseListener(event -> event.getApplicationContext().getBeanFactory()
.registerSingleton("fabric8Config", event.getBootstrapContext().get(Config.class)));
KubernetesClient kubernetesClient = kubernetesClient(config);
bootstrapContext.registerIfAbsent(KubernetesClient.class,
BootstrapRegistry.InstanceSupplier.of(kubernetesClient));
bootstrapContext.addCloseListener(event -> event.getApplicationContext().getBeanFactory()
.registerSingleton("configKubernetesClient", event.getBootstrapContext().get(KubernetesClient.class)));
if (isRetryEnabled(configMapProperties, secretsProperties)) {
registerRetryBeans(configMapProperties, secretsProperties, bootstrapContext, kubernetesClient,
namespaceProvider);
}
else {
if (configMapProperties.isEnabled()) {
Fabric8ConfigMapPropertySourceLocator configMapPropertySourceLocator = new Fabric8ConfigMapPropertySourceLocator(
kubernetesClient, configMapProperties, namespaceProvider);
bootstrapContext.registerIfAbsent(ConfigMapPropertySourceLocator.class,
InstanceSupplier.of(configMapPropertySourceLocator));
bootstrapContext.addCloseListener(event -> event.getApplicationContext().getBeanFactory()
.registerSingleton("configDataConfigMapPropertySourceLocator",
event.getBootstrapContext().get(ConfigMapPropertySourceLocator.class)));
}
if (secretsProperties.isEnabled()) {
Fabric8SecretsPropertySourceLocator secretsPropertySourceLocator = new Fabric8SecretsPropertySourceLocator(
kubernetesClient, secretsProperties, namespaceProvider);
bootstrapContext.registerIfAbsent(SecretsPropertySourceLocator.class,
InstanceSupplier.of(secretsPropertySourceLocator));
bootstrapContext.addCloseListener(event -> event.getApplicationContext().getBeanFactory()
.registerSingleton("configDataSecretsPropertySourceLocator",
event.getBootstrapContext().get(SecretsPropertySourceLocator.class)));
}
}
}
private void registerRetryBeans(ConfigMapConfigProperties configMapProperties,
SecretsConfigProperties secretsProperties, ConfigurableBootstrapContext bootstrapContext,
KubernetesClient kubernetesClient, KubernetesNamespaceProvider namespaceProvider) {
if (configMapProperties.isEnabled()) {
ConfigMapPropertySourceLocator configMapPropertySourceLocator = new Fabric8ConfigMapPropertySourceLocator(
kubernetesClient, configMapProperties, namespaceProvider);
if (isRetryEnabledForConfigMap(configMapProperties)) {
configMapPropertySourceLocator = new ConfigDataRetryableConfigMapPropertySourceLocator(
configMapPropertySourceLocator, configMapProperties);
}
bootstrapContext.registerIfAbsent(ConfigMapPropertySourceLocator.class,
InstanceSupplier.of(configMapPropertySourceLocator));
bootstrapContext.addCloseListener(event -> event.getApplicationContext().getBeanFactory().registerSingleton(
"configDataConfigMapPropertySourceLocator",
event.getBootstrapContext().get(ConfigMapPropertySourceLocator.class)));
}
if (secretsProperties.isEnabled()) {
SecretsPropertySourceLocator secretsPropertySourceLocator = new Fabric8SecretsPropertySourceLocator(
kubernetesClient, secretsProperties, namespaceProvider);
if (isRetryEnabledForSecrets(secretsProperties)) {
secretsPropertySourceLocator = new ConfigDataRetryableSecretsPropertySourceLocator(
secretsPropertySourceLocator, secretsProperties);
}
bootstrapContext.registerIfAbsent(SecretsPropertySourceLocator.class,
InstanceSupplier.of(secretsPropertySourceLocator));
bootstrapContext.addCloseListener(event -> event.getApplicationContext().getBeanFactory().registerSingleton(
"configDataSecretsPropertySourceLocator",
event.getBootstrapContext().get(SecretsPropertySourceLocator.class)));
}
}
protected KubernetesNamespaceProvider kubernetesNamespaceProvider(Environment environment) {
return new KubernetesNamespaceProvider(environment);
}
private Config config(KubernetesClientProperties properties) {
return new Fabric8AutoConfiguration().kubernetesClientConfig(properties);
}
private KubernetesClient kubernetesClient(Config config) {
return new Fabric8AutoConfiguration().kubernetesClient(config);
}
}

View File

@@ -24,6 +24,7 @@ import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnCloudPlatform;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.cloud.CloudPlatform;
import org.springframework.cloud.kubernetes.commons.KubernetesCommonsAutoConfiguration;
import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
@@ -48,6 +49,7 @@ import org.springframework.context.annotation.Import;
@AutoConfigureAfter(KubernetesBootstrapConfiguration.class)
@ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES)
@ConditionalOnKubernetesConfigOrSecretsRetryEnabled
@ConditionalOnProperty(value = "spring.cloud.bootstrap.enabled", havingValue = "true")
public class Fabric8RetryBootstrapConfiguration {
@Bean

View File

@@ -3,3 +3,6 @@ org.springframework.cloud.kubernetes.fabric8.config.reload.ConfigReloadAutoConfi
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.springframework.cloud.kubernetes.fabric8.config.Fabric8BootstrapConfiguration,\
org.springframework.cloud.kubernetes.fabric8.config.Fabric8RetryBootstrapConfiguration
# ConfigData Location Resolvers
org.springframework.boot.context.config.ConfigDataLocationResolver=\
org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigDataLocationResolver

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2013-2019 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.fabric8.config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* @author Charles Moulliard
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
properties = { "spring.application.name=configmap-example", "spring.cloud.kubernetes.reload.enabled=false",
"spring.main.cloud-platform=KUBERNETES", "spring.cloud.bootstrap.enabled=true" })
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
public class BoostrapConfigMapsTests extends ConfigMapsTests {
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2013-2021 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.fabric8.config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.cloud.bootstrap.enabled=true" })
@TestPropertySource("classpath:/application-secrets.properties")
@EnableKubernetesMockClient(crud = true, https = false)
class BoostrapFabric8SecretsPropertySourceTest extends Fabric8SecretsPropertySourceTest {
private static KubernetesClient mockClient;
@BeforeAll
static void setUpBeforeClass() {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2013-2019 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.fabric8.config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example2.ExampleApp;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* @author Charles Moulliard
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = ExampleApp.class,
properties = { "spring.cloud.bootstrap.name=multiplecms", "spring.main.cloud-platform=KUBERNETES",
"spring.cloud.bootstrap.enabled=true" })
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
public class BoostrapMultipleConfigMapsTests extends MultipleConfigMapsTests {
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2013-2021 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.fabric8.config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.include_profile_specific_sources.IncludeProfileSpecificSourcesApp;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* @author wind57
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = IncludeProfileSpecificSourcesApp.class,
properties = { "spring.cloud.bootstrap.name=include-profile-specific-sources",
"spring.main.cloud-platform=KUBERNETES", "spring.cloud.bootstrap.enabled=true" })
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
@ActiveProfiles("dev")
class BootstrapConfigMapWithIncludeProfileSpecificSourcesTests extends ConfigMapWithIncludeProfileSpecificSourcesTests {
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2013-2021 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.fabric8.config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.with_prefix.WithPrefixApp;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* @author wind57
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = WithPrefixApp.class,
properties = { "spring.cloud.bootstrap.name=config-map-name-as-prefix", "spring.main.cloud-platform=KUBERNETES",
"spring.cloud.bootstrap.enabled=true" })
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
class BootstrapConfigMapWithPrefixTests extends ConfigMapWithPrefixTests {
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2013-2019 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.fabric8.config;
import java.io.IOException;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class, properties = {
"spring.application.name=configmap-path-example", "spring.cloud.kubernetes.config.enableApi=false",
"spring.cloud.kubernetes.config.paths=" + BootstrapConfigMapsFromFilePathsTests.FIRST_FILE_NAME_FULL_PATH + ","
+ BootstrapConfigMapsFromFilePathsTests.SECOND_FILE_NAME_FULL_PATH + ","
+ BootstrapConfigMapsFromFilePathsTests.FIRST_FILE_NAME_DUPLICATED_FULL_PATH,
"spring.main.cloud-platform=KUBERNETES", "spring.cloud.bootstrap.enabled=true" })
@EnableKubernetesMockClient(crud = true, https = false)
public class BootstrapConfigMapsFromFilePathsTests extends ConfigMapsFromFilePathsTests {
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() throws IOException {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2013-2019 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.fabric8.config;
import java.io.IOException;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
properties = { "spring.application.name=" + BootstrapConfigMapsMixedTests.APPLICATION_NAME,
"spring.cloud.kubernetes.config.enableApi=true",
"spring.cloud.kubernetes.config.paths=" + BootstrapConfigMapsMixedTests.FILE_NAME_FULL_PATH,
"spring.main.cloud-platform=KUBERNETES", "spring.cloud.bootstrap.enabled=true" })
@EnableKubernetesMockClient(crud = true, https = false)
public class BootstrapConfigMapsMixedTests extends ConfigMapsMixedTests {
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() throws IOException {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2013-2019 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.fabric8.config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
/**
* @author Ali Shahbour
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = RANDOM_PORT, classes = App.class,
properties = { "spring.application.name=configmap-with-active-profile-name-example",
"spring.cloud.kubernetes.reload.enabled=false", "spring.main.cloud-platform=KUBERNETES",
"spring.cloud.bootstrap.enabled=true" })
@ActiveProfiles("development")
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
public class BootstrapConfigMapsWithActiveProfilesNameTests extends ConfigMapsWithActiveProfilesNameTests {
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright 2013-2018 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.fabric8.config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* Tests reading property from YAML document specified by profile expression.
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
properties = { "spring.application.name=configmap-with-profile-example",
"spring.cloud.kubernetes.reload.enabled=false", "spring.main.cloud-platform=KUBERNETES",
"spring.cloud.bootstrap.enabled=true" })
@ActiveProfiles({ "production", "us-east" })
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
public class BootstrapConfigMapsWithProfileExpressionTests extends ConfigMapsWithProfileExpressionTests {
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2013-2019 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.fabric8.config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* @author Charles Moulliard
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
properties = { "spring.application.name=configmap-with-profile-no-active-profiles-example",
"spring.cloud.kubernetes.reload.enabled=false", "spring.main.cloud-platform=KUBERNETES",
"spring.cloud.bootstrap.enabled=true" })
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
public class BootstrapConfigMapsWithProfilesNoActiveProfileTests extends ConfigMapsWithProfilesNoActiveProfileTests {
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2013-2019 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.fabric8.config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* @author Charles Moulliard
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
properties = { "spring.application.name=configmap-with-profile-example",
"spring.cloud.kubernetes.reload.enabled=false", "spring.main.cloud-platform=KUBERNETES",
"spring.cloud.bootstrap.enabled=true" })
@ActiveProfiles("development")
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
public class BootstrapConfigMapsWithProfilesTests extends ConfigMapsWithProfilesTests {
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2013-2019 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.fabric8.config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
properties = { "spring.application.name=configmap-without-profile-example",
"spring.cloud.kubernetes.reload.enabled=false", "spring.main.cloud-platform=KUBERNETES",
"spring.cloud.bootstrap.enabled=true" })
@ActiveProfiles("development")
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
public class BootstrapConfigMapsWithoutProfilesTests extends ConfigMapsWithoutProfilesTests {
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2013-2021 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.fabric8.config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = TestApplication.class,
properties = { "spring.application.name=testapp", "spring.cloud.kubernetes.client.namespace=testns",
"spring.cloud.kubernetes.client.trustCerts=true", "spring.cloud.kubernetes.config.namespace=testns",
"spring.cloud.kubernetes.secrets.enableApi=true", "spring.main.cloud-platform=KUBERNETES",
"spring.cloud.bootstrap.enabled=true" })
@EnableKubernetesMockClient(crud = true, https = false)
public class BootstrapCoreTest extends CoreTest {
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright 2013-2021 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.fabric8.config;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = TestApplication.class,
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.application.name=testapp",
"spring.cloud.kubernetes.client.namespace=testns", "spring.cloud.kubernetes.client.trustCerts=true",
"spring.cloud.kubernetes.config.namespace=testns", "spring.cloud.kubernetes.secrets.enableApi=true",
"spring.cloud.bootstrap.enabled=true" })
public class BootstrapCoreTestClientViaSystemProperties extends CoreTestClientViaSystemProperties {
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2013-2019 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.fabric8.config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example3.MultiSecretsApp;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* @author Haytham Mohamed
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = MultiSecretsApp.class,
properties = { "spring.cloud.bootstrap.name=multiple-secrets", "spring.main.cloud-platform=KUBERNETES",
"spring.cloud.bootstrap.enabled=true" })
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
public class BootstrapMultipleSecretsTests extends MultipleSecretsTests {
// will be injected by KubernetesMockServerExtension
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2013-2021 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.fabric8.config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.include_profile_specific_sources.IncludeProfileSpecificSourcesApp;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* @author wind57
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = IncludeProfileSpecificSourcesApp.class,
properties = { "spring.application.name=include-profile-specific-sources",
"spring.main.cloud-platform=KUBERNETES",
"spring.config.import=kubernetes:,classpath:./include-profile-specific-sources.yaml" })
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
@ActiveProfiles("dev")
class ConfigDataConfigMapWithIncludeProfileSpecificSourcesTests
extends ConfigMapWithIncludeProfileSpecificSourcesTests {
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2013-2021 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.fabric8.config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.with_prefix.WithPrefixApp;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* @author wind57
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = WithPrefixApp.class,
properties = { "spring.application.name=config-map-name-as-prefix", "spring.main.cloud-platform=KUBERNETES",
"spring.config.import=kubernetes:,classpath:./config-map-name-as-prefix.yaml" })
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
class ConfigDataConfigMapWithPrefixTests extends ConfigMapWithPrefixTests {
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2013-2019 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.fabric8.config;
import java.io.IOException;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class, properties = {
"spring.application.name=configmap-path-example", "spring.cloud.kubernetes.config.enableApi=false",
"spring.cloud.kubernetes.config.paths=" + ConfigDataConfigMapsFromFilePathsTests.FIRST_FILE_NAME_FULL_PATH + ","
+ ConfigDataConfigMapsFromFilePathsTests.SECOND_FILE_NAME_FULL_PATH + ","
+ ConfigDataConfigMapsFromFilePathsTests.FIRST_FILE_NAME_DUPLICATED_FULL_PATH,
"spring.main.cloud-platform=KUBERNETES", "spring.config.import=kubernetes:" })
@EnableKubernetesMockClient(crud = true, https = false)
public class ConfigDataConfigMapsFromFilePathsTests extends ConfigMapsFromFilePathsTests {
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() throws IOException {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2013-2019 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.fabric8.config;
import java.io.IOException;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
properties = { "spring.application.name=" + ConfigDataConfigMapsMixedTests.APPLICATION_NAME,
"spring.cloud.kubernetes.config.enableApi=true",
"spring.cloud.kubernetes.config.paths=" + ConfigDataConfigMapsMixedTests.FILE_NAME_FULL_PATH,
"spring.main.cloud-platform=KUBERNETES", "spring.config.import=kubernetes:" })
@EnableKubernetesMockClient(crud = true, https = false)
public class ConfigDataConfigMapsMixedTests extends ConfigMapsMixedTests {
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() throws IOException {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2013-2019 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.fabric8.config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* @author Charles Moulliard
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
properties = { "spring.application.name=configmap-example", "spring.cloud.kubernetes.reload.enabled=false",
"spring.main.cloud-platform=KUBERNETES", "spring.config.import=kubernetes:" })
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
public class ConfigDataConfigMapsTests extends ConfigMapsTests {
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2013-2019 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.fabric8.config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
/**
* @author Ali Shahbour
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = RANDOM_PORT, classes = App.class,
properties = { "spring.application.name=configmap-with-active-profile-name-example",
"spring.cloud.kubernetes.reload.enabled=false", "spring.main.cloud-platform=KUBERNETES",
"spring.config.import=kubernetes:" })
@ActiveProfiles("development")
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
public class ConfigDataConfigMapsWithActiveProfilesNameTests extends ConfigMapsWithActiveProfilesNameTests {
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,51 @@
/*
* Copyright 2013-2018 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.fabric8.config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* Tests reading property from YAML document specified by profile expression.
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
properties = { "spring.application.name=configmap-with-profile-example",
"spring.cloud.kubernetes.reload.enabled=false", "spring.main.cloud-platform=KUBERNETES",
"spring.config.import=kubernetes:" })
@ActiveProfiles({ "production", "us-east" })
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
public class ConfigDataConfigMapsWithProfileExpressionTests extends ConfigMapsWithProfileExpressionTests {
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2013-2019 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.fabric8.config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* @author Charles Moulliard
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
properties = { "spring.application.name=configmap-with-profile-no-active-profiles-example",
"spring.cloud.kubernetes.reload.enabled=false", "spring.main.cloud-platform=KUBERNETES",
"spring.config.import=kubernetes:" })
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
public class ConfigDataConfigMapsWithProfilesNoActiveProfileTests extends ConfigMapsWithProfilesNoActiveProfileTests {
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2013-2019 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.fabric8.config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* @author Charles Moulliard
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
properties = { "spring.application.name=configmap-with-profile-example",
"spring.cloud.kubernetes.reload.enabled=false", "spring.main.cloud-platform=KUBERNETES",
"spring.config.import=kubernetes:" })
@ActiveProfiles("development")
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
public class ConfigDataConfigMapsWithProfilesTests extends ConfigMapsWithProfilesTests {
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2013-2019 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.fabric8.config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
properties = { "spring.application.name=configmap-without-profile-example",
"spring.cloud.kubernetes.reload.enabled=false", "spring.main.cloud-platform=KUBERNETES",
"spring.config.import=kubernetes:" })
@ActiveProfiles("development")
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
public class ConfigDataConfigMapsWithoutProfilesTests extends ConfigMapsWithoutProfilesTests {
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2013-2021 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.fabric8.config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = TestApplication.class,
properties = { "spring.application.name=testapp", "spring.cloud.kubernetes.client.namespace=testns",
"spring.cloud.kubernetes.client.trustCerts=true", "spring.cloud.kubernetes.config.namespace=testns",
"spring.cloud.kubernetes.secrets.enableApi=true", "spring.main.cloud-platform=KUBERNETES",
"spring.config.import=kubernetes:" })
@EnableKubernetesMockClient(crud = true, https = false)
public class ConfigDataCoreTest extends CoreTest {
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright 2013-2021 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.fabric8.config;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = TestApplication.class,
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.application.name=testapp",
"spring.cloud.kubernetes.client.namespace=testns", "spring.cloud.kubernetes.client.trustCerts=true",
"spring.cloud.kubernetes.config.namespace=testns", "spring.cloud.kubernetes.secrets.enableApi=true",
"spring.config.import=kubernetes:" })
public class ConfigDataCoreTestClientViaSystemProperties extends CoreTestClientViaSystemProperties {
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2013-2021 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.fabric8.config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.config.import=kubernetes:" })
@TestPropertySource("classpath:/application-secrets.properties")
@EnableKubernetesMockClient(crud = true, https = false)
class ConfigDataFabric8SecretsPropertySourceTest extends Fabric8SecretsPropertySourceTest {
private static KubernetesClient mockClient;
@BeforeAll
static void setUpBeforeClass() {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2013-2019 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.fabric8.config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example2.ExampleApp;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* @author Charles Moulliard
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = ExampleApp.class,
properties = { "spring.application.name=multiplecms", "spring.main.cloud-platform=KUBERNETES",
"spring.config.import=kubernetes:,classpath:./multiplecms.yml" })
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
public class ConfigDataMultipleConfigMapsTests extends MultipleConfigMapsTests {
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() {
setUpBeforeClass(mockClient);
}
}

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2013-2019 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.fabric8.config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example3.MultiSecretsApp;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* @author Haytham Mohamed
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = MultiSecretsApp.class,
properties = { "spring.cloud.bootstrap.name=multiple-secrets", "spring.main.cloud-platform=KUBERNETES",
"spring.config.import=kubernetes:,classpath:./multiple-secrets.yml" })
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
public class ConfigDataMultipleSecretsTests extends MultipleSecretsTests {
// will be injected by KubernetesMockServerExtension
private static KubernetesClient mockClient;
@BeforeAll
public static void setUpBeforeClass() {
setUpBeforeClass(mockClient);
}
}

View File

@@ -22,41 +22,24 @@ import java.util.Map;
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.include_profile_specific_sources.IncludeProfileSpecificSourcesApp;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;
/**
* @author wind57
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = IncludeProfileSpecificSourcesApp.class,
properties = { "spring.cloud.bootstrap.name=include-profile-specific-sources",
"spring.main.cloud-platform=KUBERNETES" })
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
@ActiveProfiles("dev")
class ConfigMapWithIncludeProfileSpecificSourcesTests {
abstract class ConfigMapWithIncludeProfileSpecificSourcesTests {
private static KubernetesClient mockClient;
@Autowired
private WebTestClient webClient;
@BeforeAll
public static void setUpBeforeClass() {
public static void setUpBeforeClass(KubernetesClient mockClient) {
ConfigMapWithIncludeProfileSpecificSourcesTests.mockClient = mockClient;
// Configure the kubernetes master url to point to the mock server
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl());
System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true");

View File

@@ -22,9 +22,7 @@ import java.util.Map;
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -43,17 +41,15 @@ import org.springframework.test.web.reactive.server.WebTestClient;
properties = { "spring.cloud.bootstrap.name=config-map-name-as-prefix",
"spring.main.cloud-platform=KUBERNETES" })
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
class ConfigMapWithPrefixTests {
abstract class ConfigMapWithPrefixTests {
private static KubernetesClient mockClient;
@Autowired
private WebTestClient webClient;
@BeforeAll
public static void setUpBeforeClass() {
public static void setUpBeforeClass(KubernetesClient mockClient) {
ConfigMapWithPrefixTests.mockClient = mockClient;
// Configure the kubernetes master url to point to the mock server
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl());
System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true");

View File

@@ -22,9 +22,7 @@ import java.nio.file.Paths;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -44,8 +42,7 @@ import static org.assertj.core.util.Lists.newArrayList;
+ ConfigMapsFromFilePathsTests.SECOND_FILE_NAME_FULL_PATH + ","
+ ConfigMapsFromFilePathsTests.FIRST_FILE_NAME_DUPLICATED_FULL_PATH,
"spring.main.cloud-platform=KUBERNETES" })
@EnableKubernetesMockClient(crud = true, https = false)
public class ConfigMapsFromFilePathsTests {
abstract class ConfigMapsFromFilePathsTests {
protected static final String FILES_ROOT_PATH = "/tmp/scktests";
@@ -66,13 +63,10 @@ public class ConfigMapsFromFilePathsTests {
protected static final String FIRST_FILE_NAME_DUPLICATED_FULL_PATH = FILES_ROOT_PATH + "/" + FILES_SUB_PATH + "/"
+ FIRST_FILE_NAME;
private static KubernetesClient mockClient;
@Autowired
private WebTestClient webClient;
@BeforeAll
public static void setUpBeforeClass() throws IOException {
public static void setUpBeforeClass(KubernetesClient mockClient) throws IOException {
// Configure the kubernetes master url to point to the mock server
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl());

View File

@@ -25,28 +25,15 @@ import io.fabric8.kubernetes.api.model.ConfigMap;
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;
import static org.assertj.core.util.Lists.newArrayList;
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
properties = { "spring.application.name=" + ConfigMapsMixedTests.APPLICATION_NAME,
"spring.cloud.kubernetes.config.enableApi=true",
"spring.cloud.kubernetes.config.paths=" + ConfigMapsMixedTests.FILE_NAME_FULL_PATH,
"spring.main.cloud-platform=KUBERNETES" })
@EnableKubernetesMockClient(crud = true, https = false)
public class ConfigMapsMixedTests {
abstract class ConfigMapsMixedTests {
protected static final String FILES_ROOT_PATH = "/tmp/scktests";
@@ -56,13 +43,10 @@ public class ConfigMapsMixedTests {
protected static final String APPLICATION_NAME = "configmap-mixed-example";
private static KubernetesClient mockClient;
@Autowired
private WebTestClient webClient;
@BeforeAll
public static void setUpBeforeClass() throws IOException {
public static void setUpBeforeClass(KubernetesClient mockClient) throws IOException {
// Configure the kubernetes master url to point to the mock server
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl());

View File

@@ -22,16 +22,9 @@ import io.fabric8.kubernetes.api.model.ConfigMap;
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;
import static org.assertj.core.api.Assertions.assertThat;
@@ -39,13 +32,7 @@ import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Charles Moulliard
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
properties = { "spring.application.name=configmap-example", "spring.cloud.kubernetes.reload.enabled=false",
"spring.main.cloud-platform=KUBERNETES" })
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
public class ConfigMapsTests {
abstract class ConfigMapsTests {
private static final String APPLICATION_NAME = "configmap-example";
@@ -57,9 +44,8 @@ public class ConfigMapsTests {
@Autowired
private WebTestClient webClient;
@BeforeAll
public static void setUpBeforeClass() {
public static void setUpBeforeClass(KubernetesClient mockClient) {
ConfigMapsTests.mockClient = mockClient;
// Configure the kubernetes master url to point to the mock server
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl());
System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true");

View File

@@ -21,47 +21,27 @@ import java.util.HashMap;
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
import static org.springframework.cloud.kubernetes.fabric8.config.ConfigMapTestUtil.readResourceFile;
/**
* @author Ali Shahbour
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = RANDOM_PORT, classes = App.class,
properties = { "spring.application.name=configmap-with-active-profile-name-example",
"spring.cloud.kubernetes.reload.enabled=false", "spring.main.cloud-platform=KUBERNETES" })
@ActiveProfiles("development")
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
public class ConfigMapsWithActiveProfilesNameTests {
abstract class ConfigMapsWithActiveProfilesNameTests {
private static final String APPLICATION_NAME = "configmap-with-active-profile-name-example";
private static KubernetesClient mockClient;
@Autowired(required = false)
Config config;
@Autowired
private WebTestClient webClient;
@BeforeAll
public static void setUpBeforeClass() {
public static void setUpBeforeClass(KubernetesClient mockClient) {
// Configure the kubernetes master url to point to the mock server
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl());
System.setProperty(Config.KUBERNETES_TRUST_CERT_SYSTEM_PROPERTY, "true");

View File

@@ -21,41 +21,23 @@ import java.util.HashMap;
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;
/**
* Tests reading property from YAML document specified by profile expression.
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
properties = { "spring.application.name=configmap-with-profile-example",
"spring.cloud.kubernetes.reload.enabled=false", "spring.main.cloud-platform=KUBERNETES" })
@ActiveProfiles({ "production", "us-east" })
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
public class ConfigMapsWithProfileExpressionTests {
private static KubernetesClient mockClient;
abstract class ConfigMapsWithProfileExpressionTests {
private static final String APPLICATION_NAME = "configmap-with-profile-example";
@Autowired
private WebTestClient webClient;
@BeforeAll
public static void setUpBeforeClass() {
public static void setUpBeforeClass(KubernetesClient mockClient) {
// Configure the kubernetes master url to point to the mock server
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl());

View File

@@ -21,16 +21,9 @@ import java.util.HashMap;
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;
import static org.springframework.cloud.kubernetes.fabric8.config.ConfigMapTestUtil.readResourceFile;
@@ -38,23 +31,14 @@ import static org.springframework.cloud.kubernetes.fabric8.config.ConfigMapTestU
/**
* @author Charles Moulliard
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
properties = { "spring.application.name=configmap-with-profile-no-active-profiles-example",
"spring.cloud.kubernetes.reload.enabled=false", "spring.main.cloud-platform=KUBERNETES" })
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
public class ConfigMapsWithProfilesNoActiveProfileTests {
abstract class ConfigMapsWithProfilesNoActiveProfileTests {
private static final String APPLICATION_NAME = "configmap-with-profile-no-active-profiles-example";
private static KubernetesClient mockClient;
@Autowired
private WebTestClient webClient;
@BeforeAll
public static void setUpBeforeClass() {
public static void setUpBeforeClass(KubernetesClient mockClient) {
// Configure the kubernetes master url to point to the mock server
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl());

View File

@@ -21,43 +21,25 @@ import java.util.HashMap;
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;
/**
* @author Charles Moulliard
*/
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
properties = { "spring.application.name=configmap-with-profile-example",
"spring.cloud.kubernetes.reload.enabled=false", "spring.main.cloud-platform=KUBERNETES" })
@ActiveProfiles("development")
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
public class ConfigMapsWithProfilesTests {
abstract class ConfigMapsWithProfilesTests {
private static final String APPLICATION_NAME = "configmap-with-profile-example";
private static KubernetesClient mockClient;
@Autowired(required = false)
Config config;
@Autowired
private WebTestClient webClient;
@BeforeAll
public static void setUpBeforeClass() {
public static void setUpBeforeClass(KubernetesClient mockClient) {
// Configure the kubernetes master url to point to the mock server
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl());

View File

@@ -21,37 +21,19 @@ import java.util.HashMap;
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
properties = { "spring.application.name=configmap-without-profile-example",
"spring.cloud.kubernetes.reload.enabled=false", "spring.main.cloud-platform=KUBERNETES" })
@ActiveProfiles("development")
@AutoConfigureWebTestClient
@EnableKubernetesMockClient(crud = true, https = false)
public class ConfigMapsWithoutProfilesTests {
abstract class ConfigMapsWithoutProfilesTests {
private static final String APPLICATION_NAME = "configmap-without-profile-example";
private static KubernetesClient mockClient;
@Autowired
private WebTestClient webClient;
@BeforeAll
public static void setUpBeforeClass() {
public static void setUpBeforeClass(KubernetesClient mockClient) {
// Configure the kubernetes master url to point to the mock server
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl());

View File

@@ -23,25 +23,14 @@ import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
import io.fabric8.kubernetes.api.model.SecretBuilder;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.env.Environment;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = TestApplication.class,
properties = { "spring.application.name=testapp", "spring.cloud.kubernetes.client.namespace=testns",
"spring.cloud.kubernetes.client.trustCerts=true", "spring.cloud.kubernetes.config.namespace=testns",
"spring.cloud.kubernetes.secrets.enableApi=true", "spring.main.cloud-platform=KUBERNETES" })
@EnableKubernetesMockClient(crud = true, https = false)
public class CoreTest {
abstract class CoreTest {
private static KubernetesClient mockClient;
@@ -51,9 +40,8 @@ public class CoreTest {
@Autowired
private Config config;
@BeforeAll
public static void setUpBeforeClass() {
public static void setUpBeforeClass(KubernetesClient mockClient) {
CoreTest.mockClient = mockClient;
Map<String, String> data1 = new HashMap<>();
data1.put("spring.kubernetes.test.value", "value1");
mockClient.configMaps().inNamespace("testns").create(

View File

@@ -20,20 +20,12 @@ import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.KubernetesClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = TestApplication.class,
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.application.name=testapp",
"spring.cloud.kubernetes.client.namespace=testns", "spring.cloud.kubernetes.client.trustCerts=true",
"spring.cloud.kubernetes.config.namespace=testns", "spring.cloud.kubernetes.secrets.enableApi=true" })
public class CoreTestClientViaSystemProperties {
abstract class CoreTestClientViaSystemProperties {
@Autowired
private KubernetesClient client;

View File

@@ -22,33 +22,19 @@ import io.fabric8.kubernetes.api.model.Secret;
import io.fabric8.kubernetes.api.model.SecretBuilder;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
import org.springframework.core.env.Environment;
import org.springframework.core.env.PropertySource;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import static java.util.Collections.singletonMap;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
properties = "spring.main.cloud-platform=KUBERNETES")
@TestPropertySource("classpath:/application-secrets.properties")
@EnableKubernetesMockClient(crud = true, https = false)
class Fabric8SecretsPropertySourceTest {
abstract class Fabric8SecretsPropertySourceTest {
private static final String NAMESPACE = "test";
private static KubernetesClient mockClient;
private static final String SECRET_VALUE = "secretValue";
@Autowired
@@ -57,8 +43,7 @@ class Fabric8SecretsPropertySourceTest {
@Autowired
private Environment environment;
@BeforeAll
static void setUpBeforeClass() {
static void setUpBeforeClass(KubernetesClient mockClient) {
// Configure the kubernetes master url to point to the mock server
System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, mockClient.getConfiguration().getMasterUrl());

View File

@@ -41,13 +41,21 @@ public class KubernetesConfigConfigurationTest extends KubernetesConfigTestBase
private static KubernetesClient mockClient;
@Test
public void kubernetesWhenKubernetesDefaultEnabled() {
public void kubernetesBootstrapWhenKubernetesDefaultEnabled() {
setup(KubernetesClientTestConfiguration.class, "spring.main.cloud-platform=KUBERNETES",
"spring.cloud.kubernetes.client.namespace=default");
"spring.cloud.kubernetes.client.namespace=default", "spring.cloud.bootstrap.enabled=true");
assertThat(getContext().containsBean("configMapPropertySourceLocator")).isTrue();
assertThat(getContext().containsBean("secretsPropertySourceLocator")).isTrue();
}
@Test
public void kubernetesConfigDataWhenKubernetesDefaultEnabled() {
setup(KubernetesClientTestConfiguration.class, "spring.main.cloud-platform=KUBERNETES",
"spring.cloud.kubernetes.client.namespace=default", "spring.config.import=kubernetes:");
assertThat(getContext().containsBean("configDataConfigMapPropertySourceLocator")).isTrue();
assertThat(getContext().containsBean("configDataSecretsPropertySourceLocator")).isTrue();
}
@Test
public void kubernetesWhenKubernetesDisabled() {
setup(KubernetesClientTestConfiguration.class);
@@ -64,31 +72,59 @@ public class KubernetesConfigConfigurationTest extends KubernetesConfigTestBase
}
@Test
public void kubernetesWhenKubernetesConfigEnabledButSecretDisabled() {
public void kubernetesBootstrapWhenKubernetesConfigEnabledButSecretDisabled() {
setup(KubernetesClientTestConfiguration.class, "spring.cloud.kubernetes.config.enabled=true",
"spring.cloud.kubernetes.secrets.enabled=false", "spring.cloud.kubernetes.client.namespace=default",
"spring.main.cloud-platform=KUBERNETES");
"spring.main.cloud-platform=KUBERNETES", "spring.cloud.bootstrap.enabled=true");
assertThat(getContext().containsBean("configMapPropertySourceLocator")).isTrue();
assertThat(getContext().containsBean("secretsPropertySourceLocator")).isFalse();
}
@Test
public void kubernetesWhenKubernetesConfigDisabledButSecretEnabled() {
public void kubernetesConfigDataWhenKubernetesConfigEnabledButSecretDisabled() {
setup(KubernetesClientTestConfiguration.class, "spring.cloud.kubernetes.config.enabled=true",
"spring.cloud.kubernetes.secrets.enabled=false", "spring.cloud.kubernetes.client.namespace=default",
"spring.main.cloud-platform=KUBERNETES", "spring.config.import=kubernetes:");
assertThat(getContext().containsBean("configDataConfigMapPropertySourceLocator")).isTrue();
assertThat(getContext().containsBean("configDataSecretsPropertySourceLocator")).isFalse();
}
@Test
public void kubernetesBootstrapWhenKubernetesConfigDisabledButSecretEnabled() {
setup(KubernetesClientTestConfiguration.class, "spring.cloud.kubernetes.config.enabled=false",
"spring.cloud.kubernetes.secrets.enabled=true", "spring.main.cloud-platform=KUBERNETES");
"spring.cloud.kubernetes.secrets.enabled=true", "spring.main.cloud-platform=KUBERNETES",
"spring.cloud.bootstrap.enabled=true");
assertThat(getContext().containsBean("configMapPropertySourceLocator")).isFalse();
assertThat(getContext().containsBean("secretsPropertySourceLocator")).isTrue();
}
@Test
public void kubernetesConfigWhenKubernetesEnabledAndKubernetesConfigEnabled() {
public void kubernetesConfigDataWhenKubernetesConfigDisabledButSecretEnabled() {
setup(KubernetesClientTestConfiguration.class, "spring.cloud.kubernetes.config.enabled=false",
"spring.cloud.kubernetes.secrets.enabled=true", "spring.main.cloud-platform=KUBERNETES",
"spring.config.import=kubernetes:");
assertThat(getContext().containsBean("configDataConfigMapPropertySourceLocator")).isFalse();
assertThat(getContext().containsBean("configDataSecretsPropertySourceLocator")).isTrue();
}
@Test
public void kubernetesBootstrapConfigWhenKubernetesEnabledAndKubernetesConfigEnabled() {
setup(KubernetesClientTestConfiguration.class, "spring.cloud.kubernetes.config.enabled=true",
"spring.cloud.kubernetes.secrets.enabled=true", "spring.cloud.kubernetes.client.namespace=default",
"spring.main.cloud-platform=KUBERNETES");
"spring.main.cloud-platform=KUBERNETES", "spring.cloud.bootstrap.enabled=true");
assertThat(getContext().containsBean("configMapPropertySourceLocator")).isTrue();
assertThat(getContext().containsBean("secretsPropertySourceLocator")).isTrue();
}
@Test
public void kubernetesConfigDataConfigWhenKubernetesEnabledAndKubernetesConfigEnabled() {
setup(KubernetesClientTestConfiguration.class, "spring.cloud.kubernetes.config.enabled=true",
"spring.cloud.kubernetes.secrets.enabled=true", "spring.cloud.kubernetes.client.namespace=default",
"spring.main.cloud-platform=KUBERNETES", "spring.config.import=kubernetes:");
assertThat(getContext().containsBean("configDataConfigMapPropertySourceLocator")).isTrue();
assertThat(getContext().containsBean("configDataSecretsPropertySourceLocator")).isTrue();
}
@Test
public void kubernetesConfigWhenKubernetesEnabledAndKubernetesConfigDisabled() {
setup(KubernetesClientTestConfiguration.class, "spring.cloud.kubernetes.config.enabled=false");

Some files were not shown because too many files have changed in this diff Show More