2011-08-30

Introduction to using coils.workflow.9100

Imagine you have a big and very expensive industrial device that performs a critical diagnostic function.  This device expends a great deal of effort [and energy] to produce a text file on a Windows 2000 SP2 workstation that is tethered to the device through a complex proprietary interface; on that workstation is a proprietary software application that communicates with the device via that complex proprietary interface.  You can't modify the software application, you can't even join the workstation to the corporate domain, and the last thing you want to do is anything that might break this critical, complex, proprietary, expensive, and hopelessly undocumented appliance.  But a text file on a workstation is just data; it isn't information.  You need to move this file onto the network and you want to relate it to other data - thus producing information.

What can a Windows 2000 SP2 workstation that isn't a domain member do?  It can print; or at least it believes that it can print.  Jet-Direct [aka "socket"] printing has been around since man-kind started to replace RS-232 multiplexors and access-servers with packet switched networks.  Of course, with socket printing, the client never really knows what happens on the other end - it just dumps data down the hole and assumes everything proceeds from there.
Enter the new coils.workflow.9100 component that provides a socket listener for accepting TCP data streams into work-flow messages.  Just as the client is oblivious to what happens when it pours a 'print job' into a socket the coils.workflow.9100 is just as unconcerned as to what that client expects to happen.  The upside is that once the data is successfully transitioned into a work-flow engine - anything is possible.

The first step to using the coils.workflow.9100 component to receive your data stream is to configure the interface it listens to. For security reasons, unless otherwise configured, it listens only to the IPv4 loopback interface.  To change this we must change the Coils9100ListenAddress default - by setting this to an IP address the component can be set to listen to just that address, otherwise by setting it to an empty string the component will listen on all interfaces:

$ coils-server-config --directive=Coils9100ListenAddress --value='' Setting the component to listen on all addresses/interfaces. Don't forget to also adjust any related firewall and/or network policy rules that much block the connection or traffic.

Now send a termination signal (signal 15) to the coils.workflow.9100 component and when it restarts it will be listening on all interfaces.

Now on that Windows 2000 SP2 workstation we use the Microsoft "Add Printer" wizard to add a new "Local" printer connected to a new port of type "Standard TCP/IP Port".  The IP address of the "TCP/IP Printer Port" is "coils.example.com" (the host name of your Coils server); the "Port Name" can be any string value you prefer.  Microsoft Windows will be unable to identify our new "device" (possibly because it doesn't exist?) so when prompted for "Additional Port Information" select the standard type "Generic Network Card".  Now that the port is created a printer driver must be assigned.  Select manufacurer "Generic" and printer model "Generc / Text Only".
Next the printer just be named.  Since you are creating the printer to connect to an OIE workflow named "CiscoLoadTester" you will choose to name the printer "OIE:CiscoLoadTester".  Nice and obvious.  Now just click through the remaining dialog panes and the printer is setup. You can now print jobs to the workflow engine!

But, wait, there's a problem.  You have many routes defined - how will OIE know to which route it should deliver the data it receives on the raw socket?  It is just a socket connection after all.  To solve this problem there are two options.

The first option, if the device has a static IP and will only be submitting data to this route, is to set the {http://www.opengroupware.us/oie}clientNetworkAddress property on the route you want to received the data.  If that property is set all connections from the matching network [IP] address will be routed to the route bearing that property.  That is simple but then only one [actually two] clients can submit data to the route, that client can only ever use that one route, and if the client's IP address changes someone has to remember to update the property value.

The second option, and probably the better one in this case, is to define a stream preamble.  A stream  preamble is a string of characters at the beginning of the data stream that the coils.workflow.9100 component will detect and use to route the contents of the stream.  For many applications it isn't possible, or at least not easy, to inject a preamble into the stream.  But since you are using a Microsoft Windows 2000 [or XP, Vista, 7] workstation with a Generic Text printer adding a preamble is simple.  Select the printer in the system's "Printers" dialog, right click and select "Properties". Then under the "Printer Commands" tab in the "Begin Print Job" field enter the text "::{Workflow:CiscoLoadTester}::".  This string will be sent at the beginning of every job queued to the printer.  The coils.workflow.9100 will detect the string "::{Workflow:routeName}::" and attempt to use the specified route.  This preamble will be removed from the stream and the OIE work-flow engine will only receive the remaining contents.

Now when the user finishes generated a report from that enourmous and expensive industrial device that provides only limited network integration - they just print that text file to the "OIE:CiscoLoadTester" printer and the data magically propogates through the rest of the system and to the appropriate applications.

When the component sees your stream preamble it will make a log entry like:
INFO:coils.workflow.9100:Stream preamble specified route named "CiscoLoadTester".
INFO:coils.workflow.9100:Paired stream to route "CiscoLoadTester" via preamble.
Log sample from coils.log when a route is matched via the preamble.
If you don't see that then something is wrong with your setup [possibly after entering the string to the "Begin Print Job" field you didn't hit the dialog's "Apply" button? 

When there is a connection which the component can't match to a work-flow route you'll see log entries like:
DEBUG:coils.workflow.9100:Incoming connection from ('192.168.21.178', 1134)
DEBUG:coils.workflow.9100:Maximum connection transfer is 4294967296b
INFO:coils.workflow.9100:Processing stream from "192.168.21.178"
INFO:coils.workflow.9100:No matching route found for inbound 9100 connection
DEBUG:coils.workflow.9100:Closing connection from ('192.168.21.178', 1134)
Log entries for an unmatched in-bound stream.
In order to be as helpful as possible the coils.workflow.9100 component will still store the contents of the stream in a server-side attachment in case that data was valuable [it won't be lost] and send an e-mail message to the address you configured via the AdministrativeEMailAddress default. This allows you to catch if someone or something is attempting to stream data to OIE but OIE can't determine what it should be doing with that data.

No comments:

Post a Comment