Author: lresende
Date: Tue May  5 07:22:02 2009
New Revision: 771601

URL: http://svn.apache.org/viewvc?rev=771601&view=rev
Log:
TUSCANY-2968 - JSONRPC invocation using operation selector and wire formats 
working end to end

Added:
    
tuscany/branches/sca-java-1.x/modules/binding-http-new/src/main/java/org/apache/tuscany/sca/binding/http/HTTPBindingContext.java
   (with props)
Modified:
    
tuscany/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
    
tuscany/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
    
tuscany/branches/sca-java-1.x/modules/binding-http-new-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPRRBListenerServlet.java

Modified: 
tuscany/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
URL: 
http://svn.apache.org/viewvc/tuscany/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?rev=771601&r1=771600&r2=771601&view=diff
==============================================================================
--- 
tuscany/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
 (original)
+++ 
tuscany/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
 Tue May  5 07:22:02 2009
@@ -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 @@
     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 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<Operation> 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;
+    }    
 
 }

Modified: 
tuscany/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
URL: 
http://svn.apache.org/viewvc/tuscany/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?rev=771601&r1=771600&r2=771601&view=diff
==============================================================================
--- 
tuscany/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
 (original)
+++ 
tuscany/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
 Tue May  5 07:22:02 2009
@@ -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 @@
     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 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<Operation> operations = interfaze.getOperations();
+        for (Operation operation : operations) {
+            operation.setDataBinding(JSONDataBinding.NAME);
+            DataType<List<DataType>> inputType = operation.getInputType();
+            if (inputType != null) {
+                List<DataType> 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);
+                }
+            }
+        }
+    }
 }

Modified: 
tuscany/branches/sca-java-1.x/modules/binding-http-new-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPRRBListenerServlet.java
URL: 
http://svn.apache.org/viewvc/tuscany/branches/sca-java-1.x/modules/binding-http-new-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPRRBListenerServlet.java?rev=771601&r1=771600&r2=771601&view=diff
==============================================================================
--- 
tuscany/branches/sca-java-1.x/modules/binding-http-new-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPRRBListenerServlet.java
 (original)
+++ 
tuscany/branches/sca-java-1.x/modules/binding-http-new-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPRRBListenerServlet.java
 Tue May  5 07:22:02 2009
@@ -19,16 +19,18 @@
 
 package org.apache.tuscany.sca.binding.http.provider;
 
+import java.io.BufferedReader;
+import java.io.CharArrayWriter;
 import java.io.IOException;
+import java.io.InputStreamReader;
 
 import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.tuscany.sca.assembly.Binding;
+import org.apache.tuscany.sca.binding.http.HTTPBindingContext;
 import org.apache.tuscany.sca.invocation.Invoker;
 import org.apache.tuscany.sca.invocation.Message;
 import org.apache.tuscany.sca.invocation.MessageFactory;
@@ -36,7 +38,7 @@
 public class HTTPRRBListenerServlet extends HttpServlet {
 
     private static final long serialVersionUID = 6688524143716091739L;
-    
+
     transient private Binding binding;
     transient private Invoker bindingInvoker;
     transient private MessageFactory messageFactory;
@@ -49,18 +51,52 @@
         this.bindingInvoker = bindingInvoker;
         this.messageFactory = messageFactory;
     }
-    
-   public void service(HttpServletRequest request, HttpServletResponse 
response) throws ServletException, IOException {
-       
+
+    public void service(HttpServletRequest request, HttpServletResponse 
response) throws ServletException, IOException {
+        
+        // Decode using the charset in the request if it exists otherwise
+        // use UTF-8 as this is what all browser implementations use.
+        // The JSON-RPC-Java JavaScript client is ASCII clean so it
+        // although here we can correctly handle data from other clients
+        // that do not escape non ASCII data
+        String charset = request.getCharacterEncoding();
+        if (charset == null) {
+            charset = "UTF-8";
+        }
+        BufferedReader in = new BufferedReader(new 
InputStreamReader(request.getInputStream(), charset));
+
+        // Read the request
+        CharArrayWriter data = new CharArrayWriter();
+        char[] buf = new char[4096];
+        int ret;
+        while ((ret = in.read(buf, 0, 4096)) != -1) {
+            data.write(buf, 0, ret);
+        }
+        
+        HTTPBindingContext bindingContext = new HTTPBindingContext();
+        bindingContext.setHttpRequest(request);
+        bindingContext.setHttpResponse(response);
+
         // Dispatch the service interaction to the service invoker
         Message requestMessage = messageFactory.createMessage();
-        requestMessage.setBody(new Object[]{request, response});
+        requestMessage.setBindingContext(bindingContext);
+        requestMessage.setBody(new Object[]{data});
+        
         Message responseMessage = bindingInvoker.invoke(requestMessage);
+        
+        // return response to client
         if (responseMessage.isFault()) {            
             // Turn a fault into an exception
             //throw new ServletException((Throwable)responseMessage.getBody());
             Throwable e = (Throwable)responseMessage.getBody();
             response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, 
e.toString());
-        }
+        } else {
+            byte[] bout;
+            bout = 
responseMessage.<Object>getBody().toString().getBytes("UTF-8");
+            response.getOutputStream().write(bout);
+            response.getOutputStream().flush();
+            response.getOutputStream().close();
+        } 
     }
+    
 }

Added: 
tuscany/branches/sca-java-1.x/modules/binding-http-new/src/main/java/org/apache/tuscany/sca/binding/http/HTTPBindingContext.java
URL: 
http://svn.apache.org/viewvc/tuscany/branches/sca-java-1.x/modules/binding-http-new/src/main/java/org/apache/tuscany/sca/binding/http/HTTPBindingContext.java?rev=771601&view=auto
==============================================================================
--- 
tuscany/branches/sca-java-1.x/modules/binding-http-new/src/main/java/org/apache/tuscany/sca/binding/http/HTTPBindingContext.java
 (added)
+++ 
tuscany/branches/sca-java-1.x/modules/binding-http-new/src/main/java/org/apache/tuscany/sca/binding/http/HTTPBindingContext.java
 Tue May  5 07:22:02 2009
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+
+package org.apache.tuscany.sca.binding.http;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * HTTP Binding Context
+ *
+ * @version $Rev$ $Date$
+ */
+public class HTTPBindingContext {
+    private HttpServletRequest request;
+    private HttpServletResponse response;
+    
+    public HttpServletRequest getHttpRequest() {
+        return request;
+    }
+    public void setHttpRequest(HttpServletRequest request) {
+        this.request = request;
+    }
+    public HttpServletResponse getHttpResponse() {
+        return response;
+    }
+    public void setHttpResponse(HttpServletResponse response) {
+        this.response = response;
+    }
+
+}

Propchange: 
tuscany/branches/sca-java-1.x/modules/binding-http-new/src/main/java/org/apache/tuscany/sca/binding/http/HTTPBindingContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
tuscany/branches/sca-java-1.x/modules/binding-http-new/src/main/java/org/apache/tuscany/sca/binding/http/HTTPBindingContext.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date


Reply via email to