You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by mp...@apache.org on 2018/04/06 15:49:04 UTC

[ambari] branch trunk updated: AMBARI-23463. Server should support saving configs with names which contains slash. (mpapirkovskyy)

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 <mp...@apache.org>
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
mpapirkovskyy@apache.org.