[CORD-2903] Improve SR/Multicast APIs
Change-Id: Id44af87569e0a83129c96504b21c69e1d455f785
(cherry picked from commit a2858a34a26e02e9d2dd66dc562d0f6fb2c4bdd1)
diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/McastTreeListCommand.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/McastTreeListCommand.java
index d1de73c..a1ee1f2 100644
--- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/McastTreeListCommand.java
+++ b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/cli/McastTreeListCommand.java
@@ -16,7 +16,10 @@
package org.onosproject.segmentrouting.cli;
-import com.google.common.collect.ArrayListMultimap;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import org.apache.karaf.shell.commands.Command;
import org.apache.karaf.shell.commands.Option;
@@ -24,21 +27,13 @@
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.mcast.cli.McastGroupCompleter;
import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DeviceId;
import org.onosproject.segmentrouting.SegmentRoutingService;
-import org.onosproject.segmentrouting.mcast.McastRole;
-import org.onosproject.segmentrouting.storekey.McastStoreKey;
-import java.util.Collection;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import static com.google.common.base.Strings.isNullOrEmpty;
-import static org.onosproject.segmentrouting.mcast.McastRole.EGRESS;
-import static org.onosproject.segmentrouting.mcast.McastRole.INGRESS;
-import static org.onosproject.segmentrouting.mcast.McastRole.TRANSIT;
/**
* Command to show the list of mcast trees.
@@ -51,9 +46,9 @@
McastGroupCompleter completer;
// Format for group line
- private static final String G_FORMAT_MAPPING = "group=%s, ingress=%s, transit=%s, egress=%s";
+ private static final String G_FORMAT_MAPPING = "group=%s";
// Format for sink line
- private static final String S_FORMAT_MAPPING = "\tsink=%s\tpath=%s";
+ private static final String S_FORMAT_MAPPING = " sink=%s\tpath=%s";
@Option(name = "-gAddr", aliases = "--groupAddress",
description = "IP Address of the multicast group",
@@ -61,53 +56,76 @@
required = false, multiValued = false)
String gAddr = null;
+ @Option(name = "-src", aliases = "--connectPoint",
+ description = "Source port of:XXXXXXXXXX/XX",
+ valueToShowInHelp = "of:0000000000000001/1",
+ required = false, multiValued = false)
+ String source = null;
+
@Override
protected void execute() {
- // Verify mcast group
- IpAddress mcastGroup = null;
- if (!isNullOrEmpty(gAddr)) {
- mcastGroup = IpAddress.valueOf(gAddr);
-
- }
- // Get SR service
+ // Get SR service and the handled mcast groups
SegmentRoutingService srService = get(SegmentRoutingService.class);
- // Get the mapping
- Map<McastStoreKey, McastRole> keyToRole = srService.getMcastRoles(mcastGroup);
- // Reduce to the set of mcast groups
- Set<IpAddress> mcastGroups = keyToRole.keySet().stream()
- .map(McastStoreKey::mcastIp)
- .collect(Collectors.toSet());
- // Print the trees for each group
+ Set<IpAddress> mcastGroups = ImmutableSet.copyOf(srService.getMcastLeaders(null)
+ .keySet());
+
+ if (!isNullOrEmpty(gAddr)) {
+ mcastGroups = mcastGroups.stream()
+ .filter(mcastIp -> mcastIp.equals(IpAddress.valueOf(gAddr)))
+ .collect(Collectors.toSet());
+ }
+
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode root = mapper.createObjectNode();
+
+ // Print the trees for each group or build json objects
mcastGroups.forEach(group -> {
- // Create a new map for the group
- Multimap<McastRole, DeviceId> roleDeviceIdMap = ArrayListMultimap.create();
- keyToRole.entrySet()
- .stream()
- // Filter only the elements related to this group
- .filter(entry -> entry.getKey().mcastIp().equals(group))
- // For each create a new entry in the group related map
- .forEach(entry -> roleDeviceIdMap.put(entry.getValue(), entry.getKey().deviceId()));
- // Print the map
- printMcastRole(group,
- roleDeviceIdMap.get(INGRESS),
- roleDeviceIdMap.get(TRANSIT),
- roleDeviceIdMap.get(EGRESS)
- );
- // Get sinks paths
- Map<ConnectPoint, List<ConnectPoint>> mcastPaths = srService.getMcastPaths(group);
- // Print the paths
- mcastPaths.forEach(this::printMcastSink);
+ // We want to use source cp only for a specific group
+ ConnectPoint sourcecp = null;
+ if (!isNullOrEmpty(source) &&
+ !isNullOrEmpty(gAddr)) {
+ sourcecp = ConnectPoint.deviceConnectPoint(source);
+ }
+ Multimap<ConnectPoint, List<ConnectPoint>> mcastTree = srService.getMcastTrees(group,
+ sourcecp);
+ // Build a json object for each group
+ if (outputJson()) {
+ root.putPOJO(group.toString(), json(mcastTree));
+ } else {
+ // Banner and then the trees
+ printMcastGroup(group);
+ mcastTree.forEach(this::printMcastSink);
+ }
});
+
+ // Print the json object at the end
+ if (outputJson()) {
+ print("%s", root);
+ }
+
}
- private void printMcastRole(IpAddress mcastGroup,
- Collection<DeviceId> ingress,
- Collection<DeviceId> transit,
- Collection<DeviceId> egress) {
- print(G_FORMAT_MAPPING, mcastGroup, ingress, transit, egress);
+ private void printMcastGroup(IpAddress mcastGroup) {
+ print(G_FORMAT_MAPPING, mcastGroup);
}
private void printMcastSink(ConnectPoint sink, List<ConnectPoint> path) {
print(S_FORMAT_MAPPING, sink, path);
}
-}
+
+ private ObjectNode json(Multimap<ConnectPoint, List<ConnectPoint>> mcastTree) {
+ ObjectMapper mapper = new ObjectMapper();
+ ObjectNode jsonSinks = mapper.createObjectNode();
+ mcastTree.asMap().forEach((sink, paths) -> {
+ ArrayNode jsonPaths = mapper.createArrayNode();
+ paths.forEach(path -> {
+ ArrayNode jsonPath = mapper.createArrayNode();
+ path.forEach(connectPoint -> jsonPath.add(connectPoint.toString()));
+ jsonPaths.addPOJO(jsonPath);
+ });
+ jsonSinks.putPOJO(sink.toString(), jsonPaths);
+ });
+ return jsonSinks;
+ }
+
+}
\ No newline at end of file