Kryo related changes.

Change-Id: I5b4fab63d6ece084b65aa712971a22d953d0caf0
diff --git a/core/api/src/main/java/org/onlab/onos/net/DeviceId.java b/core/api/src/main/java/org/onlab/onos/net/DeviceId.java
index ef8c5ab..8d96d8b 100644
--- a/core/api/src/main/java/org/onlab/onos/net/DeviceId.java
+++ b/core/api/src/main/java/org/onlab/onos/net/DeviceId.java
@@ -7,6 +7,9 @@
  */
 public final class DeviceId extends ElementId {
 
+    // Default constructor for serialization
+    protected DeviceId() {}
+
     // Public construction is prohibited
     private DeviceId(URI uri) {
         super(uri);
diff --git a/core/api/src/main/java/org/onlab/onos/net/ElementId.java b/core/api/src/main/java/org/onlab/onos/net/ElementId.java
index e205bb6..a75f11e 100644
--- a/core/api/src/main/java/org/onlab/onos/net/ElementId.java
+++ b/core/api/src/main/java/org/onlab/onos/net/ElementId.java
@@ -10,6 +10,11 @@
 
     private final URI uri;
 
+    // Default constructor for serialization
+    protected ElementId() {
+        this.uri = null;
+    }
+
     /**
      * Creates an element identifier using the supplied URI.
      *
diff --git a/core/api/src/main/java/org/onlab/onos/net/provider/ProviderId.java b/core/api/src/main/java/org/onlab/onos/net/provider/ProviderId.java
index e9af0eb..5fc0150 100644
--- a/core/api/src/main/java/org/onlab/onos/net/provider/ProviderId.java
+++ b/core/api/src/main/java/org/onlab/onos/net/provider/ProviderId.java
@@ -12,6 +12,12 @@
     private final String scheme;
     private final String id;
 
+    // Default constructor for serialization
+    protected ProviderId() {
+        scheme = null;
+        id = null;
+    }
+
     /**
      * Creates a new provider identifier from the specified string.
      * The providers are expected to follow the reverse DNS convention, e.g.
diff --git a/core/store/pom.xml b/core/store/pom.xml
index cf01c5a..246355c 100644
--- a/core/store/pom.xml
+++ b/core/store/pom.xml
@@ -25,6 +25,14 @@
             <groupId>org.apache.felix</groupId>
             <artifactId>org.apache.felix.scr.annotations</artifactId>
         </dependency>
+        <dependency>
+          <groupId>com.hazelcast</groupId>
+          <artifactId>hazelcast</artifactId>
+        </dependency>
+        <dependency>
+          <groupId>de.javakaffee</groupId>
+          <artifactId>kryo-serializers</artifactId>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/core/store/src/main/java/org/onlab/onos/store/device/impl/DefaultPortSerializer.java b/core/store/src/main/java/org/onlab/onos/store/device/impl/DefaultPortSerializer.java
new file mode 100644
index 0000000..4a60eb8
--- /dev/null
+++ b/core/store/src/main/java/org/onlab/onos/store/device/impl/DefaultPortSerializer.java
@@ -0,0 +1,53 @@
+package org.onlab.onos.store.device.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.onlab.onos.net.DefaultPort;
+import org.onlab.onos.net.Element;
+import org.onlab.onos.net.PortNumber;
+import org.onlab.packet.IpPrefix;
+
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryo.Serializer;
+import com.esotericsoftware.kryo.io.Input;
+import com.esotericsoftware.kryo.io.Output;
+import com.esotericsoftware.kryo.serializers.CollectionSerializer;
+import com.google.common.collect.ImmutableSet;
+
+// TODO move to util, etc.
+public final class DefaultPortSerializer extends
+        Serializer<DefaultPort> {
+
+    private final CollectionSerializer ipAddrSerializer
+        = new CollectionSerializer(IpPrefix.class,
+                            new IpPrefixSerializer(), false);
+
+    public DefaultPortSerializer() {
+        // non-null, immutable
+        super(false, true);
+    }
+
+    @Override
+    public void write(Kryo kryo, Output output, DefaultPort object) {
+        kryo.writeClassAndObject(output, object.element());
+        kryo.writeObject(output, object.number());
+        output.writeBoolean(object.isEnabled());
+        kryo.writeObject(output, object.ipAddresses(),
+                ipAddrSerializer);
+    }
+
+    @Override
+    public DefaultPort read(Kryo kryo, Input input,
+            Class<DefaultPort> type) {
+        Element element = (Element) kryo.readClassAndObject(input);
+        PortNumber number = kryo.readObject(input, PortNumber.class);
+        boolean isEnabled = input.readBoolean();
+        @SuppressWarnings("unchecked")
+        Collection<IpPrefix> ipAddresses = kryo.readObject(
+                    input, ArrayList.class, ipAddrSerializer);
+
+        return new DefaultPort(element, number, isEnabled,
+                            ImmutableSet.copyOf(ipAddresses));
+    }
+}
diff --git a/core/store/src/main/java/org/onlab/onos/store/device/impl/IpPrefixSerializer.java b/core/store/src/main/java/org/onlab/onos/store/device/impl/IpPrefixSerializer.java
new file mode 100644
index 0000000..3d3efe0
--- /dev/null
+++ b/core/store/src/main/java/org/onlab/onos/store/device/impl/IpPrefixSerializer.java
@@ -0,0 +1,36 @@
+package org.onlab.onos.store.device.impl;
+
+import org.onlab.packet.IpPrefix;
+
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryo.Serializer;
+import com.esotericsoftware.kryo.io.Input;
+import com.esotericsoftware.kryo.io.Output;
+
+// TODO move to util, etc.
+public final class IpPrefixSerializer extends Serializer<IpPrefix> {
+
+    public IpPrefixSerializer() {
+        // non-null, immutable
+        super(false, true);
+    }
+
+    @Override
+    public void write(Kryo kryo, Output output,
+            IpPrefix object) {
+        byte[] octs = object.toOctets();
+        output.writeInt(octs.length);
+        output.writeBytes(octs);
+        output.writeInt(object.prefixLength());
+    }
+
+    @Override
+    public IpPrefix read(Kryo kryo, Input input,
+            Class<IpPrefix> type) {
+        int octLen = input.readInt();
+        byte[] octs = new byte[octLen];
+        input.read(octs);
+        int prefLen = input.readInt();
+        return IpPrefix.valueOf(octs, prefLen);
+    }
+}
diff --git a/core/store/src/main/java/org/onlab/onos/store/device/impl/PortNumberSerializer.java b/core/store/src/main/java/org/onlab/onos/store/device/impl/PortNumberSerializer.java
new file mode 100644
index 0000000..4483187
--- /dev/null
+++ b/core/store/src/main/java/org/onlab/onos/store/device/impl/PortNumberSerializer.java
@@ -0,0 +1,29 @@
+package org.onlab.onos.store.device.impl;
+
+import org.onlab.onos.net.PortNumber;
+
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryo.Serializer;
+import com.esotericsoftware.kryo.io.Input;
+import com.esotericsoftware.kryo.io.Output;
+
+// TODO move to util, etc.
+public final class PortNumberSerializer extends
+        Serializer<PortNumber> {
+
+    public PortNumberSerializer() {
+        // non-null, immutable
+        super(false, true);
+    }
+
+    @Override
+    public void write(Kryo kryo, Output output, PortNumber object) {
+        output.writeLong(object.toLong());
+    }
+
+    @Override
+    public PortNumber read(Kryo kryo, Input input,
+            Class<PortNumber> type) {
+        return PortNumber.portNumber(input.readLong());
+    }
+}