blob: 2d08196ced8a4dae247a65a69e2f2449e4b0edf7 [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;
Ray Milkey7a2dee52018-09-28 10:58:28 -070026import org.apache.karaf.shell.api.action.lifecycle.Service;
Pier Luigib29144d2018-01-15 18:06:43 +010027import org.onlab.packet.IpAddress;
28import org.onosproject.cli.AbstractShellCommand;
Pier3ee24552018-03-14 16:47:32 -070029import org.onosproject.mcast.cli.McastGroupCompleter;
Pier Luigib29144d2018-01-15 18:06:43 +010030import org.onosproject.net.ConnectPoint;
Pier Luigib29144d2018-01-15 18:06:43 +010031import org.onosproject.segmentrouting.SegmentRoutingService;
Pier Luigib29144d2018-01-15 18:06:43 +010032
Pier Luigib29144d2018-01-15 18:06:43 +010033import java.util.List;
Pier Luigib29144d2018-01-15 18:06:43 +010034import java.util.Set;
35import java.util.stream.Collectors;
36
37import static com.google.common.base.Strings.isNullOrEmpty;
Pier Luigib29144d2018-01-15 18:06:43 +010038
39/**
40 * Command to show the list of mcast trees.
41 */
Ray Milkey7a2dee52018-09-28 10:58:28 -070042@Service
Pier Luigib29144d2018-01-15 18:06:43 +010043@Command(scope = "onos", name = "sr-mcast-tree",
44 description = "Lists all mcast trees")
45public class McastTreeListCommand extends AbstractShellCommand {
46
Pier3ee24552018-03-14 16:47:32 -070047 // OSGi workaround to introduce package dependency
48 McastGroupCompleter completer;
49
Pier Luigib29144d2018-01-15 18:06:43 +010050 // Format for group line
Pierb1fe7382018-04-17 17:25:22 +020051 private static final String G_FORMAT_MAPPING = "group=%s";
Pier Luigib29144d2018-01-15 18:06:43 +010052 // Format for sink line
Pierb1fe7382018-04-17 17:25:22 +020053 private static final String S_FORMAT_MAPPING = " sink=%s\tpath=%s";
Pier Luigib29144d2018-01-15 18:06:43 +010054
Pier3ee24552018-03-14 16:47:32 -070055 @Option(name = "-gAddr", aliases = "--groupAddress",
56 description = "IP Address of the multicast group",
57 valueToShowInHelp = "224.0.0.0",
Pier Luigib29144d2018-01-15 18:06:43 +010058 required = false, multiValued = false)
Pier3ee24552018-03-14 16:47:32 -070059 String gAddr = null;
Pier Luigib29144d2018-01-15 18:06:43 +010060
Pierb1fe7382018-04-17 17:25:22 +020061 @Option(name = "-src", aliases = "--connectPoint",
62 description = "Source port of:XXXXXXXXXX/XX",
63 valueToShowInHelp = "of:0000000000000001/1",
64 required = false, multiValued = false)
65 String source = null;
66
Pier Luigib29144d2018-01-15 18:06:43 +010067 @Override
Ray Milkey86ad7bb2018-09-27 12:32:28 -070068 protected void doExecute() {
Pierb1fe7382018-04-17 17:25:22 +020069 // Get SR service and the handled mcast groups
Pier Luigib29144d2018-01-15 18:06:43 +010070 SegmentRoutingService srService = get(SegmentRoutingService.class);
Pierb1fe7382018-04-17 17:25:22 +020071 Set<IpAddress> mcastGroups = ImmutableSet.copyOf(srService.getMcastLeaders(null)
72 .keySet());
73
74 if (!isNullOrEmpty(gAddr)) {
75 mcastGroups = mcastGroups.stream()
76 .filter(mcastIp -> mcastIp.equals(IpAddress.valueOf(gAddr)))
77 .collect(Collectors.toSet());
78 }
79
80 ObjectMapper mapper = new ObjectMapper();
81 ObjectNode root = mapper.createObjectNode();
82
83 // Print the trees for each group or build json objects
Pier Luigib29144d2018-01-15 18:06:43 +010084 mcastGroups.forEach(group -> {
Pierb1fe7382018-04-17 17:25:22 +020085 // We want to use source cp only for a specific group
86 ConnectPoint sourcecp = null;
87 if (!isNullOrEmpty(source) &&
88 !isNullOrEmpty(gAddr)) {
89 sourcecp = ConnectPoint.deviceConnectPoint(source);
90 }
91 Multimap<ConnectPoint, List<ConnectPoint>> mcastTree = srService.getMcastTrees(group,
92 sourcecp);
Pier3e793752018-04-19 16:47:06 +020093 if (!mcastTree.isEmpty()) {
94 // Build a json object for each group
95 if (outputJson()) {
96 root.putPOJO(group.toString(), json(mcastTree));
97 } else {
98 // Banner and then the trees
99 printMcastGroup(group);
100 mcastTree.forEach(this::printMcastSink);
101 }
Pierb1fe7382018-04-17 17:25:22 +0200102 }
Pier Luigib29144d2018-01-15 18:06:43 +0100103 });
Pierb1fe7382018-04-17 17:25:22 +0200104
105 // Print the json object at the end
106 if (outputJson()) {
107 print("%s", root);
108 }
109
Pier Luigib29144d2018-01-15 18:06:43 +0100110 }
111
Pierb1fe7382018-04-17 17:25:22 +0200112 private void printMcastGroup(IpAddress mcastGroup) {
113 print(G_FORMAT_MAPPING, mcastGroup);
Pier Luigib29144d2018-01-15 18:06:43 +0100114 }
115
116 private void printMcastSink(ConnectPoint sink, List<ConnectPoint> path) {
117 print(S_FORMAT_MAPPING, sink, path);
118 }
Pierb1fe7382018-04-17 17:25:22 +0200119
120 private ObjectNode json(Multimap<ConnectPoint, List<ConnectPoint>> mcastTree) {
121 ObjectMapper mapper = new ObjectMapper();
122 ObjectNode jsonSinks = mapper.createObjectNode();
123 mcastTree.asMap().forEach((sink, paths) -> {
124 ArrayNode jsonPaths = mapper.createArrayNode();
125 paths.forEach(path -> {
126 ArrayNode jsonPath = mapper.createArrayNode();
127 path.forEach(connectPoint -> jsonPath.add(connectPoint.toString()));
128 jsonPaths.addPOJO(jsonPath);
129 });
130 jsonSinks.putPOJO(sink.toString(), jsonPaths);
131 });
132 return jsonSinks;
133 }
134
135}