SOAP Processing Model
SOAP provides a distributed processing model that assumes a SOAP message originates at an initial SOAP sender and is sent to an ultimate SOAP receiver via zero or more SOAP intermediaries. Note that the SOAP distributed processing model can support many Message Exchange Patterns (MEPs) including but not limited to one-way messages, request/response interactions, and peer-to-peer conversations.
The SOAP processing model specifies how a SOAP receiver processes a SOAP message. It applies to a single message only, in isolation from any other SOAP message. The SOAP processing model itself does not maintain any state or perform any correlation or coordination between messages, even, for example, when used in combination with a SOAP feature which involves sending multiple SOAP messages in sequence, each subsequent message depending on the response to the previous message. It is the responsibility of each such feature to define any combined processing.
A SOAP node can be the initial SOAP sender, an ultimate SOAP receiver, or a SOAP intermediary. A SOAP node receiving a SOAP message MUST perform processing according to the SOAP processing model as described in this section and in the remainder of this specification. A SOAP node is identified by a URI.
SOAP Roles and SOAP Nodes
In processing a SOAP message, a SOAP node is said to act in one or more SOAP roles, each of which is identified by a URI known as the SOAP role name. The roles assumed by a node MUST be invariant during the processing of an individual SOAP message. This specification deals only with the processing of individual SOAP messages. No statement is made regarding the possibility that a given SOAP node might or might not act in varying roles when processing more than one SOAP message.
Table below defines three role names which have special significance in a SOAP message:
Table 2.3. SOAP Roles defined by SOAP 1.2 specification
|next||"http://www.w3.org/2003/05/soap-envelope/role/next"||Each SOAP intermediary and the ultimate SOAP receiver MUST act in this role.|
|none||"http://www.w3.org/2003/05/soap-envelope/role/none"||SOAP nodes MUST NOT act in this role.|
|ultimateReceiver||"http://www.w3.org/2003/05/soap-envelope/role/ultimateReceiver"||The ultimate receiver MUST act in this role.|
In addition to the SOAP role names defined in the table, other role names MAY be used as necessary to meet the needs of SOAP applications.
Targeting SOAP Header Blocks
A SOAP header block MAY carry a role attribute information item that is used to target the header block at SOAP nodes operating in the specified role. SOAP 1.2 specification refers to the value of the SOAP role attribute information item as the SOAP role for the corresponding SOAP header block.
A SOAP header block is said to be targeted at a SOAP node if the SOAP role for the header block is the name of a role in which the SOAP node operates. SOAP header blocks targeted at the special role "http://www.w3.org/2003/05/soap-envelope/role/none" are never formally processed. Such SOAP header blocks MAY carry data that is required for processing of other SOAP header blocks. Unless removed by the action of an intermediary, such blocks are relayed with the message to the ultimate receiver.
Understanding SOAP Header Blocks
A SOAP header block MAY carry a mustUnderstand attribute information item. When the value of such an attribute information item is "true", the SOAP header block is said to be mandatory.
Mandatory SOAP header blocks are presumed to somehow modify the semantics of other SOAP header blocks or SOAP body elements. Therefore, for every mandatory SOAP header block targeted to a node, that node MUST either process the header block or not process the SOAP message at all, and instead generate a fault. Tagging SOAP header blocks as mandatory thus assures that such modifications will not be silently (and, presumably, erroneously) ignored by a SOAP node to which the header block is targeted.
Processing SOAP Messages
Unless otherwise stated, processing of all generated SOAP messages, SOAP faults and application-level side effects MUST be semantically equivalent to performing the following steps separately, and in the order given:
Determine the set of roles in which the node is to act. The contents of the SOAP envelope, including any SOAP header blocks and the SOAP body, MAY be inspected in making such determination.
Identify all header blocks targeted at the node that are mandatory.
If one or more of the SOAP header blocks identified in the preceding step are not understood by the node then generate a single SOAP fault with the Value of Code set to "env:MustUnderstand". If such a fault is generated, any further processing MUST NOT be done. Faults relating to the contents of the SOAP body MUST NOT be generated in this step.
Process all mandatory SOAP header blocks targeted at the node and, in the case of an ultimate SOAP receiver, the SOAP body. A SOAP node MAY also choose to process non-mandatory SOAP header blocks targeted at it.
In the case of a SOAP intermediary, and where the SOAP message exchange pattern and results of processing (e.g., no fault generated) require that the SOAP message be sent further along the SOAP message path, relay the message.
Relaying SOAP Messages
A SOAP header block MAY carry a relay attribute information item. When the value of such an attribute information item is "true", the header block is said to be relayable.
Forwarding SOAP intermediaries MUST process the message according to the SOAP processing model defined in "Processing SOAP Messages". In addition, when generating a SOAP message for the purpose of forwarding, they MUST:
Remove all processed SOAP header blocks.
Remove all non-relayable SOAP header blocks that were targeted at the forwarding node but ignored during processing.
Retain all relayable SOAP header blocks that were targeted at the forwarding node but ignored during processing.
SOAP Versioning Model
The version of a SOAP message is identified by the XML expanded name of the child element information item of the document information item. A SOAP Version 1.2 message has a child element information item of the document information item with a [local name] of Envelope and a [namespace name] of "http://www.w3.org/2003/05/soap-envelope".
If a SOAP node receives a message whose version is not supported it MUST generate a fault with a Value of Code set to "env:VersionMismatch". Any other malformation of the message construct MUST result in the generation of a fault with a Value of Code set to "env:Sender".
The example below shows a version mismatch SOAP fault generated by a SOAP Version 1.2 node as a result of receiving a SOAP/1.1 message. The fault message is a SOAP/1.1 message with an Upgrade SOAP header block indicating support for SOAP Version 1.2:
<?xml version="1.0" ?> <env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"> <env:Header> <env:Upgrade> <env:SupportedEnvelope qname="ns1:Envelope" xmlns:ns1="http://www.w3.org/2003/05/soap-envelope"/> </env:Upgrade> </env:Header> <env:Body> <env:Fault> <faultcode>env:VersionMismatch</faultcode> <faultstring>Version Mismatch</faultstring> </env:Fault> </env:Body> </env:Envelope>
Let's start by looking at a basic SOAP message and its nested elements.
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"> <env:Header> <pns:qualityOfService xmlns:pns="http://example.org/qos"> <pns:priority>3</pns:priority> <pns:timestamp>2004-02-25T01:00:00-00:00</pns:timestamp> <pns:persist>true</pns:persist> </pns:appHeaderBlock> </env:Header> <env:Body> <bmns:businessPO xmlns:env="http://example.org/po"> <bmns:description>Widgets</bmns:description> <bmns:quantity>100</bmns:quantity> <bmns:price>20.5</bmns:price> </bmns:businessPO> </env:Body> </env:Envelope>
The outermost element is the env:Envelope that includes the namespace URL for SOAP. Enclosed within this are two subelements that SOAP defines. These are the env:Header and env:Body elements. SOAP does not define their contents. The elements are specific to the application that creates and processes the SOAP message. However, the SOAP specification does define how a SOAP node processes these elements.
The env:Header element is OPTIONAL in SOAP, but it has been included in the sample to illustrate its use. The SOAP header is an extension mechanism that provides a way for information to be passed within a SOAP message that is not part of the business message payload. In the previous example, the env:Header includes an immediate child element that contains a set of quality of service parameters. This immediate child is called a header block. A header can contain many header blocks. The header block has its own XML namespace in which the priority, timestamp, and persist elements appear. The SOAP specification allows header blocks to be targeted at specific SOAP nodes for processing as the message travels along its message path. The SOAP headers control and process a message as it moves along a message path. They include information that controls messaging qualities of service such as security, reliability, and addressing. By specifying new headers, you can create interoperable protocols based on SOAP. These form the basis of the services architecture.
The env:Body element within the SOAP message is MANDATORY. It contains the payload of the message, which is the information that is being transferred from the initial SOAP sender to the ultimate SOAP receiver. The choice of what information goes into the env:Header and what goes into the env:Body elements is a matter of business application and system design. In a typical enterprise environment, middleware that supports a defined set of service policies mandates what headers are required in a SOAP message. The env:Body is then used to contain necessary application-specific information, which is processed by the ultimate receiver of the remote service implemention.
The "role" Attribute
When a SOAP node processes a SOAP message, the node is said to act in one of several roles. A SOAP role identifies how a SOAP node should process a message. A URI identifies the SOAP role. It might be one of the three roles within the SOAP specification or one that systems designers assign to meet the needs of some applications. It appears as an attribute on the parent header block element:
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"> <env:Header> <hb1:firstHeaderBlock xmlns:hb1="http://example.org/hb1" env:role="http://example.org/Qos"> ..... </hb1:firstHeaderBlock> <hb2:secondHeaderBlock xmlns:hb1="http://example.org/hb2" env:role="http://www.w3.org/2003/05/soap-envelope/role/next"> ..... </hb2:secondHeaderBlock> <hb3:thirdHeaderBlock xmlns:hb1="http://example.org/hb3"> ..... </hb3:thirdHeaderBlock> </env:Header> <env:Body> ..... </env:Body> </env:Envelope>
The hb1:firstHeaderBlock element has a role attribute set to a value of http://example.org/Qos. The system designer assumes that the SOAP node that plays this role uses the information within the header block to manage message delivery quality of service in some specified way. The second header block hb2:secondHeaderBlock has its role attribute set to one of the roles defined within the SOAP 1.2 specification. The SOAP 1.2 specification defines three roles:
If a header block has a role set to the "none" URI, no SOAP node should process the contents of the header block. Nodes might need to examine the header contents if another header block references them, but they should not be processed.
Every SOAP node must be capable of processing a header block with its role attribute set to the "next" URI, because this is a role that every node should assume. A header block with a role set to the "next" URI is one that the next SOAP node in the message path should examine and possibly process. In the previous example, the hb2:secondHeaderBlock has its role attribute set to "next".
A SOAP node that assumes the role of an ultimate SOAP receiver processes a header block with its role attribute set to the "ultimateReceiver" URI. A header block that has no role attribute is targeted at the SOAP node that is acting as an ultimate SOAP receiver. In the example, the hb3:thirdHeaderBlock is targeted at the ultimate SOAP receiver because it doesn't have a role attribute.
NOTE: SOAP 1.1 has the actor attribute. In SOAP 1.2 this attribute is renamed to role. The semantics of the attribute are unchanged.
The "mustUnderstand" Attribute
Sometimes a SOAP node MUST process a particular header completely if it is acting in that SOAP role. The SOAP specification signals this condition by introducing a "mustUnderstand" attribute that can be added to a header block:
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"> <env:Header> <hb1:firstHeaderBlock exmlns:hb1="http://example.org/hb1" env:role="http://example.org/Qos" env:mustUnderstand="1"> ..... </hb1:firstHeaderBlock> <hb2:secondHeaderBlock xmlns:hb1="http://example.org/hb2" env:role="http://www.w3.org/2003/05/soap-envelope/role/next"> ..... </hb2:secondHeaderBlock> <hb3:thirdHeaderBlock xmlns:hb1="http://example.org/hb3"> ..... </hb3:thirdHeaderBlock> </env:Header> <env:Body> ..... </env:Body> </env:Envelope>
In the example, the SOAP node that is targeted by the hb1:firstHeaderBlock element must process the header block because a "mustUnderstand" attribute is set to 1. This is commonly referred to as a mandatory header block. The SOAP processing model states that processing of a SOAP message must not start until a SOAP node has identified all the mandatory header blocks targeted at it and is prepared to process them in accordance with the specification for those header blocks. If a header block has a "mustUnderstand" attribute set to 0, or there is no such attribute, a SOAP node might choose to ignore and not process the header block, even though it might be targeted at it. If a header block has a "mustUnderstand" attribute and is targeted at a SOAP node, the SOAP node is obliged to generate and return a SOAP fault if it is unable to process the header block.
NOTE: According to Basic Profile Version 1.1:
An ENVELOPE containing a soap:mustUnderstand attribute MUST only use the lexical forms "0" and "1".
The "relay" Attribute
The SOAP processing model states that a node that processes a header must remove it from the message before passing it to another node along the message path. This is because the SOAP specification errs on the side of caution, making sure that an intermediary makes no assumptions about what will happen to the message header it has processed later in the message path. The SOAP specification does, however, allow a node to reinsert a header into an outbound message with its contents unchanged or altered in some way, but the default behavior of the node is to remove the header after processing.
Sometimes, however, a systems designer wants a particular header to be targeted at any or all nodes within a message path. To allow this, SOAP 1.2 introduces the "relay" attribute. If this attribute is set to true, a SOAP node that detects a header targeted at itself can forward the header block to the next node if it chooses not to process it.
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope"> <env:Header> <hb1:firstHeaderBlock xmlns:hb1="http://example.org/hb1" env:role="http://example.org/Qos" env:mustUnderstand="1"> ..... </hb1:firstHeaderBlock> <hb2:secondHeaderBlock xmlns:hb1="http://example.org/hb2" env:role="http://www.w3.org/2003/05/soap-envelope/role/next" env:relay="true"> ..... </hb2:secondHeaderBlock> <hb3:thirdHeaderBlock xmlns:hb1="http://example.org/hb3"> ..... </hb3:thirdHeaderBlock> </env:Header> <env:Body> ..... </env:Body> </env:Envelope>
In the example, the second header block is targeted at the "next" node in the message path. It also has the "relay" attribute set to true. This means that a SOAP node that receives this message can process the header if it understands it. If it does so, the SOAP processing rules must be obeyed and the header removed before forwarding the entire message. A "relay" attribute set to true means that the node, if it chooses to, can ignore the header block and forward it to the next node. Remember that if a header block also has the "mustUnderstand" attribute set to true, this over-rules a "relay", and the node must process the header block if it understands its meaning.
NOTE: According to SOAP Version 1.2 Part 1: Messaging Framework:
If relaying the message, a SOAP intermediary MAY substitute "true" for the value "1", or "false" for "0". In addition, a SOAP intermediary MAY omit a SOAP mustUnderstand attribute information item if its value is "0".
SOAP Extensibility Model
SOAP provides a simple messaging framework whose core functionality is concerned with providing extensibility. The extensibility mechanisms can be used to add capabilities found in richer messaging environments.
A SOAP feature is an extension of the SOAP messaging framework. Although SOAP poses no constraints on the potential scope of such features, example features may include "reliability", "security", "correlation", "routing", and message exchange patterns (MEPs) such as request/response, one-way, and peer-to-peer conversations.
The SOAP extensibility model provides two mechanisms through which features can be expressed: the SOAP Processing Model (describes the behavior of a single SOAP node with respect to the processing of an individual message) and the SOAP Protocol Binding Framework (mediates the act of sending and receiving SOAP messages by a SOAP node via an underlying protocol).
SOAP Message Exchange Patterns (MEPs)
A Message Exchange Pattern (MEP) is a template that establishes a pattern for the exchange of messages between SOAP nodes. MEPs are a type of feature, and unless otherwise stated, references in this specification to the term "feature" apply also to MEPs. The request-response MEP specified in SOAP 1.2 Part 2 [SOAP Part 2] illustrates the specification of a MEP feature.
The specification of a message exchange pattern MUST:
Provide a URI to name the MEP.
Describe the life cycle of a message exchange conforming to the pattern.
Describe the temporal/causal relationships, if any, of multiple messages exchanged in conformance with the pattern (e.g., responses follow requests and are sent to the originator of the request.)
Describe the normal and abnormal termination of a message exchange conforming to the pattern.
The term "SOAP module" refers to the specification of the syntax and semantics of one or more SOAP header blocks. A SOAP module realizes zero or more SOAP features. A module specification adheres to the following rules. It:
MUST identify itself with a URI. This enables the module to be unambiguously referenced in description languages or during negotiation.
MUST declare the features provided by a module.
MUST clearly and completely specify the content and semantics of the SOAP header blocks used to implement the behavior in question, including if appropriate any modifications to the SOAP processing model. The SOAP extensibility model does not limit the extent to which SOAP can be extended. Nor does it prevent extensions from modifying the SOAP processing model.
MAY utilize the property conventions defined in SOAP 1.2 Part 2 [SOAP Part 2], section A Convention for Describing Features and Bindings, in describing the functionality that the module provides. If these conventions are followed, the module specification MUST clearly describe the relationship between the abstract properties and their representations in the SOAP envelope. Note that it is possible to write a feature specification purely in terms of abstract properties, and then write a separate module specification which implements that feature, mapping the properties defined in the feature specification to SOAP header blocks in the SOAP module.
MUST clearly specify any known interactions with or changes to the interpretation of the SOAP body. Furthermore, it MUST clearly specify any known interactions with or changes to the interpretation of other SOAP features and SOAP modules. For example, we can imagine a module which encrypts and removes the SOAP body, inserting instead a SOAP header block containing a checksum and an indication of the encryption mechanism used. The specification for such a module would indicate that the decryption algorithm on the receiving side is to be run prior to any other modules which rely on the contents of the SOAP body.