1 package org.opendaylight.ovsdb.lib.jsonrpc;
3 import com.fasterxml.jackson.core.JsonProcessingException;
4 import com.fasterxml.jackson.databind.JsonNode;
5 import com.fasterxml.jackson.databind.ObjectMapper;
6 import com.fasterxml.jackson.databind.node.ArrayNode;
7 import com.google.common.collect.Maps;
8 import com.google.common.reflect.Reflection;
9 import com.google.common.reflect.TypeToken;
10 import com.google.common.util.concurrent.ListenableFuture;
11 import com.google.common.util.concurrent.SettableFuture;
13 import org.opendaylight.controller.sal.core.Node;
14 import org.opendaylight.ovsdb.lib.message.Response;
15 import org.opendaylight.ovsdb.plugin.Connection;
16 import org.opendaylight.ovsdb.plugin.ConnectionService;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
20 import java.lang.reflect.InvocationHandler;
21 import java.lang.reflect.Method;
22 import java.util.ArrayList;
23 import java.util.List;
25 import java.util.UUID;
27 public class JsonRpcEndpoint {
29 protected static final Logger logger = LoggerFactory.getLogger(JsonRpcEndpoint.class);
31 public class CallContext {
33 JsonRpc10Request request;
34 SettableFuture<Object> future;
36 public CallContext(JsonRpc10Request request, Method method, SettableFuture<Object> future) {
38 this.request = request;
42 public Method getMethod() {
46 public JsonRpc10Request getRequest() {
50 public SettableFuture<Object> getFuture() {
55 ObjectMapper objectMapper;
56 ConnectionService service;
57 Map<String, CallContext> methodContext = Maps.newHashMap();
59 public JsonRpcEndpoint(ObjectMapper objectMapper, ConnectionService service) {
60 this.objectMapper = objectMapper;
61 this.service = service;
64 public <T> T getClient(final Node node, Class<T> klazz) {
66 return Reflection.newProxy(klazz, new InvocationHandler() {
68 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
70 JsonRpc10Request request = new JsonRpc10Request(UUID.randomUUID().toString());
71 request.setMethod(method.getName());
74 if (args != null && args.length != 0) {
75 List<Object> params = null;
77 if (args.length == 1) {
78 if (args[0] instanceof Params) {
79 params = ((Params) args[0]).params();
80 } else if (args[0] instanceof List) {
81 params = (List<Object>) args[0];
85 throw new RuntimeException("do not understand this argument yet");
87 request.setParams(params);
91 String s = objectMapper.writeValueAsString(request);
92 logger.debug("{}", s);
94 SettableFuture<Object> sf = SettableFuture.create();
95 methodContext.put(request.getId(), new CallContext(request, method, sf));
97 Connection connection = service.getConnection(node);
98 connection.getChannel().writeAndFlush(s);
106 public void processResult(JsonNode response) throws NoSuchMethodException {
108 CallContext returnCtxt = methodContext.get(response.get("id").asText());
109 if (returnCtxt == null) return;
111 Class<?> returnType = null;
112 if (ListenableFuture.class == returnCtxt.getMethod().getReturnType()) {
113 TypeToken<?> retType = TypeToken.of(
114 returnCtxt.getMethod().getGenericReturnType())
115 .resolveType(ListenableFuture.class.getMethod("get").getGenericReturnType());
117 JsonNode result = response.get("result");
118 logger.debug("Response : {}", result.toString());
119 Object result1 = objectMapper.convertValue(result, retType.getRawType());
120 JsonNode error = response.get("error");
122 logger.debug("Error : {}", error.toString());
125 returnCtxt.getFuture().set(result1);
128 throw new RuntimeException("donno how to deal with this");
132 public void processRequest(Node node, JsonNode requestJson) {
133 JsonRpc10Request request = new JsonRpc10Request(requestJson.get("id").asText());
134 request.setMethod(requestJson.get("method").asText());
136 // TODO : Take care of listener interested in the async message from ovsdb-server
137 // and return a result to be sent back.
138 // The following piece of code will help with ECHO handling as is.
139 JsonRpc10Response response = new JsonRpc10Response(request.getId());
140 response.setError(null);
142 String s = objectMapper.writeValueAsString(response);
143 Connection connection = service.getConnection(node);
144 connection.getChannel().writeAndFlush(s);
145 } catch (JsonProcessingException e) {
150 public Map<String, CallContext> getMethodContext() {
151 return methodContext;