ebXML messaging
ebMS 2.0 exchanges in Python - MessageHeader, Manifest, MIME payloads and per-payload signing and encryption.
ebXML Message Service (ebMS 2.0) predates the WS-* stack and is still the backbone of several national health networks - the NHS Spine in England and the Norwegian Helsenett among them. An ebMS message is a SOAP 1.1 envelope whose header contains an eb:MessageHeader naming the parties, the service and the action, whose body holds an eb:Manifest pointing at the payloads, and whose payloads travel as MIME parts next to the envelope.
In Zato, ebXML runs over the same outgoing SOAP connections as everything else - the difference is a dedicated call, invoke_ebxml, which takes the exchange's addressing details and the payload parts.
Sending a message
# -*- coding: utf-8 -*-
# Zato
from zato.common.soap.ebxml import EbXMLInfo
from zato.common.util.xml_.mime_ import Part
from zato.server.service import Service
class SendPatientRecord(Service):
name = 'demo.ebxml.send-patient-record'
def handle(self) -> 'None':
# Who is talking to whom, about what
info = EbXMLInfo()
info.from_party = 'my-organization'
info.to_party = 'their-organization'
info.cpa_id = 'cpa-123'
info.conversation_id = self.cid
info.service = 'urn:example:records'
info.action = 'SubmitRecord'
# The business payload is a MIME part
part = Part()
part.content_id = 'payload-1'
part.content_type = 'application/xml'
part.data = b'<PatientRecord>...</PatientRecord>'
# Send and read the acknowledgment
conn = self.soap['Health Network']
ack = conn.invoke_ebxml(info, [part])
self.logger.info('Acknowledged, ref: %s', ack.ref_to_message_id)
The platform builds the eb:MessageHeader with a fresh eb:MessageId and timestamp, adds the eb:Manifest referencing each part, packages everything as a MIME multipart and returns the parsed header of the reply - typically an ebMS acknowledgment whose ref_to_message_id points back at what was sent.
Party identifiers that need a type attribute - the NHS convention of urn:nhs:names:partyType:... values, for instance - use info.from_party_type and info.to_party_type.
Payload signing and encryption
Networks that protect the payloads themselves, rather than the transport alone, sign and encrypt each MIME part - the Norwegian health network profile is the canonical example. Both are switches on the call:
Each payload is signed first, so the signature covers the plaintext, then encrypted for the recipient. The keys and certificates come from the WS-Security definition attached to the connection - the same Signing key, Peer certificate and related fields that the X.509 mode uses.
Mutual TLS
ebMS endpoints commonly authenticate at the transport layer as well - the connection's Client certificate and Client key fields cover that, exactly as they do for any other SOAP connection.
Learn more
- NHS Spine and Norwegian Helsenett - the networks these exchanges connect to