Here is an unofficial guide on how to create a custom message process in Infor M3 Enterprise Collaborator (MEC).
What is a message process?
A message process in MEC is one of the steps in a process flow. Technically speaking, it is a Java class that reads a stream of bytes as an input, does some processing on it, and writes a stream of bytes as an output, for example transform a flat file to XML, apply XSLT to an XML, remove an envelope, archive the message, or make a SOAP request. Message processes are chained together in a partner agreement in the Partner Admin Tool.
Documentation
The Partner Admin Tool User Guide has some information about message processes:
Java classes
The message processes are Java classes located in MEC’s core library:
D:\Infor\LifeCycle\host\grid\M3\grids\M3\applications\MECSRVDEV\MecServer\lib\ec-core-x.y.z.jar
Each message process is a Java class in package com.intentia.ec.server.process:
Each message process may have a configuration dialog box in package com.intentia.ec.partneradmin.swt.agreement:
Database
The message processes are declared in the MEC database in table PR_Process:
Java code
To create your own message process follow these steps:
- Use the following skeleton Java code, fill with your code, set the file extension for the output message (in my example it is .something), use the in input and out output streams to process the message as you need, and eventually use the cat logger to write debug info in the log file:
package somewhere; import java.io.InputStream; import java.io.OutputStream; import org.apache.log4j.Category; import com.intentia.ec.server.process.AbstractProcess; import com.intentia.ec.server.process.ProcessException; public class SomeProcess extends AbstractProcess { private static Category cat = Category.getInstance(SomeProcess.class.getName()); public String getState() { return "SomeProcess"; } public boolean hasOutput() { return true; } public String getFileExtension() { return ".something"; } public void process(InputStream in, OutputStream out) throws ProcessException { // your code here cat.info("processing..."); } }
Note: I do not have a sample code for the dialog box, but you can get inspiration from one of the existing classes in package com.intentia.ec.partneradmin.swt.agreement.
- Compile the Java code with:
javac -extdirs D:\Infor\LifeCycle\host\grid\M3\grids\M3\applications\MECSRV\MecServer\lib\ SomeProcess.java
- Copy the resulting Java class to the classpath of the MEC server and Partner Admin Tool, in the folder corresponding to the package (in my case it was package somewhere):
D:\Infor\LifeCycle\host\grid\M3\grids\M3\applications\MECSRV\MecServer\custom\somewhere\SomeProcess.class D:\Infor\MECTOOLS\Partner Admin\classes\somewhere\SomeProcess.class
Note: You can probably also put the Java class in a JAR file; to be tested.
- In the MEC database, add the process to the PR_Process table, where ?? is a new ID, for example 27:
INSERT INTO MECDBDEV.dbo.PR_Process (ID, Name, Description, ConfigurationClass, WorkClass, Standard) VALUES (??, 'Thibaud Process', 'My custom message process', null, 'somewhere.SomeProcess', 1)
- In the Infor Grid, restart the MECSRV application to pick up the new Java class:
- In the Partner Admin Tool, create a partner agreement and add the message process:
- Reload the MEC server to pick up the new agreement:
- Run the partner agreement, for example I have a channel detection with a HTTPIn receive channel listening on port 8084, and I make an HTTP request to that port number to trigger the partner agreement.
- Check the message received (.rcv) and the message produced (in my case it was extension .something); for that, you will need one Archive process in your partner agreement, before and after your custom process:
- You can also open the files directly in the folder specified:
- And if you used the logger, you can check your logs in the Event tab:
Real-world example
In my case, I needed a custom message process for the following real-world scenario. My current customer does Procurement PunchOut with its partners using cXML, an old protocol from 1999. In that protocol, there is a step (PunchOutOrderMessage) that sends an XML document in a hidden field cxml-urlencoded of an HTML form. That results in a POST HTTP request (to MEC) with Content-Type: application/x-www-form-urlencoded, with the XML document that is URL-encoded as a value of parameter cxml-urlencoded in the request body. Unfortunately, MEC does not have a message process to extract a specific parameter value of a message, and URL-decode it. So I developed my custom message process as explained above, to take the request body, extract the desired parameter value, URL-decode it, and output the resulting XML. I may write a detailed post about it some day, maybe not.
Conclusion
That was a guide on how to create a custom message process in MEC, doing Java development, to take an input message in a partner agreement, do some custom processing on it, and produce an output message. This is an unofficial solution that I figured out by de-compiling and hacking MEC. There may be a simpler solution, I do not know.
That’s it! Thank you for supporting this blog, please like, subscribe, share around you, and come author the next blog post with us.
UPDATE: To change the log level of the custom process go to MECSRV > Grid Management Pages > Event > Log Configuration > somewhere.SomeProcess > DEBUG > Submit. Somehow when I click Submit I get this error message even though it succeeded to change the log level: “Error occured. Problem saving to log.config: java.io.FileNotFoundException: D:\Infor\MECDEV\log.config (Access is denied)”
LikeLike
UPDATES:
I now prefer to use the Logger instead of the Category, and I add the Manifest UUID:
private static Logger log = org.apache.log4j.Logger.getLogger(HelloWorld.class);
log.debug(manifest.getUUID() + “[:] Hello, World!”);
Also, we can search the logs in the MEC database:
SELECT * FROM [MECDBDEV].[dbo].[MecLog]
WHERE Category=’HelloWorld’ AND UUID=’34567890-1234-5678-9012-345678901234′
LikeLike
UPDATE: The string returned by getState() must be 32 characters long maximum due to MEC’s table dbo.DocStates.
LikeLike
UPDATE: The string returned by getState() does not get SQL escaped, so it’s subject to SQL injection, e.g. “Thibaud’s process” with an ampersand. It’s not really a security vulnerability as only MEC admins/developers have access to this.
LikeLike