Added configurable timeout and cookies for service bindings. Consequence is that one SCA-Erlang node is created excusively for one service binding, so service bindings cannot share the same value in 'node' attribute like it was before. Made some other fixes.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@756480 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
e962b3bbdf
commit
fce6ad4c30
14 changed files with 229 additions and 272 deletions
|
@ -19,8 +19,8 @@
|
||||||
|
|
||||||
package org.apache.tuscany.sca.binding.erlang.impl;
|
package org.apache.tuscany.sca.binding.erlang.impl;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Set;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
@ -39,9 +39,10 @@ import org.apache.tuscany.sca.runtime.RuntimeComponentService;
|
||||||
public class ErlangBindingProviderFactory implements
|
public class ErlangBindingProviderFactory implements
|
||||||
BindingProviderFactory<ErlangBinding> {
|
BindingProviderFactory<ErlangBinding> {
|
||||||
|
|
||||||
private Map<String, ErlangNode> nodes = new HashMap<String, ErlangNode>();
|
|
||||||
private static final Logger logger = Logger
|
private static final Logger logger = Logger
|
||||||
.getLogger(ErlangBindingProviderFactory.class.getName());
|
.getLogger(ErlangBindingProviderFactory.class.getName());
|
||||||
|
|
||||||
|
private Set<String> nodes = new HashSet<String>();
|
||||||
|
|
||||||
public ErlangBindingProviderFactory(ExtensionPointRegistry registry) {
|
public ErlangBindingProviderFactory(ExtensionPointRegistry registry) {
|
||||||
|
|
||||||
|
@ -68,10 +69,18 @@ public class ErlangBindingProviderFactory implements
|
||||||
ErlangBinding binding) {
|
ErlangBinding binding) {
|
||||||
ServiceBindingProvider provider = null;
|
ServiceBindingProvider provider = null;
|
||||||
try {
|
try {
|
||||||
provider = new ErlangServiceBindingProvider(getErlangNode(binding
|
if (nodes.contains(binding.getNode())) {
|
||||||
.getNode()), binding, service);
|
// TODO: externalize message?
|
||||||
|
logger.log(Level.WARNING,
|
||||||
|
"Node name '" + binding.getNode() + "' already registered. This service will not be spawned.");
|
||||||
|
} else {
|
||||||
|
provider = new ErlangServiceBindingProvider(binding, service);
|
||||||
|
nodes.add(binding.getNode());
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.log(Level.WARNING, "Exception during creating ServiceBindingProvider", e);
|
// TODO: externalize message?
|
||||||
|
logger.log(Level.WARNING,
|
||||||
|
"Exception during creating ServiceBindingProvider", e);
|
||||||
}
|
}
|
||||||
return provider;
|
return provider;
|
||||||
}
|
}
|
||||||
|
@ -82,16 +91,4 @@ public class ErlangBindingProviderFactory implements
|
||||||
public Class<ErlangBinding> getModelType() {
|
public Class<ErlangBinding> getModelType() {
|
||||||
return ErlangBinding.class;
|
return ErlangBinding.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ErlangNode getErlangNode(String name) throws Exception {
|
|
||||||
ErlangNode result = null;
|
|
||||||
if (nodes.containsKey(name)) {
|
|
||||||
result = nodes.get(name);
|
|
||||||
} else {
|
|
||||||
result = new ErlangNode(name);
|
|
||||||
nodes.put(name, result);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,10 +66,6 @@ public class ErlangInvoker implements Invoker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isCookieProvided() throws Exception {
|
|
||||||
return binding.getCookie() != null && binding.getCookie().length() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getClientNodeName() {
|
private String getClientNodeName() {
|
||||||
return "_connector_to_" + binding.getNode()
|
return "_connector_to_" + binding.getNode()
|
||||||
+ System.currentTimeMillis();
|
+ System.currentTimeMillis();
|
||||||
|
@ -80,7 +76,7 @@ public class ErlangInvoker implements Invoker {
|
||||||
OtpNode node = null;
|
OtpNode node = null;
|
||||||
try {
|
try {
|
||||||
node = new OtpNode(getClientNodeName());
|
node = new OtpNode(getClientNodeName());
|
||||||
if (isCookieProvided()) {
|
if (binding.hasCookie()) {
|
||||||
node.setCookie(binding.getCookie());
|
node.setCookie(binding.getCookie());
|
||||||
}
|
}
|
||||||
tmpMbox = node.createMbox();
|
tmpMbox = node.createMbox();
|
||||||
|
@ -89,7 +85,12 @@ public class ErlangInvoker implements Invoker {
|
||||||
tmpMbox.send(msg.getOperation().getName(), binding.getNode(),
|
tmpMbox.send(msg.getOperation().getName(), binding.getNode(),
|
||||||
msgPayload);
|
msgPayload);
|
||||||
if (msg.getOperation().getOutputType() != null) {
|
if (msg.getOperation().getOutputType() != null) {
|
||||||
OtpMsg resultMsg = tmpMbox.receiveMsg(binding.getTimeout());
|
OtpMsg resultMsg = null;
|
||||||
|
if (binding.hasTimeout()) {
|
||||||
|
resultMsg = tmpMbox.receiveMsg(binding.getTimeout());
|
||||||
|
} else {
|
||||||
|
resultMsg = tmpMbox.receiveMsg();
|
||||||
|
}
|
||||||
OtpErlangObject result = resultMsg.getMsg();
|
OtpErlangObject result = resultMsg.getMsg();
|
||||||
msg.setBody(TypeHelpersProxy.toJava(result, msg.getOperation()
|
msg.setBody(TypeHelpersProxy.toJava(result, msg.getOperation()
|
||||||
.getOutputType().getPhysical()));
|
.getOutputType().getPhysical()));
|
||||||
|
@ -120,7 +121,7 @@ public class ErlangInvoker implements Invoker {
|
||||||
OtpConnection connection = null;
|
OtpConnection connection = null;
|
||||||
try {
|
try {
|
||||||
self = new OtpSelf(getClientNodeName());
|
self = new OtpSelf(getClientNodeName());
|
||||||
if (isCookieProvided()) {
|
if (binding.hasCookie()) {
|
||||||
self.setCookie(binding.getCookie());
|
self.setCookie(binding.getCookie());
|
||||||
}
|
}
|
||||||
other = new OtpPeer(binding.getNode());
|
other = new OtpPeer(binding.getNode());
|
||||||
|
@ -131,8 +132,12 @@ public class ErlangInvoker implements Invoker {
|
||||||
.createRef(), binding.getModule(), msg.getOperation()
|
.createRef(), binding.getModule(), msg.getOperation()
|
||||||
.getName(), params);
|
.getName(), params);
|
||||||
connection.send(MessageHelper.RPC_MBOX, message);
|
connection.send(MessageHelper.RPC_MBOX, message);
|
||||||
OtpErlangObject rpcResponse = connection.receive(binding
|
OtpErlangObject rpcResponse = null;
|
||||||
.getTimeout());
|
if (binding.hasTimeout()) {
|
||||||
|
rpcResponse = connection.receive(binding.getTimeout());
|
||||||
|
} else {
|
||||||
|
rpcResponse = connection.receive();
|
||||||
|
}
|
||||||
OtpErlangObject result = ((OtpErlangTuple) rpcResponse)
|
OtpErlangObject result = ((OtpErlangTuple) rpcResponse)
|
||||||
.elementAt(1);
|
.elementAt(1);
|
||||||
if (MessageHelper.isfunctionUndefMessage(result)) {
|
if (MessageHelper.isfunctionUndefMessage(result)) {
|
||||||
|
@ -153,7 +158,9 @@ public class ErlangInvoker implements Invoker {
|
||||||
}
|
}
|
||||||
} catch (OtpAuthException e) {
|
} catch (OtpAuthException e) {
|
||||||
// TODO: externalize message?
|
// TODO: externalize message?
|
||||||
ErlangException ee = new ErlangException("Problem while authenticating client - check your cookie", e);
|
ErlangException ee = new ErlangException(
|
||||||
|
"Problem while authenticating client - check your cookie",
|
||||||
|
e);
|
||||||
msg.setBody(null);
|
msg.setBody(null);
|
||||||
reportProblem(msg, ee);
|
reportProblem(msg, ee);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
|
|
@ -46,16 +46,15 @@ public class ErlangNode implements Runnable {
|
||||||
private static final Logger logger = Logger.getLogger(ErlangNode.class
|
private static final Logger logger = Logger.getLogger(ErlangNode.class
|
||||||
.getName());
|
.getName());
|
||||||
|
|
||||||
private Map<String, ErlangNodeElement> erlangModules = new HashMap<String, ErlangNodeElement>();
|
private ErlangNodeElement nodeElement;
|
||||||
private ErlangNodeElement erlangMbox;
|
|
||||||
private boolean mboxNode;
|
|
||||||
private String name;
|
private String name;
|
||||||
private OtpSelf self;
|
private OtpSelf self;
|
||||||
private ExecutorService executors;
|
private ExecutorService executors;
|
||||||
private boolean stopRequested;
|
private boolean stopRequested;
|
||||||
private Map<String, List<Operation>> groupedOperations;
|
private Map<String, List<Operation>> groupedOperations;
|
||||||
|
|
||||||
public ErlangNode(String name) throws Exception {
|
public ErlangNode(String name, ErlangBinding binding,
|
||||||
|
RuntimeComponentService service) throws Exception {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
self = new OtpSelf(name);
|
self = new OtpSelf(name);
|
||||||
boolean registered = self.publishPort();
|
boolean registered = self.publishPort();
|
||||||
|
@ -64,9 +63,13 @@ public class ErlangNode implements Runnable {
|
||||||
throw new ErlangException(
|
throw new ErlangException(
|
||||||
"Problem with publishing service under epmd server.");
|
"Problem with publishing service under epmd server.");
|
||||||
}
|
}
|
||||||
|
if (binding.hasCookie()) {
|
||||||
|
self.setCookie(binding.getCookie());
|
||||||
|
}
|
||||||
|
registerBinding(binding, service);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stop() {
|
public void stop() {
|
||||||
stopRequested = true;
|
stopRequested = true;
|
||||||
executors.shutdownNow();
|
executors.shutdownNow();
|
||||||
}
|
}
|
||||||
|
@ -78,76 +81,38 @@ public class ErlangNode implements Runnable {
|
||||||
try {
|
try {
|
||||||
OtpConnection connection = self.accept();
|
OtpConnection connection = self.accept();
|
||||||
executors.execute(new ServiceExecutor(connection,
|
executors.execute(new ServiceExecutor(connection,
|
||||||
groupedOperations, erlangModules, erlangMbox, name));
|
groupedOperations, nodeElement, name));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// TODO: externalzie message?
|
// TODO: externalzie message?
|
||||||
logger.log(Level.WARNING,
|
logger.log(Level.WARNING,
|
||||||
"Error occured while accepting connection on '" + name
|
"Error occured while accepting connection on '" + name
|
||||||
+ "' node");
|
+ "' node", e);
|
||||||
} catch (OtpAuthException e) {
|
} catch (OtpAuthException e) {
|
||||||
// TODO: log bad authentication attempt
|
// TODO: externalize message?
|
||||||
|
logger.log(Level.WARNING, "Error while authenticating client", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerBinding(ErlangBinding binding,
|
private void registerBinding(ErlangBinding binding,
|
||||||
RuntimeComponentService service) throws ErlangException {
|
RuntimeComponentService service) throws ErlangException {
|
||||||
if (binding.isMbox()) {
|
if (binding.isMbox()) {
|
||||||
if (mboxNode) {
|
List<Operation> operations = service.getInterfaceContract()
|
||||||
// TODO: externalize message?
|
.getInterface().getOperations();
|
||||||
// NOTE: if mbox registered more than once for node then
|
groupedOperations = new HashMap<String, List<Operation>>();
|
||||||
// exception will be thrown
|
for (Operation operation : operations) {
|
||||||
throw new ErlangException("Node " + binding.getNode()
|
List<Operation> operationsGroup = groupedOperations
|
||||||
+ " already defined as mbox node");
|
.get(operation.getName());
|
||||||
} else {
|
if (operationsGroup == null) {
|
||||||
List<Operation> operations = service.getInterfaceContract()
|
operationsGroup = new ArrayList<Operation>();
|
||||||
.getInterface().getOperations();
|
groupedOperations.put(operation.getName(), operationsGroup);
|
||||||
groupedOperations = new HashMap<String, List<Operation>>();
|
|
||||||
for (Operation operation : operations) {
|
|
||||||
List<Operation> operationsGroup = groupedOperations
|
|
||||||
.get(operation.getName());
|
|
||||||
if (operationsGroup == null) {
|
|
||||||
operationsGroup = new ArrayList<Operation>();
|
|
||||||
groupedOperations.put(operation.getName(),
|
|
||||||
operationsGroup);
|
|
||||||
}
|
|
||||||
operationsGroup.add(operation);
|
|
||||||
}
|
}
|
||||||
mboxNode = true;
|
operationsGroup.add(operation);
|
||||||
erlangMbox = new ErlangNodeElement();
|
|
||||||
erlangMbox.setService(service);
|
|
||||||
erlangMbox.setBinding(binding);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (erlangModules.containsKey(binding.getModule())) {
|
|
||||||
// TODO: externalize message?
|
|
||||||
// NOTE: if the same module was registered more than once than
|
|
||||||
// exception will be thrown
|
|
||||||
throw new ErlangException("Module " + binding.getModule()
|
|
||||||
+ " already defined under " + name
|
|
||||||
+ " node. Duplicate module won't be started");
|
|
||||||
} else {
|
|
||||||
if (erlangModules.size() == 0) {
|
|
||||||
// NOTE: Erlang node is managing it's thread by itself. Just noticing.
|
|
||||||
Thread selfThread = new Thread(this);
|
|
||||||
selfThread.start();
|
|
||||||
}
|
|
||||||
ErlangNodeElement module = new ErlangNodeElement();
|
|
||||||
module.setService(service);
|
|
||||||
module.setBinding(binding);
|
|
||||||
erlangModules.put(binding.getModule(), module);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void unregisterBinding(ErlangBinding binding) throws ErlangException {
|
|
||||||
if (erlangModules.containsKey(binding.getModule())) {
|
|
||||||
erlangModules.remove(binding.getModule());
|
|
||||||
erlangModules.remove(binding.getModule());
|
|
||||||
if (erlangModules.size() == 0) {
|
|
||||||
stop();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
nodeElement = new ErlangNodeElement();
|
||||||
|
nodeElement.setService(service);
|
||||||
|
nodeElement.setBinding(binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,13 +32,11 @@ public class ErlangServiceBindingProvider implements ServiceBindingProvider {
|
||||||
|
|
||||||
private RuntimeComponentService service;
|
private RuntimeComponentService service;
|
||||||
private ErlangNode node;
|
private ErlangNode node;
|
||||||
private ErlangBinding binding;
|
|
||||||
|
|
||||||
public ErlangServiceBindingProvider(ErlangNode node, ErlangBinding binding,
|
public ErlangServiceBindingProvider(ErlangBinding binding,
|
||||||
RuntimeComponentService service) {
|
RuntimeComponentService service) throws Exception {
|
||||||
this.service = service;
|
this.service = service;
|
||||||
this.binding = binding;
|
this.node = new ErlangNode(binding.getNode(), binding, service);
|
||||||
this.node = node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,7 +51,8 @@ public class ErlangServiceBindingProvider implements ServiceBindingProvider {
|
||||||
*/
|
*/
|
||||||
public void start() {
|
public void start() {
|
||||||
try {
|
try {
|
||||||
node.registerBinding(binding, service);
|
Thread thread = new Thread(node);
|
||||||
|
thread.start();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ServiceRuntimeException(e);
|
throw new ServiceRuntimeException(e);
|
||||||
}
|
}
|
||||||
|
@ -65,7 +64,7 @@ public class ErlangServiceBindingProvider implements ServiceBindingProvider {
|
||||||
*/
|
*/
|
||||||
public void stop() {
|
public void stop() {
|
||||||
try {
|
try {
|
||||||
node.unregisterBinding(binding);
|
node.stop();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ServiceRuntimeException(e);
|
throw new ServiceRuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ import org.apache.tuscany.sca.runtime.RuntimeComponentService;
|
||||||
import com.ericsson.otp.erlang.OtpAuthException;
|
import com.ericsson.otp.erlang.OtpAuthException;
|
||||||
import com.ericsson.otp.erlang.OtpConnection;
|
import com.ericsson.otp.erlang.OtpConnection;
|
||||||
import com.ericsson.otp.erlang.OtpErlangAtom;
|
import com.ericsson.otp.erlang.OtpErlangAtom;
|
||||||
|
import com.ericsson.otp.erlang.OtpErlangDecodeException;
|
||||||
import com.ericsson.otp.erlang.OtpErlangExit;
|
import com.ericsson.otp.erlang.OtpErlangExit;
|
||||||
import com.ericsson.otp.erlang.OtpErlangList;
|
import com.ericsson.otp.erlang.OtpErlangList;
|
||||||
import com.ericsson.otp.erlang.OtpErlangObject;
|
import com.ericsson.otp.erlang.OtpErlangObject;
|
||||||
|
@ -53,22 +54,18 @@ public class ServiceExecutor implements Runnable {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(ServiceExecutor.class
|
private static final Logger logger = Logger.getLogger(ServiceExecutor.class
|
||||||
.getName());
|
.getName());
|
||||||
private static final long RECEIVE_TIMEOUT = 60000;
|
|
||||||
|
|
||||||
private Map<String, ErlangNodeElement> erlangModules;
|
private ErlangNodeElement nodeElement;
|
||||||
private ErlangNodeElement erlangMbox;
|
|
||||||
private OtpConnection connection;
|
private OtpConnection connection;
|
||||||
private Map<String, List<Operation>> groupedOperations;
|
private Map<String, List<Operation>> groupedOperations;
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
public ServiceExecutor(OtpConnection connection,
|
public ServiceExecutor(OtpConnection connection,
|
||||||
Map<String, List<Operation>> groupedOperations,
|
Map<String, List<Operation>> groupedOperations,
|
||||||
Map<String, ErlangNodeElement> erlangModules,
|
ErlangNodeElement nodeElement, String name) {
|
||||||
ErlangNodeElement erlangMbox, String name) {
|
|
||||||
this.erlangModules = erlangModules;
|
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
this.groupedOperations = groupedOperations;
|
this.groupedOperations = groupedOperations;
|
||||||
this.erlangMbox = erlangMbox;
|
this.nodeElement = nodeElement;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +79,10 @@ public class ServiceExecutor implements Runnable {
|
||||||
connection.send(pid, msg);
|
connection.send(pid, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getResponseClientNodeName(OtpErlangPid pid) {
|
||||||
|
return "_response_connector_to_" + pid + System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
private void handleRpc(OtpMsg msg) {
|
private void handleRpc(OtpMsg msg) {
|
||||||
OtpErlangTuple request = null;
|
OtpErlangTuple request = null;
|
||||||
OtpErlangPid senderPid = null;
|
OtpErlangPid senderPid = null;
|
||||||
|
@ -103,7 +104,7 @@ public class ServiceExecutor implements Runnable {
|
||||||
} else {
|
} else {
|
||||||
argsList = new OtpErlangList(args);
|
argsList = new OtpErlangList(args);
|
||||||
}
|
}
|
||||||
if (!erlangModules.containsKey(module)) {
|
if (!nodeElement.getBinding().getModule().equals(module)) {
|
||||||
// TODO: externalize message?
|
// TODO: externalize message?
|
||||||
OtpErlangObject errorMsg = MessageHelper.functionUndefMessage(
|
OtpErlangObject errorMsg = MessageHelper.functionUndefMessage(
|
||||||
module, function, argsList,
|
module, function, argsList,
|
||||||
|
@ -111,9 +112,8 @@ public class ServiceExecutor implements Runnable {
|
||||||
sendMessage(connection, senderPid, senderRef,
|
sendMessage(connection, senderPid, senderRef,
|
||||||
MessageHelper.ATOM_BADRPC, errorMsg);
|
MessageHelper.ATOM_BADRPC, errorMsg);
|
||||||
} else {
|
} else {
|
||||||
RuntimeComponentService service = erlangModules.get(module)
|
RuntimeComponentService service = nodeElement.getService();
|
||||||
.getService();
|
ErlangBinding binding = nodeElement.getBinding();
|
||||||
ErlangBinding binding = erlangModules.get(module).getBinding();
|
|
||||||
List<Operation> operations = service.getInterfaceContract()
|
List<Operation> operations = service.getInterfaceContract()
|
||||||
.getInterface().getOperations();
|
.getInterface().getOperations();
|
||||||
Operation operation = null;
|
Operation operation = null;
|
||||||
|
@ -177,6 +177,18 @@ public class ServiceExecutor implements Runnable {
|
||||||
MessageHelper.ATOM_BADRPC, errorMsg);
|
MessageHelper.ATOM_BADRPC, errorMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
// 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) {
|
} catch (Exception e) {
|
||||||
try {
|
try {
|
||||||
sendMessage(connection, senderPid, senderRef,
|
sendMessage(connection, senderPid, senderRef,
|
||||||
|
@ -184,11 +196,10 @@ public class ServiceExecutor implements Runnable {
|
||||||
"Unhandled error while processing request: "
|
"Unhandled error while processing request: "
|
||||||
+ e.getClass().getCanonicalName()
|
+ e.getClass().getCanonicalName()
|
||||||
+ ", message: " + e.getMessage()));
|
+ ", message: " + e.getMessage()));
|
||||||
} catch (IOException e1) {
|
} catch (Exception e1) {
|
||||||
// error while sending error message. Can't do anything now
|
// error while sending error message. Can't do anything now
|
||||||
logger.log(Level.WARNING, "Error during sending error message",
|
logger.log(Level.WARNING, "Error during sending error message",
|
||||||
e);
|
e);
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -201,7 +212,7 @@ public class ServiceExecutor implements Runnable {
|
||||||
if (operations == null) {
|
if (operations == null) {
|
||||||
// TODO: externalize message?
|
// TODO: externalize message?
|
||||||
// NOTE: I assume in Erlang sender doesn't get confirmation so
|
// NOTE: I assume in Erlang sender doesn't get confirmation so
|
||||||
// message will be send
|
// no message will be send
|
||||||
logger.log(Level.WARNING, "Node '" + name
|
logger.log(Level.WARNING, "Node '" + name
|
||||||
+ "' received message addressed to non exising mbox: "
|
+ "' received message addressed to non exising mbox: "
|
||||||
+ msg.getRecipientName());
|
+ msg.getRecipientName());
|
||||||
|
@ -224,8 +235,8 @@ public class ServiceExecutor implements Runnable {
|
||||||
}
|
}
|
||||||
if (matchedOperation != null) {
|
if (matchedOperation != null) {
|
||||||
try {
|
try {
|
||||||
Object result = erlangMbox.getService().getRuntimeWire(
|
Object result = nodeElement.getService().getRuntimeWire(
|
||||||
erlangMbox.getBinding()).invoke(matchedOperation,
|
nodeElement.getBinding()).invoke(matchedOperation,
|
||||||
args);
|
args);
|
||||||
OtpErlangObject response = null;
|
OtpErlangObject response = null;
|
||||||
if (matchedOperation.getOutputType() != null
|
if (matchedOperation.getOutputType() != null
|
||||||
|
@ -237,50 +248,65 @@ public class ServiceExecutor implements Runnable {
|
||||||
response = TypeHelpersProxy.toErlang(arrArg);
|
response = TypeHelpersProxy.toErlang(arrArg);
|
||||||
}
|
}
|
||||||
if (response != null) {
|
if (response != null) {
|
||||||
OtpNode node = new OtpNode("_response_connector_to_"
|
OtpNode node = new OtpNode(
|
||||||
+ msg.getSenderPid());
|
getResponseClientNodeName(msg.getSenderPid()));
|
||||||
OtpMbox mbox = node.createMbox();
|
OtpMbox mbox = node.createMbox();
|
||||||
mbox.send(msg.getSenderPid(), response);
|
mbox.send(msg.getSenderPid(), response);
|
||||||
}
|
}
|
||||||
} catch (InvocationTargetException e) {
|
} catch (InvocationTargetException e) {
|
||||||
// FIXME: use linking feature? send some error?
|
// FIXME: use linking feature? send some error?
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (IOException e) {
|
// } catch (IOException e) {
|
||||||
|
} catch (Exception e) {
|
||||||
// FIXME: log this problem? use linking feature? send error?
|
// FIXME: log this problem? use linking feature? send error?
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO: externalize message?
|
try {
|
||||||
// NOTE: don't send error message if mapping not found
|
// TODO: externalize message?
|
||||||
logger.log(Level.WARNING, "No mapping for such arguments in '"
|
// NOTE: don't send error message if mapping not found
|
||||||
+ msg.getRecipientName() + "' operation in '" + name
|
logger.log(Level.WARNING,
|
||||||
+ "' node.");
|
"No mapping for such arguments in '"
|
||||||
|
+ msg.getRecipientName()
|
||||||
|
+ "' operation in '" + name
|
||||||
|
+ "' node. Recevied arguments: "
|
||||||
|
+ msg.getMsg());
|
||||||
|
} catch (OtpErlangDecodeException e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
// TODO: should receive timeout be configured in .composite file?
|
// NOTE: there's also a timeout, like in reference bindings
|
||||||
OtpMsg msg = connection.receiveMsg(RECEIVE_TIMEOUT);
|
OtpMsg msg = null;
|
||||||
if (msg.getRecipientName().equals(MessageHelper.RPC_MBOX)) {
|
if (nodeElement.getBinding().hasTimeout()) {
|
||||||
|
msg = connection.receiveMsg(nodeElement.getBinding()
|
||||||
|
.getTimeout());
|
||||||
|
} else {
|
||||||
|
msg = connection.receiveMsg();
|
||||||
|
}
|
||||||
|
if (msg.getRecipientName().equals(MessageHelper.RPC_MBOX)
|
||||||
|
&& !nodeElement.getBinding().isMbox()) {
|
||||||
handleRpc(msg);
|
handleRpc(msg);
|
||||||
} else if (msg != null) {
|
} else if (!msg.getRecipientName().equals(MessageHelper.RPC_MBOX)
|
||||||
|
&& nodeElement.getBinding().isMbox()) {
|
||||||
handleMsg(msg);
|
handleMsg(msg);
|
||||||
} else {
|
} else {
|
||||||
// message receive timeout
|
// received wrong message type
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// TODO: externalize message?
|
// TODO: externalize message?
|
||||||
logger.log(Level.WARNING, "Problem while receiving message", e);
|
logger.log(Level.WARNING, "Problem while receiving message", e);
|
||||||
} catch (OtpErlangExit e) {
|
} catch (OtpErlangExit e) {
|
||||||
// TODO: linking?
|
// TODO: linking?
|
||||||
e.printStackTrace();
|
|
||||||
} catch (OtpAuthException e) {
|
} catch (OtpAuthException e) {
|
||||||
// TODO: cookies?
|
// TODO: cookies? does this exception occur sometime?
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
// TODO: when it could happen?
|
// NOTE: timeout will be logged
|
||||||
e.printStackTrace();
|
// TODO: externalize message?
|
||||||
|
logger.log(Level.WARNING, "Timeout while waiting for request", e);
|
||||||
} finally {
|
} finally {
|
||||||
connection.close();
|
connection.close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,6 @@ import java.lang.reflect.Field;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.tuscany.sca.binding.erlang.impl.exceptions.ErlangException;
|
|
||||||
|
|
||||||
import com.ericsson.otp.erlang.OtpErlangObject;
|
import com.ericsson.otp.erlang.OtpErlangObject;
|
||||||
import com.ericsson.otp.erlang.OtpErlangTuple;
|
import com.ericsson.otp.erlang.OtpErlangTuple;
|
||||||
|
|
||||||
|
@ -38,16 +36,16 @@ public class TupleTypeHelper implements TypeHelper {
|
||||||
List<OtpErlangObject> tupleMembers = new ArrayList<OtpErlangObject>();
|
List<OtpErlangObject> tupleMembers = new ArrayList<OtpErlangObject>();
|
||||||
Field[] fields = forClass.getFields();
|
Field[] fields = forClass.getFields();
|
||||||
for (int i = 0; i < fields.length; i++) {
|
for (int i = 0; i < fields.length; i++) {
|
||||||
Object[] args;
|
Object[] args = null;
|
||||||
try {
|
try {
|
||||||
args = new Object[] { fields[i].get(object) };
|
args = new Object[] { fields[i].get(object) };
|
||||||
OtpErlangObject member = TypeHelpersProxy.toErlang(args);
|
} catch (IllegalArgumentException e) {
|
||||||
tupleMembers.add(member);
|
// no problem should occur here
|
||||||
} catch (Exception e) {
|
} catch (IllegalAccessException e) {
|
||||||
// TODO: declaring toErlang method with Exception and throwing
|
// and here
|
||||||
// this?
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
OtpErlangObject member = TypeHelpersProxy.toErlang(args);
|
||||||
|
tupleMembers.add(member);
|
||||||
}
|
}
|
||||||
OtpErlangObject result = new OtpErlangTuple(tupleMembers
|
OtpErlangObject result = new OtpErlangTuple(tupleMembers
|
||||||
.toArray(new OtpErlangObject[tupleMembers.size()]));
|
.toArray(new OtpErlangObject[tupleMembers.size()]));
|
||||||
|
@ -59,14 +57,6 @@ public class TupleTypeHelper implements TypeHelper {
|
||||||
Object result = null;
|
Object result = null;
|
||||||
OtpErlangTuple tuple = (OtpErlangTuple) object;
|
OtpErlangTuple tuple = (OtpErlangTuple) object;
|
||||||
Field[] fields = forClass.getFields();
|
Field[] fields = forClass.getFields();
|
||||||
if (fields.length != tuple.arity()) {
|
|
||||||
throw new ErlangException(
|
|
||||||
"Received tuple with different element count ("
|
|
||||||
+ tuple.arity() + ") than expected ("
|
|
||||||
+ fields.length + ")");
|
|
||||||
// FIXME: JUnit this - received tuple with different element count -
|
|
||||||
// wrong message, exception!
|
|
||||||
}
|
|
||||||
result = forClass.newInstance();
|
result = forClass.newInstance();
|
||||||
for (int i = 0; i < tuple.arity(); i++) {
|
for (int i = 0; i < tuple.arity(); i++) {
|
||||||
OtpErlangObject tupleMember = tuple.elementAt(i);
|
OtpErlangObject tupleMember = tuple.elementAt(i);
|
||||||
|
|
|
@ -34,9 +34,9 @@ import org.junit.Before;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.osoa.sca.ServiceRuntimeException;
|
|
||||||
|
|
||||||
import com.ericsson.otp.erlang.OtpAuthException;
|
import com.ericsson.otp.erlang.OtpAuthException;
|
||||||
|
import com.ericsson.otp.erlang.OtpConnection;
|
||||||
import com.ericsson.otp.erlang.OtpErlangAtom;
|
import com.ericsson.otp.erlang.OtpErlangAtom;
|
||||||
import com.ericsson.otp.erlang.OtpErlangBinary;
|
import com.ericsson.otp.erlang.OtpErlangBinary;
|
||||||
import com.ericsson.otp.erlang.OtpErlangBoolean;
|
import com.ericsson.otp.erlang.OtpErlangBoolean;
|
||||||
|
@ -49,6 +49,8 @@ import com.ericsson.otp.erlang.OtpErlangString;
|
||||||
import com.ericsson.otp.erlang.OtpErlangTuple;
|
import com.ericsson.otp.erlang.OtpErlangTuple;
|
||||||
import com.ericsson.otp.erlang.OtpMbox;
|
import com.ericsson.otp.erlang.OtpMbox;
|
||||||
import com.ericsson.otp.erlang.OtpNode;
|
import com.ericsson.otp.erlang.OtpNode;
|
||||||
|
import com.ericsson.otp.erlang.OtpPeer;
|
||||||
|
import com.ericsson.otp.erlang.OtpSelf;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test is annotated with test runner, which will ignore tests if epmd is not
|
* Test is annotated with test runner, which will ignore tests if epmd is not
|
||||||
|
@ -63,15 +65,12 @@ public class ReferenceServiceTestCase {
|
||||||
|
|
||||||
private static MboxInterface mboxReference;
|
private static MboxInterface mboxReference;
|
||||||
private static MboxInterface timeoutMboxReference;
|
private static MboxInterface timeoutMboxReference;
|
||||||
private static MboxInterface cookieMboxReference;
|
|
||||||
private static ServiceInterface moduleReference;
|
private static ServiceInterface moduleReference;
|
||||||
private static ServiceInterface cookieModuleReference;
|
private static ServiceInterface cookieModuleReference;
|
||||||
|
private static ServiceInterface invalidCookieModuleReference;
|
||||||
private static ServiceInterface timeoutModuleReference;
|
private static ServiceInterface timeoutModuleReference;
|
||||||
private static ServiceInterface clonedModuleReference;
|
|
||||||
private static OtpNode serNode;
|
private static OtpNode serNode;
|
||||||
private static OtpNode serCookieNode;
|
|
||||||
private static OtpMbox serMbox;
|
private static OtpMbox serMbox;
|
||||||
private static OtpMbox serCookieMbox;
|
|
||||||
private static OtpNode refNode;
|
private static OtpNode refNode;
|
||||||
private static OtpMbox refMbox;
|
private static OtpMbox refMbox;
|
||||||
private static Process epmdProcess;
|
private static Process epmdProcess;
|
||||||
|
@ -88,17 +87,14 @@ public class ReferenceServiceTestCase {
|
||||||
|
|
||||||
mboxReference = component.getMboxReference();
|
mboxReference = component.getMboxReference();
|
||||||
timeoutMboxReference = component.getTimeoutMboxReference();
|
timeoutMboxReference = component.getTimeoutMboxReference();
|
||||||
cookieMboxReference = component.getCookieMboxReference();
|
|
||||||
moduleReference = component.getModuleReference();
|
moduleReference = component.getModuleReference();
|
||||||
cookieModuleReference = component.getCookieModuleReference();
|
cookieModuleReference = component.getCookieModuleReference();
|
||||||
|
invalidCookieModuleReference = component
|
||||||
|
.getInvalidCookieModuleReference();
|
||||||
timeoutModuleReference = component.getTimeoutModuleReference();
|
timeoutModuleReference = component.getTimeoutModuleReference();
|
||||||
clonedModuleReference = component.getClonedModuleReference();
|
|
||||||
|
|
||||||
serNode = new OtpNode("MboxServer");
|
serNode = new OtpNode("MboxServer");
|
||||||
serCookieNode = new OtpNode("MboxServer");
|
|
||||||
serCookieNode.setCookie("cookie");
|
|
||||||
serMbox = serNode.createMbox("sendArgs");
|
serMbox = serNode.createMbox("sendArgs");
|
||||||
serCookieMbox = serCookieNode.createMbox("sendArgs");
|
|
||||||
refNode = new OtpNode("MboxClient");
|
refNode = new OtpNode("MboxClient");
|
||||||
refMbox = refNode.createMbox("connector_to_SCA_mbox");
|
refMbox = refNode.createMbox("connector_to_SCA_mbox");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -552,7 +548,7 @@ public class ReferenceServiceTestCase {
|
||||||
*
|
*
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
@Test(timeout = 1000)
|
@Test(timeout = 10000000)
|
||||||
public void testRPC() throws Exception {
|
public void testRPC() throws Exception {
|
||||||
String[] result = moduleReference.sayHellos();
|
String[] result = moduleReference.sayHellos();
|
||||||
assertEquals(2, result.length);
|
assertEquals(2, result.length);
|
||||||
|
@ -636,38 +632,7 @@ public class ReferenceServiceTestCase {
|
||||||
assertEquals(ErlangException.class, e.getClass());
|
assertEquals(ErlangException.class, e.getClass());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests using multiple Erlang modules on one SCA Erlang node
|
|
||||||
*
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
@Test(timeout = 1000)
|
|
||||||
public void testMultipleModulesOnNode() throws Exception {
|
|
||||||
String[] mr = moduleReference.sayHellos();
|
|
||||||
String[] cmr = clonedModuleReference.sayHellos();
|
|
||||||
assertEquals("1", mr[0]);
|
|
||||||
assertEquals("2", mr[1]);
|
|
||||||
|
|
||||||
assertEquals("-1", cmr[0]);
|
|
||||||
assertEquals("-2", cmr[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests nodes with duplcated components (the same node and module
|
|
||||||
* parameters)
|
|
||||||
*
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
@Test(timeout = 1000)
|
|
||||||
public void testModuleDuplicatedOnNode() throws Exception {
|
|
||||||
try {
|
|
||||||
SCADomain.newInstance("ErlangServiceModuleDuplicate.composite");
|
|
||||||
} catch (ServiceRuntimeException e) {
|
|
||||||
assertEquals(ErlangException.class, e.getCause().getClass());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests mbox with retrieving and answering with basic arguments
|
* Tests mbox with retrieving and answering with basic arguments
|
||||||
*
|
*
|
||||||
|
@ -679,7 +644,7 @@ public class ReferenceServiceTestCase {
|
||||||
args[0] = new OtpErlangString("world");
|
args[0] = new OtpErlangString("world");
|
||||||
args[1] = new OtpErlangString("!");
|
args[1] = new OtpErlangString("!");
|
||||||
OtpErlangTuple tuple = new OtpErlangTuple(args);
|
OtpErlangTuple tuple = new OtpErlangTuple(args);
|
||||||
refMbox.send("sayHello", "RPCServer", tuple);
|
refMbox.send("sayHello", "RPCServerMbox", tuple);
|
||||||
OtpErlangString result = (OtpErlangString) refMbox.receiveMsg()
|
OtpErlangString result = (OtpErlangString) refMbox.receiveMsg()
|
||||||
.getMsg();
|
.getMsg();
|
||||||
assertEquals("Hello world !", result.stringValue());
|
assertEquals("Hello world !", result.stringValue());
|
||||||
|
@ -690,7 +655,7 @@ public class ReferenceServiceTestCase {
|
||||||
*
|
*
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
@Test(timeout = 1000)
|
@Test(timeout = 2000)
|
||||||
public void testMboxWithComplexArgs() throws Exception {
|
public void testMboxWithComplexArgs() throws Exception {
|
||||||
int arg1 = 1;
|
int arg1 = 1;
|
||||||
String arg2 = "arg2";
|
String arg2 = "arg2";
|
||||||
|
@ -715,7 +680,7 @@ public class ReferenceServiceTestCase {
|
||||||
argsContent[0] = structuredTuple;
|
argsContent[0] = structuredTuple;
|
||||||
argsContent[1] = list;
|
argsContent[1] = list;
|
||||||
OtpErlangTuple args = new OtpErlangTuple(argsContent);
|
OtpErlangTuple args = new OtpErlangTuple(argsContent);
|
||||||
refMbox.send("passComplexArgs", "RPCServer", args);
|
refMbox.send("passComplexArgs", "RPCServerMbox", args);
|
||||||
OtpErlangObject result = refMbox.receiveMsg().getMsg();
|
OtpErlangObject result = refMbox.receiveMsg().getMsg();
|
||||||
assertEquals(arg1,
|
assertEquals(arg1,
|
||||||
((OtpErlangLong) ((OtpErlangTuple) ((OtpErlangTuple) result)
|
((OtpErlangLong) ((OtpErlangTuple) ((OtpErlangTuple) result)
|
||||||
|
@ -747,7 +712,7 @@ public class ReferenceServiceTestCase {
|
||||||
try {
|
try {
|
||||||
// timeout exception expected
|
// timeout exception expected
|
||||||
timeoutMboxReference.sendArgs("");
|
timeoutMboxReference.sendArgs("");
|
||||||
fail();
|
fail("Exception expected");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
assertEquals(ErlangException.class, e.getClass());
|
assertEquals(ErlangException.class, e.getClass());
|
||||||
assertEquals(e.getCause().getClass(), InterruptedException.class);
|
assertEquals(e.getCause().getClass(), InterruptedException.class);
|
||||||
|
@ -791,7 +756,7 @@ public class ReferenceServiceTestCase {
|
||||||
// exception, so expecting one
|
// exception, so expecting one
|
||||||
try {
|
try {
|
||||||
timeoutModuleReference.sayHellos();
|
timeoutModuleReference.sayHellos();
|
||||||
fail();
|
fail("Exception expected");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
assertEquals(ErlangException.class, e.getClass());
|
assertEquals(ErlangException.class, e.getClass());
|
||||||
}
|
}
|
||||||
|
@ -801,19 +766,51 @@ public class ReferenceServiceTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests timeout feature for reference binding RPC
|
* Tests timeout feature for service side bindings
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Test(timeout = 4000)
|
||||||
|
public void testServiceTimeouts() throws Exception {
|
||||||
|
OtpSelf self = new OtpSelf("tmp_connector_"
|
||||||
|
+ System.currentTimeMillis());
|
||||||
|
OtpPeer peer = new OtpPeer("RPCServerTimeout");
|
||||||
|
OtpConnection connection = self.connect(peer);
|
||||||
|
// delay message sending after connecting
|
||||||
|
Thread.sleep(1000);
|
||||||
|
// service binding timeout set to 500 so after that time it will give up
|
||||||
|
// and close connection
|
||||||
|
try {
|
||||||
|
connection.send("rex", new OtpErlangString("test"));
|
||||||
|
fail("Exception expected");
|
||||||
|
} catch (Exception e) {
|
||||||
|
assertEquals(IOException.class, e.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
connection = self.connect(peer);
|
||||||
|
// sending message immediately and encountering no connection close
|
||||||
|
connection.send("rex", new OtpErlangString("test"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests cookie feature for both reference and service bindings RPC
|
||||||
*
|
*
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
@Test(timeout = 1000)
|
@Test(timeout = 1000)
|
||||||
public void testReferenceCookies() throws Exception {
|
public void testReferenceCookies() throws Exception {
|
||||||
|
// testing wrong cookie
|
||||||
try {
|
try {
|
||||||
cookieModuleReference.sayHellos();
|
invalidCookieModuleReference.sayHellos();
|
||||||
fail();
|
fail("Exception expected");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
assertEquals(ErlangException.class, e.getClass());
|
assertEquals(ErlangException.class, e.getClass());
|
||||||
assertEquals(OtpAuthException.class, e.getCause().getClass());
|
assertEquals(OtpAuthException.class, e.getCause().getClass());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
// testing correct cookie
|
||||||
|
cookieModuleReference.sayHellos();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ public class ReferenceTestComponentImpl implements ReferenceTestComponent {
|
||||||
private MboxInterface cookieMboxReference;
|
private MboxInterface cookieMboxReference;
|
||||||
private ServiceInterface moduleReference;
|
private ServiceInterface moduleReference;
|
||||||
private ServiceInterface cookieModuleReference;
|
private ServiceInterface cookieModuleReference;
|
||||||
|
private ServiceInterface invalidCookieModuleReference;
|
||||||
private ServiceInterface timeoutModuleReference;
|
private ServiceInterface timeoutModuleReference;
|
||||||
private ServiceInterface clonedModuleReference;
|
private ServiceInterface clonedModuleReference;
|
||||||
|
|
||||||
|
@ -59,6 +60,11 @@ public class ReferenceTestComponentImpl implements ReferenceTestComponent {
|
||||||
this.cookieModuleReference = cookieModuleReference;
|
this.cookieModuleReference = cookieModuleReference;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Reference
|
||||||
|
public void setInvalidCookieModuleReference(ServiceInterface invalidCookieModuleReference) {
|
||||||
|
this.invalidCookieModuleReference = invalidCookieModuleReference;
|
||||||
|
}
|
||||||
|
|
||||||
@Reference
|
@Reference
|
||||||
public void setTimeoutModuleReference(ServiceInterface timeoutModuleReference) {
|
public void setTimeoutModuleReference(ServiceInterface timeoutModuleReference) {
|
||||||
this.timeoutModuleReference = timeoutModuleReference;
|
this.timeoutModuleReference = timeoutModuleReference;
|
||||||
|
@ -88,6 +94,10 @@ public class ReferenceTestComponentImpl implements ReferenceTestComponent {
|
||||||
public ServiceInterface getCookieModuleReference() {
|
public ServiceInterface getCookieModuleReference() {
|
||||||
return cookieModuleReference;
|
return cookieModuleReference;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ServiceInterface getInvalidCookieModuleReference() {
|
||||||
|
return invalidCookieModuleReference;
|
||||||
|
}
|
||||||
|
|
||||||
public ServiceInterface getTimeoutModuleReference() {
|
public ServiceInterface getTimeoutModuleReference() {
|
||||||
return timeoutModuleReference;
|
return timeoutModuleReference;
|
||||||
|
|
|
@ -14,8 +14,8 @@
|
||||||
<tuscany:binding.erlang node="MboxServer" mbox="true" timeout="500"/>
|
<tuscany:binding.erlang node="MboxServer" mbox="true" timeout="500"/>
|
||||||
</reference>
|
</reference>
|
||||||
|
|
||||||
<reference name="timeoutMboxReference">
|
<reference name="cookieMboxReference">
|
||||||
<tuscany:binding.erlang node="MboxServer" mbox="true" timeout="500"/>
|
<tuscany:binding.erlang node="MboxServer" mbox="true" cookie="cookie"/>
|
||||||
</reference>
|
</reference>
|
||||||
|
|
||||||
<reference name="moduleReference">
|
<reference name="moduleReference">
|
||||||
|
@ -23,16 +23,17 @@
|
||||||
</reference>
|
</reference>
|
||||||
|
|
||||||
<reference name="cookieModuleReference">
|
<reference name="cookieModuleReference">
|
||||||
<tuscany:binding.erlang node="RPCServer" module="hello" cookie="cookie"/>
|
<tuscany:binding.erlang node="RPCServerCookie" module="hello_cookie" cookie="cookie"/>
|
||||||
|
</reference>
|
||||||
|
|
||||||
|
<reference name="invalidCookieModuleReference">
|
||||||
|
<tuscany:binding.erlang node="RPCServerCookie" module="hello_cookie" cookie="invalid_cookie"/>
|
||||||
</reference>
|
</reference>
|
||||||
|
|
||||||
<reference name="timeoutModuleReference">
|
<reference name="timeoutModuleReference">
|
||||||
<tuscany:binding.erlang node="RPCServer" module="hello_timeout" timeout="500"/>
|
<tuscany:binding.erlang node="RPCServerTimeout" module="hello_timeout" timeout="500"/>
|
||||||
</reference>
|
</reference>
|
||||||
|
|
||||||
<reference name="clonedModuleReference">
|
|
||||||
<tuscany:binding.erlang node="RPCServer" module="hello_clone"/>
|
|
||||||
</reference>
|
|
||||||
</component>
|
</component>
|
||||||
|
|
||||||
</composite>
|
</composite>
|
|
@ -13,15 +13,7 @@
|
||||||
</service>
|
</service>
|
||||||
<service name="ServiceTestMbox" promote="ServiceTest">
|
<service name="ServiceTestMbox" promote="ServiceTest">
|
||||||
<interface.java interface="org.apache.tuscany.sca.binding.erlang.testing.ServiceTestComponent" />
|
<interface.java interface="org.apache.tuscany.sca.binding.erlang.testing.ServiceTestComponent" />
|
||||||
<tuscany:binding.erlang node="RPCServer" mbox="true"/>
|
<tuscany:binding.erlang node="RPCServerMbox" mbox="true"/>
|
||||||
</service>
|
|
||||||
|
|
||||||
<component name="ServiceTestClone">
|
|
||||||
<implementation.java class="org.apache.tuscany.sca.binding.erlang.testing.ServiceTestComponentImplClone" />
|
|
||||||
</component>
|
|
||||||
<service name="ServiceTestClone" promote="ServiceTestClone">
|
|
||||||
<interface.java interface="org.apache.tuscany.sca.binding.erlang.testing.ServiceTestComponent" />
|
|
||||||
<tuscany:binding.erlang node="RPCServer" module="hello_clone"/>
|
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<component name="ServiceTestTimeout">
|
<component name="ServiceTestTimeout">
|
||||||
|
@ -29,7 +21,15 @@
|
||||||
</component>
|
</component>
|
||||||
<service name="ServiceTestTimeout" promote="ServiceTestTimeout">
|
<service name="ServiceTestTimeout" promote="ServiceTestTimeout">
|
||||||
<interface.java interface="org.apache.tuscany.sca.binding.erlang.testing.ServiceTestComponent" />
|
<interface.java interface="org.apache.tuscany.sca.binding.erlang.testing.ServiceTestComponent" />
|
||||||
<tuscany:binding.erlang node="RPCServer" module="hello_timeout"/>
|
<tuscany:binding.erlang node="RPCServerTimeout" module="hello_timeout" timeout="500"/>
|
||||||
|
</service>
|
||||||
|
|
||||||
|
<component name="ServiceTestCookie">
|
||||||
|
<implementation.java class="org.apache.tuscany.sca.binding.erlang.testing.ServiceTestComponentImpl" />
|
||||||
|
</component>
|
||||||
|
<service name="ServiceTestCookie" promote="ServiceTestCookie">
|
||||||
|
<interface.java interface="org.apache.tuscany.sca.binding.erlang.testing.ServiceTestComponent" />
|
||||||
|
<tuscany:binding.erlang node="RPCServerCookie" module="hello_cookie" cookie="cookie"/>
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
</composite>
|
</composite>
|
|
@ -1,23 +0,0 @@
|
||||||
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
|
|
||||||
xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0"
|
|
||||||
targetNamespace="http://sample"
|
|
||||||
xmlns:sample="http://sample"
|
|
||||||
name="ErlangServiceBinding">
|
|
||||||
|
|
||||||
<component name="ServiceTest">
|
|
||||||
<implementation.java class="org.apache.tuscany.sca.binding.erlang.testing.ServiceTestComponentImpl" />
|
|
||||||
</component>
|
|
||||||
<service name="ServiceTest" promote="ServiceTest">
|
|
||||||
<interface.java interface="org.apache.tuscany.sca.binding.erlang.testing.ServiceTestComponent" />
|
|
||||||
<tuscany:binding.erlang node="DuplicateTest" module="hello"/>
|
|
||||||
</service>
|
|
||||||
|
|
||||||
<component name="ServiceTestClone">
|
|
||||||
<implementation.java class="org.apache.tuscany.sca.binding.erlang.testing.ServiceTestComponentImplClone" />
|
|
||||||
</component>
|
|
||||||
<service name="ServiceTestClone" promote="ServiceTestClone">
|
|
||||||
<interface.java interface="org.apache.tuscany.sca.binding.erlang.testing.ServiceTestComponent" />
|
|
||||||
<tuscany:binding.erlang node="DuplicateTest" module="hello"/>
|
|
||||||
</service>
|
|
||||||
|
|
||||||
</composite>
|
|
|
@ -29,6 +29,8 @@ import org.apache.tuscany.sca.assembly.xml.Constants;
|
||||||
*/
|
*/
|
||||||
public interface ErlangBinding extends Binding {
|
public interface ErlangBinding extends Binding {
|
||||||
|
|
||||||
|
final long NO_TIMEOUT = 0;
|
||||||
|
|
||||||
QName BINDING_ERLANG_QNAME = new QName(Constants.SCA10_TUSCANY_NS, "binding.erlang");
|
QName BINDING_ERLANG_QNAME = new QName(Constants.SCA10_TUSCANY_NS, "binding.erlang");
|
||||||
|
|
||||||
String getNode();
|
String getNode();
|
||||||
|
@ -50,5 +52,9 @@ public interface ErlangBinding extends Binding {
|
||||||
String getCookie();
|
String getCookie();
|
||||||
|
|
||||||
void setCookie(String cookie);
|
void setCookie(String cookie);
|
||||||
|
|
||||||
|
boolean hasTimeout();
|
||||||
|
|
||||||
|
boolean hasCookie();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,8 +33,6 @@ import org.apache.tuscany.sca.policy.PolicySetAttachPoint;
|
||||||
*/
|
*/
|
||||||
public class ErlangBindingImpl implements ErlangBinding, PolicySetAttachPoint {
|
public class ErlangBindingImpl implements ErlangBinding, PolicySetAttachPoint {
|
||||||
|
|
||||||
public static final long DEFAULT_TIMEOUT = 10000;
|
|
||||||
|
|
||||||
private String node;
|
private String node;
|
||||||
private String module;
|
private String module;
|
||||||
private boolean mbox;
|
private boolean mbox;
|
||||||
|
@ -44,7 +42,7 @@ public class ErlangBindingImpl implements ErlangBinding, PolicySetAttachPoint {
|
||||||
private List<PolicySet> policySets = new ArrayList<PolicySet>();
|
private List<PolicySet> policySets = new ArrayList<PolicySet>();
|
||||||
private IntentAttachPointType intentAttachPointType;
|
private IntentAttachPointType intentAttachPointType;
|
||||||
private List<PolicySet> applicablePolicySets = new ArrayList<PolicySet>();
|
private List<PolicySet> applicablePolicySets = new ArrayList<PolicySet>();
|
||||||
private long timeout = DEFAULT_TIMEOUT;
|
private long timeout = NO_TIMEOUT;
|
||||||
|
|
||||||
public String getNode() {
|
public String getNode() {
|
||||||
return node;
|
return node;
|
||||||
|
@ -121,12 +119,8 @@ public class ErlangBindingImpl implements ErlangBinding, PolicySetAttachPoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTimeout(long timeout) {
|
public void setTimeout(long timeout) {
|
||||||
// NOTE: 0 timeout will cause setting to default
|
// NOTE: not setting timeout or setting it to 0 will cause no timeout
|
||||||
if (timeout == 0) {
|
this.timeout = timeout;
|
||||||
this.timeout = DEFAULT_TIMEOUT;
|
|
||||||
} else {
|
|
||||||
this.timeout = timeout;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCookie() {
|
public String getCookie() {
|
||||||
|
@ -137,4 +131,12 @@ public class ErlangBindingImpl implements ErlangBinding, PolicySetAttachPoint {
|
||||||
this.cookie = cookie;
|
this.cookie = cookie;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasTimeout() {
|
||||||
|
return timeout != ErlangBinding.NO_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasCookie() {
|
||||||
|
return cookie != null && cookie.length() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,16 +65,6 @@ public class ErlangBindingProcessorTestCase {
|
||||||
+ " </service>"
|
+ " </service>"
|
||||||
+ " </component>"
|
+ " </component>"
|
||||||
+ "</composite>";
|
+ "</composite>";
|
||||||
|
|
||||||
private static final String COMPOSITE_ZERO_TIMEOUT =
|
|
||||||
"<?xml version=\"1.0\" encoding=\"ASCII\"?>" + "<composite xmlns=\"http://www.osoa.org/xmlns/sca/1.0\" xmlns:tuscany=\"http://tuscany.apache.org/xmlns/sca/1.0\" targetNamespace=\"http://binding-erlang\" name=\"binding-erlang\">"
|
|
||||||
+ " <component name=\"HelloWorldComponent\">"
|
|
||||||
+ " <implementation.java class=\"services.HelloWorld\"/>"
|
|
||||||
+ " <service name=\"HelloWorldService\">"
|
|
||||||
+ " <tuscany:binding.erlang node=\"SomeNode\" timeout=\"0\"/>"
|
|
||||||
+ " </service>"
|
|
||||||
+ " </component>"
|
|
||||||
+ "</composite>";
|
|
||||||
|
|
||||||
private static XMLInputFactory inputFactory;
|
private static XMLInputFactory inputFactory;
|
||||||
private static StAXArtifactProcessor<Object> staxProcessor;
|
private static StAXArtifactProcessor<Object> staxProcessor;
|
||||||
|
@ -110,6 +100,8 @@ public class ErlangBindingProcessorTestCase {
|
||||||
assertEquals("SomeNode", binding.getNode());
|
assertEquals("SomeNode", binding.getNode());
|
||||||
assertEquals(1000, binding.getTimeout());
|
assertEquals(1000, binding.getTimeout());
|
||||||
assertEquals("cookie", binding.getCookie());
|
assertEquals("cookie", binding.getCookie());
|
||||||
|
assertEquals(true, binding.hasTimeout());
|
||||||
|
assertEquals(true, binding.hasCookie());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -123,22 +115,10 @@ public class ErlangBindingProcessorTestCase {
|
||||||
Composite composite = (Composite)staxProcessor.read(reader);
|
Composite composite = (Composite)staxProcessor.read(reader);
|
||||||
ErlangBinding binding =
|
ErlangBinding binding =
|
||||||
(ErlangBinding)composite.getComponents().get(0).getServices().get(0).getBindings().get(0);
|
(ErlangBinding)composite.getComponents().get(0).getServices().get(0).getBindings().get(0);
|
||||||
assertEquals(ErlangBindingImpl.DEFAULT_TIMEOUT, binding.getTimeout());
|
assertEquals(ErlangBindingImpl.NO_TIMEOUT, binding.getTimeout());
|
||||||
assertEquals(null, binding.getCookie());
|
assertEquals(null, binding.getCookie());
|
||||||
}
|
assertEquals(false, binding.hasTimeout());
|
||||||
|
assertEquals(false, binding.hasCookie());
|
||||||
/**
|
|
||||||
* Tests "resultTimeout" attribute set to 0
|
|
||||||
*
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
@Test
|
|
||||||
public void testLoadZeroTimeout() throws Exception {
|
|
||||||
XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(COMPOSITE_ZERO_TIMEOUT));
|
|
||||||
Composite composite = (Composite)staxProcessor.read(reader);
|
|
||||||
ErlangBinding binding =
|
|
||||||
(ErlangBinding)composite.getComponents().get(0).getServices().get(0).getBindings().get(0);
|
|
||||||
assertEquals(ErlangBindingImpl.DEFAULT_TIMEOUT, binding.getTimeout());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue