Space: Apache Tuscany (http://cwiki.apache.org/confluence/display/TUSCANY)
Page: SCA Java binding.erlang
(http://cwiki.apache.org/confluence/display/TUSCANY/SCA+Java+binding.erlang)
Edited by Wojtek Janiszewski:
---------------------------------------------------------------------
{section:border=false}
{column:width=15%}
{include: SCA Java Subproject Menu}
{include: Java SCA Menu New}
{column}
{column:width=85%}
h3. <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*|#using]
** [*Requirements*|#requirements]
** [*Binding configuration*|#configuration]
** [*Declaring interface*|#interface]
* [*Details of message based RPC*|#messaging]
* [*Exceptions*|#Exceptions]
* [*Samples*|#Samples]
{anchor:using}
h2. 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.
{anchor:requirements}
h4. 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*.
{anchor:configuration}
h4. 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.
h5. 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".
{code}
<service name="HelloWorldService">
<interface.java interface="helloworld.HelloWorld"/>
<tuscany:binding.erlang node="HelloNodeModule" module="HelloModule"/>
</service>
{code}
*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.
{code}
<service name="HelloWorldService">
<interface.java interface="helloworld.HelloWorld"/>
<tuscany:binding.erlang node="HelloNodeMbox" mbox="true" cookie="secret
string" timeout="1000" serviceThreadPool="10"/>
</service>
{code}
h5. 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
{code}
<reference name="helloWorldReference">
<tuscany:binding.erlang node="HelloNodeModule" module="HelloModule"
cookie="secret string" timeout="1000"/>
</reference>
{code}
*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".
{code}
<reference name="helloWorldReference">
<tuscany:binding.erlang node="HelloNodeMbox" mbox="true"/>
</reference>
{code}
{anchor:interface}
h4. 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 |
h5. Atoms sample
{code}
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;
}
{code}
h5. Tuples sample
Following interface:
{code}
public class TupleClass1 {
public long field1;
public TupleClass2 field2;
}
public class TupleClass2 {
public long field1;
public double field2;
}
{code}
will correspond to live tuple structure (using Erlang notation):
{code}
{10, {10, 0.9}}
{code}
{anchor:messaging}
h2. 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.
h4. Overloading operations
Overloading operations allows user to send message with different structure.
Ie., in reference binding we could declare interface:
{code}
public interface SomeInterface {
void someMbox(String argument);
void someMbox(String arg1, String arg2);
}
{code}
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.
h4. Service side example
For service defined by following interface:
{code}
public String operation(long arg1, @ErlangTuple arg2);
{code}
expected Erlang message is (sample using Erlang notation):
{code}
{SomePid, {10, AtomValue}}
{code}
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.
h4. Reference side example
For reference interface defined as:
{code}
public String operation(long arg1, @ErlangTuple String arg2);
{code}
executing it with following arguments:
{code}
obj.operation(10, "AtomValue");
{code}
will make Tuscany to convert input arguments to Erlang tuple (using Erlang
notation):
{code}
{10, AtomValue}
{code}
and wrap with tuple containing PID as follows (using Erlang notation):
{code}
{SomePid, {10, AtomValue}}
{code}
In this example Erlang message box would receive message and know PID for reply.
{anchor:exceptions}
h2. 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*
{anchor:samples}
h2. 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*|#requirements].
{column}
{section}
Change your notification preferences:
http://cwiki.apache.org/confluence/users/viewnotifications.action