Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

iris-lab

A local InterSystems IRIS for Health sandbox plus a one-hotkey round trip from Notepad++: edit a transform, hit the key, see the transformed message.

Built for learning IRIS interoperability coming from a Mirth/BridgeLink background.


Why this shape

The obvious reading of "a Notepad++ plugin that runs IRIS transforms" is a new plugin. It should not be. Two reasons:

  1. PipeHat already is the plugin. It owns HL7 loading, parsing, the message tree, and field-aware Compare Views. A second plugin would rebuild all of it to add one button.
  2. The hard part is not the editor, it is the execution engine. DTL only runs inside IRIS. Anything you build in Notepad++ is a client to an IRIS instance you still have to stand up. Stand up the instance first; the editor integration is then a four-line NppExec script.

So v1 is: Docker sandbox + a bun driver + NppExec. v2 folds the driver into PipeHat as a command so the result lands in the second view and Compare Views highlights every changed field automatically.


Setup

# Start Docker Desktop first, then:
cd C:\opencode\iris-lab
docker compose up -d          # ~1 GB pull the first time, a few minutes
bun setup.ts                  # one-time: enable interoperability on USER
bun xform.ts                  # the round trip

bun setup.ts must print ENSEMBLE-ENABLED=1 and HL7-CLASS=1. If it does not, nothing downstream will compile, because EnsLib.HL7.* is only mapped into interoperability-enabled namespaces.

Management Portal: http://localhost:52773/csp/sys/UtilHome.csp (_SYSTEM / SYS).

License: Community Edition is development-and-learning only. Fine for this. Not fine for anything client-facing.

Against a native install instead of the container

$env:IRIS_MODE     = "local"
$env:IRIS_INSTANCE = "<from `iris list`>"
$env:IRIS_NAMESPACE= "USER"
Get-Content lab\input.hl7 -Raw | bun xform.ts

Three things differ from the container, all of them discovered the hard way:

There is no iris session on Windows. That spelling is UNIX-only; iris.exe rejects session as an invalid parameter. The scriptable terminal is a separate executable, irissession.exe, in the instance's own bin directory. xform.ts finds it by reading the directory: line out of iris list. Override with $env:IRIS_SESSION_EXE if it picks wrong.

A native install asks for a password. The container has no web application and makes no auth decision, so this never comes up there. A piped session gets Access Denied on the first line unless it supplies credentials:

$env:IRIS_USER     = "<your iris username>"
$env:IRIS_PASSWORD = Read-Host "IRIS password"

Read-Host keeps it out of your shell history. Credentials go over stdin, not command-line arguments — arguments are visible to every other user on the box through the process list, which on a shared or work machine is not theoretical. Don't persist them into a script or a machine-level environment variable.

Windows PowerShell 5.1 will show a red NativeCommandError on success. Not a failure. xform.ts follows the UNIX split — the transformed message goes to stdout so it can be piped, and the OK Lab.Transform ... ms status goes to stderr so it never contaminates the message. PowerShell 5.1 wraps any stderr output from a native executable in an ErrorRecord and renders it red, regardless of exit code.

Check the thing that actually matters:

$LASTEXITCODE     # 0 means it worked

To silence the noise, at the cost of losing the timing line:

Get-Content lab\input.hl7 -Raw | bun xform.ts 2>$null

PowerShell 7 does not do this. Neither does cmd.

The namespace needs interoperability enabled. Check it once:

zn "USER"
write ##class(%EnsembleMgr).IsEnsembleNamespace($namespace)
write ##class(%Dictionary.CompiledClass).%ExistsId("EnsLib.HL7.Message")

Both must print 1. If the first is 0: do ##class(%EnsembleMgr).EnableNamespace($namespace,1) — but only on an instance that is yours. It modifies the namespace, and change control on a shared dev engine belongs to someone else.


The loop

