Wednesday, 16 November 2022

Loop over HL7 OBX fields and add the results to a database

I needed to loop over OBX segments in an HL7 message, then extract the values and write them to a database.

There are several ways of doing this, such as calling a sub-workflow, but I wanted a single-step process, so instead I just created the c# code in a Code Activity.  It's pretty straightforward.  HL7 Soup has a great API for working with HL7, and I use both Looping over segments as well as the simple to use GetValueAtPath.  API details can be found here.

Note that you can also turn this into a reusable activity following these steps.

//Bring in the assemblies that we need that are not included by default.
#r "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.1\System.Data.dll"

string connectionString = @"Server=xps17\sqlexpress;Database=HL7 Soup;User Id=HL7 Soup;Password=xxx;";
//Get the message template
IHL7Message message = (IHL7Message)activityInstance.Message; //Use IHL7Message for HL7 Messages and IMessage for other message types

using (System.Data.SqlClient.SqlConnection connection = new System.Data.SqlClient.SqlConnection(connectionString))
    //get other values not in the loop
    string patientName = message.GetValueAtPath("PID-5.2");
    //Get all OBX segments and loop over them
    IHL7Segments allSegments = message.GetSegments("OBX");
    foreach (IHL7Segment segment in allSegments)
        //update your database
        using (System.Data.SqlClient.SqlCommand command = connection.CreateCommand())
            string obxvalue2 = segment.GetField(2).Text; 
            string obxvalue5 = segment.GetField(5).GetComponent(1).Text;
            command.CommandText =$"Insert into MyTable (fieldname, fieldname2,fieldname3) values ('{patientName}','{obxvalue2}','{obxvalue5}')";

Wednesday, 21 September 2022

HL7 Soup Licensing Proxy error

I was attempting to license HL7 Soup and Integration Host on a hospital network, but I was getting an error preventing the license number from activating.

The problem was that the calls went through a proxy server.

The solution was to open the .config file for each app and uncomment the section that tells the proxy server to use the default credentials.


    <defaultProxy useDefaultCredentials="true">



This isn't credentials for calling the server, just the proxy server.

Monday, 22 August 2022

Integration Host HTTP sender as code

 The HTTP Sender in HL7 Soup's Integration Host is simple to use, but doesn't expose every possible feature of HTTP messaging.  I had to retrieve response headers, and these are not provided back in the UI.

Fortunately it uses c# in the code activity, so I was able to add the following code to save the day.

 //The following code is just a indication for getting started for an Activity. Edit or delete as you wish. Use the variable workflowInstance and activityInstance to access the running states of the workflow.

using System.Net;
using System.IO;

Encoding encoding = Encoding.UTF8;
using (WebClient client = new WebClient())
    client.UseDefaultCredentials = true;
    //Add all the headers that you want.
    // client.Headers.Add("yourHeaderName", workflowInstance.GetVariable("yourVariableName"));
    byte[] data = null;
    //Payload for posts if you need it.
    //var payload = "";
    //if (posting the message)
    //   payload =activityInstance.Message.Text;
    //    if (payload != null)
    //     {
    //        data = encoding.GetBytes(payload);
    //    }
    //     else
    //     {
    //         data = new byte[] { };
    //     }
    // }
    client.Credentials = new NetworkCredential("","");
    //Get the method as a string.
    string method = "GET";
    string url = HTTP://";
    //Call HTTP Service
    string result = "";
    if (method == "GET")
        //Get cannot pass a payload
        using (Stream stream = client.OpenRead(url))
                 using (var streamReader = new StreamReader(stream))
                    result = streamReader.ReadToEnd();
        //Post, Put and Delete pass a payload.
        var bytes = client.UploadData(url, method, data);
        result = encoding.GetString(bytes);
    if ( client.ResponseHeaders!=null)
        foreach (var responseHeader in client.ResponseHeaders)
            //process your response headers
            workflowInstance.SetVariable("MyVariable", responseHeader.ToString());

Sunday, 8 May 2022

Processing HL7 in the Cloud

While Integration Host has long been my preferred program for processing HL7 messages I've only really used it in local settings. Being able to handle workflows in the cloud was something I've wanted to do for a while now so you can imagine my delight when I saw the announcement on their website that their program was now available as a Docker container and that they'd already published a tutorial on getting it up and running on Azure as a container instance. 

 It's stupidly easy to get going and the Azure container instance pulls directly from their Dockerhub repo so there's no mucking around with downloading and uploading files. All in all, I can see this being a popular way to use Integration Host going forward.

Tuesday, 22 February 2022

Change HL7 Soup Senders or Receivers to a text Encoding that is not listed

 Not all text Encodings are listed in the HL7 Soup UI.  It makes it too noisy for most users, so only the common ones are there. However, you can change it to any installed encoding via the following steps.

  1. Create your sender. Set the Encoding to 8859-1 and save it.
  2. Close HL7 Soup
  3. Load the file in notepad C:\ProgramData\Popokey\HL7Soup\Settings\1\FunctionSettings.json
  4. Search in the file for the name of your sender.
  5. Change the Encoding property to your Encoding. Google "C# encodings" if you want to find the official encoding name.
  6. Save the file
  7. Reopen HL7 Soup.

Now, if you send with that sender, it will use your Encoding.

Monday, 13 December 2021

Sending Client Certificates with an HTTP Sender in Azure

If you are running inside an Azure App Service and you need to send a client certificate with you message, you'll need to follow these steps. 

             1. To configure the location on the key vault in the config "KeyVault:VaultUri".  Set it with the URL of your Azure Vault

             2. Another app setting, set "WEBSITE_LOAD_USER_PROFILE" with the value of "1".  Without this you will get the error "The system cannot find the file specified"

             3. Add a certificate with a private key in the Azure vault.  You can generate one in the azure vault.

             4. Under the App Service settings/Identity/System Assigned, turn status to ON.  Copy Object ID

             5. In the Vault / Access Policies, Add Access Policy.  

             6. Add Secret Permissions (Get)

             7. Add Certificate Permissions (Get, List)

             8. Set the Principle to the App Service using the object ID you got at step 4.

             8.1 Click "Add", and then also click "Save".  "Add" doesn't save even though the window closes, and this caused me much frustration.

             9. In the workflow, configure the http sender to use the vaults name of the certificate as the thumbprint.

             10. This was a very helpfull page that enabled me to work all this out


Note:  Integration Host stores the certificates once they have been acquired in memory.  It costs money and performance to keep pulling the certificate from the vault.  If you update the certificate, don't forget to restart the app.

Monday, 6 December 2021

Create a self-signed Client Certificate for Mutual SSL authentication

Here are the instructions for creating a self-signed Client Certificate for Mutual SSL authentication.  These can be used to client authentication in HL7 Soup, Integration Host, and their deployments to AWS and AZURE.

  • Install Open SSL.  I got it from here: It requires a $10 paypal donation.
  • Run Win64 OpenSSL Command Prompt from your start menu.
  • CD to the directory you will create your certificate
  • Execute the following commands.  You will want to run them one at a time, and they will ask you for details about your business.  Fill it all out:

openssl ecparam -name prime256v1 -genkey -noout -out client1.key

openssl req -new -sha256 -key client1.key -out client1.csr

openssl x509 -signkey client1.key -req -in client1.csr -out client1.crt -days 1000 -sha256

openssl pkcs12 -export -out client1.pfx -inkey client1.key -in client1.crt 

  • Double-Click the PFX to install it into your user certificates.

Very handy😊


The Azure Certificate Vault also allows you to generate a certificate that has everything you need. It was very easy to do.  You can then export it as a PFX.