Added a flag to identify first NC start during creation

Change-Id: If1b76ec83ae19f9c643a223e44712228ed7037f5
Reviewed-on: https://asterix-gerrit.ics.uci.edu/272
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Ian Maxon <imaxon@uci.edu>
diff --git a/asterix-app/src/main/java/edu/uci/ics/asterix/hyracks/bootstrap/NCApplicationEntryPoint.java b/asterix-app/src/main/java/edu/uci/ics/asterix/hyracks/bootstrap/NCApplicationEntryPoint.java
index 89158a0..117ea20 100644
--- a/asterix-app/src/main/java/edu/uci/ics/asterix/hyracks/bootstrap/NCApplicationEntryPoint.java
+++ b/asterix-app/src/main/java/edu/uci/ics/asterix/hyracks/bootstrap/NCApplicationEntryPoint.java
@@ -53,6 +53,9 @@
     @Option(name = "-metadata-port", usage = "IP port to bind metadata listener (default: random port)", required = false)
     public int metadataRmiPort = 0;
 
+    @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;
+
     private INCApplicationContext ncApplicationContext = null;
     private IAsterixAppRuntimeContext runtimeContext;
     private String nodeId;
@@ -93,22 +96,29 @@
         runtimeContext.initialize();
         ncApplicationContext.setApplicationObject(runtimeContext);
 
-        // #. recover if the system is corrupted by checking system state.
-        IRecoveryManager recoveryMgr = runtimeContext.getTransactionSubsystem().getRecoveryManager();
-        systemState = recoveryMgr.getSystemState();
+        if (initialRun) {
+            LOGGER.info("System is being initialized. (first run)");
+            systemState = SystemState.NEW_UNIVERSE;
+        } else {
+            // #. recover if the system is corrupted by checking system state.
+            IRecoveryManager recoveryMgr = runtimeContext.getTransactionSubsystem().getRecoveryManager();
+            systemState = recoveryMgr.getSystemState();
 
-        if (LOGGER.isLoggable(Level.INFO)) {
-            LOGGER.info("System is in a state: " + systemState);
+            if (LOGGER.isLoggable(Level.INFO)) {
+                LOGGER.info("System is in a state: " + systemState);
+            }
+
+            if (systemState != SystemState.NEW_UNIVERSE) {
+                PersistentLocalResourceRepository localResourceRepository = (PersistentLocalResourceRepository) runtimeContext
+                        .getLocalResourceRepository();
+                localResourceRepository.initialize(nodeId, null, false, runtimeContext.getResourceIdFactory());
+            }
+            
+            if (systemState == SystemState.CORRUPTED) {
+                recoveryMgr.startRecovery(true);
+            }
         }
 
-        if (systemState != SystemState.NEW_UNIVERSE) {
-            PersistentLocalResourceRepository localResourceRepository = (PersistentLocalResourceRepository) runtimeContext
-                    .getLocalResourceRepository();
-            localResourceRepository.initialize(nodeId, null, false, runtimeContext.getResourceIdFactory());
-        }
-        if (systemState == SystemState.CORRUPTED) {
-            recoveryMgr.startRecovery(true);
-        }
     }
 
     @Override
diff --git a/asterix-events/src/main/java/edu/uci/ics/asterix/event/util/PatternCreator.java b/asterix-events/src/main/java/edu/uci/ics/asterix/event/util/PatternCreator.java
index 9af9307..178663b 100644
--- a/asterix-events/src/main/java/edu/uci/ics/asterix/event/util/PatternCreator.java
+++ b/asterix-events/src/main/java/edu/uci/ics/asterix/event/util/PatternCreator.java
@@ -79,7 +79,8 @@
         return patterns;
     }
 
-    public Patterns getStartAsterixPattern(String asterixInstanceName, Cluster cluster) throws Exception {
+    public Patterns getStartAsterixPattern(String asterixInstanceName, Cluster cluster, boolean createCommand)
+            throws Exception {
         String ccLocationId = cluster.getMasterNode().getId();
         List<Pattern> ps = new ArrayList<Pattern>();
 
@@ -90,7 +91,7 @@
         for (Node node : cluster.getNode()) {
             String iodevices = node.getIodevices() == null ? cluster.getIodevices() : node.getIodevices();
             Pattern createNC = createNCStartPattern(cluster.getMasterNode().getClusterIp(), node.getId(),
-                    asterixInstanceName + "_" + node.getId(), iodevices);
+                    asterixInstanceName + "_" + node.getId(), iodevices, createCommand);
             addInitialDelay(createNC, 5, "sec");
             ps.add(createNC);
         }
@@ -555,9 +556,13 @@
         return new Pattern(null, 1, null, event);
     }
 
