User synchronization between M3 and IPA – Part 4

I re-discovered a technique to synchronize users between Infor M3 and Infor Process Automation (IPA) using IPA’s web based administration tools.

It is now my preferred technique for the initial mass load of users, whereas previously in part 2, I had been using command line tools.

IPA web admin tools

The IPA web admin tools are located at http://host/UserManagement/home?csk.gen=true for the gen data area, to create the Identities, Actors, Actor-Identity, and Actor-Roles; and at http://host/lmprdlpa/LpaAdmin for the environment data area – PRD in my case – to create the Users, Tasks, and User-Tasks. It is the same as the IPA Rich Client Admin but web-based instead of Java GUI based.

To find the tools, use the shortcuts ValidationURLs.htm in your IPA installation folder: 0

Replaying the actions

I manually created users in the IPA web admin tools, intercepted in Fiddler the HTTP requests of each action, replayed the POST requests in Fiddler Composer, and repeatedly pruned the unnecessary data away until I identified the minimum set of values.

I then translated the result into the equivalent JavaScript code.


Here below is the result. It supposes you already have an array of users which you can generate with SQL or M3 API (from MNS150 and CRS111).






Source code

I posted the source code WebAdmin.js on my GitHub repository. I will update the source code there.

Future work

  • Stitch the JavaScript code together
  • Create the Tasks (from MNS405)
  • Create the User-Tasks (from MNS410)


This is yet another technique to synchronize users between M3 and IPA. I find it easier than the command line tools I was using previously. Follow the progress on the GitHub repo.

Related articles

  • Part 1, overview of user synchronization between M3 and IPA

That’s it! Please like, comment, subscribe, share, and author with us.

User synchronization between M3 and IPA – Part 3

Now I will do the incremental backup of M3 users and roles.

Refer to part 1 and part 2 for the background.

Design decisions: Pull or Push?

We can either make IPA pull the data from M3, or make M3 push the data to IPA.


We can make a process flow with SQL queries that pull data from M3, creates or updates the respective record in IPA, scheduled to run at a certain frequency, e.g. once an hour.

It is the simplest strategy to implement. But it is not efficient because it re-processes so frequently thousands of records that have already been processed. And it does not reflect the changes of M3 sooner than the scheduled frequency. And each iteration causes unnecessary noise in the IPA logs and database, so the less iterations the better. And IPA is already slow and inefficient for some reason, so the less work in IPA the faster it is. And after an undetermined amount of work, IPA becomes unstable and stops responding after which we have to restart it, so the less work in IPA the more stable it is.


We can also make a series of Event Hub subscriptions and a process flow with Landmark activity nodes. It will reflect the changes in IPA virtually immediately, faster. And it will operate only on the record being affected, not all, which is efficient.


I will use a mix: I used the pull strategy for the initial mass load (see part 2), and here below I will use the push strategy for the incremental backup.

Process flow

Here is my process flow that does the incremental backup:

  • The top section handles the M3 user (MNS150, CMNUSR) and the respective IPA identity, actor, actor-identity, actor-role, in the gen data area, and the user in the environment data area (e.g. DEV, TST).
  • The second section handles the M3 email address (CRS111, CEMAIL, EMTP=4) and the respective IPA actor email address.
  • The third section handles the M3 role (MNS405, CMNROL) and the respective IPA task.
  • The bottom section handles the M3 user-roles (MNS410, CMNRUS) and the respective IPA user-tasks.
  • Each section handles the M3 operations: create, update, and delete.
  • I merged everything in one big flow, but we could split it in individual flows too.
  • I upload the process with logs disabled to avoid polluting the logs and database.

Source code

You can download the process flow source code on my GitHub here.

Event Hub subscriptions

I created the corresponding Event Hub subscriptions in the IPA Channels Administrator:




Here are the resulting WorkUnits:

Repeat per environment

Deploy the process flow, and setup the event hub subscriptions on each environment data area (e.g. DEV, TST).


Refer to the challenges section in part 1 for the limitations, notably the data model dissonance which will cause collisions, the out-of-order execution which will cause inconsistencies, and the constraint mismatch which will cause failures.

Future work

  • Prevent deleting the administrative users M3SRVADM and lawson.
  • Recursively delete dependencies (e.g. in IPA we cannot delete a user that has pending WorkUnits)


This three-part blog post was a complete solution to do unidirectional synchronization of users between M3 and IPA, by means of an initial mass load via the command line, and an incremental backup via a process flow and Event Hub subscriptions. Unfortunately, Infor does not have complete documentation about this, there are serious shortcomings, and IPA is defunct anyway. Also, check out the valuable comments of Alain Tallieu whom takes user synchronization to the next level.

Related articles

That’s it!

Please like, comment, follow, share, and come author with us.

User synchronization between M3 and IPA – Part 2

Now I will do the initial mass load of users.

As a reminder, we create the identities and actors in the gen data area, and the users and tasks in the environment data area (e.g. DEV, TST). For more information, refer to part 1.

Design decisions: Command line or process flow?

We could use either the command line or the Landmark activity node in a process flow. I will explore the former now, and the latter next time. Note the command line is not available in Infor CloudSuite.

1. Identities and actors

I will generate a file of identities and actors, reading from M3, and I will use the secadm command to import the file to the gen data area in IPA.

1.1. Documentation

There is some documentation for the secadm command at Infor Landmark Technology Administration Guides > Infor Landmark Technology User Setup and Security > Landmark for Administrators > Using the Administrative Tools > The Security Administration Utility (secadm):

1.2. Extract the data

Extract all the users (MNS150) and email addresses (CRS111) from M3, and save them to a file somewhere (e.g. semi-colon separated users.csv):



Note: If you already know the subset, you can filter the list to only the users that will participate in approval flows, and discard the rest.

PROBLEM: M3 is environment specific (e.g. DEV, TST), but the gen data area is not. And M3 is company (CONO) specific, whereas IPA is not. So we will have collisions and omissions.

1.3. Transform

Transform the list of users to a list of secadm commands, where for each user, we have the commands to create the identity, actor, actor-identity, and actor-role, e.g.:

