diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigReloadAutoConfigurationTest.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigReloadAutoConfigurationTest.java index a78b344d2..67778d601 100644 --- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigReloadAutoConfigurationTest.java +++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigReloadAutoConfigurationTest.java @@ -504,8 +504,7 @@ static class LocalTestConfig { @Bean KubernetesClientProperties kubernetesClientProperties() { return new KubernetesClientProperties(null, null, null, "default", null, null, null, null, null, null, null, - null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null); + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null); } @Bean diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/KubernetesClientProperties.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/KubernetesClientProperties.java index f9dc5a699..24ecfda7f 100644 --- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/KubernetesClientProperties.java +++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/KubernetesClientProperties.java @@ -33,9 +33,9 @@ public record KubernetesClientProperties(Boolean trustCerts, String masterUrl, S String caCertFile, String caCertData, String clientCertFile, String clientCertData, String clientKeyFile, String clientKeyData, String clientKeyAlgo, String clientKeyPassphrase, String username, String password, Duration watchReconnectInterval, Duration watchReconnectLimit, Duration connectionTimeout, - Duration requestTimeout, @Deprecated(forRemoval = true) Duration rollingTimeout, Duration loggingInterval, - String httpProxy, String httpsProxy, String proxyUsername, String proxyPassword, String oauthToken, - String[] noProxy, @DefaultValue(SERVICE_ACCOUNT_NAMESPACE_PATH) String serviceAccountNamespacePath, + Duration requestTimeout, Duration loggingInterval, String httpProxy, String httpsProxy, String proxyUsername, + String proxyPassword, String oauthToken, String[] noProxy, + @DefaultValue(SERVICE_ACCOUNT_NAMESPACE_PATH) String serviceAccountNamespacePath, @DefaultValue(DEFAULT_USER_AGENT) String userAgent) { /** @@ -61,9 +61,9 @@ public KubernetesClientProperties withNamespace(String namespace) { this.caCertFile(), this.caCertData(), this.clientCertFile(), this.clientCertData(), this.clientKeyFile(), this.clientKeyData(), this.clientKeyAlgo(), this.clientKeyPassphrase(), this.username(), this.password(), this.watchReconnectInterval(), this.watchReconnectLimit(), - this.connectionTimeout(), this.requestTimeout(), this.rollingTimeout(), this.loggingInterval(), - this.httpProxy(), this.httpsProxy(), this.proxyUsername(), this.proxyPassword(), this.oauthToken(), - this.noProxy(), this.serviceAccountNamespacePath(), this.userAgent()); + this.connectionTimeout(), this.requestTimeout(), this.loggingInterval(), this.httpProxy(), + this.httpsProxy(), this.proxyUsername(), this.proxyPassword(), this.oauthToken(), this.noProxy(), + this.serviceAccountNamespacePath(), this.userAgent()); } } diff --git a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/KubernetesClientPropertiesTests.java b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/KubernetesClientPropertiesTests.java index a3ceef1ba..9732997ca 100644 --- a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/KubernetesClientPropertiesTests.java +++ b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/KubernetesClientPropertiesTests.java @@ -54,7 +54,6 @@ void testDefaults() { assertThat(properties.watchReconnectLimit()).isNull(); assertThat(properties.connectionTimeout()).isNull(); assertThat(properties.requestTimeout()).isNull(); - assertThat(properties.rollingTimeout()).isNull(); assertThat(properties.loggingInterval()).isNull(); assertThat(properties.httpProxy()).isNull(); assertThat(properties.httpsProxy()).isNull(); @@ -89,7 +88,6 @@ void testNonDefaults() { "spring.cloud.kubernetes.client.watch-reconnect-limit=300ms", "spring.cloud.kubernetes.client.connection-timeout=400ms", "spring.cloud.kubernetes.client.request-timeout=500ms", - "spring.cloud.kubernetes.client.rolling-timeout=600ms", "spring.cloud.kubernetes.client.logging-interval=700ms", "spring.cloud.kubernetes.client.http-proxy=http-proxy", "spring.cloud.kubernetes.client.https-proxy=https-proxy", @@ -120,7 +118,6 @@ void testNonDefaults() { assertThat(properties.watchReconnectLimit()).isEqualTo(Duration.ofMillis(300)); assertThat(properties.connectionTimeout()).isEqualTo(Duration.ofMillis(400)); assertThat(properties.requestTimeout()).isEqualTo(Duration.ofMillis(500)); - assertThat(properties.rollingTimeout()).isEqualTo(Duration.ofMillis(600)); assertThat(properties.loggingInterval()).isEqualTo(Duration.ofMillis(700)); assertThat(properties.httpProxy()).isEqualTo("http-proxy"); assertThat(properties.httpsProxy()).isEqualTo("https-proxy"); @@ -156,7 +153,6 @@ void testCopyWithNamespaceConstructor() { "spring.cloud.kubernetes.client.watch-reconnect-limit=300ms", "spring.cloud.kubernetes.client.connection-timeout=400ms", "spring.cloud.kubernetes.client.request-timeout=500ms", - "spring.cloud.kubernetes.client.rolling-timeout=600ms", "spring.cloud.kubernetes.client.logging-interval=700ms", "spring.cloud.kubernetes.client.http-proxy=http-proxy", "spring.cloud.kubernetes.client.https-proxy=https-proxy", @@ -188,7 +184,6 @@ void testCopyWithNamespaceConstructor() { assertThat(properties.watchReconnectLimit()).isEqualTo(Duration.ofMillis(300)); assertThat(properties.connectionTimeout()).isEqualTo(Duration.ofMillis(400)); assertThat(properties.requestTimeout()).isEqualTo(Duration.ofMillis(500)); - assertThat(properties.rollingTimeout()).isEqualTo(Duration.ofMillis(600)); assertThat(properties.loggingInterval()).isEqualTo(Duration.ofMillis(700)); assertThat(properties.httpProxy()).isEqualTo("http-proxy"); assertThat(properties.httpsProxy()).isEqualTo("https-proxy"); diff --git a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/KubernetesConfigDataLocationResolverTests.java b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/KubernetesConfigDataLocationResolverTests.java index e830ac4a0..0d0fabd5f 100644 --- a/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/KubernetesConfigDataLocationResolverTests.java +++ b/spring-cloud-kubernetes-commons/src/test/java/org/springframework/cloud/kubernetes/commons/config/KubernetesConfigDataLocationResolverTests.java @@ -154,7 +154,7 @@ void testResolveProfileSpecificTwo() { DefaultBootstrapContext context = new DefaultBootstrapContext(); KubernetesClientProperties properties = new KubernetesClientProperties(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, - null, null, null, "user-agent"); + null, null, "user-agent"); context.register(KubernetesClientProperties.class, BootstrapRegistry.InstanceSupplier.of(properties)); Mockito.when(RESOLVER_CONTEXT.getBinder()).thenReturn(binder); diff --git a/spring-cloud-kubernetes-dependencies/pom.xml b/spring-cloud-kubernetes-dependencies/pom.xml index 724eb4a15..f6c35a1f8 100644 --- a/spring-cloud-kubernetes-dependencies/pom.xml +++ b/spring-cloud-kubernetes-dependencies/pom.xml @@ -32,6 +32,7 @@ Spring Cloud Kubernetes :: Dependencies Spring Cloud Kubernetes Dependencies + 0.13.0 6.13.4 19.0.2 3.4.2 diff --git a/spring-cloud-kubernetes-fabric8-autoconfig/src/main/java/org/springframework/cloud/kubernetes/fabric8/Fabric8AutoConfiguration.java b/spring-cloud-kubernetes-fabric8-autoconfig/src/main/java/org/springframework/cloud/kubernetes/fabric8/Fabric8AutoConfiguration.java index fb5260475..b63e5f6d2 100644 --- a/spring-cloud-kubernetes-fabric8-autoconfig/src/main/java/org/springframework/cloud/kubernetes/fabric8/Fabric8AutoConfiguration.java +++ b/spring-cloud-kubernetes-fabric8-autoconfig/src/main/java/org/springframework/cloud/kubernetes/fabric8/Fabric8AutoConfiguration.java @@ -56,10 +56,6 @@ private static Integer orDurationInt(Duration left, Integer right) { return left != null ? (int) left.toMillis() : right; } - private static Long orDurationLong(Duration left, Long right) { - return left != null ? left.toMillis() : right; - } - @Bean @ConditionalOnMissingBean(Config.class) public Config kubernetesClientConfig(KubernetesClientProperties kubernetesClientProperties) { diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySourceLocatorTests.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySourceLocatorTests.java index 9b26bf7f1..94df9159f 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySourceLocatorTests.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySourceLocatorTests.java @@ -58,6 +58,10 @@ static void beforeAll() { @Test void locateShouldThrowExceptionOnFailureWhenFailFastIsEnabled() { + + mockClient.getConfiguration().setRequestRetryBackoffLimit(0); + mockClient.getConfiguration().setRequestRetryBackoffInterval(0); + String name = "my-config"; String namespace = "default"; String path = "/api/v1/namespaces/default/configmaps"; diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySourceTests.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySourceTests.java index 8e550838b..6743c6a5e 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySourceTests.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySourceTests.java @@ -55,6 +55,10 @@ void afterEach() { @Test void constructorShouldThrowExceptionOnFailureWhenFailFastIsEnabled() { + + mockClient.getConfiguration().setRequestRetryBackoffLimit(0); + mockClient.getConfiguration().setRequestRetryBackoffInterval(0); + String name = "my-config"; String namespace = "default"; String path = "/api/v1/namespaces/" + namespace + "/configmaps"; diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8SecretsPropertySourceLocatorTests.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8SecretsPropertySourceLocatorTests.java index e8ac439dc..e2a81bd99 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8SecretsPropertySourceLocatorTests.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8SecretsPropertySourceLocatorTests.java @@ -58,6 +58,10 @@ static void beforeAll() { @Test void locateShouldThrowExceptionOnFailureWhenFailFastIsEnabled() { + + mockClient.getConfiguration().setRequestRetryBackoffLimit(0); + mockClient.getConfiguration().setRequestRetryBackoffInterval(0); + String name = "my-secret"; String namespace = "default"; String path = "/api/v1/namespaces/default/secrets"; diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8SecretsPropertySourceMockTests.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8SecretsPropertySourceMockTests.java index a0a246ede..7e7435596 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8SecretsPropertySourceMockTests.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8SecretsPropertySourceMockTests.java @@ -66,6 +66,10 @@ void namedStrategyShouldThrowExceptionOnFailureWhenFailFastIsEnabled() { @Test void labeledStrategyShouldThrowExceptionOnFailureWhenFailFastIsEnabled() { + + client.getConfiguration().setRequestRetryBackoffInterval(0); + client.getConfiguration().setRequestRetryBackoffLimit(0); + final String namespace = "default"; final Map labels = Collections.singletonMap("a", "b"); final String path = String.format("/api/v1/namespaces/%s/secrets", namespace); diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/core_system_properties/CoreTestClientViaSystemProperties.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/core_system_properties/CoreTestClientViaSystemProperties.java index 9b2db1f68..2e2bcfdbf 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/core_system_properties/CoreTestClientViaSystemProperties.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/core_system_properties/CoreTestClientViaSystemProperties.java @@ -39,6 +39,8 @@ abstract class CoreTestClientViaSystemProperties { @BeforeAll static void setUpBeforeClass() { System.setProperty(Config.KUBERNETES_MASTER_SYSTEM_PROPERTY, "masterURL"); + System.setProperty(Config.KUBERNETES_REQUEST_RETRY_BACKOFFLIMIT_SYSTEM_PROPERTY, "0"); + System.setProperty(Config.KUBERNETES_REQUEST_RETRY_BACKOFFINTERVAL_SYSTEM_PROPERTY, "0"); } @Test diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/locator_retry/config_disabled_secrets_enabled/BoostrapConfigRetryDisabledButSecretsRetryEnabledTests.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/locator_retry/config_disabled_secrets_enabled/BoostrapConfigRetryDisabledButSecretsRetryEnabledTests.java new file mode 100644 index 000000000..967ca8fd9 --- /dev/null +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/locator_retry/config_disabled_secrets_enabled/BoostrapConfigRetryDisabledButSecretsRetryEnabledTests.java @@ -0,0 +1,50 @@ +/* + * 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.config_disabled_secrets_enabled; + +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.springframework.context.ApplicationContext; +import org.springframework.test.context.TestPropertySource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Isik Erhan + */ +@TestPropertySource(properties = "spring.cloud.bootstrap.enabled=true") +@EnableKubernetesMockClient +class BoostrapConfigRetryDisabledButSecretsRetryEnabledTests extends ConfigRetryDisabledButSecretsRetryEnabled { + + private static KubernetesMockServer mockServer; + + private static KubernetesClient mockClient; + + @BeforeAll + static void setup() { + setup(mockClient, mockServer); + } + + @Override + protected void assertRetryBean(ApplicationContext context) { + assertThat(context.containsBean("kubernetesConfigRetryInterceptor")).isTrue(); + } + +} diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/locator_retry/config_disabled_secrets_enabled/ConfigDataConfigRetryDisabledButSecretsRetryEnabledTests.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/locator_retry/config_disabled_secrets_enabled/ConfigDataConfigRetryDisabledButSecretsRetryEnabledTests.java new file mode 100644 index 000000000..708873548 --- /dev/null +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/locator_retry/config_disabled_secrets_enabled/ConfigDataConfigRetryDisabledButSecretsRetryEnabledTests.java @@ -0,0 +1,52 @@ +/* + * 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.config_disabled_secrets_enabled; + +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.springframework.cloud.kubernetes.commons.config.ConfigDataRetryableSecretsPropertySourceLocator; +import org.springframework.context.ApplicationContext; +import org.springframework.test.context.TestPropertySource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Isik Erhan + */ + +@TestPropertySource(properties = { "spring.config.import=kubernetes:" }) +@EnableKubernetesMockClient +class ConfigDataConfigRetryDisabledButSecretsRetryEnabledTests extends ConfigRetryDisabledButSecretsRetryEnabled { + + private static KubernetesMockServer mockServer; + + private static KubernetesClient mockClient; + + @BeforeAll + static void setup() { + setup(mockClient, mockServer); + } + + @Override + protected void assertRetryBean(ApplicationContext context) { + assertThat(context.getBean(ConfigDataRetryableSecretsPropertySourceLocator.class)).isNotNull(); + } + +} diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/locator_retry/config_disabled_secrets_enabled/ConfigRetryDisabledButSecretsRetryEnabled.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/locator_retry/config_disabled_secrets_enabled/ConfigRetryDisabledButSecretsRetryEnabled.java new file mode 100644 index 000000000..12eb3b4f5 --- /dev/null +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/locator_retry/config_disabled_secrets_enabled/ConfigRetryDisabledButSecretsRetryEnabled.java @@ -0,0 +1,99 @@ +/* + * 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.config_disabled_secrets_enabled; + +import io.fabric8.kubernetes.api.model.ConfigMapListBuilder; +import io.fabric8.kubernetes.client.Config; +import io.fabric8.kubernetes.client.KubernetesClient; +import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer; +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.Fabric8ConfigMapPropertySourceLocator; +import org.springframework.cloud.kubernetes.fabric8.config.TestApplication; +import org.springframework.context.ApplicationContext; +import org.springframework.mock.env.MockEnvironment; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +/** + * @author Isik Erhan + */ +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, + properties = { "spring.cloud.kubernetes.client.namespace=default", + "spring.cloud.kubernetes.config.fail-fast=true", "spring.cloud.kubernetes.config.retry.enabled=false", + "spring.cloud.kubernetes.secrets.fail-fast=true", "spring.main.cloud-platform=KUBERNETES" }, + classes = TestApplication.class) +abstract class ConfigRetryDisabledButSecretsRetryEnabled { + + private static final String API = "/api/v1/namespaces/default/configmaps"; + + private static KubernetesMockServer mockServer; + + private static KubernetesClient mockClient; + + @Autowired + private Fabric8ConfigMapPropertySourceLocator propertySourceLocator; + + static void setup(KubernetesClient mockClient, KubernetesMockServer mockServer) { + ConfigRetryDisabledButSecretsRetryEnabled.mockClient = mockClient; + ConfigRetryDisabledButSecretsRetryEnabled.mockServer = mockServer; + // 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"); + + System.setProperty(Config.KUBERNETES_REQUEST_RETRY_BACKOFFLIMIT_SYSTEM_PROPERTY, "0"); + System.setProperty(Config.KUBERNETES_REQUEST_RETRY_BACKOFFINTERVAL_SYSTEM_PROPERTY, "0"); + + // return empty secret list to not fail context creation + mockServer.expect().withPath(API).andReturn(200, new ConfigMapListBuilder().build()).always(); + } + + @Autowired + private ApplicationContext context; + + @Test + void locateShouldFailWithoutRetrying() { + Fabric8ConfigMapPropertySourceLocator psl = spy(propertySourceLocator); + /* + * 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.clearExpectations(); + mockServer.expect().withPath(API).andReturn(500, "Internal Server Error").once(); + + assertRetryBean(context); + assertThatThrownBy(() -> psl.locate(new MockEnvironment())).isInstanceOf(IllegalStateException.class) + .hasMessageContaining("v1/namespaces/default/configmaps. Message: Internal Server Error"); + + // verify that propertySourceLocator.locate is called only once + verify(psl, times(1)).locate(any()); + } + + protected abstract void assertRetryBean(ApplicationContext context); + +} diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/locator_retry/config_retry_disabled_sercrets_enabled/ConfigRetryDisabledButSecretsRetryEnabled.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/locator_retry/config_retry_disabled_sercrets_enabled/ConfigRetryDisabledButSecretsRetryEnabled.java index 4beb6cb06..398a935cf 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/locator_retry/config_retry_disabled_sercrets_enabled/ConfigRetryDisabledButSecretsRetryEnabled.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/locator_retry/config_retry_disabled_sercrets_enabled/ConfigRetryDisabledButSecretsRetryEnabled.java @@ -64,6 +64,9 @@ static void setup(KubernetesClient mockClient, KubernetesMockServer mockServer) System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false"); System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true"); + System.setProperty(Config.KUBERNETES_REQUEST_RETRY_BACKOFFLIMIT_SYSTEM_PROPERTY, "0"); + System.setProperty(Config.KUBERNETES_REQUEST_RETRY_BACKOFFINTERVAL_SYSTEM_PROPERTY, "0"); + // return empty secret list to not fail context creation mockServer.expect().withPath(API).andReturn(200, new ConfigMapListBuilder().build()).always(); } diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/locator_retry/config_retry_enabled/ConfigRetryEnabled.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/locator_retry/config_retry_enabled/ConfigRetryEnabled.java index bb6f5d4b1..fe88250cf 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/locator_retry/config_retry_enabled/ConfigRetryEnabled.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/locator_retry/config_retry_enabled/ConfigRetryEnabled.java @@ -68,6 +68,8 @@ static void setup(KubernetesClient mockClient, KubernetesMockServer mockServer) 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"); + System.setProperty(Config.KUBERNETES_REQUEST_RETRY_BACKOFFLIMIT_SYSTEM_PROPERTY, "0"); + System.setProperty(Config.KUBERNETES_REQUEST_RETRY_BACKOFFINTERVAL_SYSTEM_PROPERTY, "0"); // needed so that initial call, before our test method kicks in, succeeds mockServer.expect().withPath(API).andReturn(200, new ConfigMapListBuilder().build()).once(); diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/retry/secrets_enabled/SecretsRetryEnabled.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/retry/secrets_enabled/SecretsRetryEnabled.java index 37ec044a0..e4d5ecb7f 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/retry/secrets_enabled/SecretsRetryEnabled.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/retry/secrets_enabled/SecretsRetryEnabled.java @@ -70,6 +70,8 @@ static void setup(KubernetesClient mockClient, KubernetesMockServer mockServer) 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"); + System.setProperty(Config.KUBERNETES_REQUEST_RETRY_BACKOFFLIMIT_SYSTEM_PROPERTY, "0"); + System.setProperty(Config.KUBERNETES_REQUEST_RETRY_BACKOFFINTERVAL_SYSTEM_PROPERTY, "0"); // return empty secret list to not fail context creation mockServer.expect().withPath(LIST_API).andReturn(200, new SecretListBuilder().build()).once(); diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/retry/secrets_fail_fast_disabled/SecretsFailFastDisabled.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/retry/secrets_fail_fast_disabled/SecretsFailFastDisabled.java index ae0b932be..c3cc2f822 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/retry/secrets_fail_fast_disabled/SecretsFailFastDisabled.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/retry/secrets_fail_fast_disabled/SecretsFailFastDisabled.java @@ -65,6 +65,9 @@ static void setup(KubernetesClient mockClient, KubernetesMockServer mockServer) System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false"); System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true"); + System.setProperty(Config.KUBERNETES_REQUEST_RETRY_BACKOFFLIMIT_SYSTEM_PROPERTY, "0"); + System.setProperty(Config.KUBERNETES_REQUEST_RETRY_BACKOFFINTERVAL_SYSTEM_PROPERTY, "0"); + // return empty secret list to not fail context creation mockServer.expect().withPath(LIST_API).andReturn(200, new SecretListBuilder().build()).always(); } diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/retry/secrets_fail_fast_enabled_retry_disabled/SecretsFailFastEnabledButRetryDisabled.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/retry/secrets_fail_fast_enabled_retry_disabled/SecretsFailFastEnabledButRetryDisabled.java index 9d1e1b574..2f236e498 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/retry/secrets_fail_fast_enabled_retry_disabled/SecretsFailFastEnabledButRetryDisabled.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/retry/secrets_fail_fast_enabled_retry_disabled/SecretsFailFastEnabledButRetryDisabled.java @@ -66,6 +66,9 @@ static void setup(KubernetesClient mockClient, KubernetesMockServer mockServer) System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false"); System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true"); + System.setProperty(Config.KUBERNETES_REQUEST_RETRY_BACKOFFLIMIT_SYSTEM_PROPERTY, "0"); + System.setProperty(Config.KUBERNETES_REQUEST_RETRY_BACKOFFINTERVAL_SYSTEM_PROPERTY, "0"); + // return empty secret list to not fail context creation mockServer.expect().withPath(LIST_API).andReturn(200, new SecretListBuilder().build()).always(); } diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/retry/secrets_retry_disabled_config_enabled/SecretsRetryDisabledButConfigRetryEnabled.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/retry/secrets_retry_disabled_config_enabled/SecretsRetryDisabledButConfigRetryEnabled.java index c9255bf3a..ae6e3154e 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/retry/secrets_retry_disabled_config_enabled/SecretsRetryDisabledButConfigRetryEnabled.java +++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/retry/secrets_retry_disabled_config_enabled/SecretsRetryDisabledButConfigRetryEnabled.java @@ -68,6 +68,9 @@ protected static void setup(KubernetesClient mockClient, KubernetesMockServer mo System.setProperty(Config.KUBERNETES_AUTH_TRYSERVICEACCOUNT_SYSTEM_PROPERTY, "false"); System.setProperty(Config.KUBERNETES_HTTP2_DISABLE, "true"); + System.setProperty(Config.KUBERNETES_REQUEST_RETRY_BACKOFFLIMIT_SYSTEM_PROPERTY, "0"); + System.setProperty(Config.KUBERNETES_REQUEST_RETRY_BACKOFFINTERVAL_SYSTEM_PROPERTY, "0"); + // return empty secret list to not fail context creation mockServer.expect().withPath(SECRET_API).andReturn(200, new SecretListBuilder().build()).always(); mockServer.expect().withPath(CONFIG_MAP_API).andReturn(200, new ConfigMapListBuilder().build()).always(); diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/resources/logback-test.xml b/spring-cloud-kubernetes-fabric8-config/src/test/resources/logback-test.xml index 60fab6fb9..c7c1ca619 100644 --- a/spring-cloud-kubernetes-fabric8-config/src/test/resources/logback-test.xml +++ b/spring-cloud-kubernetes-fabric8-config/src/test/resources/logback-test.xml @@ -6,4 +6,5 @@ + diff --git a/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/fabric8_client/Util.java b/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/fabric8_client/Util.java index 8d98a078e..3de03fcd9 100644 --- a/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/fabric8_client/Util.java +++ b/spring-cloud-kubernetes-test-support/src/main/java/org/springframework/cloud/kubernetes/integration/tests/commons/fabric8_client/Util.java @@ -233,12 +233,12 @@ public void setUpClusterWide(String serviceAccountNamespace, Set namespa InputStream serviceAccountAsStream = inputStream("cluster/service-account.yaml"); InputStream roleBindingAsStream = inputStream("cluster/role-binding.yaml"); - ClusterRole clusterRole = client.rbac().clusterRoles().load(clusterRoleBindingAsStream).item(); + ClusterRole clusterRole = Serialization.unmarshal(clusterRoleBindingAsStream, ClusterRole.class); if (client.rbac().clusterRoles().withName(clusterRole.getMetadata().getName()).get() == null) { client.rbac().clusterRoles().resource(clusterRole).create(); } - ServiceAccount serviceAccountFromStream = client.serviceAccounts().load(serviceAccountAsStream).item(); + ServiceAccount serviceAccountFromStream = Serialization.unmarshal(serviceAccountAsStream, ServiceAccount.class); serviceAccountFromStream.getMetadata().setNamespace(serviceAccountNamespace); if (client.serviceAccounts() .inNamespace(serviceAccountNamespace) @@ -247,7 +247,7 @@ public void setUpClusterWide(String serviceAccountNamespace, Set namespa client.serviceAccounts().inNamespace(serviceAccountNamespace).resource(serviceAccountFromStream).create(); } - RoleBinding roleBindingFromStream = client.rbac().roleBindings().load(roleBindingAsStream).item(); + RoleBinding roleBindingFromStream = Serialization.unmarshal(roleBindingAsStream, RoleBinding.class); namespaces.forEach(namespace -> { roleBindingFromStream.getMetadata().setNamespace(namespace); @@ -352,7 +352,7 @@ public void wiremock(String namespace, String path, Phase phase, boolean withIng if (phase.equals(Phase.CREATE)) { if (withIngress) { - ingress = client.network().v1().ingresses().load(ingressStream).get(); + ingress = Serialization.unmarshal(ingressStream, Ingress.class); ingress.getMetadata().setNamespace(namespace); ingress.getSpec().getRules().get(0).getHttp().getPaths().get(0).setPath(path); } @@ -364,7 +364,7 @@ public void wiremock(String namespace, String path, Phase phase, boolean withIng else { if (withIngress) { - ingress = client.network().v1().ingresses().load(ingressStream).get(); + ingress = Serialization.unmarshal(ingressStream, Ingress.class); } deleteAndWait(namespace, deployment, service, ingress); @@ -524,37 +524,26 @@ private boolean isDeploymentReadyAfterPatch(String deploymentName, String namesp private void innerSetup(String namespace, InputStream serviceAccountAsStream, InputStream roleBindingAsStream, InputStream roleAsStream) { - ServiceAccount serviceAccountFromStream = client.serviceAccounts() - .inNamespace(namespace) - .load(serviceAccountAsStream) - .item(); + ServiceAccount serviceAccount = Serialization.unmarshal(serviceAccountAsStream, ServiceAccount.class); if (client.serviceAccounts() .inNamespace(namespace) - .withName(serviceAccountFromStream.getMetadata().getName()) + .withName(serviceAccount.getMetadata().getName()) .get() == null) { - client.serviceAccounts().inNamespace(namespace).resource(serviceAccountFromStream).create(); + client.serviceAccounts().inNamespace(namespace).resource(serviceAccount).create(); } - RoleBinding roleBindingFromStream = client.rbac() - .roleBindings() - .inNamespace(namespace) - .load(roleBindingAsStream) - .item(); + RoleBinding roleBinding = Serialization.unmarshal(roleBindingAsStream, RoleBinding.class); if (client.rbac() .roleBindings() .inNamespace(namespace) - .withName(roleBindingFromStream.getMetadata().getName()) + .withName(roleBinding.getMetadata().getName()) .get() == null) { - client.rbac().roleBindings().inNamespace(namespace).resource(roleBindingFromStream).create(); + client.rbac().roleBindings().inNamespace(namespace).resource(roleBinding).create(); } - Role roleFromStream = client.rbac().roles().inNamespace(namespace).load(roleAsStream).item(); - if (client.rbac() - .roles() - .inNamespace(namespace) - .withName(roleFromStream.getMetadata().getName()) - .get() == null) { - client.rbac().roles().inNamespace(namespace).resource(roleFromStream).create(); + Role role = Serialization.unmarshal(roleAsStream, Role.class); + if (client.rbac().roles().inNamespace(namespace).withName(role.getMetadata().getName()).get() == null) { + client.rbac().roles().inNamespace(namespace).resource(role).create(); } }