diff options
author | wjaniszewski <wjaniszewski@13f79535-47bb-0310-9956-ffa450edef68> | 2009-03-02 22:49:01 +0000 |
---|---|---|
committer | wjaniszewski <wjaniszewski@13f79535-47bb-0310-9956-ffa450edef68> | 2009-03-02 22:49:01 +0000 |
commit | 65c9710b644bd3ef0f5dd21aaa0049f984394c57 (patch) | |
tree | e67b40fea3ffe03bc0d28f0fbca5e020ef49fcc9 /sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca | |
parent | 6c6ad2fbdd72a4aabc4025339a3d6aa090668444 (diff) |
Epmd starts automatically - if epmd is not available tests are beeing ignored. Normalized service/reference RPC, added some error handling.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@749461 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca')
9 files changed, 455 insertions, 278 deletions
diff --git a/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/ErlangInvoker.java b/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/ErlangInvoker.java index 7e963cc34a..fd9e89bc2d 100644 --- a/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/ErlangInvoker.java +++ b/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/ErlangInvoker.java @@ -20,15 +20,16 @@ package org.apache.tuscany.sca.binding.erlang.impl;
import org.apache.tuscany.sca.binding.erlang.ErlangBinding;
+import org.apache.tuscany.sca.binding.erlang.impl.exceptions.ErlangException;
import org.apache.tuscany.sca.binding.erlang.impl.types.TypeHelpersProxy;
import org.apache.tuscany.sca.invocation.Invoker;
import org.apache.tuscany.sca.invocation.Message;
-import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
import com.ericsson.otp.erlang.OtpConnection;
import com.ericsson.otp.erlang.OtpEpmd;
import com.ericsson.otp.erlang.OtpErlangList;
import com.ericsson.otp.erlang.OtpErlangObject;
+import com.ericsson.otp.erlang.OtpErlangTuple;
import com.ericsson.otp.erlang.OtpMbox;
import com.ericsson.otp.erlang.OtpMsg;
import com.ericsson.otp.erlang.OtpNode;
@@ -40,78 +41,102 @@ import com.ericsson.otp.erlang.OtpSelf; */
public class ErlangInvoker implements Invoker {
- private RuntimeComponentReference reference;
- private ErlangBinding binding;
- private OtpNode node;
+ private ErlangBinding binding;
+ private OtpNode node;
- public ErlangInvoker(RuntimeComponentReference reference, ErlangBinding binding) {
- this.reference = reference;
- this.binding = binding;
- }
+ public ErlangInvoker(ErlangBinding binding) {
+ this.binding = binding;
+ }
- private Message sendMessage(Message msg) {
- OtpMbox tmpMbox = null;
- try {
- String nodeName = "_connector_to_" + binding.getNode();
- node = new OtpNode(nodeName);
- tmpMbox = node.createMbox();
- Object[] args = msg.getBody();
- OtpErlangObject msgPayload = TypeHelpersProxy.toErlang(args);
- tmpMbox.send(msg.getOperation().getName(), binding.getNode(), msgPayload);
- if (msg.getOperation().getOutputType() != null) {
- OtpMsg resultMsg = tmpMbox.receiveMsg();
- OtpErlangObject result = resultMsg.getMsg();
- msg.setBody(TypeHelpersProxy.toJava(result, msg.getOperation().getOutputType().getPhysical()));
- }
- } catch (Exception e) {
- msg.setFaultBody(e);
- } finally {
- if (tmpMbox != null) {
- tmpMbox.close();
- }
- if (node != null) {
- OtpEpmd.unPublishPort(node);
- node.close();
- }
- }
- return msg;
- }
+ private Message sendMessage(Message msg) {
+ OtpMbox tmpMbox = null;
+ try {
+ String nodeName = "_connector_to_" + binding.getNode();
+ node = new OtpNode(nodeName);
+ tmpMbox = node.createMbox();
+ Object[] args = msg.getBody();
+ OtpErlangObject msgPayload = TypeHelpersProxy.toErlang(args);
+ tmpMbox.send(msg.getOperation().getName(), binding.getNode(),
+ msgPayload);
+ if (msg.getOperation().getOutputType() != null) {
+ OtpMsg resultMsg = tmpMbox.receiveMsg();
+ OtpErlangObject result = resultMsg.getMsg();
+ msg.setBody(TypeHelpersProxy.toJava(result, msg.getOperation()
+ .getOutputType().getPhysical()));
+ }
+ } catch (Exception e) {
+ msg.setFaultBody(e);
+ } finally {
+ if (tmpMbox != null) {
+ tmpMbox.close();
+ }
+ if (node != null) {
+ OtpEpmd.unPublishPort(node);
+ node.close();
+ }
+ }
+ return msg;
+ }
- private Message invokeOperation(Message msg) {
- OtpSelf self = null;
- OtpPeer other = null;
- OtpConnection connection = null;
- try {
- String nodeName = "_connector_to_" + binding.getNode();
- self = new OtpSelf(nodeName);
- other = new OtpPeer(binding.getNode());
- connection = self.connect(other);
- OtpErlangList params = TypeHelpersProxy.toErlangAsList((Object[])msg.getBody());
- connection.sendRPC(binding.getModule(), msg.getOperation().getName(), params);
- if (msg.getOperation().getOutputType() != null) {
- OtpErlangObject result = connection.receiveRPC();
- msg.setBody(TypeHelpersProxy.toJava(result, msg.getOperation().getOutputType().getPhysical()));
- }
- } catch (Exception e) {
- msg.setFaultBody(e);
- } finally {
- if (connection != null) {
- connection.close();
- }
- }
- return msg;
- }
+ private Message invokeOperation(Message msg) {
+ OtpSelf self = null;
+ OtpPeer other = null;
+ OtpConnection connection = null;
+ try {
+ String nodeName = "_connector_to_" + binding.getNode();
+ self = new OtpSelf(nodeName);
+ other = new OtpPeer(binding.getNode());
+ connection = self.connect(other);
+ OtpErlangList params = TypeHelpersProxy
+ .toErlangAsList((Object[]) msg.getBody());
+ OtpErlangTuple message = MessageHelper.rpcMessage(self.pid(), self
+ .createRef(), binding.getModule(), msg.getOperation()
+ .getName(), params);
+ connection.send("rex", message);
+ OtpErlangObject result = connection.receiveRPC();
+ if (MessageHelper.isfunctionUndefMessage(result)) {
+ // TODO: externalize message?
+ Exception e = new ErlangException(
+ "No such function in referenced Erlang node.");
+ if (msg.getOperation().getFaultTypes().size() == 0) {
+ // TODO: no way to throw exception, log it (temporary as System.out)
+ // TODO: do we really want not to throw any exception?
+ System.out.println("PROBLEM: " + e.getMessage());
+ // in this case we don't throw occured problem, so we need
+ // to reset message body (if body is not cleared then
+ // operation arguments would be set as operation output)
+ msg.setBody(null);
+ } else {
+ msg.setFaultBody(e);
+ }
+ } else if (msg.getOperation().getOutputType() != null) {
+ if (result.getClass().equals(OtpErlangTuple.class)) {
+ OtpErlangObject resultBody = ((OtpErlangTuple) result)
+ .elementAt(1);
+ msg.setBody(TypeHelpersProxy.toJava(resultBody, msg
+ .getOperation().getOutputType().getPhysical()));
+ }
+ }
+ } catch (Exception e) {
+ msg.setFaultBody(e);
+ } finally {
+ if (connection != null) {
+ connection.close();
+ }
+ }
+ return msg;
+ }
- /**
- * @see org.apache.tuscany.sca.invocation.Invoker#invoke(org.apache.tuscany.sca.invocation.Message)
- */
- public Message invoke(Message msg) {
- if (binding.isMbox()) {
- return sendMessage(msg);
- } else {
- return invokeOperation(msg);
- }
+ /**
+ * @see org.apache.tuscany.sca.invocation.Invoker#invoke(org.apache.tuscany.sca.invocation.Message)
+ */
+ public Message invoke(Message msg) {
+ if (binding.isMbox()) {
+ return sendMessage(msg);
+ } else {
+ return invokeOperation(msg);
+ }
- }
+ }
}
diff --git a/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/ErlangReferenceBindingProvider.java b/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/ErlangReferenceBindingProvider.java index 34af39ce41..0ce9d33238 100644 --- a/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/ErlangReferenceBindingProvider.java +++ b/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/ErlangReferenceBindingProvider.java @@ -48,7 +48,7 @@ public class ErlangReferenceBindingProvider implements ReferenceBindingProvider */
public Invoker createInvoker(Operation operation) {
try {
- return new ErlangInvoker(reference, binding);
+ return new ErlangInvoker(binding);
} catch (Exception e) {
logger.log(Level.WARNING, "Exception during creating Erlang invoker", e);
}
diff --git a/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/ErlangServiceBindingProvider.java b/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/ErlangServiceBindingProvider.java index 8d6e2e810c..df82c5813c 100644 --- a/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/ErlangServiceBindingProvider.java +++ b/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/ErlangServiceBindingProvider.java @@ -32,6 +32,7 @@ public class ErlangServiceBindingProvider implements ServiceBindingProvider { private RuntimeComponentService service;
private ErlangBinding binding;
+ private RpcServer rpcServer;
public ErlangServiceBindingProvider(ErlangBinding binding, RuntimeComponentService service) {
this.service = service;
@@ -50,8 +51,8 @@ public class ErlangServiceBindingProvider implements ServiceBindingProvider { */
public void start() {
try {
- Runnable server = new RpcServer(service, binding);
- Thread thread = new Thread(server);
+ rpcServer = new RpcServer(service, binding);
+ Thread thread = new Thread(rpcServer);
thread.start();
} catch (Exception e) {
throw new ServiceRuntimeException(e);
@@ -64,7 +65,7 @@ public class ErlangServiceBindingProvider implements ServiceBindingProvider { */
public void stop() {
try {
- //TODO: stop RPC server
+ rpcServer.stop();
} catch (Exception e) {
throw new ServiceRuntimeException(e);
}
diff --git a/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/MessageHelper.java b/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/MessageHelper.java new file mode 100644 index 0000000000..55134782d5 --- /dev/null +++ b/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/MessageHelper.java @@ -0,0 +1,93 @@ +package org.apache.tuscany.sca.binding.erlang.impl; + +import com.ericsson.otp.erlang.OtpErlangAtom; +import com.ericsson.otp.erlang.OtpErlangList; +import com.ericsson.otp.erlang.OtpErlangObject; +import com.ericsson.otp.erlang.OtpErlangPid; +import com.ericsson.otp.erlang.OtpErlangRef; +import com.ericsson.otp.erlang.OtpErlangTuple; + +public class MessageHelper { + + private static String ATOM_BADRPC = "badrpc"; + private static String ATOM_EXIT = "EXIT"; + private static String ATOM_UNDEF = "undef"; + + public static OtpErlangObject functionUndefMessage(String module, String function, OtpErlangList args, String tuscanyMsg) { + OtpErlangObject[] args4 = new OtpErlangObject[3]; + args4[0] = new OtpErlangAtom(module); + args4[1] = new OtpErlangAtom(function); + args4[2] = args; + + OtpErlangObject[] args3 = new OtpErlangObject[2]; + args3[0] = new OtpErlangTuple(args4); + args3[1] = new OtpErlangAtom(tuscanyMsg); + + OtpErlangObject[] args2 = new OtpErlangObject[2]; + args2[0] = new OtpErlangAtom(ATOM_UNDEF); + args2[1] = new OtpErlangList(args3); + + OtpErlangObject[] args1 = new OtpErlangObject[2]; + args1[0] = new OtpErlangAtom(ATOM_EXIT); + args1[1] = new OtpErlangTuple(args2); + + OtpErlangTuple result = new OtpErlangTuple(args1); + return result; + } + + public static boolean isfunctionUndefMessage(OtpErlangObject msg) { + if (msg.getClass().equals(OtpErlangTuple.class)) { + OtpErlangTuple tupleMsg = (OtpErlangTuple) msg; + if (tupleMsg.arity() == 2 + && tupleMsg.elementAt(0).getClass().equals( + OtpErlangAtom.class) + && tupleMsg.elementAt(1).getClass().equals( + OtpErlangTuple.class) + && ((OtpErlangAtom) tupleMsg.elementAt(0)).atomValue() + .equals(ATOM_BADRPC)) { + OtpErlangTuple badrpcTuple = (OtpErlangTuple) tupleMsg + .elementAt(1); + if (badrpcTuple.arity() == 2 + && badrpcTuple.elementAt(0).getClass().equals( + OtpErlangAtom.class) + && badrpcTuple.elementAt(1).getClass().equals( + OtpErlangTuple.class) + && ((OtpErlangAtom) badrpcTuple.elementAt(0)) + .atomValue().equals(ATOM_EXIT)) { + OtpErlangTuple exitTuple = (OtpErlangTuple) badrpcTuple + .elementAt(1); + if (exitTuple.arity() == 2 + && exitTuple.elementAt(0).getClass().equals( + OtpErlangAtom.class) + && ((OtpErlangAtom) exitTuple.elementAt(0)) + .atomValue().equals(ATOM_UNDEF)) { + return true; + } + } + + } + } + return false; + } + + public static OtpErlangTuple rpcMessage(OtpErlangPid senderPid, OtpErlangRef ref, String module, String function, OtpErlangList args) { + OtpErlangObject[] args3 = new OtpErlangObject[5]; + args3[0] = new OtpErlangAtom("call"); + args3[1] = new OtpErlangAtom(module); + args3[2] = new OtpErlangAtom(function); + args3[3] = args; + args3[4] = senderPid; + + OtpErlangObject[] args2 = new OtpErlangObject[2]; + args2[0] = senderPid; + args2[1] = ref; + + OtpErlangObject[] args1 = new OtpErlangObject[3]; + args1[0] = new OtpErlangAtom("$gen_call"); + args1[1] = new OtpErlangTuple(args2); + args1[2] = new OtpErlangTuple(args3); + + OtpErlangTuple result = new OtpErlangTuple(args1); + return result; + } +} diff --git a/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/RpcExecutor.java b/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/RpcExecutor.java index 3940c34b7b..6707496194 100644 --- a/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/RpcExecutor.java +++ b/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/RpcExecutor.java @@ -20,6 +20,7 @@ package org.apache.tuscany.sca.binding.erlang.impl; import java.io.IOException; +import java.lang.reflect.InvocationTargetException; import java.util.List; import org.apache.tuscany.sca.binding.erlang.ErlangBinding; @@ -39,105 +40,134 @@ import com.ericsson.otp.erlang.OtpErlangTuple; public class RpcExecutor implements Runnable { - private RuntimeComponentService service; - private ErlangBinding binding; - private OtpConnection connection; + private RuntimeComponentService service; + private ErlangBinding binding; + private OtpConnection connection; - private static final OtpErlangAtom OK = new OtpErlangAtom("ok"); - private static final OtpErlangAtom ERROR = new OtpErlangAtom("error"); + private static final OtpErlangAtom OK = new OtpErlangAtom("ok"); + private static final OtpErlangAtom ERROR = new OtpErlangAtom("error"); + private static final OtpErlangAtom BADRPC = new OtpErlangAtom("badrpc"); - public RpcExecutor(RuntimeComponentService service, ErlangBinding binding, OtpConnection connection) { - this.service = service; - this.binding = binding; - this.connection = connection; - } + public RpcExecutor(RuntimeComponentService service, ErlangBinding binding, + OtpConnection connection) { + this.service = service; + this.binding = binding; + this.connection = connection; + } - private void sendMessage(OtpConnection connection, - OtpErlangPid pid, - OtpErlangRef ref, - OtpErlangAtom head, - OtpErlangObject message) throws IOException { - OtpErlangTuple tResult = new OtpErlangTuple(new OtpErlangObject[] {head, message}); - OtpErlangObject msg = null; - if (ref != null) { - msg = new OtpErlangTuple(new OtpErlangObject[] {ref, tResult}); - } else { - msg = tResult; - } - connection.send(pid, msg); - } - - public void run() { - OtpErlangTuple request = null; - OtpErlangPid senderPid = null; - OtpErlangRef senderRef = null; - try { - OtpErlangTuple call = (OtpErlangTuple)connection.receive(); - if (call.arity() == 2) { - // is call from jinterface library - senderPid = (OtpErlangPid)call.elementAt(0); - request = (OtpErlangTuple)call.elementAt(1); - } else { - // is call from native *erl* console - OtpErlangTuple from = (OtpErlangTuple)call.elementAt(1); - request = (OtpErlangTuple)call.elementAt(2); - senderPid = (OtpErlangPid)from.elementAt(0); - senderRef = (OtpErlangRef)from.elementAt(1); - } - String module = ((OtpErlangAtom)request.elementAt(1)).atomValue(); - String function = ((OtpErlangAtom)request.elementAt(2)).atomValue(); - OtpErlangObject args = request.elementAt(3); - OtpErlangList argsList = null; - if (args instanceof OtpErlangList) { - argsList = (OtpErlangList)args; - } else { - argsList = new OtpErlangList(args); - } - if (!binding.getModule().equals(module)) { - sendMessage(connection, senderPid, senderRef, ERROR, new OtpErlangString("No such module")); - } else { - List<Operation> operations = service.getInterfaceContract().getInterface().getOperations(); - Operation operation = null; - for (Operation o : operations) { - if (o.getName().equals(function)) { - operation = o; - break; - } - } - if (operation != null) { - List<DataType> iTypes = operation.getInputType().getLogical(); - Class<?>[] forClasses = new Class<?>[iTypes.size()]; - for (int i = 0; i < iTypes.size(); i++) { - forClasses[i] = iTypes.get(i).getPhysical(); - } - Object result = - service.getRuntimeWire(binding).invoke(operation, - TypeHelpersProxy.toJavaFromList(argsList, forClasses)); - OtpErlangObject response = null; - if (operation.getOutputType() != null && operation.getOutputType().getPhysical().isArray()) { - response = TypeHelpersProxy.toErlangAsList(result); - } else if (operation.getOutputType() == null) { - Object[] arrArg = new Object[] {}; - response = TypeHelpersProxy.toErlang(arrArg); - } else { - Object[] arrArg = new Object[] {result}; - response = TypeHelpersProxy.toErlang(arrArg); - } - sendMessage(connection, senderPid, senderRef, OK, response); - } else { - sendMessage(connection, senderPid, senderRef, ERROR, new OtpErlangString("No such operation")); - } - } - } catch (Exception e) { - // TODO: distinguish and describe errors! - try { - sendMessage(connection, senderPid, senderRef, ERROR, new OtpErlangString("Error while processing request")); - } catch (IOException e1) { - // error while sending error message. Can't do anything now - } - } finally { - connection.close(); - } - } + private void sendMessage(OtpConnection connection, OtpErlangPid pid, + OtpErlangRef ref, OtpErlangAtom head, OtpErlangObject message) + throws IOException { + OtpErlangTuple tResult = new OtpErlangTuple(new OtpErlangObject[] { + head, message }); + OtpErlangObject msg = null; + msg = new OtpErlangTuple(new OtpErlangObject[] { ref, tResult }); + connection.send(pid, msg); + } + public void run() { + OtpErlangTuple request = null; + OtpErlangPid senderPid = null; + OtpErlangRef senderRef = null; + try { + OtpErlangTuple call = (OtpErlangTuple) connection.receive(); + OtpErlangTuple from = (OtpErlangTuple) call.elementAt(1); + request = (OtpErlangTuple) call.elementAt(2); + senderPid = (OtpErlangPid) from.elementAt(0); + senderRef = (OtpErlangRef) from.elementAt(1); + String module = ((OtpErlangAtom) request.elementAt(1)).atomValue(); + String function = ((OtpErlangAtom) request.elementAt(2)) + .atomValue(); + OtpErlangObject args = request.elementAt(3); + OtpErlangList argsList = null; + if (args instanceof OtpErlangList) { + argsList = (OtpErlangList) args; + } else { + argsList = new OtpErlangList(args); + } + if (!binding.getModule().equals(module)) { + // TODO: externalize message? + OtpErlangObject errorMsg = MessageHelper.functionUndefMessage( + module, function, argsList, + "Module not found in SCA component."); + sendMessage(connection, senderPid, senderRef, BADRPC, errorMsg); + } else { + List<Operation> operations = service.getInterfaceContract() + .getInterface().getOperations(); + Operation operation = null; + for (Operation o : operations) { + if (o.getName().equals(function)) { + operation = o; + break; + } + } + if (operation != null) { + List<DataType> iTypes = operation.getInputType() + .getLogical(); + Class<?>[] forClasses = new Class<?>[iTypes.size()]; + for (int i = 0; i < iTypes.size(); i++) { + forClasses[i] = iTypes.get(i).getPhysical(); + } + try { + Object result = service.getRuntimeWire(binding).invoke( + operation, + TypeHelpersProxy.toJavaFromList(argsList, + forClasses)); + OtpErlangObject response = null; + if (operation.getOutputType() != null + && operation.getOutputType().getPhysical() + .isArray()) { + response = TypeHelpersProxy.toErlangAsList(result); + } else if (operation.getOutputType() == null) { + Object[] arrArg = new Object[] {}; + response = TypeHelpersProxy.toErlang(arrArg); + } else { + Object[] arrArg = new Object[] { result }; + response = TypeHelpersProxy.toErlang(arrArg); + } + sendMessage(connection, senderPid, senderRef, OK, + response); + } catch (Exception e) { + if ((e.getClass().equals( + InvocationTargetException.class) && e + .getCause().getClass().equals( + IllegalArgumentException.class)) + || e.getClass().equals( + TypeMismatchException.class)) { + // TODO: externalize message? + OtpErlangObject errorMsg = MessageHelper + .functionUndefMessage(module, function, + argsList, + "Operation name found in SCA component, but parameters types didn't match."); + sendMessage(connection, senderPid, senderRef, + BADRPC, errorMsg); + } else { + throw e; + } + } + } else { + // TODO: externalize message? + OtpErlangObject errorMsg = MessageHelper + .functionUndefMessage(module, function, argsList, + "Operation name not found in SCA component."); + sendMessage(connection, senderPid, senderRef, BADRPC, + errorMsg); + } + } + } catch (Exception e) { + // TODO: distinguish and describe errors! + try { + e.printStackTrace(); + sendMessage(connection, senderPid, senderRef, ERROR, + new OtpErlangString( + "Unhandled error while processing request: " + + e.getClass().getCanonicalName() + + ", message: " + e.getMessage())); + } catch (IOException e1) { + // error while sending error message. Can't do anything now + } + } finally { + connection.close(); + } + } } diff --git a/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/RpcServer.java b/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/RpcServer.java index 90c47091e8..ab10865c83 100644 --- a/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/RpcServer.java +++ b/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/RpcServer.java @@ -23,6 +23,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.apache.tuscany.sca.binding.erlang.ErlangBinding; +import org.apache.tuscany.sca.binding.erlang.impl.exceptions.ErlangException; import org.apache.tuscany.sca.runtime.RuntimeComponentService; import com.ericsson.otp.erlang.OtpConnection; @@ -33,6 +34,8 @@ public class RpcServer implements Runnable { private RuntimeComponentService service; private ErlangBinding binding; private OtpSelf self; + ExecutorService executors; + private boolean stopRequested; public RpcServer(RuntimeComponentService service, ErlangBinding binding) throws Exception { this.service = service; @@ -40,14 +43,19 @@ public class RpcServer implements Runnable { self = new OtpSelf(binding.getNode()); boolean registered = self.publishPort(); if (!registered) { - // TODO: throw exception, no epmd + //TODO: externalize messages? + throw new ErlangException("Problem with publishing service under epmd server."); } + executors = Executors.newFixedThreadPool(10); + } + + public void stop() { + stopRequested = true; + executors.shutdownNow(); } public void run() { - // TODO: thread management - ExecutorService executors = Executors.newFixedThreadPool(10); - while (true) { + while (!stopRequested) { try { OtpConnection connection = self.accept(); executors.execute(new RpcExecutor(service, binding, connection)); diff --git a/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/TypeMismatchException.java b/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/TypeMismatchException.java index 7a3e727aa4..03b53b60bd 100644 --- a/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/TypeMismatchException.java +++ b/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/TypeMismatchException.java @@ -30,6 +30,10 @@ public class TypeMismatchException extends Exception { this.expected = expected; this.received = received; } + + public TypeMismatchException() { + super("Arguments don't match"); + } public Class<?> getExpected() { return expected; diff --git a/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/exceptions/ErlangException.java b/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/exceptions/ErlangException.java new file mode 100644 index 0000000000..6ae919b969 --- /dev/null +++ b/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/exceptions/ErlangException.java @@ -0,0 +1,9 @@ +package org.apache.tuscany.sca.binding.erlang.impl.exceptions; + +public class ErlangException extends Exception { + + public ErlangException(String message) { + super(message); + } + +} diff --git a/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/TypeHelpersProxy.java b/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/TypeHelpersProxy.java index e695f87dce..208216eef2 100644 --- a/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/TypeHelpersProxy.java +++ b/sandbox/wjaniszewski/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/types/TypeHelpersProxy.java @@ -33,115 +33,122 @@ import com.ericsson.otp.erlang.OtpErlangTuple; public class TypeHelpersProxy {
- private static Map<Class<?>, TypeHelper> primitiveTypes = null;
+ private static Map<Class<?>, TypeHelper> primitiveTypes = null;
- static {
- // initiate type helpers
- primitiveTypes = new HashMap<Class<?>, TypeHelper>();
- primitiveTypes.put(boolean.class, new BooleanTypeHelper());
- primitiveTypes.put(short.class, new ShortTypeHelper());
- primitiveTypes.put(byte.class, new ByteTypeHelper());
- primitiveTypes.put(char.class, new CharTypeHelper());
- primitiveTypes.put(int.class, new IntTypeHelper());
- primitiveTypes.put(long.class, new LongTypeHelper());
- primitiveTypes.put(float.class, new FloatTypeHelper());
- primitiveTypes.put(double.class, new DoubleTypeHelper());
- primitiveTypes.put(String.class, new StringTypeHelper());
- primitiveTypes.put(Boolean.class, primitiveTypes.get(boolean.class));
- primitiveTypes.put(Character.class, primitiveTypes.get(char.class));
- primitiveTypes.put(Short.class, primitiveTypes.get(char.class));
- primitiveTypes.put(Byte.class, primitiveTypes.get(byte.class));
- primitiveTypes.put(Short.class, primitiveTypes.get(short.class));
- primitiveTypes.put(Integer.class, primitiveTypes.get(int.class));
- primitiveTypes.put(Long.class, primitiveTypes.get(long.class));
- primitiveTypes.put(Float.class, primitiveTypes.get(float.class));
- primitiveTypes.put(Double.class, primitiveTypes.get(double.class));
- primitiveTypes.put(String.class, primitiveTypes.get(String.class));
- }
+ static {
+ // initiate type helpers
+ primitiveTypes = new HashMap<Class<?>, TypeHelper>();
+ primitiveTypes.put(boolean.class, new BooleanTypeHelper());
+ primitiveTypes.put(short.class, new ShortTypeHelper());
+ primitiveTypes.put(byte.class, new ByteTypeHelper());
+ primitiveTypes.put(char.class, new CharTypeHelper());
+ primitiveTypes.put(int.class, new IntTypeHelper());
+ primitiveTypes.put(long.class, new LongTypeHelper());
+ primitiveTypes.put(float.class, new FloatTypeHelper());
+ primitiveTypes.put(double.class, new DoubleTypeHelper());
+ primitiveTypes.put(String.class, new StringTypeHelper());
+ primitiveTypes.put(Boolean.class, primitiveTypes.get(boolean.class));
+ primitiveTypes.put(Character.class, primitiveTypes.get(char.class));
+ primitiveTypes.put(Short.class, primitiveTypes.get(char.class));
+ primitiveTypes.put(Byte.class, primitiveTypes.get(byte.class));
+ primitiveTypes.put(Short.class, primitiveTypes.get(short.class));
+ primitiveTypes.put(Integer.class, primitiveTypes.get(int.class));
+ primitiveTypes.put(Long.class, primitiveTypes.get(long.class));
+ primitiveTypes.put(Float.class, primitiveTypes.get(float.class));
+ primitiveTypes.put(Double.class, primitiveTypes.get(double.class));
+ primitiveTypes.put(String.class, primitiveTypes.get(String.class));
+ }
- private static TypeHelper getTypeHelper(Class<?> forClass) {
- TypeHelper typeHelper = null;
- if (forClass.isArray()) {
- typeHelper = new ListTypeHelper();
- } else {
- typeHelper = primitiveTypes.get(forClass);
- }
- if (typeHelper == null) {
- typeHelper = new TupleTypeHelper();
- }
- return typeHelper;
- }
+ private static TypeHelper getTypeHelper(Class<?> forClass) {
+ TypeHelper typeHelper = null;
+ if (forClass.isArray()) {
+ typeHelper = new ListTypeHelper();
+ } else {
+ typeHelper = primitiveTypes.get(forClass);
+ }
+ if (typeHelper == null) {
+ typeHelper = new TupleTypeHelper();
+ }
+ return typeHelper;
+ }
- public static OtpErlangObject toErlang(Object[] objects) {
- OtpErlangObject result = null;
- if (objects != null) {
- TypeHelper helper = null;
- switch (objects.length) {
- case 0:
- result = new OtpErlangList();
- break;
- case 1:
- helper = getTypeHelper(objects[0].getClass());
- result = helper.toErlang(objects[0]);
- break;
- default:
- OtpErlangObject[] erlObjects = new OtpErlangObject[objects.length];
- for (int i = 0; i < objects.length; i++) {
- helper = getTypeHelper(objects[i].getClass());
- erlObjects[i] = helper.toErlang(objects[i]);
- }
- result = new OtpErlangTuple(erlObjects);
- break;
- }
- }
- return result;
- }
+ public static OtpErlangObject toErlang(Object[] objects) {
+ OtpErlangObject result = null;
+ if (objects != null) {
+ TypeHelper helper = null;
+ switch (objects.length) {
+ case 0:
+ result = new OtpErlangList();
+ break;
+ case 1:
+ helper = getTypeHelper(objects[0].getClass());
+ result = helper.toErlang(objects[0]);
+ break;
+ default:
+ OtpErlangObject[] erlObjects = new OtpErlangObject[objects.length];
+ for (int i = 0; i < objects.length; i++) {
+ helper = getTypeHelper(objects[i].getClass());
+ erlObjects[i] = helper.toErlang(objects[i]);
+ }
+ result = new OtpErlangTuple(erlObjects);
+ break;
+ }
+ }
+ return result;
+ }
- public static OtpErlangList toErlangAsList(Object array) {
- OtpErlangList result = null;
- if (array != null) {
- if (!array.getClass().isArray()) {
- array = new Object[] {array};
- }
- List<OtpErlangObject> attrsList = new ArrayList<OtpErlangObject>();
- int i = 0;
- while (true) {
- try {
- TypeHelper helper = getTypeHelper(Array.get(array, i).getClass());
- attrsList.add(helper.toErlang(Array.get(array, i)));
- i++;
- } catch (ArrayIndexOutOfBoundsException e) {
- break;
- }
- }
- result = new OtpErlangList(attrsList.toArray(new OtpErlangObject[attrsList.size()]));
- } else {
- result = new OtpErlangList();
- }
- return result;
- }
+ public static OtpErlangList toErlangAsList(Object array) {
+ OtpErlangList result = null;
+ if (array != null) {
+ if (!array.getClass().isArray()) {
+ array = new Object[] { array };
+ }
+ List<OtpErlangObject> attrsList = new ArrayList<OtpErlangObject>();
+ int i = 0;
+ while (true) {
+ try {
+ TypeHelper helper = getTypeHelper(Array.get(array, i)
+ .getClass());
+ attrsList.add(helper.toErlang(Array.get(array, i)));
+ i++;
+ } catch (ArrayIndexOutOfBoundsException e) {
+ break;
+ }
+ }
+ result = new OtpErlangList(attrsList
+ .toArray(new OtpErlangObject[attrsList.size()]));
+ } else {
+ result = new OtpErlangList();
+ }
+ return result;
+ }
- public static Object toJava(OtpErlangObject object, Class<?> forClass) throws Exception {
- try {
- TypeHelper helper = getTypeHelper(forClass);
- return helper.toJava(object, forClass);
- } catch (ClassCastException e) {
- throw new TypeMismatchException(forClass, object.getClass());
- }
- }
+ public static Object toJava(OtpErlangObject object, Class<?> forClass)
+ throws Exception {
+ try {
+ TypeHelper helper = getTypeHelper(forClass);
+ return helper.toJava(object, forClass);
+ } catch (ClassCastException e) {
+ throw new TypeMismatchException(forClass, object.getClass());
+ }
+ }
- public static Object[] toJavaFromList(OtpErlangList objects, Class<?>[] forClass) throws Exception {
- Object[] result = new Object[objects.arity()];
- try {
- for (int i = 0; i < objects.arity(); i++) {
- TypeHelper helper = getTypeHelper(forClass[i]);
- result[i] = helper.toJava(objects.elementAt(i), forClass[i]);
- }
- } catch (ClassCastException e) {
- e.printStackTrace();
- // throw new TypeMismatchException(forClass, objects[i].getClass());
- }
- return result;
- }
+ public static Object[] toJavaFromList(OtpErlangList objects,
+ Class<?>[] forClass) throws Exception {
+ Object[] result = new Object[objects.arity()];
+ try {
+ for (int i = 0; i < objects.arity(); i++) {
+ TypeHelper helper = getTypeHelper(forClass[i]);
+ result[i] = helper.toJava(objects.elementAt(i), forClass[i]);
+ }
+ } catch (Exception e) {
+ // type mismatch as mismatch of parameters count or parameters type
+ if (e.getClass().equals(ClassCastException.class)
+ || e.getClass()
+ .equals(ArrayIndexOutOfBoundsException.class))
+ throw new TypeMismatchException();
+ }
+ return result;
+ }
}
|