[ONOS-6142] Add SrcDst and TE extension addresses with unit tests
Change-Id: If16b1217d44774e91e0452aedb53daacf33f4e23
diff --git a/drivers/lisp/src/main/java/org/onosproject/drivers/lisp/extensions/LispSrcDstAddress.java b/drivers/lisp/src/main/java/org/onosproject/drivers/lisp/extensions/LispSrcDstAddress.java
index 1c1dee7..95c3be3 100644
--- a/drivers/lisp/src/main/java/org/onosproject/drivers/lisp/extensions/LispSrcDstAddress.java
+++ b/drivers/lisp/src/main/java/org/onosproject/drivers/lisp/extensions/LispSrcDstAddress.java
@@ -16,10 +16,16 @@
package org.onosproject.drivers.lisp.extensions;
+import com.google.common.collect.Maps;
import org.onosproject.mapping.addresses.ExtensionMappingAddress;
import org.onosproject.mapping.addresses.ExtensionMappingAddressType;
+import org.onosproject.mapping.addresses.MappingAddress;
import org.onosproject.net.flow.AbstractExtension;
+import java.util.Map;
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
import static org.onosproject.mapping.addresses.ExtensionMappingAddressType
.ExtensionMappingAddressTypes.SOURCE_DEST_ADDRESS;
@@ -31,6 +37,75 @@
*/
public class LispSrcDstAddress extends AbstractExtension
implements ExtensionMappingAddress {
+
+ private static final String SRC_MASK_LENGTH = "srcMaskLength";
+ private static final String DST_MASK_LENGTH = "dstMaskLength";
+ private static final String SRC_PREFIX = "srcPrefix";
+ private static final String DST_PREFIX = "dstPrefix";
+
+ private byte srcMaskLength;
+ private byte dstMaskLength;
+ private MappingAddress srcPrefix;
+ private MappingAddress dstPrefix;
+
+ /**
+ * Default constructor.
+ */
+ public LispSrcDstAddress() {
+ }
+
+ /**
+ * Creates an instance with initialized parameters.
+ *
+ * @param srcMaskLength source mask length
+ * @param dstMaskLength destination mask length
+ * @param srcPrefix source address prefix
+ * @param dstPrefix destination address prefix
+ */
+ private LispSrcDstAddress(byte srcMaskLength, byte dstMaskLength,
+ MappingAddress srcPrefix, MappingAddress dstPrefix) {
+ this.srcMaskLength = srcMaskLength;
+ this.dstMaskLength = dstMaskLength;
+ this.srcPrefix = srcPrefix;
+ this.dstPrefix = dstPrefix;
+ }
+
+ /**
+ * Obtains source mask length.
+ *
+ * @return source mask length
+ */
+ public byte getSrcMaskLength() {
+ return srcMaskLength;
+ }
+
+ /**
+ * Obtains destination mask length.
+ *
+ * @return destination mask length
+ */
+ public byte getDstMaskLength() {
+ return dstMaskLength;
+ }
+
+ /**
+ * Obtains source address prefix.
+ *
+ * @return source address prefix
+ */
+ public MappingAddress getSrcPrefix() {
+ return srcPrefix;
+ }
+
+ /**
+ * Obtains destination address prefix.
+ *
+ * @return destination address prefix
+ */
+ public MappingAddress getDstPrefix() {
+ return dstPrefix;
+ }
+
@Override
public ExtensionMappingAddressType type() {
return SOURCE_DEST_ADDRESS.type();
@@ -38,11 +113,119 @@
@Override
public byte[] serialize() {
- return new byte[0];
+ Map<String, Object> parameterMap = Maps.newHashMap();
+
+ parameterMap.put(SRC_MASK_LENGTH, srcMaskLength);
+ parameterMap.put(DST_MASK_LENGTH, dstMaskLength);
+ parameterMap.put(SRC_PREFIX, srcPrefix);
+ parameterMap.put(DST_PREFIX, dstPrefix);
+
+ return APP_KRYO.serialize(parameterMap);
}
@Override
public void deserialize(byte[] data) {
+ Map<String, Object> parameterMap = APP_KRYO.deserialize(data);
+ this.srcMaskLength = (byte) parameterMap.get(SRC_MASK_LENGTH);
+ this.dstMaskLength = (byte) parameterMap.get(DST_MASK_LENGTH);
+ this.srcPrefix = (MappingAddress) parameterMap.get(SRC_PREFIX);
+ this.dstPrefix = (MappingAddress) parameterMap.get(DST_PREFIX);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(srcPrefix, dstPrefix, srcMaskLength, dstMaskLength);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof LispSrcDstAddress) {
+ final LispSrcDstAddress other = (LispSrcDstAddress) obj;
+ return Objects.equals(this.srcPrefix, other.srcPrefix) &&
+ Objects.equals(this.dstPrefix, other.dstPrefix) &&
+ Objects.equals(this.srcMaskLength, other.srcMaskLength) &&
+ Objects.equals(this.dstMaskLength, other.dstMaskLength);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("source prefix", srcPrefix)
+ .add("destination prefix", dstPrefix)
+ .add("source mask length", srcMaskLength)
+ .add("destination mask length", dstMaskLength)
+ .toString();
+ }
+
+ /**
+ * A builder for building LispSrcDstAddress.
+ */
+ public static final class Builder {
+ private byte srcMaskLength;
+ private byte dstMaskLength;
+ private MappingAddress srcPrefix;
+ private MappingAddress dstPrefix;
+
+ /**
+ * Sets source address prefix.
+ *
+ * @param srcPrefix source prefix
+ * @return Builder object
+ */
+ public Builder withSrcPrefix(MappingAddress srcPrefix) {
+ this.srcPrefix = srcPrefix;
+ return this;
+ }
+
+ /**
+ * Sets destination address prefix.
+ *
+ * @param dstPrefix destination prefix
+ * @return Builder object
+ */
+ public Builder withDstPrefix(MappingAddress dstPrefix) {
+ this.dstPrefix = dstPrefix;
+ return this;
+ }
+
+ /**
+ * Sets source mask length.
+ *
+ * @param srcMaskLength source mask length
+ * @return Builder object
+ */
+ public Builder withSrcMaskLength(byte srcMaskLength) {
+ this.srcMaskLength = srcMaskLength;
+ return this;
+ }
+
+ /**
+ * Sets destination mask length.
+ *
+ * @param dstMaskLength destination mask length
+ * @return Builder object
+ */
+ public Builder withDstMaskLength(byte dstMaskLength) {
+ this.dstMaskLength = dstMaskLength;
+ return this;
+ }
+
+ /**
+ * Builds LispSrcDstAddress instance.
+ *
+ * @return LispSrcDstAddress instance
+ */
+ public LispSrcDstAddress build() {
+
+ return new LispSrcDstAddress(srcMaskLength, dstMaskLength,
+ srcPrefix, dstPrefix);
+ }
}
}
diff --git a/drivers/lisp/src/main/java/org/onosproject/drivers/lisp/extensions/LispTeAddress.java b/drivers/lisp/src/main/java/org/onosproject/drivers/lisp/extensions/LispTeAddress.java
index 4415d30..c569e61 100644
--- a/drivers/lisp/src/main/java/org/onosproject/drivers/lisp/extensions/LispTeAddress.java
+++ b/drivers/lisp/src/main/java/org/onosproject/drivers/lisp/extensions/LispTeAddress.java
@@ -16,10 +16,24 @@
package org.onosproject.drivers.lisp.extensions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Maps;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.mapping.addresses.ASMappingAddress;
+import org.onosproject.mapping.addresses.DNMappingAddress;
+import org.onosproject.mapping.addresses.EthMappingAddress;
import org.onosproject.mapping.addresses.ExtensionMappingAddress;
import org.onosproject.mapping.addresses.ExtensionMappingAddressType;
+import org.onosproject.mapping.addresses.IPMappingAddress;
+import org.onosproject.mapping.addresses.MappingAddress;
import org.onosproject.net.flow.AbstractExtension;
+import org.onosproject.store.serializers.KryoNamespaces;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
import static org.onosproject.mapping.addresses.ExtensionMappingAddressType
.ExtensionMappingAddressTypes.TRAFFIC_ENGINEERING_ADDRESS;
@@ -30,6 +44,46 @@
*/
public final class LispTeAddress extends AbstractExtension
implements ExtensionMappingAddress {
+
+ private static final String TE_RECORDS = "records";
+
+ private List<TeRecord> records;
+
+ private KryoNamespace appKryo = new KryoNamespace.Builder()
+ .register(KryoNamespaces.API)
+ .register(MappingAddress.class)
+ .register(MappingAddress.Type.class)
+ .register(IPMappingAddress.class)
+ .register(ASMappingAddress.class)
+ .register(DNMappingAddress.class)
+ .register(EthMappingAddress.class)
+ .register(TeRecord.class)
+ .build();
+
+ /**
+ * Default constructor.
+ */
+ public LispTeAddress() {
+ }
+
+ /**
+ * Creates an instance with initialized parameters.
+ *
+ * @param records a collection of TE records
+ */
+ private LispTeAddress(List<TeRecord> records) {
+ this.records = records;
+ }
+
+ /**
+ * Obtains a collection of TE records.
+ *
+ * @return a collection of TE records
+ */
+ public List<TeRecord> getTeRecords() {
+ return ImmutableList.copyOf(records);
+ }
+
@Override
public ExtensionMappingAddressType type() {
return TRAFFIC_ENGINEERING_ADDRESS.type();
@@ -37,11 +91,224 @@
@Override
public byte[] serialize() {
- return new byte[0];
+ Map<String, Object> parameterMap = Maps.newHashMap();
+
+ parameterMap.put(TE_RECORDS, records);
+ return appKryo.serialize(parameterMap);
}
@Override
public void deserialize(byte[] data) {
+ Map<String, Object> parameterMap = appKryo.deserialize(data);
+ this.records = (List<TeRecord>) parameterMap.get(TE_RECORDS);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(records);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof LispTeAddress) {
+ final LispTeAddress other = (LispTeAddress) obj;
+ return Objects.equals(records, other.records);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("TE records", records).toString();
+ }
+
+ /**
+ * A builder for building LispTeAddress.
+ */
+ public static final class Builder {
+ private List<TeRecord> records;
+
+ /**
+ * Sets a collection of TE records.
+ *
+ * @param records a collection of TE records
+ * @return Builder object
+ */
+ public Builder withTeRecords(List<TeRecord> records) {
+ this.records = records;
+ return this;
+ }
+
+ /**
+ * Builds LispTeAddress instance.
+ *
+ * @return LispTeAddress instance
+ */
+ public LispTeAddress build() {
+ return new LispTeAddress(records);
+ }
+ }
+
+ /**
+ * Traffic engineering record class.
+ */
+ public static final class TeRecord {
+ private boolean lookup;
+ private boolean rlocProbe;
+ private boolean strict;
+ private MappingAddress address;
+
+ /**
+ *
+ *
+ * @param lookup lookup bit
+ * @param rlocProbe rloc probe bit
+ * @param strict strict bit
+ * @param address RTR address
+ */
+ private TeRecord(boolean lookup, boolean rlocProbe, boolean strict,
+ MappingAddress address) {
+ this.lookup = lookup;
+ this.rlocProbe = rlocProbe;
+ this.strict = strict;
+ this.address = address;
+ }
+
+ /**
+ * Obtains lookup bit flag.
+ *
+ * @return lookup bit flag
+ */
+ public boolean isLookup() {
+ return lookup;
+ }
+
+ /**
+ * Obtains RLOC probe bit flag.
+ *
+ * @return RLOC probe bit flag
+ */
+ public boolean isRlocProbe() {
+ return rlocProbe;
+ }
+
+ /**
+ * Obtains strict bit flag.
+ *
+ * @return strict bit flag
+ */
+ public boolean isStrict() {
+ return strict;
+ }
+
+ /**
+ * Obtains Re-encapsulated RLOC address.
+ *
+ * @return Re-encapsulated RLOC address
+ */
+ public MappingAddress getAddress() {
+ return address;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(lookup, rlocProbe, strict, address);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof TeRecord) {
+ final TeRecord other = (TeRecord) obj;
+ return Objects.equals(this.lookup, other.lookup) &&
+ Objects.equals(this.rlocProbe, other.rlocProbe) &&
+ Objects.equals(this.strict, other.strict) &&
+ Objects.equals(this.address, other.address);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("Lookup bit", lookup)
+ .add("RLOC probe bit", rlocProbe)
+ .add("strict bit", strict)
+ .add("RTR address", address)
+ .toString();
+ }
+
+ /**
+ * A builder for building TeRecord.
+ */
+ public static final class Builder {
+ private boolean lookup;
+ private boolean rlocProbe;
+ private boolean strict;
+ private MappingAddress address;
+
+ /**
+ * Sets lookup flag.
+ *
+ * @param lookup lookup flag
+ * @return Builder object
+ */
+ public Builder withIsLookup(boolean lookup) {
+ this.lookup = lookup;
+ return this;
+ }
+
+ /**
+ * Sets RLOC probe flag.
+ *
+ * @param rlocProbe RLOC probe flag
+ * @return Builder object
+ */
+ public Builder withIsRlocProbe(boolean rlocProbe) {
+ this.rlocProbe = rlocProbe;
+ return this;
+ }
+
+ /**
+ * Sets strict flag.
+ *
+ * @param strict strict flag
+ * @return Builder object
+ */
+ public Builder withIsStrict(boolean strict) {
+ this.strict = strict;
+ return this;
+ }
+
+ /**
+ * Sets RTR RLOC address.
+ *
+ * @param address RTR RLOC address
+ * @return Builder object
+ */
+ public Builder withRtrRlocAddress(MappingAddress address) {
+ this.address = address;
+ return this;
+ }
+
+ /**
+ * Builds TeRecord instance.
+ *
+ * @return TeRcord instance
+ */
+ public TeRecord build() {
+
+ return new TeRecord(lookup, rlocProbe, strict, address);
+ }
+ }
}
}
diff --git a/drivers/lisp/src/test/java/org/onosproject/drivers/lisp/extensions/LispSrcDstAddressTest.java b/drivers/lisp/src/test/java/org/onosproject/drivers/lisp/extensions/LispSrcDstAddressTest.java
new file mode 100644
index 0000000..c86c672
--- /dev/null
+++ b/drivers/lisp/src/test/java/org/onosproject/drivers/lisp/extensions/LispSrcDstAddressTest.java
@@ -0,0 +1,100 @@
+/*
+ * 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.onosproject.drivers.lisp.extensions;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.IpPrefix;
+import org.onosproject.mapping.addresses.MappingAddress;
+import org.onosproject.mapping.addresses.MappingAddresses;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+
+/**
+ * Unit tests for LispSrcDstAddress extension class.
+ */
+public class LispSrcDstAddressTest {
+
+ private static final IpPrefix IP_ADDRESS_1 = IpPrefix.valueOf("1.2.3.4/24");
+ private static final IpPrefix IP_ADDRESS_2 = IpPrefix.valueOf("5.6.7.8/24");
+
+ private static final byte MASK_LENGTH_1 = 0x01;
+ private static final byte MASK_LENGTH_2 = 0x02;
+
+ private LispSrcDstAddress address1;
+ private LispSrcDstAddress sameAsAddress1;
+ private LispSrcDstAddress address2;
+
+ @Before
+ public void setUp() {
+
+ MappingAddress ma1 = MappingAddresses.ipv4MappingAddress(IP_ADDRESS_1);
+
+ address1 = new LispSrcDstAddress.Builder()
+ .withSrcMaskLength(MASK_LENGTH_1)
+ .withDstMaskLength(MASK_LENGTH_1)
+ .withSrcPrefix(ma1)
+ .withDstPrefix(ma1)
+ .build();
+
+ sameAsAddress1 = new LispSrcDstAddress.Builder()
+ .withSrcMaskLength(MASK_LENGTH_1)
+ .withDstMaskLength(MASK_LENGTH_1)
+ .withSrcPrefix(ma1)
+ .withDstPrefix(ma1)
+ .build();
+
+ MappingAddress ma2 = MappingAddresses.ipv4MappingAddress(IP_ADDRESS_2);
+
+ address2 = new LispSrcDstAddress.Builder()
+ .withSrcMaskLength(MASK_LENGTH_2)
+ .withDstMaskLength(MASK_LENGTH_2)
+ .withSrcPrefix(ma2)
+ .withDstPrefix(ma2)
+ .build();
+ }
+
+ @Test
+ public void testEquality() {
+ new EqualsTester()
+ .addEqualityGroup(address1, sameAsAddress1)
+ .addEqualityGroup(address2).testEquals();
+ }
+
+ @Test
+ public void testConstruction() {
+ LispSrcDstAddress address = address1;
+
+ MappingAddress ma = MappingAddresses.ipv4MappingAddress(IP_ADDRESS_1);
+
+ assertThat(address.getSrcMaskLength(), is(MASK_LENGTH_1));
+ assertThat(address.getDstMaskLength(), is(MASK_LENGTH_1));
+ assertThat(address.getSrcPrefix(), is(ma));
+ assertThat(address.getDstPrefix(), is(ma));
+ }
+
+ @Test
+ public void testSerialization() {
+ LispSrcDstAddress other = new LispSrcDstAddress();
+ other.deserialize(address1.serialize());
+
+ new EqualsTester()
+ .addEqualityGroup(address1, other)
+ .testEquals();
+ }
+}
diff --git a/drivers/lisp/src/test/java/org/onosproject/drivers/lisp/extensions/LispTeAddressTest.java b/drivers/lisp/src/test/java/org/onosproject/drivers/lisp/extensions/LispTeAddressTest.java
new file mode 100644
index 0000000..afccf87
--- /dev/null
+++ b/drivers/lisp/src/test/java/org/onosproject/drivers/lisp/extensions/LispTeAddressTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.onosproject.drivers.lisp.extensions;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.testing.EqualsTester;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.IpPrefix;
+import org.onosproject.mapping.addresses.MappingAddress;
+import org.onosproject.mapping.addresses.MappingAddresses;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+
+/**
+ * Unit tests for LispTeAddress extension class.
+ */
+public class LispTeAddressTest {
+
+ private static final IpPrefix IP_ADDRESS_1 = IpPrefix.valueOf("1.2.3.4/24");
+ private static final IpPrefix IP_ADDRESS_2 = IpPrefix.valueOf("5.6.7.8/24");
+
+ private static final boolean IS_LOOKUP_1 = false;
+ private static final boolean IS_RLOC_PROBE_1 = true;
+ private static final boolean IS_STRICT_1 = false;
+
+ private static final boolean IS_LOOKUP_2 = true;
+ private static final boolean IS_RLOC_PROBE_2 = false;
+ private static final boolean IS_STRICT_2 = true;
+
+ private LispTeAddress address1;
+ private LispTeAddress sameAsAddress1;
+ private LispTeAddress address2;
+
+ @Before
+ public void setUp() {
+
+ MappingAddress ma1 = MappingAddresses.ipv4MappingAddress(IP_ADDRESS_1);
+ MappingAddress ma2 = MappingAddresses.ipv4MappingAddress(IP_ADDRESS_2);
+
+ LispTeAddress.TeRecord tr1 = new LispTeAddress.TeRecord.Builder()
+ .withIsLookup(IS_LOOKUP_1)
+ .withIsRlocProbe(IS_RLOC_PROBE_1)
+ .withIsStrict(IS_STRICT_1)
+ .withRtrRlocAddress(ma1)
+ .build();
+
+ LispTeAddress.TeRecord tr2 = new LispTeAddress.TeRecord.Builder()
+ .withIsLookup(IS_LOOKUP_2)
+ .withIsRlocProbe(IS_RLOC_PROBE_2)
+ .withIsStrict(IS_STRICT_2)
+ .withRtrRlocAddress(ma2)
+ .build();
+
+ address1 = new LispTeAddress.Builder()
+ .withTeRecords(ImmutableList.of(tr1, tr2))
+ .build();
+
+ sameAsAddress1 = new LispTeAddress.Builder()
+ .withTeRecords(ImmutableList.of(tr1, tr2))
+ .build();
+
+ address2 = new LispTeAddress.Builder()
+ .withTeRecords(ImmutableList.of(tr2, tr1))
+ .build();
+ }
+
+ @Test
+ public void testEquality() {
+ new EqualsTester()
+ .addEqualityGroup(address1, sameAsAddress1)
+ .addEqualityGroup(address2).testEquals();
+ }
+
+ @Test
+ public void testConstruction() {
+ LispTeAddress address = address1;
+
+ MappingAddress ma = MappingAddresses.ipv4MappingAddress(IP_ADDRESS_1);
+
+ assertThat(address.getTeRecords().get(0).isLookup(), is(IS_LOOKUP_1));
+ assertThat(address.getTeRecords().get(0).isRlocProbe(), is(IS_RLOC_PROBE_1));
+ assertThat(address.getTeRecords().get(0).isStrict(), is(IS_STRICT_1));
+ assertThat(address.getTeRecords().get(0).getAddress(), is(ma));
+ }
+
+ @Test
+ public void testSerialization() {
+ LispTeAddress other = new LispTeAddress();
+ other.deserialize(address1.serialize());
+
+ new EqualsTester()
+ .addEqualityGroup(address1, other)
+ .testEquals();
+ }
+}