Library support for the Notification handling & Update processing to keep cache upto... 35/2235/1
authorMadhu Venugopal <mavenugo@gmail.com>
Tue, 29 Oct 2013 02:34:25 +0000 (19:34 -0700)
committerMadhu Venugopal <mavenugo@gmail.com>
Tue, 29 Oct 2013 02:34:25 +0000 (19:34 -0700)
Signed-off-by: Madhu Venugopal <mavenugo@gmail.com>
ovsdb/src/main/java/org/opendaylight/ovsdb/lib/jsonrpc/JsonRpcEndpoint.java
ovsdb/src/main/java/org/opendaylight/ovsdb/lib/message/OVSDB.java
ovsdb/src/main/java/org/opendaylight/ovsdb/lib/message/UpdateNotification.java [new file with mode: 0644]
ovsdb/src/main/java/org/opendaylight/ovsdb/lib/notation/json/Converter.java
ovsdb/src/test/java/org/opendaylight/ovsdb/lib/message/OVSDBNettyFactoryTest.java

index 306bb342560bf2959b94cd0faf8c2bc7d69417e0..d29afd111ad78e55c1b7bd214db961859dd935a2 100644 (file)
@@ -13,6 +13,7 @@ import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.SettableFuture;
 
 import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.ovsdb.lib.message.OVSDB;
 import org.opendaylight.ovsdb.lib.message.Response;
 import org.opendaylight.ovsdb.plugin.Connection;
 import org.opendaylight.ovsdb.plugin.ConnectionService;
