diff --git a/src/test/java/org/opencord/cordvtn/codec/ServiceNetworkCodecTest.java b/src/test/java/org/opencord/cordvtn/codec/ServiceNetworkCodecTest.java
index 35d9a1b..95701bd 100644
--- a/src/test/java/org/opencord/cordvtn/codec/ServiceNetworkCodecTest.java
+++ b/src/test/java/org/opencord/cordvtn/codec/ServiceNetworkCodecTest.java
@@ -16,15 +16,16 @@
 package org.opencord.cordvtn.codec;
 
 import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.fasterxml.jackson.databind.node.NullNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.google.common.collect.ImmutableMap;
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
-import org.junit.rules.ExpectedException;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
 import org.onosproject.codec.JsonCodec;
 import org.opencord.cordvtn.api.net.NetworkId;
+import org.opencord.cordvtn.api.net.SegmentId;
 import org.opencord.cordvtn.api.net.ServiceNetwork;
 import org.opencord.cordvtn.api.net.ServiceNetwork.DependencyType;
 import org.opencord.cordvtn.impl.DefaultServiceNetwork;
@@ -38,7 +39,6 @@
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.notNullValue;
 import static org.opencord.cordvtn.api.net.ServiceNetwork.DependencyType.BIDIRECTIONAL;
-import static org.opencord.cordvtn.api.net.ServiceNetwork.NetworkType.MANAGEMENT_LOCAL;
 import static org.opencord.cordvtn.api.net.ServiceNetwork.NetworkType.PRIVATE;
 import static org.opencord.cordvtn.codec.ServiceNetworkJsonMatcher.matchesServiceNetwork;
 
@@ -51,30 +51,35 @@
     private static final String NAME = "name";
     private static final String TYPE = "type";
     private static final String PROVIDERS = "providers";
+    private static final String SEGMENT_ID = "segment_id";
+    private static final String SUBNET = "subnet";
+    private static final String SERVICE_IP = "service_ip";
+    private static final String DEP_TYPE = "bidirectional";
 
-    private final Map<NetworkId, DependencyType> providerA =
+    private static final String NAME_1 = "network_1";
+    private static final NetworkId ID_1 = NetworkId.of("network_1");
+    private static final NetworkId PROVIDER_ID_1 = NetworkId.of("provider_1");
+    private static final SegmentId SEGMENT_ID_1 = SegmentId.of(1L);
+    private static final IpPrefix SUBNET_1 = IpPrefix.valueOf("192.168.0.0/24");
+    private static final IpAddress SERVICE_IP_1 = IpAddress.valueOf("192.168.0.1");
+
+    private static final Map<NetworkId, DependencyType> PROVIDER_1 =
             new HashMap<NetworkId, DependencyType>() {
                 {
-                    put(NetworkId.of("A"), BIDIRECTIONAL);
+                    put(NetworkId.of("provider_1"), BIDIRECTIONAL);
                 }
             };
 
-    private final ServiceNetwork networkA = DefaultServiceNetwork.builder()
-            .id(NetworkId.of("A"))
-            .name("A")
-            .type(MANAGEMENT_LOCAL)
-            .build();
-
-    private final ServiceNetwork networkB = DefaultServiceNetwork.builder()
-            .id(NetworkId.of("B"))
-            .name("B")
+    private static final ServiceNetwork NETWORK_1 = DefaultServiceNetwork.builder()
+            .id(ID_1)
+            .name(NAME_1)
             .type(PRIVATE)
-            .providers(providerA)
+            .segmentId(SEGMENT_ID_1)
+            .subnet(SUBNET_1)
+            .serviceIp(SERVICE_IP_1)
+            .providers(PROVIDER_1)
             .build();
 
-    @Rule
-    public ExpectedException exception = ExpectedException.none();
-
     private JsonCodec<ServiceNetwork> codec;
     private MockCodecContext context;
 
@@ -89,89 +94,332 @@
         assertThat(codec, notNullValue());
     }
 
+    /**
+     * Checks if encoding service network works properly.
+     */
     @Test
     public void testServiceNetworkEncode() {
-        ObjectNode networkJson = codec.encode(networkA, context);
+        ObjectNode networkJson = codec.encode(NETWORK_1, context);
         assertThat(networkJson, notNullValue());
-        assertThat(networkJson, matchesServiceNetwork(networkA));
-
-        networkJson = codec.encode(networkB, context);
-        assertThat(networkJson, notNullValue());
-        assertThat(networkJson, matchesServiceNetwork(networkB));
+        assertThat(networkJson, matchesServiceNetwork(NETWORK_1));
     }
 
+    /**
+     * Checks if decoding service network works properly.
+     */
     @Test
     public void testServiceNetworkDecode() throws IOException {
-        ServiceNetwork snet = getServiceNetwork("service-network.json");
-        assertThat(snet.id(), is(NetworkId.of("A")));
-        assertThat(snet.name(), is("A"));
-        assertThat(snet.type(), is(MANAGEMENT_LOCAL));
-        assertThat(snet.providers(), is(ImmutableMap.of()));
-
-        snet = getServiceNetwork("service-network-with-provider.json");
-        assertThat(snet.id(), is(NetworkId.of("B")));
-        assertThat(snet.name(), is("B"));
-        assertThat(snet.type(), is(PRIVATE));
-        assertThat(snet.providers(), is(providerA));
+        ServiceNetwork sNet = getServiceNetwork("service-network.json");
+        assertThat(sNet.id(), is(ID_1));
+        assertThat(sNet.name(), is(NAME_1));
+        assertThat(sNet.type(), is(PRIVATE));
+        assertThat(sNet.providers(), is(PROVIDER_1));
     }
 
