1. Sure, this will work find for just passing a file through to the target system.

2. Yes. You can use public/private key authentication as well.

3. Do you really want to put the files into the root directory? Normally, a FTP/SFTP server will default to the "home" directory for the account your operation logs in under. If you don't specify a path, that's where the data you're transferring will end up. If the account has its home directory set to the root directory and has permission to write there, your files will end up there.

4. You'll need to set the SSL configuration to the special value "!SFTP". There's no profile for it; it's just an indicator for the operation that you'll be using the SFTP protocol.

Hi Leon,

You're actually looking to create a batch, with a batch header for your file output.

To do this you'll need to define a batch class in your RecordMap, and in that class define your header (I'm assuming it's a fixed header, like field names).

You'll then want to use EnsLib.RecordMap.Operation.BatchFileOperation (or BatchFTPOperation) to deliver the batches. There are a few ways to trigger the batch rollover; a schedule, a record limit, or a Batch Rollover Request depending on your needs.

Hi Robert,

You can actually export the entire production in a single go through the Export button found in the Actions tab of the Production Settings. You would then use the "Manage / Deployment Changes" page on the target system to deploy the entire production to the destination namespace.

Other options include: Select "Files of type: DTL Document (*.dtl)" in Studio's Export option under the Tools menu (click "Add"), and select the entire list with shift-click (and similarly import through Studio), or use the ObjectScript class method  $System.OBJ.Export("*.dtl","/path/to/exportfile.xml") and corresponding import method $system.OBJ.Load("/path/to/importfile.xml") in the target environment.

The class methods work locally on your HealthConnect servers; if they're physically distinct hosts you'll need to copy the export file to the target server. Also you would run the export/load utilities in the namespace in which your production is located, of course ...

You could do it with an SQL query:

DELETE FROM Ens_Util.LookupTable WHERE TableName = '<name of table>'

You can create the query either via the Management Console (System Explorer | SQL | Execute Query tab) or from the SQL Shell

JEFF>d $system.SQL.Shell()
SQL Command Line Shell
----------------------------------------------------
 
The command prefix is currently set to: <<nothing>>.
Enter q to quit, ? for help.
JEFF>>delete from Ens_Util.LookupTable where TableName = 'facLookup'
1.      delete from Ens_Util.LookupTable where TableName = 'facLookup'
 
3 Rows Affected
statement prepare time(s)/globals/lines/disk: 0.1893s/11322/125529/16ms
          execute time(s)/globals/lines/disk: 0.0021s/29/408/0ms
                          cached query class: %sqlcq.JEFF.cls27
---------------------------------------------------------------------------

The Inactivity Timeout is a fixed value, and you can't easily reset it for different times of the day. You can, however, fairly easily control which times of the day alerts are actually sent, based on a variety of criteria:

The TimeIsBetween() and DayIsAWeekDay() functions in the screenshot above are relatively simple custom methods in a class that extends Ens.Rule.FunctionSet, which makes them selectable in the rule editor's function editor dropdown. I wrote them simply for the improved readability they provide for the routing rule.

In the rule above, alerts for the HIE_ADT_out interface are sent only between 7am and 7pm to the Integration team; on weekdays only the help desk is included. Any that fall outside of that timeframe are discarded.

Is that screen shot from the Ensemble Message Viewer? If yes, than what you're seeing is Ensemble's visualization of an empty field/component/subcomponent/repetition. The tilde (~) character is the repetition delimiter at the field level; InterSystems uses the "·" character as an indicator that the repetition was left empty. There's no actual character there to split on, but you can certainly iterate through repetitions within OBX:5 and build a new message segment for each.

The DTL would be something like this:

OK, it's quick and dirty and I'm probably doing something that will make the old-timers here laugh hysterically, but it works. The caveats are:

  • It only cares about word wrapping on the space character. Punctuation adjacent to non-space characters will stay with the adjacent characters.
  • It totally ignores things like \.br\ tags. they're just text as far as it's concerned.
  • It returns a $LIST, where each list element is a line of text from the source string, no longer than the width specified. You can iterate through it with $LISTNEXT or $LISTGET and populate your OBX segments, but you'll probably have to do that in a CODE rule.

