Cameleer

MLLP component

The mllp component sends and receives HL7 v2 healthcare messages over TCP with MLLP framing, and generates HL7 acknowledgements automatically.

Scheme: mllp: · Crate: cameleer-protocols · Cargo feature: protocols · Consumer: yes · Producer: yes · Apache Camel: MLLP

When to use it

  • Build an HL7 interface engine: receive ADT, ORM or ORU messages from a hospital system and forward them.
  • Run a small HL7 gateway next to lab devices or in a clinic (edge), forwarding messages to Kafka or HTTP.
  • Send HL7 messages to a remote system and check its acknowledgement (AA, AE, AR).

URI format

text
mllp://host:port[?options]

A consumer listens on host:port (0.0.0.0 for all interfaces); a producer connects to it.

Example

yaml example: mllp-hl7-gateway
- route:
    id: hl7-inbound
    from:
      uri: mllp://0.0.0.0:{{env:MLLP_PORT:2575}}
      steps:
        - log: "HL7 ${header.CamelMllpMessageType} from ${header.CamelMllpSendingApplication}, control id ${header.CamelMllpMessageControlId}"
        - to: log:hl7

Each message is answered with MSA|AA|<control id> when the route succeeds and MSA|AE|... when it fails. Send a test message with another route: to: mllp://localhost:2575.

Rust DSL

rust
use cameleer_core::prelude::*;

pub fn routes(ctx: &CamelContext) -> Result<()> {
    ctx.add_routes(|b| {
        b.from("mllp://0.0.0.0:2575")
            .route_id("hl7-inbound")
            .log("HL7 ${header.CamelMllpMessageType} from ${header.CamelMllpSendingApplication}, control id ${header.CamelMllpMessageControlId}")
            .to("log:hl7");
    })
}

Options

optiondefaultdescription
autoAcktrueConsumer: generate the HL7 acknowledgement.
hl7HeaderstrueConsumer: set the CamelMllp* headers from the MSH segment.
stringPayloadtrueBody as a string; false gives bytes.
validatePayloadfalseCheck the HL7 structure of received messages.
charsetNameUTF-8UTF-8 or ISO-8859-1.
receiveTimeout15000Producer: how long (ms) to wait for the acknowledgement.
readTimeout5000How long (ms) to wait for the rest of a started frame.
connectTimeout30000Producer: connect timeout (ms).
idleTimeout0Consumer: close idle connections after this many ms. 0 never closes.
keepAlivetrueTCP keep-alive.
tcpNoDelaytrueDisable Nagle's algorithm.
maxBufferSize1 GiBLargest accepted frame.
sslContextParameters#bean: the consumer accepts TLS (needs key material) and the producer connects with TLS.
useGlobalSslContextParametersfalseUse the global camel.ssl.* parameters for TLS.

Message headers

headerdirectiondescription
CamelMllpSendingApplication, CamelMllpSendingFacility, CamelMllpReceivingApplication, CamelMllpReceivingFacilityout (consumer)From MSH-3 to MSH-6.
CamelMllpTimestamp, CamelMllpSecurity, CamelMllpMessageType, CamelMllpEventType, CamelMllpTriggerEvent, CamelMllpMessageControlId, CamelMllpProcessingId, CamelMllpVersionIdout (consumer)From the other MSH fields.
CamelMllpCharsetout (consumer)The character set.
CamelMllpLocalAddress, CamelMllpRemoteAddressoutSocket addresses.
CamelMllpAcknowledgement / CamelMllpAcknowledgementStringin (consumer), out (producer)The acknowledgement as bytes / string. A route can set it to send its own.
CamelMllpAcknowledgementTypein (consumer), out (producer)AA, AE, AR (or CA, CE, CR). A route can set it to force the code.

A producer that receives AE / AR fails with MllpApplicationErrorAcknowledgementException / MllpApplicationRejectAcknowledgementException; no acknowledgement gives MllpAcknowledgementTimeoutException.

Run it with Docker

sh
docker run --rm -p 2575:2575 -v "$PWD:/routes:ro" pmsudhi/cameleer run /routes/hl7.camel.yaml

Common questions

How do I send my own acknowledgement?

Set the header CamelMllpAcknowledgementString (or CamelMllpAcknowledgement as bytes) in the route. To only change the code, set CamelMllpAcknowledgementType to AE or AR.

How do I read HL7 fields?

Use the hl7terser language with a terser path, for example a setHeader step whose expression is hl7terser: PID-5-1 (the patient's family name). The hl7 data format parses the whole message.

Is the connection kept open?

Yes. The producer reuses its connection between messages.

Found a problem?

If something on this page doesn't match what Cameleer does, or you hit a bug while building with it, please help fix it, whether you are a person or a coding agent: open an issue that describes what you saw, then fork the repository, fix it, add or update a test, run cargo test --workspace, and open a pull request. CONTRIBUTING.md explains the ground rules.

Edit this page on GitHub