Improved the SMD and error handling
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1171688 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
562a484efb
commit
5103397852
5 changed files with 163 additions and 87 deletions
|
|
@ -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<List<DataType>> outputType = operation.getOutputType();
|
||||
DataType returnType =
|
||||
(outputType != null && !outputType.getLogical().isEmpty()) ? outputType.getLogical().get(0)
|
||||
: null;
|
||||
entity = response.getEntity();
|
||||
String entityResponse = EntityUtils.toString(entity);
|
||||
entity.consumeContent();
|
||||
if (!db.equals(JSONDataBinding.NAME)) {
|
||||
JSONObject jsonResponse = new JSONObject(entityResponse);
|
||||
|
||||
if (returnType == null) {
|
||||
msg.setBody(null);
|
||||
return msg;
|
||||
}
|
||||
if (!jsonResponse.has("result")) {
|
||||
processException(jsonResponse);
|
||||
}
|
||||
DataType<List<DataType>> outputType = operation.getOutputType();
|
||||
DataType returnType =
|
||||
(outputType != null && !outputType.getLogical().isEmpty()) ? outputType.getLogical().get(0)
|
||||
: null;
|
||||
|
||||
//check requestId
|
||||
if (!requestId.equalsIgnoreCase(jsonResponse.optString("id"))) {
|
||||
throw new ServiceRuntimeException("Invalid response id:" + requestId);
|
||||
}
|
||||
|
||||
Object rawResult = jsonResponse.get("result");
|
||||
if (rawResult == null) {
|
||||
processException(jsonResponse);
|
||||
}
|
||||
|
||||
Class<?> returnClass = returnType.getPhysical();
|
||||
Type genericReturnType = returnType.getGenericType();
|
||||
|
||||
ObjectMapper mapper = createObjectMapper(returnClass);
|
||||
String json = rawResult.toString();
|
||||
|
||||
// Jackson requires the quoted String so that readValue can work
|
||||
if (returnClass == String.class) {
|
||||
json = "\"" + json + "\"";
|
||||
}
|
||||
Object body = mapper.readValue(json, TypeFactory.type(genericReturnType));
|
||||
|
||||
msg.setBody(body);
|
||||
} else {
|
||||
msg.setBody(entityResponse);
|
||||
if (returnType == null) {
|
||||
msg.setBody(null);
|
||||
return msg;
|
||||
}
|
||||
|
||||
} 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);
|
||||
//check requestId
|
||||
if (!requestId.equalsIgnoreCase(jsonResponse.optString("id"))) {
|
||||
throw new ServiceRuntimeException("Invalid response id:" + requestId);
|
||||
}
|
||||
|
||||
Object rawResult = jsonResponse.get("result");
|
||||
if (rawResult == null) {
|
||||
processException(jsonResponse);
|
||||
}
|
||||
|
||||
Class<?> returnClass = returnType.getPhysical();
|
||||
Type genericReturnType = returnType.getGenericType();
|
||||
|
||||
ObjectMapper mapper = createObjectMapper(returnClass);
|
||||
String json = rawResult.toString();
|
||||
|
||||
// Jackson requires the quoted String so that readValue can work
|
||||
if (returnClass == String.class) {
|
||||
json = "\"" + json + "\"";
|
||||
}
|
||||
Object body = mapper.readValue(json, TypeFactory.type(genericReturnType));
|
||||
|
||||
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());
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
smdSb.append("]}");
|
||||
|
||||
smd.put("methods", services);
|
||||
|
||||
return smd.toString(2);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
smdSb.append("]}");
|
||||
|
||||
return smdSb.toString();
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
return "object";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ public class EchoClientImpl implements Echo {
|
|||
}
|
||||
|
||||
public void echoBusinessException() throws EchoBusinessException {
|
||||
throw new UnsupportedOperationException("UNsupported !");
|
||||
echoReference.echoBusinessException();
|
||||
}
|
||||
|
||||
public int echoInt(int param) {
|
||||
|
|
@ -80,7 +80,7 @@ public class EchoClientImpl implements Echo {
|
|||
}
|
||||
|
||||
public void echoRuntimeException() throws RuntimeException {
|
||||
throw new UnsupportedOperationException("UNsupported !");
|
||||
echoReference.echoRuntimeException();
|
||||
}
|
||||
|
||||
public Set echoSet(HashSet set) {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ public class JSONRPCReferenceTestCase {
|
|||
private static final String SERVICE_URL = "http://localhost:8085/SCADomain" + SERVICE_PATH;
|
||||
|
||||
private static Node nodeServer;
|
||||
private static Node node;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUp() throws Exception {
|
||||
|
|
@ -42,6 +43,11 @@ public class JSONRPCReferenceTestCase {
|
|||
String contribution = ContributionLocationHelper.getContributionLocation(JSONRPCReferenceTestCase.class);
|
||||
nodeServer = NodeFactory.newInstance().createNode("JSONRPCBinding.composite", new Contribution("testServer", contribution));
|
||||
nodeServer.start();
|
||||
|
||||
contribution = ContributionLocationHelper.getContributionLocation(JSONRPCReferenceTestCase.class);
|
||||
node = NodeFactory.newInstance().createNode("JSONRPCReference.composite", new Contribution("testClient", contribution));
|
||||
node.start();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
|
@ -50,37 +56,31 @@ public class JSONRPCReferenceTestCase {
|
|||
@AfterClass
|
||||
public static void tearDown() throws Exception {
|
||||
nodeServer.stop();
|
||||
node.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvokeReference() throws Exception {
|
||||
Node node = null;
|
||||
|
||||
String contribution = ContributionLocationHelper.getContributionLocation(JSONRPCReferenceTestCase.class);
|
||||
node = NodeFactory.newInstance().createNode("JSONRPCReference.composite", new Contribution("testClient", contribution));
|
||||
node.start();
|
||||
|
||||
Echo echoComponent = node.getService(Echo.class,"EchoComponentWithReference");
|
||||
String result = echoComponent.echo("ABC");
|
||||
Assert.assertEquals("echo: ABC", result);
|
||||
if (node != null) {
|
||||
node.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvokeReferenceVoidOperation() throws Exception {
|
||||
Node node = null;
|
||||
|
||||
String contribution = ContributionLocationHelper.getContributionLocation(JSONRPCReferenceTestCase.class);
|
||||
node = NodeFactory.newInstance().createNode("JSONRPCReference.composite", new Contribution("testClient", contribution));
|
||||
node.start();
|
||||
|
||||
Echo echoComponent = node.getService(Echo.class,"EchoComponentWithReference");
|
||||
echoComponent.echoVoid();
|
||||
|
||||
if (node != null) {
|
||||
node.stop();
|
||||
}
|
||||
|
||||
@Test(expected = Exception.class)
|
||||
public void testInvokeReferenceException() throws Exception {
|
||||
Echo echoComponent = node.getService(Echo.class, "EchoComponentWithReference");
|
||||
try {
|
||||
echoComponent.echoBusinessException();
|
||||
} catch (Exception e) {
|
||||
System.err.println(e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import org.apache.tuscany.sca.node.Contribution;
|
|||
import org.apache.tuscany.sca.node.ContributionLocationHelper;
|
||||
import org.apache.tuscany.sca.node.Node;
|
||||
import org.apache.tuscany.sca.node.NodeFactory;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
|
@ -34,6 +35,8 @@ import com.meterware.httpunit.WebConversation;
|
|||
import com.meterware.httpunit.WebRequest;
|
||||
import com.meterware.httpunit.WebResponse;
|
||||
|
||||
import echo.Echo;
|
||||
|
||||
/**
|
||||
* @version $Rev$ $Date$
|
||||
*/
|
||||
|
|
@ -51,7 +54,9 @@ public class JSONRPCSmdTestCase {
|
|||
public static void setUp() throws Exception {
|
||||
try {
|
||||
String contribution = ContributionLocationHelper.getContributionLocation(JSONRPCSmdTestCase.class);
|
||||
node = NodeFactory.newInstance().createNode("JSONRPCBinding.composite", new Contribution("test", contribution));
|
||||
node =
|
||||
NodeFactory.newInstance()
|
||||
.createNode("JSONRPCBinding.composite", new Contribution("test", contribution));
|
||||
node.start();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
|
@ -69,12 +74,13 @@ public class JSONRPCSmdTestCase {
|
|||
*/
|
||||
public void testJSONRPCSmdSpecialCharacters() throws Exception {
|
||||
WebConversation wc = new WebConversation();
|
||||
WebRequest request = new GetMethodWebRequest(SMD_URL);
|
||||
WebRequest request = new GetMethodWebRequest(SMD_URL);
|
||||
WebResponse response = wc.getResource(request);
|
||||
|
||||
Assert.assertEquals(200, response.getResponseCode());
|
||||
Assert.assertNotNull(response.getText());
|
||||
JSONObject smd = new JSONObject(response.getText());
|
||||
Assert.assertEquals(Echo.class.getMethods().length, smd.getJSONArray("methods").length());
|
||||
|
||||
//System.out.println(">>>SMD:" + response.getText());
|
||||
// System.out.println(">>>SMD:\n" + response.getText());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue