Merge branch 'master' into 2.0.x
# Conflicts: # docs/pom.xml # pom.xml # spring-cloud-config-client/pom.xml # spring-cloud-config-dependencies/pom.xml # spring-cloud-config-monitor/pom.xml # spring-cloud-config-sample/pom.xml # spring-cloud-config-server/pom.xml # spring-cloud-starter-config/pom.xml
This commit is contained in:
@@ -594,7 +594,7 @@ Properties written to `secret/application` are available to
|
||||
<<_vault_server,all applications using the Config Server>>. An
|
||||
application with the name `myApp` would have any properties
|
||||
written to `secret/myApp` and `secret/application` available to it.
|
||||
When `myApp` has the `dev` profile enabled than properties written to
|
||||
When `myApp` has the `dev` profile enabled then properties written to
|
||||
all of the above paths would be available to it, with properties in
|
||||
the first path in the list taking priority over the others.
|
||||
|
||||
@@ -680,7 +680,7 @@ using one of the environment repositories from Spring Cloud. To do this your be
|
||||
must implement the `EnvironmentRepository` interface. If you would like to control
|
||||
the priority of you custom `EnvironmentRepository` within the composite
|
||||
environment you should also implement the `Ordered` interface and override the
|
||||
`getOrdered` method. If you do not implement the `Ordered` interface than your
|
||||
`getOrdered` method. If you do not implement the `Ordered` interface then your
|
||||
`EnvironmentRepository` will be given the lowest priority.
|
||||
|
||||
==== Property Overrides
|
||||
|
||||
10
mvnw
vendored
10
mvnw
vendored
@@ -238,8 +238,16 @@ else
|
||||
echo $MAVEN_ARGS | grep -q milestone && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pmilestone//')
|
||||
fi
|
||||
|
||||
if echo $VERSION | egrep -q 'RELEASE'; then
|
||||
echo Activating \"central\" profile for version=\"$VERSION\"
|
||||
echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pcentral"
|
||||
else
|
||||
echo Deactivating \"central\" profile for version=\"$VERSION\"
|
||||
echo $MAVEN_ARGS | grep -q central && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pcentral//')
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" \
|
||||
$MAVEN_OPTS \
|
||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||
${WRAPPER_LAUNCHER} ${MAVEN_ARGS} "$@"
|
||||
${WRAPPER_LAUNCHER} ${MAVEN_ARGS} "$@"
|
||||
7
pom.xml
7
pom.xml
@@ -49,6 +49,13 @@
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-commons</artifactId>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
<version>${spring-cloud-commons.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
<profiles>
|
||||
|
||||
@@ -76,6 +76,12 @@
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-commons</artifactId>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -18,10 +18,13 @@ package org.springframework.cloud.config.client;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
@@ -95,6 +98,11 @@ public class ConfigClientProperties {
|
||||
*/
|
||||
private String authorization;
|
||||
|
||||
/**
|
||||
* Additional headers used to create the client request.
|
||||
*/
|
||||
private Map<String, String> headers = new HashMap<>();
|
||||
|
||||
private ConfigClientProperties() {
|
||||
}
|
||||
|
||||
@@ -190,6 +198,8 @@ public class ConfigClientProperties {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
@DeprecatedConfigurationProperty(reason = "replaced by headers", replacement = "headers")
|
||||
@Deprecated
|
||||
public String getAuthorization() {
|
||||
return this.authorization;
|
||||
}
|
||||
@@ -198,6 +208,14 @@ public class ConfigClientProperties {
|
||||
this.authorization = authorization;
|
||||
}
|
||||
|
||||
public Map<String, String> getHeaders() {
|
||||
return headers;
|
||||
}
|
||||
|
||||
public void setHeaders(Map<String, String> headers) {
|
||||
this.headers = headers;
|
||||
}
|
||||
|
||||
private Credentials extractCredentials() {
|
||||
Credentials result = new Credentials();
|
||||
String uri = this.uri;
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package org.springframework.cloud.config.client;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.retry.annotation.Retryable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ConfigServerInstanceProvider {
|
||||
|
||||
private static Log logger = LogFactory.getLog(ConfigServerInstanceProvider.class);
|
||||
private final DiscoveryClient client;
|
||||
|
||||
public ConfigServerInstanceProvider(DiscoveryClient client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@Retryable(interceptor = "configServerRetryInterceptor")
|
||||
public ServiceInstance getConfigServerInstance(String serviceId) {
|
||||
logger.debug("Locating configserver (" + serviceId + ") via discovery");
|
||||
List<ServiceInstance> instances = this.client.getInstances(serviceId);
|
||||
if (instances.isEmpty()) {
|
||||
throw new IllegalStateException(
|
||||
"No instances found of configserver (" + serviceId + ")");
|
||||
}
|
||||
ServiceInstance instance = instances.get(0);
|
||||
logger.debug(
|
||||
"Located configserver (" + serviceId + ") via discovery: " + instance);
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -52,6 +53,7 @@ import static org.springframework.cloud.config.client.ConfigClientProperties.TOK
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* @author Mathieu Ouellet
|
||||
*
|
||||
*/
|
||||
@Order(0)
|
||||
@@ -191,8 +193,10 @@ public class ConfigServicePropertySourceLocator implements PropertySourceLocator
|
||||
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
|
||||
requestFactory.setReadTimeout((60 * 1000 * 3) + 5000); //TODO 3m5s, make configurable?
|
||||
RestTemplate template = new RestTemplate(requestFactory);
|
||||
String username = client.getUsername();
|
||||
String password = client.getPassword();
|
||||
String authorization = client.getAuthorization();
|
||||
Map<String, String> headers = new HashMap<>(client.getHeaders());
|
||||
|
||||
if (password != null && authorization != null) {
|
||||
throw new IllegalStateException(
|
||||
@@ -200,53 +204,36 @@ public class ConfigServicePropertySourceLocator implements PropertySourceLocator
|
||||
}
|
||||
|
||||
if (password != null) {
|
||||
template.setInterceptors(Arrays.<ClientHttpRequestInterceptor> asList(
|
||||
new BasicAuthorizationInterceptor(client.getUsername(), password)));
|
||||
byte[] token = Base64Utils.encode((username + ":" + password).getBytes());
|
||||
headers.put("Authorization", "Basic " + new String(token));
|
||||
}
|
||||
else if (authorization != null) {
|
||||
headers.put("Authorization", authorization);
|
||||
}
|
||||
|
||||
if (!headers.isEmpty()) {
|
||||
template.setInterceptors(Arrays.<ClientHttpRequestInterceptor> asList(
|
||||
new GenericAuthorization(authorization)));
|
||||
new GenericRequestHeaderInterceptor(headers)));
|
||||
}
|
||||
|
||||
return template;
|
||||
}
|
||||
|
||||
private static class BasicAuthorizationInterceptor implements
|
||||
ClientHttpRequestInterceptor {
|
||||
public static class GenericRequestHeaderInterceptor
|
||||
implements ClientHttpRequestInterceptor {
|
||||
|
||||
private final String username;
|
||||
private final Map<String, String> headers;
|
||||
|
||||
private final String password;
|
||||
|
||||
public BasicAuthorizationInterceptor(String username, String password) {
|
||||
this.username = username;
|
||||
this.password = (password == null ? "" : password);
|
||||
public GenericRequestHeaderInterceptor(Map<String, String> headers) {
|
||||
this.headers = headers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientHttpResponse intercept(HttpRequest request, byte[] body,
|
||||
ClientHttpRequestExecution execution) throws IOException {
|
||||
byte[] token = Base64Utils.encode((this.username + ":" + this.password).getBytes());
|
||||
request.getHeaders().add("Authorization", "Basic " + new String(token));
|
||||
return execution.execute(request, body);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static class GenericAuthorization implements
|
||||
ClientHttpRequestInterceptor {
|
||||
|
||||
private final String authorizationToken;
|
||||
|
||||
public GenericAuthorization(String authorizationToken) {
|
||||
this.authorizationToken = (authorizationToken == null ? "" : authorizationToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
|
||||
throws IOException {
|
||||
request.getHeaders().add("Authorization", authorizationToken);
|
||||
for (Entry<String, String> header : headers.entrySet()) {
|
||||
request.getHeaders().add(header.getKey(), header.getValue());
|
||||
}
|
||||
return execution.execute(request, body);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.cloud.config.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -28,6 +26,7 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
|
||||
import org.springframework.cloud.client.discovery.event.HeartbeatMonitor;
|
||||
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
@@ -52,10 +51,16 @@ public class DiscoveryClientConfigServiceBootstrapConfiguration {
|
||||
private ConfigClientProperties config;
|
||||
|
||||
@Autowired
|
||||
private DiscoveryClient client;
|
||||
private ConfigServerInstanceProvider instanceProvider;
|
||||
|
||||
private HeartbeatMonitor monitor = new HeartbeatMonitor();
|
||||
|
||||
@Bean
|
||||
public ConfigServerInstanceProvider configServerInstanceProvider(
|
||||
DiscoveryClient discoveryClient) {
|
||||
return new ConfigServerInstanceProvider(discoveryClient);
|
||||
}
|
||||
|
||||
@EventListener(ContextRefreshedEvent.class)
|
||||
public void startup(ContextRefreshedEvent event) {
|
||||
refresh();
|
||||
@@ -70,14 +75,9 @@ public class DiscoveryClientConfigServiceBootstrapConfiguration {
|
||||
|
||||
private void refresh() {
|
||||
try {
|
||||
logger.debug("Locating configserver via discovery");
|
||||
String serviceId = this.config.getDiscovery().getServiceId();
|
||||
List<ServiceInstance> instances = this.client.getInstances(serviceId);
|
||||
if (instances.isEmpty()) {
|
||||
logger.warn("No instances found of configserver (" + serviceId + ")");
|
||||
return;
|
||||
}
|
||||
ServiceInstance server = instances.get(0);
|
||||
ServiceInstance server = this.instanceProvider
|
||||
.getConfigServerInstance(serviceId);
|
||||
String url = getHomePage(server);
|
||||
if (server.getMetadata().containsKey("password")) {
|
||||
String user = server.getMetadata().get("user");
|
||||
@@ -96,7 +96,12 @@ public class DiscoveryClientConfigServiceBootstrapConfiguration {
|
||||
this.config.setUri(url);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
logger.warn("Could not locate configserver via discovery", ex);
|
||||
if (config.isFailFast()) {
|
||||
throw ex;
|
||||
}
|
||||
else {
|
||||
logger.warn("Could not locate configserver via discovery", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
package org.springframework.cloud.config.client;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.test.util.EnvironmentTestUtils;
|
||||
import org.springframework.cloud.client.DefaultServiceInstance;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.springframework.cloud.config.client.ConfigClientProperties.Discovery.DEFAULT_CONFIG_SERVER;
|
||||
|
||||
public abstract class BaseDiscoveryClientConfigServiceBootstrapConfigurationTests {
|
||||
|
||||
@Rule
|
||||
public ExpectedException expectedException = ExpectedException.none();
|
||||
|
||||
protected AnnotationConfigApplicationContext context;
|
||||
|
||||
protected DiscoveryClient client = Mockito.mock(DiscoveryClient.class);
|
||||
|
||||
protected ServiceInstance info = new DefaultServiceInstance("app", "foo", 8877,
|
||||
false);
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
void givenDiscoveryClientReturnsNoInfo() {
|
||||
given(this.client.getInstances(DEFAULT_CONFIG_SERVER))
|
||||
.willReturn(Collections.<ServiceInstance> emptyList());
|
||||
}
|
||||
|
||||
void givenDiscoveryClientReturnsInfo() {
|
||||
given(this.client.getInstances(DEFAULT_CONFIG_SERVER))
|
||||
.willReturn(Arrays.asList(this.info));
|
||||
}
|
||||
|
||||
void givenDiscoveryClientReturnsInfoOnThirdTry() {
|
||||
given(this.client.getInstances(DEFAULT_CONFIG_SERVER))
|
||||
.willReturn(Collections.<ServiceInstance> emptyList())
|
||||
.willReturn(Collections.<ServiceInstance> emptyList())
|
||||
.willReturn(Arrays.asList(this.info));
|
||||
}
|
||||
|
||||
void expectNoInstancesOfConfigServerException() {
|
||||
expectedException.expect(IllegalStateException.class);
|
||||
expectedException.expectMessage(
|
||||
"No instances found of configserver (" + DEFAULT_CONFIG_SERVER + ")");
|
||||
}
|
||||
|
||||
void expectDiscoveryClientConfigServiceBootstrapConfigurationIsSetup() {
|
||||
assertEquals(1, this.context.getBeanNamesForType(
|
||||
DiscoveryClientConfigServiceBootstrapConfiguration.class).length);
|
||||
}
|
||||
|
||||
void expectConfigClientPropertiesHasDefaultConfiguration() {
|
||||
expectConfigClientPropertiesHasConfiguration("http://localhost:8888");
|
||||
}
|
||||
|
||||
void expectConfigClientPropertiesHasConfigurationFromEureka() {
|
||||
expectConfigClientPropertiesHasConfiguration("http://foo:8877/");
|
||||
}
|
||||
|
||||
void expectConfigClientPropertiesHasConfiguration(final String expectedUri) {
|
||||
ConfigClientProperties properties = this.context
|
||||
.getBean(ConfigClientProperties.class);
|
||||
assertEquals(expectedUri, properties.getRawUri());
|
||||
}
|
||||
|
||||
void verifyDiscoveryClientCalledThreeTimes() {
|
||||
verify(this.client, times(3)).getInstances(DEFAULT_CONFIG_SERVER);
|
||||
}
|
||||
|
||||
void verifyDiscoveryClientCalledOnce() {
|
||||
verify(this.client).getInstances(DEFAULT_CONFIG_SERVER);
|
||||
}
|
||||
|
||||
void setup(String... env) {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
EnvironmentTestUtils.addEnvironment(this.context, env);
|
||||
EnvironmentTestUtils.addEnvironment(this.context, "eureka.client.enabled=false");
|
||||
this.context.getDefaultListableBeanFactory().registerSingleton("discoveryClient",
|
||||
this.client);
|
||||
this.context.register(UtilAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class,
|
||||
DiscoveryClientConfigServiceBootstrapConfiguration.class,
|
||||
ConfigServiceBootstrapConfiguration.class, ConfigClientProperties.class);
|
||||
this.context.refresh();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
package org.springframework.cloud.config.client;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.net.URI;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.hamcrest.core.IsInstanceOf;
|
||||
import org.hamcrest.core.IsNull;
|
||||
@@ -24,8 +27,11 @@ import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.client.ClientHttpRequest;
|
||||
import org.springframework.http.client.ClientHttpRequestExecution;
|
||||
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.mock.http.client.MockClientHttpRequest;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.web.client.HttpServerErrorException;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@@ -103,7 +109,7 @@ public class ConfigServicePropertySourceLocatorTests {
|
||||
this.expected.expectCause(IsInstanceOf
|
||||
.<Throwable> instanceOf(HttpServerErrorException.class));
|
||||
this.expected.expectMessage("fail fast property is set");
|
||||
assertNull(this.locator.locate(this.environment));
|
||||
this.locator.locate(this.environment);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -131,7 +137,85 @@ public class ConfigServicePropertySourceLocatorTests {
|
||||
this.locator.setRestTemplate(restTemplate);
|
||||
this.expected.expectCause(IsNull.nullValue(Throwable.class));
|
||||
this.expected.expectMessage("fail fast property is set");
|
||||
assertNull(this.locator.locate(this.environment));
|
||||
this.locator.locate(this.environment);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failFastWhenBothPasswordAndAuthorizationPropertiesSet() throws Exception {
|
||||
ClientHttpRequestFactory requestFactory = Mockito
|
||||
.mock(ClientHttpRequestFactory.class);
|
||||
ClientHttpRequest request = Mockito.mock(ClientHttpRequest.class);
|
||||
Mockito.when(
|
||||
requestFactory.createRequest(Mockito.any(URI.class),
|
||||
Mockito.any(HttpMethod.class))).thenReturn(request);
|
||||
ConfigClientProperties defaults = new ConfigClientProperties(this.environment);
|
||||
defaults.setFailFast(true);
|
||||
defaults.setUsername("username");
|
||||
defaults.setPassword("password");
|
||||
defaults.setAuthorization("Basic dXNlcm5hbWU6cGFzc3dvcmQNCg==");
|
||||
this.locator = new ConfigServicePropertySourceLocator(defaults);
|
||||
this.expected.expect(IllegalStateException.class);
|
||||
this.expected.expectMessage("You must set either 'password' or 'authorization'");
|
||||
this.locator.locate(this.environment);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void interceptorShouldAddHeaderWhenPasswordPropertySet() throws Exception {
|
||||
ClientHttpRequestFactory requestFactory = Mockito
|
||||
.mock(ClientHttpRequestFactory.class);
|
||||
ClientHttpRequest request = Mockito.mock(ClientHttpRequest.class);
|
||||
Mockito.when(requestFactory.createRequest(Mockito.any(URI.class),
|
||||
Mockito.any(HttpMethod.class))).thenReturn(request);
|
||||
|
||||
ConfigClientProperties defaults = new ConfigClientProperties(this.environment);
|
||||
defaults.setUsername("username");
|
||||
defaults.setPassword("password");
|
||||
this.locator = new ConfigServicePropertySourceLocator(defaults);
|
||||
|
||||
RestTemplate restTemplate = ReflectionTestUtils.invokeMethod(this.locator,
|
||||
"getSecureRestTemplate", defaults);
|
||||
restTemplate.setRequestFactory(requestFactory);
|
||||
|
||||
this.locator.setRestTemplate(restTemplate);
|
||||
this.locator.locate(this.environment);
|
||||
|
||||
assertThat(restTemplate.getInterceptors()).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void interceptorShouldAddHeaderWhenAuthorizationPropertySet() throws Exception {
|
||||
ClientHttpRequestFactory requestFactory = Mockito
|
||||
.mock(ClientHttpRequestFactory.class);
|
||||
ClientHttpRequest request = Mockito.mock(ClientHttpRequest.class);
|
||||
Mockito.when(requestFactory.createRequest(Mockito.any(URI.class),
|
||||
Mockito.any(HttpMethod.class))).thenReturn(request);
|
||||
|
||||
ConfigClientProperties defaults = new ConfigClientProperties(this.environment);
|
||||
defaults.setAuthorization("Basic dXNlcm5hbWU6cGFzc3dvcmQ=");
|
||||
this.locator = new ConfigServicePropertySourceLocator(defaults);
|
||||
|
||||
RestTemplate restTemplate = ReflectionTestUtils.invokeMethod(this.locator,
|
||||
"getSecureRestTemplate", defaults);
|
||||
restTemplate.setRequestFactory(requestFactory);
|
||||
|
||||
this.locator.setRestTemplate(restTemplate);
|
||||
this.locator.locate(this.environment);
|
||||
|
||||
assertThat(restTemplate.getInterceptors()).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void interceptorShouldAddHeadersWhenHeadersPropertySet() throws Exception {
|
||||
MockClientHttpRequest request = new MockClientHttpRequest();
|
||||
ClientHttpRequestExecution execution = Mockito
|
||||
.mock(ClientHttpRequestExecution.class);
|
||||
byte[] body = new byte[] {};
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put("X-Example-Version", "2.1");
|
||||
new ConfigServicePropertySourceLocator.GenericRequestHeaderInterceptor(headers)
|
||||
.intercept(request, body, execution);
|
||||
Mockito.verify(execution).execute(request, body);
|
||||
assertThat(request.getHeaders().getFirst("X-Example-Version")).isEqualTo("2.1");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package org.springframework.cloud.config.client;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.cloud.ClassPathExclusions;
|
||||
import org.springframework.cloud.FilteredClassPathRunner;
|
||||
|
||||
@RunWith(FilteredClassPathRunner.class)
|
||||
@ClassPathExclusions({ "spring-retry-*.jar", "spring-boot-starter-aop-*.jar" })
|
||||
public class DiscoveryClientConfigServiceBootstrapConfigurationNoSpringRetryTests
|
||||
extends BaseDiscoveryClientConfigServiceBootstrapConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void shouldFailWithExceptionGetConfigServerInstanceFromDiscoveryClient()
|
||||
throws Exception {
|
||||
givenDiscoveryClientReturnsNoInfo();
|
||||
|
||||
expectNoInstancesOfConfigServerException();
|
||||
|
||||
setup("spring.cloud.config.discovery.enabled=true",
|
||||
"spring.cloud.config.failFast=true");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFailWithMessageGetConfigServerInstanceFromDiscoveryClient()
|
||||
throws Exception {
|
||||
givenDiscoveryClientReturnsNoInfo();
|
||||
|
||||
setup("spring.cloud.config.discovery.enabled=true",
|
||||
"spring.cloud.config.failFast=false");
|
||||
|
||||
expectDiscoveryClientConfigServiceBootstrapConfigurationIsSetup();
|
||||
expectConfigClientPropertiesHasDefaultConfiguration();
|
||||
verifyDiscoveryClientCalledOnce();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldSucceedGetConfigServerInstanceFromDiscoveryClient()
|
||||
throws Exception {
|
||||
givenDiscoveryClientReturnsInfo();
|
||||
|
||||
setup("spring.cloud.config.discovery.enabled=true",
|
||||
"spring.cloud.config.failFast=true");
|
||||
|
||||
expectDiscoveryClientConfigServiceBootstrapConfigurationIsSetup();
|
||||
expectConfigClientPropertiesHasConfigurationFromEureka();
|
||||
verifyDiscoveryClientCalledOnce();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,46 +16,24 @@
|
||||
|
||||
package org.springframework.cloud.config.client;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.springframework.cloud.config.client.ConfigClientProperties.Discovery.DEFAULT_CONFIG_SERVER;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.test.util.EnvironmentTestUtils;
|
||||
import org.springframework.cloud.client.DefaultServiceInstance;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
|
||||
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class DiscoveryClientConfigServiceBootstrapConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
private DiscoveryClient client = Mockito.mock(DiscoveryClient.class);
|
||||
|
||||
private ServiceInstance info = new DefaultServiceInstance("app", "foo", 8877, false);
|
||||
|
||||
@After
|
||||
public void close() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
public class DiscoveryClientConfigServiceBootstrapConfigurationTests extends BaseDiscoveryClientConfigServiceBootstrapConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void offByDefault() throws Exception {
|
||||
this.context = new AnnotationConfigApplicationContext(
|
||||
DiscoveryClientConfigServiceBootstrapConfiguration.class);
|
||||
|
||||
assertEquals(0, this.context.getBeanNamesForType(DiscoveryClient.class).length);
|
||||
assertEquals(0, this.context.getBeanNamesForType(
|
||||
DiscoveryClientConfigServiceBootstrapConfiguration.class).length);
|
||||
@@ -63,51 +41,49 @@ public class DiscoveryClientConfigServiceBootstrapConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void onWhenRequested() throws Exception {
|
||||
given(this.client.getInstances(DEFAULT_CONFIG_SERVER))
|
||||
.willReturn(Arrays.asList(this.info));
|
||||
givenDiscoveryClientReturnsInfo();
|
||||
|
||||
setup("spring.cloud.config.discovery.enabled=true");
|
||||
assertEquals(1, this.context.getBeanNamesForType(
|
||||
DiscoveryClientConfigServiceBootstrapConfiguration.class).length);
|
||||
Mockito.verify(this.client).getInstances(DEFAULT_CONFIG_SERVER);
|
||||
ConfigClientProperties locator = this.context
|
||||
.getBean(ConfigClientProperties.class);
|
||||
assertEquals("http://foo:8877/", locator.getRawUri());
|
||||
|
||||
expectDiscoveryClientConfigServiceBootstrapConfigurationIsSetup();
|
||||
verifyDiscoveryClientCalledOnce();
|
||||
expectConfigClientPropertiesHasConfigurationFromEureka();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onWhenHeartbeat() throws Exception {
|
||||
setup("spring.cloud.config.discovery.enabled=true");
|
||||
assertEquals(1, this.context.getBeanNamesForType(
|
||||
DiscoveryClientConfigServiceBootstrapConfiguration.class).length);
|
||||
given(this.client.getInstances(DEFAULT_CONFIG_SERVER))
|
||||
.willReturn(Arrays.asList(this.info));
|
||||
Mockito.verify(this.client).getInstances(DEFAULT_CONFIG_SERVER);
|
||||
|
||||
expectDiscoveryClientConfigServiceBootstrapConfigurationIsSetup();
|
||||
|
||||
givenDiscoveryClientReturnsInfo();
|
||||
verifyDiscoveryClientCalledOnce();
|
||||
|
||||
context.publishEvent(new HeartbeatEvent(context, "new"));
|
||||
ConfigClientProperties locator = this.context
|
||||
.getBean(ConfigClientProperties.class);
|
||||
assertEquals("http://foo:8877/", locator.getRawUri());
|
||||
|
||||
expectConfigClientPropertiesHasConfigurationFromEureka();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void secureWhenRequested() throws Exception {
|
||||
this.info = new DefaultServiceInstance("app", "foo", 443, true);
|
||||
given(this.client.getInstances(DEFAULT_CONFIG_SERVER))
|
||||
.willReturn(Arrays.asList(this.info));
|
||||
givenDiscoveryClientReturnsInfo();
|
||||
|
||||
setup("spring.cloud.config.discovery.enabled=true");
|
||||
assertEquals(1, this.context.getBeanNamesForType(
|
||||
DiscoveryClientConfigServiceBootstrapConfiguration.class).length);
|
||||
Mockito.verify(this.client).getInstances(DEFAULT_CONFIG_SERVER);
|
||||
ConfigClientProperties locator = this.context
|
||||
.getBean(ConfigClientProperties.class);
|
||||
assertEquals("https://foo:443/", locator.getRawUri());
|
||||
|
||||
expectDiscoveryClientConfigServiceBootstrapConfigurationIsSetup();
|
||||
|
||||
verifyDiscoveryClientCalledOnce();
|
||||
expectConfigClientPropertiesHasConfiguration("https://foo:443/");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setsPasssword() throws Exception {
|
||||
this.info.getMetadata().put("password", "bar");
|
||||
given(this.client.getInstances(DEFAULT_CONFIG_SERVER))
|
||||
.willReturn(Arrays.asList(this.info));
|
||||
givenDiscoveryClientReturnsInfo();
|
||||
|
||||
setup("spring.cloud.config.discovery.enabled=true");
|
||||
|
||||
ConfigClientProperties locator = this.context
|
||||
.getBean(ConfigClientProperties.class);
|
||||
assertEquals("http://foo:8877/", locator.getRawUri());
|
||||
@@ -118,25 +94,80 @@ public class DiscoveryClientConfigServiceBootstrapConfigurationTests {
|
||||
@Test
|
||||
public void setsPath() throws Exception {
|
||||
this.info.getMetadata().put("configPath", "/bar");
|
||||
given(this.client.getInstances(DEFAULT_CONFIG_SERVER))
|
||||
.willReturn(Arrays.asList(this.info));
|
||||
givenDiscoveryClientReturnsInfo();
|
||||
|
||||
setup("spring.cloud.config.discovery.enabled=true");
|
||||
ConfigClientProperties locator = this.context
|
||||
.getBean(ConfigClientProperties.class);
|
||||
assertEquals("http://foo:8877/bar", locator.getRawUri());
|
||||
|
||||
expectConfigClientPropertiesHasConfiguration("http://foo:8877/bar");
|
||||
}
|
||||
|
||||
private void setup(String... env) {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
EnvironmentTestUtils.addEnvironment(this.context, env);
|
||||
EnvironmentTestUtils.addEnvironment(this.context, "eureka.client.enabled=false");
|
||||
this.context.getDefaultListableBeanFactory().registerSingleton("discoveryClient",
|
||||
this.client);
|
||||
this.context.register(UtilAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class,
|
||||
DiscoveryClientConfigServiceBootstrapConfiguration.class,
|
||||
ConfigClientProperties.class);
|
||||
this.context.refresh();
|
||||
@Test
|
||||
public void shouldFailGetConfigServerInstanceFromDiscoveryClient() throws Exception {
|
||||
givenDiscoveryClientReturnsNoInfo();
|
||||
|
||||
setup("spring.cloud.config.discovery.enabled=true");
|
||||
|
||||
expectDiscoveryClientConfigServiceBootstrapConfigurationIsSetup();
|
||||
verifyDiscoveryClientCalledOnce();
|
||||
expectConfigClientPropertiesHasDefaultConfiguration();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRetryAndSucceedGetConfigServerInstanceFromDiscoveryClient()
|
||||
throws Exception {
|
||||
givenDiscoveryClientReturnsInfoOnThirdTry();
|
||||
|
||||
setup("spring.cloud.config.discovery.enabled=true",
|
||||
"spring.cloud.config.retry.maxAttempts=3",
|
||||
"spring.cloud.config.retry.initialInterval=10",
|
||||
"spring.cloud.config.failFast=true");
|
||||
|
||||
expectDiscoveryClientConfigServiceBootstrapConfigurationIsSetup();
|
||||
verifyDiscoveryClientCalledThreeTimes();
|
||||
|
||||
context.publishEvent(new HeartbeatEvent(context, "new"));
|
||||
|
||||
expectConfigClientPropertiesHasConfigurationFromEureka();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotRetryIfNotFailFastPropertySet() throws Exception {
|
||||
givenDiscoveryClientReturnsInfoOnThirdTry();
|
||||
|
||||
setup("spring.cloud.config.discovery.enabled=true",
|
||||
"spring.cloud.config.retry.maxAttempts=3",
|
||||
"spring.cloud.config.retry.initialInterval=10");
|
||||
|
||||
expectDiscoveryClientConfigServiceBootstrapConfigurationIsSetup();
|
||||
verifyDiscoveryClientCalledOnce();
|
||||
expectConfigClientPropertiesHasDefaultConfiguration();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRetryAndFailWithExceptionGetConfigServerInstanceFromDiscoveryClient()
|
||||
throws Exception {
|
||||
givenDiscoveryClientReturnsNoInfo();
|
||||
|
||||
expectNoInstancesOfConfigServerException();
|
||||
|
||||
setup("spring.cloud.config.discovery.enabled=true",
|
||||
"spring.cloud.config.retry.maxAttempts=3",
|
||||
"spring.cloud.config.retry.initialInterval=10",
|
||||
"spring.cloud.config.failFast=true");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRetryAndFailWithMessageGetConfigServerInstanceFromDiscoveryClient()
|
||||
throws Exception {
|
||||
givenDiscoveryClientReturnsNoInfo();
|
||||
|
||||
setup("spring.cloud.config.discovery.enabled=true",
|
||||
"spring.cloud.config.retry.maxAttempts=3",
|
||||
"spring.cloud.config.retry.initialInterval=10",
|
||||
"spring.cloud.config.failFast=false");
|
||||
|
||||
expectDiscoveryClientConfigServiceBootstrapConfigurationIsSetup();
|
||||
expectConfigClientPropertiesHasDefaultConfiguration();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<description>Spring Cloud Config Monitor</description>
|
||||
<properties>
|
||||
<main.basedir>${basedir}/../..</main.basedir>
|
||||
<spring-cloud-bus.version>1.3.0.BUILD-SNAPSHOT</spring-cloud-bus.version>
|
||||
<spring-cloud-bus.version>1.3.1.BUILD-SNAPSHOT</spring-cloud-bus.version>
|
||||
</properties>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
@@ -3,7 +3,8 @@ package sample;
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public class ApplicationFailFastTests {
|
||||
|
||||
|
||||
@@ -77,8 +77,13 @@ public class CipherEnvironmentEncryptor implements EnvironmentEncryptor {
|
||||
catch (Exception e) {
|
||||
value = "<n/a>";
|
||||
name = "invalid." + name;
|
||||
logger.warn("Cannot decrypt key: " + key + " (" + e.getClass()
|
||||
+ ": " + e.getMessage() + ")");
|
||||
String message = "Cannot decrypt key: " + key + " (" + e.getClass()
|
||||
+ ": " + e.getMessage() + ")";
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(message, e);
|
||||
} else if (logger.isWarnEnabled()) {
|
||||
logger.warn(message);
|
||||
}
|
||||
}
|
||||
map.put(name, value);
|
||||
}
|
||||
|
||||
@@ -125,19 +125,14 @@ public class EncryptionController {
|
||||
public String encrypt(@PathVariable String name, @PathVariable String profiles,
|
||||
@RequestBody String data, @RequestHeader("Content-Type") MediaType type) {
|
||||
checkEncryptorInstalled(name, profiles);
|
||||
try {
|
||||
String input = stripFormData(data, type, false);
|
||||
Map<String, String> keys = this.helper.getEncryptorKeys(name, profiles,
|
||||
input);
|
||||
String textToEncrypt = this.helper.stripPrefix(input);
|
||||
String encrypted = this.helper.addPrefix(keys,
|
||||
this.encryptor.locate(keys).encrypt(textToEncrypt));
|
||||
logger.info("Encrypted data");
|
||||
return encrypted;
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
throw new InvalidCipherException();
|
||||
}
|
||||
String input = stripFormData(data, type, false);
|
||||
Map<String, String> keys = this.helper.getEncryptorKeys(name, profiles,
|
||||
input);
|
||||
String textToEncrypt = this.helper.stripPrefix(input);
|
||||
String encrypted = this.helper.addPrefix(keys,
|
||||
this.encryptor.locate(keys).encrypt(textToEncrypt));
|
||||
logger.info("Encrypted data");
|
||||
return encrypted;
|
||||
}
|
||||
|
||||
@RequestMapping(value = "decrypt", method = RequestMethod.POST)
|
||||
@@ -161,7 +156,8 @@ public class EncryptionController {
|
||||
logger.info("Decrypted cipher data");
|
||||
return decrypted;
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
catch (IllegalArgumentException|IllegalStateException e) {
|
||||
logger.error("Cannot decrypt key:" + name + ", value:" + data, e);
|
||||
throw new InvalidCipherException();
|
||||
}
|
||||
}
|
||||
@@ -241,4 +237,4 @@ class KeyNotAvailableException extends RuntimeException {
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
class InvalidCipherException extends RuntimeException {
|
||||
}
|
||||
}
|
||||
@@ -170,7 +170,7 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
|
||||
/**
|
||||
* Get the working directory ready.
|
||||
*/
|
||||
private String refresh(String label) {
|
||||
public String refresh(String label) {
|
||||
initialize();
|
||||
Git git = null;
|
||||
try {
|
||||
@@ -197,7 +197,7 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
|
||||
return git.getRepository().getRef("HEAD").getObjectId().getName();
|
||||
}
|
||||
catch (RefNotFoundException e) {
|
||||
throw new NoSuchLabelException("No such label: " + label);
|
||||
throw new NoSuchLabelException("No such label: " + label, e);
|
||||
}
|
||||
catch (GitAPIException e) {
|
||||
throw new IllegalStateException("Cannot clone or checkout repository", e);
|
||||
@@ -302,14 +302,15 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
|
||||
setCredentialsProvider(fetch);
|
||||
FetchResult result = fetch.call();
|
||||
if(result.getTrackingRefUpdates() != null && result.getTrackingRefUpdates().size() > 0) {
|
||||
this.logger.info("Fetched for remote " + label + " and found " + result.getTrackingRefUpdates().size()
|
||||
logger.info("Fetched for remote " + label + " and found " + result.getTrackingRefUpdates().size()
|
||||
+ " updates");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
this.logger.warn("Could not fetch remote for " + label + " remote: " + git
|
||||
.getRepository().getConfig().getString("remote", "origin", "url"));
|
||||
String message = "Could not fetch remote for " + label + " remote: " + git
|
||||
.getRepository().getConfig().getString("remote", "origin", "url");
|
||||
warn(message, ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -325,8 +326,9 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
this.logger.warn("Could not merge remote for " + label + " remote: " + git
|
||||
.getRepository().getConfig().getString("remote", "origin", "url"));
|
||||
String message = "Could not merge remote for " + label + " remote: " + git
|
||||
.getRepository().getConfig().getString("remote", "origin", "url");
|
||||
warn(message, ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -343,9 +345,10 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
|
||||
return resetRef;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
this.logger.warn("Could not reset to remote for " + label + " (current ref="
|
||||
String message = "Could not reset to remote for " + label + " (current ref="
|
||||
+ ref + "), remote: " + git.getRepository().getConfig()
|
||||
.getString("remote", "origin", "url"));
|
||||
.getString("remote", "origin", "url");
|
||||
warn(message, ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -449,10 +452,9 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
|
||||
return status.call().isClean();
|
||||
}
|
||||
catch (Exception e) {
|
||||
this.logger
|
||||
.warn("Could not execute status command on local repository. Cause: ("
|
||||
+ e.getClass().getSimpleName() + ") " + e.getMessage());
|
||||
|
||||
String message = "Could not execute status command on local repository. Cause: ("
|
||||
+ e.getClass().getSimpleName() + ") " + e.getMessage();
|
||||
warn(message, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -486,6 +488,13 @@ public class JGitEnvironmentRepository extends AbstractScmEnvironmentRepository
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void warn(String message, Exception ex) {
|
||||
logger.warn(message);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Stacktrace for: " + message, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the static method calls to {@link org.eclipse.jgit.api.Git} and
|
||||
* {@link org.eclipse.jgit.api.CloneCommand} allowing for easier unit testing.
|
||||
|
||||
@@ -119,7 +119,7 @@ public class MultipleJGitEnvironmentRepository extends JGitEnvironmentRepository
|
||||
if (logger.isDebugEnabled()) {
|
||||
this.logger.debug("Cannot retrieve resource locations from "
|
||||
+ candidate.getUri() + ", cause: ("
|
||||
+ e.getClass().getSimpleName() + ") " + e.getMessage());
|
||||
+ e.getClass().getSimpleName() + ") " + e.getMessage(), e);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -154,7 +154,7 @@ public class MultipleJGitEnvironmentRepository extends JGitEnvironmentRepository
|
||||
if (logger.isDebugEnabled()) {
|
||||
this.logger.debug("Cannot load configuration from "
|
||||
+ candidate.getUri() + ", cause: ("
|
||||
+ e.getClass().getSimpleName() + ") " + e.getMessage());
|
||||
+ e.getClass().getSimpleName() + ") " + e.getMessage(), e);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -27,4 +27,8 @@ public class NoSuchLabelException extends RepositoryException {
|
||||
super(string);
|
||||
}
|
||||
|
||||
public NoSuchLabelException(String string, Exception e) {
|
||||
super(string, e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,4 +27,8 @@ public class RepositoryException extends RuntimeException {
|
||||
super(string);
|
||||
}
|
||||
|
||||
public RepositoryException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -146,9 +146,13 @@ public class SvnKitEnvironmentRepository extends AbstractScmEnvironmentRepositor
|
||||
return version.toString();
|
||||
}
|
||||
catch (Exception e) {
|
||||
this.logger.warn("Could not update remote for " + label + " (current local="
|
||||
+ getWorkingDirectory().getPath() + "), remote: " + this.getUri()
|
||||
+ ")");
|
||||
String message = "Could not update remote for " + label + " (current local="
|
||||
+ getWorkingDirectory().getPath() + "), remote: " + this.getUri() + ")";
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(message, e);
|
||||
} else if (logger.isWarnEnabled()) {
|
||||
logger.warn(message);
|
||||
}
|
||||
}
|
||||
|
||||
final SVNStatus status = SVNClientManager.newInstance().getStatusClient()
|
||||
|
||||
@@ -128,7 +128,7 @@ public class VaultEnvironmentRepository implements EnvironmentRepository, Ordere
|
||||
private List<String> findKeys(String application, List<String> profiles) {
|
||||
List<String> keys = new ArrayList<>();
|
||||
|
||||
if (StringUtils.hasText(this.defaultKey)) {
|
||||
if (StringUtils.hasText(this.defaultKey) && !this.defaultKey.equals(application)) {
|
||||
keys.add(this.defaultKey);
|
||||
addProfiles(keys, this.defaultKey, profiles);
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@ import java.nio.charset.Charset;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.cloud.config.environment.Environment;
|
||||
import org.springframework.cloud.config.server.environment.EnvironmentRepository;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
@@ -35,6 +35,7 @@ import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.util.UrlPathHelper;
|
||||
@@ -68,10 +69,12 @@ public class ResourceController {
|
||||
}
|
||||
|
||||
@RequestMapping("/{name}/{profile}/{label}/**")
|
||||
public String resolve(@PathVariable String name, @PathVariable String profile,
|
||||
@PathVariable String label, HttpServletRequest request) throws IOException {
|
||||
public String retrieve(@PathVariable String name, @PathVariable String profile,
|
||||
@PathVariable String label, HttpServletRequest request,
|
||||
@RequestParam(defaultValue = "true") boolean resolvePlaceholders)
|
||||
throws IOException {
|
||||
String path = getFilePath(request, name, profile, label);
|
||||
return resolve(name, profile, label, path);
|
||||
return retrieve(name, profile, label, path, resolvePlaceholders);
|
||||
}
|
||||
|
||||
private String getFilePath(HttpServletRequest request, String name, String profile,
|
||||
@@ -82,21 +85,24 @@ public class ResourceController {
|
||||
return path;
|
||||
}
|
||||
|
||||
synchronized String resolve(String name, String profile, String label, String path)
|
||||
throws IOException {
|
||||
synchronized String retrieve(String name, String profile, String label, String path,
|
||||
boolean resolvePlaceholders) throws IOException {
|
||||
if (label != null && label.contains("(_)")) {
|
||||
// "(_)" is uncommon in a git branch name, but "/" cannot be matched
|
||||
// by Spring MVC
|
||||
label = label.replace("(_)", "/");
|
||||
}
|
||||
StandardEnvironment environment = prepareEnvironment(
|
||||
this.environmentRepository.findOne(name, profile, label));
|
||||
|
||||
// ensure InputStream will be closed to prevent file locks on Windows
|
||||
try (InputStream is = this.resourceRepository.findOne(name, profile, label, path)
|
||||
.getInputStream()) {
|
||||
String text = StreamUtils.copyToString(is, Charset.forName("UTF-8"));
|
||||
return resolvePlaceholders(environment, text);
|
||||
if (resolvePlaceholders) {
|
||||
Environment environment = this.environmentRepository.findOne(name,
|
||||
profile, label);
|
||||
text = resolvePlaceholders(prepareEnvironment(environment), text);
|
||||
}
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.cloud.config.server.credentials;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.eclipse.jgit.errors.UnsupportedCredentialItem;
|
||||
@@ -30,6 +28,13 @@ import org.springframework.cloud.config.server.support.GitCredentialsProviderFac
|
||||
|
||||
import com.amazonaws.auth.AWSCredentialsProvider;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* It would be nice to do an integration test, however, this would require
|
||||
* using real AWS credentials. How can we test the credential generation
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.cloud.config.server.credentials;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.eclipse.jgit.transport.CredentialsProvider;
|
||||
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
|
||||
import org.junit.Before;
|
||||
@@ -26,6 +24,12 @@ import org.springframework.cloud.config.server.support.AwsCodeCommitCredentialPr
|
||||
import org.springframework.cloud.config.server.support.GitCredentialsProviderFactory;
|
||||
import org.springframework.cloud.config.server.support.PassphraseCredentialsProvider;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author don laidlaw
|
||||
*
|
||||
|
||||
@@ -55,6 +55,21 @@ public class EncryptionControllerTests {
|
||||
this.controller.decrypt("foo", MediaType.TEXT_PLAIN);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidCipherException.class)
|
||||
public void shouldThrowExceptionOnDecryptInvalidData() {
|
||||
this.controller = new EncryptionController(
|
||||
new SingleTextEncryptorLocator(new RsaSecretEncryptor()));
|
||||
controller.decrypt("foo", MediaType.TEXT_PLAIN);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidCipherException.class)
|
||||
public void shouldThrowExceptionOnDecryptWrongKey() {
|
||||
RsaSecretEncryptor encryptor = new RsaSecretEncryptor();
|
||||
this.controller = new EncryptionController(
|
||||
new SingleTextEncryptorLocator(new RsaSecretEncryptor()));
|
||||
controller.decrypt(encryptor.encrypt("foo"), MediaType.TEXT_PLAIN);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sunnyDayRsaKey() {
|
||||
this.controller = new EncryptionController(
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.eclipse.jgit.api.CheckoutCommand;
|
||||
import org.eclipse.jgit.api.CloneCommand;
|
||||
import org.eclipse.jgit.api.FetchCommand;
|
||||
@@ -72,7 +73,9 @@ import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.mockingDetails;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
@@ -703,6 +706,27 @@ public class JGitEnvironmentRepositoryTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldPrintStacktraceIfDebugEnabled() throws Exception {
|
||||
final Log mockLogger = mock(Log.class);
|
||||
JGitEnvironmentRepository envRepository = new JGitEnvironmentRepository(this.environment){
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.logger = mockLogger;
|
||||
}
|
||||
};
|
||||
envRepository.afterPropertiesSet();
|
||||
when(mockLogger.isDebugEnabled()).thenReturn(true);
|
||||
|
||||
envRepository.warn("", new RuntimeException());
|
||||
|
||||
verify(mockLogger).warn(eq(""));
|
||||
verify(mockLogger).debug(eq("Stacktrace for: "), any(RuntimeException.class));
|
||||
|
||||
int numberOfInvocations = mockingDetails(mockLogger).getInvocations().size();
|
||||
assertEquals("should call isDebugEnabled warn and debug", 3, numberOfInvocations);
|
||||
}
|
||||
|
||||
class MockCloneCommand extends CloneCommand {
|
||||
private Git mockGit;
|
||||
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
package org.springframework.cloud.config.server.environment;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
@@ -17,6 +14,8 @@ import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* @author Ryan Baxter
|
||||
@@ -27,10 +26,11 @@ public class VaultEnvironmentRepositoryTests {
|
||||
public void init() {}
|
||||
|
||||
@Test
|
||||
public void testFindOne() throws IOException {
|
||||
public void testFindOneNoDefaultKey() throws IOException {
|
||||
MockHttpServletRequest configRequest = new MockHttpServletRequest();
|
||||
configRequest.addHeader("X-CONFIG-TOKEN", "mytoken");
|
||||
RestTemplate rest = Mockito.mock(RestTemplate.class);
|
||||
|
||||
ResponseEntity<VaultEnvironmentRepository.VaultResponse> myAppResp = Mockito.mock(ResponseEntity.class);
|
||||
Mockito.when(myAppResp.getStatusCode()).thenReturn(HttpStatus.OK);
|
||||
VaultEnvironmentRepository.VaultResponse myAppVaultResp = Mockito.mock(VaultEnvironmentRepository.VaultResponse.class);
|
||||
@@ -39,20 +39,104 @@ public class VaultEnvironmentRepositoryTests {
|
||||
Mockito.when(rest.exchange(Mockito.eq("http://127.0.0.1:8200/v1/{backend}/{key}"),
|
||||
Mockito.eq(HttpMethod.GET), Mockito.any(HttpEntity.class), Mockito.eq(VaultEnvironmentRepository.VaultResponse.class),
|
||||
Mockito.eq("secret"), Mockito.eq("myapp"))).thenReturn(myAppResp);
|
||||
|
||||
ResponseEntity<VaultEnvironmentRepository.VaultResponse> appResp = Mockito.mock(ResponseEntity.class);
|
||||
Mockito.when(appResp.getStatusCode()).thenReturn(HttpStatus.OK);
|
||||
VaultEnvironmentRepository.VaultResponse appVaultResp = Mockito.mock(VaultEnvironmentRepository.VaultResponse.class);
|
||||
Mockito.when(appVaultResp.getData()).thenReturn(null);
|
||||
Mockito.when(appVaultResp.getData()).thenReturn("{\"def-foo\":\"def-bar\"}");
|
||||
Mockito.when(appResp.getBody()).thenReturn(appVaultResp);
|
||||
Mockito.when(rest.exchange(Mockito.eq("http://127.0.0.1:8200/v1/{backend}/{key}"),
|
||||
Mockito.eq(HttpMethod.GET), Mockito.any(HttpEntity.class), Mockito.eq(VaultEnvironmentRepository.VaultResponse.class),
|
||||
Mockito.eq("secret"), Mockito.eq("application"))).thenReturn(appResp);
|
||||
|
||||
VaultEnvironmentRepository repo = new VaultEnvironmentRepository(configRequest, new EnvironmentWatch.Default(), rest);
|
||||
|
||||
Environment e = repo.findOne("myapp", null, null);
|
||||
assertEquals("myapp", e.getName());
|
||||
Map<String,String> result = new HashMap<String,String>();
|
||||
assertEquals("Name should be the same as the application argument", "myapp", e.getName());
|
||||
assertEquals("Properties for specified application and default application with key 'application' should be returned", 2, e.getPropertySources().size());
|
||||
Map<String, String> firstResult = new HashMap<String, String>();
|
||||
firstResult.put("foo", "bar");
|
||||
assertEquals("Properties for specified application should be returned in priority position", firstResult, e.getPropertySources().get(0).getSource());
|
||||
|
||||
Map<String, String> secondResult = new HashMap<String, String>();
|
||||
secondResult.put("def-foo", "def-bar");
|
||||
assertEquals("Properties for default application with key 'application' should be returned in second position", secondResult, e.getPropertySources().get(1).getSource());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindOneDefaultKeySetAndDifferentToApplication() throws IOException {
|
||||
MockHttpServletRequest configRequest = new MockHttpServletRequest();
|
||||
configRequest.addHeader("X-CONFIG-TOKEN", "mytoken");
|
||||
RestTemplate rest = Mockito.mock(RestTemplate.class);
|
||||
|
||||
ResponseEntity<VaultEnvironmentRepository.VaultResponse> myAppResp = Mockito.mock(ResponseEntity.class);
|
||||
Mockito.when(myAppResp.getStatusCode()).thenReturn(HttpStatus.OK);
|
||||
VaultEnvironmentRepository.VaultResponse myAppVaultResp = Mockito.mock(VaultEnvironmentRepository.VaultResponse.class);
|
||||
Mockito.when(myAppVaultResp.getData()).thenReturn("{\"foo\":\"bar\"}");
|
||||
Mockito.when(myAppResp.getBody()).thenReturn(myAppVaultResp);
|
||||
Mockito.when(rest.exchange(Mockito.eq("http://127.0.0.1:8200/v1/{backend}/{key}"),
|
||||
Mockito.eq(HttpMethod.GET), Mockito.any(HttpEntity.class), Mockito.eq(VaultEnvironmentRepository.VaultResponse.class),
|
||||
Mockito.eq("secret"), Mockito.eq("myapp"))).thenReturn(myAppResp);
|
||||
|
||||
ResponseEntity<VaultEnvironmentRepository.VaultResponse> myDefaultKeyResp = Mockito.mock(ResponseEntity.class);
|
||||
Mockito.when(myDefaultKeyResp.getStatusCode()).thenReturn(HttpStatus.OK);
|
||||
VaultEnvironmentRepository.VaultResponse myDefaultKeyVaultResp = Mockito.mock(VaultEnvironmentRepository.VaultResponse.class);
|
||||
Mockito.when(myDefaultKeyVaultResp.getData()).thenReturn("{\"def-foo\":\"def-bar\"}");
|
||||
Mockito.when(myDefaultKeyResp.getBody()).thenReturn(myDefaultKeyVaultResp);
|
||||
Mockito.when(rest.exchange(Mockito.eq("http://127.0.0.1:8200/v1/{backend}/{key}"),
|
||||
Mockito.eq(HttpMethod.GET), Mockito.any(HttpEntity.class), Mockito.eq(VaultEnvironmentRepository.VaultResponse.class),
|
||||
Mockito.eq("secret"), Mockito.eq("mydefaultkey"))).thenReturn(myDefaultKeyResp);
|
||||
|
||||
VaultEnvironmentRepository repo = new VaultEnvironmentRepository(configRequest, new EnvironmentWatch.Default(), rest);
|
||||
repo.setDefaultKey("mydefaultkey");
|
||||
|
||||
Environment e = repo.findOne("myapp", null, null);
|
||||
assertEquals("Name should be the same as the application argument", "myapp", e.getName());
|
||||
assertEquals("Properties for specified application and default application with key 'mydefaultkey' should be returned", 2, e.getPropertySources().size());
|
||||
|
||||
Map<String, String> firstResult = new HashMap<String, String>();
|
||||
firstResult.put("foo", "bar");
|
||||
assertEquals("Properties for specified application should be returned in priority position", firstResult, e.getPropertySources().get(0).getSource());
|
||||
|
||||
Map<String, String> secondResult = new HashMap<String, String>();
|
||||
secondResult.put("def-foo", "def-bar");
|
||||
assertEquals("Properties for default application with key 'mydefaultkey' should be returned in second position", secondResult, e.getPropertySources().get(1).getSource());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindOneDefaultKeySetAndEqualToApplication() throws IOException {
|
||||
MockHttpServletRequest configRequest = new MockHttpServletRequest();
|
||||
configRequest.addHeader("X-CONFIG-TOKEN", "mytoken");
|
||||
RestTemplate rest = Mockito.mock(RestTemplate.class);
|
||||
|
||||
ResponseEntity<VaultEnvironmentRepository.VaultResponse> myAppResp = Mockito.mock(ResponseEntity.class);
|
||||
Mockito.when(myAppResp.getStatusCode()).thenReturn(HttpStatus.OK);
|
||||
VaultEnvironmentRepository.VaultResponse myAppVaultResp = Mockito.mock(VaultEnvironmentRepository.VaultResponse.class);
|
||||
Mockito.when(myAppVaultResp.getData()).thenReturn("{\"foo\":\"bar\"}");
|
||||
Mockito.when(myAppResp.getBody()).thenReturn(myAppVaultResp);
|
||||
Mockito.when(rest.exchange(Mockito.eq("http://127.0.0.1:8200/v1/{backend}/{key}"),
|
||||
Mockito.eq(HttpMethod.GET), Mockito.any(HttpEntity.class), Mockito.eq(VaultEnvironmentRepository.VaultResponse.class),
|
||||
Mockito.eq("secret"), Mockito.eq("myapp"))).thenReturn(myAppResp);
|
||||
|
||||
ResponseEntity<VaultEnvironmentRepository.VaultResponse> appResp = Mockito.mock(ResponseEntity.class);
|
||||
Mockito.when(appResp.getStatusCode()).thenReturn(HttpStatus.OK);
|
||||
VaultEnvironmentRepository.VaultResponse appVaultResp = Mockito.mock(VaultEnvironmentRepository.VaultResponse.class);
|
||||
Mockito.when(appVaultResp.getData()).thenReturn("{\"def-foo\":\"def-bar\"}");
|
||||
Mockito.when(appResp.getBody()).thenReturn(appVaultResp);
|
||||
Mockito.when(rest.exchange(Mockito.eq("http://127.0.0.1:8200/v1/{backend}/{key}"),
|
||||
Mockito.eq(HttpMethod.GET), Mockito.any(HttpEntity.class), Mockito.eq(VaultEnvironmentRepository.VaultResponse.class),
|
||||
Mockito.eq("secret"), Mockito.eq("application"))).thenReturn(appResp);
|
||||
|
||||
VaultEnvironmentRepository repo = new VaultEnvironmentRepository(configRequest, new EnvironmentWatch.Default(), rest);
|
||||
repo.setDefaultKey("myapp");
|
||||
|
||||
Environment e = repo.findOne("myapp", null, null);
|
||||
assertEquals("Name should be the same as the application argument", "myapp", e.getName());
|
||||
assertEquals("Only properties for specified application should be returned", 1, e.getPropertySources().size());
|
||||
|
||||
Map<String, String> result = new HashMap<String, String>();
|
||||
result.put("foo", "bar");
|
||||
assertEquals(result, e.getPropertySources().get(0).getSource());
|
||||
assertEquals("Properties should be returned for specified application", result, e.getPropertySources().get(0).getSource());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
|
||||
@@ -62,9 +62,16 @@ public class ResourceControllerTests {
|
||||
@Test
|
||||
public void templateReplacement() throws Exception {
|
||||
this.environmentRepository.setSearchLocations("classpath:/test");
|
||||
String resource = this.controller.resolve("foo", "bar", "dev", "template.json");
|
||||
String resource = this.controller.retrieve("foo", "bar", "dev", "template.json", true);
|
||||
assertTrue("Wrong content: " + resource, resource.matches("\\{\\s*\"foo\": \"dev_bar\"\\s*\\}"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void templateReplacementNotForResolvePlaceholdersFalse() throws Exception {
|
||||
this.environmentRepository.setSearchLocations("classpath:/test");
|
||||
String resource = this.controller.retrieve("foo", "bar", "dev", "template.json", false);
|
||||
assertTrue("Wrong content: " + resource, resource.matches("\\{\\s*\"foo\": \"\\$\\{foo\\}\"\\s*\\}"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void templateReplacementNotForBinary() throws Exception {
|
||||
@@ -76,21 +83,21 @@ public class ResourceControllerTests {
|
||||
@Test
|
||||
public void escapedPlaceholder() throws Exception {
|
||||
this.environmentRepository.setSearchLocations("classpath:/test");
|
||||
String resource = this.controller.resolve("foo", "bar", "dev", "placeholder.txt");
|
||||
String resource = this.controller.retrieve("foo", "bar", "dev", "placeholder.txt", true);
|
||||
assertEquals("foo: ${foo}", resource);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void labelWithSlash() throws Exception {
|
||||
this.environmentRepository.setSearchLocations("classpath:/test");
|
||||
String resource = this.controller.resolve("foo", "bar", "dev(_)spam", "foo.txt");
|
||||
String resource = this.controller.retrieve("foo", "bar", "dev(_)spam", "foo.txt", true);
|
||||
assertEquals("foo: dev_bar/spam", resource);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resourceWithSlash() throws Exception {
|
||||
this.environmentRepository.setSearchLocations("classpath:/test");
|
||||
String resource = this.controller.resolve("foo", "bar", "dev", "spam/foo.txt");
|
||||
String resource = this.controller.retrieve("foo", "bar", "dev", "spam/foo.txt", true);
|
||||
assertEquals("foo: dev_bar/spam", resource);
|
||||
}
|
||||
|
||||
@@ -99,7 +106,7 @@ public class ResourceControllerTests {
|
||||
this.environmentRepository.setSearchLocations("classpath:/test");
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setRequestURI("/foo/bar/dev/" + "spam/foo.txt");
|
||||
String resource = this.controller.resolve("foo", "bar", "dev", request);
|
||||
String resource = this.controller.retrieve("foo", "bar", "dev", request, true);
|
||||
assertEquals("foo: dev_bar/spam", resource);
|
||||
}
|
||||
|
||||
@@ -109,10 +116,33 @@ public class ResourceControllerTests {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setServletPath("/spring");
|
||||
request.setRequestURI("/foo/bar/dev/" + "spam/foo.txt");
|
||||
String resource = this.controller.resolve("foo", "bar", "dev", request);
|
||||
String resource = this.controller.retrieve("foo", "bar", "dev", request, true);
|
||||
assertEquals("foo: dev_bar/spam", resource);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void labelWithSlashForResolvePlaceholdersFalse() throws Exception {
|
||||
this.environmentRepository.setSearchLocations("classpath:/test");
|
||||
String resource = this.controller.retrieve("foo", "bar", "dev(_)spam", "foo.txt", false);
|
||||
assertEquals("foo: dev_bar/spam", resource);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resourceWithSlashForResolvePlaceholdersFalse() throws Exception {
|
||||
this.environmentRepository.setSearchLocations("classpath:/test");
|
||||
String resource = this.controller.retrieve("foo", "bar", "dev", "spam/foo.txt", false);
|
||||
assertEquals("foo: dev_bar/spam", resource);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resourceWithSlashForResolvePlaceholdersFalseRequest() throws Exception {
|
||||
this.environmentRepository.setSearchLocations("classpath:/test");
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.setRequestURI("/foo/bar/dev/" + "spam/foo.txt");
|
||||
String resource = this.controller.retrieve("foo", "bar", "dev", request, false);
|
||||
assertEquals("foo: dev_bar/spam", resource);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void labelWithSlashForBinary() throws Exception {
|
||||
this.environmentRepository.setSearchLocations("classpath:/test");
|
||||
|
||||
Reference in New Issue
Block a user