Ray Milkey
Committed by Gerrit Code Review

ONOS-743 - Use REST API Codecs to generate JSON for CLI commands

Change-Id: I25e0840d1af03341c638f837498c95275e6cf31b
Showing 23 changed files with 133 additions and 295 deletions
...@@ -41,6 +41,10 @@ ...@@ -41,6 +41,10 @@
41 <groupId>org.onosproject</groupId> 41 <groupId>org.onosproject</groupId>
42 <artifactId>onlab-osgi</artifactId> 42 <artifactId>onlab-osgi</artifactId>
43 </dependency> 43 </dependency>
44 + <dependency>
45 + <groupId>org.onosproject</groupId>
46 + <artifactId>onos-core-common</artifactId>
47 + </dependency>
44 48
45 <dependency> 49 <dependency>
46 <groupId>com.fasterxml.jackson.core</groupId> 50 <groupId>com.fasterxml.jackson.core</groupId>
......
...@@ -15,20 +15,24 @@ ...@@ -15,20 +15,24 @@
15 */ 15 */
16 package org.onosproject.cli; 16 package org.onosproject.cli;
17 17
18 -import com.fasterxml.jackson.databind.ObjectMapper;
19 -import com.fasterxml.jackson.databind.node.ObjectNode;
20 import org.apache.karaf.shell.commands.Option; 18 import org.apache.karaf.shell.commands.Option;
21 import org.apache.karaf.shell.console.AbstractAction; 19 import org.apache.karaf.shell.console.AbstractAction;
22 import org.onlab.osgi.DefaultServiceDirectory; 20 import org.onlab.osgi.DefaultServiceDirectory;
23 import org.onlab.osgi.ServiceNotFoundException; 21 import org.onlab.osgi.ServiceNotFoundException;
22 +import org.onosproject.codec.CodecContext;
23 +import org.onosproject.codec.CodecService;
24 +import org.onosproject.codec.JsonCodec;
24 import org.onosproject.core.ApplicationId; 25 import org.onosproject.core.ApplicationId;
25 import org.onosproject.core.CoreService; 26 import org.onosproject.core.CoreService;
26 import org.onosproject.net.Annotations; 27 import org.onosproject.net.Annotations;
27 28
29 +import com.fasterxml.jackson.databind.ObjectMapper;
30 +import com.fasterxml.jackson.databind.node.ObjectNode;
31 +
28 /** 32 /**
29 * Base abstraction of Karaf shell commands. 33 * Base abstraction of Karaf shell commands.
30 */ 34 */
31 -public abstract class AbstractShellCommand extends AbstractAction { 35 +public abstract class AbstractShellCommand extends AbstractAction implements CodecContext {
32 36
33 @Option(name = "-j", aliases = "--json", description = "Output JSON", 37 @Option(name = "-j", aliases = "--json", description = "Output JSON",
34 required = false, multiValued = false) 38 required = false, multiValued = false)
...@@ -129,4 +133,35 @@ public abstract class AbstractShellCommand extends AbstractAction { ...@@ -129,4 +133,35 @@ public abstract class AbstractShellCommand extends AbstractAction {
129 return null; 133 return null;
130 } 134 }
131 135
136 +
137 +
138 + private final ObjectMapper mapper = new ObjectMapper();
139 +
140 + @Override
141 + public ObjectMapper mapper() {
142 + return mapper;
143 + }
144 +
145 + @Override
146 + @SuppressWarnings("unchecked")
147 + public <T> JsonCodec<T> codec(Class<T> entityClass) {
148 + return get(CodecService.class).getCodec(entityClass);
149 + }
150 +
151 + @Override
152 + public <T> T getService(Class<T> serviceClass) {
153 + return get(serviceClass);
154 + }
155 +
156 + /**
157 + * Generates a Json representation of an object.
158 + *
159 + * @param entity object to generate JSON for
160 + * @param entityClass class to format with - this chooses which codec to use
161 + * @param <T> Type of the object being formatted
162 + * @return JSON object representation
163 + */
164 + public <T> ObjectNode jsonForEntity(T entity, Class<T> entityClass) {
165 + return codec(entityClass).encode(entity, this);
166 + }
132 } 167 }
......
...@@ -15,9 +15,9 @@ ...@@ -15,9 +15,9 @@
15 */ 15 */
16 package org.onosproject.cli.app; 16 package org.onosproject.cli.app;
17 17
18 -import com.fasterxml.jackson.databind.JsonNode; 18 +import java.util.Collections;
19 -import com.fasterxml.jackson.databind.ObjectMapper; 19 +import java.util.List;
20 -import com.fasterxml.jackson.databind.node.ArrayNode; 20 +
21 import org.apache.karaf.shell.commands.Command; 21 import org.apache.karaf.shell.commands.Command;
22 import org.apache.karaf.shell.commands.Option; 22 import org.apache.karaf.shell.commands.Option;
23 import org.onosproject.app.ApplicationService; 23 import org.onosproject.app.ApplicationService;
...@@ -25,8 +25,9 @@ import org.onosproject.cli.AbstractShellCommand; ...@@ -25,8 +25,9 @@ import org.onosproject.cli.AbstractShellCommand;
25 import org.onosproject.cli.Comparators; 25 import org.onosproject.cli.Comparators;
26 import org.onosproject.core.Application; 26 import org.onosproject.core.Application;
27 27
28 -import java.util.Collections; 28 +import com.fasterxml.jackson.databind.JsonNode;
29 -import java.util.List; 29 +import com.fasterxml.jackson.databind.ObjectMapper;
30 +import com.fasterxml.jackson.databind.node.ArrayNode;
30 31
31 import static com.google.common.collect.Lists.newArrayList; 32 import static com.google.common.collect.Lists.newArrayList;
32 import static org.onosproject.app.ApplicationState.ACTIVE; 33 import static org.onosproject.app.ApplicationState.ACTIVE;
...@@ -88,25 +89,12 @@ public class ApplicationsListCommand extends AbstractShellCommand { ...@@ -88,25 +89,12 @@ public class ApplicationsListCommand extends AbstractShellCommand {
88 for (Application app : apps) { 89 for (Application app : apps) {
89 boolean isActive = service.getState(app.id()) == ACTIVE; 90 boolean isActive = service.getState(app.id()) == ACTIVE;
90 if (activeOnly && isActive || !activeOnly) { 91 if (activeOnly && isActive || !activeOnly) {
91 - result.add(json(service, mapper, app)); 92 + result.add(jsonForEntity(app, Application.class));
92 } 93 }
93 } 94 }
94 return result; 95 return result;
95 } 96 }
96 97
97 - protected JsonNode json(ApplicationService service, ObjectMapper mapper, 98 +
98 - Application app) {
99 - return mapper.createObjectNode()
100 - .put("name", app.id().name())
101 - .put("id", app.id().id())
102 - .put("version", app.version().toString())
103 - .put("description", app.description())
104 - .put("origin", app.origin())
105 - .put("permissions", app.permissions().toString())
106 - .put("featuresRepo", app.featuresRepo().isPresent() ?
107 - app.featuresRepo().get().toString() : "")
108 - .put("features", app.features().toString())
109 - .put("state", service.getState(app.id()).toString());
110 - }
111 99
112 } 100 }
......
...@@ -43,7 +43,7 @@ public class ClusterLinksCommand extends ClustersListCommand { ...@@ -43,7 +43,7 @@ public class ClusterLinksCommand extends ClustersListCommand {
43 if (cluster == null) { 43 if (cluster == null) {
44 error("No such cluster %s", cid); 44 error("No such cluster %s", cid);
45 } else if (outputJson()) { 45 } else if (outputJson()) {
46 - print("%s", json(service.getClusterLinks(topology, cluster))); 46 + print("%s", json(this, service.getClusterLinks(topology, cluster)));
47 } else { 47 } else {
48 for (Link link : service.getClusterLinks(topology, cluster)) { 48 for (Link link : service.getClusterLinks(topology, cluster)) {
49 print(linkString(link)); 49 print(linkString(link));
......
...@@ -55,12 +55,11 @@ public class ClustersListCommand extends TopologyCommand { ...@@ -55,12 +55,11 @@ public class ClustersListCommand extends TopologyCommand {
55 private JsonNode json(Iterable<TopologyCluster> clusters) { 55 private JsonNode json(Iterable<TopologyCluster> clusters) {
56 ObjectMapper mapper = new ObjectMapper(); 56 ObjectMapper mapper = new ObjectMapper();
57 ArrayNode result = mapper.createArrayNode(); 57 ArrayNode result = mapper.createArrayNode();
58 - for (TopologyCluster cluster : clusters) { 58 +
59 - result.add(mapper.createObjectNode() 59 + clusters.spliterator()
60 - .put("id", cluster.id().index()) 60 + .forEachRemaining(cluster ->
61 - .put("deviceCount", cluster.deviceCount()) 61 + result.add(jsonForEntity(cluster, TopologyCluster.class)));
62 - .put("linkCount", cluster.linkCount())); 62 +
63 - }
64 return result; 63 return result;
65 } 64 }
66 65
......
...@@ -116,7 +116,7 @@ public class DevicePortsListCommand extends DevicesListCommand { ...@@ -116,7 +116,7 @@ public class DevicePortsListCommand extends DevicesListCommand {
116 .set("annotations", annotations(mapper, port.annotations()))); 116 .set("annotations", annotations(mapper, port.annotations())));
117 } 117 }
118 } 118 }
119 - result.set("device", json(service, mapper, device)); 119 + result.set("device", jsonForEntity(device, Device.class));
120 result.set("ports", ports); 120 result.set("ports", ports);
121 return result; 121 return result;
122 } 122 }
......
...@@ -15,18 +15,18 @@ ...@@ -15,18 +15,18 @@
15 */ 15 */
16 package org.onosproject.cli.net; 16 package org.onosproject.cli.net;
17 17
18 -import com.fasterxml.jackson.databind.JsonNode; 18 +import java.util.Collections;
19 -import com.fasterxml.jackson.databind.ObjectMapper; 19 +import java.util.List;
20 -import com.fasterxml.jackson.databind.node.ArrayNode; 20 +
21 -import com.fasterxml.jackson.databind.node.ObjectNode;
22 import org.apache.karaf.shell.commands.Command; 21 import org.apache.karaf.shell.commands.Command;
23 import org.onosproject.cli.AbstractShellCommand; 22 import org.onosproject.cli.AbstractShellCommand;
24 import org.onosproject.cli.Comparators; 23 import org.onosproject.cli.Comparators;
25 import org.onosproject.net.Device; 24 import org.onosproject.net.Device;
26 import org.onosproject.net.device.DeviceService; 25 import org.onosproject.net.device.DeviceService;
27 26
28 -import java.util.Collections; 27 +import com.fasterxml.jackson.databind.JsonNode;
29 -import java.util.List; 28 +import com.fasterxml.jackson.databind.ObjectMapper;
29 +import com.fasterxml.jackson.databind.node.ArrayNode;
30 30
31 import static com.google.common.collect.Lists.newArrayList; 31 import static com.google.common.collect.Lists.newArrayList;
32 32
...@@ -44,7 +44,7 @@ public class DevicesListCommand extends AbstractShellCommand { ...@@ -44,7 +44,7 @@ public class DevicesListCommand extends AbstractShellCommand {
44 protected void execute() { 44 protected void execute() {
45 DeviceService service = get(DeviceService.class); 45 DeviceService service = get(DeviceService.class);
46 if (outputJson()) { 46 if (outputJson()) {
47 - print("%s", json(service, getSortedDevices(service))); 47 + print("%s", json(getSortedDevices(service)));
48 } else { 48 } else {
49 for (Device device : getSortedDevices(service)) { 49 for (Device device : getSortedDevices(service)) {
50 printDevice(service, device); 50 printDevice(service, device);
...@@ -55,40 +55,14 @@ public class DevicesListCommand extends AbstractShellCommand { ...@@ -55,40 +55,14 @@ public class DevicesListCommand extends AbstractShellCommand {
55 /** 55 /**
56 * Returns JSON node representing the specified devices. 56 * Returns JSON node representing the specified devices.
57 * 57 *
58 - * @param service device service
59 * @param devices collection of devices 58 * @param devices collection of devices
60 * @return JSON node 59 * @return JSON node
61 */ 60 */
62 - public static JsonNode json(DeviceService service, Iterable<Device> devices) { 61 + private JsonNode json(Iterable<Device> devices) {
63 ObjectMapper mapper = new ObjectMapper(); 62 ObjectMapper mapper = new ObjectMapper();
64 ArrayNode result = mapper.createArrayNode(); 63 ArrayNode result = mapper.createArrayNode();
65 for (Device device : devices) { 64 for (Device device : devices) {
66 - result.add(json(service, mapper, device)); 65 + result.add(jsonForEntity(device, Device.class));
67 - }
68 - return result;
69 - }
70 -
71 - /**
72 - * Returns JSON node representing the specified device.
73 - *
74 - * @param service device service
75 - * @param mapper object mapper
76 - * @param device infrastructure device
77 - * @return JSON node
78 - */
79 - public static ObjectNode json(DeviceService service, ObjectMapper mapper,
80 - Device device) {
81 - ObjectNode result = mapper.createObjectNode();
82 - if (device != null) {
83 - result.put("id", device.id().toString())
84 - .put("available", service.isAvailable(device.id()))
85 - .put("type", device.type().toString())
86 - .put("role", service.getRole(device.id()).toString())
87 - .put("mfr", device.manufacturer())
88 - .put("hw", device.hwVersion())
89 - .put("sw", device.swVersion())
90 - .put("serial", device.serialNumber())
91 - .set("annotations", annotations(mapper, device.annotations()));
92 } 66 }
93 return result; 67 return result;
94 } 68 }
......
...@@ -15,31 +15,28 @@ ...@@ -15,31 +15,28 @@
15 */ 15 */
16 package org.onosproject.cli.net; 16 package org.onosproject.cli.net;
17 17
18 -import com.fasterxml.jackson.databind.JsonNode; 18 +import java.util.Collections;
19 -import com.fasterxml.jackson.databind.ObjectMapper; 19 +import java.util.List;
20 -import com.fasterxml.jackson.databind.node.ArrayNode; 20 +import java.util.Map;
21 -import com.fasterxml.jackson.databind.node.ObjectNode; 21 +import java.util.SortedMap;
22 +import java.util.TreeMap;
22 23
23 import org.apache.karaf.shell.commands.Argument; 24 import org.apache.karaf.shell.commands.Argument;
24 import org.apache.karaf.shell.commands.Command; 25 import org.apache.karaf.shell.commands.Command;
25 -import org.onosproject.core.ApplicationId;
26 -import org.onosproject.core.CoreService;
27 import org.onosproject.cli.AbstractShellCommand; 26 import org.onosproject.cli.AbstractShellCommand;
28 import org.onosproject.cli.Comparators; 27 import org.onosproject.cli.Comparators;
28 +import org.onosproject.core.CoreService;
29 import org.onosproject.net.Device; 29 import org.onosproject.net.Device;
30 import org.onosproject.net.DeviceId; 30 import org.onosproject.net.DeviceId;
31 import org.onosproject.net.device.DeviceService; 31 import org.onosproject.net.device.DeviceService;
32 import org.onosproject.net.flow.FlowEntry; 32 import org.onosproject.net.flow.FlowEntry;
33 import org.onosproject.net.flow.FlowEntry.FlowEntryState; 33 import org.onosproject.net.flow.FlowEntry.FlowEntryState;
34 import org.onosproject.net.flow.FlowRuleService; 34 import org.onosproject.net.flow.FlowRuleService;
35 -import org.onosproject.net.flow.criteria.Criterion;
36 -import org.onosproject.net.flow.instructions.Instruction;
37 35
38 -import java.util.Collections; 36 +import com.fasterxml.jackson.databind.JsonNode;
39 -import java.util.List; 37 +import com.fasterxml.jackson.databind.ObjectMapper;
40 -import java.util.Map; 38 +import com.fasterxml.jackson.databind.node.ArrayNode;
41 -import java.util.SortedMap; 39 +import com.fasterxml.jackson.databind.node.ObjectNode;
42 -import java.util.TreeMap;
43 40
44 import static com.google.common.collect.Lists.newArrayList; 41 import static com.google.common.collect.Lists.newArrayList;
45 42
...@@ -73,7 +70,7 @@ public class FlowsListCommand extends AbstractShellCommand { ...@@ -73,7 +70,7 @@ public class FlowsListCommand extends AbstractShellCommand {
73 SortedMap<Device, List<FlowEntry>> flows = getSortedFlows(deviceService, service); 70 SortedMap<Device, List<FlowEntry>> flows = getSortedFlows(deviceService, service);
74 71
75 if (outputJson()) { 72 if (outputJson()) {
76 - print("%s", json(coreService, flows.keySet(), flows)); 73 + print("%s", json(flows.keySet(), flows));
77 } else { 74 } else {
78 flows.forEach((device, flow) -> printFlows(device, flow, coreService)); 75 flows.forEach((device, flow) -> printFlows(device, flow, coreService));
79 } 76 }
...@@ -82,30 +79,27 @@ public class FlowsListCommand extends AbstractShellCommand { ...@@ -82,30 +79,27 @@ public class FlowsListCommand extends AbstractShellCommand {
82 /** 79 /**
83 * Produces a JSON array of flows grouped by the each device. 80 * Produces a JSON array of flows grouped by the each device.
84 * 81 *
85 - * @param coreService core service
86 * @param devices collection of devices to group flow by 82 * @param devices collection of devices to group flow by
87 * @param flows collection of flows per each device 83 * @param flows collection of flows per each device
88 * @return JSON array 84 * @return JSON array
89 */ 85 */
90 - private JsonNode json(CoreService coreService, Iterable<Device> devices, 86 + private JsonNode json(Iterable<Device> devices,
91 Map<Device, List<FlowEntry>> flows) { 87 Map<Device, List<FlowEntry>> flows) {
92 ObjectMapper mapper = new ObjectMapper(); 88 ObjectMapper mapper = new ObjectMapper();
93 ArrayNode result = mapper.createArrayNode(); 89 ArrayNode result = mapper.createArrayNode();
94 for (Device device : devices) { 90 for (Device device : devices) {
95 - result.add(json(coreService, mapper, device, flows.get(device))); 91 + result.add(json(mapper, device, flows.get(device)));
96 } 92 }
97 return result; 93 return result;
98 } 94 }
99 95
100 // Produces JSON object with the flows of the given device. 96 // Produces JSON object with the flows of the given device.
101 - private ObjectNode json(CoreService coreService, ObjectMapper mapper, 97 + private ObjectNode json(ObjectMapper mapper,
102 Device device, List<FlowEntry> flows) { 98 Device device, List<FlowEntry> flows) {
103 ObjectNode result = mapper.createObjectNode(); 99 ObjectNode result = mapper.createObjectNode();
104 ArrayNode array = mapper.createArrayNode(); 100 ArrayNode array = mapper.createArrayNode();
105 101
106 - for (FlowEntry flow : flows) { 102 + flows.forEach(flow -> array.add(jsonForEntity(flow, FlowEntry.class)));
107 - array.add(json(coreService, mapper, flow));
108 - }
109 103
110 result.put("device", device.id().toString()) 104 result.put("device", device.id().toString())
111 .put("flowCount", flows.size()) 105 .put("flowCount", flows.size())
...@@ -113,37 +107,6 @@ public class FlowsListCommand extends AbstractShellCommand { ...@@ -113,37 +107,6 @@ public class FlowsListCommand extends AbstractShellCommand {
113 return result; 107 return result;
114 } 108 }
115 109
116 - // Produces JSON structure with the specified flow data.
117 - private ObjectNode json(CoreService coreService, ObjectMapper mapper,
118 - FlowEntry flow) {
119 - ObjectNode result = mapper.createObjectNode();
120 - ArrayNode crit = mapper.createArrayNode();
121 - for (Criterion c : flow.selector().criteria()) {
122 - crit.add(c.toString());
123 - }
124 -
125 - ArrayNode instr = mapper.createArrayNode();
126 - for (Instruction i : flow.treatment().allInstructions()) {
127 - instr.add(i.toString());
128 - }
129 -
130 - ApplicationId appCoreId = coreService.getAppId(flow.appId());
131 - String appName = appCoreId == null ?
132 - Short.toString(flow.appId())
133 - : appCoreId.name();
134 -
135 - result.put("flowId", Long.toHexString(flow.id().value()))
136 - .put("state", flow.state().toString())
137 - .put("bytes", flow.bytes())
138 - .put("packets", flow.packets())
139 - .put("life", flow.life())
140 - .put("tableId", flow.tableId())
141 - .put("appId", appName);
142 - result.set("selector", crit);
143 - result.set("treatment", instr);
144 - return result;
145 - }
146 -
147 /** 110 /**
148 * Returns the list of devices sorted using the device ID URIs. 111 * Returns the list of devices sorted using the device ID URIs.
149 * 112 *
......
...@@ -15,19 +15,18 @@ ...@@ -15,19 +15,18 @@
15 */ 15 */
16 package org.onosproject.cli.net; 16 package org.onosproject.cli.net;
17 17
18 -import com.fasterxml.jackson.databind.JsonNode; 18 +import java.util.Collections;
19 -import com.fasterxml.jackson.databind.ObjectMapper; 19 +import java.util.List;
20 -import com.fasterxml.jackson.databind.node.ArrayNode; 20 +
21 -import com.fasterxml.jackson.databind.node.ObjectNode;
22 import org.apache.karaf.shell.commands.Command; 21 import org.apache.karaf.shell.commands.Command;
23 import org.onosproject.cli.AbstractShellCommand; 22 import org.onosproject.cli.AbstractShellCommand;
24 import org.onosproject.cli.Comparators; 23 import org.onosproject.cli.Comparators;
25 import org.onosproject.net.Host; 24 import org.onosproject.net.Host;
26 import org.onosproject.net.host.HostService; 25 import org.onosproject.net.host.HostService;
27 -import org.onlab.packet.IpAddress;
28 26
29 -import java.util.Collections; 27 +import com.fasterxml.jackson.databind.JsonNode;
30 -import java.util.List; 28 +import com.fasterxml.jackson.databind.ObjectMapper;
29 +import com.fasterxml.jackson.databind.node.ArrayNode;
31 30
32 import static com.google.common.collect.Lists.newArrayList; 31 import static com.google.common.collect.Lists.newArrayList;
33 32
...@@ -54,30 +53,11 @@ public class HostsListCommand extends AbstractShellCommand { ...@@ -54,30 +53,11 @@ public class HostsListCommand extends AbstractShellCommand {
54 } 53 }
55 54
56 // Produces JSON structure. 55 // Produces JSON structure.
57 - private static JsonNode json(Iterable<Host> hosts) { 56 + private JsonNode json(Iterable<Host> hosts) {
58 ObjectMapper mapper = new ObjectMapper(); 57 ObjectMapper mapper = new ObjectMapper();
59 ArrayNode result = mapper.createArrayNode(); 58 ArrayNode result = mapper.createArrayNode();
60 - for (Host host : hosts) {
61 - result.add(json(mapper, host));
62 - }
63 - return result;
64 - }
65 59
66 - // Produces JSON structure. 60 + hosts.forEach(host -> result.add(jsonForEntity(host, Host.class)));
67 - private static JsonNode json(ObjectMapper mapper, Host host) {
68 - ObjectNode loc = LinksListCommand.json(mapper, host.location())
69 - .put("time", host.location().time());
70 - ArrayNode ips = mapper.createArrayNode();
71 - for (IpAddress ip : host.ipAddresses()) {
72 - ips.add(ip.toString());
73 - }
74 - ObjectNode result = mapper.createObjectNode()
75 - .put("id", host.id().toString())
76 - .put("mac", host.mac().toString())
77 - .put("vlan", host.vlan().toString());
78 - result.set("location", loc);
79 - result.set("ips", ips);
80 - result.set("annotations", annotations(mapper, host.annotations()));
81 return result; 61 return result;
82 } 62 }
83 63
......
...@@ -15,16 +15,11 @@ ...@@ -15,16 +15,11 @@
15 */ 15 */
16 package org.onosproject.cli.net; 16 package org.onosproject.cli.net;
17 17
18 -import com.fasterxml.jackson.databind.JsonNode; 18 +import java.util.List;
19 -import com.fasterxml.jackson.databind.ObjectMapper; 19 +
20 -import com.fasterxml.jackson.databind.node.ArrayNode;
21 -import com.fasterxml.jackson.databind.node.ObjectNode;
22 import org.apache.karaf.shell.commands.Command; 20 import org.apache.karaf.shell.commands.Command;
23 import org.apache.karaf.shell.commands.Option; 21 import org.apache.karaf.shell.commands.Option;
24 import org.onosproject.cli.AbstractShellCommand; 22 import org.onosproject.cli.AbstractShellCommand;
25 -import org.onosproject.net.ConnectPoint;
26 -import org.onosproject.net.Link;
27 -import org.onosproject.net.NetworkResource;
28 import org.onosproject.net.intent.ConnectivityIntent; 23 import org.onosproject.net.intent.ConnectivityIntent;
29 import org.onosproject.net.intent.HostToHostIntent; 24 import org.onosproject.net.intent.HostToHostIntent;
30 import org.onosproject.net.intent.Intent; 25 import org.onosproject.net.intent.Intent;
...@@ -36,8 +31,10 @@ import org.onosproject.net.intent.PathIntent; ...@@ -36,8 +31,10 @@ import org.onosproject.net.intent.PathIntent;
36 import org.onosproject.net.intent.PointToPointIntent; 31 import org.onosproject.net.intent.PointToPointIntent;
37 import org.onosproject.net.intent.SinglePointToMultiPointIntent; 32 import org.onosproject.net.intent.SinglePointToMultiPointIntent;
38 33
39 -import java.util.List; 34 +import com.fasterxml.jackson.databind.JsonNode;
40 -import java.util.Set; 35 +import com.fasterxml.jackson.databind.ObjectMapper;
36 +import com.fasterxml.jackson.databind.node.ArrayNode;
37 +import com.fasterxml.jackson.databind.node.ObjectNode;
41 38
42 /** 39 /**
43 * Lists the inventory of intents and their states. 40 * Lists the inventory of intents and their states.
...@@ -393,81 +390,9 @@ public class IntentsListCommand extends AbstractShellCommand { ...@@ -393,81 +390,9 @@ public class IntentsListCommand extends AbstractShellCommand {
393 private JsonNode json(IntentService service, Iterable<Intent> intents) { 390 private JsonNode json(IntentService service, Iterable<Intent> intents) {
394 ObjectMapper mapper = new ObjectMapper(); 391 ObjectMapper mapper = new ObjectMapper();
395 ArrayNode result = mapper.createArrayNode(); 392 ArrayNode result = mapper.createArrayNode();
396 - for (Intent intent : intents) {
397 - result.add(json(service, mapper, intent));
398 - }
399 - return result;
400 - }
401 -
402 - private JsonNode json(IntentService service, ObjectMapper mapper, Intent intent) {
403 - ObjectNode result = mapper.createObjectNode()
404 - .put("id", intent.id().toString())
405 - .put("type", intent.getClass().getSimpleName())
406 - .put("appId", intent.appId().name());
407 -
408 - IntentState state = service.getIntentState(intent.key());
409 - if (state != null) {
410 - result.put("state", state.toString());
411 - }
412 393
413 - if (!intent.resources().isEmpty()) { 394 + intents.forEach(intent -> result.add(jsonForEntity(intent, Intent.class)));
414 - ArrayNode rnode = mapper.createArrayNode();
415 - for (NetworkResource resource : intent.resources()) {
416 - rnode.add(resource.toString());
417 - }
418 - result.set("resources", rnode);
419 - }
420 -
421 - if (intent instanceof ConnectivityIntent) {
422 - ConnectivityIntent ci = (ConnectivityIntent) intent;
423 - if (!ci.selector().criteria().isEmpty()) {
424 - result.put("selector", ci.selector().criteria().toString());
425 - }
426 - if (!ci.treatment().allInstructions().isEmpty()) {
427 - result.put("treatment", ci.treatment().allInstructions().toString());
428 - }
429 - }
430 -
431 - if (intent instanceof PathIntent) {
432 - PathIntent pi = (PathIntent) intent;
433 - ArrayNode pnode = mapper.createArrayNode();
434 - for (Link link : pi.path().links()) {
435 - pnode.add(link.toString());
436 - }
437 - result.set("path", pnode);
438 - } else if (intent instanceof HostToHostIntent) {
439 - HostToHostIntent pi = (HostToHostIntent) intent;
440 - result.set("host1", LinksListCommand.json(mapper, pi.one()));
441 - result.set("host2", LinksListCommand.json(mapper, pi.two()));
442 - } else if (intent instanceof PointToPointIntent) {
443 - PointToPointIntent pi = (PointToPointIntent) intent;
444 - result.set("ingress", LinksListCommand.json(mapper, pi.ingressPoint()));
445 - result.set("egress", LinksListCommand.json(mapper, pi.egressPoint()));
446 - } else if (intent instanceof MultiPointToSinglePointIntent) {
447 - MultiPointToSinglePointIntent pi = (MultiPointToSinglePointIntent) intent;
448 - result.set("ingress", json(mapper, pi.ingressPoints()));
449 - result.set("egress", LinksListCommand.json(mapper, pi.egressPoint()));
450 - } else if (intent instanceof SinglePointToMultiPointIntent) {
451 - SinglePointToMultiPointIntent pi = (SinglePointToMultiPointIntent) intent;
452 - result.set("ingress", LinksListCommand.json(mapper, pi.ingressPoint()));
453 - result.set("egress", json(mapper, pi.egressPoints()));
454 - } else if (intent instanceof LinkCollectionIntent) {
455 - LinkCollectionIntent li = (LinkCollectionIntent) intent;
456 - result.set("links", LinksListCommand.json(li.links()));
457 - }
458 -
459 - List<Intent> installable = service.getInstallableIntents(intent.key());
460 - if (installable != null && !installable.isEmpty()) {
461 - result.set("installable", json(service, installable));
462 - }
463 return result; 395 return result;
464 } 396 }
465 397
466 - private JsonNode json(ObjectMapper mapper, Set<ConnectPoint> connectPoints) {
467 - ArrayNode result = mapper.createArrayNode();
468 - for (ConnectPoint cp : connectPoints) {
469 - result.add(LinksListCommand.json(mapper, cp));
470 - }
471 - return result;
472 - }
473 } 398 }
......
...@@ -15,18 +15,17 @@ ...@@ -15,18 +15,17 @@
15 */ 15 */
16 package org.onosproject.cli.net; 16 package org.onosproject.cli.net;
17 17
18 -import com.fasterxml.jackson.databind.JsonNode;
19 -import com.fasterxml.jackson.databind.ObjectMapper;
20 -import com.fasterxml.jackson.databind.node.ArrayNode;
21 -import com.fasterxml.jackson.databind.node.ObjectNode;
22 import org.apache.karaf.shell.commands.Argument; 18 import org.apache.karaf.shell.commands.Argument;
23 import org.apache.karaf.shell.commands.Command; 19 import org.apache.karaf.shell.commands.Command;
24 import org.onosproject.cli.AbstractShellCommand; 20 import org.onosproject.cli.AbstractShellCommand;
25 -import org.onosproject.net.ConnectPoint;
26 -import org.onosproject.net.HostId;
27 import org.onosproject.net.Link; 21 import org.onosproject.net.Link;
28 import org.onosproject.net.link.LinkService; 22 import org.onosproject.net.link.LinkService;
29 23
24 +import com.fasterxml.jackson.databind.JsonNode;
25 +import com.fasterxml.jackson.databind.ObjectMapper;
26 +import com.fasterxml.jackson.databind.node.ArrayNode;
27 +import com.fasterxml.jackson.databind.node.ObjectNode;
28 +
30 import static org.onosproject.net.DeviceId.deviceId; 29 import static org.onosproject.net.DeviceId.deviceId;
31 30
32 /** 31 /**
...@@ -49,7 +48,7 @@ public class LinksListCommand extends AbstractShellCommand { ...@@ -49,7 +48,7 @@ public class LinksListCommand extends AbstractShellCommand {
49 Iterable<Link> links = uri != null ? 48 Iterable<Link> links = uri != null ?
50 service.getDeviceLinks(deviceId(uri)) : service.getLinks(); 49 service.getDeviceLinks(deviceId(uri)) : service.getLinks();
51 if (outputJson()) { 50 if (outputJson()) {
52 - print("%s", json(links)); 51 + print("%s", json(this, links));
53 } else { 52 } else {
54 for (Link link : links) { 53 for (Link link : links) {
55 print(linkString(link)); 54 print(linkString(link));
...@@ -60,59 +59,28 @@ public class LinksListCommand extends AbstractShellCommand { ...@@ -60,59 +59,28 @@ public class LinksListCommand extends AbstractShellCommand {
60 /** 59 /**
61 * Produces a JSON array containing the specified links. 60 * Produces a JSON array containing the specified links.
62 * 61 *
62 + * @param context context to use for looking up codecs
63 * @param links collection of links 63 * @param links collection of links
64 * @return JSON array 64 * @return JSON array
65 */ 65 */
66 - public static JsonNode json(Iterable<Link> links) { 66 + public static JsonNode json(AbstractShellCommand context, Iterable<Link> links) {
67 ObjectMapper mapper = new ObjectMapper(); 67 ObjectMapper mapper = new ObjectMapper();
68 ArrayNode result = mapper.createArrayNode(); 68 ArrayNode result = mapper.createArrayNode();
69 - for (Link link : links) { 69 +
70 - result.add(json(mapper, link)); 70 + links.forEach(link -> result.add(context.jsonForEntity(link, Link.class)));
71 - } 71 +
72 return result; 72 return result;
73 } 73 }
74 74
75 /** 75 /**
76 * Produces a JSON object for the specified link. 76 * Produces a JSON object for the specified link.
77 * 77 *
78 - * @param mapper object mapper 78 + * @param context context to use for looking up codecs
79 * @param link link to encode 79 * @param link link to encode
80 * @return JSON object 80 * @return JSON object
81 */ 81 */
82 - public static ObjectNode json(ObjectMapper mapper, Link link) { 82 + public static ObjectNode json(AbstractShellCommand context, Link link) {
83 - ObjectNode result = mapper.createObjectNode(); 83 + return context.jsonForEntity(link, Link.class);
84 - result.set("src", json(mapper, link.src()));
85 - result.set("dst", json(mapper, link.dst()));
86 - result.put("type", link.type().toString());
87 - result.put("state", link.state().toString());
88 - result.set("annotations", annotations(mapper, link.annotations()));
89 - return result;
90 - }
91 -
92 - /**
93 - * Produces a JSON object for the specified host ID.
94 - *
95 - * @param mapper object mapper
96 - * @param hostId host ID to encode
97 - * @return JSON object
98 - */
99 - public static ObjectNode json(ObjectMapper mapper, HostId hostId) {
100 - return mapper.createObjectNode()
101 - .put("mac", hostId.mac().toString())
102 - .put("vlanId", hostId.vlanId().toString());
103 - }
104 -
105 - /**
106 - * Produces a JSON object for the specified connect point.
107 - *
108 - * @param mapper object mapper
109 - * @param connectPoint connection point to encode
110 - * @return JSON object
111 - */
112 - public static ObjectNode json(ObjectMapper mapper, ConnectPoint connectPoint) {
113 - return mapper.createObjectNode()
114 - .put("device", connectPoint.deviceId().toString())
115 - .put("port", connectPoint.port().toString());
116 } 84 }
117 85
118 /** 86 /**
......
...@@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; ...@@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
20 import com.fasterxml.jackson.databind.node.ArrayNode; 20 import com.fasterxml.jackson.databind.node.ArrayNode;
21 import org.apache.karaf.shell.commands.Argument; 21 import org.apache.karaf.shell.commands.Argument;
22 import org.apache.karaf.shell.commands.Command; 22 import org.apache.karaf.shell.commands.Command;
23 +import org.onosproject.cli.AbstractShellCommand;
23 import org.onosproject.net.Link; 24 import org.onosproject.net.Link;
24 import org.onosproject.net.Path; 25 import org.onosproject.net.Path;
25 26
...@@ -51,7 +52,7 @@ public class PathListCommand extends TopologyCommand { ...@@ -51,7 +52,7 @@ public class PathListCommand extends TopologyCommand {
51 init(); 52 init();
52 Set<Path> paths = service.getPaths(topology, deviceId(src), deviceId(dst)); 53 Set<Path> paths = service.getPaths(topology, deviceId(src), deviceId(dst));
53 if (outputJson()) { 54 if (outputJson()) {
54 - print("%s", json(paths)); 55 + print("%s", json(this, paths));
55 } else { 56 } else {
56 for (Path path : paths) { 57 for (Path path : paths) {
57 print(pathString(path)); 58 print(pathString(path));
...@@ -62,16 +63,17 @@ public class PathListCommand extends TopologyCommand { ...@@ -62,16 +63,17 @@ public class PathListCommand extends TopologyCommand {
62 /** 63 /**
63 * Produces a JSON array containing the specified paths. 64 * Produces a JSON array containing the specified paths.
64 * 65 *
66 + * @param context context to use for looking up codecs
65 * @param paths collection of paths 67 * @param paths collection of paths
66 * @return JSON array 68 * @return JSON array
67 */ 69 */
68 - public static JsonNode json(Iterable<Path> paths) { 70 + public static JsonNode json(AbstractShellCommand context, Iterable<Path> paths) {
69 ObjectMapper mapper = new ObjectMapper(); 71 ObjectMapper mapper = new ObjectMapper();
70 ArrayNode result = mapper.createArrayNode(); 72 ArrayNode result = mapper.createArrayNode();
71 for (Path path : paths) { 73 for (Path path : paths) {
72 - result.add(LinksListCommand.json(mapper, path) 74 + result.add(LinksListCommand.json(context, path)
73 .put("cost", path.cost()) 75 .put("cost", path.cost())
74 - .set("links", LinksListCommand.json(path.links()))); 76 + .set("links", LinksListCommand.json(context, path.links())));
75 } 77 }
76 return result; 78 return result;
77 } 79 }
......
...@@ -27,8 +27,6 @@ import org.onosproject.net.topology.Topology; ...@@ -27,8 +27,6 @@ import org.onosproject.net.topology.Topology;
27 import org.onosproject.net.topology.TopologyProvider; 27 import org.onosproject.net.topology.TopologyProvider;
28 import org.onosproject.net.topology.TopologyService; 28 import org.onosproject.net.topology.TopologyService;
29 29
30 -import com.fasterxml.jackson.databind.ObjectMapper;
31 -
32 /** 30 /**
33 * Lists summary of the current topology. 31 * Lists summary of the current topology.
34 */ 32 */
...@@ -64,14 +62,7 @@ public class TopologyCommand extends AbstractShellCommand { ...@@ -64,14 +62,7 @@ public class TopologyCommand extends AbstractShellCommand {
64 62
65 } else if (outputJson()) { 63 } else if (outputJson()) {
66 print("%s", 64 print("%s",
67 - new ObjectMapper() 65 + jsonForEntity(topology, Topology.class));
68 - .createObjectNode()
69 - .put("time", topology.time())
70 - .put("created", formatCreationTime(topology.creationTime()))
71 - .put("uptime", formatElapsedTime(topologyUptime))
72 - .put("deviceCount", topology.deviceCount())
73 - .put("linkCount", topology.linkCount())
74 - .put("clusterCount", topology.clusterCount()));
75 } else { 66 } else {
76 print(FMT, formatCreationTime(topology.creationTime()), 67 print(FMT, formatCreationTime(topology.creationTime()),
77 formatElapsedTime(topologyUptime), 68 formatElapsedTime(topologyUptime),
......
...@@ -45,6 +45,6 @@ public interface CodecContext { ...@@ -45,6 +45,6 @@ public interface CodecContext {
45 * @param <T> service type 45 * @param <T> service type
46 * @return JSON codec; null if no codec available for the class 46 * @return JSON codec; null if no codec available for the class
47 */ 47 */
48 - <T> T get(Class<T> serviceClass); 48 + <T> T getService(Class<T> serviceClass);
49 49
50 } 50 }
......
...@@ -60,4 +60,9 @@ public class AbstractWebResource extends BaseResource implements CodecContext { ...@@ -60,4 +60,9 @@ public class AbstractWebResource extends BaseResource implements CodecContext {
60 return result; 60 return result;
61 } 61 }
62 62
63 + @Override
64 + public <T> T getService(Class<T> serviceClass) {
65 + return get(serviceClass);
66 + }
67 +
63 } 68 }
......
...@@ -92,7 +92,7 @@ public class JsonCodecTest { ...@@ -92,7 +92,7 @@ public class JsonCodecTest {
92 } 92 }
93 93
94 @Override 94 @Override
95 - public <T> T get(Class<T> serviceClass) { 95 + public <T> T getService(Class<T> serviceClass) {
96 return null; 96 return null;
97 } 97 }
98 } 98 }
......
...@@ -31,7 +31,7 @@ public final class ApplicationCodec extends JsonCodec<Application> { ...@@ -31,7 +31,7 @@ public final class ApplicationCodec extends JsonCodec<Application> {
31 @Override 31 @Override
32 public ObjectNode encode(Application app, CodecContext context) { 32 public ObjectNode encode(Application app, CodecContext context) {
33 checkNotNull(app, "Application cannot be null"); 33 checkNotNull(app, "Application cannot be null");
34 - ApplicationService service = context.get(ApplicationService.class); 34 + ApplicationService service = context.getService(ApplicationService.class);
35 ObjectNode result = context.mapper().createObjectNode() 35 ObjectNode result = context.mapper().createObjectNode()
36 .put("name", app.id().name()) 36 .put("name", app.id().name())
37 .put("id", app.id().id()) 37 .put("id", app.id().id())
......
...@@ -35,7 +35,7 @@ public final class ControllerNodeCodec extends JsonCodec<ControllerNode> { ...@@ -35,7 +35,7 @@ public final class ControllerNodeCodec extends JsonCodec<ControllerNode> {
35 @Override 35 @Override
36 public ObjectNode encode(ControllerNode node, CodecContext context) { 36 public ObjectNode encode(ControllerNode node, CodecContext context) {
37 checkNotNull(node, "Controller node cannot be null"); 37 checkNotNull(node, "Controller node cannot be null");
38 - ClusterService service = context.get(ClusterService.class); 38 + ClusterService service = context.getService(ClusterService.class);
39 return context.mapper().createObjectNode() 39 return context.mapper().createObjectNode()
40 .put("id", node.id().toString()) 40 .put("id", node.id().toString())
41 .put("ip", node.ip().toString()) 41 .put("ip", node.ip().toString())
......
...@@ -48,7 +48,7 @@ public final class DeviceCodec extends AnnotatedCodec<Device> { ...@@ -48,7 +48,7 @@ public final class DeviceCodec extends AnnotatedCodec<Device> {
48 @Override 48 @Override
49 public ObjectNode encode(Device device, CodecContext context) { 49 public ObjectNode encode(Device device, CodecContext context) {
50 checkNotNull(device, "Device cannot be null"); 50 checkNotNull(device, "Device cannot be null");
51 - DeviceService service = context.get(DeviceService.class); 51 + DeviceService service = context.getService(DeviceService.class);
52 ObjectNode result = context.mapper().createObjectNode() 52 ObjectNode result = context.mapper().createObjectNode()
53 .put(ID, device.id().toString()) 53 .put(ID, device.id().toString())
54 .put(TYPE, device.type().name()) 54 .put(TYPE, device.type().name())
......
...@@ -37,6 +37,7 @@ public final class LinkCodec extends AnnotatedCodec<Link> { ...@@ -37,6 +37,7 @@ public final class LinkCodec extends AnnotatedCodec<Link> {
37 private static final String SRC = "src"; 37 private static final String SRC = "src";
38 private static final String DST = "dst"; 38 private static final String DST = "dst";
39 private static final String TYPE = "type"; 39 private static final String TYPE = "type";
40 + private static final String STATE = "state";
40 41
41 @Override 42 @Override
42 public ObjectNode encode(Link link, CodecContext context) { 43 public ObjectNode encode(Link link, CodecContext context) {
...@@ -46,6 +47,9 @@ public final class LinkCodec extends AnnotatedCodec<Link> { ...@@ -46,6 +47,9 @@ public final class LinkCodec extends AnnotatedCodec<Link> {
46 result.set(SRC, codec.encode(link.src(), context)); 47 result.set(SRC, codec.encode(link.src(), context));
47 result.set(DST, codec.encode(link.dst(), context)); 48 result.set(DST, codec.encode(link.dst(), context));
48 result.put(TYPE, link.type().toString()); 49 result.put(TYPE, link.type().toString());
50 + if (link.state() != null) {
51 + result.put(STATE, link.state().toString());
52 + }
49 return annotate(result, link, context); 53 return annotate(result, link, context);
50 } 54 }
51 55
......
...@@ -52,7 +52,7 @@ public class MockCodecContext implements CodecContext { ...@@ -52,7 +52,7 @@ public class MockCodecContext implements CodecContext {
52 52
53 @SuppressWarnings("unchecked") 53 @SuppressWarnings("unchecked")
54 @Override 54 @Override
55 - public <T> T get(Class<T> serviceClass) { 55 + public <T> T getService(Class<T> serviceClass) {
56 return (T) services.get(serviceClass); 56 return (T) services.get(serviceClass);
57 } 57 }
58 58
......
...@@ -67,7 +67,7 @@ public class ApplicationsResourceTest extends ResourceTest { ...@@ -67,7 +67,7 @@ public class ApplicationsResourceTest extends ResourceTest {
67 67
68 @Override 68 @Override
69 @SuppressWarnings("unchecked") 69 @SuppressWarnings("unchecked")
70 - public <T> T get(Class<T> serviceClass) { 70 + public <T> T getService(Class<T> serviceClass) {
71 return (T) service; 71 return (T) service;
72 } 72 }
73 } 73 }
......