W3C

Web Services Choreography Description Language Version 1.0

W3C Candidate Recommendation 9 November 2005

This version:
http://www.w3.org/TR/2005/CR-ws-cdl-10-20051109/
Latest version:
http://www.w3.org/TR/ws-cdl-10/
Previous version:
http://www.w3.org/TR/2004/WD-ws-cdl-10-20041217/
Editors:
Nickolas Kavantzas, Oracle
David Burdett, Commerce One
Gregory Ritzinger, Novell
Tony Fletcher, Choreology
Yves Lafon, W3C
Charlton Barreto, Adobe Systems Incorporated

摘要

Web 服务编排描述语言 (Web Services Choreography Description Language, WS-CDL) 是一种基于 XML 的语言, 用于从全局观点描述一组参与方 (participant) 的点对点协作, 描述有关参与方的公共的或互补的行为. 这些参与方按特定顺序进行消息交换, 共同完成某一公共业务目标.

Web 服务规范为异质计算环境中开发或运行应用系统提供相互通讯的通道. E-Business 应用的未来有赖于多个参与方服务一起执行长时的点对点合作的功能, 可能在一个组织的置信域内, 也可能跨越不同置信域.

Web 服务编排规范规范的目标是为了组合任意类型的多个参与方之间的, 可互操作的点对点合作 (peer-to-peer collaborations), 无论其宿主环境的实现所使用的支撑平台 (supporting platform) 或编程模型如何.

本文档的状态 (Status)

本节描述这一文档在其出版之日的状态. 其他文档可能取代这一文档. 有关当前 W3C 出版物的列表和本技术报告的最新版本可以在 http://www.w3.org/TR/ 的 W3C technical reports index 找到.

本文档是 "Web Services Choreography Description Language, Version 1.0" 的 2005 年 11 月 9 日的 W3C 候选建议书. W3C 将一个技术报告作为候选建议书出版, 表明该文档已被认为是稳定的, 鼓励开发社团进行实现. 候选建议书状态在 Process Document 的 7.1.1 节描述. 有关意见请发送到 public-ws-chor-comments@w3.org (公开文档, public archive). 请勿向该地址发送讨论问题的 email.

有关本文档的讨论在公开的 public-ws-chor@w3.org mailing list (公开文档) 有关 email 通讯规则由 Web Services Choreography Working Group 管理.

本文档出自 Web Services Choreography Working Group, 它是 Web Services Activity 的一个组成部分.

本文档由 Web Services Choreography Working Group 特许发布. 有关问题记录在该组的 issue section.

本文档基于 2004 年 12 月 12 日最后公布的工作稿. 两个版本之间的修改在 diff document 描述.

在这一建议书阶段特别希望得到具有如下特征的批评建议:
必须 有示例表现 WS-CDL 的关键性特征, 这些示例:

这里的 "合法 WS-CDL" 表示它在 schema 方面和 WS-CDL 的操作语义方面都符合本规范.
这里 "实现" 表示处理 WS-CDL 文档并生成端点的工具.
这里 "端点" 表示一个 web 服务.
这里 "平台" 表示一种支持 web 服务运行的软件栈功能.
这里 "互操作" 表示两个 web 服务扮演至少两个不同角色.
互操作性关注各种实现细节, 例如校准协议, 合作协议和定址.

细节实现需求和对参与方的邀请在 Implementation Report Plan 的实现报告处提供.

This document has been produced under the 24 January 2002 CPP as amended by the W3C Patent Policy Transition Procedure. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) with respect to this specification should disclose the information in accordance with section 6 of the W3C Patent Policy. Patent disclosures relevant to this specification may be found on the Working Group's patent disclosure page.

作为候选建议书出版并不意味着得到 W3C 成员们的认可. 这仍是一个草稿文档, 可能在任何时候被其他文档更新, 取代或者变为过时文档. 本文档是一项正在进行中的工作, 以其他方式引证本文档都是不合适的.

目录

1 引言
    1.1 记法约定
    1.2 WS-CDL 的作用
    1.3 目标
    1.4 与 XML 和 WSDL 的关系
    1.5 与业务进程语言 (Business Process Languages) 的关系
    1.6 时间假设
    1.7 信任 Schema (Authoritative Schema)
2 WS-CDL 模型概览
3 WS-CDL 文档结构
    3.1 编排包 (Choreography Package)
    3.2 包含 WS-CDL 类型定义
    3.3 WS-CDL 文档命名和链接
    3.4 语言扩充
    3.5 语义
4 合作的参与方 (Collaborating Participants)
    4.1 角色类型 (RoleType)
    4.2 关系类型 (RelationshipType)
    4.3 参与方类型 (ParticipantType)
    4.4 通道类型 (ChannelType)
5 信息驱动的合作 (Information Driven Collaborations)
    5.1 信息类型 (InformationType)
    5.2 变量
    5.3 表达式
        5.3.1 WS-CDL 提供的函数 (Supplied Functions)
    5.4 单词和单词定位符 (Token and TokenLocator)
    5.5 编排 (Choreography)
    5.6 工作单元 (WorkUnit)
    5.7 编排的生命线 (Choreography Life-line)
    5.8 编排的异常处理(Choreography Exception Handling)
    5.9 编排的终结 (Choreography Finalization)
    5.10 编排的协调 (Choreography Coordination)
6 活动 (Activities)
    6.1 序结构 (Ordering Structures)
        6.1.1 顺序 (Sequence)
        6.1.2 并行 (Parallel)
        6.1.3 选择 (Choice)
    6.2 交互 (Interacting)
        6.2.1 基于交互的信息校准 (Interaction Based Information Alignment)
        6.2.2 交互的生命线 (Interaction Life-line)
        6.2.3 交互的语法 (Interaction Syntax)
    6.3 组合编排 (Composing Choreographies)
    6.4 变量赋值 (Assigning Variables)
    6.5 标出的无声操作 (Marking Silent Actions)
    6.6 标出的无操作 (Marking the Absence of Actions)
    6.7 一个编排的终结 (Finalizing a Choreography)
7 与其他规范的互作用 (Interoperability with other Specifications)
    7.1 与安全性框架的互作用 Interoperability with Security frameworks
    7.2 与可靠消息框架的互作用 (Interoperability with Reliable Messaging frameworks)
    7.3 与协调框架的互作用 (Interoperability with Coordination frameworks)
    7.4 与寻址框架的互作用 (Interoperability with Addressing frameworks)
8 符合性 (Conformance)
    8.1 符合 WS-CDL 文档 (Conforming WS-CDL documents)
    8.2 端点符合性 (Endpoint conformance)
9 致谢
10 参考文献 (References)
    10.1 官方参考文献 (Normative References)
    10.2 非官方的参考文献 (Informative References)

附录

A Mime 类型定义 (Mime Type definition)
B WS-CDL 的 XSD Schemas


1 引言

多年以来, 许多组织都为其自己的自动化点对点合作开发解决方案, 可能是在其置信域 (trusted domain) 内的, 或跨越不同的置信域, 目的是提高生产率或降低操作成本.

近年, 可扩展标记语言 (XML) 和 Web 服务框架正在发展成为独立于业务接口的, 描述可互操作数据和平台的事实选择标准, 因为它们更有利于开放性的业务事务 (business transactions) 的开发.

在正处于发展中的松耦合的基于 Web 的计算框架中, Web 服务是最关键的部分. 一个 Web 服务是一个自主的基于标准的组件, 其公开接口用 XML 定义并描述. 其他系统可以按 Web 服务定义所描述好的方式, 通过互联网协议传递基于 XML 的消息与之交互.

Web 服务规范为异质计算环境中开发或运行应用系统提供相互通讯的通道. E-Business 应用的未来有赖于多个参与方服务一起执行长时的点对点合作的功能, 可能在一个组织的置信域内, 也可能跨越不同置信域.

Web 服务体系结构栈的目标是集成由下述组件构成的交互式应用:

Web 服务编排规范的目标是组合任意类型的参与方之间的可互操作的协作, 无论其实现所用宿主环境的支持平台或编程模型是什么. 一个编排描述就是一个多参与方的合约, 它从一种全局观点描述了这一组合. Web 服务编排描述语言 (Web Services Choreography Description Language, WS-CDL) 是描述这种技术合约的方法.

1.1 记法约定

本文档里的关键字 "必须", "必须不", "需要", "", "将不", "应该", "不应该", "建议", "可以" 和 "可选" 采用 RFC-2119 [RFC2119] 的解释.

下面名字空间前缀在本文档里通篇使用:

本规范里使用的前缀和名字空间
前缀 名字空间 URI 定义
wsdl http://www.w3.org/2005/08/wsdl WSDL 2.0 的 WSDL 框架的名字空间.
cdl http://www.w3.org/2005/10/cdl 用于 Choreography Description Language 的 WSCDL 名字空间.
xsi http://www.w3.org/2001/XMLSchema-instance XSD [XMLSchemaP1] 定义的实例名字空间.
xsd http://www.w3.org/2001/XMLSchema XSD [XMLSchemaP2] 定义的 Schema 名字空间.
tns (各种情况) 名字空间前缀 tns (表示 this namespace) 作为引用当前文档的方便形式.
rns (各种情况) 用于引用一个 (示例和假设的) WSDL 接口描述的名字空间前缀.
(其他) (各种情况) 其他名字空间前缀只是例子. 特别的, 以 "http://www.example.com" 开头的 URI 代表某个与具体应用或具体上下文有关的 URI [RFC2396].