-    @Test
-    public void testServiceNetworkDecodeMissingId() throws IllegalArgumentException {
+    /**
+     * Checks if decoding service network without ID fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServiceNetworkDecodeMissingId() {
         final JsonNode jsonMissingId = context.mapper().createObjectNode()
-                .put(NAME, "A")
+                .put(NAME, NAME_1)
                 .put(TYPE, PRIVATE.name())
-                .put(PROVIDERS, "");
-        exception.expect(IllegalArgumentException.class);
+                .put(SEGMENT_ID, SEGMENT_ID_1.id())
+                .put(SUBNET, SUBNET_1.toString())
+                .put(SERVICE_IP, SERVICE_IP_1.toString());
         codec.decode((ObjectNode) jsonMissingId, context);
     }
 
-    @Test
-    public void testServiceNetworkDecodeEmptyId() throws IllegalArgumentException {
+    /**
+     * Checks if decoding service network with empty ID fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServiceNetworkDecodeEmptyId() {
         final JsonNode jsonEmptyId = context.mapper().createObjectNode()
                 .put(ID, "")
-                .put(NAME, "A")
+                .put(NAME, NAME_1)
                 .put(TYPE, PRIVATE.name())
-                .put(PROVIDERS, "");
-        exception.expect(IllegalArgumentException.class);
+                .put(SEGMENT_ID, SEGMENT_ID_1.id())
+                .put(SUBNET, SUBNET_1.toString())
+                .put(SERVICE_IP, SERVICE_IP_1.toString());
         codec.decode((ObjectNode) jsonEmptyId, context);
     }
 
-    @Test
-    public void testServiceNetworkDecodeNullId() throws NullPointerException {
+    /**
+     * Checks if decoding service network with null ID fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServiceNetworkDecodeNullId() {
         final JsonNode jsonNullId = context.mapper().createObjectNode()
-                .put(NAME, "A")
+                .put(NAME, NAME_1)
                 .put(TYPE, PRIVATE.name())
-                .put(PROVIDERS, "")
+                .put(SEGMENT_ID, SEGMENT_ID_1.id())
+                .put(SUBNET, SUBNET_1.toString())
+                .put(SERVICE_IP, SERVICE_IP_1.toString())
                 .set(ID, NullNode.getInstance());
-        exception.expect(IllegalArgumentException.class);
         codec.decode((ObjectNode) jsonNullId, context);
     }
 
-    @Test
-    public void testServiceNetworkDecodeWithMissingProviderId() throws NullPointerException {
-        final JsonNode jsonMissingProviderId = context.mapper().createObjectNode()
-                .put(TYPE, "B");
-        final JsonNode jsonWithProvider = context.mapper().createObjectNode()
-                .put(ID, "A")
-                .put(NAME, "A")
-                .put(TYPE, PRIVATE.name())
-                .set(PROVIDERS, jsonMissingProviderId);
-        exception.expect(IllegalArgumentException.class);
-        codec.decode((ObjectNode) jsonWithProvider, context);
+    /**
+     * Checks if decoding service network with invalid type fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServiceNetworkDecodeInvalidType() {
+        final JsonNode jsonInvalidType = context.mapper().createObjectNode()
+                .put(ID, ID_1.id())
+                .put(NAME, NAME_1)
+                .put(TYPE, "type")
+                .put(SEGMENT_ID, SEGMENT_ID_1.id())
+                .put(SUBNET, SUBNET_1.toString())
+                .put(SERVICE_IP, SERVICE_IP_1.toString());
+        codec.decode((ObjectNode) jsonInvalidType, context);
     }
 
-    @Test
-    public void testServiceNetworkDecodeWithWrongProviderType() throws NullPointerException {
-        final JsonNode jsonWrongProviderType = context.mapper().createObjectNode()
-                .put(ID, "B")
-                .put(TYPE, "none");
-        final JsonNode jsonWithProvider = context.mapper().createObjectNode()
-                .put(ID, "A")
-                .put(NAME, "A")
+    /**
+     * Checks if decoding service network with null type fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServiceNetworkDecodeNullType() {
+        final JsonNode jsonNullType = context.mapper().createObjectNode()
+                .put(ID, ID_1.id())
+                .put(NAME, NAME_1)
+                .put(SEGMENT_ID, SEGMENT_ID_1.id())
+                .put(SUBNET, SUBNET_1.toString())
+                .put(SERVICE_IP, SERVICE_IP_1.toString())
+                .set(TYPE, NullNode.getInstance());
+        codec.decode((ObjectNode) jsonNullType, context);
+    }
+
+    /**
+     * Checks if decoding service network with invalid segment ID fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServiceNetworkDecodeInvalidSegmentId() {
+        final JsonNode jsonInvalidSeg = context.mapper().createObjectNode()
+                .put(ID, ID_1.id())
+                .put(NAME, NAME_1)
                 .put(TYPE, PRIVATE.name())
-                .set(PROVIDERS, jsonWrongProviderType);
-        exception.expect(IllegalArgumentException.class);
-        codec.decode((ObjectNode) jsonWithProvider, context);
+                .put(SEGMENT_ID, "segmentId")
+                .put(SUBNET, SUBNET_1.toString())
+                .put(SERVICE_IP, SERVICE_IP_1.toString());
+        codec.decode((ObjectNode) jsonInvalidSeg, context);
+    }
+
+    /**
+     * Checks if decoding service network with 0 segment ID fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServiceNetworkDecodeZeroSegmentId() {
+        final JsonNode jsonInvalidSeg = context.mapper().createObjectNode()
+                .put(ID, ID_1.id())
+                .put(NAME, NAME_1)
+                .put(TYPE, PRIVATE.name())
+                .put(SEGMENT_ID, 0)
+                .put(SUBNET, SUBNET_1.toString())
+                .put(SERVICE_IP, SERVICE_IP_1.toString());
+        codec.decode((ObjectNode) jsonInvalidSeg, context);
+    }
+
+    /**
+     * Checks if decoding service network with 0 segment ID fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServiceNetworkDecodeNullSegmentId() {
+        final JsonNode jsonInvalidSeg = context.mapper().createObjectNode()
+                .put(ID, ID_1.id())
+                .put(NAME, NAME_1)
+                .put(TYPE, PRIVATE.name())
+                .put(SUBNET, SUBNET_1.toString())
+                .put(SERVICE_IP, SERVICE_IP_1.toString())
+                .set(SEGMENT_ID, NullNode.getInstance());
+        codec.decode((ObjectNode) jsonInvalidSeg, context);
+    }
+
+    /**
+     * Checks if decoding service network with invalid subnet fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServiceNetworkDecodeInvalidSubnet() {
+        final JsonNode jsonInvalidSubnet = context.mapper().createObjectNode()
+                .put(ID, ID_1.id())
+                .put(NAME, NAME_1)
+                .put(TYPE, PRIVATE.name())
+                .put(SEGMENT_ID, SEGMENT_ID_1.id())
+                .put(SUBNET, "")
+                .put(SERVICE_IP, SERVICE_IP_1.toString());
+        codec.decode((ObjectNode) jsonInvalidSubnet, context);
+    }
+
+    /**
+     * Checks if decoding service network with invalid subnet fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServiceNetworkDecodeNullSubnet() {
+        final JsonNode jsonInvalidSubnet = context.mapper().createObjectNode()
+                .put(ID, ID_1.id())
+                .put(NAME, NAME_1)
+                .put(TYPE, PRIVATE.name())
+                .put(SEGMENT_ID, SEGMENT_ID_1.id())
+                .put(SERVICE_IP, SERVICE_IP_1.toString())
+                .set(SUBNET, NullNode.getInstance());
+        codec.decode((ObjectNode) jsonInvalidSubnet, context);
+    }
+
+    /**
+     * Checks if decoding service network with invalid service IP fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServiceNetworkDecodeInvalidServiceIp() {
+        final JsonNode jsonInvalidServiceIp = context.mapper().createObjectNode()
+                .put(ID, ID_1.id())
+                .put(NAME, NAME_1)
+                .put(TYPE, PRIVATE.name())
+                .put(SEGMENT_ID, SEGMENT_ID_1.id())
+                .put(SUBNET, SUBNET_1.toString())
+                .put(SERVICE_IP, "");
+        codec.decode((ObjectNode) jsonInvalidServiceIp, context);
+    }
+
+    /**
+     * Checks if decoding service network with null service IP fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServiceNetworkDecodeNullServiceIp() {
+        final JsonNode jsonInvalidServiceIp = context.mapper().createObjectNode()
+                .put(ID, ID_1.id())
+                .put(NAME, NAME_1)
+                .put(TYPE, PRIVATE.name())
+                .put(SEGMENT_ID, SEGMENT_ID_1.id())
+                .put(SUBNET, SUBNET_1.toString())
+                .set(SERVICE_IP, NullNode.getInstance());
+        codec.decode((ObjectNode) jsonInvalidServiceIp, context);
+    }
+
+    /**
+     * Checks if decoding service network with null and empty providers allowed.
+     */
+    @Test
+    public void testServiceNetworkDecodeNullAndEmptyProviders() {
+        JsonNode jsonInvalidProvider = context.mapper().createObjectNode()
+                .put(ID, ID_1.id())
+                .put(NAME, NAME_1)
+                .put(TYPE, PRIVATE.name())
+                .put(SEGMENT_ID, SEGMENT_ID_1.id())
+                .put(SUBNET, SUBNET_1.toString())
+                .put(SERVICE_IP, SERVICE_IP_1.toString())
+                .set(PROVIDERS, NullNode.getInstance());
+        codec.decode((ObjectNode) jsonInvalidProvider, context);
+
+        jsonInvalidProvider = context.mapper().createObjectNode()
+                .put(ID, ID_1.id())
+                .put(NAME, NAME_1)
+                .put(TYPE, PRIVATE.name())
+                .put(SEGMENT_ID, SEGMENT_ID_1.id())
+                .put(SUBNET, SUBNET_1.toString())
+                .put(SERVICE_IP, SERVICE_IP_1.toString())
+                .set(PROVIDERS, context.mapper().createArrayNode());
+        codec.decode((ObjectNode) jsonInvalidProvider, context);
+    }
+
+    /**
+     * Checks if decoding service network with non-array providers value fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServiceNetworkNonArrayProviders() {
+        final JsonNode jsonProvider = context.mapper().createObjectNode()
+                .put(ID, PROVIDER_ID_1.id())
+                .put(DEP_TYPE, true);
+        final JsonNode jsonInvalidProvider = context.mapper().createObjectNode()
+                .put(ID, ID_1.id())
+                .put(NAME, NAME_1)
+                .put(TYPE, PRIVATE.name())
+                .put(SEGMENT_ID, SEGMENT_ID_1.id())
+                .put(SUBNET, SUBNET_1.toString())
+                .put(SERVICE_IP, SERVICE_IP_1.toString())
+                .set(PROVIDERS, jsonProvider);
+        codec.decode((ObjectNode) jsonInvalidProvider, context);
+    }
+
+    /**
+     * Checks if decoding service network with invalid provider fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServiceNetworkMissingProviderId() {
+        final ArrayNode jsonProviders = context.mapper().createArrayNode();
+        final JsonNode jsonProvider = context.mapper().createObjectNode()
+                .put(DEP_TYPE, true);
+        jsonProviders.add(jsonProvider);
+        final JsonNode jsonInvalidProvider = context.mapper().createObjectNode()
+                .put(ID, ID_1.id())
+                .put(NAME, NAME_1)
+                .put(TYPE, PRIVATE.name())
+                .put(SEGMENT_ID, SEGMENT_ID_1.id())
+                .put(SUBNET, SUBNET_1.toString())
+                .put(SERVICE_IP, SERVICE_IP_1.toString())
+                .set(PROVIDERS, jsonProvider);
+        codec.decode((ObjectNode) jsonInvalidProvider, context);
+    }
+
+    /**
+     * Checks if decoding service network with invalid provider fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServiceNetworkMissingProviderType() {
+        final ArrayNode jsonProviders = context.mapper().createArrayNode();
+        final JsonNode jsonProvider = context.mapper().createObjectNode()
+                .put(ID, PROVIDER_ID_1.id());
+        jsonProviders.add(jsonProvider);
+        final JsonNode jsonInvalidProvider = context.mapper().createObjectNode()
+                .put(ID, ID_1.id())
+                .put(NAME, NAME_1)
+                .put(TYPE, PRIVATE.name())
+                .put(SEGMENT_ID, SEGMENT_ID_1.id())
+                .put(SUBNET, SUBNET_1.toString())
+                .put(SERVICE_IP, SERVICE_IP_1.toString())
+                .set(PROVIDERS, jsonProvider);
+        codec.decode((ObjectNode) jsonInvalidProvider, context);
+    }
+
+    /**
+     * Checks if decoding service network with invalid provider fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServiceNetworkNullProviderId() {
+        final ArrayNode jsonProviders = context.mapper().createArrayNode();
+        final JsonNode jsonProvider = context.mapper().createObjectNode()
+                .put(DEP_TYPE, true)
+                .set(ID, NullNode.getInstance());
+        jsonProviders.add(jsonProvider);
+        final JsonNode jsonInvalidProvider = context.mapper().createObjectNode()
+                .put(ID, ID_1.id())
+                .put(NAME, NAME_1)
+                .put(TYPE, PRIVATE.name())
+                .put(SEGMENT_ID, SEGMENT_ID_1.id())
+                .put(SUBNET, SUBNET_1.toString())
+                .put(SERVICE_IP, SERVICE_IP_1.toString())
+                .set(PROVIDERS, jsonProvider);
+        codec.decode((ObjectNode) jsonInvalidProvider, context);
+    }
+
+    /**
+     * Checks if decoding service network with invalid provider fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServiceNetworkNullProviderType() {
+        final ArrayNode jsonProviders = context.mapper().createArrayNode();
+        final JsonNode jsonProvider = context.mapper().createObjectNode()
+                .put(ID, PROVIDER_ID_1.id())
+                .set(DEP_TYPE, NullNode.getInstance());
+        jsonProviders.add(jsonProvider);
+        final JsonNode jsonInvalidProvider = context.mapper().createObjectNode()
+                .put(ID, ID_1.id())
+                .put(NAME, NAME_1)
+                .put(TYPE, PRIVATE.name())
+                .put(SEGMENT_ID, SEGMENT_ID_1.id())
+                .put(SUBNET, SUBNET_1.toString())
+                .put(SERVICE_IP, SERVICE_IP_1.toString())
+                .set(PROVIDERS, jsonProvider);
+        codec.decode((ObjectNode) jsonInvalidProvider, context);
     }
 
     private ServiceNetwork getServiceNetwork(String resource) throws IOException {
diff --git a/src/test/java/org/opencord/cordvtn/codec/ServiceNetworkJsonMatcher.java b/src/test/java/org/opencord/cordvtn/codec/ServiceNetworkJsonMatcher.java
index da321e3..f5a484b 100644
--- a/src/test/java/org/opencord/cordvtn/codec/ServiceNetworkJsonMatcher.java
+++ b/src/test/java/org/opencord/cordvtn/codec/ServiceNetworkJsonMatcher.java
@@ -66,31 +66,40 @@
         }
 
         JsonNode jsonProviders = jsonNet.get("providers");
-        if (jsonProviders == null || jsonProviders == NullNode.getInstance()) {
-            description.appendText("provider networks were empty");
-            return false;
-        }
-
-        if (jsonProviders.size() != network.providers().size()) {
-            return false;
-        }
-
-        for (JsonNode provider : jsonProviders) {
-            NetworkId id = NetworkId.of(provider.get("id").asText());
-            boolean bidirectional = provider.get("bidirectional").asBoolean();
-
-            if (!network.providers().containsKey(id)) {
-                final String msg = String.format("provider id:%s couldn't find", id);
-                description.appendText(msg);
+        if (network.providers().isEmpty()) {
+            if (jsonProviders != null &&
+                    jsonProviders != NullNode.getInstance() &&
+                    jsonProviders.size() != 0) {
+                description.appendText("provider networks did not match");
                 return false;
             }
-
-            if (network.providers().get(id).equals(BIDIRECTIONAL) != bidirectional) {
-                final String msg = String.format(
-                        "mismatch provider id:%s, bidirectional: %s",
-                        id, bidirectional);
-                description.appendText(msg);
+        } else {
+            if (jsonProviders == null ||
+                    jsonProviders == NullNode.getInstance() ||
+                    jsonProviders.size() == 0) {
+                description.appendText("provider networks did not match");
                 return false;
+            } else if (jsonProviders.size() != network.providers().size()) {
+                description.appendText("provider networks did not match");
+                return false;
+            } else {
+                for (JsonNode provider : jsonProviders) {
+                    NetworkId id = NetworkId.of(provider.get("id").asText());
+                    boolean bidirectional = provider.get("bidirectional").asBoolean();
+
+                    if (!network.providers().containsKey(id)) {
+                        final String msg = String.format("provider id:%s couldn't find", id);
+                        description.appendText(msg);
+                        return false;
+                    }
+                    if (network.providers().get(id).equals(BIDIRECTIONAL) != bidirectional) {
+                        final String msg = String.format(
+                                "mismatch provider id:%s, bidirectional: %s",
+                                id, bidirectional);
+                        description.appendText(msg);
+                        return false;
+                    }
+                }
             }
         }
         return true;
diff --git a/src/test/java/org/opencord/cordvtn/codec/ServicePortCodecTest.java b/src/test/java/org/opencord/cordvtn/codec/ServicePortCodecTest.java
new file mode 100644
index 0000000..02d0103
--- /dev/null
+++ b/src/test/java/org/opencord/cordvtn/codec/ServicePortCodecTest.java
@@ -0,0 +1,500 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.opencord.cordvtn.codec;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.NullNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.codec.JsonCodec;
+import org.opencord.cordvtn.api.net.AddressPair;
+import org.opencord.cordvtn.api.net.NetworkId;
+import org.opencord.cordvtn.api.net.PortId;
+import org.opencord.cordvtn.api.net.ServicePort;
+import org.opencord.cordvtn.impl.DefaultServicePort;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.opencord.cordvtn.codec.ServicePortJsonMatcher.matchesServicePort;
+
+/**
+ * Unit tests for ServiceNetwork codec.
+ */
+public final class ServicePortCodecTest {
+
+    private static final String SERVICE_PORT = "servicePort";
+    private static final String ID = "id";
+    private static final String NETWORK_ID = "network_id";
+    private static final String NAME = "name";
+    private static final String IP_ADDRESS = "ip_address";
+    private static final String MAC_ADDRESS = "mac_address";
+    private static final String FLOATING_ADDRESS_PAIRS = "floating_address_pairs";
+    private static final String VLAN_ID = "vlan_id";
+
+    private static final PortId PORT_ID_1 = PortId.of("port-1");
+    private static final NetworkId NETWORK_ID_1 = NetworkId.of("network-1");
+    private static final String PORT_NAME_1 = "tap1";
+    private static final MacAddress MAC_ADDRESS_1 = MacAddress.valueOf("00:00:00:00:00:01");
+    private static final IpAddress IP_ADDRESS_1 = IpAddress.valueOf("10.0.0.1");
+    private static final VlanId VLAN_ID_1 = VlanId.vlanId("222");
+
+    private static final AddressPair ADDRESS_PAIR_1 = AddressPair.of(
+            IpAddress.valueOf("192.168.0.1"),
+            MacAddress.valueOf("02:42:0a:06:01:01"));
+    private static final AddressPair ADDRESS_PAIR_2 = AddressPair.of(
+            IpAddress.valueOf("192.168.0.2"),
+            MacAddress.valueOf("02:42:0a:06:01:02"));
+
+    private static final Set<AddressPair> ADDRESS_PAIRS_1 =
+            new HashSet<AddressPair>() {
+                {
+                    add(ADDRESS_PAIR_1);
+                    add(ADDRESS_PAIR_2);
+                }
+            };
+
+    private static final ServicePort PORT_1 = DefaultServicePort.builder()
+            .id(PORT_ID_1)
+            .networkId(NETWORK_ID_1)
+            .name(PORT_NAME_1)
+            .ip(IP_ADDRESS_1)
+            .mac(MAC_ADDRESS_1)
+            .addressPairs(ADDRESS_PAIRS_1)
+            .vlanId(VLAN_ID_1)
+            .build();
+
+    private JsonCodec<ServicePort> codec;
+    private MockCodecContext context;
+
+    /**
+     * Creates a context and gets the servicePort codec for each test.
+     */
+    @Before
+    public void setUp() {
+        context = new MockCodecContext();
+        codec = context.codec(ServicePort.class);
+        assertThat(codec, notNullValue());
+    }
+
+    /**
+     * Checks if encoding service port works properly.
+     */
+    @Test
+    public void testServicePortEncode() {
+        ObjectNode jsonPort = codec.encode(PORT_1, context);
+        assertThat(jsonPort, notNullValue());
+        assertThat(jsonPort, matchesServicePort(PORT_1));
+    }
+
+    /**
+     * Checks if decoding service port works properly.
+     */
+    @Test
+    public void testServicePortDecode() throws IOException {
+        ServicePort sPort = getServicePort("service-port.json");
+        assertThat(sPort.id(), is(PORT_ID_1));
+        assertThat(sPort.networkId(), is(NETWORK_ID_1));
+        assertThat(sPort.name(), is(PORT_NAME_1));
+        assertThat(sPort.ip(), is(IP_ADDRESS_1));
+        assertThat(sPort.mac(), is(MAC_ADDRESS_1));
+        assertThat(sPort.addressPairs(), is(ADDRESS_PAIRS_1));
+        assertThat(sPort.vlanId(), is(VLAN_ID_1));
+    }
+
+    /**
+     * Checks if decoding service port without ID fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServicePortDecodeMissingId() {
+        final JsonNode jsonInvalidId = context.mapper().createObjectNode()
+                .put(NETWORK_ID, NETWORK_ID_1.id())
+                .put(NAME, PORT_NAME_1)
+                .put(IP_ADDRESS, IP_ADDRESS_1.toString())
+                .put(MAC_ADDRESS, MAC_ADDRESS_1.toString())
+                .put(VLAN_ID, VLAN_ID_1.toShort());
+        codec.decode((ObjectNode) jsonInvalidId, context);
+    }
+
+    /**
+     * Checks if decoding service port with empty ID fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServicePortDecodeEmptyId() {
+        final JsonNode jsonInvalidId = context.mapper().createObjectNode()
+                .put(ID, "")
+                .put(NETWORK_ID, NETWORK_ID_1.id())
+                .put(NAME, PORT_NAME_1)
+                .put(IP_ADDRESS, IP_ADDRESS_1.toString())
+                .put(MAC_ADDRESS, MAC_ADDRESS_1.toString())
+                .put(VLAN_ID, VLAN_ID_1.toShort());
+        codec.decode((ObjectNode) jsonInvalidId, context);
+    }
+
+    /**
+     * Checks if decoding service port with null ID fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServicePortDecodeNullId() {
+        final JsonNode jsonInvalidId = context.mapper().createObjectNode()
+                .put(NETWORK_ID, NETWORK_ID_1.id())
+                .put(NAME, PORT_NAME_1)
+                .put(IP_ADDRESS, IP_ADDRESS_1.toString())
+                .put(MAC_ADDRESS, MAC_ADDRESS_1.toString())
+                .put(VLAN_ID, VLAN_ID_1.toShort())
+                .set(ID, NullNode.getInstance());
+        codec.decode((ObjectNode) jsonInvalidId, context);
+    }
+
+    /**
+     * Checks if empty string is not allowed for network ID.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServicePortDecodeEmptyNetworkId() {
+        final JsonNode jsonInvalidId = context.mapper().createObjectNode()
+                .put(ID, PORT_ID_1.id())
+                .put(NETWORK_ID, "")
+                .put(NAME, PORT_NAME_1)
+                .put(IP_ADDRESS, IP_ADDRESS_1.toString())
+                .put(MAC_ADDRESS, MAC_ADDRESS_1.toString())
+                .put(VLAN_ID, VLAN_ID_1.toShort());
+        codec.decode((ObjectNode) jsonInvalidId, context);
+    }
+
+    /**
+     * Checks if null is not allowed for network ID.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServicePortDecodeNullNetworkId() {
+        final JsonNode jsonInvalidId = context.mapper().createObjectNode()
+                .put(ID, PORT_ID_1.id())
+                .put(NAME, PORT_NAME_1)
+                .put(IP_ADDRESS, IP_ADDRESS_1.toString())
+                .put(MAC_ADDRESS, MAC_ADDRESS_1.toString())
+                .put(VLAN_ID, VLAN_ID_1.toShort())
+                .set(NETWORK_ID, NullNode.getInstance());
+        codec.decode((ObjectNode) jsonInvalidId, context);
+    }
+
+    /**
+     * Checks if empty string is not allowed for port name.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServicePortDecodeEmptyName() {
+        JsonNode jsonInvalidName = context.mapper().createObjectNode()
+                .put(ID, PORT_ID_1.id())
+                .put(NETWORK_ID, NETWORK_ID_1.id())
+                .put(NAME, "")
+                .put(IP_ADDRESS, IP_ADDRESS_1.toString())
+                .put(MAC_ADDRESS, MAC_ADDRESS_1.toString())
+                .put(VLAN_ID, VLAN_ID_1.toShort());
+        codec.decode((ObjectNode) jsonInvalidName, context);
+    }
+
+    /**
+     * Checks if null is not allowed for port name.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServicePortDecodeNullName() {
+        final JsonNode jsonInvalidName = context.mapper().createObjectNode()
+                .put(ID, PORT_ID_1.id())
+                .put(NETWORK_ID, NETWORK_ID_1.id())
+                .put(IP_ADDRESS, IP_ADDRESS_1.toString())
+                .put(MAC_ADDRESS, MAC_ADDRESS_1.toString())
+                .put(VLAN_ID, VLAN_ID_1.toShort())
+                .set(NAME, NullNode.getInstance());
+        codec.decode((ObjectNode) jsonInvalidName, context);
+    }
+
+    /**
+     * Checks if invalid IP address string is not allowed.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServicePortDecodeInvalidIpAddress() {
+        final JsonNode jsonInvalidIp = context.mapper().createObjectNode()
+                .put(ID, PORT_ID_1.id())
+                .put(NETWORK_ID, NETWORK_ID_1.id())
+                .put(NAME, PORT_NAME_1)
+                .put(IP_ADDRESS, "ipAddress")
+                .put(MAC_ADDRESS, MAC_ADDRESS_1.toString())
+                .put(VLAN_ID, VLAN_ID_1.toShort());
+        codec.decode((ObjectNode) jsonInvalidIp, context);
+    }
+
+    /**
+     * Checks if invalid IP address string is not allowed.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServicePortDecodeNullIpAddress() {
+        final JsonNode jsonInvalidIp = context.mapper().createObjectNode()
+                .put(ID, PORT_ID_1.id())
+                .put(NETWORK_ID, NETWORK_ID_1.id())
+                .put(NAME, PORT_NAME_1)
+                .put(MAC_ADDRESS, MAC_ADDRESS_1.toString())
+                .put(VLAN_ID, VLAN_ID_1.toShort())
+                .set(IP_ADDRESS, NullNode.getInstance());
+        codec.decode((ObjectNode) jsonInvalidIp, context);
+    }
+
+    /**
+     * Checks if invalid MAC address string is not allowed.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServicePortDecodeInvalidMacAddress() {
+        final JsonNode jsonInvalidMac = context.mapper().createObjectNode()
+                .put(ID, PORT_ID_1.id())
+                .put(NETWORK_ID, NETWORK_ID_1.id())
+                .put(NAME, PORT_NAME_1)
+                .put(IP_ADDRESS, IP_ADDRESS_1.toString())
+                .put(MAC_ADDRESS, "macAddress")
+                .put(VLAN_ID, VLAN_ID_1.toShort());
+        codec.decode((ObjectNode) jsonInvalidMac, context);
+    }
+
+    /**
+     * Checks if null is not allowed for MAC address.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServicePortDecodeNullMacAddress() {
+        final JsonNode jsonInvalidMac = context.mapper().createObjectNode()
+                .put(ID, PORT_ID_1.id())
+                .put(NETWORK_ID, NETWORK_ID_1.id())
+                .put(NAME, PORT_NAME_1)
+                .put(IP_ADDRESS, IP_ADDRESS_1.toString())
+                .put(VLAN_ID, VLAN_ID_1.toShort())
+                .set(MAC_ADDRESS, NullNode.getInstance());
+        codec.decode((ObjectNode) jsonInvalidMac, context);
+    }
+
+    /**
+     * Checks if invalid VLAN ID is not allowed.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServicePortDecodeInvalidVlanId() {
+        final JsonNode jsonInvalidVlan = context.mapper().createObjectNode()
+                .put(ID, PORT_ID_1.id())
+                .put(NETWORK_ID, NETWORK_ID_1.id())
+                .put(NAME, PORT_NAME_1)
+                .put(IP_ADDRESS, IP_ADDRESS_1.toString())
+                .put(MAC_ADDRESS, MAC_ADDRESS_1.toString())
+                .put(VLAN_ID, "vlanId");
+        codec.decode((ObjectNode) jsonInvalidVlan, context);
+    }
+
+    /**
+     * Checks if null is not allowed for VLAN ID.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServicePortDecodeNullVlanId() {
+        final JsonNode jsonInvalidVlan = context.mapper().createObjectNode()
+                .put(ID, PORT_ID_1.id())
+                .put(NETWORK_ID, NETWORK_ID_1.id())
+                .put(NAME, PORT_NAME_1)
+                .put(IP_ADDRESS, IP_ADDRESS_1.toString())
+                .put(MAC_ADDRESS, MAC_ADDRESS_1.toString())
+                .set(VLAN_ID, NullNode.getInstance());
+        codec.decode((ObjectNode) jsonInvalidVlan, context);
+    }
+
+    /**
+     * Checks if only array node is allowed for floating address pairs.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServicePortDecodeNonArrayAddressPairs() {
+        final JsonNode jsonAddrPair = context.mapper().createObjectNode()
+                .put(IP_ADDRESS, ADDRESS_PAIR_1.ip().toString())
+                .put(MAC_ADDRESS, ADDRESS_PAIR_1.mac().toString());
+        final JsonNode jsonInvalidAddrPair = context.mapper().createObjectNode()
+                .put(ID, PORT_ID_1.id())
+                .put(NETWORK_ID, NETWORK_ID_1.id())
+                .put(NAME, PORT_NAME_1)
+                .put(IP_ADDRESS, IP_ADDRESS_1.toString())
+                .put(MAC_ADDRESS, MAC_ADDRESS_1.toString())
+                .put(VLAN_ID, VLAN_ID_1.toShort())
+                .set(FLOATING_ADDRESS_PAIRS, jsonAddrPair);
+        codec.decode((ObjectNode) jsonInvalidAddrPair, context);
+    }
+
+    /**
+     * Checks if null and empty array node is allowed for floating address pairs.
+     */
+    @Test
+    public void testServicePortDecodeNullAndEmptyAddressPairs() {
+        JsonNode jsonInvalidAddrPair = context.mapper().createObjectNode()
+                .put(ID, PORT_ID_1.id())
+                .put(NETWORK_ID, NETWORK_ID_1.id())
+                .put(NAME, PORT_NAME_1)
+                .put(IP_ADDRESS, IP_ADDRESS_1.toString())
+                .put(MAC_ADDRESS, MAC_ADDRESS_1.toString())
+                .put(VLAN_ID, VLAN_ID_1.toShort())
+                .set(FLOATING_ADDRESS_PAIRS, NullNode.getInstance());
+        codec.decode((ObjectNode) jsonInvalidAddrPair, context);
+
+        jsonInvalidAddrPair = context.mapper().createObjectNode()
+                .put(ID, PORT_ID_1.id())
+                .put(NETWORK_ID, NETWORK_ID_1.id())
+                .put(NAME, PORT_NAME_1)
+                .put(IP_ADDRESS, IP_ADDRESS_1.toString())
+                .put(MAC_ADDRESS, MAC_ADDRESS_1.toString())
+                .put(VLAN_ID, VLAN_ID_1.toShort())
+                .set(FLOATING_ADDRESS_PAIRS, context.mapper().createArrayNode());
+        codec.decode((ObjectNode) jsonInvalidAddrPair, context);
+    }
+
+    /**
+     * Checks if floating address pair without IP address field fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServicePortDecodeMissingFloatingAddrPairIp() {
+        final ArrayNode jsonAddrPairs = context.mapper().createArrayNode();
+        final JsonNode jsonAddrPair = context.mapper().createObjectNode()
+                .put(MAC_ADDRESS, ADDRESS_PAIR_1.mac().toString());
+        jsonAddrPairs.add(jsonAddrPair);
+        final JsonNode jsonInvalidAddrPair = context.mapper().createObjectNode()
+                .put(ID, PORT_ID_1.id())
+                .put(NETWORK_ID, NETWORK_ID_1.id())
+                .put(NAME, PORT_NAME_1)
+                .put(IP_ADDRESS, IP_ADDRESS_1.toString())
+                .put(MAC_ADDRESS, MAC_ADDRESS_1.toString())
+                .put(VLAN_ID, VLAN_ID_1.toShort())
+                .set(FLOATING_ADDRESS_PAIRS, jsonAddrPairs);
+        codec.decode((ObjectNode) jsonInvalidAddrPair, context);
+    }
+
+    /**
+     * Checks if floating address pair without MAC address field fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServicePortDecodeMissingFloatingAddrPairMac() {
+        final ArrayNode jsonAddrPairs = context.mapper().createArrayNode();
+        final JsonNode jsonAddrPair = context.mapper().createObjectNode()
+                .put(IP_ADDRESS, ADDRESS_PAIR_1.ip().toString());
+        jsonAddrPairs.add(jsonAddrPair);
+        final JsonNode jsonInvalidAddrPair = context.mapper().createObjectNode()
+                .put(ID, PORT_ID_1.id())
+                .put(NETWORK_ID, NETWORK_ID_1.id())
+                .put(NAME, PORT_NAME_1)
+                .put(IP_ADDRESS, IP_ADDRESS_1.toString())
+                .put(MAC_ADDRESS, MAC_ADDRESS_1.toString())
+                .put(VLAN_ID, VLAN_ID_1.toShort())
+                .set(FLOATING_ADDRESS_PAIRS, jsonAddrPairs);
+        codec.decode((ObjectNode) jsonInvalidAddrPair, context);
+    }
+
+    /**
+     * Checks if null IP address for floating address pair fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServicePortDecodeNullFloatingAddrPairIp() {
+        final ArrayNode jsonAddrPairs = context.mapper().createArrayNode();
+        final JsonNode jsonAddrPair = context.mapper().createObjectNode()
+                .put(MAC_ADDRESS, ADDRESS_PAIR_1.mac().toString())
+                .set(IP_ADDRESS, NullNode.getInstance());
+        jsonAddrPairs.add(jsonAddrPair);
+        final JsonNode jsonInvalidAddrPair = context.mapper().createObjectNode()
+                .put(ID, PORT_ID_1.id())
+                .put(NETWORK_ID, NETWORK_ID_1.id())
+                .put(NAME, PORT_NAME_1)
+                .put(IP_ADDRESS, IP_ADDRESS_1.toString())
+                .put(MAC_ADDRESS, MAC_ADDRESS_1.toString())
+                .put(VLAN_ID, VLAN_ID_1.toShort())
+                .set(FLOATING_ADDRESS_PAIRS, jsonAddrPairs);
+        codec.decode((ObjectNode) jsonInvalidAddrPair, context);
+    }
+
+    /**
+     * Checks if null MAC address for floating address pair fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServicePortDecodeNullFloatingAddrPairMac() {
+        final ArrayNode jsonAddrPairs = context.mapper().createArrayNode();
+        final JsonNode jsonAddrPair = context.mapper().createObjectNode()
+                .put(IP_ADDRESS, ADDRESS_PAIR_1.ip().toString())
+                .set(MAC_ADDRESS, NullNode.getInstance());
+        jsonAddrPairs.add(jsonAddrPair);
+        final JsonNode jsonInvalidAddrPair = context.mapper().createObjectNode()
+                .put(ID, PORT_ID_1.id())
+                .put(NETWORK_ID, NETWORK_ID_1.id())
+                .put(NAME, PORT_NAME_1)
+                .put(IP_ADDRESS, IP_ADDRESS_1.toString())
+                .put(MAC_ADDRESS, MAC_ADDRESS_1.toString())
+                .put(VLAN_ID, VLAN_ID_1.toShort())
+                .set(FLOATING_ADDRESS_PAIRS, jsonAddrPairs);
+        codec.decode((ObjectNode) jsonInvalidAddrPair, context);
+    }
+
+    /**
+     * Checks if invalid IP address for floating address pair fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServicePortDecodeInvalidFloatingAddrPairIp() {
+        final ArrayNode jsonAddrPairs = context.mapper().createArrayNode();
+        final JsonNode jsonAddrPair = context.mapper().createObjectNode()
+                .put(IP_ADDRESS, "ipAddress")
+                .put(MAC_ADDRESS, ADDRESS_PAIR_1.mac().toString());
+        jsonAddrPairs.add(jsonAddrPair);
+        final JsonNode jsonInvalidAddrPair = context.mapper().createObjectNode()
+                .put(ID, PORT_ID_1.id())
+                .put(NETWORK_ID, NETWORK_ID_1.id())
+                .put(NAME, PORT_NAME_1)
+                .put(IP_ADDRESS, IP_ADDRESS_1.toString())
+                .put(MAC_ADDRESS, MAC_ADDRESS_1.toString())
+                .put(VLAN_ID, VLAN_ID_1.toShort())
+                .set(FLOATING_ADDRESS_PAIRS, jsonAddrPairs);
+        codec.decode((ObjectNode) jsonInvalidAddrPair, context);
+    }
+
+    /**
+     * Checks if invalid MAC address for floating address pair fails.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testServicePortDecodeInvalidFloatingAddrPairMac() {
+        final ArrayNode jsonAddrPairs = context.mapper().createArrayNode();
+        final JsonNode jsonAddrPair = context.mapper().createObjectNode()
+                .put(IP_ADDRESS, ADDRESS_PAIR_1.ip().toString())
+                .put(MAC_ADDRESS, "macAddress");
+        jsonAddrPairs.add(jsonAddrPair);
+        final JsonNode jsonInvalidAddrPair = context.mapper().createObjectNode()
+                .put(ID, PORT_ID_1.id())
+                .put(NETWORK_ID, NETWORK_ID_1.id())
+                .put(NAME, PORT_NAME_1)
+                .put(IP_ADDRESS, IP_ADDRESS_1.toString())
+                .put(MAC_ADDRESS, MAC_ADDRESS_1.toString())
+                .put(VLAN_ID, VLAN_ID_1.toShort())
+                .set(FLOATING_ADDRESS_PAIRS, jsonAddrPairs);
+        codec.decode((ObjectNode) jsonInvalidAddrPair, context);
+    }
+
+    private ServicePort getServicePort(String resource) throws IOException {
+        InputStream jsonStream = ServicePortCodecTest.class.getResourceAsStream(resource);
+        JsonNode jsonNode = context.mapper().readTree(jsonStream).get(SERVICE_PORT);
+        assertThat(jsonNode, notNullValue());
+
+        ServicePort sPort = codec.decode((ObjectNode) jsonNode, context);
+        assertThat(sPort, notNullValue());
+        return sPort;
+    }
+}
diff --git a/src/test/java/org/opencord/cordvtn/codec/ServicePortJsonMatcher.java b/src/test/java/org/opencord/cordvtn/codec/ServicePortJsonMatcher.java
new file mode 100644
index 0000000..08aa126
--- /dev/null
+++ b/src/test/java/org/opencord/cordvtn/codec/ServicePortJsonMatcher.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.opencord.cordvtn.codec;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.NullNode;
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.opencord.cordvtn.api.net.AddressPair;
+import org.opencord.cordvtn.api.net.ServicePort;
+
+import java.util.Objects;
+
+/**
+ * Json matcher for ServicePort.
+ */
+public final class ServicePortJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> {
+
+    private final ServicePort port;
+
+    private ServicePortJsonMatcher(ServicePort port) {
+        this.port = port;
+    }
+
+    /**
+     * Factory to allocate ServicePort matcher.
+     *
+     * @param port service port object to match
+     * @return matcher
+     */
+    public static ServicePortJsonMatcher matchesServicePort(ServicePort port) {
+        return new ServicePortJsonMatcher(port);
+    }
+
+    @Override
+    protected boolean matchesSafely(JsonNode jsonNode, Description description) {
+        final String jsonPortId = jsonNode.get("id").asText();
+        if (!Objects.equals(jsonPortId, port.id().id())) {
+            description.appendText("Port id was " + jsonPortId);
+            return false;
+        }
+
+        final String jsonPortName = jsonNode.get("name").asText();
+        if (!Objects.equals(jsonPortName, port.name())) {
+            description.appendText("Port name was " + jsonPortName);
+            return false;
+        }
+
+        final String jsonPortNetId = jsonNode.get("network_id").asText();
+        if (!Objects.equals(jsonPortNetId, port.networkId().id())) {
+            description.appendText("Network id was " + jsonPortNetId);
+            return false;
+        }
+
+        final String jsonMacAddr = jsonNode.get("mac_address").asText();
+        if (!Objects.equals(jsonMacAddr, port.mac().toString())) {
+            description.appendText("MAC address was " + jsonMacAddr);
+            return false;
+        }
+
+        final String jsonIpAddr = jsonNode.get("ip_address").asText();
+        if (!Objects.equals(jsonIpAddr, port.ip().toString())) {
+            description.appendText("IP address was " + jsonIpAddr);
+            return false;
+        }
+
+        final String jsonVlanId = jsonNode.get("vlan_id").asText();
+        if (!Objects.equals(jsonVlanId, port.vlanId().toString())) {
+            description.appendText("VLAN id was " + jsonVlanId);
+            return false;
+        }
+
+        final JsonNode jsonAddrPairs = jsonNode.get("floating_address_pairs");
+        if (port.addressPairs().isEmpty()) {
+            if (jsonAddrPairs != null &&
+                    jsonAddrPairs != NullNode.getInstance() &&
+                    jsonAddrPairs.size() != 0) {
+                description.appendText("Floating address pairs did not match");
+                return false;
+            }
+        } else {
+            if (jsonAddrPairs == null ||
+                    jsonAddrPairs == NullNode.getInstance() ||
+                    jsonAddrPairs.size() == 0) {
+                description.appendText("Floating address pairs was empty");
+                return false;
+            } else if (jsonAddrPairs.size() != port.addressPairs().size()) {
+                description.appendText("Floating address pairs size was " +
+                        jsonAddrPairs.size());
+                return false;
+            } else {
+                for (JsonNode addrPair : jsonAddrPairs) {
+                    final AddressPair tmp = AddressPair.of(
+                            IpAddress.valueOf(addrPair.get("ip_address").asText()),
+                            MacAddress.valueOf(addrPair.get("mac_address").asText())
+                    );
+                    if (!port.addressPairs().contains(tmp)) {
+                        description.appendText("Floating address pairs did not match " + tmp);
+                        return false;
+                    }
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public void describeTo(Description description) {
+        description.appendText(port.toString());
+    }
+}
