tom

Adding JSON format to the CLI. Intents and flows still need to be done.

...@@ -26,6 +26,16 @@ ...@@ -26,6 +26,16 @@
26 <groupId>org.onlab.onos</groupId> 26 <groupId>org.onlab.onos</groupId>
27 <artifactId>onlab-osgi</artifactId> 27 <artifactId>onlab-osgi</artifactId>
28 </dependency> 28 </dependency>
29 +
30 + <dependency>
31 + <groupId>com.fasterxml.jackson.core</groupId>
32 + <artifactId>jackson-databind</artifactId>
33 + </dependency>
34 + <dependency>
35 + <groupId>com.fasterxml.jackson.core</groupId>
36 + <artifactId>jackson-annotations</artifactId>
37 + </dependency>
38 +
29 <dependency> 39 <dependency>
30 <groupId>org.osgi</groupId> 40 <groupId>org.osgi</groupId>
31 <artifactId>org.osgi.core</artifactId> 41 <artifactId>org.osgi.core</artifactId>
......
1 package org.onlab.onos.cli; 1 package org.onlab.onos.cli;
2 2
3 +import org.apache.karaf.shell.commands.Option;
3 import org.apache.karaf.shell.console.OsgiCommandSupport; 4 import org.apache.karaf.shell.console.OsgiCommandSupport;
4 import org.onlab.osgi.DefaultServiceDirectory; 5 import org.onlab.osgi.DefaultServiceDirectory;
5 import org.onlab.osgi.ServiceNotFoundException; 6 import org.onlab.osgi.ServiceNotFoundException;
...@@ -9,6 +10,10 @@ import org.onlab.osgi.ServiceNotFoundException; ...@@ -9,6 +10,10 @@ import org.onlab.osgi.ServiceNotFoundException;
9 */ 10 */
10 public abstract class AbstractShellCommand extends OsgiCommandSupport { 11 public abstract class AbstractShellCommand extends OsgiCommandSupport {
11 12
13 + @Option(name = "-j", aliases = "--json", description = "Output JSON",
14 + required = false, multiValued = false)
15 + private boolean json = false;
16 +
12 /** 17 /**
13 * Returns the reference to the implementation of the specified service. 18 * Returns the reference to the implementation of the specified service.
14 * 19 *
...@@ -46,6 +51,15 @@ public abstract class AbstractShellCommand extends OsgiCommandSupport { ...@@ -46,6 +51,15 @@ public abstract class AbstractShellCommand extends OsgiCommandSupport {
46 */ 51 */
47 protected abstract void execute(); 52 protected abstract void execute();
48 53
54 + /**
55 + * Indicates whether JSON format should be output.
56 + *
57 + * @return true if JSON is requested
58 + */
59 + protected boolean outputJson() {
60 + return json;
61 + }
62 +
49 @Override 63 @Override
50 protected Object doExecute() throws Exception { 64 protected Object doExecute() throws Exception {
51 try { 65 try {
......
1 package org.onlab.onos.cli; 1 package org.onlab.onos.cli;
2 2
3 +import com.fasterxml.jackson.databind.JsonNode;
4 +import com.fasterxml.jackson.databind.ObjectMapper;
5 +import com.fasterxml.jackson.databind.node.ArrayNode;
3 import com.google.common.collect.Lists; 6 import com.google.common.collect.Lists;
4 -
5 import org.apache.karaf.shell.commands.Command; 7 import org.apache.karaf.shell.commands.Command;
6 import org.onlab.onos.cluster.ClusterService; 8 import org.onlab.onos.cluster.ClusterService;
7 import org.onlab.onos.cluster.ControllerNode; 9 import org.onlab.onos.cluster.ControllerNode;
...@@ -26,15 +28,50 @@ public class MastersListCommand extends AbstractShellCommand { ...@@ -26,15 +28,50 @@ public class MastersListCommand extends AbstractShellCommand {
26 MastershipService mastershipService = get(MastershipService.class); 28 MastershipService mastershipService = get(MastershipService.class);
27 List<ControllerNode> nodes = newArrayList(service.getNodes()); 29 List<ControllerNode> nodes = newArrayList(service.getNodes());
28 Collections.sort(nodes, Comparators.NODE_COMPARATOR); 30 Collections.sort(nodes, Comparators.NODE_COMPARATOR);
31 +
32 + if (outputJson()) {
33 + print("%s", json(service, mastershipService, nodes));
34 + } else {
35 + for (ControllerNode node : nodes) {
36 + List<DeviceId> ids = Lists.newArrayList(mastershipService.getDevicesOf(node.id()));
37 + Collections.sort(ids, Comparators.ELEMENT_ID_COMPARATOR);
38 + print("%s: %d devices", node.id(), ids.size());
39 + for (DeviceId deviceId : ids) {
40 + print(" %s", deviceId);
41 + }
42 + }
43 + }
44 + }
45 +
46 + // Produces JSON structure.
47 + private JsonNode json(ClusterService service, MastershipService mastershipService,
48 + List<ControllerNode> nodes) {
49 + ObjectMapper mapper = new ObjectMapper();
50 + ArrayNode result = mapper.createArrayNode();
29 ControllerNode self = service.getLocalNode(); 51 ControllerNode self = service.getLocalNode();
30 for (ControllerNode node : nodes) { 52 for (ControllerNode node : nodes) {
31 List<DeviceId> ids = Lists.newArrayList(mastershipService.getDevicesOf(node.id())); 53 List<DeviceId> ids = Lists.newArrayList(mastershipService.getDevicesOf(node.id()));
32 - Collections.sort(ids, Comparators.ELEMENT_ID_COMPARATOR); 54 + result.add(mapper.createObjectNode()
33 - print("%s: %d devices", node.id(), ids.size()); 55 + .put("id", node.id().toString())
34 - for (DeviceId deviceId : ids) { 56 + .put("size", ids.size())
35 - print(" %s", deviceId); 57 + .set("devices", json(mapper, ids)));
36 - } 58 + }
59 + return result;
60 + }
61 +
62 + /**
63 + * Produces a JSON array containing the specified device identifiers.
64 + *
65 + * @param mapper object mapper
66 + * @param ids collection of device identifiers
67 + * @return JSON array
68 + */
69 + public static JsonNode json(ObjectMapper mapper, Iterable<DeviceId> ids) {
70 + ArrayNode result = mapper.createArrayNode();
71 + for (DeviceId deviceId : ids) {
72 + result.add(deviceId.toString());
37 } 73 }
74 + return result;
38 } 75 }
39 76
40 } 77 }
......
1 package org.onlab.onos.cli; 1 package org.onlab.onos.cli;
2 2
3 +import com.fasterxml.jackson.databind.JsonNode;
4 +import com.fasterxml.jackson.databind.ObjectMapper;
5 +import com.fasterxml.jackson.databind.node.ArrayNode;
3 import org.apache.karaf.shell.commands.Command; 6 import org.apache.karaf.shell.commands.Command;
4 import org.onlab.onos.cluster.ClusterService; 7 import org.onlab.onos.cluster.ClusterService;
5 import org.onlab.onos.cluster.ControllerNode; 8 import org.onlab.onos.cluster.ControllerNode;
...@@ -24,12 +27,32 @@ public class NodesListCommand extends AbstractShellCommand { ...@@ -24,12 +27,32 @@ public class NodesListCommand extends AbstractShellCommand {
24 ClusterService service = get(ClusterService.class); 27 ClusterService service = get(ClusterService.class);
25 List<ControllerNode> nodes = newArrayList(service.getNodes()); 28 List<ControllerNode> nodes = newArrayList(service.getNodes());
26 Collections.sort(nodes, Comparators.NODE_COMPARATOR); 29 Collections.sort(nodes, Comparators.NODE_COMPARATOR);
30 + if (outputJson()) {
31 + print("%s", json(service, nodes));
32 + } else {
33 + ControllerNode self = service.getLocalNode();
34 + for (ControllerNode node : nodes) {
35 + print(FMT, node.id(), node.ip(), node.tcpPort(),
36 + service.getState(node.id()),
37 + node.equals(self) ? "*" : "");
38 + }
39 + }
40 + }
41 +
42 + // Produces JSON structure.
43 + private JsonNode json(ClusterService service, List<ControllerNode> nodes) {
44 + ObjectMapper mapper = new ObjectMapper();
45 + ArrayNode result = mapper.createArrayNode();
27 ControllerNode self = service.getLocalNode(); 46 ControllerNode self = service.getLocalNode();
28 for (ControllerNode node : nodes) { 47 for (ControllerNode node : nodes) {
29 - print(FMT, node.id(), node.ip(), node.tcpPort(), 48 + result.add(mapper.createObjectNode()
30 - service.getState(node.id()), 49 + .put("id", node.id().toString())
31 - node.equals(self) ? "*" : ""); 50 + .put("ip", node.ip().toString())
51 + .put("tcpPort", node.tcpPort())
52 + .put("state", service.getState(node.id()).toString())
53 + .put("self", node.equals(self)));
32 } 54 }
55 + return result;
33 } 56 }
34 57
35 } 58 }
......
1 package org.onlab.onos.cli; 1 package org.onlab.onos.cli;
2 2
3 +import com.fasterxml.jackson.databind.ObjectMapper;
3 import org.apache.karaf.shell.commands.Command; 4 import org.apache.karaf.shell.commands.Command;
4 import org.onlab.onos.CoreService; 5 import org.onlab.onos.CoreService;
5 import org.onlab.onos.cluster.ClusterService; 6 import org.onlab.onos.cluster.ClusterService;
...@@ -22,18 +23,32 @@ public class SummaryCommand extends AbstractShellCommand { ...@@ -22,18 +23,32 @@ public class SummaryCommand extends AbstractShellCommand {
22 protected void execute() { 23 protected void execute() {
23 TopologyService topologyService = get(TopologyService.class); 24 TopologyService topologyService = get(TopologyService.class);
24 Topology topology = topologyService.currentTopology(); 25 Topology topology = topologyService.currentTopology();
25 - print("node=%s, version=%s", 26 + if (outputJson()) {
26 - get(ClusterService.class).getLocalNode().ip(), 27 + print("%s", new ObjectMapper().createObjectNode()
27 - get(CoreService.class).version().toString()); 28 + .put("node", get(ClusterService.class).getLocalNode().ip().toString())
28 - print("nodes=%d, devices=%d, links=%d, hosts=%d, clusters=%s, paths=%d, flows=%d, intents=%d", 29 + .put("version", get(CoreService.class).version().toString())
29 - get(ClusterService.class).getNodes().size(), 30 + .put("nodes", get(ClusterService.class).getNodes().size())
30 - get(DeviceService.class).getDeviceCount(), 31 + .put("devices", get(DeviceService.class).getDeviceCount())
31 - get(LinkService.class).getLinkCount(), 32 + .put("links", get(LinkService.class).getLinkCount())
32 - get(HostService.class).getHostCount(), 33 + .put("hosts", get(HostService.class).getHostCount())
33 - topologyService.getClusters(topology).size(), 34 + .put("clusters", topologyService.getClusters(topology).size())
34 - topology.pathCount(), 35 + .put("paths", topology.pathCount())
35 - get(FlowRuleService.class).getFlowRuleCount(), 36 + .put("flows", get(FlowRuleService.class).getFlowRuleCount())
36 - get(IntentService.class).getIntentCount()); 37 + .put("intents", get(IntentService.class).getIntentCount()));
38 + } else {
39 + print("node=%s, version=%s",
40 + get(ClusterService.class).getLocalNode().ip(),
41 + get(CoreService.class).version().toString());
42 + print("nodes=%d, devices=%d, links=%d, hosts=%d, clusters=%s, paths=%d, flows=%d, intents=%d",
43 + get(ClusterService.class).getNodes().size(),
44 + get(DeviceService.class).getDeviceCount(),
45 + get(LinkService.class).getLinkCount(),
46 + get(HostService.class).getHostCount(),
47 + topologyService.getClusters(topology).size(),
48 + topology.pathCount(),
49 + get(FlowRuleService.class).getFlowRuleCount(),
50 + get(IntentService.class).getIntentCount());
51 + }
37 } 52 }
38 53
39 } 54 }
......
1 package org.onlab.onos.cli.net; 1 package org.onlab.onos.cli.net;
2 2
3 +import com.fasterxml.jackson.databind.ObjectMapper;
3 import com.google.common.collect.Lists; 4 import com.google.common.collect.Lists;
4 import org.apache.karaf.shell.commands.Argument; 5 import org.apache.karaf.shell.commands.Argument;
5 import org.apache.karaf.shell.commands.Command; 6 import org.apache.karaf.shell.commands.Command;
...@@ -10,6 +11,7 @@ import org.onlab.onos.net.topology.TopologyCluster; ...@@ -10,6 +11,7 @@ import org.onlab.onos.net.topology.TopologyCluster;
10 import java.util.Collections; 11 import java.util.Collections;
11 import java.util.List; 12 import java.util.List;
12 13
14 +import static org.onlab.onos.cli.MastersListCommand.json;
13 import static org.onlab.onos.net.topology.ClusterId.clusterId; 15 import static org.onlab.onos.net.topology.ClusterId.clusterId;
14 16
15 /** 17 /**
...@@ -33,11 +35,14 @@ public class ClusterDevicesCommand extends ClustersListCommand { ...@@ -33,11 +35,14 @@ public class ClusterDevicesCommand extends ClustersListCommand {
33 } else { 35 } else {
34 List<DeviceId> ids = Lists.newArrayList(service.getClusterDevices(topology, cluster)); 36 List<DeviceId> ids = Lists.newArrayList(service.getClusterDevices(topology, cluster));
35 Collections.sort(ids, Comparators.ELEMENT_ID_COMPARATOR); 37 Collections.sort(ids, Comparators.ELEMENT_ID_COMPARATOR);
36 - for (DeviceId deviceId : ids) { 38 + if (outputJson()) {
37 - print("%s", deviceId); 39 + print("%s", json(new ObjectMapper(), ids));
40 + } else {
41 + for (DeviceId deviceId : ids) {
42 + print("%s", deviceId);
43 + }
38 } 44 }
39 } 45 }
40 } 46 }
41 47
42 -
43 } 48 }
......
...@@ -5,6 +5,7 @@ import org.apache.karaf.shell.commands.Command; ...@@ -5,6 +5,7 @@ import org.apache.karaf.shell.commands.Command;
5 import org.onlab.onos.net.Link; 5 import org.onlab.onos.net.Link;
6 import org.onlab.onos.net.topology.TopologyCluster; 6 import org.onlab.onos.net.topology.TopologyCluster;
7 7
8 +import static org.onlab.onos.cli.net.LinksListCommand.json;
8 import static org.onlab.onos.cli.net.LinksListCommand.linkString; 9 import static org.onlab.onos.cli.net.LinksListCommand.linkString;
9 import static org.onlab.onos.net.topology.ClusterId.clusterId; 10 import static org.onlab.onos.net.topology.ClusterId.clusterId;
10 11
...@@ -26,6 +27,8 @@ public class ClusterLinksCommand extends ClustersListCommand { ...@@ -26,6 +27,8 @@ public class ClusterLinksCommand extends ClustersListCommand {
26 TopologyCluster cluster = service.getCluster(topology, clusterId(cid)); 27 TopologyCluster cluster = service.getCluster(topology, clusterId(cid));
27 if (cluster == null) { 28 if (cluster == null) {
28 error("No such cluster %s", cid); 29 error("No such cluster %s", cid);
30 + } else if (outputJson()) {
31 + print("%s", json(service.getClusterLinks(topology, cluster)));
29 } else { 32 } else {
30 for (Link link : service.getClusterLinks(topology, cluster)) { 33 for (Link link : service.getClusterLinks(topology, cluster)) {
31 print(linkString(link)); 34 print(linkString(link));
......
1 package org.onlab.onos.cli.net; 1 package org.onlab.onos.cli.net;
2 2
3 +import com.fasterxml.jackson.databind.JsonNode;
4 +import com.fasterxml.jackson.databind.ObjectMapper;
5 +import com.fasterxml.jackson.databind.node.ArrayNode;
3 import com.google.common.collect.Lists; 6 import com.google.common.collect.Lists;
4 import org.apache.karaf.shell.commands.Command; 7 import org.apache.karaf.shell.commands.Command;
5 import org.onlab.onos.cli.Comparators; 8 import org.onlab.onos.cli.Comparators;
...@@ -24,9 +27,26 @@ public class ClustersListCommand extends TopologyCommand { ...@@ -24,9 +27,26 @@ public class ClustersListCommand extends TopologyCommand {
24 List<TopologyCluster> clusters = Lists.newArrayList(service.getClusters(topology)); 27 List<TopologyCluster> clusters = Lists.newArrayList(service.getClusters(topology));
25 Collections.sort(clusters, Comparators.CLUSTER_COMPARATOR); 28 Collections.sort(clusters, Comparators.CLUSTER_COMPARATOR);
26 29
30 + if (outputJson()) {
31 + print("%s", json(clusters));
32 + } else {
33 + for (TopologyCluster cluster : clusters) {
34 + print(FMT, cluster.id().index(), cluster.deviceCount(), cluster.linkCount());
35 + }
36 + }
37 + }
38 +
39 + // Produces a JSON result.
40 + private JsonNode json(Iterable<TopologyCluster> clusters) {
41 + ObjectMapper mapper = new ObjectMapper();
42 + ArrayNode result = mapper.createArrayNode();
27 for (TopologyCluster cluster : clusters) { 43 for (TopologyCluster cluster : clusters) {
28 - print(FMT, cluster.id().index(), cluster.deviceCount(), cluster.linkCount()); 44 + result.add(mapper.createObjectNode()
45 + .put("id", cluster.id().index())
46 + .put("deviceCount", cluster.deviceCount())
47 + .put("linkCount", cluster.linkCount()));
29 } 48 }
49 + return result;
30 } 50 }
31 51
32 } 52 }
......
1 package org.onlab.onos.cli.net; 1 package org.onlab.onos.cli.net;
2 2
3 +import com.fasterxml.jackson.databind.JsonNode;
4 +import com.fasterxml.jackson.databind.ObjectMapper;
5 +import com.fasterxml.jackson.databind.node.ArrayNode;
6 +import com.fasterxml.jackson.databind.node.ObjectNode;
3 import org.apache.karaf.shell.commands.Argument; 7 import org.apache.karaf.shell.commands.Argument;
4 import org.apache.karaf.shell.commands.Command; 8 import org.apache.karaf.shell.commands.Command;
5 import org.onlab.onos.cli.Comparators; 9 import org.onlab.onos.cli.Comparators;
...@@ -30,19 +34,61 @@ public class DevicePortsListCommand extends DevicesListCommand { ...@@ -30,19 +34,61 @@ public class DevicePortsListCommand extends DevicesListCommand {
30 protected void execute() { 34 protected void execute() {
31 DeviceService service = get(DeviceService.class); 35 DeviceService service = get(DeviceService.class);
32 if (uri == null) { 36 if (uri == null) {
33 - for (Device device : getSortedDevices(service)) { 37 + if (outputJson()) {
34 - printDevice(service, device); 38 + print("%s", jsonPorts(service, getSortedDevices(service)));
39 + } else {
40 + for (Device device : getSortedDevices(service)) {
41 + printDevice(service, device);
42 + }
35 } 43 }
44 +
36 } else { 45 } else {
37 Device device = service.getDevice(deviceId(uri)); 46 Device device = service.getDevice(deviceId(uri));
38 if (device == null) { 47 if (device == null) {
39 error("No such device %s", uri); 48 error("No such device %s", uri);
49 + } else if (outputJson()) {
50 + print("%s", jsonPorts(service, new ObjectMapper(), device));
40 } else { 51 } else {
41 printDevice(service, device); 52 printDevice(service, device);
42 } 53 }
43 } 54 }
44 } 55 }
45 56
57 + /**
58 + * Produces JSON array containing ports of the specified devices.
59 + *
60 + * @param service device service
61 + * @param devices collection of devices
62 + * @return JSON array
63 + */
64 + public static JsonNode jsonPorts(DeviceService service, Iterable<Device> devices) {
65 + ObjectMapper mapper = new ObjectMapper();
66 + ArrayNode result = mapper.createArrayNode();
67 + for (Device device : devices) {
68 + result.add(jsonPorts(service, mapper, device));
69 + }
70 + return result;
71 + }
72 +
73 + /**
74 + * Produces JSON array containing ports of the specified device.
75 + *
76 + * @param service device service
77 + * @param mapper object mapper
78 + * @param device infrastructure devices
79 + * @return JSON array
80 + */
81 + public static JsonNode jsonPorts(DeviceService service, ObjectMapper mapper, Device device) {
82 + ObjectNode result = mapper.createObjectNode();
83 + ArrayNode ports = mapper.createArrayNode();
84 + for (Port port : service.getPorts(device.id())) {
85 + ports.add(mapper.createObjectNode()
86 + .put("port", port.number().toString())
87 + .put("isEnabled", port.isEnabled()));
88 + }
89 + return result.put("device", device.id().toString()).set("ports", ports);
90 + }
91 +
46 @Override 92 @Override
47 protected void printDevice(DeviceService service, Device device) { 93 protected void printDevice(DeviceService service, Device device) {
48 super.printDevice(service, device); 94 super.printDevice(service, device);
......
1 package org.onlab.onos.cli.net; 1 package org.onlab.onos.cli.net;
2 2
3 +import com.fasterxml.jackson.databind.JsonNode;
4 +import com.fasterxml.jackson.databind.ObjectMapper;
5 +import com.fasterxml.jackson.databind.node.ArrayNode;
6 +import com.fasterxml.jackson.databind.node.ObjectNode;
3 import org.apache.karaf.shell.commands.Command; 7 import org.apache.karaf.shell.commands.Command;
4 import org.onlab.onos.cli.AbstractShellCommand; 8 import org.onlab.onos.cli.AbstractShellCommand;
5 import org.onlab.onos.cli.Comparators; 9 import org.onlab.onos.cli.Comparators;
...@@ -24,12 +28,55 @@ public class DevicesListCommand extends AbstractShellCommand { ...@@ -24,12 +28,55 @@ public class DevicesListCommand extends AbstractShellCommand {
24 @Override 28 @Override
25 protected void execute() { 29 protected void execute() {
26 DeviceService service = get(DeviceService.class); 30 DeviceService service = get(DeviceService.class);
27 - for (Device device : getSortedDevices(service)) { 31 + if (outputJson()) {
28 - printDevice(service, device); 32 + print("%s", json(service, getSortedDevices(service)));
33 + } else {
34 + for (Device device : getSortedDevices(service)) {
35 + printDevice(service, device);
36 + }
29 } 37 }
30 } 38 }
31 39
32 /** 40 /**
41 + * Returns JSON node representing the specified devices.
42 + *
43 + * @param service device service
44 + * @param devices collection of devices
45 + * @return JSON node
46 + */
47 + public static JsonNode json(DeviceService service, Iterable<Device> devices) {
48 + ObjectMapper mapper = new ObjectMapper();
49 + ArrayNode result = mapper.createArrayNode();
50 + for (Device device : devices) {
51 + result.add(json(service, mapper, device));
52 + }
53 + return result;
54 + }
55 +
56 + /**
57 + * Returns JSON node representing the specified device.
58 + *
59 + * @param service device service
60 + * @param mapper object mapper
61 + * @param device infrastructure device
62 + * @return JSON node
63 + */
64 + public static ObjectNode json(DeviceService service, ObjectMapper mapper,
65 + Device device) {
66 + ObjectNode result = mapper.createObjectNode();
67 + if (device != null) {
68 + result.put("id", device.id().toString())
69 + .put("available", service.isAvailable(device.id()))
70 + .put("role", service.getRole(device.id()).toString())
71 + .put("mfr", device.manufacturer())
72 + .put("hw", device.hwVersion())
73 + .put("sw", device.swVersion())
74 + .put("serial", device.serialNumber());
75 + }
76 + return result;
77 + }
78 +
79 + /**
33 * Returns the list of devices sorted using the device ID URIs. 80 * Returns the list of devices sorted using the device ID URIs.
34 * 81 *
35 * @param service device service 82 * @param service device service
......
1 package org.onlab.onos.cli.net; 1 package org.onlab.onos.cli.net;
2 2
3 +import com.fasterxml.jackson.databind.JsonNode;
4 +import com.fasterxml.jackson.databind.ObjectMapper;
5 +import com.fasterxml.jackson.databind.node.ArrayNode;
6 +import com.fasterxml.jackson.databind.node.ObjectNode;
3 import org.apache.karaf.shell.commands.Command; 7 import org.apache.karaf.shell.commands.Command;
4 import org.onlab.onos.cli.AbstractShellCommand; 8 import org.onlab.onos.cli.AbstractShellCommand;
5 import org.onlab.onos.cli.Comparators; 9 import org.onlab.onos.cli.Comparators;
6 import org.onlab.onos.net.Host; 10 import org.onlab.onos.net.Host;
7 import org.onlab.onos.net.host.HostService; 11 import org.onlab.onos.net.host.HostService;
12 +import org.onlab.packet.IpPrefix;
8 13
9 import java.util.Collections; 14 import java.util.Collections;
10 import java.util.List; 15 import java.util.List;
...@@ -15,7 +20,7 @@ import static com.google.common.collect.Lists.newArrayList; ...@@ -15,7 +20,7 @@ import static com.google.common.collect.Lists.newArrayList;
15 * Lists all currently-known hosts. 20 * Lists all currently-known hosts.
16 */ 21 */
17 @Command(scope = "onos", name = "hosts", 22 @Command(scope = "onos", name = "hosts",
18 - description = "Lists all currently-known hosts.") 23 + description = "Lists all currently-known hosts.")
19 public class HostsListCommand extends AbstractShellCommand { 24 public class HostsListCommand extends AbstractShellCommand {
20 25
21 private static final String FMT = 26 private static final String FMT =
...@@ -24,11 +29,42 @@ public class HostsListCommand extends AbstractShellCommand { ...@@ -24,11 +29,42 @@ public class HostsListCommand extends AbstractShellCommand {
24 @Override 29 @Override
25 protected void execute() { 30 protected void execute() {
26 HostService service = get(HostService.class); 31 HostService service = get(HostService.class);
27 - for (Host host : getSortedHosts(service)) { 32 + if (outputJson()) {
28 - printHost(host); 33 + print("%s", json(getSortedHosts(service)));
34 + } else {
35 + for (Host host : getSortedHosts(service)) {
36 + printHost(host);
37 + }
29 } 38 }
30 } 39 }
31 40
41 + // Produces JSON structure.
42 + private static JsonNode json(Iterable<Host> hosts) {
43 + ObjectMapper mapper = new ObjectMapper();
44 + ArrayNode result = mapper.createArrayNode();
45 + for (Host host : hosts) {
46 + result.add(json(mapper, host));
47 + }
48 + return result;
49 + }
50 +
51 + // Produces JSON structure.
52 + private static JsonNode json(ObjectMapper mapper, Host host) {
53 + ObjectNode loc = LinksListCommand.json(mapper, host.location())
54 + .put("time", host.location().time());
55 + ArrayNode ips = mapper.createArrayNode();
56 + for (IpPrefix ip : host.ipAddresses()) {
57 + ips.add(ip.toString());
58 + }
59 + ObjectNode result = mapper.createObjectNode()
60 + .put("id", host.id().toString())
61 + .put("mac", host.mac().toString())
62 + .put("vlan", host.vlan().toString());
63 + result.set("location", loc);
64 + result.set("ips", ips);
65 + return result;
66 + }
67 +
32 /** 68 /**
33 * Returns the list of devices sorted using the device ID URIs. 69 * Returns the list of devices sorted using the device ID URIs.
34 * 70 *
...@@ -44,14 +80,14 @@ public class HostsListCommand extends AbstractShellCommand { ...@@ -44,14 +80,14 @@ public class HostsListCommand extends AbstractShellCommand {
44 /** 80 /**
45 * Prints information about a host. 81 * Prints information about a host.
46 * 82 *
47 - * @param host 83 + * @param host end-station host
48 */ 84 */
49 protected void printHost(Host host) { 85 protected void printHost(Host host) {
50 if (host != null) { 86 if (host != null) {
51 print(FMT, host.id(), host.mac(), 87 print(FMT, host.id(), host.mac(),
52 - host.location().deviceId(), 88 + host.location().deviceId(),
53 - host.location().port(), 89 + host.location().port(),
54 - host.vlan(), host.ipAddresses()); 90 + host.vlan(), host.ipAddresses());
55 } 91 }
56 } 92 }
57 - } 93 +}
......
1 package org.onlab.onos.cli.net; 1 package org.onlab.onos.cli.net;
2 2
3 +import com.fasterxml.jackson.databind.JsonNode;
4 +import com.fasterxml.jackson.databind.ObjectMapper;
5 +import com.fasterxml.jackson.databind.node.ArrayNode;
6 +import com.fasterxml.jackson.databind.node.ObjectNode;
3 import org.apache.karaf.shell.commands.Argument; 7 import org.apache.karaf.shell.commands.Argument;
4 import org.apache.karaf.shell.commands.Command; 8 import org.apache.karaf.shell.commands.Command;
5 import org.onlab.onos.cli.AbstractShellCommand; 9 import org.onlab.onos.cli.AbstractShellCommand;
10 +import org.onlab.onos.net.ConnectPoint;
6 import org.onlab.onos.net.Link; 11 import org.onlab.onos.net.Link;
7 import org.onlab.onos.net.link.LinkService; 12 import org.onlab.onos.net.link.LinkService;
8 13
...@@ -27,9 +32,55 @@ public class LinksListCommand extends AbstractShellCommand { ...@@ -27,9 +32,55 @@ public class LinksListCommand extends AbstractShellCommand {
27 LinkService service = get(LinkService.class); 32 LinkService service = get(LinkService.class);
28 Iterable<Link> links = uri != null ? 33 Iterable<Link> links = uri != null ?
29 service.getDeviceLinks(deviceId(uri)) : service.getLinks(); 34 service.getDeviceLinks(deviceId(uri)) : service.getLinks();
35 + if (outputJson()) {
36 + print("%s", json(links));
37 + } else {
38 + for (Link link : links) {
39 + print(linkString(link));
40 + }
41 + }
42 + }
43 +
44 + /**
45 + * Produces a JSON array containing the specified links.
46 + *
47 + * @param links collection of links
48 + * @return JSON array
49 + */
50 + public static JsonNode json(Iterable<Link> links) {
51 + ObjectMapper mapper = new ObjectMapper();
52 + ArrayNode result = mapper.createArrayNode();
30 for (Link link : links) { 53 for (Link link : links) {
31 - print(linkString(link)); 54 + result.add(json(mapper, link));
32 } 55 }
56 + return result;
57 + }
58 +
59 + /**
60 + * Produces a JSON object for the specified link.
61 + *
62 + * @param mapper object mapper
63 + * @param link link to encode
64 + * @return JSON object
65 + */
66 + public static ObjectNode json(ObjectMapper mapper, Link link) {
67 + ObjectNode result = mapper.createObjectNode();
68 + result.set("src", json(mapper, link.src()));
69 + result.set("dst", json(mapper, link.src()));
70 + return result;
71 + }
72 +
73 + /**
74 + * Produces a JSON object for the specified connect point.
75 + *
76 + * @param mapper object mapper
77 + * @param connectPoint connection point to encode
78 + * @return JSON object
79 + */
80 + public static ObjectNode json(ObjectMapper mapper, ConnectPoint connectPoint) {
81 + return mapper.createObjectNode()
82 + .put("device", connectPoint.deviceId().toString())
83 + .put("port", connectPoint.port().toString());
33 } 84 }
34 85
35 /** 86 /**
......
1 package org.onlab.onos.cli.net; 1 package org.onlab.onos.cli.net;
2 2
3 +import com.fasterxml.jackson.databind.ObjectMapper;
3 import org.apache.karaf.shell.commands.Command; 4 import org.apache.karaf.shell.commands.Command;
4 import org.onlab.onos.cli.AbstractShellCommand; 5 import org.onlab.onos.cli.AbstractShellCommand;
5 import org.onlab.onos.net.topology.Topology; 6 import org.onlab.onos.net.topology.Topology;
...@@ -30,8 +31,17 @@ public class TopologyCommand extends AbstractShellCommand { ...@@ -30,8 +31,17 @@ public class TopologyCommand extends AbstractShellCommand {
30 @Override 31 @Override
31 protected void execute() { 32 protected void execute() {
32 init(); 33 init();
33 - print(FMT, topology.time(), topology.deviceCount(), topology.linkCount(), 34 + if (outputJson()) {
34 - topology.clusterCount(), topology.pathCount()); 35 + print("%s", new ObjectMapper().createObjectNode()
36 + .put("time", topology.time())
37 + .put("deviceCount", topology.deviceCount())
38 + .put("linkCount", topology.linkCount())
39 + .put("clusterCount", topology.clusterCount())
40 + .put("pathCount", topology.pathCount()));
41 + } else {
42 + print(FMT, topology.time(), topology.deviceCount(), topology.linkCount(),
43 + topology.clusterCount(), topology.pathCount());
44 + }
35 } 45 }
36 46
37 } 47 }
......