Tuesday, November 28, 2023

#997 - OIC - Integration with RabbitMQ on CloudAMQP


CloudAMQP provides managed RabbitMQ clusters on the cloud. It is quite popular, so it was only a matter of time before I got the question - How can I use OIC to integrate with RabbitMQ. Never one to dodge a challenge, I began by subscribing to the free version of RabbitMQ - Little Lemur.

Setting up the CloudAMQP account and RabbitMQ itself is very simple, I just needed to note the following details from the setup screens - the User, vHost and Password provided. I will need these later on when constructing the REST requests to RabbitMQ in Postman.

From the CloudAMQP homepage - I  click on the RabbitMQ Manager button to create my Queue - I provide a name - NiallCQueue - and just accept all the default settings.

A very simple task - my Queue is set up, now to the api docs to check out how to write to and read from the queue -

  Here is the link.

Next step is Postman, to try out the RabbitMQ apis - I begin with the most simple request - to retrieve the queue information -

I copy the relevant curl command from the RabbitMQ api docs and paste into Postman - 
Note that the first part of the url is user:password. You can get rid of this by setting up Basic Authorization with the same user/password in Postman.

Next request is to put a message on the queue -

Here I use Basic Auth, so no username/password in the url.

Let's look at the payload - 
routing_key - set to the name of the queue
payload - yes, the payload I want to write to the queue
payload_encoding - I left this as "string". 
From the docs - The payload_encoding key should be either "string" (in which case the payload will be taken to be the UTF-8 encoding of the payload field) or "base64" (in which case the payload field is taken to be base64 encoded).

properties - I left empty, to begin with.

The routed = true response tells me the message has been successfully sent to at least one queue.

Next api is the GET - 

Note the request payload - 

count - the max number of messages to retrieve from the queue.

encoding - set to auto

from the docs - encoding must be either "auto" (in which case the payload will be returned as a string if it is valid UTF-8, and base64 encoded otherwise), or "base64" (in which case the payload will always be base64 encoded).

ackmode - ack_requeue_false 

from the docs - ackmode determines whether the messages will be removed from the queue. If ackmode is ack_requeue_true or reject_requeue_true they will be requeued - if ackmode is ack_requeue_false or reject_requeue_false they will be removed.

All is working in Postman, so now on to OIC - 

Step 1 - Create the Connection

Here we use the OIC REST adapter -

Step 2 - Create a Scheduled Integration

Here is the configuration of the REST invoke - 

I use the request and response payloads from my Postman test as the request and response JSON samples.


The For-Each configuration - 

The Logger action just logs the payload - 

Now to testing the integration - for this I have put 6 messages in the queue -

I run the integration and check out the activity stream - 

I check out one of the log actions - 


Tuesday, November 7, 2023

#996 OIC Healthcare: MLLP Adapter Part II

Leading on from the previous post, let's now look at outbound, i.e. OIC sending HL7 messages to a target, in my case, HL7 Inspector

Th following connection will be used - note the port. This is what is configured in HL7 Inspector.

The use case here is very simple, I just send back the message received. Remember the patient admission integration from the previous post? In that integration, AA-ADT01-Processor, I converted the message stream received into an xml based version of the ADT01 message.

Now I will use the OIC Healthcare action to transform this canonical version of the message back to HL7 format and forward it to HL7 Inspector.

Here is that integration before I make the changes - 

I add a new Healthcare action, after the Logger, and configure as follows - 

The Target to be mapped is as follows - 

The Source is the xml representation of the HL7 message received - 


I map the relevant fields, then add the MLLP Invoke.

The final integration flow - 

I activate the integration and test by sending a new ADT01 message from HL7 Inspector. This message will trigger my router/dispatcher integration, which, in turn, will invoke AA-ADT01-Processor.

I check out the HL7 Inspector Receiver - 

You will notice some new field values in the above message, i.e. this is not a simple echo.

I put in these Sender values via the map - 

<0x0b><0x1c><0x0d>MSH|^~\&|OIC^AA-ADT01-Processor^Integration|Commiskey Healthcare Inc.^Commiskey Healthcare Inc.^Clinic for the disturbed|ADT1|GOOD HEALTH HOSPITAL|198808181126|SECURITY|ADT^A01^ADT_A01|MSG00001|P|2.8<0x0d> EVN|A01|200708181123<0x0d> PID|1||PATID1234 123456789^5|||||M<0x0d> NK1|1|NUCLEAR|SPO^SPOUSE||||NK^NEXT OF KIN<0x0d> PV1|1|I|2000||||004777^ATTEND^AARON<0x0d> <0x0d>

