Support frozen Intents

- setReroutable() and isReroutable() methods are added to Intent classes
- The intent is called as "frozen intent" if its isReroutable() method returns false
- Path calculation of Each frozen intent is skipped in PathCalcRuntimeModule.reroutePaths() method

Note:
Before this commit, the frozen intent was defined with its ID starting from "F".
Now this ID-based expression of frozen intent is completely removed from Intent classes,
but it still remains in REST API.
We should redesign REST API to remove the ID-based definition completely in the future.

Change-Id: Id8050052ca5be5d18911bcf22f647d4c54064651
diff --git a/src/main/java/net/onrc/onos/datagrid/web/GetNGFlowsSummaryResource.java b/src/main/java/net/onrc/onos/datagrid/web/GetNGFlowsSummaryResource.java
index cf02a12..16f41ef 100644
--- a/src/main/java/net/onrc/onos/datagrid/web/GetNGFlowsSummaryResource.java
+++ b/src/main/java/net/onrc/onos/datagrid/web/GetNGFlowsSummaryResource.java
@@ -1,7 +1,6 @@
 package net.onrc.onos.datagrid.web;
 
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.SortedMap;
 import java.util.TreeMap;
 
@@ -69,8 +68,6 @@
 	    // Decode the Shortest Path ID
 	    String applnIntentId = parentIntent.getId();
 	    String intentId = applnIntentId.split(":")[1];
- 	    // A hack for Flow IDs that are not routable 
-	    intentId = intentId.replace("F", "");
 
 	    // Create the Flow Path
 	    FlowId flowId = new FlowId(intentId);
diff --git a/src/main/java/net/onrc/onos/datagrid/web/IntentResource.java b/src/main/java/net/onrc/onos/datagrid/web/IntentResource.java
index c625f3f..b07be6b 100755
--- a/src/main/java/net/onrc/onos/datagrid/web/IntentResource.java
+++ b/src/main/java/net/onrc/onos/datagrid/web/IntentResource.java
@@ -7,7 +7,6 @@
 import java.io.IOException;
 import java.util.Collection;
 import java.util.Iterator;
-import net.onrc.onos.datagrid.IDatagridService;
 import net.onrc.onos.intent.ConstrainedShortestPathIntent;
 import net.onrc.onos.intent.ShortestPathIntent;
 import net.onrc.onos.intent.IntentOperation;
@@ -40,34 +39,6 @@
     private final static Logger log = LoggerFactory.getLogger(IntentResource.class);
     // TODO need to assign proper application id.
     private final String APPLN_ID = "1";
-
-    private class IntentStatus {
-        String intentId;
-        String status;
-        
-        public IntentStatus() {}
-        
-        public IntentStatus(String intentId, String status) {
-            this.intentId = intentId;
-            this.status = status;
-        }
-        
-        public String getIntentId() {
-            return intentId;
-        }
-        
-        public void setIntentId(String intentId) {
-            this.intentId = intentId;
-        }
-        
-        public String getStatus() {
-            return status;
-        }
-        
-        public void setStatus(String status) {
-            this.status = status;
-        }
-    }
     
     @Post("json")
     public String store(String jsonIntent) throws IOException {
@@ -204,7 +175,13 @@
         String intentType = (String)fields.get("intent_type");
         String intentOp = (String)fields.get("intent_op");
         Intent intent;
-        String applnIntentId = APPLN_ID + ":" + (String)fields.get("intent_id");
+        String intentId = (String)fields.get("intent_id");
+        boolean pathFrozen = false;
+        if (intentId.startsWith("F")) { // TODO define REST API for frozen intents
+            pathFrozen = true;
+            intentId = intentId.substring(1);
+        }
+        String applnIntentId = APPLN_ID + ":" + intentId;
         
         IntentOperation.Operator operation = IntentOperation.Operator.ADD;
         if ((intentOp.equals("remove"))) {
@@ -218,6 +195,7 @@
                     Long.decode((String) fields.get("dstSwitch")),
                     (long) fields.get("dstPort"),
                     MACAddress.valueOf((String) fields.get("dstMac")).toLong());
+            spi.setPathFrozen(pathFrozen);
             operations.add(operation, spi);
             intent = spi;
         } else {
@@ -229,6 +207,7 @@
                     (long) fields.get("dstPort"),
                     MACAddress.valueOf((String) fields.get("dstMac")).toLong(),
                     (double) fields.get("bandwidth"));
+            cspi.setPathFrozen(pathFrozen);
             operations.add(operation, cspi);
             intent = cspi;
         }
diff --git a/src/main/java/net/onrc/onos/intent/Intent.java b/src/main/java/net/onrc/onos/intent/Intent.java
index c6a960f..eba6e32 100644
--- a/src/main/java/net/onrc/onos/intent/Intent.java
+++ b/src/main/java/net/onrc/onos/intent/Intent.java
@@ -21,6 +21,7 @@
 
 	private String id;
 	private IntentState state = IntentState.CREATED;
+	private boolean pathFrozen = false;
 
 	@Optional(value="logs")
 	private LinkedList<String> logs = new LinkedList<>();
@@ -62,6 +63,14 @@
 		return oldState;
 	}
 
+	public boolean isPathFrozen() {
+		return pathFrozen;
+	}
+
+	public void setPathFrozen(boolean isFrozen) {
+		pathFrozen = isFrozen;
+	}
+
 	public LinkedList<String> getLogs() {
 		return logs;
 	}
diff --git a/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java b/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java
index 1101dc9..8cd3c32 100755
--- a/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java
+++ b/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java
@@ -100,7 +100,7 @@
 		IntentOperationList reroutingOperation = new IntentOperationList();
 		for (Intent intent : oldPaths) {
 			PathIntent pathIntent = (PathIntent) intent;
-			if (pathIntent.getId().startsWith("1:F")) // XXX: demo special, the intent start with "F" is skipped
+			if (pathIntent.isPathFrozen())
 				continue;
 			if (pathIntent.getState().equals(IntentState.INST_ACK) && // XXX: path intents in flight
 					!reroutingOperation.contains(pathIntent.getParentIntent())) {