Implement CLI commands to view and delete SR internal stores

sr-next-dst (renamed from sr-next-hops)
sr-next-port
sr-next-vlan
sr-next-mcast (renamed from sr-mcast-next)
sr-next-pw
sr-next-xconnect
sr-next-invalidate <next-id>

Change-Id: Id5178f786bb97e26ddb86015105dd19604ac0817
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/mcast/McastHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/mcast/McastHandler.java
index 88601aa..4f70a1b 100644
--- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/mcast/McastHandler.java
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/mcast/McastHandler.java
@@ -286,7 +286,7 @@
                     Map<ConnectPoint, List<ConnectPoint>> mcastPaths = Maps.newHashMap();
                     Set<DeviceId> visited = Sets.newHashSet();
                     List<ConnectPoint> currentPath = Lists.newArrayList(source);
-                    buildMcastPaths(source.deviceId(), visited, mcastPaths,
+                    mcastUtils.buildMcastPaths(mcastNextObjStore.asJavaMap(), source.deviceId(), visited, mcastPaths,
                                     currentPath, mcastRoute.group(), source);
                     // Get all the sinks and process them
                     Set<ConnectPoint> sinks = processSinksToBeAdded(source, mcastRoute.group(),
@@ -1816,7 +1816,7 @@
      * @param mcastIp the group ip
      * @return the mapping mcastIp-device to next id
      */
-    public Map<McastStoreKey, Integer> getMcastNextIds(IpAddress mcastIp) {
+    public Map<McastStoreKey, Integer> getNextIds(IpAddress mcastIp) {
         if (mcastIp != null) {
             return mcastNextObjStore.entrySet().stream()
                     .filter(mcastEntry -> mcastIp.equals(mcastEntry.getKey().mcastIp()))
@@ -1827,6 +1827,19 @@
     }
 
     /**
+     * Removes given next ID from mcast next id store.
+     *
+     * @param nextId next id
+     */
+    public void removeNextId(int nextId) {
+        mcastNextObjStore.entrySet().forEach(e -> {
+            if (e.getValue().value().id() == nextId) {
+                mcastNextObjStore.remove(e.getKey());
+            }
+        });
+    }
+
+    /**
      * Returns the associated roles to the mcast groups or to the single
      * group if mcastIp is present.
      *
@@ -1891,7 +1904,8 @@
         if (source != null) {
             Set<DeviceId> visited = Sets.newHashSet();
             List<ConnectPoint> currentPath = Lists.newArrayList(source);
-            buildMcastPaths(source.deviceId(), visited, mcastPaths, currentPath, mcastIp, source);
+            mcastUtils.buildMcastPaths(mcastNextObjStore.asJavaMap(), source.deviceId(), visited, mcastPaths,
+                    currentPath, mcastIp, source);
         }
         return mcastPaths;
     }
@@ -1916,7 +1930,8 @@
                 Map<ConnectPoint, List<ConnectPoint>> mcastPaths = Maps.newHashMap();
                 Set<DeviceId> visited = Sets.newHashSet();
                 List<ConnectPoint> currentPath = Lists.newArrayList(source);
-                buildMcastPaths(source.deviceId(), visited, mcastPaths, currentPath, mcastIp, source);
+                mcastUtils.buildMcastPaths(mcastNextObjStore.asJavaMap(), source.deviceId(), visited, mcastPaths,
+                        currentPath, mcastIp, source);
                 mcastPaths.forEach(mcastTrees::put);
             });
         }
@@ -1924,63 +1939,6 @@
     }
 
     /**
-     * Build recursively the mcast paths.
-     *
-     * @param toVisit the node to visit
-     * @param visited the visited nodes
-     * @param mcastPaths the current mcast paths
-     * @param currentPath the current path
-     * @param mcastIp the group ip
-     * @param source the source
-     */
-    private void buildMcastPaths(DeviceId toVisit, Set<DeviceId> visited,
-                                 Map<ConnectPoint, List<ConnectPoint>> mcastPaths,
-                                 List<ConnectPoint> currentPath, IpAddress mcastIp,
-                                 ConnectPoint source) {
-        // If we have visited the node to visit there is a loop
-        if (visited.contains(toVisit)) {
-            return;
-        }
-        // Visit next-hop
-        visited.add(toVisit);
-        VlanId assignedVlan = mcastUtils.assignedVlan(toVisit.equals(source.deviceId()) ? source : null);
-        McastStoreKey mcastStoreKey = new McastStoreKey(mcastIp, toVisit, assignedVlan);
-        // Looking for next-hops
-        if (mcastNextObjStore.containsKey(mcastStoreKey)) {
-            // Build egress connect points, get ports and build relative cps
-            NextObjective nextObjective = mcastNextObjStore.get(mcastStoreKey).value();
-            Set<PortNumber> outputPorts = mcastUtils.getPorts(nextObjective.next());
-            ImmutableSet.Builder<ConnectPoint> cpBuilder = ImmutableSet.builder();
-            outputPorts.forEach(portNumber -> cpBuilder.add(new ConnectPoint(toVisit, portNumber)));
-            Set<ConnectPoint> egressPoints = cpBuilder.build();
-            Set<Link> egressLinks;
-            List<ConnectPoint> newCurrentPath;
-            Set<DeviceId> newVisited;
-            DeviceId newToVisit;
-            for (ConnectPoint egressPoint : egressPoints) {
-                egressLinks = srManager.linkService.getEgressLinks(egressPoint);
-                // If it does not have egress links, stop
-                if (egressLinks.isEmpty()) {
-                    // Add the connect points to the path
-                    newCurrentPath = Lists.newArrayList(currentPath);
-                    newCurrentPath.add(0, egressPoint);
-                    mcastPaths.put(egressPoint, newCurrentPath);
-                } else {
-                    newVisited = Sets.newHashSet(visited);
-                    // Iterate over the egress links for the next hops
-                    for (Link egressLink : egressLinks) {
-                        newToVisit = egressLink.dst().deviceId();
-                        newCurrentPath = Lists.newArrayList(currentPath);
-                        newCurrentPath.add(0, egressPoint);
-                        newCurrentPath.add(0, egressLink.dst());
-                        buildMcastPaths(newToVisit, newVisited, mcastPaths, newCurrentPath, mcastIp, source);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
      * Return the leaders of the mcast groups.
      *
      * @param mcastIp the group ip
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/mcast/McastUtils.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/mcast/McastUtils.java
index 0793984..52232b9 100644
--- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/mcast/McastUtils.java
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/mcast/McastUtils.java
@@ -18,7 +18,9 @@
 
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
 import com.google.common.hash.HashFunction;
 import com.google.common.hash.Hashing;
 import org.onlab.packet.Ethernet;
@@ -31,6 +33,7 @@
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.HostId;
+import org.onosproject.net.Link;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.config.basics.McastConfig;
 import org.onosproject.net.flow.DefaultTrafficSelector;
@@ -55,6 +58,7 @@
 import org.slf4j.Logger;
 
 import java.util.Collection;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -486,4 +490,64 @@
         // Otherwise take all the groups
         return ImmutableMap.copyOf(mcastLeaderCache);
     }
+
+    /**
+     * Build recursively the mcast paths.
+     *
+     * @param mcastNextObjStore mcast next obj store
+     * @param toVisit the node to visit
+     * @param visited the visited nodes
+     * @param mcastPaths the current mcast paths
+     * @param currentPath the current path
+     * @param mcastIp the group ip
+     * @param source the source
+     */
+    void buildMcastPaths(Map<McastStoreKey, NextObjective> mcastNextObjStore,
+                                 DeviceId toVisit, Set<DeviceId> visited,
+                                 Map<ConnectPoint, List<ConnectPoint>> mcastPaths,
+                                 List<ConnectPoint> currentPath, IpAddress mcastIp,
+                                 ConnectPoint source) {
+        // If we have visited the node to visit there is a loop
+        if (visited.contains(toVisit)) {
+            return;
+        }
+        // Visit next-hop
+        visited.add(toVisit);
+        VlanId assignedVlan = assignedVlan(toVisit.equals(source.deviceId()) ? source : null);
+        McastStoreKey mcastStoreKey = new McastStoreKey(mcastIp, toVisit, assignedVlan);
+        // Looking for next-hops
+        if (mcastNextObjStore.containsKey(mcastStoreKey)) {
+            // Build egress connect points, get ports and build relative cps
+            NextObjective nextObjective = mcastNextObjStore.get(mcastStoreKey);
+            Set<PortNumber> outputPorts = getPorts(nextObjective.next());
+            ImmutableSet.Builder<ConnectPoint> cpBuilder = ImmutableSet.builder();
+            outputPorts.forEach(portNumber -> cpBuilder.add(new ConnectPoint(toVisit, portNumber)));
+            Set<ConnectPoint> egressPoints = cpBuilder.build();
+            Set<Link> egressLinks;
+            List<ConnectPoint> newCurrentPath;
+            Set<DeviceId> newVisited;
+            DeviceId newToVisit;
+            for (ConnectPoint egressPoint : egressPoints) {
+                egressLinks = srManager.linkService.getEgressLinks(egressPoint);
+                // If it does not have egress links, stop
+                if (egressLinks.isEmpty()) {
+                    // Add the connect points to the path
+                    newCurrentPath = Lists.newArrayList(currentPath);
+                    newCurrentPath.add(0, egressPoint);
+                    mcastPaths.put(egressPoint, newCurrentPath);
+                } else {
+                    newVisited = Sets.newHashSet(visited);
+                    // Iterate over the egress links for the next hops
+                    for (Link egressLink : egressLinks) {
+                        newToVisit = egressLink.dst().deviceId();
+                        newCurrentPath = Lists.newArrayList(currentPath);
+                        newCurrentPath.add(0, egressPoint);
+                        newCurrentPath.add(0, egressLink.dst());
+                        buildMcastPaths(mcastNextObjStore, newToVisit, newVisited, mcastPaths, newCurrentPath, mcastIp,
+                                source);
+                    }
+                }
+            }
+        }
+    }
 }