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;
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;
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;
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;
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);
e.printStackTrace();
}
}
+
+ logger.error("No handler for Request : {} on {}",requestJson.toString(), node);
}
public Map<String, CallContext> getMethodContext() {
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);
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);
}
-*/
}
--- /dev/null
+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;
+ }
+}
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;
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
}
}
+ 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()) {
}
}
+ 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 {
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);
}
OVSDB ovsdb = factory.getClient(node, OVSDB.class);
+ ovsdb.registerCallback(this);
//GET DB-SCHEMA
List<String> dbNames = Arrays.asList(Open_vSwitch.NAME.getName());
String newPort = "new_port";
String newSwitch = "new_switch";
- String bridgeIdentifier = "br1";
Operation addSwitchRequest = null;
if(ovsTable != null){
// 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) {
+ }
+
}