Thomas Vachuska

Added CLI support for showing key/value annotations for devices, ports, links & hosts.

...@@ -18,10 +18,13 @@ ...@@ -18,10 +18,13 @@
18 */ 18 */
19 package org.onlab.onos.cli; 19 package org.onlab.onos.cli;
20 20
21 +import com.fasterxml.jackson.databind.ObjectMapper;
22 +import com.fasterxml.jackson.databind.node.ObjectNode;
21 import org.apache.karaf.shell.commands.Option; 23 import org.apache.karaf.shell.commands.Option;
22 import org.apache.karaf.shell.console.OsgiCommandSupport; 24 import org.apache.karaf.shell.console.OsgiCommandSupport;
23 import org.onlab.onos.ApplicationId; 25 import org.onlab.onos.ApplicationId;
24 import org.onlab.onos.CoreService; 26 import org.onlab.onos.CoreService;
27 +import org.onlab.onos.net.Annotations;
25 import org.onlab.osgi.DefaultServiceDirectory; 28 import org.onlab.osgi.DefaultServiceDirectory;
26 import org.onlab.osgi.ServiceNotFoundException; 29 import org.onlab.osgi.ServiceNotFoundException;
27 30
...@@ -76,6 +79,34 @@ public abstract class AbstractShellCommand extends OsgiCommandSupport { ...@@ -76,6 +79,34 @@ public abstract class AbstractShellCommand extends OsgiCommandSupport {
76 } 79 }
77 80
78 /** 81 /**
82 + * Produces a string image of the specified key/value annotations.
83 + *
84 + * @param annotations key/value annotations
85 + * @return string image with ", k1=v1, k2=v2, ..." pairs
86 + */
87 + public static String annotations(Annotations annotations) {
88 + StringBuilder sb = new StringBuilder();
89 + for (String key : annotations.keys()) {
90 + sb.append(", ").append(key).append('=').append(annotations.value(key));
91 + }
92 + return sb.toString();
93 + }
94 +
95 + /**
96 + * Produces a JSON object from the specified key/value annotations.
97 + *
98 + * @param annotations key/value annotations
99 + * @return JSON object
100 + */
101 + public static ObjectNode annotations(ObjectMapper mapper, Annotations annotations) {
102 + ObjectNode result = mapper.createObjectNode();
103 + for (String key : annotations.keys()) {
104 + result.put(key, annotations.value(key));
105 + }
106 + return result;
107 + }
108 +
109 + /**
79 * Executes this command. 110 * Executes this command.
80 */ 111 */
81 protected abstract void execute(); 112 protected abstract void execute();
......
...@@ -43,7 +43,7 @@ import static org.onlab.onos.net.DeviceId.deviceId; ...@@ -43,7 +43,7 @@ import static org.onlab.onos.net.DeviceId.deviceId;
43 description = "Lists all ports or all ports of a device") 43 description = "Lists all ports or all ports of a device")
44 public class DevicePortsListCommand extends DevicesListCommand { 44 public class DevicePortsListCommand extends DevicesListCommand {
45 45
46 - private static final String FMT = " port=%s, state=%s"; 46 + private static final String FMT = " port=%s, state=%s%s";
47 47
48 @Option(name = "-e", aliases = "--enabled", description = "Show only enabled ports", 48 @Option(name = "-e", aliases = "--enabled", description = "Show only enabled ports",
49 required = false, multiValued = false) 49 required = false, multiValued = false)
...@@ -112,7 +112,8 @@ public class DevicePortsListCommand extends DevicesListCommand { ...@@ -112,7 +112,8 @@ public class DevicePortsListCommand extends DevicesListCommand {
112 if (isIncluded(port)) { 112 if (isIncluded(port)) {
113 ports.add(mapper.createObjectNode() 113 ports.add(mapper.createObjectNode()
114 .put("port", port.number().toString()) 114 .put("port", port.number().toString())
115 - .put("isEnabled", port.isEnabled())); 115 + .put("isEnabled", port.isEnabled())
116 + .set("annotations", annotations(mapper, port.annotations())));
116 } 117 }
117 } 118 }
118 return result.put("device", device.id().toString()).set("ports", ports); 119 return result.put("device", device.id().toString()).set("ports", ports);
...@@ -131,7 +132,8 @@ public class DevicePortsListCommand extends DevicesListCommand { ...@@ -131,7 +132,8 @@ public class DevicePortsListCommand extends DevicesListCommand {
131 Collections.sort(ports, Comparators.PORT_COMPARATOR); 132 Collections.sort(ports, Comparators.PORT_COMPARATOR);
132 for (Port port : ports) { 133 for (Port port : ports) {
133 if (isIncluded(port)) { 134 if (isIncluded(port)) {
134 - print(FMT, port.number(), port.isEnabled() ? "enabled" : "disabled"); 135 + print(FMT, port.number(), port.isEnabled() ? "enabled" : "disabled",
136 + annotations(port.annotations()));
135 } 137 }
136 } 138 }
137 } 139 }
......
...@@ -41,7 +41,7 @@ import static com.google.common.collect.Lists.newArrayList; ...@@ -41,7 +41,7 @@ import static com.google.common.collect.Lists.newArrayList;
41 public class DevicesListCommand extends AbstractShellCommand { 41 public class DevicesListCommand extends AbstractShellCommand {
42 42
43 private static final String FMT = 43 private static final String FMT =
44 - "id=%s, available=%s, role=%s, type=%s, mfr=%s, hw=%s, sw=%s, serial=%s"; 44 + "id=%s, available=%s, role=%s, type=%s, mfr=%s, hw=%s, sw=%s, serial=%s%s";
45 45
46 @Override 46 @Override
47 protected void execute() { 47 protected void execute() {
...@@ -89,7 +89,8 @@ public class DevicesListCommand extends AbstractShellCommand { ...@@ -89,7 +89,8 @@ public class DevicesListCommand extends AbstractShellCommand {
89 .put("mfr", device.manufacturer()) 89 .put("mfr", device.manufacturer())
90 .put("hw", device.hwVersion()) 90 .put("hw", device.hwVersion())
91 .put("sw", device.swVersion()) 91 .put("sw", device.swVersion())
92 - .put("serial", device.serialNumber()); 92 + .put("serial", device.serialNumber())
93 + .set("annotations", annotations(mapper, device.annotations()));
93 } 94 }
94 return result; 95 return result;
95 } 96 }
...@@ -117,7 +118,7 @@ public class DevicesListCommand extends AbstractShellCommand { ...@@ -117,7 +118,7 @@ public class DevicesListCommand extends AbstractShellCommand {
117 print(FMT, device.id(), service.isAvailable(device.id()), 118 print(FMT, device.id(), service.isAvailable(device.id()),
118 service.getRole(device.id()), device.type(), 119 service.getRole(device.id()), device.type(),
119 device.manufacturer(), device.hwVersion(), device.swVersion(), 120 device.manufacturer(), device.hwVersion(), device.swVersion(),
120 - device.serialNumber()); 121 + device.serialNumber(), annotations(device.annotations()));
121 } 122 }
122 } 123 }
123 124
......
...@@ -42,7 +42,7 @@ import static com.google.common.collect.Lists.newArrayList; ...@@ -42,7 +42,7 @@ import static com.google.common.collect.Lists.newArrayList;
42 public class HostsListCommand extends AbstractShellCommand { 42 public class HostsListCommand extends AbstractShellCommand {
43 43
44 private static final String FMT = 44 private static final String FMT =
45 - "id=%s, mac=%s, location=%s/%s, vlan=%s, ip(s)=%s"; 45 + "id=%s, mac=%s, location=%s/%s, vlan=%s, ip(s)=%s%s";
46 46
47 @Override 47 @Override
48 protected void execute() { 48 protected void execute() {
...@@ -80,6 +80,7 @@ public class HostsListCommand extends AbstractShellCommand { ...@@ -80,6 +80,7 @@ public class HostsListCommand extends AbstractShellCommand {
80 .put("vlan", host.vlan().toString()); 80 .put("vlan", host.vlan().toString());
81 result.set("location", loc); 81 result.set("location", loc);
82 result.set("ips", ips); 82 result.set("ips", ips);
83 + result.set("annotations", annotations(mapper, host.annotations()));
83 return result; 84 return result;
84 } 85 }
85 86
...@@ -105,7 +106,8 @@ public class HostsListCommand extends AbstractShellCommand { ...@@ -105,7 +106,8 @@ public class HostsListCommand extends AbstractShellCommand {
105 print(FMT, host.id(), host.mac(), 106 print(FMT, host.id(), host.mac(),
106 host.location().deviceId(), 107 host.location().deviceId(),
107 host.location().port(), 108 host.location().port(),
108 - host.vlan(), host.ipAddresses()); 109 + host.vlan(), host.ipAddresses(),
110 + annotations(host.annotations()));
109 } 111 }
110 } 112 }
111 } 113 }
......
...@@ -38,7 +38,7 @@ import static org.onlab.onos.net.DeviceId.deviceId; ...@@ -38,7 +38,7 @@ import static org.onlab.onos.net.DeviceId.deviceId;
38 description = "Lists all infrastructure links") 38 description = "Lists all infrastructure links")
39 public class LinksListCommand extends AbstractShellCommand { 39 public class LinksListCommand extends AbstractShellCommand {
40 40
41 - private static final String FMT = "src=%s/%s, dst=%s/%s, type=%s"; 41 + private static final String FMT = "src=%s/%s, dst=%s/%s, type=%s%s";
42 private static final String COMPACT = "%s/%s-%s/%s"; 42 private static final String COMPACT = "%s/%s-%s/%s";
43 43
44 @Argument(index = 0, name = "uri", description = "Device ID", 44 @Argument(index = 0, name = "uri", description = "Device ID",
...@@ -85,6 +85,7 @@ public class LinksListCommand extends AbstractShellCommand { ...@@ -85,6 +85,7 @@ public class LinksListCommand extends AbstractShellCommand {
85 ObjectNode result = mapper.createObjectNode(); 85 ObjectNode result = mapper.createObjectNode();
86 result.set("src", json(mapper, link.src())); 86 result.set("src", json(mapper, link.src()));
87 result.set("dst", json(mapper, link.dst())); 87 result.set("dst", json(mapper, link.dst()));
88 + result.set("annotations", annotations(mapper, link.annotations()));
88 return result; 89 return result;
89 } 90 }
90 91
...@@ -109,7 +110,8 @@ public class LinksListCommand extends AbstractShellCommand { ...@@ -109,7 +110,8 @@ public class LinksListCommand extends AbstractShellCommand {
109 */ 110 */
110 public static String linkString(Link link) { 111 public static String linkString(Link link) {
111 return String.format(FMT, link.src().deviceId(), link.src().port(), 112 return String.format(FMT, link.src().deviceId(), link.src().port(),
112 - link.dst().deviceId(), link.dst().port(), link.type()); 113 + link.dst().deviceId(), link.dst().port(), link.type(),
114 + annotations(link.annotations()));
113 } 115 }
114 116
115 /** 117 /**
......