本规范采用一种 非形式的语法 描述 WS-CDL 文档的 XML 文法:

  • 该语法以 XML 实例的形式出现, 但其中的值表示的是数据类型而不是值

  • 元素或属性后附加字符的意义如下: "?" (0 或 1), "*" (0 或多), "+" (1 或多).

  • 以 ". . ." 结束的元素 (例如 "<element. . ./>" 或 "<element. . .>") 表明被忽略的元素/属性与上下文无关.

  • 用黑体的文法表示在文档前面没介绍过, 或者只是在例子里考虑过.

  • "<-- extensibility element -->" 是来自 "其他" 名字空间的元素的占位符 (就像 XSD 里的 ##other).

  • XML 名字空间前缀 (如上面定义) 用于指明被定义元素的名字空间.

  • 以 "<?xml" 开头的元素包含了符合本规范的足够信息; 其他元素只是片段, 需要增加一些信息才能符合本规范

第 11 节提供了 WS-CDL 文法的 XSD 形式定义.

如果在本规范的正文, 非形式的 schema 片段与附录中的完全形式化的 schema 之间有任何不一致, 那就是本规范里的一个错误. 如发现这样的错误请通知 W3C. 在问题未解决之前, 正文描述优先于附录中的形式化 schema, 而形式化 schema 又优先于非形式化的 schema 片段.

1.2 WS-CDL 的用途

各种业务活动或者其他涉及到不同组织或多个独立过程的活动, 都要求为达到某种共同的业务目标而合作, 例如 Order Fulfillment (按顺序履行约定).

为使各种合作工作取得成功, 必须制定参与交互的所有参与方之间的活动规则. 然而, 今天这些规则通常是用自然语言写的, 用于精确定义这类交互行为, 为参与方提供各自责任的无歧义文档的标准方式尚且不存在.

WS-CDL 规范的设计目标就是能精确描述任何类型的参与方之间的合作, 无论其实现所用的宿主环境的支持平台或编程模型是什么.

采用 WS-CDL 规范做出的一个合约是一个有关信息交换的公共顺序性条件和约束的 "全局" 定义, 它以全局观点描述了所有参与方的公共的和互补的可观察行为. 各个参与方可以根据这一全局定义构造和测试与之相符的解决方案. 该全局规范转而由这样得到的局部系统的组合在适当基础设施的支持下实现.

与基于任一端点 (endpoint) 的观点不同, 基于全局观点的合约的优势, 就在于它分离了一个 "控制域" (一个端点) 内部的业务或系统必须遵守的整体 "全局" 过程, 和这些业务或系统与其他方交换信息的序列的定义. 这意味着, 只要 "可观察的" 序列没有改变, 无论一个控制域 (端点) 的内部规则和逻辑如何根据需要改变, 互操作性仍能得到保证.

在现实世界的场景中, 法人实体通常不愿意把对自己业务过程的控制权委托给它们的集成合作方. 编排的思想提供了一种途径, 通过它, 各个实体可能以合作方式共同定义出一套清晰的参与规则, 而后各自根据公共全局观点确定的编排实现其中自己的那个部分. WS-CDL 中还希望表述这些实现与其公共观点的相符性, 使之能够方便地检查.

下图展示了 WS-CDL 的一个可能应用.

Integrating Web Services based applications using WS-CDL

在图 1 里, A 公司和 B 公司希望基于一些应用集成它们的 Web 服务. 两公司各自的业务分析师首先就合作中涉及到的服务, 这些服务之间的交互, 以及这些交互发生的公共顺序和约束规则等达成共识. 而后他们编写出一个 WS-CDL 表述. 在这个示例里, 他们用编排来描述保证跨业务体的服务之间互操作性的交互过程, 但把实际的实现决策留给各公司自己考虑:

  • 公司 "A" 基于一个 WS-BPEL [WSBPEL] 解决方案实现编排中自己的部分

  • 公司 "B" 由于自身已有的系统集成的需要, 在实现编排中自己的部分时, 基于一个 J2EE [J2EE] 解决方案, 其中结合了 Java 和 Enterprise Java Bean Components, 或用一个结合 C# 的 .NET [C#S] 解决方案

类似的, 编排也可用于描述一个业务体内部的各种服务之间的互操作和交互.

1.3 目标

WS-CDL 规范的基本目标是定义一种基于 XML 的说明性语言, 用于从全局观点定义公共的互补的可观察行为, 特别是其中出现的信息交换, 以及必须满足的多方同意的顺序规则.

说的更细致些, WS-CDL 规范的目标是得到:

  • 可重用性. 同一个编排定义可以用于不同的参与方, 这些参与方可能在不同的上下文环境 (行业, 地点等) 中使用不同的软件 (例如应用软件) 工作

  • 合作. 编排通过描述两个 (或多个) 独立参与方或进程应如何协作的方式, 定义它们之间交换消息的序列

  • 多方合作. 可以定义涉及任意多个参与方或进程的编排

  • 语义. 在编排里可以包含有关编排中所有组件的可供人阅读的文档和语义

  • 可组合性. 已有编排可以组合起来, 构成可以在不同的上下文中重用的新编排

  • 模块化. 提供一种 "包含" 功能, 使人可以基于多个不同编排里的一些部分创建新的编排

  • 信息驱动的合作. 编排描述多个参与方如何在合作中取得进展, 记录使顺序性约束得以履行并取得进展的过程中的可观察的交换信息和变化

  • 信息校准 (Alignment). 编排使参与该编排的各方可以相互通讯并能同步其可观察信息

  • 异常处理. 编排可以定义在编排执行中出现的异常或非常见的条件应该如何处理

  • 事务性. 参与编排的进程或参与方可以按某种 "事务" 的方式工作, 以便在长时合作的结果方面相互协作. 这种长时合作可以涉及多个参与方, 各方有自己的不可观察的业务规则和目标

  • 规范的可组合性. 本规范意在与其他许多规范一起使用或互相补充, 例如 WS-Reliability [WSRM], WS-Composite Application Framework (WS-CAF) [WSCAF], WS-Security [WSS], Business Process Execution Language for WS (WS-BPEL) [WSBPEL], ebXML Business Process Specification Schema [ebBP20], [BPSS11], 等等.

1.4 与 XML 和 WSDL 的关系

WS-CDL 规范依赖于下述规范: XML 1.0 [XML], XML-Namespaces [XMLNS], XML-Schema 1.0 [XMLSchemaP1], [XMLSchemaP2] 和 XPath 1.0 [XPTRF]. 支持 WSDL 2.0 [WSDL20] 里包含和引用的服务定义是 WS-CDL 规范的一个标准部分. 此外, 支持 WSDL 1.1 里给出的作为 WS-I Basic Profile [BP11] 限制的包含和引用的服务定义也是 WS-CDL 规范的标准部分.

1.5 与业务处理语言的关系

WS-CDL 不是 "可执行的业务过程描述语言", 也不是实现语言. 描述应用系统中执行逻辑的工作由 [XLANG], [WSFL], [WSBPEL], [BPML], [XPDL], [JLS], [C#S] 或其他规范处理.

WS-CDL 不依赖于任何特定的业务过程实现语言. 这使它可以描述真正可互操作的任何类型的参与方之间的合作, 不论支撑平台或编程模型使用哪种宿主环境实现. WS-CDL 可以与其他语言结合, 如那些提供了进一步的可计算语义定义的语言.

符合一个 WS-CDL 合作描述的各参与方可以用完全不同的机制实现, 例如:

  • 应用系统, 基于某种可执行业务过程语言实现, 如 [XLANG], [WSFL], [WSBPEL], [BPML], [XPDL]

  • 应用系统, 基于通用编程语言实现, 如 [JLS], [C#S]

  • 或者人控制的软件代理

1.6 有关时间的假定

WS-CDL 技术规范里没有描述时钟同步, 将其看作是与具体设计有关的事项. 在所涉及的参与方所在的特定环境里, 可以合理地假定所有参与方在每一秒的时间边界上良好同步. 除此之外, 这里没有定义参与方内部或参与方之间的更细粒度的时间同步, 或者其他支持或控制, 认为这些超出了 WS-CDL 规范的范围.

1.7 信任 Schema (Authoritative Schema)

如果在 WS-CDL 片段和附录中给出的完整 schema 之间出现任何歧义或不一致, 总以完整 schema 为准.

2 WS-CDL 模型概览

WS-CDL 描述多个参与方之间可互操作的点对点合作. 为了有利于这种合作, 各个服务需要通过建立形式化的关系而承诺相互间的责任. 服务间的合作表现为对一集顺序和约束规则的共识, 有关参与方根据这些共识进行各种信息交换.

WS-CDL 模型由下列成分组成:

3 WS-CDL 文档结构

一个 WS-CDL 文档也就是一组定义. 每个定义是一个有名字的可以被引用的构造. 有一个 包(package) 元素作为根, 里面是一些独立的编排类型定义.

3.1 编排的包

一个 编排的包 汇集了一组 WS-CDL 类型定义, 为这些定义提供一个名字空间, 通过使用 XInclude [XInclude], 可以 语法地将其它编排包里的定义的 WS-CDL 类型定义包含进来.

的语法结构是:

<package  
   name="NCName" 
   author="xsd:string"?
   version="xsd:string"?
   targetNamespace="uri"
    xmlns="http://www.w3.org/2005/10/cdl">

   <informationType/>*
   <token/>*
   <tokenLocator/>*
   <roleType/>*
   <relationshipType/>*
   <participantType/>*
   <channelType/>*

   Choreography-Notation*
</package>

一个编排包包含下列 WS-CDL 类型定义:

  • 零个或多个 informationTypes

  • 零个或多个 tokens 及 token locators

  • 零个或多个 roleTypes

  • 零个或多个 relationshipTypes

  • 零个或多个 participantTypes

  • 零个或多个 channelTypes

  • 零个或多个包级别的编排

最高层属性 name, authorversion 定义这个编排文档的版权信息.

属性 targetNamespace 为本编排包中的所有 WS-CDL 类型定义关联一个名字空间, 通过使用包含机制 (inclusion mechanism), 还 可以 把这个包里的 WS-CDL 定义关联于其它名字空间.

元素 informationType, token, tokenLocator, roleType, relationshipType, participantTypechannelType 可以 用作这一编排包里定义的所有编排的元素.

3.2 WS-CDL 类型定义的包含机制

通过使用 [XInclude], WS-CDL 类型定义或定义片断可以语法地复用于任何 WS-CDL 类型定义. 利用这种机制, 我们可以用多个小的良好构造的 WS-CDL 类型定义或定义片断组装成一个更大的 WS-CDL 类型定义.

以包含方式使用其它 WS-CDL 类型定义时需要特别小心, 以防止重复定义 (变量, 块等等) . WS-CDL 处理器 必须 确保文档是一个符合要求的 (conforming) WS-CDL 文档 [Conforming Document]. 它 (WS-CDL处理器)可能 检查文档是否符合给定模式 (schema) [WS-CDL Schema].

下面的例子展示了 WS-CDL 类型定义的可能复用情况.

<choreography name="newChoreography" root="true">
...
   <variable name="newVariable" informationType="someType"
             roleType="randomRoleType"/>
   <xi:include href="genericVariableDefinitions.xml"/>
   <xi:include href="otherChoreography.xml"
               xpointer="xpointer(//choreography/variable[1])"/>
... 
</choreography>

3.3 WS-CDL 文档命名和连接

WS-CDL 文档 必须 有一个类型为 NCNAME 的名字, 作为该文档的一个简单描述形式.

必须 指定一个 URI 类型的 targetNamespace 属性.

这一 URI 必须不 是相关的 URI.

必须用 "QName" 引用一个定义.

每个 WS-CDL 类型定义有其自身的名字作用域 (name scope).

在一个名字作用域中的名字 必须 在整个 WS-CDL 文档中都是唯一的.

WS-CDL 中 "QName" 的解析类似于 XML Schemas 规范 [XMLSchemaP1] 中描述的 "QName" 的解析.

3.4 语言的扩展性

为支持 WS-CDL 语言的扩展, 本规范允许在任何 WS-CDL 语言元素里使用其他 XML 名字空间中定义的扩展元素和 (或) 属性.

扩展的元素和 (或) 属性 必须 使用与 WS-CDL 不同的 XML 名字空间.

在 WS-CDL 文档中使用的所有扩展名字空间都 必须 声明.

这些扩展 必须不 与 WS-CDL 名字空间中的任何元素或属性的语义冲突.

3.5 语义

在÷一个 WS-CDL 文档里的描述可以引用语义定义或者其它文档. 任何 WS-CDL 语言元素中都允许 可选的 description (描述) 子元素. 这些 description 可能 是用多种不同的人可读的语言写出的文本或文档引用. 既使这些 description 子元素是机器可处理的, 也不要求 WS-CDL 解析器去解析其内容.

description 子元素中提供的信息可引用下列一些或所有形式的描述:

  • 文本. 普通文本, HTML 或者其它未编码文本格式 (如 text/plain, text/html, text/sgml, text/xml 等等).

  • 文档引用. 它 可能 包含一个 URI, 所指文档更全面地描述了这个组件.

  • 面向机器的语义描述. 它 可能 包含机器可处理的用诸如 RDF [RDF] 或 OWL [OWL] 写的定义. 描述 可能 包含一个 URI.

应当保证 WS-CDL 名字空间中任何元素或属性的语义不变且 必须不 出现矛盾.

4 合作的参与方

WSDL 规范 [WSDL20] 基于无状态的客户-服务器模型, 描述由一个参与方提供的一种服务的功能. 正在发展的基于 Web 的应用程序要求有在对等环境里交换信息的能力. 在这类环境里, 一个参与方作为获取其他参与方提供的服务的需求方, 同时又是其他参与方所请求的服务的提供方, 这就形成了多参与方之间相互的服务依赖.

一个 WS-CDL 文档描述了一个参与方如何能参加到与相同或不同参与方的合作中.

roleTypes, relationshipTypes, participantTypeschannelTypes 定义了合作的参与方和它们之间的联系.

用在 participantTypes, relationshipTypeschannelTypes 里的复杂类型定义 typeRef 都互不相同. 它们是不同局部元素的类型定义, 即使其标签名一样. 下面的正文逐一描述它们的不同属性和子元素:

4.1 角色类型 (RoleType)

一个 角色类型 枚举一个参与方为参与交互而可能表现出的可观察行为. 举例说, 角色类型 "Buyer" 关联于购买商品或者购买服务, "Supplier" 关联于提供商品或者服务并取得报酬.

roleType 结构的语法是:

<roleType  name="NCName">
   <behavior name="NCName" interface="QName"? />+
</roleType>

属性 name 为同一编排包里声明的各 roleType 元素指定互不相同的名字.

roleType 元素内部, 一个 behavior 元素刻画了一个参与方表现出的一部分可见行为. 一个角色类型 必须 包含一个或多个 behavior 元素. 一个 roleType 里声明的每个 behavior 元素的 name 属性为它描述一个与其他 behavior 不同的名字.

behavior 元素有一个 可选interface 属性, 它确定了一个 WSDL 接口类型. 如果没有 interface, 这个 behavior 描述的就是一个不需要支持任何 Web 服务接口的角色类型.

4.2 关系类型 (RelationshipType)

一个 关系类型 明确说明为使合作成功, 参与方之间相互在角色类型和行为方面 必须 做出的承诺. 举例说, 一个 "Buyer" 和一个 "Seller" 之间的关系类型可能包括:

  • 一个 "Purchasing" 关系类型, 用于初始化对商品或者服务的请求

  • 一个 "Customer Management" 关系类型, 使 "Supplier" 能够提供服务, 并提供对于所售商品或服务的售后支持.

虽然关系类型总存在于两个角色类型之间, 编排则可能涉及两个以上的角色类型. 举例说, 如果购买某商品需要第三方的 "承运人 (Shipper)", 该承运方由 "供货商" 签定合同并为其发送货物, 那么, 除了上面提到的 "购买 (Purchasing)" 和 "客户管理 (Customer Management)", 还可能出现下面的关系类型:

  • "供货商" 和 "承运人" 之间有一个 "物流提供者 (Logistics Provider)" 关系类型

  • "顾客" 和 "承运人" 之间有一个 "货物送交 (Goods Delivery)" 关系类型.

元素 relationshipType 结构的语法是:

<relationshipType name="NCName">
   <roleType typeRef="QName" behavior="list of NCName"? />
   <roleType typeRef="QName" behavior="list of NCName"? />
</relationshipType>

属性 name 为同一编排包里声明的各 relationshipType 元素指定互不相同的名字.

一个 relationshipType 元素 必须 有且仅有两个关系类型, 每个角色类型用 roleType 元素中的 typeRef 属性指定. typeRef属性的 "QName" 值 必须 引用一个角色类型的名字.

每个 roleType 元素里的 可选 属性 behavior 明确说明参与方的承诺, 这是一个属于该角色类型的一些行为类型的 XML-Schema 列表. 如果没有 behavior 属性, 那么该角色类型的所有行为都当作参与方的承诺. 如果有 behavior 属性, 那么这一行为列表 必须是 该角色类型的行为的一个真子集.

4.3 参与方类型 (ParticipantType)

一个 participantType 把一个 参与方 必须 实现的多个可见行为组合在一起. 一个逻辑实体或组织 可能 由编排里的多个参与方类型表示.

participantType 结构的语法是:

<participantType  name="NCName">
   <roleType typeRef="QName" />+
</participantType>

属性 name 用于为同一编排包里声明的各 participantType 元素指定互不相同的名字.

participantType 元素里, 一个或多个 roleType 元素指定了该参与方类型 必须 实现的一组角色类型. 每个角色类型由一个 roleType 元素中的 typeRef 属性描述. 其中 typeRef 属性的 "QName" 值 必须 引用一个角色类型的名字. 一个特定的角色类型 必须不 出现在多于一个 participantType 里.

下面例子展示的是一个 "Buyer-Seller" 关系类型, 其中的 "SellerForBuyer" 角色类型由参与方类型 "Broker" 实现, 它还实现了 "Seller-Shipper" 关系类型中的 "SellerForShipper" 角色类型.

<roleType name="Buyer">
   . . .
</roleType>
<roleType name="SellerForBuyer">
    <behavior name="sellerForBuyer" interface="rns:sellerForBuyerPT"/>
</roleType>
<roleType name="SellerForShipper">
    <behavior name="sellerForShipper" interface="rns:sellerForShipperPT"/>
</roleType>

<roleType name="Shipper">
   . . .
</roleType>

<relationshipType name="Buyer-Seller">
    <roleType typeRef="tns:Buyer" />
    <roleType typeRef="tns:SellerForBuyer" />
</relationshipType>
<relationshipType name="Seller-Shipper">
    <roleType typeRef="tns:SellerForShipper" />
    <roleType typeRef="tns:Shipper" />
</relationshipType>

<participantType name="Broker">
   <roleType typeRef="tns:SellerForBuyer" />
   <roleType typeRef="tns:SellerForShipper" />
</participantType>

4.4 通道类型 (ChannelType)

一个 通道类型 描述信息交换的位置和进行方式, 实现参与方类型之间的一个合作点. 此外, 在通道变量中捕获的通道类型实例信息 (channelType instance information) 可以通过消息交换在参与方之间传递. 由交换得到的通道类型实例 可以 用在后续的交互活动中. 这样可以对静态和动态的消息目标进行建模. 举例说, 一个 "Buyer" 可能指定一个通道类型实例用于传输送货的信息. 该 "Buyer" 可以把这个通道信息发给 "Seller", 后者再把它转发给某 "Shipper". 该 "Shipper" 就可以通过这个最初是由 "Buyer" 提供的通道实例直接向 "Shipper" 发送送货信息.

一个通道类型 必须 描述 roleType 和参与方引用的类型, 携带正确定位信息交换目标的参与方(请求动作的接受者或回复动作的发送者) 所需的信息, 以确定如何以及从何处由参与方接受信息或向其传输信息.

一个通道类型 可能 描述参与方之间的一个或多个逻辑会话的实例标识的类型, 其中每个会话包含一组相关的信息交换. 通道类型实例标识可用于在同一个编排实例中关联于多个会话 (多个通道实例).

一个或多个通道类型实例 可能 在一个信息交换中被从一个参与方传到另一个参与方. 通道类型 可能 用于:

  • 限制这一通道类型的实例能被使用的次数.

  • 限制这一通道类型的实例能用于传递的信息的类型.

  • 限制能被这个通道类型的实例传递的通道的类型

  • 要求被传递的通道实例是唯一的

channelType 结构的语法是:

<channelType  name="NCName"
              usage="once"|"distinct"|"shared"?
              action="request-respond"|"request"|"respond"? >

   <passing  channel="QName"
             action="request-respond"|"request"|"respond"?
             new="true"|"false"? />*

   <roleType typeRef="QName"  behavior="NCName"? />

   <reference>
      <token name="QName"/>
   </reference>

   <identity usage="primary"|"alternate"|"derived"|"association">
      <token name="QName"/>+
   <identity>*

</channelType>

属性 name 用于为一个编排包中声明的所有 channelType 元素指定互不相同的名字.

可选属性 usage 用于约束该通道类型的实例的使用方式. 这一属性的可能取值是:

  1. "once" - 意味着这个通道只能用于进行一次交互, 或者被传给其它角色类型. 如果这种通道类型的一个通道实例被传出, 其传出方 必须 放弃对这个实例的控制权 (仅对输出), 并将控制转给接受方. 这种通道类型的一个实例 必须不 被同时传递给两个或多个接受方.

  2. "distinct" (默认使用模式) - 表示该类型的实例可被该参与方类型在多个交互中多次使用. 当这种通道类型的通道实例被传出时, 传出方 必须 放弃对这一通道实例的控制权 (仅对输出), 并将其转给接受方. 这种通道类型的一个实例 必须不 被同时传递给两个或多个接受方. 在这种模式下, 参与方类型 必须不 在两个或多个并发交互里以同一操作名使用同一通道实例.

  3. "shared" - 共享的意味着该类型的通道实例可以被多个参与方类型在多个交互中多次使用. 当这种类型的一个通道实例被传出时, 传出它的参与方 必须不 放弃对该实例的控制权. 在这种模式下, 参与方类型 必须不 在两个或多个并发交互里以同一操作名使用同一通道实例.

可选属性 action 约束使用该通道类型的实例时所允许的信息交换的类型. 信息交换的类型可以是 “请求-回答”(request-respond), “请求”(request) , 或者是 “回复”(response). 本属性的默认值是 “请求”.

可选子元素 passing 描述用这一类型的通道做信息交换时, 一个参与方可以给另一个传递的通道实例类型. 元素 passing 中的属性 action, 定义在什么时候 必须 传递一个通道实例, 是在 “请求”(request) 交换时还是在 “回复”(response) 时, 或是两个时候都做. 本属性的默认值是 "request". passing 元素中的 可选 属性 new 设为 "true" 时, 就要求被传送的通道实例是唯一的. 如果没有 passing元素, 那么这个通道类型 可能 用于交换信息, 但是 必须不 用于传递任何类型的通道实例.

元素 roleType 用于指定一个参与方作为信息交换目标的角色类型. 而后就可以用它静态确定在哪里和怎样对/从该参与方发送或接收信息. 每个角色类型由该 roleType 元素中的 typeRef 属性指定. 这一 typeRef 属性的 "QName" 值 必须 引用本编排包中定义的某个角色类型的名字. 在这个 roleType 元素里, 可选 属性 behavior 确定了一个特定的可观察行为, 它属于作为消息交换目标的这个角色类型. 如果没有 behavior 属性, 那么该角色类型的任何行为类型都 可以 成为消息交换的目标.

元素 reference 用于指定一个参与方引用的类型, 传递用于定位作为消息交换的目标的参与方所需的信息, 它可以用于动态确定何时及怎样向/从该参与方发送或接收消息. 参与方引用的类型用一个 token 区分, 由该 token 元素的 name 属性描述.

可选的 identity 元素列表 可能 用于给每个这个通道类型的每个实例关联一个唯一标识. 这个标识由 identity 元素的 token 子元素的 name 属性描述的一个 tokens 集合定义. 如果在同一个或不同的 channelType 元素中描述了两个 identity 元素, 这两个元素有相同的命名 tokens 集合且顺序相同, 那么就认为它们表示同样的标识类型.

元素 identity 必须有一个 usage 属性, 定义这个标识在本通道类型的上下文中的作用. 该属性的值可能为:

  1. "primary" - "primary" 用法类表明本标识由这个通道类型的实例的初始化信息创建. 一个通道类型必须有唯一一个 'primary' 标识域.

    下面是这种用法的一个例子.

    <channelType name="OrderChannel">
       ...
      <identity usage="primary">
        <token name="OrderId" />
      </identity>
    </channelType>
    

    这意味着所有通过这个 "OrderChannel" 交换的消息 (请求和回答) 必须包含一个 'OrderId' 域.

  2. "alternate" - 'alternate' 用法类表示可以为一个通道类型实例创建另一个替代标识. 该替代标识可以基于这个通道实例的任何会话中的消息 (也就是说, 不必基于第一条消息) 进行初始化. 如果不是基于第一条消息, 那么该消息要么包含这个通道实例的 primary key, 要么前面已有另一消息初始化了替代标识, 并将该标识绑定到这一通道实例上. 一旦替代标识与通道实例绑定, 随后就只有包含了这个标识的消息才能与这个通道实例关联.

    下面是使用这一属性的一个例子.

    <channelType name="OrderChannel">
       ...
      <identity usage="primary">
        <token name="OrderId" /> 
      </identity> 
      <identity usage="alternate"> 
        <token name="TxnId" />
      </identity>
    </channelType>
    

    在这个例子中, 一个 "OrderChannel" 通道实例将初始地用域 'OrderId' 的值作为标识. 然而, 在这一会话的某个时刻, 将交换一个包含域 'TxnId' 的消息. 一旦这个消息出现, 在这个通道实例上后面的消息既可以通过原来的 'OrderId' 域关联, 也可以通过 'TxnId' 域关联.

  3. "derived" - "derived" 用法类意味着本标识将由当前通道实例 (会话) 发送的一个消息派生, 但它并不直接决定当前通道实例的标识. 随后另一通道实例 (同一类型的或是其他类型的) 会在它的 'primary' 标识域中引用这个标识值, 而这将导致该引用的通道实例与当前通道实例在同一编排实例中相关联.

    下面例子展示了这一属性的使用.

    <channelType name="OrderChannel">
       ...
      <identity usage="primary">
        <token name="OrderId" />
      </identity>
      <identity usage="derived">
        <token name="DeliveryId" />
      </identity>
    </channelType>
    
    <channelType name="DeliveryChannel">
       ...
      <identity usage="primary">
        <token name="DeliveryId" />
      </identity>
    </channelType>
    

    在这个例子中, 'OrderId' 标识了这个 "OrderChannel" 通道实例, 在这个会话的某个时刻将交换一个包含 'DeliveryId' 信息的消息. 尽管从 "OrderChannel" 的角度看, 这个标识 (DeliveryId) 没有用, 但此后可以用它确定一个 "DeliveryChannel" 通道实例的标识, 然后将该 "DeliveryChannel" 实例约束到原 "OrderChannel" 实例所在的那个编排实例.

  4. "association" - 'association' 用法类意味着这个通道实例和已有的某通道实例的标识相关联, 并因此与那个通道实例所在的编排实例关联. 这种类型的标识不会被用于确定当前通道的标识, 而只是用于和同一编排实例中的某个已有通道实例建立联系. 这个标识可以和 (在另一个通道类型里) 的另一个具有 'primary'/'alternate' 类别的标识定义关联, 也可以和 'derived' 类别的标识关联. 在通道实例上的初始化消息 必须 包含可以解析出这个标识域的信息.

    下面实例展示了这个属性的使用.

    <channelType name="OrderChannel">
       ...
      <identity usage="primary">
        <token name="OrderId" />
      </identity>
    </channelType>
    
    <channelType name="SupplierChannel">
       ...
      <identity usage="association">
        <token name="OrderId" />
      </identity>
    
      <identity usage="primary">
        <token name="SupplierName" />
        <token name="OrderId" />
      </identity>
    </channelType>
    

    这个例子说明了有关编排如何包含一个 "OrderChannel" 通道实例, 以及与之关联的基于一个 'association' 标识为此 "OrderChannel" 通道实例建立的零个或多个 "SupplierChannel" 通道实例.

5 信息驱动的协作

当信息交换的记录工作已完成, 可观察的信息改变已发生, 并因此履行了顺序约束条件时, 合作的各参与方就将向前推进. 一个 WS-CDL 文档容许在编排中定义各种信息, 这些信息将影响协作参与方的可观察行为.

变量 获取编排中的对象信息, 如交换的信息或者有关角色类型 (roleTypes) 的可观察信息. token 表示别名, 可用于引用变量中的一部分内容. 变量和 token 都有信息类型 (informationTypes), 它定义了变量包含的或者 token 引用的信息的类型.

5.1 信息类型 (InformationType)

信息类型描述编排中使用的各种信息的类型. 通过引入这种抽象, 可以避免在编排定义中直接引用各种数据类型, 如 WSDL 文档或者 XML Schema 文档中定义的数据类型.

信息类型结构的语法为:

<informationType name="NCName"
   type="QName"?|element="QName"? />

属性 name 描述在一个编排包中声明的各个信息类型元素的名称.

可选属性 typeelement 描述编排中使用的信息类型为 WSDL1.1 消息类型, 或者 XML Schema 类型, 或者 WSDL2.0 Schema 元素, 或者 XML Schema 元素. 属性 typeelement 两者只能出现一个.

下面的例子展示了信息类型结构的一些用法.

Example 1: The informationType "purchaseOrder" refers to the WSDL 1.1 Message type "pns:purchaseOrderMessage"

   <informationType name="purchaseOrder" type="pns:purchaseOrderMessage"/>

 

Example 2: The informationType "customerAddress" refers to the WSDL 2.0 Schema element "cns:CustomerAddress"

   <informationType name="customerAddress" element="cns:CustomerAddress"/>

 

Example 3: The informationType "intType" refers to the XML Schema type "xsd:int"

   <informationType name="intType" type="xsd:int"/>

5.2 变量 (Variables)

变量捕获编排中的对象信息, 按其用法可以定义:

  • 信息交换捕获变量 (information exchange capturing variables), 如一个订单 (Order) , 包含的信息有:

    • 用于在 message-has-been-sent-event (消息发送事件) 发生前或发生时, 放置被发送的消息内容

    • 放置 message-received-event (消息接收事件) 的结果

  • 状态捕获变量 (state capturing variables) 包含作为信息交换的结果在一个角色类型上可观察的变化信息. 例如, 当 "Buyer" 发送一个 "Order" 给 "Seller", "Buyer" 可能有一个名字为 "OrderState" 的变量, 其值设置为 'OrderSent', 一旦 "Seller" 收到这个消息, "Seller" 可能把一个名字为 "OrderState" 的变量设置为 'OrderReceived' 的值, "Buyer" 的变量 "OrderState" 与 "Seller" 的变量 "OrderState" 不是同一个变量.

  • 通道捕获变量 (channel capturing variables) 包含信息如: 作为消息发送地址的 URL, 所使用的策略 (如安全性), 是否采用可靠消息传输等等. 如何表示以及在哪儿表示这些信息都超出了本规范的范围.

  • 异常捕获变量 (exception capturing variables) 包含有关出现的一个异常的信息.

变量的值:
  • 当一个变量包含着属于公共知识的信息且符合变量定义的描述时, 可以被一个编排里的角色类型使用. 例如, 以小时的方式描述对 "Create Order" 请求必须作出回应的时间限制变量 "OrderResponseTime" 必须在编排初始化之前进行初始化, 如果该变量是为所有角色类型定义的, 那么它就可以被编排中的所有角色类型使用.

  • 作为一次交互的结果而变成可用的

    • 在一次交互结束时, 被设置的信息交换获取变量可以在特定角色类型上使用
    • 状态捕获变量包含角色类型上作为信息交换和记录结果的可观察信息改变, 在交互结束后可以使用
  • 通过从其它信息赋值, 可以在一个角色类型的局部创建, 改变和使用. 该变量可以是信息交换变量, 状态变量或通道获取变量. 例如, "Maximum Order Amount" 可能是 "Seller" 创建的数据, 与 "Seller" 从一个 "Create Order" 请求中接收到的实际变量 "Order amount" 一起用于控制编排中的活动顺序. 这种情况下, 其它角色类型将不会知道 "Maximum Order Amount" 的计算方法以及它的值

  • 可用于决定编排里采取的决策和动作

  • 当变量具有相同名字时, 作为同一参与方类型的部分的不同角色类型里的值可以在这些角色类型之间共享

如果一个未初始化的变量被用于任何动作, 除非是用于阻塞工作单元或用在 WS-CDL 函数 isVariableAvailable 中, 否则动作的结果无定义.

variableDefinitions 结构用于在编排中定义一个或多个变量.

variableDefinitions 结构的语法如下:

<variableDefinitions>
   <variable   name="NCName"
       informationType="QName"?|channelType="QName"?
       mutable="true|false"?
       free="true|false"?
       silent="true|false"?
       roleTypes="list of QName"? />+
</variableDefinitions>

informationType 属性定义的变量是信息交换捕获变量或状态捕获变量. 用 channelType 属性定义的变量是通道捕获变量. informationTypechannelType 属性 必须 是两者取一.

可选 属性 mutable 为 "false" 时, 说明变量信息一旦初始化就 必须不 改变. 属性 mutable 的缺省值为 "true".

可选 属性 silent 设置为 "true" 时, 说明编排中任何活动都 不应该 创建或修改这一变量. 这种变量用于表示参与方的不可观察的, 或者 WS-CDL 不感兴趣的动作的结果. 属性 silent 的缺省值为 "false".

可选 属性 free 设置为 "true" 时, 说明在 enclosing 编排中定义的这个变量在当前编排中使用, 这样就共享了该变量的信息. 下面的规则适用于这一情况:

  • free 变量的类型 (由 informationType 或者 channelType 属性描述) 必须 匹配 enclosing 编排中定义的变量类型

  • free 变量的属性 silentmutable 必须 匹配 enclosing 编排中定义的变量的 silentmutable 属性

  • perform 活动 必须 将被执行编排中的一个自由变量与 执行编排中的一个变量绑定

可选 属性 free 为 "false" 说明该变量在当前编排中定义. free 属性的缺省值为 "false".

可选 属性 roleTypes 是一个 XML-Schema 列表, 描述参与方的一个或多个角色类型, 说明本变量属于这些角色类型. 没有说明角色类型的变量等价于定义在编排中所有角色类型上的变量, 即该变量定义所在编排里作为各关系类型的部分的那些角色类型. 例如, 如果编排 "choreo1" 里包含关系类型 "rel", 而关系类型 "rel" 包含角色类型 "roleType1" 和 "roleType2", 如果编排 "choreo1" 中定义的变量 "var" 没有 roleTypes 属性, 就意味着它定义在两个角色类型 "roleType1" 和 "roleType2" 上.

name 属性用于为 variableDefinitions 元素中声明的每个变量的指定一个唯一名字. 如果一个变量的可见完全在某个角色类型内部, 就应在相关变量定义中用 roleTypes 属性指定变量的角色类型. 当一个变量被编排中的角色类型的某个子集共享时, 需要在变量定义中用 roleTypes 属性列出这些角色类型作为该变量的角色类型.

5.3 表达式 (Expressions)

表达式可用于在 WS-CDL 中创建新信息, 也可用于获得或改变已有信息.

一般表达式和字面量 (literals) 可用于传给变量. 谓词表达式用于在 WS-CDL 中描述条件. 查询表达式用于描述查询.

用在 WS-CDL 中描述表达式, 查询或条件谓词的语言必须是 XPath1.0.

WS-CDL 定义了一个 Xpath1.0 扩展函数集合, 实现 必须 支持这些扩展函数. 这些函数在标准 WS-CDL 名字空间 http://www.w3.org/2005/10/cdl 中定义. 前缀 "cdl:" 与该名字空间关联.

5.3.1 WS-CDL 提供的函数

WS-CDL 提供了一些 XPath1.0 的扩展函数. 只要类型匹配, 这些函数可以用于任何XPath1.0表达式:

  • 函数 xsd:time getCurrentTime(xsd:QName roleTypeName?) 返回调用者的当前时间. 调用者由参数 roleTypeName 描述 (也就是说, 一个角色类型只能查询自己的时间). 参数 roleTypeName可选 的, 如果有这个参数, 当前时间信息 必须 在参数 roleTypeName 所描述的角色类型上是可用的 (available); 如果没有, 那么就根据使用这个函数的上下文中推导出相应的角色类型.

  • xsd:date getCurrentDate(xsd:QName roleTypeName?) 返回调用者的当前日期, 调用者由参数 roleTypeName 描述 (也就是说, 一个角色类型只能询问自己的日期). 参数 roleTypeName可选 的. 如果有这个参数, 当前日期信息必须在参数 roleTypeName 所描述的角色类型上是可用的; 如果没有, 那么就根据使用这个函数的上下文中推导出相应的角色类型.

  • xsd:dateTime getCurrentDateTime(xsd:QName roleTypeName?) 返回调用者的当前日期和时间, 调用者由参数 roleTypeName 描述 (也就是说, 一个角色类型只能询问自己的日期/时间) . 参数 roleTypeName可选 的, 如果使用这个参数, 当前日期和时间信息必须在参数 roleTypeName 所描述的角色类型上是可用的. 如果没有该参数, 那么将从使用这个函数的上下文中推导出相应的角色类型.

  • xsd:Boolean hasDurationPassed(xsd:duration elapsedTime, xsd:QName roleTypeName?) 返回"true" 如果 (a) 它被作为 workunit 中的卫式或循环条件, 其中的 block 属性为"true", 或者它出现在一个编排的 complete 条件中; 或者 (b) 在由参数 roleTypeName 描述的调用方, 用 elapsedTime 描述的时间段已经过去, 从卫式或循环条件为了匹配而被激活, 或者相关编排被激活的时刻算起. 否则本函数返回 "false". 这里的 roleTypeName 参数是 可选 的. 如果没给出这个参数, 那么就从使用这个函数的上下文中推导出相应角色类型.

  • xsd:Boolean hasDeadlinePassed(xsd:dateTime deadlineTime, xsd:QName roleTypeName?) 返回 "true" 如果 (a) 它被作为 workunit 中的卫式或循环条件, 其中的 block 属性为"true", 或者它出现在一个编排的 complete 条件中  (b) 在由参数 roleTypeName 描述的角色类型上, 由 deadlineTime 描述的时刻已经过去, 假设或者卫式或循环条件匹配而被激活, 或者相应编排被激活. 否则本函数返回"false". 这里的 roleTypeName 参数是 可选 的. 如果没有这个参数, 那么就根据使用这个函数的上下文推导出相应角色类型.

  • xsd:any getVariable(xsd:string varName, xsd:string part, xsd:string documentPath, xsd:QName roleTypeName?) 返回名为 varName 的变量信息, 形式为包含一个结点的结点集合. 第二个参数 part 描述了一个 WSDL1.1 文档的消息部分. 对 WSDL 2.0 文档, 这个参数 必须 为空. 当第三个参数 documentPath 为空时, 本函数从变量信息获取整个文档. 第四个参数是 可选的. 如果有这个参数, 在 roleTypeName 描述的角色类型上这个变量的信息 必须 可用; 如果没有这个参数, 那么就根据使用这个函数的上下文推导出相应的角色类型.

  • xsd:Boolean isVariableAvailable(xsd:string varName, xsd:QName roleTypeName?) 返回"true", 如果变量名为 varName 的变量信息在 roleTypeName 描述的角色类型上可用; 否则返回"false". roleTypeName 参数是可选的. 当使用这个参数时, 变量信息 必须roleTypeName 描述的角色类型上可访问. 如果没用该参数, 那么就从使用这个函数的上下文推导出相应的角色类型.

  • xsd:boolean variablesAligned(xsd:string varName, xsd:string withVarName, xsd:QName relationshipTypeName) 返回"true", 如果在 relationshipTypeName 描述的关系类型中, 变量名为 varName 的属于第一个角色类型的变量已经与变量名为 withVarName 的属于第二个角色类型的变量信息校准 (aligned) .

  • xsd:any getChannelReference(xsd:string varName) 返回变量名为 varName 的变量引用信息. 该变量的类型必须是 channelType.

  • xsd:any getChannelIdentity(xsd:string varName) 返回变量名为 varName 的标识 (identity) 信息. 该变量的类型必须是 channelType.

  • xsd:Boolean globalizedTrigger(xsd:string expression1, xsd:string roleTypeName1, xsd:string expression2, xsd:string roleTypeName2, . . .) 组合起定义在不同角色类型上的表达式. 这样, expression1 基于 role1 上的变量定义, expression2 基于 role2 上的变量定义, 等等. globalizedTrigger 函数在各个 roleType 上求值, 它在一个角色上为"true" 当且仅当在该角色类型上的表达式算出 "true".

  • xsd:boolean hasExceptionOccurred(xsd:QName exceptionType) 返回 "true", 如果由参数 exceptionType 标识的异常类型已经发生. 否则就返回"false".

  • xsd:boolean hasChoreographyCompleted(xsd:string choreoName, xsd:string choreoInstanceId?) 返回"true", 如果参数 'choreoName' 和 可选choreoInstanceId 所关联的 performed 编排的状态是 completed (不管成功与否). 如果没说明 choreoInstanceId, 函数将计算是否所有具有给定名字的 performed 编排都已经完成. 如果在这个函数调用前给定名字的编排还没有执行, 函数将返回 "false".

  • xsd:string getChoreographyStatus(xsd:string choreoName, xsd:string choreoInstanceId?) 返回特定编排标识和 可选的 choreoInstanceId 所关联的编排的当前状态. 如果没说明 choreoInstanceId, 那么在当前编排的作用域里 必须 只有一个 performed 编排实例, 检查的就是这个编排的状态, 否则函数 必须 返回状态 'ambiguous'. 状态值可以是 'enabled', 'completed-successfully', 'completed-unsuccessfully', 'closed', 'ambiguous', 或者 'instance-unknown'. 当这一函数被调用时指定编排尚未激活, 将得到 'instance-unknown' 状态. 编排状态的其它合法转换在 5.7 节的编排生命周期中概述.

5.4 Token 与 TokenLocator (token 定位符)

token 是编排需要使用的变量或消息中的数据片段的别名. token 与变量的区别在于变量包含值, 这些值 可以 作为动作或事件的结果在一个编排的生命周期内传播, 而 token 包含的信息定义了数据中的某个相关片段.

每个 tokens 必须 有一个 informationType, 例如, "Order Id" 可能是 'alphanumeric' 类型, 而 "Counter" 可能是 'integer' 类型.

一个 token 引用编排定义中的一个文档片断. token 定位符是一种用于选择 tokens 的查询机制. 通过引入这些抽象, 可以避免编排定义对用 WSDL 描述的特定消息类型或用 XPath 1.0 说明的特定查询串的依赖. 这样, 改变文档中的一部分或查询串时就不会影响编排的定义.

token 结构的语法如下:

<token  name="NCName"  informationType="QName" />

属性 name 用于为一个编排包中声明的各个 token 元素指定唯一的名字.

属性 informationType 标识文档片段的类型.

token 定位符 tokenLocator 结构的语法如下:

<tokenLocator  tokenName="QName" 
               informationType="QName" 
               part="NCName"?
               query="XPath-expression" />

属性 tokenName 标识与文档片断 (fragment) 定位符关联的 token 名.

属性 informationType 标识文档的类型, 查询在该文档上执行, 定位相应的 token.

可选的 属性 part 定义相关的文档部分, 查询在该文档部分上执行, 定位相应的 token. 不应该 对 WSDL 2.0 文档定义这个属性.

属性 query 定义用于在文档或文档部分中选择文档片断的查询串.

在下面例子里 token "purchaseOrderID" 具有 XML-Schema类型 'int'. 例子展示了两个 token 定位符如何在 "purchaseOrder" 和 "purchaseOrderAck" 消息中访问该 token.

<token name="purchaseOrderID" informationType="xsd:int"/>

<tokenLocator tokenName="tns:purchaseOrderID" informationType="purchaseOrder"       
                query="/PO/OrderId"/>
<tokenLocator tokenName="tns:purchaseOrderID" informationType="purchaseOrderAck" 
                query="/POAck/OrderId"/>

5.5 编排 (Choreography)

一个编排根据两个或多个交互参与方之间的共识定义一些可复用的公共规则, 这些规则制约着消息交换的顺序和协作行为的提供模式.

在编排包层面上定义的编排称为顶层 (top-level) 编排, 它不与其它顶层编排共享上下文. 一个编排包 必须 包含零个或一个明确标识为根 (root) 编排的顶层编排.

在一个编排中封装的可复用行为 可以 在一个独立的 enclosed 编排中被执行, 以利于编排的组合性. 被执行的编排称为 enclosed 编排, 可以 如下定义:

  • 局部地 (locally) -在其 enclosing 编排的内部定义

  • 全局地 (globally) - 在同一或不同编排包中用独立的顶层非根编排定义来描述, 它可以被其它编排使用, 使该编排所描述的合约被复用

根编排是唯一被默认激活 (enabled) 的编排. 而非根编排只有在被执行时才激活.

一个编排 必须 包含至少一个关系类型, 用于列举这一编排要求其参与方表现的可观察行为. 在一个编排里 可以 定义一个或多个关系类型, 以建模多方协作.

编排也作为变量的词法的名字作用域. 在一个编排里定义的变量仅在这个编排以及它的所有 enclosed 编排里使用, 除非该变量被重新定义为一个非自由变量, 这就规定了一个变量在编排中的可见区域.

一个编排里 可以 包含一个或多个编排定义, 这些编排只 可以 在该编排里局部地执行.

一个编排 必须 包括一个活动描述 (Activity-Notation), 描述这个编排执行的动作. 当其隶属编排激活时, 这些动作被激活.

一个编排 可以 定义一个异常块 (exceptionBlock) 用于从可能发生的异常条件中恢复.

一个已成功完成的 enclosed 编排 可能 需要提供一些 finalization 动作, 用于确认, 取消或者修改已完成的动作的效果. 为处理这些修改, 在一个 enclosed 编排里 可以 定义一个或多个独立的终结块 (finalizerBlocks).

一个编排也能被协调 (coordinated), 编排的协调确保涉及的所有角色类型在对编排如何结束上达成一致. 即: 编排是成功完成还是遭遇了异常, 以及当编排成功完成且安装了终结块, 所有角色类型都激活同一个终结块.

Choreography-Notation 用于定义一个编排:

<choreography  name="NCName"
      complete="xsd:boolean XPath-expression"?
      isolation="true"|"false"?
      root="true"|"false"?
      coordination="true"|"false"? >

   <relationship  type="QName" />+

   variableDefinitions?

   Choreography-Notation*

      Activity-Notation 

   <exceptionBlock  name="NCName">
      WorkUnit-Notation+
   </exceptionBlock>?

   <finalizerBlock  name="NCName">
      Activity-Notation
   </finalizerBlock>*
</choreography>

属性 name 用于为包里声明的每个编排定义一个唯一名字.

可选的 complete 属性使人可按如下面编排的生命周期部分所描述的那样明确地结束一个编排. 这个布尔条件表达式必须根据 XPath 1.0 的词法规则, 采用短路求值 (short circuit evaluation).

可选的 isolation (隔离) 属性描述当某 enclosing 编排中定义的一个变量在其 enclosed 编排里修改时, 它何时可以被其兄弟编排访问. 这个属性的缺省值是 "false". 相关规则如下:

  • isolation 设为 "false" 时, 变量信息 可以 立即被其兄弟编排中的动作复写.

  • isolation 设为 "true" 时, 只有当这个编排已经完成后, 对变量信息的修改才 必须 对其兄弟编排的读或写是可见的.

一个隔离编排 必须不 直接或间接执行另一隔离编排.

如果一个编排的 isolation 属性设为 "true", 那么它的所有 enclosed 编排 必须 假定为采用了这个属性值.

可选的 coordination 属性说明是否需要编排协调. 本属性的缺省值是 "false". 相关规则如下:

  • coordination 属性设为"true" 时要求编排协调, 有关协调协议 必须 确保所有的角色类型在编排如何结束方面取得共识.

  • coordination 属性设为 "false", 这一编排不绑定一个协调协议. 因为没有如上所述的对结果的一致观点, 任何需要的协调都 应该 通过明确建模的交互来执行.

编排中的 relationship 元素枚举本编排 可以 参与的所有关系.

可选的 variableDefinitions 元素枚举本编排里定义的变量.

可选的 root 元素把一个顶层编排标记为这个包的根编排. 这个属性的缺省值为 "false".

编排中 可选的 Choreography-Notation 定义只能在这一编排的内部执行的局部编排.

可选的 exceptionBlock 元素用 WorkUnit-Notation (工作单元的形式) 描述一个或多个异常工作单元, 定义这个编排的异常块 (exceptionBlock). 在该元素中, 属性 name 用于描述异常块的名字.

可选的 finalizerBlock 元素定义编排的终结块 (finalizerBlock). 一个编排 可以 有多个终结块. 每个终结块用一个 Activity-Notation 描述一个终结器 (finalizer) 活动. 如果一个编排定义了多个终结块, 那么这些终结块就 必须 用唯一名字区分, 名字用 finalizerBlock 元素里 name 属性描述.

5.6 工作单元 (WorkUnit)

一个 工作单元 规定了一些在编排向前推进 (making progress ) 和执行动作时必须履行的约束. 工作单元也可用于规定为保证参与方之间共同执行的协作一致性所需要的约束. 利用工作单元机制, 应用可以从非正常动作而导致的错误结果中恢复, 也可用于 finalize 已经成功完成但需要进一步动作的编排. 例如, 用于确认或逻辑回滚已有的效果, 或者关闭编排使已定义的 "rollback" 工作单元不会再被激活. 工作单元的例子包括:

  • 一个 "Change Order" 工作单元在收到了订单确认消息且未收到订单拒绝消息时可以执行.

  • 一个 "Order Delivery Error" 工作单元, 当 "Place Order" 工作单元无法到达 'normal' 结果时被执行. 这里将会有一个标识错误的约束.

如果工作单元描述了卫式 (guard ) 条件, 那就表示它关注在规定约束下可用的一个或多个 (已存在的或在未来将变为可用的) 变量的信息. 要激活这种工作单元的内嵌动作, 它所表示的关注 必须 得到匹配.

当所有内嵌动作都成功完成时, 该工作单元 必须 成功完成.

如果一个成功完成的工作单元的循环条件为 "true", 则它 必须 重新考虑匹配问题 (根据其卫式条件).

定义工作单元的 WorkUnit-Notation 如下:

<workunit  name="NCName"
      guard="xsd:boolean XPath-expression"? 
      repeat="xsd:boolean XPath-expression"? 
      block="true|false"? >

      Activity-Notation 
</workunit>

属性 name 为编排包中声明的工作单元元素命名.

Activity-Notation 描述工作单元中内嵌的动作.

可选 属性 guard 描述工作单元的卫式条件. 这个布尔条件表达式 必须 根据 XPath 1.0 词法规则采用短路求值.

可选的 属性 repeat 描述工作单元的重复执行条件. 这个布尔条件表达式 必须 根据 XPath 1.0 词法规则采用短路求值.

可选的 属性 block 描述该工作单元是否以阻塞方式等待卫式条件中引用的变量变为可用 (如果当时不可用) 且卫式条件求值为 "true" 时. 在异常工作单元中这个属性 必须 总设为 "false". 这一属性的缺省值是 "false".

上面是一些细节, 下面是有关的规则:

  • 如果没有说明卫式条件, 那么这个工作单元总是匹配

  • 一个或多个工作单元 可以 同时匹配, 只要它们各自所表示的关注都得到匹配

  • 如果没说明重复执行条件, 那么该工作单元匹配一次后将不会被再次考虑

  • 在各卫式条件或重复执行条件中都可描述一个或多个变量, 使用 5.3.1 节所说的 XPath 1.0 和 WS-CDL 函数

  • 在卫式或重复条件里可以用 WS-CDL 函数 getVariable 获得特定角色类型上的变量的值 (不能用于获取远程的值)

  • 如果在卫式或重复条件里用 WS-CDL 函数 isVariableAvailable, 就意味着这个卫式或循环条件的工作单元将根据 block 属性是 "false" 或 "true", 检查有关变量是否已经在给定角色类型上可用, 或者等待该变量变为可用

  • 如果在卫式或重复条件里用 WS-CDL 函数 variablesAligned, 就意味着这个卫式或循环条件的工作单元将根据 block 属性是 "false" 或 "true", 检查或者等待发生在两个角色类型之间的适当的校准 (alignment) 交互. 为校准而检查的或等待的变量或是校准交互中发送和接收的变量, 或是校准交互结束后用在两个角色类型上用于记录的变量. 如果把 variablesAligned 函数用在卫式或重复条件中, 那么 variablesAligned 中的 relationshipType 必须 是直接 enclosing 编排定义的 relationshipType 的子集.

  • 在不同角色类型上定义的变量 可以 用在一个卫式条件或者重复条件里, 形成一种全局观点, 这样就组合了各个角色类型上规定的约束, 但并不要求所有这些约束必须履行才能取得进展. 对这种情况下, 必须 在卫式条件或者重复条件里用 WS-CDL 函数 globalizedTrigger. 在卫式条件或循环条件中, 在相同角色类型上定义的变量 可以 用所有可用的 XPath 1.0 操作符和 WS-CDL 函数进行组合.

  • 如果属性 block 被设为 "true", 在一个或多个需要的变量不可用时或者卫式条件求值得到 "false" 时, 本工作单元 必须 阻塞. 当由卫式条件描述的所需变量的信息变为可用, 且卫式条件求值得到 "true" 时本工作单元匹配成功. 如果给出了重复条件, 那么当这个工作单元成功完成时, 重新求值重复条件. 如果重复条件的所需变量的信息可用, 而且循环条件计算为 "true", 那就认为这一工作单元被再次匹配. 否则就认为这个工作单元不匹配.

  • 如果属性 block 设为 "false", 那就假定相应卫式条件或重复条件有关的变量信息当前可用. 如果或者变量信息不可用或者卫式条件求值出 "false", 那么本工作单元的匹配失败, 其中内嵌的 Activity-Notation 被忽略, 即使有重复条件也不去求值. 否则, 如果工作单元匹配成功, 那么如果有重复条件, 则在工作单元成功完成时将求值它. 如果重复条件描述的所需变量的信息可用, 且该重复条件求值出 "true", 那就认为该工作单元再次匹配成功. 否则就不再考虑该工作单元的匹配.

下面的例子展示了工作单元的一些用法:

a. 阻塞属性为 "true" 的工作单元的例子:

在下面工作单元里, 卫式条件等待 "Customer" 角色类型上的变量 "POAcknowledgement" 变得可用, 如果该变量已经可用, 那么有关的活动发生, 否则, 这一活动将被阻塞, 直到该变量在 "Customer" 上变得可用.

<workunit  name="POProcess" 
           guard="cdl:isVariableAvailable('POAcknowledgement','','','tns:Customer')"
      block="true">
   ... <!--some activity -->
</workunit>

b. 阻塞属性为"false"的工作单元的例子:

在下面工作单元里, 卫式条件检查在 "Retailer" 角色类型上的变量 "StockQuantity" 是否可用, 而且其值大于10. 如果这些成立则活动发生. 如果该变量不可用或者其值小于 '10', 那么匹配条件为 "false", 有关活动被忽略.

<workunit  name="StockCheck" 
    guard="cdl:getVariable('StockQuantity','','/Product/Qty', 'tns:Retailer') > 10)"
    block="false" >
   ... <!--some activity -->
</workunit>

c. 等待校准的工作单元的例子:

在这个例子中, 工作单元等待 "Customer" 和 "Retailer" 角色类型上的 "purchase order" 信息已基于前面的交互实现了校准. 校准意味着两个角色类型对各自的 "purchase order" 变量的值达成一致.

<roleType name="Customer">
   . . .
</roleType>
<roleType name="Retailer">
   . . .
</roleType>
<relationshipType name="Customer-Retailer-Relationship">
    <roleType typeRef="tns:Customer" />
    <roleType typeRef="tns:Retailer" />
</relationshipType>

<workunit  name="WaitForAlignment" 
       guard="cdl:variablesAligned('
                    PurchaseOrderAtBuyer','PurchaseOrderAtSeller',
                    'tns:Customer-Retailer-Relationship')"
       block="true" >
   ... <!--some activity -->
</workunit>

5.7 编排的生命周期 (Choreography Life-line)

编排的生命周期表示通过激活某些活动和 enclosed 编排而导致的协作进展 (progression). 最初在参与方之间建立协作, 然后执行其工作, 最后结束.

顶层编排或 enclosed 编排的不同实例所涉及的通讯动作 必须不 相互干扰, 即使这些实例在当时以时序上交迭的方式执行. 换句话说, 给定了一个编排描述, 属于其一个实例的交互必须在逻辑上 (logically), 从而也在操作上 (operationally) 明确区别于其他实例的交互.

当明确标记为编排的启动器 (initiator) 的交互被执行时, 相应编排被初始化从而建立起一个协作. 这导致其异常块的安装, 并使编排进入 Enabled (活动) 状态. 在这一点之前各参与方之间没有可观察的关联.

可以 将两个或多个交互标记为编排的启动器, 用于说明为建立一个协作而可供选择的不同交互. 在这种情况下, 第一个执行的交互将建立协作, 其它交互将参与 (enlist) 已经建立的协作.

可以 在根编排或者一个 enclosed 编排中定义编排的启动器交互. 在这两种情况里, 协作都是在执行第一个编排启动器交互时建立的.

当一个处在 Enabled 状态的编排中发生异常时, 该编排 必须 以未成功的方式完成, 如果这个编排有异常块, 则 必须 将其激活. 这 必须 导致该编排进入 Unsuccessfully Completed 状态.

如果一个未成功而完成的编排里有异常块, 而且该异常块也已完成, 这个编排就 必须 进入 Closed 状态. 如果该编排没有异常块, 它就隐式地转入 Closed 状态, 如果这里存在 enclosing 编排, 所发生的异常 必须 传播到其 enclosing 编排.

当处于 Enabled 状态的编排中再也没有激活的活动了, 该编排就 必须 成功完成. 这也导致该编排的异常块 (如果存在) 的卸载, 并将装载这个编排的终结块 (如果存在), 而后该编排进入 Successfully Completed 状态.

换一种情况, 如果一个编排的 complete 条件求值为 "true" 而被匹配, 则该编排 必须 成功完成. 当编排处于 Enabled 状态时, 就认为 complete 条件是匹配的. 有关的 complete 条件 必须 能在参与这一编排的所有角色类型上匹配成功. 当一个编排的 complete 条件匹配时, 编排中的所有活动 必须 被 disabled, 除了那些终结块, 而且这一编排完成, 就好像其中没有任何激活的活动一样. 当一个编排完成时, 所有未完成的 enclosed 编排 必须 自动变为成功完成. 编排完成后, 作为编排中的一部分而发送的消息 必须 被忽略. 如果完成条件计算为 "true" 时已经进入了一个终结块, 那么它将不受影响, 其消息也 必须不 忽略.

如果一个处在 Successfully Completed 状态的编排没有描述终结块, 它就直接进入 Closed 状态.

如果一个处在 Successfully Completed 状态的编排有终结块, 当安装的其中一个终结块被激活而且完成时, 该编排进入 Closed 状态. 编排的终结块可以通过其直接 enclosing 编排中的 finalize 活动激活. 另一情况: 如果一个有终结块的编排处在 Successfully Completed 状态, 其 enclosing 编排进入 Closed 状态而没有激活这个 enclosed 编排的终结块, 那么这个编排也隐含地进入 Closed 状态. 换句话说, 当一个编排进入 Closed 状态时, 所有其成功完成的 enclosed 编排都隐含地进入 Closed 状态, 即使它们的终结块没有被激活.

5.8 编排的异常处理 (Choreography Exception Handling)

一个编排可能因为一个异常的环境情况或在执行期间发生的一个 "error" 而失败. 有许多不同类型的可能异常, 下面是一个不完全的列表.

  • 交互失败 (Interaction failures) - 例如, 一个消息的发送没有成功

  • 基于协议的消息交换失败 (Protocol based exchange failures) - 例如, 没收到作为可靠消息协议的一部分的确认消息

  • 安全性失败 (Security failures) - 例如, 由于数字签名非法, 消息被接收方拒绝

  • 延时错误 (Timeout errors) - 例如, 一个交互在要求的时间内没有完成

  • 验证错误 (Validation errors) - 例如, 一个 XML "Order" 文档 不是良形式的或者不符合相关的 XML-Schema 定义

  • 应用层的失败 (Application failures) - 例如, "Goods Ordered" 是 'Out of stock'

在 WS-CDL 里, 可以 在编排的异常块中针对需要处理的各种异常定义一个或多个异常工作单元. 在编排的异常块部分, 至少 必须 定义一个异常工作单元.

一个异常工作单元 可以 用包含 WS-CDL 函数 hasExceptionOccurred 的卫式条件表示对发生特定类型的异常的关注. 没有卫式条件的异常工作单元称为 默认异常工作单元, 表示它关注所有的异常类型. 一个编排的异常块里 必须不 包含多个缺省异常工作单元. 异常工作单元的 block 属性 必须 设置为 "false", 而且 必须 没有定义重复条件.

当一个异常块所属的编排被激活时, 其异常工作单元 必须 激活. 编排中激活的异常工作单元 可以 看作是在当前编排及其 enclosed 编排中发生异常时的恢复机制.

在编排的异常块里只 可能 有一个异常工作单元被匹配.

异常匹配的规则如下:

  • 当异常工作单元用 WS-CDL 函数 hasExceptionOccurred (exceptionType) 作为卫式条件, 那么当导致异常的 "QName" 值与所说明的 exceptionType 参数匹配时, 这一异常工作单元 必须 被匹配.

  • 如果一个异常与一个异常工作单元的卫式条件匹配, 那么被匹配工作单元的动作被激活. 如果定义了两个或更多异常工作单元, 那么求值其卫式条件的顺序根据在异常块中工作单元的定义顺序确定.

  • 如果没有匹配的卫式条件, 那么, 如果存在未定义卫式条件的默认异常工作单元, 则其动作被激活.

  • 如果一个异常没有被发生该异常的编排中的异常工作单元匹配, 该异常将被递归地传播到该编排的直接 enclosing 编排的异常工作单元, 直到取得一次成功的匹配.

  • 如果在一个编排中发生了一个异常, 那么该编排为非成功完成. 在这种情况下其终结块 必须不 安装. 在某个异常工作单元得到匹配前, 这一编排中的动作, 以及任何还没有完成的 enclosing 编排的动作都非正常完成.

一个异常工作单元里的动作 可以 使用所属编排的可见域里当前可见的变量的信息.

一个异常工作单元中的动作也 可以 导致一个异常. 异常匹配的语义以及动作与这一节里的描述相同.

5.9 编排终结 (Finalization)

一个编排实例成功完成后, 它 可能 需要提供终结动作, 用于确认, 取消或者修改其已完成动作的效果. 为了处理这类修改, 可以 为一个 enclosed 编排定义一个或多个独立的终结块. 当一个编排的体成功完成, 而且描述了与之关联的终结块, 那么该终结块 必须 被安装.

如果在一个编排里定义了多个终结块, 那么它们 必须 能用其 name 属性相互区分. 然而, 在 enclosing 编排的进展中, 包括在异常处理和终结处理阶段, 对任何给定的编排实例至多 可以 激活它的一个终结块.

终结块 可以 实现适合特定编排需要的任何工作. 常见模式包括:

  • 一个终结块, 用于语义地 "rollback" (回滚) 这个编排

  • 两个终结块, 例如一个用于 "confirm" (确认), 另一个用于 "cancel" (取消), 以实现某种两阶段的结果协议.

  • 一个 "undo" (撤销) 终结块和一个"close" (关闭) 终结块. 如果激活 "close" 终结块, 那么这一编排将关闭, 而且 "undo" 终结块也不再激活.

在 finalizer 活动里的动作 可以 使用其所属编排的可见域内可见的变量的信息, 属于这个编排的变量处于该编排完成时的状态, 属于相应 enclosing 编排的变量处于它们当时的状态.

finalizer 活动的动作也 可以 失败. 与这种失败错误匹配的语义以及动作与 5.8 部分描述的相同.

5.10 编排协调 (Choreography Coordination)

编排协调保证其涉及的所有角色类型在一个编排如何结束上达成共识, 也就是说, 所有角色类型都一致确认该编排为成功完成或是遭遇一个异常, 当编排成功完成且其终结块被安装时, 所有角色类型在激活哪个终结块上达成一致. 这种共识与基于交互的校准不同, 在这里被协调的编排作为整体进行校准, 无论被协调编排中的各个交互是否校准. 与校准的交互不同, 一个协调的编排提供了一个更大的协调单位 —— 即一组交互, 最终使所有参与方类型达成共识, 它们之间的协调达到了一个明确定义的状态. 这样的协调单位不必在每步上校准 —— 它只要求有一些清晰的校准点, 以保证涉及到的所有角色类型在编排如何结束上取得共识.

要求协调的编排 必须 绑定到一个协调协议上. 在不需要编排协调时, 有关编排则不绑定到一个协调协议上, 而且, 由于这种情况下没有上面那样的对于结果的保证, 所需的任何协调都必须通过明确建模的交互来实施.

编排协调的内涵对于根编排或者 enclosed 编排是不同的:

  • 一个 enclosed 编排 可以 有一个或多个终结块. 对于这种情况, 协调意味着所有角色类型在编排成功完成或遭遇一个异常上取得共识. 如果编排成功完成而且相关终结块被安装, 所有角色类型在应激活哪个终结块上达成一致.

  • 根编排也可以协调, 但它 必须不 包含终结块. 在这种情况下, 协调意味着所有角色类型在编排成功完成或遭遇某异常上达成共识

  • 在这两种情况里, 所有角色类型 必须 对编排是否成功完成取得共识, 如果一个异常发生, 所有角色类型 必须 经历 (experience) 一个异常而不是成功完成. 当编排中发生一个异常, 协调协议将把一个异常抛 (throw) 给还没有识别出该异常发生的角色类型.

当编排没有被协调时, 异常 必须 用导致异常的交互 (exception causing interactions) 明确建模, 将异常传到编排的所有参与方. 这 必须 导致整个编排进入异常状态, 如果这里有明确说明的异常块, 则 必须 激活它.

下面两个例子展示了协调编排的两种用法.

Example 1: Coordinated credit authorization without finalizerBlocks:

<informationType name="creditDeniedType" />

<!-- Coordinated CreditAuthorization Choreography without finalizerBlocks-->
<choreography name="CreditAuthorization" root="false" coordination="true">
   <relationship type="tns:CreditReqCreditResp"/>
   <variableDefinitions>
      <variable name="CreditExtended" informationType="xsd:int" silent="true"       
                roleTypes="tns:CreditResponder"/>
      <variable name="creditRequest"/>
      <variable name="creditAuthorized"/>
      <variable name="creditDenied" informationType = "tns:creditDeniedType"/>
   </variableDefinitions>
   
   <!-- the normal work - receive the request and decide whether to approve -->
   <interaction name="creditAuthorization" channelVariable="tns:CreditRequestor" 
                operation="authorize">
      <participate relationshipType="SuperiorInferior"
                   fromRoleTypeRef="tns:Superior" 
                   toRoleTypeRef="tns:Inferior"/>
      <exchange name="creditRequest" informationType="creditRequest" 
                action="request">
         <send variable="getVariable('tns:creditRequest','','')"/>
         <receive variable="getVariable('tns:creditRequest','','')"/>
      </exchange>
      <exchange name="creditAuthorized" informationType="creditAuthorizedType"   
                action="respond">
         <send variable="getVariable('tns:creditAuthorized','','')"/>
         <receive variable="getVariable('tns:creditAuthorized','','')"/>
      </exchange>
      <exchange name="creditDenied" informationType="creditDeniedType" 
                action="respond">
         <send variable="getVariable('tns:creditDenied','','')"
                         causeException="tns:creditDenied"/>
         <receive variable="getVariable('tns:creditDenied','','')"
                         causeException="tns:creditDenied"/>
      </exchange>
   </interaction>

   <!-- catch the (application) exception - as an exception it will abort the 
        choreography -->
   <exceptionBlock name="handleBadCreditException">
     <workunit  name="handleBadCredit" >
                <interaction name="badCreditInteraction" 
                             channelVariable="tns:CreditResponder"
                             operation="creditDenied">
                    <participate relationshipType="CreditReqCreditResp"
                         fromRoleTypeRef="tns:Responder"
                         toRoleTypeRef="tns:CreditRequestor"/>
      </interaction>
     </workunit>
  </exceptionBlock>
</choreography>

Example 2: Coordinated credit authorization with finalizerBlocks

<informationType name="creditDeniedType" />

<!-- Coordinated CreditAuthorization Choreography with finalizerBlocks -->
<choreography name="CreditAuthorization" root="false" coordination="true">
   <relationship type="tns:CreditReqCreditResp"/>
   <variableDefinitions>
      <variable name="CreditExtended" informationType="xsd:int" silent="true"  
                roleTypes="tns:CreditResponder"/>
      <variable name="creditRequest"/>
      <variable name="creditAuthorized"/>
      <variable name="creditDenied" informationType = "creditDeniedType"/>
   </variableDefinitions>

   <!-- the normal work -receive the request and decide whether to approve -->
   <interaction name="creditAuthorization" channelVariable="tns:CreditRequestor"  
                operation="authorize">
      <participate relationshipType="SuperiorInferior"
                   fromRoleTypeRef="tns:Superior" 
                   toRoleTypeRef="tns:Inferior"/>
      <exchange name="creditRequest" informationType="creditRequest"  
             action="request">
         <send variable="tns:creditRequest"/>
         <receive variable="tns:creditRequest"/>
      </exchange>
      <exchange name="creditAuthorized" informationType="creditAuthorizedType" 
                action="respond">
         <send variable="tns:creditAuthorized"/>
         <receive variable="tns:creditAuthorized"/>
      </exchange>
      <exchange name="creditDenied" informationType="creditDeniedType" 
                action="respond">
         <send variable="tns:creditDenied" causeException="tns:creditDenied"/>
         <receive variable="tns:creditDenied" causeException="tns:creditDenied"/>
      </exchange>
   </interaction>

   <!-- catch the (application) exception - as an exception it will abort the 
        choreography and the finalizerBlocks are not accessible -->
   <exceptionBlock name="handleBadCreditException">
       <workunit  name="handleBadCredit" >
          <interaction name="badCreditInteraction" 
                channelVariable="tns:CreditResponder"
                operation="creditDenied">
                <participate relationshipType="CreditReqCreditResp"
                      fromRoleTypeRef="tns:Responder"
                      toRoleTypeRef="tns:CreditRequestor"/>
          </interaction>
       </workunit>
   </exceptionBlock>

   <!-- finalizerBlocks -->
   <!-- what to do if the credit is drawn down -->
   <finalizerBlock name="drawDown">
      <!-- if there is no application content to send, this could just be an 
           assignment to the statecapturevariable creditExtended -->
       <workunit  name="drawdown" >
            <interaction name="drawdownInteraction" 
                         channelVariable="tns:CreditRequestor"
                         operation="drawDown">
                  <participate relationshipType="CreditReqCreditResp"
                      fromRoleTypeRef="tns:CreditRequestor"
                      toRoleTypeRef="tns:CreditResponder"/>
                  <exchange name="dummy" action="request">
                      <send></send>
                      <receive recordReference="drawdownRecord"/>
                  </exchange>  
                 <record name="drawdownRecord" when="before">
                      <source expression="drawnDown"/>
                      <target variable="CreditExtended"/>
                  </record>               
            </interaction>
           </workunit>
   </finalizerBlock>

   <!-- what to do if the credit is not used -->
   <finalizerBlock name="replenish">      
   <!-- if there is no application content to send, this could just be an  
           assignment to the state capturing variable creditExtended -->
       <workunit name="replenishWU">
            <interaction name="replenishInteraction" 
                         channelVariable="tns:CreditRequestor"
                         operation="replenish">
                <participate relationshipType="CreditReqCreditResp"
                      fromRoleTypeRef="tns:CreditRequestor"
                      toRoleTypeRef="tns:CreditResponder"/>
                <exchange name="dummy" action="request">
                     <send></send>
                       <receive recordReference="replenishRecord"/>
                </exchange>                
                <record name="replenishRecord" when="before">
                       <source expression="released"/>
                       <target variable="CreditExtended"/>
                </record>
             </interaction>
        </workunit>
   </finalizerBlock>
</choreography>        

6 活动

活动 (activity) 描述编排中执行的动作. Activity-Notation 用于定义活动, 它可以是下述几种类型之一:

6.1 序结构 (Ordering Structures)

序结构可以与其他序结构嵌套地把多个活动组合起来, 描述编排里执行的多个活动之间的顺序规则. 一个序结构 可以是如下几种类型:

  • 顺序 (sequence)

  • 并行 (parallel)

  • 选择 (choice)

6.1.1 顺序 (Sequence)

顺序 序结构包含一到多个 Activity-Notation (活动描述). 当顺序结构被激活时, 它所包含的各个活动 (用一个或多个 Activity-Notation 定义) 必须 按其定义的顺序依次激活.

这一结构的语法是:

<sequence>
Activity-Notation+
</sequence>

6.1.2 并行 (Parallel)

并行 序结构包含一到多个 Activity-Notation. 当并行活动被激活时, 这些 Activity-Notation 将同时激活. 当在并行结构中执行工作的所有活动 (用一个或多个Activity-Notation定义) 都成功完成时, 该并行活动也 必须 成功完成.

这一结构的语法是:

<parallel>
Activity-Notation+
</parallel>

6.1.3 选择 (Choice)

选择 序结构说明其内部包含的两个或更多活动 (用两个或多个 Activity-Notation 定义) 中只有一个 应该 执行.

如果在一个 choice 中描述了两个或更多的活动, 则将只有一个活动被选择, 其他活动将被禁止 (disable). 如果该 choice 里包含带卫式约束的工作单元, 第一个卫式条件匹配的工作单元将被选, 其他的工作单元将被禁用. 如果存在多个匹配, 则基于词法顺序选择其一. 如果在选择里包含其他类型的活动, 则假定这些活动的选取标准是不可观察的.

这一结构的语法是:

<choice>
Activity-Notation+
</choice>

下面例子中里的 choice 包含 "processGoodCredit" 和 "processBadCredit" 两个交互活动. 这两个交互的方向相同, 所参与的 relationshipType 相同, 并且它们的 fromRoleTypeRef 和 toRoleTypeRef 名字也相同. 如果其中一个交互发生, 另一个则会被禁用.

<choice>
<interaction name=""processGoodCredit"
channelVariable="goodCredit-channel" operation="doCredit">
...
</interaction>

<interaction name=""processBadCredit"
channelVariable="badCredit-channel" operation="doBadCredit">
...
</interaction>
<choice>

6.2 交互 (Interacting)

交互活动 (interaction) 是编排的基本构件. 其结果是互相协作的参与方之间的信息交换, 并可能对这些参与方的可观察信息的变化以及所交换信息的实际值进行同步.

交互是编排组合的基本元素. 多个交互组合在一起就构成了一个编排, 它可被用于不同的业务环境.

当参与交互的某角色类型通过一个公用通道给参与这个交互的另一角色类型发一条消息时, 该交互活动被初始化. 如果这条初始消息是一个请求, 那么接收方角色类型可以选择用一条正常应答消息或一条失败消息作为应答, 该消息将被发送方角色类型接收.

交互活动也包含对如下内容的 "引用":

  • 一个通道获取变量 (channel capturing variable), 描述与接收方角色类型之间的消息从哪里发送和接收, 如何发送和接收.

  • 一个操作 (operation), 描述接收方在收到消息之后应该做什么.

  • 交互中涉及的 'from' 角色类型和'to' 角色类型

  • 所交换信息的信息类型 (informationType) 或通道类型 (channelType)

  • 'from' 角色类型和 'to' 角色类型的信息交换获取变量 (information exchange capturing variables), 它们是消息内容的来源和目的地.

  • 一系列可能的状态获取变量, 记录所捕捉到的因执行交互而发生的可观察的信息变化.

6.2.1 基于交互的信息校准 (Interaction Based Information Alignment)

在某些编排里可能会有这样的需求: 当某个交互被执行时, 编排中的一些角色类型必须对执行结果达成共识. 说的更明确些, 在一个交互中, 某个角色类型可能需要对一个或多个 状态获取变量 的可观察信息的创建或变化有一个共识, 而这些变量是与某伙伴角色类型上的一个或多个状态变量互补的. 此外, 在一个交互中, 一个角色类型可能要对其伙伴角色类型上的信息交换获取变量 (Information exchange capturing variables) 的值有共同认识.

例如, 在一次交互发生后, "Buyer" 和 "Seller" 希望达成以下共识:

  • 包含 "Buyer" 和 "Seller" 可观察信息的状态获取变量应具有对两者互补的值, 例如 "Order State", 在 "Buyer" 上的值是 "Sent", 而在 "Seller" 上的值是 "Received".

  • 信息交换获取变量应具有同样类型和同样内容. 例如在 "Buyer" 和 "Seller" 上的 "Order" 变量应该有同样的信息类型, 两者中包含同样的订单信息

在 WS-CDL 里, 如果交互的两个参与方需要对其可观察信息的变化和交换信息的值进行校准, 那就 必须 明确地使用校准型交互 (alignment interaction). 当校准型交互结束后, 两个参与方应以一种互锁步骤的方式同时前进, 且双方的变量信息应已被校准. 变量校准来自这样的事实: 在两个参与方采取下一步行动 (progress) 前, 请求方必须确定接受方已经收到了消息; 而接受方也要确定发送方已经发送了消息. 不存在这样的中间状态: 某一方发送了消息后就独立地继续执行, 或者另一方在接受了消息后就独立地继续执行. 换句话说, 在每个校准型交互后, 参与双方都将基于对信息交换和所记录的信息的共识继续行动.

6.2.2 交互的生命周期

当交互的消息交换成功完成时, 该交互 必须 正常完成.

下列情况发生时, 交互必须 非正常完成:

  • 在管理一个请求 (request) 或在参与方处理该请求的过程中, 某个应用程序报错.

  • 在交互被初始化但未完成时, 发生了 time-to-complete 超时

  • 发生其他类型的错误, 例如基于协议的交换失败, 安全性错误, 文档校验错误, 等等.

6.2.3 交互结构的语法

交互结构的语法如下:

<interaction name="NCName"
channelVariable="QName"
operation="NCName"
align="true"|"false"?
initiate="true"|"false"? >

<participate relationshipType="QName"
fromRoleTypeRef="QName" toRoleTypeRef="QName" />

<exchange name="NCName"
faultName="QName"?
informationType="QName"?|channelType="QName"?
action="request"|"respond" >
<send variable="XPath-expression"?
recordReference="list of NCName"?
causeException="QName"? />
<receive variable="XPath-expression"?
recordReference="list of NCName"?
causeException="QName"? />
</exchange>*

<timeout time-to-complete="XPath-expression"
fromRoleTypeRecordRef="list of NCName"?
toRoleTypeRecordRef="list of NCName"? />?

<record name="NCName"
when="before"|"after"|"timeout"
causeException="QName"? >
<source variable="XPath-expression"? | expression="XPath-expression"? />
<target variable="XPath-expression" />
</record>*
</interaction>

name 属性用于为编排里定义的每个交互元素指定一个名字.

channelVariable 属性指定在交互期间用于通讯的通道获取变量. 该通道变量包含该交互的目标参与方的信息. 此信息被用于决定参与方通过哪里, 以及如何发送和接收信息. 在交互 可能 发生之前, 交互中使用的通道变量 必须 在两个角色类型上都可用. 在运行时, 有关通道变量的信息将被进一步扩展. 这要求在编排中交换的消息也要包含引用和 correlation 信息, 例如:

  • 包含某个协议头, 比如一个 SOAP 头, 或者

  • 使用消息中的实际数据值, 例如 "Order" 的 "Order Number" 对于通过这个通道传递的所有消息而言该数据都一样.

operation 属性指定一个与此交互相关的操作. 所指定的操作属于这个交互中使用的通道变量里的通道类型的 roleTypebehavior 元素所标明的接口.

可选的 align 属性设为 "true" 时, 说明这个校准型交换使 fromRoleTypeReftoRoleTypeRef 元素指定的两个交互方将对所交换的信息和其中可观察信息的建立或改变取得共识, 换句话说, 在每个校准型交互之后, 两个参与方所进行的动作将基于双方对所交换消息和所记录信息的共识而进行. 这一属性的默认值为 "false".

可选 属性 initiate 设置为 "true" 时, 这一交互活动 必须 被标记为编排的启动器 (initiator). 此属性的默认值为 "false".

participate 元素里, relationshipType 属性指定该交互所参与的关系类型; fromRoleTypeReftoRoleTypeRef 属性分别指定进行请求和接收的角色类型. toRoleTypeRef 属性所指定的角色类型 必须 与交互中用到的通道变量里的通道类型的 roleType 元素所指定的角色类型相同.

可选exchange 元素允许信息在交互过程中被交换. name 属性用于为这一交换元素指定一个名字.

在交换 (exchange) 元素里, 可选faultName 属性用于将该交换元素标识为基于所指定名字的一次故障交换 (fault exchange). 如果指定了 faultName 属性, 那么它将用于标识有关操作的上下文中的某个特定的故障. 如果该操作是用 WSDL 定义的, 这个故障 必须 以如下方式发生:

  • 对于WSDL1.1, 将使用 "QName" 的 LocalPart 去匹配操作中声明的故障. 如果指定了前缀, 则要求该前缀必须与操作所关联的命名空间相匹配. 如果某个 WSDL1.1 操作含有多个故障引用, 而这些错误引用的 LocalPart 都与在 faultName 属性中所指定的名字相同, 则认为这是一个错误.

  • 对于 WSDL2, 用完整量化的 "QName" 去匹配故障声明. 如果仅指定了 "QName" 的 LocalPart, 那么就先用 targetNamespace 限定 LocalPart, 然后进行匹配. 如果仍找不到匹配的故障声明, 那么就用操作所定义的各故障声明中的 'ref' 属性来匹配这个 LocalPart. 如果某个 WSDL2 操作含有多个故障引用, 而这些故障引用的 LocalPart 都与在 faultName 属性中指定的名字相同, 就认为这是一个错误.

exchange 元素中, 可选informationTypechannelType 属性指明, 在交互中两个角色类型之间所交换的信息属于哪个信息类型或通道类型. informationTypechannelType 属性二者只能出现一个. 如果没有这两个属性, 就假定要么没有信息被交换, 要么从编排定义的角度看, 被交换的信息的类型无关紧要.

exchange 元素中, action 属性描述交互活动中信息交换的方向:

  • 如果 action 属性设为 "request", 信息交换的方向是从 'from' 角色类型到 'to' 角色类型

  • 如果 action 属性设为 "respond", 信息交换的方向是从 'to' 角色类型到 'from' 角色类型

exchange 元素里, send 元素说明在该交互活动中信息从这个角色类型上发送; receive 元素说明信息被这个角色类型接收:

  • sendreceive 元素中的 variable 属性 必须 只使用 WS-CDL 的 getVariable 函数给定

  • sendreceive 元素中描述的 可选 变量的类型 必须informationType 或是 channelType 属性中所描述的类型

  • 如果 action 元素设为 "request", 那么在 send 元素中通过 variable 属性指定的变量 必须 在 'from' 角色类型上有定义; 在 receive 元素中通过 variable 属性所指定的变量 必须 在 'to' 角色类型上有定义. 第 5.2 节描述了变量如何关联到某个特定角色类型上

  • 如果 action 元素设为 "respond", 那么在 send 元素中通过 variable 属性指定的变量 必须 在 'to' 角色类型上有定义; 在 receive 元素中通过 variable 属性所指定的变量 必须 在 'from' 角色类型上有定义. 第 5.2 节描述了变量如何关联到某个特定角色类型上

  • 对于 receive 元素中指定的变量, 必须不silent 属性设为 "true"

  • exchange 元素的 sendreceive 元素里, recordReference 属性包含一个 XML-Schema 引用序列, 引用在这个交互活动中定义的一些 record 元素. 同一 record 元素 可以 在一个交互活动中的不同 sendreceive 元素中被多次引用, 以便允许复用

  • exchange 元素的 sendreceive 元素里, 如果设置了 可选causeException 属性, 则说明某个异常 必须 在相应角色类型上引发. 此时该属性的 "QName" 值用于标识应引发的异常.

  • request 类型的 exchange 必须不 指定 faultName 属性, 也不指定 causeException 属性

  • 如果指定了两个或更多 respond 型的 exchange, 则 必须 在这些 respond 型 exchange 中作一次隐式选择

  • 如果交互活动的 align 属性设为 "false", 那就表明:

    • 对于 request exchange, 只要请求角色类型成功发送了 send 元素中指定的变量所包含的信息, 交互就在这个角色类型上成功完成; 只要接收的角色类型已成功接收了 receive 元素中指定的变量所包含的信息, 交互就在该角色类型上成功完成
    • 对于 response exchange, 只要接收角色类型成功发送了 send 元素中指定的变量所包含的信息, 交互就在这个角色类型上成功完成; 只要请求角色类型已经成功地接收了 receive 元素中指定的变量所包含的信息, 交互就在该角色类型上成功完成
  • 如果交互活动的 align 属性设为 "true", 那就表明只有到该交互的 Request 和 Response exchanges 都成功完成, 而且所有引用的记录都成功完成时, 该交互 必须 成功完成:

    • 对于 request exchange, 当请求角色类型成功发送 send 元素中指定的变量所包含的信息; 而且接收角色类型也成功接收 receive 元素中指定的变量所含有的信息, 该交换才成功完成
    • 对于 response exchange, 当接收角色变量成功发送 send 元素中指定的变量所含有的信息; 而且请求角色类型也已成功地接收 receive 元素中指定的变量所包含的信息, 该交换才成功完成

可选timeout 元素里的 time-to-complete 属性可以指定一个时间范围 (timeframe), 要求本交互启动后 必须 在限定时间范围内完成; 也可以指定一个最后期限 (deadline), 要求交互 必须 在这个期限之前完成. 如果已启动的交互完成之前超过了 time-to-complete 规定的时间, 就引发一个 time-to-complete 超时事件. 如果这个 time-to-complete 事件包含一个时间范围, 其类型 应该 是 XML-Schema 定义的 duration 类型. 如果包含了一个最后期限, 其类型 应该 是 XML-Schema 的 dateTime 类型. 如果使用了 可选fromRoleTypeRecordRef 属性, 它应包含对同一交互中的一些 record 元素的一个 XML-Schema 引用列表, 出现超时时 应该 在 'from' 角色类型上执行这些记录动作. 如果使用了 可选toRoleTypeRecordRef 属性, 它应包含对同一交互中的一些 record 元素的一个 XML-Schema 引用列表. 出现超时时 应该 在 'to' 角色类型上执行执行这些记录动作.

可选record 元素用于在一个角色类型里用别的变量或表达式去创建或改变一个或多个变量的值, 并使之在这个角色类型上可用. name 属性用于为交互活动中的一个 record 元素指定一个不同的名字. 在 record 元素中, sourcetarget 元素分别指定在交互的发送端和接收端发生的信息记录动作.

  • 如果 action 元素设为 "request", 那么在 sourcetarget 元素中所指定的记录动作 必须: 对于 send 是在 'from' 角色类型上发生, 对于 receive 是在 'to' 角色类型上发生

  • 如果 action 元素设为 "response", 那么在 sourcetarget 元素中所指定的记录动作 必须: 对于 send 是在 'to' 角色类型上发生, 对于 receive 是在 'from' 角色类型上发生

record 元素中的 when 属性指定, 在某个请求或应答信息交换中, 或者出现超时时, 记录 (record) 动作的发生是在相应角色类型发送消息之前还是在发送消息之后; 或者收到消息之前还是收到消息之后. 当 when 属性设为 "timeout" 时, 这个 record 元素指定记录动作将在超时时执行. 如果两个或更多 record 元素的 when 属性值相同, 并且都在某个 sendreceive 元素里的 recordReference 属性中被引用, 那么就按定义的顺序依次执行这些记录.

使用record元素时, 遵循如下的规则:

  • source 必须 定义一个 variable 属性或 expression 属性

    • 如果 source 定义了一个 expression 属性, 那么该属性 必须 包含如第 5.3 节中所定义的表达式. 所定义表达式的结果类型 必须 与 target 变量的类型相容

    • 如果 source 定义了一个变量, 那么 source 和 target 变量 必须 类型相容

  • 如果 source 定义了一个变量, 那么 source 和 target 变量 必须 定义在同一角色类型上. 如果定义了 variable 属性, 那么 必须 只使用 WS-CDL 的 getVariable 函数. 该函数内指定的变量应以第 5.2 节中所描述的方式关联于某个特定角色类型

  • target 变量的 silent 属性 必须 不设为 "true"

  • 在一个交互里, 可以 在一方或两方角色类型上指定并执行一个或多个 record元素

  • 一个 record 元素 必须 有引用它的交换元素或者 timeout 元素

  • 如果一个 record 元素中指定了 可选causeException 属性, 那么在相应角色类型上 可能 引发异常. 此时, 该属性的 "QName" 值将用于标识 可能 被引发的异常

  • 如果在一个交互中为同一个角色类型描述了两个或更多 record 元素, 而且设定了这些元素的 causeException 属性说明要引发的异常, 那么这些异常类型中的某一个 可能 被引发. 异常抛出的动作中含有一个隐式关联的不可观察的谓词条件 (predicate condition), 用于决定是否引发异常

  • 如果交互的 align 属性设为 "false", 则表明在每一个记录动作成功完成后, 在 record 元素中创建或改变的信息在 record 元素中指定的角色类型中立即可用.

  • 如果交互的 align 属性被设为 "true", 则表明:

    • 双方角色类型都 应该 保证, 只要交互活动成功完成, 在 record 元素中指定的信息创建或改变都可用

    • 如果在一个交互中指定了两个或更多的 record 元素, 那么交互的成功完成 必须 要求所有的 record 操作都成功完成. 否则, 在 target 属性中指定的所有变量都不会受影响.

下面的例子展示了一个完整的编排, 其中涉及从角色类型 "Consumer" 到角色类型 "Retailer" 的一次交互, 该交互发生在 "retailer-channel" 通道上, 其 exchange 类型是 request/response:

  • "purchaseOrder" 消息是从 "Consumer" 发往 "Retailer" 的一条请求消息

  • "purchaseOrderAck" 消息是从 "Retailer" 发往 "Consumer" 的一条应答消息

  • 通过使用 record 元素, "consumer-channel" 变量在 "Retailer" 上变为可用的

  • 该交互在 "retailer-channel" 上发生, 该通道带有 "purchaseOrderID" token, 此 token 是在通道的 identity 元素中给出的. 这个 identity 元素用于标识 "Retailer" 的业务流程.

  • "purchaseOrder" 请求消息包含 "Retailer" 业务流程的标识, 通过 "purchaseOrder" 消息的 token 定位符给定

  • "purchaseOrderAck" 应答消息包含 "Consumer" 业务流程的标识, 通过 "purchaseOrderAck" 消息的 token 定位符给定

  • 在请求过程中, 作为"purchaseOrder" 交互的一部分, "consumer-channel" 被通过 "retailer-channel" 通道从 "Consumer" 发送给 "Retailer". 这里使用了 record 元素, 以使 "consumer-channel" 在 "Retailer" 角色类型上变为可用的. 如果该交互的 align 属性设为 "true", 那同时就表明 "Consumer" 知道 "Retailer" 现在拥有了 "Consumer" 的联系信息. 作为另一个例子, 也可以通过 record 元素, 让 "Consumer" 将其 "OrderSent" 变量设为 "true", 同时 "Retailer" 也将其 "OrderReceived" 变量设为 "true"

  • 交互 "badPurchaseOrderAckException" 说明, 在参与的双方上都可能发生类型为 "badPOAck" 的异常

<?xml version="1.0" encoding="UTF-8"?>
<package xmlns="http://www.w3.org/2005/10/cdl"
xmlns:cdl="http://www.w3.org/2005/10/cdl"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:rns="http://www.example.com/ConsumerRetailerChoreographyIFsample"
xmlns:tns="http://www.example.com/ConsumerRetailerChoreographysample"
targetNamespace="http://www.example.com/ConsumerRetailerChoreographysample"
name="ConsumerRetailerChoreography"
version="1.0">

<informationType name="purchaseOrderType" type="tns:PurchaseOrderMsg"/>
<informationType name="purchaseOrderAckType" type="tns:PurchaseOrderAckMsg"/>
<informationType name="badPOAckType" type="xsd:QName" />
<informationType name="uriType" type="xsd:string" />
<informationType name="intType" type="xsd:integer" />

<token name="purchaseOrderID" informationType="tns:intType"/>
<token name="retailerRef" informationType="tns:uriType"/>
<token name="consumerRef" informationType="tns:uriType"/>
<tokenLocator tokenName="tns:purchaseOrderID"
informationType="tns:purchaseOrderType" query="/PO/orderId"/>
<tokenLocator tokenName="tns:purchaseOrderID"
informationType="tns:purchaseOrderAckType" query="/PO/orderId"/>
<roleType name="Consumer">
<behavior name="consumerForRetailer" interface="rns:ConsumerRetailerPT"/>
<behavior name="consumerForWarehouse" interface="rns:ConsumerWarehousePT"/>
</roleType>
<roleType name="Retailer">
<behavior name="retailerForConsumer" interface="rns:RetailerConsumerPT"/>
</roleType>

<relationshipType name="ConsumerRetailerRelationship">
<roleType typeRef="tns:Consumer" behavior="consumerForRetailer"/>
<roleType typeRef="tns:Retailer" behavior="retailerForConsumer"/>
</relationshipType>

<channelType name="ConsumerChannel">
<roleType typeRef="tns:Consumer"/>
<reference>
<token name="tns:consumerRef"/>
</reference>
<identity>
<token name="tns:purchaseOrderID"/>
</identity>
</channelType>
<channelType name="RetailerChannel">
<passing channel="ConsumerChannel" action="request" />
<roleType typeRef="tns:Retailer" behavior="retailerForConsumer"/>
<reference>
<token name="tns:retailerRef"/>
</reference>
<identity>
<token name="tns:purchaseOrderID"/>
</identity>
</channelType>

<choreography name="ConsumerRetailerChoreography">
<relationship type="tns:ConsumerRetailerRelationship"/>
<variableDefinitions>
<variable name="purchaseOrder" informationType="tns:purchaseOrderType"
silent="false" />
<variable name="purchaseOrderAck"
informationType="tns:purchaseOrderAckType" />
<variable name="retailer-channel" channelType="tns:RetailerChannel"/>
<variable name="consumer-channel" channelType="tns:ConsumerChannel"/>
<variable name="badPurchaseOrderAck"
informationType="tns:badPOAckType" />
</variableDefinitions>

<interaction name="createPO"
channelVariable="tns:retailer-channel"
operation="handlePurchaseOrder" >
<participate relationshipType="tns:ConsumerRetailerRelationship"
fromRoleTypeRef="tns:Consumer" toRoleTypeRef="tns:Retailer"/>
<exchange name="request"
informationType="tns:purchaseOrderType" action="request">
<send variable="cdl:getVariable('tns:purchaseOrder','','')" />
<receive variable="cdl:getVariable('tns:purchaseOrder','','')"
recordReference="record-the-channel-info" />
</exchange>
<exchange name="response"
informationType="purchaseOrderAckType" action="respond">
<send variable="cdl:getVariable('tns:purchaseOrderAck','','')" />
<receive variable="cdl:getVariable('tns:purchaseOrderAck','','')" />
</exchange>
<exchange name="badPurchaseOrderAckException" faultName="badPurchaseOrderAckException"
informationType="badPOAckType" action="respond">
<send variable="cdl:getVariable('tns:badPurchaseOrderAck','','')"
causeException="tns:badPOAck" />
<receive variable="cdl:getVariable('tns:badPurchaseOrderAck','','')"
causeException="tns:badPOAck" />
</exchange>
<record name="record-the-channel-info" when="after">
<source variable="cdl:getVariable('tns:purchaseOrder','',
'/PO/CustomerRef')"/>
<target variable="cdl:getVariable('tns:consumer-channel','','')"/>
</record>
</interaction>
</choreography>
</package>

6.3 编排组合 (Composing Choreographies)

perform 活动实现编排的组合, 用于组合现有编排以创建新编排. 例如, 假设有如下的两个独立的编排定义:

  • 在 "Request for Quote" ("RFQ") 编排中, "Buyer" 角色类型给 "Supplier" 角色类型发请求, 试图取得其货物和所提供服务的报价单, "Supplier" 角色类型对此应答一个 "Quotation" 或 "Decline to Quote" 消息.

  • 在 "Order Placement" 编排中, "Buyer" 角色类型向 "Supplier" 角色类型下订货单或服务订单. "Supplier" 角色类型要么接受订单, 要么拒绝订单.

可以复用上面这两个编排创建一个新的 "Quote and Order" 编排, 其中首先执行 "RFQ" 编排, 然后根据 "RFQ" 编排的结果, 用 "Order Placement" 编排取代其中的发订单. 在这种情况下, 新编排就是由先前已有定义的两个编排 "组合" 而成. 通过这种途径, 可以将已有编排组合起来支持任意复杂的编排, 也由于可以复用其他地方定义的编排而得到更大的灵活性.

perform 活动使一个编排可以指定另一编排在其定义中的某一点执行, 这使被执行的编排成为一个内部 (enclosed) 编排. 即使被执行的编排在另一不同的编排包中定义, 概念上也应把它看作一个内部编排.

perform 结构的语法是:

<perform choreographyName="QName" 
choreographyInstanceId="XPath-expression"?
block="true|false"? >
<bind name="NCName">
<this variable="XPath-expression" roleType="QName"/>
<free variable="XPath-expression" roleType="QName"/>
</bind>*
Choreography-Notation?
</perform>

perform 元素里, choreographyName 属性给出被执行编排的名字.

可选choreographyInstanceId 属性为 choreographyName 属性所指定编排的执行实例 (performance) 定义一个标识符. 如果被执行编排在其外层 (enclosing) 编排中仅被执行一次, choreographyInstanceId 属性就是 可选 的. 否则就 必须 指定该属性, 而且每个执行实例的属性值 必须 互不相同. 这一要求是动态的. 例如, 如果某个单独的 perform 元素出现在一个可以重复执行的工作单元中, 那么每次执行 perform 时都必须给出不同的 choreographyInstanceId 标识符.

可选block 属性用于说明执行 perform 的编排完成这一 perform 活动前, 是否等待被执行的编排完成:

如果 block 属性设为 "true", 那么 perform 活动 必须 等待被执行的编排完成

如果 block 属性设为 "false", 那么 perform 活动 必须 在激活被执行编排后立刻完成. 这可能导致被执行编排与 perform 活动之后的其他活动同时处于活动状态.

block 属性的默认值为 "true". 为清晰起见, 对任何以非阻塞方式执行的内层编排, 如果到了执行 perform 的外层编排结束时它们还未完成, 那么在外层编排完成时, 就认为它们已经成功完成了.

perform 元素里 可选 的 Choreography-Notation 用于定义只能被此 perform 活动执行的局部编排. 如果给了这一 Choreography-Notation , 那么 perform 元素里的 choreographyName 属性 必须 与 Choreography-Notation 中 choreography 元素里的 name 属性相匹配.

perform 元素中的 可选 元素 bind 使执行 perform 的编排与被执行的编排可以共享信息. 在 bind 元素中, name 属性为在该 perform 活动中声明的每个 bind 元素指定一个名字. bind 元素中的 roleType 属性说明被执行 编排的一个角色类型是执行 perform 的编排的一个角色类型的别名.

this 元素里的 variable 属性指定执行 perform 的编排中的一个变量被绑定到由被执行编排里 free 元素的 variable 属性标识的那个变量上.

这里的规则是:

  • 被执行的编排 必须 或是直接包含于执行 perform 的编排中的局部定义的编排, 或是全局定义的编排. 如果被执行的编排是在另一个不同的编排包中声明的, 那么 必须 先把这个编排包含 (include) 进来, 然后才能执行它.

  • 在一个单独的 bind 元素里的各角色类型 必须 来自同一参与方, 因此, 它们 必须 属于同一个参与方类型

  • this 元素和 free 元素里的 variable 属性 必须 只用 WS-CDL 的 getVariable 函数定义.

  • 对于 free 元素中指定的那些自由变量, 在被执行的编排里这些变量的定义的 free 属性 必须 设为 "true"

  • 被执行的编排之间 必须不 形成循环依赖关系. 例如, 不允许出现编排 "C1" 执行编排 "C2", 而编排 "C2" 又执行编排 "C1" 的情形

下面是一个编排组合的例子. 这里的 "PurchaseChoreography" 编排执行了在全局定义的 "RetailerWarehouseChoreography" 编排, 并把 "purchaseOrderAtRetailer" 变量作为在被执行的 "RetailerWarehouseChoreography" 编排中定义的 "purchaseOrder" 变量的别名. 建立了别名后, "purchaseOrderAtRetailer" 变量被扩展到内层编排里; 可以互换地使用这些变量以共享它们所包含的信息.

<choreography name="PurchaseChoreography">
...
<variableDefinitions>
<variable name="purchaseOrderAtRetailer"
informationType="purchaseOrder" roleTypes="tns:Retailer"/>
</variableDefinitions>
...
<perform choreographyName="RetailerWarehouseChoreography">
<bind name="aliasRetailer">
<this variable="cdl:getVariable('tns:purchaseOrderAtRetailer','','')"
roleType="tns:Retailer"/>
<free variable="cdl:getVariable('tns:purchaseOrder','','')"
roleType="tns:Retailer"/>
</bind>
</perform>
...
</choreography>

<choreography name="RetailerWarehouseChoreography">
<variableDefinitions>
<variable name="purchaseOrder"
informationType="purchaseOrder" roleTypes="tns:Retailer" free="true"/>
</variableDefinitions>
...
</choreography>

6.4 变量赋值 (Assigning Variables)

Assign 活动用于在一个角色类型里, 利用变量或表达式创建或改变一个或多个变量的值, 并使之可用.

赋值活动也 可能 在一个角色类型上的引发异常.

assign 结构的语法是:

<assign roleType="QName">
<copy name="NCName" causeException="QName"? >
<source variable="XPath-expression"?|expression="XPath-expression"? />
<target variable="XPath-expression" />
</copy>+
</assign>

roleType 元素所指定的角色类型上, assign 元素内的 copy 元素用由 source 元素给定 的变量或表达式去创建或改变 target 元素所给定的变量. 这些变量必须定义在同一角色类型上. copy 元素里的 name 属性为该赋值活动中声明的每个 copy 元素指定一个名字.

以下规则适用于赋值:

  • source 必须 定义一个 variable 属性或一个 expression 属性

    • 如果 source 定义了 expression 属性, 那么它 必须 包含一个如 5.3 节所定义的表达式. 所定义表达式的结果类型 必须 与目标变量类型相容 (compatible)
    • 如果 source 定义了一个变量, 那么 source 和 target 变量的类型必须相容
    • 如果 source 定义了一个变量, 那么 source 和 target 变量 必须 定义在同一角色类型上
  • 如果定义了 variable 属性, 它 必须 只使用 WS-CDL 的 getVariable 函数

  • 用作 target 的变量 必须不silent 属性设为 "true"

  • 如果一个 assign 元素里有两个或更多的 copy 元素, 那么它们按定义的顺序依次执行.

  • 如果一个 assign 中指定了两个或更多 copy 元素, 则这一赋值的成功完成 必须 要求所有复制操作都成功完成. 否则 target 属性指定的所有变量都不受影响.

  • 至多一个 copy 元素 可以 指定 可选causeException 属性

  • 如果某个 copy 元素指定了 causeException 属性, 那么在赋值活动完成后, 应该roleType 元素所指定的角色类型上引发一个异常. 此时, causeException 属性的 "QName" 值将用于标识 应该 引发的异常

下面的例子展示赋值结构的几种可能的用法.

例1: 

<assign roleType="tns:Retailer">
<copy name="copyAddressInfo">
<source variable="cdl:getVariable('PurchaseOrderMsg','',
'/PO/CustomerAddress')" />
<target variable="cdl:getVariable('CustomerAddress','','')" />
</copy>
</assign>

