1 package org.opendaylight.ovsdb.lib.jsonrpc;
3 import com.fasterxml.jackson.core.JsonProcessingException;
4 import com.fasterxml.jackson.databind.JavaType;
5 import com.fasterxml.jackson.databind.JsonNode;
6 import com.fasterxml.jackson.databind.ObjectMapper;
7 import com.fasterxml.jackson.databind.node.ArrayNode;
8 import com.fasterxml.jackson.databind.type.TypeFactory;
9 import com.google.common.collect.Maps;
10 import com.google.common.reflect.Reflection;
11 import com.google.common.reflect.TypeToken;
12 import com.google.common.util.concurrent.ListenableFuture;
13 import com.google.common.util.concurrent.SettableFuture;
15 import org.opendaylight.controller.sal.core.Node;
16 import org.opendaylight.ovsdb.lib.message.Response;
17 import org.opendaylight.ovsdb.plugin.Connection;
18 import org.opendaylight.ovsdb.plugin.ConnectionService;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
22 import java.lang.reflect.InvocationHandler;
23 import java.lang.reflect.Method;
24 import java.lang.reflect.Type;
25 import java.util.ArrayList;
26 import java.util.List;
28 import java.util.UUID;
30 public class JsonRpcEndpoint {
32 protected static final Logger logger = LoggerFactory.getLogger(JsonRpcEndpoint.class);
34 public class CallContext {
36 JsonRpc10Request request;
37 SettableFuture<Object> future;
39 public CallContext(JsonRpc10Request request, Method method, SettableFuture<Object> future) {
41 this.request = request;
45 public Method getMethod() {
49 public JsonRpc10Request getRequest() {
53 public SettableFuture<Object> getFuture() {
58 ObjectMapper objectMapper;
59 ConnectionService service;
60 Map<String, CallContext> methodContext = Maps.newHashMap();
62 public JsonRpcEndpoint(ObjectMapper objectMapper, ConnectionService service) {
63 this.objectMapper = objectMapper;
64 this.service = service;
67 public <T> T getClient(final Node node, Class<T> klazz) {
69 return Reflection.newProxy(klazz, new InvocationHandler() {
71 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
73 JsonRpc10Request request = new JsonRpc10Request(UUID.randomUUID().toString());
74 request.setMethod(method.getName());
77 if (args != null && args.length != 0) {
78 List<Object> params = null;
80 if (args.length == 1) {
81 if (args[0] instanceof Params) {
82 params = ((Params) args[0]).params();
83 } else if (args[0] instanceof List) {
84 params = (List<Object>) args[0];
88 throw new RuntimeException("do not understand this argument yet");
90 request.setParams(params);
94 String s = objectMapper.writeValueAsString(request);
95 logger.debug("{}", s);
97 SettableFuture<Object> sf = SettableFuture.create();
98 methodContext.put(request.getId(), new CallContext(request, method, sf));
100 Connection connection = service.getConnection(node);
101 connection.getChannel().writeAndFlush(s);
109 @SuppressWarnings("deprecation")
110 public void processResult(JsonNode response) throws NoSuchMethodException {
112 CallContext returnCtxt = methodContext.get(response.get("id").asText());
113 if (returnCtxt == null) return;
115 if (ListenableFuture.class == returnCtxt.getMethod().getReturnType()) {
116 TypeToken<?> retType = TypeToken.of(
117 returnCtxt.getMethod().getGenericReturnType())
118 .resolveType(ListenableFuture.class.getMethod("get").getGenericReturnType());
119 JavaType javaType = TypeFactory.defaultInstance().constructType (retType.getType());
121 JsonNode result = response.get("result");
122 logger.debug("Response : {}", result.toString());
124 Object result1 = objectMapper.convertValue(result, javaType);
125 JsonNode error = response.get("error");
127 logger.debug("Error : {}", error.toString());
130 returnCtxt.getFuture().set(result1);
133 throw new RuntimeException("donno how to deal with this");
137 public void processRequest(Node node, JsonNode requestJson) {
138 JsonRpc10Request request = new JsonRpc10Request(requestJson.get("id").asText());
139 request.setMethod(requestJson.get("method").asText());
141 // TODO : Take care of listener interested in the async message from ovsdb-server
142 // and return a result to be sent back.
143 // The following piece of code will help with ECHO handling as is.
144 if (request.getMethod().equals("echo")) {
145 JsonRpc10Response response = new JsonRpc10Response(request.getId());
146 response.setError(null);
148 String s = objectMapper.writeValueAsString(response);
149 Connection connection = service.getConnection(node);
150 connection.getChannel().writeAndFlush(s);
151 } catch (JsonProcessingException e) {
157 public Map<String, CallContext> getMethodContext() {
158 return methodContext;