EAISystem
|
|
EAISystem is the main class of the Submarine engine. It is a Runnable class
so the launcher class could create a thread to run it. The setConfig() method
of this class initializes all the core elements (Channels,
PoolingFunctions, ListeningFunctions, WritingFunctions and
Resources) from the xml configuration file.
The run() method is responsible to open the declared
resources, to start the listeners,
to create threads for driving the pooling functions and running the
channels.
The stop() method is used to terminate the engine in a clean
way.
EAISystem implements two other interfaces.
|
|
Submiter
|
The Submiter interface allows callers to send messages in the eai engine using the
submit() method.
This interface permits also to retrieve the ConnectorControler by calling the getControler() method on the
submitter.
|
|
ConnectorsControler
|
The ConnectorControler interface gives caller a way to find the core elements declared in
the configuration file using the methods getResourceById(), getWriterById(), getListenerById(),
getPoolerById() and getChannelByName().
|
XMLConfigurable
|
|
The XMLConfigurable interface has a unique method init(org.w3c.dom.Element). This method
allows implementers to receive an XML elements as its initialization
parameters.
Conventionally, the implementer should not take care where the xml element come from. It
should either not take care of the name of the element. It should only be interested with
the content: attributes and children elements and text nodes.
All the core elements classes of the Submarine project implements this interface, in order
to be initialized from the xml configuration file of the project.
There is two main advantages of this interface. The main is that all the configurations
class could be stored in a single xml file. The second advantage is that a class configuration
can be encapsulated in an other class configuration, giving classes the opportunity to reuse
existing components. The ContextSerializer is a good example of
that.
|
Channel
|
|
The Channel class is the second most important class in the Submarine project. Channel is a
Runnable class because associated with a ChannelInfos class instance, it executes a set of
transformations rules defined in the ChannelInfos (loaded from the configuration file) in a
thread created by EAISystem.
The run() method sleep until a message is drop in the waiting queue of the EAISystem. Then, it
loads the channel information associated with the message and execute the following
steps:
-
Archiving IN : Archiving the message (java.lang.Object) according to the
configuration.
-
Parsing : Transforming the message (java.lang.Object) into XML (org.w3c.xml.Document) using the parser
description.
-
Archiving IN_XML : Archiving the parsing result (org.w3c.xml.Document) according to the
configuration.
-
Transforming : Transforming the parsing result (org.w3c.xml.Document) into another document
(org.w3c.xml.Document) using a XSLT processor (javax.xml.transform.Transformer).
-
Archiving OUT_XML : Archiving the transformation result (org.w3c.xml.Document) according to the
configuration.
-
Serializing : Transforming the transformation result (org.w3c.xml.Document) into a java object
(java.lang.Object)
-
Archiving OUT : Archiving the serializing result (java.lang.Object) according to the
configuration.
-
Writing : Calling the writer putDocument() method with the serializing result as
parameter.
The channel is responsible of managing errors. If an error (Exception) occur while processing
the channel, an error message is created and written in the archive directory.
|
|
Message
|
A channel process messages. A Message instance in the Submarine project is a set of information
associated together to process correctly the initial object (the document) send to the Submarine
engine by a client. These information are:
-
the document (java.lang.Object) itself
-
the routing information (see class RouteInfos) that select the channel
-
the channel information (see class ChannelInfos)
-
the message context (see Message.MsgContext class) that hold states and the unique message identifier
(docId).
A message is uniquely identified in the engine by a docId. The docId is a string build
in the following way: serverID-yyyymmdd-hhnnss-counter where ‘serverID’ is the Submarine engine identifier
(see global/server/@id configuration value) and ‘counter’ a number starting from 0 to 9999.
|
|
ConnectorsControler
|
The context of a message follow the message from its submission in the EAISystem to the processing by
the writer.
The context is designed to hold several data like quality of service, transaction or security. But in
the actual implementation, context only hold string properties (java.util.Properties) in its attribute
member.
|
PoolingFunction
|
|
The PoolingFunction interface (extends XMLConfigurable) is the contract passed between the Submarine
engine and connectors to one kind of source.
This kind of source represents the systems containing documents to submit to the engine but that need
a client request to return the new documents. Those systems has no way to notify a potential client of
the arrival of a document. So the only way to integrate them in a light manner is to pool on the system
at a particular frequency.
For instance file system is of that kind, EAI need to pool on a directory, waiting for new files.
The PoolingFunction interface is not used directly either by the EAISystem. But it should be implemented
by any constructor (or developer) that need to access to that kind of source.
The EAISystem drives these implementation in a dedicated thread. The call of the PoolingFunction methods
are always in the same thread context so implementation can use internal members safely.
The implementation of this interface is based on the following methods:
-
hasNewDocument()
is called by EAISystem, after a sleep, to know if new documents are available. If true, EAISystem call
getNextDocument().
-
getNextDocument()
is called by EAISystem in a loop until this method return a null value. In the other case, EAISystem submit
the result in the engine using getRouteInfos().
-
notifyResponse()
is called by EAISystem after the submission to the engine (either synchronously or asynchronously) to tell
the implementation what is the response and is the submission failed or not.
-
getFrequency()
is called after each call to hasNewDocument() that returns false or after a call to getNextDocument()
that returns null in order to suspend the thread for a certain delay.
-
getRouteInfos()
is called after each call to getNextDocument() that returns an object in order to get
the routing information for the submission. The result of this call could be dependant to the last document
returned.
It exists a sub interface of the PoolingFunction interface, named PoolingFunctionWithContext. This interface
add a parameter to the getNextDocument() method. This parameter is an initialised message context that could
be used by the implementation to fill particular attributes associated to the resulting document.
The EAISystem know dynamically if the PoolingFunctionWithContext is implemented. If so, it prefers to call
its getNextDocument() method in place of the PoolingFunction one.
|
ListeningFunction
|
|
The ListeningFunction interface (extends XMLConfigurable) is the contract passed between the Submarine
engine and connectors to one kind of source.
This kind of source represents the other case of source that those represented by a PoolingFunction.
A system connected to the EAISystem by a ListeningFunction is a system that notify its clients by a
callback or a special event. ListeningFunction implementation is responsible to manage their threads
(start and stop it) and to submit documents to the Submarine engine (using the Submiter and SubmiterAware
interfaces).
A mail system is an example of this type of source because it knows how to informs a client of the
arrival of new mail (see javax.mail.Folder.addMessageCountListener() ). Another example is the SubMLListener
that wait xml documents on a TCP port.
The implementation is based on one method :
listen().
This method is called in a dedicated thread by EAISystem.
It must be a blocking implementation while the calling thread is interrupted. In that case, the implementation
must release any resources and threads before returning. So it is required by the implementation to check as
soon as possible the interrupted state of the calling thread.
|
WritingFunction
|
|
The WritingFunction interface (extends XMLConfigurable) is the contract passed between Submarine
engine and connectors designed to send documents to the underlying system.
WritingFunction implementation are used by the channel processing thread. So, because writers are
shared in Submarine, the implementation must be multithreaded. Implementation are based on two methods,
both designed to send message to the system.
-
putDocument()
is called when the write to the underlying system must be asynchronous.
It returns true or false whether the write succeeded or not.
-
putSyncDocument()
is called when the write to the underlying system must by synchronous.
It returns an object as a response to the document write.
|
Resource
|
|
The Resource interface (extends XMLConfigurable) is designed for hosting data and
objects linked to an underlying resource. For instance it is useful to host a connection pool to a database.
This implementation is based on two methods:
-
open()
is called by the Submarine engine at its start time in order to tell the resource to create any
underlying sessions and connections.
-
close() is called by the Submarine engine just before the engine stops but after all the connectors
were interrupted or destroyed.
The implementation of a Resource must have its own interface to be used by connectors. The typical way to use
a Resource instance is to get the ConnectorsControler interface (from a Submiter instance) and by calling
the getResourceById() method, and then cast the result into the specific interface. Another way could be
to pass through a jndi service.
|
SubmiterAware
|
|
The SubmiterAware interface should be implemented by any of the core components that need
to have a Submiter reference. Each time a component is to be initialized, EAISystem previously check whether
the class implements the SubmiterAware interface. In this case,
the setSubmiter()
method is called by EAISystem with the Submiter as a parameter. Then the init() method of the XMLConfigurable
interface is called.
The implementation of this interface should save the Submiter reference in a private member in order to use it when it wants. The Submarine engine ensure that the reference will be valid until the engine stops.
|
|