File What it is
lab/input.hl7 The sample message. Paste any HL7 v2 here.
lab/Transform.cls The file you edit. Your DTL. Must stay named Lab.Transform.
lab/output.hl7 The result. Overwritten every run.
src/Lab.Runner.cls The harness. Recompiles your transform on every run.

Errors land in lab/output.hl7 prefixed with ###, on purpose — you should see the compile error in the editor, not go digging through container logs.

The contract

xform.ts is a UNIX filter and nothing more:

stdin   <- raw HL7
stdout  -> transformed HL7
stderr  -> diagnostics (compile errors, timings)
exit 0  =  success, non-zero = failure

Nothing in it knows about Notepad++. Run it from a shell, a test script, CI, or any editor that can spawn a process:

Get-Content lab\input.hl7 -Raw | bun xform.ts

Notepad++ wiring

PipeHat's External Transform Provider speaks exactly that contract. Add this to PipeHat.providers in the Notepad++ plugin config dir:

iris.command = bun.exe C:\opencode\iris-lab\xform.ts
iris.workdir = C:\opencode\iris-lab
iris.timeout = 20000
iris.desc    = InterSystems IRIS DTL

Then, with a message open and a second view showing:

  • Ctrl+Alt+Shift+X — pick the provider
  • Ctrl+Alt+Shift+A — run it again

The result lands in the other view and PipeHat diffs it field by field automatically. PipeHat never learns the word "InterSystems"; it just runs a command. Any other engine you wrap the same way is another line in that file.


Coming from Mirth

Mirth / BridgeLink IRIS Note
Channel Production The container for everything
Source connector Business Service EnsLib.HL7.Service.TCPService for MLLP
Destination connector Business Operation EnsLib.HL7.Operation.TCPOperation
Filter + Router Business Process, usually a Routing Rule Rules are their own editor
Transformer step (JavaScript) DTL XML, drawn as a graphical mapper
msg['PID']['PID.5']['PID.5.1'] source.{PID:5.1} Same idea, different punctuation
channelMap / globalMap Production settings, Ens.Util.* No direct equivalent to channelMap
JavaScript escape hatch <code> block, ObjectScript Same role, different language
Message Browser Message Viewer / Visual Trace Visual Trace is genuinely better
Channel deploy Production start/update

The one that bites: MSH field numbering. In EnsLib.HL7, MSH:1 is the field separator, so MSH:9 is the message type and MSH:10 the control ID — the schema numbering, not the raw-pipe offset. PipeHat already honors this, so your instincts transfer.


Learning path

  1. Break it on purpose. Change {PID:5.1} to {PID:99.1} and run. Read the error. Do it again with a bad XML tag. Learn what each failure looks like now, while the loop is two seconds long.
  2. Work the DTL vocabulary<assign>, <if>, <foreach>, <subtransform>, <code>. The sample uses the first four.
  3. Open the same class in the Management Portal (Interoperability > Build > Data Transformations). Same file, graphical view. Edit it there, watch the XML change here. That connection is the thing that makes DTL click.
  4. Then leave the sandbox and build an actual production: TCP service, routing rule, TCP operation. Point PipeHat's MLLP sender at it — you already have the test harness.
  5. ObjectScript proper comes after DTL, not before. You will have absorbed half of it from <code> blocks by then.

Reference: Developing DTL Transformations · DTL for HL7 · EnsLib.HL7.Message class ref


Status

Scaffolded, not yet run — the Docker daemon was stopped when this was built. The ObjectScript in src/Lab.Runner.cls is written against the documented APIs but has not been compiled. Expect one or two fixups on first run, most likely in OutputToLibraryStream or ResolveSchemaTypeToDocType argument order. Debug with:

docker exec -it iris-lab iris session IRIS

then zn "USER" and call the pieces by hand.

No PHI in lab/. Ever.

About

InterSystems IRIS DTL playground: six worked ObjectScript transformation recipes plus a harness that round-trips an HL7 message through a containerised IRIS instance.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages