Add logic to be more specific about when mark a property source to be profile specific (#2437)

Fixes #2417

Co-authored-by: Ryan Baxter <524254+ryanjbaxter@users.noreply.github.com>
This commit is contained in:
Ryan Baxter
2024-07-04 09:03:03 -04:00
committed by GitHub
parent dbfc5d2346
commit 37656d33bb
2 changed files with 74 additions and 1 deletions

View File

@@ -55,6 +55,7 @@ import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;
import static org.springframework.cloud.config.client.ConfigClientProperties.DEFAULT_PROFILE;
import static org.springframework.cloud.config.client.ConfigClientProperties.STATE_HEADER;
import static org.springframework.cloud.config.client.ConfigClientProperties.TOKEN_HEADER;
@@ -67,6 +68,8 @@ public class ConfigServerConfigDataLoader implements ConfigDataLoader<ConfigServ
private static final EnumSet<Option> ALL_OPTIONS = EnumSet.allOf(Option.class);
private static final String OVERRIDES_NAME = "configserver:overrides";
protected final Log logger;
public ConfigServerConfigDataLoader(DeferredLogFactory logFactory) {
@@ -168,7 +171,13 @@ public class ConfigServerConfigDataLoader implements ConfigDataLoader<ConfigServ
// - is the default profile-separator for property sources
// TODO This is error prone logic see
// https://github.com/spring-cloud/spring-cloud-config/issues/2291
if (propertySourceName.matches(".*[-,]" + profile + ".*")) {
// When we see the overrides property source name we
// should always prioritize those
// properties over everything else, even profile specific
// property sources so also
// label this property source profile specific.
if (OVERRIDES_NAME.equals(propertySourceName) || (!DEFAULT_PROFILE.equals(profile)
&& propertySourceName.matches(".*[-,]" + profile + "\\b.*"))) {
// // TODO: switch to Options.with() when implemented
options.add(Option.PROFILE_SPECIFIC);
}

View File

@@ -506,6 +506,70 @@ public class ConfigServerConfigDataLoaderTests {
}
@Test
void testProfileSpecificPropertySources() {
PropertySource p1 = new PropertySource("overrides", Collections.singletonMap("foo", "bar"));
PropertySource p2 = new PropertySource("classpath:/test-default/config-client/application.yaml",
Collections.singletonMap("foo", "baroverride"));
PropertySource p3 = new PropertySource(
"git@github.com:demo/support-configuration-repo.git/Config resource 'file [/var/folders/k3/zv8hzdm17vv69j485fv3cf9r0000gp/T/config-repo-14772121892716396795/commons/application.properties' via location 'commons/' (document #0)",
Collections.singletonMap("hello", "world"));
PropertySource p4 = new PropertySource("aws:secrets:/secret/application-name_profile",
Collections.singletonMap("hello", "world"));
Map<String, Object> activatesOnProfileCamelCase = new HashMap<>();
activatesOnProfileCamelCase.put("spring.config.activate.onProfile", "foo");
PropertySource p5 = new PropertySource(
"git@github.com:demo/support-configuration-repo.git/Config resource 'file [/var/folders/k3/zv8hzdm17vv69j485fv3cf9r0000gp/T/config-repo-14772121892716396795/commons/application.properties' via location 'commons/' (document #1)",
activatesOnProfileCamelCase);
Map<String, Object> activatesOnProfile = new HashMap<>();
activatesOnProfile.put("spring.config.activate.on-profile", "foo");
PropertySource p6 = new PropertySource(
"ssh://git@stash.int.openbet.com:7999/dbs/environments.git/Config resource 'file [/tmp/config-repo-16512912790018624282/platform/pinnacle-def.yaml' via location 'platform/' (document#0)",
activatesOnProfile);
ConfigData configData = setupConfigServerConfigDataLoader(Arrays.asList(p6, p5, p4, p3, p2, p1),
"application-slash", "def");
assertThat(configData.getPropertySources()).hasSize(7);
assertThat(configData.getOptions(configData.getPropertySources().get(0))
.contains(ConfigData.Option.PROFILE_SPECIFIC)).isFalse();
assertThat(configData.getOptions(configData.getPropertySources().get(1))
.contains(ConfigData.Option.PROFILE_SPECIFIC)).isTrue();
assertThat(configData.getOptions(configData.getPropertySources().get(2))
.contains(ConfigData.Option.PROFILE_SPECIFIC)).isFalse();
assertThat(configData.getOptions(configData.getPropertySources().get(3))
.contains(ConfigData.Option.PROFILE_SPECIFIC)).isFalse();
assertThat(configData.getOptions(configData.getPropertySources().get(4))
.contains(ConfigData.Option.PROFILE_SPECIFIC)).isFalse();
assertThat(configData.getOptions(configData.getPropertySources().get(5))
.contains(ConfigData.Option.PROFILE_SPECIFIC)).isFalse();
assertThat(configData.getOptions(configData.getPropertySources().get(6))
.contains(ConfigData.Option.PROFILE_SPECIFIC)).isTrue();
}
@Test
void testProfileSpecificPropertySourcesWithDefaultProfile() {
PropertySource p1 = new PropertySource("overrides", Collections.singletonMap("foo", "bar"));
PropertySource p2 = new PropertySource("classpath:/test-default/config-client/application.yaml",
Collections.singletonMap("foo", "baroverride"));
PropertySource p3 = new PropertySource(
"git@github.com:demo/support-configuration-repo.git/Config resource 'file [/var/folders/k3/zv8hzdm17vv69j485fv3cf9r0000gp/T/config-repo-14772121892716396795/commons/application.properties' via location 'commons/' (document #0)",
Collections.singletonMap("hello", "world"));
PropertySource p4 = new PropertySource("aws:secrets:/secret/application-name_profile",
Collections.singletonMap("hello", "world"));
ConfigData configData = setupConfigServerConfigDataLoader(Arrays.asList(p4, p3, p2, p1), "application-slash",
"default");
assertThat(configData.getPropertySources()).hasSize(5);
assertThat(configData.getOptions(configData.getPropertySources().get(0))
.contains(ConfigData.Option.PROFILE_SPECIFIC)).isFalse();
assertThat(configData.getOptions(configData.getPropertySources().get(1))
.contains(ConfigData.Option.PROFILE_SPECIFIC)).isTrue();
assertThat(configData.getOptions(configData.getPropertySources().get(2))
.contains(ConfigData.Option.PROFILE_SPECIFIC)).isFalse();
assertThat(configData.getOptions(configData.getPropertySources().get(3))
.contains(ConfigData.Option.PROFILE_SPECIFIC)).isFalse();
assertThat(configData.getOptions(configData.getPropertySources().get(4))
.contains(ConfigData.Option.PROFILE_SPECIFIC)).isFalse();
}
private ConfigData setupConfigServerConfigDataLoader(List<PropertySource> propertySources, String applicationName,
String... profileList) {
RestTemplate rest = mock(RestTemplate.class);