So anyway ...

ClassMethod WordWrap(pTxt As %String, pWidth As %Integer) As %List
{
    If $LENGTH(pTxt) > pWidth
    {
        set tLine = ""
        Set tCnt = 0
        Set tWordList = $LFS(pTxt," ")
        Set tListLen  = $LISTLENGTH(tWordList)
        Set tWordPtr = 0
        Set tWordCur = ""
        While $LISTNEXT(tWordList,tWordPtr,tWordCur)
        {
            If $LENGTH(tLine_tWordCur) > pWidth
            {
                Set $LIST(tList,*+1) = $ZSTRIP(tLine,">W")
                Set tLine = tWordCur_" "
                Set tLastCnt = tCnt
            }
            Else
            {
                Set tLine = tLine_tWordCur_" "
            }
            Set tCnt = tCnt + 1
        }
    }
    Else
    {
 	Set tList = $LB(pTxt)
	Set (tLastCnt,tListLen) = 0
    }
    If tLastCnt < tListLen
    {
         Set $LIST(tList,*+1) = $LTS($LIST(tWordList,tLastCnt + 1,tListLen)," ")
    }
    Return tList
}

Have fun!

I'm reasonably confident this will fix the issue without any side effects ...

TIE> Set ^Ens.Queue("ClinicomMsgRouter",0,"count")=0
TIE> Set ^Ens.Queue("PathologyRouter",0,"count")=0
Question though ... do you have the pool size for these routers set higher than 1? I'm concerned about the number of job entries  under each queue. This could have an impact on FIFO, and may have something to do with the erroneous queue counts.

The "N" parameter always creates a new file. If you want to open a file (optionally creating it if it doesn't exist), use "E" instead,  and if you intend to Append to it, include the "A" parameter: open file:("EWA"):1. You don't need the "R" parameter unless you intend to read from it using the same device.

Depending on your Cache configuration, you may not even need the "E" parameter. The default behavior in my Windows installation is to create the file if it doesn't exist, with or without the "E" parameter (the documentation refers to "E" as  "UNIX-only", FYI).

Adding categories will  have no direct impact on message processing. As you noted, there may be a tiny incremental increase in overhead temporarily if you query for them, and you may see a slight delay in the drop-down list ... but only if  you're talking about multiple hundreds of them.

If the intent is to better document your interfaces, though, take a look at the Business Partner configuration. It's an often-overlooked option to keep details regarding the vendor, its contacts, and other information associated with each interface. This may help make the number of categories more manageable.

I haven't had the need to do this yet, but my guess is you're going to have to create a custom operation that modifies the received NAK via the OnReplyDocument() method. If the stack trace is really big, it may be stored as a Stream Object rather than a %String. And if that's the case, you're going to have to scan the Stream for the string you need, and replace the contents of the MSA:3 with that string.

I'd whip up an example for you but I'm headed out the door and will be OoO for the day. I'll check back tonight to see if anyone's beaten me to it :D

Eduard, are you referring to the Priority property of the Ens.MessageHeader class? That seems to be used exclusively for marking the message for Async vs. Synchronous delivery.

The need for message prioritization within a single message flow (one that would otherwise be FIFO) is valid and has been addressed in other integration products. One healthcare use case that I've encountered in multiple implementations is that the downstream system uses a session-oriented connection ("always on" MLLP) and receives both ADT and lab orders over the same connection. As the patient demographic data and "stat" lab orders should always be prioritized over routine order messages, a "high" priority value would be set for those messages during in-engine routing/transformation processing and would be a primary selection criteria for the process (eWay/Connection Point/Communication Client) to deliver it to the receiving system.

Given modern hardware and software, latency caused by the integration engine itself is rarely an issue. However, not all applications can receive messages as fast as integration engines can send them ...