随笔-128  评论-55  文章-5  trackbacks-0
 

理解 WSRF第1部分-使用 WS-ResourceProperties

 

本教程是一个由 4 部分组成的系列文章中的第 1 部分,该系列介绍 WSRF 背后的概念。WSRF 是一组规范,提供一种标准方式,在 Web 服务应用程序的本质上“无状态的”环境中与“有状态”资源交互。这种有状态资源实际上可以是任何东西,从数据库到电子鼠标都是有状态资源。实际上,可以使用 WSRF 来处理任何可以通过改变其属性来操纵的东西。

WS-Resource 是一个有状态资源(比如数据库或硬盘)和它与之交互的 Web 服务的组合。本教程解释了创建 WS-Resources、请求和更新用于定义 WS-Resource 状态的属性。我们将介绍以下内容:

1.       WSRF 规范的概述。

2.       本系列教程中使用的系统的概述。

3.       关于 WSDL 的基本信息。

4.       关于的 WS-Addressing 的基本信息,WS-Addressing 用于定位 WS-Resource。

5.       创建 WS-Resource。

6.       获得和设置 WS-Resource 属性。

注意,WSRF 作为一种规范,定义了描述这些操作的 WSDL 文件的结构。该 WSDL 文件然后可以被任何语言的实现所使用。本教程描述 WSDL 文件的创建并展示产生的 SOAP 消息。

一定要明白,WSRF 规范只定义应该做什么,而不定义应该如何做。这里描述的概念的实际实现留给了应用程序去完成。在本系列的第 4 部分中,我们将使用 Globus Alliance 提供的 Core Java WSRF 类来讨论该实现。

在本系列中,我们将使用一系列围绕地球的人造卫星作为例子。我们将创建一个 WS-Resource,它就代表这样一个人造卫星。然后我们将请求它的属性以检索它的数据,更改它的属性以将它发射到天空中,并更改它观测的对象。

l         网格计算简介

首先,我们指出 WSRF 的应用远远超出了网格,但是 WSRF 是在网格中开发的,所以网格是 WSRF 可以做什么的一个很好的例子。之后,将花点时间为那些不熟悉网格的人解释一下网格是什么。

数百万的 Web 用户已经体验了网格计算,只是大多数人都没有感觉到而已。1998 年,由于 NASA 发起了一个新计划,使得 Search for Extraterrestrial Intelligence (SETI) 项目差点夭折,此时就创建了也许是最著名的网格计算项目。他们的 Aricebo 无线电望远镜得到非常大量的数据,但是没有足够的处理能力可以处理这些数据。为了解决这个问题,他们创建了一个 screensaver,当计算机不忙时,它会从中央服务器请求一包数据并进行分析,然后把结果发送回去。然后又请求一包新的数据,并重复刚才的步骤。数百万用户下载了 screensaver 并参与该项目。

大型网格应用程序更加复杂,要处理的问题也更多,这些问题与身份验证、跨组织边界的进程间通信和高性能数据传输等方面有关。尽管网格狂热者可能不愿意听到 SETI@Home 的情况,但是它确实提供了网格工作原理的一个很好的例子。它涉及以下步骤:

工作被分成适合于在多个系统上处理的“单元”。该“工作”可以是计算、存储或其他类型的处理。

单元被分布到多个客户机。这个步骤通过让客户机请求或“pull”工作,或者让中央服务器将工作“push”给可用的客户机来完成。

总体进展、需求和状态由中央系统或系统组维护。

当前的网格应用程序一般遵循这种模式,有一个中央系统与客户机交互,这些客户机位于那些一般在地理位置上与中央服务器分离的系统上。

l         使用 Web 服务:承诺和问题

既然多个客户机在不同的地方,那么 Web 服务应该是网格计算顺理成章的选择。毕竟,它提供一种标准而容易的方法,以从一个系统到另一个系统获得信息,而不用求助于特定于平台或语言的方法,比如 CORBA、DCOM 或 Java-RMI。

但是,原来并不是这样的。早期的网格应用程序使用其他更加不可移植的方法。但是为什么呢?

也许最贴切的是体系结构方面的原因。尽管网格应用程序可以在很多机器上实现,但它仍然是一个应用程序,因此很难与本质上是无状态的体系结构相协调。当使用数据库客户机连接到一个数据库时,您就保持了连接,并且可以插入记录,然后再查看插入的结果。另一个客户查看表时不会看到该记录,除非您提交了事务,但是数据库认识您的会话,并知道是您。

Web 服务的工作方式不是这样的。利用 Web 服务,您发出请求(比如插入一条记录)并得到响应(比如插入成功),然后断开连接。没有正在进行的会话需要管理。例如 HTTP —— 在大多数情况下,Web 服务通过 HTTP 传输 —— 每个请求独立于前一个请求,Web 服务没有访问或使用任何不是当前输入消息一部分的信息。

WSRF 的目标是通过创建“状态”概念以及处理状态的方法来解决该问题。

l         有状态资源

那么到底什么是“状态”,什么又是“有状态”资源呢?

有状态资源是一些即使您不与之交互也存在的东西。例如数据库,即使在您不查询它的时候,它也存在。围绕行星的人造卫星即使在您不与之对话时也存在。甚至简单的计数器,在调用之间,或者每次调用它返回一个 1 时,都必须存在。

此外,一定要明白,状态概念也包含属性的思想。当要求您把所借的东西以原状态返还时,涉及某些属性的值,比如清洁度、修理要求、油罐中的汽油量,等等。有状态资源与此类似,具有定义其状态的属性,并且这些属性就是我们将与资源交互的方式,如 WS-Resource 的属性 中所示。

l         Web 服务 + 有状态资源 = WS-Resource

根据规范可知,WS-Resource 是 Web 服务与它在其上起作用的有状态资源的组合。但是这真正的含义是什么呢?

让我们从实际的角度来看这个问题。假设我们有一个系统,涉及到管理一组人造卫星。每个人造卫星是一个有状态资源,因为即使在我们不与之对话时它也存在。我们还有一个 Web 服务,它提供人造卫星功能,比如更改反向、检索信息,或者甚至调整姿势。

通过将者二者组合起来,我们创建了一个 WS-Resource。注意,并不需要一对一的对应关系。例如,这个 Web 服务可以与几个不同的人造卫星交互,从而创建几个引用相同服务的不同 WS-Resources。另一方面,一个人造卫星可以与几个不同的服务(比如控制宇宙实验的服务和发射激光束的服务)交互,从而创建几个引用相同有状态资源的不同 WS-Resources。

为了使用 WS-Resource,必须了解它的属性。

l         WS-Resource 的属性

正如 有状态资源 中所提到的,有状态资源(以及 WS-Resource)具有各种与之相关的属性。例如,人造卫星可能具有以下属性:

latitude

longitude

altitude

pitch

yaw

roll

focalLength

currentView

在本例中,latitude、longitude 和 altitude 这前三个属性指定人造卫星的位置。其次,pitch、 yaw 和 roll 指定它的方位,或者说它看起来的方向。最后两个属性,focalLength 和 currentView,指定它离观测点的距离以及它在这一点所看到的东西。

这些属性的值定义资源的状态。更改属性值,就更改了状态。事实上,我们就是这样来控制人造卫星的。要更改它的位置,我们就改变它的一个位置属性。要更改它的方位,我们就改变它的一个方位属性。实际上,我们想要对该人造卫星做任何事情(在这个非常有限的实现中),我们都只要改变这些属性就可以了。

但是如何来做到 这一点?

l         进入 WSRF

好了,既然 WS-Resource 是有状态资源和 Web 服务的组合,并且我们通过请求和设置它的属性来操纵它,那么如何来做到这一点呢?

有很多方法来做到这一点,但是问题也正在于此。需要的是一种做出请求的标准方式,以获取和设置各个属性。

进入 WSRF。WSRF 实际上是一系列规范,用于定义标准的“消息模式”或方法,以请求属性的值或者指定这些属性应该变更。实际上,WSRF 定义一些标准方法,以处理关于处理 WS-Resources 的各个方面,比如处理它们的属性,从而将它们成组在一起,以达到诸如这样的目的 —— 进行身份验证,确保它们被及时地销毁。

WSRF 定义这些操作的方法是,指定它们应该如何出现在 Web 服务描述语言(Web Services Description Language,WSDL)文件中。WSDL 文件定义 Web 服务会话两端之间传输的消息,所以通过定义 WSDL 文件,WSRF 定义了发生的任何交互的形式。

当我们说到“WSRF”时,实际上是指几个不同的规范:

