What Response From does is control which responses from a call to an operation (or another component) are returned to the business service that called the router. By default the router won't return the response to the service, but setting Response From will enable responses to be returned from specific operations (or * for all operations). This is how you can control which response gets sent back to the service in a case when a router calls multiple operations. If multiple responses match the Response From setting, then only the first response will be returned to the service.

Response Target Config Names allows you to specify additional components (beyond the service that called the router) that should receive a copy of the response that came back from the operation. So you could send a copy of an ACK or other response to another operation for some reason.

All of this is probably moot, because I'm guessing your service doesn't need to receive a response.

In terms of the NULL responses, these shouldn't become orphans -- the fact that they appear in the message trace tells us that the production knows which session they belong to so they should get deleted along with the rest of the session.

Absolutely. You can do this with two assign actions:

First assign action moves the stream pointer to the end of the stream content:

The second assign action writes our new content to the end of the stream:

And an extra note of explanation: what we're actually doing with these assigns is calling a method in the request class, which returns a status code, and assigning that status code to a temporary variable. It would be best to check this status code to see if there was an error, but I haven't added that here to keep things simple.

This section in the docs discusses business processes and routers. You could use either one -- routing rules tend to be faster/easier to create.

Basically, your business process or routing rule would create a notification message and send it to a business operation. The process/router could construct the notification message directly or could call a data transformation that would create the notification message.

The operation would send the notification to an external system. One example would be to use an email operation to send the notification to an email server.

Our online learning portal also has some courses that cover these topics:

Integration Architecture
https://learning.intersystems.com/course/view.php?id=908

Building a Message Router
https://learning.intersystems.com/enrol/index.php?id=1745

Building BPL Business Processes
https://learning.intersystems.com/enrol/index.php?id=1290

Data Transformations Basics
https://learning.intersystems.com/course/view.php?id=1170

calling Method from ClassMethod

This is the problem. A Method needs to be called in the context of an instantiated object. A ClassMethod by definition isn't associated with an instantiated object.

If it's necessary to do it this way, your ClassMethod could use %New() to instantiate an object and then call the Method on that object:

set myObj = ##class(My.Object.Class).%New()
set tSC=myObj.myMethod()

But, it looks like you're working with a Business Service class. For that, it isn't enough to simply use %New(). You need to use Ens.Director::CreateBusinessService to instantiate the object before calling the Method.

https://docs.intersystems.com/irisforhealth20212/csp/docbook/DocBook.UI....

How about polling the global looking for updates? It would be lightweight to just check if the value of ^FSLOG has incremented since the last check:

set lastFSEntry = ^FSLOG

or use $order:

set lastFSEntry = $order(^FSLOG(""),-1)

As for timestamps, in my test environment all of the ^FSLOG entries seem to end with timestamps already:

^FSLOG(41)="DispatchRequest^HS.FHIRServer.Service^11062|Msg|  [1] -> DO  0|03/14/2022 01:57:19.398158PM"

Vivek,

The method for transforming HL7 to SDA can be found here. Note that this doc covers transforming HL7>SDA>C-CDA, so you'll only be interested in the first half of that:
https://docs.intersystems.com/irisforhealth20191/csp/docbook/DocBook.UI....

And the methods for transforming SDA to FHIR can be found here:
https://docs.intersystems.com/irisforhealth20191/csp/docbook/DocBook.UI....

-Marc

I created a simple inbound adapter and a simple business service that uses it, and the &sql() call succeeds for me. It would be good to check the event log and see if any additional error information got logged.

Class Example.InboundAdapter Extends Ens.InboundAdapter [ ProcedureBlock ]
{

Method OnTask() As %Status
{
        set suspendedCount=-1
        &sql(SELECT count(ID) into :suspendedCount FROM Ens.MessageHeader where TargetQueueName not like '_S%' and TargetQueueName not like 'ENS%' and Status='5')
        
        // log what we got back
        set ^ztest($now(),"SQLCODE") = SQLCODE
        set ^ztest($now(),"suspendedCount") = suspendedCount
        
        quit 1
}

}
Class Example.Service Extends Ens.BusinessService
{

/// The type of adapter used to communicate with external systems
Parameter ADAPTER = "Example.InboundAdapter";

}

Yep, RawContent is potentially truncated and isn't meant for accessing the full message.

You can use the OutputTo* methods to get the whole message. OutputToLibraryStream is going to be the best option because a stream object can be of unlimited size. OutputToString will work, but only for messages that are smaller than the maximum string size (around 3 megabytes, assuming you have long strings enabled in the Caché config. If not, then 32k).