blob: 39a8bc217e95c0c674c75dc7f71b949b1ce0f4cc [file] [log] [blame]
alshabib9290eea2014-09-22 11:58:17 -07001package org.onlab.onos.cli.net;
2
Thomas Vachuskabb0272e2014-10-16 09:32:04 -07003import com.fasterxml.jackson.databind.JsonNode;
4import com.fasterxml.jackson.databind.ObjectMapper;
5import com.fasterxml.jackson.databind.node.ArrayNode;
6import com.fasterxml.jackson.databind.node.ObjectNode;
toma6897792014-10-08 22:21:05 -07007import com.google.common.collect.Maps;
alshabib99b8fdc2014-09-25 14:30:22 -07008import org.apache.karaf.shell.commands.Argument;
9import org.apache.karaf.shell.commands.Command;
toma6897792014-10-08 22:21:05 -070010import org.onlab.onos.CoreService;
alshabib99b8fdc2014-09-25 14:30:22 -070011import org.onlab.onos.cli.AbstractShellCommand;
tom91c7bd02014-09-25 22:50:44 -070012import org.onlab.onos.cli.Comparators;
alshabib99b8fdc2014-09-25 14:30:22 -070013import org.onlab.onos.net.Device;
14import org.onlab.onos.net.DeviceId;
15import org.onlab.onos.net.device.DeviceService;
alshabib1c319ff2014-10-04 20:29:09 -070016import org.onlab.onos.net.flow.FlowEntry;
17import org.onlab.onos.net.flow.FlowEntry.FlowEntryState;
alshabib99b8fdc2014-09-25 14:30:22 -070018import org.onlab.onos.net.flow.FlowRuleService;
Thomas Vachuskabb0272e2014-10-16 09:32:04 -070019import org.onlab.onos.net.flow.criteria.Criterion;
20import org.onlab.onos.net.flow.instructions.Instruction;
alshabib99b8fdc2014-09-25 14:30:22 -070021
toma6897792014-10-08 22:21:05 -070022import java.util.Collections;
23import java.util.List;
24import java.util.Map;
25
26import static com.google.common.collect.Lists.newArrayList;
27import static org.onlab.onos.cli.net.DevicesListCommand.getSortedDevices;
alshabib9290eea2014-09-22 11:58:17 -070028
29/**
30 * Lists all currently-known hosts.
31 */
32@Command(scope = "onos", name = "flows",
toma6897792014-10-08 22:21:05 -070033 description = "Lists all currently-known flows.")
alshabib9290eea2014-09-22 11:58:17 -070034public class FlowsListCommand extends AbstractShellCommand {
35
alshabib144a2942014-09-25 18:44:02 -070036 public static final String ANY = "any";
37
alshabib9290eea2014-09-22 11:58:17 -070038 private static final String FMT =
toma6897792014-10-08 22:21:05 -070039 " id=%s, state=%s, bytes=%s, packets=%s, duration=%s, priority=%s, appId=%s";
alshabib99b8fdc2014-09-25 14:30:22 -070040 private static final String TFMT = " treatment=%s";
41 private static final String SFMT = " selector=%s";
42
alshabib144a2942014-09-25 18:44:02 -070043 @Argument(index = 1, name = "uri", description = "Device ID",
toma6897792014-10-08 22:21:05 -070044 required = false, multiValued = false)
alshabib99b8fdc2014-09-25 14:30:22 -070045 String uri = null;
alshabib9290eea2014-09-22 11:58:17 -070046
alshabib144a2942014-09-25 18:44:02 -070047 @Argument(index = 0, name = "state", description = "Flow Rule state",
toma6897792014-10-08 22:21:05 -070048 required = false, multiValued = false)
alshabib144a2942014-09-25 18:44:02 -070049 String state = null;
alshabib64231d82014-09-25 18:25:31 -070050
alshabib9290eea2014-09-22 11:58:17 -070051 @Override
tom0872a172014-09-23 11:24:26 -070052 protected void execute() {
toma6897792014-10-08 22:21:05 -070053 CoreService coreService = get(CoreService.class);
tomcaf3bf72014-09-23 13:20:53 -070054 DeviceService deviceService = get(DeviceService.class);
55 FlowRuleService service = get(FlowRuleService.class);
alshabib1c319ff2014-10-04 20:29:09 -070056 Map<Device, List<FlowEntry>> flows = getSortedFlows(deviceService, service);
Thomas Vachuskabb0272e2014-10-16 09:32:04 -070057
58 if (outputJson()) {
59 print("%s", json(coreService, getSortedDevices(deviceService), flows));
60 } else {
61 for (Device d : getSortedDevices(deviceService)) {
62 printFlows(d, flows.get(d), coreService);
63 }
alshabib9290eea2014-09-22 11:58:17 -070064 }
alshabib9290eea2014-09-22 11:58:17 -070065 }
66
alshabib9290eea2014-09-22 11:58:17 -070067 /**
Thomas Vachuskabb0272e2014-10-16 09:32:04 -070068 * Produces a JSON array of flows grouped by the each device.
69 *
70 * @param coreService core service
71 * @param devices collection of devices to group flow by
72 * @param flows collection of flows per each device
73 * @return JSON array
74 */
75 private JsonNode json(CoreService coreService, Iterable<Device> devices,
76 Map<Device, List<FlowEntry>> flows) {
77 ObjectMapper mapper = new ObjectMapper();
78 ArrayNode result = mapper.createArrayNode();
79 for (Device device : devices) {
80 result.add(json(coreService, mapper, device, flows.get(device)));
81 }
82 return result;
83 }
84
85 // Produces JSON object with the flows of the given device.
86 private ObjectNode json(CoreService coreService, ObjectMapper mapper,
87 Device device, List<FlowEntry> flows) {
88 ObjectNode result = mapper.createObjectNode();
89 ArrayNode array = mapper.createArrayNode();
90
91 for (FlowEntry flow : flows) {
92 array.add(json(coreService, mapper, flow));
93 }
94
95 result.put("device", device.id().toString())
96 .put("flowCount", flows.size())
Thomas Vachuskadfe48a72014-10-16 10:32:08 -070097 .set("flows", array);
Thomas Vachuskabb0272e2014-10-16 09:32:04 -070098 return result;
99 }
100
101 // Produces JSON structure with the specified flow data.
102 private ObjectNode json(CoreService coreService, ObjectMapper mapper,
103 FlowEntry flow) {
104 ObjectNode result = mapper.createObjectNode();
105 ArrayNode crit = mapper.createArrayNode();
106 for (Criterion c : flow.selector().criteria()) {
107 crit.add(c.toString());
108 }
109
110 ArrayNode instr = mapper.createArrayNode();
111 for (Instruction i : flow.treatment().instructions()) {
112 instr.add(i.toString());
113 }
114
115 result.put("flowId", Long.toHexString(flow.id().value()))
116 .put("state", flow.state().toString())
117 .put("bytes", flow.bytes())
118 .put("packets", flow.packets())
119 .put("life", flow.life())
120 .put("appId", coreService.getAppId(flow.appId()).name());
121 result.set("selector", crit);
122 result.set("treatment", instr);
123 return result;
124 }
125
126 /**
alshabib9290eea2014-09-22 11:58:17 -0700127 * Returns the list of devices sorted using the device ID URIs.
128 *
129 * @param service device service
130 * @return sorted device list
131 */
tom1dd08e42014-10-07 11:40:00 -0700132 protected Map<Device, List<FlowEntry>> getSortedFlows(DeviceService deviceService,
133 FlowRuleService service) {
alshabib1c319ff2014-10-04 20:29:09 -0700134 Map<Device, List<FlowEntry>> flows = Maps.newHashMap();
135 List<FlowEntry> rules;
136 FlowEntryState s = null;
alshabib144a2942014-09-25 18:44:02 -0700137 if (state != null && !state.equals("any")) {
alshabib1c319ff2014-10-04 20:29:09 -0700138 s = FlowEntryState.valueOf(state.toUpperCase());
alshabib144a2942014-09-25 18:44:02 -0700139 }
tom1dd08e42014-10-07 11:40:00 -0700140 Iterable<Device> devices = uri == null ? deviceService.getDevices() :
toma6897792014-10-08 22:21:05 -0700141 Collections.singletonList(deviceService.getDevice(DeviceId.deviceId(uri)));
alshabib99b8fdc2014-09-25 14:30:22 -0700142 for (Device d : devices) {
alshabib144a2942014-09-25 18:44:02 -0700143 if (s == null) {
144 rules = newArrayList(service.getFlowEntries(d.id()));
145 } else {
146 rules = newArrayList();
alshabib1c319ff2014-10-04 20:29:09 -0700147 for (FlowEntry f : service.getFlowEntries(d.id())) {
alshabib144a2942014-09-25 18:44:02 -0700148 if (f.state().equals(s)) {
149 rules.add(f);
150 }
151 }
152 }
tom1380eee2014-09-24 09:22:02 -0700153 Collections.sort(rules, Comparators.FLOW_RULE_COMPARATOR);
alshabib9290eea2014-09-22 11:58:17 -0700154 flows.put(d, rules);
155 }
156 return flows;
157 }
158
159 /**
160 * Prints flows.
toma6897792014-10-08 22:21:05 -0700161 *
162 * @param d the device
alshabib9290eea2014-09-22 11:58:17 -0700163 * @param flows the set of flows for that device.
164 */
toma6897792014-10-08 22:21:05 -0700165 protected void printFlows(Device d, List<FlowEntry> flows,
166 CoreService coreService) {
tom1dd08e42014-10-07 11:40:00 -0700167 boolean empty = flows == null || flows.isEmpty();
168 print("deviceId=%s, flowRuleCount=%d", d.id(), empty ? 0 : flows.size());
169 if (!empty) {
170 for (FlowEntry f : flows) {
toma6897792014-10-08 22:21:05 -0700171 print(FMT, Long.toHexString(f.id().value()), f.state(),
172 f.bytes(), f.packets(), f.life(), f.priority(),
173 coreService.getAppId(f.appId()).name());
tom1dd08e42014-10-07 11:40:00 -0700174 print(SFMT, f.selector().criteria());
175 print(TFMT, f.treatment().instructions());
176 }
alshabib99b8fdc2014-09-25 14:30:22 -0700177 }
alshabib9290eea2014-09-22 11:58:17 -0700178 }
179
Yuta HIGUCHIe76a24d2014-09-27 00:48:34 -0700180}