blob: 5ea316e97cd302415051eae2ad2021c965f3106e [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 Hartbfc5c482016-04-05 18:57:00 -070025import org.onosproject.incubator.net.routing.Route;
Jonathan Hart96c146b2017-02-24 16:32:00 -080026import org.onosproject.incubator.net.routing.RouteInfo;
Jonathan Hartbfc5c482016-04-05 18:57:00 -070027import org.onosproject.incubator.net.routing.RouteService;
28import org.onosproject.incubator.net.routing.RouteTableId;
29
30import java.util.Collection;
Jonathan Hart96c146b2017-02-24 16:32:00 -080031import java.util.Comparator;
32import java.util.Objects;
33import java.util.Optional;
Jonathan Hartbfc5c482016-04-05 18:57:00 -070034
35/**
36 * Command to show the routes in the routing tables.
37 */
Jonathan Hart92ca5d32016-04-14 18:05:52 -070038@Command(scope = "onos", name = "routes",
Jonathan Hart96c146b2017-02-24 16:32:00 -080039 description = "Lists routes in the route store")
Jonathan Hartbfc5c482016-04-05 18:57:00 -070040public class RoutesListCommand extends AbstractShellCommand {
41
42 private static final String FORMAT_HEADER =
Jonathan Hart96c146b2017-02-24 16:32:00 -080043 " Network Next Hop Source";
Jonathan Hartbfc5c482016-04-05 18:57:00 -070044 private static final String FORMAT_ROUTE =
Jonathan Hart96c146b2017-02-24 16:32:00 -080045 "%-1s %-18s %-15s %-10s";
Jonathan Hartbfc5c482016-04-05 18:57:00 -070046
47 private static final String FORMAT_TABLE = "Table: %s";
48 private static final String FORMAT_TOTAL = " Total: %d";
49
50 @Override
51 protected void execute() {
52 RouteService service = AbstractShellCommand.get(RouteService.class);
53
Jonathan Hartb2111342016-04-20 16:57:37 -070054 if (outputJson()) {
55 ObjectMapper mapper = new ObjectMapper();
56 ObjectNode result = mapper.createObjectNode();
Jonathan Hart96c146b2017-02-24 16:32:00 -080057 result.set("routes4", json(service.getRoutes(new RouteTableId("ipv4"))));
58 result.set("routes6", json(service.getRoutes(new RouteTableId("ipv6"))));
Jonathan Hartb2111342016-04-20 16:57:37 -070059 print("%s", result);
60 } else {
Jonathan Hart96c146b2017-02-24 16:32:00 -080061 service.getRouteTables().forEach(id -> {
Jonathan Hartb2111342016-04-20 16:57:37 -070062 print(FORMAT_TABLE, id);
63 print(FORMAT_HEADER);
Jonathan Hart96c146b2017-02-24 16:32:00 -080064 Collection<RouteInfo> tableRoutes = service.getRoutes(id);
65
66 tableRoutes.stream()
67 .sorted(Comparator.comparing(r -> r.prefix().address()))
68 .forEach(this::print);
69
70 print(FORMAT_TOTAL, tableRoutes.size());
Jonathan Hartb2111342016-04-20 16:57:37 -070071 print("");
72 });
73 }
Jonathan Hart96c146b2017-02-24 16:32:00 -080074 }
Jonathan Hartbfc5c482016-04-05 18:57:00 -070075
Jonathan Hart96c146b2017-02-24 16:32:00 -080076 private void print(RouteInfo routeInfo) {
77 routeInfo.allRoutes()
78 .forEach(r -> print(FORMAT_ROUTE, isBestRoute(routeInfo.bestRoute(), r) ? ">" : "",
79 r.prefix(), r.nextHop(), Route.Source.UNDEFINED));
80 }
81
82
83
84 private boolean isBestRoute(Optional<ResolvedRoute> bestRoute, ResolvedRoute route) {
85 return Objects.equals(bestRoute.orElse(null), route);
Jonathan Hartbfc5c482016-04-05 18:57:00 -070086 }
87
Jonathan Hartb2111342016-04-20 16:57:37 -070088 /**
89 * Produces a JSON array of routes.
90 *
91 * @param routes the routes with the data
92 * @return JSON array with the routes
93 */
Jonathan Hart96c146b2017-02-24 16:32:00 -080094 private JsonNode json(Collection<RouteInfo> routes) {
Jonathan Hartb2111342016-04-20 16:57:37 -070095 ObjectMapper mapper = new ObjectMapper();
96 ArrayNode result = mapper.createArrayNode();
97
Jonathan Hart96c146b2017-02-24 16:32:00 -080098 routes.stream()
99 .flatMap(ri -> ri.allRoutes().stream())
100 .forEach(r -> result.add(json(mapper, r)));
101
Jonathan Hartb2111342016-04-20 16:57:37 -0700102 return result;
103 }
104
105 /**
106 * Produces JSON object for a route.
107 *
108 * @param mapper the JSON object mapper to use
109 * @param route the route with the data
110 * @return JSON object for the route
111 */
Jonathan Hart96c146b2017-02-24 16:32:00 -0800112 private ObjectNode json(ObjectMapper mapper, ResolvedRoute route) {
Jonathan Hartb2111342016-04-20 16:57:37 -0700113 ObjectNode result = mapper.createObjectNode();
114
115 result.put("prefix", route.prefix().toString());
116 result.put("nextHop", route.nextHop().toString());
117
118 return result;
119 }
120
Jonathan Hartbfc5c482016-04-05 18:57:00 -0700121}