[ONOS-6142] Add geo coordinate & list ext addresses with unit test

Change-Id: I538009b8a0d86b2d9229eae382c094a66a9b137e
diff --git a/drivers/lisp/src/main/java/org/onosproject/drivers/lisp/extensions/LispListAddress.java b/drivers/lisp/src/main/java/org/onosproject/drivers/lisp/extensions/LispListAddress.java
index 77beeee..bba2c17 100644
--- a/drivers/lisp/src/main/java/org/onosproject/drivers/lisp/extensions/LispListAddress.java
+++ b/drivers/lisp/src/main/java/org/onosproject/drivers/lisp/extensions/LispListAddress.java
@@ -16,10 +16,22 @@
 
 package org.onosproject.drivers.lisp.extensions;
 
+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.Map;
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
 import static org.onosproject.mapping.addresses.ExtensionMappingAddressType
                                 .ExtensionMappingAddressTypes.LIST_ADDRESS;
 
@@ -31,6 +43,58 @@
  */
 public class LispListAddress extends AbstractExtension
                                             implements ExtensionMappingAddress {
+
+    private static final String IPV4 = "ipv4";
+    private static final String IPV6 = "ipv6";
+
+    private MappingAddress ipv4;
+    private MappingAddress ipv6;
+
+    private final 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)
+                                                .build();
+
+    /**
+     * Default constructor.
+     */
+    public LispListAddress() {
+    }
+
+    /**
+     * Creates an instance with initialized parameters.
+     *
+     * @param ipv4 IPv4 address
+     * @param ipv6 IPv6 address
+     */
+    private LispListAddress(MappingAddress ipv4, MappingAddress ipv6) {
+        this.ipv4 = ipv4;
+        this.ipv6 = ipv6;
+    }
+
+    /**
+     * Obtains IPv4 address.
+     *
+     * @return IPv4 address
+     */
+    public MappingAddress getIpv4() {
+        return ipv4;
+    }
+
+    /**
+     * Obtains IPv6 address.
+     *
+     * @return IPv6 address
+     */
+    public MappingAddress getIpv6() {
+        return ipv6;
+    }
+
     @Override
     public ExtensionMappingAddressType type() {
         return LIST_ADDRESS.type();
@@ -38,11 +102,86 @@
 
     @Override
     public byte[] serialize() {
-        return new byte[0];
+
+        Map<String, Object> parameterMap = Maps.newHashMap();
+
+        parameterMap.put(IPV4, ipv4);
+        parameterMap.put(IPV6, ipv6);
+
+        return appKryo.serialize(parameterMap);
     }
 
     @Override
     public void deserialize(byte[] data) {
 
+        Map<String, Object> parameterMap = appKryo.deserialize(data);
+
+        this.ipv4 = (MappingAddress) parameterMap.get(IPV4);
+        this.ipv6 = (MappingAddress) parameterMap.get(IPV6);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(ipv4, ipv6);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof LispListAddress) {
+            LispListAddress that = (LispListAddress) obj;
+            return Objects.equals(ipv4, that.ipv4) &&
+                    Objects.equals(ipv6, that.ipv6);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+                .add("ipv4", ipv4)
+                .add("ipv6", ipv6)
+                .toString();
+    }
+
+    /**
+     * A builder for building LispListAddress.
+     */
+    public static final class Builder {
+        private MappingAddress ipv4;
+        private MappingAddress ipv6;
+
+        /**
+         * Sets IPv4 address.
+         *
+         * @param ipv4 IPv4 address
+         * @return Builder object
+         */
+        public Builder withIpv4(MappingAddress ipv4) {
+            this.ipv4 = ipv4;
+            return this;
+        }
+
+        /**
+         * Sets IPv6 address.
+         *
+         * @param ipv6 IPv6 address
+         * @return Builder object
+         */
+        public Builder withIpv6(MappingAddress ipv6) {
+            this.ipv6 = ipv6;
+            return this;
+        }
+
+        /**
+         * Builds LispListAddress instance.
+         *
+         * @return LispListAddress instance
+         */
+        public LispListAddress build() {
+            return new LispListAddress(ipv4, ipv6);
+        }
     }
 }