例2: 

<assign roleType="tns:Retailer">
<copy name="copyPriceInfo">
  <source expression="(10+237)/34" />
  <target variable="cdl:getVariable('ProductPrice','','','tns:Retailer')" />
</copy>
</assign>

例3: 

<assign roleType="tns:Customer">
<copy name="copyLiteral">
  <source expression="'Hello World'" />
  <target variable="cdl:getVariable('VarName','','','tns:Customer')" />
</copy>
</assign>

6.5 标记无声活动 (Marking Silent Actions)

silentAction 活动是一种明确的标记, 用于标明某些特定于参与方的具有不可观察的操作细节的活动 必须 在该处被执行. 例如, 某个 "Buyer" 用于检查仓库存货的机制对其他参与方而言应该是不可观察的. 但是, 库存水平确实会影响到 "Buyer" 的全局可观察行为, 这一事实需要在编排定义中说明.

silentAction 结构的语法是:

<silentAction roleType="QName"? />

可选roleType 属性用于指明该无声活动将在哪个参与方上执行. 如果某个无声活动的定义里不包含角色类型, 则意味着该活动将在其所在编排中作为关系类型的部分的所有角色类型上执行.

6.6 标记无活动 (Marking the Absence of Actions)

noAction 活动是一种明确的标记, 表示某参与方在该点不执行任何活动. noAction 活动可用于这样的场景: 按照语法需要一个活动, 但在这里又没有适用的活动, 如下面异常块实例所示.

 <exceptionBlock name="handleTimeoutException">
