# 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-\* specifications and remains the messaging standard of several national health networks, including the NHS Spine in England and the Norwegian Helsenett. An ebMS message is a SOAP 1.1 envelope. Its header contains an `eb:MessageHeader` that identifies the parties, the service and the action, its body contains an `eb:Manifest` that references the payloads, and the payloads are transmitted as MIME parts alongside the envelope.

In Zato, ebXML messages are sent through outgoing SOAP connections. The `invoke_ebxml` method accepts the addressing details of the exchange and the payload parts.

## Sending a message {#sending-a-message}

```python
# -*- 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':

        # Parties, service and action of the exchange
        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)
```

Zato builds the `eb:MessageHeader` with a new `eb:MessageId` and timestamp, adds the `eb:Manifest` that references each part, packages the message as MIME multipart and returns the parsed header of the reply. The reply is typically an ebMS acknowledgment whose `ref_to_message_id` identifies the message that was sent.

Party identifiers that require a type attribute, such as the NHS `urn:nhs:names:partyType:...` values, are set in `info.from_party_type` and `info.to_party_type`.

The CPA (Collaboration Protocol Agreement) is the agreement that two parties establish before they exchange messages. Its identifier is set in `info.cpa_id` and sent in the `eb:CPAId` element. The remaining terms of the CPA, including the endpoint, certificates, signing and encryption, are configured in the outgoing SOAP connection and in the parameters of the call.

## Payload signing and encryption {#payload-signing-and-encryption}

Networks that protect the payloads in addition to the transport require each MIME part to be signed and encrypted, as the Norwegian health network profile does. Both are enabled through parameters of the call:

```python
ack = conn.invoke_ebxml(info, [part], sign=True, encrypt=True)
```

Each payload is signed first, so that the signature covers the plaintext, and then encrypted for the recipient. The keys and certificates are taken from the [WS-Security definition](https://zato.io/docs/dev/soap/security/index.html) assigned to the connection, using the same **Signing key**, **Peer certificate** and related fields as the X.509 mode.

## Mutual TLS {#mutual-tls}

ebMS endpoints commonly require authentication at the transport layer as well. The connection's **Client certificate** and **Client key** fields provide it, configured as described for [other SOAP connections](https://zato.io/docs/dev/soap/security/index.html#mutual-tls).

## Learn more {#learn-more}

- [SOAP integrations](https://zato.io/docs/dev/soap/) - Envelopes, versions and Python objects instead of XML
- [SOAP as Python objects](https://zato.io/docs/dev/soap/python-objects/) - Build requests and read responses with dot access, no schemas
- [SOAP security](https://zato.io/docs/dev/soap/security/) - WS-Security, credentials in the body and client certificates
- [MTOM and SwA attachments](https://zato.io/docs/dev/soap/attachments/) - Binary content out of the envelope and into MIME parts
- [SOAP mandates](https://zato.io/docs/dev/soap/mandates/) - What each national and sector profile requires, and how to meet it
- [SOAP tutorial](https://zato.io/tutorials/soap/calling.html) - Call any SOAP service with Python objects, start to finish

- [NHS Spine](https://zato.io/docs/dev/soap/mandates/nhs-spine/index.html) and [Norwegian Helsenett](https://zato.io/docs/dev/soap/mandates/norway-helsenett/index.html) - the networks that use these exchanges
