HIGUCHI Yuta
Committed by Yuta HIGUCHI

Add support to decode Device, Port, Link JSON.

- Device, Port, Link can now be encoded and decoded back to Java Object,
  which will be Object#equals to the original.
- Modified DeviceServiceAdapter to be null-safe when possible
- Modified JSON assertion/matcher not to check for exact number of attributes

Change-Id: I7cf02e2254cf17f6265fb15847912519e564b14f
...@@ -17,12 +17,14 @@ package org.onosproject.net.device; ...@@ -17,12 +17,14 @@ package org.onosproject.net.device;
17 17
18 import com.google.common.base.Predicate; 18 import com.google.common.base.Predicate;
19 import com.google.common.collect.FluentIterable; 19 import com.google.common.collect.FluentIterable;
20 +
20 import org.onosproject.net.Device; 21 import org.onosproject.net.Device;
21 import org.onosproject.net.DeviceId; 22 import org.onosproject.net.DeviceId;
22 import org.onosproject.net.MastershipRole; 23 import org.onosproject.net.MastershipRole;
23 import org.onosproject.net.Port; 24 import org.onosproject.net.Port;
24 import org.onosproject.net.PortNumber; 25 import org.onosproject.net.PortNumber;
25 26
27 +import java.util.Collections;
26 import java.util.List; 28 import java.util.List;
27 29
28 /** 30 /**
...@@ -36,7 +38,7 @@ public class DeviceServiceAdapter implements DeviceService { ...@@ -36,7 +38,7 @@ public class DeviceServiceAdapter implements DeviceService {
36 38
37 @Override 39 @Override
38 public Iterable<Device> getDevices() { 40 public Iterable<Device> getDevices() {
39 - return null; 41 + return Collections.emptyList();
40 } 42 }
41 43
42 @Override 44 @Override
...@@ -58,12 +60,12 @@ public class DeviceServiceAdapter implements DeviceService { ...@@ -58,12 +60,12 @@ public class DeviceServiceAdapter implements DeviceService {
58 60
59 @Override 61 @Override
60 public MastershipRole getRole(DeviceId deviceId) { 62 public MastershipRole getRole(DeviceId deviceId) {
61 - return null; 63 + return MastershipRole.NONE;
62 } 64 }
63 65
64 @Override 66 @Override
65 public List<Port> getPorts(DeviceId deviceId) { 67 public List<Port> getPorts(DeviceId deviceId) {
66 - return null; 68 + return Collections.emptyList();
67 } 69 }
68 70
69 @Override 71 @Override
......
...@@ -16,10 +16,12 @@ ...@@ -16,10 +16,12 @@
16 package org.onosproject.codec.impl; 16 package org.onosproject.codec.impl;
17 17
18 import com.fasterxml.jackson.databind.node.ObjectNode; 18 import com.fasterxml.jackson.databind.node.ObjectNode;
19 +
19 import org.onosproject.codec.CodecContext; 20 import org.onosproject.codec.CodecContext;
20 import org.onosproject.codec.JsonCodec; 21 import org.onosproject.codec.JsonCodec;
21 import org.onosproject.net.Annotated; 22 import org.onosproject.net.Annotated;
22 import org.onosproject.net.Annotations; 23 import org.onosproject.net.Annotations;
24 +import org.onosproject.net.DefaultAnnotations;
23 25
24 /** 26 /**
25 * Base JSON codec for annotated entities. 27 * Base JSON codec for annotated entities.
...@@ -42,4 +44,21 @@ public abstract class AnnotatedCodec<T extends Annotated> extends JsonCodec<T> { ...@@ -42,4 +44,21 @@ public abstract class AnnotatedCodec<T extends Annotated> extends JsonCodec<T> {
42 return node; 44 return node;
43 } 45 }
44 46
47 + /**
48 + * Extracts annotations of given Object.
49 + *
50 + * @param objNode annotated JSON object node
51 + * @param context decode context
52 + * @return extracted Annotations
53 + */
54 + protected Annotations extractAnnotations(ObjectNode objNode, CodecContext context) {
55 +
56 + JsonCodec<Annotations> codec = context.codec(Annotations.class);
57 + if (objNode.has("annotations") && objNode.isObject()) {
58 + return codec.decode((ObjectNode) objNode.get("annotations"), context);
59 + } else {
60 + return DefaultAnnotations.EMPTY;
61 + }
62 + }
63 +
45 } 64 }
......
...@@ -16,9 +16,12 @@ ...@@ -16,9 +16,12 @@
16 package org.onosproject.codec.impl; 16 package org.onosproject.codec.impl;
17 17
18 import com.fasterxml.jackson.databind.node.ObjectNode; 18 import com.fasterxml.jackson.databind.node.ObjectNode;
19 +
19 import org.onosproject.codec.CodecContext; 20 import org.onosproject.codec.CodecContext;
20 import org.onosproject.codec.JsonCodec; 21 import org.onosproject.codec.JsonCodec;
21 import org.onosproject.net.Annotations; 22 import org.onosproject.net.Annotations;
23 +import org.onosproject.net.DefaultAnnotations;
24 +import org.onosproject.net.DefaultAnnotations.Builder;
22 25
23 /** 26 /**
24 * Annotations JSON codec. 27 * Annotations JSON codec.
...@@ -34,4 +37,13 @@ public final class AnnotationsCodec extends JsonCodec<Annotations> { ...@@ -34,4 +37,13 @@ public final class AnnotationsCodec extends JsonCodec<Annotations> {
34 return result; 37 return result;
35 } 38 }
36 39
40 + @Override
41 + public Annotations decode(ObjectNode json, CodecContext context) {
42 + Builder builder = DefaultAnnotations.builder();
43 +
44 + json.fields().forEachRemaining(e ->
45 + builder.set(e.getKey(), e.getValue().asText()));
46 +
47 + return builder.build();
48 + }
37 } 49 }
......
...@@ -16,32 +16,59 @@ ...@@ -16,32 +16,59 @@
16 package org.onosproject.codec.impl; 16 package org.onosproject.codec.impl;
17 17
18 import com.fasterxml.jackson.databind.node.ObjectNode; 18 import com.fasterxml.jackson.databind.node.ObjectNode;
19 +
19 import org.onosproject.codec.CodecContext; 20 import org.onosproject.codec.CodecContext;
20 import org.onosproject.codec.JsonCodec; 21 import org.onosproject.codec.JsonCodec;
21 import org.onosproject.net.ConnectPoint; 22 import org.onosproject.net.ConnectPoint;
22 import org.onosproject.net.DeviceId; 23 import org.onosproject.net.DeviceId;
24 +import org.onosproject.net.ElementId;
23 import org.onosproject.net.HostId; 25 import org.onosproject.net.HostId;
26 +import org.onosproject.net.PortNumber;
24 27
25 import static com.google.common.base.Preconditions.checkNotNull; 28 import static com.google.common.base.Preconditions.checkNotNull;
29 +import static org.onosproject.net.PortNumber.portNumber;
26 30
27 /** 31 /**
28 * Connection point JSON codec. 32 * Connection point JSON codec.
29 */ 33 */
30 public final class ConnectPointCodec extends JsonCodec<ConnectPoint> { 34 public final class ConnectPointCodec extends JsonCodec<ConnectPoint> {
31 35
36 + // JSON field names
37 + private static final String ELEMENT_HOST = "host";
38 + private static final String ELEMENT_DEVICE = "device";
39 + private static final String PORT = "port";
40 +
32 @Override 41 @Override
33 public ObjectNode encode(ConnectPoint point, CodecContext context) { 42 public ObjectNode encode(ConnectPoint point, CodecContext context) {
34 checkNotNull(point, "Connect point cannot be null"); 43 checkNotNull(point, "Connect point cannot be null");
35 ObjectNode root = context.mapper().createObjectNode() 44 ObjectNode root = context.mapper().createObjectNode()
36 - .put("port", point.port().toString()); 45 + .put(PORT, point.port().toString());
37 46
38 if (point.elementId() instanceof DeviceId) { 47 if (point.elementId() instanceof DeviceId) {
39 - root.put("device", point.deviceId().toString()); 48 + root.put(ELEMENT_DEVICE, point.deviceId().toString());
40 } else if (point.elementId() instanceof HostId) { 49 } else if (point.elementId() instanceof HostId) {
41 - root.put("host", point.hostId().toString()); 50 + root.put(ELEMENT_HOST, point.hostId().toString());
42 } 51 }
43 52
44 return root; 53 return root;
45 } 54 }
46 55
56 + @Override
57 + public ConnectPoint decode(ObjectNode json, CodecContext context) {
58 + if (json == null || !json.isObject()) {
59 + return null;
60 + }
61 +
62 + ElementId elementId;
63 + if (json.has(ELEMENT_DEVICE)) {
64 + elementId = DeviceId.deviceId(json.get(ELEMENT_DEVICE).asText());
65 + } else if (json.has(ELEMENT_HOST)) {
66 + elementId = HostId.hostId(json.get(ELEMENT_HOST).asText());
67 + } else {
68 + // invalid JSON
69 + return null;
70 + }
71 + PortNumber portNumber = portNumber(json.get(PORT).asText());
72 + return new ConnectPoint(elementId, portNumber);
73 + }
47 } 74 }
......
...@@ -16,32 +16,78 @@ ...@@ -16,32 +16,78 @@
16 package org.onosproject.codec.impl; 16 package org.onosproject.codec.impl;
17 17
18 import com.fasterxml.jackson.databind.node.ObjectNode; 18 import com.fasterxml.jackson.databind.node.ObjectNode;
19 +
20 +import org.onlab.packet.ChassisId;
19 import org.onosproject.codec.CodecContext; 21 import org.onosproject.codec.CodecContext;
22 +import org.onosproject.net.Annotations;
23 +import org.onosproject.net.DefaultDevice;
20 import org.onosproject.net.Device; 24 import org.onosproject.net.Device;
25 +import org.onosproject.net.Device.Type;
26 +import org.onosproject.net.DeviceId;
21 import org.onosproject.net.device.DeviceService; 27 import org.onosproject.net.device.DeviceService;
28 +import org.onosproject.net.provider.ProviderId;
22 29
23 import static com.google.common.base.Preconditions.checkNotNull; 30 import static com.google.common.base.Preconditions.checkNotNull;
31 +import static org.onosproject.net.DeviceId.deviceId;
24 32
25 /** 33 /**
26 * Device JSON codec. 34 * Device JSON codec.
27 */ 35 */
28 public final class DeviceCodec extends AnnotatedCodec<Device> { 36 public final class DeviceCodec extends AnnotatedCodec<Device> {
29 37
38 + // JSON fieldNames
39 + private static final String ID = "id";
40 + private static final String TYPE = "type";
41 + private static final String MFR = "mfr";
42 + private static final String HW = "hw";
43 + private static final String SW = "sw";
44 + private static final String SERIAL = "serial";
45 + private static final String CHASSIS_ID = "chassisId";
46 +
47 +
30 @Override 48 @Override
31 public ObjectNode encode(Device device, CodecContext context) { 49 public ObjectNode encode(Device device, CodecContext context) {
32 checkNotNull(device, "Device cannot be null"); 50 checkNotNull(device, "Device cannot be null");
33 DeviceService service = context.get(DeviceService.class); 51 DeviceService service = context.get(DeviceService.class);
34 ObjectNode result = context.mapper().createObjectNode() 52 ObjectNode result = context.mapper().createObjectNode()
35 - .put("id", device.id().toString()) 53 + .put(ID, device.id().toString())
36 - .put("type", device.type().name()) 54 + .put(TYPE, device.type().name())
37 .put("available", service.isAvailable(device.id())) 55 .put("available", service.isAvailable(device.id()))
38 .put("role", service.getRole(device.id()).toString()) 56 .put("role", service.getRole(device.id()).toString())
39 - .put("mfr", device.manufacturer()) 57 + .put(MFR, device.manufacturer())
40 - .put("hw", device.hwVersion()) 58 + .put(HW, device.hwVersion())
41 - .put("sw", device.swVersion()) 59 + .put(SW, device.swVersion())
42 - .put("serial", device.serialNumber()) 60 + .put(SERIAL, device.serialNumber())
43 - .put("chassisId", device.chassisId().toString()); 61 + .put(CHASSIS_ID, device.chassisId().toString());
44 return annotate(result, device, context); 62 return annotate(result, device, context);
45 } 63 }
46 64
65 +
66 + /**
67 + * {@inheritDoc}
68 + *
69 + * Note: ProviderId is not part of JSON representation.
70 + * Returned object will have random ProviderId set.
71 + */
72 + @Override
73 + public Device decode(ObjectNode json, CodecContext context) {
74 + if (json == null || !json.isObject()) {
75 + return null;
76 + }
77 +
78 + DeviceId id = deviceId(json.get(ID).asText());
79 + // TODO: add providerId to JSON if we need to recover them.
80 + ProviderId pid = new ProviderId(id.uri().getScheme(), "DeviceCodec");
81 +
82 + Type type = Type.valueOf(json.get(TYPE).asText());
83 + String mfr = json.get(MFR).asText();
84 + String hw = json.get(HW).asText();
85 + String sw = json.get(SW).asText();
86 + String serial = json.get(SERIAL).asText();
87 + ChassisId chassisId = new ChassisId(json.get(CHASSIS_ID).asText());
88 + Annotations annotations = extractAnnotations(json, context);
89 +
90 + return new DefaultDevice(pid, id, type, mfr, hw, sw, serial,
91 + chassisId, annotations);
92 + }
47 } 93 }
......
...@@ -16,11 +16,15 @@ ...@@ -16,11 +16,15 @@
16 package org.onosproject.codec.impl; 16 package org.onosproject.codec.impl;
17 17
18 import com.fasterxml.jackson.databind.node.ObjectNode; 18 import com.fasterxml.jackson.databind.node.ObjectNode;
19 +
19 import org.onosproject.codec.CodecContext; 20 import org.onosproject.codec.CodecContext;
20 import org.onosproject.codec.JsonCodec; 21 import org.onosproject.codec.JsonCodec;
22 +import org.onosproject.net.Annotations;
21 import org.onosproject.net.ConnectPoint; 23 import org.onosproject.net.ConnectPoint;
24 +import org.onosproject.net.DefaultLink;
22 import org.onosproject.net.Link; 25 import org.onosproject.net.Link;
23 -import org.onosproject.net.device.DeviceService; 26 +import org.onosproject.net.Link.Type;
27 +import org.onosproject.net.provider.ProviderId;
24 28
25 import static com.google.common.base.Preconditions.checkNotNull; 29 import static com.google.common.base.Preconditions.checkNotNull;
26 30
...@@ -29,15 +33,44 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -29,15 +33,44 @@ import static com.google.common.base.Preconditions.checkNotNull;
29 */ 33 */
30 public final class LinkCodec extends AnnotatedCodec<Link> { 34 public final class LinkCodec extends AnnotatedCodec<Link> {
31 35
36 + // JSON field names
37 + private static final String SRC = "src";
38 + private static final String DST = "dst";
39 + private static final String TYPE = "type";
40 +
32 @Override 41 @Override
33 public ObjectNode encode(Link link, CodecContext context) { 42 public ObjectNode encode(Link link, CodecContext context) {
34 checkNotNull(link, "Link cannot be null"); 43 checkNotNull(link, "Link cannot be null");
35 - DeviceService service = context.get(DeviceService.class);
36 JsonCodec<ConnectPoint> codec = context.codec(ConnectPoint.class); 44 JsonCodec<ConnectPoint> codec = context.codec(ConnectPoint.class);
37 ObjectNode result = context.mapper().createObjectNode(); 45 ObjectNode result = context.mapper().createObjectNode();
38 - result.set("src", codec.encode(link.src(), context)); 46 + result.set(SRC, codec.encode(link.src(), context));
39 - result.set("dst", codec.encode(link.dst(), context)); 47 + result.set(DST, codec.encode(link.dst(), context));
48 + result.put(TYPE, link.type().toString());
40 return annotate(result, link, context); 49 return annotate(result, link, context);
41 } 50 }
42 51
52 +
53 + /**
54 + * {@inheritDoc}
55 + *
56 + * Note: ProviderId is not part of JSON representation.
57 + * Returned object will have random ProviderId set.
58 + */
59 + @Override
60 + public Link decode(ObjectNode json, CodecContext context) {
61 + if (json == null || !json.isObject()) {
62 + return null;
63 + }
64 +
65 + JsonCodec<ConnectPoint> codec = context.codec(ConnectPoint.class);
66 + // TODO: add providerId to JSON if we need to recover them.
67 + ProviderId pid = new ProviderId("json", "LinkCodec");
68 +
69 + ConnectPoint src = codec.decode((ObjectNode) json.get(SRC), context);
70 + ConnectPoint dst = codec.decode((ObjectNode) json.get(DST), context);
71 + Type type = Type.valueOf(json.get(TYPE).asText());
72 + Annotations annotations = extractAnnotations(json, context);
73 +
74 + return new DefaultLink(pid, src, dst, type, annotations);
75 + }
43 } 76 }
......
...@@ -16,9 +16,18 @@ ...@@ -16,9 +16,18 @@
16 package org.onosproject.codec.impl; 16 package org.onosproject.codec.impl;
17 17
18 import com.fasterxml.jackson.databind.node.ObjectNode; 18 import com.fasterxml.jackson.databind.node.ObjectNode;
19 +
20 +import org.onlab.packet.ChassisId;
19 import org.onosproject.codec.CodecContext; 21 import org.onosproject.codec.CodecContext;
22 +import org.onosproject.net.Annotations;
23 +import org.onosproject.net.DefaultAnnotations;
24 +import org.onosproject.net.DefaultPort;
25 +import org.onosproject.net.Device;
26 +import org.onosproject.net.DeviceId;
20 import org.onosproject.net.Port; 27 import org.onosproject.net.Port;
28 +import org.onosproject.net.Port.Type;
21 import org.onosproject.net.PortNumber; 29 import org.onosproject.net.PortNumber;
30 +import org.onosproject.net.provider.ProviderId;
22 31
23 import static com.google.common.base.Preconditions.checkNotNull; 32 import static com.google.common.base.Preconditions.checkNotNull;
24 33
...@@ -27,19 +36,125 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -27,19 +36,125 @@ import static com.google.common.base.Preconditions.checkNotNull;
27 */ 36 */
28 public final class PortCodec extends AnnotatedCodec<Port> { 37 public final class PortCodec extends AnnotatedCodec<Port> {
29 38
39 + // JSON field names
40 + private static final String ELEMENT = "element"; // DeviceId
41 + private static final String PORT_NAME = "port";
42 + private static final String IS_ENABLED = "isEnabled";
43 + private static final String TYPE = "type";
44 + private static final String PORT_SPEED = "portSpeed";
45 +
46 + // Special port name alias
47 + private static final String PORT_NAME_LOCAL = "local";
48 +
30 @Override 49 @Override
31 public ObjectNode encode(Port port, CodecContext context) { 50 public ObjectNode encode(Port port, CodecContext context) {
32 checkNotNull(port, "Port cannot be null"); 51 checkNotNull(port, "Port cannot be null");
33 ObjectNode result = context.mapper().createObjectNode() 52 ObjectNode result = context.mapper().createObjectNode()
34 - .put("port", portName(port.number())) 53 + .put(ELEMENT, port.element().id().toString())
35 - .put("isEnabled", port.isEnabled()) 54 + .put(PORT_NAME, portName(port.number()))
36 - .put("type", port.type().toString().toLowerCase()) 55 + .put(IS_ENABLED, port.isEnabled())
37 - .put("portSpeed", port.portSpeed()); 56 + .put(TYPE, port.type().toString().toLowerCase())
57 + .put(PORT_SPEED, port.portSpeed());
38 return annotate(result, port, context); 58 return annotate(result, port, context);
39 } 59 }
40 60
41 private String portName(PortNumber port) { 61 private String portName(PortNumber port) {
42 - return port.equals(PortNumber.LOCAL) ? "local" : port.toString(); 62 + return port.equals(PortNumber.LOCAL) ? PORT_NAME_LOCAL : port.toString();
43 } 63 }
44 64
65 + private static PortNumber portNumber(String portName) {
66 + if (portName.equalsIgnoreCase(PORT_NAME_LOCAL)) {
67 + return PortNumber.LOCAL;
68 + }
69 +
70 + return PortNumber.portNumber(portName);
71 + }
72 +
73 +
74 + /**
75 + * {@inheritDoc}
76 + *
77 + * Note: Result of {@link Port#element()} returned Port object,
78 + * is not a full Device object.
79 + * Only it's DeviceId can be used.
80 + */
81 + @Override
82 + public Port decode(ObjectNode json, CodecContext context) {
83 + if (json == null || !json.isObject()) {
84 + return null;
85 + }
86 +
87 + DeviceId did = DeviceId.deviceId(json.get(ELEMENT).asText());
88 + Device device = new DummyDevice(did);
89 + PortNumber number = portNumber(json.get(PORT_NAME).asText());
90 + boolean isEnabled = json.get(IS_ENABLED).asBoolean();
91 + Type type = Type.valueOf(json.get(TYPE).asText().toUpperCase());
92 + long portSpeed = json.get(PORT_SPEED).asLong();
93 + Annotations annotations = extractAnnotations(json, context);
94 +
95 + return new DefaultPort(device, number, isEnabled, type, portSpeed, annotations);
96 + }
97 +
98 +
99 + /**
100 + * Dummy Device which only holds DeviceId.
101 + */
102 + private static final class DummyDevice implements Device {
103 +
104 + private final DeviceId did;
105 +
106 + /**
107 + * Constructs Dummy Device which only holds DeviceId.
108 + *
109 + * @param did device Id
110 + */
111 + public DummyDevice(DeviceId did) {
112 + this.did = did;
113 + }
114 +
115 + @Override
116 + public Annotations annotations() {
117 + return DefaultAnnotations.EMPTY;
118 + }
119 +
120 + @Override
121 + public ProviderId providerId() {
122 + return new ProviderId(did.uri().getScheme(), "PortCodec");
123 + }
124 +
125 + @Override
126 + public DeviceId id() {
127 + return did;
128 + }
129 +
130 + @Override
131 + public Type type() {
132 + return Type.SWITCH;
133 + }
134 +
135 + @Override
136 + public String manufacturer() {
137 + return "dummy";
138 + }
139 +
140 + @Override
141 + public String hwVersion() {
142 + return "0";
143 + }
144 +
145 + @Override
146 + public String swVersion() {
147 + return "0";
148 + }
149 +
150 + @Override
151 + public String serialNumber() {
152 + return "0";
153 + }
154 +
155 + @Override
156 + public ChassisId chassisId() {
157 + return new ChassisId();
158 + }
159 + }
45 } 160 }
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.codec.impl;
18 +
19 +import static org.hamcrest.MatcherAssert.assertThat;
20 +import static org.hamcrest.Matchers.notNullValue;
21 +import static org.hamcrest.Matchers.is;
22 +import static org.onosproject.codec.impl.JsonCodecUtils.assertJsonEncodable;
23 +
24 +import org.junit.Test;
25 +import org.onosproject.codec.JsonCodec;
26 +import org.onosproject.net.DefaultDevice;
27 +import org.onosproject.net.Device;
28 +import org.onosproject.net.device.DeviceService;
29 +import org.onosproject.net.device.DeviceServiceAdapter;
30 +
31 +/**
32 + * Unit test for DeviceCodec.
33 + */
34 +public class DeviceCodecTest {
35 +
36 + private Device device = new DefaultDevice(JsonCodecUtils.PID,
37 + JsonCodecUtils.DID1,
38 + Device.Type.SWITCH,
39 + JsonCodecUtils.MFR,
40 + JsonCodecUtils.HW,
41 + JsonCodecUtils.SW1,
42 + JsonCodecUtils.SN,
43 + JsonCodecUtils.CID,
44 + JsonCodecUtils.A1);
45 +
46 +
47 +
48 + @Test
49 + public void deviceCodecTest() {
50 + final MockCodecContext context = new MockCodecContext();
51 + context.registerService(DeviceService.class, new DeviceServiceAdapter());
52 + final JsonCodec<Device> codec = context.codec(Device.class);
53 + assertThat(codec, is(notNullValue()));
54 + final Device pojoIn = device;
55 +
56 + assertJsonEncodable(context, codec, pojoIn);
57 + }
58 +
59 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.codec.impl;
18 +
19 +import static org.hamcrest.MatcherAssert.assertThat;
20 +import static org.hamcrest.Matchers.is;
21 +import static org.hamcrest.Matchers.notNullValue;
22 +import static org.junit.Assert.assertEquals;
23 +import static org.onosproject.net.DeviceId.deviceId;
24 +
25 +import org.onlab.packet.ChassisId;
26 +import org.onosproject.codec.CodecContext;
27 +import org.onosproject.codec.JsonCodec;
28 +import org.onosproject.net.ConnectPoint;
29 +import org.onosproject.net.DefaultAnnotations;
30 +import org.onosproject.net.DeviceId;
31 +import org.onosproject.net.PortNumber;
32 +import org.onosproject.net.SparseAnnotations;
33 +import org.onosproject.net.provider.ProviderId;
34 +
35 +import com.fasterxml.jackson.databind.node.ObjectNode;
36 +
37 +/**
38 + * JsonCodec test utilities.
39 + */
40 +public abstract class JsonCodecUtils {
41 +
42 + /**
43 + * Checks if given Object can be encoded to JSON and back.
44 + *
45 + * @param context CodecContext
46 + * @param codec JsonCodec
47 + * @param pojoIn Java Object to encode.
48 + * Object is expected to have #equals implemented.
49 + */
50 + public static <T> void assertJsonEncodable(final CodecContext context,
51 + final JsonCodec<T> codec,
52 + final T pojoIn) {
53 + final ObjectNode json = codec.encode(pojoIn, context);
54 +
55 + assertThat(json, is(notNullValue()));
56 +
57 + final T pojoOut = codec.decode(json, context);
58 + assertThat(pojoOut, is(notNullValue()));
59 +
60 + assertEquals(pojoIn, pojoOut);
61 + }
62 +
63 + static final ProviderId PID = new ProviderId("of", "foo");
64 + static final ProviderId PIDA = new ProviderId("of", "bar", true);
65 + static final DeviceId DID1 = deviceId("of:foo");
66 + static final DeviceId DID2 = deviceId("of:bar");
67 + static final String MFR = "whitebox";
68 + static final String HW = "1.1.x";
69 + static final String SW1 = "3.8.1";
70 + static final String SW2 = "3.9.5";
71 + static final String SN = "43311-12345";
72 + static final ChassisId CID = new ChassisId();
73 + static final PortNumber P1 = PortNumber.portNumber(1);
74 + static final PortNumber P2 = PortNumber.portNumber(2);
75 + static final PortNumber P3 = PortNumber.portNumber(3);
76 + static final SparseAnnotations A1 = DefaultAnnotations.builder()
77 + .set("A1", "a1")
78 + .set("B1", "b1")
79 + .build();
80 + static final ConnectPoint CP1 = new ConnectPoint(DID1, P1);
81 + static final ConnectPoint CP2 = new ConnectPoint(DID2, P2);
82 +
83 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.codec.impl;
18 +
19 +import static org.hamcrest.MatcherAssert.assertThat;
20 +import static org.hamcrest.Matchers.is;
21 +import static org.hamcrest.Matchers.notNullValue;
22 +import static org.onosproject.codec.impl.JsonCodecUtils.assertJsonEncodable;
23 +
24 +import org.junit.Test;
25 +import org.onosproject.codec.JsonCodec;
26 +import org.onosproject.net.DefaultLink;
27 +import org.onosproject.net.Link;
28 +import org.onosproject.net.device.DeviceService;
29 +import org.onosproject.net.device.DeviceServiceAdapter;
30 +
31 +/**
32 + * Unit test for LinkCodec.
33 + */
34 +public class LinkCodecTest {
35 +
36 + private final Link link = new DefaultLink(JsonCodecUtils.PID,
37 + JsonCodecUtils.CP1,
38 + JsonCodecUtils.CP2,
39 + Link.Type.DIRECT,
40 + Link.State.ACTIVE,
41 + false,
42 + JsonCodecUtils.A1);
43 +
44 + @Test
45 + public void linkCodecTest() {
46 + final MockCodecContext context = new MockCodecContext();
47 + context.registerService(DeviceService.class, new DeviceServiceAdapter());
48 + final JsonCodec<Link> codec = context.codec(Link.class);
49 + assertThat(codec, is(notNullValue()));
50 + final Link pojoIn = link;
51 +
52 + assertJsonEncodable(context, codec, pojoIn);
53 + }
54 +}
...@@ -15,6 +15,9 @@ ...@@ -15,6 +15,9 @@
15 */ 15 */
16 package org.onosproject.codec.impl; 16 package org.onosproject.codec.impl;
17 17
18 +import java.util.HashMap;
19 +import java.util.Map;
20 +
18 import org.onosproject.codec.CodecContext; 21 import org.onosproject.codec.CodecContext;
19 import org.onosproject.codec.JsonCodec; 22 import org.onosproject.codec.JsonCodec;
20 23
...@@ -25,8 +28,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; ...@@ -25,8 +28,9 @@ import com.fasterxml.jackson.databind.ObjectMapper;
25 */ 28 */
26 public class MockCodecContext implements CodecContext { 29 public class MockCodecContext implements CodecContext {
27 30
28 - private ObjectMapper mapper = new ObjectMapper(); 31 + private final ObjectMapper mapper = new ObjectMapper();
29 - private CodecManager manager = new CodecManager(); 32 + private final CodecManager manager = new CodecManager();
33 + private final Map<Class<? extends Object>, Object> services = new HashMap<>();
30 34
31 /** 35 /**
32 * Constructs a new mock codec context. 36 * Constructs a new mock codec context.
...@@ -46,9 +50,15 @@ public class MockCodecContext implements CodecContext { ...@@ -46,9 +50,15 @@ public class MockCodecContext implements CodecContext {
46 return manager.getCodec(entityClass); 50 return manager.getCodec(entityClass);
47 } 51 }
48 52
53 + @SuppressWarnings("unchecked")
49 @Override 54 @Override
50 public <T> T get(Class<T> serviceClass) { 55 public <T> T get(Class<T> serviceClass) {
51 - return null; 56 + return (T) services.get(serviceClass);
57 + }
58 +
59 + // for registering mock services
60 + public <T> void registerService(Class<T> serviceClass, T impl) {
61 + services.put(serviceClass, impl);
52 } 62 }
53 63
54 } 64 }
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +package org.onosproject.codec.impl;
18 +
19 +import static org.hamcrest.MatcherAssert.assertThat;
20 +import static org.hamcrest.Matchers.is;
21 +import static org.hamcrest.Matchers.notNullValue;
22 +import static org.onosproject.codec.impl.JsonCodecUtils.assertJsonEncodable;
23 +
24 +import org.junit.Test;
25 +import org.onosproject.codec.JsonCodec;
26 +import org.onosproject.net.DefaultDevice;
27 +import org.onosproject.net.DefaultPort;
28 +import org.onosproject.net.Device;
29 +import org.onosproject.net.Port;
30 +import org.onosproject.net.device.DeviceService;
31 +import org.onosproject.net.device.DeviceServiceAdapter;
32 +
33 +/**
34 + * Unit test for PortCodec.
35 + */
36 +public class PortCodecTest {
37 +
38 +
39 +
40 + private final Device device = new DefaultDevice(JsonCodecUtils.PID,
41 + JsonCodecUtils.DID1,
42 + Device.Type.SWITCH,
43 + JsonCodecUtils.MFR,
44 + JsonCodecUtils.HW,
45 + JsonCodecUtils.SW1,
46 + JsonCodecUtils.SN,
47 + JsonCodecUtils.CID,
48 + JsonCodecUtils.A1);
49 +
50 + private final Port port = new DefaultPort(device,
51 + JsonCodecUtils.P1,
52 + true,
53 + JsonCodecUtils.A1);
54 +
55 + @Test
56 + public void portCodecTest() {
57 + final MockCodecContext context = new MockCodecContext();
58 + context.registerService(DeviceService.class, new DeviceServiceAdapter());
59 + final JsonCodec<Port> codec = context.codec(Port.class);
60 + assertThat(codec, is(notNullValue()));
61 + final Port pojoIn = port;
62 +
63 + assertJsonEncodable(context, codec, pojoIn);
64 + }
65 +
66 +}
...@@ -343,7 +343,6 @@ public class DevicesResourceTest extends ResourceTest { ...@@ -343,7 +343,6 @@ public class DevicesResourceTest extends ResourceTest {
343 for (int portIndex = 0; portIndex < jsonPorts.size(); portIndex++) { 343 for (int portIndex = 0; portIndex < jsonPorts.size(); portIndex++) {
344 JsonObject jsonPort = jsonPorts.get(portIndex).asObject(); 344 JsonObject jsonPort = jsonPorts.get(portIndex).asObject();
345 345
346 - assertThat(jsonPort.size(), is(4));
347 assertThat(jsonPort.get("port").asString(), 346 assertThat(jsonPort.get("port").asString(),
348 is(Integer.toString(portIndex + 1))); 347 is(Integer.toString(portIndex + 1)));
349 assertThat(jsonPort.get("isEnabled").asBoolean(), 348 assertThat(jsonPort.get("isEnabled").asBoolean(),
......
...@@ -123,11 +123,6 @@ public class LinksResourceTest extends ResourceTest { ...@@ -123,11 +123,6 @@ public class LinksResourceTest extends ResourceTest {
123 123
124 JsonObject jsonLink = json.get(jsonLinkIndex).asObject(); 124 JsonObject jsonLink = json.get(jsonLinkIndex).asObject();
125 125
126 - if (jsonLink.names().size() != expectedAttributes) {
127 - reason = "Found a link with the wrong number of attributes";
128 - return false;
129 - }
130 -
131 if (matchesLink(link).matchesSafely(jsonLink)) { 126 if (matchesLink(link).matchesSafely(jsonLink)) {
132 return true; 127 return true;
133 } 128 }
......