Call M3 API from MEC process

I had a requirement for one of my customers to call M3 API in Infor M3 Enterprise Collaborator (MEC) specifically from a custom process – not from a mapping – and I realized MEC does not have any built-in process for that, so I reverse engineered MEC again, and here is what I found.

Let’s see what MEC has to call M3 API from a process; I am using MEC version 11.4.1.

Processes

The Partner Admin has the following built-in processes:
3_

According to their Java source code, none of these processes calls M3 API, at least not that allow the user to call any M3 API arbitrarily; that does not meet my requirement.

API reference holders

There is a list of API reference holders in Partner Admin > Manage > Communication > M3 API:
1

They are used by the mappings in the XML Transform processes to select the M3 API server at run time:
9

I can get these properties with the following code with ec-core-11.4.1.0.0.jar:

import com.lawson.ec.server.m3api.APIRef;
import com.lawson.ec.server.m3api.APIReferenceHolder;

APIReferenceHolder instance = APIReferenceHolder.getInstance();
List<APIRef> apiRefs = instance.getAPIRefs();
for (APIRef r: apiRefs) {
    String id = r.getId();
    String hostName = r.getHostName();
    String portNumber = r.getPortNumber();
    String username = r.getUsername();
    String password_ = r.getPassword();
    String encodingIANA = r.getEncodingIANA();
    boolean proxyUsage = r.isProxyUsage();
    String refName = r.getRefName();
    List<String> agreements = r.getAgreements();
}

Good.

Note: APIReferenceHolder will run an SQL to table PR_Basic_Property in the MEC database with PR_Basic_Group_Type.Type=’APIRef’:
1_

MEC Mapper

The MEC Mapper (a.k.a. ION Mapper) can call M3 API, and there are settings for design time:
5____ 8__

But I am not interested in the Mapper for my requirement, so I will skip this.

Properties *

The MEC server has properties about M3 API in the groups APIMapper and MvxAPI:
6_

I can get these values with the technique of my previous post:

import java.util.Properties;
import com.lawson.ec.gridui.PropertiesSourceFactory;

Properties props = PropertiesSourceFactory.getInstance().getProperties();
// APIMapper
String name = props.getProperty("APIMapper.mi.name");
String host = props.getProperty("APIMapper.mi.host");
String port = props.getProperty("APIMapper.mi.port");
String user = props.getProperty("APIMapper.mi.user");
String password = props.getProperty("APIMapper.mi.password");
// MvxAPI
String enabled = props.getProperty("MvxAPI.Pool.Enabled");
String max = props.getProperty("MvxAPI.Pool.Connection.Max");
String expires = props.getProperty("MvxAPI.Pool.Connection.Expires");
String timeout = props.getProperty("MvxAPI.Pool.Connection.Connect.TimeOut");

Good. I will use APIMapper.

Connection pool

There is also a connection pool, which is recommended for repeated calls, but I have not yet looked into it as it appears to be used only by the Mapper:
Pool

I found this code in com.intentia.ec.mapper.BasicXMLMapper:

import com.intentia.ec.mapper.APIPool;
import com.lawson.ec.mapper.APIPoolInfo;
APIPool apiPool = APIPool.getInstance();
MetaAPI.getAPI(manifest, apiEncoding);
apiPool.getAPI(programName, host, port, user, password, isProxy, manifest, encoding, CONO, DIVI);
List<APIPoolInfo> list = apiPool.getAPIPoolInfo();

For future work.

MvxSockJ *

There is the good old M3 API Java library MvxSockJ-6.1.jar in the MEC server library folder:
7

Refer to the M3 API Toolkit documentation for its complete usage. Here is the minimalist version:

import MvxAPI.MvxSockJ;

MvxSockJ s = new MvxSockJ();
s.mvxConnect(host, port, user, password, "CRS610MI", CONO);
s.mvxSetField("CUNO", "ACME");
s.mvxAccess("GetBasicData");
s.mvxGetField("CUNM")
s.mvxClose();

Good. I will use this.

Remember to check for nulls and return codes.

EBZSocket et al.

There are plenty of other Java classes in MEC that are related to M3 API, they lead to EBZSocket, but they seem to be used mostly by the mapper, and they require knowledge of the M3 API metadata. I have not looked more into it. Here is a screenshot of the dependency graph from JArchitect:
JArchitect__

Here is some code I found, to be tested:

import com.intentia.ec.mapper.APICaller;

//APICaller ac = new APICaller(poolKey, strUUID, apiEncoding);
APICaller ac = new APICaller(pgm, host, port, user, password, strUUID, apiEncoding, forcedProxy, company, division);
int connectionTimeout = 10000;
int readTimeout = 10000;
ac.initMISock(connectionTimeout, readTimeout);
int startPos = 0;
int maxLength = 28;
String data = "GetBasicData 106AAACRBE01";
ac.setRecord(startPos, maxLength, data);
ac.callMI();

Or:

import com.intentia.ec.mapper.EBZSocket;

EBZSocket sock = new EBZSocket(strUUID, host, Integer.parseInt(port), "EBZSocket", apiEncoding);
String logonStr = "";
sock.mvxLogOn(logonStr, user, password, library, pgm, connectionTimeout, readTimeout, forceProxy);
sock.mvxSend(char[] apiData, int dataLength)
sock.mvxClose();

For future work too.

Conclusion

There does not seem to be a built-in solution to call any M3 API in a process in MEC. However, we can get the existing server properties – either from the API reference holders, either from the property group APIMapper – and use the good old MvxAPI.MvxSockJ to call the M3 API. Now you can add that to your custom process. With some more work, we could perhaps also use the connection pool, and explore more of the remaining Java classes.

I highlighted my favorite with an asterisk.

That’s it!

Thanks for reading. If you liked this, please consider subscribing, give a like, leave a comment, share around you, and help us write the next post.

Published by

thibaudatwork

ex- M3 Technical Consultant

3 thoughts on “Call M3 API from MEC process”

Leave a comment