1.       WS-ResourceProperties (WSRF-RP)指定 ResourceProperties 在 WSDL 文件中被定义的形式。它还指定消息的形式,这些消息用于请求和接收属性的值,还解释了如何更改、添加和删除 WS-Resource 的属性。

2.       WS-ResourceLifetime (WSRF-RL)谈论这样一些状态,即 WS-Resource 需要过期了,或者在它不再需要了时应该被显式地销毁。

3.       WS-ServiceGroup (WSRF-SG)定义创建一组 Web 服务(比如可用服务的注册表)的方法。

4.       WS-Base Faults (WSRF-BF)定义一种标准的方法,用于指出基于 WSRF 的应用程序中的错误。

您将注意到,没有哪一个规范简单地描述了所有这一切应该如何一起工作。这项工作(几乎)是由 Modeling Stateful Resources with Web Services 白皮书完成的,该书解释了一般的概念,并将它们联系在一起。

本教程除了介绍白皮书中的一些概念之外,还将讨论 WS-ResourceProperties 规范。本系列的以后各期将讨论其他的 WSRF 规范,以及 Web Services Notifications (WSN) 规范(整个 WSRF 中都引用了这些规范)。

l         什么是 WSDL,为什么我要关注它?

在正式开始在 WSDL 文件中创建 WS-Resources 之前,我们首先花点时间来看一下 WSDL 文件的目的和结构。这些描述就是在 WSDL 文件中。

Web 服务 —— 或者至少是与 WS-Resources 相关的 Web 服务 —— 由 SOAP 消息组成。SOAP 消息具有一个标准的“信封”,其中包含一个“有效负载”。该有效负载是由服务器(在请求时)和客户机(在响应时)分析的数据。考虑下面这个 SOAP 消息:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">

    <SOAP-ENV:Header/>

    <SOAP-ENV:Body>

        <SetAltitudeRequest xmlns="http://example.com/satellite.xsd">

            <altitude>47700</altitude>

        </SetAltitudeRequest>

    </SOAP-ENV:Body>

</SOAP-ENV:Envelope>

它包含标准信封和有效负载,前者在 http://schemas.xmlsoap.org/soap/envelope/ 名称空间(SOAP-ENV)中,后者在 http://example.com/satellite.xsd 名称空间中。

有效负载可以是任何东西,因此存在这样一个问题:如何定义应用程序期望看到什么,以及返回什么?因而有了 WSDL 文件的用武之地。最终,我们将使用一个 WSDL 文件来定义 WS-Resource 所使用的“消息模式”,但是在本节,我们只来看 WSDL 文件的各部分是如何组合在一起的。

l         消息和类型

我们首先定义一条我们将会发送的实际消息:

<?xml version="1.0"?>

<definitions name="Satellite"

    targetNamespace="http://example.com/satellite.wsdl"

    xmlns:tns="http://example.com/satellite.wsdl"

    xmlns:satTypes="http://example.com/satellite.xsd"

    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"

    xmlns="http://schemas.xmlsoap.org/wsdl/">

    <types>

        <schema targetNamespace="http://example.com/satellite.xsd"

              xmlns="http://www.w3.org/2000/10/XMLSchema">

           <element name="SetAltitudeRequest">

              <complexType>

                  <all>

                      <element name="altitude" type="float"/>

                  </all>

              </complexType>

           </element>

           <element name="SetAltitudeResponse">

              <complexType>

                  <all>

                      <element name="result" type="string"/>

                  </all>

              </complexType>

           </element>

       </schema>

    </types>

    <message name="SetAltitudeInput">

        <part name="body" element="satTypes:SetAltitudeRequest"/>

    </message>

    <message name="SetAltitudeOutput">

        <part name="body" element="satTypes:SetAltitudeResponse"/>

    </message>

</definitions>

从底部开始,我们定义了两种类型的消息。第一种是 SetAltitudeInput,这是我们将发送给服务器作为输入的消息。它是您在什么是 WSDL,为什么我要关注它? 中看到的 SOAP 消息中的消息。第二种消息是 SetAltitudeOutput,这是服务器发送给客户机的响应。两种消息都指定一个元素,消息体将放在该元素中。

这些元素的实际定义位于文件顶部的模式(schema)中。例如,SetAltitudeInput 消息包含一个 SetAltitudeRequest 元素,该元素自己又包含一个 altitude 元素,后面这个元素的内容必须是一个 float。

接下来,我们将组合这些消息,以创建服务器执行的一个操作。

l         端口类型和操作

既然知道了我们将要发送的消息是什么,现在就需要指定它们将要完成的角色。要做到这一点,我们将创建一个 portType 及其相关的 operation:

...

    <message name="SetAltitudeInput">

        <part name="body" element="satTypes:SetAltitudeRequest"/>

    </message>

    <message name="SetAltitudeOutput">

        <part name="body" element="satTypes:SetAltitudeResponse"/>

    </message>

    <portType name="AltitudePortType">

        <operation name="SetAltitude">

           <input message="tns:SetAltitudeInput"

                  wsa:Action="http://example.com/SetAltitude" />

           <output message="tns:SetAltitudeOutput"

                  wsa:Action="http://example.com/SetAltitudeResponse" />

        </operation>

    </portType>

</definitions>

这里,我们定义了一个 portType 叫做 AltitudePortType,以及它的一个 operation 叫做 SetAltitude。我们实际上可以在该 portType 中定义任意数量的操作,但是现在我们是为了保持简单。SetAltitude 操作指定一个 input 消息 SetAltitudeInput 和一个 output 消息 SetAltitudeOutput。(下一节我们将处理 wsa:Action 属性。此外,请注意名称空间信息。)

您也可以指定一个 fault 消息在有问题时发送,在本教程系列的后面将会介绍这一点,但是现在还是保持简单。

l         服务和绑定

至此,我们已经使用 portType 定义了可以做什么 事情,但是没有定义如何 做。要完成这个过程,我们需要创建一个描述如何做的 binding,并将它附加到实际的 service:

...

    <portType name="AltitudePortType">

        <operation name="SetAltitude">

           <input message="tns:SetAltitudeInput"

                  wsa:Action="http://example.com/SetAltitude" />

           <output message="tns:SetAltitudeOutput"

                  wsa:Action="http://example.com/SetAltitudeResponse" />

        </operation>

    </portType>

    <binding name="AltitudeSoapBinding" type="tns:AltitudePortType">

        <soap:binding style="document"

                  transport="http://schemas.xmlsoap.org/soap/http"/>

        <operation name="SetAltitude">

           <input>

               <soap:body use="literal"/>

           </input>

           <output>

               <soap:body use="literal"/>

           </output>

        </operation>

    </binding>

    <service name="SatelliteService">

        <port name="AltitudePort" binding="tns:AltitudeSoapBinding">

            <soap:address location="http://example.com/satellite"/>

        </port>

    </service>

</definitions>

我们还是从底部开始,先看 service 元素。一个 WSDL 文件可以定义多个服务。例如,您可能有用于不同目的的不同服务,或者在不同位置有具有相同目的的不同服务,或者具有不同绑定的不同服务,比如一个用于 SOAP 的服务和一个用于 SMTP 的服务。

在本例中,我们将利用一个端口 AltitudePort 来定义一个服务 SatelliteService。但是我们知道关于该端口的哪些情况呢?哦,我们知道 SOAP 请求应该发送到 http://example.com/satellite。我们还知道,为了获得关于如何发送消息的更多信息,应该检查 AltitudeSoapBinding。

AltitudeSoapBinding 指定它是 AltitudePortType 的一个实现,所以我们知道发送什么消息。binding 本身指定每个操作中的消息是如何格式化的。在本例中,我们使用“document/literal”样式,这意味着我们只是将定义好的元素拖放到 Body 中。

我们知道了消息将发送到哪里,如何格式化这些消息,以及这些消息应该是什么。到 创建 WS-Resource 一节,我们将介绍如何创建 WSRF 定义的特定消息,但是首先我们需要了解一下 WS-Addressing。

l         什么是 WS-Addressing,为什么我要关注它?

以前,很容易指定 Web 服务的地址。所有您真正需要的就是 URL,所有其他信息都包含在 SoapAction 头部或消息本身中。现在,Web 服务应用程序变得越来越复杂,并不总是那么简单。您若想要让应答发送到除最初的请求者之外的其他地方,或者需要其他信息(比如会话标识符)来定义实际的“位置”,那该怎么办?

或者您只是需要附加到 Web 服务的一个特定实例,那该怎么办?我们在 WS-Resources 的情况中将会遇到这个问题,所以我们需要一种处理它的方式。

