Configuration Revamp

- Ini section of node / cc details now returns ini param names instead of
  managix option names
- Normalized command line -vs- ini file configuration parameter names
- Eliminated unused parameters
- Ini validation
- Migrate *DB parameters out of [app] and into nc / cc sections as
  appropriate
- Eliminate [app] section.  Cluster-wide configuration lives in [common]
- Sort properties alphabetically when returned by HTTP api

Change-Id: I95b7e0bd4538ef42817c8826e76412150074b754
Reviewed-on: https://asterix-gerrit.ics.uci.edu/1487
Reviewed-by: Michael Blow <mblow@apache.org>
Integration-Tests: Michael Blow <mblow@apache.org>
Tested-by: Michael Blow <mblow@apache.org>
diff --git a/asterixdb/asterix-app/pom.xml b/asterixdb/asterix-app/pom.xml
index 74102a1..ede8cb1 100644
--- a/asterixdb/asterix-app/pom.xml
+++ b/asterixdb/asterix-app/pom.xml
@@ -149,11 +149,11 @@
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-dependency-plugin</artifactId>
         <configuration>
-          <ignoredUsedUndeclaredDependencies>
+          <ignoredUsedUndeclaredDependencies combine.children="append">
             <ignoredUsedUndeclaredDependency>commons-logging:commons-logging-api:*</ignoredUsedUndeclaredDependency>
             <ignoredUsedUndeclaredDependency>org.apache.hive:hive-exec:*</ignoredUsedUndeclaredDependency>
           </ignoredUsedUndeclaredDependencies>
-          <usedDependencies>
+          <usedDependencies combine.children="append">
             <usedDependency>org.apache.hadoop:hadoop-common</usedDependency>
             <usedDependency>org.apache.asterix:asterix-external-data</usedDependency>
           </usedDependencies>
diff --git a/asterixdb/asterix-app/scripts/asterix/startnc.sh b/asterixdb/asterix-app/scripts/asterix/startnc.sh
index b4b9c3c..43f9e2a 100644
--- a/asterixdb/asterix-app/scripts/asterix/startnc.sh
+++ b/asterixdb/asterix-app/scripts/asterix/startnc.sh
@@ -27,5 +27,5 @@
 
 export JAVA_OPTS="-Xmx10g -Djava.net.preferIPv4Stack=true -Djava.io.tmpdir=/mnt/data/sdd/space/onose/tmp"
 
-echo $HYRACKS_HOME/hyracks-server/target/hyracks-server-0.1.3.1-binary-assembly/bin/hyracksnc -cc-host 10.1.0.1 -cc-port 2222 -data-ip-address $IPADDR -node-id $NODEID
-$HYRACKS_HOME/hyracks-server/target/hyracks-server-0.1.3.1-binary-assembly/bin/hyracksnc -cc-host 10.1.0.1 -cc-port 2222 -data-ip-address $IPADDR -node-id $NODEID &> $LOGSDIR/$NODEID.log &
+echo $HYRACKS_HOME/hyracks-server/target/hyracks-server-0.1.3.1-binary-assembly/bin/hyracksnc -cluster-address 10.1.0.1 -cluster-port 2222 -data-listen-address $IPADDR -node-id $NODEID
+$HYRACKS_HOME/hyracks-server/target/hyracks-server-0.1.3.1-binary-assembly/bin/hyracksnc -cluster-address 10.1.0.1 -cluster-port 2222 -data-listen-address $IPADDR -node-id $NODEID &> $LOGSDIR/$NODEID.log &
diff --git a/asterixdb/asterix-app/scripts/idefix/startnc1.sh b/asterixdb/asterix-app/scripts/idefix/startnc1.sh
index e17253a..ae15596 100644
--- a/asterixdb/asterix-app/scripts/idefix/startnc1.sh
+++ b/asterixdb/asterix-app/scripts/idefix/startnc1.sh
@@ -22,4 +22,4 @@
 export JAVA_OPTS="-DAsterixConfigFileName=test.properties -Djava.util.logging.config.file=/home/nicnic/Work/Asterix/hyracks/logging.properties"
 export HYRACKS_HOME="/home/nicnic/workspace/hyracks/tags/hyracks-0.1.5"
 
-bash ${HYRACKS_HOME}/hyracks-server/target/appassembler/bin/hyracksnc -cc-host 127.0.0.1 -data-ip-address 127.0.0.1 -node-id "nc1" $* 
+bash ${HYRACKS_HOME}/hyracks-server/target/appassembler/bin/hyracksnc -cluster-address 127.0.0.1 -data-listen-address 127.0.0.1 -node-id "nc1" $*
diff --git a/asterixdb/asterix-app/scripts/idefix/startnc2.sh b/asterixdb/asterix-app/scripts/idefix/startnc2.sh
index 2074cd7..4a3e370 100644
--- a/asterixdb/asterix-app/scripts/idefix/startnc2.sh
+++ b/asterixdb/asterix-app/scripts/idefix/startnc2.sh
@@ -20,5 +20,5 @@
 export JAVA_OPTS="-DAsterixConfigFileName=test.properties -Djava.util.logging.config.file=/home/nicnic/Work/Asterix/hyracks/logging.properties"
 export HYRACKS_HOME="/home/nicnic/workspace/hyracks/tags/hyracks-0.1.5"
 
-bash ${HYRACKS_HOME}/hyracks-server/target/appassembler/bin/hyracksnc -cc-host 127.0.0.1 -data-ip-address 127.0.0.1 -node-id "nc2" $*
+bash ${HYRACKS_HOME}/hyracks-server/target/appassembler/bin/hyracksnc -cluster-address 127.0.0.1 -data-listen-address 127.0.0.1 -node-id "nc2" $*
 
diff --git a/asterixdb/asterix-app/scripts/rainbow/startnc.sh b/asterixdb/asterix-app/scripts/rainbow/startnc.sh
index 5f1dadf..3d7b75e 100644
--- a/asterixdb/asterix-app/scripts/rainbow/startnc.sh
+++ b/asterixdb/asterix-app/scripts/rainbow/startnc.sh
@@ -27,5 +27,5 @@
 
 export JAVA_OPTS="-DNodeControllerDataPath=/tmp/ncX/"
 
-echo $HYRACKS_HOME/hyracks-server/target/hyracks-server-0.1.3.1-binary-assembly/bin/hyracksnc -cc-host 128.195.52.177 -cc-port 2222 -data-ip-address $IPADDR -node-id $NODEID
-$HYRACKS_HOME/hyracks-server/target/hyracks-server-0.1.3.1-binary-assembly/bin/hyracksnc -cc-host 128.195.52.177 -cc-port 2222 -data-ip-address $IPADDR -node-id $NODEID &> $LOGSDIR/$NODEID.log &
+echo $HYRACKS_HOME/hyracks-server/target/hyracks-server-0.1.3.1-binary-assembly/bin/hyracksnc -cluster-address 128.195.52.177 -cluster-port 2222 -data-listen-address $IPADDR -node-id $NODEID
+$HYRACKS_HOME/hyracks-server/target/hyracks-server-0.1.3.1-binary-assembly/bin/hyracksnc -cluster-address 128.195.52.177 -cluster-port 2222 -data-listen-address $IPADDR -node-id $NODEID &> $LOGSDIR/$NODEID.log &
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
index 0f16179..0759599 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
@@ -34,9 +34,8 @@
 import org.apache.asterix.app.result.ResultUtil;
 import org.apache.asterix.common.config.CompilerProperties;
 import org.apache.asterix.common.config.ExternalProperties;
-import org.apache.asterix.common.config.IPropertyInterpreter;
 import org.apache.asterix.common.config.OptimizationConfUtil;
-import org.apache.asterix.common.config.PropertyInterpreters;
+import org.apache.hyracks.control.common.config.OptionTypes;
 import org.apache.asterix.common.exceptions.ACIDException;
 import org.apache.asterix.common.exceptions.CompilationException;
 import org.apache.asterix.common.utils.Job;
@@ -96,6 +95,7 @@
 import org.apache.hyracks.api.job.JobSpecification;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.hyracks.api.config.IOptionType;
 
 /**
  * Provides helper methods for compilation of a query into a JobSpec and submission
@@ -451,16 +451,15 @@
 
     // Gets the frame limit.
     private int getFrameLimit(String parameter, long memBudgetInConfiguration, int frameSize) {
-        IPropertyInterpreter<Long> longBytePropertyInterpreter = PropertyInterpreters.getLongBytePropertyInterpreter();
+        IOptionType<Long> longBytePropertyInterpreter = OptionTypes.LONG_BYTE_UNIT;
         long memBudget =
-                parameter == null ? memBudgetInConfiguration : longBytePropertyInterpreter.interpret(parameter);
+                parameter == null ? memBudgetInConfiguration : longBytePropertyInterpreter.parse(parameter);
         return (int) (memBudget / frameSize);
     }
 
     // Gets the parallelism parameter.
     private int getParallelism(String parameter, int parallelismInConfiguration) {
-        IPropertyInterpreter<Integer> integerIPropertyInterpreter =
-                PropertyInterpreters.getIntegerPropertyInterpreter();
-        return parameter == null ? parallelismInConfiguration : integerIPropertyInterpreter.interpret(parameter);
+        IOptionType<Integer> integerIPropertyInterpreter = OptionTypes.INTEGER;
+        return parameter == null ? parallelismInConfiguration : integerIPropertyInterpreter.parse(parameter);
     }
 }
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/AsterixHyracksIntegrationUtil.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/AsterixHyracksIntegrationUtil.java
index 54804a1..fbb2208 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/AsterixHyracksIntegrationUtil.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/AsterixHyracksIntegrationUtil.java
@@ -18,6 +18,17 @@
  */
 package org.apache.asterix.api.common;
 
+import static org.apache.asterix.api.common.AsterixHyracksIntegrationUtil.LoggerHolder.LOGGER;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
 import org.apache.asterix.common.api.IClusterManagementWork.ClusterState;
 import org.apache.asterix.common.config.GlobalConfig;
 import org.apache.asterix.common.config.PropertiesAccessor;
@@ -26,28 +37,19 @@
 import org.apache.asterix.hyracks.bootstrap.NCApplicationEntryPoint;
 import org.apache.asterix.runtime.utils.ClusterStateManager;
 import org.apache.commons.io.FileUtils;
+import org.apache.hyracks.api.application.ICCApplicationEntryPoint;
+import org.apache.hyracks.api.application.INCApplicationEntryPoint;
 import org.apache.hyracks.api.client.HyracksConnection;
 import org.apache.hyracks.api.client.IHyracksClientConnection;
 import org.apache.hyracks.api.job.JobFlag;
 import org.apache.hyracks.api.job.JobId;
 import org.apache.hyracks.api.job.JobSpecification;
 import org.apache.hyracks.control.cc.ClusterControllerService;
+import org.apache.hyracks.control.common.config.ConfigManager;
 import org.apache.hyracks.control.common.controllers.CCConfig;
 import org.apache.hyracks.control.common.controllers.NCConfig;
 import org.apache.hyracks.control.nc.NodeControllerService;
 
