Friday, December 19, 2008

Getting Started with Mirth (Part 2)

December 19, 2008 Posted by Jason , , 7 comments
This is the second post in a 2 part series. The first post is available here
To continue with our Mirth messaging channel, lets first describe the setup of the web service which will be called by our Mirth channel. This is somewhat of a contrived example will little attention to coding standards, referential integrity or database normalization…but we wont let that stop us!
Firstly, I’ve created a second database named demodetailsdb. Ideally these databases would be on disparate servers (otherwise there would be little need for such an elaborate messaging system) but for our purposes I will run both off the same (localhost) box. In the demodetailsdb I have created a single user_details table.
Loading ....
I have created a simple .NET Web Service to which we will pass the information gathered from the database in our previous post, perform some simple lookups in the user_details table based on the input data and return relevant information. The service contains one webmethod named GetUserData which does exactly as the name suggests – it takes returns user information based on the input parameters. Below is the ASMX.vb file:
Loading ....
The ASMX.VB file calls a class named dummyClass used to perform the actual database connection and call the GetUserInfo stored procedure.
Loading ....

All returned information is passed in the form of a dummyUserClass object which returns the DOB, SSN and address of the input user. The dummyUserClass code looks as follows:
Loading ....

Now that we have the web service and database set up the way we want them (the tables aren’t yet populated – i’ll leave that up to you…) we can move on to the destination tab of the Mirth we previously created. By default you’ll have a placeholder destination created for you. image

We want a SOAP connector type, so choose SOAP from the connector type dropdownlist. You’ll notice that the screen refreshes with controls specific to our new connector type. Here’s where things start to get cool…There are a number of ways to create your soap envelope. By far the most simple is entering the path of your WSDL definition file. Doing so and clicking Get Methods results in the method dropdown being populated with all of the web methods defined in the WSDL file – on selection of a method the SOAP envelope is automatically generated (and is editable) and a tree is created allowing parameters to be passed to the method with next to no work on the developer’s part.

For demonstrative purposes we’ll create a couple of transformers and filters on the destination and we’ll be ready to talk to our web service. First of all the filter. One of the fields we pulled from the database was created date. This may correspond to an employees start date or entry into payroll. In our case we don’t want to process any users whose created date is in the future. There are two types of filters: 1. Rule based filters 2. Javascript filters. The first are great for smaller quicker tasks, the second when you need more functionality.

We use some simple Javascript to check that today’s date is greater than or equal to the created_date field. If so we return true to indicate that we accept the record, otherwise false to reject the record…simple! (note: in order to access the inbound message i had to enter the expected xml - the output template from the source - into the message template textbox. I remember this being automatically generated and am using 1.8.0 RC3 right now, so you might not need to take this step.)

The functionality contained in the following transformers can be achieved in a number of different ways – it is included here for demonstrative purposes. Simply, we will define channel level variables for the fields we wish to pass to our web service. For instance, dragging the value node from the id field into the top-left pane creates an id mapping. Doing the same for first_name creates another mapping and so forth…

Returning to our SOAP sender (exiting the transformer screen…) you will now notice the variables that we mapped in the Destination Mappings list. From here it is a simple matter of dragging the relevant variable from this list into the Value field (highlighted in red below) of the corresponding variable in the SOAP web method signature. For the easily frustrated: 1) Make sure to click in the value field to give the field focusing before dragging and dropping 2) After dragging the variable into the value field hit return, otherwise the assignment wont hold.

Once all of the relevant variables have been mapped and assigned, your SOAP envelope (bottom-most textbox) should look something like this:
Loading ....
In terms of calling the web service, we are done…pretty simple, right? At this point you can save the changes to your channel.

The final piece of the puzzle is handling the web service response. For the sake of this post lets take the returned data and log it in a wsvc_responses table in the demodb database that we created for the first post. I defined the table as follows:
Loading ....

Back in Mirth create a second channel named WSVC Response Handler. Again, the data type will be XML and you can enter a description of your choosing. Under the summary tab make sure to uncheck Strip namespace from messages. If you leave this checked then the channel will not know how to handle the SOAP namespace and will inevitable error out.