WS-Addressing 提供一种方式来指定关于位置的信息,而不只是一个统一资源标识符(Universal Resource Identifier,URI)或 URL。实际上,在我们的例子中,它提供一种标准的方式,将大量的信息添加到 SOAP 消息。我们来构造一个 SOAP 消息,比如:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

xmlns:wsa="http://www.w3.org/2005/02/addressing"

xmlns:sat="http://example.org/satelliteSystem">

    <SOAP-ENV:Header>

      <wsa:To SOAP-ENV:mustUnderstand="1">http://example.com/satellite</wsa:To>

      <wsa:Action>http://example.com/SetAltitude</wsa:Action>

      <sat:SatelliteId>SAT9928</sat:SatelliteId>

    </SOAP-ENV:Header>

    <SOAP-ENV:Body>

        <SetAltitudeRequest xmlns="http://example.com/satellite.xsd">

            <altitude>47700</altitude>

        </SetAltitudeRequest>

    </SOAP-ENV:Body>

</SOAP-ENV:Envelope>

在实际的 SOAP 消息中具有该信息似乎并不重要,但是请记住,消息可能会传输通过多个系统,甚至需要多次传输才能到达最终目的地。

要指定该信息,我们需要创建一个 EndpointReference。

WS-Addressing 引入了 EndpointReference 概念。EndpointReference 是一种方式,用于指定让消息到达适当的位置并带有适当的相关信息所需的信息。例如,我们在前一屏中指定的消息的 EndpointReference 应该是:

<wsa:EndpointReference xmlns:wsa="http://www.w3.org/2005/02/addressing"

xmlns:sat="http://example.org/satelliteSystem">

    <wsa:Address>http://example.com/satellite</wsa:Address>

    <wsa:ReferenceProperties>

         <sat:SatelliteId>SAT9928</sat:SatelliteId>

    </wsa:ReferenceProperties>

</wsa:EndpointReference>

理解 EndpointReference 和 SOAP 消息之间的关系很重要,因为 EndpointReference 就是我们指定特定 WS-Resource 的位置的方式。例如,当我们请求创建新的 WS-Resource 时,响应将包含一个指向它的 EndpointReference。

l         什么是 WS-Resource?

至此,您应该在概念上对什么是 WS-Resource 有了很好的理解,并且应该对 WSDL 和 WS-Addressing 有了很好的基本了解。现在开始实际地创建和使用 WS-Resources。

我们首先来定义 WS-Resource 到底真正是什么。在我们的人造卫星例子中,我们可以具有几种类型的 WS-Resources,比如:

一个服务,用于设置或检索特定人造卫星的高度。

一个服务,用于设置或检索特定人造卫星的位置或方位。

一个服务,用于提供对一个进程的访问,该进程计数特定人造卫星观测到的恒星。

关于该列表有两件事情一定要注意:即所有三个 WS-Resources 都可以引用相同的人造卫星,还有,WS-Resource 是由服务和有状态资源(在本例中是人造卫星)的组合定义的,而不是由它可以执行的操作数量定义的。

现在,我们可以说 WS-Resource 是 Web 服务和有状态资源的组合,但是我们如何在应用程序中表示这个有状态资源呢?答案就在它的 ResouceProperties 中。正如 有状态资源 中提到的,对象的状态可以由它的各种属性的值来决定。因为我们真正感兴趣的就是对象的状态,所以我们可以把有状态资源表示为一个展示其属性的 XML 文档。该文档叫做资源属性文档。在我们的人造卫星例子中,它可能是具有以下代码行的文档:

<satProp:GenericSatelliteProperties  xmlns:satProp="http://example.com/satellite">

   <satProp:latitude>30.3</satProp:latitude>

   <satProp:longitude>223.2</satProp:latitude>

   <satProp:altitude>47700</satProp:altitude>

   <satProp:pitch>49</satProp:pitch>

   <satProp:yaw>0</satProp:yaw>

   <satProp:roll>32</satProp:roll>

   <satProp:focalLength>21999992</satProp:focalLength>

   <satProp:currentView>

        http://example.com/satellite/2239992333.zip

   </satProp:currentView>

</satProp:GenericSatelliteProperties>

状态的更改需要一个或多个这些属性的更改,反之亦然。

就像可以通过添加成员或方法来扩展类一样,我么可以通过添加属性来扩展 WS-Resource。例如,考虑这样一种情形,我们具有一个人造卫星,它也充当恒星计数器。除了有状态资源的一般属性之外,我们可能还有一个 currentCount 属性:

<satProp:GenericSatelliteProperties

       xmlns:satProp="http://example.com/satellite"

       xmlns:counterProp="http://example.com/satellite/CounterSatelliteProperties">

   <satProp:latitude>30.3</satProp:latitude>

   <satProp:longitude>223.2</satProp:latitude>

   <satProp:altitude>47700</satProp:altitude>

   <satProp:pitch>49</satProp:pitch>

   <satProp:yaw>0</satProp:yaw>

   <satProp:roll>32</satProp:roll>

   <satProp:focalLength>21999992</satProp:focalLength>

   <satProp:currentView>

        http://example.com/satellite/2239992333.zip

   </satProp:currentView>

   <counterProp:currentCount>92828</counterProp:currentCount>

</satProp:GenericSatelliteProperties>

注意新信息是在一个独立的名称空间中。

l         合并 WS- 和 Resource:WSDL 文件

至此,我们已经创建了有状态资源(人造卫星)的表示,但是要真正地创建 WS-Resource,我们还必须使用 WSDL 文件将它绑定到服务。

我们首先来看一个基本的 WSDL 文件:

<?xml version="1.0" encoding="UTF-8"?>

<definitions name="Satellite"

    targetNamespace="http://example.com/satellite"

    xmlns="http://schemas.xmlsoap.org/wsdl/"

    xmlns:tns="http://example.com/satellite"

    xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"

    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

    xmlns:wsrp=

"http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.xsd"

    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

        <wsdl:import namespace=

"http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.wsdl"

       location="WS-ResourceProperties.wsdl" />

        <types>

          <xsd:schema targetNamespace="http://example.com/satellite"

                      xmlns:xsd="http://www.w3.org/2001/XMLSchema">

                        <xsd:import namespace=

 "http://schemas.xmlsoap.org/ws/2004/03/addressing"

                           schemaLocation="WS-Addressing.xsd" />

          </xsd:schema>

        </types>

</definitions>

该文件现在还很空,但是请注意,为了能够工作,还需要导入两个文件。WS-ResourceProperties.wsdl 和 WS-Addressing.xsd 文件的典型版本可能会引用您还没创建在机器上的目录,所以为了简单起见,您可以从教程参考资料 下载简化的版本。

既然有了框架,现在我们就来填充它吧。

首先,我们将实际的有状态资源添加到文件,并将之与 Web 服务关联:

<?xml version="1.0" encoding="UTF-8"?>

<definitions name="Satellite"

    targetNamespace="http://example.com/satellite"

    xmlns="http://schemas.xmlsoap.org/wsdl/"

    xmlns:tns="http://example.com/satellite"

    xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"

    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

    xmlns:wsrp=

"http://docs.oasis-open.org/wsrf/2004/06/wsrf-

WS-ResourceProperties-1.2-draft-01.xsd"

    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

        <wsdl:import namespace=

"http://docs.oasis-open.org/wsrf/2004/06/wsrf-

WS-ResourceProperties-1.2-draft-01.wsdl"

          location="WS-ResourceProperties.wsdl" />

      <types>

      <xsd:schema targetNamespace="http://example.com/satellite"

          xmlns:xsd="http://www.w3.org/2001/XMLSchema">

     

          <xsd:import namespace=

                  "http://schemas.xmlsoap.org/ws/2004/03/addressing"

                  schemaLocation="WS-Addressing.xsd" />

           

          <xsd:element name="latitude" type="xsd:float" />

          <xsd:element name="longitude" type="xsd:float" />

          <xsd:element name="altitude" type="xsd:float" />

          <xsd:element name="pitch" type="xsd:float" />

          <xsd:element name="yaw" type="xsd:float" />

          <xsd:element name="roll" type="xsd:float" />

          <xsd:element name="focalLength" type="xsd:float" />

          <xsd:element name="currentView" type="xsd:string" />

           

          <xsd:element name="GenericSatelliteProperties">

            <xsd:complexType>

               <xsd:sequence>

                 <xsd:element ref="latitude" minOccurs="1"

                 maxOccurs="1"/>

                 <xsd:element ref="longitude" minOccurs="1"

                 maxOccurs="1"/>

                 <xsd:element ref="altitude" minOccurs="1"

                 maxOccurs="1"/>

                 <xsd:element ref="pitch" minOccurs="1"

                 maxOccurs="1"/>

                 <xsd:element ref="yaw" minOccurs="1"

                 maxOccurs="1"/>

                 <xsd:element ref="roll" minOccurs="1"

                 maxOccurs="1"/>

                <xsd:element ref="focalLength" minOccurs="1"

                 maxOccurs="1"/>

                 <xsd:element ref="currentView" minOccurs="1"

                 maxOccurs="1"/>

               </xsd:sequence>

            </xsd:complexType>

          </xsd:element>             

           

      </xsd:schema>

       

    </types>

    <portType name="SatellitePortType"

            wsrp:ResourceProperties=

            "tns:GenericSatelliteProperties">

    </portType>

   

    <binding name="SatelliteSoapBinding"

    type="tns:SatellitePortType">

      <soap:binding style="document"

      transport="http://schemas.xmlsoap.org/soap/http"/>

    </binding>

   

    <service name="SatelliteService">

        <port name="SatellitePort"

        binding="tns:SatelliteSoapBinding">

            <soap:address location=

            "http://example.com/satellite"/>

        </port>

    </service>

