This is an automated email from the ASF dual-hosted git repository.
mpapirkovskyy pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git
The following commit(s) were added to refs/heads/trunk by this push:
new 8c9b198 AMBARI-23463. Server should support saving configs with names
which contains slash. (mpapirkovskyy)
8c9b198 is described below
commit 8c9b19848174dfc529d55b6864cfeb8fe0f9a8ff
Author: Myroslav Papirkovskyi <[email protected]>
AuthorDate: Fri Apr 6 18:14:18 2018 +0300
AMBARI-23463. Server should support saving configs with names which
contains slash. (mpapirkovskyy)
---
.../services/parsers/JsonRequestBodyParser.java | 47 ++++++++++++++++++++--
.../apache/ambari/server/state/ConfigHelper.java | 27 +++++++++++++
2 files changed, 70 insertions(+), 4 deletions(-)
diff --git
a/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/JsonRequestBodyParser.java
b/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/JsonRequestBodyParser.java
index eaa652e..d64b590 100644
---
a/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/JsonRequestBodyParser.java
+++
b/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/JsonRequestBodyParser.java
@@ -32,6 +32,8 @@ import org.apache.ambari.server.api.services.NamedPropertySet;
import org.apache.ambari.server.api.services.RequestBody;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.SerializableString;
+import org.codehaus.jackson.io.CharacterEscapes;
import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -45,6 +47,12 @@ public class JsonRequestBodyParser implements
RequestBodyParser {
*/
private final static Logger LOG =
LoggerFactory.getLogger(JsonRequestBodyParser.class);
+ private final static ObjectMapper mapper = new ObjectMapper();
+
+ static {
+ mapper.getJsonFactory().setCharacterEscapes(new AmbariEscapes());
+ }
+
@Override
public Set<RequestBody> parse(String body) throws BodyParseException {
@@ -53,7 +61,6 @@ public class JsonRequestBodyParser implements
RequestBodyParser {
rootBody.setBody(body);
if (body != null && body.length() != 0) {
- ObjectMapper mapper = new ObjectMapper();
try {
JsonNode root = mapper.readTree(ensureArrayFormat(body));
@@ -110,8 +117,7 @@ public class JsonRequestBodyParser implements
RequestBodyParser {
}
private void processNode(JsonNode node, String path, NamedPropertySet
propertySet,
- Map<String, String> requestInfoProps) {
-
+ Map<String, String> requestInfoProps) throws
IOException {
Iterator<String> iterator = node.getFieldNames();
while (iterator.hasNext()) {
String name = iterator.next();
@@ -160,8 +166,9 @@ public class JsonRequestBodyParser implements
RequestBodyParser {
path.substring(REQUEST_INFO_PATH.length() + SLASH.length()),
name),
value);
} else {
+ String escapedName = AmbariEscapes.escapeValue(mapper, name);
propertySet.getProperties().put(PropertyHelper.getPropertyId(
- path.equals(BODY_TITLE) ? "" : path, name), value);
+ path.equals(BODY_TITLE) ? "" : path, escapedName), value);
}
}
}
@@ -170,4 +177,36 @@ public class JsonRequestBodyParser implements
RequestBodyParser {
private String ensureArrayFormat(String s) {
return s.startsWith("[") ? s : '[' + s + ']';
}
+
+ static class AmbariEscapes extends CharacterEscapes {
+
+ private final int[] escapeCodesForAscii;
+
+ public AmbariEscapes() {
+ this.escapeCodesForAscii = standardAsciiEscapesForJSON();
+ escapeCodesForAscii['/'] = CharacterEscapes.ESCAPE_STANDARD;
+ }
+
+ @Override
+ public int[] getEscapeCodesForAscii() {
+ return escapeCodesForAscii;
+ }
+
+ @Override
+ public SerializableString getEscapeSequence(int ch) {
+ return null;
+ }
+
+ /**
+ * Converts string to escaped and removes first and last symbols (double
brackets)
+ * @param mapper mapper
+ * @param value string to be escaped
+ * @return escaped string
+ * @throws IOException
+ */
+ private static String escapeValue(ObjectMapper mapper, String value)
throws IOException {
+ String escapedString = mapper.writeValueAsString(value);
+ return escapedString.substring(1, escapedString.length() - 1);
+ }
+ }
}
diff --git
a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java
b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java
index ac543b7..71d1cc4 100644
---
a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java
+++
b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigHelper.java
@@ -58,6 +58,7 @@ import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
+import org.apache.commons.lang3.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -1952,7 +1953,9 @@ public class ConfigHelper {
LOG.info("For configs update on host {} will be used following effective
desired tags {}", hostId, configTags.toString());
getAndMergeHostConfigs(configurations, configTags, cl);
+ configurations = unescapeConfigNames(configurations);
getAndMergeHostConfigAttributes(configurationAttributes, configTags, cl);
+ configurationAttributes =
unescapeConfigAttributeNames(configurationAttributes);
SortedMap<String, SortedMap<String, String>> configurationsTreeMap =
sortConfigutations(configurations);
SortedMap<String, SortedMap<String, SortedMap<String, String>>>
configurationAttributesTreeMap =
@@ -1966,6 +1969,30 @@ public class ConfigHelper {
return agentConfigsUpdateEvent;
}
+ private Map<String, Map<String, String>> unescapeConfigNames(Map<String,
Map<String, String>> configurations) {
+ Map<String, Map<String, String>> unescapedConfigs = new HashMap<>();
+ for (Entry<String, Map<String, String>> configTypeEntry :
configurations.entrySet()) {
+ Map<String, String> unescapedTypeConfigs = new HashMap<>();
+ for (Entry<String, String> config :
configTypeEntry.getValue().entrySet()) {
+
unescapedTypeConfigs.put(StringEscapeUtils.unescapeJava(config.getKey()),
config.getValue());
+ }
+ unescapedConfigs.put(configTypeEntry.getKey(), unescapedTypeConfigs);
+ }
+
+ return unescapedConfigs;
+ }
+
+ private Map<String, Map<String, Map<String, String>>>
unescapeConfigAttributeNames(
+ Map<String, Map<String, Map<String, String>>> configurationAttributes) {
+ Map<String, Map<String, Map<String, String>>> unescapedConfigAttributes =
new HashMap<>();
+
+ for (Entry<String, Map<String, Map<String, String>>> configAttrTypeEntry :
configurationAttributes.entrySet()) {
+ unescapedConfigAttributes.put(configAttrTypeEntry.getKey(),
unescapeConfigNames(configAttrTypeEntry.getValue()));
+ }
+
+ return unescapedConfigAttributes;
+ }
+
public SortedMap<String, SortedMap<String, String>>
sortConfigutations(Map<String, Map<String, String>> configurations) {
SortedMap<String, SortedMap<String, String>> configurationsTreeMap = new
TreeMap<>();
configurations.forEach((k, v) -> {
--
To stop receiving notification emails like this one, please contact
[email protected].