Hi,

Using out-of-the-box classes in the EnsLib.HL7 package, you can either completely ignore responses, either process them synchronously. More complex scenarios involving multiple responses (ack/nack) are supported (see Important HL7 Scenarios | Routing HL7 Version 2 Messages in Productions | InterSystems IRIS for Health 2023.1
), but I think they do not match your supplier requirements.

According to the standard, when sending multiple HL7 v2.x messages over MLLP/TCP, the sender (initiating module) must wait for a response before sending the next message. This is described in  "Health Level Seven Implementation Support Guide", Appendix C, section  C.6.4, item 5. : 

It is assumed that an initiating module may connect and perform more than one message transaction before disconnecting, but it may not have more than one outstanding message waiting for a response.  In other words, the initiating task must wait for the response to a given message before sending another message.

This vendor requirement to receive multiple messages before sending responses is thus non-standard. It would require the sender to keep track of sent messages with a pending response, handle asynchronous replies and retry errored messages.

While this is possible by writing custom adapter/operation extending the out-of-the-box classes in EnsLib.HL7 package, it would add a lot of complexity and has IMHO, little added value compared to the usual synchronous implementation.

Hi Evgeny,

If the operation class is using the mechanism in Ens.BusinessOperation to route incoming requests to the OnMessage() method, you can use the XData content to get a list of supported request (just as the Portal testing dialog does). If the operation class implements it’s own custom OnMessage(), there is no simple way to tell what request classes are supported. The XData is described in the documentation.

For responses, there is a RESPONSECLASSNAME parameter defined in classes extending Ens.Request. I believe this used by the BPL editor. This is somewhat limited however, since the operation can as well respond with any %RegisteredObject object and accept any kind of request (via OnMessage), e.g. any class extending %RegisteredObject if it is marked as "in process".

Anyways, as Robert C. points out, documenting what the operation intent is and it's interface, especially if they are not trivial, helps a lot and IMHO is best practice.

For a simple message transformation flow example, I would go for record map :

So you can focus on DTL and the whole flow can be done from the administration portal, look ma, no code  ;-)

You can call the Tranform(source,target) class method implemented by classes that extend Ens.DataTransform :

  • directly in objectscript code
  • through code generated for a BPL or router process ('send' action optionally uses a list of transformation classes that gets applied in sequence to the message before it is sent to target(s)). 
  • through code generated by a DTL ('subtransform')

If you need to process the entire file and no line filtering, I would go for using pass through file service (EnsLib.File.PassthroughService) to send an instance of stream container (Ens.StreamContainer) to either a message router (EnsLib.MsgRouter.RoutingEngine) or custom (BPL or code) process, and use a transform (class extending Ens.DataTransform) to transform the source stream container into a target stream container and send it to the file pass through operation (EnsLib.File.PassthroughOperation) for output.

I would use a custom process over message router if transform needs data source(s) (e.g. response from another process or operation) other than the input file. The transform can pick a suitable target stream class (Extending %Stream.Object) to hold in the Ens.StreamContainer depending on where you want to store the data (database vs file system,…)

HTH

Merry Christmas everyone !

My first time with AoC was a lot of fun, thank you for running this Objectscript ladder.

Congratulations to all participants.

My repository: https://github.com/theanor/idc-aoc-2022-theanor

And quality scanner status : https://community.objectscriptquality.com/dashboard?id=intersystems_iris_community%2Fidc-aoc-2022-theanor

Hi,

Assuming your question is about HL7 (or EDI) message serialization.

The DTL is meant for parsing and transforming the message into another one.
Serialization occurs when you output the message using the corresponding instance methods.

For an instance of the EnsLib.HL7.Message class, methods that output the message such as OutputToFile() are using instance properties to determine what separators to use : .Separators, .SegmentTerminator.

Also, business operations (extending EnsLib.HL7.Operation.Standard) expose a setting (Separators) that let you configure what separators to use.

To get an IRIS session integrated in VSCode terminal, you can add it to settings.json :

  "terminal.integrated.profiles.windows": {
        "IRIS Terminal": {
            "path": [
                "C:\\InterSystems\\IRISHealth\\bin\\irissession.exe"
            ],
            "args": ["<instance name>"],
            "icon": "terminal-cmd"
        }
    }

However, this terminal window will lack the niceties of the ISC Terminal application, such as command history.