</definitions>

我们首先是添加 Web 服务的基础、实际的 service 元素和将之与 portType 关联的 binding。portType 本身还没有任何操作,但是重要的部分是 wsrp:ResourceProperties 属性。该属性指定,Web 服务执行的任何操作都是在一个特定类型的有状态资源上执行的,如 GenericSatelliteProperties 元素所定义的。GenericSatelliteProperties 元素定义在 schema 中。该有状态资源和该 Web 服务的组合就是 WS-Resource。

注意,规范中指出,在创建资源属性文档(比如本例中的 GenericSatelliteProperties)时,必须 使用这里展示的样式,即初始元素是定义和引用的,而不是内联地定义的。

现在我们向 WSDL 文件添加一些实际的操作,看它是如何工作的。

l         请求新的人造卫星

当然,该练习的整个目的是真正对 WS-Resource 做一些事情,所以我们要做的第一件事情是,创建对实际 WS-Resource 实例的一个引用:

...

    <types>

       <xsd:schema targetNamespace="http://example.com/satellite"

           xmlns:xsd="http://www.w3.org/2001/XMLSchema">

           

            <xsd:import namespace=

               "http://schemas.xmlsoap.org/ws/2004/03/addressing"

                  schemaLocation="WS-Addressing.xsd" />

           

          <xsd:element name="createSatellite">

              <xsd:complexType/>

          </xsd:element>

           

          <xsd:element name="createSatelliteResponse">

             <xsd:complexType>

                 <xsd:sequence>

                     <xsd:element ref="wsa:EndpointReference"/>

                  </xsd:sequence>

              </xsd:complexType>

          </xsd:element>

           

          <xsd:element name="GenericSatelliteProperties">

               ...

          </xsd:element>           

           

        </xsd:schema>

       

    </types>

    <message name="CreateSatelliteRequest">

      <part name="request" element="tns:createSatellite"/>

    </message>

   

    <message name="CreateSatelliteResponse">

     <part name="response" element=

     "tns:createSatelliteResponse"/>

    </message>

   

    <portType name="SatellitePortType"

      wsrp:ResourceProperties=

      "tns:GenericSatelliteProperties">

      <operation name="createSatellite">

          <input message="tns:CreateSatelliteRequest"

               wsa:Action=

               "http://example.com/CreateSatellite" />

           <output message="tns:CreateSatelliteResponse"

              wsa:Action=

              "http://example.com/CreateSatelliteResponse" />

        </operation>

    </portType>

   

   <binding name="SatelliteSoapBinding" type=

   "tns:SatellitePortType">

    <soap:binding style="document" transport=

    "http://schemas.xmlsoap.org/soap/http"/>

      <operation name="createSatellite">

          <input>

              <soap:body use="literal"/>

           </input>

           <output>

              <soap:body use="literal"/>

           </output>

     </operation>

   </binding>

   

   <service name="SatelliteService">

      <port name="SatellitePort" binding=

      "tns:SatelliteSoapBinding">

          <soap:address location=

          "http://example.com/satellite"/>

       </port>

   </service>

</definitions>

乍一看,这与我们在 需要了解的 WSDL 知识 中创建的 WSDL 文件没有太大的区别。我们具有一个指向 binding 的 service,binding 解释如何实现 portType。portType 定义一个操作,即 createSatellite,该操作使用一个 input 和一个 output 消息。这两个消息定义在 schema 中。

这个文件有一点稍微与最初的文件不同:不是返回一个简单的值,服务是返回一个指向新创建的 WS-Resource 的 EndpointReference。我们来看这在 SOAP 消息中是如何实现的。

l         SOAP 请求

关于创建 WS-Resource 的实际 SOAP 请求是非常简单的:

<SOAP-ENV:Envelope  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">

    <SOAP-ENV:Header/>

    <SOAP-ENV:Body>

        <createSatellite xmlns="http://example.com/satellite"/>

    </SOAP-ENV:Body>

</SOAP-ENV:Envelope>

我们还没有实际的对象,所以该请求到达 WSDL 文件中列出的 URI,并且我们将该请求定义为一个简单的 createSatellite 元素。

响应要稍微有意思一些。

l         SOAP 响应

一旦您发送针对新人造卫星的请求,服务器就创建一个对新 WS-Resource 的引用,并以 EndpointReference 形式将它返回:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">

    <SOAP-ENV:Header/>

    <SOAP-ENV:Body>

       <wsa:EndpointReference

       xmlns:wsa="http://www.w3.org/2005/02/addressing"

             xmlns:sat="http://example.org/satelliteSystem">

           <wsa:Address>http://example.com/satellite</wsa:Address>

           <wsa:ReferenceProperties>

               <sat:SatelliteId>SAT9928</sat:SatelliteId>

           </wsa:ReferenceProperties>

       </wsa:EndpointReference>

    </SOAP-ENV:Body>

</SOAP-ENV:Envelope>

注意,EndpointReference 的 Address 元素指向我们在 WSDL 文件中列出的同一 URI,所以信息仍然到达相同的地方,只是量的增多。

现在我们应该注意,这不是一个普通的端点引用。 ReferenceProperties 元素展示一个标识符,该标识符最终将用于识别 WS-Resource,所以这实际上是一个 WS-Resource 限定的端点引用。正如您马上就会看到的,我们可以使用该信息来对 WS-Resource 做出后续调用。

l         我们想要完成什么?

好的,已经创建了 WS-Resource,那么我们可以对它做什么呢?

实际上,可以通过调整它的属性来做任何事情。例如,可以通过更改 altitude 属性来改变人造卫星轨道的大小。不,只是更改值并不能移动人造卫星;人造卫星的实际移动是由 Web 服务背后的应用程序决定的。但是这是 WS-Resources 所真正关心的:创建一种方式,以便通过更改属性来操纵对象。规范只是指出了如何将这些更改告诉 Web 服务。它不关心应用程序是如何真正操纵对象的,我们也不关心。

但是在真正开始更改属性之前,我们先来看看属性。在本节中,首先来看我们在 创建 WS-Resource 中创建的人造卫星 WS-Resource 的 altitude 属性。然后将讲述一次性请求所有的 orientation 值。然后再介绍使用 XPath 来查询多个值。

l         请求属性

请求属性的值是构造适当 SOAP 消息过程中的一个简单过程。例如,假设我们想要请求 altitude 属性的值。基本的 SOAP 消息可能看起来像下面这样:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

    xmlns:wsrp=

"http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-

ResourceProperties-1.2-draft-01.xsd">

 <SOAP-ENV:Header>...</SOAP-ENV:Header>

 <SOAP-ENV:Body>

     <wsrp:GetResourceProperty xmlns:satProp=

     "http://example.com/satellite">

        satProp:altitude

     </wsrp:GetResourceProperty>

 </SOAP-ENV:Body>

</SOAP-ENV:Envelope>

wsrp:GetResourceProperty 元素是 WS-ResourceProperties 规范的一部分。我们甚至不必在 WSDL 文件中定义它。它给我们这样一个地方,可以指定我们想要获得值的属性。

但是,SOAP 消息还没有真正完成。是的,它是一个 SOAP 消息,但是如果我们像这样把它发送给 Web 服务,服务将不知道我们引用的是哪个 WS-Resource。接下来我们将关心这个问题。

l         完全的 SOAP 请求

在前一屏,即 请求属性 中,我们创建了一个 SOAP 消息,它指定了我们想要检索的属性,但是为哪个 WS-Resource 创建的呢?