<workunit name="handleTimeoutException" >
<noAction>
</workunit>
</exceptionBlock>

noAction结构的语法是:

<noAction roleType="QName? />

可选roleType 属性用于指定某个具体参与方不执行任何活动. 如果某个无动作定义不包含角色类型, 则意味着作为本动作所在编排中定义的关系类型中的所有角色类型上都不执行活动.

6.7 编排的终结 (Finalizing a Choreography)

finalize 活动用于激活已成功完成的直接内层编排实例中的某个特定终结块, 使这种编排进入定义清晰的完结状态.

如果一个编排没有执行任何包含终结块定义的子编排, 那么它里面就 必须不 包含任何 finalize 活动. finalize 活动 可以 出现在这样的编排中: 该编排已经执行过包含一个或多个预定义终结块的子编排. 此时 finalize 活动可以出现在该编排的体, 或其异常块, 或其终结块里.

对被执行的一个编排实例而言, 至多只有它的一个终结块 应该 被外层编排中随后的活动 (包括异常处理和 finalize 活动) 所激活. 对未安装的终结块执行 finalize 活动没有任何作用.

finalize结构的语法是:

<finalize name="NCName"? choreographyName="NCName"
choreographyInstanceId="XPath-expression"?
finalizerName="NCName"? />

可选name 属性用于为编排包中声明的每个 finalize 元素指定一个唯一名字.

