Nested split (#962)
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.actuate.health.ReactiveHealthContributorRegistry;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.client.example.App;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
|
||||
properties = { "management.health.kubernetes.enabled=false", "management.endpoint.health.show-details=always",
|
||||
"management.endpoint.health.show-components=always",
|
||||
"management.endpoints.web.exposure.include=health" })
|
||||
class ActuatorDisabledHealthTest {
|
||||
|
||||
@Autowired
|
||||
private ReactiveHealthContributorRegistry registry;
|
||||
|
||||
@Autowired
|
||||
private WebTestClient webClient;
|
||||
|
||||
@Value("${local.server.port}")
|
||||
private int port;
|
||||
|
||||
@Test
|
||||
void healthEndpointShouldContainKubernetes() {
|
||||
this.webClient.get().uri("http://localhost:{port}/actuator/health", this.port)
|
||||
.accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isOk().expectBody(String.class)
|
||||
.value(Matchers.not(Matchers.containsString("kubernetes")));
|
||||
|
||||
Assertions.assertNull(registry.getContributor("kubernetes"),
|
||||
"reactive kubernetes contributor must NOT be present when 'management.health.kubernetes.enabled=false'");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.actuate.health.ReactiveHealthContributorRegistry;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.client.example.App;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
|
||||
properties = { "management.health.kubernetes.enabled=true", "management.endpoint.health.show-details=always",
|
||||
"management.endpoint.health.show-components=always", "management.endpoints.web.exposure.include=health",
|
||||
"spring.main.cloud-platform=KUBERNETES" })
|
||||
class ActuatorEnabledHealthTest {
|
||||
|
||||
@Autowired
|
||||
private WebTestClient webClient;
|
||||
|
||||
@Autowired
|
||||
private ReactiveHealthContributorRegistry registry;
|
||||
|
||||
@Value("${local.server.port}")
|
||||
private int port;
|
||||
|
||||
@Test
|
||||
void healthEndpointShouldContainKubernetes() {
|
||||
this.webClient.get().uri("http://localhost:{port}/actuator/health", this.port)
|
||||
.accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isOk().expectBody(String.class)
|
||||
.value(Matchers.containsString("kubernetes"));
|
||||
|
||||
Assertions.assertNotNull(registry.getContributor("kubernetes"),
|
||||
"reactive kubernetes contributor must be present when 'management.health.kubernetes.enabled=true'");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.default_api;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
|
||||
import io.kubernetes.client.openapi.ApiClient;
|
||||
import okhttp3.Request;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Robert McNees
|
||||
*
|
||||
* This tests that the apiClient created in KubernetesClientAutoConfiguration will not set
|
||||
* itself as the default apiClient. This is to avoid overwriting the user's
|
||||
* defaultApiClient if they include this project.
|
||||
*
|
||||
* kubernetes informer is disabled because KubernetesInformerAutoConfiguration creates a
|
||||
* defaultApiClient that will be autowired instead of the ApiClient created in
|
||||
* KubernetesClientAutoConfiguration
|
||||
*/
|
||||
@SpringBootTest(classes = App.class,
|
||||
properties = { "kubernetes.informer.enabled=false", "spring.main.cloud-platform=KUBERNETES" })
|
||||
class ApiClientUserAgentDefaultHeader {
|
||||
|
||||
@Autowired
|
||||
private ApiClient apiClient;
|
||||
|
||||
@Test
|
||||
void testApiClientUserAgentDefaultHeader() throws MalformedURLException {
|
||||
assertThat(apiClient).isNotNull();
|
||||
Request.Builder builder = new Request.Builder();
|
||||
apiClient.processHeaderParams(Collections.emptyMap(), builder);
|
||||
assertThat(builder.url(new URL("http://example.com")).build().headers().get("User-Agent"))
|
||||
.isEqualTo("Spring-Cloud-Kubernetes-Application");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.default_api;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
|
||||
import io.kubernetes.client.openapi.ApiClient;
|
||||
import okhttp3.Request;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Robert McNees
|
||||
*
|
||||
* This tests that the apiClient created in KubernetesClientAutoConfiguration will not set
|
||||
* itself as the default apiClient. This is to avoid overwriting the user's
|
||||
* defaultApiClient if they include this project.
|
||||
*
|
||||
* kubernetes informer is disabled because KubernetesInformerAutoConfiguration creates a
|
||||
* defaultApiClient that will be autowired instead of the ApiClient created in
|
||||
* KubernetesClientAutoConfiguration
|
||||
*/
|
||||
@SpringBootTest(classes = App.class, properties = { "kubernetes.informer.enabled=false",
|
||||
"spring.cloud.kubernetes.client.userAgent=non-default", "spring.main.cloud-platform=KUBERNETES" })
|
||||
class ApiClientUserAgentNonDefaultHeader {
|
||||
|
||||
@Autowired
|
||||
private ApiClient apiClient;
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void testApiClientUserAgentDefaultHeader() throws MalformedURLException {
|
||||
assertThat(apiClient).isNotNull();
|
||||
Request.Builder builder = new Request.Builder();
|
||||
apiClient.processHeaderParams(Collections.emptyMap(), builder);
|
||||
assertThat(builder.url(new URL("http://example.com")).build().headers().get("User-Agent"))
|
||||
.isEqualTo("non-default");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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.default_api;
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
class App {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.default_api;
|
||||
|
||||
import io.kubernetes.client.openapi.ApiClient;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Robert McNees
|
||||
*
|
||||
* This tests that the apiClient created in KubernetesClientAutoConfiguration will not set
|
||||
* itself as the default apiClient. This is to avoid overwriting the user's
|
||||
* defaultApiClient if they include this project.
|
||||
*
|
||||
* kubernetes informer is disabled because KubernetesInformerAutoConfiguration creates a
|
||||
* defaultApiClient that will be autowired instead of the ApiClient created in
|
||||
* KubernetesClientAutoConfiguration
|
||||
*/
|
||||
@SpringBootTest(classes = App.class,
|
||||
properties = { "kubernetes.informer.enabled=false", "spring.main.cloud-platform=KUBERNETES" })
|
||||
class DefaultApiClientNotSameAsApiClient {
|
||||
|
||||
@Autowired
|
||||
private ApiClient apiClient;
|
||||
|
||||
@Test
|
||||
void testCreatedApiClientIsNotDefault() {
|
||||
assertThat(apiClient).isNotNull();
|
||||
|
||||
ApiClient defaultApiClient = io.kubernetes.client.openapi.Configuration.getDefaultApiClient();
|
||||
assertThat(defaultApiClient).isNotNull();
|
||||
|
||||
assertThat(defaultApiClient).isNotSameAs(apiClient);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* 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.client.default_api;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Collections;
|
||||
|
||||
import io.kubernetes.client.openapi.ApiClient;
|
||||
import okhttp3.Request;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Robert McNees
|
||||
*
|
||||
* This tests that the apiClient created in KubernetesClientAutoConfiguration will not set
|
||||
* itself as the default apiClient. This is to avoid overwriting the user's
|
||||
* defaultApiClient if they include this project.
|
||||
*
|
||||
* kubernetes informer is disabled because KubernetesInformerAutoConfiguration creates a
|
||||
* defaultApiClient that will be autowired instead of the ApiClient created in
|
||||
* KubernetesClientAutoConfiguration
|
||||
*/
|
||||
|
||||
class KubernetesClientDefaultApiClientTests {
|
||||
|
||||
private static final String DISABLE_INFORMER = "kubernetes.informer.enabled=false";
|
||||
|
||||
private static final String USER_AGENT = "spring.cloud.kubernetes.client.userAgent=non-default";
|
||||
|
||||
private static final String ENABLED_K8S = "spring.main.cloud-platform=KUBERNETES";
|
||||
|
||||
@SpringBootTest(classes = KubernetesClientDefaultApiClientTests.App.class,
|
||||
properties = { DISABLE_INFORMER, ENABLED_K8S })
|
||||
@Nested
|
||||
class DefaultApiClientNotSameAsApiClient {
|
||||
|
||||
@Autowired
|
||||
private ApiClient apiClient;
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void testCreatedApiClientIsNotDefault() {
|
||||
assertThat(apiClient).isNotNull();
|
||||
|
||||
ApiClient defaultApiClient = io.kubernetes.client.openapi.Configuration.getDefaultApiClient();
|
||||
assertThat(defaultApiClient).isNotNull();
|
||||
|
||||
assertThat(defaultApiClient).isNotSameAs(apiClient);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SpringBootTest(classes = KubernetesClientDefaultApiClientTests.App.class,
|
||||
properties = { DISABLE_INFORMER, ENABLED_K8S })
|
||||
@Nested
|
||||
class ApiClientUserAgentDefaultHeader {
|
||||
|
||||
@Autowired
|
||||
private ApiClient apiClient;
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void testApiClientUserAgentDefaultHeader() throws MalformedURLException {
|
||||
assertThat(apiClient).isNotNull();
|
||||
Request.Builder builder = new Request.Builder();
|
||||
apiClient.processHeaderParams(Collections.emptyMap(), builder);
|
||||
assertThat(builder.url(new URL("http://example.com")).build().headers().get("User-Agent"))
|
||||
.isEqualTo("Spring-Cloud-Kubernetes-Application");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SpringBootTest(classes = KubernetesClientDefaultApiClientTests.App.class,
|
||||
properties = { DISABLE_INFORMER, USER_AGENT, ENABLED_K8S })
|
||||
@Nested
|
||||
class ApiClientUserAgentNonDefaultHeader {
|
||||
|
||||
@Autowired
|
||||
private ApiClient apiClient;
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void testApiClientUserAgentDefaultHeader() throws MalformedURLException {
|
||||
assertThat(apiClient).isNotNull();
|
||||
Request.Builder builder = new Request.Builder();
|
||||
apiClient.processHeaderParams(Collections.emptyMap(), builder);
|
||||
assertThat(builder.url(new URL("http://example.com")).build().headers().get("User-Agent"))
|
||||
.isEqualTo("non-default");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SpringBootApplication
|
||||
static class App {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class Application {
|
||||
|
||||
}
|
||||
@@ -1,175 +0,0 @@
|
||||
/*
|
||||
* 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.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
public class KubernetesClientBootstrapConfigurationTests {
|
||||
|
||||
@SpringBootApplication
|
||||
static class Application {
|
||||
|
||||
}
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class,
|
||||
properties = { "kubernetes.informer.enabled=false", "kubernetes.manifests.enabled=false" })
|
||||
@Nested
|
||||
class KubernetesDisabled {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void configAndSecretsBeansAreNotPresent() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientConfigMapPropertySourceLocator.class)).hasSize(0);
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientSecretsPropertySourceLocator.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@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" })
|
||||
@Nested
|
||||
class KubernetesEnabledOnPurpose {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void configAndSecretsBeansArePresent() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientConfigMapPropertySourceLocator.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientSecretsPropertySourceLocator.class)).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class,
|
||||
properties = { "spring.cloud.kubernetes.client.namespace=default",
|
||||
"spring.main.cloud-platform=KUBERNETES" })
|
||||
@Nested
|
||||
class KubernetesEnabled {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void configAndSecretsBeansArePresent() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientConfigMapPropertySourceLocator.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientSecretsPropertySourceLocator.class)).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class,
|
||||
properties = { "spring.cloud.kubernetes.config.enabled=false", "spring.main.cloud-platform=KUBERNETES" })
|
||||
@Nested
|
||||
class KubernetesEnabledConfigDisabled {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void secretsOnlyPresent() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientConfigMapPropertySourceLocator.class)).hasSize(0);
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientSecretsPropertySourceLocator.class)).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@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" })
|
||||
@Nested
|
||||
class KubernetesEnabledSecretsDisabled {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void secretsOnlyPresent() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientConfigMapPropertySourceLocator.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientSecretsPropertySourceLocator.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class,
|
||||
properties = { "spring.cloud.kubernetes.secrets.enabled=false",
|
||||
"spring.cloud.kubernetes.config.enabled=false", "spring.main.cloud-platform=KUBERNETES" })
|
||||
@Nested
|
||||
class KubernetesEnabledSecretsAndConfigDisabled {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void secretsOnlyPresent() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientConfigMapPropertySourceLocator.class)).hasSize(0);
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientSecretsPropertySourceLocator.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// tests that @ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES) has the desired
|
||||
// effect, meaning when it is enabled, both property sources are present
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class,
|
||||
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.cloud.kubernetes.client.namespace=abc" })
|
||||
@Nested
|
||||
class KubernetesClientBootstrapConfigurationInsideK8s {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void bothPresent() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientConfigMapPropertySourceLocator.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientSecretsPropertySourceLocator.class)).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// tests that @ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES) has the desired
|
||||
// effect, meaning when it is disabled, no property source bean is present
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class,
|
||||
properties = { "kubernetes.manifests.enabled=false" })
|
||||
@Nested
|
||||
class KubernetesClientBootstrapConfigurationNotInsideK8s {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void bothMissing() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientConfigMapPropertySourceLocator.class)).hasSize(0);
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientSecretsPropertySourceLocator.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,282 +0,0 @@
|
||||
/*
|
||||
* 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.client.config;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.github.tomakehurst.wiremock.WireMockServer;
|
||||
import com.github.tomakehurst.wiremock.client.WireMock;
|
||||
import io.kubernetes.client.openapi.JSON;
|
||||
import io.kubernetes.client.openapi.models.V1ConfigMap;
|
||||
import io.kubernetes.client.openapi.models.V1ConfigMapList;
|
||||
import io.kubernetes.client.openapi.models.V1ObjectMeta;
|
||||
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.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.MockedStatic;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
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.context.ApplicationContext;
|
||||
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.stubFor;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author Isik Erhan
|
||||
*/
|
||||
public class KubernetesClientConfigMapPropertySourceLocatorRetryTests {
|
||||
|
||||
private static final String API = "/api/v1/namespaces/default/configmaps";
|
||||
|
||||
private static final String SECRETS_API = "/api/v1/namespaces/default/secrets";
|
||||
|
||||
private static WireMockServer wireMockServer;
|
||||
|
||||
private static MockedStatic<KubernetesClientUtils> clientUtilsMock;
|
||||
|
||||
@BeforeAll
|
||||
public 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());
|
||||
stubConfigMapAndSecretsDefaults();
|
||||
}
|
||||
|
||||
private static void stubConfigMapAndSecretsDefaults() {
|
||||
// return empty config map / secret list to not fail context creation
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(new V1ConfigMapList()))));
|
||||
stubFor(get(SECRETS_API)
|
||||
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(new V1SecretList()))));
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void teardown() {
|
||||
wireMockServer.stop();
|
||||
clientUtilsMock.close();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void afterEach() {
|
||||
WireMock.reset();
|
||||
stubConfigMapAndSecretsDefaults();
|
||||
}
|
||||
|
||||
@Nested
|
||||
@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 {
|
||||
|
||||
@SpyBean
|
||||
private KubernetesClientConfigMapPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Test
|
||||
public void locateShouldNotRetryWhenThereIsNoFailure() {
|
||||
|
||||
Map<String, String> data = new HashMap<>();
|
||||
data.put("some.prop", "theValue");
|
||||
data.put("some.number", "0");
|
||||
|
||||
V1ConfigMapList configMapList = new V1ConfigMapList()
|
||||
.addItemsItem(new V1ConfigMap().metadata(new V1ObjectMeta().name("application")).data(data));
|
||||
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(configMapList))));
|
||||
|
||||
PropertySource<?> propertySource = Assertions
|
||||
.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
|
||||
|
||||
// verify locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
|
||||
// validate the contents of the property source
|
||||
assertThat(propertySource.getProperty("some.prop")).isEqualTo("theValue");
|
||||
assertThat(propertySource.getProperty("some.number")).isEqualTo("0");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void locateShouldRetryAndRecover() {
|
||||
Map<String, String> data = new HashMap<>();
|
||||
data.put("some.prop", "theValue");
|
||||
data.put("some.number", "0");
|
||||
|
||||
V1ConfigMapList configMapList = new V1ConfigMapList()
|
||||
.addItemsItem(new V1ConfigMap().metadata(new V1ObjectMeta().name("application")).data(data));
|
||||
|
||||
// fail 3 times
|
||||
stubFor(get(API).inScenario("Retry and Recover").whenScenarioStateIs(STARTED)
|
||||
.willReturn(aResponse().withStatus(500)).willSetStateTo("Failed once"));
|
||||
|
||||
stubFor(get(API).inScenario("Retry and Recover").whenScenarioStateIs("Failed once")
|
||||
.willReturn(aResponse().withStatus(500)).willSetStateTo("Failed twice"));
|
||||
|
||||
stubFor(get(API).inScenario("Retry and Recover").whenScenarioStateIs("Failed twice")
|
||||
.willReturn(aResponse().withStatus(500)).willSetStateTo("Failed thrice"));
|
||||
|
||||
// then succeed
|
||||
stubFor(get(API).inScenario("Retry and Recover").whenScenarioStateIs("Failed thrice")
|
||||
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(configMapList))));
|
||||
|
||||
PropertySource<?> propertySource = Assertions
|
||||
.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
|
||||
|
||||
// verify retried 4 times
|
||||
verify(propertySourceLocator, times(4)).locate(any());
|
||||
|
||||
// validate the contents of the property source
|
||||
assertThat(propertySource.getProperty("some.prop")).isEqualTo("theValue");
|
||||
assertThat(propertySource.getProperty("some.number")).isEqualTo("0");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void locateShouldRetryAndFail() {
|
||||
// fail all the 5 requests
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
|
||||
|
||||
assertThatThrownBy(() -> propertySourceLocator.locate(new MockEnvironment()))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Unable to read ConfigMap with name 'application' in namespace 'default'");
|
||||
|
||||
// verify retried 5 times until failure
|
||||
verify(propertySourceLocator, times(5)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
@SpringBootTest(
|
||||
webEnvironment = SpringBootTest.WebEnvironment.NONE, properties = {
|
||||
"spring.cloud.kubernetes.client.namespace=default", "spring.main.cloud-platform=KUBERNETES" },
|
||||
classes = App.class)
|
||||
class ConfigFailFastDisabled {
|
||||
|
||||
@SpyBean
|
||||
private KubernetesClientConfigMapPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Test
|
||||
public void locateShouldNotRetry() {
|
||||
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
|
||||
|
||||
Assertions.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
|
||||
|
||||
// verify locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
@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 {
|
||||
|
||||
@SpyBean
|
||||
private KubernetesClientConfigMapPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void locateShouldFailWithoutRetrying() {
|
||||
|
||||
/*
|
||||
* Enabling secrets retry causes Spring Retry to be enabled and a
|
||||
* RetryOperationsInterceptor bean with NeverRetryPolicy for config maps to be
|
||||
* defined. ConfigMapPropertySourceLocator should not retry even Spring Retry
|
||||
* is enabled.
|
||||
*/
|
||||
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
|
||||
|
||||
assertThat(context.containsBean("kubernetesConfigRetryInterceptor")).isTrue();
|
||||
assertThatThrownBy(() -> propertySourceLocator.locate(new MockEnvironment()))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Unable to read ConfigMap with name 'application' in namespace 'default'");
|
||||
|
||||
// verify that propertySourceLocator.locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
@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 {
|
||||
|
||||
@SpyBean
|
||||
private KubernetesClientConfigMapPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void locateShouldFailWithoutRetrying() {
|
||||
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
|
||||
|
||||
assertThat(context.containsBean("kubernetesConfigRetryInterceptor")).isFalse();
|
||||
assertThatThrownBy(() -> propertySourceLocator.locate(new MockEnvironment()))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Unable to read ConfigMap with name 'application' in namespace 'default'");
|
||||
|
||||
// verify that propertySourceLocator.locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SpringBootApplication
|
||||
static class App {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,284 +0,0 @@
|
||||
/*
|
||||
* 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.client.config;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.github.tomakehurst.wiremock.WireMockServer;
|
||||
import com.github.tomakehurst.wiremock.client.WireMock;
|
||||
import io.kubernetes.client.openapi.JSON;
|
||||
import io.kubernetes.client.openapi.models.V1ConfigMapList;
|
||||
import io.kubernetes.client.openapi.models.V1ObjectMeta;
|
||||
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.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.MockedStatic;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
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.context.ApplicationContext;
|
||||
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.stubFor;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author Isik Erhan
|
||||
*/
|
||||
public class KubernetesClientSecretsPropertySourceLocatorRetryTests {
|
||||
|
||||
private static final String API = "/api/v1/namespaces/default/secrets";
|
||||
|
||||
private static final String CONFIG_MAPS_API = "/api/v1/namespaces/default/configmaps";
|
||||
|
||||
private static WireMockServer wireMockServer;
|
||||
|
||||
private static MockedStatic<KubernetesClientUtils> clientUtilsMock;
|
||||
|
||||
@BeforeAll
|
||||
public 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());
|
||||
stubConfigMapAndSecretsDefaults();
|
||||
}
|
||||
|
||||
private static void stubConfigMapAndSecretsDefaults() {
|
||||
// return empty config map / secret list to not fail context creation
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(new V1SecretList()))));
|
||||
stubFor(get(CONFIG_MAPS_API)
|
||||
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(new V1ConfigMapList()))));
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void teardown() {
|
||||
wireMockServer.stop();
|
||||
clientUtilsMock.close();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void afterEach() {
|
||||
WireMock.reset();
|
||||
stubConfigMapAndSecretsDefaults();
|
||||
}
|
||||
|
||||
@Nested
|
||||
@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" },
|
||||
classes = App.class)
|
||||
class SecretsRetryEnabled {
|
||||
|
||||
@SpyBean
|
||||
private KubernetesClientSecretsPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Test
|
||||
public void locateShouldNotRetryWhenThereIsNoFailure() {
|
||||
|
||||
Map<String, byte[]> data = new HashMap<>();
|
||||
data.put("some.sensitive.prop", "theSensitiveValue".getBytes());
|
||||
data.put("some.sensitive.number", "1".getBytes());
|
||||
|
||||
V1SecretList secretList = new V1SecretList()
|
||||
.addItemsItem(new V1Secret().metadata(new V1ObjectMeta().name("my-secret")).data(data));
|
||||
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(secretList))));
|
||||
|
||||
PropertySource<?> propertySource = Assertions
|
||||
.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
|
||||
|
||||
// verify locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
|
||||
// validate the contents of the property source
|
||||
assertThat(propertySource.getProperty("some.sensitive.prop")).isEqualTo("theSensitiveValue");
|
||||
assertThat(propertySource.getProperty("some.sensitive.number")).isEqualTo("1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void locateShouldRetryAndRecover() {
|
||||
Map<String, byte[]> data = new HashMap<>();
|
||||
data.put("some.sensitive.prop", "theSensitiveValue".getBytes());
|
||||
data.put("some.sensitive.number", "1".getBytes());
|
||||
|
||||
V1SecretList secretList = new V1SecretList()
|
||||
.addItemsItem(new V1Secret().metadata(new V1ObjectMeta().name("my-secret")).data(data));
|
||||
|
||||
// fail 3 times
|
||||
stubFor(get(API).inScenario("Retry and Recover").whenScenarioStateIs(STARTED)
|
||||
.willReturn(aResponse().withStatus(500)).willSetStateTo("Failed once"));
|
||||
|
||||
stubFor(get(API).inScenario("Retry and Recover").whenScenarioStateIs("Failed once")
|
||||
.willReturn(aResponse().withStatus(500)).willSetStateTo("Failed twice"));
|
||||
|
||||
stubFor(get(API).inScenario("Retry and Recover").whenScenarioStateIs("Failed twice")
|
||||
.willReturn(aResponse().withStatus(500)).willSetStateTo("Failed thrice"));
|
||||
|
||||
// then succeed
|
||||
stubFor(get(API).inScenario("Retry and Recover").whenScenarioStateIs("Failed thrice")
|
||||
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(secretList))));
|
||||
|
||||
PropertySource<?> propertySource = Assertions
|
||||
.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
|
||||
|
||||
// verify retried 4 times
|
||||
verify(propertySourceLocator, times(4)).locate(any());
|
||||
|
||||
// validate the contents of the property source
|
||||
assertThat(propertySource.getProperty("some.sensitive.prop")).isEqualTo("theSensitiveValue");
|
||||
assertThat(propertySource.getProperty("some.sensitive.number")).isEqualTo("1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void locateShouldRetryAndFail() {
|
||||
// fail all the 5 requests
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
|
||||
|
||||
assertThatThrownBy(() -> propertySourceLocator.locate(new MockEnvironment()))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Unable to read Secret with name 'my-secret' or labels [{}] in namespace 'default'");
|
||||
|
||||
// verify retried 5 times until failure
|
||||
verify(propertySourceLocator, times(5)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
@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" },
|
||||
classes = App.class)
|
||||
class SecretsFailFastDisabled {
|
||||
|
||||
@SpyBean
|
||||
private KubernetesClientSecretsPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Test
|
||||
public void locateShouldNotRetry() {
|
||||
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
|
||||
|
||||
Assertions.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
|
||||
|
||||
// verify locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
|
||||
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" },
|
||||
classes = App.class)
|
||||
class SecretsRetryDisabledButConfigRetryEnabled {
|
||||
|
||||
@SpyBean
|
||||
private KubernetesClientSecretsPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void locateShouldFailWithoutRetrying() {
|
||||
|
||||
/*
|
||||
* Enabling config retry causes Spring Retry to be enabled and a
|
||||
* RetryOperationsInterceptor bean with NeverRetryPolicy for secrets to be
|
||||
* defined. SecretsPropertySourceLocator should not retry even Spring Retry is
|
||||
* enabled.
|
||||
*/
|
||||
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
|
||||
|
||||
assertThat(context.containsBean("kubernetesSecretsRetryInterceptor")).isTrue();
|
||||
assertThatThrownBy(() -> propertySourceLocator.locate(new MockEnvironment()))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Unable to read Secret with name 'my-secret' or labels [{}] in namespace 'default'");
|
||||
|
||||
// verify that propertySourceLocator.locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, 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" },
|
||||
classes = App.class)
|
||||
class SecretsFailFastEnabledButRetryDisabled {
|
||||
|
||||
@SpyBean
|
||||
private KubernetesClientSecretsPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void locateShouldFailWithoutRetrying() {
|
||||
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
|
||||
|
||||
assertThat(context.containsBean("kubernetesSecretsRetryInterceptor")).isFalse();
|
||||
assertThatThrownBy(() -> propertySourceLocator.locate(new MockEnvironment()))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Unable to read Secret with name 'my-secret' or labels [{}] in namespace 'default'");
|
||||
|
||||
// verify that propertySourceLocator.locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SpringBootApplication
|
||||
static class App {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.boostrap_configuration;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.client.config.Application;
|
||||
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySourceLocator;
|
||||
import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySourceLocator;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
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" })
|
||||
class KubernetesClientBootstrapConfigurationInsideK8s {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
// tests that @ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES) has the desired
|
||||
// effect, meaning when it is enabled, both property sources are present
|
||||
@Test
|
||||
public void bothPresent() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientConfigMapPropertySourceLocator.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientSecretsPropertySourceLocator.class)).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.boostrap_configuration;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.client.config.Application;
|
||||
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySourceLocator;
|
||||
import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySourceLocator;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class,
|
||||
properties = { "kubernetes.manifests.enabled=false" })
|
||||
class KubernetesClientBootstrapConfigurationNotInsideK8s {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
// tests that @ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES) has the desired
|
||||
// effect, meaning when it is disabled, no property source bean is present
|
||||
@Test
|
||||
void bothMissing() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientConfigMapPropertySourceLocator.class)).hasSize(0);
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientSecretsPropertySourceLocator.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.boostrap_configuration;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.client.config.Application;
|
||||
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySourceLocator;
|
||||
import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySourceLocator;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
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" })
|
||||
class KubernetesDisabled {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void configAndSecretsBeansAreNotPresent() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientConfigMapPropertySourceLocator.class)).hasSize(0);
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientSecretsPropertySourceLocator.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.boostrap_configuration;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.client.config.Application;
|
||||
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySourceLocator;
|
||||
import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySourceLocator;
|
||||
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" })
|
||||
class KubernetesEnabled {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void configAndSecretsBeansArePresent() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientConfigMapPropertySourceLocator.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientSecretsPropertySourceLocator.class)).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.boostrap_configuration;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.client.config.Application;
|
||||
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySourceLocator;
|
||||
import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySourceLocator;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
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" })
|
||||
class KubernetesEnabledConfigDisabled {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void secretsOnlyPresent() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientConfigMapPropertySourceLocator.class)).hasSize(0);
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientSecretsPropertySourceLocator.class)).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.boostrap_configuration;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.client.config.Application;
|
||||
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySourceLocator;
|
||||
import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySourceLocator;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@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" })
|
||||
class KubernetesEnabledOnPurpose {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void configAndSecretsBeansArePresent() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientConfigMapPropertySourceLocator.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientSecretsPropertySourceLocator.class)).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.boostrap_configuration;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.client.config.Application;
|
||||
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySourceLocator;
|
||||
import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySourceLocator;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class,
|
||||
properties = { "spring.cloud.kubernetes.secrets.enabled=false", "spring.cloud.kubernetes.config.enabled=false",
|
||||
"spring.main.cloud-platform=KUBERNETES" })
|
||||
class KubernetesEnabledSecretsAndConfigDisabled {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void secretsOnlyPresent() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientConfigMapPropertySourceLocator.class)).hasSize(0);
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientSecretsPropertySourceLocator.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.boostrap_configuration;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.client.config.Application;
|
||||
import org.springframework.cloud.kubernetes.client.config.KubernetesClientConfigMapPropertySourceLocator;
|
||||
import org.springframework.cloud.kubernetes.client.config.KubernetesClientSecretsPropertySourceLocator;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@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" })
|
||||
class KubernetesEnabledSecretsDisabled {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void secretsOnlyPresent() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientConfigMapPropertySourceLocator.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(KubernetesClientSecretsPropertySourceLocator.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
class App {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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 com.github.tomakehurst.wiremock.WireMockServer;
|
||||
import com.github.tomakehurst.wiremock.client.WireMock;
|
||||
import io.kubernetes.client.openapi.JSON;
|
||||
import io.kubernetes.client.openapi.models.V1ConfigMapList;
|
||||
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.Test;
|
||||
import org.mockito.MockedStatic;
|
||||
|
||||
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.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.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.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 {
|
||||
|
||||
private static final String API = "/api/v1/namespaces/default/configmaps";
|
||||
|
||||
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());
|
||||
stubConfigMapAndSecretsDefaults();
|
||||
}
|
||||
|
||||
private static void stubConfigMapAndSecretsDefaults() {
|
||||
// return empty config map / secret list to not fail context creation
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(new V1ConfigMapList()))));
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void teardown() {
|
||||
wireMockServer.stop();
|
||||
clientUtilsMock.close();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void afterEach() {
|
||||
WireMock.reset();
|
||||
stubConfigMapAndSecretsDefaults();
|
||||
}
|
||||
|
||||
@SpyBean
|
||||
private KubernetesClientConfigMapPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Test
|
||||
void locateShouldNotRetry() {
|
||||
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
|
||||
|
||||
Assertions.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
|
||||
|
||||
// verify locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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 com.github.tomakehurst.wiremock.WireMockServer;
|
||||
import com.github.tomakehurst.wiremock.client.WireMock;
|
||||
import io.kubernetes.client.openapi.JSON;
|
||||
import io.kubernetes.client.openapi.models.V1ConfigMapList;
|
||||
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.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;
|
||||
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.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.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 {
|
||||
|
||||
private static final String API = "/api/v1/namespaces/default/configmaps";
|
||||
|
||||
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());
|
||||
stubConfigMapAndSecretsDefaults();
|
||||
}
|
||||
|
||||
private static void stubConfigMapAndSecretsDefaults() {
|
||||
// return empty config map / secret list to not fail context creation
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(new V1ConfigMapList()))));
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void teardown() {
|
||||
wireMockServer.stop();
|
||||
clientUtilsMock.close();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void afterEach() {
|
||||
WireMock.reset();
|
||||
stubConfigMapAndSecretsDefaults();
|
||||
}
|
||||
|
||||
@SpyBean
|
||||
private KubernetesClientConfigMapPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
void locateShouldFailWithoutRetrying() {
|
||||
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
|
||||
|
||||
assertThat(context.containsBean("kubernetesConfigRetryInterceptor")).isFalse();
|
||||
assertThatThrownBy(() -> propertySourceLocator.locate(new MockEnvironment()))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Unable to read ConfigMap with name 'application' in namespace 'default'");
|
||||
|
||||
// verify that propertySourceLocator.locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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 com.github.tomakehurst.wiremock.WireMockServer;
|
||||
import com.github.tomakehurst.wiremock.client.WireMock;
|
||||
import io.kubernetes.client.openapi.JSON;
|
||||
import io.kubernetes.client.openapi.models.V1ConfigMapList;
|
||||
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.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.KubernetesClientConfigMapPropertySourceLocator;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
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.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.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 {
|
||||
|
||||
private static final String API = "/api/v1/namespaces/default/configmaps";
|
||||
|
||||
private static final String SECRETS_API = "/api/v1/namespaces/default/secrets";
|
||||
|
||||
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());
|
||||
stubConfigMapAndSecretsDefaults();
|
||||
}
|
||||
|
||||
private static void stubConfigMapAndSecretsDefaults() {
|
||||
// return empty config map / secret list to not fail context creation
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(new V1ConfigMapList()))));
|
||||
stubFor(get(SECRETS_API)
|
||||
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(new V1SecretList()))));
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void teardown() {
|
||||
wireMockServer.stop();
|
||||
clientUtilsMock.close();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void afterEach() {
|
||||
WireMock.reset();
|
||||
stubConfigMapAndSecretsDefaults();
|
||||
}
|
||||
|
||||
@SpyBean
|
||||
private KubernetesClientConfigMapPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
void locateShouldFailWithoutRetrying() {
|
||||
|
||||
/*
|
||||
* Enabling secrets retry causes Spring Retry to be enabled and a
|
||||
* RetryOperationsInterceptor bean with NeverRetryPolicy for config maps to be
|
||||
* defined. ConfigMapPropertySourceLocator should not retry even Spring Retry is
|
||||
* enabled.
|
||||
*/
|
||||
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
|
||||
|
||||
assertThat(context.containsBean("kubernetesConfigRetryInterceptor")).isTrue();
|
||||
assertThatThrownBy(() -> propertySourceLocator.locate(new MockEnvironment()))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Unable to read ConfigMap with name 'application' in namespace 'default'");
|
||||
|
||||
// verify that propertySourceLocator.locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* 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 java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.github.tomakehurst.wiremock.WireMockServer;
|
||||
import com.github.tomakehurst.wiremock.client.WireMock;
|
||||
import io.kubernetes.client.openapi.JSON;
|
||||
import io.kubernetes.client.openapi.models.V1ConfigMap;
|
||||
import io.kubernetes.client.openapi.models.V1ConfigMapList;
|
||||
import io.kubernetes.client.openapi.models.V1ObjectMeta;
|
||||
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.Test;
|
||||
import org.mockito.MockedStatic;
|
||||
|
||||
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.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.stubFor;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @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 {
|
||||
|
||||
private static final String API = "/api/v1/namespaces/default/configmaps";
|
||||
|
||||
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());
|
||||
stubConfigMapAndSecretsDefaults();
|
||||
}
|
||||
|
||||
private static void stubConfigMapAndSecretsDefaults() {
|
||||
// return empty config map / secret list to not fail context creation
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(new V1ConfigMapList()))));
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void teardown() {
|
||||
wireMockServer.stop();
|
||||
clientUtilsMock.close();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void afterEach() {
|
||||
WireMock.reset();
|
||||
stubConfigMapAndSecretsDefaults();
|
||||
}
|
||||
|
||||
@SpyBean
|
||||
private KubernetesClientConfigMapPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Test
|
||||
void locateShouldNotRetryWhenThereIsNoFailure() {
|
||||
|
||||
Map<String, String> data = new HashMap<>();
|
||||
data.put("some.prop", "theValue");
|
||||
data.put("some.number", "0");
|
||||
|
||||
V1ConfigMapList configMapList = new V1ConfigMapList()
|
||||
.addItemsItem(new V1ConfigMap().metadata(new V1ObjectMeta().name("application")).data(data));
|
||||
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(configMapList))));
|
||||
|
||||
PropertySource<?> propertySource = Assertions
|
||||
.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
|
||||
|
||||
// verify locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
|
||||
// validate the contents of the property source
|
||||
assertThat(propertySource.getProperty("some.prop")).isEqualTo("theValue");
|
||||
assertThat(propertySource.getProperty("some.number")).isEqualTo("0");
|
||||
}
|
||||
|
||||
@Test
|
||||
void locateShouldRetryAndRecover() {
|
||||
Map<String, String> data = new HashMap<>();
|
||||
data.put("some.prop", "theValue");
|
||||
data.put("some.number", "0");
|
||||
|
||||
V1ConfigMapList configMapList = new V1ConfigMapList()
|
||||
.addItemsItem(new V1ConfigMap().metadata(new V1ObjectMeta().name("application")).data(data));
|
||||
|
||||
// fail 3 times
|
||||
stubFor(get(API).inScenario("Retry and Recover").whenScenarioStateIs(STARTED)
|
||||
.willReturn(aResponse().withStatus(500)).willSetStateTo("Failed once"));
|
||||
|
||||
stubFor(get(API).inScenario("Retry and Recover").whenScenarioStateIs("Failed once")
|
||||
.willReturn(aResponse().withStatus(500)).willSetStateTo("Failed twice"));
|
||||
|
||||
stubFor(get(API).inScenario("Retry and Recover").whenScenarioStateIs("Failed twice")
|
||||
.willReturn(aResponse().withStatus(500)).willSetStateTo("Failed thrice"));
|
||||
|
||||
// then succeed
|
||||
stubFor(get(API).inScenario("Retry and Recover").whenScenarioStateIs("Failed thrice")
|
||||
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(configMapList))));
|
||||
|
||||
PropertySource<?> propertySource = Assertions
|
||||
.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
|
||||
|
||||
// verify retried 4 times
|
||||
verify(propertySourceLocator, times(4)).locate(any());
|
||||
|
||||
// validate the contents of the property source
|
||||
assertThat(propertySource.getProperty("some.prop")).isEqualTo("theValue");
|
||||
assertThat(propertySource.getProperty("some.number")).isEqualTo("0");
|
||||
}
|
||||
|
||||
@Test
|
||||
void locateShouldRetryAndFail() {
|
||||
// fail all the 5 requests
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
|
||||
|
||||
assertThatThrownBy(() -> propertySourceLocator.locate(new MockEnvironment()))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Unable to read ConfigMap with name 'application' in namespace 'default'");
|
||||
|
||||
// verify retried 5 times until failure
|
||||
verify(propertySourceLocator, times(5)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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.secrets_retry;
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
class Application {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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.secrets_retry;
|
||||
|
||||
import com.github.tomakehurst.wiremock.WireMockServer;
|
||||
import com.github.tomakehurst.wiremock.client.WireMock;
|
||||
import io.kubernetes.client.openapi.JSON;
|
||||
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.Test;
|
||||
import org.mockito.MockedStatic;
|
||||
|
||||
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;
|
||||
|
||||
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.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
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.secrets.name=my-secret", "spring.cloud.kubernetes.secrets.enable-api=true",
|
||||
"spring.main.cloud-platform=KUBERNETES" },
|
||||
classes = Application.class)
|
||||
class SecretsFailFastDisabled {
|
||||
|
||||
private static final String API = "/api/v1/namespaces/default/secrets";
|
||||
|
||||
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());
|
||||
stubConfigMapAndSecretsDefaults();
|
||||
}
|
||||
|
||||
private static void stubConfigMapAndSecretsDefaults() {
|
||||
// return empty config map / secret list to not fail context creation
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(new V1SecretList()))));
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void teardown() {
|
||||
wireMockServer.stop();
|
||||
clientUtilsMock.close();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void afterEach() {
|
||||
WireMock.reset();
|
||||
stubConfigMapAndSecretsDefaults();
|
||||
}
|
||||
|
||||
@SpyBean
|
||||
private KubernetesClientSecretsPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Test
|
||||
void locateShouldNotRetry() {
|
||||
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
|
||||
|
||||
Assertions.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
|
||||
|
||||
// verify locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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.client.config.secrets_retry;
|
||||
|
||||
import com.github.tomakehurst.wiremock.WireMockServer;
|
||||
import com.github.tomakehurst.wiremock.client.WireMock;
|
||||
import io.kubernetes.client.openapi.JSON;
|
||||
import io.kubernetes.client.openapi.models.V1ConfigMapList;
|
||||
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.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.context.ApplicationContext;
|
||||
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.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.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.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" },
|
||||
classes = Application.class)
|
||||
class SecretsFailFastEnabledButRetryDisabled {
|
||||
|
||||
private static final String API = "/api/v1/namespaces/default/secrets";
|
||||
|
||||
private static final String CONFIG_MAPS_API = "/api/v1/namespaces/default/configmaps";
|
||||
|
||||
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());
|
||||
stubConfigMapAndSecretsDefaults();
|
||||
}
|
||||
|
||||
private static void stubConfigMapAndSecretsDefaults() {
|
||||
// return empty config map / secret list to not fail context creation
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(new V1SecretList()))));
|
||||
stubFor(get(CONFIG_MAPS_API)
|
||||
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(new V1ConfigMapList()))));
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void teardown() {
|
||||
wireMockServer.stop();
|
||||
clientUtilsMock.close();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void afterEach() {
|
||||
WireMock.reset();
|
||||
stubConfigMapAndSecretsDefaults();
|
||||
}
|
||||
|
||||
@SpyBean
|
||||
private KubernetesClientSecretsPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
void locateShouldFailWithoutRetrying() {
|
||||
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
|
||||
|
||||
assertThat(context.containsBean("kubernetesSecretsRetryInterceptor")).isFalse();
|
||||
assertThatThrownBy(() -> propertySourceLocator.locate(new MockEnvironment()))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Unable to read Secret with name 'my-secret' or labels [{}] in namespace 'default'");
|
||||
|
||||
// verify that propertySourceLocator.locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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.secrets_retry;
|
||||
|
||||
import com.github.tomakehurst.wiremock.WireMockServer;
|
||||
import com.github.tomakehurst.wiremock.client.WireMock;
|
||||
import io.kubernetes.client.openapi.JSON;
|
||||
import io.kubernetes.client.openapi.models.V1ConfigMapList;
|
||||
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.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.context.ApplicationContext;
|
||||
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.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.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.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" },
|
||||
classes = Application.class)
|
||||
class SecretsRetryDisabledButConfigRetryEnabled {
|
||||
|
||||
private static final String API = "/api/v1/namespaces/default/secrets";
|
||||
|
||||
private static final String CONFIG_MAPS_API = "/api/v1/namespaces/default/configmaps";
|
||||
|
||||
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());
|
||||
stubConfigMapAndSecretsDefaults();
|
||||
}
|
||||
|
||||
private static void stubConfigMapAndSecretsDefaults() {
|
||||
// return empty config map / secret list to not fail context creation
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(new V1SecretList()))));
|
||||
stubFor(get(CONFIG_MAPS_API)
|
||||
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(new V1ConfigMapList()))));
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void teardown() {
|
||||
wireMockServer.stop();
|
||||
clientUtilsMock.close();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void afterEach() {
|
||||
WireMock.reset();
|
||||
stubConfigMapAndSecretsDefaults();
|
||||
}
|
||||
|
||||
@SpyBean
|
||||
private KubernetesClientSecretsPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
void locateShouldFailWithoutRetrying() {
|
||||
|
||||
/*
|
||||
* Enabling config retry causes Spring Retry to be enabled and a
|
||||
* RetryOperationsInterceptor bean with NeverRetryPolicy for secrets to be
|
||||
* defined. SecretsPropertySourceLocator should not retry even Spring Retry is
|
||||
* enabled.
|
||||
*/
|
||||
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
|
||||
|
||||
assertThat(context.containsBean("kubernetesSecretsRetryInterceptor")).isTrue();
|
||||
assertThatThrownBy(() -> propertySourceLocator.locate(new MockEnvironment()))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Unable to read Secret with name 'my-secret' or labels [{}] in namespace 'default'");
|
||||
|
||||
// verify that propertySourceLocator.locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* 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.secrets_retry;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.github.tomakehurst.wiremock.WireMockServer;
|
||||
import com.github.tomakehurst.wiremock.client.WireMock;
|
||||
import io.kubernetes.client.openapi.JSON;
|
||||
import io.kubernetes.client.openapi.models.V1ObjectMeta;
|
||||
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.Test;
|
||||
import org.mockito.MockedStatic;
|
||||
|
||||
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.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.stubFor;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @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" },
|
||||
classes = Application.class)
|
||||
class SecretsRetryEnabled {
|
||||
|
||||
private static final String API = "/api/v1/namespaces/default/secrets";
|
||||
|
||||
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());
|
||||
stubConfigMapAndSecretsDefaults();
|
||||
}
|
||||
|
||||
private static void stubConfigMapAndSecretsDefaults() {
|
||||
// return empty config map / secret list to not fail context creation
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(new V1SecretList()))));
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void teardown() {
|
||||
wireMockServer.stop();
|
||||
clientUtilsMock.close();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void afterEach() {
|
||||
WireMock.reset();
|
||||
stubConfigMapAndSecretsDefaults();
|
||||
}
|
||||
|
||||
@SpyBean
|
||||
private KubernetesClientSecretsPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Test
|
||||
void locateShouldNotRetryWhenThereIsNoFailure() {
|
||||
|
||||
Map<String, byte[]> data = new HashMap<>();
|
||||
data.put("some.sensitive.prop", "theSensitiveValue".getBytes());
|
||||
data.put("some.sensitive.number", "1".getBytes());
|
||||
|
||||
V1SecretList secretList = new V1SecretList()
|
||||
.addItemsItem(new V1Secret().metadata(new V1ObjectMeta().name("my-secret")).data(data));
|
||||
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(secretList))));
|
||||
|
||||
PropertySource<?> propertySource = Assertions
|
||||
.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
|
||||
|
||||
// verify locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
|
||||
// validate the contents of the property source
|
||||
assertThat(propertySource.getProperty("some.sensitive.prop")).isEqualTo("theSensitiveValue");
|
||||
assertThat(propertySource.getProperty("some.sensitive.number")).isEqualTo("1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void locateShouldRetryAndRecover() {
|
||||
Map<String, byte[]> data = new HashMap<>();
|
||||
data.put("some.sensitive.prop", "theSensitiveValue".getBytes());
|
||||
data.put("some.sensitive.number", "1".getBytes());
|
||||
|
||||
V1SecretList secretList = new V1SecretList()
|
||||
.addItemsItem(new V1Secret().metadata(new V1ObjectMeta().name("my-secret")).data(data));
|
||||
|
||||
// fail 3 times
|
||||
stubFor(get(API).inScenario("Retry and Recover").whenScenarioStateIs(STARTED)
|
||||
.willReturn(aResponse().withStatus(500)).willSetStateTo("Failed once"));
|
||||
|
||||
stubFor(get(API).inScenario("Retry and Recover").whenScenarioStateIs("Failed once")
|
||||
.willReturn(aResponse().withStatus(500)).willSetStateTo("Failed twice"));
|
||||
|
||||
stubFor(get(API).inScenario("Retry and Recover").whenScenarioStateIs("Failed twice")
|
||||
.willReturn(aResponse().withStatus(500)).willSetStateTo("Failed thrice"));
|
||||
|
||||
// then succeed
|
||||
stubFor(get(API).inScenario("Retry and Recover").whenScenarioStateIs("Failed thrice")
|
||||
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(secretList))));
|
||||
|
||||
PropertySource<?> propertySource = Assertions
|
||||
.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
|
||||
|
||||
// verify retried 4 times
|
||||
verify(propertySourceLocator, times(4)).locate(any());
|
||||
|
||||
// validate the contents of the property source
|
||||
assertThat(propertySource.getProperty("some.sensitive.prop")).isEqualTo("theSensitiveValue");
|
||||
assertThat(propertySource.getProperty("some.sensitive.number")).isEqualTo("1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void locateShouldRetryAndFail() {
|
||||
// fail all the 5 requests
|
||||
stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
|
||||
|
||||
assertThatThrownBy(() -> propertySourceLocator.locate(new MockEnvironment()))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Unable to read Secret with name 'my-secret' or labels [{}] in namespace 'default'");
|
||||
|
||||
// verify retried 5 times until failure
|
||||
verify(propertySourceLocator, times(5)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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 org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class App {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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.bootstrap;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.commons.config.AbstractConfigProperties;
|
||||
import org.springframework.cloud.kubernetes.commons.config.App;
|
||||
import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties;
|
||||
import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.retry.interceptor.RetryOperationsInterceptor;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Isik Erhan
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = App.class,
|
||||
properties = { "spring.cloud.kubernetes.config.fail-fast=true",
|
||||
"spring.cloud.kubernetes.secrets.fail-fast=true", "spring.main.cloud-platform=KUBERNETES" })
|
||||
public class ConfigAndSecretsFailFastEnabledWithDefaultRetryConfiguration {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Autowired
|
||||
private ConfigMapConfigProperties configMapConfigProperties;
|
||||
|
||||
@Autowired
|
||||
private SecretsConfigProperties secretsConfigProperties;
|
||||
|
||||
@Test
|
||||
void shouldDefineRequiredBeans() {
|
||||
Map<String, RetryOperationsInterceptor> retryInterceptors = context
|
||||
.getBeansOfType(RetryOperationsInterceptor.class);
|
||||
assertThat(retryInterceptors.containsKey("kubernetesConfigRetryInterceptor")).isTrue();
|
||||
assertThat(retryInterceptors.containsKey("kubernetesSecretsRetryInterceptor")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void retryConfigurationShouldBeDefault() {
|
||||
AbstractConfigProperties.RetryProperties defaultRetryProperties = new AbstractConfigProperties.RetryProperties();
|
||||
|
||||
AbstractConfigProperties.RetryProperties configMapRetryProperties = configMapConfigProperties.getRetry();
|
||||
|
||||
assertThat(configMapRetryProperties.getMaxAttempts()).isEqualTo(defaultRetryProperties.getMaxAttempts());
|
||||
assertThat(configMapRetryProperties.getInitialInterval())
|
||||
.isEqualTo(defaultRetryProperties.getInitialInterval());
|
||||
assertThat(configMapRetryProperties.getMaxInterval()).isEqualTo(defaultRetryProperties.getMaxInterval());
|
||||
assertThat(configMapRetryProperties.getMultiplier()).isEqualTo(defaultRetryProperties.getMultiplier());
|
||||
|
||||
AbstractConfigProperties.RetryProperties secretsRetryProperties = secretsConfigProperties.getRetry();
|
||||
|
||||
assertThat(secretsRetryProperties.getMaxAttempts()).isEqualTo(defaultRetryProperties.getMaxAttempts());
|
||||
assertThat(secretsRetryProperties.getInitialInterval()).isEqualTo(defaultRetryProperties.getInitialInterval());
|
||||
assertThat(secretsRetryProperties.getMaxInterval()).isEqualTo(defaultRetryProperties.getMaxInterval());
|
||||
assertThat(secretsRetryProperties.getMultiplier()).isEqualTo(defaultRetryProperties.getMultiplier());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.bootstrap;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.commons.config.AbstractConfigProperties;
|
||||
import org.springframework.cloud.kubernetes.commons.config.App;
|
||||
import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.retry.interceptor.RetryOperationsInterceptor;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Isik Erhan
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = App.class,
|
||||
properties = { "spring.cloud.kubernetes.config.fail-fast=true", "spring.main.cloud-platform=KUBERNETES" })
|
||||
class ConfigFailFastEnabled {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Autowired
|
||||
private ConfigMapConfigProperties configMapConfigProperties;
|
||||
|
||||
@Test
|
||||
void shouldDefineRequiredBeans() {
|
||||
Map<String, RetryOperationsInterceptor> retryInterceptors = context
|
||||
.getBeansOfType(RetryOperationsInterceptor.class);
|
||||
assertThat(retryInterceptors.containsKey("kubernetesConfigRetryInterceptor")).isTrue();
|
||||
assertThat(retryInterceptors.containsKey("kubernetesSecretsRetryInterceptor")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void retryConfigurationShouldBeDefault() {
|
||||
AbstractConfigProperties.RetryProperties retryProperties = configMapConfigProperties.getRetry();
|
||||
AbstractConfigProperties.RetryProperties defaultRetryProperties = new AbstractConfigProperties.RetryProperties();
|
||||
|
||||
assertThat(retryProperties.getMaxAttempts()).isEqualTo(defaultRetryProperties.getMaxAttempts());
|
||||
assertThat(retryProperties.getInitialInterval()).isEqualTo(defaultRetryProperties.getInitialInterval());
|
||||
assertThat(retryProperties.getMaxInterval()).isEqualTo(defaultRetryProperties.getMaxInterval());
|
||||
assertThat(retryProperties.getMultiplier()).isEqualTo(defaultRetryProperties.getMultiplier());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.bootstrap;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.commons.config.App;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.retry.interceptor.RetryOperationsInterceptor;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Isik Erhan
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = App.class, properties = {
|
||||
"spring.cloud.kubernetes.config.fail-fast=true", "spring.cloud.kubernetes.config.retry.enabled=false" })
|
||||
class ConfigFailFastEnabledButRetryDisabled {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void shouldNotDefineRetryBeans() {
|
||||
assertThat(context.getBeansOfType(RetryOperationsInterceptor.class)).isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.bootstrap;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.commons.config.AbstractConfigProperties;
|
||||
import org.springframework.cloud.kubernetes.commons.config.App;
|
||||
import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Isik Erhan
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = App.class,
|
||||
properties = { "spring.cloud.kubernetes.config.fail-fast=true",
|
||||
"spring.cloud.kubernetes.config.retry.max-attempts=3",
|
||||
"spring.cloud.kubernetes.config.retry.initial-interval=1500",
|
||||
"spring.cloud.kubernetes.config.retry.max-interval=3000",
|
||||
"spring.cloud.kubernetes.config.retry.multiplier=1.5", "spring.main.cloud-platform=KUBERNETES" })
|
||||
class ConfigFailFastEnabledWithCustomRetryConfiguration {
|
||||
|
||||
@Autowired
|
||||
private ConfigMapConfigProperties configMapConfigProperties;
|
||||
|
||||
@Test
|
||||
void retryConfigurationShouldBeCustomized() {
|
||||
AbstractConfigProperties.RetryProperties retryProperties = configMapConfigProperties.getRetry();
|
||||
|
||||
assertThat(retryProperties.getMaxAttempts()).isEqualTo(3);
|
||||
assertThat(retryProperties.getInitialInterval()).isEqualTo(1500L);
|
||||
assertThat(retryProperties.getMaxInterval()).isEqualTo(3000L);
|
||||
assertThat(retryProperties.getMultiplier()).isEqualTo(1.5D);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.bootstrap;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.commons.config.App;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.retry.interceptor.RetryOperationsInterceptor;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Isik Erhan
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = App.class)
|
||||
class FailFastDisabled {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void shouldNotDefineRetryBeans() {
|
||||
assertThat(context.getBeansOfType(RetryOperationsInterceptor.class)).isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.commons.config.bootstrap;
|
||||
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.aop.AopAutoConfiguration;
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.cloud.kubernetes.commons.config.KubernetesBootstrapConfiguration;
|
||||
import org.springframework.retry.annotation.Retryable;
|
||||
import org.springframework.retry.interceptor.RetryOperationsInterceptor;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Isik Erhan
|
||||
*/
|
||||
class FailFastEnabledWithoutSpringRetryOnClasspath {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(KubernetesBootstrapConfiguration.class))
|
||||
.withClassLoader(new FilteredClassLoader(Retryable.class, Aspect.class, AopAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void shouldNotDefineRetryBeansWhenConfigMapFailFastEnabled() {
|
||||
contextRunner.withPropertyValues("spring.cloud.kubernetes.config.fail-fast=true")
|
||||
.run(context -> assertThat(context.getBeansOfType(RetryOperationsInterceptor.class)).isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotDefineRetryBeansWhenSecretsFailFastEnabled() {
|
||||
contextRunner.withPropertyValues("spring.cloud.kubernetes.secrets.fail-fast=true")
|
||||
.run(context -> assertThat(context.getBeansOfType(RetryOperationsInterceptor.class)).isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotDefineRetryBeansWhenConfigMapAndSecretsFailFastEnabled() {
|
||||
contextRunner
|
||||
.withPropertyValues("spring.cloud.kubernetes.config.fail-fast=true",
|
||||
"spring.cloud.kubernetes.secrets.fail-fast=true")
|
||||
.run(context -> assertThat(context.getBeansOfType(RetryOperationsInterceptor.class)).isEmpty());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.commons.config.bootstrap;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.commons.config.AbstractConfigProperties;
|
||||
import org.springframework.cloud.kubernetes.commons.config.App;
|
||||
import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.retry.interceptor.RetryOperationsInterceptor;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Isik Erhan
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = App.class,
|
||||
properties = { "spring.cloud.kubernetes.secrets.fail-fast=true", "spring.main.cloud-platform=KUBERNETES" })
|
||||
class SecretsFailFastEnabled {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Autowired
|
||||
private SecretsConfigProperties secretsConfigProperties;
|
||||
|
||||
@Test
|
||||
void shouldDefineRequiredBeans() {
|
||||
Map<String, RetryOperationsInterceptor> retryInterceptors = context
|
||||
.getBeansOfType(RetryOperationsInterceptor.class);
|
||||
assertThat(retryInterceptors.containsKey("kubernetesConfigRetryInterceptor")).isTrue();
|
||||
assertThat(retryInterceptors.containsKey("kubernetesSecretsRetryInterceptor")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void retryConfigurationShouldBeDefault() {
|
||||
AbstractConfigProperties.RetryProperties retryProperties = secretsConfigProperties.getRetry();
|
||||
AbstractConfigProperties.RetryProperties defaultRetryProperties = new AbstractConfigProperties.RetryProperties();
|
||||
|
||||
assertThat(retryProperties.getMaxAttempts()).isEqualTo(defaultRetryProperties.getMaxAttempts());
|
||||
assertThat(retryProperties.getInitialInterval()).isEqualTo(defaultRetryProperties.getInitialInterval());
|
||||
assertThat(retryProperties.getMaxInterval()).isEqualTo(defaultRetryProperties.getMaxInterval());
|
||||
assertThat(retryProperties.getMultiplier()).isEqualTo(defaultRetryProperties.getMultiplier());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.commons.config.bootstrap;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.commons.config.App;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.retry.interceptor.RetryOperationsInterceptor;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Isik Erhan
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = App.class, properties = {
|
||||
"spring.cloud.kubernetes.secrets.fail-fast=true", "spring.cloud.kubernetes.secrets.retry.enabled=false" })
|
||||
class SecretsFailFastEnabledButRetryDisabled {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void shouldNotDefineRetryBeans() {
|
||||
assertThat(context.getBeansOfType(RetryOperationsInterceptor.class)).isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.commons.config.bootstrap;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.commons.config.AbstractConfigProperties;
|
||||
import org.springframework.cloud.kubernetes.commons.config.App;
|
||||
import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Isik Erhan
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = App.class,
|
||||
properties = { "spring.cloud.kubernetes.secrets.fail-fast=true",
|
||||
"spring.cloud.kubernetes.secrets.retry.max-attempts=3",
|
||||
"spring.cloud.kubernetes.secrets.retry.initial-interval=1500",
|
||||
"spring.cloud.kubernetes.secrets.retry.max-interval=3000",
|
||||
"spring.cloud.kubernetes.secrets.retry.multiplier=1.5", "spring.main.cloud-platform=KUBERNETES" })
|
||||
class SecretsFailFastEnabledWithCustomRetryConfiguration {
|
||||
|
||||
@Autowired
|
||||
private SecretsConfigProperties secretsConfigProperties;
|
||||
|
||||
@Test
|
||||
void retryConfigurationShouldBeCustomized() {
|
||||
AbstractConfigProperties.RetryProperties retryProperties = secretsConfigProperties.getRetry();
|
||||
|
||||
assertThat(retryProperties.getMaxAttempts()).isEqualTo(3);
|
||||
assertThat(retryProperties.getInitialInterval()).isEqualTo(1500L);
|
||||
assertThat(retryProperties.getMaxInterval()).isEqualTo(3000L);
|
||||
assertThat(retryProperties.getMultiplier()).isEqualTo(1.5D);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.configserver;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
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" },
|
||||
classes = { KubernetesConfigServerApplication.class, MockConfig.class })
|
||||
class ConfigServerAutoConfigurationKubernetesDisabled {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void runTest() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesEnvironmentRepository.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.configserver;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
classes = { KubernetesConfigServerApplication.class },
|
||||
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.profiles.include=kubernetes", "debug=true",
|
||||
"spring.cloud.kubernetes.client.namespace=default" })
|
||||
class ConfigServerAutoConfigurationKubernetesEnabledProfileIncluded {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void runTest() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesEnvironmentRepository.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(KubernetesPropertySourceSupplier.class)).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.configserver;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
classes = { KubernetesConfigServerApplication.class },
|
||||
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.profiles.include=kubernetes", "debug=true",
|
||||
"spring.cloud.kubernetes.client.namespace=default", "spring.cloud.kubernetes.config.enableApi=false" })
|
||||
class ConfigServerAutoConfigurationKubernetesEnabledProfileIncludedConfigApiDisabled {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void runTest() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesEnvironmentRepository.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(KubernetesPropertySourceSupplier.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.configserver;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
classes = { KubernetesConfigServerApplication.class }, properties = { "spring.main.cloud-platform=KUBERNETES",
|
||||
"spring.profiles.include=kubernetes", "debug=true", "spring.cloud.kubernetes.config.enabled=false" })
|
||||
class ConfigServerAutoConfigurationKubernetesEnabledProfileIncludedConfigMapDisabled {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void runTest() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesEnvironmentRepository.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(KubernetesPropertySourceSupplier.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.configserver;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
classes = { KubernetesConfigServerApplication.class },
|
||||
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.profiles.include=kubernetes", "debug=true",
|
||||
"spring.cloud.kubernetes.client.namespace=default" })
|
||||
class ConfigServerAutoConfigurationKubernetesEnabledProfileIncludedSecretsApiDisabled {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void runTest() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesEnvironmentRepository.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(KubernetesPropertySourceSupplier.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(KubernetesPropertySourceSupplier.class)[0])
|
||||
.isEqualTo("configMapPropertySourceSupplier");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.configserver;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
classes = { KubernetesConfigServerApplication.class },
|
||||
properties = { "spring.profiles.include=kubernetes", "debug=true", "spring.main.cloud-platform=KUBERNETES",
|
||||
"spring.cloud.kubernetes.client.namespace=default", "spring.cloud.kubernetes.secrets.enableApi=true" })
|
||||
class ConfigServerAutoConfigurationKubernetesEnabledProfileIncludedSecretsApiEnabled {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void runTest() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesEnvironmentRepository.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(KubernetesPropertySourceSupplier.class)).hasSize(2);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.configserver;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
classes = { KubernetesConfigServerApplication.class, MockConfig.class },
|
||||
properties = { "spring.cloud.kubernetes.enabled=false", "spring.profiles.include=kubernetes,kubernetesdisabled",
|
||||
"debug=true" })
|
||||
class ConfigServerAutoConfigurationKubernetesProfileMissing {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void runTest() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesEnvironmentRepository.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -75,7 +75,7 @@ public class ConfigServerIntegrationTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enabled() throws Exception {
|
||||
public void enabled() {
|
||||
Environment env = testRestTemplate.getForObject("/test-cm/default", Environment.class);
|
||||
assertThat(env.getPropertySources().size()).isEqualTo(2);
|
||||
assertThat(env.getPropertySources().get(0).getName().equals("configmap.test-cm.default")).isTrue();
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
/*
|
||||
* 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.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.config.server.environment.EnvironmentRepository;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
public class KubernetesConfigServerAutoConfigurationTests {
|
||||
|
||||
@Configuration
|
||||
static class MockConfig {
|
||||
|
||||
@Bean
|
||||
@Profile("kubernetesdisabled")
|
||||
public EnvironmentRepository environmentRepository() {
|
||||
return mock(EnvironmentRepository.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
properties = { "spring.profiles.include=kubernetes,kubernetesdisabled", "debug=true" },
|
||||
classes = { KubernetesConfigServerApplication.class, MockConfig.class })
|
||||
public class KubernetesDisabled {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void runTest() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesEnvironmentRepository.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
classes = { KubernetesConfigServerApplication.class, MockConfig.class },
|
||||
properties = { "spring.profiles.include=kubernetes,kubernetesdisabled", "debug=true" })
|
||||
@Nested
|
||||
class KubernetesProfileMissing {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void runTest() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesEnvironmentRepository.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
classes = { KubernetesConfigServerApplication.class },
|
||||
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.profiles.include=kubernetes", "debug=true",
|
||||
"spring.cloud.kubernetes.client.namespace=default" })
|
||||
@Nested
|
||||
class KubernetesEnabledProfileIncluded {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void runTest() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesEnvironmentRepository.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(KubernetesPropertySourceSupplier.class)).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
classes = { KubernetesConfigServerApplication.class },
|
||||
properties = { "spring.main.cloud-platform=KUBERNETES", // STOPSHIP: 11/10/21
|
||||
"spring.profiles.include=kubernetes", "debug=true",
|
||||
"spring.cloud.kubernetes.config.enabled=false" })
|
||||
@Nested
|
||||
class KubernetesEnabledProfileIncludedConfigMapDisabled {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void runTest() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesEnvironmentRepository.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(KubernetesPropertySourceSupplier.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
classes = { KubernetesConfigServerApplication.class },
|
||||
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.profiles.include=kubernetes", "debug=true",
|
||||
"spring.cloud.kubernetes.client.namespace=default" })
|
||||
@Nested
|
||||
class KubernetesEnabledProfileIncludedSecretsApiDisabled {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void runTest() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesEnvironmentRepository.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(KubernetesPropertySourceSupplier.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(KubernetesPropertySourceSupplier.class)[0])
|
||||
.isEqualTo("configMapPropertySourceSupplier");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
classes = { KubernetesConfigServerApplication.class },
|
||||
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.profiles.include=kubernetes", "debug=true",
|
||||
"spring.cloud.kubernetes.client.namespace=default",
|
||||
"spring.cloud.kubernetes.secrets.enableApi=true" })
|
||||
@Nested
|
||||
class KubernetesEnabledProfileIncludedSecretsApiEnabled {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void runTest() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesEnvironmentRepository.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(KubernetesPropertySourceSupplier.class)).hasSize(2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
|
||||
classes = { KubernetesConfigServerApplication.class },
|
||||
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.profiles.include=kubernetes", "debug=true",
|
||||
"spring.cloud.kubernetes.client.namespace=default",
|
||||
"spring.cloud.kubernetes.config.enableApi=false" })
|
||||
@Nested
|
||||
class KubernetesEnabledProfileIncludedConfigApiDisabled {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void runTest() {
|
||||
assertThat(context.getBeanNamesForType(KubernetesEnvironmentRepository.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(KubernetesPropertySourceSupplier.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.configserver;
|
||||
|
||||
import org.springframework.cloud.config.server.environment.EnvironmentRepository;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Profile;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
@Configuration
|
||||
class MockConfig {
|
||||
|
||||
@Bean
|
||||
@Profile("kubernetesdisabled")
|
||||
public EnvironmentRepository environmentRepository() {
|
||||
return mock(EnvironmentRepository.class);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,7 +22,6 @@ 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.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
@@ -32,11 +31,9 @@ import org.springframework.cloud.kubernetes.fabric8.Fabric8HealthIndicator;
|
||||
import org.springframework.cloud.kubernetes.fabric8.Fabric8InfoContributor;
|
||||
import org.springframework.cloud.kubernetes.fabric8.Fabric8PodUtils;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
|
||||
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.cloud.kubernetes.client.password=mypassword",
|
||||
"spring.cloud.kubernetes.client.proxy-password=myproxypassword" })
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.example.App;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*
|
||||
* test "User-Agent" functionality
|
||||
*/
|
||||
class Fabric8ClientUserAgentTests {
|
||||
|
||||
private static final String USER_AGENT = "spring.cloud.kubernetes.client.userAgent=non-default";
|
||||
|
||||
private static final String ENABLED_K8S = "spring.main.cloud-platform=KUBERNETES";
|
||||
|
||||
@Nested
|
||||
@SpringBootTest(classes = App.class, properties = ENABLED_K8S)
|
||||
class DefaultConfigurationForClient {
|
||||
|
||||
@Autowired
|
||||
private KubernetesClient client;
|
||||
|
||||
@Test
|
||||
void testUserAgent() {
|
||||
String userAgent = client.getConfiguration().getUserAgent();
|
||||
assertThat(userAgent).isEqualTo("Spring-Cloud-Kubernetes-Application");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
@SpringBootTest(classes = App.class, properties = { USER_AGENT, ENABLED_K8S })
|
||||
class PropertiesConfigurationForClient {
|
||||
|
||||
@Autowired
|
||||
private KubernetesClient client;
|
||||
|
||||
@Test
|
||||
void testUserAgent() {
|
||||
String userAgent = client.getConfiguration().getUserAgent();
|
||||
assertThat(userAgent).isEqualTo("non-default");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.fabric8;
|
||||
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.example.App;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@SpringBootTest(classes = App.class, properties = "spring.main.cloud-platform=KUBERNETES")
|
||||
class Fabric8UserAgentDefaultConfigurationTests {
|
||||
|
||||
@Autowired
|
||||
private KubernetesClient client;
|
||||
|
||||
@Test
|
||||
void testUserAgent() {
|
||||
String userAgent = client.getConfiguration().getUserAgent();
|
||||
assertThat(userAgent).isEqualTo("Spring-Cloud-Kubernetes-Application");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.fabric8;
|
||||
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.example.App;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@SpringBootTest(classes = App.class, properties = { "spring.cloud.kubernetes.client.userAgent=non-default",
|
||||
"spring.main.cloud-platform=KUBERNETES" })
|
||||
class Fabric8UserAgentPropertiesConfiguration {
|
||||
|
||||
@Autowired
|
||||
private KubernetesClient client;
|
||||
|
||||
@Test
|
||||
void testUserAgent() {
|
||||
String userAgent = client.getConfiguration().getUserAgent();
|
||||
assertThat(userAgent).isEqualTo("non-default");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* 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.Assertions;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.actuate.health.ReactiveHealthContributorRegistry;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
public class Fabric8ActuatorTests {
|
||||
|
||||
@Nested
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class, properties = {
|
||||
"management.health.kubernetes.enabled=false", "management.endpoint.health.show-details=always",
|
||||
"management.endpoint.health.show-components=always", "management.endpoints.web.exposure.include=health",
|
||||
"spring.cloud.kubernetes.client.namespace=default" })
|
||||
public class DisabledHealthTest {
|
||||
|
||||
@Autowired
|
||||
private ReactiveHealthContributorRegistry registry;
|
||||
|
||||
@Autowired
|
||||
private WebTestClient webClient;
|
||||
|
||||
@Value("${local.server.port}")
|
||||
private int port;
|
||||
|
||||
@Test
|
||||
public void healthEndpointShouldContainKubernetes() {
|
||||
this.webClient.get().uri("http://localhost:{port}/actuator/health", this.port)
|
||||
.accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isOk().expectBody(String.class)
|
||||
.value(not(containsString("kubernetes")));
|
||||
|
||||
Assertions.assertNull(registry.getContributor("kubernetes"),
|
||||
"reactive kubernetes contributor must NOT be present when 'management.health.kubernetes.enabled=false'");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class, properties = {
|
||||
"spring.main.cloud-platform=KUBERNETES", "management.health.kubernetes.enabled=true",
|
||||
"management.endpoint.health.show-details=always", "management.endpoint.health.show-components=always",
|
||||
"management.endpoints.web.exposure.include=health", "spring.cloud.kubernetes.client.namespace=default" })
|
||||
public class EnabledHealthTest {
|
||||
|
||||
@Autowired
|
||||
private WebTestClient webClient;
|
||||
|
||||
@Autowired
|
||||
private ReactiveHealthContributorRegistry registry;
|
||||
|
||||
@Value("${local.server.port}")
|
||||
private int port;
|
||||
|
||||
@Test
|
||||
public void healthEndpointShouldContainKubernetes() {
|
||||
this.webClient.get().uri("http://localhost:{port}/actuator/health", this.port)
|
||||
.accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isOk().expectBody(String.class)
|
||||
.value(containsString("kubernetes"));
|
||||
|
||||
Assertions.assertNotNull(registry.getContributor("kubernetes"),
|
||||
"reactive kubernetes contributor must be present when 'management.health.kubernetes.enabled=true'");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,167 +0,0 @@
|
||||
/*
|
||||
* 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.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
public class Fabric8BootstrapConfigurationTests {
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class)
|
||||
@Nested
|
||||
class KubernetesDisabled {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void configAndSecretsBeansAreNotPresent() {
|
||||
assertThat(context.getBeanNamesForType(Fabric8ConfigMapPropertySourceLocator.class)).hasSize(0);
|
||||
assertThat(context.getBeanNamesForType(Fabric8SecretsPropertySourceLocator.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@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" })
|
||||
@Nested
|
||||
class KubernetesEnabledOnPurpose {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void configAndSecretsBeansArePresent() {
|
||||
assertThat(context.getBeanNamesForType(Fabric8ConfigMapPropertySourceLocator.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(Fabric8SecretsPropertySourceLocator.class)).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class,
|
||||
properties = { "spring.cloud.kubernetes.client.namespace=default",
|
||||
"spring.main.cloud-platform=KUBERNETES" })
|
||||
@Nested
|
||||
class KubernetesEnabled {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void configAndSecretsBeansArePresent() {
|
||||
assertThat(context.getBeanNamesForType(Fabric8ConfigMapPropertySourceLocator.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(Fabric8SecretsPropertySourceLocator.class)).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class,
|
||||
properties = { "spring.cloud.kubernetes.config.enabled=false", "spring.main.cloud-platform=KUBERNETES" })
|
||||
@Nested
|
||||
class KubernetesEnabledConfigDisabled {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void secretsOnlyPresent() {
|
||||
assertThat(context.getBeanNamesForType(Fabric8ConfigMapPropertySourceLocator.class)).hasSize(0);
|
||||
assertThat(context.getBeanNamesForType(Fabric8SecretsPropertySourceLocator.class)).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@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" })
|
||||
@Nested
|
||||
class KubernetesEnabledSecretsDisabled {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void secretsOnlyPresent() {
|
||||
assertThat(context.getBeanNamesForType(Fabric8ConfigMapPropertySourceLocator.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(Fabric8SecretsPropertySourceLocator.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class,
|
||||
properties = { "spring.cloud.kubernetes.secrets.enabled=false",
|
||||
"spring.cloud.kubernetes.config.enabled=false" })
|
||||
@Nested
|
||||
class KubernetesEnabledSecretsAndConfigDisabled {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void secretsOnlyPresent() {
|
||||
assertThat(context.getBeanNamesForType(Fabric8ConfigMapPropertySourceLocator.class)).hasSize(0);
|
||||
assertThat(context.getBeanNamesForType(Fabric8SecretsPropertySourceLocator.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// tests that @ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES) has the desired
|
||||
// effect, meaning when it is enabled, both property sources are present
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class,
|
||||
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.cloud.kubernetes.client.namespace=abc" })
|
||||
@Nested
|
||||
class Fabric8BootstrapConfigurationInsideK8s {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void bothPresent() {
|
||||
assertThat(context.getBeanNamesForType(Fabric8ConfigMapPropertySourceLocator.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(Fabric8SecretsPropertySourceLocator.class)).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// tests that @ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES) has the desired
|
||||
// effect, meaning when it is disabled, no property source bean is present
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class)
|
||||
@Nested
|
||||
class Fabric8BootstrapConfigurationNotInsideK8s {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void bothMissing() {
|
||||
assertThat(context.getBeanNamesForType(Fabric8ConfigMapPropertySourceLocator.class)).hasSize(0);
|
||||
assertThat(context.getBeanNamesForType(Fabric8SecretsPropertySourceLocator.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,241 +0,0 @@
|
||||
/*
|
||||
* 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 java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.SecretBuilder;
|
||||
import io.fabric8.kubernetes.api.model.SecretListBuilder;
|
||||
import io.fabric8.kubernetes.client.Config;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
|
||||
import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
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.mock.mockito.SpyBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* @author Isik Erhan
|
||||
*/
|
||||
@EnableKubernetesMockClient
|
||||
public class Fabric8SecretsPropertySourceLocatorRetryTests {
|
||||
|
||||
private static final String API = "/api/v1/namespaces/default/secrets/my-secret";
|
||||
|
||||
private static final String LIST_API = "/api/v1/namespaces/default/secrets";
|
||||
|
||||
static KubernetesMockServer mockServer;
|
||||
|
||||
static KubernetesClient mockClient;
|
||||
|
||||
@BeforeAll
|
||||
public static void setup() {
|
||||
// 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");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true");
|
||||
|
||||
// return empty secret list to not fail context creation
|
||||
mockServer.expect().withPath(LIST_API).andReturn(200, new SecretListBuilder().build()).always();
|
||||
}
|
||||
|
||||
@Nested
|
||||
@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" },
|
||||
classes = Application.class)
|
||||
@EnableKubernetesMockClient
|
||||
class SecretsRetryEnabled {
|
||||
|
||||
@SpyBean
|
||||
private Fabric8SecretsPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Test
|
||||
public void locateShouldNotRetryWhenThereIsNoFailure() {
|
||||
Map<String, String> data = new HashMap<>();
|
||||
data.put("some.sensitive.prop", Base64.getEncoder().encodeToString("theSensitiveValue".getBytes()));
|
||||
data.put("some.sensitive.number", Base64.getEncoder().encodeToString("1".getBytes()));
|
||||
|
||||
// return secret without failing
|
||||
mockServer.expect().withPath(API).andReturn(200,
|
||||
new SecretBuilder().withNewMetadata().withName("my-secret").endMetadata().addToData(data).build())
|
||||
.once();
|
||||
|
||||
PropertySource<?> propertySource = Assertions
|
||||
.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
|
||||
|
||||
// verify locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
|
||||
// validate the contents of the property source
|
||||
assertThat(propertySource.getProperty("some.sensitive.prop")).isEqualTo("theSensitiveValue");
|
||||
assertThat(propertySource.getProperty("some.sensitive.number")).isEqualTo("1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void locateShouldRetryAndRecover() {
|
||||
Map<String, String> data = new HashMap<>();
|
||||
data.put("some.sensitive.prop", Base64.getEncoder().encodeToString("theSensitiveValue".getBytes()));
|
||||
data.put("some.sensitive.number", Base64.getEncoder().encodeToString("1".getBytes()));
|
||||
|
||||
// fail 3 times then succeed at the 4th call
|
||||
mockServer.expect().withPath(API).andReturn(500, "Internal Server Error").times(3);
|
||||
mockServer.expect().withPath(API).andReturn(200,
|
||||
new SecretBuilder().withNewMetadata().withName("my-secret").endMetadata().addToData(data).build())
|
||||
.once();
|
||||
|
||||
PropertySource<?> propertySource = Assertions
|
||||
.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
|
||||
|
||||
// verify retried 4 times
|
||||
verify(propertySourceLocator, times(4)).locate(any());
|
||||
|
||||
// validate the contents of the property source
|
||||
assertThat(propertySource.getProperty("some.sensitive.prop")).isEqualTo("theSensitiveValue");
|
||||
assertThat(propertySource.getProperty("some.sensitive.number")).isEqualTo("1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void locateShouldRetryAndFail() {
|
||||
// fail all the 5 requests
|
||||
mockServer.expect().withPath(API).andReturn(500, "Internal Server Error").times(5);
|
||||
|
||||
assertThatThrownBy(() -> propertySourceLocator.locate(new MockEnvironment()))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Unable to read Secret with name 'my-secret' or labels [{}] in namespace 'default'");
|
||||
|
||||
// verify retried 5 times until failure
|
||||
verify(propertySourceLocator, times(5)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
@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" },
|
||||
classes = Application.class)
|
||||
@EnableKubernetesMockClient
|
||||
class SecretsFailFastDisabled {
|
||||
|
||||
@SpyBean
|
||||
private Fabric8SecretsPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Test
|
||||
public void locateShouldNotRetry() {
|
||||
mockServer.expect().withPath(API).andReturn(500, "Internal Server Error").once();
|
||||
|
||||
Assertions.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
|
||||
|
||||
// verify locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,
|
||||
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" },
|
||||
classes = Application.class)
|
||||
@EnableKubernetesMockClient
|
||||
class SecretsRetryDisabledButConfigRetryEnabled {
|
||||
|
||||
@SpyBean
|
||||
private Fabric8SecretsPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void locateShouldFailWithoutRetrying() {
|
||||
|
||||
/*
|
||||
* Enabling config retry causes Spring Retry to be enabled and a
|
||||
* RetryOperationsInterceptor bean with NeverRetryPolicy for secrets to be
|
||||
* defined. SecretsPropertySourceLocator should not retry even Spring Retry is
|
||||
* enabled.
|
||||
*/
|
||||
|
||||
mockServer.expect().withPath(API).andReturn(500, "Internal Server Error").once();
|
||||
|
||||
assertThat(context.containsBean("kubernetesSecretsRetryInterceptor")).isTrue();
|
||||
assertThatThrownBy(() -> propertySourceLocator.locate(new MockEnvironment()))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Unable to read Secret with name 'my-secret' or labels [{}] in namespace 'default'");
|
||||
|
||||
// verify that propertySourceLocator.locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, 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" },
|
||||
classes = Application.class)
|
||||
@EnableKubernetesMockClient
|
||||
class SecretsFailFastEnabledButRetryDisabled {
|
||||
|
||||
@SpyBean
|
||||
private Fabric8SecretsPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void locateShouldFailWithoutRetrying() {
|
||||
|
||||
mockServer.expect().withPath(API).andReturn(500, "Internal Server Error").once();
|
||||
|
||||
assertThat(context.containsBean("kubernetesSecretsRetryInterceptor")).isFalse();
|
||||
assertThatThrownBy(() -> propertySourceLocator.locate(new MockEnvironment()))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Unable to read Secret with name 'my-secret' or labels [{}] in namespace 'default'");
|
||||
|
||||
// verify that propertySourceLocator.locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.fabric8.config.actuator;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.actuate.health.ReactiveHealthContributorRegistry;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
|
||||
properties = { "management.health.kubernetes.enabled=false", "management.endpoint.health.show-details=always",
|
||||
"management.endpoint.health.show-components=always", "management.endpoints.web.exposure.include=health",
|
||||
"spring.cloud.kubernetes.client.namespace=default" })
|
||||
class DisabledHealthTest {
|
||||
|
||||
@Autowired
|
||||
private ReactiveHealthContributorRegistry registry;
|
||||
|
||||
@Autowired
|
||||
private WebTestClient webClient;
|
||||
|
||||
@Value("${local.server.port}")
|
||||
private int port;
|
||||
|
||||
@Test
|
||||
void healthEndpointShouldContainKubernetes() {
|
||||
this.webClient.get().uri("http://localhost:{port}/actuator/health", this.port)
|
||||
.accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isOk().expectBody(String.class)
|
||||
.value(not(containsString("kubernetes")));
|
||||
|
||||
Assertions.assertNull(registry.getContributor("kubernetes"),
|
||||
"reactive kubernetes contributor must NOT be present when 'management.health.kubernetes.enabled=false'");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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.fabric8.config.actuator;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.actuate.health.ReactiveHealthContributorRegistry;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.example.App;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
|
||||
properties = { "management.health.kubernetes.enabled=true", "management.endpoint.health.show-details=always",
|
||||
"management.endpoint.health.show-components=always", "management.endpoints.web.exposure.include=health",
|
||||
"spring.cloud.kubernetes.client.namespace=default", "spring.main.cloud-platform=KUBERNETES" })
|
||||
class EnabledHealthTest {
|
||||
|
||||
@Autowired
|
||||
private WebTestClient webClient;
|
||||
|
||||
@Autowired
|
||||
private ReactiveHealthContributorRegistry registry;
|
||||
|
||||
@Value("${local.server.port}")
|
||||
private int port;
|
||||
|
||||
@Test
|
||||
void healthEndpointShouldContainKubernetes() {
|
||||
this.webClient.get().uri("http://localhost:{port}/actuator/health", this.port)
|
||||
.accept(MediaType.APPLICATION_JSON).exchange().expectStatus().isOk().expectBody(String.class)
|
||||
.value(containsString("kubernetes"));
|
||||
|
||||
Assertions.assertNotNull(registry.getContributor("kubernetes"),
|
||||
"reactive kubernetes contributor must be present when 'management.health.kubernetes.enabled=true'");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.fabric8.config.bootstrap;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Application;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySourceLocator;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySourceLocator;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
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" })
|
||||
class Fabric8BootstrapConfigurationInsideK8s {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
// tests that @ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES) has the desired
|
||||
// effect, meaning when it is enabled, both property sources are present
|
||||
@Test
|
||||
void bothPresent() {
|
||||
assertThat(context.getBeanNamesForType(Fabric8ConfigMapPropertySourceLocator.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(Fabric8SecretsPropertySourceLocator.class)).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.fabric8.config.bootstrap;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Application;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySourceLocator;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySourceLocator;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class)
|
||||
class Fabric8BootstrapConfigurationNotInsideK8s {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
// tests that @ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES) has the desired
|
||||
// effect, meaning when it is disabled, no property source bean is present
|
||||
@Test
|
||||
void bothMissing() {
|
||||
assertThat(context.getBeanNamesForType(Fabric8ConfigMapPropertySourceLocator.class)).hasSize(0);
|
||||
assertThat(context.getBeanNamesForType(Fabric8SecretsPropertySourceLocator.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.fabric8.config.bootstrap;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Application;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySourceLocator;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySourceLocator;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
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")
|
||||
class KubernetesDisabled {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void configAndSecretsBeansAreNotPresent() {
|
||||
assertThat(context.getBeanNamesForType(Fabric8ConfigMapPropertySourceLocator.class)).hasSize(0);
|
||||
assertThat(context.getBeanNamesForType(Fabric8SecretsPropertySourceLocator.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.fabric8.config.bootstrap;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Application;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySourceLocator;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySourceLocator;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Application.class,
|
||||
properties = { "spring.cloud.kubernetes.client.namespace=default", "spring.main.cloud-platform=KUBERNETES" })
|
||||
class KubernetesEnabled {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void configAndSecretsBeansArePresent() {
|
||||
assertThat(context.getBeanNamesForType(Fabric8ConfigMapPropertySourceLocator.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(Fabric8SecretsPropertySourceLocator.class)).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.bootstrap;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Application;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySourceLocator;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySourceLocator;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
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" })
|
||||
class KubernetesEnabledConfigDisabled {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void secretsOnlyPresent() {
|
||||
assertThat(context.getBeanNamesForType(Fabric8ConfigMapPropertySourceLocator.class)).hasSize(0);
|
||||
assertThat(context.getBeanNamesForType(Fabric8SecretsPropertySourceLocator.class)).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.fabric8.config.bootstrap;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Application;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySourceLocator;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySourceLocator;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@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" })
|
||||
class KubernetesEnabledOnPurpose {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void configAndSecretsBeansArePresent() {
|
||||
assertThat(context.getBeanNamesForType(Fabric8ConfigMapPropertySourceLocator.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(Fabric8SecretsPropertySourceLocator.class)).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.fabric8.config.bootstrap;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Application;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySourceLocator;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySourceLocator;
|
||||
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.secrets.enabled=false", "spring.cloud.kubernetes.config.enabled=false" })
|
||||
class KubernetesEnabledSecretsAndConfigDisabled {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void secretsOnlyPresent() {
|
||||
assertThat(context.getBeanNamesForType(Fabric8ConfigMapPropertySourceLocator.class)).hasSize(0);
|
||||
assertThat(context.getBeanNamesForType(Fabric8SecretsPropertySourceLocator.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.fabric8.config.bootstrap;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Application;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySourceLocator;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySourceLocator;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@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" })
|
||||
class KubernetesEnabledSecretsDisabled {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void secretsOnlyPresent() {
|
||||
assertThat(context.getBeanNamesForType(Fabric8ConfigMapPropertySourceLocator.class)).hasSize(1);
|
||||
assertThat(context.getBeanNamesForType(Fabric8SecretsPropertySourceLocator.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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.fabric8.config.locator_retry;
|
||||
|
||||
import io.fabric8.kubernetes.client.Config;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
|
||||
import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Application;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySourceLocator;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
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 = Application.class)
|
||||
@EnableKubernetesMockClient
|
||||
class ConfigFailFastDisabled {
|
||||
|
||||
private static final String API = "/api/v1/namespaces/default/configmaps/application";
|
||||
|
||||
private static KubernetesMockServer mockServer;
|
||||
|
||||
private static KubernetesClient mockClient;
|
||||
|
||||
@BeforeAll
|
||||
static void setup() {
|
||||
// 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");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true");
|
||||
}
|
||||
|
||||
@SpyBean
|
||||
private Fabric8ConfigMapPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Test
|
||||
void locateShouldNotRetry() {
|
||||
mockServer.expect().withPath(API).andReturn(500, "Internal Server Error").once();
|
||||
|
||||
Assertions.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
|
||||
|
||||
// verify that propertySourceLocator.locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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.fabric8.config.locator_retry;
|
||||
|
||||
import io.fabric8.kubernetes.client.Config;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
|
||||
import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
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.mock.mockito.SpyBean;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Application;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySourceLocator;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
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.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 = Application.class)
|
||||
@EnableKubernetesMockClient
|
||||
class ConfigFailFastEnabledButRetryDisabled {
|
||||
|
||||
private static final String API = "/api/v1/namespaces/default/configmaps/application";
|
||||
|
||||
private static KubernetesMockServer mockServer;
|
||||
|
||||
private static KubernetesClient mockClient;
|
||||
|
||||
@BeforeAll
|
||||
static void setup() {
|
||||
// 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");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true");
|
||||
}
|
||||
|
||||
@SpyBean
|
||||
private Fabric8ConfigMapPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
void locateShouldFailWithoutRetrying() {
|
||||
|
||||
mockServer.expect().withPath(API).andReturn(500, "Internal Server Error").once();
|
||||
|
||||
assertThat(context.containsBean("kubernetesConfigRetryInterceptor")).isFalse();
|
||||
assertThatThrownBy(() -> propertySourceLocator.locate(new MockEnvironment()))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Unable to read ConfigMap with name 'application' in namespace 'default'");
|
||||
|
||||
// verify that propertySourceLocator.locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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.fabric8.config.locator_retry;
|
||||
|
||||
import io.fabric8.kubernetes.client.Config;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
|
||||
import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
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.mock.mockito.SpyBean;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Application;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySourceLocator;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
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.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 = Application.class)
|
||||
@EnableKubernetesMockClient
|
||||
class ConfigRetryDisabledButSecretsRetryEnabled {
|
||||
|
||||
private static final String API = "/api/v1/namespaces/default/configmaps/application";
|
||||
|
||||
private static KubernetesMockServer mockServer;
|
||||
|
||||
private static KubernetesClient mockClient;
|
||||
|
||||
@BeforeAll
|
||||
static void setup() {
|
||||
// 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");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true");
|
||||
}
|
||||
|
||||
@SpyBean
|
||||
private Fabric8ConfigMapPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
void locateShouldFailWithoutRetrying() {
|
||||
|
||||
/*
|
||||
* Enabling secrets retry causes Spring Retry to be enabled and a
|
||||
* RetryOperationsInterceptor bean with NeverRetryPolicy for config maps to be
|
||||
* defined. ConfigMapPropertySourceLocator should not retry even Spring Retry is
|
||||
* enabled.
|
||||
*/
|
||||
|
||||
mockServer.expect().withPath(API).andReturn(500, "Internal Server Error").once();
|
||||
|
||||
assertThat(context.containsBean("kubernetesConfigRetryInterceptor")).isTrue();
|
||||
assertThatThrownBy(() -> propertySourceLocator.locate(new MockEnvironment()))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Unable to read ConfigMap with name 'application' in namespace 'default'");
|
||||
|
||||
// verify that propertySourceLocator.locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* 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.fabric8.config.locator_retry;
|
||||
|
||||
import java.util.HashMap;
|
||||
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 io.fabric8.kubernetes.client.server.mock.KubernetesMockServer;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Application;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8ConfigMapPropertySourceLocator;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
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.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.max-attempts=5",
|
||||
"spring.main.cloud-platform=KUBERNETES" },
|
||||
classes = Application.class)
|
||||
@EnableKubernetesMockClient
|
||||
class ConfigRetryEnabled {
|
||||
|
||||
private static final String API = "/api/v1/namespaces/default/configmaps/application";
|
||||
|
||||
private static KubernetesMockServer mockServer;
|
||||
|
||||
private static KubernetesClient mockClient;
|
||||
|
||||
@BeforeAll
|
||||
static void setup() {
|
||||
// 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");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true");
|
||||
}
|
||||
|
||||
@SpyBean
|
||||
private Fabric8ConfigMapPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Test
|
||||
void locateShouldNotRetryWhenThereIsNoFailure() {
|
||||
Map<String, String> data = new HashMap<>();
|
||||
data.put("some.prop", "theValue");
|
||||
data.put("some.number", "0");
|
||||
|
||||
// return config map without failing
|
||||
mockServer.expect().withPath(API).andReturn(200,
|
||||
new ConfigMapBuilder().withNewMetadata().withName("application").endMetadata().addToData(data).build())
|
||||
.once();
|
||||
|
||||
PropertySource<?> propertySource = Assertions
|
||||
.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
|
||||
|
||||
// verify locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
|
||||
// validate the contents of the property source
|
||||
assertThat(propertySource.getProperty("some.prop")).isEqualTo("theValue");
|
||||
assertThat(propertySource.getProperty("some.number")).isEqualTo("0");
|
||||
}
|
||||
|
||||
@Test
|
||||
void locateShouldRetryAndRecover() {
|
||||
Map<String, String> data = new HashMap<>();
|
||||
data.put("some.prop", "theValue");
|
||||
data.put("some.number", "0");
|
||||
|
||||
// fail 3 times then succeed at the 4th call
|
||||
mockServer.expect().withPath(API).andReturn(500, "Internal Server Error").times(3);
|
||||
mockServer.expect().withPath(API).andReturn(200,
|
||||
new ConfigMapBuilder().withNewMetadata().withName("application").endMetadata().addToData(data).build())
|
||||
.once();
|
||||
|
||||
PropertySource<?> propertySource = Assertions
|
||||
.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
|
||||
|
||||
// verify retried 4 times
|
||||
verify(propertySourceLocator, times(4)).locate(any());
|
||||
|
||||
// validate the contents of the property source
|
||||
assertThat(propertySource.getProperty("some.prop")).isEqualTo("theValue");
|
||||
assertThat(propertySource.getProperty("some.number")).isEqualTo("0");
|
||||
}
|
||||
|
||||
@Test
|
||||
void locateShouldRetryAndFail() {
|
||||
// fail all the 5 requests
|
||||
mockServer.expect().withPath(API).andReturn(500, "Internal Server Error").times(5);
|
||||
|
||||
assertThatThrownBy(() -> propertySourceLocator.locate(new MockEnvironment()))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Unable to read ConfigMap with name 'application' in namespace 'default'");
|
||||
|
||||
// verify retried 5 times until failure
|
||||
verify(propertySourceLocator, times(5)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.fabric8.config.retry;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.SecretListBuilder;
|
||||
import io.fabric8.kubernetes.client.Config;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
|
||||
import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Application;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySourceLocator;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
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.secrets.name=my-secret", "spring.cloud.kubernetes.secrets.enable-api=true",
|
||||
"spring.main.cloud-platform=KUBERNETES" },
|
||||
classes = Application.class)
|
||||
@EnableKubernetesMockClient
|
||||
class SecretsFailFastDisabled {
|
||||
|
||||
private static final String API = "/api/v1/namespaces/default/secrets/my-secret";
|
||||
|
||||
private static final String LIST_API = "/api/v1/namespaces/default/secrets";
|
||||
|
||||
private static KubernetesMockServer mockServer;
|
||||
|
||||
private static KubernetesClient mockClient;
|
||||
|
||||
@BeforeAll
|
||||
static void setup() {
|
||||
// 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");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true");
|
||||
|
||||
// return empty secret list to not fail context creation
|
||||
mockServer.expect().withPath(LIST_API).andReturn(200, new SecretListBuilder().build()).always();
|
||||
}
|
||||
|
||||
@SpyBean
|
||||
private Fabric8SecretsPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Test
|
||||
void locateShouldNotRetry() {
|
||||
mockServer.expect().withPath(API).andReturn(500, "Internal Server Error").once();
|
||||
|
||||
Assertions.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
|
||||
|
||||
// verify locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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.fabric8.config.retry;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.SecretListBuilder;
|
||||
import io.fabric8.kubernetes.client.Config;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
|
||||
import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
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.mock.mockito.SpyBean;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Application;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySourceLocator;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
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.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.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" },
|
||||
classes = Application.class)
|
||||
@EnableKubernetesMockClient
|
||||
class SecretsFailFastEnabledButRetryDisabled {
|
||||
|
||||
private static final String API = "/api/v1/namespaces/default/secrets/my-secret";
|
||||
|
||||
private static final String LIST_API = "/api/v1/namespaces/default/secrets";
|
||||
|
||||
private static KubernetesMockServer mockServer;
|
||||
|
||||
private static KubernetesClient mockClient;
|
||||
|
||||
@BeforeAll
|
||||
static void setup() {
|
||||
// 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");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true");
|
||||
|
||||
// return empty secret list to not fail context creation
|
||||
mockServer.expect().withPath(LIST_API).andReturn(200, new SecretListBuilder().build()).always();
|
||||
}
|
||||
|
||||
@SpyBean
|
||||
private Fabric8SecretsPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
void locateShouldFailWithoutRetrying() {
|
||||
|
||||
mockServer.expect().withPath(API).andReturn(500, "Internal Server Error").once();
|
||||
|
||||
assertThat(context.containsBean("kubernetesSecretsRetryInterceptor")).isFalse();
|
||||
assertThatThrownBy(() -> propertySourceLocator.locate(new MockEnvironment()))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Unable to read Secret with name 'my-secret' or labels [{}] in namespace 'default'");
|
||||
|
||||
// verify that propertySourceLocator.locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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.fabric8.config.retry;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.SecretListBuilder;
|
||||
import io.fabric8.kubernetes.client.Config;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
|
||||
import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
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.mock.mockito.SpyBean;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Application;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySourceLocator;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
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.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.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" },
|
||||
classes = Application.class)
|
||||
@EnableKubernetesMockClient
|
||||
class SecretsRetryDisabledButConfigRetryEnabled {
|
||||
|
||||
private static final String API = "/api/v1/namespaces/default/secrets/my-secret";
|
||||
|
||||
private static final String LIST_API = "/api/v1/namespaces/default/secrets";
|
||||
|
||||
private static KubernetesMockServer mockServer;
|
||||
|
||||
private static KubernetesClient mockClient;
|
||||
|
||||
@BeforeAll
|
||||
static void setup() {
|
||||
// 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");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true");
|
||||
|
||||
// return empty secret list to not fail context creation
|
||||
mockServer.expect().withPath(LIST_API).andReturn(200, new SecretListBuilder().build()).always();
|
||||
}
|
||||
|
||||
@SpyBean
|
||||
private Fabric8SecretsPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
void locateShouldFailWithoutRetrying() {
|
||||
|
||||
/*
|
||||
* Enabling config retry causes Spring Retry to be enabled and a
|
||||
* RetryOperationsInterceptor bean with NeverRetryPolicy for secrets to be
|
||||
* defined. SecretsPropertySourceLocator should not retry even Spring Retry is
|
||||
* enabled.
|
||||
*/
|
||||
|
||||
mockServer.expect().withPath(API).andReturn(500, "Internal Server Error").once();
|
||||
|
||||
assertThat(context.containsBean("kubernetesSecretsRetryInterceptor")).isTrue();
|
||||
assertThatThrownBy(() -> propertySourceLocator.locate(new MockEnvironment()))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Unable to read Secret with name 'my-secret' or labels [{}] in namespace 'default'");
|
||||
|
||||
// verify that propertySourceLocator.locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* 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.fabric8.config.retry;
|
||||
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.SecretBuilder;
|
||||
import io.fabric8.kubernetes.api.model.SecretListBuilder;
|
||||
import io.fabric8.kubernetes.client.Config;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
|
||||
import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.mock.mockito.SpyBean;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Application;
|
||||
import org.springframework.cloud.kubernetes.fabric8.config.Fabric8SecretsPropertySourceLocator;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
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.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.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" },
|
||||
classes = Application.class)
|
||||
@EnableKubernetesMockClient
|
||||
class SecretsRetryEnabled {
|
||||
|
||||
private static final String API = "/api/v1/namespaces/default/secrets/my-secret";
|
||||
|
||||
private static final String LIST_API = "/api/v1/namespaces/default/secrets";
|
||||
|
||||
private static KubernetesMockServer mockServer;
|
||||
|
||||
private static KubernetesClient mockClient;
|
||||
|
||||
@BeforeAll
|
||||
static void setup() {
|
||||
// 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");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false");
|
||||
System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true");
|
||||
|
||||
// return empty secret list to not fail context creation
|
||||
mockServer.expect().withPath(LIST_API).andReturn(200, new SecretListBuilder().build()).always();
|
||||
}
|
||||
|
||||
@SpyBean
|
||||
private Fabric8SecretsPropertySourceLocator propertySourceLocator;
|
||||
|
||||
@Test
|
||||
void locateShouldNotRetryWhenThereIsNoFailure() {
|
||||
Map<String, String> data = new HashMap<>();
|
||||
data.put("some.sensitive.prop", Base64.getEncoder().encodeToString("theSensitiveValue".getBytes()));
|
||||
data.put("some.sensitive.number", Base64.getEncoder().encodeToString("1".getBytes()));
|
||||
|
||||
// return secret without failing
|
||||
mockServer.expect().withPath(API).andReturn(200,
|
||||
new SecretBuilder().withNewMetadata().withName("my-secret").endMetadata().addToData(data).build())
|
||||
.once();
|
||||
|
||||
PropertySource<?> propertySource = Assertions
|
||||
.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
|
||||
|
||||
// verify locate is called only once
|
||||
verify(propertySourceLocator, times(1)).locate(any());
|
||||
|
||||
// validate the contents of the property source
|
||||
assertThat(propertySource.getProperty("some.sensitive.prop")).isEqualTo("theSensitiveValue");
|
||||
assertThat(propertySource.getProperty("some.sensitive.number")).isEqualTo("1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void locateShouldRetryAndRecover() {
|
||||
Map<String, String> data = new HashMap<>();
|
||||
data.put("some.sensitive.prop", Base64.getEncoder().encodeToString("theSensitiveValue".getBytes()));
|
||||
data.put("some.sensitive.number", Base64.getEncoder().encodeToString("1".getBytes()));
|
||||
|
||||
// fail 3 times then succeed at the 4th call
|
||||
mockServer.expect().withPath(API).andReturn(500, "Internal Server Error").times(3);
|
||||
mockServer.expect().withPath(API).andReturn(200,
|
||||
new SecretBuilder().withNewMetadata().withName("my-secret").endMetadata().addToData(data).build())
|
||||
.once();
|
||||
|
||||
PropertySource<?> propertySource = Assertions
|
||||
.assertDoesNotThrow(() -> propertySourceLocator.locate(new MockEnvironment()));
|
||||
|
||||
// verify retried 4 times
|
||||
verify(propertySourceLocator, times(4)).locate(any());
|
||||
|
||||
// validate the contents of the property source
|
||||
assertThat(propertySource.getProperty("some.sensitive.prop")).isEqualTo("theSensitiveValue");
|
||||
assertThat(propertySource.getProperty("some.sensitive.number")).isEqualTo("1");
|
||||
}
|
||||
|
||||
@Test
|
||||
void locateShouldRetryAndFail() {
|
||||
// fail all the 5 requests
|
||||
mockServer.expect().withPath(API).andReturn(500, "Internal Server Error").times(5);
|
||||
|
||||
assertThatThrownBy(() -> propertySourceLocator.locate(new MockEnvironment()))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Unable to read Secret with name 'my-secret' or labels [{}] in namespace 'default'");
|
||||
|
||||
// verify retried 5 times until failure
|
||||
verify(propertySourceLocator, times(5)).locate(any());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.fabric8.istio;
|
||||
|
||||
import me.snowdrop.istio.client.IstioClient;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
|
||||
properties = { "spring.cloud.istio.enabled=false" })
|
||||
class IstioAutoConfigurationClientNotPresentWhenIstioDisabled {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void istioClientNotPresent() {
|
||||
assertThat(context.getBeanNamesForType(IstioClient.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.fabric8.istio;
|
||||
|
||||
import me.snowdrop.istio.client.IstioClient;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
|
||||
properties = { "spring.cloud.kubernetes.enabled=false" })
|
||||
class IstioAutoConfigurationClientNotPresentWhenKubernetesDisabled {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void istioClientNotPresent() {
|
||||
assertThat(context.getBeanNamesForType(IstioClient.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.fabric8.istio;
|
||||
|
||||
import me.snowdrop.istio.client.IstioClient;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
|
||||
properties = "spring.main.cloud-platform=KUBERNETES")
|
||||
class IstioAutoConfigurationClientPresentByDefault {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void istioClientIsPresent() {
|
||||
assertThat(context.getBeanNamesForType(IstioClient.class)).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.fabric8.istio;
|
||||
|
||||
import me.snowdrop.istio.client.IstioClient;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
|
||||
properties = { "spring.cloud.istio.enabled=true", "spring.main.cloud-platform=KUBERNETES" })
|
||||
class IstioAutoConfigurationClientPresentWhenIstioEnabled {
|
||||
|
||||
@Autowired
|
||||
private ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
void istioClientIsPresent() {
|
||||
assertThat(context.getBeanNamesForType(IstioClient.class)).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* 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.istio;
|
||||
|
||||
import me.snowdrop.istio.client.IstioClient;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author wind57
|
||||
*/
|
||||
public class IstioAutoConfigurationTests {
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
|
||||
properties = "spring.main.cloud-platform=KUBERNETES")
|
||||
@Nested
|
||||
class IstioClientPresentByDefault {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void istioClientIsPresent() {
|
||||
assertThat(context.getBeanNamesForType(IstioClient.class)).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class)
|
||||
@Nested
|
||||
class IstioClientNotPresentWhenKubernetesDisabled {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void istioClientNotPresent() {
|
||||
assertThat(context.getBeanNamesForType(IstioClient.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
|
||||
properties = { "spring.main.cloud-platform=KUBERNETES", "spring.cloud.istio.enabled=true" })
|
||||
@Nested
|
||||
class IstioClientPresentWhenIstioEnabled {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void istioClientIsPresent() {
|
||||
assertThat(context.getBeanNamesForType(IstioClient.class)).hasSize(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = App.class,
|
||||
properties = { "spring.cloud.istio.enabled=false" })
|
||||
@Nested
|
||||
class IstioClientNotPresentPresentWhenIstioDisabled {
|
||||
|
||||
@Autowired
|
||||
ConfigurableApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void istioClientNotPresent() {
|
||||
assertThat(context.getBeanNamesForType(IstioClient.class)).hasSize(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user