- Added a function to return tunnel info
 - Change the tunnel ID type to characters (not only the integer)

Change-Id: I9f6689001a8b0dd653455f5b268f385dd6169537
diff --git a/src/main/java/net/floodlightcontroller/core/IOF13Switch.java b/src/main/java/net/floodlightcontroller/core/IOF13Switch.java
index 846197c..3c50cbc 100644
--- a/src/main/java/net/floodlightcontroller/core/IOF13Switch.java
+++ b/src/main/java/net/floodlightcontroller/core/IOF13Switch.java
@@ -142,6 +142,6 @@
      */
     public TableId getTableId(String tableType);
 
-    public int createTunnel(int tunnelId, List<String> route, NeighborSet ns);
+    public int createTunnel(String tunnelId, List<String> route, NeighborSet ns);
 
 }
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java
index 4c48e0a..8f0b47d 100644
--- a/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java
@@ -105,9 +105,10 @@
     private HashMap<String, LinkData> linksDown;
     private HashMap<String, LinkData> linksToAdd;
     private ConcurrentLinkedQueue<TopologyEvents> topologyEventQueue;
-    private HashMap<Integer, HashMap<String, PolicyRouteInfo>> stitchInfo;
-    private HashMap<Integer, HashMap<String, Integer>> tunnelGroupMap;
-    private HashMap<Integer, PolicyInfo> policyTable;
+    private HashMap<String, HashMap<String, TunnelRouteInfo>> stitchInfo;
+    private HashMap<String, HashMap<String, Integer>> tunnelGroupMap;
+    private HashMap<String, PolicyInfo> policyTable;
+    private HashMap<String, List<Dpid>> tunnelTable;
 
     private int testMode = 0;
 
@@ -173,11 +174,12 @@
         linksDown = new HashMap<String, LinkData>();
         linksToAdd = new HashMap<String, LinkData>();
         topologyEventQueue = new ConcurrentLinkedQueue<TopologyEvents>();
-        stitchInfo = new HashMap<Integer, HashMap<String, PolicyRouteInfo>>();
+        stitchInfo = new HashMap<String, HashMap<String, TunnelRouteInfo>>();
         packetService = context.getServiceImpl(IPacketService.class);
-        tunnelGroupMap = new HashMap<Integer, HashMap<String, Integer>>();
+        tunnelGroupMap = new HashMap<String, HashMap<String, Integer>>();
         restApi = context.getServiceImpl(IRestApiService.class);
-        policyTable = new HashMap<Integer, PolicyInfo>();
+        policyTable = new HashMap<String, PolicyInfo>();
+        tunnelTable = new HashMap<String, List<Dpid>>();
 
         packetService.registerPacketListener(this);
         topologyService.addListener(this, false);
