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
Showing
14 changed files
with
551 additions
and
31 deletions
... | @@ -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(); |
63 | + } | ||
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; | ||
43 | } | 85 | } |
44 | 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 | } | ... | ... |
-
Please register or login to post a comment