-import java.io.File;
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import static org.apache.asterix.api.common.AsterixHyracksIntegrationUtil.LoggerHolder.LOGGER;
-
 public class AsterixHyracksIntegrationUtil {
     static class LoggerHolder {
         static final Logger LOGGER = Logger.getLogger(AsterixHyracksIntegrationUtil.class.getName());
@@ -63,29 +65,38 @@
     public NodeControllerService[] ncs;
     public IHyracksClientConnection hcc;
 
-    private PropertiesAccessor propertiesAccessor;
+    private ConfigManager configManager;
+    private List<String> nodeNames;
 
     public void init(boolean deleteOldInstanceData) throws Exception {
         ncs = new NodeControllerService[0]; // ensure that ncs is not null
-        final CCConfig ccConfig = createCCConfig();
-        propertiesAccessor = PropertiesAccessor.getInstance(ccConfig.getAppConfig());
+        final ICCApplicationEntryPoint ccAppEntryPoint = createCCAppEntryPoint();
+        configManager = new ConfigManager();
+        ccAppEntryPoint.registerConfig(configManager);
+        final CCConfig ccConfig = createCCConfig(configManager);
+        cc = new ClusterControllerService(ccConfig, ccAppEntryPoint);
+
+        nodeNames = ccConfig.getConfigManager().getNodeNames();
         if (deleteOldInstanceData) {
             deleteTransactionLogs();
             removeTestStorageFiles();
         }
+        final List<NCConfig> ncConfigs = new ArrayList<>();
+        nodeNames.forEach(nodeId -> ncConfigs.add(createNCConfig(nodeId, configManager)));
+        final PropertiesAccessor accessor = PropertiesAccessor.getInstance(configManager.getAppConfig());
+        ncConfigs.forEach((ncConfig1) -> fixupIODevices(ncConfig1, accessor));
 
-        cc = new ClusterControllerService(ccConfig);
         cc.start();
 
         // Starts ncs.
-        List<String> nodes = propertiesAccessor.getNodeNames();
+        nodeNames = ccConfig.getConfigManager().getNodeNames();
         List<NodeControllerService> nodeControllers = new ArrayList<>();
         List<Thread> startupThreads = new ArrayList<>();
-        for (String ncName : nodes) {
-            NodeControllerService nodeControllerService = new NodeControllerService(
-                    fixupIODevices(createNCConfig(ncName)));
+        for (NCConfig ncConfig : ncConfigs) {
+            final INCApplicationEntryPoint ncAppEntryPoint = createNCAppEntryPoint();
+            NodeControllerService nodeControllerService = new NodeControllerService(ncConfig, ncAppEntryPoint);
             nodeControllers.add(nodeControllerService);
-            Thread ncStartThread = new Thread("IntegrationUtil-" + ncName) {
+            Thread ncStartThread = new Thread("IntegrationUtil-" + ncConfig.getNodeId()) {
                 @Override
                 public void run() {
                     try {
@@ -102,78 +113,83 @@
         for (Thread thread : startupThreads) {
             thread.join();
         }
+        for (NCConfig ncConfig : ncConfigs) {
+            for (String ioDevice : ncConfig.getIODevices()) {
+                if (!new File(ioDevice).isAbsolute()) {
+                    throw new IllegalStateException("iodevice not absolute: " + ioDevice);
+                }
+            }
+        }
         // Wait until cluster becomes active
         synchronized (ClusterStateManager.INSTANCE) {
             while (ClusterStateManager.INSTANCE.getState() != ClusterState.ACTIVE) {
                 ClusterStateManager.INSTANCE.wait();
             }
         }
-        hcc = new HyracksConnection(cc.getConfig().clientNetIpAddress, cc.getConfig().clientNetPort);
+        hcc = new HyracksConnection(cc.getConfig().getClientListenAddress(), cc.getConfig().getClientListenPort());
         ncs = nodeControllers.toArray(new NodeControllerService[nodeControllers.size()]);
     }
 
-    protected CCConfig createCCConfig() throws IOException {
-        CCConfig ccConfig = new CCConfig();
-        ccConfig.clusterNetIpAddress = Inet4Address.getLoopbackAddress().getHostAddress();
-        ccConfig.clientNetIpAddress = Inet4Address.getLoopbackAddress().getHostAddress();
-        ccConfig.clientNetPort = DEFAULT_HYRACKS_CC_CLIENT_PORT;
-        ccConfig.clusterNetPort = DEFAULT_HYRACKS_CC_CLUSTER_PORT;
-        ccConfig.defaultMaxJobAttempts = 0;
-        ccConfig.resultTTL = 120000;
-        ccConfig.resultSweepThreshold = 1000;
-        ccConfig.appCCMainClass = CCApplicationEntryPoint.class.getName();
+    protected CCConfig createCCConfig(ConfigManager configManager) throws IOException {
+        CCConfig ccConfig = new CCConfig(configManager);
+        ccConfig.setClusterListenAddress(Inet4Address.getLoopbackAddress().getHostAddress());
+        ccConfig.setClientListenAddress(Inet4Address.getLoopbackAddress().getHostAddress());
+        ccConfig.setClientListenPort(DEFAULT_HYRACKS_CC_CLIENT_PORT);
+        ccConfig.setClusterListenPort(DEFAULT_HYRACKS_CC_CLUSTER_PORT);
+        ccConfig.setResultTTL(120000L);
+        ccConfig.setResultSweepThreshold(1000L);
         return ccConfig;
     }
 
-    protected NCConfig createNCConfig(String ncName) throws AsterixException, IOException {
-        NCConfig ncConfig = new NCConfig();
-        ncConfig.ccHost = "localhost";
-        ncConfig.ccPort = DEFAULT_HYRACKS_CC_CLUSTER_PORT;
-        ncConfig.clusterNetIPAddress = Inet4Address.getLoopbackAddress().getHostAddress();
-        ncConfig.dataIPAddress = Inet4Address.getLoopbackAddress().getHostAddress();
-        ncConfig.resultIPAddress = Inet4Address.getLoopbackAddress().getHostAddress();
-        ncConfig.messagingIPAddress = Inet4Address.getLoopbackAddress().getHostAddress();
-        ncConfig.nodeId = ncName;
-        ncConfig.resultTTL = 120000;
-        ncConfig.resultSweepThreshold = 1000;
-        ncConfig.appArgs = Collections.singletonList("-virtual-NC");
-        ncConfig.appNCMainClass = NCApplicationEntryPoint.class.getName();
+    protected ICCApplicationEntryPoint createCCAppEntryPoint() {
+        return new CCApplicationEntryPoint();
+    }
+
+    protected NCConfig createNCConfig(String ncName, ConfigManager configManager) {
+        NCConfig ncConfig = new NCConfig(ncName, configManager);
+        ncConfig.setClusterAddress("localhost");
+        ncConfig.setClusterPort(DEFAULT_HYRACKS_CC_CLUSTER_PORT);
+        ncConfig.setClusterListenAddress(Inet4Address.getLoopbackAddress().getHostAddress());
+        ncConfig.setDataListenAddress(Inet4Address.getLoopbackAddress().getHostAddress());
+        ncConfig.setResultListenAddress(Inet4Address.getLoopbackAddress().getHostAddress());
+        ncConfig.setMessagingListenAddress(Inet4Address.getLoopbackAddress().getHostAddress());
+        ncConfig.setResultTTL(120000L);
+        ncConfig.setResultSweepThreshold(1000L);
+        ncConfig.setVirtualNC(true);
         return ncConfig;
     }
 
-    private NCConfig fixupIODevices(NCConfig ncConfig) throws AsterixException {
+    protected INCApplicationEntryPoint createNCAppEntryPoint() {
+        return new NCApplicationEntryPoint();
+    }
+
+    private NCConfig fixupIODevices(NCConfig ncConfig, PropertiesAccessor accessor) {
         String tempPath = System.getProperty(IO_DIR_KEY);
         if (tempPath.endsWith(File.separator)) {
             tempPath = tempPath.substring(0, tempPath.length() - 1);
         }
         LOGGER.info("Using the temp path: " + tempPath);
         // get initial partitions from properties
-        String[] nodeStores = propertiesAccessor.getStores().get(ncConfig.nodeId);
+        String[] nodeStores = accessor.getStores().get(ncConfig.getNodeId());
         if (nodeStores == null) {
-            throw new AsterixException("Couldn't find stores for NC: " + ncConfig.nodeId);
+            throw new IllegalStateException("Couldn't find stores for NC: " + ncConfig.getNodeId());
         }
         String tempDirPath = System.getProperty(IO_DIR_KEY);
         if (!tempDirPath.endsWith(File.separator)) {
             tempDirPath += File.separator;
         }
-        for (int p = 0; p < nodeStores.length; p++) {
+        List<String> ioDevices = new ArrayList<>();
+        for (String nodeStore : nodeStores) {
             // create IO devices based on stores
-            String iodevicePath = tempDirPath + ncConfig.nodeId + File.separator + nodeStores[p];
+            String iodevicePath = tempDirPath + ncConfig.getNodeId() + File.separator + nodeStore;
             File ioDeviceDir = new File(iodevicePath);
             ioDeviceDir.mkdirs();
-            if (p == 0) {
-                ncConfig.ioDevices = iodevicePath;
-            } else {
-                ncConfig.ioDevices += "," + iodevicePath;
-            }
+            ioDevices.add(iodevicePath);
         }
+        configManager.set(ncConfig.getNodeId(), NCConfig.Option.IODEVICES, ioDevices.toArray(new String[0]));
         return ncConfig;
     }
 
-    public String[] getNcNames() {
-        return propertiesAccessor.getNodeNames().toArray(new String[propertiesAccessor.getNodeNames().size()]);
-    }
-
     public IHyracksClientConnection getHyracksClientConnection() {
         return hcc;
     }
@@ -222,15 +238,16 @@
 
     public void removeTestStorageFiles() {
         File dir = new File(System.getProperty(IO_DIR_KEY));
-        for (String ncName : propertiesAccessor.getNodeNames()) {
+        for (String ncName : nodeNames) {
             File ncDir = new File(dir, ncName);
             FileUtils.deleteQuietly(ncDir);
         }
     }
 
-    private void deleteTransactionLogs() throws IOException {
-        for (String ncId : propertiesAccessor.getNodeNames()) {
-            File log = new File(propertiesAccessor.getTransactionLogDirs().get(ncId));
+    private void deleteTransactionLogs() throws IOException, AsterixException {
+        for (String ncId : nodeNames) {
+            File log = new File(
+                    PropertiesAccessor.getInstance(configManager.getAppConfig()).getTransactionLogDirs().get(ncId));
             if (log.exists()) {
                 FileUtils.deleteDirectory(log);
             }
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 34086e7..eafe312 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
@@ -18,37 +18,37 @@
  */
 package org.apache.asterix.api.http.server;
 
+import static org.apache.asterix.api.http.servlet.ServletConstants.ASTERIX_APP_CONTEXT_INFO_ATTR;
+
 import java.io.IOException;
 import java.io.PrintWriter;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
 import java.util.concurrent.ConcurrentMap;
+import java.util.function.Predicate;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import java.util.regex.Pattern;
 
-import org.apache.asterix.common.config.AbstractProperties;
-import org.apache.asterix.common.config.ReplicationProperties;
+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;
+import org.apache.hyracks.api.config.Section;
+import org.apache.hyracks.control.common.config.ConfigUtils;
+import org.apache.hyracks.control.common.controllers.ControllerConfig;
 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 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 {
 
     private static final Logger LOGGER = Logger.getLogger(ClusterApiServlet.class.getName());
     private static final Pattern PARENT_DIR = Pattern.compile("/[^./]+/\\.\\./");
-    private static final Pattern REPLICATION_PROPERTY = Pattern.compile("^replication\\.");
     protected static final String NODE_ID_KEY = "node_id";
     protected static final String CONFIG_URI_KEY = "configUri";
     protected static final String STATS_URI_KEY = "statsUri";
@@ -57,10 +57,9 @@
     protected static final String FULL_SHUTDOWN_URI_KEY = "fullShutdownUri";
     protected static final String VERSION_URI_KEY = "versionUri";
     protected static final String DIAGNOSTICS_URI_KEY = "diagnosticsUri";
-    protected static final String REPLICATION_URI_KEY = "replicationUri";
     private final ObjectMapper om = new ObjectMapper();
 
-    public ClusterApiServlet(ConcurrentMap<String, Object> ctx, String[] paths) {
+    public ClusterApiServlet(ConcurrentMap<String, Object> ctx, String... paths) {
         super(ctx, paths);
     }
 
@@ -75,9 +74,6 @@
                 case "":
                     json = getClusterStateJSON(request, "");
                     break;
-                case "/replication":
-                    json = getReplicationJSON();
-                    break;
                 case "/summary":
                     json = getClusterStateSummaryJSON();
                     break;
@@ -99,35 +95,11 @@
         return ClusterStateManager.INSTANCE.getClusterStateSummary();
     }
 
-    protected ObjectNode getReplicationJSON() {
-        for (AbstractProperties props : getPropertiesInstances()) {
-            if (props instanceof ReplicationProperties) {
-                ObjectNode json = om.createObjectNode();
-                json.putPOJO("config", props.getProperties(key -> REPLICATION_PROPERTY.matcher(key).replaceFirst("")));
-                return json;
-            }
-        }
-        throw new IllegalStateException("ERROR: replication properties not found");
-    }
-
-    protected Map<String, Object> getAllClusterProperties() {
-        Map<String, Object> allProperties = new HashMap<>();
-        for (AbstractProperties properties : getPropertiesInstances()) {
-            if (!(properties instanceof ReplicationProperties)) {
-                allProperties.putAll(properties.getProperties());
-            }
-        }
-        return allProperties;
-    }
-
-    protected List<AbstractProperties> getPropertiesInstances() {
-        return AbstractProperties.getImplementations();
-    }
-
     protected ObjectNode getClusterStateJSON(IServletRequest request, String pathToNode) {
         ObjectNode json = ClusterStateManager.INSTANCE.getClusterStateDescription();
-        Map<String, Object> allProperties = getAllClusterProperties();
-        json.putPOJO("config", allProperties);
+        AppContextInfo appConfig = (AppContextInfo) ctx.get(ASTERIX_APP_CONTEXT_INFO_ATTR);
+        json.putPOJO("config", ConfigUtils.getSectionOptionsForJSON(appConfig.getCCApplicationContext().getAppConfig(),
+                Section.COMMON, getConfigSelector()));
 
         ArrayNode ncs = (ArrayNode) json.get("ncs");
         final StringBuilder requestURL = new StringBuilder("http://");
@@ -156,7 +128,6 @@
         cc.put(CONFIG_URI_KEY, clusterURL + "cc/config");
         cc.put(STATS_URI_KEY, clusterURL + "cc/stats");
         cc.put(THREAD_DUMP_URI_KEY, clusterURL + "cc/threaddump");
-        json.put(REPLICATION_URI_KEY, clusterURL + "replication");
         json.put(SHUTDOWN_URI_KEY, adminURL + "shutdown");
         json.put(FULL_SHUTDOWN_URI_KEY, adminURL + "shutdown?all=true");
         json.put(VERSION_URI_KEY, adminURL + "version");
@@ -164,6 +135,11 @@
         return json;
     }
 
+    protected Predicate<IOption> getConfigSelector() {
+        return option -> option != ControllerConfig.Option.CONFIG_FILE
+                && option != ControllerConfig.Option.CONFIG_FILE_URL;
+    }
+
     private String canonicalize(CharSequence requestURL) {
         String clusterURL = "";
         String newClusterURL = requestURL.toString();
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ClusterControllerDetailsApiServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ClusterControllerDetailsApiServlet.java
index d680e6e..52d4d67 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ClusterControllerDetailsApiServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ClusterControllerDetailsApiServlet.java
@@ -41,7 +41,7 @@
     private static final Logger LOGGER = Logger.getLogger(ClusterControllerDetailsApiServlet.class.getName());
     private final ObjectMapper om = new ObjectMapper();
 
-    public ClusterControllerDetailsApiServlet(ConcurrentMap<String, Object> ctx, String[] paths) {
+    public ClusterControllerDetailsApiServlet(ConcurrentMap<String, Object> ctx, String... paths) {
         super(ctx, paths);
     }
 
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/DiagnosticsApiServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/DiagnosticsApiServlet.java
index ffe62b4..de227eb 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/DiagnosticsApiServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/DiagnosticsApiServlet.java
@@ -50,7 +50,7 @@
 public class DiagnosticsApiServlet extends NodeControllerDetailsApiServlet {
     private static final Logger LOGGER = Logger.getLogger(DiagnosticsApiServlet.class.getName());
 
-    public DiagnosticsApiServlet(ConcurrentMap<String, Object> ctx, String[] paths) {
+    public DiagnosticsApiServlet(ConcurrentMap<String, Object> ctx, String... paths) {
         super(ctx, paths);
     }
 
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NodeControllerDetailsApiServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NodeControllerDetailsApiServlet.java
index 07e70ab..d9757c7 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NodeControllerDetailsApiServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NodeControllerDetailsApiServlet.java
@@ -48,7 +48,7 @@
     private static final Logger LOGGER = Logger.getLogger(NodeControllerDetailsApiServlet.class.getName());
     private final ObjectMapper om = new ObjectMapper();
 
-    public NodeControllerDetailsApiServlet(ConcurrentMap<String, Object> ctx, String[] paths) {
+    public NodeControllerDetailsApiServlet(ConcurrentMap<String, Object> ctx, String... paths) {
         super(ctx, paths);
         om.enable(SerializationFeature.INDENT_OUTPUT);
     }
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/VersionApiServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/VersionApiServlet.java
index 91bebfe..a4cea39 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/VersionApiServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/VersionApiServlet.java
@@ -18,7 +18,7 @@
  */
 package org.apache.asterix.api.http.server;
 
-import static org.apache.asterix.api.http.servlet.ServletConstants.ASTERIX_BUILD_PROP_ATTR;
+import static org.apache.asterix.api.http.servlet.ServletConstants.ASTERIX_APP_CONTEXT_INFO_ATTR;
 
 import java.io.IOException;
 import java.io.PrintWriter;
@@ -27,18 +27,15 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import org.apache.asterix.runtime.utils.AppContextInfo;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import io.netty.handler.codec.http.HttpResponseStatus;
+import org.apache.asterix.common.config.IPropertiesProvider;
 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 com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-import io.netty.handler.codec.http.HttpMethod;
-import io.netty.handler.codec.http.HttpResponseStatus;
-
 public class VersionApiServlet extends AbstractServlet {
     private static final Logger LOGGER = Logger.getLogger(VersionApiServlet.class.getName());
 
@@ -49,7 +46,7 @@
     @Override
     protected void get(IServletRequest request, IServletResponse response) {
         response.setStatus(HttpResponseStatus.OK);
-        AppContextInfo props = (AppContextInfo) ctx.get(ASTERIX_BUILD_PROP_ATTR);
+        IPropertiesProvider props = (IPropertiesProvider) ctx.get(ASTERIX_APP_CONTEXT_INFO_ATTR);
         Map<String, String> buildProperties = props.getBuildProperties().getAllProps();
         ObjectMapper om = new ObjectMapper();
         ObjectNode responseObject = om.createObjectNode();
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ServletConstants.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ServletConstants.java
index d5f31ff..5b96cab 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ServletConstants.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/servlet/ServletConstants.java
@@ -21,7 +21,7 @@
 public class ServletConstants {
     public static final String HYRACKS_CONNECTION_ATTR = "org.apache.asterix.HYRACKS_CONNECTION";
     public static final String HYRACKS_DATASET_ATTR = "org.apache.asterix.HYRACKS_DATASET";
-    public static final String ASTERIX_BUILD_PROP_ATTR = "org.apache.asterix.PROPS";
+    public static final String ASTERIX_APP_CONTEXT_INFO_ATTR = "org.apache.asterix.APP_CONTEXT_INFO";
     public static final String EXECUTOR_SERVICE = "org.apache.asterix.EXECUTOR_SERVICE";
 
     private ServletConstants() {
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/NCAppRuntimeContext.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/NCAppRuntimeContext.java
index 625f18f..5eba31d 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/NCAppRuntimeContext.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/nc/NCAppRuntimeContext.java
@@ -41,6 +41,7 @@
 import org.apache.asterix.common.config.FeedProperties;
 import org.apache.asterix.common.config.MessagingProperties;
 import org.apache.asterix.common.config.MetadataProperties;
+import org.apache.asterix.common.config.NodeProperties;
 import org.apache.asterix.common.config.PropertiesAccessor;
 import org.apache.asterix.common.config.ReplicationProperties;
 import org.apache.asterix.common.config.StorageProperties;
@@ -113,6 +114,7 @@
     private BuildProperties buildProperties;
     private ReplicationProperties replicationProperties;
     private MessagingProperties messagingProperties;
+    private final NodeProperties nodeProperties;
     private ThreadExecutor threadExecutor;
     private IDatasetLifecycleManager datasetLifecycleManager;
     private IFileMapManager fileMapManager;
@@ -150,6 +152,7 @@
         buildProperties = new BuildProperties(propertiesAccessor);
         replicationProperties = new ReplicationProperties(propertiesAccessor);
         messagingProperties = new MessagingProperties(propertiesAccessor);
+        nodeProperties = new NodeProperties(propertiesAccessor);
         libraryManager = new ExternalLibraryManager();
         if (extensions != null) {
             allExtensions.addAll(extensions);
@@ -220,7 +223,7 @@
             //PersistentLocalResourceRepository to replicate metadata files and delete backups on drop index
             localResourceRepository.setReplicationManager(replicationManager);
 
-            /**
+            /*
              * add the partitions that will be replicated in this node as inactive partitions
              */
             //get nodes which replicate to this node
@@ -254,12 +257,12 @@
          */
         ILifeCycleComponentManager lccm = ncApplicationContext.getLifeCycleComponentManager();
         lccm.register((ILifeCycleComponent) bufferCache);
-        /**
+        /*
          * LogManager must be stopped after RecoveryManager, DatasetLifeCycleManager, and ReplicationManager
          * to process any logs that might be generated during stopping these components
          */
         lccm.register((ILifeCycleComponent) txnSubsystem.getLogManager());
-        /**
+        /*
          * ReplicationManager must be stopped after indexLifecycleManager and recovery manager
          * so that any logs/files generated during closing datasets or checkpoints are sent to remote replicas
          */
@@ -267,7 +270,7 @@
             lccm.register(replicationManager);
         }
         lccm.register((ILifeCycleComponent) txnSubsystem.getRecoveryManager());
-        /**
+        /*
          * Stopping indexLifecycleManager will flush and close all datasets.
          */
         lccm.register((ILifeCycleComponent) datasetLifecycleManager);
@@ -376,6 +379,11 @@
     }
 
     @Override
+    public NodeProperties getNodeProperties() {
+        return nodeProperties;
+    }
+
+    @Override
     public ILSMOperationTracker getLSMBTreeOperationTracker(int datasetID) {
         return datasetLifecycleManager.getOperationTracker(datasetID);
     }
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/replication/AutoFaultToleranceStrategy.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/replication/AutoFaultToleranceStrategy.java
index 5104610..8d8a0f2 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/replication/AutoFaultToleranceStrategy.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/replication/AutoFaultToleranceStrategy.java
@@ -67,6 +67,7 @@
 import org.apache.asterix.runtime.utils.AppContextInfo;
 import org.apache.asterix.util.FaultToleranceUtil;
 import org.apache.hyracks.api.application.IClusterLifecycleListener.ClusterEventType;
+import org.apache.hyracks.api.config.IOption;
 import org.apache.hyracks.api.exceptions.HyracksDataException;
 
 public class AutoFaultToleranceStrategy implements IFaultToleranceStrategy {
@@ -113,9 +114,7 @@
     }
 
     private synchronized void notifyFailbackPlansNodeFailure(String nodeId) {
-        Iterator<NodeFailbackPlan> iterator = planId2FailbackPlanMap.values().iterator();
-        while (iterator.hasNext()) {
-            NodeFailbackPlan plan = iterator.next();
+        for (NodeFailbackPlan plan : planId2FailbackPlanMap.values()) {
             plan.notifyNodeFailure(nodeId);
         }
     }
@@ -173,7 +172,7 @@
                 try {
                     messageBroker.sendApplicationMessageToNC(takeoverRequest, replica);
                 } catch (Exception e) {
-                    /**
+                    /*
                      * if we fail to send the request, it means the NC we tried to send the request to
                      * has failed. When the failure notification arrives, we will send any pending request
                      * that belongs to the failed NC to a different active replica.
@@ -186,7 +185,7 @@
 
     private boolean addActiveReplica(String replica, ClusterPartition partition,
             Map<String, List<Integer>> partitionRecoveryPlan) {
-        Map<String, Map<String, String>> activeNcConfiguration = clusterManager.getActiveNcConfiguration();
+        Map<String, Map<IOption, Object>> activeNcConfiguration = clusterManager.getActiveNcConfiguration();
         if (activeNcConfiguration.containsKey(replica) && !failedNodes.contains(replica)) {
             if (!partitionRecoveryPlan.containsKey(replica)) {
                 List<Integer> replicaPartitions = new ArrayList<>();
@@ -213,7 +212,7 @@
             ClusterPartition[] nodePartitions = clusterManager.getNodePartitions(replicaId);
             for (ClusterPartition partition : nodePartitions) {
                 plan.addParticipant(partition.getActiveNodeId());
-                /**
+                /*
                  * if the partition original node is the returning node,
                  * add it to the list of the partitions which will be failed back
                  */
@@ -232,7 +231,7 @@
 
     private synchronized void processPendingFailbackPlans() {
         ClusterState state = clusterManager.getState();
-        /**
+        /*
          * if the cluster state is not ACTIVE, then failbacks should not be processed
          * since some partitions are not active
          */
@@ -240,7 +239,7 @@
             while (!pendingProcessingFailbackPlans.isEmpty()) {
                 //take the first pending failback plan
                 NodeFailbackPlan plan = pendingProcessingFailbackPlans.pop();
-                /**
+                /*
                  * A plan at this stage will be in one of two states:
                  * 1. PREPARING -> the participants were selected but we haven't sent any request.
                  * 2. PENDING_ROLLBACK -> a participant failed before we send any requests
@@ -253,7 +252,7 @@
                         clusterManager.updateClusterPartition(partitionId, failbackNode, false);
                     }
 
-                    /**
+                    /*
                      * if the returning node is the original metadata node,
                      * then metadata node will change after the failback completes
                      */
@@ -268,7 +267,7 @@
                     //force new jobs to wait
                     clusterManager.setState(ClusterState.REBALANCING);
                     handleFailbackRequests(plan, messageBroker);
-                    /**
+                    /*
                      * wait until the current plan is completed before processing the next plan.
                      * when the current one completes or is reverted, the cluster state will be
                      * ACTIVE again, and the next failback plan (if any) will be processed.
@@ -305,11 +304,11 @@
             clusterPartitionsMap.put(partition.getPartitionId(), partition);
         }
         for (ClusterPartition partition : clusterPartitons) {
-            if (partition.getActiveNodeId().equals(nodeId)) {
+            if (nodeId.equals(partition.getActiveNodeId())) {
                 nodePartitions.add(partition);
             }
         }
-        /**
+        /*
          * if there is any pending takeover request this node was supposed to handle,
          * it needs to be sent to a different replica
          */
@@ -359,7 +358,7 @@
     public synchronized void process(PreparePartitionsFailbackResponseMessage msg) {
         NodeFailbackPlan plan = planId2FailbackPlanMap.get(msg.getPlanId());
         plan.markRequestCompleted(msg.getRequestId());
-        /**
+        /*
          * A plan at this stage will be in one of three states:
          * 1. PENDING_PARTICIPANT_REPONSE -> one or more responses are still expected (wait).
          * 2. PENDING_COMPLETION -> all responses received (time to send completion request).
@@ -382,7 +381,7 @@
     }
 
     public synchronized void process(CompleteFailbackResponseMessage response) throws HyracksDataException {
-        /**
+        /*
          * the failback plan completed successfully:
          * Remove all references to it.
          * Remove the the failing back node from the failed nodes list.
@@ -409,8 +408,7 @@
             // Since the metadata node will be changed, we need to rebind the proxy object
             MetadataManager.INSTANCE.rebindMetadataNode();
         } catch (Exception e) {
-
-            /**
+            /*
              * if we fail to send the request, it means the NC we tried to send the request to
              * has failed. When the failure notification arrives, a new NC will be assigned to
              * the metadata partition and a new metadata node takeover request will be sent to it.
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplicationEntryPoint.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplicationEntryPoint.java
index f3182cf..54f2c06 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplicationEntryPoint.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplicationEntryPoint.java
@@ -18,8 +18,33 @@
  */
 package org.apache.asterix.hyracks.bootstrap;
 
+import static org.apache.asterix.api.http.servlet.ServletConstants.ASTERIX_APP_CONTEXT_INFO_ATTR;
+import static org.apache.asterix.api.http.servlet.ServletConstants.HYRACKS_CONNECTION_ATTR;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.ConcurrentMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
 import org.apache.asterix.active.ActiveLifecycleListener;
-import org.apache.asterix.api.http.server.*;
+import org.apache.asterix.api.http.server.ApiServlet;
+import org.apache.asterix.api.http.server.ClusterApiServlet;
+import org.apache.asterix.api.http.server.ClusterControllerDetailsApiServlet;
+import org.apache.asterix.api.http.server.ConnectorApiServlet;
+import org.apache.asterix.api.http.server.DdlApiServlet;
+import org.apache.asterix.api.http.server.DiagnosticsApiServlet;
+import org.apache.asterix.api.http.server.FeedServlet;
+import org.apache.asterix.api.http.server.FullApiServlet;
+import org.apache.asterix.api.http.server.NodeControllerDetailsApiServlet;
+import org.apache.asterix.api.http.server.QueryApiServlet;
+import org.apache.asterix.api.http.server.QueryResultApiServlet;
+import org.apache.asterix.api.http.server.QueryServiceServlet;
+import org.apache.asterix.api.http.server.QueryStatusApiServlet;
+import org.apache.asterix.api.http.server.QueryWebInterfaceServlet;
+import org.apache.asterix.api.http.server.ShutdownApiServlet;
+import org.apache.asterix.api.http.server.UpdateApiServlet;
+import org.apache.asterix.api.http.server.VersionApiServlet;
 import org.apache.asterix.api.http.servlet.ServletConstants;
 import org.apache.asterix.app.cc.CCExtensionManager;
 import org.apache.asterix.app.cc.ResourceIdManager;
@@ -27,6 +52,7 @@
 import org.apache.asterix.app.replication.FaultToleranceStrategyFactory;
 import org.apache.asterix.common.api.AsterixThreadFactory;
 import org.apache.asterix.common.config.AsterixExtension;
+import org.apache.asterix.common.config.AsterixProperties;
 import org.apache.asterix.common.config.ClusterProperties;
 import org.apache.asterix.common.config.ExternalProperties;
 import org.apache.asterix.common.config.MetadataProperties;
@@ -47,9 +73,9 @@
 import org.apache.asterix.runtime.utils.AppContextInfo;
 import org.apache.asterix.translator.IStatementExecutorFactory;
 import org.apache.hyracks.api.application.ICCApplicationContext;
-import org.apache.hyracks.api.application.ICCApplicationEntryPoint;
 import org.apache.hyracks.api.client.HyracksConnection;
 import org.apache.hyracks.api.client.IHyracksClientConnection;
+import org.apache.hyracks.api.config.IConfigManager;
 import org.apache.hyracks.api.job.resource.IJobCapacityController;
 import org.apache.hyracks.api.lifecycle.LifeCycleComponentManager;
 import org.apache.hyracks.control.cc.ClusterControllerService;
@@ -57,15 +83,9 @@
 import org.apache.hyracks.http.api.IServlet;
 import org.apache.hyracks.http.server.HttpServer;
 import org.apache.hyracks.http.server.WebManager;
+import org.apache.hyracks.util.file.FileUtil;
 
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import static org.apache.asterix.api.http.servlet.ServletConstants.ASTERIX_BUILD_PROP_ATTR;
-import static org.apache.asterix.api.http.servlet.ServletConstants.HYRACKS_CONNECTION_ATTR;
-
-public class CCApplicationEntryPoint implements ICCApplicationEntryPoint {
+public class CCApplicationEntryPoint extends org.apache.hyracks.control.cc.CCApplicationEntryPoint {
 
     private static final Logger LOGGER = Logger.getLogger(CCApplicationEntryPoint.class.getName());
     private static IAsterixStateProxy proxy;
@@ -75,8 +95,15 @@
     private IJobCapacityController jobCapacityController;
     protected WebManager webManager;
 
+    public CCApplicationEntryPoint() {
+        CCConfig.defaultDir = FileUtil.joinPath(System.getProperty("java.io.tmpdir"), "asterixdb");
+    }
+
     @Override
     public void start(ICCApplicationContext ccAppCtx, String[] args) throws Exception {
+        if (args.length > 0) {
+            throw new IllegalArgumentException("Unrecognized argument(s): " + Arrays.toString(args));
+        }
         final ClusterControllerService controllerService = (ClusterControllerService) ccAppCtx.getControllerService();
         ICCMessageBroker messageBroker = new CCMessageBroker(controllerService);
         this.appCtx = ccAppCtx;
@@ -100,7 +127,7 @@
         AppContextInfo.INSTANCE.setExtensionManager(ccExtensionManager);
         final CCConfig ccConfig = controllerService.getCCConfig();
         if (System.getProperty("java.rmi.server.hostname") == null) {
-            System.setProperty("java.rmi.server.hostname", ccConfig.clusterNetIpAddress);
+            System.setProperty("java.rmi.server.hostname", ccConfig.getClusterListenAddress());
         }
         MetadataProperties metadataProperties = AppContextInfo.INSTANCE.getMetadataProperties();
 
@@ -165,7 +192,7 @@
                 new HttpServer(webManager.getBosses(), webManager.getWorkers(), externalProperties.getAPIServerPort());
         IHyracksClientConnection hcc = getNewHyracksClientConnection();
         jsonAPIServer.setAttribute(HYRACKS_CONNECTION_ATTR, hcc);
-        jsonAPIServer.setAttribute(ASTERIX_BUILD_PROP_ATTR, AppContextInfo.INSTANCE);
+        jsonAPIServer.setAttribute(ASTERIX_APP_CONTEXT_INFO_ATTR, AppContextInfo.INSTANCE);
         jsonAPIServer.setAttribute(ServletConstants.EXECUTOR_SERVICE,
                 ((ClusterControllerService) appCtx.getControllerService()).getExecutor());
 
@@ -196,7 +223,7 @@
     }
 
     protected void addServlet(HttpServer server, String path) {
-        server.addServlet(createServlet(server, path, path));
+        server.addServlet(createServlet(server.ctx(), path, path));
     }
 
     protected HttpServer setupQueryWebServer(ExternalProperties externalProperties) throws Exception {
@@ -216,53 +243,53 @@
         return feedServer;
     }
 
-    protected IServlet createServlet(HttpServer server, String key, String... paths) {
+    protected IServlet createServlet(ConcurrentMap<String, Object> ctx, String key, String... paths) {
         switch (key) {
             case Servlets.AQL:
-                return new FullApiServlet(server.ctx(), paths, ccExtensionManager.getAqlCompilationProvider(),
+                return new FullApiServlet(ctx, paths, ccExtensionManager.getAqlCompilationProvider(),
                         getStatementExecutorFactory(), componentProvider);
             case Servlets.AQL_QUERY:
-                return new QueryApiServlet(server.ctx(), paths, ccExtensionManager.getAqlCompilationProvider(),
+                return new QueryApiServlet(ctx, paths, ccExtensionManager.getAqlCompilationProvider(),
                         getStatementExecutorFactory(), componentProvider);
             case Servlets.AQL_UPDATE:
-                return new UpdateApiServlet(server.ctx(), paths, ccExtensionManager.getAqlCompilationProvider(),
+                return new UpdateApiServlet(ctx, paths, ccExtensionManager.getAqlCompilationProvider(),
                         getStatementExecutorFactory(), componentProvider);
             case Servlets.AQL_DDL:
-                return new DdlApiServlet(server.ctx(), paths, ccExtensionManager.getAqlCompilationProvider(),
+                return new DdlApiServlet(ctx, paths, ccExtensionManager.getAqlCompilationProvider(),
                         getStatementExecutorFactory(), componentProvider);
             case Servlets.SQLPP:
-                return new FullApiServlet(server.ctx(), paths, ccExtensionManager.getSqlppCompilationProvider(),
+                return new FullApiServlet(ctx, paths, ccExtensionManager.getSqlppCompilationProvider(),
                         getStatementExecutorFactory(), componentProvider);
             case Servlets.SQLPP_QUERY:
-                return new QueryApiServlet(server.ctx(), paths, ccExtensionManager.getSqlppCompilationProvider(),
+                return new QueryApiServlet(ctx, paths, ccExtensionManager.getSqlppCompilationProvider(),
                         getStatementExecutorFactory(), componentProvider);
             case Servlets.SQLPP_UPDATE:
-                return new UpdateApiServlet(server.ctx(), paths, ccExtensionManager.getSqlppCompilationProvider(),
+                return new UpdateApiServlet(ctx, paths, ccExtensionManager.getSqlppCompilationProvider(),
                         getStatementExecutorFactory(), componentProvider);
             case Servlets.SQLPP_DDL:
-                return new DdlApiServlet(server.ctx(), paths, ccExtensionManager.getSqlppCompilationProvider(),
+                return new DdlApiServlet(ctx, paths, ccExtensionManager.getSqlppCompilationProvider(),
                         getStatementExecutorFactory(), componentProvider);
             case Servlets.QUERY_STATUS:
-                return new QueryStatusApiServlet(server.ctx(), paths);
+                return new QueryStatusApiServlet(ctx, paths);
             case Servlets.QUERY_RESULT:
-                return new QueryResultApiServlet(server.ctx(), paths);
+                return new QueryResultApiServlet(ctx, paths);
             case Servlets.QUERY_SERVICE:
-                return new QueryServiceServlet(server.ctx(), paths, ccExtensionManager.getSqlppCompilationProvider(),
+                return new QueryServiceServlet(ctx, paths, ccExtensionManager.getSqlppCompilationProvider(),
                         getStatementExecutorFactory(), componentProvider);
             case Servlets.CONNECTOR:
-                return new ConnectorApiServlet(server.ctx(), paths);
+                return new ConnectorApiServlet(ctx, paths);
             case Servlets.SHUTDOWN:
-                return new ShutdownApiServlet(server.ctx(), paths);
+                return new ShutdownApiServlet(ctx, paths);
             case Servlets.VERSION:
-                return new VersionApiServlet(server.ctx(), paths);
+                return new VersionApiServlet(ctx, paths);
             case Servlets.CLUSTER_STATE:
-                return new ClusterApiServlet(server.ctx(), paths);
+                return new ClusterApiServlet(ctx, paths);
             case Servlets.CLUSTER_STATE_NODE_DETAIL:
-                return new NodeControllerDetailsApiServlet(server.ctx(), paths);
+                return new NodeControllerDetailsApiServlet(ctx, paths);
             case Servlets.CLUSTER_STATE_CC_DETAIL:
-                return new ClusterControllerDetailsApiServlet(server.ctx(), paths);
+                return new ClusterControllerDetailsApiServlet(ctx, paths);
             case Servlets.DIAGNOSTICS:
-                return new DiagnosticsApiServlet(server.ctx(), paths);
+                return new DiagnosticsApiServlet(ctx, paths);
             default:
                 throw new IllegalStateException(String.valueOf(key));
         }
@@ -283,7 +310,13 @@
         return jobCapacityController;
     }
 
+    @Override
+    public void registerConfig(IConfigManager configManager) {
+        super.registerConfig(configManager);
+        AsterixProperties.registerConfigOptions(configManager);
+    }
+
     public static synchronized void setAsterixStateProxy(IAsterixStateProxy proxy) {
-        CCApplicationEntryPoint.proxy = proxy;
+        org.apache.asterix.hyracks.bootstrap.CCApplicationEntryPoint.proxy = proxy;
     }
 }
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/ClusterLifecycleListener.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/ClusterLifecycleListener.java
index 53b577a..8883504 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/ClusterLifecycleListener.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/ClusterLifecycleListener.java
@@ -43,6 +43,7 @@
 import org.apache.asterix.metadata.cluster.RemoveNodeWorkResponse;
 import org.apache.asterix.runtime.utils.ClusterStateManager;
 import org.apache.hyracks.api.application.IClusterLifecycleListener;
+import org.apache.hyracks.api.config.IOption;
 import org.apache.hyracks.api.exceptions.HyracksException;
 
 public class ClusterLifecycleListener implements IClusterLifecycleListener {
@@ -66,7 +67,7 @@
     }
 
     @Override
-    public void notifyNodeJoin(String nodeId, Map<String, String> ncConfiguration) throws HyracksException {
+    public void notifyNodeJoin(String nodeId, Map<IOption, Object> ncConfiguration) throws HyracksException {
         if (LOGGER.isLoggable(Level.INFO)) {
             LOGGER.info("NC: " + nodeId + " joined");
         }
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/NCApplicationEntryPoint.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/NCApplicationEntryPoint.java
index 7f649bc..238e93c 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/NCApplicationEntryPoint.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/NCApplicationEntryPoint.java
@@ -18,15 +18,24 @@
  */
 package org.apache.asterix.hyracks.bootstrap;
 
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
 import org.apache.asterix.app.nc.NCAppRuntimeContext;
 import org.apache.asterix.app.replication.message.StartupTaskRequestMessage;
 import org.apache.asterix.common.api.AsterixThreadFactory;
 import org.apache.asterix.common.api.IAppRuntimeContext;
 import org.apache.asterix.common.config.AsterixExtension;
+import org.apache.asterix.common.config.AsterixProperties;
 import org.apache.asterix.common.config.ClusterProperties;
 import org.apache.asterix.common.config.IPropertiesProvider;
 import org.apache.asterix.common.config.MessagingProperties;
 import org.apache.asterix.common.config.MetadataProperties;
+import org.apache.asterix.common.config.NodeProperties;
 import org.apache.asterix.common.config.StorageProperties;
 import org.apache.asterix.common.config.TransactionProperties;
 import org.apache.asterix.common.transactions.IRecoveryManager;
@@ -40,53 +49,42 @@
 import org.apache.asterix.transaction.management.resource.PersistentLocalResourceRepository;
 import org.apache.commons.io.FileUtils;
 import org.apache.hyracks.api.application.INCApplicationContext;
-import org.apache.hyracks.api.application.INCApplicationEntryPoint;
+import org.apache.hyracks.api.config.IConfigManager;
 import org.apache.hyracks.api.job.resource.NodeCapacity;
 import org.apache.hyracks.api.messages.IMessageBroker;
+import org.apache.hyracks.control.common.controllers.NCConfig;
 import org.apache.hyracks.control.nc.NodeControllerService;
-import org.kohsuke.args4j.CmdLineException;
-import org.kohsuke.args4j.CmdLineParser;
-import org.kohsuke.args4j.Option;
+import org.apache.hyracks.util.file.FileUtil;
 
-import java.io.File;
-import java.util.Collections;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-public class NCApplicationEntryPoint implements INCApplicationEntryPoint {
+public class NCApplicationEntryPoint extends org.apache.hyracks.control.nc.NCApplicationEntryPoint {
     private static final Logger LOGGER = Logger.getLogger(NCApplicationEntryPoint.class.getName());
 
-    @Option(name = "-initial-run", usage = "A flag indicating if it's the first time the NC is started "
-            + "(default: false)", required = false)
-    public boolean initialRun = false;
-
-    @Option(name = "-virtual-NC", usage = "A flag indicating if this NC is running on virtual cluster "
-            + "(default: false)", required = false)
-    public boolean virtualNC = false;
-
-    private INCApplicationContext ncApplicationContext = null;
+    private INCApplicationContext ncAppCtx;
     private IAppRuntimeContext runtimeContext;
     private String nodeId;
     private boolean stopInitiated = false;
     private SystemState systemState;
-    private IMessageBroker messageBroker;
+
+    public NCApplicationEntryPoint() {
+        NCConfig.defaultDir = FileUtil.joinPath(System.getProperty("java.io.tmpdir"), "asterixdb");
+        NCConfig.defaultAppClass = "org.apache.asterix.hyracks.bootstrap.NCApplicationEntryPoint";
+    }
+
+    @Override
+    public void registerConfigOptions(IConfigManager configManager) {
+        super.registerConfigOptions(configManager);
+        AsterixProperties.registerConfigOptions(configManager);
+    }
 
     @Override
     public void start(INCApplicationContext ncAppCtx, String[] args) throws Exception {
-        CmdLineParser parser = new CmdLineParser(this);
-        try {
-            parser.parseArgument(args);
-        } catch (CmdLineException e) {
-            LOGGER.severe(e.getMessage());
-            LOGGER.severe("Usage:");
-            parser.printUsage(System.err);
-            throw e;
+        if (args.length > 0) {
+            throw new IllegalArgumentException("Unrecognized argument(s): " + Arrays.toString(args));
         }
-        ncAppCtx.setThreadFactory(
-                new AsterixThreadFactory(ncAppCtx.getThreadFactory(), ncAppCtx.getLifeCycleComponentManager()));
-        ncApplicationContext = ncAppCtx;
-        nodeId = ncApplicationContext.getNodeId();
+        ncAppCtx.setThreadFactory(new AsterixThreadFactory(ncAppCtx.getThreadFactory(),
+                ncAppCtx.getLifeCycleComponentManager()));
+        this.ncAppCtx = ncAppCtx;
+        nodeId = this.ncAppCtx.getNodeId();
         if (LOGGER.isLoggable(Level.INFO)) {
             LOGGER.info("Starting Asterix node controller: " + nodeId);
         }
@@ -94,25 +92,25 @@
         final NodeControllerService controllerService = (NodeControllerService) ncAppCtx.getControllerService();
 
         if (System.getProperty("java.rmi.server.hostname") == null) {
-            System.setProperty("java.rmi.server.hostname",
-                    (controllerService).getConfiguration().clusterNetPublicIPAddress);
+            System.setProperty("java.rmi.server.hostname", (controllerService)
+                    .getConfiguration().getClusterPublicAddress());
         }
-        runtimeContext = new NCAppRuntimeContext(ncApplicationContext, getExtensions());
-        MetadataProperties metadataProperties = ((IPropertiesProvider) runtimeContext).getMetadataProperties();
-        if (!metadataProperties.getNodeNames().contains(ncApplicationContext.getNodeId())) {
+        runtimeContext = new NCAppRuntimeContext(this.ncAppCtx, getExtensions());
+        MetadataProperties metadataProperties = runtimeContext.getMetadataProperties();
+        if (!metadataProperties.getNodeNames().contains(this.ncAppCtx.getNodeId())) {
             if (LOGGER.isLoggable(Level.INFO)) {
-                LOGGER.info("Substitute node joining : " + ncApplicationContext.getNodeId());
+                LOGGER.info("Substitute node joining : " + this.ncAppCtx.getNodeId());
             }
             updateOnNodeJoin();
         }
-        runtimeContext.initialize(initialRun);
-        ncApplicationContext.setApplicationObject(runtimeContext);
-        MessagingProperties messagingProperties = ((IPropertiesProvider) runtimeContext).getMessagingProperties();
-        messageBroker = new NCMessageBroker(controllerService, messagingProperties);
-        ncApplicationContext.setMessageBroker(messageBroker);
+        runtimeContext.initialize(runtimeContext.getNodeProperties().isInitialRun());
+        this.ncAppCtx.setApplicationObject(runtimeContext);
+        MessagingProperties messagingProperties = runtimeContext.getMessagingProperties();
+        IMessageBroker messageBroker = new NCMessageBroker(controllerService, messagingProperties);
+        this.ncAppCtx.setMessageBroker(messageBroker);
         MessagingChannelInterfaceFactory interfaceFactory = new MessagingChannelInterfaceFactory(
                 (NCMessageBroker) messageBroker, messagingProperties);
-        ncApplicationContext.setMessagingChannelInterfaceFactory(interfaceFactory);
+        this.ncAppCtx.setMessagingChannelInterfaceFactory(interfaceFactory);
 
         IRecoveryManager recoveryMgr = runtimeContext.getTransactionSubsystem().getRecoveryManager();
         systemState = recoveryMgr.getSystemState();
@@ -148,7 +146,7 @@
             performLocalCleanUp();
 
             //Note: stopping recovery manager will make a sharp checkpoint
-            ncApplicationContext.getLifeCycleComponentManager().stopAll(false);
+            ncAppCtx.getLifeCycleComponentManager().stopAll(false);
             runtimeContext.deinitialize();
         } else {
             if (LOGGER.isLoggable(Level.INFO)) {
@@ -160,17 +158,18 @@
     @Override
     public void notifyStartupComplete() throws Exception {
         // Since we don't pass initial run flag in AsterixHyracksIntegrationUtil, we use the virtualNC flag
-        if (systemState == SystemState.PERMANENT_DATA_LOSS && (initialRun || virtualNC)) {
+        final NodeProperties nodeProperties = runtimeContext.getNodeProperties();
+        if (systemState == SystemState.PERMANENT_DATA_LOSS && (nodeProperties.isInitialRun() || nodeProperties.isVirtualNc())) {
             systemState = SystemState.BOOTSTRAPPING;
         }
         // Request startup tasks from CC
-        StartupTaskRequestMessage.send((NodeControllerService) ncApplicationContext.getControllerService(),
+        StartupTaskRequestMessage.send((NodeControllerService) ncAppCtx.getControllerService(),
                 systemState);
     }
 
     @Override
     public NodeCapacity getCapacity() {
-        IPropertiesProvider propertiesProvider = (IPropertiesProvider) runtimeContext;
+        IPropertiesProvider propertiesProvider = runtimeContext;
         StorageProperties storageProperties = propertiesProvider.getStorageProperties();
         // Deducts the reserved buffer cache size and memory component size from the maxium heap size,
         // and deducts one core for processing heartbeats.
@@ -201,15 +200,16 @@
     }
 
     private void updateOnNodeJoin() {
-        MetadataProperties metadataProperties = ((IPropertiesProvider) runtimeContext).getMetadataProperties();
+        MetadataProperties metadataProperties = runtimeContext.getMetadataProperties();
         if (!metadataProperties.getNodeNames().contains(nodeId)) {
-            metadataProperties.getNodeNames().add(nodeId);
             Cluster cluster = ClusterProperties.INSTANCE.getCluster();
             if (cluster == null) {
                 throw new IllegalStateException("No cluster configuration found for this instance");
             }
+            NCConfig ncConfig = ((NodeControllerService) ncAppCtx.getControllerService()).getConfiguration();
+            ncConfig.getConfigManager().registerVirtualNode(nodeId);
             String asterixInstanceName = metadataProperties.getInstanceName();
-            TransactionProperties txnProperties = ((IPropertiesProvider) runtimeContext).getTransactionProperties();
+            TransactionProperties txnProperties = runtimeContext.getTransactionProperties();
             Node self = null;
             List<Node> nodes;
             if (cluster.getSubstituteNodes() != null) {
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/util/FaultToleranceUtil.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/util/FaultToleranceUtil.java
index 0ab4e54..241cd65 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/util/FaultToleranceUtil.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/util/FaultToleranceUtil.java
@@ -31,11 +31,12 @@
 import org.apache.asterix.runtime.message.ReplicaEventMessage;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.hyracks.api.application.IClusterLifecycleListener.ClusterEventType;
+import org.apache.hyracks.api.config.IOption;
+import org.apache.hyracks.control.common.controllers.NCConfig;
 
 public class FaultToleranceUtil {
 
     private static final Logger LOGGER = Logger.getLogger(FaultToleranceUtil.class.getName());
-    private static final String CLUSTER_NET_IP_ADDRESS_KEY = "cluster-net-ip-address";
 
     private FaultToleranceUtil() {
         throw new AssertionError();
@@ -47,10 +48,10 @@
         List<String> primaryRemoteReplicas = replicationStrategy.getRemotePrimaryReplicas(nodeId).stream()
                 .map(Replica::getId).collect(Collectors.toList());
         String nodeIdAddress = StringUtils.EMPTY;
-        Map<String, Map<String, String>> activeNcConfiguration = clusterManager.getActiveNcConfiguration();
+        Map<String, Map<IOption, Object>> activeNcConfiguration = clusterManager.getActiveNcConfiguration();
         // In case the node joined with a new IP address, we need to send it to the other replicas
         if (event == ClusterEventType.NODE_JOIN) {
-            nodeIdAddress = activeNcConfiguration.get(nodeId).get(CLUSTER_NET_IP_ADDRESS_KEY);
+            nodeIdAddress = (String)activeNcConfiguration.get(nodeId).get(NCConfig.Option.CLUSTER_PUBLIC_ADDRESS);
         }
         ReplicaEventMessage msg = new ReplicaEventMessage(nodeId, nodeIdAddress, event);
         for (String replica : primaryRemoteReplicas) {
diff --git a/asterixdb/asterix-app/src/main/resources/asterix-build-configuration.xml b/asterixdb/asterix-app/src/main/resources/asterix-build-configuration.xml
index 7390d57..42cc42c 100644
--- a/asterixdb/asterix-app/src/main/resources/asterix-build-configuration.xml
+++ b/asterixdb/asterix-app/src/main/resources/asterix-build-configuration.xml
@@ -110,4 +110,9 @@
     <description>Number of reusable frames for NC to NC messaging. (Default = 512)
     </description>
   </property>
+  <property>
+    <name>log.level</name>
+    <value>INFO</value>
+    <description>foo</description>
+  </property>
 </asterixConfiguration>
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/api/http/servlet/VersionApiServletTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/api/http/servlet/VersionApiServletTest.java
index 7fed010..52ac855 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/api/http/servlet/VersionApiServletTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/api/http/servlet/VersionApiServletTest.java
@@ -19,7 +19,7 @@
 
 package org.apache.asterix.api.http.servlet;
 
-import static org.apache.asterix.api.http.servlet.ServletConstants.ASTERIX_BUILD_PROP_ATTR;
+import static org.apache.asterix.api.http.servlet.ServletConstants.ASTERIX_APP_CONTEXT_INFO_ATTR;
 import static org.apache.asterix.api.http.servlet.ServletConstants.HYRACKS_CONNECTION_ATTR;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
@@ -69,7 +69,7 @@
 
         // Put stuff in let map
         servlet.ctx().put(HYRACKS_CONNECTION_ATTR, mockHcc);
-        servlet.ctx().put(ASTERIX_BUILD_PROP_ATTR, mockCtx);
+        servlet.ctx().put(ASTERIX_APP_CONTEXT_INFO_ATTR, mockCtx);
         // Sets up mock returns.
         when(mockResponse.writer()).thenReturn(outputWriter);
         when(mockRequest.getHttpRequest()).thenReturn(mockHttpRequest);
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/bootstrap/TestNodeController.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/bootstrap/TestNodeController.java
index cc12f36..2061cda 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/bootstrap/TestNodeController.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/app/bootstrap/TestNodeController.java
@@ -58,7 +58,6 @@
 import org.apache.asterix.transaction.management.resource.PersistentLocalResourceFactoryProvider;
 import org.apache.asterix.transaction.management.runtime.CommitRuntime;
 import org.apache.asterix.transaction.management.service.logging.LogReader;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
 import org.apache.hyracks.algebricks.runtime.base.IPushRuntime;
 import org.apache.hyracks.algebricks.runtime.operators.std.EmptyTupleSourceRuntimeFactory;
@@ -93,6 +92,7 @@
 import org.apache.hyracks.storage.common.file.ILocalResourceFactoryProvider;
 import org.apache.hyracks.storage.common.file.LocalResource;
 import org.apache.hyracks.test.support.TestUtils;
+import org.apache.hyracks.util.file.FileUtil;
 import org.mockito.Mockito;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
@@ -101,8 +101,7 @@
     protected static final Logger LOGGER = Logger.getLogger(TestNodeController.class.getName());
 
     protected static final String PATH_ACTUAL = "unittest" + File.separator;
-    protected static final String PATH_BASE =
-            StringUtils.join(new String[] { "src", "test", "resources", "nodetests" }, File.separator);
+    protected static final String PATH_BASE = FileUtil.joinPath("src", "test", "resources", "nodetests");
 
     protected static final String TEST_CONFIG_FILE_NAME = "asterix-build-configuration.xml";
     protected static TransactionProperties txnProperties;
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/common/config/ConfigUsageTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/common/config/ConfigUsageTest.java
new file mode 100644
index 0000000..b96b7fe
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/common/config/ConfigUsageTest.java
@@ -0,0 +1,146 @@
+/*
+ * 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.config;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
+import org.apache.asterix.hyracks.bootstrap.CCApplicationEntryPoint;
+import org.apache.hyracks.api.config.IOption;
+import org.apache.hyracks.api.config.Section;
+import org.apache.hyracks.control.common.config.ConfigManager;
+import org.apache.hyracks.util.file.FileUtil;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class ConfigUsageTest {
+
+    private static final String CSV_FILE = FileUtil.joinPath("target", "surefire-reports", "config-options.csv");
+
+    @Test
+    public void generateUsage() {
+        generateUsage("| ", " | ", " |", true, System.err);
+    }
+
+    @Test
+    public void generateUsageCSV() throws IOException {
+        new File(CSV_FILE).getParentFile().mkdirs();
+        try (final PrintStream output = new PrintStream(new FileOutputStream(CSV_FILE))) {
+            generateUsage("\"", "\",\"", "\"", false, output);
+            // TODO(mblow): add some validation (in addition to just ensuring no exceptions...)
+        }
+    }
+
+    public void generateUsage(String startDelim, String midDelim, String endDelim, boolean align, PrintStream output) {
+        ConfigManager configManager = new ConfigManager();
+        CCApplicationEntryPoint aep = new CCApplicationEntryPoint();
+        aep.registerConfig(configManager);
+        StringBuilder buf = new StringBuilder();
+        int maxSectionWidth = 0;
+        int maxNameWidth = 0;
+        int maxDescriptionWidth = 0;
+        int maxDefaultWidth = 0;
+        if (align) {
+            for (Section section : configManager.getSections()) {
+                maxSectionWidth = Math.max(maxSectionWidth, section.sectionName().length());
+                for (IOption option : configManager.getOptions(section)) {
+                    if (option.hidden()) {
+                        continue;
+                    }
+                    maxNameWidth = Math.max(maxNameWidth, option.ini().length());
+                    maxDescriptionWidth = Math.max(maxDescriptionWidth,
+                            option.description() == null ? 0 : option.description().length());
+                    maxDefaultWidth = Math.max(maxDefaultWidth, configManager.defaultTextForUsage(option, IOption::ini)
+                            .length());
+                }
+            }
+        }
+        maxDescriptionWidth = Math.min(80, maxDescriptionWidth);
+        for (Section section : configManager.getSections()) {
+            List<IOption> options = new ArrayList<>(configManager.getOptions(section));
+            options.sort(Comparator.comparing(IOption::ini));
+            for (IOption option : options) {
+                if (option.hidden()) {
+                    continue;
+                }
+                buf.append(startDelim);
+                center(buf, section.sectionName(), maxSectionWidth).append(midDelim);
+                pad(buf, option.ini(), maxNameWidth).append(midDelim);
+                String description = option.description() == null ? "" : option.description();
+                String defaultText = configManager.defaultTextForUsage(option, IOption::ini);
+                boolean extra = false;
+                while (align && description.length() > maxDescriptionWidth) {
+                    int cut = description.lastIndexOf(' ', maxDescriptionWidth);
+                    pad(buf, description.substring(0, cut), maxDescriptionWidth).append(midDelim);
+                    pad(buf, defaultText, maxDefaultWidth).append(endDelim).append('\n');
+                    defaultText = "";
+                    description = description.substring(cut + 1);
+                    buf.append(startDelim);
+                    pad(buf, "", maxSectionWidth).append(midDelim);
+                    pad(buf, "", maxNameWidth).append(midDelim);
+                }
+                pad(buf, description, maxDescriptionWidth).append(midDelim);
+                pad(buf, defaultText, maxDefaultWidth).append(endDelim).append('\n');
+                if (extra) {
+                    buf.append(startDelim);
+                    pad(buf, "", maxSectionWidth).append(midDelim);
+                    pad(buf, "", maxNameWidth).append(midDelim);
+                    pad(buf, "", maxDescriptionWidth).append(midDelim);
+                    pad(buf, "", maxDefaultWidth).append(endDelim).append('\n');
+                }
+            }
+        }
+        output.println(buf);
+    }
+
+    private StringBuilder center(StringBuilder buf, String string, int width) {
+        if (string == null) {
+            string = "";
+        }
+        int pad = width - string.length();
+        int leftPad = pad / 2;
+        for (int i = leftPad; i > 0; i--) {
+            buf.append(' ');
+        }
+        buf.append(string);
+        for (int i = pad - leftPad; i > 0; i--) {
+            buf.append(' ');
+        }
+        return buf;
+    }
+
+    private StringBuilder pad(StringBuilder buf, String string, int width) {
+        if (string == null) {
+            string = "";
+        }
+        buf.append(string);
+        for (int i = width - string.length(); i > 0; i--) {
+            buf.append(' ');
+        }
+        return buf;
+    }
+
+}
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 ae40827..7765572 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
@@ -1113,13 +1113,13 @@
 
     private void deleteNCTxnLogs(String nodeId, CompilationUnit cUnit) throws Exception {
         OutputFormat fmt = OutputFormat.forCompilationUnit(cUnit);
-        String endpoint = "/admin/cluster";
+        String endpoint = "/admin/cluster/node/" + nodeId + "/config";
         InputStream executeJSONGet = executeJSONGet(fmt, new URI("http://" + host + ":" + port + endpoint));
         StringWriter actual = new StringWriter();
         IOUtils.copy(executeJSONGet, actual, StandardCharsets.UTF_8);
         String config = actual.toString();
         ObjectMapper om = new ObjectMapper();
-        String logDir = om.readTree(config).findPath("transaction.log.dirs").get(nodeId).asText();
+        String logDir = om.readTree(config).findPath("txn.log.dir").asText();
         FileUtils.deleteQuietly(new File(logDir));
     }
 
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 c1399fb..df9782a 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
@@ -38,7 +38,7 @@
 import org.apache.asterix.common.exceptions.AsterixException;
 import org.apache.commons.compress.utils.IOUtils;
 import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang3.StringUtils;
+import org.apache.hyracks.util.file.FileUtil;
 
 public final class TestHelper {
 
@@ -54,10 +54,6 @@
         return false;
     }
 
-    public static String joinPath(String... pathElements) {
-        return StringUtils.join(pathElements, File.separatorChar);
-    }
-
     public static void unzip(String sourceFile, String outputDir) throws IOException {
         if (System.getProperty("os.name").toLowerCase().startsWith("win")) {
             try (ZipFile zipFile = new ZipFile(sourceFile)) {
@@ -117,7 +113,7 @@
 
     public static void deleteExistingInstanceFiles() {
         for (String dirName : TEST_DIRS) {
-            File f = new File(joinPath(TEST_DIR_BASE_PATH, dirName));
+            File f = new File(FileUtil.joinPath(TEST_DIR_BASE_PATH, dirName));
             if (FileUtils.deleteQuietly(f)) {
                 System.out.println("Dir " + f.getName() + " deleted");
             }
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/logging/CheckpointingTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/logging/CheckpointingTest.java
index 10e8658..34bb9cf 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/logging/CheckpointingTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/logging/CheckpointingTest.java
@@ -82,7 +82,7 @@
     private static final String DATASET_NAME = "TestDS";
     private static final String DATA_TYPE_NAME = "DUMMY";
     private static final String NODE_GROUP_NAME = "DEFAULT";
-    private static final int TXN_LOG_PARTITION_SIZE = StorageUtil.getSizeInBytes(2, StorageUnit.MEGABYTE);
+    private static final int TXN_LOG_PARTITION_SIZE = StorageUtil.getIntSizeInBytes(2, StorageUnit.MEGABYTE);
 
     @Before
     public void setUp() throws Exception {
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/ClusterStateDefaultParameterTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/ClusterStateDefaultParameterTest.java
index 545b2a1..86a9639 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/ClusterStateDefaultParameterTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/runtime/ClusterStateDefaultParameterTest.java
@@ -65,7 +65,7 @@
     @Test
     public void test() throws Exception {
         StringBuilder result = new StringBuilder();
-        URL url = new URL("http://localhost:19002/admin/cluster");
+        URL url = new URL("http://localhost:19002/admin/cluster/node/asterix_nc1/config");
         HttpURLConnection conn = (HttpURLConnection) url.openConnection();
         conn.setRequestMethod("GET");
         BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/OptimizerParserTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/OptimizerParserTest.java
index 31103a8..486a219 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/OptimizerParserTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/OptimizerParserTest.java
@@ -24,7 +24,7 @@
 import java.util.logging.Logger;
 
 import org.apache.asterix.test.base.AsterixTestHelper;
-import org.apache.asterix.test.common.TestHelper;
+import org.apache.hyracks.util.file.FileUtil;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -41,10 +41,10 @@
     private static final String EXTENSION_RESULT = "ast";
     private static final String FILENAME_IGNORE = "ignore.txt";
     private static final String FILENAME_ONLY = "only.txt";
-    private static final String PATH_BASE = TestHelper.joinPath("src", "test", "resources", "optimizerts");
-    private static final String PATH_QUERIES = TestHelper.joinPath(PATH_BASE, "queries_sqlpp");
-    private static final String PATH_EXPECTED = TestHelper.joinPath(PATH_BASE, "results_parser_sqlpp");
-    private static final String PATH_ACTUAL = TestHelper.joinPath("target", "opt_parserts", "results_parser_sqlpp");
+    private static final String PATH_BASE = FileUtil.joinPath("src", "test", "resources", "optimizerts");
+    private static final String PATH_QUERIES = FileUtil.joinPath(PATH_BASE, "queries_sqlpp");
+    private static final String PATH_EXPECTED = FileUtil.joinPath(PATH_BASE, "results_parser_sqlpp");
+    private static final String PATH_ACTUAL = FileUtil.joinPath("target", "opt_parserts", "results_parser_sqlpp");
 
     private static final ArrayList<String> ignore = AsterixTestHelper.readFile(FILENAME_IGNORE, PATH_BASE);
     private static final ArrayList<String> only = AsterixTestHelper.readFile(FILENAME_ONLY, PATH_BASE);
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/ParserTestUtil.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/ParserTestUtil.java
index 891e463..9c3c393 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/ParserTestUtil.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/ParserTestUtil.java
@@ -25,6 +25,7 @@
 
 import org.apache.asterix.test.base.AsterixTestHelper;
 import org.apache.asterix.test.common.TestHelper;
+import org.apache.hyracks.util.file.FileUtil;
 import org.junit.Assume;
 import org.junit.internal.AssumptionViolatedException;
 
@@ -34,15 +35,15 @@
             String extensionQuery, String extensionResult, String pathExpected, String pathActual) {
         if (file.isDirectory() && !file.getName().startsWith(".")) {
             for (File innerfile : file.listFiles()) {
-                String subdir = innerfile.isDirectory() ? TestHelper.joinPath(path, innerfile.getName()) : path;
+                String subdir = innerfile.isDirectory() ? FileUtil.joinPath(path, innerfile.getName()) : path;
                 suiteBuild(innerfile, testArgs, subdir, separator, extensionQuery, extensionResult, pathExpected,
                         pathActual);
             }
         }
         if (file.isFile() && file.getName().endsWith(extensionQuery)) {
             String resultFileName = AsterixTestHelper.extToResExt(file.getName(), extensionResult);
-            File expectedFile = new File(TestHelper.joinPath(pathExpected, path, resultFileName));
-            File actualFile = new File(TestHelper.joinPath(pathActual, path, resultFileName));
+            File expectedFile = new File(FileUtil.joinPath(pathExpected, path, resultFileName));
+            File actualFile = new File(FileUtil.joinPath(pathActual, path, resultFileName));
             testArgs.add(new Object[] { file, expectedFile, actualFile });
         }
     }
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/SmokeParserTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/SmokeParserTest.java
index 8fe9370..3c856b5 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/SmokeParserTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/SmokeParserTest.java
@@ -24,7 +24,7 @@
 import java.util.logging.Logger;
 
 import org.apache.asterix.test.base.AsterixTestHelper;
-import org.apache.asterix.test.common.TestHelper;
+import org.apache.hyracks.util.file.FileUtil;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 import org.junit.Test;
@@ -41,10 +41,10 @@
     private static final String EXTENSION_RESULT = "ast";
     private static final String FILENAME_IGNORE = "ignore.txt";
     private static final String FILENAME_ONLY = "only.txt";
-    private static final String PATH_BASE = TestHelper.joinPath("src", "test", "resources", "parserts");
-    private static final String PATH_QUERIES = TestHelper.joinPath(PATH_BASE, "queries_sqlpp");
-    private static final String PATH_EXPECTED = TestHelper.joinPath(PATH_BASE, "results_parser_sqlpp");
-    private static final String PATH_ACTUAL = TestHelper.joinPath("target", "parserts");
+    private static final String PATH_BASE = FileUtil.joinPath("src", "test", "resources", "parserts");
+    private static final String PATH_QUERIES = FileUtil.joinPath(PATH_BASE, "queries_sqlpp");
+    private static final String PATH_EXPECTED = FileUtil.joinPath(PATH_BASE, "results_parser_sqlpp");
+    private static final String PATH_ACTUAL = FileUtil.joinPath("target", "parserts");
 
     private static final ArrayList<String> ignore = AsterixTestHelper.readFile(FILENAME_IGNORE, PATH_BASE);
     private static final ArrayList<String> only = AsterixTestHelper.readFile(FILENAME_ONLY, PATH_BASE);
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/api.xml b/asterixdb/asterix-app/src/test/resources/runtimets/api.xml
index 0fa83dd..372aa47 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/api.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/api.xml
@@ -66,11 +66,6 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="api">
-      <compilation-unit name="replication">
-        <output-dir compare="Text">replication</output-dir>
-      </compilation-unit>
-    </test-case>
-    <test-case FilePath="api">
       <compilation-unit name="query_status_1">
         <output-dir compare="Text">query_status_1</output-dir>
         <expected-error>HTTP/1.1 404 Not Found</expected-error>
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/APIQueries.xml b/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/APIQueries.xml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/APIQueries.xml
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/replication/replication.1.get.http b/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/replication/replication.1.get.http
deleted file mode 100644
index 5976b5d..0000000
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries/api/replication/replication.1.get.http
+++ /dev/null
@@ -1,25 +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.
- */
-/*
- * Test case Name  : replication
- * Description     : Replication
- * Expected Result : Positive
- * Date            : 28th October 2016
- */
-/admin/cluster/replication
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1/cluster_state_1.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1/cluster_state_1.1.adm
index 42fb7c3..03884bd 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1/cluster_state_1.1.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1/cluster_state_1.1.adm
@@ -5,110 +5,32 @@
     "threadDumpUri" : "http://127.0.0.1:19002/admin/cluster/cc/threaddump"
   },
   "config" : {
-    "api.port" : 19002,
-    "cluster.partitions" : {
-      "0" : {
-        "partitionId" : 0,
-        "nodeId" : "asterix_nc1",
-        "activeNodeId" : "asterix_nc1",
-        "active" : true,
-        "iodeviceNum" : 0
-      },
-      "1" : {
-        "partitionId" : 1,
-        "nodeId" : "asterix_nc1",
-        "activeNodeId" : "asterix_nc1",
-        "active" : true,
-        "iodeviceNum" : 1
-      },
-      "2" : {
-        "partitionId" : 2,
-        "nodeId" : "asterix_nc2",
-        "activeNodeId" : "asterix_nc2",
-        "active" : true,
-        "iodeviceNum" : 0
-      },
-      "3" : {
-        "partitionId" : 3,
-        "nodeId" : "asterix_nc2",
-        "activeNodeId" : "asterix_nc2",
-        "active" : true,
-        "iodeviceNum" : 1
-      }
-    },
     "compiler.framesize" : 32768,
     "compiler.groupmemory" : 163840,
     "compiler.joinmemory" : 262144,
     "compiler.parallelism" : 0,
     "compiler.pregelix.home" : "~/pregelix",
     "compiler.sortmemory" : 327680,
-    "core.dump.paths" : { },
     "feed.central.manager.port" : 4500,
     "feed.max.threshold.period" : 5,
     "feed.memory.available.wait.timeout" : 10,
     "feed.memory.global.budget" : 67108864,
     "feed.pending.work.threshold" : 50,
-    "feed.port" : 19003,
-    "instance.name" : null,
-    "log.level" : "WARNING",
+    "instance.name" : "DEFAULT_INSTANCE",
+    "log.level" : "INFO",
     "max.wait.active.cluster" : 60,
+    "messaging.frame.count" : 512,
+    "messaging.frame.size" : 4096,
     "metadata.callback.port" : 0,
+    "metadata.listen.port" : 0,
     "metadata.node" : "asterix_nc1",
-    "metadata.partition" : {
-      "partitionId" : 0,
-      "nodeId" : "asterix_nc1",
-      "activeNodeId" : "asterix_nc1",
-      "active" : true,
-      "iodeviceNum" : 0
-    },
-    "metadata.port" : 0,
     "metadata.registration.timeout.secs" : 60,
-    "node.partitions" : {
-      "asterix_nc1" : [ {
-        "partitionId" : 0,
-        "nodeId" : "asterix_nc1",
-        "activeNodeId" : "asterix_nc1",
-        "active" : true,
-        "iodeviceNum" : 0
-      }, {
-        "partitionId" : 1,
-        "nodeId" : "asterix_nc1",
-        "activeNodeId" : "asterix_nc1",
-        "active" : true,
-        "iodeviceNum" : 1
-      } ],
-      "asterix_nc2" : [ {
-        "partitionId" : 2,
-        "nodeId" : "asterix_nc2",
-        "activeNodeId" : "asterix_nc2",
-        "active" : true,
-        "iodeviceNum" : 0
-      }, {
-        "partitionId" : 3,
-        "nodeId" : "asterix_nc2",
-        "activeNodeId" : "asterix_nc2",
-        "active" : true,
-        "iodeviceNum" : 1
-      } ]
-    },
-    "node.stores" : {
-      "asterix_nc1" : [ "iodevice0", "iodevice1" ],
-      "asterix_nc2" : [ "iodevice0", "iodevice1" ]
-    },
     "plot.activate" : false,
-    "storage.buffercache.maxopenfiles" : 2147483647,
-    "storage.buffercache.pagesize" : 32768,
-    "storage.buffercache.size" : 50331648,
-    "storage.lsm.bloomfilter.falsepositiverate" : 0.01,
-    "storage.memorycomponent.globalbudget" : 536870912,
-    "storage.memorycomponent.numcomponents" : 2,
-    "storage.memorycomponent.numpages" : 8,
-    "storage.memorycomponent.pagesize" : 131072,
-    "storage.metadata.memorycomponent.numpages" : 85,
-    "transaction.log.dirs" : {
-      "asterix_nc1" : "target/txnLogDir/asterix_nc1",
-      "asterix_nc2" : "target/txnLogDir/asterix_nc2"
-    },
+    "replication.log.batchsize" : 4096,
+    "replication.log.buffer.numpages" : 8,
+    "replication.log.buffer.pagesize" : 131072,
+    "replication.max.remote.recovery.attempts" : 5,
+    "replication.timeout" : 30,
     "txn.commitprofiler.reportinterval" : 5,
     "txn.job.recovery.memorysize" : 67108864,
     "txn.lock.escalationthreshold" : 1000,
@@ -120,10 +42,7 @@
     "txn.log.checkpoint.history" : 0,
     "txn.log.checkpoint.lsnthreshold" : 67108864,
     "txn.log.checkpoint.pollfrequency" : 120,
-    "txn.log.partitionsize" : 268435456,
-    "web.port" : 19001,
-    "web.queryinterface.port" : 19006,
-    "web.secondary.port" : 19005
+    "txn.log.partitionsize" : 268435456
   },
   "diagnosticsUri" : "http://127.0.0.1:19002/admin/diagnostics",
   "fullShutdownUri" : "http://127.0.0.1:19002/admin/shutdown?all=true",
@@ -155,7 +74,6 @@
     "statsUri" : "http://127.0.0.1:19002/admin/cluster/node/asterix_nc2/stats",
     "threadDumpUri" : "http://127.0.0.1:19002/admin/cluster/node/asterix_nc2/threaddump"
   } ],
-  "replicationUri" : "http://127.0.0.1:19002/admin/cluster/replication",
   "shutdownUri" : "http://127.0.0.1:19002/admin/shutdown",
   "state" : "ACTIVE",
   "versionUri" : "http://127.0.0.1:19002/admin/version"
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1_full/cluster_state_1_full.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1_full/cluster_state_1_full.1.adm
index 75c4d3e..372ac00 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1_full/cluster_state_1_full.1.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1_full/cluster_state_1_full.1.adm
@@ -5,110 +5,32 @@
     "threadDumpUri" : "http://127.0.0.1:19002/admin/cluster/cc/threaddump"
   },
   "config" : {
-    "api.port" : 19002,
-    "cluster.partitions" : {
-      "0" : {
-        "partitionId" : 0,
-        "nodeId" : "asterix_nc1",
-        "activeNodeId" : "asterix_nc1",
-        "active" : true,
-        "iodeviceNum" : 0
-      },
-      "1" : {
-        "partitionId" : 1,
-        "nodeId" : "asterix_nc1",
-        "activeNodeId" : "asterix_nc1",
-        "active" : true,
-        "iodeviceNum" : 1
-      },
-      "2" : {
-        "partitionId" : 2,
-        "nodeId" : "asterix_nc2",
-        "activeNodeId" : "asterix_nc2",
-        "active" : true,
-        "iodeviceNum" : 0
-      },
-      "3" : {
-        "partitionId" : 3,
-        "nodeId" : "asterix_nc2",
-        "activeNodeId" : "asterix_nc2",
-        "active" : true,
-        "iodeviceNum" : 1
-      }
-    },
     "compiler.framesize" : 32768,
     "compiler.groupmemory" : 163840,
     "compiler.joinmemory" : 262144,
     "compiler.parallelism" : -1,
     "compiler.pregelix.home" : "~/pregelix",
     "compiler.sortmemory" : 327680,
-    "core.dump.paths" : { },
     "feed.central.manager.port" : 4500,
     "feed.max.threshold.period" : 5,
     "feed.memory.available.wait.timeout" : 10,
     "feed.memory.global.budget" : 67108864,
     "feed.pending.work.threshold" : 50,
-    "feed.port" : 19003,
-    "instance.name" : null,
+    "instance.name" : "DEFAULT_INSTANCE",
     "log.level" : "WARNING",
     "max.wait.active.cluster" : 60,
+    "messaging.frame.count" : 512,
+    "messaging.frame.size" : 4096,
     "metadata.callback.port" : 0,
+    "metadata.listen.port" : 0,
     "metadata.node" : "asterix_nc1",
-    "metadata.partition" : {
-      "partitionId" : 0,
-      "nodeId" : "asterix_nc1",
-      "activeNodeId" : "asterix_nc1",
-      "active" : true,
-      "iodeviceNum" : 0
-    },
-    "metadata.port" : 0,
     "metadata.registration.timeout.secs" : 60,
-    "node.partitions" : {
-      "asterix_nc1" : [ {
-        "partitionId" : 0,
-        "nodeId" : "asterix_nc1",
-        "activeNodeId" : "asterix_nc1",
-        "active" : true,
-        "iodeviceNum" : 0
-      }, {
-        "partitionId" : 1,
-        "nodeId" : "asterix_nc1",
-        "activeNodeId" : "asterix_nc1",
-        "active" : true,
-        "iodeviceNum" : 1
-      } ],
-      "asterix_nc2" : [ {
-        "partitionId" : 2,
-        "nodeId" : "asterix_nc2",
-        "activeNodeId" : "asterix_nc2",
-        "active" : true,
-        "iodeviceNum" : 0
-      }, {
-        "partitionId" : 3,
-        "nodeId" : "asterix_nc2",
-        "activeNodeId" : "asterix_nc2",
-        "active" : true,
-        "iodeviceNum" : 1
-      } ]
-    },
-    "node.stores" : {
-      "asterix_nc1" : [ "iodevice0", "iodevice1" ],
-      "asterix_nc2" : [ "iodevice0", "iodevice1" ]
-    },
     "plot.activate" : false,
-    "storage.buffercache.maxopenfiles" : 2147483647,
-    "storage.buffercache.pagesize" : 32768,
-    "storage.buffercache.size" : 50331648,
-    "storage.lsm.bloomfilter.falsepositiverate" : 0.01,
-    "storage.memorycomponent.globalbudget" : 536870912,
-    "storage.memorycomponent.numcomponents" : 2,
-    "storage.memorycomponent.numpages" : 8,
-    "storage.memorycomponent.pagesize" : 131072,
-    "storage.metadata.memorycomponent.numpages" : 85,
-    "transaction.log.dirs" : {
-      "asterix_nc1" : "target/txnLogDir/asterix_nc1",
-      "asterix_nc2" : "target/txnLogDir/asterix_nc2"
-    },
+    "replication.log.batchsize" : 4096,
+    "replication.log.buffer.numpages" : 8,
+    "replication.log.buffer.pagesize" : 131072,
+    "replication.max.remote.recovery.attempts" : 5,
+    "replication.timeout" : 30,
     "txn.commitprofiler.reportinterval" : 5,
     "txn.job.recovery.memorysize" : 67108864,
     "txn.lock.escalationthreshold" : 1000,
@@ -120,10 +42,7 @@
     "txn.log.checkpoint.history" : 0,
     "txn.log.checkpoint.lsnthreshold" : 67108864,
     "txn.log.checkpoint.pollfrequency" : 120,
-    "txn.log.partitionsize" : 268435456,
-    "web.port" : 19001,
-    "web.queryinterface.port" : 19006,
-    "web.secondary.port" : 19005
+    "txn.log.partitionsize" : 268435456
   },
   "diagnosticsUri" : "http://127.0.0.1:19002/admin/diagnostics",
   "fullShutdownUri" : "http://127.0.0.1:19002/admin/shutdown?all=true",
@@ -155,7 +74,6 @@
     "statsUri" : "http://127.0.0.1:19002/admin/cluster/node/asterix_nc2/stats",
     "threadDumpUri" : "http://127.0.0.1:19002/admin/cluster/node/asterix_nc2/threaddump"
   } ],
-  "replicationUri" : "http://127.0.0.1:19002/admin/cluster/replication",
   "shutdownUri" : "http://127.0.0.1:19002/admin/shutdown",
   "state" : "ACTIVE",
   "versionUri" : "http://127.0.0.1:19002/admin/version"
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1_less/cluster_state_1_less.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1_less/cluster_state_1_less.1.adm
index 76219aa..9d1ba6e 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1_less/cluster_state_1_less.1.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1_less/cluster_state_1_less.1.adm
@@ -5,110 +5,32 @@
     "threadDumpUri" : "http://127.0.0.1:19002/admin/cluster/cc/threaddump"
   },
   "config" : {
-    "api.port" : 19002,
-    "cluster.partitions" : {
-      "0" : {
-        "partitionId" : 0,
-        "nodeId" : "asterix_nc1",
-        "activeNodeId" : "asterix_nc1",
-        "active" : true,
-        "iodeviceNum" : 0
-      },
-      "1" : {
-        "partitionId" : 1,
-        "nodeId" : "asterix_nc1",
-        "activeNodeId" : "asterix_nc1",
-        "active" : true,
-        "iodeviceNum" : 1
-      },
-      "2" : {
-        "partitionId" : 2,
-        "nodeId" : "asterix_nc2",
-        "activeNodeId" : "asterix_nc2",
-        "active" : true,
-        "iodeviceNum" : 0
-      },
-      "3" : {
-        "partitionId" : 3,
-        "nodeId" : "asterix_nc2",
-        "activeNodeId" : "asterix_nc2",
-        "active" : true,
-        "iodeviceNum" : 1
-      }
-    },
     "compiler.framesize" : 32768,
     "compiler.groupmemory" : 163840,
     "compiler.joinmemory" : 262144,
     "compiler.parallelism" : 3,
     "compiler.pregelix.home" : "~/pregelix",
     "compiler.sortmemory" : 327680,
-    "core.dump.paths" : { },
     "feed.central.manager.port" : 4500,
     "feed.max.threshold.period" : 5,
     "feed.memory.available.wait.timeout" : 10,
     "feed.memory.global.budget" : 67108864,
     "feed.pending.work.threshold" : 50,
-    "feed.port" : 19003,
-    "instance.name" : null,
+    "instance.name" : "DEFAULT_INSTANCE",
     "log.level" : "WARNING",
     "max.wait.active.cluster" : 60,
+    "messaging.frame.count" : 512,
+    "messaging.frame.size" : 4096,
     "metadata.callback.port" : 0,
+    "metadata.listen.port" : 0,
     "metadata.node" : "asterix_nc1",
-    "metadata.partition" : {
-      "partitionId" : 0,
-      "nodeId" : "asterix_nc1",
-      "activeNodeId" : "asterix_nc1",
-      "active" : true,
-      "iodeviceNum" : 0
-    },
-    "metadata.port" : 0,
     "metadata.registration.timeout.secs" : 60,
-    "node.partitions" : {
-      "asterix_nc1" : [ {
-        "partitionId" : 0,
-        "nodeId" : "asterix_nc1",
-        "activeNodeId" : "asterix_nc1",
-        "active" : true,
-        "iodeviceNum" : 0
-      }, {
-        "partitionId" : 1,
-        "nodeId" : "asterix_nc1",
-        "activeNodeId" : "asterix_nc1",
-        "active" : true,
-        "iodeviceNum" : 1
-      } ],
-      "asterix_nc2" : [ {
-        "partitionId" : 2,
-        "nodeId" : "asterix_nc2",
-        "activeNodeId" : "asterix_nc2",
-        "active" : true,
-        "iodeviceNum" : 0
-      }, {
-        "partitionId" : 3,
-        "nodeId" : "asterix_nc2",
-        "activeNodeId" : "asterix_nc2",
-        "active" : true,
-        "iodeviceNum" : 1
-      } ]
-    },
-    "node.stores" : {
-      "asterix_nc1" : [ "iodevice0", "iodevice1" ],
-      "asterix_nc2" : [ "iodevice0", "iodevice1" ]
-    },
     "plot.activate" : false,
-    "storage.buffercache.maxopenfiles" : 2147483647,
-    "storage.buffercache.pagesize" : 32768,
-    "storage.buffercache.size" : 50331648,
-    "storage.lsm.bloomfilter.falsepositiverate" : 0.01,
-    "storage.memorycomponent.globalbudget" : 536870912,
-    "storage.memorycomponent.numcomponents" : 2,
-    "storage.memorycomponent.numpages" : 8,
-    "storage.memorycomponent.pagesize" : 131072,
-    "storage.metadata.memorycomponent.numpages" : 85,
-    "transaction.log.dirs" : {
-      "asterix_nc1" : "target/txnLogDir/asterix_nc1",
-      "asterix_nc2" : "target/txnLogDir/asterix_nc2"
-    },
+    "replication.log.batchsize" : 4096,
+    "replication.log.buffer.numpages" : 8,
+    "replication.log.buffer.pagesize" : 131072,
+    "replication.max.remote.recovery.attempts" : 5,
+    "replication.timeout" : 30,
     "txn.commitprofiler.reportinterval" : 5,
     "txn.job.recovery.memorysize" : 67108864,
     "txn.lock.escalationthreshold" : 1000,
@@ -120,10 +42,7 @@
     "txn.log.checkpoint.history" : 0,
     "txn.log.checkpoint.lsnthreshold" : 67108864,
     "txn.log.checkpoint.pollfrequency" : 120,
-    "txn.log.partitionsize" : 268435456,
-    "web.port" : 19001,
-    "web.queryinterface.port" : 19006,
-    "web.secondary.port" : 19005
+    "txn.log.partitionsize" : 268435456
   },
   "diagnosticsUri" : "http://127.0.0.1:19002/admin/diagnostics",
   "fullShutdownUri" : "http://127.0.0.1:19002/admin/shutdown?all=true",
@@ -155,7 +74,6 @@
     "statsUri" : "http://127.0.0.1:19002/admin/cluster/node/asterix_nc2/stats",
     "threadDumpUri" : "http://127.0.0.1:19002/admin/cluster/node/asterix_nc2/threaddump"
   } ],
-  "replicationUri" : "http://127.0.0.1:19002/admin/cluster/replication",
   "shutdownUri" : "http://127.0.0.1:19002/admin/shutdown",
   "state" : "ACTIVE",
   "versionUri" : "http://127.0.0.1:19002/admin/version"
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/api/replication/replication.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/replication/replication.1.adm
deleted file mode 100644
index a614faa..0000000
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/api/replication/replication.1.adm
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "config" : {
-    "log.batchsize" : 4096,
-    "log.buffer.numpages" : 8,
-    "log.buffer.pagesize" : 131072,
-    "max.remote.recovery.attempts" : 5,
-    "timeout" : 30
-  }
-}