blob: afb405ded1611182b0f1d2e16c13c09b450079b6 [file] [log] [blame]
Jonathan Hartbfc5c482016-04-05 18:57:00 -07001/*
Jonathan Hart96c146b2017-02-24 16:32:00 -08002 * Copyright 2017-present Open Networking Laboratory
Jonathan Hartbfc5c482016-04-05 18:57:00 -07003 *
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 */
16package org.onosproject.cli.net;
17
Jonathan Hartb2111342016-04-20 16:57:37 -070018import com.fasterxml.jackson.databind.JsonNode;
19import com.fasterxml.jackson.databind.ObjectMapper;
20import com.fasterxml.jackson.databind.node.ArrayNode;
21import com.fasterxml.jackson.databind.node.ObjectNode;
Jonathan Hartbfc5c482016-04-05 18:57:00 -070022import org.apache.karaf.shell.commands.Command;
23import org.onosproject.cli.AbstractShellCommand;
Jonathan Hart96c146b2017-02-24 16:32:00 -080024import org.onosproject.incubator.net.routing.ResolvedRoute;
Jonathan Hart96c146b2017-02-24 16:32:00 -080025import org.onosproject.incubator.net.routing.RouteInfo;
Jonathan Hartbfc5c482016-04-05 18:57:00 -070026import org.onosproject.incubator.net.routing.RouteService;
27import org.onosproject.incubator.net.routing.RouteTableId;
28
29import java.util.Collection;
Jonathan Hart96c146b2017-02-24 16:32:00 -080030import java.util.Comparator;
31import java.util.Objects;
32import java.util.Optional;
Jonathan Hartbfc5c482016-04-05 18:57:00 -070033
34/**
35 * Command to show the routes in the routing tables.
36 */
Jonathan Hart92ca5d32016-04-14 18:05:52 -070037@Command(scope = "onos", name = "routes",
Jonathan Hart96c146b2017-02-24 16:32:00 -080038 description = "Lists routes in the route store")
Jonathan Hartbfc5c482016-04-05 18:57:00 -070039public class RoutesListCommand extends AbstractShellCommand {
40
Charles Chan92ca94d2017-03-17 18:05:22 -070041 private static final String NETWORK = "Network";
42 private static final String NEXTHOP = "Next Hop";
43 private static final String SOURCE = "Source";
Jonathan Hart10dbafd2017-05-18 15:53:03 -070044 private static final String NODE = "Node";
Charles Chan92ca94d2017-03-17 18:05:22 -070045
Jonathan Hart10dbafd2017-05-18 15:53:03 -070046 private static final String FORMAT_ROUTE = "%-1s %-18s %-15s %s (%s)";
47 private static final String FORMAT_ROUTE6 = "%-1s %-43s %-39s %s (%s)";
Jonathan Hartbfc5c482016-04-05 18:57:00 -070048
49 private static final String FORMAT_TABLE = "Table: %s";
50 private static final String FORMAT_TOTAL = " Total: %d";
51
52 @Override
53 protected void execute() {
54 RouteService service = AbstractShellCommand.get(RouteService.class);
55
Jonathan Hartb2111342016-04-20 16:57:37 -070056 if (outputJson()) {
57 ObjectMapper mapper = new ObjectMapper();
58 ObjectNode result = mapper.createObjectNode();
Jonathan Hart96c146b2017-02-24 16:32:00 -080059 result.set("routes4", json(service.getRoutes(new RouteTableId("ipv4"))));
60 result.set("routes6", json(service.getRoutes(new RouteTableId("ipv6"))));
Jonathan Hartb2111342016-04-20 16:57:37 -070061 print("%s", result);
62 } else {
Jonathan Hart96c146b2017-02-24 16:32:00 -080063 service.getRouteTables().forEach(id -> {
Jonathan Hart96c146b2017-02-24 16:32:00 -080064 Collection<RouteInfo> tableRoutes = service.getRoutes(id);
65
Charles Chan92ca94d2017-03-17 18:05:22 -070066 String format = tableRoutes.stream().anyMatch(route -> route.prefix().isIp6()) ?
67 FORMAT_ROUTE6 : FORMAT_ROUTE;
68
69 // Print header
70 print(FORMAT_TABLE, id);
Jonathan Hart10dbafd2017-05-18 15:53:03 -070071 print(format, "", NETWORK, NEXTHOP, SOURCE, NODE);
Charles Chan92ca94d2017-03-17 18:05:22 -070072
73 // Print routing entries
Jonathan Hart96c146b2017-02-24 16:32:00 -080074 tableRoutes.stream()
75 .sorted(Comparator.comparing(r -> r.prefix().address()))
Charles Chan92ca94d2017-03-17 18:05:22 -070076 .forEach(route -> this.print(format, route));
Jonathan Hart96c146b2017-02-24 16:32:00 -080077
78 print(FORMAT_TOTAL, tableRoutes.size());
Jonathan Hartb2111342016-04-20 16:57:37 -070079 print("");
80 });
81 }
Jonathan Hart96c146b2017-02-24 16:32:00 -080082 }
Jonathan Hartbfc5c482016-04-05 18:57:00 -070083
Charles Chan92ca94d2017-03-17 18:05:22 -070084 private void print(String format, RouteInfo routeInfo) {
Jonathan Hart58ea8f22017-05-08 15:09:31 -070085 routeInfo.allRoutes().stream()
86 .sorted(Comparator.comparing(r -> r.nextHop()))
Charles Chan92ca94d2017-03-17 18:05:22 -070087 .forEach(r -> print(format, isBestRoute(routeInfo.bestRoute(), r) ? ">" : "",
Jonathan Hart10dbafd2017-05-18 15:53:03 -070088 r.prefix(), r.nextHop(), r.route().source(), r.route().sourceNode()));
Jonathan Hart96c146b2017-02-24 16:32:00 -080089 }
90
Jonathan Hart96c146b2017-02-24 16:32:00 -080091 private boolean isBestRoute(Optional<ResolvedRoute> bestRoute, ResolvedRoute route) {
92 return Objects.equals(bestRoute.orElse(null), route);
Jonathan Hartbfc5c482016-04-05 18:57:00 -070093 }
94
Jonathan Hartb2111342016-04-20 16:57:37 -070095 /**
96 * Produces a JSON array of routes.
97 *
98 * @param routes the routes with the data
99 * @return JSON array with the routes
100 */
Jonathan Hart96c146b2017-02-24 16:32:00 -0800101 private JsonNode json(Collection<RouteInfo> routes) {
Jonathan Hartb2111342016-04-20 16:57:37 -0700102 ObjectMapper mapper = new ObjectMapper();
103 ArrayNode result = mapper.createArrayNode();
104
Jonathan Hart96c146b2017-02-24 16:32:00 -0800105 routes.stream()
106 .flatMap(ri -> ri.allRoutes().stream())
107 .forEach(r -> result.add(json(mapper, r)));
108
Jonathan Hartb2111342016-04-20 16:57:37 -0700109 return result;
110 }
111
112 /**
113 * Produces JSON object for a route.
114 *
115 * @param mapper the JSON object mapper to use
116 * @param route the route with the data
117 * @return JSON object for the route
118 */
Jonathan Hart96c146b2017-02-24 16:32:00 -0800119 private ObjectNode json(ObjectMapper mapper, ResolvedRoute route) {
Jonathan Hartb2111342016-04-20 16:57:37 -0700120 ObjectNode result = mapper.createObjectNode();
121
122 result.put("prefix", route.prefix().toString());
123 result.put("nextHop", route.nextHop().toString());
124
125 return result;
126 }
127
Jonathan Hartbfc5c482016-04-05 18:57:00 -0700128}