[Cache from http://www.gotdotnet.com/team/xml_wsspecs/xlang-c/default.htm; please use this canonical URL/source if possible.]


XLANG

Web Services for Business Process Design

Author

Satish Thatte

Copyright Notice

(c) 2001 Microsoft Corporation. All rights reserved.

The presentation, distribution or other dissemination of the information contained herein by Microsoft is not a license, either expressly or impliedly, to any intellectual property owned or controlled by Microsoft.

This document and the information contained herein is provided on an "AS IS" basis and to the maximum extent permitted by applicable law, Microsoft provides the document AS IS AND WITH ALL FAULTS, and hereby disclaims all other warranties and conditions, either express, implied or statutory, including, but not limited to, any (if any) implied warranties, duties or conditions of merchantability, of fitness for a particular purpose, of accuracy or completeness of responses, of results, of workmanlike effort, of lack of viruses, and of lack of negligence, all with regard to the document. ALSO, THERE IS NO WARRANTY OR CONDITION OF TITLE, QUIET ENJOYMENT, QUIET POSSESSION, CORRESPONDENCE TO DESCRIPTION OR NON-INFRINGEMENT WITH REGARD TO THE DOCUMENT.

IN NO EVENT WILL MICROSOFT BE LIABLE TO ANY OTHER PARTY FOR THE COST OF PROCURING SUBSTITUTE GOODS OR SERVICES, LOST PROFITS, LOSS OF USE, LOSS OF DATA, OR ANY INCIDENTAL, CONSEQUENTIAL, DIRECT, INDIRECT, OR SPECIAL DAMAGES WHETHER UNDER CONTRACT, TORT, WARRANTY, OR OTHERWISE, ARISING IN ANY WAY OUT OF THIS OR ANY OTHER AGREEMENT RELATING TO THIS DOCUMENT, WHETHER OR NOT SUCH PARTY HAD ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.

STATUS

XLANG and related specifications are provided as-is and for review and evaluation only. Microsoft hopes to solicit your contributions and suggestions in the near future. Microsoft Corporation makes no warrantees or representations regarding the specifications in any manner whatsoever.

Contents

1. Abstract
2. Document Status
3. Motivation
4. The Challenge of Business Protocols
5. Services as Autonomous Agents
6. Notational Conventions
7. Relationship with WSDL
8. Describing Service Behavior
8.1. Initial Example
8.2. Behavior Description
8.3. Instance Initiation and Termination
9. Basic Actions
9.1. Operations
9.2. Delays
9.3. Signaling Exceptions
10. Basic Control Processes
10.1. Empty
10.2. Sequence
10.3. Switch
10.4. While
10.5. All
10.6. Pick
11. Correlation and Port References
11.1. Message Properties
11.2. Message Correlation
11.3. Defining Correlation Sets and Groups
11.4. Port References and Dynamic Port Binding
12. Contexts
12.1. Local Declarations
12.2. Exception Handling
12.3. Transactions
13. Business Process Contracts
14. Future Extensions
14.1. Enabling Executable Business Processes
14.2. Modular Description of Service Behavior
14.2.1. Reuse of Parameterized Behavior
14.2.2. Autonomous Sub-behaviors
14.3. Dynamic Partner Enlistment
15. WSDL Issues
16. Acknowledgements
17. References
Appendix A XSD Schema

1. Abstract

Automation of business processes based on web services requires a notation for the specification of message exchange behavior among participating web services. This document specifies such a notation. We call it XLANG. XLANG is expected to serve as the basis for automated protocol engines that can track the state of process instances and help enforce protocol correctness in message flows.

2. Document Status

This is an initial public draft release of the XLANG specification that focuses on the language constructs used to define the behavior of an individual web service that participates in business processes. We also address the approach to combining such services into multi-party business processes. This release does not provide detailed examples and tutorial exposition.

We anticipate a number of extensions to the feature set of XLANG that are discussed briefly at the end of the document.

3. Motivation

There are two trends coming together in the world of e-commerce that are creating enormous opportunities and pressures for automation of business processes across business boundaries. One is enabling technology: the XML-based open protocols, and description and discovery standards that are growing up around SOAP. Programmatic service integration based on XML [1], SOAP [2], WSDL [3], and UDDI [4] is clearly going to become increasingly seamless as interoperable implementations become commonplace. Formal standardization of this technology stack within the XMLP Activity at W3C [5] validates and accelerates this trend. The other trend is a business imperative: the pressing need to truly realize the potential and promise of e-commerce by creating virtual enterprises, networks of applications that automate business processes across enterprise boundaries. There are already strong business process automation initiatives in areas ranging from securities trade settlement [6] to health insurance claims processing [7], and this trend can be expected to accelerate.

One key requirement in actually making cross-enterprise business process automation happen is the ability to describe the public/contractual aspects of these business protocols in a standard form that can be consumed by tools for process implementation and monitoring. Enterprise workflow systems today support the definition, execution and monitoring of long-running processes that coordinate the activities of multiple business applications. But they do not separate internal implementation from external protocol description. When processes span business boundaries, loose coupling based on precise external protocols is required because the parties involved do not share application and workflow implementation technologies, and will not allow external control over the use of their backend applications. Such protocols are by necessity message-centric; they specify the flow of messages representing business actions among trading partners, without requiring any specific implementation mechanism.

The RosettaNet Partner Interface Processes™ (PIPs™) [8] along with the RosettaNet Implementation Framework (RNIF) exemplify the current state of the art in business protocol specification. A major limitation of PIPs™ and similar current protocol specifications is that these are essentially paper specifications. They are meant to be used for human understanding and human-mediated enforcement. As business protocols proliferate and evolve more rapidly, the social processes necessary for dissemination, common understanding, and enforcement of paper protocols will break down as a result of their inability to scale. Progress in business process automation will be halted unless the specification of protocols is formalized to the point where their enforcement can be automated. Such protocol specifications must serve as the basis for automated protocol enforcement engines that can track the state of protocol instances and detect protocol errors in message flows. This is the primary motivation driving the development of XLANG.

4. The Challenge of Business Protocols

The definition of external views of business protocols presents some peculiar challenges because such protocols fall somewhere between service interfaces and full-blown network protocols in the explicit definition of behavior. Business protocols are like interfaces in that the implementation behind the public face of each service provider is meant to be completely opaque and changeable so long as the public contract defined for the provider's role by the protocol is maintained. The internal processes that actually drive the behavior, including the decisions to be made regarding alternative paths of behavior and the determination of the actual data content (as opposed to shape) of messages, are completely hidden. But these protocols need to go far beyond simple interfaces. In addition to defining the shape of messages on the wire, they need to describe the message exchange behavior in the same way that network protocols do. The difference is that ordinary network protocols define the shape and content of the protocol envelopes that flow on the wire and the behavior they describe is driven solely by the data in these envelopes. Business protocols must define behavior without reference to the business-specific data that actually flows on the wire and drives the behavior in large measure.

Take the example of a purchasing protocol. The seller has a service that receives a purchase order and responds with either acceptance or rejection based on a number of criteria including availability of the goods and the credit of the buyer. Obviously, the decision processes are opaque, but the fact of the decision must be reflected as behavior alternatives in the external business protocol. In other words, the protocol requires something like a switch statement in the behavior of the seller but with an opaque condition. Of course, there are aspects of business protocols that parallel normal network protocols, such as retry loops and correlation tokens. In the current version of XLANG, we have chosen to limit the ability to describe actual data manipulation to very specific features such as correlation sets and dynamic port references. We expect this constraint to be loosened in future extensions.

5. Services as Autonomous Agents

The unit of action offered by a service as described in WSDL is an operation. An operation can be a single asynchronous message, or a request/response pair of messages (with optional fault messages). The operation can be either incoming or outgoing. But an operation on what? WSDL does not say. It could be on a stateless service which has no memory of previous operations, such as a stock quote service. Or it could be an operation on an object, in the usual sense of object oriented programming systems, in which case the object will have the ability to use its state variables to keep a record of the consequences of previous operations. In the latter case, we usually think of the object as being subservient to the caller—the caller controls the entire life history of the object. The object itself has minimal say regarding the order in which its operations are invoked and no independent behavior. There is a third possibility. The service might represent stateful autonomous agents. In this case the service supports stateful long-running interactions in which each interaction has a beginning, a defined protocol for operation invocation, and an end. This is typically the case in cross-enterprise business processes such as supply chains. A seller may offer a service that begins an interaction by accepting a purchase order via an input message, then returns an acknowledgement to the buyer if the order can be fulfilled. It may later send further messages to the buyer such as shipping notices and invoices. These input and output operations do not occur in random order. They occur according to a defined sequence, a service process. And the seller's service remembers the state of each such purchase order interaction separately from other similar interactions. This is necessary because a buyer may be carrying on many simultaneous purchase processes with the same seller. Finally, every instance of the service process may have a private life of its own and it may autonomously perform activities in the background without the stimulus of an input operation.

There are obviously many challenges in describing realistic business processes of this nature, especially in the loosely coupled environment that must be assumed across business boundaries. The primary challenge is that unlike traditional enterprise workflow architectures, we cannot assume the existence of a central authority that manages the business process for the collection of participating enterprises. Each enterprise provides one or more process-capable services that act as autonomous agents, and the coordination among them occurs implicitly as a result of the operations performed rather that through a collective state management system. In XLANG, we strictly follow the discipline that the behavior of each autonomous agent is specified independently, and the only interaction between them occurs through message exchanges expressed as WSDL operations. We show how the ports and operations of the participants can be linked to each other to construct an overall business process.

To summarize, the goal of XLANG is to make it possible to formally specify business processes as stateful long-running interactions. Business processes always involve more than one participant. The full description of a process must show not only the behavior of each participant, but the way these behaviors match to produce the overall process. The focus is on the publicly visible behavior in the form of messages exchanged. Each participant clearly implements its behavior using some private means. The details of these private implementations are not a part of the business protocol, and XLANG provides no means to specify them. XLANG aims to specify all the behavior and only the behavior that the participant explicitly wants partners to understand in designing their own service processes. The specific high level feature categories that define the scope of XLANG are listed below.

These are discussed in the rest of the specification.

6. Notational Conventions

Throughout this document, the namespace prefix "wsdl:" is assumed to represent the namespace "http://schemas.xmlsoap.org/wsdl/", defined in [3]. The prefix "xlang:" is assumed to represent the namespace "http://schemas.microsoft.com/biztalk/xlang/", defined in this specification. The namespace prefix "xs:" is assumed to be associated with the URI "http://www.w3.org/2001/XMLSchema", defined in [9]. The namespace prefix "tns" is used to indicate the target namespace of the document in which it occurs. All other namespace prefixes are samples only.

The text uses an informal BNF style for the syntax. Keywords are italicized. No distinction is made between elements and attributes. The BNF is meant to show the abstract structure in a readable way. Examples are given to illustrate concrete syntax. A complete XSD schema is provided in the Appendix.

7. Relationship with WSDL

Full specification of business processes requires the specification of a number of different aspects: document schemas, message envelopes, reliable delivery, security, endpoint properties such as certificates, reliability requirements and service windows, and even legal agreements and personal contact information. Many of these aspects are involved in multiple web service usage domains. Building monolithic standards that address entire usage domains invariably creates egregiously different standards for requirements that are common to many domains. We believe it is better to develop a collection of building block standards that can be combined into domain specific standards as required. This simplifies implementation, interoperability, and compliance verification, making the development of web services standards and infrastructure much more practical and cost effective.

The building block standard that XLANG is most dependent on is WSDL [3]. WSDL specifies a number of fundamental concepts that form the starting point for defining an XLANG service. XLANG has a two-fold relationship with WSDL. An XLANG service description is a WSDL service description with an extension element that describes the behavior of the service as a part of a business process. XLANG service behavior may also rely on simple WSDL services as providers of basic functionality for the implementation of the business process. The latter aspect will become more prominent when the current version of XLANG is extended to allow for the description of executable business processes.

We assume that the reader is familiar with WSDL but the key WSDL concepts we build on are listed below for completeness.

Message
A message is a potentially multi-part package of documents and context data that constitutes the unit of communication with a web service. Each part in a message is defined using some well-defined type system. The type system may be abstract and the wire format of the messages may not be defined by the type. Messages are in this sense abstract.
Operation
An operation is a basic interaction pattern supported by a web service. These are either one way messages or request-response message pairs. The direction may be either incoming or outgoing. Operations are defined in terms of messages.
Port Type
A port type is a named set of abstract operations, defined using abstract message types.
Binding
A binding defines message format and protocol details for operations and messages defined by a particular port type. There may be multiple bindings for a given port type. The binding for a message defines the wire form of a message, typically in the context of a specific message format standard such as SOAP or MIME.
Port
A port is an externally visible target for a set of operations supported by a web service. A port minimally specifies a transport endpoint at which a binding is deployed.
Service
A (web) service is a group of related ports.

8. Describing Service Behavior

8.1. Initial Example

An XLANG service description extends a WSDL service description with an extension element describing the behavioral aspects of the service. The following simple example illustrates the overall structure of an XLANG service definition, in relation to a WSDL service definition. Note that we assume statically configured participant topologies to start with, where all participants have prior agreements in place including agreements on communication endpoints. Dynamic participant enlistment techniques are expected to be added in a future version of XLANG.

<?xml version="1.0"?>
<definitions name="StockQuoteProvider"

  targetNamespace="http://example.com/stockquote/provider"
  xmlns:tns="http://example.com/stockquote/provider"
  xmlns:xlang="http://schemas.microsoft.com/biztalk/xlang/"
  xmlns="http://schemas.xmlsoap.org/wsdl/">

  <!-- WSDL type and message definitions used -->
  <!-- below have been omitted here for brevity -->

  <portType name="RequestReceivePortType">
    <documentation>
      This port receives an asynchronous message requesting
      the price of the given stock.
    </documentation>
    <operation name="AskLastTradePrice">
      <input message="..."/>
    </operation>
  </portType>

  <portType name="ResponseSendPortType">
    <documentation>
      This port sends an asynchronous message providing
      the price of the given stock.
    </documentation>
    <operation name="SendLastTradePrice">
      <output message="..."/>
    </operation>
  </portType>

  <binding name="RequestReceivePortBinding" 
    type="tns:RequestReceivePortType">
    <!-- details omitted -->
  </binding>

  <binding name="ResponseSendPortBinding" 
    type="tns:ResponseSendPortType">
    <!-- details omitted -->
  </binding>

  <service name="StockQuoteProviderService">
    <documentation>
      The externally visible behavior of a simple asynchronous stock 
      quote provider service. A price quote request arrives via 
      E-mail. The request contains a ticker symbol and the address to 
      which we should send the stock price. There is an invisible 
      backend implementation that obtains the quote and the service 
      then returns this to the appropriate address.
    </documentation>

    <port name="pGetRequest" binding="tns:RequestReceivePortBinding">
      <soap:address location="mailto:quote@example1.com"/>
    </port>

    <port name="pSendResponse" binding="tns:ResponseSendPortBinding">
      <soap:address location="mailto:response@example2.com"/>
    </port>

    <xlang:behavior>
      <xlang:body>
        <xlang:sequence>
          <xlang:action operation="AskLastTradePrice" 
            port="pGetRequest" activation="true"/>
            <xlang:action operation="SendLastTradePrice" 
              port="pSendResponse"/>
            </xlang:sequence>
          </xlang:body>
        </xlang:behavior>

  </service>

</definitions>

Example 1: XLANG service definition at location http://example.com/stockquote/provider.xlg

This example contains a very simple behavior, in which the sequence in which two asynchronous operations occur in a single trade price query interaction is defined. Note that the asynchronous output operation has a statically defined target address since we are assuming a static participant topology in this example. The participant making the query is known and its communication endpoint is configured as part of the service contract. The reason the sequence element is wrapped within a body element is to prepare for the extension to parameterized behaviors which would may have a parameter declaration section separate from the process description section of the behavior.

See Instance Initiation and Termination for an explanation of the activation attribute in the first action.

8.2. Behavior Description

behavior ::= behavior body
body ::= body headerProcess

headerProcess ::= header? process
header ::= header localDecls

localDecls ::= local portReferenceDecl* correlationSetDecl*

XLANG service is a WSDL service with a behavior. Instances of XLANG services are started either implicitly by specially marked operations or explicitly by some background functionality. Further details on the elements of a behavior description are given in the following sections.

8.3. Instance Initiation and Termination

A service with a behavior represents an interaction spanning many operations. As such the interaction has a well-defined beginning and end. We speak of such an interaction as an instance of the service. An instance can be started in two ways. A service may be explicitly instantiated using some implementation-specific functionality or it may be implicitly instantiated with an operation in its behavior that is meant to be an instantiation operation.  An operation in the behavior that serves to start a new service instance must be marked with an activation attribute with a value of true. We shall refer to such an operation as an activation operation. The default value of this attribute is false. The first action in Example 1 is marked this way. Such an action must be either an input or a request/response operation.

A service instance terminates when the process that defines its behavior terminates.

9. Basic Actions

Actions are the atoms of behavior. The four WSDL operations at port types can be used as XLANG actions, as illustrated in the example above. XLANG defines some additional actions listed below

action ::= operation | delay | raise
delay ::= delayFor | delayUntil

The two other kinds of action are timeouts (deadline and duration) and exceptions. Each action type is described below.

9.1. Operations

These actions simply reference WSDL operations on the available ports. The semantics of WSDL operations is defined in [3] and carried over to XLANG.

operation ::= action operationRef portRef activation? 
              correlationBegin? correlationSetRef*
              portDescription*

Example

<action operation="AskLastTradePrice" port="pRequest" activation="true"/>

See Message Correlation and Port References for explanations and examples of the remaining syntax.

9.2. Delays

delayFor

The delayFor action causes the thread of behavior within which it occurs to pause for the specified time interval. See All for a description of the all process form that creates multiple threads of behavior.

The delay duration is meant to represent a non-negative value of type duration. Conformant implementations are required to pause the relevant thread of behavior for at least the duration specified and should make the pause as close to the duration specified as possible. Realistic process descriptions need to be able to compute the duration dynamically. In keeping with the philosophy used in this version of XLANG, we use a QName to represent the duration.

delayFor ::= delayFor QName

Example

<delayFor period="SupplyChain:OrderAcknowledgementTimeout"/>

delayUntil

delayUntil is similar to delayFor except that it causes the thread of behavior within which it occurs to pause until the specified absolute time has been reached. The delay expiration is meant to represent a value of type dateTime. We use a QName in this version as before.

delayUntil ::= delayUntil QName

Example

<delayUntil clock="SupplyChain:ShippingDeadline" />

9.3. Signaling Exceptions

An exceptional condition is explicitly signaled by the raise action which optionally takes a QName representing the condition as a parameter. The QName, if present, is passed to the exception process that handles the exception.

raise ::= raise QName?

Example

<raise signal="creditCheck:creditDenied">

10. Basic Control Processes

Processes combine actions together in useful ways. The basic process forms in the table below are described in this section. The advanced forms context and compensate are described in subsequent sections.

process ::= sequence | switch | pick | all | while |
            context | compensate | empty

10.1. Empty

The simplest process is the empty process that contains no actions and completes as soon as it has begun. It plays a role rather like the null statement of ordinary programming languages.

empty ::= empty

Example

<empty/>

10.2. Sequence

A sequence contains zero or more actions or processes which are executed serially. The sequence concludes when its final action or process has finished.

sequence ::= sequence [action | process]*

Example

<xlang:sequence>
  <xlang:action operation="AskLastTradePrice" activation="true"/>
  <xlang:action operation="SendLastTradePrice"/>
</xlang:sequence>

10.3. Switch

The switch process supports conditional behavior. The branches of the switch are considered in the order in which they appear. The first branch whose condition holds true provides the process for the switch. If no branch with a rule is taken, then the default branch will be taken. If the default branch is absent then a default branch with an empty process is deemed to be present. The switch is complete when the process form of the selected branch completes.

The conditions in a switch are opaque and are represented by QNames. These opaque conditions represent alternatives with documented domain-specific semantics that are decided using opaque internal procedures as part of the implementation.

switch ::= switch branch* default? 
default ::= default process
branch ::= branch case process
case ::= case QName

Example

<switch xmlns:inventory="http://supply-chain.org/inventory">
  <branch>
    <case>
      inventory:OutOfStock
    </case>
    <sequence>
      ...
    </sequence>
  </branch>
  <branch>
    <case>
      inventory:InStock
    </case>
    <sequence>
      ...
    </sequence>
  </branch>
</switch>

10.4. While

Support for looping is provided by the while construct. A specified process is executed until the given condition no longer holds true. The possible forms of condition are the same as in switch.

while ::= while case process

Example

<while xmlns:protocol="http://protocol.org/retry/">
  <case>
    protocol:retryEnabled
  </case>

  <sequence>
    ...
    <!-- retry some behavior -->
  </sequence>
</while>

10.5. All

The all process executes each of the specified sub-processes concurrently. XLANG compliant implementations may or may not provide true concurrent behavior but must, at a minimum, provide the illusion of concurrency by not imposing any temporal ordering constraints on the execution of actions across different sub-processes.

In order to avoid race conditions between sub-processes in all, the use of common ports for operations across different sub-processes is disallowed.

all ::= all process*

Example

<all>
  <sequence>
    <!-- perform airline reservation -->
  </sequence>

  <sequence>
    <!-- perform car reservation -->
  </sequence>

  <sequence>
    <!-- perform hotel reservation -->
  </sequence>
</all>

10.6. Pick

The pick process form awaits the arrival of one of a set of events and then executes a process form associated with that message. The form of pick is a set of branches of the form event/process, and exactly one of the branches will be selected based on the occurrence of the event associated with it. It is very similar to a switch except that the conditions for the branches are events that may or may not occur. If more than one of the events occurs there is a race and the choice of branch to be executed is dependent on both timing and implementation. The possible events are the arrival of some message at a given port in the form of the invocation of an input or request/response operation, or the completion of a delay action. In an exception handling process, a catch event is also permitted to allow interception of exception signals.

This process form completes when one of the branches has been triggered by the occurrence of its associated event and the corresponding process terminates. The example below shows a typical usage of pick. Such a pick process may occur in a loop that is accepting line items for a large order, but a completion action is enabled as an alternative event.

pick ::= pick eventHandler+
eventHandler ::= eventHandler event process
event ::= delayFor | delayUntil | operation | catch
catch ::= catch QName

Example

<pick>
  <eventHandler>
    <action operation="inputLineItem">
      <sequence>
        <!-- add line item to order -->
        ...
      </sequence>
  </eventHandler>

  <eventHandler>
    <action operation="receiveOrderCompletion">
      <sequence>
        <!-- perform order completion routine -->
        <sequence>
  </eventHandler>
</pick>

11. Correlation and Port References

We have so far maintained the illusion that the target for the delivery of messages between XLANG services is just the WSDL port of the recipient service. The reason this is an illusion is that by their very nature, stateful services are instantiated in order to act in accordance with the history of an extended interaction. Therefore, messages sent to such services need to be delivered not only to the correct destination port, but to the correct instance of the service that defines the port. The infrastructure hosting the service needs to be able to do this in a fairly generic manner, so as to avoid burdening every service implementation with the need to implement a custom mechanism for instance routing.

Consider the usual supply chain situation where a buyer sends a purchase order to the seller. Let us suppose that the buyer and seller have a stable business relationship and are statically configured to send documents related to the purchasing interaction to the URLs associated with the relevant WSDL ports. The seller needs to return an acknowledgement for the order, and the acknowledgement must be routed to the correct service instance at the buyer. The obvious and standard mechanism to do this is to carry a token or "cookie" in the order message that is copied into the acknowledgement for correlation. The token may be in the message envelope in a header or in the business document (purchase order) itself. In either case, the exact location and type of the token in the relevant messages is fixed and instance independent. Only the value of the token is instance dependent. Therefore, the structure and position of the correlation tokens in each message can be expressed declaratively in the service description. The XLANG notions of correlation set and correlation group (see below) provide this feature. The declarative information allows XLANG compliant infrastructure to use correlation tokens to provide instance routing automatically.

An entirely different form of dynamic communication is needed when a service needs to perform an operation at another service with which it has no static acquaintance. The initiating service clearly needs to know the port type and binding since it must know the abstract shape and wire format of the messages to be sent and received, as well as their intent. The information likely to be missing is the transport endpoint of the port and any other information specific to the port declaration, as opposed to the port type or binding declaration. Consider for instance a supply chain process in which the seller dynamically selects the shipper based on availability and pricing. The buyer needs to use a tracking operation at the shipper to obtain an expected delivery schedule. The standard service description for a shipper is statically known to the buyer but the identity of the specific shipper involved must be dynamically communicated for every order processed by the seller. XLANG provides a notion of port references to allow the seller to communicate the port information for the shipper dynamically to the buyer, say in the purchase order acceptance message. Of course, in this case, the buyer needs to communicate with a specific instance of the shipper's service, instantiated by the seller for the specific order involved. The seller must provide the buyer the correlation tokens involved as well. The combination of port reference and correlation permits the seller to provide the buyer with a port reference logically scoped to a specific service instance.

The declarative specification of both correlation and port references relies on declarative properties of messages. A property is simply a (simple or structured) "field" within a message part identified by an XPath. This is only possible when the type of the message part is described using an XML schema. We restrict the usage of correlation tokens and port references to message parts described in this way.

11.1. Message Properties

Business protocol messages often carry values of special interest in the protocol. A purchase order document may carry a purchase order number. A BizTalk Framework [11] message header may carry a process instance identity. Such properties need to be identified in message definitions, and the obvious way to do so would be to use XPath in combination with XML Schema definitions of message part types to define properties. Message definitions in WSDL do not permit an extension element, but XML schema does permit annotations.

In this version of XLANG, we assume that the types of message parts that carry properties of interest in the business protocol are defined using XML Schema as the type definition language. This excludes supporting documents carried as binary attachments and the like. To be clear, the actual wire format of such types may still be non-XML, e.g., EDI flat files based on different bindings for port types. The canonical semantics for extracting a property from a message therefore involves parsing the message into an XML document according to the schemas and bindings of the parts involved, and then applying the XPath query to the instance. Efficient shortcuts that confirm to the semantics are permitted in conformant implementations. The following is an example of a property definition in a schema

<complexType name="purchaseOrder" xmlns:po="http://myNamespace">
  <annotation>
    <appInfo>
      <xlang:propertyDef name="po:orderNumber" 
        path="./purchaseOrder/orderNumber"/>
    </appInfo>
  </annotation>
  <element name="orderNumber" type="decimal"/>
    <!-- the rest of the PO -->
</complexType>

We assume that properties have globally unique qualified names (QNames). Properties may be either simple or structured. Simple properties are used for correlation, while structured properties are used for passing port references and participant bindings for constructing dynamic participant topologies. Both usage patterns are described below.

11.2. Message Correlation

During its lifetime, a service instance will typically hold one or more conversations with other service instances representing other participants involved in the interaction. Conversations may use sophisticated transport infrastructure that correlates the messages involved in a conversation and routes them to the correct service instance. However, in many cases correlated conversations may involve more than two parties or may use lightweight transport infrastructure with correlation tokens embedded directly in the business documents being exchanged. Correlation patterns can become quite complex. The scope of correlation is not, in general, the entire interaction specified by a service, but may span a part of the service behavior. Correlated exchanges within the behavior of a service instance may nest and overlap, and messages may in general carry several sets of correlation tokens. For instance, a buyer may start a correlated exchange with a seller by sending a purchase order (PO) and using a PO number embedded in the PO document as the correlation token. The PO number is used in the PO acknowledgement by the seller. The seller may later send an invoice that carries both the PO number, to correlate it with the PO, and also an invoice number so that future payment related messages that need carry only the invoice number as the correlation token. The invoice message thus carries two separate correlation tokens and participates in two overlapping correlated exchanges.

XLANG addresses correlation scenarios by providing a very general mechanism to specify correlated groups of operations within a service instance. A set of correlation tokens can be defined as a set of properties shared by all messages in the correlated group. Such a set of properties is called a correlation set. The set of operations (in a single service) that is correlated via a correlation set is called a correlation group.

Correlation groups are themselves instantiated and terminated, within the scope of an instance of the service they belong to. A correlation group may go through several instantiations within the lifetime of a single service instance, for instance in a loop. Like the (implicit) instantiation of a service, the instantiation of a correlation group is triggered by a specially marked operation. The lifetime of a correlation group instance is determined by the lifetime of the lexical scope (context or service) within which its correlation set is declared.

In the context of multiparty business processes, each service involved in a correlated conversation acts either as the initiator or a follower within a given conversation instance. The initiator service performs the first (outgoing) operation that starts the conversation, and therefore defines the actual values of the properties in the correlation set that tag the conversation. All other participants are followers that instantiate their correlation groups in the conversation with an incoming operation that provides the values of the properties in the correlation set. Both initiator and followers must mark the first operation in their respective groups as the operation that begins an instance of the correlation group and therefore defines the values of the correlation set for that instance of the group.

11.3. Defining Correlation Sets and Groups

Correlation sets declare a named group of properties that, taken together, will serve to define a correlation group. A given operation may participate in multiple correlation groups. In an instance of a correlation group, the actual values of the properties in the associated correlation set must be identical for all the actual messages in all the operations involved in the instance.

correlationSetDecl ::= correlation name propertyRef+
name ::= NCName
propertyRef ::= QName

 

Examples:

<correlation name="CustomerKeys">
  POProps:CustomerNumber POProps:OrderNumber
</correlation>

A particular operation may carry the tokens of one or more correlation sets. When an operation that involves multiple messages is associated with a correlation set, every message involved in the definition of that operation must possess all the properties in the set. In reality this is likely to be too restrictive and we expect to relax this constraint in future versions that address implementation issues.

In an action, when a reference is made to an operation that carries correlation information, the action indicates this by supplying a correlation set reference.

correlationRef ::= correlation setNames
correlationBegin ::= correlationBegin setNames
setNames ::= NCNameList

Examples

<action operation="receiveInvoice" 
correlation="PONumber invoiceNumber" 
correlationBegin="PONumber"/>

11.4. Port References and Dynamic Port Binding

A port in WSDL is defined as an occurrence in a service of a binding of a specific port type. The only information WSDL mandates for a port definition is an address. Clearly, in the context of business protocols, other characteristics will need to be specified for individual ports. An example is server certificates when the port address requires an SSL connection. Other possibilities include service windows, connection timeout behavior, and so on. It is necessary to standardize a schema for this information but this is outside the scope of XLANG. We assume the existence of a usable dynamic port information schema. For completeness, we use the following open content schema in this specification.

<xsd:complexType name="portInformation">
  <xsd:complexContent>
    <xsd:restriction base="xsd:anyType">
      <xsd:attribute name="uri" type="xsd:anyURI"/>
    </xsd:restriction>
  </xsd:complexContent>
</xsd:complexType>
portReference ::= portReference portInformation

A port reference is conveyed as a message property whose value conforms to the dynamic port information schema. For example

<myMessage
  ...
  <portReference uri=http://electrocommerce.org>
    <!-- additional port information -->
  </portReference>
  ...
</myMessage>

XLANG permits ports instantiated from outgoing port types (port types that only include notification or solicit/response operations) to specify that the specifics including the address bound to the port will be supplied dynamically. For example

<wsdl:service ... >
  <wsdl:port name="pResponse" binding="outgoingPortType">
    <xlang:portDescription type="dynamic">
  </wsdl:port>
</wsdl:service>

The port description for such a port is treated as a variable that can be (initialized and) updated by appropriately annotated incoming messages. An incoming operation may specify one or more port references that occur as message properties in the incoming message. Such a port reference can be used to provide run-time port data for a dynamically bound port including its associated address. For example

<xlang:action operation="AskLastTradePrice" port="pRequest">
  <portDescriptionIn property="OM:PortRef" dynamicPort="pResponse"/>
</xlang:action>

This allows a one-way operation to also provide the port reference for the response to be sent as a notification operation for which the port used is dynamically bound.

An outgoing operation may specify a port reference that occurs as a message property in the outgoing message that is to be used to dynamically provide the port data for a local port to a remote service, to be used in an outgoing operation by that service. For example

<xlang:action operation="sendPurchaseOrder" port="pSendPO">
  <portDescriptionOut property="PO:PortRef" localPort="pPOAck"/>
</xlang:action>

This causes the "PO:PortRef" property of the outgoing message to be initialized to the port reference for the local service port "pPOAck" at which the service expects the recipient of the PO to send an acknowledgement.

12. Contexts

The context process form provides a framework for local declarations as well as exception handling and transactional behavior. The grammar is

context ::= context localDecls? process transaction? exception?
transaction ::= transaction txnid compensation?
txnid ::= NCName
compensation ::= compensation process
exception ::= exception pick finally?
finally ::= finally process

12.1. Local Declarations

XLANG currently only allows local declaration of correlation sets and port references. If local declarations are provided, the contained process is executed in a local naming scope. The correlation sets and port references declared locally are only visible within the context process (or in its exception or compensation blocks) and hide any conflicting names declared at outer scopes. A correlation group that depends on a correlation set local to a context must itself be entirely contained within the context.

12.2. Exception Handling

Exception handling in XLANG can be thought of as a mode switch from the normal processing in a context. The optional exception block attached to a context provides a way to define a set of custom exception handling processes. These processes are structured as a pick process with exceptional events guarding each pick alternative. A finally block optionally follows the pick, and provides a convenient way to design exception handling code that is common to all exceptional cases. Note that the pick process is not optional. The exception block must specify the exceptions it is prepared to handle.

Aside from the normal pick event types, i.e., delays and incoming operations, exception blocks allow a catch event that intercepts explicit exceptions signaled within a context. In case a catch is not provided for an exception signaled within the context, there is a default catch that is implicitly provided as described below.

Exceptions signaled internally within a context may either be explicitly raised via a raise action, or implicitly due to infrastructure errors such as communication failures.

The pick process in the exception block is enabled as soon as a context process starts. If any of the events guarding a pick alternative in the exception block occurs, all normal processing in the context is halted and control passes to the process following the exceptional pick event. If the normal process in the context completes without exceptional events, the pick process in the exception block is terminated without being executed. This is equivalent to a normal completion event with an empty process that is an implicit alternative in the pick.

If the exception block is missing, or a catch is missing, the default exception handling behavior for an exception signaled within the context is to

  1. Invoke the compensation blocks of its immediately enclosed transactions in the reverse order of completion.
  2. Re-raise the exception, i.e., treat the exception as unhandled and make it available for the next enclosing exception block for handling.

The following examples show a typical usage pattern for exception handling

Examples

<context> non-transactional context
  <sequence>
    ... normal context process here
  </sequence>

  <exception>
    <pick>
      <delayFor period="PT100S"/>
        <!-- timeout behavior -->
        <action operation="receiveCancelMessage"/>
          <!-- cancel behavior -->
        <catch code="PO:OutOfStock"/>
          <!-- out of stock behavior -->
    </pick>
    <finally>
      <!-- send a message to a monitoring app to
      notify it that an exception occurred -->
    </finally>
  </exception>
</context>

12.3. Transactions

A transaction is normally viewed as an atomic consistency-preserving state update. ACID database transactions have this characteristic along with the guarantee that in case of any failure during the transactional update the partial update will be rolled back and its effects erased. Long running business processes require a different and somewhat looser notion of transaction (often called a long-running transaction, or LRT for short) in which individual steps may be ACID transactions but the overall business transaction may fail or may be cancelled for a variety of business and technical reasons and the partial work done during its progress must be compensated for as best as possible. Moreover, isolation of state updates is not maintained during the lifetime of the LRT since the locking necessary is impractical for long durations. It is important to understand that the notion of LRT described here is purely local and occurs within a single service instance. There is no distributed coordination regarding an agreed-upon outcome among multiple participant services. We view the achievement of distributed agreement as an orthogonal problem outside the scope of XLANG.

As an example of an LRT, consider the planning and fulfillment of a travel itinerary. This can be viewed as an LRT in which individual service reservations may use nested transactions within the scope of the overall LRT. In case the itinerary is cancelled the reservation transactions must be compensated for by cancellation transactions, and the corresponding payment transactions must be compensated accordingly as well. For ACID transactions in databases the transaction coordinator(s) know all of the uncommitted updates, the order in which they must be reversed, and are in full control of such reversal. In the case of business transactions, the compensation behavior is itself a part of the business protocol and must be explicitly specified. For instance, there may be penalties or fees applied for cancellation and modification depending on the timing. If a payroll advance has been given to pay for the travel, the reservation must be successfully cancelled before the payroll advance for it can be reversed in the form of a payroll deduction. This means the compensation actions may need to run in the same order as the original transactions, which is not the standard or default in most systems. XLANG provides a notion of long-running transactions and compensation that addresses these requirements.

Contexts may be used to delineate the scope of a part of the behavior that has transaction-like properties. Within XLANG this primarily means that an implicit or explicit compensation process is associated with the context, and this can be invoked using the compensate process form described above. The transaction qualifier for a context declaration includes a transaction name. Contexts with transaction qualifiers may be nested.

For brevity, we refer to contexts with transaction qualifiers as transactions hereafter.

Compensation

All transactions may optionally include a compensation block that consists of a process to be executed if the transaction needs to be compensated after successful completion of the main process, due to a subsequent fault in an enclosing transaction. The compensate process form invokes the compensation process block of an enclosed transaction. This process form may only appear in the following situations:

  1. In the exception block of any context that immediately encloses contexts with transaction qualifiers. In this case, compensate would be used to call the compensation blocks of one or more of these inner transactions, in any order.
  2. In the compensation block of a long-running transaction. In this case, the compensation block itself uses compensate to perform the compensation logic of one or more inner transactions, in any order.

compensate refers to the target compensation block in one of the following two ways:

  1. By the name of an immediately enclosed (nested) transaction.
  2. By the name of this transaction. For transactions, a default compensation behavior exists (see below). A compensation block may request the default behavior by calling compensate with its own name.

compensate is equivalent to empty (i.e. it does nothing) if the transaction named by the txnid did not successfully commit, or the local call named by the txnid did not return without an exception. This allows simple compensation sequences to be written in exception handling code without regard to the amount of forward progress made within the enclosed context.

compensate ::= compensate txnid

Example

<compensate transaction="RecordPayment">

If the compensation block for a transaction is absent, the default compensation behavior is to invoke the compensation blocks of its immediately enclosed transactions in the reverse order of completion.

Example

<context>
  <sequence>
    ... normal behavior here
  </sequence>
  <transaction atomic="false" name="RecordPayment">
  <compensation>
    <sequence>
      ... compensation code here
    </sequence>
  </compensation>
  </transaction>
</context>

13. Business Process Contracts

A business process is a contract between two or more parties. An XLANG service description is used to define the behavior of each party. To complete the definition of the business process, it is necessary to define how the XLANG services for each party fit together. XLANG provides a notation for stitching together the individual service descriptions using a map that defines the connections between the ports of the services involved.

One of the issues that comes up in defining the connections is the fact that WSDL does not restrict port types to aggregate only incoming (one-way and request/response) or only outgoing (notification and solicit/response) operations. In other words, WSDL port types do not have polarity. This is in part due to the ambiguity of the interpretation of outgoing operations in WSDL, as described in WSDL Issues below. Based on our interpretation, we believe that allowing a mixture of incoming and outgoing operation types in a port type is highly undesirable. The only reasonable case where a port type can support both incoming and outgoing operations is when it is bound to a full-duplex conversational communication medium, in which case we would need a way to constrain the binding of the port type to such a communication medium. Given the absence of such a constraint notation, in this version of XLANG we assume that port types used in the definition of XLANG service descriptions are constrained to contain only incoming, or only outgoing operations.

Ports represent communication endpoints. They therefore form the only point of "physical" contact between the parties to a contract. Each port of each service must be mapped to at least one port of another service in such a way that the transport endpoints for the mapped ports are identical. In addition, a port that supports only outgoing operations must be mapped to exactly one port of a partner service. Outgoing operations are not multicast.

The combination of XLANG behavior definitions with port maps allows the multiparty contract to be treated as a structured interaction diagram that fully explicates the contract.

The diagram below shows an example of a three party business process. The port maps are shown via arrows bridging corresponding operations at the connected ports. The operations at connected ports must clearly be mirror images of each other. A notification operation at one service must appear as a one-way operation at a partner service, for the same message type. Similarly, a solicit/response operation maps to a request /response operation at a partner service. There is a small potential for ambiguity in the relationships between operations in the rare cases when a port type contains more than one operation with the same signature. This is important in automated static analysis of business protocols based on XLANG contract descriptions, and will be addressed in a future version of XLANG.

Finally, any set of operations that belongs to a single correlation group in one service and corresponds to operations in a single other service must correspond to operations in a corresponding correlation group in that service. In fact, each correlation group of each service must correspond to exactly one correlation group of each partner service to which at least one of the operations in the group connects. The correlation group relationships are shown by color coding the operation arrows for the operations that belong in each correlation group.

Schematic Three Party Contract

Figure 1: Schematic Three Party Contract

As a simple example, consider the mirror image of the service described in Example 1. This is given in Example 2 below.

<?xml version="1.0"?>
<definitions name="StockQuoteUser"

  targetNamespace="http://example.com/stockquote/user"
  xmlns:tns="http://example.com/stockquote/user"
  xmlns:xlang="http://schemas.microsoft.com/biztalk/xlang/"
  xmlns="http://schemas.xmlsoap.org/wsdl/">

  <!-- WSDL type and message definitions used -->
  <!-- below have been omitted here for brevity -->

  <portType name="RequestSendPortType">
    <documentation>
      This port sends an asynchronous message requesting
      the price of the given stock.
    </documentation>
    <operation name="FetchLastTradePrice">
      <output message="..."/>
    </operation>
  </portType>

  <portType name="ResponseReceivePortType">
    <documentation>
      This port receives an asynchronous message providing
      the price of the given stock.
    </documentation>
    <operation name="ReceiveLastTradePrice">
      <input message="..."/>
    </operation>
  </portType>

  <binding name="RequestSendPortBinding" 
    type="tns:RequestSendPortType">
    <!-- details omitted -->
  </binding>

  <binding name="ResponseReceivePortBinding" 
    type="tns:ResponseReceivePortType">
    <!-- details omitted -->
  </binding>

  <service name="StockQuoteUserService">

    <port name="pSendRequest" binding="tns:RequestSendPortBinding">
      <soap:address location="mailto:quote@example1.com"/>
    </port>

    <port name="pGetResponse" binding="tns:ResponseReceivePortBinding">
      <soap:address location="mailto:response@example2.com"/>
    </port>

    <xlang:behavior>
      <xlang:body>
        <xlang:sequence>
          <xlang:action operation="FetchLastTradePrice" 
            port="pSendRequest" activation="true"/>
          <xlang:action operation="ReceiveLastTradePrice" 
            port="pGetResponse"/>
        </xlang:sequence>
      </xlang:body>
    </xlang:behavior>

  </service>

</definitions>

Example 2: XLANG service definition at location http://example.com/stockquote/user.xlg

In order to construct the business contract stitching the StockQuoteProviderService and the StockQuoteUserService together, we use the import mechanism of WSDL. The resulting contract is shown below.

<?xml version="1.0"?>
<definitions name="StockQuoteContract"

  targetNamespace="http://example.com/stockquote/contract"
  xmlns:tns="http://example.com/stockquote/contract"
  xmlns:xlang="http://schemas.microsoft.com/biztalk/xlang/"
  xmlns:provider="http://example.com/stockquote/provider"
  xmlns:user="http://example.com/stockquote/user"
  xmlns="http://schemas.xmlsoap.org/wsdl/">

  <!-- import the provider and user namespaces -->

  <import namespace="http://example.com/stockquote/provider"
    location="http://example.com/stockquote/provider.xlg"/>

  <import namespace="http://example.com/stockquote/user"
    location="http://example.com/stockquote/user.xlg"/>

  <xlang:contract>
    <xlang:services refs="provider:StockQuoteProviderService
      user:StockQuoteUserService"/>
    <xlang:portMap>
      <xlang:connect 
        port="provider:StockQuoteProviderService/pGetRequest"
        port="user:StockQuoteProviderService/pSendRequest"/>
      <xlang:connect 
        port="provider:StockQuoteProviderService/pSendResponse"
        port="user:StockQuoteProviderService/pGetResponse"/>
    </xlang:portMap>
  </xlang:contract>

</definitions>

14. Future Extensions

XLANG is still a work in progress. There are a number of features that we know are required but absent in the specification. We intend to extend the specification with these features in future versions. The sections below discuss a few of the salient extensions we expect to add.

14.1. Enabling Executable Business Processes

XLANG in this version is focused on description of public aspects of business processes with multiple participants. It introduces some innovations such as opaque conditions represented by QNames to allow process description using opaque decision processes. As we discussed in the Challenge of Business Protocols, such abstraction, while needed, is not sufficient to describe realistic public protocols, since public aspects of protocols may in fact involve description of actual computation with the data content of messages. For this and other reasons, it is necessary to ultimately standardize a process description language that covers the entire spectrum from purely abstract processes to fully executable processes. In this section, we discuss a few of the extensions needed to reach this goal.

An interaction that spans many operations is necessarily stateful. A service instance that represents a participant in such an interaction must have the means to maintain the state of its view of the interaction, in particular the data accumulated during the history of the interaction. The most basic part of the history is the messages received. This essentially means that we need to add state variables for messages, and when receiving a message as part of an operation, we need to specify an appropriately typed message variable to hold the data. We expect variables of the simple types allowed by XML Schema to be very useful as well. State will be scoped using contexts and lexical scopes will also coincide with lifetime scopes. The exception to this are the interesting issues regarding what state/history is available to exception handling and compensation processes. In general, "current state" is not a good answer, especially for compensation.

Just as incoming messages need to be saved, outgoing messages need to be constructed. In effect, this is a problem of merging and transforming parts of the state of the service to initialize a message variable that can be used as the staging area for the outgoing message. The use of XPath and XSLT for data extraction and transformation would be useful. Custom computation can be provided by component services described using WSDL.

Finally, abstract conditions signified by QNames are clearly inappropriate for executable processes. We anticipate the need to provide a notation for Boolean expressions based on state variables and constants of simple types.

14.2. Modular Description of Service Behavior

14.2.1. Reuse of Parameterized Behavior

XLANG as it stands works well for the description of services with relatively simple behavior. As the usage of this approach to service description matures, all the usual issues with increasingly complex service behaviors will begin to appear. Reuse of existing behavior descriptions as "subroutines" is an obvious first step. This could be accomplished by permitting the definition of parameterized service behaviors and a localCall process form analogous to a function call in traditional programming languages. A localCall would not start a new service instance. Rather, it would embed the behavior of the called service within the service instance that executes the call.

Both input and output parameters would make sense. This extension makes most sense in conjunction with executable processes, but even in the context of the present version, it is meaningful to consider passing port references and correlation sets in both directions as parameters. The semantics of port reference parameters is straightforward. A correlation set as an input parameter serves the same function inside the called service behavior as an operation that initiates a correlation group instance (by defining the actual values of the tokens in the set). Conversely, a correlation set as an output parameter serves the same function in the caller service behavior as an operation that initiates a correlation group instance (again by defining the actual values of the tokens in the set).

An interesting aspect of parameterized services is the interaction with transactions and compensation. Transactions may occur inside a called service and therefore there is need to enable compensation for each localCall. This implies a compensation process attached to the parameterized behavior and the ability to attach a label to each specific localCall so that its compensation block can be referenced. Compensation blocks themselves could be parameterized to flow data into and out of compensation processes to reflect and influence the environment during compensation.

14.2.2. Autonomous Sub-behaviors

Neither the all process form nor the localCall construct discussed above provide for truly concurrent autonomous "agents" spawned by the main service behavior to start activities that can be kept at arm's length in so far as sharing state and synchronization is concerned. This is a common feature of existing workflow systems, and is a variant of modularity that is required in many scenarios. We anticipate the introduction of a spawn primitive to explicitly initiate ("fork") a "shared nothing" service instance. The form of spawn can be expected to be quite similar to localCall except that output parameters would not be allowed. Synchronization with the termination of one or more spawned service instances (so-called join functionality) is also an interesting possibility.

Interestingly, spawn also makes explicit the functionality required for an implementation to initiate a service instance as a result of a background event rather than implicitly via an incoming operation marked for activation. Thus spawn could serve as the starting point of an explicit lifecycle management feature, which when extended could include other primitives such as suspend, resume, and terminate.

14.3. Dynamic Partner Enlistment

The ability to use port references and dynamic binding of such references to outgoing ports is useful for services that need the capability to connect dynamically to unknown operation targets. A business process may include the requirement for notifications to be sent to a dynamically specified target port via references provided dynamically by one participant to another. XLANG provides for passing and dynamic binding of port references for this purpose. However, in this case the target of an isolated port reference can rarely be thought of as a first class participant in a fully specified business process.

As regards enlistment of participants, this version of XLANG assumes static participant topologies. What this implies is that all the actual participants, including all the data for the ports they own, are statically specified before the business process in put into operation. There are cases where a business process is well defined with all the roles and their behavior fully specified as XLANG services, but the actual identity of one or more of the participants is not known before the process is put into operation. As a result, the port data for the ports owned by these participants is unspecified at the time an instance of such a process is initiated. The expectation is that each statically unfilled role will be filled by having one of the statically specified participants dynamically provide a referral to a service that confirms to the required service type. For the purposes of specifying service behavior, such a referral at a minimum requires provision of port references for the ports expected to be owned by that participant.

We expect to add the ability to dynamically enlist participants in a future version of XLANG. The basic schema for dynamic referral of a participant is therefore a list of port references, which can be provided and bound as described for individual port references. There are of course legal and other business issues that are involved in dynamic enlistment of participants, but these are outside the scope of XLANG.

15. WSDL Issues

There are some limitations and unclear aspects of WSDL 1.1 that need to be addressed to achieve the goals of XLANG. These are listed below

Ports and Port Types:

Several ports in a service may be derived from the same port type. They are treated as equivalent alternatives by WSDL. For instance, a port type may have bindings for EDI, BizTalk and ebXML message formats. Of course, a service may have ports for several port types, and each port type may support a parallel set of bindings such as the ones mentioned above. In the example, it makes sense to either use all EDI bindings, or all BizTalk bindings, etc. However, WSDL 1.1 does not offer a way to group the ports in this fashion. We may need a notion of service type instantiated into multiple alternative service forms, each of which is based on a single type of binding. It should be possible to provide this using the extensibility features of WSDL. However, for maximum interoperability, inclusion of the feature in WSDL would be desirable.

Outgoing operations:

Although WSDL provides the outgoing operations of notification and solicit/response, the definition of these operations in WSDL 1.1 is incomplete and the interpretation of some aspects is unclear. The WSDL specification [3] states:

Although the base WSDL structure supports bindings for these four transmission primitives, WSDL only defines bindings for the One-way and Request-response primitives. It is expected that specifications that define the protocols for Solicit-response or Notification would also include WSDL binding extensions that allow use of these primitives.

XLANG is clearly dependent on full specification of the outgoing operations. Moreover, the ambiguities in the interpretation of the operations themselves, and of ports involving these operations must be clarified. For instance, the notification operation can be viewed as a simple outgoing message as XLANG does, or as a publish/subscribe type of notification as the name suggests. The interpretation of the address of a port in the two cases is very different. XLANG interprets it as the address of the destination for the message. It is possible to interpret it as the address at which a subscriber could register for the notification. The two interpretations are clearly in conflict.

16. Acknowledgements

The original work on XLANG was done by Bimal Mehta, Brian Beckman, Greg Meredith, Marc Levy and Tony Andrews. The design of the current version of XLANG was done by Balinder Malhi, Bimal Mehta, Don McCrady, Johannes Klein, Marc Levy, Satish Thatte and Tony Andrews. Sreenivas Simhadri constructed the XSD schemas in the appendix and provided other valuable assistance.

17. References

[1] W3C Recommendation "The XML Specification"

[2] W3C Note "Simple Object Access Protocol (SOAP) 1.1"

[3] W3C Note "Web Services Definition Language (WSDL) 1.1"

[4] Industry Initiative "Universal Description, Discovery and Integration"

[5] W3C Activity "XML Protocol"

[6] Streetside Processing Committee Whitepaper"SIA T+1"

[7] United States Government Act "The Health Insurance Portability and Accountability Act of 1996"

[8] Standards Consortium "RosettaNet"

[9] W3C Proposed Recommendation "XML Schema Part 1: Structures"

[10] W3C Proposed Recommendation "XML Schema Part 2: Datatypes"

[11] BizTalk "BizTalk Framework 2.0: Document and Message Specification"

Appendix A - XSD Schema

<schema xmlns="http://www.w3.org/2000/10/XMLSchema"
  xmlns:xlang="urn:schemas-microsoft-com:xlang"
  targetNamespace="urn:schemas-microsoft-com:xlang"
  elementFormDefault="qualified">


  <!-- ==================================================================== -->


  <annotation>
    <documentation>
      Optional documentation element used as first child of xlang elements.
    </documentation>
  </annotation>

  <element name="documentation">
    <complexType mixed="true">
      <choice minOccurs="0" maxOccurs="unbounded">
        <any minOccurs="0" maxOccurs="unbounded"/>
      </choice>
      <anyAttribute/>
    </complexType>
  </element>
  <complexType name="documented" abstract="true">
    <sequence>
      <element ref="xlang:documentation" minOccurs="0" maxOccurs="1"/>
    </sequence>
  </complexType>


  <!-- ==================================================================== -->


  <annotation>
    <documentation>
      behavior := BEHAVIOR body
      body := BODY headerProcess
    </documentation>
  </annotation>

  <element name="behavior" type="xlang:behaviorType"/>
  <complexType name="behaviorType">
    <complexContent>
      <extension base="xlang:documented">
        <sequence>
          <element name="body" type="xlang:headerProcessType" 
            minOccurs="1" maxOccurs="1"/>
        </sequence>
      </extension>
    </complexContent>
  </complexType>

  <annotation>
    <documentation>
      headerProcess := header? process
    </documentation>
  </annotation>
  <complexType name="headerProcessType">
    <complexContent>
      <extension base="xlang:documented">
        <sequence>
          <element name="header" type="xlang:headerType" 
            minOccurs="0" maxOccurs="1"/>
          <group ref="xlang:processGroup" 
            minOccurs="1" maxOccurs="1"/>
        </sequence>
      </extension>
    </complexContent>
  </complexType>

  <annotation>
    <documentation>
      header := HEADER localDecls
      localDecls := LOCAL decls
      decls := portReferenceDecl* correlationSetDecl*
    </documentation>
  </annotation>

  <complexType name="headerType">
    <complexContent>
      <extension base="xlang:documented">
        <sequence>
          <element name="local" type="xlang:decls" 
            minOccurs="0" maxOccurs="1"/>
        </sequence>
      </extension>
    </complexContent>
  </complexType>

  <complexType name="decls">
    <complexContent>
      <extension base="xlang:documented">
        <sequence>
          <element name="portReferenceDecl" type="xlang:portInformation" 
            minOccurs="0" maxOccurs="unbounded"/>
          <element name="correlationSetDecl" 
            type="xlang:correlationSetDeclType" 
            minOccurs="0" maxOccurs="unbounded"/>
        </sequence>
      </extension>
    </complexContent>
  </complexType>


  <!-- ==================================================================== -->

  <annotation>
    <documentation>
      portReferenceDecl := portReference URI
    </documentation>
  </annotation>
  <complexType name="portInformation">
    <attribute name="portReference" type="anyUri" use="required"/>
  </complexType>

  <element name="propertyRef">
    <complexType>
      <attribute name="name" type="QName" use="required"/>
    </complexType>
  </element>


  <annotation>
    <documentation>
      correlationSetDecl := correlationSetDecl name propertyRef+
      name := NCName
      propertyRef := propertyRef QName
    </documentation>
  </annotation>
  <complexType name="correlationSetDeclType">
    <sequence>
      <element ref="xlang:propertyRef" minOccurs="1" maxOccurs="unbounded"/>
    </sequence>
    <attribute name="name" type="NCName" use="required"/>
  </complexType>


  <!-- ==================================================================== -->

  <annotation>
    <documentation>
      action := operation | delay | raise
      delay := delayFor | delayUntil
    </documentation>
  </annotation>
  <group name="actionGroup">
    <choice>
      <element ref="xlang:operation"/>
      <element ref="xlang:raise"/>
      <element ref="xlang:delayFor"/>
      <element ref="xlang:delayUntil"/>
    </choice>
  </group>


  <complexType name="agentBaseType" abstract="true">
    <!-- stuff common to all agents -->
    <complexContent>
      <extension base="xlang:documented">
        <attribute name="comment" type="string" use="optional"/>
      </extension>
    </complexContent>
  </complexType>

  <complexType name="actionBaseType" abstract="true">
    <!-- stuff common to all actions -->
    <complexContent>
      <extension base="xlang:agentBaseType">
      </extension>
    </complexContent>
  </complexType>


  <!-- ==================================================================== -->

  <annotation>
    <documentation>
      operation := action operationRef portRef activation? correlationBegin? correlationSetRef* portDescription*
      correlationSetRef := CORRELATION setNames
      correlationBegin := CORRELATIONBEGIN setNames 
      operationRef := OPERATION NCName
      setNames := NCNameList
    </documentation>
  </annotation>

  <complexType name="correlationBeginType">
    <attribute name="correlationBegin" type="NCName" use="required"/>
    <sequence>
      <element ref="xlang:correlationSetRef" minOccurs="1" maxOccurs="unbounded"/>
    </sequence>
  </complexType>

  <complexType name="operationRef">
    <attribute name="operation" type="NCName" use="required"/>
  </complexType>

  <element name="action">
    <complexType>
      <complexContent>
        <extension base="xlang:actionBaseType">
          <sequence>
            <element ref="xlang:operationRef" minOccurs="1" maxOccurs="1"/>
            <element ref="xlang:portRef" minOccurs="1" maxOccurs="1"/>
            <element ref="xlang:correlationBeginType" 
              minOccurs="0" maxOccurs="1"/>
            <element ref="xlang:portDescription" 
              minOccurs="1" maxOccurs="unbounded"/>
          </sequence>
          <attribute name="activation" type="boolean"/>
        </extension>
      </complexContent>
    </complexType>
  </element>



  <!-- ==================================================================== -->

  <annotation>
    <documentation>
      delayFor := DELAYFOR QName
      delayUntil := DELAYUNTIL QName
    </documentation>
  </annotation>
  <element name="delayFor">
    <complexType>
      <complexContent>
        <extension base="xlang:actionBaseType">
          <attribute name="period" type="QName" />
        </extension>
      </complexContent>
    </complexType>
  </element>

  <element name="delayUntil">
    <complexType>
      <complexContent>
        <extension base="xlang:actionBaseType">
          <attribute name="clock" type="QName" />
        </extension>
      </complexContent>
    </complexType>
  </element>


  <!-- ==================================================================== -->

  <annotation>
    <documentation>
      raise := raise QName? 
    </documentation>
  </annotation>
  <element name="raise">
    <complexType>
      <complexContent>
        <extension base="xlang:actionBaseType">
          <attribute name="signal" type="QName" use="required"/>
        </extension>
      </complexContent>
    </complexType>
  </element>

  <!-- ==================================================================== -->

  <annotation>
    <documentation>
      process := empty | sequence | switch | pick | all | while 
      | context | compensate
    </documentation>
  </annotation>
  <group name="processGroup">
    <choice>
      <element ref="xlang:empty"/>
      <element ref="xlang:sequence"/>
      <element ref="xlang:switch"/>
      <element ref="xlang:pick"/>
      <element ref="xlang:all"/>
      <element ref="xlang:while"/>
      <element ref="xlang:context"/>
      <element ref="xlang:compensate"/>
    </choice>
  </group>

  <complexType name="processBaseType" abstract="true">
    <!-- stuff common to all processes go here -->
    <complexContent>
      <extension base="xlang:agentBaseType">
        <attribute name="expanded" type="boolean" use="optional" default="true"/>
      </extension>
    </complexContent>
  </complexType>

  <!-- ==================================================================== -->

  <annotation>
    <documentation>
      empty := EMPTY
    </documentation>
  </annotation>
  <element name="empty">
    <complexType>
      <complexContent>
        <restriction base="xlang:processBaseType"/>
      </complexContent>
    </complexType>
  </element>

  <!-- ==================================================================== -->

  <annotation>
    <documentation>
      sequence := SEQUENCE [action | process ]* 
    </documentation>
  </annotation>
  <element name="sequence">
    <complexType>
      <complexContent>
        <extension base="xlang:processBaseType">
          <choice minOccurs="0" maxOccurs="unbounded">
            <group ref="xlang:actionGroup" />
            <element ref="xlang:empty"/>
            <element ref="xlang:sequence"/>
            <element ref="xlang:switch"/>
            <element ref="xlang:pick"/>
            <element ref="xlang:all"/>
            <element ref="xlang:while"/>
            <element ref="xlang:context"/>
            <element ref="xlang:compensate"/>
          </choice>
        </extension>
      </complexContent>
    </complexType>
  </element>

  <!-- ==================================================================== -->

  <annotation>
    <documentation>
      pick := PICK eventHandler+
      eventHandler := EVENTHANDLER event process
      event := delayFor | delayUntil | operation | catch
      catch := catch QName
    </documentation>
  </annotation>
  <element name="catch">
    <complexType>
      <complexContent>
        <extension base="xlang:processBaseType">
          <attribute name="catch" type="QName" use="required"/>
        </extension>
      </complexContent>
    </complexType>
  </element>

  <complexType name="eventHandlerType">
    <complexContent>
      <extension base="xlang:documented">
        <sequence>
          <choice minOccurs="1" maxOccurs="1">
            <element ref="xlang:delayFor"/>
            <element ref="xlang:delayUntil"/>
            <element ref="xlang:operation"/>
            <element ref="xlang:catch"/>
          </choice>
          <choice minOccurs="1" maxOccurs="1">
            <element ref="xlang:empty"/>
            <element ref="xlang:sequence"/>
            <element ref="xlang:switch"/>
            <element ref="xlang:pick"/>
            <element ref="xlang:all"/>
            <element ref="xlang:while"/>
            <element ref="xlang:context"/>
            <element ref="xlang:compensate"/>
          </choice>
        </sequence>
      </extension>
    </complexContent>
  </complexType>

  <element name="pick">
    <complexType>
      <complexContent>
        <extension base="xlang:processBaseType">
          <sequence>
            <element name="eventHandler" type="xlang:eventHandlerType" 
              minOccurs="1" maxOccurs="unbounded"/>
          </sequence>
        </extension>
      </complexContent>
    </complexType>
  </element>


  <!-- ==================================================================== -->

  <annotation>
    <documentation>
      all := ALL (process)*
    </documentation>
  </annotation>
  <element name="all">
    <complexType>
      <complexContent>
        <extension base="xlang:processBaseType">
          <choice minOccurs="0" maxOccurs="unbounded">
            <element ref="xlang:empty"/>
            <element ref="xlang:sequence"/>
            <element ref="xlang:switch"/>
            <element ref="xlang:pick"/>
            <element ref="xlang:all"/>
            <element ref="xlang:while"/>
            <element ref="xlang:context"/>
            <element ref="xlang:compensate"/>
          </choice>
        </extension>
      </complexContent>
    </complexType>
  </element>

  <!-- ==================================================================== -->

  <annotation>
    <documentation>
      switch := SWITCH branch* default? 
    </documentation>
  </annotation>
  <element name="switch">
    <complexType>
      <complexContent>
        <extension base="xlang:processBaseType">
          <sequence>
            <element name="branch" type="xlang:branchType" 
              minOccurs="0" maxOccurs="unbounded"/>
            <element name="default" type="xlang:defaultType" 
              minOccurs="0" maxOccurs="1"/>
          </sequence>
        </extension>
      </complexContent>
    </complexType> 
  </element>

  <annotation>
    <documentation>
      branch := BRANCH case process 
    </documentation>
  </annotation>
  <complexType name="branchType">
    <complexContent>
      <extension base="xlang:documented">
        <sequence>
          <element name="case" type="xlang:caseType" 
            minOccurs="1" maxOccurs="1"/>
          <choice minOccurs="1" maxOccurs="1">
            <element ref="xlang:empty"/>
            <element ref="xlang:sequence"/>
            <element ref="xlang:switch"/>
            <element ref="xlang:pick"/>
            <element ref="xlang:all"/>
            <element ref="xlang:while"/>
            <element ref="xlang:context"/>
            <element ref="xlang:compensate"/>
          </choice>
        </sequence>
      </extension>
    </complexContent>
  </complexType>

  <annotation>
    <documentation>
      case := CASE QName
    </documentation>
  </annotation>
  <complexType name="caseType">
    <complexContent>
      <extension base="xlang:documented">
        <attribute name="case" type="QName" use="required"/>
      </extension>
    </complexContent>
  </complexType>

  <annotation>
    <documentation>
      default := DEFAULT process
    </documentation>
  </annotation>
  <complexType name="defaultType">
    <complexContent>
      <extension base="xlang:documented">
        <choice minOccurs="1" maxOccurs="1">
          <element ref="xlang:empty"/>
          <element ref="xlang:sequence"/>
          <element ref="xlang:switch"/>
          <element ref="xlang:pick"/>
          <element ref="xlang:all"/>
          <element ref="xlang:while"/>
          <element ref="xlang:context"/>
          <element ref="xlang:compensate"/>
        </choice>
      </extension>
    </complexContent>
  </complexType>

  <!-- ==================================================================== -->

  <annotation>
    <documentation>
      while := WHILE case process 
    </documentation>
  </annotation>
  <element name="while">
    <complexType>
      <complexContent>
        <extension base="xlang:processBaseType">
          <sequence>
            <element name="case" type="xlang:caseType" 
              minOccurs="1" maxOccurs="1"/>
            <choice minOccurs="1" maxOccurs="1">
              <element ref="xlang:empty"/>
              <element ref="xlang:sequence"/>
              <element ref="xlang:switch"/>
              <element ref="xlang:pick"/>
              <element ref="xlang:all"/>
              <element ref="xlang:while"/>
              <element ref="xlang:context"/>
              <element ref="xlang:compensate"/>
            </choice>
          </sequence>
        </extension>
      </complexContent>
    </complexType> 
  </element>

  <!-- ==================================================================== -->

  <annotation>
    <documentation>
      context := CONTEXT localDecls? process transaction? exception? 
      transaction := TRANSACTION txnid compensation? 
      tnxid := name NCName
      compensation := COMPENSATION process
      exception := EXCEPTION pick finally?
      finally := FINALLY process
    </documentation>
  </annotation>
  <element name="finally">
    <complexType>
      <extension base="xlang:documented">
        <choice minOccurs="1" maxOccurs="1">
          <element ref="xlang:empty"/>
          <element ref="xlang:sequence"/>
          <element ref="xlang:switch"/>
          <element ref="xlang:pick"/>
          <element ref="xlang:all"/>
          <element ref="xlang:while"/>
          <element ref="xlang:context"/>
          <element ref="xlang:compensate"/>
        </choice>
      </extension>
    </complexType>
  </element>

  <element name="exception">
    <complexType>
      <sequence>
        <element ref="xlang:pick" minOccurs="1" maxOccurs="1"/>
        <element ref="xlang:finally" minOccurs="0" maxOccurs="1"/>
      </sequence>
    </complexType> 
  </element>


  <element name="compensation">
    <complexContent>
      <extension base="xlang:documented">
        <choice minOccurs="1" maxOccurs="1">
          <element ref="xlang:empty"/>
          <element ref="xlang:sequence"/>
          <element ref="xlang:switch"/>
          <element ref="xlang:pick"/>
          <element ref="xlang:all"/>
          <element ref="xlang:while"/>
          <element ref="xlang:context"/>
          <element ref="xlang:compensate"/>
        </choice>
      </extension>
    </complexContent>
  </element>

  <element name="transaction">
    <sequence>
      <element name="compensation" type="xlang:compensationType" minOccurs="0" maxOccurs="1"/>
    </sequence>
    <attribute name="name" type="NCName" use="required"/>
  </element>

  <element name="context">
    <complexType>
      <complexContent>
        <extension base="xlang:processBaseType">
          <sequence>
            <element name="local" type="xlang:localDeclsType" 
              minOccurs="0" maxOccurs="1"/>
            <choice minOccurs="1" maxOccurs="1">
              <element ref="xlang:empty"/>
              <element ref="xlang:sequence"/>
              <element ref="xlang:switch"/>
              <element ref="xlang:pick"/>
              <element ref="xlang:all"/>
              <element ref="xlang:while"/>
              <element ref="xlang:context"/>
              <element ref="xlang:compensate"/>
            </choice>
            <element ref="xlang:transaction" minOccurs="0" maxOccurs="1"/>
            <element ref="xlang:exception" minOccurs="0" maxOccurs="1"/>
          </sequence>
        </extension>
      </complexContent>
    </complexType> 
  </element>

  <annotation>
    <documentation>
      compensate := COMPENSATE txn-id
    </documentation>
  </annotation>
  <element name="compensate">
    <complexType>
      <complexContent>
        <extension base="xlang:processBaseType">
          <attribute name="name" type="NCName" use="required"/>
        </extension>
      </complexContent>
    </complexType> 
  </element>


</schema>