Cameleer / Use cases / HL7 over MLLP
Healthcare integration
HL7 v2 over MLLP, FHIR, and an acknowledgement that means it
A hospital gateway receives ADT and lab messages from the HIS over MLLP, reads the patient id with a terser path, posts the message to the EHR and acknowledges after delivery. The route is Camel YAML; the runtime is one native binary that fits next to the other software on the gateway.
fhir componentThe tested route
From examples/edge/hl7-mllp-to-http.camel.yaml, which the test suite runs against an embedded EHR mock. ADT messages are forwarded; other types are acknowledged and dropped.
- route:
id: hl7-to-ehr
errorHandler:
defaultErrorHandler:
redeliveryPolicy:
maximumRedeliveries: 5
redeliveryDelay: "{{env:RETRY_DELAY_MS:2000}}"
from:
uri: "mllp://{{env:MLLP_HOST:0.0.0.0}}:{{env:MLLP_PORT:2575}}"
steps:
- filter:
simple: "${header.CamelMllpEventType} == 'ADT'"
steps:
- setHeader:
name: X-Patient-Id
hl7terser: "PID-3-1"
- setHeader:
name: X-Message-Control-Id
simple: "${header.CamelMllpMessageControlId}"
- setHeader:
name: Content-Type
constant: application/hl7-v2
- enrich:
uri: "{{env:EHR_URL:http://localhost:9000}}/hl7/v2?httpMethod=POST"
What happens on failure
- The EHR call is retried five times with a delay; the MLLP connection waits.
- If it still fails, the acknowledgement is
AE: the sending system keeps the message and resends it later. Nothing is lost on the gateway. - Set
CamelMllpAcknowledgementTypein the route to forceAA,AEorARyourself, or turnautoAckoff and build the ACK.
Components and languages used
Patterns that healthcare routes need
| need | pattern | in Cameleer |
|---|---|---|
| Deliver each message once | idempotent consumer on MSH-10 (the message control id) | idempotentConsumer with an in-memory, JDBC or Redis repository |
| Convert v2 to FHIR | read segments with the terser, build the resource, post it | hl7terser headers, setBody with Simple or jq, fhir producer |
| Keep working when the EHR is down | store and forward | dead letter channel to a folder, a replay route: the edge page shows it |
| Fan out to several systems | multicast with per-target error handling | multicast, wireTap for an archive copy |
| Send HL7 and check the reply | MLLP producer | to: mllp://host:port; CamelMllpAcknowledgementType on the way out is AA, AE or AR |
| Audit | every message and acknowledgement to an append-only log | wireTap to file, kafka or sql |
Why not a JVM on the gateway?
What changes with one native binary
- About 10 MB of memory for a running route, against hundreds for a JVM; the gateway can be a small box or a VM shared with other software.
- Starts in milliseconds, so a restart after a power cut or an update is invisible to the sending system's MLLP retry.
- Nothing to install: no JRE to patch. The image runs read-only, as non-root, on amd64 and arm64.
- Routes are files in Git;
cameleer validatechecks them before deployment.
Where Apache Camel still fits better
- You depend on HAPI's full HL7 object model or a Java terminology library in the route.
- Your interface team works in a Java application server and wants the JVM's tooling.
- You need a Camel component Cameleer does not have; the feature matrix lists what exists.
Common questions
Does Cameleer parse HL7 v2 messages?
Yes. The mllp component frames and acknowledges messages, the hl7 data format parses ER7 (pipe-delimited) text into a structured value and encodes it back, and the hl7terser language reads a field by path, such as PID-3-1.
Which FHIR versions does it support?
The fhir component talks to FHIR servers for R4, R4B, R5 and DSTU3: create, read, update, delete, search, history, transactions, operations, patch and validation. The fhirJson and fhirXml data formats parse and serialize resources and convert between the two encodings.
When is the MLLP acknowledgement sent?
After the route finishes. In the tested route the EHR call runs first, so the sender gets AA only when the message was delivered and AE when it still failed after the retries, and keeps the message to resend it. A route can set the acknowledgement type itself.
Is it an interface engine like Mirth Connect?
It is a routing engine with HL7 v2, MLLP and FHIR support: channels are routes in YAML files kept in Git, with Apache Camel's error handling, transformation and routing patterns. There is no visual channel editor or message browser.
Does MLLP support TLS?
Yes. The consumer accepts TLS connections and the producer connects with TLS when sslContextParameters or the global camel.ssl.* parameters are set.
Run it
Set the EHR URL, start the container, and point the sending system at port 2575.
export EHR_URL=https://ehr.example.org # optional: MLLP_PORT (default 2575) docker run --rm -p 2575:2575 --read-only -e EHR_URL \ -v "$PWD:/routes:ro" pmsudhi/cameleer run /routes/hl7-mllp-to-http.camel.yaml