当创建人造卫星时,Web 服务返回一个指向新创建的 WS-Resource 的端点引用。我们可以将该信息添加到 SOAP 消息的 Header,像下面这样:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

       xmlns:sat="http://example.org/satelliteSystem"

       xmlns:wsa="http://www.w3.org/2005/02/addressing"

       xmlns:wsrp="http://docs.oasis-open.org/wsrf/2004/06/wsrf-

       WS-ResourceProperties-1.2-draft-01.xsd">

    <SOAP-ENV:Header>

       <wsa:Action>

http://docs.oasis-open.org/wsrf/2004/06/WS-ResourceProperties/GetResourceProperty

       </wsa:Action>

       <wsa:To SOAP-ENV:mustUnderstand="1">

            http://example.com/satellite

       </wsa:To>

       <sat:SatelliteId>SAT9928</sat:SatelliteId>

    </SOAP-ENV:Header>

    <SOAP-ENV:Body>

       <wsrp:GetResourceProperty

       xmlns:satProp="http://example.com/satellite">

          satProp:altitude

       </wsrp:GetResourceProperty>

    </SOAP-ENV:Body>

</SOAP-ENV:Envelope>

wsa:Action 元素不是初始端点引用的一部分;它随我们想要做的事情而变化。在本例中,我们使用 GetResourceProperty 操作。wsa:To 元素从端点引用中的 wsa:Address 获得值,而任何 wsa:ReferenceProperty 值都直接包含在 Header 中。

您会注意到,我们没有讨论 SatelliteId 值。这是故意的。包含在端点引用中的任何用于识别特定 WS-Resource 的信息都必须被应用程序忽略,只是在发送消息时要传送它。根据规范,即使尝试去解释值也认为是不适当的。这意味着被传输为一个“黑盒”,导致一种未经检查的生活。

l         接收 ResourceProperty

一旦请求属性,就需要获得返回值,并且 WS-ResourceProperties 规范也定义了这种消息的形式。在我们的例子中,我们将接收这样一个消息:

<SOAP-ENV:Envelope xmlns:SOAP-ENV=

"http://schemas.xmlsoap.org/soap/envelope/"

     xmlns:sat="http://example.org/satelliteSystem"

     xmlns:wsa="http://www.w3.org/2005/02/addressing"

     xmlns:wsrp=

"http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-

ResourceProperties-1.2-draft-01.xsd">

 <SOAP-ENV:Header>

       <wsa:Action>

http://docs.oasis-open.org/wsrf/2004/06/WS-

ResourceProperties/GetResourcePropertyResponse

       </wsa:Action>

       <wsa:To SOAP-ENV:mustUnderstand="1">

            http://example.com/myClient

       </wsa:To>

    </SOAP-ENV:Header>

    <SOAP-ENV:Body>

       <wsrp:GetResourcePropertyResponse

             xmlns:satProp=

             "http://example.com/satellite">

          <satProp:altitude>

          47700

          </satProp:altitude>

       </wsrp:GetResourcePropertyResponse>

    </SOAP-ENV:Body>

</SOAP-ENV:Envelope>

在本例中,Header 信息并不引用服务,而是引用客户机; http://example.com/myClient 是应该接收响应的客户机的 URI。在大多数情况下,这与发出请求的客户机是相同的,但是您也可以使用 wsa:Reply-To 元素将响应发送到别的地方。

在实际的消息体中还有一个标准元素 wsrp:GetResourcePropertyResponse,但是在本例中,它包含请求的实际属性,以及它的当前值。

现在来看这在 WSDL 文件中是什么样的。

l         WSDL 文件

为了将这些功能添加到应用程序,我们需要将它们添加到 WSDL 文件,但是因为我们使用已经定义好的标准消息交换模式,所以我们只需要添加一个新操作,像下面这样:

<?xml version="1.0" encoding="UTF-8"?>

<definitions name="Satellite"

    targetNamespace="http://example.com/satellite"

    xmlns="http://schemas.xmlsoap.org/wsdl/"

    xmlns:tns="http://example.com/satellite"

    xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"

    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

    xmlns:wsrp="http://docs.oasis-open.org/wsrf/2004/06/

    wsrf-WS-ResourceProperties-1.2-draft-01.xsd"

    xmlns:wsrpwsdl=

    "http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-

    ResourceProperties-1.2-draft-01.wsdl"

    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

   

    <wsdl:import namespace=

"http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.wsdl"

              location="WS-ResourceProperties.wsdl" />

   

 <types>

      <xsd:schema targetNamespace="http://example.com/satellite"

          xmlns:xsd="http://www.w3.org/2001/XMLSchema">

 ...

     </xsd:schema>

       

    </types>

 <message name="CreateSatelliteRequest">

      <part name="request" element="tns:createSatellite"/>

 </message>

   

 <message name="CreateSatelliteResponse">

      <part name="response" element="tns:createSatelliteResponse"/>

 </message>

   

 <portType name="SatellitePortType"

           wsrp:ResourceProperties="tns:GenericSatelliteProperties">

      <operation name="createSatellite">

          <input message="tns:CreateSatelliteRequest"

              wsa:Action="http://example.com/CreateSatellite" />

          <output message="tns:CreateSatelliteResponse"

              wsa:Action="http://example.com/CreateSatelliteResponse" />

      </operation>

      <operation name="getAltitude">

          <input message="wsrpwsdl:GetResourcePropertyRequest"

              wsa:Action="http://docs.oasis-open.org/wsrf/2004/

              06/WS-ResourceProperties/GetResourceProperty/>

            <output message="wsrpwsdl:GetResourcePropertyResponse"

                wsa:Action="http://docs.oasis-open.org/wsrf/2004/

                06/WS-ResourceProperties/GetResourcePropertyResponse/>

        </operation>

    </portType>

    <binding name="SatelliteSoapBinding" type="tns:SatellitePortType">

        <soap:binding style="document"

            transport="http://schemas.xmlsoap.org/soap/http"/>

        <operation name="createSatellite">

            <input>

                <soap:body use="literal"/>

            </input>

            <output>

                <soap:body use="literal"/>

            </output>

        </operation>

        <operation name="getAltitude">

            <input>

                <soap:body use="literal"/>

            </input>

            <output>

                <soap:body use="literal"/>

            </output>

        </operation>

    </binding>

    <service name="SatelliteService">

        <port name="SatellitePort" binding=

        "tns:SatelliteSoapBinding">

            <soap:address location=

            "http://example.com/satellite"/>

        </port>

    </service>

</definitions>

一开始是 portType,我们创建一个叫做 getAltitude 的新操作。该操作具有一个 input 和一个 output 消息,但是两个消息都已经定义在我们以前导入的 WS-ReferenceProperties.wsdl 文件中,所以我们需要做的就是使用适当的名称空间别名来引用它们。

一旦创建了 operation,我们只要将它添加到 binding 就行了,而这一点我们已经很内行了。

l         请求多个属性

幸运的是,我们并不局限于检索单个属性值。我们也可以检索多个属性:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

        xmlns:sat="http://example.org/satelliteSystem"

        xmlns:wsa="http://www.w3.org/2005/02/addressing"

        xmlns:wsrp="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-Resour

ceProperties-1.2-draft-01.xsd">

    <SOAP-ENV:Header>

       <wsa:Action>

            http://docs.oasis-open.org/wsrf/2004/06/

            WS-ResourceProperties/GetMultipleResourceProperties

       </wsa:Action>

       <wsa:To SOAP-ENV:mustUnderstand="1">

            http://example.com/satellite

       </wsa:To>

       <sat:SatelliteId>SAT9928</sat:SatelliteId>

    </SOAP-ENV:Header>

    <SOAP-ENV:Body>

       <wsrp:GetMultipleResourceProperties

              xmlns:satProp="http://example.com/satellite">

          <wsrp:ResourceProperty>

          satProp:roll

          </wsrp:ResourceProperty>

          <wsrp:ResourceProperty>

          satProp:pitch

          </wsrp:ResourceProperty>

          <wsrp:ResourceProperty>

          satProp:yaw

          </wsrp:ResourceProperty>

       </wsrp:GetMultipleResourceProperties>

    </SOAP-ENV:Body>

</SOAP-ENV:Envelope>

同前面一样,Header 中的信息来自端点引用。

l         接收多个属性

