redeemefy
redeemefy

Reputation: 4849

Reading JS library from CDN within Mirth

I'm doing some testing around Mirth-Connect. I have a test channel that the datatypes are Raw for the source and one destination. The destination is not doing anything right now. In the source, the connector type is JavaScript Reader, and the code is doing the following...

var url = new java.net.URL('https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.fp.min.js');
var conn = url.openConnection();
conn.setRequestMethod('GET');

if(conn.getResponseCode() === 200) {
    var body = org.apache.commons.io.IOUtils.toString(conn.getInputStream(), 'UTF-8');
    logger.debug('CONTENT: ' + body);
    globalMap.put('_', body);
}

conn.disconnect();

// This code is in source but also tested in destination
logger.debug('FROM GLOBAL: ' + $('_')); // library was found
var arr = [1, 2, 3, 4];
var _ = $('_');
var newArr = _.chunk(arr, 2);

The error I'm getting is: TypeError: Cannot find function chunk in object.

The reason I want to do this is to build custom/internal libraries with unit test and serve them with an internal/company CDN and allow Mirth to consume them.

How can I make the library available to Mirth?

Upvotes: 3

Views: 994

Answers (2)

redeemefy
redeemefy

Reputation: 4849

Even though importing third party libraries could be an option, I was actually looking into this for our team to write our own custom functions, write unit-test for them, and lastly be able to pull that code inside Mirth. I was experimenting with lodash but it was not my end goal to use it, it is. My solution was to do a REST GET call with java in the global script. Your URL would be the GitHub raw URL of the code you want to pull in. Same code of my original question but like I said, the URL is the raw GitHub URL for the function I want to pull in.

Upvotes: 0

agermano
agermano

Reputation: 1729

Rhino actually has commonjs support, but mirth doesn't have it enabled by default. Here's how you can use it in your channel.

channel deploy script

with (JavaImporter(
    org.mozilla.javascript.Context,
    org.mozilla.javascript.commonjs.module.Require,
    org.mozilla.javascript.commonjs.module.provider.SoftCachingModuleScriptProvider,
    org.mozilla.javascript.commonjs.module.provider.UrlModuleSourceProvider,
    java.net.URI
)) {
var require = new Require(
    Context.getCurrentContext(),
    this,
    new SoftCachingModuleScriptProvider(new UrlModuleSourceProvider([
        // Search path. You can add multiple URIs to this array
        new URI('https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/')
    ],null)),
    null,
    null,
    true
);
} // end JavaImporter

var _ = require('lodash.min');
require('lodash.fp.min')(_); // convert lodash to fp

$gc('_', _);

Note: There's something funky with the cdnjs lodash fp packages that don't detect the environment correctly and force that weird two stage import. If you use https://cdn.jsdelivr.net/npm/[email protected]/ instead you only need to do var _ = require('fp'); and it loads everything in one step.

transformer

var _ = $gc('_');
logger.info(JSON.stringify(_.chunk(2)([1,2,3,4])));

Note: This is the correct way to use fp/chunk. In your OP you were calling with the standard chunk syntax.

Additional Commentary

I think it's probably ok to do it this way where you download the library once at deploy time and store it in the globalChannelMap, then retrieve it from the map where needed. It would probably also work to store the require object itself in the map if you wanted to call it elsewhere. It will cache and reuse the object created for future calls to the same resource.

I would not create new Require objects anywhere but the deploy script, or you will be redownloading the resource on every message (or every poll in the case of a Javascript Reader.)

Edit: I guess for an internal webhost, this could be desirable in a Javascript Reader if you intend for it to pick up changes immediately on the next poll without a redeploy, assuming you would be upgrading the library in place instead of incrementing a version

The benefit to using Code Templates, as Vibin suggested is that they get compiled directly into your channel at deploy time and there is no additional fetching step at runtime. Making the library available is as simple as assigning it to your channel.

Upvotes: 5

Related Questions