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 <tillw@apache.org>
Sonar-Qube: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
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.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.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 {
 
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.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.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;
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 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.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;
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.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;
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.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.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;
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 @@
         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);
+        }
+
     }
 }
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 @@
     void addCmdLineSections(Section... sections);
 
     void setUsageFilter(OptionHandlerFilter usageFilter);
+
+    void setVersionString(String versionString);
 }
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 @@
     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 @@
         }
     }
 
+    @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 @@
                     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 @@
     private static class Args4jBean {
         @Option(name = "-help", help = true)
         boolean help;
+
+        @Option(name = "-version", help = true)
+        boolean version;
     }
 }
\ No newline at end of file
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 @@
             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();
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>
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/JSONUtil.java b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/JSONUtil.java
similarity index 96%
rename from asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/JSONUtil.java
rename to hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/JSONUtil.java
index 80df260..7075417 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/utils/JSONUtil.java
+++ b/hyracks-fullstack/hyracks/hyracks-util/src/main/java/org/apache/hyracks/util/JSONUtil.java
@@ -16,17 +16,17 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.asterix.common.utils;
+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;
 
-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());
@@ -44,8 +44,7 @@
 
     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;
+        return SORTED_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
     }
 
     public static String indent(String str, int initialIndent) {