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 2017/03/31 01:24:28 UTC

asterixdb git commit: Support -version Argument For CC/NC Drivers

Repository: asterixdb
Updated Branches:
  refs/heads/master 309ef98b8 -> 1fb232d96


Support -version Argument For CC/NC Drivers

Output the build version when -version is passed to asterixcc/asterixnc

Change-Id: I7ba105f693170ba781897dd2039783e1c5f6544b
Reviewed-on: https://asterix-gerrit.ics.uci.edu/1637
Reviewed-by: Till Westmann <ti...@apache.org>
Sonar-Qube: Jenkins <je...@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <je...@fulliautomatix.ics.uci.edu>


Project: http://git-wip-us.apache.org/repos/asf/asterixdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/asterixdb/commit/1fb232d9
Tree: http://git-wip-us.apache.org/repos/asf/asterixdb/tree/1fb232d9
Diff: http://git-wip-us.apache.org/repos/asf/asterixdb/diff/1fb232d9

Branch: refs/heads/master
Commit: 1fb232d9621f04bd635e647d5c4a7630279b093f
Parents: 309ef98
Author: Michael Blow <mb...@apache.org>
Authored: Thu Mar 30 20:11:34 2017 -0400
Committer: Michael Blow <mb...@apache.org>
Committed: Thu Mar 30 18:24:03 2017 -0700

----------------------------------------------------------------------
 .../api/http/server/ClusterApiServlet.java      |  14 +-
 .../api/http/server/QueryServiceServlet.java    |   2 +-
 .../asterix/api/http/server/ResultUtil.java     |   2 +-
 .../api/http/server/ShutdownApiServlet.java     |   2 +-
 .../asterix/app/result/ResultPrinter.java       |   2 +-
 .../bootstrap/ApplicationConfigurator.java      |  19 ++
 .../apache/asterix/common/utils/JSONUtil.java   | 178 -------------------
 .../hyracks/api/config/IConfigManager.java      |   2 +
 .../control/common/config/ConfigManager.java    |  35 ++--
 .../org/apache/hyracks/control/nc/NCDriver.java |   4 +-
 hyracks-fullstack/hyracks/hyracks-util/pom.xml  |   8 +
 .../java/org/apache/hyracks/util/JSONUtil.java  | 177 ++++++++++++++++++
 12 files changed, 243 insertions(+), 202 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1fb232d9/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ClusterApiServlet.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ClusterApiServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ClusterApiServlet.java
index 6b16be1..984eef2 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ClusterApiServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ClusterApiServlet.java
@@ -28,12 +28,6 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.regex.Pattern;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import io.netty.handler.codec.http.HttpHeaderNames;
-import io.netty.handler.codec.http.HttpResponseStatus;
-import org.apache.asterix.common.utils.JSONUtil;
 import org.apache.asterix.runtime.utils.AppContextInfo;
 import org.apache.asterix.runtime.utils.ClusterStateManager;
 import org.apache.hyracks.api.config.IOption;
@@ -44,6 +38,14 @@ import org.apache.hyracks.http.api.IServletRequest;
 import org.apache.hyracks.http.api.IServletResponse;
 import org.apache.hyracks.http.server.AbstractServlet;
 import org.apache.hyracks.http.server.utils.HttpUtil;
