blob: 2037800e8f6d69e4e2ed6e4e91053e30569d7beb [file] [log] [blame]
Srikanth Vavilapalli95810f52015-09-14 15:49:56 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Srikanth Vavilapalli95810f52015-09-14 15:49:56 -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
18import static com.google.common.collect.Lists.newArrayList;
19
20import java.util.Collections;
21import java.util.List;
22import java.util.Map;
23import java.util.SortedMap;
24import java.util.TreeMap;
25
26import org.apache.karaf.shell.commands.Argument;
27import org.apache.karaf.shell.commands.Command;
28import org.apache.karaf.shell.commands.Option;
29import org.onosproject.cli.AbstractShellCommand;
Ray Milkeyc7477292016-03-11 10:53:43 -080030import org.onosproject.utils.Comparators;
Srikanth Vavilapalli95810f52015-09-14 15:49:56 -070031import org.onosproject.net.Device;
32import org.onosproject.net.DeviceId;
33import org.onosproject.net.device.DeviceService;
34import org.onosproject.net.flow.FlowRuleService;
35import org.onosproject.net.flow.TableStatisticsEntry;
36
37import com.fasterxml.jackson.databind.JsonNode;
38import com.fasterxml.jackson.databind.ObjectMapper;
39import com.fasterxml.jackson.databind.node.ArrayNode;
40import com.fasterxml.jackson.databind.node.ObjectNode;
41
42/**
43 * Lists port statistic of all ports in the system.
44 */
45@Command(scope = "onos", name = "tablestats",
46 description = "Lists statistics of all tables in the device")
47public class TableStatisticsCommand extends AbstractShellCommand {
48
49 @Option(name = "-t", aliases = "--table", description = "Show human readable table format for statistics",
50 required = false, multiValued = false)
51 private boolean table = false;
52
53 @Argument(index = 0, name = "uri", description = "Device ID",
54 required = false, multiValued = false)
55 String uri = null;
56
57 private static final String FORMAT =
hjtsao1a4333c2018-10-22 11:02:00 -070058 " table=%s, active=%s, lookedup=%s, matched=%s, maxsize=%s";
59 private static final String NA = "N/A";
Srikanth Vavilapalli95810f52015-09-14 15:49:56 -070060
61 @Override
62 protected void execute() {
63 FlowRuleService flowService = get(FlowRuleService.class);
64 DeviceService deviceService = get(DeviceService.class);
Srikanth Vavilapalli95810f52015-09-14 15:49:56 -070065 SortedMap<Device, List<TableStatisticsEntry>> deviceTableStats =
66 getSortedTableStats(deviceService, flowService);
67
68 if (outputJson()) {
69 print("%s", json(deviceTableStats.keySet(), deviceTableStats));
70 } else {
71 deviceTableStats.forEach((device, tableStats) -> printTableStats(device, tableStats));
72 }
73 }
74
75 /**
76 * Produces a JSON array of table statistics grouped by the each device.
77 *
78 * @param devices collection of devices
79 * @param deviceTableStats collection of table statistics per each device
80 * @return JSON array
81 */
82 private JsonNode json(Iterable<Device> devices,
83 Map<Device, List<TableStatisticsEntry>> deviceTableStats) {
84 ObjectMapper mapper = new ObjectMapper();
85 ArrayNode result = mapper.createArrayNode();
86 for (Device device : devices) {
87 result.add(json(mapper, device, deviceTableStats.get(device)));
88 }
89 return result;
90 }
91
92 // Produces JSON object with the table statistics of the given device.
93 private ObjectNode json(ObjectMapper mapper,
94 Device device, List<TableStatisticsEntry> tableStats) {
95 ObjectNode result = mapper.createObjectNode();
96 ArrayNode array = mapper.createArrayNode();
97
98 tableStats.forEach(tableStat -> array.add(jsonForEntity(tableStat, TableStatisticsEntry.class)));
99
100 result.put("device", device.id().toString())
101 .put("tableCount", tableStats.size())
102 .set("tables", array);
103 return result;
104 }
105
106 /**
107 * Prints flow table statistics.
108 *
109 * @param d the device
110 * @param tableStats the set of flow table statistics for that device
111 */
112 protected void printTableStats(Device d,
113 List<TableStatisticsEntry> tableStats) {
114 boolean empty = tableStats == null || tableStats.isEmpty();
115 print("deviceId=%s, tableCount=%d", d.id(), empty ? 0 : tableStats.size());
116 if (!empty) {
117 for (TableStatisticsEntry t : tableStats) {
hjtsao1a4333c2018-10-22 11:02:00 -0700118 print(FORMAT, t.table(), t.activeFlowEntries(),
119 t.hasPacketsLookedup() ? t.packetsLookedup() : NA, t.packetsMatched(),
120 t.hasMaxSize() ? t.maxSize() : NA);
Srikanth Vavilapalli95810f52015-09-14 15:49:56 -0700121 }
122 }
123 }
124
125 /**
126 * Returns the list of table statistics sorted using the device ID URIs and table IDs.
127 *
128 * @param deviceService device service
129 * @param flowService flow rule service
130 * @return sorted table statistics list
131 */
132 protected SortedMap<Device, List<TableStatisticsEntry>> getSortedTableStats(DeviceService deviceService,
hjtsao1a4333c2018-10-22 11:02:00 -0700133 FlowRuleService flowService) {
Srikanth Vavilapalli95810f52015-09-14 15:49:56 -0700134 SortedMap<Device, List<TableStatisticsEntry>> deviceTableStats = new TreeMap<>(Comparators.ELEMENT_COMPARATOR);
135 List<TableStatisticsEntry> tableStatsList;
136 Iterable<Device> devices = uri == null ? deviceService.getDevices() :
137 Collections.singletonList(deviceService.getDevice(DeviceId.deviceId(uri)));
138 for (Device d : devices) {
139 tableStatsList = newArrayList(flowService.getFlowTableStatistics(d.id()));
140 tableStatsList.sort((p1, p2) -> Integer.valueOf(p1.tableId()).compareTo(Integer.valueOf(p2.tableId())));
141 deviceTableStats.put(d, tableStatsList);
142 }
143 return deviceTableStats;
144 }
145
hjtsao1a4333c2018-10-22 11:02:00 -0700146}