[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);
+        }
     }
 }