Whenever a workitem leaves the engine for the worklist or an APRE, it has to be dispatched (except if the target component is in the same JVM as the engine, in which case, direct delivery may have been configured).
Dispatchers are java classes specified in the participant map (usually etc/engine/participant-map.xml).
There are currently three dispatcher implementations : file, socket and SMTP.
Listeners are OpenWFE services tied to an engine, a worklist or an APRE. For each class of dispatcher, there is one class of Listener. Respectively : file, socket and mail.
Out of the box, OpenWFE dispatches workitem over TCP sockets. This is configured in the participant-map.xml with for example :
<participant name="role-.*">
<param>
<param-name>dispatcherClass</param-name>
<param-value>openwfe.org.engine.impl.dispatch.SocketDispatcher</param-value>
</param>
<param>
<param-name>host</param-name>
<param-value>127.0.0.1</param-value>
</param>
<param>
<param-name>port</param-name>
<param-value>7008</param-value>
</param>
</participant>
that tell the engine (and other interested components) that workitem for participants whose name begin with "role-" should be sent by using an instance of the class SocketDispatcher. The parameters of the participant are then fed to the dispatcher, these are 'host' and 'port', they indicate the destination of the socket despatchement.
On the other side, the 'receiving' component ought to have a listener ready :
<service
name="Listener.socket"
class="openwfe.org.engine.impl.listen.SocketListener"
>
<param>
<param-name>port</param-name>
<param-value>7008</param-value>
</param>
<param>
<param-name>workItemConsumer</param-name>
<param-value>Consumer.worklist</param-value>
</param>
<!--
For machines with multiple interfaces,
you can specify on which one it should listen.
By default, it listens on all.
<param>
<param-name>inetAddress</param-name>
<param-value>192.168.7.3</param-value>
</param>
-->
</service>
The listener is listening on port 7008, the received workitems are fed to the consumer service named 'Consumer.worklist'. For an engine component, the consumer would probably be 'Consumer.engine'.
<!-- The consumer takes care of verifying workitems before
giving them to other components. This consumer gives workitem
to the worklist -->
<service
name="Consumer.worklist"
class="openwfe.org.worklist.ListWorkItemConsumer"
>
</service>
There isn't much to configure about a consumer, but it's important to tie the listener to the appropriate consumer.
OpenWFE is able to use the internet mail infrastructure to transmit its workitem. The mail thus sent contain as payload workitems and are thus not intended for human 'consumption'. Though you could imagine one human recipient tweaking XML in a workitem thus 'participating' in a flow.
Using the internet email infrastructure might be slower than direct TCP connection, but that infrastructure is robust : a message can stay in a POP3 inbox while no engine MailListener is polling for it. Smtp servers like sendmail and exim do their best at trying to deliver mail messages, they implement proven retry techniques. For a 'WAN' workflow, this dispatcher/listener couple might be optimal.
On the emitting side, an smtp enabled participant (etc/engine/participant-map.xml) :
<participant name="over-smtp">
<param>
<param-name>dispatcherClass</param-name>
<param-value>openwfe.org.engine.impl.dispatch.SmtpDispatcher</param-value>
</param>
<param>
<param-name>recipient</param-name>
<param-value>pivot@nowhere.comp</param-value>
</param>
<param>
<param-name>smtp-server</param-name>
<param-value>mail.nowhere.comp</param-value>
</param>
<!--
<param>
<param-name>smtp-port</param-name>
<param-value>25</param-value>
</param>
-->
<param>
<param-name>mail-from</param-name>
<param-value>glups@nowhere.comp</param-value>
</param>
<!--
You can specify a 'carbon-copy' recipient.
Maybe an 'archive' account.
-->
<param>
<param-name>cc</param-name>
<param-value>nada@nowhere.comp</param-value>
</param>
<param>
<param-name>workItemCoder</param-name>
<param-value>xmlCoder</param-value>
</param>
</participant>
The 'MailListener' service is a daemon polling a POP3 or an IMAP inbox for new workitems. Consumed workitems are then removed from the box.
It's configured in etc/engine/engine-configuration.xml :
<service
name="mailListener"
class="openwfe.org.engine.impl.listen.MailListener"
>
<param>
<param-name>accountUrl</param-name>
<param-value>pop3://username:password@mail.nowhere.comp</param-value>
</param>
<!-- for POP3, defaults to INBOX
<param>
<param-name>folder</param-name>
<param-value>INBOX</param-value>
</param>
-->
<!--
the default frequency is '30s'
-->
<param>
<param-name>frequency</param-name>
<param-value>20s</param-value>
</param>
<param>
<param-name>workItemConsumer</param-name>
<param-value>Consumer</param-value>
</param>
</service>
(showing how to use SSH-tunnelling for easily protecting communications between remote OpenWFE components)
Dispatchers do decide which encoder is used to turn a workitem instance into a stream of bytes transferrable from one OpenWFE component to the other.
This is done via the 'workItemCoder' parameter they're attributed in the etc/engine/participant-map.xml file :
<param>
<param-name>workItemCoder</param-name>
<param-value>xmlCoder</param-value>
</param>
Other possible values are defined in the file etc/engine/coder-configuration.xml where our 'xmlCoder' is specified (where its java implementation is revealed to the OpenWFE components).