diff --git a/spring-cloud-kubernetes-client-config/pom.xml b/spring-cloud-kubernetes-client-config/pom.xml
index ae492891..e243450a 100644
--- a/spring-cloud-kubernetes-client-config/pom.xml
+++ b/spring-cloud-kubernetes-client-config/pom.xml
@@ -57,6 +57,16 @@
org.springframework.cloud
spring-cloud-starter-bootstrap
+
+ org.springframework.retry
+ spring-retry
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+ true
+
org.springframework.boot
@@ -93,12 +103,6 @@
spring-boot-starter-webflux
test
-
-
- org.springframework.retry
- spring-retry
- test
-
org.springframework.boot
spring-boot-starter-aop
diff --git a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientBootstrapConfiguration.java b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientBootstrapConfiguration.java
index 564515a5..93018d0d 100644
--- a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientBootstrapConfiguration.java
+++ b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientBootstrapConfiguration.java
@@ -27,6 +27,8 @@ import org.springframework.cloud.kubernetes.commons.ConditionalOnKubernetesEnabl
import org.springframework.cloud.kubernetes.commons.ConditionalOnKubernetesSecretsEnabled;
import org.springframework.cloud.kubernetes.commons.KubernetesCommonsAutoConfiguration;
import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
+import org.springframework.cloud.kubernetes.commons.config.ConditionalOnKubernetesConfigRetryDisabled;
+import org.springframework.cloud.kubernetes.commons.config.ConditionalOnKubernetesSecretsRetryDisabled;
import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties;
import org.springframework.cloud.kubernetes.commons.config.KubernetesBootstrapConfiguration;
import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties;
@@ -46,6 +48,7 @@ public class KubernetesClientBootstrapConfiguration {
@Bean
@ConditionalOnKubernetesConfigEnabled
+ @ConditionalOnKubernetesConfigRetryDisabled
public KubernetesClientConfigMapPropertySourceLocator configMapPropertySourceLocator(
ConfigMapConfigProperties properties, CoreV1Api coreV1Api,
KubernetesNamespaceProvider kubernetesNamespaceProvider) {
@@ -54,6 +57,7 @@ public class KubernetesClientBootstrapConfiguration {
@Bean
@ConditionalOnKubernetesSecretsEnabled
+ @ConditionalOnKubernetesSecretsRetryDisabled
public KubernetesClientSecretsPropertySourceLocator secretsPropertySourceLocator(SecretsConfigProperties properties,
CoreV1Api coreV1Api, KubernetesNamespaceProvider kubernetesNamespaceProvider) {
return new KubernetesClientSecretsPropertySourceLocator(coreV1Api, kubernetesNamespaceProvider, properties);
diff --git a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientRetryBootstrapConfiguration.java b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientRetryBootstrapConfiguration.java
new file mode 100644
index 00000000..0dff4e67
--- /dev/null
+++ b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientRetryBootstrapConfiguration.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2013-2022 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cloud.kubernetes.client.config;
+
+import io.kubernetes.client.openapi.apis.CoreV1Api;
+
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnCloudPlatform;
+import org.springframework.boot.cloud.CloudPlatform;
+import org.springframework.cloud.kubernetes.client.KubernetesClientAutoConfiguration;
+import org.springframework.cloud.kubernetes.commons.ConditionalOnKubernetesEnabled;
+import org.springframework.cloud.kubernetes.commons.KubernetesCommonsAutoConfiguration;
+import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
+import org.springframework.cloud.kubernetes.commons.config.ConditionalOnKubernetesConfigOrSecretsRetryEnabled;
+import org.springframework.cloud.kubernetes.commons.config.ConditionalOnKubernetesConfigRetryEnabled;
+import org.springframework.cloud.kubernetes.commons.config.ConditionalOnKubernetesSecretsRetryEnabled;
+import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties;
+import org.springframework.cloud.kubernetes.commons.config.KubernetesBootstrapConfiguration;
+import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+/**
+ * @author Ryan Baxter
+ */
+@Configuration(proxyBeanMethods = false)
+@ConditionalOnKubernetesEnabled
+@AutoConfigureAfter(KubernetesBootstrapConfiguration.class)
+@AutoConfigureBefore(KubernetesClientBootstrapConfiguration.class)
+@Import({ KubernetesCommonsAutoConfiguration.class, KubernetesClientAutoConfiguration.class })
+@ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES)
+@ConditionalOnKubernetesConfigOrSecretsRetryEnabled
+public class KubernetesClientRetryBootstrapConfiguration {
+
+ @Bean
+ @ConditionalOnKubernetesConfigRetryEnabled
+ public KubernetesClientConfigMapPropertySourceLocator retryableConfigMapPropertySourceLocator(
+ ConfigMapConfigProperties properties, CoreV1Api coreV1Api,
+ KubernetesNamespaceProvider kubernetesNamespaceProvider) {
+ return new RetryableKubernetesClientConfigMapPropertySourceLocator(coreV1Api, properties,
+ kubernetesNamespaceProvider);
+ }
+
+ @Bean
+ @ConditionalOnKubernetesSecretsRetryEnabled
+ public KubernetesClientSecretsPropertySourceLocator retryableSecretsPropertySourceLocator(
+ SecretsConfigProperties properties, CoreV1Api coreV1Api,
+ KubernetesNamespaceProvider kubernetesNamespaceProvider) {
+ return new RetryableKubernetesClientSecretsPropertySourceLocator(coreV1Api, kubernetesNamespaceProvider,
+ properties);
+ }
+
+}
diff --git a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/RetryableKubernetesClientConfigMapPropertySourceLocator.java b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/RetryableKubernetesClientConfigMapPropertySourceLocator.java
new file mode 100644
index 00000000..1dc602ed
--- /dev/null
+++ b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/RetryableKubernetesClientConfigMapPropertySourceLocator.java
@@ -0,0 +1,53 @@
+/*
+ * 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 java.util.Collection;
+
+import io.kubernetes.client.openapi.apis.CoreV1Api;
+
+import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
+import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties;
+import org.springframework.core.env.Environment;
+import org.springframework.core.env.PropertySource;
+import org.springframework.retry.annotation.Retryable;
+
+/**
+ * ConfigMapPropertySourceLocator for when retry is enabled.
+ *
+ * @author Ryan Baxter
+ */
+class RetryableKubernetesClientConfigMapPropertySourceLocator extends KubernetesClientConfigMapPropertySourceLocator {
+
+ RetryableKubernetesClientConfigMapPropertySourceLocator(CoreV1Api coreV1Api, ConfigMapConfigProperties properties,
+ KubernetesNamespaceProvider kubernetesNamespaceProvider) {
+ super(coreV1Api, properties, kubernetesNamespaceProvider);
+ }
+
+ @Override
+ @Retryable(interceptor = "kubernetesConfigRetryInterceptor")
+ public PropertySource> locate(Environment environment) {
+ return super.locate(environment);
+ }
+
+ @Override
+ @Retryable(interceptor = "kubernetesConfigRetryInterceptor")
+ public Collection> locateCollection(Environment environment) {
+ return super.locateCollection(environment);
+ }
+
+}
diff --git a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/RetryableKubernetesClientSecretsPropertySourceLocator.java b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/RetryableKubernetesClientSecretsPropertySourceLocator.java
new file mode 100644
index 00000000..ab922d66
--- /dev/null
+++ b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/RetryableKubernetesClientSecretsPropertySourceLocator.java
@@ -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.client.config;
+
+import java.util.Collection;
+
+import io.kubernetes.client.openapi.apis.CoreV1Api;
+
+import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
+import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties;
+import org.springframework.core.env.Environment;
+import org.springframework.core.env.PropertySource;
+import org.springframework.retry.annotation.Retryable;
+
+/**
+ * SecretsPropertySourceLocator for when retry is enabled.
+ *
+ * @author Ryan Baxter
+ */
+class RetryableKubernetesClientSecretsPropertySourceLocator extends KubernetesClientSecretsPropertySourceLocator {
+
+ RetryableKubernetesClientSecretsPropertySourceLocator(CoreV1Api coreV1Api,
+ KubernetesNamespaceProvider kubernetesNamespaceProvider, SecretsConfigProperties secretsConfigProperties) {
+ super(coreV1Api, kubernetesNamespaceProvider, secretsConfigProperties);
+ }
+
+ @Override
+ @Retryable(interceptor = "kubernetesSecretsRetryInterceptor")
+ public PropertySource> locate(Environment environment) {
+ return super.locate(environment);
+ }
+
+ @Override
+ @Retryable(interceptor = "kubernetesSecretsRetryInterceptor")
+ public Collection> locateCollection(Environment environment) {
+ return super.locateCollection(environment);
+ }
+
+}
diff --git a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedConfigMapChangeDetector.java b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedConfigMapChangeDetector.java
index 5db77916..9d03ae75 100644
--- a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedConfigMapChangeDetector.java
+++ b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedConfigMapChangeDetector.java
@@ -49,9 +49,9 @@ public class KubernetesClientEventBasedConfigMapChangeDetector extends Configura
private CoreV1Api coreV1Api = null;
- private KubernetesClientConfigMapPropertySourceLocator propertySourceLocator;
+ private final KubernetesClientConfigMapPropertySourceLocator propertySourceLocator;
- private SharedInformerFactory factory;
+ private final SharedInformerFactory factory;
private KubernetesClientProperties kubernetesClientProperties;
diff --git a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedSecretsChangeDetector.java b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedSecretsChangeDetector.java
index d62b208e..e81ff395 100644
--- a/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedSecretsChangeDetector.java
+++ b/spring-cloud-kubernetes-client-config/src/main/java/org/springframework/cloud/kubernetes/client/config/reload/KubernetesClientEventBasedSecretsChangeDetector.java
@@ -48,9 +48,9 @@ public class KubernetesClientEventBasedSecretsChangeDetector extends Configurati
private CoreV1Api coreV1Api;
- private KubernetesClientSecretsPropertySourceLocator propertySourceLocator;
+ private final KubernetesClientSecretsPropertySourceLocator propertySourceLocator;
- private SharedInformerFactory factory;
+ private final SharedInformerFactory factory;
private KubernetesClientProperties kubernetesClientProperties;
diff --git a/spring-cloud-kubernetes-client-config/src/main/resources/META-INF/spring.factories b/spring-cloud-kubernetes-client-config/src/main/resources/META-INF/spring.factories
index 067e1fb4..2efd0550 100644
--- a/spring-cloud-kubernetes-client-config/src/main/resources/META-INF/spring.factories
+++ b/spring-cloud-kubernetes-client-config/src/main/resources/META-INF/spring.factories
@@ -1,4 +1,5 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.kubernetes.client.config.reload.KubernetesClientConfigReloadAutoConfiguration
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
-org.springframework.cloud.kubernetes.client.config.KubernetesClientBootstrapConfiguration
+org.springframework.cloud.kubernetes.client.config.KubernetesClientBootstrapConfiguration,\
+org.springframework.cloud.kubernetes.client.config.KubernetesClientRetryBootstrapConfiguration
diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/EnableRetryBootstrapConfiguration.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/EnableRetryBootstrapConfiguration.java
new file mode 100644
index 00000000..c9a5cc5f
--- /dev/null
+++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/EnableRetryBootstrapConfiguration.java
@@ -0,0 +1,33 @@
+/*
+ * 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.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+import org.springframework.retry.annotation.EnableRetry;
+
+/**
+ * @author Ryan Baxter
+ */
+@Order(0)
+@Configuration
+@ConditionalOnProperty("spring.cloud.kubernetes.test.enable-retry")
+@EnableRetry
+public class EnableRetryBootstrapConfiguration {
+
+}
diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapPropertySourceLocatorRetryTests.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapPropertySourceLocatorRetryTests.java
index 31aee7ce..4a792317 100644
--- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapPropertySourceLocatorRetryTests.java
+++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientConfigMapPropertySourceLocatorRetryTests.java
@@ -16,7 +16,10 @@
package org.springframework.cloud.kubernetes.client.config;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import com.github.tomakehurst.wiremock.WireMockServer;
@@ -36,13 +39,26 @@ import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
+import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
+import org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration;
+import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration;
+import org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration;
import org.springframework.cloud.kubernetes.client.KubernetesClientUtils;
+import org.springframework.cloud.kubernetes.client.config.reload.KubernetesClientConfigReloadAutoConfiguration;
+import org.springframework.cloud.kubernetes.commons.config.KubernetesBootstrapConfiguration;
+import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadAutoConfiguration;
import org.springframework.context.ApplicationContext;
+import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.PropertySource;
import org.springframework.mock.env.MockEnvironment;
+import org.springframework.retry.annotation.RetryConfiguration;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
@@ -274,6 +290,44 @@ public class KubernetesClientConfigMapPropertySourceLocatorRetryTests {
}
+ @Nested
+ public class EnableRetryWithoutFailFastTest {
+
+ private ConfigurableApplicationContext context;
+
+ protected void setup(String... env) {
+ List envList = (env != null) ? new ArrayList<>(Arrays.asList(env)) : new ArrayList<>();
+ envList.add("spring.cloud.kubernetes.client.namespace=default");
+ String[] envArray = envList.toArray(new String[0]);
+
+ context = new SpringApplicationBuilder(RetryConfiguration.class, PropertyPlaceholderAutoConfiguration.class,
+ ConfigReloadAutoConfiguration.class, RefreshAutoConfiguration.class,
+ EndpointAutoConfiguration.class, InfoEndpointAutoConfiguration.class,
+ RefreshEndpointAutoConfiguration.class, ConfigurationPropertiesBindingPostProcessor.class,
+ ConfigurationPropertiesRebinderAutoConfiguration.class,
+ KubernetesClientBootstrapConfiguration.class, KubernetesClientRetryBootstrapConfiguration.class,
+ KubernetesBootstrapConfiguration.class, KubernetesClientConfigReloadAutoConfiguration.class)
+ .web(org.springframework.boot.WebApplicationType.NONE).properties(envArray).run();
+ }
+
+ @AfterEach
+ public void afterEach() {
+ if (this.context != null) {
+ this.context.close();
+ this.context = null;
+ }
+ }
+
+ @Test
+ public void doesNotContainRetryableConfigMapPropertySourceLocator() throws Exception {
+ stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
+ setup("debug=true", "spring.main.cloud-platform=KUBERNETES",
+ "spring.cloud.kubernetes.test.enable-retry=true");
+ assertThat(context.containsBean("retryableConfigMapPropertySourceLocator")).isFalse();
+ }
+
+ }
+
@SpringBootApplication
static class App {
diff --git a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientSecretsPropertySourceLocatorRetryTests.java b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientSecretsPropertySourceLocatorRetryTests.java
index a7863e22..02629b96 100644
--- a/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientSecretsPropertySourceLocatorRetryTests.java
+++ b/spring-cloud-kubernetes-client-config/src/test/java/org/springframework/cloud/kubernetes/client/config/KubernetesClientSecretsPropertySourceLocatorRetryTests.java
@@ -16,7 +16,10 @@
package org.springframework.cloud.kubernetes.client.config;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import com.github.tomakehurst.wiremock.WireMockServer;
@@ -36,13 +39,26 @@ import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
+import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
+import org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration;
+import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration;
+import org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration;
import org.springframework.cloud.kubernetes.client.KubernetesClientUtils;
+import org.springframework.cloud.kubernetes.client.config.reload.KubernetesClientConfigReloadAutoConfiguration;
+import org.springframework.cloud.kubernetes.commons.config.KubernetesBootstrapConfiguration;
+import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadAutoConfiguration;
import org.springframework.context.ApplicationContext;
+import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.PropertySource;
import org.springframework.mock.env.MockEnvironment;
+import org.springframework.retry.annotation.RetryConfiguration;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
@@ -276,6 +292,45 @@ public class KubernetesClientSecretsPropertySourceLocatorRetryTests {
}
+ @Nested
+ public class EnableRetryWithoutFailFastTest {
+
+ private ConfigurableApplicationContext context;
+
+ protected void setup(String... env) {
+ List envList = (env != null) ? new ArrayList<>(Arrays.asList(env)) : new ArrayList<>();
+ envList.add("spring.cloud.kubernetes.client.namespace=default");
+ String[] envArray = envList.toArray(new String[0]);
+
+ context = new SpringApplicationBuilder(RetryConfiguration.class, PropertyPlaceholderAutoConfiguration.class,
+ ConfigReloadAutoConfiguration.class, RefreshAutoConfiguration.class,
+ EndpointAutoConfiguration.class, InfoEndpointAutoConfiguration.class,
+ RefreshEndpointAutoConfiguration.class, ConfigurationPropertiesBindingPostProcessor.class,
+ ConfigurationPropertiesRebinderAutoConfiguration.class,
+ KubernetesClientBootstrapConfiguration.class, KubernetesClientRetryBootstrapConfiguration.class,
+ KubernetesBootstrapConfiguration.class, KubernetesClientConfigReloadAutoConfiguration.class)
+ .web(org.springframework.boot.WebApplicationType.NONE).properties(envArray).run();
+ }
+
+ @AfterEach
+ public void afterEach() {
+ if (this.context != null) {
+ this.context.close();
+ this.context = null;
+ }
+ }
+
+ @Test
+ public void doesNotContainRetryableSecretsPropertySourceLocator() throws Exception {
+ stubFor(get(API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
+ setup("debug=true", "spring.main.cloud-platform=KUBERNETES",
+ "spring.cloud.kubernetes.test.enable-retry=true", "spring.cloud.kubernetes.secrets.name=my-secret",
+ "spring.cloud.kubernetes.secrets.enable-api=true");
+ assertThat(context.containsBean("retryableSecretsPropertySourceLocator")).isFalse();
+ }
+
+ }
+
@SpringBootApplication
static class App {
diff --git a/spring-cloud-kubernetes-client-config/src/test/resources/META-INF/spring.factories b/spring-cloud-kubernetes-client-config/src/test/resources/META-INF/spring.factories
index 5d0b2c08..6332427d 100644
--- a/spring-cloud-kubernetes-client-config/src/test/resources/META-INF/spring.factories
+++ b/spring-cloud-kubernetes-client-config/src/test/resources/META-INF/spring.factories
@@ -1,3 +1,4 @@
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.springframework.cloud.kubernetes.client.config.boostrap.stubs.IncludeProfileSpecificSourcesConfigurationStub, \
-org.springframework.cloud.kubernetes.client.config.boostrap.stubs.ConfigMapNameAsPrefixConfigurationStub
+org.springframework.cloud.kubernetes.client.config.boostrap.stubs.ConfigMapNameAsPrefixConfigurationStub, \
+org.springframework.cloud.kubernetes.client.config.EnableRetryBootstrapConfiguration
diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/ConfigMapPropertySourceLocator.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/ConfigMapPropertySourceLocator.java
index 3f54243a..38d96efd 100644
--- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/ConfigMapPropertySourceLocator.java
+++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/ConfigMapPropertySourceLocator.java
@@ -37,7 +37,6 @@ import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
-import org.springframework.retry.annotation.Retryable;
import static org.springframework.cloud.kubernetes.commons.config.ConfigUtils.getApplicationName;
import static org.springframework.cloud.kubernetes.commons.config.PropertySourceUtils.KEY_VALUE_TO_PROPERTIES;
@@ -65,7 +64,6 @@ public abstract class ConfigMapPropertySourceLocator implements PropertySourceLo
String configurationTarget, ConfigurableEnvironment environment);
@Override
- @Retryable(interceptor = "kubernetesConfigRetryInterceptor")
public PropertySource> locate(Environment environment) {
if (environment instanceof ConfigurableEnvironment) {
ConfigurableEnvironment env = (ConfigurableEnvironment) environment;
@@ -85,7 +83,6 @@ public abstract class ConfigMapPropertySourceLocator implements PropertySourceLo
}
@Override
- @Retryable(interceptor = "kubernetesConfigRetryInterceptor")
public Collection> locateCollection(Environment environment) {
return PropertySourceLocator.super.locateCollection(environment);
}
diff --git a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/SecretsPropertySourceLocator.java b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/SecretsPropertySourceLocator.java
index ee07aca3..7afa8689 100644
--- a/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/SecretsPropertySourceLocator.java
+++ b/spring-cloud-kubernetes-commons/src/main/java/org/springframework/cloud/kubernetes/commons/config/SecretsPropertySourceLocator.java
@@ -43,7 +43,6 @@ import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
-import org.springframework.retry.annotation.Retryable;
/**
* Kubernetes {@link PropertySourceLocator} for secrets.
@@ -64,7 +63,6 @@ public abstract class SecretsPropertySourceLocator implements PropertySourceLoca
}
@Override
- @Retryable(interceptor = "kubernetesSecretsRetryInterceptor")
public PropertySource> locate(Environment environment) {
if (environment instanceof ConfigurableEnvironment) {
ConfigurableEnvironment env = (ConfigurableEnvironment) environment;
@@ -86,7 +84,6 @@ public abstract class SecretsPropertySourceLocator implements PropertySourceLoca
}
@Override
- @Retryable(interceptor = "kubernetesSecretsRetryInterceptor")
public Collection> locateCollection(Environment environment) {
return PropertySourceLocator.super.locateCollection(environment);
}
diff --git a/spring-cloud-kubernetes-fabric8-config/pom.xml b/spring-cloud-kubernetes-fabric8-config/pom.xml
index 3230fa91..9ae7b7ac 100644
--- a/spring-cloud-kubernetes-fabric8-config/pom.xml
+++ b/spring-cloud-kubernetes-fabric8-config/pom.xml
@@ -67,6 +67,14 @@
org.springframework.security
spring-security-rsa
+
+ org.springframework.retry
+ spring-retry
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
@@ -157,17 +165,6 @@
${groovy.version}
test
-
-
- org.springframework.retry
- spring-retry
- test
-
-
- org.springframework.boot
- spring-boot-starter-aop
- test
-
diff --git a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8BootstrapConfiguration.java b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8BootstrapConfiguration.java
index 1e6f9a96..b10b5797 100644
--- a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8BootstrapConfiguration.java
+++ b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8BootstrapConfiguration.java
@@ -29,6 +29,8 @@ import org.springframework.cloud.kubernetes.commons.ConditionalOnKubernetesEnabl
import org.springframework.cloud.kubernetes.commons.ConditionalOnKubernetesSecretsEnabled;
import org.springframework.cloud.kubernetes.commons.KubernetesCommonsAutoConfiguration;
import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
+import org.springframework.cloud.kubernetes.commons.config.ConditionalOnKubernetesConfigRetryDisabled;
+import org.springframework.cloud.kubernetes.commons.config.ConditionalOnKubernetesSecretsRetryDisabled;
import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties;
import org.springframework.cloud.kubernetes.commons.config.KubernetesBootstrapConfiguration;
import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties;
@@ -58,6 +60,7 @@ public class Fabric8BootstrapConfiguration {
@Bean
@ConditionalOnKubernetesConfigEnabled
+ @ConditionalOnKubernetesConfigRetryDisabled
public Fabric8ConfigMapPropertySourceLocator configMapPropertySourceLocator(ConfigMapConfigProperties properties,
KubernetesClient client, KubernetesNamespaceProvider provider) {
return new Fabric8ConfigMapPropertySourceLocator(client, properties, provider);
@@ -65,6 +68,7 @@ public class Fabric8BootstrapConfiguration {
@Bean
@ConditionalOnKubernetesSecretsEnabled
+ @ConditionalOnKubernetesSecretsRetryDisabled
public Fabric8SecretsPropertySourceLocator secretsPropertySourceLocator(SecretsConfigProperties properties,
KubernetesClient client, KubernetesNamespaceProvider provider) {
return new Fabric8SecretsPropertySourceLocator(client, properties, provider);
diff --git a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8RetryBootstrapConfiguration.java b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8RetryBootstrapConfiguration.java
new file mode 100644
index 00000000..5e2009d1
--- /dev/null
+++ b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8RetryBootstrapConfiguration.java
@@ -0,0 +1,69 @@
+/*
+ * 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;
+
+import io.fabric8.kubernetes.api.model.ConfigMap;
+import io.fabric8.kubernetes.api.model.Secret;
+import io.fabric8.kubernetes.client.KubernetesClient;
+
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnCloudPlatform;
+import org.springframework.boot.cloud.CloudPlatform;
+import org.springframework.cloud.kubernetes.commons.ConditionalOnKubernetesEnabled;
+import org.springframework.cloud.kubernetes.commons.KubernetesCommonsAutoConfiguration;
+import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
+import org.springframework.cloud.kubernetes.commons.config.ConditionalOnKubernetesConfigOrSecretsRetryEnabled;
+import org.springframework.cloud.kubernetes.commons.config.ConditionalOnKubernetesConfigRetryEnabled;
+import org.springframework.cloud.kubernetes.commons.config.ConditionalOnKubernetesSecretsRetryEnabled;
+import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties;
+import org.springframework.cloud.kubernetes.commons.config.KubernetesBootstrapConfiguration;
+import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties;
+import org.springframework.cloud.kubernetes.fabric8.Fabric8AutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+/**
+ * @author Ryan Baxter
+ */
+@Configuration(proxyBeanMethods = false)
+@ConditionalOnKubernetesEnabled
+@AutoConfigureBefore(Fabric8BootstrapConfiguration.class)
+@Import({ KubernetesCommonsAutoConfiguration.class, Fabric8AutoConfiguration.class })
+@ConditionalOnClass({ ConfigMap.class, Secret.class })
+@AutoConfigureAfter(KubernetesBootstrapConfiguration.class)
+@ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES)
+@ConditionalOnKubernetesConfigOrSecretsRetryEnabled
+public class Fabric8RetryBootstrapConfiguration {
+
+ @Bean
+ @ConditionalOnKubernetesConfigRetryEnabled
+ public Fabric8ConfigMapPropertySourceLocator configMapPropertySourceLocator(ConfigMapConfigProperties properties,
+ KubernetesClient client, KubernetesNamespaceProvider provider) {
+ return new RetryableFabric8ConfigMapPropertySourceLocator(client, properties, provider);
+ }
+
+ @Bean
+ @ConditionalOnKubernetesSecretsRetryEnabled
+ public Fabric8SecretsPropertySourceLocator secretsPropertySourceLocator(SecretsConfigProperties properties,
+ KubernetesClient client, KubernetesNamespaceProvider provider) {
+ return new RetryableFabric8SecretsPropertySourceLocator(client, properties, provider);
+ }
+
+}
diff --git a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/RetryableFabric8ConfigMapPropertySourceLocator.java b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/RetryableFabric8ConfigMapPropertySourceLocator.java
new file mode 100644
index 00000000..941ef384
--- /dev/null
+++ b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/RetryableFabric8ConfigMapPropertySourceLocator.java
@@ -0,0 +1,55 @@
+/*
+ * 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.fabric8.config;
+
+import java.util.Collection;
+
+import io.fabric8.kubernetes.client.KubernetesClient;
+
+import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
+import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties;
+import org.springframework.core.annotation.Order;
+import org.springframework.core.env.Environment;
+import org.springframework.core.env.PropertySource;
+import org.springframework.retry.annotation.Retryable;
+
+/**
+ * ConfigMapPropertySourceLocator for when retry is enabled.
+ *
+ * @author Ryan Baxter
+ */
+@Order(1)
+class RetryableFabric8ConfigMapPropertySourceLocator extends Fabric8ConfigMapPropertySourceLocator {
+
+ RetryableFabric8ConfigMapPropertySourceLocator(KubernetesClient client, ConfigMapConfigProperties properties,
+ KubernetesNamespaceProvider provider) {
+ super(client, properties, provider);
+ }
+
+ @Override
+ @Retryable(interceptor = "kubernetesConfigRetryInterceptor")
+ public PropertySource> locate(Environment environment) {
+ return super.locate(environment);
+ }
+
+ @Override
+ @Retryable(interceptor = "kubernetesConfigRetryInterceptor")
+ public Collection> locateCollection(Environment environment) {
+ return super.locateCollection(environment);
+ }
+
+}
diff --git a/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/RetryableFabric8SecretsPropertySourceLocator.java b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/RetryableFabric8SecretsPropertySourceLocator.java
new file mode 100644
index 00000000..880427fc
--- /dev/null
+++ b/spring-cloud-kubernetes-fabric8-config/src/main/java/org/springframework/cloud/kubernetes/fabric8/config/RetryableFabric8SecretsPropertySourceLocator.java
@@ -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.fabric8.config;
+
+import java.util.Collection;
+
+import io.fabric8.kubernetes.client.KubernetesClient;
+
+import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
+import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties;
+import org.springframework.core.env.Environment;
+import org.springframework.core.env.PropertySource;
+import org.springframework.retry.annotation.Retryable;
+
+/**
+ * SecretsPropertySourceLocator for when retry is enabled.
+ *
+ * @author Ryan Baxter
+ */
+class RetryableFabric8SecretsPropertySourceLocator extends Fabric8SecretsPropertySourceLocator {
+
+ RetryableFabric8SecretsPropertySourceLocator(KubernetesClient client, SecretsConfigProperties properties,
+ KubernetesNamespaceProvider provider) {
+ super(client, properties, provider);
+ }
+
+ @Override
+ @Retryable(interceptor = "kubernetesSecretsRetryInterceptor")
+ public PropertySource> locate(Environment environment) {
+ return super.locate(environment);
+ }
+
+ @Override
+ @Retryable(interceptor = "kubernetesSecretsRetryInterceptor")
+ public Collection> locateCollection(Environment environment) {
+ return super.locateCollection(environment);
+ }
+
+}
diff --git a/spring-cloud-kubernetes-fabric8-config/src/main/resources/META-INF/spring.factories b/spring-cloud-kubernetes-fabric8-config/src/main/resources/META-INF/spring.factories
index 79ca4b9f..cdd2220a 100644
--- a/spring-cloud-kubernetes-fabric8-config/src/main/resources/META-INF/spring.factories
+++ b/spring-cloud-kubernetes-fabric8-config/src/main/resources/META-INF/spring.factories
@@ -1,4 +1,5 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.kubernetes.fabric8.config.reload.ConfigReloadAutoConfiguration
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
-org.springframework.cloud.kubernetes.fabric8.config.Fabric8BootstrapConfiguration
+org.springframework.cloud.kubernetes.fabric8.config.Fabric8BootstrapConfiguration,\
+org.springframework.cloud.kubernetes.fabric8.config.Fabric8RetryBootstrapConfiguration
diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/EnableRetryBootstrapConfiguration.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/EnableRetryBootstrapConfiguration.java
new file mode 100644
index 00000000..daecc5ab
--- /dev/null
+++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/EnableRetryBootstrapConfiguration.java
@@ -0,0 +1,33 @@
+/*
+ * 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;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+import org.springframework.retry.annotation.EnableRetry;
+
+/**
+ * @author Ryan Baxter
+ */
+@Order(0)
+@Configuration
+@ConditionalOnProperty("spring.cloud.kubernetes.test.enable-retry")
+@EnableRetry
+public class EnableRetryBootstrapConfiguration {
+
+}
diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySourceLocatorRetryTests.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySourceLocatorRetryTests.java
index cb8b56a8..1a650274 100644
--- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySourceLocatorRetryTests.java
+++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8ConfigMapPropertySourceLocatorRetryTests.java
@@ -16,7 +16,10 @@
package org.springframework.cloud.kubernetes.fabric8.config;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
@@ -24,17 +27,30 @@ 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.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.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
+import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration;
+import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
+import org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration;
+import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration;
+import org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration;
+import org.springframework.cloud.kubernetes.commons.config.KubernetesBootstrapConfiguration;
+import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadAutoConfiguration;
import org.springframework.context.ApplicationContext;
+import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.PropertySource;
import org.springframework.mock.env.MockEnvironment;
+import org.springframework.retry.annotation.RetryConfiguration;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -227,4 +243,42 @@ public class Fabric8ConfigMapPropertySourceLocatorRetryTests {
}
+ @Nested
+ @EnableKubernetesMockClient
+ public class EnableRetryWithoutFailFastTest {
+
+ private ConfigurableApplicationContext context;
+
+ protected void setup(String... env) {
+ List envList = (env != null) ? new ArrayList<>(Arrays.asList(env)) : new ArrayList<>();
+ envList.add("spring.cloud.kubernetes.client.namespace=default");
+ String[] envArray = envList.toArray(new String[0]);
+
+ context = new SpringApplicationBuilder(RetryConfiguration.class, PropertyPlaceholderAutoConfiguration.class,
+ ConfigReloadAutoConfiguration.class, RefreshAutoConfiguration.class,
+ EndpointAutoConfiguration.class, InfoEndpointAutoConfiguration.class,
+ RefreshEndpointAutoConfiguration.class, ConfigurationPropertiesBindingPostProcessor.class,
+ ConfigurationPropertiesRebinderAutoConfiguration.class, Fabric8BootstrapConfiguration.class,
+ Fabric8RetryBootstrapConfiguration.class, KubernetesBootstrapConfiguration.class)
+ .web(org.springframework.boot.WebApplicationType.NONE).properties(envArray).run();
+ }
+
+ @AfterEach
+ public void afterEach() {
+ if (this.context != null) {
+ this.context.close();
+ this.context = null;
+ }
+ }
+
+ @Test
+ public void doesNotContainRetryableConfigMapPropertySourceLocator() throws Exception {
+ mockServer.expect().withPath(API).andReturn(500, "Internal Server Error").once();
+ setup("debug=true", "spring.main.cloud-platform=KUBERNETES",
+ "spring.cloud.kubernetes.test.enable-retry=true");
+ assertThat(context.containsBean("retryableConfigMapPropertySourceLocator")).isFalse();
+ }
+
+ }
+
}
diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8SecretsPropertySourceLocatorRetryTests.java b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8SecretsPropertySourceLocatorRetryTests.java
index a3d4232f..b840da4f 100644
--- a/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8SecretsPropertySourceLocatorRetryTests.java
+++ b/spring-cloud-kubernetes-fabric8-config/src/test/java/org/springframework/cloud/kubernetes/fabric8/config/Fabric8SecretsPropertySourceLocatorRetryTests.java
@@ -16,8 +16,11 @@
package org.springframework.cloud.kubernetes.fabric8.config;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Base64;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import io.fabric8.kubernetes.api.model.SecretBuilder;
@@ -26,17 +29,30 @@ 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.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.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.actuate.autoconfigure.endpoint.EndpointAutoConfiguration;
+import org.springframework.boot.actuate.autoconfigure.info.InfoEndpointAutoConfiguration;
+import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
+import org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration;
+import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration;
+import org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration;
+import org.springframework.cloud.kubernetes.commons.config.KubernetesBootstrapConfiguration;
+import org.springframework.cloud.kubernetes.commons.config.reload.ConfigReloadAutoConfiguration;
import org.springframework.context.ApplicationContext;
+import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.PropertySource;
import org.springframework.mock.env.MockEnvironment;
+import org.springframework.retry.annotation.RetryConfiguration;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -238,4 +254,43 @@ public class Fabric8SecretsPropertySourceLocatorRetryTests {
}
+ @Nested
+ @EnableKubernetesMockClient
+ public class EnableRetryWithoutFailFastTest {
+
+ private ConfigurableApplicationContext context;
+
+ protected void setup(String... env) {
+ List envList = (env != null) ? new ArrayList<>(Arrays.asList(env)) : new ArrayList<>();
+ envList.add("spring.cloud.kubernetes.client.namespace=default");
+ String[] envArray = envList.toArray(new String[0]);
+
+ context = new SpringApplicationBuilder(RetryConfiguration.class, PropertyPlaceholderAutoConfiguration.class,
+ ConfigReloadAutoConfiguration.class, RefreshAutoConfiguration.class,
+ EndpointAutoConfiguration.class, InfoEndpointAutoConfiguration.class,
+ RefreshEndpointAutoConfiguration.class, ConfigurationPropertiesBindingPostProcessor.class,
+ ConfigurationPropertiesRebinderAutoConfiguration.class, Fabric8BootstrapConfiguration.class,
+ Fabric8RetryBootstrapConfiguration.class, KubernetesBootstrapConfiguration.class)
+ .web(org.springframework.boot.WebApplicationType.NONE).properties(envArray).run();
+ }
+
+ @AfterEach
+ public void afterEach() {
+ if (this.context != null) {
+ this.context.close();
+ this.context = null;
+ }
+ }
+
+ @Test
+ public void doesNotContainRetryableSecretsPropertySourceLocator() throws Exception {
+ mockServer.expect().withPath(API).andReturn(500, "Internal Server Error").once();
+ setup("debug=true", "spring.main.cloud-platform=KUBERNETES",
+ "spring.cloud.kubernetes.test.enable-retry=true", "spring.cloud.kubernetes.secrets.name=my-secret",
+ "spring.cloud.kubernetes.secrets.enable-api=true");
+ assertThat(context.containsBean("retryableSecretsPropertySourceLocator")).isFalse();
+ }
+
+ }
+
}
diff --git a/spring-cloud-kubernetes-fabric8-config/src/test/resources/META-INF/spring.factories b/spring-cloud-kubernetes-fabric8-config/src/test/resources/META-INF/spring.factories
new file mode 100644
index 00000000..18fd93e0
--- /dev/null
+++ b/spring-cloud-kubernetes-fabric8-config/src/test/resources/META-INF/spring.factories
@@ -0,0 +1,2 @@
+org.springframework.cloud.bootstrap.BootstrapConfiguration=\
+org.springframework.cloud.kubernetes.client.config.EnableRetryBootstrapConfiguration