Skip to content

Commit

Permalink
Merge branch 'main' into move-to-a-common-configuration-for-health
Browse files Browse the repository at this point in the history
  • Loading branch information
wind57 committed Mar 31, 2024
2 parents 02de9f9 + 9c74e14 commit ce72c22
Show file tree
Hide file tree
Showing 79 changed files with 538 additions and 172 deletions.
2 changes: 1 addition & 1 deletion docs/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes</artifactId>
<version>3.1.1-SNAPSHOT</version>
<version>3.1.2-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<packaging>jar</packaging>
Expand Down
12 changes: 6 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-build</artifactId>
<version>4.1.1-SNAPSHOT</version>
<version>4.1.2-SNAPSHOT</version>
<relativePath/>
</parent>

<artifactId>spring-cloud-kubernetes</artifactId>
<version>3.1.1-SNAPSHOT</version>
<version>3.1.2-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Spring Cloud Kubernetes</name>

Expand Down Expand Up @@ -70,10 +70,10 @@
<failsafe-reports-directory>failsafe-reports</failsafe-reports-directory>
<!-- Dependency Versions -->
<mockito-inline.version>4.8.1</mockito-inline.version>
<spring-cloud-commons.version>4.1.2-SNAPSHOT</spring-cloud-commons.version>
<spring-cloud-config.version>4.1.1-SNAPSHOT</spring-cloud-config.version>
<spring-cloud-bus.version>4.1.1-SNAPSHOT</spring-cloud-bus.version>
<spring-cloud-contract.version>4.1.1-SNAPSHOT</spring-cloud-contract.version>
<spring-cloud-commons.version>4.1.3-SNAPSHOT</spring-cloud-commons.version>
<spring-cloud-config.version>4.1.2-SNAPSHOT</spring-cloud-config.version>
<spring-cloud-bus.version>4.1.2-SNAPSHOT</spring-cloud-bus.version>
<spring-cloud-contract.version>4.1.3-SNAPSHOT</spring-cloud-contract.version>

