Move configmap and secrets properties to record (#1108)

This commit is contained in:
erabii
2022-10-27 15:35:57 +03:00
committed by GitHub
parent 11b8e38752
commit 03a4b1ad56
29 changed files with 501 additions and 434 deletions

View File

@@ -70,7 +70,7 @@ public class KubernetesClientConfigDataLocationResolver extends KubernetesConfig
registerRetryBeans(configMapProperties, secretsProperties, bootstrapContext, coreV1Api, namespaceProvider);
}
else {
if (configMapProperties != null && configMapProperties.isEnabled()) {
if (configMapProperties != null && configMapProperties.enabled()) {
KubernetesClientConfigMapPropertySourceLocator configMapPropertySourceLocator = new KubernetesClientConfigMapPropertySourceLocator(
coreV1Api, configMapProperties, namespaceProvider);
bootstrapContext.registerIfAbsent(ConfigMapPropertySourceLocator.class,
@@ -80,7 +80,7 @@ public class KubernetesClientConfigDataLocationResolver extends KubernetesConfig
event.getBootstrapContext().get(ConfigMapPropertySourceLocator.class)));
}
if (secretsProperties != null && secretsProperties.isEnabled()) {
if (secretsProperties != null && secretsProperties.enabled()) {
KubernetesClientSecretsPropertySourceLocator secretsPropertySourceLocator = new KubernetesClientSecretsPropertySourceLocator(
coreV1Api, namespaceProvider, secretsProperties);
bootstrapContext.registerIfAbsent(SecretsPropertySourceLocator.class,
@@ -95,7 +95,7 @@ public class KubernetesClientConfigDataLocationResolver extends KubernetesConfig
private void registerRetryBeans(ConfigMapConfigProperties configMapProperties,
SecretsConfigProperties secretsProperties, ConfigurableBootstrapContext bootstrapContext,
CoreV1Api coreV1Api, KubernetesNamespaceProvider namespaceProvider) {
if (configMapProperties != null && configMapProperties.isEnabled()) {
if (configMapProperties != null && configMapProperties.enabled()) {
ConfigMapPropertySourceLocator configMapPropertySourceLocator = new KubernetesClientConfigMapPropertySourceLocator(
coreV1Api, configMapProperties, namespaceProvider);
if (isRetryEnabledForConfigMap(configMapProperties)) {
@@ -110,7 +110,7 @@ public class KubernetesClientConfigDataLocationResolver extends KubernetesConfig
event.getBootstrapContext().get(ConfigMapPropertySourceLocator.class)));
}
if (secretsProperties != null && secretsProperties.isEnabled()) {
if (secretsProperties != null && secretsProperties.enabled()) {
SecretsPropertySourceLocator secretsPropertySourceLocator = new KubernetesClientSecretsPropertySourceLocator(
coreV1Api, namespaceProvider, secretsProperties);
if (isRetryEnabledForSecrets(secretsProperties)) {

View File

@@ -18,6 +18,7 @@ package org.springframework.cloud.kubernetes.client.config;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
@@ -38,6 +39,7 @@ import org.springframework.cloud.kubernetes.commons.KubernetesClientProperties;
import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties;
import org.springframework.cloud.kubernetes.commons.config.NamespaceResolutionFailedException;
import org.springframework.cloud.kubernetes.commons.config.RetryProperties;
import org.springframework.core.env.PropertySource;
import org.springframework.mock.env.MockEnvironment;
@@ -96,8 +98,8 @@ class KubernetesClientConfigMapPropertySourceLocatorTests {
CoreV1Api api = new CoreV1Api();
stubFor(get("/api/v1/namespaces/default/configmaps")
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(PROPERTIES_CONFIGMAP_LIST))));
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties();
configMapConfigProperties.setName("bootstrap-640");
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(), List.of(),
Map.of(), true, "bootstrap-640", null, false, false, false, RetryProperties.DEFAULT);
MockEnvironment mockEnvironment = new MockEnvironment();
mockEnvironment.setProperty("spring.cloud.kubernetes.client.namespace", "default");
PropertySource<?> propertySource = new KubernetesClientConfigMapPropertySourceLocator(api,
@@ -111,13 +113,12 @@ class KubernetesClientConfigMapPropertySourceLocatorTests {
CoreV1Api api = new CoreV1Api();
stubFor(get("/api/v1/namespaces/default/configmaps")
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(PROPERTIES_CONFIGMAP_LIST))));
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties();
configMapConfigProperties.setName("fake-name");
ConfigMapConfigProperties.Source source = new ConfigMapConfigProperties.Source("bootstrap-640", "default",
Collections.emptyMap(), null, null, null);
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(),
List.of(source), Map.of(), true, "fake-name", null, false, false, false, RetryProperties.DEFAULT);
List<ConfigMapConfigProperties.Source> sources = Collections.singletonList(source);
configMapConfigProperties.setSources(sources);
KubernetesClientProperties kubernetesClientProperties = new KubernetesClientProperties();
kubernetesClientProperties.setNamespace("dev");
PropertySource<?> propertySource = new KubernetesClientConfigMapPropertySourceLocator(api,
@@ -138,8 +139,8 @@ class KubernetesClientConfigMapPropertySourceLocatorTests {
CoreV1Api api = new CoreV1Api();
stubFor(get("/api/v1/namespaces/default/configmaps")
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(PROPERTIES_CONFIGMAP_LIST))));
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties();
configMapConfigProperties.setName("bootstrap-640");
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(), List.of(),
Map.of(), true, "bootstrap-640", null, false, false, false, RetryProperties.DEFAULT);
KubernetesClientProperties kubernetesClientProperties = new KubernetesClientProperties();
kubernetesClientProperties.setNamespace(""); // empty on purpose
assertThatThrownBy(() -> new KubernetesClientConfigMapPropertySourceLocator(api, configMapConfigProperties,
@@ -159,8 +160,8 @@ class KubernetesClientConfigMapPropertySourceLocatorTests {
CoreV1Api api = new CoreV1Api();
stubFor(get("/api/v1/namespaces/default/configmaps")
.willReturn(aResponse().withStatus(200).withBody(new JSON().serialize(PROPERTIES_CONFIGMAP_LIST))));
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties();
configMapConfigProperties.setName("bootstrap-640");
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(), List.of(),
Map.of(), true, "bootstrap-640", null, false, false, false, RetryProperties.DEFAULT);
KubernetesClientProperties kubernetesClientProperties = new KubernetesClientProperties();
kubernetesClientProperties.setNamespace(""); // empty on purpose
assertThatThrownBy(() -> new KubernetesClientConfigMapPropertySourceLocator(api, configMapConfigProperties,
@@ -174,10 +175,8 @@ class KubernetesClientConfigMapPropertySourceLocatorTests {
stubFor(get("/api/v1/namespaces/default/configmaps")
.willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties();
configMapConfigProperties.setName("bootstrap-640");
configMapConfigProperties.setNamespace("default");
configMapConfigProperties.setFailFast(true);
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(), List.of(),
Map.of(), true, "bootstrap-640", "default", false, false, true, RetryProperties.DEFAULT);
KubernetesClientConfigMapPropertySourceLocator locator = new KubernetesClientConfigMapPropertySourceLocator(api,
configMapConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment()));
@@ -192,10 +191,8 @@ class KubernetesClientConfigMapPropertySourceLocatorTests {
stubFor(get("/api/v1/namespaces/default/configmaps")
.willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties();
configMapConfigProperties.setName("bootstrap-640");
configMapConfigProperties.setNamespace("default");
configMapConfigProperties.setFailFast(false);
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(), List.of(),
Map.of(), true, "bootstrap-640", "default", false, false, false, RetryProperties.DEFAULT);
KubernetesClientConfigMapPropertySourceLocator locator = new KubernetesClientConfigMapPropertySourceLocator(api,
configMapConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment()));

View File

@@ -16,9 +16,9 @@
package org.springframework.cloud.kubernetes.client.config;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
@@ -33,6 +33,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
import org.springframework.cloud.kubernetes.commons.config.NamespaceResolutionFailedException;
import org.springframework.cloud.kubernetes.commons.config.RetryProperties;
import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties;
import org.springframework.core.env.PropertySource;
import org.springframework.mock.env.MockEnvironment;
@@ -106,7 +107,6 @@ class KubernetesClientSecretsPropertySourceLocatorTests {
void getLocateWithSources() {
CoreV1Api api = new CoreV1Api();
stubFor(get(LIST_API).willReturn(aResponse().withStatus(200).withBody(LIST_BODY)));
SecretsConfigProperties secretsConfigProperties = new SecretsConfigProperties();
SecretsConfigProperties.Source source1 = new SecretsConfigProperties.Source("db-secret", "",
Collections.emptyMap(), null, null, null);
@@ -114,13 +114,9 @@ class KubernetesClientSecretsPropertySourceLocatorTests {
SecretsConfigProperties.Source source2 = new SecretsConfigProperties.Source("rabbit-password", "",
Collections.emptyMap(), null, null, null);
List<SecretsConfigProperties.Source> sources = new ArrayList<>();
sources.add(source1);
sources.add(source2);
secretsConfigProperties.setName("app");
secretsConfigProperties.setNamespace("default");
secretsConfigProperties.setSources(sources);
secretsConfigProperties.setEnableApi(true);
SecretsConfigProperties secretsConfigProperties = new SecretsConfigProperties(true, Map.of(), List.of(),
List.of(source1, source2), true, "app", "default", false, true, false, RetryProperties.DEFAULT);
PropertySource<?> propertySource = new KubernetesClientSecretsPropertySourceLocator(api,
new KubernetesNamespaceProvider(new MockEnvironment()), secretsConfigProperties).locate(ENV);
assertThat(propertySource.containsProperty("password")).isTrue();
@@ -131,10 +127,9 @@ class KubernetesClientSecretsPropertySourceLocatorTests {
void getLocateWithOutSources() {
CoreV1Api api = new CoreV1Api();
stubFor(get(LIST_API).willReturn(aResponse().withStatus(200).withBody(LIST_BODY)));
SecretsConfigProperties secretsConfigProperties = new SecretsConfigProperties();
secretsConfigProperties.setName("db-secret");
secretsConfigProperties.setNamespace("default");
secretsConfigProperties.setEnableApi(true);
SecretsConfigProperties secretsConfigProperties = new SecretsConfigProperties(true, Map.of(), List.of(),
List.of(), true, "db-secret", "default", false, true, false, RetryProperties.DEFAULT);
PropertySource<?> propertySource = new KubernetesClientSecretsPropertySourceLocator(api,
new KubernetesNamespaceProvider(new MockEnvironment()), secretsConfigProperties).locate(ENV);
assertThat(propertySource.containsProperty("password")).isTrue();
@@ -152,10 +147,10 @@ class KubernetesClientSecretsPropertySourceLocatorTests {
void testLocateWithoutNamespaceConstructor() {
CoreV1Api api = new CoreV1Api();
stubFor(get(LIST_API).willReturn(aResponse().withStatus(200).withBody(LIST_BODY)));
SecretsConfigProperties secretsConfigProperties = new SecretsConfigProperties();
secretsConfigProperties.setName("db-secret");
secretsConfigProperties.setNamespace(""); // empty on purpose
secretsConfigProperties.setEnableApi(true);
SecretsConfigProperties secretsConfigProperties = new SecretsConfigProperties(true, Map.of(), List.of(),
List.of(), true, "db-secret", "", false, true, false, RetryProperties.DEFAULT);
assertThatThrownBy(() -> new KubernetesClientSecretsPropertySourceLocator(api,
new KubernetesNamespaceProvider(new MockEnvironment()), secretsConfigProperties).locate(ENV))
.isInstanceOf(NamespaceResolutionFailedException.class);
@@ -166,11 +161,8 @@ class KubernetesClientSecretsPropertySourceLocatorTests {
CoreV1Api api = new CoreV1Api();
stubFor(get(LIST_API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
SecretsConfigProperties secretsConfigProperties = new SecretsConfigProperties();
secretsConfigProperties.setName("db-secret");
secretsConfigProperties.setNamespace("default");
secretsConfigProperties.setEnableApi(true);
secretsConfigProperties.setFailFast(true);
SecretsConfigProperties secretsConfigProperties = new SecretsConfigProperties(true, Map.of(), List.of(),
List.of(), true, "db-secret", "default", false, true, true, RetryProperties.DEFAULT);
KubernetesClientSecretsPropertySourceLocator locator = new KubernetesClientSecretsPropertySourceLocator(api,
new KubernetesNamespaceProvider(new MockEnvironment()), secretsConfigProperties);
@@ -184,11 +176,8 @@ class KubernetesClientSecretsPropertySourceLocatorTests {
CoreV1Api api = new CoreV1Api();
stubFor(get(LIST_API).willReturn(aResponse().withStatus(500).withBody("Internal Server Error")));
SecretsConfigProperties secretsConfigProperties = new SecretsConfigProperties();
secretsConfigProperties.setName("db-secret");
secretsConfigProperties.setNamespace("default");
secretsConfigProperties.setEnableApi(true);
secretsConfigProperties.setFailFast(false);
SecretsConfigProperties secretsConfigProperties = new SecretsConfigProperties(true, Map.of(), List.of(),
List.of(), true, "db-secret", "default", false, true, false, RetryProperties.DEFAULT);
KubernetesClientSecretsPropertySourceLocator locator = new KubernetesClientSecretsPropertySourceLocator(api,
new KubernetesNamespaceProvider(new MockEnvironment()), secretsConfigProperties);

View File

@@ -1,120 +0,0 @@
/*
* Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.kubernetes.commons.config;
import org.springframework.boot.context.properties.bind.DefaultValue;
/**
* Abstraction over configuration properties.
*
* @author Ioannis Canellos
* @author Isik Erhan
*/
public abstract class AbstractConfigProperties {
protected boolean enabled = true;
protected String name;
protected String namespace;
// use config map or secret name to prefix properties
protected boolean useNameAsPrefix;
// use profile name to append config map name
protected boolean includeProfileSpecificSources = true;
protected boolean failFast = false;
protected RetryProperties retry = RetryProperties.DEFAULT;
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getNamespace() {
return this.namespace;
}
public void setNamespace(String namespace) {
this.namespace = namespace;
}
public boolean isUseNameAsPrefix() {
return useNameAsPrefix;
}
public void setUseNameAsPrefix(boolean useNameAsPrefix) {
this.useNameAsPrefix = useNameAsPrefix;
}
public boolean isIncludeProfileSpecificSources() {
return includeProfileSpecificSources;
}
public void setIncludeProfileSpecificSources(boolean includeProfileSpecificSources) {
this.includeProfileSpecificSources = includeProfileSpecificSources;
}
public boolean isFailFast() {
return failFast;
}
public void setFailFast(boolean failFast) {
this.failFast = failFast;
}
public RetryProperties getRetry() {
return retry;
}
public void setRetry(RetryProperties retry) {
this.retry = retry;
}
/**
* Kubernetes config retry properties.
* @param initialInterval Initial retry interval in milliseconds.
* @param multiplier Maximum interval for backoff.
* @param maxInterval Maximum interval
* @param maxAttempts Maximum number of attempts.
* @param enabled Retry enabled or not
*/
public record RetryProperties(@DefaultValue("1000") long initialInterval, @DefaultValue("1.1") double multiplier,
@DefaultValue("2000") long maxInterval, @DefaultValue("6") int maxAttempts,
@DefaultValue("true") boolean enabled) {
/**
* Default instance.
*/
public static final RetryProperties DEFAULT = new RetryProperties(1000, 1.1, 2000, 6, true);
}
}

View File

@@ -39,9 +39,9 @@ public class ConfigDataRetryableConfigMapPropertySourceLocator extends ConfigMap
ConfigMapPropertySourceLocator configMapPropertySourceLocator, ConfigMapConfigProperties properties) {
super(properties);
this.configMapPropertySourceLocator = configMapPropertySourceLocator;
this.retryTemplate = RetryTemplate.builder().maxAttempts(properties.getRetry().maxAttempts())
.exponentialBackoff(properties.getRetry().initialInterval(), properties.getRetry().multiplier(),
properties.getRetry().maxInterval())
this.retryTemplate = RetryTemplate.builder().maxAttempts(properties.retry().maxAttempts())
.exponentialBackoff(properties.retry().initialInterval(), properties.retry().multiplier(),
properties.retry().maxInterval())
.build();
}

View File

@@ -39,9 +39,9 @@ public class ConfigDataRetryableSecretsPropertySourceLocator extends SecretsProp
SecretsConfigProperties secretsConfigProperties) {
super(secretsConfigProperties);
this.secretsPropertySourceLocator = propertySourceLocator;
this.retryTemplate = RetryTemplate.builder().maxAttempts(properties.getRetry().maxAttempts())
.exponentialBackoff(properties.getRetry().initialInterval(), properties.getRetry().multiplier(),
properties.getRetry().maxInterval())
this.retryTemplate = RetryTemplate.builder().maxAttempts(properties.retry().maxAttempts())
.exponentialBackoff(properties.retry().initialInterval(), properties.retry().multiplier(),
properties.retry().maxInterval())
.build();
}

View File

@@ -17,7 +17,6 @@
package org.springframework.cloud.kubernetes.commons.config;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@@ -37,53 +36,17 @@ import static org.springframework.cloud.kubernetes.commons.config.ConfigUtils.ge
* @author Isik Erhan
*/
@ConfigurationProperties(ConfigMapConfigProperties.PREFIX)
public class ConfigMapConfigProperties extends AbstractConfigProperties {
public record ConfigMapConfigProperties(@DefaultValue("true") boolean enableApi, @DefaultValue List<String> paths,
@DefaultValue List<Source> sources, @DefaultValue Map<String, String> labels,
@DefaultValue("true") boolean enabled, String name, String namespace, boolean useNameAsPrefix,
@DefaultValue("true") boolean includeProfileSpecificSources, boolean failFast,
@DefaultValue RetryProperties retry) {
/**
* Prefix for Kubernetes config maps configuration properties.
*/
public static final String PREFIX = "spring.cloud.kubernetes.config";
private boolean enableApi = true;
private List<String> paths = Collections.emptyList();
private List<Source> sources = Collections.emptyList();
private Map<String, String> labels = Collections.emptyMap();
public boolean isEnableApi() {
return this.enableApi;
}
public void setEnableApi(boolean enableApi) {
this.enableApi = enableApi;
}
public List<String> getPaths() {
return this.paths;
}
public void setPaths(List<String> paths) {
this.paths = paths;
}
public List<Source> getSources() {
return this.sources;
}
public void setSources(List<Source> sources) {
this.sources = sources;
}
public Map<String, String> getLabels() {
return labels;
}
public void setLabels(Map<String, String> labels) {
this.labels = labels;
}
/**
* @return A list of config map source(s) to use.
*/

View File

@@ -25,7 +25,6 @@ import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -66,7 +65,7 @@ public abstract class ConfigMapPropertySourceLocator implements PropertySourceLo
if (environment instanceof ConfigurableEnvironment env) {
CompositePropertySource composite = new CompositePropertySource("composite-configmap");
if (this.properties.isEnableApi()) {
if (this.properties.enableApi()) {
Set<NormalizedSource> sources = new LinkedHashSet<>(this.properties.determineSources(environment));
LOG.debug("Config Map normalized sources : " + sources);
sources.forEach(s -> composite.addFirstPropertySource(getMapPropertySource(s, env)));
@@ -85,7 +84,7 @@ public abstract class ConfigMapPropertySourceLocator implements PropertySourceLo
}
private void addPropertySourcesFromPaths(Environment environment, CompositePropertySource composite) {
Set<String> uniquePaths = new LinkedHashSet<>(properties.getPaths());
Set<String> uniquePaths = new LinkedHashSet<>(properties.paths());
uniquePaths.stream().map(Paths::get).filter(p -> {
boolean exists = Files.exists(p);
if (!exists) {
@@ -99,7 +98,7 @@ public abstract class ConfigMapPropertySourceLocator implements PropertySourceLo
LOG.warn("Configured input path: " + p + " will be ignored because it is not a regular file");
}
return regular;
}).collect(Collectors.toList()).forEach(p -> {
}).toList().forEach(p -> {
try {
String content = new String(Files.readAllBytes(p)).trim();
String filename = p.toAbsolutePath().toString().toLowerCase();

View File

@@ -48,8 +48,7 @@ public class KubernetesBootstrapConfiguration {
@Import(AopAutoConfiguration.class)
public static class RetryConfiguration {
public static RetryOperationsInterceptor retryOperationsInterceptor(
AbstractConfigProperties.RetryProperties retryProperties) {
public static RetryOperationsInterceptor retryOperationsInterceptor(RetryProperties retryProperties) {
return RetryInterceptorBuilder.stateless().backOffOptions(retryProperties.initialInterval(),
retryProperties.multiplier(), retryProperties.maxInterval())
.maxAttempts(retryProperties.maxAttempts()).build();
@@ -58,7 +57,7 @@ public class KubernetesBootstrapConfiguration {
@Bean
@ConditionalOnKubernetesConfigRetryEnabled
public RetryOperationsInterceptor kubernetesConfigRetryInterceptor(ConfigMapConfigProperties configProperties) {
return retryOperationsInterceptor(configProperties.getRetry());
return retryOperationsInterceptor(configProperties.retry());
}
@Bean("kubernetesConfigRetryInterceptor")
@@ -70,7 +69,7 @@ public class KubernetesBootstrapConfiguration {
@Bean
@ConditionalOnKubernetesSecretsRetryEnabled
public RetryOperationsInterceptor kubernetesSecretsRetryInterceptor(SecretsConfigProperties configProperties) {
return retryOperationsInterceptor(configProperties.getRetry());
return retryOperationsInterceptor(configProperties.retry());
}
@Bean("kubernetesSecretsRetryInterceptor")

View File

@@ -127,13 +127,13 @@ public abstract class KubernetesConfigDataLocationResolver
}
protected final boolean isRetryEnabledForConfigMap(ConfigMapConfigProperties configMapProperties) {
return RETRY_IS_PRESENT && configMapProperties != null && configMapProperties.getRetry().enabled()
&& configMapProperties.isFailFast();
return RETRY_IS_PRESENT && configMapProperties != null && configMapProperties.retry().enabled()
&& configMapProperties.failFast();
}
protected final boolean isRetryEnabledForSecrets(SecretsConfigProperties secretsProperties) {
return RETRY_IS_PRESENT && secretsProperties != null && secretsProperties.getRetry().enabled()
&& secretsProperties.isFailFast();
return RETRY_IS_PRESENT && secretsProperties != null && secretsProperties.retry().enabled()
&& secretsProperties.failFast();
}
protected KubernetesNamespaceProvider kubernetesNamespaceProvider(Environment environment) {

View File

@@ -0,0 +1,39 @@
/*
* Copyright 2013-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.kubernetes.commons.config;
import org.springframework.boot.context.properties.bind.DefaultValue;
/**
*
* @author wind57 Kubernetes config retry properties.
* @param initialInterval Initial retry interval in milliseconds.
* @param multiplier Maximum interval for backoff.
* @param maxInterval Maximum interval
* @param maxAttempts Maximum number of attempts.
* @param enabled Retry enabled or not
*/
public record RetryProperties(@DefaultValue("1000") long initialInterval, @DefaultValue("1.1") double multiplier,
@DefaultValue("2000") long maxInterval, @DefaultValue("6") int maxAttempts,
@DefaultValue("true") boolean enabled) {
/**
* Default instance.
*/
public static final RetryProperties DEFAULT = new RetryProperties(1000, 1.1, 2000, 6, true);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2021 the original author or authors.
* 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.
@@ -17,7 +17,6 @@
package org.springframework.cloud.kubernetes.commons.config;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@@ -38,53 +37,17 @@ import static org.springframework.cloud.kubernetes.commons.config.ConfigUtils.ge
* @author Isik Erhan
*/
@ConfigurationProperties(SecretsConfigProperties.PREFIX)
public class SecretsConfigProperties extends AbstractConfigProperties {
public record SecretsConfigProperties(boolean enableApi, @DefaultValue Map<String, String> labels,
@DefaultValue List<String> paths, @DefaultValue List<Source> sources, @DefaultValue("true") boolean enabled,
String name, String namespace, boolean useNameAsPrefix,
@DefaultValue("true") boolean includeProfileSpecificSources, boolean failFast,
@DefaultValue RetryProperties retry) {
/**
* Prefix for Kubernetes secrets configuration properties.
*/
public static final String PREFIX = "spring.cloud.kubernetes.secrets";
private boolean enableApi = false;
private Map<String, String> labels = Collections.emptyMap();
private List<String> paths = Collections.emptyList();
private List<Source> sources = Collections.emptyList();
public boolean isEnableApi() {
return this.enableApi;
}
public void setEnableApi(boolean enableApi) {
this.enableApi = enableApi;
}
public Map<String, String> getLabels() {
return this.labels;
}
public void setLabels(Map<String, String> labels) {
this.labels = labels;
}
public List<String> getPaths() {
return this.paths;
}
public void setPaths(List<String> paths) {
this.paths = paths;
}
public List<Source> getSources() {
return sources;
}
public void setSources(List<Source> sources) {
this.sources = sources;
}
/**
* @return A list of Secret source(s) to use.
*/

View File

@@ -73,7 +73,7 @@ public abstract class SecretsPropertySourceLocator implements PropertySourceLoca
// read for secrets mount
putPathConfig(composite);
if (this.properties.isEnableApi()) {
if (this.properties.enableApi()) {
uniqueSources.forEach(s -> composite.addPropertySource(getMapPropertySourceForSingleSecret(env, s)));
}
@@ -98,7 +98,7 @@ public abstract class SecretsPropertySourceLocator implements PropertySourceLoca
protected void putPathConfig(CompositePropertySource composite) {
this.properties.getPaths().stream().map(Paths::get).filter(Files::exists).flatMap(x -> {
this.properties.paths().stream().map(Paths::get).filter(Files::exists).flatMap(x -> {
try {
return Files.walk(x);
}

View File

@@ -0,0 +1,123 @@
/*
* Copyright 2013-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.kubernetes.commons.config;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Configuration;
/**
* @author wind57
*
* tests that prove that binding works. We need these because we moved to a record for
* configuration properties.
*/
class ConfigMapConfigPropertiesBindingTests {
@Test
void testWithDefaults() {
new ApplicationContextRunner().withUserConfiguration(Config.class).run(context -> {
ConfigMapConfigProperties props = context.getBean(ConfigMapConfigProperties.class);
Assertions.assertNotNull(props);
Assertions.assertTrue(props.enableApi());
Assertions.assertTrue(props.paths().isEmpty());
Assertions.assertTrue(props.sources().isEmpty());
Assertions.assertTrue(props.labels().isEmpty());
Assertions.assertTrue(props.enabled());
Assertions.assertNull(props.name());
Assertions.assertNull(props.namespace());
Assertions.assertFalse(props.useNameAsPrefix());
Assertions.assertTrue(props.includeProfileSpecificSources());
Assertions.assertFalse(props.failFast());
Assertions.assertNotNull(props.retry());
Assertions.assertEquals(props.retry().initialInterval(), 1000L);
Assertions.assertEquals(props.retry().multiplier(), 1.1D);
Assertions.assertEquals(props.retry().maxInterval(), 2000L);
Assertions.assertEquals(props.retry().maxAttempts(), 6);
Assertions.assertTrue(props.retry().enabled());
});
}
@Test
void testWithNonDefaults() {
new ApplicationContextRunner().withUserConfiguration(Config.class).withPropertyValues(
"spring.cloud.kubernetes.config.enableApi=false", "spring.cloud.kubernetes.config.paths[0]=a",
"spring.cloud.kubernetes.config.paths[1]=b", "spring.cloud.kubernetes.config.sources[0].name=source-a",
"spring.cloud.kubernetes.config.sources[0].namespace=source-namespace-a",
"spring.cloud.kubernetes.config.sources[0].labels.key=source-value",
"spring.cloud.kubernetes.config.sources[0].explicit-prefix=source-prefix",
"spring.cloud.kubernetes.config.sources[0].use-name-as-prefix=true",
"spring.cloud.kubernetes.config.sources[0].include-profile-specific-sources=true",
"spring.cloud.kubernetes.config.labels.label-a=label-a", "spring.cloud.kubernetes.config.enabled=false",
"spring.cloud.kubernetes.config.name=name", "spring.cloud.kubernetes.config.namespace=namespace",
"spring.cloud.kubernetes.config.use-name-as-prefix=true",
"spring.cloud.kubernetes.config.include-profile-specific-sources=true",
"spring.cloud.kubernetes.config.fail-fast=true",
"spring.cloud.kubernetes.config.retry.initial-interval=1",
"spring.cloud.kubernetes.config.retry.multiplier=1.2",
"spring.cloud.kubernetes.config.retry.max-interval=3",
"spring.cloud.kubernetes.config.retry.max-attempts=4",
"spring.cloud.kubernetes.config.retry.enabled=false").run(context -> {
ConfigMapConfigProperties props = context.getBean(ConfigMapConfigProperties.class);
Assertions.assertNotNull(props);
Assertions.assertFalse(props.enableApi());
Assertions.assertEquals(props.paths().size(), 2);
Assertions.assertEquals(props.paths().get(0), "a");
Assertions.assertEquals(props.paths().get(1), "b");
Assertions.assertEquals(props.sources().size(), 1);
ConfigMapConfigProperties.Source source = props.sources().get(0);
Assertions.assertEquals(source.name(), "source-a");
Assertions.assertEquals(source.namespace(), "source-namespace-a");
Assertions.assertEquals(source.labels().size(), 1);
Assertions.assertEquals(source.labels().get("key"), "source-value");
Assertions.assertEquals(source.explicitPrefix(), "source-prefix");
Assertions.assertTrue(source.useNameAsPrefix());
Assertions.assertTrue(source.includeProfileSpecificSources());
Assertions.assertEquals(props.labels().size(), 1);
Assertions.assertEquals(props.labels().get("label-a"), "label-a");
Assertions.assertFalse(props.enabled());
Assertions.assertEquals(props.name(), "name");
Assertions.assertEquals(props.namespace(), "namespace");
Assertions.assertTrue(props.useNameAsPrefix());
Assertions.assertTrue(props.includeProfileSpecificSources());
Assertions.assertTrue(props.failFast());
RetryProperties retryProperties = props.retry();
Assertions.assertNotNull(retryProperties);
Assertions.assertEquals(retryProperties.initialInterval(), 1);
Assertions.assertEquals(retryProperties.multiplier(), 1.2);
Assertions.assertEquals(retryProperties.maxInterval(), 3);
Assertions.assertFalse(retryProperties.enabled());
});
}
@Configuration
@EnableConfigurationProperties(ConfigMapConfigProperties.class)
static class Config {
}
}

View File

@@ -16,7 +16,6 @@
package org.springframework.cloud.kubernetes.commons.config;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
@@ -47,10 +46,8 @@ class ConfigMapConfigPropertiesTests {
*/
@Test
void testUseNameAsPrefixUnsetEmptySources() {
ConfigMapConfigProperties properties = new ConfigMapConfigProperties();
properties.setSources(Collections.emptyList());
properties.setName("config-map-a");
properties.setNamespace("spring-k8s");
ConfigMapConfigProperties properties = new ConfigMapConfigProperties(true, List.of(), List.of(), Map.of(), true,
"config-map-a", "spring-k8s", false, false, false, RetryProperties.DEFAULT);
List<NormalizedSource> sources = properties.determineSources(new MockEnvironment());
Assertions.assertEquals(sources.size(), 1, "empty sources must generate a List with a single NormalizedSource");
@@ -75,11 +72,8 @@ class ConfigMapConfigPropertiesTests {
*/
@Test
void testUseNameAsPrefixSetEmptySources() {
ConfigMapConfigProperties properties = new ConfigMapConfigProperties();
properties.setSources(Collections.emptyList());
properties.setUseNameAsPrefix(true);
properties.setName("config-map-a");
properties.setNamespace("spring-k8s");
ConfigMapConfigProperties properties = new ConfigMapConfigProperties(true, List.of(), List.of(), Map.of(), true,
"config-map-a", "spring-k8s", true, false, false, RetryProperties.DEFAULT);
List<NormalizedSource> sources = properties.determineSources(new MockEnvironment());
Assertions.assertEquals(sources.size(), 1, "empty sources must generate a List with a single NormalizedSource");
@@ -106,13 +100,12 @@ class ConfigMapConfigPropertiesTests {
*/
@Test
void testUseNameAsPrefixUnsetNonEmptySources() {
ConfigMapConfigProperties properties = new ConfigMapConfigProperties();
properties.setUseNameAsPrefix(true);
properties.setNamespace("spring-k8s");
ConfigMapConfigProperties.Source one = new ConfigMapConfigProperties.Source("config-map-one", null,
Collections.emptyMap(), null, null, null);
properties.setSources(Collections.singletonList(one));
ConfigMapConfigProperties properties = new ConfigMapConfigProperties(true, List.of(), List.of(one), Map.of(),
true, "config-map-a", "spring-k8s", true, false, false, RetryProperties.DEFAULT);
List<NormalizedSource> sources = properties.determineSources(new MockEnvironment());
Assertions.assertEquals(sources.size(), 1, "a single NormalizedSource is expected");
@@ -144,9 +137,6 @@ class ConfigMapConfigPropertiesTests {
*/
@Test
void testUseNameAsPrefixSetNonEmptySources() {
ConfigMapConfigProperties properties = new ConfigMapConfigProperties();
properties.setUseNameAsPrefix(true);
properties.setNamespace("spring-k8s");
ConfigMapConfigProperties.Source one = new ConfigMapConfigProperties.Source("config-map-one", null,
Collections.emptyMap(), null, false, null);
@@ -157,7 +147,8 @@ class ConfigMapConfigPropertiesTests {
ConfigMapConfigProperties.Source three = new ConfigMapConfigProperties.Source("config-map-three", null,
Collections.emptyMap(), null, true, null);
properties.setSources(Arrays.asList(one, two, three));
ConfigMapConfigProperties properties = new ConfigMapConfigProperties(true, List.of(), List.of(one, two, three),
Map.of(), true, "config-map-a", "spring-k8s", true, false, false, RetryProperties.DEFAULT);
List<NormalizedSource> sources = properties.determineSources(new MockEnvironment());
Assertions.assertEquals(sources.size(), 3, "3 NormalizedSources are expected");
@@ -192,9 +183,6 @@ class ConfigMapConfigPropertiesTests {
*/
@Test
void testMultipleCases() {
ConfigMapConfigProperties properties = new ConfigMapConfigProperties();
properties.setUseNameAsPrefix(false);
properties.setNamespace("spring-k8s");
ConfigMapConfigProperties.Source one = new ConfigMapConfigProperties.Source("config-map-one", null,
Collections.emptyMap(), "one", false, null);
@@ -208,7 +196,9 @@ class ConfigMapConfigPropertiesTests {
ConfigMapConfigProperties.Source four = new ConfigMapConfigProperties.Source(null, "config-map-four",
Collections.emptyMap(), null, false, null);
properties.setSources(Arrays.asList(one, two, three, four));
ConfigMapConfigProperties properties = new ConfigMapConfigProperties(true, List.of(),
List.of(one, two, three, four), Map.of(), true, "config-map-a", "spring-k8s", true, false, false,
RetryProperties.DEFAULT);
List<NormalizedSource> sources = properties.determineSources(new MockEnvironment());
Assertions.assertEquals(sources.size(), 4, "4 NormalizedSources are expected");
@@ -238,10 +228,9 @@ class ConfigMapConfigPropertiesTests {
*/
@Test
void testUseIncludeProfileSpecificSourcesNoChanges() {
ConfigMapConfigProperties properties = new ConfigMapConfigProperties();
properties.setSources(Collections.emptyList());
properties.setName("config-map-a");
properties.setNamespace("spring-k8s");
ConfigMapConfigProperties properties = new ConfigMapConfigProperties(true, List.of(), List.of(), Map.of(), true,
"config-map-a", "spring-k8s", false, true, false, RetryProperties.DEFAULT);
List<NormalizedSource> sources = properties.determineSources(new MockEnvironment());
Assertions.assertEquals(sources.size(), 1, "empty sources must generate a List with a single NormalizedSource");
@@ -268,11 +257,9 @@ class ConfigMapConfigPropertiesTests {
*/
@Test
void testUseIncludeProfileSpecificSourcesDefaultChanged() {
ConfigMapConfigProperties properties = new ConfigMapConfigProperties();
properties.setSources(Collections.emptyList());
properties.setName("config-map-a");
properties.setNamespace("spring-k8s");
properties.setIncludeProfileSpecificSources(false);
ConfigMapConfigProperties properties = new ConfigMapConfigProperties(true, List.of(), List.of(), Map.of(), true,
"config-map-a", "spring-k8s", false, false, false, RetryProperties.DEFAULT);
List<NormalizedSource> sources = properties.determineSources(new MockEnvironment());
Assertions.assertEquals(sources.size(), 1, "empty sources must generate a List with a single NormalizedSource");
@@ -305,11 +292,6 @@ class ConfigMapConfigPropertiesTests {
*/
@Test
void testUseIncludeProfileSpecificSourcesDefaultChangedSourceOverride() {
ConfigMapConfigProperties properties = new ConfigMapConfigProperties();
properties.setSources(Collections.emptyList());
properties.setName("config-map-a");
properties.setNamespace("spring-k8s");
properties.setIncludeProfileSpecificSources(false);
ConfigMapConfigProperties.Source one = new ConfigMapConfigProperties.Source("config-map-one", null,
Collections.emptyMap(), "one", null, true);
@@ -320,7 +302,8 @@ class ConfigMapConfigPropertiesTests {
ConfigMapConfigProperties.Source three = new ConfigMapConfigProperties.Source("config-map-three", null,
Collections.emptyMap(), null, null, false);
properties.setSources(Arrays.asList(one, two, three));
ConfigMapConfigProperties properties = new ConfigMapConfigProperties(true, List.of(), List.of(one, two, three),
Map.of(), true, "config-map-a", "spring-k8s", false, false, false, RetryProperties.DEFAULT);
List<NormalizedSource> sources = properties.determineSources(new MockEnvironment());
Assertions.assertEquals(sources.size(), 3);
@@ -363,10 +346,6 @@ class ConfigMapConfigPropertiesTests {
*/
@Test
void testLabelsMultipleCases() {
ConfigMapConfigProperties properties = new ConfigMapConfigProperties();
properties.setUseNameAsPrefix(false);
properties.setNamespace("spring-k8s");
properties.setIncludeProfileSpecificSources(false);
ConfigMapConfigProperties.Source one = new ConfigMapConfigProperties.Source(null, null,
Map.of("first-label", "configmap-one"), "one", false, null);
@@ -380,7 +359,9 @@ class ConfigMapConfigPropertiesTests {
ConfigMapConfigProperties.Source four = new ConfigMapConfigProperties.Source(null, null,
Map.of("fourth-label", "configmap-four"), null, null, null);
properties.setSources(Arrays.asList(one, two, three, four));
ConfigMapConfigProperties properties = new ConfigMapConfigProperties(true, List.of(),
List.of(one, two, three, four), Map.of(), true, "config-map-a", "spring-k8s", false, false, false,
RetryProperties.DEFAULT);
List<NormalizedSource> sources = properties.determineSources(new MockEnvironment());
// we get 8 property sources, since "named" ones with "application" are

View File

@@ -0,0 +1,126 @@
/*
* Copyright 2013-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.kubernetes.commons.config;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Configuration;
/**
* @author wind57
*
* tests that prove that binding works. We need these because we moved to a record for
* configuration properties.
*/
class SecretsConfigPropertiesBindingTests {
@Test
void testWithDefaults() {
new ApplicationContextRunner().withUserConfiguration(Config.class).run(context -> {
SecretsConfigProperties props = context.getBean(SecretsConfigProperties.class);
Assertions.assertNotNull(props);
Assertions.assertFalse(props.enableApi());
Assertions.assertTrue(props.paths().isEmpty());
Assertions.assertTrue(props.sources().isEmpty());
Assertions.assertTrue(props.labels().isEmpty());
Assertions.assertTrue(props.enabled());
Assertions.assertNull(props.name());
Assertions.assertNull(props.namespace());
Assertions.assertFalse(props.useNameAsPrefix());
Assertions.assertTrue(props.includeProfileSpecificSources());
Assertions.assertFalse(props.failFast());
Assertions.assertNotNull(props.retry());
Assertions.assertEquals(props.retry().initialInterval(), 1000L);
Assertions.assertEquals(props.retry().multiplier(), 1.1D);
Assertions.assertEquals(props.retry().maxInterval(), 2000L);
Assertions.assertEquals(props.retry().maxAttempts(), 6);
Assertions.assertTrue(props.retry().enabled());
});
}
@Test
void testWithNonDefaults() {
new ApplicationContextRunner().withUserConfiguration(Config.class)
.withPropertyValues("spring.cloud.kubernetes.secrets.enableApi=false",
"spring.cloud.kubernetes.secrets.paths[0]=a", "spring.cloud.kubernetes.secrets.paths[1]=b",
"spring.cloud.kubernetes.secrets.sources[0].name=source-a",
"spring.cloud.kubernetes.secrets.sources[0].namespace=source-namespace-a",
"spring.cloud.kubernetes.secrets.sources[0].labels.key=source-value",
"spring.cloud.kubernetes.secrets.sources[0].explicit-prefix=source-prefix",
"spring.cloud.kubernetes.secrets.sources[0].use-name-as-prefix=true",
"spring.cloud.kubernetes.secrets.sources[0].include-profile-specific-sources=true",
"spring.cloud.kubernetes.secrets.labels.label-a=label-a",
"spring.cloud.kubernetes.secrets.enabled=false", "spring.cloud.kubernetes.secrets.name=name",
"spring.cloud.kubernetes.secrets.namespace=namespace",
"spring.cloud.kubernetes.secrets.use-name-as-prefix=true",
"spring.cloud.kubernetes.secrets.include-profile-specific-sources=true",
"spring.cloud.kubernetes.secrets.fail-fast=true",
"spring.cloud.kubernetes.secrets.retry.initial-interval=1",
"spring.cloud.kubernetes.secrets.retry.multiplier=1.2",
"spring.cloud.kubernetes.secrets.retry.max-interval=3",
"spring.cloud.kubernetes.secrets.retry.max-attempts=4",
"spring.cloud.kubernetes.secrets.retry.enabled=false")
.run(context -> {
SecretsConfigProperties props = context.getBean(SecretsConfigProperties.class);
Assertions.assertNotNull(props);
Assertions.assertFalse(props.enableApi());
Assertions.assertEquals(props.paths().size(), 2);
Assertions.assertEquals(props.paths().get(0), "a");
Assertions.assertEquals(props.paths().get(1), "b");
Assertions.assertEquals(props.sources().size(), 1);
SecretsConfigProperties.Source source = props.sources().get(0);
Assertions.assertEquals(source.name(), "source-a");
Assertions.assertEquals(source.namespace(), "source-namespace-a");
Assertions.assertEquals(source.labels().size(), 1);
Assertions.assertEquals(source.labels().get("key"), "source-value");
Assertions.assertEquals(source.explicitPrefix(), "source-prefix");
Assertions.assertTrue(source.useNameAsPrefix());
Assertions.assertTrue(source.includeProfileSpecificSources());
Assertions.assertEquals(props.labels().size(), 1);
Assertions.assertEquals(props.labels().get("label-a"), "label-a");
Assertions.assertFalse(props.enabled());
Assertions.assertEquals(props.name(), "name");
Assertions.assertEquals(props.namespace(), "namespace");
Assertions.assertTrue(props.useNameAsPrefix());
Assertions.assertTrue(props.includeProfileSpecificSources());
Assertions.assertTrue(props.failFast());
RetryProperties retryProperties = props.retry();
Assertions.assertNotNull(retryProperties);
Assertions.assertEquals(retryProperties.initialInterval(), 1);
Assertions.assertEquals(retryProperties.multiplier(), 1.2);
Assertions.assertEquals(retryProperties.maxInterval(), 3);
Assertions.assertFalse(retryProperties.enabled());
});
}
@Configuration
@EnableConfigurationProperties(SecretsConfigProperties.class)
static class Config {
}
}

View File

@@ -16,7 +16,6 @@
package org.springframework.cloud.kubernetes.commons.config;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
@@ -34,18 +33,19 @@ import org.springframework.mock.env.MockEnvironment;
*/
class SecretsConfigPropertiesTests {
private final SecretsConfigProperties properties = new SecretsConfigProperties();
/**
* the case when labels are empty
*/
@Test
void emptySourcesSecretName() {
properties.setNamespace("namespace");
SecretsConfigProperties properties = new SecretsConfigProperties(false, Map.of(), List.of(), List.of(), true,
null, "namespace", false, true, false, RetryProperties.DEFAULT);
List<NormalizedSource> source = properties.determineSources(new MockEnvironment());
properties.setSources(Collections.emptyList());
Assertions.assertEquals(source.size(), 1);
Assertions.assertTrue(source.get(0) instanceof NamedSecretNormalizedSource);
Assertions.assertTrue(source.get(0).name().isPresent());
Assertions.assertEquals(source.get(0).name().get(), "application");
}
@@ -70,16 +70,18 @@ class SecretsConfigPropertiesTests {
*/
@Test
void multipleSources() {
SecretsConfigProperties.Source one = new SecretsConfigProperties.Source("one", "spring-k8s",
Collections.singletonMap("one", "1"), null, null, null);
SecretsConfigProperties.Source two = new SecretsConfigProperties.Source(null, "spring-k8s",
Collections.singletonMap("two", "2"), null, null, null);
SecretsConfigProperties.Source one = new SecretsConfigProperties.Source("one", "spring-k8s", Map.of("one", "1"),
null, false, false);
SecretsConfigProperties.Source two = new SecretsConfigProperties.Source(null, "spring-k8s", Map.of("two", "2"),
null, false, false);
SecretsConfigProperties.Source three = new SecretsConfigProperties.Source(null, "spring-k8s",
Collections.singletonMap("three", "3"), null, null, null);
Map.of("three", "3"), null, false, false);
properties.setSources(Arrays.asList(one, two, three));
SecretsConfigProperties properties = new SecretsConfigProperties(false, Map.of(), List.of(),
List.of(one, two, three), true, null, "namespace", false, true, false, RetryProperties.DEFAULT);
List<NormalizedSource> result = properties.determineSources(new MockEnvironment());
Assertions.assertEquals(result.size(), 6);
@@ -122,10 +124,9 @@ class SecretsConfigPropertiesTests {
*/
@Test
void testUseNameAsPrefixUnsetEmptySources() {
SecretsConfigProperties properties = new SecretsConfigProperties();
properties.setSources(Collections.emptyList());
properties.setName("secret-a");
properties.setNamespace("spring-k8s");
SecretsConfigProperties properties = new SecretsConfigProperties(false, Map.of(), List.of(), List.of(), true,
"secret-a", "namespace", false, true, false, RetryProperties.DEFAULT);
List<NormalizedSource> sources = properties.determineSources(new MockEnvironment());
Assertions.assertEquals(sources.size(), 1, "empty sources must generate a List with a single NormalizedSource");
@@ -149,11 +150,9 @@ class SecretsConfigPropertiesTests {
*/
@Test
void testUseNameAsPrefixSetEmptySources() {
SecretsConfigProperties properties = new SecretsConfigProperties();
properties.setSources(Collections.emptyList());
properties.setUseNameAsPrefix(true);
properties.setName("secret-a");
properties.setNamespace("spring-k8s");
SecretsConfigProperties properties = new SecretsConfigProperties(false, Map.of(), List.of(), List.of(), true,
"secret-a", "namespace", true, true, false, RetryProperties.DEFAULT);
List<NormalizedSource> sources = properties.determineSources(new MockEnvironment());
Assertions.assertEquals(sources.size(), 1, "empty sources must generate a List with a single NormalizedSource");
@@ -180,13 +179,12 @@ class SecretsConfigPropertiesTests {
*/
@Test
void testUseNameAsPrefixUnsetNonEmptySources() {
SecretsConfigProperties properties = new SecretsConfigProperties();
properties.setUseNameAsPrefix(true);
properties.setNamespace("spring-k8s");
SecretsConfigProperties.Source one = new SecretsConfigProperties.Source("secret-one", null,
Collections.emptyMap(), null, null, null);
properties.setSources(Collections.singletonList(one));
SecretsConfigProperties.Source one = new SecretsConfigProperties.Source("secret-one", "spring-k8s", Map.of(),
null, true, false);
SecretsConfigProperties properties = new SecretsConfigProperties(false, Map.of(), List.of(), List.of(one), true,
"secret-one", null, false, true, false, RetryProperties.DEFAULT);
List<NormalizedSource> sources = properties.determineSources(new MockEnvironment());
Assertions.assertEquals(sources.size(), 1, "a single NormalizedSource is expected");
@@ -218,20 +216,18 @@ class SecretsConfigPropertiesTests {
*/
@Test
void testUseNameAsPrefixSetNonEmptySources() {
SecretsConfigProperties properties = new SecretsConfigProperties();
properties.setUseNameAsPrefix(true);
properties.setNamespace("spring-k8s");
SecretsConfigProperties.Source one = new SecretsConfigProperties.Source("secret-one", null,
Collections.emptyMap(), null, false, null);
SecretsConfigProperties.Source one = new SecretsConfigProperties.Source("secret-one", "spring-k8s", Map.of(),
null, false, false);
SecretsConfigProperties.Source two = new SecretsConfigProperties.Source("secret-two", null,
Collections.emptyMap(), null, true, null);
SecretsConfigProperties.Source two = new SecretsConfigProperties.Source("secret-two", "spring-k8s", Map.of(),
null, true, false);
SecretsConfigProperties.Source three = new SecretsConfigProperties.Source("secret-three", null,
Collections.emptyMap(), null, null, null);
SecretsConfigProperties.Source three = new SecretsConfigProperties.Source("secret-three", "spring-k8s",
Map.of(), null, true, false);
properties.setSources(Arrays.asList(one, two, three));
SecretsConfigProperties properties = new SecretsConfigProperties(false, Map.of(), List.of(),
List.of(one, two, three), true, "secret-one", null, false, true, false, RetryProperties.DEFAULT);
List<NormalizedSource> sources = properties.determineSources(new MockEnvironment());
Assertions.assertEquals(sources.size(), 3, "3 NormalizedSources are expected");
@@ -266,23 +262,22 @@ class SecretsConfigPropertiesTests {
*/
@Test
void testMultipleCases() {
SecretsConfigProperties properties = new SecretsConfigProperties();
properties.setUseNameAsPrefix(false);
properties.setNamespace("spring-k8s");
SecretsConfigProperties.Source one = new SecretsConfigProperties.Source("secret-one", null,
Collections.emptyMap(), "one", false, null);
SecretsConfigProperties.Source one = new SecretsConfigProperties.Source("secret-one", "spring-k8s", Map.of(),
"one", false, false);
SecretsConfigProperties.Source two = new SecretsConfigProperties.Source("secret-two", null,
Collections.emptyMap(), "two", true, null);
SecretsConfigProperties.Source two = new SecretsConfigProperties.Source("secret-two", "spring-k8s", Map.of(),
"two", true, false);
SecretsConfigProperties.Source three = new SecretsConfigProperties.Source("secret-three", null,
Collections.emptyMap(), "three", null, null);
SecretsConfigProperties.Source three = new SecretsConfigProperties.Source("secret-three", "spring-k8s",
Map.of(), "three", false, false);
SecretsConfigProperties.Source four = new SecretsConfigProperties.Source("secret-four", null,
Collections.emptyMap(), null, null, null);
SecretsConfigProperties.Source four = new SecretsConfigProperties.Source("secret-four", "spring-k8s", Map.of(),
null, false, false);
properties.setSources(Arrays.asList(one, two, three, four));
SecretsConfigProperties properties = new SecretsConfigProperties(false, Map.of(), List.of(),
List.of(one, two, three, four), true, "secret-one", "spring-k8s", false, false, false,
RetryProperties.DEFAULT);
List<NormalizedSource> sources = properties.determineSources(new MockEnvironment());
Assertions.assertEquals(sources.size(), 4, "4 NormalizedSources are expected");
@@ -328,24 +323,21 @@ class SecretsConfigPropertiesTests {
@Test
void testLabelsMultipleCases() {
SecretsConfigProperties properties = new SecretsConfigProperties();
properties.setUseNameAsPrefix(false);
properties.setNamespace("spring-k8s");
properties.setIncludeProfileSpecificSources(false);
SecretsConfigProperties.Source one = new SecretsConfigProperties.Source(null, "spring-k8s",
Map.of("first-label", "secret-one"), "one", false, false);
SecretsConfigProperties.Source one = new SecretsConfigProperties.Source(null, null,
Map.of("first-label", "secret-one"), "one", false, null);
SecretsConfigProperties.Source two = new SecretsConfigProperties.Source(null, null,
SecretsConfigProperties.Source two = new SecretsConfigProperties.Source(null, "spring-k8s",
Map.of("second-label", "secret-two"), "two", true, true);
SecretsConfigProperties.Source three = new SecretsConfigProperties.Source(null, null,
Map.of("third-label", "secret-three"), "three", null, null);
SecretsConfigProperties.Source three = new SecretsConfigProperties.Source(null, "spring-k8s",
Map.of("third-label", "secret-three"), "three", false, false);
SecretsConfigProperties.Source four = new SecretsConfigProperties.Source(null, null,
Map.of("fourth-label", "secret-four"), null, null, null);
SecretsConfigProperties.Source four = new SecretsConfigProperties.Source(null, "spring-k8s",
Map.of("fourth-label", "secret-four"), null, false, false);
properties.setSources(Arrays.asList(one, two, three, four));
SecretsConfigProperties properties = new SecretsConfigProperties(false, Map.of(), List.of(),
List.of(one, two, three, four), false, null, "spring-k8s", false, false, false,
RetryProperties.DEFAULT);
List<NormalizedSource> sources = properties.determineSources(new MockEnvironment());
// we get 8 property sources, since "named" ones with "application" are

View File

@@ -22,9 +22,9 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.commons.config.AbstractConfigProperties;
import org.springframework.cloud.kubernetes.commons.config.App;
import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties;
import org.springframework.cloud.kubernetes.commons.config.RetryProperties;
import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.retry.interceptor.RetryOperationsInterceptor;
@@ -58,16 +58,15 @@ public class ConfigAndSecretsFailFastEnabledWithDefaultRetryConfiguration {
@Test
void retryConfigurationShouldBeDefault() {
AbstractConfigProperties.RetryProperties defaultRetryProperties = AbstractConfigProperties.RetryProperties.DEFAULT;
AbstractConfigProperties.RetryProperties configMapRetryProperties = configMapConfigProperties.getRetry();
RetryProperties defaultRetryProperties = RetryProperties.DEFAULT;
RetryProperties configMapRetryProperties = configMapConfigProperties.retry();
assertThat(configMapRetryProperties.maxAttempts()).isEqualTo(defaultRetryProperties.maxAttempts());
assertThat(configMapRetryProperties.initialInterval()).isEqualTo(defaultRetryProperties.initialInterval());
assertThat(configMapRetryProperties.maxInterval()).isEqualTo(defaultRetryProperties.maxInterval());
assertThat(configMapRetryProperties.multiplier()).isEqualTo(defaultRetryProperties.multiplier());
AbstractConfigProperties.RetryProperties secretsRetryProperties = secretsConfigProperties.getRetry();
RetryProperties secretsRetryProperties = secretsConfigProperties.retry();
assertThat(secretsRetryProperties.maxAttempts()).isEqualTo(defaultRetryProperties.maxAttempts());
assertThat(secretsRetryProperties.initialInterval()).isEqualTo(defaultRetryProperties.initialInterval());

View File

@@ -22,9 +22,9 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.commons.config.AbstractConfigProperties;
import org.springframework.cloud.kubernetes.commons.config.App;
import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties;
import org.springframework.cloud.kubernetes.commons.config.RetryProperties;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.retry.interceptor.RetryOperationsInterceptor;
@@ -53,8 +53,8 @@ class ConfigFailFastEnabled {
@Test
void retryConfigurationShouldBeDefault() {
AbstractConfigProperties.RetryProperties retryProperties = configMapConfigProperties.getRetry();
AbstractConfigProperties.RetryProperties defaultRetryProperties = AbstractConfigProperties.RetryProperties.DEFAULT;
RetryProperties retryProperties = configMapConfigProperties.retry();
RetryProperties defaultRetryProperties = RetryProperties.DEFAULT;
assertThat(retryProperties.maxAttempts()).isEqualTo(defaultRetryProperties.maxAttempts());
assertThat(retryProperties.initialInterval()).isEqualTo(defaultRetryProperties.initialInterval());

View File

@@ -20,9 +20,9 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.commons.config.AbstractConfigProperties;
import org.springframework.cloud.kubernetes.commons.config.App;
import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties;
import org.springframework.cloud.kubernetes.commons.config.RetryProperties;
import static org.assertj.core.api.Assertions.assertThat;
@@ -42,7 +42,7 @@ class ConfigFailFastEnabledWithCustomRetryConfiguration {
@Test
void retryConfigurationShouldBeCustomized() {
AbstractConfigProperties.RetryProperties retryProperties = configMapConfigProperties.getRetry();
RetryProperties retryProperties = configMapConfigProperties.retry();
assertThat(retryProperties.maxAttempts()).isEqualTo(3);
assertThat(retryProperties.initialInterval()).isEqualTo(1500L);

View File

@@ -22,8 +22,8 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.commons.config.AbstractConfigProperties;
import org.springframework.cloud.kubernetes.commons.config.App;
import org.springframework.cloud.kubernetes.commons.config.RetryProperties;
import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.retry.interceptor.RetryOperationsInterceptor;
@@ -53,9 +53,8 @@ class SecretsFailFastEnabled {
@Test
void retryConfigurationShouldBeDefault() {
AbstractConfigProperties.RetryProperties retryProperties = secretsConfigProperties.getRetry();
AbstractConfigProperties.RetryProperties defaultRetryProperties = new AbstractConfigProperties.RetryProperties(
1000, 1.1, 2000, 6, true);
RetryProperties retryProperties = secretsConfigProperties.retry();
RetryProperties defaultRetryProperties = RetryProperties.DEFAULT;
assertThat(retryProperties.maxAttempts()).isEqualTo(defaultRetryProperties.maxAttempts());
assertThat(retryProperties.initialInterval()).isEqualTo(defaultRetryProperties.initialInterval());

View File

@@ -20,8 +20,8 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.commons.config.AbstractConfigProperties;
import org.springframework.cloud.kubernetes.commons.config.App;
import org.springframework.cloud.kubernetes.commons.config.RetryProperties;
import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties;
import static org.assertj.core.api.Assertions.assertThat;
@@ -42,7 +42,7 @@ class SecretsFailFastEnabledWithCustomRetryConfiguration {
@Test
void retryConfigurationShouldBeCustomized() {
AbstractConfigProperties.RetryProperties retryProperties = secretsConfigProperties.getRetry();
RetryProperties retryProperties = secretsConfigProperties.retry();
assertThat(retryProperties.maxAttempts()).isEqualTo(3);
assertThat(retryProperties.initialInterval()).isEqualTo(1500L);

View File

@@ -72,7 +72,7 @@ public class Fabric8ConfigDataLocationResolver extends KubernetesConfigDataLocat
namespaceProvider);
}
else {
if (configMapProperties != null && configMapProperties.isEnabled()) {
if (configMapProperties != null && configMapProperties.enabled()) {
Fabric8ConfigMapPropertySourceLocator configMapPropertySourceLocator = new Fabric8ConfigMapPropertySourceLocator(
kubernetesClient, configMapProperties, namespaceProvider);
bootstrapContext.registerIfAbsent(ConfigMapPropertySourceLocator.class,
@@ -81,7 +81,7 @@ public class Fabric8ConfigDataLocationResolver extends KubernetesConfigDataLocat
.registerSingleton("configDataConfigMapPropertySourceLocator",
event.getBootstrapContext().get(ConfigMapPropertySourceLocator.class)));
}
if (secretsProperties != null && secretsProperties.isEnabled()) {
if (secretsProperties != null && secretsProperties.enabled()) {
Fabric8SecretsPropertySourceLocator secretsPropertySourceLocator = new Fabric8SecretsPropertySourceLocator(
kubernetesClient, secretsProperties, namespaceProvider);
bootstrapContext.registerIfAbsent(SecretsPropertySourceLocator.class,
@@ -96,7 +96,7 @@ public class Fabric8ConfigDataLocationResolver extends KubernetesConfigDataLocat
private void registerRetryBeans(ConfigMapConfigProperties configMapProperties,
SecretsConfigProperties secretsProperties, ConfigurableBootstrapContext bootstrapContext,
KubernetesClient kubernetesClient, KubernetesNamespaceProvider namespaceProvider) {
if (configMapProperties != null && configMapProperties.isEnabled()) {
if (configMapProperties != null && configMapProperties.enabled()) {
ConfigMapPropertySourceLocator configMapPropertySourceLocator = new Fabric8ConfigMapPropertySourceLocator(
kubernetesClient, configMapProperties, namespaceProvider);
if (isRetryEnabledForConfigMap(configMapProperties)) {
@@ -111,7 +111,7 @@ public class Fabric8ConfigDataLocationResolver extends KubernetesConfigDataLocat
event.getBootstrapContext().get(ConfigMapPropertySourceLocator.class)));
}
if (secretsProperties != null && secretsProperties.isEnabled()) {
if (secretsProperties != null && secretsProperties.enabled()) {
SecretsPropertySourceLocator secretsPropertySourceLocator = new Fabric8SecretsPropertySourceLocator(
kubernetesClient, secretsProperties, namespaceProvider);
if (isRetryEnabledForSecrets(secretsProperties)) {

View File

@@ -16,6 +16,9 @@
package org.springframework.cloud.kubernetes.fabric8.config;
import java.util.List;
import java.util.Map;
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
@@ -29,6 +32,7 @@ import org.springframework.cloud.kubernetes.commons.config.ConfigUtils;
import org.springframework.cloud.kubernetes.commons.config.NamedConfigMapNormalizedSource;
import org.springframework.cloud.kubernetes.commons.config.NamespaceResolutionFailedException;
import org.springframework.cloud.kubernetes.commons.config.NormalizedSource;
import org.springframework.cloud.kubernetes.commons.config.RetryProperties;
import org.springframework.mock.env.MockEnvironment;
import static org.assertj.core.api.Assertions.assertThatNoException;
@@ -52,14 +56,12 @@ class Fabric8ConfigMapPropertySourceLocatorTests {
void locateShouldThrowExceptionOnFailureWhenFailFastIsEnabled() {
String name = "my-config";
String namespace = "default";
String path = String.format("/api/v1/namespaces/%s/configmaps", namespace);
String path = "/api/v1/namespaces/default/configmaps";
mockServer.expect().withPath(path).andReturn(500, "Internal Server Error").once();
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties();
configMapConfigProperties.setName(name);
configMapConfigProperties.setNamespace(namespace);
configMapConfigProperties.setFailFast(true);
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(), List.of(),
Map.of(), true, name, namespace, false, true, true, RetryProperties.DEFAULT);
Fabric8ConfigMapPropertySourceLocator locator = new Fabric8ConfigMapPropertySourceLocator(mockClient,
configMapConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment()));
@@ -72,14 +74,12 @@ class Fabric8ConfigMapPropertySourceLocatorTests {
void locateShouldNotThrowExceptionOnFailureWhenFailFastIsDisabled() {
String name = "my-config";
String namespace = "default";
String path = String.format("/api/v1/namespaces/%s/configmaps/%s", namespace, name);
String path = "/api/v1/namespaces/default/configmaps/my-config";
mockServer.expect().withPath(path).andReturn(500, "Internal Server Error").once();
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties();
configMapConfigProperties.setName(name);
configMapConfigProperties.setNamespace(namespace);
configMapConfigProperties.setFailFast(false);
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(), List.of(),
Map.of(), true, name, namespace, false, true, false, RetryProperties.DEFAULT);
Fabric8ConfigMapPropertySourceLocator locator = new Fabric8ConfigMapPropertySourceLocator(mockClient,
configMapConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment()));
@@ -90,10 +90,8 @@ class Fabric8ConfigMapPropertySourceLocatorTests {
@Test
void constructorWithoutClientNamespaceMustFail() {
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties();
configMapConfigProperties.setName("name");
configMapConfigProperties.setNamespace(null);
configMapConfigProperties.setFailFast(false);
ConfigMapConfigProperties configMapConfigProperties = new ConfigMapConfigProperties(true, List.of(), List.of(),
Map.of(), true, "name", null, false, true, false, RetryProperties.DEFAULT);
Mockito.when(client.getNamespace()).thenReturn(null);
Fabric8ConfigMapPropertySourceLocator source = new Fabric8ConfigMapPropertySourceLocator(client,

View File

@@ -16,12 +16,16 @@
package org.springframework.cloud.kubernetes.fabric8.config;
import java.util.List;
import java.util.Map;
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.Test;
import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
import org.springframework.cloud.kubernetes.commons.config.RetryProperties;
import org.springframework.cloud.kubernetes.commons.config.SecretsConfigProperties;
import org.springframework.mock.env.MockEnvironment;
@@ -40,17 +44,14 @@ class Fabric8SecretsPropertySourceLocatorTests {
@Test
void locateShouldThrowExceptionOnFailureWhenFailFastIsEnabled() {
final String name = "my-config";
final String namespace = "default";
final String path = String.format("/api/v1/namespaces/%s/secrets", namespace);
String name = "my-secret";
String namespace = "default";
String path = "/api/v1/namespaces/default/secrets";
mockServer.expect().withPath(path).andReturn(500, "Internal Server Error").once();
SecretsConfigProperties configMapConfigProperties = new SecretsConfigProperties();
configMapConfigProperties.setName(name);
configMapConfigProperties.setNamespace(namespace);
configMapConfigProperties.setEnableApi(true);
configMapConfigProperties.setFailFast(true);
SecretsConfigProperties configMapConfigProperties = new SecretsConfigProperties(true, Map.of(), List.of(),
List.of(), true, name, namespace, false, true, true, RetryProperties.DEFAULT);
Fabric8SecretsPropertySourceLocator locator = new Fabric8SecretsPropertySourceLocator(mockClient,
configMapConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment()));
@@ -61,17 +62,14 @@ class Fabric8SecretsPropertySourceLocatorTests {
@Test
void locateShouldNotThrowExceptionOnFailureWhenFailFastIsDisabled() {
final String name = "my-config";
final String namespace = "default";
final String path = String.format("/api/v1/namespaces/%s/secrets/%s", namespace, name);
String name = "my-secret";
String namespace = "default";
String path = "/api/v1/namespaces/default/secrets/my-secret";
mockServer.expect().withPath(path).andReturn(500, "Internal Server Error").once();
SecretsConfigProperties configMapConfigProperties = new SecretsConfigProperties();
configMapConfigProperties.setName(name);
configMapConfigProperties.setNamespace(namespace);
configMapConfigProperties.setEnableApi(true);
configMapConfigProperties.setFailFast(false);
SecretsConfigProperties configMapConfigProperties = new SecretsConfigProperties(true, Map.of(), List.of(),
List.of(), true, name, namespace, false, true, false, RetryProperties.DEFAULT);
Fabric8SecretsPropertySourceLocator locator = new Fabric8SecretsPropertySourceLocator(mockClient,
configMapConfigProperties, new KubernetesNamespaceProvider(new MockEnvironment()));

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.kubernetes.fabric8.config.bootstrap;
package org.springframework.cloud.kubernetes.fabric8.config.bootstrap.kubernetes_enabled;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.Application;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.kubernetes.fabric8.config.bootstrap;
package org.springframework.cloud.kubernetes.fabric8.config.bootstrap.kubernetes_enabled;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.kubernetes.fabric8.config.Application;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.springframework.cloud.kubernetes.fabric8.config.bootstrap;
package org.springframework.cloud.kubernetes.fabric8.config.bootstrap.kubernetes_enabled;
import org.junit.jupiter.api.Test;

View File

@@ -16,6 +16,9 @@
package org.springframework.cloud.kubernetes.fabric8.config.locator_retry.fail_fast_enabled_retry_disabled;
import java.util.List;
import java.util.Map;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient;
import io.fabric8.kubernetes.client.server.mock.KubernetesMockServer;
@@ -23,10 +26,14 @@ import org.junit.jupiter.api.BeforeAll;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.cloud.kubernetes.commons.KubernetesNamespaceProvider;
import org.springframework.cloud.kubernetes.commons.config.ConfigMapConfigProperties;
import org.springframework.cloud.kubernetes.commons.config.RetryProperties;
import org.springframework.cloud.kubernetes.fabric8.config.Application;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.env.Environment;
/**
* we call Fabric8ConfigMapPropertySourceLocator::locate directly, thus no need for
@@ -44,6 +51,7 @@ import org.springframework.cloud.kubernetes.fabric8.config.Application;
"spring.cloud.kubernetes.secrets.enabled=false", "spring.config.import=kubernetes:" },
classes = Application.class)
@EnableKubernetesMockClient
@Import(ConfigDataConfigFailFastEnabledButRetryDisabled.LocalConfig.class)
class ConfigDataConfigFailFastEnabledButRetryDisabled extends ConfigFailFastEnabledButRetryDisabled {
private static KubernetesMockServer mockServer;
@@ -53,12 +61,26 @@ class ConfigDataConfigFailFastEnabledButRetryDisabled extends ConfigFailFastEnab
@MockBean
private KubernetesNamespaceProvider kubernetesNamespaceProvider;
@SpyBean
private ConfigMapConfigProperties properties;
@BeforeAll
static void setup() {
setup(mockClient, mockServer);
}
@Configuration
static class LocalConfig {
/**
* we need this config because ConfigMapConfigProperties is now a record, so we
* can't use @SpyBean on it. We also read the property of fail-fast from the
* Environment, that in turn is set in the @SpringBootTest properties.
*/
@Bean
ConfigMapConfigProperties properties(Environment environment) {
return new ConfigMapConfigProperties(true, List.of(), List.of(), Map.of(), true, null, null, false, true,
Boolean.parseBoolean(environment.getProperty("spring.cloud.kubernetes.config.fail-fast")),
RetryProperties.DEFAULT);
}
}
}