Merge branch 'Walliee-GH-1586'

This commit is contained in:
spencergibb
2021-07-27 23:20:35 -04:00
6 changed files with 186 additions and 3 deletions

View File

@@ -48,6 +48,13 @@ public class ConfigClientProperties {
*/
public static final String PREFIX = "spring.cloud.config";
/**
* Placeholder string that allows ${spring.cloud.config.name} to override
* ${spring.application.name:application}.
*/
public static final String NAME_PLACEHOLDER = "${" + ConfigClientProperties.PREFIX
+ ".name:${spring.application.name:application}}";
/**
* Name of config discovery enabled property.
*/
@@ -374,8 +381,7 @@ public class ConfigClientProperties {
public ConfigClientProperties override(org.springframework.core.env.Environment environment) {
ConfigClientProperties override = new ConfigClientProperties();
BeanUtils.copyProperties(this, override);
override.setName(environment.resolvePlaceholders(
"${" + ConfigClientProperties.PREFIX + ".name:${spring.application.name:application}}"));
override.setName(environment.resolvePlaceholders(NAME_PLACEHOLDER));
if (environment.containsProperty(ConfigClientProperties.PREFIX + ".profile")) {
override.setProfile(environment.getProperty(ConfigClientProperties.PREFIX + ".profile"));
}

View File

@@ -33,6 +33,7 @@ import org.springframework.boot.origin.OriginTrackedValue;
import org.springframework.cloud.bootstrap.config.PropertySourceLocator;
import org.springframework.cloud.bootstrap.support.OriginTrackedCompositePropertySource;
import org.springframework.cloud.config.client.ConfigClientProperties.Credentials;
import org.springframework.cloud.config.client.validation.InvalidApplicationNameException;
import org.springframework.cloud.config.environment.Environment;
import org.springframework.cloud.config.environment.PropertySource;
import org.springframework.core.annotation.Order;
@@ -52,6 +53,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.NAME_PLACEHOLDER;
import static org.springframework.cloud.config.client.ConfigClientProperties.STATE_HEADER;
import static org.springframework.cloud.config.client.ConfigClientProperties.TOKEN_HEADER;
@@ -77,6 +79,20 @@ public class ConfigServicePropertySourceLocator implements PropertySourceLocator
@Retryable(interceptor = "configServerRetryInterceptor")
public org.springframework.core.env.PropertySource<?> locate(org.springframework.core.env.Environment environment) {
ConfigClientProperties properties = this.defaultProperties.override(environment);
if (StringUtils.startsWithIgnoreCase(properties.getName(), "application-")) {
InvalidApplicationNameException exception = new InvalidApplicationNameException(
properties.getName());
if (properties.isFailFast()) {
throw exception;
}
else {
logger.warn(NAME_PLACEHOLDER + " resolved to " + properties.getName()
+ ", not going to load remote properties. Ensure application name doesn't start with 'application-'");
return null;
}
}
CompositePropertySource composite = new OriginTrackedCompositePropertySource("configService");
ConfigClientRequestTemplateFactory requestTemplateFactory = new ConfigClientRequestTemplateFactory(logger,
properties);

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2013-2019 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.config.client.diagnostics.analyzer;
import org.springframework.boot.diagnostics.AbstractFailureAnalyzer;
import org.springframework.boot.diagnostics.FailureAnalysis;
import org.springframework.cloud.config.client.validation.InvalidApplicationNameException;
/**
* An {@link AbstractFailureAnalyzer} that analyzes {@link InvalidApplicationNameException
* InvalidApplicationNameException}.
*
* @author Anshul Mehra
*/
public class InvalidApplicationNameExceptionFailureAnalyzer
extends AbstractFailureAnalyzer<InvalidApplicationNameException> {
@Override
protected FailureAnalysis analyze(Throwable rootFailure,
InvalidApplicationNameException cause) {
StringBuilder description = new StringBuilder(
String.format("%s:%n", cause.getMessage()));
description.append(String.format("%n Property: %s", cause.getProperty()));
description.append(String.format("%n Value: %s", cause.getValue()));
String action = "Change ${spring.application.name} or the ${spring.cloud.config.name} "
+ "override so that it does not begin with 'application-'.";
return new FailureAnalysis(description.toString(), action, cause);
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2013-2019 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.config.client.validation;
import static org.springframework.cloud.config.client.ConfigClientProperties.NAME_PLACEHOLDER;
/**
* A {@code InvalidApplicationNameException} is thrown when config client detects an
* invalid application name.
*
* @author Anshul Mehra
*/
public class InvalidApplicationNameException extends RuntimeException {
private final String property = NAME_PLACEHOLDER;
private final String value;
public InvalidApplicationNameException(String currentResolvedValue) {
super("Application name must not start with 'application-'");
this.value = currentResolvedValue;
}
public String getProperty() {
return this.property;
}
public String getValue() {
return this.value;
}
}

View File

@@ -24,3 +24,7 @@ org.springframework.cloud.config.client.ConfigServerConfigDataLoader
# Spring Boot BootstrapRegistryInitializers
org.springframework.boot.BootstrapRegistryInitializer=\
org.springframework.cloud.config.client.ConfigClientRetryBootstrapper
# Failure analyzers
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.cloud.config.client.diagnostics.analyzer.InvalidApplicationNameExceptionFailureAnalyzer

View File

@@ -16,15 +16,19 @@
package org.springframework.cloud.config.client;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.config.client.validation.InvalidApplicationNameException;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
public class ConfigClientAutoConfigurationTests {
@@ -47,4 +51,66 @@ public class ConfigClientAutoConfigurationTests {
context.close();
}
@Test
public void invalidApplicationNameOverrideWithFailFastEnabledFailsToStartup() {
SpringApplication application = new SpringApplicationBuilder(
ConfigClientAutoConfiguration.class)
.web(WebApplicationType.NONE)
.properties("spring.cloud.config.fail-fast=true",
"spring.cloud.bootstrap.enabled=true",
"spring.cloud.config.name=application-service")
.application();
assertThatThrownBy(application::run)
.isInstanceOf(InvalidApplicationNameException.class).extracting("value")
.isEqualTo("application-service");
}
@Test
public void invalidApplicationNameOverrideWithFailFastDisabledStartsUpButNoConfigServerPropertiesAreLoaded() {
SpringApplication application = new SpringApplicationBuilder(
ConfigClientAutoConfiguration.class).web(WebApplicationType.NONE)
.properties("spring.cloud.config.name=application-service",
"spring.cloud.bootstrap.enabled=true")
.application();
ConfigurableApplicationContext context = application.run();
assertThat(context.getEnvironment().getPropertySources().get("configService"))
.isNull();
context.close();
}
@Test
public void invalidApplicationNameWithFailFastEnabledFailsToStartup() {
SpringApplication application = new SpringApplicationBuilder(
ConfigClientAutoConfiguration.class)
.web(WebApplicationType.NONE)
.properties("spring.cloud.config.fail-fast=true",
"spring.cloud.bootstrap.enabled=true",
"spring.application.name=application-service")
.application();
assertThatThrownBy(application::run)
.isInstanceOf(InvalidApplicationNameException.class).extracting("value")
.isEqualTo("application-service");
}
@Test
public void invalidApplicationNameWithFailFastDisabledStartsUpButNoConfigServerPropertiesAreLoaded() {
SpringApplication application = new SpringApplicationBuilder(
ConfigClientAutoConfiguration.class).web(WebApplicationType.NONE)
.properties("spring.application.name=application-service",
"spring.cloud.bootstrap.enabled=true")
.application();
ConfigurableApplicationContext context = application.run();
assertThat(context.getEnvironment().getPropertySources().get("configService"))
.isNull();
context.close();
}
}