<binding.erlang>
The Tuscany Java SCA runtime supports Erlang using the <binding.erlang> SCDL extension. New Erlang based service can be provided using a <binding.erlang> element within a SCA <service>, existing Erlang object can be accessed using a <binding.erlang> element within a SCA <reference>.
Using Erlang binding
Basically SCA services can be exposed in two ways:
- by Erlang RPC mechanism. In this case SCA component would act as Erlang module containing functions, based on components operations names.
- by RPC realised using Erlang messaging. In this case for every operation named Erlang message box would be created - name of the box will correspond to operation name. After receiving message from Erlang node appropriate components operation will be invoked and result would be sent back to sender.
Similarly, SCA references can access Erlang modules in two ways:
- using RPC mechanism. In this case SCA reference would be mapped to remote Erlang functions module, each operation would correspond to different function, basing on its name.
- by RPC realised using Erlang messaging. In this case invoking operation on reference would cause sending Erlang message to named Erlang process - name would be the same as operation name. If operation has return value then return message will be expected.
Requirements
Erlang binding is available since Apache Tuscany SCA Java 1.6, source distribution only. To use Erlang binding module you need to build Apache Tuscany by your own, please follow instructions contained in BUILDING file which can be found in source distribution root directory.
Erlang nodes need to communicate with Erlang Port Mapper Daemon (EPMD) which should be run locally. To run JUnit tests and samples for Tuscany Erlang modules you need to have epmd binary in your system path - epmd comes with Erlang/OTP distribution. See http://erlang.org for downloads.
Erlang samples and JUnit tests inside Tuscany spawns epmd process automatically, but if you are creating your own solution using Erlang binding you need to provide running epmd process.
Binding configuration
Binding configuration can take several attributes:
- node - name of the local (service side) or remote (reference side) Erlang node. Tuscany creates separate Erlang node for each service binding, so remember to provide unique node name for every service binding.
- module - specifies name of the module mapped to SCA component/reference. When using this attribute you can't use mbox="true" attribute.
- mbox - specifies whether binding would be realised using messaging based RPC ("true") or built-in Erlang RPC ("false"). Default (no value specified) is "false". When using mbox="true" you can't use module attribute.
- cookie - (optional) authentication token. Communicating nodes should have the same cookies. You can also provide cookie in .erlang.cookie file in users home directory (it's originally supported by Jinterface).
- timeout - (optional) specifies timeout (in milliseconds) for inactive connections. Timeouts will be disabled if attribute value is 0 or not provided.
- serviceThreadPool - (optional) for service side bindings only. Specifies maximum number of threads which will be handling clients. Default value is 20.
Service configuration samples
Sample based on RPC
Following sample exposes component as Erlang module named "HelloModule". Modules functions would be the same as in service interface - helloworld.HelloWorld. Node which will host this module will be named "HelloNodeModule".
<service name="HelloWorldService"> <interface.java interface="helloworld.HelloWorld"/> <tuscany:binding.erlang node="HelloNodeModule" module="HelloModule"/> </service>
Sample based on messaging
Following sample exposes component as several message boxes - each box will correspond to each component operation. Node which will host those message boxes will be named "HelloNodeMbox".
Additional attributes are used:
- cookie for authentication purposes - "secret string"
- timeout (1 second) for disconnecting hanging clients
- number of threads that handles clients (serviceThreadPool attribute) is set to 10.
<service name="HelloWorldService"> <interface.java interface="helloworld.HelloWorld"/> <tuscany:binding.erlang node="HelloNodeMbox" mbox="true" cookie="secret string" timeout="1000" serviceThreadPool="10"/> </service>
Reference configuration samples
Sample based on RPC
Following sample uses remote Erlang module as reference. Configuration points to module named "HelloModule", hosted on "HelloNodeModule".
Additional attributes are used:
- cookie for authentication purposes - "secret string"
- timeout (1 second) for quitting from hanging server
<reference name="helloWorldReference"> <tuscany:binding.erlang node="HelloNodeModule" module="HelloModule" cookie="secret string" timeout="1000"/> </reference>
Sample based on messaging
Following sample uses remote Erlang message boxes in RPC style. Message boxes with names the same as reference operations are available on "HelloNodeMbox".
<reference name="helloWorldReference"> <tuscany:binding.erlang node="HelloNodeMbox" mbox="true"/> </reference>
Declaring interface
Following table describes mapping used between Java and Erlang types.
Java type |
Erlang type |
---|---|
byte, short, char, int, long |
number - Erlang does not distinguish numbers size |
float, double |
Double - Erlang does not distinguish floating numbers size |
String |
Array of characters |
String annotated with @ErlangAtom (package org.apache.tuscany.sca.binding.erlang.meta) |
Atom |
array |
List |
User defined class with pubic no argument constructor and public fields of type from this table. |
Tuple |
Atoms sample
public interface SomeInterface { // Returns user defined class - tuple TupleClass operation1(); // Returns list of characters and takes list of characters as an argument String operation2(String argument); // Returns atom and takes atom as an argument @ErlangAtom String operation3(@ErlangAtom String argument); // Returns list of atoms @ErlangAtom String[] operation4(); } // Java class represents tuple which contains atom and list of characters. public class TupleClass { @EralngAtom public String atom; public String notAtom; }
Tuples sample
Following interface:
public class TupleClass1 { public long field1; public TupleClass2 field2; } public class TupleClass2 { public long field1; public double field2; }
will correspond to live tuple structure (using Erlang notation):
{10, {10, 0.9}}
Details of message based RPC communication
RPC based on messaging uses messages for requests and responses.
- For service bindings incoming messages should contain SCA operation arguments, formed in tuple. Operation result will be send in return message.
- For reference bindings Tuscany creates message with content depending on attributes passed to reference operation. If reference operation has return value defined then Tuscany will wait for reply from remote process.
In Erlang messaging it's common technique for sender to provide it's PID at the beginning - it allows recipient to respond. In Tuscany every Erlang message is a tuple which contains operation arguments. This tuple is wrapped with tuple with PID.
Overloading operations
Overloading operations allows user to send message with different structure. Ie., in reference binding we could declare interface:
public interface SomeInterface { void someMbox(String argument); void someMbox(String arg1, String arg2); }
Invoking first someMbox operation would cause sending message addressed to someMbox message box. This message would contain one string value. Invoking second someMbox operation would cause sending message addressed also to someMbox message box, but message content would differ - now it would contain two string values.
Service side example
For service defined by following interface:
public String operation(long arg1, @ErlangTuple arg2);
expected Erlang message is (sample using Erlang notation):
{SomePid, {10, AtomValue}}
After receiving such formed message Tuscany is able to process it correctly, invoke SCA operation and send reply to PID provided as first element of outer tuple.
Reference side example
For reference interface defined as:
public String operation(long arg1, @ErlangTuple String arg2);
executing it with following arguments:
obj.operation(10, "AtomValue");
will make Tuscany to convert input arguments to Erlang tuple (using Erlang notation):
{10, AtomValue}
and wrap with tuple containing PID as follows (using Erlang notation):
{SomePid, {10, AtomValue}}
In this example Erlang message box would receive message and know PID for reply.
Exceptions
While communicating with Erlang nodes (reference bindings) several error can be raised:
- Function on remote Erlang doesn't exist
- Connection problems
- Others and unexpected errors
In case of error two things can happen:
- Exception will be thrown, only for operations which declares exceptions
- Problem will be logged, only for operations with no exception declared
Samples
Samples can be found under sca/java/samples/:
- helloworld-service-erlang
- helloworld-reference-erlang
Samples use service and reference Erlang bindings realised via Erlang RPC. If you want to play with Erlang binding it's good place to start. Maybe you would like to experiment by changing communication model to message based?
For running instructions please read README files. You should also get familiar with requirements.