Fixed service port create failure
Also enhanced service network and port codec and added more unit tests
Change-Id: I523acc49dc1472520bd15a47f9a591cd95297ea0
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());
+ }
+}