响应消息类似于它的单个属性对应物:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

         xmlns:sat="http://example.org/satelliteSystem"

         xmlns:wsa="http://www.w3.org/2005/02/addressing"

         xmlns:wsrp="http://docs.oasis-open.org/wsrf/200

         4/06/wsrf-WS-ResourceProperties-1.2-draft-01.xsd">

    <SOAP-ENV:Header>

       <wsa:Action>

            http://docs.oasis-open.org/wsrf/2004/06/WS-Res

            ourceProperties/GetMultipleResourcePropertiesResponse

       </wsa:Action>

       <wsa:To SOAP-ENV:mustUnderstand="1">

            http://example.com/myClient

       </wsa:To>

    </SOAP-ENV:Header>

    <SOAP-ENV:Body>

       <wsrp:GetMultipleResourcePropertiesResponse    

               xmlns:satProp="http://example.com/satellite">

          <satProp:roll>32</satProp:roll>

          <satProp:pitch>49</satProp:pitch>                    

          <satProp:yaw>0</satProp:yaw>

       </wsrp:GetMultipleResourcePropertiesResponse>

    </SOAP-ENV:Body>

</SOAP-ENV:Envelope>

同样,我们要将它添加到 WSDL 文件。

l         WSDL 文件

同样,因为我们传递的实际消息已经定义在 WS-ResourceProperties.wsdl 文件中,把该功能添加到应用程序所要做的就是创建一个新 operation:

...

    <message name="CreateSatelliteRequest">

        <part name="request" element=

        "tns:createSatellite"/>

    </message>

   

   <message name="CreateSatelliteResponse">

        <part name="response" element=

        "tns:createSatelliteResponse"/>

    </message>

   

    <portType name="SatellitePortType"

           wsrp:ResourceProperties =

           "tns:GenericSatelliteProperties">

        <operation name="createSatellite">

            <input message="tns:CreateSatelliteRequest"

                 wsa:Action=

                 "http://example.com/CreateSatellite" />

            <output message="tns:CreateSatelliteResponse"

                 wsa:Action=

                 "http://example.com/CreateSatelliteResponse" />

        </operation>

       

        <operation name="getAltitude">

            <input message=

            "wsrpwsdl:GetResourcePropertyRequest"

                 wsa:Action="http://docs.oasis-open.org/ws

                 rf/2004/06/WS-ResourceProperties/GetResourceProperty"/>

            <output message=

            "wsrpwsdl:GetResourcePropertyResponse"

                 wsa:Action="http://docs.oasis-open.org/wsrf/2004/0

                 6/WS-ResourceProperties/GetResourcePropertyResponse"/>

        </operation>

       

        <operation name="getOrientation">

            <input message="wsrpwsdl:

            GetMultipleResourcePropertiesRequest"

                 wsa:Action="http://docs.oasis-open.org/wsrf/2004/0

                 6/WS-ResourceProperties/GetMultipleResourceProperties"/>

            <output message=

            "wsrpwsdl:GetMultipleResourcePropertiesResponse"

                 wsa:Action=

                 "http://docs.oasis-open.org/wsrf/2004/06/WS-ResourcePro

                 perties/GetMultipleResourcePropertiesResponse"/>

        </operation>

       

    </portType>

   

    <binding name="SatelliteSoapBinding" type=

    "tns:SatellitePortType">

       <soap:binding style="document"

              transport=

              "http://schemas.xmlsoap.org/soap/http"/>

        <operation name="createSatellite">

            <input>

                <soap:body use="literal"/>

            </input>

            <output>

                <soap:body use="literal"/>

            </output>

        </operation>

        <operation name="getAltitude">

            <input>

                <soap:body use="literal"/>

            </input>

            <output>

                <soap:body use="literal"/>

            </output>

        </operation>

        <operation name="getOrientation">

            <input>

                <soap:body use="literal"/>

            </input>

            <output>

                <soap:body use="literal"/>

            </output>

        </operation>

    </binding>

   

    <service name="SatelliteService">

        <port name="SatellitePort" binding="tns:SatelliteSoapBinding">

            <soap:address location="http://example.com/satellite"/>

        </port>

    </service>

</definitions>

一旦我们将 getOrientation operation 添加到了 binding,它就可以由应用程序使用了。

我们也可以查询属性,正如您马上就会看到的。

l         使用 XPath 查询

尽管请求所需的属性相当直观,但是也有需要使用其他方法的情景。不是简单地按名称请求资源属性,我们可以使用 XPath 中可用的查询。(有关 XPath 的更多信息,请参阅 参考资料。)例如,如果不能确定某个特定的属性是否存在,您可能想要在属性上使用 XPath 函数。

XPath 的另一个有用功能是,能够请求多个相同命名的属性,或者甚至能够查询参数。我们将在“理解 WSRF(第 2 部分)”中做前一件事,而马上就会做后一件事。例如,我们可以与 boolean() 函数一起使用一个 XPath 表达式,来确定人造卫星是否指向正确的方向,而不用显式地分析数据:

<SOAP-ENV:Envelope xmlns:SOAP-ENV=

