[AETHER-76] Impelentation of a new Trellis Troubleshoot Tool (T3) for offline mode
- For the performance improvement, T3 offline mode uses snapshots of the network states
called Network Information Base (NIB) instead of runtime interactions with ONOS core
during troubleshooting a Trellis system.
- Partially tested with some mininet topos for trellis
(https://github.com/opennetworkinglab/routing/tree/master/trellis).
- Usage instruction docs (https://docs.trellisfabric.org/troubleshooting.html).
Change-Id: Ice608f77aa96bfbcadfff34991c4a1b6d93125b6
(cherry picked from commit eaa6329aba67c2577fdca7d3ddf230611e82f9f7)
diff --git a/apps/mcast/cli/BUILD b/apps/mcast/cli/BUILD
index 9a9d616..553eb5b 100644
--- a/apps/mcast/cli/BUILD
+++ b/apps/mcast/cli/BUILD
@@ -1,4 +1,4 @@
-COMPILE_DEPS = CORE_DEPS + CLI + REST + [
+COMPILE_DEPS = CORE_DEPS + JACKSON + CLI + REST + [
"//core/store/serializers:onos-core-serializers",
"//apps/mcast/api:onos-apps-mcast-api",
]
diff --git a/apps/mcast/cli/src/main/java/org/onosproject/mcast/cli/McastShowHostCommand.java b/apps/mcast/cli/src/main/java/org/onosproject/mcast/cli/McastShowHostCommand.java
index 7ab5da0..2261378 100644
--- a/apps/mcast/cli/src/main/java/org/onosproject/mcast/cli/McastShowHostCommand.java
+++ b/apps/mcast/cli/src/main/java/org/onosproject/mcast/cli/McastShowHostCommand.java
@@ -15,6 +15,8 @@
*/
package org.onosproject.mcast.cli;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.karaf.shell.api.action.Command;
import org.apache.karaf.shell.api.action.Completion;
import org.apache.karaf.shell.api.action.Option;
@@ -29,7 +31,6 @@
import java.util.Comparator;
import java.util.Map;
import java.util.Set;
-import java.util.stream.Collectors;
import static com.google.common.base.Strings.isNullOrEmpty;
@@ -41,7 +42,9 @@
public class McastShowHostCommand extends AbstractShellCommand {
// Format for group line
- private static final String FORMAT_MAPPING = "origin=%s, group=%s, source IP=%s, sources=%s, sinks=%s";
+ private static final String FORMAT_MAPPING = "origin=%s, group=%s, source IP=%s, sources=%s, sinks=%s\n";
+ private StringBuilder routesBuilder = new StringBuilder();
+ private ArrayNode routesNode = mapper().createArrayNode();
@Option(name = "-gAddr", aliases = "--groupAddress",
description = "IP Address of the multicast group",
@@ -65,41 +68,43 @@
.findAny().orElse(null);
// If it exists
if (mcastRoute != null) {
- printRoute(mcastService, mcastRoute);
+ prepareResult(mcastService, mcastRoute);
}
- return;
+ } else {
+ routes.stream()
+ .filter(mcastRoute -> mcastRoute.group().isIp4())
+ .sorted(Comparator.comparing(McastRoute::group))
+ .forEach(route -> {
+ prepareResult(mcastService, route);
+ });
+ routes.stream()
+ .filter(mcastRoute -> mcastRoute.group().isIp6())
+ .sorted(Comparator.comparing(McastRoute::group))
+ .forEach(route -> {
+ prepareResult(mcastService, route);
+ });
}
- // Filter ipv4
- Set<McastRoute> ipv4Routes = routes.stream()
- .filter(mcastRoute -> mcastRoute.group().isIp4())
- .collect(Collectors.toSet());
- // Print ipv4 first
- ipv4Routes.stream()
- .sorted(Comparator.comparing(McastRoute::group))
- .forEach(route -> {
- printRoute(mcastService, route);
- });
- // Filter ipv6
- Set<McastRoute> ipv6Routes = routes.stream()
- .filter(mcastRoute -> mcastRoute.group().isIp6())
- .collect(Collectors.toSet());
- // Then print ipv6
- ipv6Routes.stream()
- .sorted(Comparator.comparing(McastRoute::group))
- .forEach(route -> {
- printRoute(mcastService, route);
- });
+ if (outputJson()) {
+ print("%s", routesNode);
+ } else {
+ print("%s", routesBuilder.toString());
+ }
}
- private void printRoute(MulticastRouteService mcastService, McastRoute route) {
- Map<HostId, Set<ConnectPoint>> sinks = mcastService.routeData(route).sinks();
- Map<HostId, Set<ConnectPoint>> sources = mcastService.routeData(route).sources();
- String srcIp = "*";
- if (route.source().isPresent()) {
- srcIp = route.source().get().toString();
+ private void prepareResult(MulticastRouteService mcastService, McastRoute route) {
+ if (outputJson()) {
+ // McastHostRouteCodec is used to encode McastRoute
+ ObjectNode routeNode = jsonForEntity(route, McastRoute.class);
+ routesNode.add(routeNode);
+ } else {
+ Map<HostId, Set<ConnectPoint>> sinks = mcastService.routeData(route).sinks();
+ Map<HostId, Set<ConnectPoint>> sources = mcastService.routeData(route).sources();
+ String srcIp = "*";
+ if (route.source().isPresent()) {
+ srcIp = route.source().get().toString();
+ }
+ routesBuilder.append(String.format(FORMAT_MAPPING, route.type(), route.group(), srcIp, sources, sinks));
}
-
- print(FORMAT_MAPPING, route.type(), route.group(), srcIp, sources, sinks);
}
}