Strip "document" prefix from YAML by default

It's pretty uncommon for Spring apps, but sometimes YAML is not a
map, but more naturally a String or Collection. In these cases Spring
puts a "document" prefix in the Map it creates, so we can strip that
off if the user prefers it.

Fixes gh-143
This commit is contained in:
Dave Syer
2015-05-19 10:53:51 +01:00
parent 641d5b40e8
commit e94b4039a6
4 changed files with 71 additions and 1 deletions

View File

@@ -44,6 +44,7 @@ public class ConfigServerMvcConfiguration {
EnvironmentController controller = new EnvironmentController(repository, encryptionController());
controller.setDefaultLabel(getDefaultLabel());
controller.setOverrides(server.getOverrides());
controller.setStripDocumentFromYaml(server.isStripDocumentFromYaml());
return controller;
}

View File

@@ -51,6 +51,12 @@ public class ConfigServerProperties {
*/
private Map<String, String> overrides = new LinkedHashMap<String, String>();
/**
* Flag to indicate that YAML documents that are text or collections (not a map)
* should be returned in "native" form.
*/
private boolean stripDocumentFromYaml = true;
public String getDefaultLabel() {
return defaultLabel;
}
@@ -83,4 +89,12 @@ public class ConfigServerProperties {
this.overrides = overrides;
}
public boolean isStripDocumentFromYaml() {
return stripDocumentFromYaml;
}
public void setStripDocumentFromYaml(boolean stripDocumentFromYaml) {
this.stripDocumentFromYaml = stripDocumentFromYaml;
}
}

View File

@@ -17,6 +17,7 @@ package org.springframework.cloud.config.server;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
@@ -27,7 +28,6 @@ import java.util.TreeMap;
import javax.servlet.http.HttpServletResponse;
import org.yaml.snakeyaml.Yaml;
import org.springframework.boot.bind.PropertiesConfigurationFactory;
import org.springframework.cloud.config.environment.Environment;
import org.springframework.cloud.config.environment.PropertySource;
@@ -43,6 +43,9 @@ 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.RestController;
import org.yaml.snakeyaml.DumperOptions.FlowStyle;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.nodes.Tag;
/**
* @author Dave Syer
@@ -63,6 +66,8 @@ public class EnvironmentController {
private Map<String, String> overrides = new LinkedHashMap<>();
private boolean stripDocument = true;
public EnvironmentController(EnvironmentRepository repository,
EncryptionController encryption) {
super();
@@ -71,6 +76,15 @@ public class EnvironmentController {
this.encryption = encryption;
}
/**
* Flag to indicate that YAML documents which are not a map should be stripped of the
* "document" prefix that is added by Spring (to facilitate conversion to Properties).
* @param stripDocument the flag to set
*/
public void setStripDocumentFromYaml(boolean stripDocument) {
this.stripDocument = stripDocument;
}
@RequestMapping("/{name}/{profiles:.*[^-].*}")
public Environment defaultLabel(@PathVariable String name,
@PathVariable String profiles) {
@@ -141,6 +155,15 @@ public class EnvironmentController {
@PathVariable String profiles, @PathVariable String label) throws Exception {
validateNameAndProfiles(name, profiles);
Map<String, Object> result = convertToMap(labelled(name, profiles, label));
if (this.stripDocument && result.size() == 1
&& result.keySet().iterator().next().equals("document")) {
Object value = result.get("document");
if (value instanceof Collection) {
return getSuccess(new Yaml().dumpAs(value, Tag.SEQ, FlowStyle.BLOCK));
} else {
return getSuccess(new Yaml().dumpAs(value, Tag.STR, FlowStyle.BLOCK));
}
}
return getSuccess(new Yaml().dumpAsMap(result));
}

View File

@@ -91,6 +91,38 @@ public class EnvironmentControllerTests {
assertEquals("a:\n b:\n - c\n - d\n", yaml);
}
@Test
public void textAtTopLevelInYaml() throws Exception {
Map<String, Object> map = new LinkedHashMap<String, Object>();
map.put("document", "blah");
environment.add(new PropertySource("one", map));
Mockito.when(repository.findOne("foo", "bar", "master")).thenReturn(environment);
String yaml = controller.yaml("foo", "bar").getBody();
assertEquals("blah\n", yaml);
}
@Test
public void arrayAtTopLevelInYaml() throws Exception {
Map<String, Object> map = new LinkedHashMap<String, Object>();
map.put("document[0]", "c");
map.put("document[1]", "d");
environment.add(new PropertySource("one", map));
Mockito.when(repository.findOne("foo", "bar", "master")).thenReturn(environment);
String yaml = controller.yaml("foo", "bar").getBody();
assertEquals("- c\n- d\n", yaml);
}
@Test
public void arrayObObjectAtTopLevelInYaml() throws Exception {
Map<String, Object> map = new LinkedHashMap<String, Object>();
map.put("document[0].a", "c");
map.put("document[1].a", "d");
environment.add(new PropertySource("one", map));
Mockito.when(repository.findOne("foo", "bar", "master")).thenReturn(environment);
String yaml = controller.yaml("foo", "bar").getBody();
assertEquals("- a: c\n- a: d\n", yaml);
}
@Test
public void arrayOfObjectInYaml() throws Exception {
Map<String, Object> map = new LinkedHashMap<String, Object>();