Ensemble: How to embed a PDF file into an HL7 message
Tags: business, process, codesnippet, practice
Published: 2021-07-31 17:15:33

This article will describe and include an example of how to embed an external PDF file into an HL7 segment, specifically ADT_A01:2.3.1 OBX().  This can be useful when attempting to insert pictures or other external data into an HL7 message.  In this example, the name of the PDF file to be embedded is provided in the incoming HL7 message in OBX(1):ObservationValue field.

* * *

The basic stipulations for this example are as follows:![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tnqv9kxboj6mqalm095y.jpg)

  1. Accept a PDF file
  2. Accept an HL7 message
  3. Using the name of the PDF file, embed the PDF data into the HL7 message
  4. Output the message to file

 

   

* * *

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/abteuv5fp6al2p6msx1g.jpg)   ![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/spomfaf59oy2metuv6b2.jpg)

 

 

 

 

 

Using EnsLib.File.InboundAdapter, the example has two Business Services configured.  One to pull in PDF files using the built in EnsLib.File.PassthroughService.  The other to accept HL7 messages using the built in EnsLib.HL7.Service.FileService.

* * *

<p align="center">
  <strong><u><span style="font-size:18px;">PDF Processing</span></u></strong>
</p>

The order of these components is key as the PDF file needs to be pulled in first.  It is also important that the PDF Business Service has an Archive Path and Work Path set to the same directory path.  This saves a copy of the PDF locally which is then used later to embed the data into the HL7 message. 

In order for the Business Service to save the PDF file into this Archive/Work Path directory, SendRequestAsyn() needs to be called.  This method is called by default when sending between Ensemble/HealthShare components.

To accomplish this, the PDF Business Service is configured to send the PDF message to a custom Business Operation that accepts the message without performing any additional actions.

Note: The target component of the PDF Business Service is irrelevant for this example but it could be built to perform any additional actions with the PDF message.

* * *

<p align="center">
  <span style="font-size:18px;"><strong><u>HL7 Processing</u></strong></span>
</p>

The HL7 message from the Business Service is sent to a custom Business Process.  The Business Process calls a BPL that identifies and opens the correct PDF file and then calls a DTL to do the actual embedding of data into the HL7 message. 

<p align="center">
   
</p>

<p align="center">
  === <span style="font-size:18px;">BPL </span>===<strong></strong>
</p>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mlvlp6we1qk3os7kmj0y.jpg)

The BPL performs the following tasks:

  1. Extract the PDF filename from the HL7 message
  2. Query the Ens.StreamContainer table, looking for entries that match the extracted filename
  3. Call a DTL to do the embedding <ol style="list-style-type:lower-alpha;">
      <li>
        See “DTL” section of article
      </li>
    </ol>

  4. The BPL then sends the message downstream to a built in EnsLib.HL7.Operaiton.FileOperation Business Operation

 

<p align="center">
  === <span style="font-size:18px;">DTL </span>===
</p>

  1. Uses target.{OBX(*)} to count the number of OBX segments
  2. Increment the OBX count by one
  3. Adds the PDF data using StoreFieldStreamBase64() into a new OBX() segment <ol style="list-style-type:lower-alpha;">
      <li>
        See “DTL Code Action” for this code
      </li>
    </ol>

<p align="center">
   
</p>

<p align="center">
   
</p>

<p align="center">
   
</p>

<p align="center">
  === <span style="font-size:18px;">DTL Code Action</span> ===
</p>

> `//Get PDF stream object previously saved`
> 
> `   Set pdfStreamContainer = ##Class(Ens.StreamContainer).%OpenId(context.StreamContainerID)`
> 
> `   Try {`
> 
> `     Set pdfStreamObj = pdfStreamContainer.StreamGet()`
> 
> `   }`
> 
> `   Catch {`
> 
> `      $$$TRACE("Error opening stream object ID = "_context.StreamContainerID)`
> 
> `      Quit`
> 
> `   }`
> 
> ` //Set PDF stream object into new OBX:5 segment`
> 
> `   Set status = target.StoreFieldStreamBase64(pdfStreamObj,"OBX("_count_"):ObservationValue(1)")`
> 
> `   Set ^testglobal("status",$H) = status`

* * *

<p align="center">
  <span style="font-size:18px;"><strong><u>Sample Production</u></strong></span>
</p>

The following is a list of the files included in the attached sample.

  1. The initial HL7 message with only the PDF filename embedded into OBX(1)
  2. The sample PDF file
  3. A class export that includes the following: <ol style="list-style-type:lower-alpha;">
      <li>
        Production class
      </li>
      <li>
        Custom PDF Business Operation
      </li>
      <li>
        Routing Rule
      </li>
      <li>
        BPL
      </li>
      <li>
        DTL
      </li>
    </ol>

<p style="margin-left:1.0in;">
   
</p>

This example was built on Ensemble 2016.2.0 but has been tested on Ensemble 2015.1.2 with no compatibility issues.  The .zip file can be found here:

[https://community.intersystems.com/sites/default/files/post-associated-docs/sample\_hl7\_embedpdf\_production\_export.zip](https://community.intersystems.com/sites/default/files/post-associated-docs/sample_hl7_embedpdf_production_export.zip)