alshabib

flows cmd pretty print

Change-Id: I29b0971a5a862c602f8cd36f864f173c6d8330d6
package org.onlab.onos.cli.net;
import com.google.common.collect.Maps;
import static com.google.common.collect.Lists.newArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onlab.onos.cli.AbstractShellCommand;
import org.onlab.onos.net.Device;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.device.DeviceService;
import org.onlab.onos.net.flow.FlowRule;
import org.onlab.onos.net.flow.FlowRule.FlowRuleState;
import org.onlab.onos.net.flow.FlowRuleService;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static com.google.common.collect.Lists.newArrayList;
import com.google.common.collect.Maps;
/**
* Lists all currently-known hosts.
......@@ -22,14 +26,24 @@ description = "Lists all currently-known flows.")
public class FlowsListCommand extends AbstractShellCommand {
private static final String FMT =
" id=%s, selector=%s, treatment=%s, state=%s";
" id=%s, state=%s, bytes=%s, packets=%s, duration=%s, priority=%s";
private static final String TFMT = " treatment=%s";
private static final String SFMT = " selector=%s";
@Argument(index = 0, name = "state", description = "Flow rule state",
required = false, multiValued = false)
FlowRuleState state = null;
@Argument(index = 1, name = "uri", description = "Device ID",
required = false, multiValued = false)
String uri = null;
@Override
protected void execute() {
DeviceService deviceService = get(DeviceService.class);
FlowRuleService service = get(FlowRuleService.class);
Map<Device, List<FlowRule>> flows = getSortedFlows(deviceService, service);
for (Device d : deviceService.getDevices()) {
for (Device d : flows.keySet()) {
printFlows(d, flows.get(d));
}
}
......@@ -42,8 +56,10 @@ public class FlowsListCommand extends AbstractShellCommand {
*/
protected Map<Device, List<FlowRule>> getSortedFlows(DeviceService deviceService, FlowRuleService service) {
Map<Device, List<FlowRule>> flows = Maps.newHashMap();
List<FlowRule> rules;
for (Device d : deviceService.getDevices()) {
List<FlowRule> rules = newArrayList();
Iterable<Device> devices = uri == null ? deviceService.getDevices() :
Collections.singletonList(deviceService.getDevice(DeviceId.deviceId(uri)));
for (Device d : devices) {
rules = newArrayList(service.getFlowEntries(d.id()));
Collections.sort(rules, Comparators.FLOW_RULE_COMPARATOR);
flows.put(d, rules);
......@@ -58,8 +74,15 @@ public class FlowsListCommand extends AbstractShellCommand {
*/
protected void printFlows(Device d, List<FlowRule> flows) {
print("Device: " + d.id());
if (flows == null | flows.isEmpty()) {
print(" %s", "No flows installed.");
return;
}
for (FlowRule f : flows) {
print(FMT, f.id().value(), f.selector(), f.treatment(), f.state());
print(FMT, Long.toHexString(f.id().value()), f.state(), f.bytes(),
f.packets(), f.lifeMillis(), f.priority());
print(SFMT, f.selector().criteria());
print(TFMT, f.treatment().instructions());
}
}
......
package org.onlab.onos.cli.net;
import java.util.Iterator;
import java.util.List;
import java.util.SortedSet;
import org.apache.karaf.shell.console.Completer;
import org.apache.karaf.shell.console.completer.StringsCompleter;
import org.onlab.onos.cli.AbstractShellCommand;
import org.onlab.onos.net.Host;
import org.onlab.onos.net.host.HostService;
import java.util.Iterator;
import java.util.List;
import java.util.SortedSet;
public class HostIdCompleter implements Completer {
@Override
......
......@@ -72,6 +72,9 @@
<command>
<action class="org.onlab.onos.cli.net.FlowsListCommand"/>
<completers>
<ref component-id="deviceIdCompleter"/>
</completers>
</command>
<command>
......
package org.onlab.onos.net.flow.criteria;
import static com.google.common.base.MoreObjects.toStringHelper;
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.flow.criteria.Criterion.Type;
import org.onlab.packet.IpPrefix;
......@@ -129,6 +131,12 @@ public final class Criteria {
public PortNumber port() {
return this.port;
}
@Override
public String toString() {
return toStringHelper(type().toString())
.add("port", port).toString();
}
}
......@@ -149,6 +157,13 @@ public final class Criteria {
public MacAddress mac() {
return this.mac;
}
@Override
public String toString() {
return toStringHelper(type().toString())
.add("mac", mac).toString();
}
}
public static final class EthTypeCriterion implements Criterion {
......@@ -168,6 +183,12 @@ public final class Criteria {
return ethType;
}
@Override
public String toString() {
return toStringHelper(type().toString())
.add("ethType", Long.toHexString(ethType)).toString();
}
}
......@@ -190,6 +211,11 @@ public final class Criteria {
return this.ip;
}
@Override
public String toString() {
return toStringHelper(type().toString())
.add("ip", ip).toString();
}
}
......@@ -211,6 +237,12 @@ public final class Criteria {
return proto;
}
@Override
public String toString() {
return toStringHelper(type().toString())
.add("protocol", Long.toHexString(proto)).toString();
}
}
......@@ -231,6 +263,12 @@ public final class Criteria {
return vlanPcp;
}
@Override
public String toString() {
return toStringHelper(type().toString())
.add("pcp", Long.toHexString(vlanPcp)).toString();
}
}
......@@ -252,6 +290,12 @@ public final class Criteria {
return vlanId;
}
@Override
public String toString() {
return toStringHelper(type().toString())
.add("id", vlanId).toString();
}
}
......
package org.onlab.onos.net.flow.instructions;
import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import org.onlab.onos.net.PortNumber;
......@@ -47,7 +48,7 @@ public final class Instructions {
*/
public static L2ModificationInstruction modL2Src(MacAddress addr) {
checkNotNull(addr, "Src l2 address cannot be null");
return new ModEtherInstruction(L2SubType.L2_SRC, addr);
return new ModEtherInstruction(L2SubType.ETH_SRC, addr);
}
/**
......@@ -57,7 +58,7 @@ public final class Instructions {
*/
public static L2ModificationInstruction modL2Dst(MacAddress addr) {
checkNotNull(addr, "Dst l2 address cannot be null");
return new L2ModificationInstruction.ModEtherInstruction(L2SubType.L2_DST, addr);
return new L2ModificationInstruction.ModEtherInstruction(L2SubType.ETH_DST, addr);
}
/**
......@@ -87,7 +88,7 @@ public final class Instructions {
*/
public static L3ModificationInstruction modL3Src(IpPrefix addr) {
checkNotNull(addr, "Src l3 address cannot be null");
return new ModIPInstruction(L3SubType.L3_SRC, addr);
return new ModIPInstruction(L3SubType.IP_SRC, addr);
}
/**
......@@ -97,7 +98,7 @@ public final class Instructions {
*/
public static L3ModificationInstruction modL3Dst(IpPrefix addr) {
checkNotNull(addr, "Dst l3 address cannot be null");
return new ModIPInstruction(L3SubType.L3_DST, addr);
return new ModIPInstruction(L3SubType.IP_DST, addr);
}
......@@ -110,6 +111,12 @@ public final class Instructions {
public Type type() {
return Type.DROP;
}
@Override
public String toString() {
return toStringHelper(type()).toString();
}
}
......@@ -128,6 +135,11 @@ public final class Instructions {
public Type type() {
return Type.OUTPUT;
}
@Override
public String toString() {
return toStringHelper(type().toString())
.add("port", port).toString();
}
}
}
......
package org.onlab.onos.net.flow.instructions;
import static com.google.common.base.MoreObjects.toStringHelper;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
......@@ -15,12 +17,12 @@ public abstract class L2ModificationInstruction implements Instruction {
/**
* Ether src modification.
*/
L2_SRC,
ETH_SRC,
/**
* Ether dst modification.
*/
L2_DST,
ETH_DST,
/**
* VLAN id modification.
......@@ -66,6 +68,13 @@ public abstract class L2ModificationInstruction implements Instruction {
return this.mac;
}
@Override
public String toString() {
return toStringHelper(subtype().toString())
.add("mac", mac).toString();
}
}
/**
......@@ -88,6 +97,12 @@ public abstract class L2ModificationInstruction implements Instruction {
return this.vlanId;
}
@Override
public String toString() {
return toStringHelper(subtype().toString())
.add("id", vlanId).toString();
}
}
/**
......@@ -110,6 +125,12 @@ public abstract class L2ModificationInstruction implements Instruction {
return this.vlanPcp;
}
@Override
public String toString() {
return toStringHelper(subtype().toString())
.add("pcp", Long.toHexString(vlanPcp)).toString();
}
}
......
package org.onlab.onos.net.flow.instructions;
import static com.google.common.base.MoreObjects.toStringHelper;
import org.onlab.packet.IpPrefix;
/**
......@@ -14,12 +16,12 @@ public abstract class L3ModificationInstruction implements Instruction {
/**
* Ether src modification.
*/
L3_SRC,
IP_SRC,
/**
* Ether dst modification.
*/
L3_DST
IP_DST
//TODO: remaining types
}
......@@ -58,5 +60,11 @@ public abstract class L3ModificationInstruction implements Instruction {
return this.ip;
}
@Override
public String toString() {
return toStringHelper(subtype().toString())
.add("ip", ip).toString();
}
}
}
......
......@@ -133,10 +133,10 @@ public class FlowModBuilder {
L3ModificationInstruction l3m = (L3ModificationInstruction) i;
ModIPInstruction ip;
switch (l3m.subtype()) {
case L3_DST:
case IP_DST:
ip = (ModIPInstruction) i;
return factory.actions().setNwDst(IPv4Address.of(ip.ip().toInt()));
case L3_SRC:
case IP_SRC:
ip = (ModIPInstruction) i;
return factory.actions().setNwSrc(IPv4Address.of(ip.ip().toInt()));
default:
......@@ -150,10 +150,10 @@ public class FlowModBuilder {
L2ModificationInstruction l2m = (L2ModificationInstruction) i;
ModEtherInstruction eth;
switch (l2m.subtype()) {
case L2_DST:
case ETH_DST:
eth = (ModEtherInstruction) l2m;
return factory.actions().setDlDst(MacAddress.of(eth.mac().toLong()));
case L2_SRC:
case ETH_SRC:
eth = (ModEtherInstruction) l2m;
return factory.actions().setDlSrc(MacAddress.of(eth.mac().toLong()));
case VLAN_ID:
......