+import org.apache.hyracks.util.JSONUtil;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+import io.netty.handler.codec.http.HttpHeaderNames;
+import io.netty.handler.codec.http.HttpResponseStatus;
 
 public class ClusterApiServlet extends AbstractServlet {
 

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1fb232d9/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
index 101fa97..faf9968 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
@@ -35,7 +35,6 @@ import org.apache.asterix.common.api.IClusterManagementWork;
 import org.apache.asterix.common.config.GlobalConfig;
 import org.apache.asterix.common.context.IStorageComponentProvider;
 import org.apache.asterix.common.exceptions.AsterixException;
-import org.apache.asterix.common.utils.JSONUtil;
 import org.apache.asterix.compiler.provider.ILangCompilationProvider;
 import org.apache.asterix.lang.aql.parser.TokenMgrError;
 import org.apache.asterix.lang.common.base.IParser;
@@ -52,6 +51,7 @@ import org.apache.hyracks.algebricks.core.algebra.prettyprint.AlgebricksAppendab
 import org.apache.hyracks.http.api.IServletRequest;
 import org.apache.hyracks.http.api.IServletResponse;
 import org.apache.hyracks.http.server.utils.HttpUtil;
+import org.apache.hyracks.util.JSONUtil;
 
 import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.core.JsonProcessingException;

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1fb232d9/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ResultUtil.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ResultUtil.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ResultUtil.java
index 18bd7b6..a257958 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ResultUtil.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ResultUtil.java
@@ -36,7 +36,6 @@ import java.util.stream.Stream;
 import org.apache.asterix.app.result.ResultHandle;
 import org.apache.asterix.app.result.ResultPrinter;
 import org.apache.asterix.app.result.ResultReader;
-import org.apache.asterix.common.utils.JSONUtil;
 import org.apache.asterix.om.types.ARecordType;
 import org.apache.asterix.translator.IStatementExecutor.Stats;
 import org.apache.asterix.translator.SessionConfig;
@@ -44,6 +43,7 @@ import org.apache.http.ParseException;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.core.algebra.prettyprint.AlgebricksAppendable;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.util.JSONUtil;
 import org.apache.log4j.Logger;
 
 import com.fasterxml.jackson.databind.ObjectMapper;

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1fb232d9/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ShutdownApiServlet.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ShutdownApiServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ShutdownApiServlet.java
index 3d9602d..fdd106d 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ShutdownApiServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ShutdownApiServlet.java
@@ -28,13 +28,13 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import org.apache.asterix.common.config.GlobalConfig;
-import org.apache.asterix.common.utils.JSONUtil;
 import org.apache.asterix.runtime.utils.ClusterStateManager;
 import org.apache.hyracks.api.client.IHyracksClientConnection;
 import org.apache.hyracks.http.api.IServletRequest;
 import org.apache.hyracks.http.api.IServletResponse;
 import org.apache.hyracks.http.server.AbstractServlet;
 import org.apache.hyracks.http.server.utils.HttpUtil;
+import org.apache.hyracks.util.JSONUtil;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ArrayNode;

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1fb232d9/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/result/ResultPrinter.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/result/ResultPrinter.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/result/ResultPrinter.java
index 61d0eed..c77ad44 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/result/ResultPrinter.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/result/ResultPrinter.java
@@ -24,7 +24,6 @@ import java.io.IOException;
 import java.io.StringWriter;
 import java.nio.ByteBuffer;
 
-import org.apache.asterix.common.utils.JSONUtil;
 import org.apache.asterix.om.types.ARecordType;
 import org.apache.asterix.translator.IStatementExecutor.Stats;
 import org.apache.asterix.translator.SessionConfig;
@@ -35,6 +34,7 @@ import org.apache.hyracks.api.comm.IFrameTupleAccessor;
 import org.apache.hyracks.api.comm.VSizeFrame;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 import org.apache.hyracks.control.nc.resources.memory.FrameManager;
+import org.apache.hyracks.util.JSONUtil;
 
 import com.fasterxml.jackson.core.JsonGenerator;
 import com.fasterxml.jackson.core.PrettyPrinter;

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1fb232d9/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/ApplicationConfigurator.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/ApplicationConfigurator.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/ApplicationConfigurator.java
index 4a5371a..466203c 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/ApplicationConfigurator.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/ApplicationConfigurator.java
@@ -18,6 +18,11 @@
  */
 package org.apache.asterix.hyracks.bootstrap;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.util.Properties;
+
 import org.apache.asterix.common.config.AsterixProperties;
 import org.apache.hyracks.api.config.IConfigManager;
 import org.apache.hyracks.control.common.controllers.CCConfig;
@@ -34,5 +39,19 @@ class ApplicationConfigurator {
         ControllerConfig.defaultDir = FileUtil.joinPath(System.getProperty("java.io.tmpdir"), "asterixdb");
         NCConfig.defaultAppClass = NCApplication.class.getName();
         CCConfig.defaultAppClass = CCApplication.class.getName();
+        try {
+            InputStream propertyStream = ApplicationConfigurator.class.getClassLoader()
+                    .getResourceAsStream("git.properties");
+            if (propertyStream != null) {
+                Properties gitProperties = new Properties();
+                gitProperties.load(propertyStream);
+                StringWriter sw = new StringWriter();
+                gitProperties.store(sw, null);
+                configManager.setVersionString(sw.toString());
+            }
+        } catch (IOException e) {
+            throw new IllegalStateException(e);
+        }
+
     }
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1fb232d9/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/JSONUtil.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/JSONUtil.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/JSONUtil.java
deleted file mode 100644
index 80df260..0000000
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/JSONUtil.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.asterix.common.utils;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializationFeature;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.logging.Logger;
-
-public class JSONUtil {
-
-    private static final Logger LOGGER = Logger.getLogger(JSONUtil.class.getName());
-
-    private static final String INDENT = "\t";
-
-    private static final ObjectMapper SORTED_MAPPER = new ObjectMapper();
-
-    private JSONUtil() {
-    }
-
-    static {
-        SORTED_MAPPER.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
-    }
-
-    public static String convertNode(final JsonNode node) throws JsonProcessingException {
-        final Object obj = SORTED_MAPPER.treeToValue(node, Object.class);
-        final String json = SORTED_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
-        return json;
-    }
-
-    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.finest(String.valueOf(e));
-            LOGGER.finest("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(StringBuilder builder, JsonNode jobj, int indent) {
-        StringBuilder sb = builder.append("{\n");
-        boolean first = true;
-        for (Iterator<JsonNode> it = jobj.iterator(); it.hasNext();) {
-            final String key = it.next().asText();
-            if (first) {
-                first = false;
-            } else {
-                sb = sb.append(",\n");
-            }
-            sb = indent(sb, indent + 1);
-            sb = quote(sb, key);
-            sb = sb.append(": ");
-            if (jobj.get(key).isArray()) {
-                sb = appendAry(sb, jobj.get(key), indent + 1);
-            } else if (jobj.get(key).isObject()) {
-                sb = appendObj(sb, jobj.get(key), indent + 1);
-            } else {
-                sb = appendOrd(sb, jobj.get(key), indent + 1);
-            }
-        }
-        sb = sb.append("\n");
-        return indent(sb, indent).append("}");
-    }
-
-    private static StringBuilder appendAry(StringBuilder builder, JsonNode jarr, int indent) {
-        StringBuilder sb = builder.append("[\n");
-        for (int i = 0; i < jarr.size(); ++i) {
-            if (i > 0) {
-                sb = sb.append(",\n");
-            }
-            sb = indent(sb, indent + 1);
-            if (jarr.get(i).isArray()) {
-                sb = appendAry(sb, jarr.get(i), indent + 1);
-            } else if (jarr.get(i).isObject()) {
-                sb = appendObj(sb, jarr.get(i), indent + 1);
-            } else {
-                sb = appendOrd(sb, jarr.get(i), indent + 1);
-            }
-        }
-        sb = 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;
-    }
-
-    public static String quoteAndEscape(String str) {
-        return quoteAndEscape(new StringBuilder(), str).toString();
-    }
-
-    private static StringBuilder quoteAndEscape(StringBuilder sb, String str) {
-        return escape(sb.append('"'), str).append('"');
-    }
-
-    public static String escape(String str) {
-        return escape(new StringBuilder(), str).toString();
-    }
-
-    public static StringBuilder escape(StringBuilder sb, String str) {
-        for (int i = 0; i < str.length(); ++i) {
-            appendEsc(sb, str.charAt(i));
-        }
-        return sb;
-    }
-
-    private static StringBuilder appendEsc(StringBuilder sb, char c) {
-        CharSequence cs = esc(c);
-        return cs != null ? sb.append(cs) : sb.append(c);
-    }
-
-    public static CharSequence esc(char c) {
-        switch (c) {
-            case '"':
-                return "\\\"";
-            case '\\':
-                return "\\\\";
-            case '/':
-                return "\\/";
-            case '\b':
-                return "\\b";
-            case '\n':
-                return "\\n";
-            case '\f':
-                return "\\f";
-            case '\r':
-                return "\\r";
-            case '\t':
-                return "\\t";
-            default:
-                return null;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1fb232d9/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/config/IConfigManager.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/config/IConfigManager.java b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/config/IConfigManager.java
index 3944820..777f7a7 100644
--- a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/config/IConfigManager.java
+++ b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/config/IConfigManager.java
@@ -62,4 +62,6 @@ public interface IConfigManager {
     void addCmdLineSections(Section... sections);
 
     void setUsageFilter(OptionHandlerFilter usageFilter);
+
+    void setVersionString(String versionString);
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1fb232d9/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/config/ConfigManager.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/config/ConfigManager.java b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/config/ConfigManager.java
index 04cf704..63163bb 100644
--- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/config/ConfigManager.java
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/config/ConfigManager.java
@@ -82,6 +82,7 @@ public class ConfigManager implements IConfigManager, Serializable {
     private transient OptionHandlerFilter usageFilter;
     private transient SortedMap<Integer, List<IConfigurator>> configurators = new TreeMap<>();
     private boolean configured;
+    private String versionString = "version undefined";
 
     public ConfigManager() {
         this(null);
@@ -173,6 +174,11 @@ public class ConfigManager implements IConfigManager, Serializable {
         }
     }
 
+    @Override
+    public void setVersionString(String versionString) {
+        this.versionString = versionString;
+    }
+
     public IOption lookupOption(String section, String key) {
         Map<String, IOption> map = getSectionOptionMap(Section.parseSectionName(section));
         return map == null ? null : map.get(key);
@@ -242,25 +248,27 @@ public class ConfigManager implements IConfigManager, Serializable {
                     new Args4jArgument());
         }
         LOGGER.fine("parsing cmdline: " + Arrays.toString(args));
+        if (args == null || args.length == 0) {
+            LOGGER.info("no command line args supplied");
+            return appArgs;
+        }
         try {
-            if (args == null || args.length == 0) {
-                LOGGER.info("no command line args supplied");
-                return appArgs;
-            }
             cmdLineParser.parseArgument(args);
-            if (bean.help) {
-                ConfigUtils.printUsage(cmdLineParser, usageFilter, System.err);
-                System.exit(0);
-            }
         } catch (CmdLineException e) {
-            if (bean.help) {
-                ConfigUtils.printUsage(cmdLineParser, usageFilter, System.err);
-                System.exit(0);
-            } else {
+            if (!bean.help) {
                 ConfigUtils.printUsage(e, usageFilter, System.err);
                 throw e;
+            } else {
+                LOGGER.log(Level.FINE, "Ignoring parse exception due to -help", e);
             }
         }
+        if (bean.help) {
+            ConfigUtils.printUsage(cmdLineParser, usageFilter, System.err);
+            System.exit(0);
+        } else if (bean.version) {
+            System.err.println(versionString);
+            System.exit(0);
+        }
         return appArgs;
     }
 
@@ -549,5 +557,8 @@ public class ConfigManager implements IConfigManager, Serializable {
     private static class Args4jBean {
         @Option(name = "-help", help = true)
         boolean help;
+
+        @Option(name = "-version", help = true)
+        boolean version;
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1fb232d9/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/NCDriver.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/NCDriver.java b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/NCDriver.java
index d36586f..9d649f6 100644
--- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/NCDriver.java
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-nc/src/main/java/org/apache/hyracks/control/nc/NCDriver.java
@@ -44,8 +44,8 @@ public class NCDriver {
             application.registerConfig(configManager);
             NCConfig ncConfig = new NCConfig(nodeId, configManager);
             final NodeControllerService ncService = new NodeControllerService(ncConfig, application);
-            if (LOGGER.isLoggable(Level.SEVERE)) {
-                LOGGER.severe("Setting uncaught exception handler " + ncService.getLifeCycleComponentManager());
+            if (LOGGER.isLoggable(Level.INFO)) {
+                LOGGER.info("Setting uncaught exception handler " + ncService.getLifeCycleComponentManager());
             }
             Thread.currentThread().setUncaughtExceptionHandler(ncService.getLifeCycleComponentManager());
             ncService.start();

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1fb232d9/hyracks-fullstack/hyracks/hyracks-util/pom.xml
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-util/pom.xml b/hyracks-fullstack/hyracks/hyracks-util/pom.xml
index 864bd8e..420ce79 100644
--- a/hyracks-fullstack/hyracks/hyracks-util/pom.xml
+++ b/hyracks-fullstack/hyracks/hyracks-util/pom.xml
@@ -51,6 +51,14 @@
       <artifactId>junit</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-databind</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.fasterxml.jackson.core</groupId>
+      <artifactId>jackson-core</artifactId>
+    </dependency>
   </dependencies>
 
 </project>

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/1fb232d9/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/JSONUtil.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..7075417
--- /dev/null
+++ b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/JSONUtil.java
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.hyracks.util;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.logging.Logger;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+
+public class JSONUtil {
+
+    private static final Logger LOGGER = Logger.getLogger(JSONUtil.class.getName());
+
+    private static final String INDENT = "\t";
+
+    private static final ObjectMapper SORTED_MAPPER = new ObjectMapper();
+
+    private JSONUtil() {
+    }
+
+    static {
+        SORTED_MAPPER.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
+    }
+
+    public static String convertNode(final JsonNode node) throws JsonProcessingException {
+        final Object obj = SORTED_MAPPER.treeToValue(node, Object.class);
+        return SORTED_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
+    }
+
+    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.finest(String.valueOf(e));
+            LOGGER.finest("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(StringBuilder builder, JsonNode jobj, int indent) {
+        StringBuilder sb = builder.append("{\n");
+        boolean first = true;
+        for (Iterator<JsonNode> it = jobj.iterator(); it.hasNext();) {
+            final String key = it.next().asText();
+            if (first) {
+                first = false;
+            } else {
+                sb = sb.append(",\n");
+            }
+            sb = indent(sb, indent + 1);
+            sb = quote(sb, key);
+            sb = sb.append(": ");
+            if (jobj.get(key).isArray()) {
+                sb = appendAry(sb, jobj.get(key), indent + 1);
+            } else if (jobj.get(key).isObject()) {
+                sb = appendObj(sb, jobj.get(key), indent + 1);
+            } else {
+                sb = appendOrd(sb, jobj.get(key), indent + 1);
+            }
+        }
+        sb = sb.append("\n");
+        return indent(sb, indent).append("}");
+    }
+
+    private static StringBuilder appendAry(StringBuilder builder, JsonNode jarr, int indent) {
+        StringBuilder sb = builder.append("[\n");
+        for (int i = 0; i < jarr.size(); ++i) {
+            if (i > 0) {
+                sb = sb.append(",\n");
+            }
+            sb = indent(sb, indent + 1);
+            if (jarr.get(i).isArray()) {
+                sb = appendAry(sb, jarr.get(i), indent + 1);
+            } else if (jarr.get(i).isObject()) {
+                sb = appendObj(sb, jarr.get(i), indent + 1);
+            } else {
+                sb = appendOrd(sb, jarr.get(i), indent + 1);
+            }
+        }
+        sb = 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;
+    }
+
+    public static String quoteAndEscape(String str) {
+        return quoteAndEscape(new StringBuilder(), str).toString();
+    }
+
+    private static StringBuilder quoteAndEscape(StringBuilder sb, String str) {
+        return escape(sb.append('"'), str).append('"');
+    }
+
+    public static String escape(String str) {
+        return escape(new StringBuilder(), str).toString();
+    }
+
+    public static StringBuilder escape(StringBuilder sb, String str) {
+        for (int i = 0; i < str.length(); ++i) {
+            appendEsc(sb, str.charAt(i));
+        }
+        return sb;
+    }
+
+    private static StringBuilder appendEsc(StringBuilder sb, char c) {
+        CharSequence cs = esc(c);
+        return cs != null ? sb.append(cs) : sb.append(c);
+    }
+
+    public static CharSequence esc(char c) {
+        switch (c) {
+            case '"':
+                return "\\\"";
+            case '\\':
+                return "\\\\";
+            case '/':
+                return "\\/";
+            case '\b':
+                return "\\b";
+            case '\n':
+                return "\\n";
+            case '\f':
+                return "\\f";
+            case '\r':
+                return "\\r";
+            case '\t':
+                return "\\t";
+            default:
+                return null;
+        }
+    }
+}