identity add SSOPV2 USER123 --password null
actor add USER123 --firstname Thibaud --lastname "Lopez Schneider" --ContactInfo.EmailAddress
actor assign USER123 SSOPV2 USER123
role assign USER123 InbasketUser_ST

Not all attribute keys are documented, but you can find them all here:
1 2

For the transformation you can use the following DOS batch file (e.g. users.bat):

@echo off
for /f "tokens=1-3 delims=;" %%a in (users.csv) do (
    echo identity add SSOPV2 %%a --password null
    for /f "usebackq tokens=1,* delims= " %%j in ('%%b') do (
        echo actor add %%a --firstname %%j --lastname "%%k" --ContactInfo.EmailAddress %%c
    echo actor assign %%a SSOPV2 %%a
    echo role assign %%a InbasketUser_ST

Note 1: Replace delims with the delimiter of your file (e.g. semi-colon in my case).

Note 2: The command will naively split the name TX40 in two, where the first word is the first name and the rest is the last name; this will be an incorrect split in many cultures.

Save the result to a text file (e.g. users.txt):

users.bat > users.txt

We now have a list of commands ready to be executed:

1.4. secadm

Execute the secadm command to import the file to the gen data area:

cd D:\Infor\LMTST\
secadm -f users.txt -d gen


1.5. Result

Here is the resulting list of identities, actors, actor-identity, and actor-role, in the gen data area:
6 7 8 9 10

1.6. Repeat per environment

Repeat from step 1.2 for the next environment (e.g. DEV, TST). Due to the data model dissonance between M3 and IPA, there will be collisions; see the challenges section in part 1.

1.7. Delete

To delete the records, proceed in reverse with the remove and delete sub-commands and the –complete argument. Be careful to not delete the administrative users M3SRVADM and lawson.

@echo off
for /f "tokens=1-3 delims=;" %%a in (users.csv) do (
    echo role remove %%a InbasketUser_ST
    echo actor remove %%a SSOPV2 %%a
    echo actor delete %%a --complete
    echo identity delete SSOPV2 %%a

1.8. Update

I could not find a command to update the Actor; for future work; meanwhile, delete and re-add.

1.9. More

Here is some more help for the secadm command:


Usage: Utility for security administration.
Syntax: secadm [secadm-options] command [command-options]
where secadm-options are global secadm options
(specify --secadm-options for a list of secadm options)
where command is a secadm command
(specify --help-commands for a list of commands
where command-options depend on the specific command
(specify -H followed by a command name for command-specific help)
Specify --help to receive this message

D:\Infor\LMTST>secadm --secadm-options
-c Continue on error
-d dataarea
-? Print help meesage
-i Enter interactive shell mode
-H <command> Command-specific help
-f <filename> File to use as for commands
-r Recover Secadm Password
-q Run quietly
--secadm-options For a list of secadm options
-s Run silently
--help-commands For a list of commands
-m Enter interactive menu mode
-p Password for secadm
--help Print this message
-v Print version information
[-p >password>] -u Upgrade AuthenDat

D:\Infor\LMTST>secadm --help-commands

Valid sub-commands are:
accountlockoutpolicy Maintain system account lockout policies.
actor Maintain system actors
httpendpoint Maintain system HTTP endpoints and HTTP endpoint assignments.
identity Maintain system identities.
load Load data from a file.
provision Provision Lawson users
loginscheme Maintain system login schemes.
migrate Migrate supplier identities from default primary SSO service to domain primary SSO service
passwordresetpolicy Maintain system password reset policies.
role Maintain system roles
secanswer Maintain system security answers.
secquestion Maintain system security questions.
service Maintain system services.
ssoconfig Maintain Single Sign On Configuration
ssodomain Maintain system domain.
security Assign security classes to roles and control Security activation
admin Lawson Security Admin Configuration
passwordpolicy Maintain system password policies.
generate Secadm script generation from data
agent Migrate system agents and actors
principalresolver Maintain custom Principal Resolver code.
report Security Data Reports
mitrustsetup Set up trusted connections for an MI socket service.
keys Key Management
SSOCertificate Manage Federated Server Certificates
wsfederation Manage WS Federation Settings
proxy Proxy
class SecurityClass

D:\Infor\LMTST>secadm -H identity
identity Maintain system identities.

Valid sub-commands are:
privileged Maintain privileged identities.
add Add identity to the system.
update Update identity in the system.
delete Delete identity from the system.
display Display identity in the system.
pwdResetByIdentity Password reset by identity in the system.
pwdResetByService Password reset by service in the system.
listIdentities List all identities in the system.
listBadPasswords List identities with bad passwords by service in the system
overrideBadPasswords Override password for identities with bad password by service in the system

D:\Infor\LMTST>secadm -H actor
actor Maintain system actors

Valid sub-commands are:
add Add actor to the system.
delete Delete actor from the system. !This option is temporarily unavailable
assign Assign Identity to an actor.
remove Remove Identity from an actor.
accountenable Enable actor account in the system.
accountdisable Disable actor account in the system.
enablerunas Enable Run As for Actor in the system.
disablerunas Disable Run As for Actor in the system.
actorenable Enable actor in the system.
actordisable Disable actor in the system.
context Actor context maintenance
ctxproperty Context property maintenance
list List all actors in the system.
link Actor to Agent link maintenance


2. Users and tasks

Now, for each M3 environment (e.g. DEV, TST), I will generate a file of users and tasks, and I will call the importPFIdata command to import the file to the respective data area.

2.1. Documentation

There is some documentation for the importPFIdata command at Infor Landmark Technology Installation Guides > Infor Lawson System Foundation Using Infor Process Automation Configuration Guide > Post-Installation Procedures > Run migration scripts:

2.2. Extract the data

For each environment (e.g. DEV, TST), extract all the roles (MNS405) and user-roles (MNS410) from M3, and save them to files somewhere (e.g. roles.csv and user-roles.csv):


Note: If you already know the subset, you can filter the list to only the users and roles that will participate in approval flows, and discard the rest.

2.3. Transform

Transform the list of roles and user-roles to the XML syntax of importPFIdata, e.g.:

<?xml version="1.0" encoding="UTF-8"?>
<ImpExpData Version="1">
        <Table Name="WFTASK">
                    <Column Name="TASK"><Value>FLEET_MGR</Value></Column>
                    <Column Name="WF-DESCRIPTION"><Value>Fleet manager</Value></Column>

Not all table names and columns are documented, but you can find them all here:
13 14

For the transformation you can use the following DOS batch file (e.g. user-roles.bat):

@echo off
echo ^<?xml version="1.0" encoding="UTF-8"?^>
echo ^<ImpExpData Version="1"^>
echo ^<Tables^>
echo ^<Table Name="WFUSRPROFL"^>
echo ^<Rows^>
for /f "tokens=1,* delims=;" %%a in (users.csv) do (
echo ^<Row^>^<Column Name="WF-RM-ID"^>^<Value^>%%a^</Value^>^</Column^>^</Row^>
echo ^</Rows^>
echo ^</Table^>
echo ^<Table Name="WFTASK"^>
echo ^<Rows^>
for /f "tokens=1-2 delims=;" %%a in (roles.csv) do (
echo ^<Row^>^<Column Name="TASK"^>^<Value^>%%a^</Value^>^</Column^>^<Column Name="WF-DESCRIPTION"^>^<Value^>%%b^</Value^>^</Column^>^</Row^>
echo ^</Rows^>
echo ^</Table^>
echo ^<Table Name="WFUSERTASK"^>
echo ^<Rows^>
for /f "tokens=1-2 delims=;" %%a in (user-roles.csv) do (
echo ^<Row^>^<Column Name="WF-RM-ID"^>^<Value^>%%a^</Value^>^</Column^>^<Column Name="TASK"^>^<Value^>%%b^</Value^>^</Column^>^<Column Name="START-DATE"^>^<Value^>00000000^</Value^>^</Column^>^<Column Name="STOP-DATE"^>^<Value^>00000000^</Value^>^</Column^>^</Row^>
echo ^</Rows^>
echo ^</Table^>
echo ^</Tables^>
echo ^</ImpExpData^>

Save the result to an XML file (e.g. user-roles.xml):

user-roles.bat > user-roles.xml

We now have an XML file ready to be imported:


2.4. importPFIdata

Execute the importPFIdata command to import the file to the specified data area (e.g. lmdevipa):

cd D:\Infor\LMTST\
env\bin\importPFIdata.bat lmdevipa -f user-roles.xml


2.5. Result

Here is the resulting list of users, tasks, and user-tasks, in the specified data area:
21 18 20 17 19

2.6. Repeat per environment

Repeat from step 2.2 for the next environment (e.g. DEV, TST).

2.7. Delete

I do not yet know how to delete via the command line; for future work.

2.8. Update

The importPFIdata command will automatically update the record if it already exists.

Source code

I made a unified PowerShell script m3users.ps1 that I put on my GitHub.


That was the initial mass load of users from M3 to IPA using the command lines secadm for identities and actors in the gen data area, and importPFIdata for users and tasks in each environment data area (e.g. DEV, TST).

See also

See part 1 for the overview of user synchronization between M3 and IPA.

And read the comments by Alain Tallieu where he shares his experience and valuable tips.

Future work

Here is some future work:

  • What to do about the lack of environment and CONO in IPA
  • How to update actors
  • How to delete users and tasks
  • Prevent deleting the administrative users M3SRVADM and lawson.
  • Finish the PowerShell script

To be continued…

I will continue in part 3 for the incremental backup.

User synchronization between M3 and IPA – Part 1

I return to Infor Process Automation (IPA) 😱 to develop approval flows for purchase orders in Infor M3 and to setup the users and roles that will take action in the Infor Smart Office (ISO) Inbasket.

Note: The IPA product is dead and Infor is replacing it with ION, so my endeavor is obsolete; furthermore, the integration of IPA and ION with M3 is flawed by design at many levels, ergo working on it is flawed too; but my customer still uses IPA for M3, so I return.

UserAction activity node

The UserAction activity node defines who can take what actions:


The Inbasket displays the work to the respective users so they take the action (e.g. approve/reject in this purchase order to branch managers):

Email actions

Email addresses are needed to be able to allow actions via emails (e.g. Accept/Reject in this sale approval):


If the user is not setup in IPA, they will get the error “Inbasket Error, Unable to populate Inbox for the LPA server”:

To avoid the error, we have to setup the user in IPA, even if the user does not need the Inbasket.

There are some workarounds: 1) setup two Smart Office Installation Points, with or without the Infor.PF10 feature, 2) setup two Smart Office profiles, with or without the PF configuration enabled, 3) setup the Mango.Core application settings to enable roaming profiles with or without the Process Server inbasket, 4) maybe use the Category File Administration for profile.xml with or without the Inbasket and Connect Roles and Users, etc. Each workaround has advantages and disadvantages. Nonetheless, we still have to setup at least those users that need the Inbasket.


No users are setup in IPA upon installation, IPA is blank, and M3 and IPA do not have a built-in synchronization mechanism. Hence, for every M3 user that needs the Inbasket, we have to setup the user in IPA. If we have thousands of users, it is too much work to do manually. I need an automatic solution. Note: as a consolation, at least we do not need to manage passwords in IPA as IPA has LDAP binding.


I will implement a solution to automatically synchronize users between M3 and IPA.

My design decisions are:

  • Simple mirror, one-way synchronization, from M3 (primary) to IPA (replica), and ignore changes in IPA
  • One-time initial mass load + incremental backup
  • Per environment (e.g. DEV, TST)
  • Synchronize all users to avoid problem #1 above; otherwise filter to synchronize only the users that will use the Inbasket, not the others; but then must implement one of the workarounds above


  • IPA does not have the concept of CONO, whereas M3 does; thus we will have to choose one of the CONOs and discard the rest, i.e. possible data loss
  • IPA stores the email addresses in gen for all data areas, whereas M3 stores the email addresses per environment (e.g. DEV, TST); thus we will have to choose one of the email addresses and discard the others, i.e. possible data loss
  • IPA stores the user’s name in two fields firstname and lastname, whereas M3 stores it in a single field TX40; thus we will have to split the field in two, and make an assumption of where to split for names with more than two words, i.e. possible incorrect split
  • IPA is slower than M3, and there are no concurrency guarantees; thus there could be race conditions where two consecutive changes in M3 are executed in the wrong order by IPA, i.e. possible data inconsistency
  • There is a constraint mismatch between M3 and IPA; e.g. let’s take the case of M3 users and roles (that’s users and tasks in IPA), and let’s suppose a role has one or more users connected to it (one-to-many relationship): in M3 we can delete the role, and M3 will automatically and recursively delete the user-roles associations; whereas if we try to delete the corresponding task in IPA, it will throw an error that associations exist, so we would have to recursively delete the associations ourselves. I just tested that; I have not tested the rest: identities, actors, etc.
  • M3 is encoded in UTF-8, whereas IPA is encoded in ISO-8859-1, i.e. possible data loss


There is some documentation about the setup, but it is not everything we need:

Setting up users for Infor Process Automation and Infor Smart Office:

Mass-loading actors for Infor Process Automation: Overview:

User management in M3

Here are the programs, tables, and fields for M3:


Roles (MNS405, CMNROL), ROLL, TX40:

User-Roles (MNS410, CMNRUS), USID, ROLL:

Email address (CRS111, CEMAIL), CONO, EMTP, EMKY, EMAL:

Everything is stored in the M3 database in the respective tables:

MetaData Publisher (MDP) has information about the tables, columns, and keys:

User management in IPA

Here are the programs involved for IPA:

In the general data area:


Identity (with Service SSOPV2):

Actor (FirstName, LastName, and Email address):

Actor-Identity (one-to-one):

Actor-Roles (at least InbasketUser_ST):

In each data area (e.g. DEV, TST):

Users (one-to-one with Actor):

Tasks (equivalent of M3 Roles):


The data is stored in the IPA database in the respective tables (gen: IDENTITY, ACTOR, IDENTITYACTOR, ACTORROLE; DEV/TST: PFIUSERPROFILE, PFITASK, PFIUSERTASK):

To be continued…

I will continue in part 2.

Authorization hierarchies for approval flows in M3

Today I will illustrate authorization hierarchies for approval flows in Infor M3.

Approval flows

A common requirement in M3 projects is to implement approval flows, for example for purchase orders; where a buyer creates a purchase order of a certain amount; where one or more approvers must review the order, and either approve it, one approver after the other, either reject it for some reason; and where the approvers are selected from a hierarchy of managers and their maximum order amount.

There are many variations of these approval flows, each being specific to the requirements of the M3 project. Here is a simple approval flow with a single approver:
Approval flows get complex quickly, with many decisions to take, many levels of approval to have, many design trade-offs to consider, and all sorts of scenarios to support.

Infor Process Automation

To implement the approval flows we use Infor Process Automation (IPA). We can also use the former Lawson ProcessFlow Integrator (PFI). As for Infor ION, it is the new standard for implementing M3 approval flows, but its usage for M3 is still young, and it does not yet have as many features as IPA does.

M3 Purchase Authority – PPS235

To store the hierarchy of approvers and their maximum order amounts, we use the program M3 Purchase Authority – PPS235. It stores the user (AURE), the maximum order amount this user is authorized to approve (MPOA), and their manager who is the next level for authorization (MNGR). For orders that exceed this amount, authorization is required by a user with authorization rights for a higher amount.



I am not an expert on PPS235, but it looks like it does not enforce integrity, and it is not in normal form, and that can result in logical inconsistencies.

Indeed, the hierarchy of managers and maximum order amount may contradict each other. For instance, PPS235 allowed me to set a user whose maximum order amount was higher than that of its manager, in which case routing the approval to that manager will result in a logical anomaly.

Also, there is a field to set the user’s authorization level (AUTL) which results in an alternate hierarchy of approvers, and PPS235 allowed me to enter illogical values there too.

That results in several possible hierarchies: either based on the managers, either based on the maximum order amounts, either based on the authorization levels, all possibly contradicting each other.

Also, PPS235 erroneously allows cycles in the hierarchy. For instance, it allowed me to set a user to be the manager of its manager. This will cause an infinite loop in the graph traversal.

Also, users can be unreachable if there does not exist a connection to that user in the hierarchy.

There is probably a logical explanation for these design decisions. Meanwhile, you must ensure the integrity of your data before proceeding.


The data of PPS235 is stored in table MPAUTD – Authorization distribution as an adjacency list of users and their managers, for example:

Marie Eric
Keith Daniel
Eric Daniel
Charles Daniel
John Daniel
Daniel Joe
Joe Jeff

The resulting tree looks something like this (I use Graphviz to visualize the hierarchy and ensure it is correct):

To retrieve the hierarchy of managers for a certain user we traverse the adjacency list recursively using SQL’s common table expressions (CTE), for example for user Marie and for a purchase order in company 100:


That results in the hierarchy of approvers and their maximum order amount starting at the specified buyer:

You can now create a loop of UserAction activity nodes in IPA to iterate thru that hierarchy. Here is an excerpt (you will need to add the SQL activity node and everything else that may be needed; you can also use the new ForEach activity node instead of my loop with an if-then-else Branch):


That was a quick illustration of authorization hierarchies for approval flows for purchase orders in M3, more specifically how to store the hierarchy of approvers in PPS235, how to recursively query it from MPAUTD, and how to do a loop of UserAction activity nodes.

(I meant to write about this many years ago. I finally got around to doing it after I learned how to do the recursive SQL portion for a customer last week. I hope it helps you.)

M3 Web Services from Infor Process Automation

In order to securely call Infor M3 Web Services (MWS) from Infor Process Automation (IPA) we need to import the Infor Grid’s certificate in IPA’s Java truststore; here is how.

MWS authentication

MWS works with SOAP over HTTP over SSL/TLS with the digital certificate of the Infor Grid.

The Infor Grid router for MWS must have Basic authentication enabled over HTTPS (secure) and have all authentication disabled over HTTP (insecure); you can check in the Infor Grid > Configuration Manager > Routers > Default Router:

MWS from IPA

In the IPA Configuration > Web Service Connection, we set the Basic authentication with the M3 user and password:

In Infor Process Designer (IPD), we use the SOAP Web Service activity node to the HTTPS URL of MWS:

Tip: un-hard-code the scheme://host:port and replace it by a variable <!_configuration.main.MWS> to define.


When we execute the process we get the following exception: HTTP transport error: PKIX path building failed: unable to find valid certification path to requested target

That is because IPA does not know the Infor Grid certificate.

The IPA Configuration for the Web Service Connection does not have settings for an explicit truststore. Instead, IPA implicitly relies on the JVM’s truststore; let’s set it up.

Step 1. Infor Grid certificate

Get the Infor Grid certificate file. It is a signed public key that you can get for example from the main Grid Information at something like https∶//host123.local:26108/grid/info.html

Note: Preferably get the certificate of the root CA as it usually signs the certificates for all environments (DEV, TST, PRD, etc.).

Step 2. IPA server truststore

Check the path of the IPA server’s JVM as given in the Landmark Grid > Landmark-LM Application > Configuration > Properties > Java executable:

Import the certificate into that JVM’s truststore using the Java keytool:

keytool -import -keystore lib\security\cacerts -file grid.cer


Note: I may have mixed up the keystore and the truststore in the command; to be verified.

Step 3. IPD truststore

The path to the Infor Process Designer (IPD) JVM is given by the IPDesigner.ini file:
3.7 3.8

Import the certificate into that JVM’s truststore as well.

Step 4. Test

Now execute the process. The Web Service activity node should not throw that exception anymore.


If you have a certificate purchased from a certificate authority that is already trusted by the JVM, such as VeriSign, this setup is not necessary.

That’s it. Let me know what you think in the comments below.

Intercept network traffic from Infor Process Automation

Infor Process Automation (IPA) communicates with other servers over the network – using for example the WebRun, Web Service, SQL Query, and Email activity nodes – but it lacks the ability to dump the network traffic for troubleshooting purposes. Here are my solutions.


The WebRun activity node uses HTTP:

  1. HTTP request header
  2. HTTP request body
  3. HTTP response header
  4. HTTP response body

The Web Service activity node uses SOAP over HTTP:

  1. HTTP request header
  2. HTTP request body
    1. SOAP request header
    2. SOAP request body
  3. HTTP response header
  4. HTTP response body
    1. SOAP response header
    2. SOAP response body

The SQL Query activity node uses JDBC.

The Email activity node uses SMTP.

And IPA has other activity nodes for products such as Landmark, Lawson, ION, Cloverleaf.

IPA and Infor Process Designer (IPD) will only show a fraction of the network traffic. For example for the WebRun activity node it only shows the HTTP response body, and unfortunately it discards the rest of the useful information.

With Wireshark

Wireshark can naturally intercept traffic from IPA and IPD.

Here are my screenshots for the WebRun activity node:
1 2 3

We get the entire HTTP request (header and body) and HTTP response (header and body). From that traffic we learn useful information about the WebRun activity node. For example, we learn what is the User-Agent String being used, we learn that IPA only uses the POST method (not GET), we learn that IPA automatically adds a leading slash to the URL path even if we don’t want it, and we learn that some versions of IPA have a bug in the Content-Type that always sets it to application/x-www-form-urlencoded even if we set it to something else. And we have the rest of the data to do the troubleshooting we may need.

And here are my screenshots for the Web Service activity node:
2.1 2.3 2.4

We get the entire HTTP request (header and body), HTTP response (header and body), SOAP request (header and body), and SOAP response (header and body). From that traffic we learn useful information about the Web Service activity node. For example, we learn what is the User-Agent String being used, and we learn that IPA will send our private M3 user/password to a server on the Internet even if we didn’t specify it (be careful if you leave Configuration blank, that means Configuration main, and if you had set an M3 user/password for M3 Web Services). And we have the rest of the data to do the troubleshooting we may need. This will prove crucial for troubleshooting M3 Web Services.

Here is a screenshot for the Email activity node:

You can even decode JDBC traffic from the SQL Query activity node, including JDBC traffic from IPA to its database. For that, in Wireshark select Decode As > TDS.

You can also decrypt HTTPS traffic (encrypted) of internal servers for which you have the private keys, such as M3 Web Services. For that, you can follow my previous post on how to decrypt Smart Office HTTPS traffic. I haven’t applied it here yet as I don’t have the server’s private keys so I can’t show you if it works or not, but I’m confident it would work.

With Fiddler

Fiddler can also capture HTTP traffic from IPA/IPD but we have to tell the JVM to use a proxy. I’ve only tested this with IPD; I haven’t tested this with IPA yet, but I’m confident it would work.

Also, Fiddler only captures HTTP, it doesn’t capture JDBC/SMTP.

Also, Fiddler can intercept and decrypt HTTPS (encrypted) traffic.

To set a proxy for IPD, open the IPD ini files and add the following arguments for the JVM:


3.1 3.2

To decrypt HTTPS traffic you have to tell Fiddler to capture and decrypt HTTPS traffic, and you have to import Fiddler’s root certificate into the JVM used by IPD with the keytool:

3.3 3.4

And now you can intercept encrypted traffic from IPD as for example M3 Web Services in this screenshot:



After your troubleshooting, remember to remove the proxy arguments from the IPD ini files or IPD will break if you don’t have Fiddler running, and remember to remove the Fiddler DO_NOT_TRUST root certificate.


That was a brief illustration of how to intercept network traffic from Infor Process Automation and Infor Process Designer using Wireshark and Fiddler, and how to intercept and decrypt HTTPS traffic. This is very useful for me to troubleshoot the Web Run and Web Services activity nodes, specially for M3 Web Services.


That’s it! If you liked this, please follow this blog, leave your comments, and share around you.

Hello Google Glass from Infor Process Automation

As a continuation of my Google Glass project, my next step is to write Hello World on Google Glass using Infor Process Automation (IPA).

As a reminder of my project, I’m writing an application to show M3 picking lists on Google Glass using Event Analytics and Infor Process Automation to have rich interactive picking lists in Glass with a list of items to pick, quantities, stock locations, item image from Infor Document Archive, and walking directions on a warehouse plan.


From a software architecture point of view, we have the following tiers:

  • I’m wearing Glassware and they are connected to the Internet
  • Google’s servers periodically communicate with my Glass
  • My IPA server is located in a Local Area Network (LAN) at the office behind a firewall.

Timeline card

To keep the proof-of-concept simple, I use the Google Mirror API; that’s simpler than using Glass Development Kit (GDK). A sample HTTP Request to insert Hello World in a static card in my Glass timeline looks like this with the proper OAuth 2.0 token:

Authorization: Bearer ya29.HQABS3kFLP2b-BsOWMFyGUpUv4JPAhKeEnDbLcjDUAHREBK6mYYVAadIa68S6A
Content-Type: application/json
Content-Length: 29

{ "text": "Hello from IPA" }

Note: For the purposes of this proof-of-concept I bootstrapped the OAuth 2.0 token manually by copy/pasting it from another computer where I already had the Android Development Tools (ADT) and the Glass Java Quick Start Project.

The resulting timeline card looks like this where the black pixels are see-through pixels in Glass:

Process Automation

IPA can make HTTP Requests using the Web Run activity node. With WebRun, we can specify the following parts of an HTTP Request: scheme (HTTP/HTTPS), host, port number, method (GET/POST), path, query, Basic Authentication, HTTP Request Body, Content-Type, and HTTP Request Headers.

Here is my sample WebRun for Glass:

Problems and rescue

At first, I ran into the following problems:

  1. I didn’t know where to set the scheme (HTTP/HTTPS); the Web Root seemed to me like it was only used to set the host and port number.
  2. The User id and Password fields seem to support Basic Authentication only, not OAuth 2.0.
  3. I need to set the OAuth 2.0 token as a variable because it expires and must be renewed every hour, but the WebRun activity node doesn’t support variable substitution in the Authorization header (CTRL+SPACE and <!var1> are not supported).
  4. I didn’t see the Header string field at first because when the input field is empty it has no border which makes it hard to spot.
  5. The Header string occupies only one line of height so it seems to indicate that it only accepts one HTTP Request Header.
  6. The Content-Type field didn’t propose application/json in the drop down list, so I had to hack into the LPD file with Notepad and write it and XML-encode it manually.
  7. The WebRun failed to execute and returned an HTTP 400 error without additional information.
  8. We cannot set a proxy like Fiddler in the WebRun configuration to intercept the HTTP Request (header and body) and HTTP Response (header and body) which makes it hard to troubleshoot.
  9. The WorkUnit log only shows the HTTP Response body which is only a quarter useful.

I sent an email with the problems to James Jeyachandran (j…, the Product Manager for IPA at Infor Product Development whom I know from my previous work on Lawson ProcessFlow Integrator (PFI) and IPA. It has always been a pleasure to work with James for his availability and responsiveness. Once more he impressed me as he called me back within four minutes. He was interested in my Glass project, he addressed my questions, and to assist me he graciously made available Samar Upadhyay s…, one of the software engineers of IPA. After troubleshooting together, here are the respective answers to my problems:

  1. The scheme can be set in the Web Root (as shown in the screenshot above).
  2. The OAuth 2.0 token can be set in an Authorization header in the Header string (as shown in the screenshot above).
  3. Samar said he will add variable substitution to the Header string.
  4. Samar said he will make the Header string field wider.
  5. Samar said he will make the Header string field multi-line.
  6. Samar said there is a new version of IPA that adds application/json as a possible Content-type.
  7. Samar said that’s a known problem with Content-type application/json and there is a bug fix available to correct it. Meanwhile, James said I can add it as an additional Header string; for that I had to use Notepad again to add the two Header strings on two lines. Also, Samar said he will attempt to upgrade my server with the new version of IPA.
  8. Samar said he will look into adding an optional proxy configuration for host and port number like we can do in web browsers.
  9. Samar said he will look into adding an option to log the full HTTP Request and Response.

After that collaboration we had a working proof-of-concept within 20mn.


Here is the resulting WorkUnit log:

And here is the resulting vignette in my Glass:

Future work

The next step will be to get the OAuth 2.0 token automatically, and to display the M3 picking list onto Glass.


That was a proof-of-concept to write Hello World from Infor Process Automation onto Google Glass using the WebRun activity node to make an HTTP Request to the Mirror API.

That’s it!

I want to specially thank James Jeyachandran and Samar Upadhyay for their support and responsiveness, and for their enthusiasm with this project. They will be at Inforum 2014.

Like. Comment. Share. Subscribe. Enjoy.

Event Analytics for Infor Process Automation (IPA)

Today I will illustrate how to setup Event Analytics for Infor Process Automation (IPA). Event Analytics is an application that subscribes to Event Hub, that filters events based on conditions, and that takes actions. My goal is to single out specific Infor M3 events to trigger IPA flows with accuracy, for example to trigger a HelloWrrrld flow only when an M3 Item number ABC123 has changed from Status 10 to 20, specifically. This post is intended for readers already familiar with IPA and Event Hub, yet not too familiar with Event Analytics. For an introduction on Event Hub for IPA, I invite you to read my previous article.

About Event Analytics

Event Analytics is an application for the Infor Grid that subscribes to Event Hub. It uses a rules engine with business rules to single out specific events out of the million of events produced by M3, i.e. it will find the needle in the haystack, and it will carry out actions. It’ s fast and scalable and doesn’t affect M3 performance. It’s used for example to pass Business Object Documents (BODs) to Infor ION.

It uses the Production Rule System JBoss Drools, a “Business Logic integration Platform which provides a unified and integrated platform for Rules, Workflow and Event Processing”,  and it uses the Drools Rule language, a declarative domain-specific language that looks like when <condition> then <action> . Drools Rule files have the .drl extension. The Smart Rules Editor is an optional plugin for Eclipse based on Drools Expert to help produce Drools Rules for Event Analytics. For further reading on JBoss Drools and Drools Rules, I recommend the Rules Programming tutorial by Srinath Perera.


The Infor LifeCycle Manager (LCM) InfoCenter has detailed documentation about Event Analytics: facts, subscriptions, administration, example rules, etc. For that, go to your LCM InfoCenter at http://lcmserver:4062/ and then navigate to Documentation > Infor Smart Office Infocenter > Installation Guides > Infor ION Grid Extensions Installation and Administration Guide > Event Hub and Event Analytics Grid Extensions:

Event Analytics or Event Hub?

Why should we use Event Analytics to trigger IPA flows when we can use Event Hub alone? Well, if we used Event Hub alone to directly trigger IPA flows we could potentially get too many false positives. For instance, in my example above I want to trigger a flow only when the Item number ABC123 has changed from Status 10 to 20; I don’t want events for other Item numbers nor Statuses. Unwanted events would create too many unnecessary WorkUnits in IPA, and that would clog the server with noise in the database even if we used an if-then-else Branch activity node at the start of the flow to eventually cancel the execution downstream. The solution is to filter events upstream with Event Analytics.

Dual subscriber/publisher

Once a condition is met in a Drools Rule, a typical action for Event Analytics is to post a new event to Event Hub. Then, subscribers like IPA can subscribe to those events with Publisher:EventAnalytics instead of the traditional Publisher:M3. Thus, Event Analytics is dual subscriber and publisher. It took me a while to figure out the gymnastics in my head, eventually it became clear.

Here is an illustration:


The HelloWrrrld scenario

For illustration purposes in this article, the simple scenario will be to trigger a HelloWrrrld flow when an M3 Item number ABC123 has changed from Status 10 to 20. The baby steps will be:

First, I will create a Drools Rule that will subscribe to events where Publisher:M3, Document:MITMAS, and Operation:U, and with the conditions ITNO=ABC123, old STAT=10, and new STAT=20. If that condition is met, the Rule will carry out the action to post a new event MITMAS_ABC123_20.

Then, with Infor Process Designer (IPD), I will create and deploy a simple HelloWrrrld flow. The flow will receive as input variables all the data from the event. So I will add a simple activity node that will show the M3 fields <!CONO>, <!ITNO>, <!ITDS>, and <!STAT>.

Then, in IPA Rich Client Admin, I will create a new Event Hub Receiver with a subscription to EventAnalytics:MITMAS_ABC123_20 that will trigger the HelloWrrrld flow.

Then, I will do a test. I will go to MMS001 in Smart Office, I will prepare an Item ABC123 with Status 10, I will save it, and then I will change it to Status 20. I will also update other Items to produce additional events (noise). M3 will send all those events to Event Hub. Event Hub will pass those events to Event Analytics. Event Analytics will single out the event that matches the condition ITNO=ABC123, old STAT=10, new STAT=20, and it will post a new Event MITMAS_ABC123_20. Then, the Event Hub Receiver will receive that event and will trigger my HelloWrrrld flow with the data.

Finally, the resulting WorkUnit will contain all the variables of the event, the M3 fields, the old values, and the new values.

OK let’s do it.

Create a Drools Rule

First, let’s create the new Drools Rule in Event Analytics:

  1. Go to Infor LifeCycle Manager (LCM).
  2. Find EventAnalytics in your Grid (expand the tree or use the filter).
  3. Right-click > Manage Application.
  4. There will be one or more Sessions. We’ll use Session Default for now. Click Rules.
  5. There will be zero or more Drools Rule Language Files, active or not. Click Create.
  6. Enter a Resource Name, for example MITMAS_ABC123_20_Rule.
  7. The editor will generate a sample Drools Rule with subscription M3:MITMAS:U, and condition elementValues[“STAT”]=”20″. Good. We’ll keep that.
  8. Rename the rule MITMAS_20_Demo to MITMAS_ABC123_20_Demo.
  9. Add the condition elementValues[“ITNO”]=”ABC123″ .
  10. Add the condition elementOldValues[“STAT”]=”10″ .
  11. In the actions, rename the postEvent to MITMAS_ABC123_20.
  12. Delete the rules Start_Demo, Time_Demo, and Stop_Demo.
  13. Click Save.
  14. The result will look like this:
  15. Close the editor.
  16. Back in the list of Drools Rule Language File, select the checkbox next to your Rule to activate it.
  17. Click Reload to load your Rule.
  18. Verify in the list of Rules that your Rule is now there.

Create a HelloWrrrld flow

Then, with Infor Process Designer (IPD), let’s create and deploy the simple HelloWrrrld flow that will show the M3 fields <!CONO>, <!ITNO>, <!ITDS>, and <!STAT>.

It will look like this:

Create an Event Hub Receiver

Then, let’s create the new Event Hub Receiver in IPA Rich Client Admin:

  1. Go to IPA Rich Client Admin.
  2. Switch to the desired data area (development, test, production, etc.)
  3. Open Channels Administrator.
  4. Create a new Event Hub Receiver.
  5. Set the Subscription to EventAnalytics:MITMAS_ABC123_20.
  6. Select Process HelloWrrrld.
  7. Select Startup Type Automatic.
  8. Click Save.
  9. Select Actions > Activate.
  10. The status bar will show “Activate Completed”.

The result will look like this:

Test in Smart Office

Then, let’s do a test in Smart Office.

  1. Go to MMS001 in Smart Office.
  2. Create an Item ABC123 with Status 10, and save it.
  3. Change the Item to Status 20:
  4. Optionally, update other Items to produce additional events (noise).

Resulting WorkUnit

Finally, open the resulting WorkUnit in Rich Client Admin, switch to the Variables tab. It will show all the input variables of the event, the M3 fields, the old values, and the new values:

That’s it!

If you liked this post, please subscribe to this blog by clicking the Follow button below. And leave your comments in the section below. That will support and grow the community. Also, spread the word to your colleagues, customers, and partners. And if you have something to share, let me know and I will send you an author invite. And even better, create your own blog to grow the community even more.


Event Hub for Infor Process Automation (IPA)

Today I will illustrate how to setup Event Hub for Infor Process Automation (IPA). The goal is to receive M3 events in IPA in order to trigger approval flows, for example to trigger a User approval flow when a new User is created in M3, or to trigger a Purchase Order flow when a new Purchase Order is created in M3. This technique has been around for several years and replaces pretty much all the previous techniques to trigger flows.

This post is intended for readers already familiar with IPA, yet not too familiar with Event Hub.

About Event Hub

Event Hub is a publish-subscribe distributed messaging system for M3. It seems to use JBoss HornetQ, the “open source project to build a multi-protocol, embeddable, very high performance, clustered, asynchronous messaging system”, it seems to use JGroups, “a toolkit for reliable messaging [that] can be used to create clusters whose nodes can send messages to each other”, it seems to use Netty, “an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients”, and it seems to use Disruptor, a “High Performance Inter-Thread Messaging Library”, based on unzipping the Grid Archive file Infor\LifeCycle Manager\LCM-Server\products\eventhub-installer\components\eventhub-gar-2.0.16.gar.

M3 produces millions of events as part of its daily operation. For example: users open programs, they create new records and update existing ones, the database gets updated, etc. M3 is the Producer of events. The Documents can be M3 Programs (such as M3 Customer – CRS610) and M3 Tables (such as OCUSMA). The Operations on M3 Programs can be: Start, eXit, Fail, reQuest, and Response. The Operations on M3 Tables can be Create, Update, and Delete. When an event happens in M3, M3 sends that event to Event Hub. Then Event Hub distributes that event to any subscriber that is interested in that event, for example to M3 Enterprise-Collaborator (MeC) whom will exchange BODs and initiate EDI transactions, to Infor Enterprise Search (IES) whom will update the search engine’s indexes, to Infor Process Automation (IPA) whom will trigger flows, to Infor Customer Lifecycle Management (CLM) whom will synchronize M3 and CLM customer records, etc.

Here’s an illustration:

I like Event Hub because it’s a beautiful piece of engineering, and it’s based on modern, well documented, open source software.


The Infor LifeCycle Manager (LCM) InfoCenter has detailed documentation about Event Hub: overview, events, documents, operations, subscriptions, administration, etc. For that, go to your LCM InfoCenter at http://lcmserver:4062/ and then navigate to Documentation > Infor Smart Office Infocenter > Installation Guides > Infor ION Grid Extensions Installation and Administration Guide > Event Hub and Event Analytics Grid Extensions:

The HelloWorld scenario

The simple Hello World scenario I will illustrate in this post is the following: when the user closes M3 Program EUS001 I will trigger a HelloWorld flow. It’s as simple as that. Why not. It doesn’t have any value from a functional point of view, but it’s a great illustration from a technical point of view. Here are the baby steps:

First, I will go to the Event Hub Configuration in my Grid and determine what the host and port number are to subscribe to Event Hub.

Then, I will enter the host and port number in IPA Rich Client Admin to setup IPA as a subscriber of Event Hub. (Conversely, IPA can also be a publisher and publish events to Event Hub but I won’t cover that scenario here.)

Then, I will create a HelloWorld flow, and I will setup a subscription M3:EUS001:X that will trigger the flow. The flow will be a simple Start -> End flow with no intermediate activity nodes. No need for fluff.

Finally, I will do a complete test, I will: start Infor Smart Office, open and close EUS001, and analyze the resulting WorkUnit in IPA.

Event Hub Configuration

Let’s go to the Event Hub Configuration in the Grid and determine what the host and port number are to subscribe to Event Hub:

  1. Open Infor LifeCycle Manager (LCM)
  2. Expand the Grid (for example, Development, Test, Production)
  3. Expand the Products until you find EventHub (you can expand the tree, or use the filter)
  4. Right-click > Configure Application
  5. In the Bindings section, write down the Host:
  6. Select Edit Properties
  7. Expand Server
  8. Write down the Port number:

Setup IPA as a subscriber of Event Hub

Then, let’s enter the host and port number in IPA Rich Client Admin to setup IPA as a subscriber of Event Hub:

  1. Start the IPA Rich Client Admin
  2. Switch the data area (for example, dev, test, prod, etc.)
  3. Start Channels Administrator (either search for channel, either go to Start > Applications > Process Server Administrator > Administration)
  4. Create an Event Hub Channel (Actions > Create):
  5. Enter a Name, for example EventHub
  6. Enter a Description, for example EventHub
  7. Check the box External
  8. Enter the Host
  9. Enter the Port Number:
  10. Click Save, the status bar will say “Channel Created”
  11. Select Actions > Activate, the status bar will say “Activate Completed”

Create a flow, the subscription, and the trigger

Then, let’s create a HelloWorld flow and setup a subscription M3:EUS001:X that will trigger the flow.

  1. Create a new HelloWorld flow in Infor Process Designer (IPD), a simple Start -> End flow with no intermediate activity nodes will suffice (you can add other nodes if you want), and deploy it on the server with Process > Upload process:
  2. Back in the Event Hub Channel in IPA Rich Client Admin, switch to the tab Event Hub Channel Receivers and create a new Receiver:
  3. Enter a Receiver and Description, for example HelloWorld.
  4. Enter Subscription M3:EUS001:X.
  5. Select Process HelloWorld (the flow).
  6. Select Startup type Automatic.
  7. Click Save, the status bar will say “Pfi Receiver Created”:
  8. Select Actions > Activate, the status bar will “Activate Completed”.
  9. Close the Event Hub Receiver window.
  10. Close the Event Hub Channel Receivers window.
  11. You will be back in the Channels Administrator window. Make sure the Event Hub Channel EventHub is Active and the Event Hub Receiver HelloWorld is Active.
  12. You can close the Channels Administrator window.


Finally, let’s do a complete test: start Infor Smart Office, open and close EUS001, and analyze the resulting WorkUnit in IPA.

  1. Go to Infor Smart Office.
  2. Open EUS001 (mforms://eus001), and close it (F3):
  3. That will cause the event M3:EUS001:X to happen in M3, Event Hub will forward the event to IPA, and IPA will trigger the HelloWorld flow.
  4. Back in IPA Rich Client Admin, open the Work Units (Start > Applications > Process Server Administrator > Administration > Work Units)
  5. Find the latest WorkUnit for the HelloWorld Process:
  6. Open it, and switch to the WorkUnit Variables, it will show all the keys/values for the event:

That’s it! We setup IPA as a subscriber of Event Hub, we created a receiver to subscribe to a specific event and trigger our flow, we did a test and caused the event to happen, and we analyzed the resulting WorkUnit. That illustrates how to setup Event Hub for IPA to receive M3 events in order to trigger a flow.

Next time I will show you how to setup Event Analytics for IPA and how to setup Drools Rules to filter events with conditions.

If you liked this, please subscribe to this blog by clicking the Follow button, and let us know your comments in the section below. You can also become an author and share your ideas (let me know and I’ll send you an author invite).