One thing to note about OpenAS2 is that it uses public and private
certificates to encrypt the data being sent, and to allow for easy
testing they packaged a private and public key with OpenAS2 to make it
easier for you, however now that this private key is known by anyone
who downloads OpenAS2 you will need to substitute your own private/
public keystore before you go into production mode with this but as
long as you are just testing in-house then using these keys is fine. I
will explain how to do that once I have explained how to set every
thing else up including the code edits to OpenAS2.
Ok so as you can probably tell, the fact that Bots can refer to files
for input/output is perfect for using OpenAS2 since all you need to do
is have the OpenAS2 server running and then you can just drop files
into the folders for the right partner, and OpenAS2 will detect that a
new file is waiting to be sent and it will automatically send it off
to the corresponding partner.
Before I get into the code editing bits for OpenAS2 I wanted to go
over the reasons for the changes that I did. So first of all I needed
a way for bots to know that a file had been delivered by OpenAS2 to be
processed. So since OpenAS2 is written in java, I found where the code
was handling incoming files and after the file was processed and
verified as being fully delivered, I added in a bit of code that just
launched a console window and ran the bots engine, the reason this is
so easy is because as long as the route on bots is active, then by
running the engine it will automatically check for available files to
run and process them. But this lead to another problem, bots will run
any file that it finds in the correct directory as long as it fits the
correct file name as described when setting up the bots "channels". To
solve this I had to have the bots route delete the file once it was
processed, but then if bots deleted the file, then there would be no
archive of that file and there wouldn't be a way to check for errors
or mistakes after bots ran the file. So I added another bit of code
into OpenAS2 that changed how the file was stored. My code allowed the
file to be saved correctly in the index folder, but then the code will
create an archive file and place a copy of the received file in there.
This allowed me to let bots delete the file once it was processed (the
in folder to the bots "Channel" was set to be the inbox folder, NOT
the archive folder, as these files should not be looked at/touched by
bots) and also keep a copy for later reference. OK so now onto the
actual code bits.
The first edit was to org/openas2/processor/receiver/
AS2ReceiverHandler.java in the public void handle(NetModule owner,
Socket s) { ... } function. (line 61 in my code)
at the end of this function, after these lines (148 - 153):
} catch (DispositionException de) {
sendMDN(s, msg, de.getDisposition(), de.getText());
getModule().handleError(msg, de);
} catch (OpenAS2Exception oae) {
getModule().handleError(msg, oae);
}
I added my code block that will invoke the bots engine after the file
is received (lines 155 -171) :
try
{
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("cmd /c F:\\Python27\\Scripts\
\bots-engine.py");
InputStream stderr = proc.getErrorStream();
InputStreamReader isr = new InputStreamReader(stderr);
BufferedReader br = new BufferedReader(isr);
String line = null;
System.out.println("<ERROR>");
while ( (line = br.readLine()) != null)
System.out.println(line);
System.out.println("</ERROR>");
int exitVal = proc.waitFor();
System.out.println("Process exitValue: " + exitVal);
} catch (Throwable t) {
t.printStackTrace();
}
Of course you will need to change the F:\\Python27\\Scripts\\bots-
engine.py to the path of your bots-engine.py.
The second code edit that I made to allow an archive file was in org/
openas2/processor/storage/MessageFileModule.java in the function
public void handle(String action, Message msg, Map options) throws
OpenAS2Exception { ... } (starting on line 31)
Right under line 36 (shown below)
logger.info("stored message to " + msgFile.getAbsolutePath()
+msg.getLoggingText());
I added my own code (lines 38-45):
String fileParent = msgFile.getParent();
String childFilename = msgFile.getName();
String archiveString = fileParent + "\\archive\\";
File archiveDirectory = new File(archiveString);
archiveDirectory.mkdirs();
File archiveFile = new File(archiveDirectory,
childFilename);
writeStream(msg.getData().getInputStream(), archiveFile);
logger.info("archived message to " +
archiveFile.getAbsolutePath());
Ok so now that the code is edited, try it out for yourself make sure
it still works (you can run bots inside eclipse)
Ok I will stop there and continue in the next post.
~Alex