Here is how to call M3 API from a Drools rule in Infor Event Analytics; this is a common requirement.
Sample scenario
Here is my sample business case.
When a user changes the status of an approval line in OIS115 (OOAPRO), I have to find the order type (ORTP) of the order to determine which approval flow to trigger in Infor Process Automation (IPA), but ORTP is not part of the table OOAPRO, for that reason I must previously make a call to OIS100MI.GetHead.
I could call M3 in the approval flow, but false positives would generate noise in the WorkUnits.
Is it possible?
I asked Nichlas Karlsson, Senior Architect – Business Integration at Infor, if it was possible to call M3 API directly in the Drools rule. He is one of the original developers of Event Hub and Event Analytics and very helpful with my projects (thank you) although he does not work with these products any longer. He responded that Event Analytics is a generic software with no specific connection to M3, so unfortunately this is not possible out of the box, however it is a common requirement. He said I could solve it using MvxSockJ to call M3 APIs in my own Java class, included in a jar that I put in the lib folder. He added to not forget that the execution time for all rules within a session must be less than the proxy timeout, i.e. 30s. And I would also need to manage host, port, user, password and other properties in some way.
Instead of MvxSockJ I will use the MI-WS proxy of the Grid as illustrated in my previous post.
Sample Drools rule
Here is my sample Drools rule that works:
package com.lawson.eventhub.analytics.drools; import java.util.List; import com.lawson.eventhub.analytics.drools.model.Event; import com.lawson.eventhub.analytics.drools.model.HubEvent; import com.lawson.eventhub.EventOperation; import com.lawson.grid.node.Node; import com.lawson.grid.proxy.access.SessionId; import com.lawson.grid.proxy.access.SessionProvider; import com.lawson.grid.proxy.access.SessionUtils; import com.lawson.grid.proxy.ProxyClient; import com.lawson.grid.registry.Registry; import com.lawson.miws.api.data.MIParameters; import com.lawson.miws.api.data.MIRecord; import com.lawson.miws.api.data.MIResult; import com.lawson.miws.api.data.NameValue; import com.lawson.miws.proxy.MIAccessProxy; declare HubEvent @typesafe(false) end rule "TestSubscription" @subscription(M3:OOAPRO:U) then end rule "TestRule" no-loop when event: HubEvent(publisher == "M3", documentName == "OOAPRO", operation == EventOperation.UPDATE, elementOldValues["STAT"] == 10, elementValues["STAT"] == "20") then // connect to MI-WS Registry registry = Node.getRegistry(); SessionUtils su = SessionUtils.getInstance(registry); SessionProvider sp = su.getProvider(SessionProvider.TYPE_USER_PASSWORD); SessionId sid = sp.logon("Thibaud", "******".toCharArray()); MIAccessProxy proxy = (MIAccessProxy)registry.getProxy(MIAccessProxy.class); ProxyClient.setSessionId(proxy, sid); // prepare input parameters MIParameters p = new MIParameters(); p.setProgram("OIS100MI"); p.setTransaction("GetHead"); MIRecord r = new MIRecord(); r.add("CONO", event.getElementValue("CONO")); r.add("ORNO", event.getElementValue("ORNO")); p.setParameters(r); // execute and get output MIResult s = proxy.execute(p); List<MIRecord> records = s.getResult(); // all records if (records.isEmpty()) return; MIRecord record = records.get(0); // zeroth record List<NameValue> nameValues = record.getValues(); // all output parameters String ORTP = nameValues.get(4).getValue(); // PROBLEM: somehow nameValues.indexOf("X") returns -1 // make decision if (ORTP.equals("100")) event.postEvent("ApprovalFlowA"); if (ORTP.equals("200")) event.postEvent("ApprovalFlowB"); if (ORTP.equals("300")) event.postEvent("ApprovalFlowC"); end
Note: You will need to drop foundation-client-10.1.1.3.0.jar in the lib folder of Event Analytics, and restart the application
Limitations
There are some limitations with this code:
- The execution time must be less than the 30s proxy timeout
- Limit the number of return columns; there is currently a bug with Serializable in ColumnList, see Infor Xtreme incident 8629267
- If the M3 API returns an error message it will throw the bug with Serializable in MITransactionException, see Infor Xtreme incident 8629267
- Somehow NameValue.indexOf(name) always returned -1 during my tests, it is probably a bug in the class, so I had to hard-code the index value of the output field (yikes)
- I do not know how to avoid the logon to M3 with user and password to get a SessionId; I wish there was a generic SYSTEM account that Event Analytics could use
- For simplicity of illustration I did not verify all the null pointers; you should do the proper verifications
- The code may throw MITransactionException, ProxyException and IndexOutOfBoundsException
- You can move the Java code to a separate class in the lib folder; for that refer to my previous post
Related articles
- How to call M3 API from the Grid application proxy
- Application proxies in the Infor Grid
- Java code in Event Analytics rules
That’s it. Let me know what you think in the comments below.