Forces environment controller to be backwards compatible.

Does this by adding produces application/json on backwards compatible
controller methods. Otherwise, old clients would get the new format.

fixes gh-1520
This commit is contained in:
Spencer Gibb
2019-12-11 18:25:57 -05:00
parent 0eedcb886e
commit 02d59362e6
10 changed files with 178 additions and 24 deletions

View File

@@ -102,7 +102,8 @@ public class EnvironmentController {
this.acceptEmpty = acceptEmpty;
}
@RequestMapping("/{name}/{profiles:.*[^-].*}")
@RequestMapping(path = "/{name}/{profiles:.*[^-].*}",
produces = MediaType.APPLICATION_JSON_VALUE)
public Environment defaultLabel(@PathVariable String name,
@PathVariable String profiles) {
return getEnvironment(name, profiles, null, false);
@@ -115,7 +116,8 @@ public class EnvironmentController {
return getEnvironment(name, profiles, null, true);
}
@RequestMapping("/{name}/{profiles}/{label:.*}")
@RequestMapping(path = "/{name}/{profiles}/{label:.*}",
produces = MediaType.APPLICATION_JSON_VALUE)
public Environment labelled(@PathVariable String name, @PathVariable String profiles,
@PathVariable String label) {
return getEnvironment(name, profiles, label, false);

View File

@@ -30,11 +30,14 @@ import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.cloud.config.environment.Environment;
import org.springframework.cloud.config.server.test.ConfigServerTestUtils;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.cloud.config.server.test.ConfigServerTestUtils.assertOriginTrackedValue;
import static org.springframework.cloud.config.server.test.ConfigServerTestUtils.getV2AcceptEntity;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ConfigServerApplication.class,
@@ -63,8 +66,10 @@ public class BootstrapConfigServerIntegrationTests {
@Test
public void contextLoads() {
Environment environment = new TestRestTemplate().getForObject(
"http://localhost:" + this.port + "/foo/development/", Environment.class);
ResponseEntity<Environment> response = new TestRestTemplate().exchange(
"http://localhost:" + this.port + "/foo/development/", HttpMethod.GET,
getV2AcceptEntity(), Environment.class);
Environment environment = response.getBody();
assertThat(environment.getPropertySources()).hasSize(2);
assertOriginTrackedValue(environment, 0, "bar", "foo");
assertOriginTrackedValue(environment, 1, "info.foo", "bar");

View File

@@ -27,11 +27,14 @@ import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.cloud.config.environment.Environment;
import org.springframework.cloud.config.server.test.ConfigServerTestUtils;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
import static org.springframework.cloud.config.server.test.ConfigServerTestUtils.getV2AcceptEntity;
/**
* @author Ryan Baxter
@@ -64,9 +67,10 @@ public class CompositeIntegrationTests {
@Test
public void contextLoads() {
Environment environment = new TestRestTemplate().getForObject(
"http://localhost:" + this.port + "/foo/development/",
Environment.class);
ResponseEntity<Environment> response = new TestRestTemplate().exchange(
"http://localhost:" + this.port + "/foo/development/", HttpMethod.GET,
getV2AcceptEntity(), Environment.class);
Environment environment = response.getBody();
assertThat(3).isEqualTo(environment.getPropertySources().size());
assertThat("overrides")
.isEqualTo(environment.getPropertySources().get(0).getName());
@@ -125,9 +129,10 @@ public class CompositeIntegrationTests {
@Test
public void contextLoads() {
Environment environment = new TestRestTemplate().getForObject(
"http://localhost:" + this.port + "/foo/development/",
Environment.class);
ResponseEntity<Environment> response = new TestRestTemplate().exchange(
"http://localhost:" + this.port + "/foo/development/", HttpMethod.GET,
getV2AcceptEntity(), Environment.class);
Environment environment = response.getBody();
assertThat(environment.getPropertySources()).hasSize(3);
assertThat("overrides")
.isEqualTo(environment.getPropertySources().get(0).getName());

View File

@@ -0,0 +1,114 @@
/*
* Copyright 2018-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.server;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import org.eclipse.jgit.junit.MockSystemReader;
import org.eclipse.jgit.util.SystemReader;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.cloud.config.server.test.ConfigServerTestUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
import static org.springframework.cloud.config.server.test.ConfigServerTestUtils.getV2AcceptEntity;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ConfigServerApplication.class,
properties = { "spring.config.name:configserver" }, webEnvironment = RANDOM_PORT)
@ActiveProfiles({ "test", "native" })
public class ConfigClientBackwardsCompatibilityIntegrationTests {
@LocalServerPort
private int port;
@Autowired
private ApplicationContext context;
@BeforeClass
public static void init() throws IOException {
// mock Git configuration to make tests independent of local Git configuration
SystemReader.setInstance(new MockSystemReader());
ConfigServerTestUtils.prepareLocalRepo();
}
@Test
public void testBackwardsCompatibleFormat() {
Map environment = new TestRestTemplate().getForObject(
"http://localhost:" + this.port + "/foo/development/", Map.class);
Object value = getPropertySourceValue(environment);
assertThat(value).isInstanceOf(String.class).isEqualTo("true");
}
@Test
public void testBackwardsCompatibleFormatWithLabel() {
Map environment = new TestRestTemplate().getForObject(
"http://localhost:" + this.port + "/foo/development/master", Map.class);
Object value = getPropertySourceValue(environment);
assertThat(value).isInstanceOf(String.class).isEqualTo("true");
}
@Test
public void testNewFormat() {
ResponseEntity<Map> response = new TestRestTemplate().exchange(
"http://localhost:" + this.port + "/foo/development/", HttpMethod.GET,
getV2AcceptEntity(), Map.class);
Object value = getPropertySourceValue(response.getBody());
assertThat(value).isInstanceOf(Map.class);
Map valueMap = Map.class.cast(value);
assertThat(valueMap).containsEntry("value", "true");
}
@Test
public void testNewFormatWithLabel() {
ResponseEntity<Map> response = new TestRestTemplate().exchange(
"http://localhost:" + this.port + "/foo/development/master",
HttpMethod.GET, getV2AcceptEntity(), Map.class);
Object value = getPropertySourceValue(response.getBody());
assertThat(value).isInstanceOf(Map.class);
Map valueMap = Map.class.cast(value);
assertThat(valueMap).containsEntry("value", "true");
}
private Object getPropertySourceValue(Map environment) {
assertThat(environment).isNotNull();
assertThat(environment.containsKey("propertySources"));
List propertySources = (List) environment.get("propertySources");
assertThat(propertySources).hasSizeGreaterThan(1);
Map source = (Map) propertySources.get(0);
assertThat(source).containsKeys("source");
Map sourceValue = (Map) source.get("source");
assertThat(sourceValue).containsKeys("spring.cloud.config.enabled");
return sourceValue.get("spring.cloud.config.enabled");
}
}

View File

@@ -29,6 +29,7 @@ import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.cloud.config.environment.Environment;
import org.springframework.cloud.config.server.test.ConfigServerTestUtils;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.ActiveProfiles;
@@ -36,6 +37,7 @@ import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
import static org.springframework.cloud.config.server.test.ConfigServerTestUtils.getV2AcceptEntity;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ConfigServerApplication.class,
@@ -56,8 +58,10 @@ public class NativeConfigServerIntegrationTests {
@Test
public void contextLoads() {
Environment environment = new TestRestTemplate().getForObject(
"http://localhost:" + this.port + "/foo/development/", Environment.class);
ResponseEntity<Environment> response = new TestRestTemplate().exchange(
"http://localhost:" + this.port + "/foo/development/", HttpMethod.GET,
getV2AcceptEntity(), Environment.class);
Environment environment = response.getBody();
assertThat(environment.getPropertySources().isEmpty()).isFalse();
assertThat(environment.getPropertySources().get(0).getName())
.isEqualTo("overrides");

View File

@@ -41,6 +41,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.test.annotation.DirtiesContext;
@@ -52,6 +53,7 @@ import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.BDDMockito.given;
import static org.springframework.cloud.config.server.test.ConfigServerTestUtils.assertOriginTrackedValue;
import static org.springframework.cloud.config.server.test.ConfigServerTestUtils.getV2AcceptEntity;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestConfiguration.class,
@@ -91,8 +93,10 @@ public class RefreshableConfigServerIntegrationTests {
*/
@Test
public void refreshOverrides() {
Environment environment = new TestRestTemplate().getForObject(
"http://localhost:" + this.port + "/foo/development/", Environment.class);
ResponseEntity<Environment> entity = new TestRestTemplate().exchange(
"http://localhost:" + this.port + "/foo/development/", HttpMethod.GET,
getV2AcceptEntity(), Environment.class);
Environment environment = entity.getBody();
assertThat(environment.getPropertySources()).isEmpty();
String actuatorEndpoint = "http://localhost:" + this.port + "/actuator";
@@ -109,8 +113,10 @@ public class RefreshableConfigServerIntegrationTests {
null, Void.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
environment = new TestRestTemplate().getForObject(
"http://localhost:" + this.port + "/foo/development/", Environment.class);
entity = new TestRestTemplate().exchange(
"http://localhost:" + this.port + "/foo/development/", HttpMethod.GET,
getV2AcceptEntity(), Environment.class);
environment = entity.getBody();
assertThat(environment.getPropertySources()).isNotEmpty();
assertOriginTrackedValue(environment, 0, "foo", "bar");
}

View File

@@ -31,12 +31,15 @@ import org.springframework.cloud.config.environment.Environment;
import org.springframework.cloud.config.server.environment.SvnKitEnvironmentRepository;
import org.springframework.cloud.config.server.test.ConfigServerTestUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
import static org.springframework.cloud.config.server.test.ConfigServerTestUtils.REPO_PREFIX;
import static org.springframework.cloud.config.server.test.ConfigServerTestUtils.getV2AcceptEntity;
/**
* @author Michael Prankl
@@ -65,8 +68,10 @@ public class SubversionConfigServerIntegrationTests {
@Test
public void contextLoads() {
Environment environment = new TestRestTemplate().getForObject(
"http://localhost:" + this.port + "/foo/development/", Environment.class);
ResponseEntity<Environment> exchange = new TestRestTemplate().exchange(
"http://localhost:" + this.port + "/foo/development/", HttpMethod.GET,
getV2AcceptEntity(), Environment.class);
Environment environment = exchange.getBody();
assertThat(environment.getPropertySources().isEmpty()).isFalse();
assertThat(environment.getPropertySources().get(0).getName())
.isEqualTo("overrides");

View File

@@ -40,6 +40,7 @@ import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
import static org.springframework.cloud.config.server.test.ConfigServerTestUtils.getV2AcceptEntity;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ConfigServerApplication.class,
@@ -62,8 +63,10 @@ public class VanillaConfigServerIntegrationTests {
@Test
public void contextLoads() {
Environment environment = new TestRestTemplate().getForObject(
"http://localhost:" + this.port + "/foo/development/", Environment.class);
ResponseEntity<Environment> response = new TestRestTemplate().exchange(
"http://localhost:" + this.port + "/foo/development/", HttpMethod.GET,
getV2AcceptEntity(), Environment.class);
Environment environment = response.getBody();
assertThat(environment.getPropertySources().isEmpty()).isFalse();
assertThat(environment.getPropertySources().get(0).getName())
.isEqualTo("overrides");

View File

@@ -99,10 +99,11 @@ public class EncryptionIntegrationTests {
}
@RunWith(SpringRunner.class)
@SpringBootTest(classes = { ConfigServerApplication.class }, properties = {
"spring.cloud.bootstrap.name:keystore-bootstrap",
"spring.cloud.config.server.encrypt.enabled=false",
"encrypt.keyStore.alias=myencryptionkey" }, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@SpringBootTest(classes = { ConfigServerApplication.class },
properties = { "spring.cloud.bootstrap.name:keystore-bootstrap",
"spring.cloud.config.server.encrypt.enabled=false",
"encrypt.keyStore.alias=myencryptionkey" },
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles({ "test", "git" })
@DirtiesContext
public static class KeystoreConfigurationEncryptionOnlyIntegrationTests {

View File

@@ -26,7 +26,10 @@ import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.FileUtils;
import org.springframework.cloud.config.environment.Environment;
import org.springframework.cloud.config.environment.EnvironmentMediaType;
import org.springframework.cloud.config.environment.PropertySource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.util.FileSystemUtils;
import org.springframework.util.StringUtils;
@@ -163,4 +166,10 @@ public final class ConfigServerTestUtils {
assertThat(map).containsEntry("value", expectedValue);
}
public static HttpEntity getV2AcceptEntity() {
HttpHeaders headers = new HttpHeaders();
headers.set(HttpHeaders.ACCEPT, EnvironmentMediaType.V2_JSON);
return new HttpEntity(headers);
}
}