@@ -20,6 +21,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
@@ -58,6 +60,7 @@ public class JsonRpcEndpoint {
     ObjectMapper objectMapper;
     ConnectionService service;
     Map<String, CallContext> methodContext = Maps.newHashMap();
+    Map<Node, OVSDB.Callback> requestCallbacks = Maps.newHashMap();
 
     public JsonRpcEndpoint(ObjectMapper objectMapper, ConnectionService service) {
         this.objectMapper = objectMapper;
@@ -69,11 +72,15 @@ public class JsonRpcEndpoint {
         return Reflection.newProxy(klazz, new InvocationHandler() {
             @Override
             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+                if (method.getName().equals(OVSDB.REGISTER_CALLBACK_METHOD)) {
+                    if ((args == null) || args.length != 1 || !(args[0] instanceof OVSDB.Callback)) return false;
+                    requestCallbacks.put(node, (OVSDB.Callback)args[0]);
+                    return true;
+                }
 
                 JsonRpc10Request request = new JsonRpc10Request(UUID.randomUUID().toString());
                 request.setMethod(method.getName());
 
-
                 if (args != null && args.length != 0) {
                     List<Object> params = null;
 
@@ -137,10 +144,27 @@ public class JsonRpcEndpoint {
     public void processRequest(Node node, JsonNode requestJson) {
         JsonRpc10Request request = new JsonRpc10Request(requestJson.get("id").asText());
         request.setMethod(requestJson.get("method").asText());
+        logger.debug("Request : {} {}", requestJson.get("method"), requestJson.get("params"));
+        OVSDB.Callback callback = requestCallbacks.get(node);
+        if (callback != null) {
+            Method[] methods = callback.getClass().getDeclaredMethods();
+            for (Method m : methods) {
+                if (m.getName().equals(request.getMethod())) {
+                    Class<?>[] parameters = m.getParameterTypes();
+                    JsonNode params = requestJson.get("params");
+                    Object param = objectMapper.convertValue(params, parameters[1]);
+                    try {
+                        m.invoke(callback, node, param);
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                    return;
+                }
+            }
+        }
+
+        // Echo dont need any special processing. hence handling it internally.
 
-        // TODO : Take care of listener interested in the async message from ovsdb-server
-        // and return a result to be sent back.
-        // The following piece of code will help with ECHO handling as is.
         if (request.getMethod().equals("echo")) {
             JsonRpc10Response response = new JsonRpc10Response(request.getId());
             response.setError(null);
@@ -152,6 +176,8 @@ public class JsonRpcEndpoint {
                 e.printStackTrace();
             }
         }
+
+        logger.error("No handler for Request : {} on {}",requestJson.toString(), node);
     }
 
     public Map<String, CallContext> getMethodContext() {
index 763a0cb3481526f1459c833f8f7a3135810eaf23..4c0ce4cb4dcc4b44cd21b738e3b9684e3e7f6cc7 100644 (file)
@@ -9,6 +9,7 @@ import org.opendaylight.ovsdb.lib.database.DatabaseSchema;
 import org.opendaylight.ovsdb.lib.message.operations.OperationResult;
 
 public interface OVSDB {
+    public static final String REGISTER_CALLBACK_METHOD = "registerCallback";
 
     public ListenableFuture<DatabaseSchema> get_schema(List<String> db_names);
 
@@ -29,13 +30,12 @@ public interface OVSDB {
     public ListenableFuture<Object> steal(List<String> id);
 
     public ListenableFuture<Object> unlock(List<String> id);
-/*
-    public void registerListener(Callback callback);
+
+    public boolean registerCallback(Callback callback);
 
     public static interface Callback {
-        public void update(Node node, TableUpdates upadate);
+        public void update(Node node, UpdateNotification upadateNotification);
         public void locked(Node node, Object json_value);
-        public void echo(Node node, Object json_value);
+        // public void echo(Node node, Object json_value);
     }
-*/
 }
diff --git a/ovsdb/src/main/java/org/opendaylight/ovsdb/lib/message/UpdateNotification.java b/ovsdb/src/main/java/org/opendaylight/ovsdb/lib/message/UpdateNotification.java
new file mode 100644 (file)
index 0000000..f9f0778
--- /dev/null
@@ -0,0 +1,22 @@
+package org.opendaylight.ovsdb.lib.message;
+
+import org.opendaylight.ovsdb.lib.notation.json.Converter.UpdateNotificationConverter;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+
+@JsonDeserialize(converter = UpdateNotificationConverter.class)
+public class UpdateNotification {
+    Object context;
+    TableUpdates update;
+    public Object getContext() {
+        return context;
+    }
+    public void setContext(Object context) {
+        this.context = context;
+    }
+    public TableUpdates getUpdate() {
+        return update;
+    }
+    public void setUpdate(TableUpdates update) {
+        this.update = update;
+    }
+}
index 22479fc4f5d208fbe864a9f9627727796df8df95..7098f72275a505da4617fe16ce75dd08fbb7b00d 100644 (file)
@@ -1,8 +1,12 @@
 package org.opendaylight.ovsdb.lib.notation.json;
 
+import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.util.StdConverter;
 
+import org.opendaylight.ovsdb.lib.message.TableUpdates;
+import org.opendaylight.ovsdb.lib.message.UpdateNotification;
 import org.opendaylight.ovsdb.lib.notation.OvsDBMap;
 import org.opendaylight.ovsdb.lib.notation.OvsDBSet;
 import org.opendaylight.ovsdb.lib.notation.UUID;
@@ -12,6 +16,7 @@ public class Converter {
     static AtomDeser atomDeser = new AtomDeser();
     static MapDeser mapDeser = new MapDeser();
     static SetDeser setDeser = new SetDeser();
+    static UpdateNotificationDeser unDeser = new UpdateNotificationDeser();
 
     public static class MapConverter extends StdConverter<JsonNode, OvsDBMap<Object, Object>> {
         @Override
@@ -27,6 +32,13 @@ public class Converter {
         }
     }
 
+    public static class UpdateNotificationConverter extends StdConverter<JsonNode, UpdateNotification> {
+        @Override
+        public UpdateNotification convert(JsonNode value) {
+            return unDeser.deserialize(value);
+        }
+    }
+
     static class MapDeser {
         public OvsDBMap<Object, Object> deserialize(JsonNode node) {
             if (node.isArray()) {
@@ -74,6 +86,22 @@ public class Converter {
         }
     }
 
+    static class UpdateNotificationDeser {
+        public UpdateNotification deserialize(JsonNode node) {
+            UpdateNotification un = new UpdateNotification();
+            if (node.isArray()) {
+                if (node.size() == 2) {
+                    un.setContext(node.get(0).asText());
+                    ObjectMapper objectMapper = new ObjectMapper();
+                    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+                    TableUpdates updates = objectMapper.convertValue(node.get(1), TableUpdates.class);
+                    un.setUpdate(updates);
+                    return un;
+                }
+            }
+            return null;
+        }
+    }
 
     static class AtomDeser {
 
index 4615e0d98518f4ca032320c5634cd7997346ebce..46cd5aac24b318ae6c51f10bdb6e2eb3359de834 100644 (file)
@@ -47,11 +47,13 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ExecutionException;
 
-public class OVSDBNettyFactoryTest {
+public class OVSDBNettyFactoryTest implements OVSDB.Callback {
+    InventoryServiceInternal inventoryService;
+    private static String bridgeIdentifier = "br1";
     @Test
     public void testSome() throws InterruptedException, ExecutionException {
         ConnectionService service = new ConnectionService();
-        InventoryServiceInternal inventoryService = new InventoryService();
+        inventoryService = new InventoryService();
         ObjectMapper objectMapper = new ObjectMapper();
         objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
         JsonRpcEndpoint factory = new JsonRpcEndpoint(objectMapper, service);
@@ -76,6 +78,7 @@ public class OVSDBNettyFactoryTest {
         }
 
         OVSDB ovsdb = factory.getClient(node, OVSDB.class);
+        ovsdb.registerCallback(this);
 
         //GET DB-SCHEMA
         List<String> dbNames = Arrays.asList(Open_vSwitch.NAME.getName());
@@ -103,7 +106,6 @@ public class OVSDBNettyFactoryTest {
         String newPort = "new_port";
         String newSwitch = "new_switch";
 
-        String bridgeIdentifier = "br1";
         Operation addSwitchRequest = null;
 
         if(ovsTable != null){
@@ -169,8 +171,17 @@ public class OVSDBNettyFactoryTest {
 
         // TEST ECHO REQUEST/REPLY
 
-        Thread.sleep(10);
         service.disconnect(node);
     }
 
+    @Override
+    public void update(Node node, UpdateNotification updateNotification) {
+        inventoryService.processTableUpdates(node, updateNotification.getUpdate());
+        inventoryService.printCache(node);
+    }
+
+    @Override
+    public void locked(Node node, Object json_value) {
+    }
+
 }