finalize 活动激活已完成的某个直接内层编排实例的一个终结块.

choreographyName 属性用于标识由 perform 结构中的 choreographyName 属性所引用的编排.

可选choreographyInstanceId 属性用于标识应该被终结的已执行编排实例, 其值来自 perform 结构中定义的 choreographyInstanceId 属性. 如果执行 perform 的编排的业务逻辑满足: 当 finalize 活动被激活时, choreographyName 属性指定的编排仅执行过一个实例, 那么就 可以 省略 choreographyInstanceId 属性, 如果 choreographyName 属性所指定的编排可能被执行过多次, 那么 必须 给出 choreographyInstanceId属性.

finalizerName 属性指明应激活已执行实例中的哪个终结块. 如果作为目标的直接内层编排里定义了多个终结块, 那么就 必须 给出 finalizerName 属性.

在下面的例子中, "CreditDecider" 编排为两个投标者 "A" 和 "B" 进行信用授权 (credit authorization), 最多只能选择二者之一. "CreditDecider" 为每个投标者执行一次 "CoordinatedCreditAuthorization" 编排. 然后根据是选择了 "A" 还是 "B", 还是什么都没选择, 为各已执行编排分别启动不同的 finalize 活动.

<choreography name="CreditDecider">

<!-- only a snippet is shown here -->