"http://schemas.xmlsoap.org/soap/envelope/"

        xmlns:sat="http://example.org/satelliteSystem"

        xmlns:wsa="http://www.w3.org/2005/02/addressing"

        xmlns:wsrp="http://docs.oasis-open.org/wsrf/20

        04/06/wsrf-WS-ResourceProperties-1.2-draft-01.xsd">

    <SOAP-ENV:Header>

       <wsa:Action>

            http://docs.oasis-open.org/wsrf/2004/06/WS-ResourcePro

            perties/QueryResourceProperties

       </wsa:Action>

       <wsa:To SOAP-ENV:mustUnderstand="1">

            http://example.com/satellite

       </wsa:To>

       <sat:SatelliteId>SAT9928</sat:SatelliteId>

    </SOAP-ENV:Header>

    <SOAP-ENV:Body>

       <wsrp:QueryResourceProperties>

          <wsrp:QueryExpression Dialect=

          "http://www.w3.org/TR/1999/REC-xpath-19991116">

             boolean(/*/pitch=25 and /*/roll=0 and /*/yaw=10)

          </wsrp:QueryExpression>

       </wsrp:QueryResourceProperties>

    </SOAP-ENV:Body>

</SOAP-ENV:Envelope>

注意 Dialect 属性的使用,以区分 XPath V1.0 (这里展示的)和 XPath V2.0(http://www.w3.org/TR/2003/WD-xpath20-20031112)。规范没有限制您可以支持的方言(dialect),但是如果实现不认识 Dialect,它就会返回一个 fault 和错误。

l         查询结果

结果看起来非常像前面的两个响应:

<SOAP-ENV:Envelope xmlns:SOAP-ENV=

"http://schemas.xmlsoap.org/soap/envelope/"

        xmlns:sat="http://example.org/satelliteSystem"

        xmlns:wsa="http://www.w3.org/2005/02/addressing"

        xmlns:wsrp="http://docs.oasis-open.org/wsrf/20

        04/06/wsrf-WS-ResourceProperties-1.2-draft-01.xsd">

    <SOAP-ENV:Header>

       <wsa:Action>

            http://docs.oasis-open.org/wsrf/2004/06/

            WS-ResourceProperties/Quer

yResourcePropertiesResponse

       </wsa:Action>

       <wsa:To SOAP-ENV:mustUnderstand="1">

            http://example.com/myClient

       </wsa:To>

    </SOAP-ENV:Header>

    <SOAP-ENV:Body>

       <wsrp:QueryResourcePropertiesResponse>

           false

       </wsrp:QueryResourcePropertiesResponse>

    </SOAP-ENV:Body>

</SOAP-ENV:Envelope>

在本例中,我们只是返回一个布尔值,但是您可以返回 XPath 可以返回的任何类型的值。

l         WSDL 文件

同样,我们向 WSDL 文件添加一个新 operation:

...

    <portType name="SatellitePortType"

          wsrp:ResourceProperties=

          "tns:GenericSatelliteProperties">

...

      <operation name="getOrientation">

          <input message=

          "wsrpwsdl:GetMultipleResourcePropertiesRequest"

              wsa:Action="http://docs.oasis-open.org/wsrf/20

            04/06/WS-ResourceProperties/GetMultipleResourceProperties"/>

          <output message=

          "wsrpwsdl:GetMultipleResourcePropertiesResponse"

              wsa:Action="http://docs.oasis-open.org/wsrf/2004/06/W

          S-ResourceProperties/GetMultipleResourcePropertiesResponse"/>

      </operation>

       

        <operation name="checkOrientation">

            <input message=

            "wsrpwsdl:QueryResourcePropertiesRequest"

                wsa:Action="http://docs.oasis-open.org/wsrf/20

                04/06/WS-ResourceProperties/QueryResourceProperties"/>

            <output message=

            "wsrpwsdl:QueryResourcePropertiesResponse"

                wsa:Action="http://docs.oasis-open.org/wsrf/2004/06/W

             S-ResourceProperties/QueryResourcePropertiesResponse"/>

        </operation>

       

    </portType>

   

    <binding name="SatelliteSoapBinding" type=

    "tns:SatellitePortType">

        <soap:binding style="document"

            transport="http://schemas.xmlsoap.org/soap/http"/>

...

        <operation name="getOrientation">

            <input>

                <soap:body use="literal"/>

            </input>

            <output>

               <soap:body use="literal"/>

            </output>

        </operation>

        <operation name="checkOrientation">

            <input>

                <soap:body use="literal"/>

            </input>

            <output>

                <soap:body use="literal"/>

            </output>

        </operation>

    </binding>

   

    <service name="SatelliteService">

        <port name="SatellitePort" binding=

        "tns:SatelliteSoapBinding">

            <soap:address location=

            "http://example.com/satellite"/>

        </port>

    </service>

</definitions>

这关注检索属性。现在来看设置属性的值。

l         我们想要完成什么

至此,我们创建了一个 WS-Resource,并且了解了一个或多个用于表示它的状态的属性。但是这与真正地操纵 WS-Resource 没有太大的关系。在本节中,我们来看添加、悬挂和删除 WS-Resource 的属性。

至此,我们的人造卫星已经在天空中相对于地球的轨道中稳定了,而不是观测到某些特定的东西了。在本节中,我们要添加一个 ResourceProperty,它表示一个特定的目标。然后我们通过更新位置属性将人造卫星移向该目标,然后再删除所创建的目标属性。最后,通过将适当的操作添加到 WSDL 文件,我们将把所有事情综合在一起。

l         添加属性

向 WS-Resource 添加属性涉及到使用 Insert 元素:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

         xmlns:sat="http://example.org/satelliteSystem"

         xmlns:wsa="http://www.w3.org/2005/02/addressing"

         xmlns:wsrp="http://docs.oasis-open.org/wsrf/

     2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.xsd">

    <SOAP-ENV:Header>

       <wsa:Action>

           http://docs.oasis-open.org/wsrf/2004/06/W

           S-ResourceProperties/SetResourceProperties

       </wsa:Action>

       <wsa:To SOAP-ENV:mustUnderstand="1">

            http://example.com/satellite

       </wsa:To>

       <sat:SatelliteId>SAT9928</sat:SatelliteId>

    </SOAP-ENV:Header>

    <SOAP-ENV:Body>

       <wsrp:SetResourceProperties

              xmlns:satProp="http://example.com/satellite">

           <wsrp:Insert>

               <satProp:targetCoords>

               36n11, 115w08

               </satProp:targetCoords>

           </wsrp:Insert>

       </wsrp:SetResourceProperties>

    </SOAP-ENV:Body>

</SOAP-ENV:Envelope>

我们可以给这个新属性取任何好听的名字,但是我们必须允许该新元素在 Resource Properties 文档中。(当我们在 WSDL 文件 中调整 WSDL 文件时将来做这一件事。)

l         添加属性的结果

当成功添加、删除或更改属性之后,我们将会得到一个只是确认操作的响应消息:

<SOAP-ENV:Envelope xmlns:SOAP-ENV=

"http://schemas.xmlsoap.org/soap/envelope/"

          xmlns:sat="http://example.org/satelliteSystem"

          xmlns:wsa="http://www.w3.org/2005/02/addressing"

          xmlns:wsrp="http://docs.oasis-open.org/wsrf/

    2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.xsd">

    <SOAP-ENV:Header>

       <wsa:Action>

            http://docs.oasis-open.org/wsrf/2004/06/W

    S-ResourceProperties/SetResourcePropertiesResponse

       </wsa:Action>

       <wsa:To SOAP-ENV:mustUnderstand="1">

            http://example.com/myClient

       </wsa:To>

    </SOAP-ENV:Header>

    <SOAP-ENV:Body>

       <wsrp:SetResourcePropertiesResponse>

       </wsrp:SetResourcePropertiesResponse>

    </SOAP-ENV:Body>

</SOAP-ENV:Envelope>

该响应与 Update 和 Delete 操作产生的响应是相同的。

l         更改属性值

在 添加属性 中,我们添加了一个新属性,但是我们也能更改现有属性的值。例如,我们可以告诉系统,通过使用 Update 元素更改人造卫星的位置属性来移动人造卫星:

<SOAP-ENV:Envelope xmlns:SOAP-ENV=

"http://schemas.xmlsoap.org/soap/envelope/"

       xmlns:sat="http://example.org/satelliteSystem"

       xmlns:wsa="http://www.w3.org/2005/02/addressing"

       xmlns:wsrp="http://docs.oasis-open.org/wsrf/2004/0

    6/wsrf-WS-ResourceProperties-1.2-draft-01.xsd">

    <SOAP-ENV:Header>

       <wsa:Action>

            http://docs.oasis-open.org/wsrf/2004/06/WS-Re

       sourceProperties/SetResourceProperties

      </wsa:Action>

      <wsa:To SOAP-ENV:mustUnderstand="1">

           http://example.com/satellite

      </wsa:To>

     <sat:SatelliteId>SAT9928</sat:SatelliteId>

 </SOAP-ENV:Header>

 <SOAP-ENV:Body>

     <wsrp:SetResourceProperties

             xmlns:satProp="http://example.com/satellite">

         <wsrp:Update>

            <satProp:latitude>36.11</satProp:latitude>

         </wsrp:Update>

         <wsrp:Update>

            <satProp:longitude>158.08</satProp:latitude>

         </wsrp:Update>

      </wsrp:SetResourceProperties>

   </SOAP-ENV:Body>

</SOAP-ENV:Envelope>

在本例中,我们使用了两个 Update 组件,但是我们实际上可以使用 Insert、Update 和 Delete 组件的任意组合。

l         删除属性

属性可以被完全删除。例如,如果我们决定不再观测某个特定的目标,就可以删除该属性:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

         xmlns:sat="http://example.org/satelliteSystem"

         xmlns:wsa="http://www.w3.org/2005/02/addressing"

         xmlns:wsrp="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-Resour

ceProperties-1.2-draft-01.xsd">

    <SOAP-ENV:Header>

       <wsa:Action>

         http://docs.oasis-open.org/wsrf/2004/06/WS-Resou

         rceProperties/SetResourceProperties

       </wsa:Action>

       <wsa:To SOAP-ENV:mustUnderstand="1">

            http://example.com/satellite

       </wsa:To>

       <sat:SatelliteId>SAT9928</sat:SatelliteId>

    </SOAP-ENV:Header>

    <SOAP-ENV:Body>

       <wsrp:SetResourceProperties

                xmlns:satProp="http://example.com/satellite">

           <wsrp:Delete resourceProperty="targetCoords"/>

       </wsrp:SetResourceProperties>

    </SOAP-ENV:Body>

</SOAP-ENV:Envelope>

同样,我们的资源属性文档的模式定义必须允许我们做这一更改。

l         WSDL 文件

同样,因为标准元素已经定义在 WS-ResourceProperties.wsdl 中,所以我们可以简单地添加新操作:

<?xml version="1.0" encoding="UTF-8"?>

<definitions name="Satellite"

    targetNamespace="http://example.com/satellite"

    xmlns="http://schemas.xmlsoap.org/wsdl/"

    xmlns:tns="http://example.com/satellite"

    xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"

    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

    xmlns:wsrp="http://docs.oasis-open.org/wsrf/2004/06/

    wsrf-WS-ResourceProperties-1.2-draft-01.xsd"

    xmlns:wsrpwsdl="http://docs.oasis-open.org/wsrf/200

4/06/wsrf-WS-ResourceProperties-1.2-draft-01.wsdl"

    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

   

    <wsdl:import namespace="http://docs.oasis-open.org/

 wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.wsdl"

        location="WS-ResourceProperties.wsdl" />

   

    <types>

        <xsd:schema

          targetNamespace="http://example.com/satellite"

            xmlns:xsd="http://www.w3.org/2001/XMLSchema">

           

            <xsd:import namespace=

      "http://schemas.xmlsoap.org/ws/2004/03/addressing"

                   schemaLocation="WS-Addressing.xsd" />

           

           <xsd:element name="createSatellite">

               <xsd:complexType/>

           </xsd:element>

           

           <xsd:element name="createSatelliteResponse">

               <xsd:complexType>

                   <xsd:sequence>

                       <xsd:element ref=

                       "wsa:EndpointReference"/>

                   </xsd:sequence>

               </xsd:complexType>

           </xsd:element>

           

          <xsd:element name="latitude" type="xsd:float" />

          <xsd:element name="longitude" type="xsd:float" />

          <xsd:element name="altitude" type="xsd:float" />

          <xsd:element name="pitch" type="xsd:float" />

          <xsd:element name="yaw" type="xsd:float" />

          <xsd:element name="roll" type="xsd:float" />

          <xsd:element name="focalLength" type="xsd:float" />

          <xsd:element name="currentView" type="xsd:string" />

           

          <xsd:element name="GenericSatelliteProperties">

              <xsd:complexType>

                  <xsd:sequence>

                      <xsd:element ref="latitude" minOccurs="1"

                      maxOccurs="1"/>

                      <xsd:element ref="longitude" minOccurs="1"

                      maxOccurs="1"/>

                      <xsd:element ref="altitude" minOccurs="1"

                      maxOccurs="1"/>

                      <xsd:element ref="pitch" minOccurs="1"

                      maxOccurs="1"/>

                      <xsd:element ref="yaw" minOccurs="1"

                      maxOccurs="1"/>

                      <xsd:element ref="roll" minOccurs="1"

                      maxOccurs="1"/>

                      <xsd:element ref="focalLength"

                      minOccurs="1" maxOccurs="1"/>

                      <xsd:element ref="currentView"

                      minOccurs="1" maxOccurs="1"/>

                      <xsd:any/>

                  </xsd:sequence>

              </xsd:complexType>

           </xsd:element>

           

        </xsd:schema>

       

    </types>

    <message name="CreateSatelliteRequest">

        <part name="request" element="tns:createSatellite"/>

    </message>

   

    <message name="CreateSatelliteResponse">

        <part name="response" element=

        "tns:createSatelliteResponse"/>

    </message>

   

    <portType name="SatellitePortType"

             wsrp:ResourceProperties=

             "tns:GenericSatelliteProperties">

        <operation name="createSatellite">

            <input message="tns:CreateSatelliteRequest"

       wsa:Action="http://example.com/CreateSatellite" />

            <output message="tns:CreateSatelliteResponse"

                wsa:Action=

          "http://example.com/CreateSatelliteResponse" />

        </operation>

       

        <operation name="getAltitude">

            <input message=

            "wsrpwsdl:GetResourcePropertyRequest"

              wsa:Action="http://docs.oasis-open.org/wsr

f/2004/06/WS-ResourceProperties/GetResourceProperty"/>

            <output message=

            "wsrpwsdl:GetResourcePropertyResponse"

      wsa:Action="http://docs.oasis-open.org/wsrf/2004/0

6/WS-ResourceProperties/GetResourcePropertyResponse"/>

        </operation>

       

        <operation name="getOrientation">

            <input message=

         "wsrpwsdl:GetMultipleResourcePropertiesRequest"

      wsa:Action="http://docs.oasis-open.org/wsrf/2004/0

6/WS-ResourceProperties/GetMultipleResourceProperties"/>

            <output message=

        "wsrpwsdl:GetMultipleResourcePropertiesResponse"

                      wsa:Action=

"http://docs.oasis-open.org/wsrf/2004/06/WS-ResourceProp

erties/GetMultipleResourcePropertiesResponse"/>

        </operation>

       

        <operation name="checkOrientation">

            <input message=

                "wsrpwsdl:QueryResourcePropertiesRequest"

               wsa:Action="http://docs.oasis-open.org/wsr

f/2004/06/WS-ResourceProperties/QueryResourceProperties"/>

            <output message=

               "wsrpwsdl:QueryResourcePropertiesResponse"

       wsa:Action="http://docs.oasis-open.org/wsrf/2004/0

6/WS-ResourceProperties/QueryResourcePropertiesResponse"/>

        </operation>

       

        <operation name="addTarget">

            <input message=

                  "wsrpwsdl:SetResourcePropertiesRequest"

       wsa:Action="http://docs.oasis-open.org/wsrf/2004/0

6/WS-ResourceProperties/SetResourceProperty"/>

            <output message=

                 "wsrpwsdl:SetResourcePropertiesResponse"

       wsa:Action="http://docs.oasis-open.org/wsrf/2004/0

6/WS-ResourceProperties/SetResourcePropertyResponse"/>

        </operation>

        <operation name="moveToTarget">

            <input message=

                  "wsrpwsdl:SetResourcePropertiesRequest"

       wsa:Action="http://docs.oasis-open.org/wsrf/2004/0

6/WS-ResourceProperties/SetResourceProperty"/>

            <output message=

                 "wsrpwsdl:SetResourcePropertiesResponse"

       wsa:Action="http://docs.oasis-open.org/wsrf/2004/0

6/WS-ResourceProperties/SetResourcePropertyResponse"/>

        </operation>

        <operation name="removeTarget">

            <input message=

                  "wsrpwsdl:SetResourcePropertiesRequest"

                 wsa:Action="http://docs.oasis-open.org/ws

rf/2004/06/WS-ResourceProperties/SetResourceProperty"/>

            <output message=

                 "wsrpwsdl:SetResourcePropertiesResponse"

       wsa:Action="http://docs.oasis-open.org/wsrf/2004/0

6/WS-ResourceProperties/SetResourcePropertyResponse"/>

        </operation>

       

    </portType>

   

    <binding name="SatelliteSoapBinding"

    type="tns:SatellitePortType">

        <soap:binding style="document" transport=

                "http://schemas.xmlsoap.org/soap/http"/>

        <operation name="createSatellite">

            <input>

                <soap:body use="literal"/>

            </input>

            <output>

                <soap:body use="literal"/>

            </output>

        </operation>

        <operation name="getAltitude">

            <input>

                <soap:body use="literal"/>

            </input>

            <output>

                <soap:body use="literal"/>

            </output>

        </operation>

        <operation name="getOrientation">

            <input>

                <soap:body use="literal"/>

            </input>

            <output>

                <soap:body use="literal"/>

            </output>

        </operation>

       <operation name="checkOrientation">

            <input>

                <soap:body use="literal"/>

            </input>

            <output>

                <soap:body use="literal"/>

            </output>

        </operation>

        <operation name="addTarget">

            <input>

                <soap:body use="literal"/>

            </input>

            <output>

                <soap:body use="literal"/>

            </output>

        </operation>

        <operation name="moveToTarget">

            <input>

                <soap:body use="literal"/>

            </input>

            <output>

                <soap:body use="literal"/>

            </output>

        </operation>

        <operation name="removeTarget">

            <input>

                <soap:body use="literal"/>

            </input>

            <output>

                <soap:body use="literal"/>

            </output>

        </operation>

    </binding>

   

    <service name="SatelliteService">

        <port name="SatellitePort"

        binding="tns:SatelliteSoapBinding">

            <soap:address location=

            "http://example.com/satellite"/>

        </port>

    </service>

</definitions>

还请注意,我们可以添加任意元素到 GenericSatelliteProperties,所以我们可以容易地添加新属性,比如 targetCoords。

l         结束语

在本教程,也即 4 篇关于 WSRF 的系列文章中的第一篇文章中,我们一开始解释了 WSRF 背后的目的,以及为什么单有 Web 服务还不够。然后解释了 WS-Resource 是有状态资源(比如数据库或卫星)与 Web 服务的组合。

资源本身是由一系列属性来描述的,这些属性是与 WSDL 文件中的 Web 服务相关联的。我们还介绍了 WSDL 和 WS-Addressing 的基础,WSRF 使用 WS-Addressing 来指向一个特定的 WS-Resource 实例。

我们介绍了创建 WS-Resources,了解了它们的属性,以及调整这些属性,以便操纵资源。

在本系列的以后部分中,我们将会介绍 WSRF 的一些更高级的用途,比如 ServiceGroups 和错误处理,以及 WS-Notifications。在本系列的最后一部分中,我们将把所有内容综合在一起,并编写一个应用程序,它使用类来实现本系列前两部分中讨论的每个概念。

l         参考资料

Web 服务资源框架(Web Services Resource Framework,WSRF)涉及大量不同领域。下面是起步所需的一些参考资料:

单击 下载本教程中介绍的完整 WSDL 文件。

WSRF 和相关规范

WSRF 文档 的主要位置在 Globus Alliance Web 站点上,但是最新的规范可以在 Oasis 处找到。文档包括:

Web 服务资源框架(白皮书)

The WS-Resource Framework

WS-ResourceProperties (WSRF-RP)

WS-ResourceLifetime (WSRF-RL)

WS-ServiceGroup (WSRF-SG)

WS-Base Faults (WSRF-BF)

Web 服务和相关的规范



Author: orangelizq
email: orangelizq@163.com

欢迎大家访问我的个人网站 萌萌的IT人
posted on 2007-11-07 22:04 桔子汁 阅读(1361) 评论(1)  编辑  收藏 所属分类: Web Service

评论:
# re: 理解WSRF之一 使用WS-ResourceProperties (整理自IBM网站) 2007-11-23 10:34 | aier
thans!  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: