JMS Destination
Send messages to a JMS queue for integration with enterprise messaging systems.
Overview
The JMS destination publishes messages to a Java Message Service (JMS) queue, enabling integration with enterprise messaging systems such as Apache ActiveMQ and IBM MQ. JMS queues are common in large healthcare organizations that rely on Java-based middleware for reliable message delivery between clinical, administrative, and financial systems. This destination provides guaranteed delivery through the JMS provider's persistence and acknowledgment mechanisms.
Configuration
Define a JMS destination in your root intu.yaml under the destinations key:
# intu.yaml
destinations:
legacy-mq:
type: jms
jms:
provider: activemq
url: tcp://activemq.hospital.internal:61616
queue: HEALTHCARE.ADT.INBOUND
auth:
username: ${JMS_USER}
password: ${JMS_PASS}
timeout_ms: 30000
Properties
activemq, ibmmq.tcp://host:61616 for ActiveMQ, or the appropriate connection string for IBM MQ.
Supports environment variable interpolation.
30000 (30 seconds).true.4 (normal).0 (no expiration).Authentication
${VAR} to reference environment variables.IBM MQ Specific Properties
When using provider: ibmmq, additional properties are available:
Full Example
Receive FHIR Encounter resources via HTTP, transform them to a legacy message format, and publish to an ActiveMQ queue consumed by a hospital billing system.
Root Configuration
# intu.yaml
destinations:
billing-queue:
type: jms
jms:
provider: activemq
url: tcp://activemq.hospital.internal:61616
queue: BILLING.ENCOUNTERS.INBOUND
persistent: true
priority: 6
auth:
username: ${JMS_USER}
password: ${JMS_PASS}
timeout_ms: 15000
Channel Configuration
# channels/encounter-to-billing/channel.yaml
name: encounter-to-billing
description: Transform FHIR Encounters to billing messages for legacy system
source:
type: http
http:
port: 8082
path: /fhir/Encounter
destinations:
- billing-queue
Destination Transformer
// channels/encounter-to-billing/transformer.ts
import { Message, Context } from "@intu/sdk";
interface BillingMessage {
messageType: string;
encounterNumber: string;
patientMrn: string;
admitDate: string;
dischargeDate: string;
encounterClass: string;
department: string;
attendingProvider: string;
diagnoses: Array<{
code: string;
system: string;
display: string;
rank: number;
}>;
procedures: Array<{
code: string;
system: string;
display: string;
date: string;
}>;
}
export default function transform(msg: Message, ctx: Context): Message {
const encounter = msg.body;
const patientRef = encounter.subject?.reference ?? "";
const patientMrn = patientRef.split("/").pop() ?? "";
const billing: BillingMessage = {
messageType: "ENCOUNTER_NOTIFICATION",
encounterNumber: encounter.id ?? "",
patientMrn,
admitDate: encounter.period?.start ?? "",
dischargeDate: encounter.period?.end ?? "",
encounterClass: encounter.class?.code ?? "",
department: encounter.serviceProvider?.display ?? "",
attendingProvider:
encounter.participant?.find(
(p: any) => p.type?.[0]?.coding?.[0]?.code === "ATND"
)?.individual?.display ?? "",
diagnoses: (encounter.diagnosis ?? []).map((d: any, i: number) => ({
code: d.condition?.coding?.[0]?.code ?? "",
system: d.condition?.coding?.[0]?.system ?? "",
display: d.condition?.coding?.[0]?.display ?? "",
rank: d.rank ?? i + 1,
})),
procedures: (encounter.procedure ?? []).map((p: any) => ({
code: p.code?.coding?.[0]?.code ?? "",
system: p.code?.coding?.[0]?.system ?? "",
display: p.code?.coding?.[0]?.display ?? "",
date: p.performedDateTime ?? "",
})),
};
ctx.logger.info(
`Publishing billing message for encounter ${billing.encounterNumber}`
);
return {
...msg,
body: billing,
};
}
persistent: true for healthcare messages to ensure they survive
broker restarts. Non-persistent messages offer lower latency but risk data loss
if the broker fails.
priority field to ensure time-sensitive messages (such as emergency
department encounters) are processed ahead of routine messages in the queue.