blob: 92fbf2c9a27e79ad96f0444058ef80bc891cff2b [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;
Ray Milkey86ad7bb2018-09-27 12:32:28 -070024import org.apache.karaf.shell.api.action.Command;
25import org.apache.karaf.shell.api.action.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
Ray Milkey86ad7bb2018-09-27 12:32:28 -070066 protected void doExecute() {
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);
Pier3e793752018-04-19 16:47:06 +020091 if (!mcastTree.isEmpty()) {
92 // Build a json object for each group
93 if (outputJson()) {
94 root.putPOJO(group.toString(), json(mcastTree));
95 } else {
96 // Banner and then the trees
97 printMcastGroup(group);
98 mcastTree.forEach(this::printMcastSink);
99 }
Pierb1fe7382018-04-17 17:25:22 +0200100 }
Pier Luigib29144d2018-01-15 18:06:43 +0100101 });
Pierb1fe7382018-04-17 17:25:22 +0200102
103 // Print the json object at the end
104 if (outputJson()) {
105 print("%s", root);
106 }
107
Pier Luigib29144d2018-01-15 18:06:43 +0100108 }
109
Pierb1fe7382018-04-17 17:25:22 +0200110 private void printMcastGroup(IpAddress mcastGroup) {
111 print(G_FORMAT_MAPPING, mcastGroup);
Pier Luigib29144d2018-01-15 18:06:43 +0100112 }
113
114 private void printMcastSink(ConnectPoint sink, List<ConnectPoint> path) {
115 print(S_FORMAT_MAPPING, sink, path);
116 }
Pierb1fe7382018-04-17 17:25:22 +0200117
118 private ObjectNode json(Multimap<ConnectPoint, List<ConnectPoint>> mcastTree) {
119 ObjectMapper mapper = new ObjectMapper();
120 ObjectNode jsonSinks = mapper.createObjectNode();
121 mcastTree.asMap().forEach((sink, paths) -> {
122 ArrayNode jsonPaths = mapper.createArrayNode();
123 paths.forEach(path -> {
124 ArrayNode jsonPath = mapper.createArrayNode();
125 path.forEach(connectPoint -> jsonPath.add(connectPoint.toString()));
126 jsonPaths.addPOJO(jsonPath);
127 });
128 jsonSinks.putPOJO(sink.toString(), jsonPaths);
129 });
130 return jsonSinks;
131 }
132
133}