HL7v2

Health Level Seven International Version 2 (HL7v2) is a clinical messaging format that provides data about events that occur inside an organization.

See the HL7 Version 2 Product Suite documentation for more details on HL7v2.

HL7v2 stores

An HL7v2 store is a data store that resides within a dataset. HL7v2 stores hold HL7v2 messages.

The HL7V2Store resource provides a representation of an HL7v2 store’s attributes. For each of your HL7v2 stores, you can choose options such as:

  • Whether to publish changes to the HL7v2 store (if, for example, your application receives a new message) to a Cloud Pub/Sub topic.
  • How to parse messages ingested into an HL7v2 store.

HL7v2 messages

Raw HL7v2 messages can be difficult to read. For example, take the following message:

MSH|^~\&|FROM_APP|FROM_FACILITY|TO_APP|TO_FACILITY|20180101000000||ADT^A01|20180101000000|P|2.5|
EVN|A01|20110613083617|
PID|1|843125^^^^MRN|21004053^^^^MRN~2269030303^^^^ORGNMBR||SULLY^BRIAN||19611209|M|||123 MAIN ST^^CITY^STATE^12345|
PV1||I|H73 RM1^1^^HIGHWAY 01 CLINIC||||5148^MARY QUINN|||||||||Y||||||||||||||||||||||||||||20180101000000|

The Cloud Healthcare API can parse a message, extract several fields from the message header segment (MSH) to allow for filtering, and represent the message's content as JSON data for further processing or data exchange.

The Message resource provides a representation of an HL7v2 message. It includes information like the time when the message was created, who created it, what data it contains, and so on. The Message resource for the message above looks like this:

{
  "name": "projects/PROJECT_ID/locations/REGION/datasets/DATASET_ID/hl7V2Stores/HL7V2_STORE_ID/messages/W5_pxOBkoLoCxiFxE4cg8zwEWRzMlOzIfaLBrZPf0Zg=",
  "data": "TVNIfF5+XCZ8RlJPTV9BUFB8RlJPTV9GQUNJTElUWXxUT19BUFB8VE9fRkFDSUxJVFl8MjAxODAxMDEwMDAwMDB8fEFEVF5BMDF8MjAxODAxMDEwMDAwMDB8UHwyLjV8DUVWTnxBMDF8MjAxMTA2MTMwODM2MTd8DVBJRHwxfDg0MzEyNV5eXl5NUk58MjEwMDQwNTNeXl5eTVJOfjIyNjkwMzAzMDNeXl5eT1JHTk1CUnx8U1VMTFleQlJJQU58fDE5NjExMjA5fE18fHwxMjMgTUFJTiBTVF5eQ0lUWV5TVEFURV4xMjM0NXwNUFYxfHxJfEg3MyBSTTFeMV5eSElHSFdBWSAwMSBDTElOSUN8fHx8NTE0OF5NQVJZIFFVSU5OfHx8fHx8fHx8WXx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHwyMDE4MDEwMTAwMDAwMHw=",
  "sendFacility": "FROM_FACILITY",
  "sendTime": "2018-01-01T00:00:00Z",
  "messageType": "ADT",
  "createTime": "2018-01-01T00:00:00Z",
  "patientIds": [
    {
      "value": "843125",
      "type": "MRN"
    },
    {
      "value": "21004053",
      "type": "MRN"
    },
    {
      "value": "2269030303",
      "type": "ORGNMBR"
    }
  ],
  "parsedData": {
    "segments": [
      {
        "segmentId": "MSH",
        "fields": {
          "5": "TO_FACILITY",
          "2": "FROM_APP",
          "3": "FROM_FACILITY",
          "0": "MSH",
          "1": "^~\\&",
          "10": "P",
          "4": "TO_APP",
          "9": "20180101000000",
          "8.1": "ADT",
          "11": "2.5",
          "8.2": "A01",
          "6": "20180101000000"
        }
      },
      {
        "segmentId": "EVN",
        "fields": {
          "1": "A01",
          "2": "20110613083617",
          "0": "EVN"
        }
      },
      {
        "segmentId": "PID",
        "fields": {
          "1": "1",
          "3[0].1": "21004053",
          "3[1].1": "2269030303",
          "3[0].5": "MRN",
          "0": "PID",
          "11.4": "STATE",
          "11.5": "12345",
          "2.1": "843125",
          "2.5": "MRN",
          "5.1": "SULLY",
          "11.3": "CITY",
          "8": "M",
          "11.1": "123 MAIN ST",
          "3[1].5": "ORGNMBR",
          "7": "19611209",
          "5.2": "BRIAN"
        }
      },
      {
        "segmentId": "PV1",
        "fields": {
          "44": "20180101000000",
          "7.1": "5148",
          "16": "Y",
          "2": "I",
          "3.2": "1",
          "3.4": "HIGHWAY 01 CLINIC",
          "7.2": "MARY QUINN",
          "3.1": "H73 RM1",
          "0": "PV1"
        }
      }
    ]
  }
}