<maven-checkstyle-plugin.failsOnError>true</maven-checkstyle-plugin.failsOnError>
<maven-checkstyle-plugin.failsOnViolation>true
Expand Down
2 changes: 1 addition & 1 deletion spring-cloud-kubernetes-client-autoconfig/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>spring-cloud-kubernetes</artifactId>
<groupId>org.springframework.cloud</groupId>
<version>3.1.1-SNAPSHOT</version>
<version>3.1.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
2 changes: 1 addition & 1 deletion spring-cloud-kubernetes-client-config/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>spring-cloud-kubernetes</artifactId>
<groupId>org.springframework.cloud</groupId>
<version>3.1.1-SNAPSHOT</version>
<version>3.1.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,10 @@
* @author wind57
*/
public record KubernetesClientConfigContext(CoreV1Api client, NormalizedSource normalizedSource, String namespace,
Environment environment) {
Environment environment, boolean includeDefaultProfileData) {

public KubernetesClientConfigContext(CoreV1Api client, NormalizedSource normalizedSource, String namespace,
Environment environment) {
this(client, normalizedSource, namespace, environment, true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
*
* @author wind57
*/
final class KubernetesClientConfigMapsCache implements ConfigMapCache {
public final class KubernetesClientConfigMapsCache implements ConfigMapCache {

private static final LogAccessor LOG = new LogAccessor(LogFactory.getLog(KubernetesClientConfigMapsCache.class));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,13 @@ static MultipleSourcesContainer configMapsDataByLabels(CoreV1Api coreV1Api, Stri
* </pre>
*/
static MultipleSourcesContainer secretsDataByName(CoreV1Api coreV1Api, String namespace,
LinkedHashSet<String> sourceNames, Environment environment) {
LinkedHashSet<String> sourceNames, Environment environment, boolean includeDefaultProfileData) {
List<StrippedSourceContainer> strippedSecrets = strippedSecrets(coreV1Api, namespace);
if (strippedSecrets.isEmpty()) {
return MultipleSourcesContainer.empty();
}
return ConfigUtils.processNamedData(strippedSecrets, environment, sourceNames, namespace, DECODE);
return ConfigUtils.processNamedData(strippedSecrets, environment, sourceNames, namespace, DECODE,
includeDefaultProfileData);
}

/**
Expand All @@ -125,12 +126,13 @@ static MultipleSourcesContainer secretsDataByName(CoreV1Api coreV1Api, String na
* </pre>
*/
static MultipleSourcesContainer configMapsDataByName(CoreV1Api coreV1Api, String namespace,
LinkedHashSet<String> sourceNames, Environment environment) {
LinkedHashSet<String> sourceNames, Environment environment, boolean includeDefaultProfileData) {
List<StrippedSourceContainer> strippedConfigMaps = strippedConfigMaps(coreV1Api, namespace);
if (strippedConfigMaps.isEmpty()) {
return MultipleSourcesContainer.empty();
}
return ConfigUtils.processNamedData(strippedConfigMaps, environment, sourceNames, namespace, DECODE);
return ConfigUtils.processNamedData(strippedConfigMaps, environment, sourceNames, namespace, DECODE,
includeDefaultProfileData);
}

private static List<StrippedSourceContainer> strippedConfigMaps(CoreV1Api coreV1Api, String namespace) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
*/
public class KubernetesClientSecretsPropertySource extends SecretsPropertySource {

@Deprecated(forRemoval = true)
public KubernetesClientSecretsPropertySource(SourceData sourceData) {
super(sourceData);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.LinkedHashSet;
import java.util.function.Supplier;

import org.springframework.cloud.kubernetes.commons.config.ConfigUtils;
import org.springframework.cloud.kubernetes.commons.config.MultipleSourcesContainer;
import org.springframework.cloud.kubernetes.commons.config.NamedConfigMapNormalizedSource;
import org.springframework.cloud.kubernetes.commons.config.NamedSourceData;
Expand All @@ -42,10 +43,19 @@ public KubernetesClientContextToSourceData get() {
NamedConfigMapNormalizedSource source = (NamedConfigMapNormalizedSource) context.normalizedSource();

return new NamedSourceData() {
@Override
protected String generateSourceName(String target, String sourceName, String namespace,
String[] activeProfiles) {
if (source.appendProfileToName()) {
return ConfigUtils.sourceName(target, sourceName, namespace, activeProfiles);
}
return super.generateSourceName(target, sourceName, namespace, activeProfiles);
}

@Override
public MultipleSourcesContainer dataSupplier(LinkedHashSet<String> sourceNames) {
return KubernetesClientConfigUtils.configMapsDataByName(context.client(), context.namespace(),
sourceNames, context.environment());
sourceNames, context.environment(), context.includeDefaultProfileData());
}
}.compute(source.name().orElseThrow(), source.prefix(), source.target(), source.profileSpecificSources(),
source.failFast(), context.namespace(), context.environment().getActiveProfiles());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.LinkedHashSet;
import java.util.function.Supplier;

import org.springframework.cloud.kubernetes.commons.config.ConfigUtils;
import org.springframework.cloud.kubernetes.commons.config.MultipleSourcesContainer;
import org.springframework.cloud.kubernetes.commons.config.NamedSecretNormalizedSource;
import org.springframework.cloud.kubernetes.commons.config.NamedSourceData;
Expand All @@ -41,10 +42,19 @@ public KubernetesClientContextToSourceData get() {
NamedSecretNormalizedSource source = (NamedSecretNormalizedSource) context.normalizedSource();

return new NamedSourceData() {
@Override
protected String generateSourceName(String target, String sourceName, String namespace,
String[] activeProfiles) {
if (source.appendProfileToName()) {
return ConfigUtils.sourceName(target, sourceName, namespace, activeProfiles);
}
return super.generateSourceName(target, sourceName, namespace, activeProfiles);
}

@Override
public MultipleSourcesContainer dataSupplier(LinkedHashSet<String> sourceNames) {
return KubernetesClientConfigUtils.secretsDataByName(context.client(), context.namespace(),
sourceNames, context.environment());
sourceNames, context.environment(), context.includeDefaultProfileData());
}
}.compute(source.name().orElseThrow(), source.prefix(), source.target(), source.profileSpecificSources(),
source.failFast(), context.namespace(), context.environment().getActiveProfiles());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,17 +164,18 @@ void matchIncludeSingleProfile() {
stubCall(configMapList);
CoreV1Api api = new CoreV1Api();

NormalizedSource source = new NamedConfigMapNormalizedSource(RED_CONFIG_MAP_NAME, NAMESPACE, true, true);
NormalizedSource source = new NamedConfigMapNormalizedSource(RED_CONFIG_MAP_NAME, NAMESPACE, true,
ConfigUtils.Prefix.DEFAULT, true, true);
MockEnvironment environment = new MockEnvironment();
environment.setActiveProfiles("with-profile");
KubernetesClientConfigContext context = new KubernetesClientConfigContext(api, source, NAMESPACE, environment);
KubernetesClientConfigContext context = new KubernetesClientConfigContext(api, source, NAMESPACE, environment,
false);

KubernetesClientContextToSourceData data = new NamedConfigMapContextToSourceDataProvider().get();
SourceData sourceData = data.apply(context);

Assertions.assertEquals(sourceData.sourceName(), "configmap.red.red-with-profile.default");
Assertions.assertEquals(sourceData.sourceData().size(), 2);
Assertions.assertEquals(sourceData.sourceData().get("color"), "really-red");
Assertions.assertEquals(sourceData.sourceName(), "configmap.red.red-with-profile.default.with-profile");
Assertions.assertEquals(sourceData.sourceData().size(), 1);
Assertions.assertEquals(sourceData.sourceData().get("taste"), "mango");

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,17 +217,18 @@ void matchIncludeSingleProfile() {
stubCall(secretList);
CoreV1Api api = new CoreV1Api();

NormalizedSource source = new NamedSecretNormalizedSource("red", NAMESPACE, false, true);
NormalizedSource source = new NamedSecretNormalizedSource("red", NAMESPACE, false, ConfigUtils.Prefix.DEFAULT,
true, true);
MockEnvironment environment = new MockEnvironment();
environment.addActiveProfile("with-profile");
KubernetesClientConfigContext context = new KubernetesClientConfigContext(api, source, NAMESPACE, environment);
KubernetesClientConfigContext context = new KubernetesClientConfigContext(api, source, NAMESPACE, environment,
false);

KubernetesClientContextToSourceData data = new NamedSecretContextToSourceDataProvider().get();
SourceData sourceData = data.apply(context);

Assertions.assertEquals(sourceData.sourceName(), "secret.red.red-with-profile.default");
Assertions.assertEquals(sourceData.sourceData().size(), 2);
Assertions.assertEquals(sourceData.sourceData().get("color"), "really-red");
Assertions.assertEquals(sourceData.sourceName(), "secret.red.red-with-profile.default.with-profile");
Assertions.assertEquals(sourceData.sourceData().size(), 1);
Assertions.assertEquals(sourceData.sourceData().get("taste"), "mango");

}
Expand Down
2 changes: 1 addition & 1 deletion spring-cloud-kubernetes-client-discovery/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>spring-cloud-kubernetes</artifactId>
<groupId>org.springframework.cloud</groupId>
<version>3.1.1-SNAPSHOT</version>
<version>3.1.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
2 changes: 1 addition & 1 deletion spring-cloud-kubernetes-client-loadbalancer/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<artifactId>spring-cloud-kubernetes</artifactId>
<groupId>org.springframework.cloud</groupId>

<version>3.1.1-SNAPSHOT</version>
<version>3.1.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
2 changes: 1 addition & 1 deletion spring-cloud-kubernetes-commons/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-kubernetes</artifactId>
<version>3.1.1-SNAPSHOT</version>
<version>3.1.2-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.springframework.cloud.kubernetes.commons.config;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.HashMap;
import java.util.LinkedHashSet;
Expand Down Expand Up @@ -161,13 +162,27 @@ public static String sourceName(String target, String applicationName, String na
return target + PROPERTY_SOURCE_NAME_SEPARATOR + applicationName + PROPERTY_SOURCE_NAME_SEPARATOR + namespace;
}

public static String sourceName(String target, String applicationName, String namespace, String[] profiles) {
String name = sourceName(target, applicationName, namespace);
if (profiles != null && profiles.length > 0) {
name = name + PROPERTY_SOURCE_NAME_SEPARATOR + StringUtils.arrayToDelimitedString(profiles, "-");
}
return name;
}

public static MultipleSourcesContainer processNamedData(List<StrippedSourceContainer> strippedSources,
Environment environment, LinkedHashSet<String> sourceNames, String namespace, boolean decode) {
return processNamedData(strippedSources, environment, sourceNames, namespace, decode, true);
}

/**
* transforms raw data from one or multiple sources into an entry of source names and
* flattened data that they all hold (potentially overriding entries without any
* defined order).
*/
public static MultipleSourcesContainer processNamedData(List<StrippedSourceContainer> strippedSources,
Environment environment, LinkedHashSet<String> sourceNames, String namespace, boolean decode) {
Environment environment, LinkedHashSet<String> sourceNames, String namespace, boolean decode,
boolean includeDefaultProfileData) {

Map<String, StrippedSourceContainer> hashByName = strippedSources.stream()
.collect(Collectors.toMap(StrippedSourceContainer::name, Function.identity()));
Expand All @@ -179,24 +194,48 @@ public static MultipleSourcesContainer processNamedData(List<StrippedSourceConta
// processed before profile based sources. This way, we replicate that
// "application-dev.yaml"
// overrides properties from "application.yaml"
sourceNames.forEach(source -> {
StrippedSourceContainer stripped = hashByName.get(source);
sourceNames.forEach(sourceName -> {
StrippedSourceContainer stripped = hashByName.get(sourceName);
if (stripped != null) {
LOG.debug("Found source with name : '" + source + " in namespace: '" + namespace + "'");
foundSourceNames.add(source);
LOG.debug("Found source with name : '" + sourceName + " in namespace: '" + namespace + "'");
foundSourceNames.add(sourceName);
// see if data is a single yaml/properties file and if it needs decoding
Map<String, String> rawData = stripped.data();
if (decode) {
rawData = decodeData(rawData);
}
data.putAll(SourceDataEntriesProcessor.processAllEntries(rawData == null ? Map.of() : rawData,
environment));

// In some cases we want to include properties from the default profile
// along with any active profiles
// In these cases includeDefaultProfileData will be true
// If includeDefaultProfileData is false then we want to make sure that we
// only return properties from any active profiles

// Check the source to see if it contains any active profiles
boolean containsActiveProfile = environment.getActiveProfiles().length == 0
|| Arrays.stream(environment.getActiveProfiles())
.anyMatch(activeProfile -> sourceName.endsWith("-" + activeProfile)
|| "default".equals(activeProfile));
if (includeDefaultProfileData || containsActiveProfile
|| containsDataWithProfile(rawData, environment.getActiveProfiles())) {
data.putAll(SourceDataEntriesProcessor.processAllEntries(rawData == null ? Map.of() : rawData,
environment, includeDefaultProfileData));
}
}
});

return new MultipleSourcesContainer(foundSourceNames, data);
}

/*
* In the case there the data contains yaml or properties files we need to check their
* names to see if they contain any active profiles.
*/
private static boolean containsDataWithProfile(Map<String, String> rawData, String[] activeProfiles) {
return rawData.keySet().stream().anyMatch(key -> Arrays.stream(activeProfiles)
.anyMatch(activeProfile -> key.contains("-" + activeProfile) || "default".equals(activeProfile)));
}

/**
* transforms raw data from one or multiple sources into an entry of source names and
* flattened data that they all hold (potentially overriding entries without any
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,25 @@ public final class NamedConfigMapNormalizedSource extends NormalizedSource {

private final boolean includeProfileSpecificSources;

private final boolean appendProfileToName;

public NamedConfigMapNormalizedSource(String name, String namespace, boolean failFast, ConfigUtils.Prefix prefix,
boolean includeProfileSpecificSources) {
super(name, namespace, failFast);
this.prefix = Objects.requireNonNull(prefix);
this.includeProfileSpecificSources = includeProfileSpecificSources;
this(name, namespace, failFast, prefix, includeProfileSpecificSources, false);
}

public NamedConfigMapNormalizedSource(String name, String namespace, boolean failFast,
boolean includeProfileSpecificSources) {
this(name, namespace, failFast, ConfigUtils.Prefix.DEFAULT, includeProfileSpecificSources);
}

public NamedConfigMapNormalizedSource(String name, String namespace, boolean failFast, ConfigUtils.Prefix prefix,
boolean includeProfileSpecificSources, boolean appendProfileToName) {
super(name, namespace, failFast);
this.prefix = ConfigUtils.Prefix.DEFAULT;
this.prefix = Objects.requireNonNull(prefix);
this.includeProfileSpecificSources = includeProfileSpecificSources;
this.appendProfileToName = appendProfileToName;

}

public ConfigUtils.Prefix prefix() {
Expand All @@ -51,6 +58,14 @@ public boolean profileSpecificSources() {
return includeProfileSpecificSources;
}

/**
* append or not the active profiles to the name of the generated source. At the
* moment this is true only for config server generated sources.
*/
public boolean appendProfileToName() {
return appendProfileToName;
}

@Override
public NormalizedSourceType type() {
return NormalizedSourceType.NAMED_CONFIG_MAP;
Expand Down
Loading

0 comments on commit ce72c22

Please sign in to comment.