Adding JSON format to the CLI. Intents and flows still need to be done.
Showing
13 changed files
with
357 additions
and
40 deletions
... | @@ -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 | } | ... | ... |
-
Please register or login to post a comment