You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by mb...@apache.org on 2021/03/26 11:10:48 UTC

[asterixdb] 05/09: [NO ISSUE] Stop pretty-printing JSON results

This is an automated email from the ASF dual-hosted git repository.

mblow pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/asterixdb.git

commit f4f28980a6621e928f78b352222a75e98c07c68d
Author: Michael Blow <mb...@apache.org>
AuthorDate: Sat Feb 27 09:50:43 2021 -0500

    [NO ISSUE] Stop pretty-printing JSON results
    
    - += prettifyjsonresult test file keyword to pretty-print actual
      JSON results before comparison
    
    Change-Id: I19aa93568ca619f85d52ba354edd356c194b5b2a
    Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/10045
    Integration-Tests: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Tested-by: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Reviewed-by: Michael Blow <mb...@apache.org>
    Reviewed-by: Murtadha Hubail <mh...@apache.org>
---
 .../apache/asterix/test/common/TestExecutor.java   | 15 +++-
 .../org/apache/asterix/test/common/TestHelper.java | 87 +++++++++++++++++---
 .../asterix/test/runtime/SqlppRQGTestBase.java     |  2 +-
 .../api/cluster_state_1/cluster_state_1.1.get.http |  1 +
 .../api/diagnostics_1/diagnostics_1.1.get.http     |  1 +
 .../api/net-diagnostics/net-diagnostics.1.get.http |  1 +
 .../add_replica/add_replica.2.pollget.http         |  1 +
 .../replication/bulkload/bulkload.11.pollget.http  |  1 +
 .../replication/bulkload/bulkload.3.pollget.http   |  1 +
 .../replication/bulkload/bulkload.4.pollget.http   |  1 +
 .../bulkload.11.pollget.http                       |  1 +
 .../bulkload.3.pollget.http                        |  1 +
 .../bulkload.4.pollget.http                        |  1 +
 .../flushed_component.2.pollget.http               |  1 +
 .../flushed_component.8.pollget.http               |  1 +
 .../flushed_component_compressed.12.pollget.http   |  1 +
 .../flushed_component_compressed.3.pollget.http    |  1 +
 .../flushed_component_compressed.4.pollget.http    |  1 +
 .../mem_component_recovery.11.pollget.http         |  1 +
 .../mem_component_recovery.3.pollget.http          |  1 +
 .../mem_component_recovery.4.pollget.http          |  1 +
 .../metadata_failover.2.pollget.http               |  1 +
 .../metadata_failover/metadata_failover.5.get.http |  2 +
 .../metadata_failover.8.pollget.http               |  1 +
 .../release_partition.2.pollget.http               |  1 +
 .../release_partition/release_partition.4.get.http |  2 +
 .../metadata_failover/metadata_failover.11.adm     |  4 +-
 .../reuse_data_port/reuse_data_port.4.pollget.http |  1 +
 .../reuse_data_port/reuse_data_port.7.pollget.http |  1 +
 ...euse_data_port.5.adm => reuse_data_port.4.json} |  0
 ...euse_data_port.7.adm => reuse_data_port.7.json} |  0
 .../resync_failed_replica.10.pollget.http          |  1 +
 .../resync_failed_replica.13.pollget.http          |  1 +
 .../resync_failed_replica.2.pollget.http           |  1 +
 .../resync_failed_replica.5.pollget.http           |  1 +
 .../resync_failed_replica.6.pollget.http           |  1 +
 .../resync_failed_replica.8.pollget.http           |  1 +
 asterixdb/pom.xml                                  |  2 +
 .../java/org/apache/hyracks/util/JSONUtil.java     | 94 +---------------------
 39 files changed, 128 insertions(+), 109 deletions(-)

diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
index e1d81a4..3cc6353 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
@@ -33,6 +33,7 @@ import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.PrintStream;
 import java.io.PrintWriter;
+import java.io.Reader;
 import java.io.StringWriter;
 import java.net.Inet4Address;
 import java.net.InetAddress;