Under the source tab choose Channel Reader. The output of our web service sender channel will become the input for this channel, so there is no need to specify any other data connections. In the source tab create a transformer and paste the SOAP you expect to receive from your web service in the Inbound Message Template field. This information will be available through the web service API, or in the case .NET web services, the ASMX page itself:

The resulting Inbound Message Template Tree will look like this:

Repeating one of our steps above, we want to create variable mappings for the fields of import. In this case there is a gotcha: Mirth doesn’t handle SOAP in the most predictable of fashions (specifically where namespaces are concerned) so it is better to use relative rather than absolute paths where variable assignments are concerned.

Once you have defined mappings for all of the fields of interest you can finish off your connector by modifying the destination of the channel to point to your database and insert the data into the wsvc_responses table that we created earlier. It will look a little like this:

Save this channel and return to the original sender channel that we used to send the data to the web service to begin with. In order to hook the two channels up, choose your response handler channel from the Send Response To dropdownlist.

Save your channel and return to the Channels screen. Right-click anywhere on the screen and choose deploy all.

After deploying you will be routed back to the dashboard where you can monitor your channels. You’ll notice that we’ve sent 5 records (there were 5 entries in the mytable table) from the sender channel and all 5 were received and sent (to the database) by the response handler channel. One record was filtered by the sender channel and there were no errors.
Double clicking on either channel name in this list allows further drilldown. Not only can we view our data for each user at each step (source/destination) of the transformer but we can also view the raw/transformed/encoded message and any variable mappings and errors encountered. Lets look at the filtered record. Double clicking on the sender channel we can see one record with the status ‘filtered’. This record was for the user Tom Smith. His created date is January of 2009 – greater than today’s date, therefore falling into our filter criteria.
The ability to drill down into the information is key to debugging. Below you’ll see the SOAP response for the user Mark Jones. We can see exactly what information was sent back from our web service and also what variable mappings were made.
Finally, looking in our wsvc_responses table we can see that all of our records have been processed and the web service responses logged to the database:
To summarize, we’ve taken data from a SQL Server database, packaged it up in a SOAP envelope, sent it to a .NET web service, awaited response on an asynchronous channel and logged the parsed response into another database. Moreover, we have the ability to monitor our Channels and delve deep into the details should the needs arise. Pretty sweet for 20 minutes work!


Marshall said...


I am just starting out using Mirth, as of last week, on my new job, and I have got to say this.

You have saved me about a whole week's worth of learning. Your two posts on Mirth have saved me a lot of questions to my coworkers about how this app works.

Thank you so much for putting your knowledge and experience into this post. You covered everything I needed - web services (sending and receiving), db writing, and inter-channel communicating.

One question: are you able to share any info on how you learned the syntax for the Web Service Receiver's Source Transformer?

I haven't been able to find any documentation on this.

jirwin said...

Thank you for the kind feedback.

With respect to the msg..*::['MyNode'].toString() syntax there is nothing crazy going on. I'm using XPath in Javascript to find all instances of the MyNode node and returning the value as a string. In my case I was guaranteed that only one such node would exist, but this can backfire if multiple similarly named nodes exist.

There is an excellent XPath reference on the w3 website that should explain the syntax better than I can:

Anonymous said...

Thanks for enlightening us Mirth newbies. I came across this today and it appears that Part I is still missing in action and is a pretty important prereq to this page. Please let us know if you have a chance to redux.


jirwin said...

The first post is available and you can find it using the TOC. If you're looking for a quick link please see below:

Thanks for your feedback!

SkaRootz said...

Hi, after the first channel sends the xml response from the web service call to the second one, is there someway to get the response from the second channel in the first channel to send it as a response to the first channel caller?? It is messy... I know.

Jason Irwin said...

SkaRootz, can you please tell me what you are trying to achieve. I am having difficulty visualizing your issue...Thanks, Jason

Anonymous said...

Hi, i am new to mirth, just started exploring this app this week so excuse me for this rookie questions:
1. is there a way to use a mirth channel through another app?for example, imagine you add an app that needed some info from a server which communicates only in HL7. Is there a way to do this through mirth channels?

2. other question i have is about the ack messages sent by mirth. i want to be able to send the acks only after the processing. Because for all i've seen mirth only sends aa or ar never ee.

if you could answer this questions it would be of major help.