<parallel>
<perform name="creditForA"
choreographyName="CoordinatedCreditAuthorization"
choreographyInstanceId="'creditForA'">
<!-- bind such that this does the business for A -->
</perform>
<perform name="creditForB"
choreographyName="CoordinatedCreditAuthorization"
choreographyInstanceId="'creditForB'">
<!-- bind such that this does the business for B -->
</perform>
</parallel>

<!-- other stuff here -->

<workunit name="chooseA"
guard="cdl:getVariable('Chosen','','','Broker')='A'" >
<finalize choreographyName="CoordinatedCreditAuthorization"
choreographyInstanceId="'creditForA'"
finalizerName="drawDown"/>
<finalize choreographyName="CoordinatedCreditAuthorization"
choreographyInstanceId="'creditForB'"
finalizerName="replenish"/>
</workunit>

<workunit name="chooseB"
guard="cdl:getVariable('Chosen','','','Broker')='B'" >
<finalize choreographyName="CoordinatedCreditAuthorization"
choreographyInstanceId="'creditForB'"
finalizerName="drawDown"/>
<finalize choreographyName="CoordinatedCreditAuthorization"
choreographyInstanceId="'creditForA'"
finalizerName="replenish"/>
</workunit>

<workunit name="chooseNeither"
guard="cdl:getVariable('Chosen','','','Broker')='0'" >
<finalize choreographyName="CoordinatedCreditAuthorization"
choreographyInstanceId="'creditForA'"
finalizerName="replenish"/>
<finalize choreographyName="CoordinatedCreditAuthorization"
choreographyInstanceId="'creditForB'"
finalizerName="replenish"/>
</workunit>


