summaryrefslogtreecommitdiffstats
path: root/branches
diff options
context:
space:
mode:
authorlresende <lresende@13f79535-47bb-0310-9956-ffa450edef68>2009-05-05 07:22:02 +0000
committerlresende <lresende@13f79535-47bb-0310-9956-ffa450edef68>2009-05-05 07:22:02 +0000
commitc5e4337f496dd4a9ef2ef2dac9a783e2e2be2d66 (patch)
treebbea8c49dd9fd18b2ac0c53c6509eb18c123888f /branches
parent841b4c7adf6c13158b17909b8208c59da793e376 (diff)
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
Diffstat (limited to 'branches')
-rw-r--r--branches/sca-java-1.x/modules/binding-http-new-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/http/operationselector/jsonrpc/provider/JSONRPCOperationSelectorInterceptor.java58
-rw-r--r--branches/sca-java-1.x/modules/binding-http-new-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/http/wireformat/jsonrpc/provider/JSONRPCWireFormatInterceptor.java103
-rw-r--r--branches/sca-java-1.x/modules/binding-http-new-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPRRBListenerServlet.java52
-rw-r--r--branches/sca-java-1.x/modules/binding-http-new/src/main/java/org/apache/tuscany/sca/binding/http/HTTPBindingContext.java47
4 files changed, 251 insertions, 9 deletions
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<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;
+ }
}
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<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);
+ }
+ }
+ }
+ }
}
diff --git a/branches/sca-java-1.x/modules/binding-http-new-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPRRBListenerServlet.java b/branches/sca-java-1.x/modules/binding-http-new-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPRRBListenerServlet.java
index 89bea9f75a..605e2c6211 100644
--- a/branches/sca-java-1.x/modules/binding-http-new-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPRRBListenerServlet.java
+++ b/branches/sca-java-1.x/modules/binding-http-new-runtime/src/main/java/org/apache/tuscany/sca/binding/http/provider/HTTPRRBListenerServlet.java
@@ -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 @@ import org.apache.tuscany.sca.invocation.MessageFactory;
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 @@ public class HTTPRRBListenerServlet extends HttpServlet {
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();
+ }
}
+
}
diff --git a/branches/sca-java-1.x/modules/binding-http-new/src/main/java/org/apache/tuscany/sca/binding/http/HTTPBindingContext.java b/branches/sca-java-1.x/modules/binding-http-new/src/main/java/org/apache/tuscany/sca/binding/http/HTTPBindingContext.java
new file mode 100644
index 0000000000..f7e5bac606
--- /dev/null
+++ b/branches/sca-java-1.x/modules/binding-http-new/src/main/java/org/apache/tuscany/sca/binding/http/HTTPBindingContext.java
@@ -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;
+ }
+
+}