Support nested arrays when translating properties to map when generating yml or json

Fixes gh-518
This commit is contained in:
Ian Bondoc
2016-09-30 02:16:26 +13:00
committed by Dave Syer
parent a51412e629
commit 3bfdd4b61c
2 changed files with 328 additions and 144 deletions

View File

@@ -31,17 +31,12 @@ import java.util.TreeMap;
import javax.servlet.http.HttpServletResponse;
import org.springframework.boot.bind.PropertiesConfigurationFactory;
import org.springframework.cloud.config.environment.Environment;
import org.springframework.cloud.config.environment.PropertySource;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -62,14 +57,13 @@ import com.fasterxml.jackson.databind.ObjectMapper;
* @author Rafal Zukowski
* @author Ivan Corrales Solera
* @author Daniel Frey
* @author Ian Bondoc
*
*/
@RestController
@RequestMapping(method = RequestMethod.GET, path = "${spring.cloud.config.server.prefix:}")
public class EnvironmentController {
private static final String MAP_PREFIX = "map";
private EnvironmentRepository repository;
private ObjectMapper objectMapper;
@@ -152,7 +146,7 @@ public class EnvironmentController {
throws Exception {
validateProfiles(profiles);
Environment environment = labelled(name, profiles, label);
Map<String, Object> properties = convertToMap(environment, resolvePlaceholders);
Map<String, Object> properties = convertToMap(environment);
String json = this.objectMapper.writeValueAsString(properties);
if (resolvePlaceholders) {
json = resolvePlaceholders(prepareEnvironment(environment), json);
@@ -188,7 +182,7 @@ public class EnvironmentController {
throws Exception {
validateProfiles(profiles);
Environment environment = labelled(name, profiles, label);
Map<String, Object> result = convertToMap(environment, resolvePlaceholders);
Map<String, Object> result = convertToMap(environment);
if (this.stripDocument && result.size() == 1
&& result.keySet().iterator().next().equals("document")) {
Object value = result.get("document");
@@ -208,26 +202,25 @@ public class EnvironmentController {
return getSuccess(yaml);
}
private Map<String, Object> convertToMap(Environment input, boolean resolvePlaceholders) throws BindException {
Map<String, Object> target = new LinkedHashMap<>();
PropertiesConfigurationFactory<Map<String, Object>> factory = new PropertiesConfigurationFactory<>(
target);
if (!resolvePlaceholders) {
factory.setResolvePlaceholders(false);
/**
* Method {@code convertToMap} converts an {@code Environment} to a nested Map which represents a yml/json structure.
*
* @param input the environment to be converted
* @return the nested map containing the environment's properties
*/
private Map<String, Object> convertToMap(Environment input) {
// First use the current convertToProperties to get a flat Map from the environment
Map<String, Object> properties = convertToProperties(input);
// The root map which holds all the first level properties
Map<String, Object> rootMap = new LinkedHashMap<>();
for (Map.Entry<String, Object> entry : properties.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
PropertyNavigator nav = new PropertyNavigator(key);
nav.setMapValue(rootMap, value);
}
Map<String, Object> data = convertToProperties(input);
LinkedHashMap<String, Object> properties = new LinkedHashMap<>();
for (String key : data.keySet()) {
properties.put(MAP_PREFIX + "." + key, data.get(key));
}
addArrays(target, properties);
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addFirst(new MapPropertySource("properties", properties));
factory.setPropertySources(propertySources);
factory.bindPropertiesToTarget();
@SuppressWarnings("unchecked")
Map<String, Object> result = (Map<String, Object>) target.get(MAP_PREFIX);
return result == null ? new LinkedHashMap<String, Object>() : result;
return rootMap;
}
@ExceptionHandler(NoSuchLabelException.class)
@@ -262,55 +255,6 @@ public class EnvironmentController {
return new ResponseEntity<>(body, getHttpHeaders(mediaType), HttpStatus.OK);
}
/**
* Create Lists of the right size for any YAML arrays that are going to need to be
* bound. Some of this might be do-able in RelaxedDataBinder, but we need to do it
* here for now. Only supports arrays at leaf level currently (i.e. the properties
* keys end in [*]).
*
* @param target the target Map
* @param properties the properties (with key names to check)
*/
private void addArrays(Map<String, Object> target, Map<String, Object> properties) {
for (String key : properties.keySet()) {
int index = key.indexOf("[");
Map<String, Object> current = target;
if (index > 0) {
String stem = key.substring(0, index);
String[] keys = StringUtils.delimitedListToStringArray(stem, ".");
for (int i = 0; i < keys.length - 1; i++) {
if (current.get(keys[i]) == null) {
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
current.put(keys[i], map);
current = map;
}
else {
@SuppressWarnings("unchecked")
Map<String, Object> map = (Map<String, Object>) current
.get(keys[i]);
current = map;
}
}
String name = keys[keys.length - 1];
if (current.get(name) == null) {
current.put(name, new ArrayList<>());
}
@SuppressWarnings("unchecked")
List<Object> value = (List<Object>) current.get(name);
int position = Integer
.valueOf(key.substring(index + 1, key.indexOf("]")));
while (position >= value.size()) {
if (key.indexOf("].", index) > 0) {
value.add(new LinkedHashMap<String, Object>());
}
else {
value.add("");
}
}
}
}
}
private Map<String, Object> convertToProperties(Environment profiles) {
// Map of unique keys containing full map of properties for each unique
@@ -367,4 +311,144 @@ public class EnvironmentController {
}
}
/**
* Class {@code PropertyNavigator} is used to navigate through the property key and create necessary Maps and Lists
* making up the nested structure to finally set the property value at the leaf node.
* <p>
* The following rules in yml/json are implemented:
* <pre>
* 1. an array element can be:
* - a value (leaf)
* - a map
* - a nested array
* 2. a map value can be:
* - a value (leaf)
* - a nested map
* - an array
* </pre>
*/
private static class PropertyNavigator {
private enum NodeType {LEAF, MAP, ARRAY}
private final String propertyKey;
private int currentPos;
private NodeType valueType;
private PropertyNavigator(String propertyKey) {
this.propertyKey = propertyKey;
currentPos = -1;
valueType = NodeType.MAP;
}
private void setMapValue(Map<String, Object> map, Object value) {
String key = getKey();
if (NodeType.MAP.equals(valueType)) {
Map<String, Object> nestedMap = (Map<String, Object>) map.get(key);
if (nestedMap == null) {
nestedMap = new LinkedHashMap<>();
map.put(key, nestedMap);
}
setMapValue(nestedMap, value);
} else if (NodeType.ARRAY.equals(valueType)) {
List<Object> list = (List<Object>) map.get(key);
if (list == null) {
list = new ArrayList<>();
map.put(key, list);
}
setListValue(list, value);
} else {
map.put(key, value);
}
}
private void setListValue(List<Object> list, Object value) {
int index = getIndex();
// Fill missing elements if needed
while (list.size() <= index) {
list.add(null);
}
if (NodeType.MAP.equals(valueType)) {
Map<String, Object> map = (Map<String, Object>) list.get(index);
if (map == null) {
map = new LinkedHashMap<>();
list.set(index, map);
}
setMapValue(map, value);
} else if (NodeType.ARRAY.equals(valueType)) {
List<Object> nestedList = (List<Object>) list.get(index);
if (nestedList == null) {
nestedList = new ArrayList<>();
list.set(index, nestedList);
}
setListValue(nestedList, value);
} else {
list.set(index, value);
}
}
private int getIndex() {
// Consider [
int start = currentPos + 1;
for (int i = start; i < propertyKey.length(); i++) {
char c = propertyKey.charAt(i);
if (c == ']') {
currentPos = i;
break;
} else if (!Character.isDigit(c)) {
throw new IllegalArgumentException("Invalid key: " + propertyKey);
}
}
// If no closing ] or if '[]'
if (currentPos < start || currentPos == start) {
throw new IllegalArgumentException("Invalid key: " + propertyKey);
} else {
int index = Integer.parseInt(propertyKey.substring(start, currentPos));
// Skip the closing ]
currentPos++;
if (currentPos == propertyKey.length()) {
valueType = NodeType.LEAF;
} else {
switch (propertyKey.charAt(currentPos)) {
case '.':
valueType = NodeType.MAP;
break;
case '[':
valueType = NodeType.ARRAY;
break;
default:
throw new IllegalArgumentException("Invalid key: " + propertyKey);
}
}
return index;
}
}
private String getKey() {
// Consider initial value or previous char '.' or '['
int start = currentPos + 1;
for (int i = start; i < propertyKey.length(); i++) {
char currentChar = propertyKey.charAt(i);
if (currentChar == '.') {
valueType = NodeType.MAP;
currentPos = i;
break;
} else if (currentChar == '[') {
valueType = NodeType.ARRAY;
currentPos = i;
break;
}
}
// If there's no delimiter then it's a key of a leaf
if (currentPos < start) {
currentPos = propertyKey.length();
valueType = NodeType.LEAF;
// Else if we encounter '..' or '.[' or start of the property is . or [ then it's invalid
} else if (currentPos == start) {
throw new IllegalArgumentException("Invalid key: " + propertyKey);
}
return propertyKey.substring(start, currentPos);
}
}
}

View File

@@ -15,14 +15,6 @@
*/
package org.springframework.cloud.config.server.environment;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
@@ -34,6 +26,7 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.mockito.Mockito;
import org.springframework.cloud.config.environment.Environment;
import org.springframework.cloud.config.environment.PropertySource;
import org.springframework.http.MediaType;
@@ -42,11 +35,21 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
/**
* @author Dave Syer
* @author Roy Clarkson
* @author Ivan Corrales Solera
* @author Daniel Frey
* @author Ian Bondoc
*/
public class EnvironmentControllerTests {
@@ -74,7 +77,8 @@ public class EnvironmentControllerTests {
Map<String, Object> map = new HashMap<String, Object>();
map.put("a.b.c", "d");
this.environment.add(new PropertySource("one", map));
Mockito.when(this.repository.findOne("foo", "bar", null)).thenReturn(this.environment);
Mockito.when(this.repository.findOne("foo", "bar", null))
.thenReturn(this.environment);
String yaml = this.controller.yaml("foo", "bar", false).getBody();
assertEquals("a:\n b:\n c: d\n", yaml);
}
@@ -84,8 +88,10 @@ public class EnvironmentControllerTests {
Map<String, Object> map = new LinkedHashMap<String, Object>();
map.put("a.b.c", "d");
this.environment.add(new PropertySource("one", map));
this.environment.addFirst(new PropertySource("two", Collections.singletonMap("a.b.c", "e")));
Mockito.when(this.repository.findOne("foo", "bar", null)).thenReturn(this.environment);
this.environment.addFirst(
new PropertySource("two", Collections.singletonMap("a.b.c", "e")));
Mockito.when(this.repository.findOne("foo", "bar", null))
.thenReturn(this.environment);
String yaml = this.controller.yaml("foo", "bar", false).getBody();
assertEquals("a:\n b:\n c: e\n", yaml);
}
@@ -101,7 +107,8 @@ public class EnvironmentControllerTests {
map.put("A", "Z");
map.put("S", 3);
this.environment.addFirst(new PropertySource("two", map));
Mockito.when(this.repository.findOne("foo", "bar", null)).thenReturn(this.environment);
Mockito.when(this.repository.findOne("foo", "bar", null))
.thenReturn(this.environment);
String yaml = this.controller.yaml("foo", "bar", false).getBody();
assertEquals("A: Z\nS: 3\nY: 0\n", yaml);
}
@@ -128,14 +135,16 @@ public class EnvironmentControllerTests {
}
@Test
public void placeholdersNotResolvedInYamlFromSystemPropertiesWhenNotFlagged() throws Exception {
public void placeholdersNotResolvedInYamlFromSystemPropertiesWhenNotFlagged()
throws Exception {
whenPlaceholdersSystemProps();
String yaml = this.controller.yaml("foo", "bar", false).getBody();
assertEquals("a:\n b:\n c: ${foo}\n", yaml);
}
@Test
public void placeholdersNotResolvedInYamlFromSystemPropertiesWhenNotFlaggedWithDefault() throws Exception {
public void placeholdersNotResolvedInYamlFromSystemPropertiesWhenNotFlaggedWithDefault()
throws Exception {
whenPlaceholdersSystemPropsWithDefault();
String yaml = this.controller.yaml("foo", "bar", false).getBody();
// If there is a default value we prevent the placeholder being resolved
@@ -143,7 +152,8 @@ public class EnvironmentControllerTests {
}
@Test
public void placeholdersResolvedInYamlFromSystemPropertiesWhenFlagged() throws Exception {
public void placeholdersResolvedInYamlFromSystemPropertiesWhenFlagged()
throws Exception {
whenPlaceholdersSystemPropsWithDefault();
String yaml = this.controller.yaml("foo", "bar", true).getBody();
// If there is a default value we do not prevent the placeholder being resolved
@@ -156,7 +166,8 @@ public class EnvironmentControllerTests {
map.put("a.b[0]", "c");
map.put("a.b[1]", "d");
this.environment.add(new PropertySource("one", map));
Mockito.when(this.repository.findOne("foo", "bar", null)).thenReturn(this.environment);
Mockito.when(this.repository.findOne("foo", "bar", null))
.thenReturn(this.environment);
String yaml = this.controller.yaml("foo", "bar", false).getBody();
assertEquals("a:\n b:\n - c\n - d\n", yaml);
}
@@ -176,7 +187,8 @@ public class EnvironmentControllerTests {
twoMap.put("a.b[1]", "h");
this.environment.addFirst(new PropertySource("two", twoMap));
Mockito.when(this.repository.findOne("foo", "bar", "two")).thenReturn(this.environment);
Mockito.when(this.repository.findOne("foo", "bar", "two"))
.thenReturn(this.environment);
Environment environment = this.controller.labelled("foo", "bar", "two");
assertThat(environment, not(nullValue()));
assertThat(environment.getName(), equalTo("foo"));
@@ -185,9 +197,11 @@ public class EnvironmentControllerTests {
assertThat(environment.getVersion(), nullValue());
assertThat(environment.getPropertySources(), hasSize(2));
assertThat(environment.getPropertySources().get(0).getName(), equalTo("two"));
assertThat(environment.getPropertySources().get(0).getSource().entrySet(), hasSize(2));
assertThat(environment.getPropertySources().get(0).getSource().entrySet(),
hasSize(2));
assertThat(environment.getPropertySources().get(1).getName(), equalTo("one"));
assertThat(environment.getPropertySources().get(1).getSource().entrySet(), hasSize(3));
assertThat(environment.getPropertySources().get(1).getSource().entrySet(),
hasSize(3));
}
@Test
@@ -205,7 +219,8 @@ public class EnvironmentControllerTests {
twoMap.put("a.b[1]", "h");
this.environment.addFirst(new PropertySource("two", twoMap));
Mockito.when(this.repository.findOne("foo", "bar", null)).thenReturn(this.environment);
Mockito.when(this.repository.findOne("foo", "bar", null))
.thenReturn(this.environment);
String yaml = this.controller.yaml("foo", "bar", false).getBody();
// Result will not contain original, extra values from oneMap
@@ -217,7 +232,8 @@ public class EnvironmentControllerTests {
Map<String, Object> map = new LinkedHashMap<String, Object>();
map.put("document", "blah");
this.environment.add(new PropertySource("one", map));
Mockito.when(this.repository.findOne("foo", "bar", null)).thenReturn(this.environment);
Mockito.when(this.repository.findOne("foo", "bar", null))
.thenReturn(this.environment);
String yaml = this.controller.yaml("foo", "bar", false).getBody();
assertEquals("blah\n", yaml);
}
@@ -228,7 +244,8 @@ public class EnvironmentControllerTests {
map.put("document[0]", "c");
map.put("document[1]", "d");
this.environment.add(new PropertySource("one", map));
Mockito.when(this.repository.findOne("foo", "bar", null)).thenReturn(this.environment);
Mockito.when(this.repository.findOne("foo", "bar", null))
.thenReturn(this.environment);
String yaml = this.controller.yaml("foo", "bar", false).getBody();
assertEquals("- c\n- d\n", yaml);
}
@@ -239,7 +256,8 @@ public class EnvironmentControllerTests {
map.put("document[0].a", "c");
map.put("document[1].a", "d");
this.environment.add(new PropertySource("one", map));
Mockito.when(this.repository.findOne("foo", "bar", null)).thenReturn(this.environment);
Mockito.when(this.repository.findOne("foo", "bar", null))
.thenReturn(this.environment);
String yaml = this.controller.yaml("foo", "bar", false).getBody();
assertEquals("- a: c\n- a: d\n", yaml);
}
@@ -251,10 +269,61 @@ public class EnvironmentControllerTests {
map.put("a.b[0].d", "e");
map.put("a.b[1].c", "d");
this.environment.add(new PropertySource("one", map));
Mockito.when(this.repository.findOne("foo", "bar", null)).thenReturn(this.environment);
Mockito.when(this.repository.findOne("foo", "bar", null))
.thenReturn(this.environment);
String yaml = this.controller.yaml("foo", "bar", false).getBody();
assertTrue("Wrong output: " + yaml, "a:\n b:\n - d: e\n c: d\n - c: d\n".equals(yaml)
|| "a:\n b:\n - c: d\n d: e\n - c: d\n".equals(yaml));
assertTrue("Wrong output: " + yaml,
"a:\n b:\n - d: e\n c: d\n - c: d\n".equals(yaml)
|| "a:\n b:\n - c: d\n d: e\n - c: d\n".equals(yaml));
}
@Test
public void nestedArraysOfObjectInYaml() throws Exception {
Map<String, Object> map = new LinkedHashMap<String, Object>();
map.put("a.b[0].c", "x");
map.put("a.b[2].e[0].d", "z");
map.put("a.b[0].d[2]", "yy");
map.put("a.b[0].d[0]", "xx");
map.put("a.b[2].c", "y");
map.put("a.b[3][0]", "r");
map.put("a.b[3][1]", "s");
this.environment.add(new PropertySource("one", map));
Mockito.when(this.repository.findOne("foo", "bar", null))
.thenReturn(this.environment);
String yaml = this.controller.yaml("foo", "bar", false).getBody();
String expected = // @formatter:off
"a:\n" +
" b:\n" +
" - c: x\n" +
" d:\n" +
" - xx\n" +
" - null\n" +
" - yy\n" +
" - null\n" +
" - c: y\n" +
" e:\n" +
" - d: z\n" +
" - - r\n" +
" - s\n";
// @formatter:on
assertThat("Wrong output: " + yaml, yaml, is(expected));
}
@Test
public void nestedArraysOfObjectInJson() throws Exception {
Map<String, Object> map = new LinkedHashMap<String, Object>();
map.put("a.b[0].c", "x");
map.put("a.b[0].d[0]", "xx");
map.put("a.b[0].d[1]", "yy");
map.put("a.b[1].c", "y");
map.put("a.b[1].e[0].d", "z");
this.environment.add(new PropertySource("one", map));
Mockito.when(this.repository.findOne("foo", "bar", null))
.thenReturn(this.environment);
String json = this.controller.jsonProperties("foo", "bar", false).getBody();
System.err.println(json);
assertThat("Wrong output: " + json, json, is(
"{\"a\":{\"b\":[{\"c\":\"x\",\"d\":[\"xx\",\"yy\"]},{\"c\":\"y\",\"e\":[{\"d\":\"z\"}]}]}}"));
}
@Test
@@ -263,7 +332,8 @@ public class EnvironmentControllerTests {
map.put("b[0].c", "d");
map.put("b[1].c", "d");
this.environment.add(new PropertySource("one", map));
Mockito.when(this.repository.findOne("foo", "bar", null)).thenReturn(this.environment);
Mockito.when(this.repository.findOne("foo", "bar", null))
.thenReturn(this.environment);
String yaml = this.controller.yaml("foo", "bar", false).getBody();
assertEquals("b:\n- c: d\n- c: d\n", yaml);
}
@@ -274,7 +344,8 @@ public class EnvironmentControllerTests {
map.put("x.a.b[0].c", "d");
map.put("x.a.b[1].c", "d");
this.environment.add(new PropertySource("one", map));
Mockito.when(this.repository.findOne("foo", "bar", null)).thenReturn(this.environment);
Mockito.when(this.repository.findOne("foo", "bar", null))
.thenReturn(this.environment);
String yaml = this.controller.yaml("foo", "bar", false).getBody();
assertEquals("x:\n a:\n b:\n - c: d\n - c: d\n", yaml);
}
@@ -294,21 +365,24 @@ public class EnvironmentControllerTests {
}
@Test
public void placeholdersNotResolvedInPropertiesFromSystemProperties() throws Exception {
public void placeholdersNotResolvedInPropertiesFromSystemProperties()
throws Exception {
whenPlaceholdersSystemProps();
String text = this.controller.properties("foo", "bar", true).getBody();
assertEquals("a.b.c: ${foo}", text);
}
@Test
public void placeholdersNotResolvedInPropertiesFromSystemPropertiesWhenNotFlagged() throws Exception {
public void placeholdersNotResolvedInPropertiesFromSystemPropertiesWhenNotFlagged()
throws Exception {
whenPlaceholdersSystemProps();
String text = this.controller.properties("foo", "bar", false).getBody();
assertEquals("a.b.c: ${foo}", text);
}
@Test
public void placeholdersNotResolvedInPropertiesFromSystemPropertiesWhenNotFlaggedWithDefault() throws Exception {
public void placeholdersNotResolvedInPropertiesFromSystemPropertiesWhenNotFlaggedWithDefault()
throws Exception {
whenPlaceholdersSystemPropsWithDefault();
String text = this.controller.properties("foo", "bar", false).getBody();
assertEquals("a.b.c: ${foo:spam}", text);
@@ -336,14 +410,16 @@ public class EnvironmentControllerTests {
}
@Test
public void placeholdersNotResolvedInJsonFromSystemPropertiesWhenNotFlagged() throws Exception {
public void placeholdersNotResolvedInJsonFromSystemPropertiesWhenNotFlagged()
throws Exception {
whenPlaceholdersSystemProps();
String json = this.controller.jsonProperties("foo", "bar", false).getBody();
assertEquals("{\"a\":{\"b\":{\"c\":\"${foo}\"}}}", json);
}
@Test
public void placeholdersNotResolvedInJsonFromSystemPropertiesWhenNotFlaggedWithDefault() throws Exception {
public void placeholdersNotResolvedInJsonFromSystemPropertiesWhenNotFlaggedWithDefault()
throws Exception {
whenPlaceholdersSystemPropsWithDefault();
String json = this.controller.jsonProperties("foo", "bar", false).getBody();
// If there is a default value we prevent the placeholder being resolved
@@ -351,7 +427,8 @@ public class EnvironmentControllerTests {
}
@Test
public void placeholdersResolvedInJsonFromSystemPropertiesWhenFlagged() throws Exception {
public void placeholdersResolvedInJsonFromSystemPropertiesWhenFlagged()
throws Exception {
whenPlaceholdersSystemPropsWithDefault();
String json = this.controller.jsonProperties("foo", "bar", true).getBody();
// If there is a default value we do not prevent the placeholder being resolved
@@ -362,108 +439,131 @@ public class EnvironmentControllerTests {
Map<String, Object> map = new LinkedHashMap<String, Object>();
map.put("foo", "bar");
this.environment.add(new PropertySource("one", map));
this.environment.addFirst(new PropertySource("two", Collections.singletonMap("a.b.c", "${foo}")));
Mockito.when(this.repository.findOne("foo", "bar", null)).thenReturn(this.environment);
this.environment.addFirst(
new PropertySource("two", Collections.singletonMap("a.b.c", "${foo}")));
Mockito.when(this.repository.findOne("foo", "bar", null))
.thenReturn(this.environment);
}
private void whenPlaceholdersSystemProps() {
System.setProperty("foo", "bar");
this.environment.addFirst(new PropertySource("two", Collections.singletonMap("a.b.c", "${foo}")));
Mockito.when(this.repository.findOne("foo", "bar", null)).thenReturn(this.environment);
this.environment.addFirst(
new PropertySource("two", Collections.singletonMap("a.b.c", "${foo}")));
Mockito.when(this.repository.findOne("foo", "bar", null))
.thenReturn(this.environment);
}
private void whenPlaceholdersSystemPropsWithDefault() {
System.setProperty("foo", "bar");
this.environment.addFirst(new PropertySource("two", Collections.singletonMap("a.b.c", "${foo:spam}")));
Mockito.when(this.repository.findOne("foo", "bar", null)).thenReturn(this.environment);
this.environment.addFirst(new PropertySource("two",
Collections.singletonMap("a.b.c", "${foo:spam}")));
Mockito.when(this.repository.findOne("foo", "bar", null))
.thenReturn(this.environment);
}
@Test
public void mappingForEnvironment() throws Exception {
Mockito.when(this.repository.findOne("foo", "bar", null)).thenReturn(this.environment);
Mockito.when(this.repository.findOne("foo", "bar", null))
.thenReturn(this.environment);
MockMvc mvc = MockMvcBuilders.standaloneSetup(this.controller).build();
mvc.perform(MockMvcRequestBuilders.get("/foo/bar")).andExpect(MockMvcResultMatchers.status().isOk());
mvc.perform(MockMvcRequestBuilders.get("/foo/bar"))
.andExpect(MockMvcResultMatchers.status().isOk());
}
@Test
public void mappingForLabelledEnvironment() throws Exception {
Mockito.when(this.repository.findOne("foo", "bar", "other")).thenReturn(this.environment);
Mockito.when(this.repository.findOne("foo", "bar", "other"))
.thenReturn(this.environment);
MockMvc mvc = MockMvcBuilders.standaloneSetup(this.controller).build();
mvc.perform(MockMvcRequestBuilders.get("/foo/bar/other")).andExpect(MockMvcResultMatchers.status().isOk());
mvc.perform(MockMvcRequestBuilders.get("/foo/bar/other"))
.andExpect(MockMvcResultMatchers.status().isOk());
}
@Test
public void mappingForYaml() throws Exception {
Mockito.when(this.repository.findOne("foo", "bar", null)).thenReturn(this.environment);
Mockito.when(this.repository.findOne("foo", "bar", null))
.thenReturn(this.environment);
MockMvc mvc = MockMvcBuilders.standaloneSetup(this.controller).build();
mvc.perform(MockMvcRequestBuilders.get("/foo-bar.yml"))
.andExpect(MockMvcResultMatchers.content().contentType(MediaType.TEXT_PLAIN))
.andExpect(
MockMvcResultMatchers.content().contentType(MediaType.TEXT_PLAIN))
.andExpect(MockMvcResultMatchers.content().string("{}\n"));
}
@Test
public void mappingForJson() throws Exception {
Mockito.when(this.repository.findOne("foo", "bar", null)).thenReturn(this.environment);
Mockito.when(this.repository.findOne("foo", "bar", null))
.thenReturn(this.environment);
MockMvc mvc = MockMvcBuilders.standaloneSetup(this.controller).build();
mvc.perform(MockMvcRequestBuilders.get("/foo-bar.json"))
.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.content()
.contentType(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.content().string("{}"));
}
@Test
public void mappingForLabelledYaml() throws Exception {
Mockito.when(this.repository.findOne("foo", "bar", "other")).thenReturn(this.environment);
Mockito.when(this.repository.findOne("foo", "bar", "other"))
.thenReturn(this.environment);
MockMvc mvc = MockMvcBuilders.standaloneSetup(this.controller).build();
mvc.perform(MockMvcRequestBuilders.get("/other/foo-bar.yml"))
.andExpect(MockMvcResultMatchers.content().contentType(MediaType.TEXT_PLAIN));
mvc.perform(MockMvcRequestBuilders.get("/other/foo-bar.yml")).andExpect(
MockMvcResultMatchers.content().contentType(MediaType.TEXT_PLAIN));
}
@Test
public void mappingForLabelledProperties() throws Exception {
Mockito.when(this.repository.findOne("foo", "bar", "other")).thenReturn(this.environment);
Mockito.when(this.repository.findOne("foo", "bar", "other"))
.thenReturn(this.environment);
MockMvc mvc = MockMvcBuilders.standaloneSetup(this.controller).build();
mvc.perform(MockMvcRequestBuilders.get("/other/foo-bar.properties"))
.andExpect(MockMvcResultMatchers.content().contentType(MediaType.TEXT_PLAIN));
mvc.perform(MockMvcRequestBuilders.get("/other/foo-bar.properties")).andExpect(
MockMvcResultMatchers.content().contentType(MediaType.TEXT_PLAIN));
}
@Test
public void mappingForProperties() throws Exception {
Mockito.when(this.repository.findOne("foo", "bar", null)).thenReturn(this.environment);
Mockito.when(this.repository.findOne("foo", "bar", null))
.thenReturn(this.environment);
MockMvc mvc = MockMvcBuilders.standaloneSetup(this.controller).build();
mvc.perform(MockMvcRequestBuilders.get("/foo-bar.properties"))
.andExpect(MockMvcResultMatchers.content().contentType(MediaType.TEXT_PLAIN));
mvc.perform(MockMvcRequestBuilders.get("/foo-bar.properties")).andExpect(
MockMvcResultMatchers.content().contentType(MediaType.TEXT_PLAIN));
}
@Test
public void mappingForLabelledYamlWithHyphen() throws Exception {
Mockito.when(this.repository.findOne("foo-bar-foo2-bar2", "spam", "other")).thenReturn(this.environment);
Mockito.when(this.repository.findOne("foo-bar-foo2-bar2", "spam", "other"))
.thenReturn(this.environment);
MockMvc mvc = MockMvcBuilders.standaloneSetup(this.controller).build();
mvc.perform(MockMvcRequestBuilders.get("/other/foo-bar-foo2-bar2-spam.yml"))
.andExpect(MockMvcResultMatchers.content().contentType(MediaType.TEXT_PLAIN));
.andExpect(MockMvcResultMatchers.content()
.contentType(MediaType.TEXT_PLAIN));
}
@Test
public void mappingforLabelledJsonProperties() throws Exception {
Mockito.when(this.repository.findOne("foo", "bar", "other")).thenReturn(this.environment);
Mockito.when(this.repository.findOne("foo", "bar", "other"))
.thenReturn(this.environment);
MockMvc mvc = MockMvcBuilders.standaloneSetup(this.controller).build();
mvc.perform(MockMvcRequestBuilders.get("/other/foo-bar.json"))
.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON));
mvc.perform(MockMvcRequestBuilders.get("/other/foo-bar.json")).andExpect(
MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON));
}
@Test
public void mappingforJsonProperties() throws Exception {
Mockito.when(this.repository.findOne("foo", "bar", null)).thenReturn(this.environment);
Mockito.when(this.repository.findOne("foo", "bar", null))
.thenReturn(this.environment);
MockMvc mvc = MockMvcBuilders.standaloneSetup(this.controller).build();
mvc.perform(MockMvcRequestBuilders.get("/foo-bar.json"))
.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON));
mvc.perform(MockMvcRequestBuilders.get("/foo-bar.json")).andExpect(
MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON));
}
@Test
public void mappingForLabelledJsonPropertiesWithHyphen() throws Exception {
Mockito.when(this.repository.findOne("foo-bar-foo2-bar2", "spam", "other")).thenReturn(this.environment);
Mockito.when(this.repository.findOne("foo-bar-foo2-bar2", "spam", "other"))
.thenReturn(this.environment);
MockMvc mvc = MockMvcBuilders.standaloneSetup(this.controller).build();
mvc.perform(MockMvcRequestBuilders.get("/other/foo-bar-foo2-bar2-spam.json"))
.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON));
.andExpect(MockMvcResultMatchers.content()
.contentType(MediaType.APPLICATION_JSON));
}