</choreography>

7 与其他规范的互操作性 (Interoperability)

7.1 与安全框架的互操作性

WS-Security [WSS] 等安全协议对 SOAP 消息作了一些增强, 通过提供消息完整性 (integrity), 消息机密性 (confidentiality) 和单个消息鉴别 (authentication) 获得高质量的保护; 还包括一套将安全令牌与消息关联的通用机制和有关编码安全令牌的描述.

因为消息会对真实世界产生影响, 所以相互协作的各参与方对所交换的信息有强制性的安全需求. WS-Security 和其他安全规范可用于满足此类需求.

违反安全规范中的任一条安全一致性保证 (consistency guarantees) 就会导致 “错误”. 反映到编排中, 这些 "错误" 可能 变成可由不同 "QNames" 区分的异常.

7.2 与可靠消息传递框架 (Reliable Messaging) 的互操作性

WS-Reliability [WSRM] 和 WS-ReliableMessaging [WSRM] 等可靠性规范提供了一种在多个相互协作的参与方之间的可靠信息交换机制. 这些规范规定了所有被交换信息的格式, 但并未对这些信息所封装的业务文档附加任何限制. 这些规范支持基于各种传输协议 (例如 HTTP/S, FTP, SMTP 等) 的消息交互模式 (message exchange patterns), 支持消息之间的确定顺序, 并保证每条消息恰好只传递一次.

违反上述任一条一致性保证将会导致 “错误”. 反映到编排中, 这些 “错误” 就可能 变成可由不同 “QNames” 区分的异常.

7.3 与协调 (Coordination) 框架的互操作性

在WS-CDL中需要一个协调协议 (coordination protocol) 支持 alignment interactionscoordinated choreographies, 以保证即使在失败和消息丢失的情形下, 各参与方也能达成一致. 在此种情形下, alignment interactions 和 coordinated choreographies 必须 被绑定到某个协调协议上.

7.4 与寻址框架的互操作性

Web服务寻址 [WSAD] 提供了一些独立于传输的机制, 以对 Web 服务和消息进行寻址. Web Services Addressing 1.0 - Core 定义了一集抽象属性和一个 XML Infoset [XML], [XMLNS] 表示方式, 用于识别 Web 服务端点, 并服务于消息内部 "端到端" 的端点识别. 基于某种独立于传输的方式, 该规范可使消息传递系统能支持穿过包含有处理结点 (如端点管理器 (endpoint managers), 防火墙和网关) 的网络的消息传输.

WS-Addressing 可传递这样的引用和 correlation 信息: 这些信息可以把经扩展之后的通道变量信息规范为一种统一格式, 因而对其进行处理时, 与具体传输和具体应用程序无关.

WS-Addressing 规范正在制定之中. WS-Choreography 工作组将审核该规范, 并持续地对其进展作出评论.

8 符合性 (Conformance)

8.1 符合要求的 WS-CDL 文档 (Conforming WS-CDL documents)

一个 WS-CDL 文档遵从附录 B (第12节) 中给出的 XML schema, 也遵从规范正文第 2 至 6 节中定义的附加语法和语义约束. 文档的根元素 (root element) 必须<package>, 而且 必须 属于 WS-CDL 的命名空间.

8.2 端点符合性 (Endpoint conformance)

一个符合的 WS-CDL端点 (endpoint) 是一个能正确实现 WS-CDL 编排中定义的某个角色类型的可观察行为的实体.

9 致谢

本文由 Web 服务编排工作组的成员们撰写. 本工作组的主席是 Martin Chapman (Oracle Corporation) 和 Steve Ross-Talbot (Pi4 Technologies Ltd). 全体编辑对工作组成员们所作的贡献表示感谢. 时至本文写作之日, 工作组成员包括: Daniel Austin (Sun Microsystems, Inc.), Abbie Barbir (Nortel Networks), Charlton Barreto (Adobe Systems, Inc), Carine Bournez (W3C), Gary Brown (Pi4 Technologies Ltd), Ugo Corda (SeeBeyond Technology Corporation), Anthony Fletcher (Choreology Ltd), Peter Furniss (Choreology Ltd), Kohei Honda (Queen Mary and Westerfield College), Duncan Johnston-Watt (Enigmatec Corporation), Nickolas Kavantzas (Oracle Corporation), Yves Lafon (W3C), Monica Martin (Sun Microsystems, Inc.), Robin Milner (Cambridge University), Jeff Mischkinsky (Oracle Corporation), Greg Ritzinger (Novell), Nobuko Yoshida (Imperial College London). 工作组的前任成员包括: Assaf Arkin (Intalio Inc.), Alistair Barros (DSTC Pty Ltd (CITEC)), Richard Bonneau (IONA), Allen Brown (Microsoft Corporation), Mike Brumbelow (Apple), David Burdett (Commerce One), Ravi Byakod (Intalio Inc.), Michael Champion (Software AG), David Chapell (Sonic Software), Fred Cummins (EDS), Jon Dart (TIBCO Software), Jean-Jacques Dubray (Attachmate), William Eidson (TIBCO Software), Colleen Evans (Sonic Software), Keith Evans (Hewlett-Packard), Yaron Goland (BEA Systems), Leonard Greski (W. W. Grainger, Inc.), Jim Hendler (University of Maryland (Mind Lab)), Ricky Ho (Cisco Systems Inc.), Andre Huertas (Uniform Code Council), Eunju Kim (National Computerization Agency), Mayilraj Krishnan (Cisco Systems Inc.), Melanie Kudela (Uniform Code Council), Yutaka Kudou (Hitachi, Ltd.), Bruno Kurtic (webMethods, Inc.), Paul Lipton (Computer Associates), Kevin Liu (SAP AG), Francis McCabe (Fujitsu Ltd.), Carol McDonald (Sun Microsystems, Inc.), Greg Meredith (Microsoft Corporation), Eric Newcomer (IONA), Bijan Parsia (University of Maryland (Mind Lab)), Sanjay Patil (IONA), Ed Peters (webMethods, Inc.), Steve Pruitt (Novell), Yoko Seki (Hitachi, Ltd.), Dinesh Shahane (TIBCO Software), Evren Sirin (University of Maryland (Mind Lab)), Ivana Trickovic (SAP AG), William Vambenepe (Hewlett-Packard), Jim Webber (Arjuna Technologies Ltd.), Stuart Wheater (Arjuna Technologies Ltd.), Steven White (SeeBeyond Technology Corporation), Prasad Yendluri (webMethods, Inc.), Hadrian Zbarcea (IONA).

10 参考文献

10.1 规范性文献 (Normative References)

RFC 3023
XML Media Types, M. Murata, S. St.Laurent and D. Kohn, Editors. IETF, January 2001. This RFC is available at http://www.ietf.org/rfc/rfc3023.txt.
RFC 2119
Key words for use in RFCs to Indicate Requirement Levels, S. Bradner, Editor. IETF, March 1997. This RFC is available at http://www.ietf.org/rfc/rfc2119.txt.
RFC 3986
Uniform Resource Identifiers (URI): Generic Syntax, T. Berners-Lee, R. Fielding and L. Masinter, Editors. IETF, January 2005. Obsoletes: RFC 2396, RFC 2732. This RFC is available at http://www.ietf.org/rfc/rfc3986.txt.
Extensible Markup Language (XML) 1.0 (Third Edition)
Extensible Markup Language (XML) 1.0 (Third Edition), Jean Paoli, Eve Maler, Tim Bray, et. al., Editors. World Wide Web Consortium, 04 February 2004. This version is http://www.w3.org/TR/2004/REC-xml-20040204. The latest version is available at http://www.w3.org/TR/REC-xml.
Extensible Markup Language (XML) 1.1
Extensible Markup Language (XML) 1.1, François Yergeau, John Cowan, Tim Bray, et. al., Editors. World Wide Web Consortium, 04 February 2004. This version is http://www.w3.org/TR/2004/REC-xml11-20040204/. The latest version is available at http://www.w3.org/TR/xml11/.
Namespaces in XML
Namespaces in XML, Andrew Layman, Dave Hollander, and Tim Bray, Editors. World Wide Web Consortium, 14 January 1999. This version is http://www.w3.org/TR/1999/REC-xml-names-19990114. The latest version is available at http://www.w3.org/TR/REC-xml-names.
XML Schema Part 1: Structures Second Edition
XML Schema Part 1: Structures Second Edition, David Beech, Murray Maloney, Henry S. Thompson, and Noah Mendelsohn, Editors. World Wide Web Consortium, 28 October 2004. This version is http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/. The latest version is available at http://www.w3.org/TR/xmlschema-1/.
XML Schema Part 2: Datatypes Second Edition
XML Schema Part 2: Datatypes Second Edition, Ashok Malhotra and Paul V. Biron, Editors. World Wide Web Consortium, 28 October 2004. This version is http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/. The latest version is available at http://www.w3.org/TR/xmlschema-2/.
XPointer Framework
XPointer Framework, Paul Grosso, Eve Maler, Jonathan Marsh, and Norman Walsh, Editors. World Wide Web Consortium, 25 March 2003. This version is http://www.w3.org/TR/2003/REC-xptr-framework-20030325/. The latest version is available at http://www.w3.org/TR/xptr-framework/.
XML Inclusions (XInclude) Version 1.0
XML Inclusions (XInclude) Version 1.0, Jonathan Marsh and David Orchard, Editors. World Wide Web Consortium, 20 December 2004. This version is http://www.w3.org/TR/2004/REC-xinclude-20041220/. The latest version is available at http://www.w3.org/TR/xinclude/.
Web Services Description Language (WSDL) Version 2.0 Part 1: Core Language
Web Services Description Language (WSDL) Version 2.0 Part 1: Core Language, Sanjiva Weerawarana, Roberto Chinnici, Martin Gudgin, et. al., Editors. World Wide Web Consortium, 03 August 2005. This version is http://www.w3.org/TR/2005/WD-wsdl20-20050803. The latest version is available at http://www.w3.org/TR/wsdl20.
Basic Profile
Basic Profile Version 1.1, Keith Ballinger, David Ehnebuske, Christopher Ferris et. al., Editors. The Web Services-Interoperability Organization, 24 September 2004. This version is http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html. The latest version is available at http://www.ws-i.org/Profiles/BasicProfile-1.1.html.

10.2 参考性文献 (Informative References)

SOAP Version 1.2 Part 1: Messaging Framework
SOAP Version 1.2 Part 1: Messaging Framework, Marc Hadley, Noah Mendelsohn, Jean-Jacques Moreau, et. al., Editors. World Wide Web Consortium, 24 June 2003. This version is http://www.w3.org/TR/2003/REC-soap12-part1-20030624/. The latest version is available at http://www.w3.org/TR/soap12-part1/.
Processing XML 1.1 documents with XML Schema 1.0 processors
Processing XML 1.1 documents with XML Schema 1.0 processors, Henry S. Thompson , Editor. World Wide Web Consortium, 11 May 2005. This version is http://www.w3.org/TR/2005/NOTE-xml11schema10-20050511/. The latest version is available at http://www.w3.org/TR/xml11schema10.
UDDI v3
UDDI Version 3.0.2, Luc Clement, Andrew Hately, Claus von Riegen, Tony Rogers, Editors. OASIS Open, 19 October 2004. This version is http://uddi.org/pubs/uddi-v3.0.2-20041019.htm. The latest version is available at http://uddi.org/pubs/uddi_v3.htm
Web Service Choreography Interface (WSCI) 1.0
Web Service Choreography Interface (WSCI) 1.0, Assaf Arkin, Sid Askary, Scott Fordin, et. al., Editors. W3C Note. This version is http://www.w3.org/TR/2002/NOTE-wsci-20020808. The latest version is available at http://www.w3.org/TR/wsci.
XLANG
XLANG, Satish Thatte, Author. Microsoft Corporation, 2001. This document is available at http://www.gotdotnet.com/team/xml_wsspecs/xlang-c/default.htm.
WSFL 1.0
Web Services Flow Language (WSFL) Version 1.0, Frank Leymann, Editor. IBM, May 2001. This PDF document is available at http://www-3.ibm.com/software/solutions/webservices/pdf/WSFL.pdf.
WS-BPEL 2.0
Web Services Business Process Execution Language Version 2.0, Assaf Arkin, Sid Askary, Ben Bloch, et. al., Editors. OASIS Open, December 2004. This document is available at http://www.oasis-open.org/committees/download.php/10347/wsbpel-specification-draft-120204.htm.
BPML 1.0
Business Process Modeling Language, Assaf Arkin, Editor. BPMI.org, November 2002. This document is available at http://www.bpmi.org/downloads/BPML1.0.zip.
WPDI XML PDL
Workflow Process Definition Interface -- XML Process Definition Language, Roberta Norin, Editor. The Workflow Management Coalition, October 2002. This pdf document is available at http://www.wfmc.org/standards/docs/TC-1025_10_xpdl_102502.pdf.
WS-CAF 1.0
OASIS Web Services Composite Application Framework (WS-CAF) TC, This TC page is available at http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=ws-caf.
WS-Reliability 1.1
WS-Reliability 1.1 , Kazunori Iwasa, Jacques Durant, Tom Rutt, et. al., Editors. OASIS Open, August 2004. This document is available at http://www.oasis-open.org/committees/download.php/9330/WS-Reliability-CD1.086.zip.
Java Language Specification
Java Language Specification , James Gosling, Bill Joy, Guy Steele, Gilad Bracha, Editors. Sun Microsystems, Inc., 2000. This document is available at http://java.sun.com/docs/books/jls/second_edition/html/j.title.doc.html.
WS-Security TC
OASIS Web Services Security (WSS) TC , This TC page is available at http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wss.
Java 2 Entreprise Edition
Java 2 Platform, Enterprise Edition (J2EE), See http://java.sun.com/j2ee/.
C# Language Specification
C# Language Specification, ECMA.. This document is available at http://www.ecma-international.org/publications/standards/Ecma-334.htm.
Web Services Addressing - Core
Web Services Addressing - Core, Martin Gudgin, Marc Hadley, Editors. World Wide Web Consortium, 17 August 2005. This version is http://www.w3.org/TR/2005/CR-ws-addr-core-20050817. The latest version is available at http://www.w3.org/TR/ws-addr-core.
Resource Description Framework (RDF): Concepts and Abstract Syntax
Resource Description Framework (RDF): Concepts and Abstract Syntax, Graham Klyne, Jeremy J. Carroll, Editors. World Wide Web Consortium, 10 February 2004. This version is http://www.w3.org/TR/2004/REC-rdf-concepts-20040210/. The latest version is available at http://www.w3.org/TR/rdf-concepts/.
OWL Web Ontology Language Overview
OWL Web Ontology Language Overview, Deborah L. McGuinness, Frank van Harmelen, Editors. World Wide Web Consortium, 10 February 2004. This version is http://www.w3.org/TR/2004/REC-owl-features-20040210/. The latest version is available at http://www.w3.org/TR/owl-features/.
UN/CEFACT Modelling Methodology
UN/CEFACT Modelling Methodology - Introduction, United Nations Economic Commission for Europe, 10 January 2005. This document is available at http://www.unece.org/cefact/umm/ch1_intro.pdf
ebBP 2.0
OASIS ebXML Business Process TC, This TC page is available at http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=ebxml-bp.
BPSS 1.1
Business Process Specification Schema v1.01, Business Process Project Team, UN/CEFACT and OASIS, 11 May 2001. This version is http://www.ebxml.org/specs/ebBPSS.pdf.

Mime 类型定义

MIME 媒体类型 (media type) 名:

application

MIME 子类名:

cdl+xml

必选参数:

可选参数:
charset

此参数的语义与 RFC 3023 [RFC 3023] 中的 "application/xml" 媒体类型所规定的 charset 参数的语义相同.

对编码的考虑:

同 RFC 3023 [RFC 3023]第 3.2 节有关 "application/xml" 的描述.

对安全性的考虑:

同 RFC3023 [RFC 3023] 第10 节中所描述的安全性考虑.

对互操作性的考虑:

尚无任何已知的互操作性问题.

已发布的规范:

本文档

使用此媒体类型的应用程序:

目前尚无任何已知应用程序使用此媒体类型.

附加信息:
文件扩展名:

CDL

Fragment identifiers:

与 RFC 3023 [RFC 3023] 第 5 节中对 "application/xml" 的描述相同. .

Base URI:

如 RFC 3023 [RFC 3023] 第 6 节中所规定.