@@ -164,6 +165,7 @@ public class TestExecutor {
     private static final Pattern RESULT_VARIABLE_PATTERN = Pattern.compile("resultvariable=(\\w+)");
     private static final Pattern COMPARE_UNORDERED_ARRAY_PATTERN = Pattern.compile("compareunorderedarray=(\\w+)");
     private static final Pattern IGNORE_EXTRA_FIELDS_PATTERN = Pattern.compile("ignoreextrafields=(\\w+)");
+    private static final Pattern PRETTIFY_JSON_PATTERN = Pattern.compile("prettifyjsonresult=(\\w+)");
     private static final Pattern BODY_REF_PATTERN = Pattern.compile("bodyref=(.*)", Pattern.MULTILINE);
     private static final Pattern MACRO_PARAM_PATTERN =
             Pattern.compile("macro (?<name>[\\w-$]+)=(?<value>.*)", Pattern.MULTILINE);
@@ -276,10 +278,12 @@ public class TestExecutor {
         if (expectedFile.getName().endsWith(".ignore")) {
             return; //skip the comparison
         }
+        boolean prettifyJsonResult = statement == null ? false : getPrettifyJsonResult(statement);
         try (BufferedReader readerExpected =
                 new BufferedReader(new InputStreamReader(new FileInputStream(expectedFile), UTF_8));
-                BufferedReader readerActual =
-                        new BufferedReader(new InputStreamReader(new FileInputStream(actualFile), actualEncoding))) {
+                Reader rawReaderActual = new InputStreamReader(new FileInputStream(actualFile), actualEncoding);
+                BufferedReader readerActual = new BufferedReader(
+                        prettifyJsonResult ? TestHelper.asPrettyJson(rawReaderActual) : rawReaderActual)) {
             if (ComparisonEnum.BINARY.equals(compare)) {
                 if (!IOUtils.contentEquals(new FileInputStream(actualFile), new FileInputStream(expectedFile))) {
                     throw new Exception("Result for " + scriptFile + ": actual file did not match expected result");
@@ -567,7 +571,7 @@ public class TestExecutor {
         } else if (actualJson == null) {
             throw new ComparisonException("No actual result for: " + scriptFile);
         }
-        if (!TestHelper.equalJson(expectedJson, actualJson, compareUnorderedArray, ignoreExtraFields)) {
+        if (!TestHelper.equalJson(expectedJson, actualJson, compareUnorderedArray, ignoreExtraFields, false, null)) {
             throw new ComparisonException("Result for " + scriptFile + " didn't match the expected JSON"
                     + "\nexpected result:\n" + expectedJson + "\nactual result:\n" + actualJson);
         }
@@ -1765,6 +1769,11 @@ public class TestExecutor {
         return matcher.find() && Boolean.parseBoolean(matcher.group(1));
     }
 
+    protected static boolean getPrettifyJsonResult(String statement) {
+        final Matcher matcher = PRETTIFY_JSON_PATTERN.matcher(statement);
+        return matcher.find() && Boolean.parseBoolean(matcher.group(1));
+    }
+
     protected static String replaceVarRef(String statement, Map<String, Object> variableCtx) {
         String tmpStmt = statement;
         Matcher variableReferenceMatcher = VARIABLE_REF_PATTERN.matcher(tmpStmt);
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestHelper.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestHelper.java
index 939acd3..24ca072 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestHelper.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestHelper.java
@@ -23,6 +23,9 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
 import java.util.BitSet;
 import java.util.Collections;
 import java.util.Enumeration;
@@ -41,10 +44,13 @@ import org.apache.asterix.testframework.xml.TestCase;
 import org.apache.commons.compress.utils.IOUtils;
 import org.apache.commons.io.FileUtils;
 import org.apache.hyracks.util.file.FileUtil;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.MapperFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ObjectWriter;
 import com.fasterxml.jackson.databind.SerializationFeature;
 import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
@@ -52,9 +58,29 @@ import com.fasterxml.jackson.databind.node.TextNode;
 
 public final class TestHelper {
 
+    private static final Logger LOGGER = LogManager.getLogger();
     private static final String TEST_DIR_BASE_PATH = System.getProperty("user.dir") + File.separator + "target";
     private static final String[] TEST_DIRS = new String[] { "txnLogDir", "IODevice", "spill_area", "config" };
 
+    private static final ObjectMapper SORTED_MAPPER = new ObjectMapper();
+    private static final ObjectWriter PRETTY_SORTED_WRITER;
+
+    static {
+        SORTED_MAPPER.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
+        SORTED_MAPPER.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);
+        PRETTY_SORTED_WRITER = SORTED_MAPPER.writerWithDefaultPrettyPrinter();
+    }
+
+    public static Reader asPrettyJson(final Reader rawJson) throws IOException {
+        try {
+            StringWriter sw = new StringWriter();
+            PRETTY_SORTED_WRITER.writeValue(sw, SORTED_MAPPER.readTree(rawJson));
+            return new StringReader(sw.toString());
+        } finally {
+            IOUtils.closeQuietly(rawJson);
+        }
+    }
+
     public static boolean isInPrefixList(List<String> prefixList, String s) {
         for (String s2 : prefixList) {
             if (s.startsWith(s2)) {
@@ -142,7 +168,7 @@ public final class TestHelper {
     }
 
     public static boolean equalJson(JsonNode expectedJson, JsonNode actualJson, boolean compareUnorderedArray,
-            boolean ignoreExtraFields) {
+            boolean ignoreExtraFields, boolean withinUnorderedComparison, String context) {
         if (expectedJson == actualJson) {
             return true;
         }
@@ -152,20 +178,36 @@ public final class TestHelper {
         }
         if ((expectedJson.isMissingNode() && !actualJson.isMissingNode())
                 || (!expectedJson.isMissingNode() && actualJson.isMissingNode())) {
+            if (!withinUnorderedComparison) {
+                LOGGER.info("missing node mismatch: expected={} actual={} context={}", expectedJson, actualJson,
+                        context);
+            }
             return false;
         }
         // both are not null
         if (isRegexField(expectedJson)) {
             String expectedRegex = expectedJson.asText();
-            String actualAsString = actualJson.isValueNode() ? actualJson.asText() : actualJson.toString();
+            String actualAsString = stringify(actualJson);
             expectedRegex = expectedRegex.substring(2, expectedRegex.length() - 1);
-            return actualAsString.matches(expectedRegex);
+            final boolean matches = actualAsString.matches(expectedRegex);
+            if (!matches && !withinUnorderedComparison) {
+                LOGGER.info("regex mismatch: expected={} actual={} context={}", expectedRegex, actualAsString, context);
+            }
+            return matches;
         } else if (expectedJson.getNodeType() != actualJson.getNodeType()) {
+            if (!withinUnorderedComparison) {
+                LOGGER.info("node type mismatch: expected={}({}) actual={}({})", stringify(expectedJson),
+                        expectedJson.getNodeType(), stringify(actualJson), actualJson.getNodeType());
+            }
             return false;
         } else if (expectedJson.isArray() && actualJson.isArray()) {
             ArrayNode expectedArray = (ArrayNode) expectedJson;
             ArrayNode actualArray = (ArrayNode) actualJson;
             if (expectedArray.size() != actualArray.size()) {
+                if (!withinUnorderedComparison) {
+                    LOGGER.info("array size mismatch: expected={} actual={}", stringify(expectedArray),
+                            stringify(actualArray));
+                }
                 return false;
             }
             return compareUnorderedArray ? compareUnordered(expectedArray, actualArray, ignoreExtraFields)
@@ -176,6 +218,10 @@ public final class TestHelper {
             ObjectNode actualObject = (ObjectNode) actualJson;
             if (!ignoreExtraFields && expectedObject.size() != actualObject.size()
                     || (ignoreExtraFields && expectedObject.size() > actualObject.size())) {
+                if (!withinUnorderedComparison) {
+                    LOGGER.info("object size mismatch: expected={} actual={} context={}", stringify(expectedObject),
+                            stringify(actualObject), context);
+                }
                 return false;
             }
             Iterator<Map.Entry<String, JsonNode>> expectedFields = expectedObject.fields();
@@ -184,17 +230,35 @@ public final class TestHelper {
             while (expectedFields.hasNext()) {
                 expectedField = expectedFields.next();
                 actualFieldValue = actualObject.get(expectedField.getKey());
-                if (actualFieldValue == null || !equalJson(expectedField.getValue(), actualFieldValue,
-                        compareUnorderedArray, ignoreExtraFields)) {
+                if (actualFieldValue == null) {
+                    if (!withinUnorderedComparison) {
+                        LOGGER.info("actual field value null: expected name={} expected value={}",
+                                expectedField.getKey(), expectedField.getValue().asText());
+                    }
+                    return false;
+                }
+                if (!equalJson(expectedField.getValue(), actualFieldValue, compareUnorderedArray, ignoreExtraFields,
+                        withinUnorderedComparison, expectedField.getKey())) {
                     return false;
                 }
             }
             return true;
         }
         // value node
-        String expectedAsString = expectedJson.isValueNode() ? expectedJson.asText() : expectedJson.toString();
-        String actualAsString = actualJson.isValueNode() ? actualJson.asText() : actualJson.toString();
-        return expectedAsString.equals(actualAsString);
+        String expectedAsString = stringify(expectedJson);
+        String actualAsString = stringify(actualJson);
+        if (!expectedAsString.equals(actualAsString)) {
+            if (!withinUnorderedComparison) {
+                LOGGER.info("value node mismatch: expected={} actual={} context={}", expectedAsString, actualAsString,
+                        context);
+            }
+            return false;
+        }
+        return true;
+    }
+
+    private static String stringify(JsonNode jsonNode) {
+        return jsonNode == null ? null : (jsonNode.isValueNode() ? jsonNode.asText() : jsonNode.toString());
     }
 
     private static boolean compareUnordered(ArrayNode expectedArray, ArrayNode actualArray, boolean ignoreExtraFields) {
@@ -203,13 +267,15 @@ public final class TestHelper {
             boolean found = false;
             JsonNode expectedElement = expectedArray.get(i);
             for (int k = 0; k < actualArray.size(); k++) {
-                if (!alreadyMatched.get(k) && equalJson(expectedElement, actualArray.get(k), true, ignoreExtraFields)) {
+                if (!alreadyMatched.get(k) && equalJson(expectedElement, actualArray.get(k), true, ignoreExtraFields,
+                        true, stringify(actualArray))) {
                     alreadyMatched.set(k);
                     found = true;
                     break;
                 }
             }
             if (!found) {
+                LOGGER.info("unordered array comparison failed; expected={} actual={}", expectedArray, actualArray);
                 return false;
             }
         }
@@ -218,7 +284,8 @@ public final class TestHelper {
 
     private static boolean compareOrdered(ArrayNode expectedArray, ArrayNode actualArray, boolean ignoreExtraFields) {
         for (int i = 0, size = expectedArray.size(); i < size; i++) {
-            if (!equalJson(expectedArray.get(i), actualArray.get(i), false, ignoreExtraFields)) {
+            if (!equalJson(expectedArray.get(i), actualArray.get(i), false, ignoreExtraFields, false,
+                    stringify(actualArray))) {
                 return false;
             }
         }
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppRQGTestBase.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppRQGTestBase.java
index c03d23b..434b368 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppRQGTestBase.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/SqlppRQGTestBase.java
@@ -164,7 +164,7 @@ public abstract class SqlppRQGTestBase {
                     ResultExtractor.extract(resultStream, StandardCharsets.UTF_8, TestCaseContext.OutputFormat.ADM));
         }
 
-        boolean eq = TestHelper.equalJson(sqlResult, sqlppResult, false, false);
+        boolean eq = TestHelper.equalJson(sqlResult, sqlppResult, false, false, false, null);
 
         File sqlResultFile = writeResult(sqlResult, testcaseId, "sql", testcaseDescription);
         File sqlppResultFile = writeResult(sqlppResult, testcaseId, "sqlpp", testcaseDescription);
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/cluster_state_1/cluster_state_1.1.get.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/cluster_state_1/cluster_state_1.1.get.http
index 08577ae..729c5d5 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/cluster_state_1/cluster_state_1.1.get.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/cluster_state_1/cluster_state_1.1.get.http
@@ -22,4 +22,5 @@
  * Expected Result : Success
  * Date            : 7th September 2016
  */
+--prettifyjsonresult=true
 /admin/cluster
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/diagnostics_1/diagnostics_1.1.get.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/diagnostics_1/diagnostics_1.1.get.http
index c309110..58fa336 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/diagnostics_1/diagnostics_1.1.get.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/diagnostics_1/diagnostics_1.1.get.http
@@ -22,4 +22,5 @@
  * Expected Result : Positive
  * Date            : 8th September 2016
  */
+--prettifyjsonresult=true
 /admin/diagnostics
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/net-diagnostics/net-diagnostics.1.get.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/net-diagnostics/net-diagnostics.1.get.http
index 12288a4..d98e4e8 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/net-diagnostics/net-diagnostics.1.get.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/net-diagnostics/net-diagnostics.1.get.http
@@ -16,4 +16,5 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+--prettifyjsonresult=true
 nc:asterix_nc1 /admin/net
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/add_replica/add_replica.2.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/add_replica/add_replica.2.pollget.http
index 6867a5d..c007931 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/add_replica/add_replica.2.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/add_replica/add_replica.2.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=30
+//prettifyjsonresult=true
 
 nc:asterix_nc1 /admin/storage/partition/0
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload/bulkload.11.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload/bulkload.11.pollget.http
index 32e2f78..274e20f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload/bulkload.11.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload/bulkload.11.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=30
+//prettifyjsonresult=true
 
 /admin/cluster/summary
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload/bulkload.3.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload/bulkload.3.pollget.http
index 4ea16d7..dc82c61 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload/bulkload.3.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload/bulkload.3.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=30
+//prettifyjsonresult=true
 
 nc:asterix_nc2 /admin/storage/partition/2
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload/bulkload.4.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload/bulkload.4.pollget.http
index 22558bc..c114930 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload/bulkload.4.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload/bulkload.4.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=30
+//prettifyjsonresult=true
 
 nc:asterix_nc2 /admin/storage/partition/3
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload_with_compression/bulkload.11.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload_with_compression/bulkload.11.pollget.http
index 32e2f78..274e20f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload_with_compression/bulkload.11.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload_with_compression/bulkload.11.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=30
+//prettifyjsonresult=true
 
 /admin/cluster/summary
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload_with_compression/bulkload.3.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload_with_compression/bulkload.3.pollget.http
index 4ea16d7..dc82c61 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload_with_compression/bulkload.3.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload_with_compression/bulkload.3.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=30
+//prettifyjsonresult=true
 
 nc:asterix_nc2 /admin/storage/partition/2
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload_with_compression/bulkload.4.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload_with_compression/bulkload.4.pollget.http
index 22558bc..c114930 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload_with_compression/bulkload.4.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/bulkload_with_compression/bulkload.4.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=30
+//prettifyjsonresult=true
 
 nc:asterix_nc2 /admin/storage/partition/3
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component/flushed_component.2.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component/flushed_component.2.pollget.http
index 6867a5d..c007931 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component/flushed_component.2.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component/flushed_component.2.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=30
+//prettifyjsonresult=true
 
 nc:asterix_nc1 /admin/storage/partition/0
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component/flushed_component.8.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component/flushed_component.8.pollget.http
index 32e2f78..274e20f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component/flushed_component.8.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component/flushed_component.8.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=30
+//prettifyjsonresult=true
 
 /admin/cluster/summary
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component_compressed/flushed_component_compressed.12.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component_compressed/flushed_component_compressed.12.pollget.http
index 32e2f78..274e20f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component_compressed/flushed_component_compressed.12.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component_compressed/flushed_component_compressed.12.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=30
+//prettifyjsonresult=true
 
 /admin/cluster/summary
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component_compressed/flushed_component_compressed.3.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component_compressed/flushed_component_compressed.3.pollget.http
index 4ea16d7..dc82c61 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component_compressed/flushed_component_compressed.3.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component_compressed/flushed_component_compressed.3.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=30
+//prettifyjsonresult=true
 
 nc:asterix_nc2 /admin/storage/partition/2
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component_compressed/flushed_component_compressed.4.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component_compressed/flushed_component_compressed.4.pollget.http
index 22558bc..c114930 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component_compressed/flushed_component_compressed.4.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/flushed_component_compressed/flushed_component_compressed.4.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=30
+//prettifyjsonresult=true
 
 nc:asterix_nc2 /admin/storage/partition/3
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/mem_component_recovery/mem_component_recovery.11.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/mem_component_recovery/mem_component_recovery.11.pollget.http
index 32e2f78..274e20f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/mem_component_recovery/mem_component_recovery.11.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/mem_component_recovery/mem_component_recovery.11.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=30
+//prettifyjsonresult=true
 
 /admin/cluster/summary
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/mem_component_recovery/mem_component_recovery.3.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/mem_component_recovery/mem_component_recovery.3.pollget.http
index 4ea16d7..dc82c61 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/mem_component_recovery/mem_component_recovery.3.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/mem_component_recovery/mem_component_recovery.3.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=30
+//prettifyjsonresult=true
 
 nc:asterix_nc2 /admin/storage/partition/2
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/mem_component_recovery/mem_component_recovery.4.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/mem_component_recovery/mem_component_recovery.4.pollget.http
index 22558bc..c114930 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/mem_component_recovery/mem_component_recovery.4.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/mem_component_recovery/mem_component_recovery.4.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=30
+//prettifyjsonresult=true
 
 nc:asterix_nc2 /admin/storage/partition/3
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/metadata_failover/metadata_failover.2.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/metadata_failover/metadata_failover.2.pollget.http
index 6867a5d..c007931 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/metadata_failover/metadata_failover.2.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/metadata_failover/metadata_failover.2.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=30
+//prettifyjsonresult=true
 
 nc:asterix_nc1 /admin/storage/partition/0
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/metadata_failover/metadata_failover.5.get.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/metadata_failover/metadata_failover.5.get.http
index 4a53aed..1a63ce7 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/metadata_failover/metadata_failover.5.get.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/metadata_failover/metadata_failover.5.get.http
@@ -16,4 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+//prettifyjsonresult=true
+
 nc:asterix_nc2 /admin/storage
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/metadata_failover/metadata_failover.8.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/metadata_failover/metadata_failover.8.pollget.http
index 32e2f78..274e20f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/metadata_failover/metadata_failover.8.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/metadata_failover/metadata_failover.8.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=30
+//prettifyjsonresult=true
 
 /admin/cluster/summary
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/release_partition/release_partition.2.pollget.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/release_partition/release_partition.2.pollget.http
index 6867a5d..c007931 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/release_partition/release_partition.2.pollget.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/release_partition/release_partition.2.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=30
+//prettifyjsonresult=true
 
 nc:asterix_nc1 /admin/storage/partition/0
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/release_partition/release_partition.4.get.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/release_partition/release_partition.4.get.http
index 74ebe94..53d75bc 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/release_partition/release_partition.4.get.http
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/replication/release_partition/release_partition.4.get.http
@@ -16,4 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+//prettifyjsonresult=true
+
 nc:asterix_nc1:19004 /admin/storage/partition/0
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/replication/metadata_failover/metadata_failover.11.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/replication/metadata_failover/metadata_failover.11.adm
index d0138cb..56a6051 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/replication/metadata_failover/metadata_failover.11.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/replication/metadata_failover/metadata_failover.11.adm
@@ -1,3 +1 @@
-1
-
-
+1
\ No newline at end of file
diff --git a/asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/queries/networking/reuse_data_port/reuse_data_port.4.pollget.http b/asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/queries/networking/reuse_data_port/reuse_data_port.4.pollget.http
index 777e3dd..6f904df 100644
--- a/asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/queries/networking/reuse_data_port/reuse_data_port.4.pollget.http
+++ b/asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/queries/networking/reuse_data_port/reuse_data_port.4.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=60
+//prettifyjsonresult=true
 
 /admin/cluster/summary
\ No newline at end of file
diff --git a/asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/queries/networking/reuse_data_port/reuse_data_port.7.pollget.http b/asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/queries/networking/reuse_data_port/reuse_data_port.7.pollget.http
index 777e3dd..6f904df 100644
--- a/asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/queries/networking/reuse_data_port/reuse_data_port.7.pollget.http
+++ b/asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/queries/networking/reuse_data_port/reuse_data_port.7.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=60
+//prettifyjsonresult=true
 
 /admin/cluster/summary
\ No newline at end of file
diff --git a/asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/results/networking/reuse_data_port/reuse_data_port.5.adm b/asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/results/networking/reuse_data_port/reuse_data_port.4.json
similarity index 100%
rename from asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/results/networking/reuse_data_port/reuse_data_port.5.adm
rename to asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/results/networking/reuse_data_port/reuse_data_port.4.json
diff --git a/asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/results/networking/reuse_data_port/reuse_data_port.7.adm b/asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/results/networking/reuse_data_port/reuse_data_port.7.json
similarity index 100%
rename from asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/results/networking/reuse_data_port/reuse_data_port.7.adm
rename to asterixdb/asterix-server/src/test/resources/integrationts/NcLifecycle/results/networking/reuse_data_port/reuse_data_port.7.json
diff --git a/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.10.pollget.http b/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.10.pollget.http
index 6867a5d..c007931 100644
--- a/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.10.pollget.http
+++ b/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.10.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=30
+//prettifyjsonresult=true
 
 nc:asterix_nc1 /admin/storage/partition/0
\ No newline at end of file
diff --git a/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.13.pollget.http b/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.13.pollget.http
index 32e2f78..274e20f 100644
--- a/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.13.pollget.http
+++ b/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.13.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=30
+//prettifyjsonresult=true
 
 /admin/cluster/summary
\ No newline at end of file
diff --git a/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.2.pollget.http b/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.2.pollget.http
index 6867a5d..c007931 100644
--- a/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.2.pollget.http
+++ b/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.2.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=30
+//prettifyjsonresult=true
 
 nc:asterix_nc1 /admin/storage/partition/0
\ No newline at end of file
diff --git a/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.5.pollget.http b/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.5.pollget.http
index 777e3dd..6f904df 100644
--- a/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.5.pollget.http
+++ b/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.5.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=60
+//prettifyjsonresult=true
 
 /admin/cluster/summary
\ No newline at end of file
diff --git a/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.6.pollget.http b/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.6.pollget.http
index 6867a5d..c007931 100644
--- a/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.6.pollget.http
+++ b/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.6.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=30
+//prettifyjsonresult=true
 
 nc:asterix_nc1 /admin/storage/partition/0
\ No newline at end of file
diff --git a/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.8.pollget.http b/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.8.pollget.http
index 777e3dd..6f904df 100644
--- a/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.8.pollget.http
+++ b/asterixdb/asterix-server/src/test/resources/integrationts/replication/queries/failover/resync_failed_replica/resync_failed_replica.8.pollget.http
@@ -17,5 +17,6 @@
  * under the License.
  */
 //polltimeoutsecs=60
+//prettifyjsonresult=true
 
 /admin/cluster/summary
\ No newline at end of file
diff --git a/asterixdb/pom.xml b/asterixdb/pom.xml
index 5cc17af..f89f0ac 100644
--- a/asterixdb/pom.xml
+++ b/asterixdb/pom.xml
@@ -200,6 +200,8 @@
             <exclude>**/*.iml</exclude>
             <exclude>**/*.json</exclude>
             <exclude>**/*.adm</exclude>
+            <exclude>**/*.regexadm</exclude>
+            <exclude>**/*.regexjson</exclude>
             <exclude>**/*.template</exclude>
             <exclude>asterix-installer/**</exclude> <!-- in case -DskipInstaller -->
           </excludes>
diff --git a/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/JSONUtil.java b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/JSONUtil.java
index b66d31d..5c1b292 100644
--- a/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/JSONUtil.java
+++ b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/JSONUtil.java
@@ -28,27 +28,18 @@ import java.util.stream.IntStream;
 import java.util.stream.LongStream;
 import java.util.stream.Stream;
 
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.MapperFeature;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.ObjectWriter;
 import com.fasterxml.jackson.databind.SerializationFeature;
 import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 
 public class JSONUtil {
 
-    private static final Logger LOGGER = LogManager.getLogger();
     private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
-
-    private static final String INDENT = "\t";
-
     private static final ObjectMapper SORTED_MAPPER = new ObjectMapper();
-    private static final ObjectWriter PRETTY_SORTED_WRITER;
 
     private JSONUtil() {
     }
@@ -56,11 +47,10 @@ public class JSONUtil {
     static {
         SORTED_MAPPER.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
         SORTED_MAPPER.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true);
-        PRETTY_SORTED_WRITER = SORTED_MAPPER.writerWithDefaultPrettyPrinter();
     }
 
     public static String convertNode(final JsonNode node) throws JsonProcessingException {
-        return PRETTY_SORTED_WRITER.writeValueAsString(SORTED_MAPPER.treeToValue(node, Object.class));
+        return SORTED_MAPPER.writeValueAsString(SORTED_MAPPER.treeToValue(node, Object.class));
     }
 
     public static String convertNodeOrThrow(final JsonNode node) {
@@ -72,87 +62,7 @@ public class JSONUtil {
     }
 
     public static void writeNode(final Writer writer, final JsonNode node) throws IOException {
-        PRETTY_SORTED_WRITER.writeValue(writer, SORTED_MAPPER.treeToValue(node, Object.class));
-    }
-
-    public static String indent(String str, int initialIndent) {
-        ObjectMapper om = new ObjectMapper();
-        try {
-            return appendObj(new StringBuilder(), om.readTree(str), initialIndent).toString();
-        } catch (IOException e) {
-            LOGGER.trace(String.valueOf(e));
-            LOGGER.trace("Could not indent JSON string, returning the input string: " + str);
-            return str;
-        }
-    }
-
-    private static StringBuilder appendOrd(StringBuilder sb, JsonNode o, int indent) {
-        if (o.isObject()) {
-            return appendObj(sb, o, indent);
-        } else if (o.isArray()) {
-            return appendAry(sb, o, indent);
-        } else if (o.isTextual()) {
-            return quoteAndEscape(sb, o.asText());
-        } else if (o.isNull() || o.isIntegralNumber() || o.isBoolean()) {
-            return sb.append(String.valueOf(o));
-        }
-        throw new UnsupportedOperationException(o.getClass().getSimpleName());
-    }
-
-    private static StringBuilder appendObj(final StringBuilder sb, final JsonNode outer, final int indent) {
-        sb.append("{\n");
-        boolean first = true;
-        for (JsonNode inner : outer) {
-            final String key = inner.asText();
-            if (first) {
-                first = false;
-            } else {
-                sb.append(",\n");
-            }
-            indent(sb, indent + 1);
-            quote(sb, key);
-            sb.append(": ");
-            appendVal(sb, outer.get(key), indent);
-        }
-        sb.append("\n");
-        return indent(sb, indent).append("}");
-    }
-
-    private static StringBuilder appendVal(final StringBuilder sb, final JsonNode value, final int indent) {
-        if (value.isArray()) {
-            appendAry(sb, value, indent + 1);
-        } else if (value.isObject()) {
-            appendObj(sb, value, indent + 1);
-        } else {
-            appendOrd(sb, value, indent + 1);
-        }
-        return sb;
-    }
-
-    private static StringBuilder appendAry(final StringBuilder sb, JsonNode jarr, int indent) {
-        sb.append("[\n");
-        for (int i = 0; i < jarr.size(); ++i) {
-            if (i > 0) {
-                sb.append(",\n");
-            }
-            indent(sb, indent + 1);
-            appendVal(sb, jarr.get(i), indent);
-        }
-        sb.append("\n");
-        return indent(sb, indent).append("]");
-    }
-
-    private static StringBuilder quote(StringBuilder sb, String str) {
-        return sb.append('"').append(str).append('"');
-    }
-
-    private static StringBuilder indent(StringBuilder sb, int i) {
-        int indent = i;
-        while (indent > 0) {
-            sb.append(INDENT);
-            --indent;
-        }
-        return sb;
+        SORTED_MAPPER.writeValue(writer, SORTED_MAPPER.treeToValue(node, Object.class));
     }
 
     public static String quoteAndEscape(String str) {