Creating and ingesting messages

There is a distinction between creating messages and ingesting messages. A created message originates from Google Cloud Platform (GCP) and is sent to a remote system (such as a hospital). In contrast, an ingested message comes from a remote system and is ingested into GCP.

message creation

message ingestion

When the Cloud Healthcare API ingests a message from a remote system, the Cloud Healthcare API sends an acknowledgment message (ACK) to the remote system and generates a response. This response contains an hl7Ack field and value, which verifies that the message was accepted. Note the following important information about the hl7ack field's value:

  • The value contains a response type. An AA response type indicates Application Accept, meaning that the message was validated and successfully ingested.
  • The sending facility and the receiving facility are reversed.
  • The value contains the original message's control ID.

After a message is created and sent to a remote system, the Cloud Healthcare API expects the remote system to return an ACK. Note that ACKs are not persisted in HL7v2 stores.

When you create or ingest an HL7v2 message, the message is assigned an ID by the server. You can use this ID when interacting with the message (for example, to delete the message or label it with user-defined labels).

MLLP and the Google Cloud Platform MLLP adapter

The minimal lower layer protocol (MLLP) is the standard used for transmitting HL7v2 messages over TCP/IP connections within a network, such as a hospital.

MLLP does not offer an exact mapping to the Cloud Healthcare API HL7v2 REST API, which uses HTTP. Therefore, an MLLP adapter must be used to convert messages transmitted over MLLP into a format that can be accepted by an HTTP/REST API. To transmit messages over MLLP and then to the Cloud Healthcare API, use the Google Cloud MLLP adapter. For a guide on how to use the adapter, see Using the Cloud Healthcare API MLLP adapter.

The adapter does not parse or inspect the HL7v2 messages; the Cloud Healthcare API parses and validates the messages as they are ingested into an HL7v2 store. You can then do further validation on the message by viewing it or labeling it for analysis.

While it runs, the adapter keeps a long-lived TCP connection open between the care system network and the adapter itself. It also exposes a TCP socket for accepting HL7v2 messages over MLLP. The adapter determines message boundaries by detecting the start and end block bytes of each message, as defined in the MLLP standard.

After the HL7v2 message is ingested into the HL7v2 store, the HL7v2 store synchronously responds to the MLLP adapter with the appropriate response (an ACK or NACK). An ACK is sent if the message is properly formed and has a valid header segment. The MLLP adapter sends the ACK or NACK response to the care system over the TCP connection.

MLLP and security

MLLP does not natively support any encryption or authentication. Therefore, a TCP connection that uses MLLP should be wrapped in a secure connection using a virtual private network (VPN). You can use Cloud VPN to create a secure connection between the GKE cluster on which the MLLP adapter runs and your on-premises application. For more information, see Configuring Cloud VPN.

HL7v2, MLLP, and Cloud Pub/Sub

A fundamental aspect of using HL7v2 with the Cloud Healthcare API involves the configuration of Cloud Pub/Sub notifications. By using a subscriber application with Cloud Pub/Sub, you can receive notifications when an HL7v2 message is ingested into an HL7v2 store.

Read Configuring Cloud Pub/Sub notifications to see how to use Cloud Pub/Sub topics with the Cloud Healthcare API HL7v2 implementation.

HL7v2, MLLP, and GCP architecture

The following diagram shows how an HL7v2 message is sent from a care system and ingested into the Cloud Healthcare API. The MLLP adapter is deployed to Google Kubernetes Engine and the message is transmitted over a VPN using Cloud VPN. After ingestion, a subscriber application subscribed to the HL7v2 store's Cloud Pub/Sub topic receives a notification that the message was ingested. The Cloud Healthcare API also generates an ACK for the MLLP adapter and sends it back through the VPN tunnel and into the care system.

The HL7v2 message sent from the care system is an "ADT" message, which is a common message in HL7v2. When a care system sends an ADT message, it does not expect a new message to be generated and returned from the remote/on-premises system.

mllp_adapter

The diagram shows the following:

  1. The on-premises care system.
  2. An ADT HL7v2 message leaves the care system.
  3. The HL7v2 message is ingested through the MLLP adapter into an HL7v2 store.
  4. The HL7v2 store's configured Cloud Pub/Sub topic receives a notification that a message was ingested.
  5. A subscriber application listens for notifications of HL7v2 message ingestions from its Cloud Pub/Sub topic.
Was this page helpful? Let us know how we did:

Send feedback about...

Cloud Healthcare API