From c5e4337f496dd4a9ef2ef2dac9a783e2e2be2d66 Mon Sep 17 00:00:00 2001 From: lresende Date: Tue, 5 May 2009 07:22:02 +0000 Subject: TUSCANY-2968 - JSONRPC invocation using operation selector and wire formats working end to end git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@771601 13f79535-47bb-0310-9956-ffa450edef68 --- .../JSONRPCOperationSelectorInterceptor.java | 58 ++++++++++++ .../provider/JSONRPCWireFormatInterceptor.java | 103 ++++++++++++++++++++- 2 files changed, 160 insertions(+), 1 deletion(-) (limited to 'branches/sca-java-1.x/modules/binding-http-new-jsonrpc-runtime/src') diff --git a/branches/sca-java-1.x/modules/binding-http-new-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/http/operationselector/jsonrpc/provider/JSONRPCOperationSelectorInterceptor.java b/branches/sca-java-1.x/modules/binding-http-new-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/http/operationselector/jsonrpc/provider/JSONRPCOperationSelectorInterceptor.java index 094a27d7a2..fb7c009aac 100644 --- a/branches/sca-java-1.x/modules/binding-http-new-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/http/operationselector/jsonrpc/provider/JSONRPCOperationSelectorInterceptor.java +++ b/branches/sca-java-1.x/modules/binding-http-new-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/http/operationselector/jsonrpc/provider/JSONRPCOperationSelectorInterceptor.java @@ -19,11 +19,18 @@ package org.apache.tuscany.sca.binding.http.operationselector.jsonrpc.provider; +import java.io.CharArrayWriter; +import java.util.List; + import org.apache.tuscany.sca.binding.http.HTTPBinding; +import org.apache.tuscany.sca.interfacedef.Operation; import org.apache.tuscany.sca.invocation.Interceptor; import org.apache.tuscany.sca.invocation.Invoker; import org.apache.tuscany.sca.invocation.Message; import org.apache.tuscany.sca.runtime.RuntimeWire; +import org.json.JSONObject; + +import com.metaparadigm.jsonrpc.JSONRPCResult; public class JSONRPCOperationSelectorInterceptor implements Interceptor { private Invoker next; @@ -31,6 +38,7 @@ public class JSONRPCOperationSelectorInterceptor implements Interceptor { private RuntimeWire runtimeWire; private HTTPBinding binding; + //TODO: Pass messageFactory to create fault messages when error occur public JSONRPCOperationSelectorInterceptor(HTTPBinding binding, RuntimeWire runtimeWire) { this.binding = binding; this.runtimeWire = runtimeWire; @@ -46,7 +54,57 @@ public class JSONRPCOperationSelectorInterceptor implements Interceptor { } public Message invoke(Message msg) { + + JSONObject jsonReq = null; + String method = null; + try { + Object[] args = msg.getBody(); + CharArrayWriter data = (CharArrayWriter) args[0]; + jsonReq = new JSONObject(data.toString()); + method = jsonReq.getString("method"); + } catch (Exception e) { + //FIXME Exceptions are not handled correctly here + // They should be reported to the client JavaScript as proper + // JavaScript exceptions. + throw new RuntimeException("Unable to parse request", e); + + //FIXME should create a fault message and stuff the JSON Result in the body of the message + //JSONRPCResult errorResult = new JSONRPCResult(JSONRPCResult.CODE_ERR_PARSE, null, e); + //return errorResult; + } + + Operation jsonOperation = findOperation(method); + msg.setOperation(jsonOperation); + msg.setBody(jsonReq); + return getNext().invoke(msg); } + + /** + * Find the operation from the component service contract + * @param componentService + * @param method + * @return + */ + private Operation findOperation(String method) { + if (method.contains(".")) { + method = method.substring(method.lastIndexOf(".") + 1); + } + + List operations = runtimeWire.getTarget().getInterfaceContract().getInterface().getOperations(); + //serviceContract.getInterface().getOperations(); + //componentService.getBindingProvider(binding).getBindingInterfaceContract().getInterface().getOperations(); + + + Operation result = null; + for (Operation o : operations) { + if (o.getName().equalsIgnoreCase(method)) { + result = o; + break; + } + } + + return result; + } } diff --git a/branches/sca-java-1.x/modules/binding-http-new-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/http/wireformat/jsonrpc/provider/JSONRPCWireFormatInterceptor.java b/branches/sca-java-1.x/modules/binding-http-new-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/http/wireformat/jsonrpc/provider/JSONRPCWireFormatInterceptor.java index 5778a2908c..80277c0e95 100644 --- a/branches/sca-java-1.x/modules/binding-http-new-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/http/wireformat/jsonrpc/provider/JSONRPCWireFormatInterceptor.java +++ b/branches/sca-java-1.x/modules/binding-http-new-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/http/wireformat/jsonrpc/provider/JSONRPCWireFormatInterceptor.java @@ -19,11 +19,23 @@ package org.apache.tuscany.sca.binding.http.wireformat.jsonrpc.provider; +import java.util.List; + import org.apache.tuscany.sca.binding.http.HTTPBinding; +import org.apache.tuscany.sca.databinding.javabeans.SimpleJavaDataBinding; +import org.apache.tuscany.sca.databinding.json.JSONDataBinding; +import org.apache.tuscany.sca.interfacedef.DataType; +import org.apache.tuscany.sca.interfacedef.Interface; +import org.apache.tuscany.sca.interfacedef.Operation; import org.apache.tuscany.sca.invocation.Interceptor; import org.apache.tuscany.sca.invocation.Invoker; import org.apache.tuscany.sca.invocation.Message; import org.apache.tuscany.sca.runtime.RuntimeWire; +import org.json.JSONArray; +import org.json.JSONObject; +import org.osoa.sca.ServiceRuntimeException; + +import com.metaparadigm.jsonrpc.JSONRPCResult; public class JSONRPCWireFormatInterceptor implements Interceptor { private Invoker next; @@ -31,6 +43,7 @@ public class JSONRPCWireFormatInterceptor implements Interceptor { private RuntimeWire runtimeWire; private HTTPBinding binding; + //TODO: Pass messageFactory to create fault messages when error occur public JSONRPCWireFormatInterceptor(HTTPBinding binding, RuntimeWire runtimeWire) { this.binding = binding; this.runtimeWire = runtimeWire; @@ -47,7 +60,95 @@ public class JSONRPCWireFormatInterceptor implements Interceptor { } public Message invoke(Message msg) { - return getNext().invoke(msg); + + // Configure JSON Databding + setDataBinding(runtimeWire.getTarget().getInterfaceContract().getInterface()); + + JSONObject jsonReq = (JSONObject) msg.getBody(); + String method = null; + Object[] args = null; + Object id = null; + try { + // Extract the method + method = jsonReq.getString("method"); + if ((method != null) && (method.indexOf('.') < 0)) { + jsonReq.putOpt("method", "Service" + "." + method); + } + + // Extract the arguments + JSONArray array = jsonReq.getJSONArray("params"); + args = new Object[array.length()]; + for (int i = 0; i < args.length; i++) { + args[i] = array.get(i); + } + id = jsonReq.get("id"); + + } catch (Exception e) { + throw new RuntimeException("Unable to find json method name", e); + } + + Message responseMessage = null; + try { + msg.setBody(args); + responseMessage = runtimeWire.getInvocationChain(msg.getOperation()).getHeadInvoker().invoke(msg); + } catch (RuntimeException re) { + //FIXME Exceptions are not handled correctly here + // They should be reported to the client JavaScript as proper + // JavaScript exceptions. + + throw new RuntimeException("Error invoking service :" + re.getMessage(), re); + + //FIXME should create a fault message and stuff the JSON Result in the body of the message + //JSONRPCResult errorResult = new JSONRPCResult(JSONRPCResult.CODE_REMOTE_EXCEPTION, id, re); + //return errorResult.toString().getBytes("UTF-8"); + } + + Object result = null; + if (!responseMessage.isFault()) { + //successful execution of the invocation + try { + result = responseMessage.getBody(); + JSONObject jsonResponse = new JSONObject(); + jsonResponse.put("result", result); + jsonResponse.putOpt("id", id); + //get response to send to client + responseMessage.setBody(jsonResponse); + return responseMessage; + } catch (Exception e) { + throw new ServiceRuntimeException("Unable to create JSON response", e); + } + } else { + //exception thrown while executing the invocation + //FIXME should create a fault message and stuff the JSON Result in the body of the message + Throwable exception = (Throwable)responseMessage.getBody(); + //JSONRPCResult errorResult = new JSONRPCResult(JSONRPCResult.CODE_REMOTE_EXCEPTION, id, exception ); + //return errorResult.toString().getBytes("UTF-8"); + } + + + return responseMessage; } + + private void setDataBinding(Interface interfaze) { + List operations = interfaze.getOperations(); + for (Operation operation : operations) { + operation.setDataBinding(JSONDataBinding.NAME); + DataType> inputType = operation.getInputType(); + if (inputType != null) { + List logical = inputType.getLogical(); + for (DataType inArg : logical) { + if (!SimpleJavaDataBinding.NAME.equals(inArg.getDataBinding())) { + inArg.setDataBinding(JSONDataBinding.NAME); + } + } + } + DataType outputType = operation.getOutputType(); + if (outputType != null) { + if (!SimpleJavaDataBinding.NAME.equals(outputType.getDataBinding())) { + outputType.setDataBinding(JSONDataBinding.NAME); + } + } + } + } } -- cgit v1.2.3