blob: 31b755559c2b52c2265a34eb5711980cd5601672 [file] [log] [blame]
/*
* Copyright 2017-present Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.cli.net;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.karaf.shell.commands.Command;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.incubator.net.routing.ResolvedRoute;
import org.onosproject.incubator.net.routing.RouteInfo;
import org.onosproject.incubator.net.routing.RouteService;
import org.onosproject.incubator.net.routing.RouteTableId;
import java.util.Collection;
import java.util.Comparator;
import java.util.Objects;
import java.util.Optional;
/**
* Command to show the routes in the routing tables.
*/
@Command(scope = "onos", name = "routes",
description = "Lists routes in the route store")
public class RoutesListCommand extends AbstractShellCommand {
private static final String NETWORK = "Network";
private static final String NEXTHOP = "Next Hop";
private static final String SOURCE = "Source";
private static final String FORMAT_ROUTE = "%-1s %-18s %-15s %-10s";
private static final String FORMAT_ROUTE6 = "%-1s %-43s %-39s %-10s";
private static final String FORMAT_TABLE = "Table: %s";
private static final String FORMAT_TOTAL = " Total: %d";
@Override
protected void execute() {
RouteService service = AbstractShellCommand.get(RouteService.class);
if (outputJson()) {
ObjectMapper mapper = new ObjectMapper();
ObjectNode result = mapper.createObjectNode();
result.set("routes4", json(service.getRoutes(new RouteTableId("ipv4"))));
result.set("routes6", json(service.getRoutes(new RouteTableId("ipv6"))));
print("%s", result);
} else {
service.getRouteTables().forEach(id -> {
Collection<RouteInfo> tableRoutes = service.getRoutes(id);
String format = tableRoutes.stream().anyMatch(route -> route.prefix().isIp6()) ?
FORMAT_ROUTE6 : FORMAT_ROUTE;
// Print header
print(FORMAT_TABLE, id);
print(format, "", NETWORK, NEXTHOP, SOURCE);
// Print routing entries
tableRoutes.stream()
.sorted(Comparator.comparing(r -> r.prefix().address()))
.forEach(route -> this.print(format, route));
print(FORMAT_TOTAL, tableRoutes.size());
print("");
});
}
}
private void print(String format, RouteInfo routeInfo) {
routeInfo.allRoutes()
.forEach(r -> print(format, isBestRoute(routeInfo.bestRoute(), r) ? ">" : "",
r.prefix(), r.nextHop(), r.route().source()));
}
private boolean isBestRoute(Optional<ResolvedRoute> bestRoute, ResolvedRoute route) {
return Objects.equals(bestRoute.orElse(null), route);
}
/**
* Produces a JSON array of routes.
*
* @param routes the routes with the data
* @return JSON array with the routes
*/
private JsonNode json(Collection<RouteInfo> routes) {
ObjectMapper mapper = new ObjectMapper();
ArrayNode result = mapper.createArrayNode();
routes.stream()
.flatMap(ri -> ri.allRoutes().stream())
.forEach(r -> result.add(json(mapper, r)));
return result;
}
/**
* Produces JSON object for a route.
*
* @param mapper the JSON object mapper to use
* @param route the route with the data
* @return JSON object for the route
*/
private ObjectNode json(ObjectMapper mapper, ResolvedRoute route) {
ObjectNode result = mapper.createObjectNode();
result.put("prefix", route.prefix().toString());
result.put("nextHop", route.nextHop().toString());
return result;
}
}