blob: a1ee1f256c33c4935c9a7081cd2fe14b860f5599 [file] [log] [blame]
Pier Luigib29144d2018-01-15 18:06:43 +01001/*
2 * Copyright 2018-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.segmentrouting.cli;
18
Pierb1fe7382018-04-17 17:25:22 +020019import com.fasterxml.jackson.databind.ObjectMapper;
20import com.fasterxml.jackson.databind.node.ArrayNode;
21import com.fasterxml.jackson.databind.node.ObjectNode;
22import com.google.common.collect.ImmutableSet;
Pier Luigib29144d2018-01-15 18:06:43 +010023import com.google.common.collect.Multimap;
Pier Luigib29144d2018-01-15 18:06:43 +010024import org.apache.karaf.shell.commands.Command;
Pier3ee24552018-03-14 16:47:32 -070025import org.apache.karaf.shell.commands.Option;
Pier Luigib29144d2018-01-15 18:06:43 +010026import org.onlab.packet.IpAddress;
27import org.onosproject.cli.AbstractShellCommand;
Pier3ee24552018-03-14 16:47:32 -070028import org.onosproject.mcast.cli.McastGroupCompleter;
Pier Luigib29144d2018-01-15 18:06:43 +010029import org.onosproject.net.ConnectPoint;
Pier Luigib29144d2018-01-15 18:06:43 +010030import org.onosproject.segmentrouting.SegmentRoutingService;
Pier Luigib29144d2018-01-15 18:06:43 +010031
Pier Luigib29144d2018-01-15 18:06:43 +010032import java.util.List;
Pier Luigib29144d2018-01-15 18:06:43 +010033import java.util.Set;
34import java.util.stream.Collectors;
35
36import static com.google.common.base.Strings.isNullOrEmpty;
Pier Luigib29144d2018-01-15 18:06:43 +010037
38/**
39 * Command to show the list of mcast trees.
40 */
41@Command(scope = "onos", name = "sr-mcast-tree",
42 description = "Lists all mcast trees")
43public class McastTreeListCommand extends AbstractShellCommand {
44
Pier3ee24552018-03-14 16:47:32 -070045 // OSGi workaround to introduce package dependency
46 McastGroupCompleter completer;
47
Pier Luigib29144d2018-01-15 18:06:43 +010048 // Format for group line
Pierb1fe7382018-04-17 17:25:22 +020049 private static final String G_FORMAT_MAPPING = "group=%s";
Pier Luigib29144d2018-01-15 18:06:43 +010050 // Format for sink line
Pierb1fe7382018-04-17 17:25:22 +020051 private static final String S_FORMAT_MAPPING = " sink=%s\tpath=%s";
Pier Luigib29144d2018-01-15 18:06:43 +010052
Pier3ee24552018-03-14 16:47:32 -070053 @Option(name = "-gAddr", aliases = "--groupAddress",
54 description = "IP Address of the multicast group",
55 valueToShowInHelp = "224.0.0.0",
Pier Luigib29144d2018-01-15 18:06:43 +010056 required = false, multiValued = false)
Pier3ee24552018-03-14 16:47:32 -070057 String gAddr = null;
Pier Luigib29144d2018-01-15 18:06:43 +010058
Pierb1fe7382018-04-17 17:25:22 +020059 @Option(name = "-src", aliases = "--connectPoint",
60 description = "Source port of:XXXXXXXXXX/XX",
61 valueToShowInHelp = "of:0000000000000001/1",
62 required = false, multiValued = false)
63 String source = null;
64
Pier Luigib29144d2018-01-15 18:06:43 +010065 @Override
66 protected void execute() {
Pierb1fe7382018-04-17 17:25:22 +020067 // Get SR service and the handled mcast groups
Pier Luigib29144d2018-01-15 18:06:43 +010068 SegmentRoutingService srService = get(SegmentRoutingService.class);
Pierb1fe7382018-04-17 17:25:22 +020069 Set<IpAddress> mcastGroups = ImmutableSet.copyOf(srService.getMcastLeaders(null)
70 .keySet());
71
72 if (!isNullOrEmpty(gAddr)) {
73 mcastGroups = mcastGroups.stream()
74 .filter(mcastIp -> mcastIp.equals(IpAddress.valueOf(gAddr)))
75 .collect(Collectors.toSet());
76 }
77
78 ObjectMapper mapper = new ObjectMapper();
79 ObjectNode root = mapper.createObjectNode();
80
81 // Print the trees for each group or build json objects
Pier Luigib29144d2018-01-15 18:06:43 +010082 mcastGroups.forEach(group -> {
Pierb1fe7382018-04-17 17:25:22 +020083 // We want to use source cp only for a specific group
84 ConnectPoint sourcecp = null;
85 if (!isNullOrEmpty(source) &&
86 !isNullOrEmpty(gAddr)) {
87 sourcecp = ConnectPoint.deviceConnectPoint(source);
88 }
89 Multimap<ConnectPoint, List<ConnectPoint>> mcastTree = srService.getMcastTrees(group,
90 sourcecp);
91 // Build a json object for each group
92 if (outputJson()) {
93 root.putPOJO(group.toString(), json(mcastTree));
94 } else {
95 // Banner and then the trees
96 printMcastGroup(group);
97 mcastTree.forEach(this::printMcastSink);
98 }
Pier Luigib29144d2018-01-15 18:06:43 +010099 });
Pierb1fe7382018-04-17 17:25:22 +0200100
101 // Print the json object at the end
102 if (outputJson()) {
103 print("%s", root);
104 }
105
Pier Luigib29144d2018-01-15 18:06:43 +0100106 }
107
Pierb1fe7382018-04-17 17:25:22 +0200108 private void printMcastGroup(IpAddress mcastGroup) {
109 print(G_FORMAT_MAPPING, mcastGroup);
Pier Luigib29144d2018-01-15 18:06:43 +0100110 }
111
112 private void printMcastSink(ConnectPoint sink, List<ConnectPoint> path) {
113 print(S_FORMAT_MAPPING, sink, path);
114 }
Pierb1fe7382018-04-17 17:25:22 +0200115
116 private ObjectNode json(Multimap<ConnectPoint, List<ConnectPoint>> mcastTree) {
117 ObjectMapper mapper = new ObjectMapper();
118 ObjectNode jsonSinks = mapper.createObjectNode();
119 mcastTree.asMap().forEach((sink, paths) -> {
120 ArrayNode jsonPaths = mapper.createArrayNode();
121 paths.forEach(path -> {
122 ArrayNode jsonPath = mapper.createArrayNode();
123 path.forEach(connectPoint -> jsonPath.add(connectPoint.toString()));
124 jsonPaths.addPOJO(jsonPath);
125 });
126 jsonSinks.putPOJO(sink.toString(), jsonPaths);
127 });
128 return jsonSinks;
129 }
130
131}