in modules/binding-erlang-runtime/src/main/java/org/apache/tuscany/sca/binding/erlang/impl/ServiceExecutor.java [88:226]
private void handleRpc(OtpMsg msg) {
OtpErlangTuple request = null;
OtpErlangPid senderPid = null;
OtpErlangRef senderRef = null;
try {
OtpErlangTuple call = (OtpErlangTuple) msg.getMsg();
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;
// normalize input
if (args instanceof OtpErlangList) {
argsList = (OtpErlangList) args;
} else {
argsList = new OtpErlangList(args);
}
if (!nodeElement.getBinding().getModule().equals(module)) {
// module not found
// TODO: externalize message?
OtpErlangObject errorMsg = MessageHelper.functionUndefMessage(
module, function, argsList,
"Module not found in SCA component.");
sendMessage(connection, senderPid, senderRef,
MessageHelper.ATOM_BADRPC, errorMsg);
} else {
// module found, looking for operation
RuntimeComponentService service = nodeElement.getService();
ErlangBinding binding = nodeElement.getBinding();
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) {
// operation found
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 {
// invoke operation
Method jmethod = ((JavaOperation) operation)
.getJavaMethod();
Object result = service.getRuntimeWire(binding,
service.getInterfaceContract()).invoke(
operation,
TypeHelpersProxy.toJavaFromList(argsList,
forClasses, jmethod
.getParameterAnnotations()));
OtpErlangObject response = null;
// send reply
if (operation.getOutputType() != null
&& operation.getOutputType().getPhysical()
.isArray()) {
// output type is array
response = TypeHelpersProxy.toErlangAsResultList(
result, jmethod.getAnnotations());
} else if (operation.getOutputType() == null) {
// output type is void, create empty reply
Object[] arrArg = new Object[] {};
response = TypeHelpersProxy.toErlang(arrArg,
new Annotation[0][0]);
} else {
// output type is not void and not array
response = TypeHelpersProxy.toErlang(result,
jmethod.getAnnotations());
}
sendMessage(connection, senderPid, senderRef, null,
response);
} catch (Exception e) {
if ((e.getClass().equals(
InvocationTargetException.class) && e
.getCause().getClass().equals(
IllegalArgumentException.class))
|| e.getClass().equals(
TypeMismatchException.class)) {
// wrong params
// 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,
MessageHelper.ATOM_BADRPC, errorMsg);
} else {
// unexpected error
throw e;
}
}
} else {
// operation not found
// TODO: externalize message?
OtpErlangObject errorMsg = MessageHelper
.functionUndefMessage(module, function, argsList,
"Operation name not found in SCA component.");
sendMessage(connection, senderPid, senderRef,
MessageHelper.ATOM_BADRPC, errorMsg);
}
}
} catch (ClassCastException e) {
// invalid request
// TODO: externalize message?
try {
logger
.log(
Level.WARNING,
"On node '"
+ nodeElement.getBinding().getNode()
+ "' received RPC request which is invalid. Request content is: "
+ msg.getMsg());
} catch (OtpErlangDecodeException e1) {
}
} catch (Exception e) {
// unknown error
try {
sendMessage(connection, senderPid, senderRef,
MessageHelper.ATOM_ERROR, new OtpErlangString(
"Unhandled error while processing request: "
+ e.getClass().getCanonicalName()
+ ", message: " + e.getMessage()));
} catch (Exception e1) {
// error while sending error message. Can't do anything now
logger.log(Level.WARNING, "Error during sending error message",
e);
}
}
}