@@ -937,12 +939,12 @@
 
     class PolicyInfo {
 
-        int policyId;
+        String policyId;
         PacketMatch match;
         int priority;
-        int tunnelId;
+        String tunnelId;
 
-        PolicyInfo(int pid, PacketMatch match, int priority, int tid) {
+        PolicyInfo(String pid, PacketMatch match, int priority, String tid) {
             this.policyId = pid;
             this.match = match;
             this.priority = priority;
@@ -950,13 +952,13 @@
         }
     }
 
-    class PolicyRouteInfo {
+    class TunnelRouteInfo {
 
         String srcSwDpid;
         List<Dpid> fwdSwDpids;
         List<String> route;
 
-        PolicyRouteInfo() {
+        TunnelRouteInfo() {
             fwdSwDpids = new ArrayList<Dpid>();
             route = new ArrayList<String>();
         }
@@ -998,13 +1000,7 @@
      * @param tunnelId  Node IDs for the tunnel
      * @param Ids tunnel ID
      */
-    public boolean createTunnel(String tid, List<Dpid> dpids) {
-
-        int tunnelId = Integer.parseInt(tid);
-        if (tunnelId < 0) {
-            log.debug("Tunnel ID should be posivtive integer.");
-            return false;
-        }
+    public boolean createTunnel(String tunnelId, List<Dpid> dpids) {
 
         if (dpids.isEmpty() || dpids.size() < 2) {
             log.debug("Wrong tunnel information");
@@ -1016,15 +1012,15 @@
             Ids.add(getMplsLabel(dpid.toString()));
         }
 
-        HashMap<String, PolicyRouteInfo> stitchingRule = getStitchingRule(Ids);
-        stitchInfo.put(Integer.valueOf(tunnelId), stitchingRule);
+        HashMap<String, TunnelRouteInfo> stitchingRule = getStitchingRule(Ids);
+        stitchInfo.put(tunnelId, stitchingRule);
         if (stitchingRule == null) {
             log.debug("Failed to get the policy rule.");
             return false;
         }
         HashMap<String, Integer> switchGroupPair = new HashMap<String, Integer>();
         for (String targetDpid: stitchingRule.keySet()) {
-            PolicyRouteInfo route = stitchingRule.get(targetDpid);
+            TunnelRouteInfo route = stitchingRule.get(targetDpid);
 
             IOF13Switch targetSw = (IOF13Switch) floodlightProvider.getMasterSwitch(
                     getSwId(targetDpid.toString()));
@@ -1044,23 +1040,34 @@
 
         }
 
-        tunnelGroupMap.put(Integer.valueOf(tunnelId), switchGroupPair);
+        tunnelGroupMap.put(tunnelId, switchGroupPair);
+        tunnelTable.put(tunnelId, dpids);
 
         return true;
     }
 
     /**
+     * Return router DPIDs for the tunnel
+     *
+     * @param tid tunnel ID
+     * @return List of DPID
+     */
+    public List<Dpid> getTunnelInfo(String tid) {
+        return tunnelTable.get(tid);
+    }
+
+    /**
      * Set policy table for policy routing
      *
      * @param sw
      * @param mplsLabel
      */
-    public void setPolicyTable(int pid, MACAddress srcMac, MACAddress dstMac,
+    public void createPolicy(String pid, MACAddress srcMac, MACAddress dstMac,
             Short etherType, IPv4Net srcIp, IPv4Net dstIp, Byte ipProto,
-            Short srcTcpPort, Short dstTcpPort, int priority, int tid) {
+            Short srcTcpPort, Short dstTcpPort, int priority, String tid) {
 
-        HashMap<String, PolicyRouteInfo> routeInfo = stitchInfo.get(Integer.valueOf(tid));
-        HashMap<String, Integer> switchGroupPair = tunnelGroupMap.get(Integer.valueOf(tid));
+        HashMap<String, TunnelRouteInfo> routeInfo = stitchInfo.get(tid);
+        HashMap<String, Integer> switchGroupPair = tunnelGroupMap.get(tid);
 
         PacketMatchBuilder packetBuilder = new PacketMatchBuilder();
 
@@ -1110,7 +1117,7 @@
         }
 
         PolicyInfo policyInfo = new PolicyInfo(pid, policyMatch, priority, tid);
-        policyTable.put(Integer.valueOf(pid), policyInfo);
+        policyTable.put(pid, policyInfo);
     }
 
     /**
@@ -1121,18 +1128,18 @@
      * @param route
      * @return
      */
-    private HashMap<String, PolicyRouteInfo> getStitchingRule(List<String> route) {
+    private HashMap<String, TunnelRouteInfo> getStitchingRule(List<String> route) {
 
         if (route.isEmpty() || route.size() < 2)
             return null;
 
-        HashMap<String, PolicyRouteInfo> rules = new HashMap<String, PolicyRouteInfo>();
+        HashMap<String, TunnelRouteInfo> rules = new HashMap<String, TunnelRouteInfo>();
 
         Switch srcSw = this.getSwitchFromNodeId(route.get(0));
         String srcDpid = srcSw.getDpid().toString();
 
         if (route.size() <= MAX_NUM_LABELS+1) {
-            PolicyRouteInfo info = new PolicyRouteInfo();
+            TunnelRouteInfo info = new TunnelRouteInfo();
             info.setSrcDpid(srcSw.getDpid().toString());
             List<Dpid> fwdSwDpids = getForwardingSwitchForNodeId(srcSw, route.get(1));
             info.setFwdSwDpid(fwdSwDpids);
@@ -1143,7 +1150,7 @@
         }
 
         int i = 0;
-        PolicyRouteInfo routeInfo = new PolicyRouteInfo();
+        TunnelRouteInfo routeInfo = new TunnelRouteInfo();
         String prevNodeId = null;
         boolean checkNeighbor = true;
 
@@ -1192,7 +1199,7 @@
 
             if (i == MAX_NUM_LABELS+1) {
                 rules.put(srcDpid, routeInfo);
-                routeInfo = new PolicyRouteInfo();
+                routeInfo = new TunnelRouteInfo();
                 srcSw = getSwitchFromNodeId(nodeId);
                 srcDpid = getSwitchFromNodeId(nodeId).getDpid().toString();
                 routeInfo.setSrcDpid(srcDpid);
@@ -1221,10 +1228,10 @@
      * @param dstTcpPort
      * @param tid
      */
-    public void removePolicy(int pid) {
-        PolicyInfo policyInfo =  policyTable.get(Integer.valueOf(pid));
+    public void removePolicy(String pid) {
+        PolicyInfo policyInfo =  policyTable.get(pid);
         PacketMatch policyMatch = policyInfo.match;
-        int tid = policyInfo.tunnelId;
+        String tid = policyInfo.tunnelId;
         int priority = policyInfo.priority;
 
         List<Action> actions = new ArrayList<>();
@@ -1240,8 +1247,7 @@
         MatchActionOperationEntry maEntry =
                 new MatchActionOperationEntry(Operator.REMOVE, matchAction);
 
-        HashMap<String, Integer> groupInfo = tunnelGroupMap.get(
-                Integer.valueOf(tid));
+        HashMap<String, Integer> groupInfo = tunnelGroupMap.get(tid);
 
         for (String dpid: groupInfo.keySet()) {
             IOF13Switch sw13 = (IOF13Switch) floodlightProvider.getMasterSwitch(
@@ -1260,12 +1266,10 @@
         }
 
         log.debug("Policy {} is removed.", pid);
-         }
+    }
 
 
-    public void removeTunnel(int tunnelId) {
-
-
+    public void removeTunnel(String tunnelId) {
 
 
     }
@@ -1627,9 +1631,9 @@
                 IPv4Net dstIp = new IPv4Net("10.1.2.1/24");
 
                 log.debug("Set the policy 1");
-                this.setPolicyTable(1, null, null, Ethernet.TYPE_IPV4, srcIp,
+                this.createPolicy("1", null, null, Ethernet.TYPE_IPV4, srcIp,
                         dstIp, IPv4.PROTOCOL_ICMP, (short)-1, (short)-1, 10000,
-                        1);
+                        "1");
                 testMode = POLICY_ADD2;
                 testTask.reschedule(10, TimeUnit.SECONDS);
             }
@@ -1652,9 +1656,9 @@
                 IPv4Net dstIp = new IPv4Net("10.1.2.1/24");
 
                 log.debug("Set the policy 2");
-                this.setPolicyTable(2, null, null, Ethernet.TYPE_IPV4, srcIp,
+                this.createPolicy("2", null, null, Ethernet.TYPE_IPV4, srcIp,
                         dstIp, IPv4.PROTOCOL_ICMP, (short)-1, (short)-1, 20000,
-                        2);
+                        "2");
                 testMode = POLICY_REMOVE2;
                 testTask.reschedule(10, TimeUnit.SECONDS);
             }
@@ -1665,13 +1669,13 @@
         }
         else if (testMode == POLICY_REMOVE2){
             log.debug("Remove the policy 2");
-            this.removePolicy(2);
+            this.removePolicy("2");
             testMode = POLICY_REMOVE1;
             testTask.reschedule(10, TimeUnit.SECONDS);
         }
         else if (testMode == POLICY_REMOVE1){
             log.debug("Remove the policy 1");
-            this.removePolicy(1);
+            this.removePolicy("1");
         }
 
     }
@@ -1710,7 +1714,7 @@
      * @param ids
      * @param tunnelId
      */
-    private void printTunnelInfo(IOF13Switch targetSw, int tunnelId,
+    private void printTunnelInfo(IOF13Switch targetSw, String tunnelId,
             List<String> ids, NeighborSet ns) {
         StringBuilder logStr = new StringBuilder("In switch " +
             targetSw.getId() + ", create a tunnel " + tunnelId + " " + " of push ");
diff --git a/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java
index 4e11b28..88fd21c 100644
--- a/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java
+++ b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java
@@ -143,6 +143,7 @@
     private boolean isEdgeRouter;
     private int sid;
     private ConcurrentMap<NeighborSet, EcmpInfo> ecmpGroups;
+    private ConcurrentMap<String, List<Integer>> tunnelGroups;
     private ConcurrentMap<PortNumber, ArrayList<NeighborSet>> portNeighborSetMap;
     private AtomicInteger groupid;
 
@@ -159,6 +160,7 @@
         ecmpGroups = new ConcurrentHashMap<NeighborSet, EcmpInfo>();
         portNeighborSetMap =
                 new ConcurrentHashMap<PortNumber, ArrayList<NeighborSet>>();
+        tunnelGroups = new ConcurrentHashMap<String, List<Integer>>();
         segmentIds = new ArrayList<Integer>();
         isEdgeRouter = false;
         groupid = new AtomicInteger(0);
@@ -1641,7 +1643,7 @@
         }
     }
 
-    public int createTunnel(int tunnelId, List<String> route, NeighborSet ns) {
+    public int createTunnel(String tunnelId, List<String> route, NeighborSet ns) {
 
         // create a last group of the group chaining
         int finalGroupId = groupid.incrementAndGet();
@@ -1650,17 +1652,20 @@
         int groupId = 0;
         int nextGroupId = finalGroupId;
         boolean bos = false;
+        List<Integer> groups = new ArrayList<Integer>();
 
-        // process the node ID in reverse order
+        // process the node ID in order
         for (int i = 0; i < route.size(); i++) {
             String nodeId = route.get(i);
             groupId = groupid.incrementAndGet();
+            groups.add(Integer.valueOf(groupId));
             if (i == route.size()-1)
                 bos = true;
             createGroupForMplsLabel(groupId, nodeId, nextGroupId, bos);
             nextGroupId = groupId;
         }
 
+        tunnelGroups.putIfAbsent(tunnelId, groups);
         return groupId;
     }