Tip for mapping - use the OIC mapper <copy-of> function at segment level to ease the mapping chore.

BTW. the following cmd is useful, if HL7 Inspector is not receiving messages - 
netstat -ano | find "2100"

Custom Schemas

The ADT01 data I used only leverages a couple of segments, so I could define a custom schema based on the standard ADT01 definition and delete the segments I don't require. This is what I did - 

The schema designer makes it very easy to delete unwanted segments or add new custom segments and elements.

Now I can use this schema when defining a new version of the ADT01 doc - 
First I create the doc based on the ADT01 version 2.8 and then edit it to use the custom schema based on ADT01 version 2.8. 

I could then use this document definition, when invoking the MLLP adapter. 

Summa, summarum, Healthcare is a compelling addition to the OIC toolkit, looking forward to helping our customers adopt it.

Monday, November 6, 2023

#995 - OIC Healthcare - MLLP adapter

The latest release of OIC includes an MLLP adapter. MLLP, aka Minimal Lower Layer Protocol, goes hand in hand with HL7 message processing. So this new adapter is very interesting from an OIC Healthcare perspective. This post shows you how this works and details a simple demo you can use. 

Firstly a BIG thanks to my colleague Steve Tindall for his support here.

The MLLP adapter leverages the connectivity agent, as you can see.

I will be invoking an OIC MLLP triggered integration via a 3rd party tool, HL7 Inspector.

First use case will be as follows - HL7 invokes the following integration - 

The only action is a Logger, which will log the incoming HL7 message.

It is configured as follows - 

Let's look at the inbound connection definition - 

The listener port can be set to a value of your choice. The actual "listening" is done by the connectivity agent, which then triggers the integration.

I have the following setup, in this simple scenario -

So HL7 Inspector sends the request to localhost:6200. 

Time to look at how this is setup in HL7 Inspector

I click on the Send icon and then, the setup icon -


HL7 Inspector ships with a sample HL7 message, which I can use for this sanity test.

I click the Send button - 
Check out response - note the acknowledgement.

Now to OIC Observability - 

That's the basics working. But how would you implement such? I have a client or clients sending me HL7 messages over MLLP. The message types can, of course, vary. For example, messages of type ADT (Admit/Discharge/Transfer) can include messages such as -
  • ADT01 - Patient Admit
  • ADT02- Patient Transfer
  • ADT03 - Patient Discharge
  • ADT04 - Patient Registration
I can adopt the following pattern - Dispatcher/Router integration receives the message. It checks an OIC lookup to retrieve the correct target( Processor) integration -

Let's implement this - first back to our Dispatcher/Router integration - 

I've added a couple of actions, as you can see. First step is the Assign - here I get a handle to the incoming HL7 message.

The next step is the HealthCare action - configured as follows - 

Note, I've selected all the HL7 documents I have created in the OIC instance.
These are available here - 

The Map to the Translate step is configured as follows - the target is set to the variable created in the Assign step.

The final activity, the Logger, outputs docType and version.

Let's this this with a valid 2.8 version of patient admission.

The activity stream output is as follows - 

Now a test with Patient Registration ADT^A04

I create 2 "processor" integrations, one for patient registration and one for patient admission.

These will have REST triggers and the input for both will be based on the output from the Translate step

The "processor" integration will then invoke Healthcare to convert the message reference to document - 

Here is the REST trigger definition of the "processor" integration for patient admission - 

The Healthcare action invoked is - Convert Message Reference to Document

The mapping is simple - the request stream is the source and the target is - 

I add a Logger as the final action, logging the patient. The final result - 

Now to the OIC Lookup, mentioned earlier - this will contain the routing rules  

The lookup will be used in the mapper, when the "dispatcher/router" invokes the "processor" integration - 

The "router" integration has been augmented as follows - 

The Mapper for the InvokeProcessor step is configured as follows -

Integration Code and Integration version are set via the Lookup.


All that's left is to add a new "processor" integration for ADT_04 - Patient Registration - same modus operandi.

Let's test with a new ADT_01 ( Admit Patient ) document from HL7 Inspector

Now to OIC Observability

and here's our patient - Adam Everyman -

That's how simple it is! Summa Summarum, this is a compelling new feature of OIC. Currently it is available via a feature flag, so ping me if you want to try this out now.