Macintosh 文件类型代码:

TEXT

Person and email address to contact for further information:

Yves Lafon <ylafon@w3.org>

预期使用方式:

COMMON

作者/修改的控制者:

WS-CDL 1.0 规范是 World Wide Web Consortium 的一项工作成果 http://www.w3.org/2002/ws/chor/. W3C 有修改此规范的权力.

B WS-CDL XSD Schemas

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:cdl="http://www.w3.org/2005/10/cdl"
targetNamespace="http://www.w3.org/2005/10/cdl"
elementFormDefault="qualified">

<complexType name="tExtensibleElements">
<annotation>
<documentation>
This type is extended by other WS-CDL component types to allow
elements and attributes from other namespaces to be added.
This type also contains the optional description element that
is applied to all WS-CDL constructs.
</documentation>
</annotation>
<sequence>
<element name="description" minOccurs="0">
<complexType mixed="true">
<sequence minOccurs="0" maxOccurs="unbounded">
<any processContents="lax"/>
</sequence>
<attribute name="type" type="cdl:tDescriptionType" use="optional"
default="documentation"/>
</complexType>
</element>
<element name="CDLExtension" minOccurs="0" maxOccurs="unbounded">
<complexType>
<sequence minOccurs="0" maxOccurs="unbounded">
<any processContents="lax"/>
</sequence>
</complexType>
</element>
</sequence>
<anyAttribute namespace="##other" processContents="lax"/>
</complexType>

<element name="package" type="cdl:tPackage"/>

<complexType name="tPackage">
<complexContent>
<extension base="cdl:tExtensibleElements">
<sequence>
<element name="informationType" type="cdl:tInformationType"
minOccurs="0" maxOccurs="unbounded"/>
<element name="token" type="cdl:tToken" minOccurs="0"
maxOccurs="unbounded"/>
<element name="tokenLocator" type="cdl:tTokenLocator"
minOccurs="0" maxOccurs="unbounded"/>
<element name="roleType" type="cdl:tRoleType" minOccurs="0"
maxOccurs="unbounded"/>
<element name="relationshipType" type="cdl:tRelationshipType"
minOccurs="0" maxOccurs="unbounded"/>
<element name="participantType" type="cdl:tParticipantType"
minOccurs="0" maxOccurs="unbounded"/>
<element name="channelType" type="cdl:tChannelType"
minOccurs="0" maxOccurs="unbounded"/>
<element name="choreography" type="cdl:tChoreography"
minOccurs="0" maxOccurs="unbounded"/>
</sequence>
<attribute name="name" type="NCName" use="required"/>
<attribute name="author" type="string" use="optional"/>
<attribute name="version" type="string" use="optional"/>
<attribute name="targetNamespace" type="anyURI"
use="required"/>
</extension>
</complexContent>
</complexType>

<complexType name="tInformationType">
<complexContent>
<extension base="cdl:tExtensibleElements">
<attribute name="name" type="NCName" use="required"/>
<attribute name="type" type="QName" use="optional"/>
<attribute name="element" type="QName" use="optional"/>
</extension>
</complexContent>
</complexType>

<complexType name="tToken">
<complexContent>
<extension base="cdl:tExtensibleElements">
<attribute name="name" type="NCName" use="required"/>
<attribute name="informationType" type="QName"
use="required"/>
</extension>
</complexContent>
</complexType>

<complexType name="tTokenLocator">
<complexContent>
<extension base="cdl:tExtensibleElements">
<attribute name="tokenName" type="QName" use="required"/>
<attribute name="informationType" type="QName"
use="required"/>
<attribute name="part" type="NCName" use="optional" />
<attribute name="query" type="cdl:tXPath-expr"
use="required"/>
</extension>
</complexContent>
</complexType>

<complexType name="tRoleType">
<complexContent>
<extension base="cdl:tExtensibleElements">
<sequence>
<element name="behavior" type="cdl:tBehavior"
maxOccurs="unbounded"/>
</sequence>
<attribute name="name" type="NCName" use="required"/>
</extension>
</complexContent>
</complexType>

<complexType name="tBehavior">
<complexContent>
<extension base="cdl:tExtensibleElements">
<attribute name="name" type="NCName" use="required"/>
<attribute name="interface" type="QName" use="optional"/>
</extension>
</complexContent>
</complexType>

<complexType name="tRelationshipType">
<complexContent>
<extension base="cdl:tExtensibleElements">
<sequence>
<element name="roleType" type="cdl:tRoleRef" minOccurs="2"
maxOccurs="2"/>
</sequence>
<attribute name="name" type="NCName" use="required"/>
</extension>
</complexContent>
</complexType>

<complexType name="tRoleRef">
<complexContent>
<extension base="cdl:tExtensibleElements">
<attribute name="typeRef" type="QName" use="required"/>
<attribute name="behavior" use="optional">
<simpleType>
<list itemType="NCName"/>
</simpleType>
</attribute>
</extension>
</complexContent>
</complexType>

<complexType name="tParticipantType">
<complexContent>
<extension base="cdl:tExtensibleElements">
<sequence>
<element name="roleType" type="cdl:tRoleRef2"
maxOccurs="unbounded"/>
</sequence>
<attribute name="name" type="NCName" use="required"/>
</extension>
</complexContent>
</complexType>

<complexType name="tRoleRef2">
<complexContent>
<extension base="cdl:tExtensibleElements">
<attribute name="typeRef" type="QName" use="required"/>
</extension>
</complexContent>
</complexType>

<complexType name="tChannelType">
<complexContent>
<extension base="cdl:tExtensibleElements">
<sequence>
<element name="passing" type="cdl:tPassing" minOccurs="0"
maxOccurs="unbounded"/>
<element name="roleType" type="cdl:tRoleRef3"/>
<element name="reference" type="cdl:tReference"/>
<element name="identity" type="cdl:tIdentity" minOccurs="0"
maxOccurs="unbounded"/>
</sequence>
<attribute name="name" type="NCName" use="required"/>
<attribute name="usage" type="cdl:tUsage" use="optional"
default="distinct"/>
<attribute name="action" type="cdl:tAction" use="optional"
default="request"/>
</extension>
</complexContent>
</complexType>

<complexType name="tRoleRef3">
<complexContent>
<extension base="cdl:tExtensibleElements">
<attribute name="typeRef" type="QName" use="required"/>
<attribute name="behavior" type="NCName" use="optional"/>
</extension>
</complexContent>
</complexType>

<complexType name="tPassing">
<complexContent>
<extension base="cdl:tExtensibleElements">
<attribute name="channel" type="QName" use="required"/>
<attribute name="action" type="cdl:tAction" use="optional"
default="request"/>
<attribute name="new" type="boolean" use="optional"
default="false"/>
</extension>
</complexContent>
</complexType>

<complexType name="tReference">
<complexContent>
<extension base="cdl:tExtensibleElements">
<sequence>
<element name="token" type="cdl:tTokenReference"
minOccurs="1" maxOccurs="1"/>
</sequence>
</extension>
</complexContent>
</complexType>

<complexType name="tTokenReference">
<complexContent>
<extension base="cdl:tExtensibleElements">
<attribute name="name" type="QName" use="required"/>
</extension>
</complexContent>
</complexType>

<complexType name="tIdentity">
<complexContent>
<extension base="cdl:tExtensibleElements">
<sequence>
<element name="token" type="cdl:tTokenReference"
minOccurs="1" maxOccurs="unbounded"/>
</sequence>
<attribute name="usage" type="cdl:tUsageI" use="optional"
default="primary"/>
</extension>
</complexContent>
</complexType>


<complexType name="tChoreography">
<complexContent>
<extension base="cdl:tExtensibleElements">
<sequence>
<element name="relationship" type="cdl:tRelationshipRef"
maxOccurs="unbounded"/>
<element name="variableDefinitions"
type="cdl:tVariableDefinitions" minOccurs="0"/>
<element name="choreography" type="cdl:tChoreography"
minOccurs="0" maxOccurs="unbounded"/>
<group ref="cdl:activity"/>
<element name="exceptionBlock" type="cdl:tException"
minOccurs="0"/>
<element name="finalizerBlock" type="cdl:tFinalizer"
minOccurs="0" maxOccurs="unbounded"/>
</sequence>
<attribute name="name" type="NCName" use="required"/>
<attribute name="complete" type="cdl:tBoolean-expr"
use="optional"/>
<attribute name="isolation" type="boolean"
use="optional" default="false"/>
<attribute name="root" type="boolean" use="optional"
default="false"/>
<attribute name="coordination" type="boolean" use="optional"
default="false"/>
</extension>
</complexContent>
</complexType>

<complexType name="tRelationshipRef">
<complexContent>
<extension base="cdl:tExtensibleElements">
<attribute name="type" type="QName" use="required"/>
</extension>
</complexContent>
</complexType>

<complexType name="tVariableDefinitions">
<complexContent>
<extension base="cdl:tExtensibleElements">
<sequence>
<element name="variable" type="cdl:tVariable"
maxOccurs="unbounded"/>
</sequence>
</extension>
</complexContent>
</complexType>

<complexType name="tVariable">
<complexContent>
<extension base="cdl:tExtensibleElements">
<attribute name="name" type="NCName" use="required"/>
<attribute name="informationType" type="QName"
use="optional"/>
<attribute name="channelType" type="QName" use="optional"/>
<attribute name="mutable" type="boolean" use="optional"
default="true"/>
<attribute name="free" type="boolean" use="optional"
default="false"/>
<attribute name="silent" type="boolean" use="optional"
default="false"/>
<attribute name="roleTypes" use="optional">
<simpleType>
<list itemType="QName"/>
</simpleType>
</attribute>
</extension>
</complexContent>
</complexType>

<group name="activity">
<choice>
<element name="sequence" type="cdl:tSequence"/>
<element name="parallel" type="cdl:tParallel"/>
<element name="choice" type="cdl:tChoice"/>
<element name="workunit" type="cdl:tWorkunit"/>
<element name="interaction" type="cdl:tInteraction"/>
<element name="perform" type="cdl:tPerform"/>
<element name="assign" type="cdl:tAssign"/>
<element name="silentAction" type="cdl:tSilentAction"/>
<element name="noAction" type="cdl:tNoAction"/>
<element name="finalize" type="cdl:tFinalize"/>
<any namespace="##other" processContents="lax"/>
</choice>
</group>

<complexType name="tSequence">
<complexContent>
<extension base="cdl:tExtensibleElements">
<sequence>
<group ref="cdl:activity" maxOccurs="unbounded"/>
</sequence>
</extension>
</complexContent>
</complexType>

<complexType name="tParallel">
<complexContent>
<extension base="cdl:tExtensibleElements">
<sequence>
<group ref="cdl:activity" maxOccurs="unbounded"/>
</sequence>
</extension>
</complexContent>
</complexType>

<complexType name="tChoice">
<complexContent>
<extension base="cdl:tExtensibleElements">
<sequence>
<group ref="cdl:activity" maxOccurs="unbounded"/>
</sequence>
</extension>
</complexContent>
</complexType>

<complexType name="tWorkunit">
<complexContent>
<extension base="cdl:tExtensibleElements">
<sequence>
<group ref="cdl:activity"/>
</sequence>
<attribute name="name" type="NCName" use="required"/>
<attribute name="guard" type="cdl:tBoolean-expr"
use="optional"/>
<attribute name="repeat" type="cdl:tBoolean-expr"
use="optional"/>
<attribute name="block" type="boolean"
use="optional" default="false"/>
</extension>
</complexContent>
</complexType>

<complexType name="tPerform">
<complexContent>
<extension base="cdl:tExtensibleElements">
<sequence>
<element name="bind" type="cdl:tBind"
minOccurs="0" maxOccurs="unbounded"/>
<element name="choreography" type="cdl:tChoreography"
minOccurs="0" maxOccurs="1"/>
</sequence>
<attribute name="choreographyName" type="QName" use="required"/>
<attribute name="choreographyInstanceId" type="cdl:tXPath-expr" use="optional"/>
<attribute name="block" type="boolean"
use="optional" default="true"/>
</extension>
</complexContent>
</complexType>

<complexType name="tBind">
<complexContent>
<extension base="cdl:tExtensibleElements">
<sequence>
<element name="this" type="cdl:tBindVariable"/>
<element name="free" type="cdl:tBindVariable"/>
</sequence>
<attribute name="name" type="NCName" use="required"/>
</extension>
</complexContent>
</complexType>

<complexType name="tBindVariable">
<complexContent>
<extension base="cdl:tExtensibleElements">
<attribute name="variable" type="cdl:tXPath-expr"
use="required"/>
<attribute name="roleType" type="QName" use="required"/>
</extension>
</complexContent>
</complexType>

<complexType name="tInteraction">
<complexContent>
<extension base="cdl:tExtensibleElements">
<sequence>
<element name="participate" type="cdl:tParticipate"/>
<element name="exchange" type="cdl:tExchange" minOccurs="0"
maxOccurs="unbounded"/>
<element name="timeout" type="cdl:tTimeout" minOccurs="0"
maxOccurs="1"/>
<element name="record" type="cdl:tRecord" minOccurs="0"
maxOccurs="unbounded"/>
</sequence>
<attribute name="name" type="NCName" use="required"/>
<attribute name="channelVariable" type="QName"
use="required"/>
<attribute name="operation" type="NCName" use="required"/>
<attribute name="align" type="boolean" use="optional"
default="false"/>
<attribute name="initiate" type="boolean"
use="optional" default="false"/>
</extension>
</complexContent>
</complexType>

<complexType name="tTimeout">
<complexContent>
<extension base="cdl:tExtensibleElements">
<attribute name="time-to-complete" type="cdl:tXPath-expr" use="required"/>
<attribute name="fromRoleTypeRecordRef" use="optional">
<simpleType>
<list itemType="NCName"/>
</simpleType>
</attribute>
<attribute name="toRoleTypeRecordRef" use="optional">
<simpleType>
<list itemType="NCName"/>
</simpleType>
</attribute>
</extension>
</complexContent>
</complexType>

<complexType name="tParticipate">
<complexContent>
<extension base="cdl:tExtensibleElements">
<attribute name="relationshipType" type="QName" use="required"/>
<attribute name="fromRoleTypeRef" type="QName" use="required"/>
<attribute name="toRoleTypeRef" type="QName" use="required"/>
</extension>
</complexContent>
</complexType>

<complexType name="tExchange">
<complexContent>
<extension base="cdl:tExtensibleElements">
<sequence>
<element name="send" type="cdl:tVariableRecordRef"/>
<element name="receive" type="cdl:tVariableRecordRef"/>
</sequence>
<attribute name="name" type="NCName" use="required"/>
<attribute name="faultName" type="QName"
use="optional"/>
<attribute name="informationType" type="QName"
use="optional"/>
<attribute name="channelType" type="QName"
use="optional"/>
<attribute name="action" type="cdl:tAction2" use="required"/>
</extension>
</complexContent>
</complexType>

<complexType name="tVariableRecordRef">
<complexContent>
<extension base="cdl:tExtensibleElements">
<attribute name="variable" type="cdl:tXPath-expr"
use="optional"/>
<attribute name="recordReference" use="optional">
<simpleType>
<list itemType="NCName"/>
</simpleType>
</attribute>
<attribute name="causeException" type="QName"
use="optional" />
</extension>
</complexContent>
</complexType>

<complexType name="tRecord">
<complexContent>
<extension base="cdl:tExtensibleElements">
<sequence>
<element name="source" type="cdl:tSourceVariableRef"/>
<element name="target" type="cdl:tVariableRef"/>
</sequence>
<attribute name="name" type="NCName" use="required"/>
<attribute name="causeException" type="QName" use="optional" />
<attribute name="when" type="cdl:tWhenType" use="required"/>
</extension>
</complexContent>
</complexType>

<complexType name="tSourceVariableRef">
<complexContent>
<extension base="cdl:tExtensibleElements">
<attribute name="variable" type="cdl:tXPath-expr"
use="optional"/>
<attribute name="expression" type="cdl:tXPath-expr"
use="optional"/>
</extension>
</complexContent>
</complexType>

<complexType name="tVariableRef">
<complexContent>
<extension base="cdl:tExtensibleElements">
<attribute name="variable" type="cdl:tXPath-expr"
use="required"/>
</extension>
</complexContent>
</complexType>

<complexType name="tAssign">
<complexContent>
<extension base="cdl:tExtensibleElements">
<sequence>
<element name="copy" type="cdl:tCopy"
maxOccurs="unbounded"/>
</sequence>
<attribute name="roleType" type="QName" use="required"/>
</extension>
</complexContent>
</complexType>

<complexType name="tCopy">
<complexContent>
<extension base="cdl:tExtensibleElements">
<sequence>
<element name="source" type="cdl:tSourceVariableRef"/>
<element name="target" type="cdl:tVariableRef"/>
</sequence>
<attribute name="name" type="NCName" use="required"/>
<attribute name="causeException" type="QName"
use="optional" />
</extension>
</complexContent>
</complexType>

<complexType name="tSilentAction">
<complexContent>
<extension base="cdl:tExtensibleElements">
<attribute name="roleType" type="QName" use="optional"/>
</extension>
</complexContent>
</complexType>

<complexType name="tNoAction">
<complexContent>
<extension base="cdl:tExtensibleElements">
<attribute name="roleType" type="QName" use="optional"/>
</extension>
</complexContent>
</complexType>

<complexType name="tFinalize">
<complexContent>
<extension base="cdl:tExtensibleElements">
<attribute name="name" type="NCName" use="required"/>
<attribute name="choreographyName" type="NCName" use="required"/>
<attribute name="choreographyInstanceId" type="cdl:tXPath-expr"
use="optional"/>
<attribute name="finalizerName" type="NCName" use="optional"/>
</extension>
</complexContent>
</complexType>

<complexType name="tException">
<complexContent>
<extension base="cdl:tExtensibleElements">
<sequence>
<element name="workunit" type="cdl:tWorkunit"
maxOccurs="unbounded"/>
</sequence>
<attribute name="name" type="NCName" use="required"/>
</extension>
</complexContent>
</complexType>

<complexType name="tFinalizer">
<complexContent>
<extension base="cdl:tExtensibleElements">
<sequence>
<group ref="cdl:activity"/>
</sequence>
<attribute name="name" type="NCName" use="required"/>
</extension>
</complexContent>
</complexType>

<simpleType name="tAction">
<restriction base="string">
<enumeration value="request-respond"/>
<enumeration value="request"/>
<enumeration value="respond"/>
</restriction>
</simpleType>

<simpleType name="tAction2">
<restriction base="string">
<enumeration value="request"/>
<enumeration value="respond"/>
</restriction>
</simpleType>

<simpleType name="tUsage">
<restriction base="string">
<enumeration value="once"/>
<enumeration value="distinct"/>
<enumeration value="shared"/>
</restriction>
</simpleType>

<simpleType name="tUsageI">
<restriction base="string">
<enumeration value="primary"/>
<enumeration value="alternate"/>
<enumeration value="derived"/>
<enumeration value="association"/>
</restriction>
</simpleType>

<simpleType name="tWhenType">
<restriction base="string">
<enumeration value="before"/>
<enumeration value="after"/>
<enumeration value="timeout"/>
</restriction>
</simpleType>


<simpleType name="tBoolean-expr">
<restriction base="string"/>
</simpleType>

<simpleType name="tXPath-expr">
<restriction base="string"/>
</simpleType>

<simpleType name="tDescriptionType">
<restriction base="string">
<enumeration value="documentation"/>
<enumeration value="reference"/>
<enumeration value="semantics"/>
</restriction>
</simpleType>

</schema>