XLANG
dvanhorn <[email protected]>
| Newsgroups | gmane.org.ballistichelmet.lambda |
|---|---|
| Message-ID | <[email protected]> |
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.
* Sequential and parallel control flow constructs
* Long running transactions with compensation
* Custom correlation of messages
* Flexible handling of internal and external exceptions
* Modular Behavior Description
* Dynamic service referral
* Multi-role contracts
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-OD3anDwflP9Wk0Htik3J/[email protected]"/>
</port>
<port name="pSendResponse" binding="tns:ResponseSendPortBinding">
<soap:address location="mailto:response-YXepAh3jYkxWk0Htik3J/[email protected]"/>
</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.
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-OD3anDwflP9Wk0Htik3J/[email protected]"/>
</port>
<port name="pGetResponse" binding="tns:ResponseReceivePortBinding">
<soap:address location="mailto:response-YXepAh3jYkxWk0Htik3J/[email protected]"/>
</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>