From 510339785280a70836958a2bf06354f576c7e322 Mon Sep 17 00:00:00 2001 From: rfeng Date: Fri, 16 Sep 2011 17:34:05 +0000 Subject: Improved the SMD and error handling git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1171688 13f79535-47bb-0310-9956-ffa450edef68 --- .../jsonrpc/provider/JSONRPCBindingInvoker.java | 81 +++++++-------- .../sca/binding/jsonrpc/provider/JavaToSmd.java | 115 +++++++++++++++++---- 2 files changed, 133 insertions(+), 63 deletions(-) (limited to 'sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache') diff --git a/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCBindingInvoker.java b/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCBindingInvoker.java index 348b76bd14..51311c2da8 100644 --- a/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCBindingInvoker.java +++ b/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JSONRPCBindingInvoker.java @@ -130,59 +130,53 @@ public class JSONRPCBindingInvoker implements Invoker, DataExchangeSemantics { if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { //success - try { - entity = response.getEntity(); - String entityResponse = EntityUtils.toString(entity); - entity.consumeContent(); - if (!db.equals(JSONDataBinding.NAME)) { - JSONObject jsonResponse = new JSONObject(entityResponse); - if (!jsonResponse.has("result")) { - processException(jsonResponse); - } - DataType> outputType = operation.getOutputType(); - DataType returnType = - (outputType != null && !outputType.getLogical().isEmpty()) ? outputType.getLogical().get(0) - : null; - - if (returnType == null) { - msg.setBody(null); - return msg; - } + entity = response.getEntity(); + String entityResponse = EntityUtils.toString(entity); + entity.consumeContent(); + if (!db.equals(JSONDataBinding.NAME)) { + JSONObject jsonResponse = new JSONObject(entityResponse); - //check requestId - if (!requestId.equalsIgnoreCase(jsonResponse.optString("id"))) { - throw new ServiceRuntimeException("Invalid response id:" + requestId); - } + if (!jsonResponse.has("result")) { + processException(jsonResponse); + } + DataType> outputType = operation.getOutputType(); + DataType returnType = + (outputType != null && !outputType.getLogical().isEmpty()) ? outputType.getLogical().get(0) + : null; + + if (returnType == null) { + msg.setBody(null); + return msg; + } - Object rawResult = jsonResponse.get("result"); - if (rawResult == null) { - processException(jsonResponse); - } + //check requestId + if (!requestId.equalsIgnoreCase(jsonResponse.optString("id"))) { + throw new ServiceRuntimeException("Invalid response id:" + requestId); + } - Class returnClass = returnType.getPhysical(); - Type genericReturnType = returnType.getGenericType(); + Object rawResult = jsonResponse.get("result"); + if (rawResult == null) { + processException(jsonResponse); + } - ObjectMapper mapper = createObjectMapper(returnClass); - String json = rawResult.toString(); + Class returnClass = returnType.getPhysical(); + Type genericReturnType = returnType.getGenericType(); - // Jackson requires the quoted String so that readValue can work - if (returnClass == String.class) { - json = "\"" + json + "\""; - } - Object body = mapper.readValue(json, TypeFactory.type(genericReturnType)); + ObjectMapper mapper = createObjectMapper(returnClass); + String json = rawResult.toString(); - msg.setBody(body); - } else { - msg.setBody(entityResponse); + // Jackson requires the quoted String so that readValue can work + if (returnClass == String.class) { + json = "\"" + json + "\""; } + Object body = mapper.readValue(json, TypeFactory.type(genericReturnType)); - } catch (Exception e) { - //FIXME Exceptions are not handled correctly here - // They should be reported to the client JavaScript as proper - // JavaScript exceptions. - throw new ServiceRuntimeException("Unable to parse response", e); + msg.setBody(body); + } else { + msg.setBody(entityResponse); } + } else { // Consume the content so the connection can be released response.getEntity().consumeContent(); @@ -241,6 +235,7 @@ public class JSONRPCBindingInvoker implements Invoker, DataExchangeSemantics { * Generate and throw exception based on the data in the 'responseMessage' */ protected void processException(JSONObject responseMessage) throws JSONException { + // FIXME: We need to find a way to build Java exceptions out of the json-rpc error JSONObject error = (JSONObject)responseMessage.get("error"); if (error != null) { throw new ServiceRuntimeException(error.toString()); diff --git a/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JavaToSmd.java b/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JavaToSmd.java index 64339fda7b..820c7a9525 100644 --- a/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JavaToSmd.java +++ b/sca-java-2.x/trunk/modules/binding-jsonrpc-runtime/src/main/java/org/apache/tuscany/sca/binding/jsonrpc/provider/JavaToSmd.java @@ -16,9 +16,13 @@ * specific language governing permissions and limitations * under the License. */ - package org.apache.tuscany.sca.binding.jsonrpc.provider; +package org.apache.tuscany.sca.binding.jsonrpc.provider; import java.lang.reflect.Method; +import java.util.Collection; + +import org.json.JSONArray; +import org.json.JSONObject; /** * Utility class to create a Simple Method Description (SMD) descriptor @@ -29,28 +33,99 @@ import java.lang.reflect.Method; * @version $Rev$ $Date$ */ class JavaToSmd { - + static String interfaceToSmd(Class klazz, String serviceUrl) { - String name = klazz.getSimpleName(); - Method[] methods = klazz.getMethods(); - - StringBuffer smdSb = new StringBuffer(); - smdSb.append("{\"SMDVersion\":\".1\",\"objectName\":\"" + name + "\",\"serviceType\":\"JSON-RPC\",\"serviceURL\":\""+ serviceUrl + "\",\"methods\":["); - for (int i = 0; i < methods.length; i++) { - if (i != 0) smdSb.append(","); - Class[] params = methods[i].getParameterTypes(); - smdSb.append("{\"name\":\""+methods[i].getName() + "\",\"parameters\":["); - for (int j = 0; j < params.length; j++) { - if (j != 0) smdSb.append(","); - // right now Dojo doesn't look at the type value, so we'll default it to STRING - // also, since we can't introspect the method parameter names we'll just create an incrementing parameter name - smdSb.append("{\"name\":\"param" + j + "\",\"type\":\"STRING\"}"); + try { + String name = klazz.getSimpleName(); + Method[] methods = klazz.getMethods(); + + JSONObject smd = new JSONObject(); + smd.put("SMDVersion", ".1"); + smd.put("objectName", name); + smd.put("serviceType", "JSON-RPC"); + smd.put("serviceURL", serviceUrl); + + JSONArray services = new JSONArray(); + for (int i = 0; i < methods.length; i++) { + JSONObject service = new JSONObject(); + Class[] params = methods[i].getParameterTypes(); + JSONArray paramArray = new JSONArray(); + for (int j = 0; j < params.length; j++) { + JSONObject param = new JSONObject(); + param.put("name", "param" + j); + param.put("type", getJSONType(params[j])); + paramArray.put(param); + } + service.put("name", methods[i].getName()); + service.put("parameters", paramArray); + services.put(service); + } + + smd.put("methods", services); + + return smd.toString(2); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + + } + + static String interfaceToSmd20(Class klazz, String serviceUrl) { + try { + String name = klazz.getSimpleName(); + Method[] methods = klazz.getMethods(); + + JSONObject smd = new JSONObject(); + smd.put("SMDVersion", "2.0"); + smd.put("transport", "POST"); + smd.put("envelope", "JSON-RPC-1.0"); + smd.put("target", serviceUrl); + smd.put("id", klazz.getName()); + smd.put("description", "JSON-RPC service provided by Tuscany: " + name); + + JSONObject services = new JSONObject(); + for (int i = 0; i < methods.length; i++) { + JSONObject service = new JSONObject(); + Class[] params = methods[i].getParameterTypes(); + JSONArray paramArray = new JSONArray(); + for (int j = 0; j < params.length; j++) { + JSONObject param = new JSONObject(); + param.put("name", "param" + j); + param.put("type", getJSONType(params[j])); + paramArray.put(param); + } + service.put("parameters", paramArray); + services.put(methods[i].getName(), service); } - smdSb.append("]}"); + + smd.put("services", services); + + return smd.toString(2); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + + } + + private static String getJSONType(Class type) { + if (type == boolean.class || type == Boolean.class) { + return "boolean"; + } + if (type == String.class) { + return "string"; + } + if (byte.class == type || short.class == type + || int.class == type + || long.class == type + || float.class == type + || double.class == type + || Number.class.isAssignableFrom(type)) { + return "number"; + } + if (type.isArray() || Collection.class.isAssignableFrom(type)) { + return "array"; } - smdSb.append("]}"); - - return smdSb.toString(); + return "object"; } } -- cgit v1.2.3