Added support for class hierarchies in the notification system.
This is done using Kryo's writeClassAndObject/readClassAndObject, which
doesn't rely on the caller specifying the class.

Also, paramterized the Class class in some places to prevent Java warning
about using raw types.

Change-Id: Ib05465c412bf7fe0c3269896cc20527082f591a6
diff --git a/src/main/java/net/onrc/onos/core/datagrid/HazelcastEventChannel.java b/src/main/java/net/onrc/onos/core/datagrid/HazelcastEventChannel.java
index 4b67b31..5774af2 100644
--- a/src/main/java/net/onrc/onos/core/datagrid/HazelcastEventChannel.java
+++ b/src/main/java/net/onrc/onos/core/datagrid/HazelcastEventChannel.java
@@ -8,6 +8,9 @@
 
 import net.onrc.onos.core.util.serializers.KryoFactory;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import com.esotericsoftware.kryo.Kryo;
 import com.esotericsoftware.kryo.io.Input;
 import com.esotericsoftware.kryo.io.Output;
@@ -23,6 +26,9 @@
  * @param <V> The class type of the value.
  */
 public class HazelcastEventChannel<K, V> implements IEventChannel<K, V> {
+    private static final Logger log =
+            LoggerFactory.getLogger(HazelcastEventChannel.class);
+
     private final HazelcastInstance hazelcastInstance; // The Hazelcast instance
     private final String channelName;        // The event channel name
     private final Class<K> typeK;            // The class type of the key
@@ -68,8 +74,8 @@
      * otherwise false.
      */
     @Override
-    public boolean verifyKeyValueTypes(Class typeKToVerify,
-                                       Class typeVToVerify) {
+    public boolean verifyKeyValueTypes(Class<?> typeKToVerify,
+                                       Class<?> typeVToVerify) {
         return (typeK.equals(typeKToVerify)) && (typeV.equals(typeVToVerify));
     }
 
@@ -178,7 +184,7 @@
         byte[] buffer = new byte[MAX_BUFFER_SIZE];
         Kryo kryo = kryoFactory.newKryo();
         Output output = new Output(buffer, -1);
-        kryo.writeObject(output, value);
+        kryo.writeClassAndObject(output, value);
         byte[] valueBytes = output.toBytes();
         kryoFactory.deleteKryo(kryo);
 
@@ -309,7 +315,15 @@
             byte[] valueBytes = event.getValue();
             Kryo kryo = kryoFactory.newKryo();
             Input input = new Input(valueBytes);
-            V value = (V) kryo.readObject(input, typeV);
+
+            Object objValue = kryo.readClassAndObject(input);
+            V value;
+            try {
+                value = typeV.cast(objValue);
+            } catch (ClassCastException e) {
+                log.error("Received notification value cast failed", e);
+                return;
+            }
 
             //
             // Deliver the notification
@@ -339,7 +353,15 @@
             byte[] valueBytes = event.getValue();
             Kryo kryo = kryoFactory.newKryo();
             Input input = new Input(valueBytes);
-            V value = (V) kryo.readObject(input, typeV);
+
+            Object objValue = kryo.readClassAndObject(input);
+            V value;
+            try {
+                value = typeV.cast(objValue);
+            } catch (ClassCastException e) {
+                log.error("Received notification value cast failed", e);
+                return;
+            }
 
             //
             // Deliver the notification
@@ -369,7 +391,15 @@
             byte[] valueBytes = event.getValue();
             Kryo kryo = kryoFactory.newKryo();
             Input input = new Input(valueBytes);
-            V value = (V) kryo.readObject(input, typeV);
+
+            Object objValue = kryo.readClassAndObject(input);
+            V value;
+            try {
+                value = typeV.cast(objValue);
+            } catch (ClassCastException e) {
+                log.error("Received notification value cast failed", e);
+                return;
+            }
 
             //
             // Deliver the notification
diff --git a/src/main/java/net/onrc/onos/core/datagrid/IEventChannel.java b/src/main/java/net/onrc/onos/core/datagrid/IEventChannel.java
index 5874b31..0c1663a 100644
--- a/src/main/java/net/onrc/onos/core/datagrid/IEventChannel.java
+++ b/src/main/java/net/onrc/onos/core/datagrid/IEventChannel.java
@@ -24,7 +24,7 @@
      * @return true if the key and value types of the channel match,
      * otherwise false.
      */
-    boolean verifyKeyValueTypes(Class typeK, Class typeV);
+    boolean verifyKeyValueTypes(Class<?> typeK, Class<?> typeV);
 
     /**
      * Add event channel listener.