-    public Pattern createNCStartPattern(String ccHost, String hostId, String nodeControllerId, String iodevices) {
+    public Pattern createNCStartPattern(String ccHost, String hostId, String nodeControllerId, String iodevices,
+            boolean isInitialRun) {
         Nodeid nodeid = new Nodeid(new Value(null, hostId));
         String pargs = ccHost + " " + nodeControllerId + " " + iodevices;
+        if (isInitialRun) {
+            pargs += " " + "-initial-run";
+        }
         Event event = new Event("node_join", nodeid, pargs);
         return new Pattern(null, 1, null, event);
     }
diff --git a/asterix-events/src/main/resources/events/node_join/nc_join.sh b/asterix-events/src/main/resources/events/node_join/nc_join.sh
index a18fe09..3dba3f8 100644
--- a/asterix-events/src/main/resources/events/node_join/nc_join.sh
+++ b/asterix-events/src/main/resources/events/node_join/nc_join.sh
@@ -15,6 +15,7 @@
 CC_HOST=$1
 NC_ID=$2
 IO_DEVICES=$3
+INITIAL_RUN_FLAG=$4
 if [ ! -d $LOG_DIR ]; 
 then 
   mkdir -p $LOG_DIR
@@ -22,4 +23,4 @@
 
 cd $WORKING_DIR
 
-$ASTERIX_HOME/bin/asterixnc -node-id $NC_ID -cc-host $CC_HOST -cc-port $CLUSTER_NET_PORT  -cluster-net-ip-address $IP_LOCATION  -data-ip-address $IP_LOCATION -iodevices $IO_DEVICES -result-ip-address $IP_LOCATION &> $LOG_DIR/${NC_ID}.log
+$ASTERIX_HOME/bin/asterixnc -node-id $NC_ID -cc-host $CC_HOST -cc-port $CLUSTER_NET_PORT  -cluster-net-ip-address $IP_LOCATION  -data-ip-address $IP_LOCATION -iodevices $IO_DEVICES -result-ip-address $IP_LOCATION -- $INITIAL_RUN_FLAG &> $LOG_DIR/${NC_ID}.log
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CreateCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CreateCommand.java
index 5b024ec..ce17e7a 100644
--- a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CreateCommand.java
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/CreateCommand.java
@@ -65,7 +65,7 @@
                 asterixInstanceName, cluster);
         eventrixClient.submit(asterixBinarytrasnferPattern);
 
-        Patterns patterns = PatternCreator.INSTANCE.getStartAsterixPattern(asterixInstanceName, cluster);
+        Patterns patterns = PatternCreator.INSTANCE.getStartAsterixPattern(asterixInstanceName, cluster, true);
         eventrixClient.submit(patterns);
 
         AsterixRuntimeState runtimeState = VerificationUtil.getAsterixRuntimeState(asterixInstance);
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/StartCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/StartCommand.java
index 63ec6fc..d58431b 100644
--- a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/StartCommand.java
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/StartCommand.java
@@ -44,7 +44,7 @@
                 asterixInstanceName, instance.getCluster());
         client.submit(asterixBinaryTransferPattern);
         AsterixEventServiceUtil.createClusterProperties(instance.getCluster(), instance.getAsterixConfiguration());
-        Patterns patterns = PatternCreator.INSTANCE.getStartAsterixPattern(asterixInstanceName, instance.getCluster());
+        Patterns patterns = PatternCreator.INSTANCE.getStartAsterixPattern(asterixInstanceName, instance.getCluster(), false);
         client.submit(patterns);
         AsterixEventServiceUtil.deleteDirectory(InstallerDriver.getManagixHome() + File.separator
                 + InstallerDriver.ASTERIX_DIR + File.separator + asterixInstanceName);
diff --git a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/StartNodeCommand.java b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/StartNodeCommand.java
index 7d0a6ee..7719702 100644
--- a/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/StartNodeCommand.java
+++ b/asterix-installer/src/main/java/edu/uci/ics/asterix/installer/command/StartNodeCommand.java
@@ -62,7 +62,7 @@
                 if (n.equals(node.getId())) {
                     String iodevices = node.getIodevices() == null ? cluster.getIodevices() : node.getIodevices();
                     Pattern createNC = PatternCreator.INSTANCE.createNCStartPattern(cluster.getMasterNode()
-                            .getClusterIp(), node.getId(), asterixInstanceName + "_" + node.getId(), iodevices);
+                            .getClusterIp(), node.getId(), asterixInstanceName + "_" + node.getId(), iodevices, false);
                     pl.add(createNC);
                     break;
                 }
diff --git a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/cluster/ClusterManager.java b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/cluster/ClusterManager.java
index cefb431..fe7f4a4 100644
--- a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/cluster/ClusterManager.java
+++ b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/cluster/ClusterManager.java
@@ -113,7 +113,7 @@
             String hostId = node.getId();
             String nodeControllerId = asterixInstanceName + "_" + node.getId();
             String iodevices = node.getIodevices() == null ? cluster.getIodevices() : node.getIodevices();
-            Pattern startNC = PatternCreator.INSTANCE.createNCStartPattern(ccHost, hostId, nodeControllerId, iodevices);
+            Pattern startNC = PatternCreator.INSTANCE.createNCStartPattern(ccHost, hostId, nodeControllerId, iodevices, false);
             pattern.add(startNC);
             Patterns startNCPattern = new Patterns(pattern);
             client.submit(startNCPattern);
diff --git a/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/recovery/RecoveryManager.java b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/recovery/RecoveryManager.java
index ea30846..a3c0a77 100644
--- a/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/recovery/RecoveryManager.java
+++ b/asterix-transactions/src/main/java/edu/uci/ics/asterix/transaction/management/service/recovery/RecoveryManager.java
@@ -107,8 +107,8 @@
         try {
             checkpointObject = readCheckpoint();
         } catch (FileNotFoundException e) {
-            //This is initial bootstrap. 
-            //Otherwise, the checkpoint file is deleted unfortunately. What we can do in this case?
+            //The checkpoint file doesn't exist => Failure happened during NC initialization.
+            //Retry to initialize the NC by setting the state to NEW_UNIVERSE
             state = SystemState.NEW_UNIVERSE;
             if (LOGGER.isLoggable(Level.INFO)) {
                 LOGGER.info("The checkpoint file doesn't exist: systemState = NEW_UNIVERSE");