2002-08-27 10:49
管理结构式Web服务元数据
-- 管理Web服务元数据的现状
Uche Ogbuji (uche.ogbuji@fourthought.com)
首席顾问,Fourthought, Inc.
2002 年 4 月
本文是建立在以前发表在 developerWorks 上的一篇介绍使用资源描述框架(Resource Description
Framework,RDF)来强化 WSDL 的文章的基础之上,并与最近的一篇关于 SOAP 和 RDF 一起使用的文章有关。Uche Ogbuji 着眼于
WSDL 的更新对以前介绍过的技术造成的影响,他还提到了有关 RDF 和 Web
服务描述的重要讨论以向开发者展示如何发挥两者的优势。
大约一年半以前,我仔细研究了当时刚宣布的 Web 服务描述语言(Web Services
Description Language,WSDL)如何从与 Web
元数据格式(RDF)交互(或者在标准层次上,或者在单独的开发人员工作的层次上)中获益。自从那时起,Web 服务社团和 RDF(以及 Semantic
web)社团中就一直有很多活动。这当中有些很好,如这些组织之间的对话已经定型,双方提出的技术也得到了改进。但也有不好的,如出版界莫名其妙地想象了 Web
服务阵营和 Semantic Web 阵营之间在 W3C
发生的一场臆想的争斗,双方为该联盟的资源而战。所有这些进展都是对下一代技术的开发与交互的深刻认识。但在本文中,我只讨论开发者感兴趣的最重要的进展。
对标准的更新
过去的一年中对标准进行了大量更改。WSDL 已经更新至版本
1.1,作为 W3C 备忘录发布,并是新的 W3C Web 服务描述工作组( W3C Web Services Activity
的一部分)的工作起点。该工作组已经发布了草案需求和用例,其中有一条非常有趣的要求格外引人注目,这就是被标为“必须(MUST)”的 DR070:
宪章:工作组将提供到 RDF 的映射,以便被描述的信息很容易同其它应用程序的信息合并。该映射将在 RDF Interest
Group 的帮助下开发。
这带来了好消息,总有一天 WSDL 和 RDF 之间会有标准映射。与 1.0 文档相比,WSDL 1.1
中在技术方面几乎没有重要的更改,大部分是印刷错误更正和对当时用到的最新版本的 W3C XML Schema 的更新。
然而,随着 W3C 的 Semantic Web 活动蓬勃发展,RDF 发生了重要的更改。最近的 RDF 模型理论和 RDF/XML 语法规范推动我对曾经采用的 WSDL 映射到 RDF 的方法进行了更改。还需要考虑一些其它因素。尤其是 Eric Prud'hommeaux 不采用我自己的机械的映射方法,而是一直在试图通过建立 WSDL 元素背后底层意图的映射来改进我的方法。当然,对于常规的 RDF 集成,这样的映射更有用,而且人们希望映射可以“丰富”到可以为 Web 服务描述工作组(Web services description working group)所接受。但是,对于自己的方法,我还有一个特殊目的:提供足够简单而且适合非 RDF 类型的映射,并尽可能与 XML 的标识转化相似。
随着 Web 服务和 RDF 阵营之间的合作越来越多,这样一种机械映射不再非常必要,因此,我将更多的着眼于开发者的前景。
您更新映射了吗?
开始是我把滑雪板运动者保险 Web 服务的 WSDL 映射到 RDF,后来 Eric
Prud'hommeaux's 进行了更新,清单 1 是我再次的更新。
清单 1:更新后的 RDF
中的滑雪板保险服务
<xi:include parse="text"
href="endorsement-services.rdf"/>
为了代码更加简单明了,我使用了
XML 通用实体。简洁起见,我还略去了 SOAP 错误消息规范,并修改了一些用到的名称空间(例如,更新 XSD 名称空间)。仍是为了简洁,我使用的 RDF
类型分别与每个资源在描述中所使用 WSDL 元素名相对应。
任何映射解决的问题都包括 WSDL 的命名方法。对于描述来说,WSDL 功能的名称不一定是唯一的;端口类型可以取与服务相同的名称。WSDL 可以根据上下文自己分辨这一点,但是这令人困惑而且容易出错。RDF 的好处就在于它迫使人们考虑清楚标识;在这一映射中,由一种方便的标记法来命名。全球唯一的 URI 提供实际的标识,虽然 URI 要向 RDF 软件提供重要的锚点,但却不需要让 WSDL 软件看到或理会。事实上,这些标识符可以由映射软件生成为基于随机数的全局唯一标识符(universally-unique identifiers,UUID)。
各种建模中常见的一个问题是,如何处理一起使用并且由相同的通用名来表示的属性和类。例如,在上面的 WSDL 映射中,消息与其部件之间的关系被称为 <wsdl:part>,这够自然的了,而该属性值的类,则被称为 <wsdl:Part>,这也是很自然的。但这有点糟糕,因为它是通过语法方面的细节来排除模棱两可的(也就是说,只能通过 RDF 和大多数语言中的大小写来分辨 URI )。但是,我认为,在这种情况下,最好通过自然命名方法来解决这一问题,而不是耍命名的把戏。
在一种情况下,这样的映射为了清晰而扭曲了这种命名方法:绑定与其相关操作(被命名为 <wsdl:operation>)的绑定细节之间的关系,以及未命名的内联资源所表示的该种细节与抽象的操作定义(来自 WSDL <operation> 元素)之间的关系。后者被命名为 <wsdl:abstractOperation> 以强调这两种关系完全不同的概念意义。WSDL 绑定的其余语句并不符合最初的 WSDL 语法所提议的直接方式,因为我曾尝试通过仔细阅读规范中对绑定元素的描述,来寻找最能抓住概念背后的意义的表达。
虽然这是很值得费些功夫的重要任务,但最终我并没有把元素模式定义分解成低级描述,而是提取每个元素的内容模型作为整段文字模式(literal schema),该模式是用 <rdf:parseType=Literal> 编码的。由于 RDF 1.0 中对 RDF 文本对象的文字内容的规定非常不完整,所以传统观点一直认为这是一种危险的做法,但是 RDF 核心工作组已经在 XML 典范和信息集工作组(XML canonicalization and infoset working groups)工作的基础之上对这一规范进行了非常重要修订工作。
把这些内容用于实际
对于开发者来说,这一 RDF
映射的直接好处在于能够把任意数目的这类 WSDL/RDF 描述聚集到数据库并进行全局查询。作为这样的一个示例,我已经把它放在了我的在线 RDF
查询演示接口(清单 1 中的 RDF)中,还有我为问题跟踪器 Web 服务所写的 WSDL/RDF 描述,这个服务是我在最近的 SOAP/RDF
文章中讨论过的。现在如果试验这些查询,您将会得到普通的三元组(triple)或者甚至是图(graph)。让我们看一些样本查询,开发者可能会发现这些查询有所帮助。
消息调度
事实上,您可以使用这一 RDF
描述编写可以灵活调度代码的驱动程序。您可以添加表示对 Web 服务本身的抽象的 RDF 资源。然后把与这一资源有关的语句添加到 WSDL
描述及实现它的编程模块。请参阅清单 2 中提供的代码片断示例。
清单 2:抽象的“参保的滑雪板运动者”web 服务的 RDF 描述
<wsdl:Service rdf:about="http://snowboard-info.com/EndorsementSearch">
<wsdl:description
rdf:resource="&sb;EndorsementSearchDef"/>
<wsdl:implementation>
com.snowboard-info.EndorsementSearch
</wsdl:implementation>
</wsdl:Service>
正如 WSDL 中规定的,这是 HTTP Web 服务,也许是众多服务之一。每当消息传入服务的托管服务器时,我们可以从 HTTP 协议实现中获得 SOAP 端点和 SOAPAction ,并迅速获取诸如根元素名称空间和本地名称等细节。接着,如果要执行请求,您可以装入包括下列查询的那个模块:
请查找实现 Web 服务的代码模块,该 Web 服务的描述指定 SOAP 动作和端点为 http://snowboard-info.com/EndorsementSearch、文档元素名称空间为 http://snowboard-info.com、名称为
GetEndorsingBoarder。
可以使用 Versa(一种 RDF 查询语言)来实现这一查询,如清单 3 所示。
清单 3:给定进入的 Web 服务请求条件,从资源库中检索代码模块的一个 Versa 查询
1 $port = filter(
2
type(wsdl:Port),
3
".-soap:address->eq(@'http://snowboard-info.com/EndorsementSearch')",
4
".-wsdl:binding->*
5
-wsdl:operation->*
6
-wsdl:soapAction->eq(@'http://snowboard-info.com/EndorsementSearch')",
7
".-wsdl:binding->*
8
-wsdl:operation->*
9
-wsdl:abstractOperation->*
10
-wsdl:input->*
11
-wsdl:part->*
12
-wsdl:element->*
13
-xsd:name->eq('GetEndorsingBoarder')",
14
".-wsdl:binding->*
15
-wsdl:operation->*
16
-wsdl:abstractOperation->*
17
-wsdl:input->*
18
-wsdl:part->*
19
-wsdl:element->*
20
-xsd:namespace->eq(@'http://snowboard-info.com')"
21 );
22
23
((($port<-wsdl:port-*)<-wsdl:service-*)<-wsdl:description-*)
24
-wsdl:implementation->*
这只是介绍了 Versa 的一点皮毛,总体上,它是一种非常简单的查询语言(请参阅参考资料寻找教程的链接)。为了使解释脉络清楚,我给每行都标上了数字。第 1 行开始变量赋值(一直延至第 21 行)。我随意使用了一些空格以加强可读性。Versa 的核心遍历表达式允许您遍历 RDF 图。
$foo - a:predicate -> *
这是向前的遍历,它按照谓词(a:predicate)从给定的主语 foo 检索模型中的所有可以以这种方式找到的宾语。您可以用布尔表达式(比如 eq("bar"))替换 * 字符来进一步细化结果宾语,这样就只能与文字为 bar 的字符串匹配。接下来,您可以象下面这样把结果宾语用作链状遍历表达式的起点:
$start-wsdl:binding->*
-wsdl:operation->*
-wsdl:soapAction->eq(@'http://snowboard-info.com/EndorsementSearch')
只要这些动作是带 URL http://snowboard-info.com/EndorsementSearch 的资源,就可以这样检索起始资源的绑定操作的所有 SOAP 动作。Versa 中资源可以写成限定名(<wsdl:binding>),或者把资源 URI 放在引号中,并在前面加上一个 @ 字符(例如,@'http://schemas.xmlsoap.org/wsdl/')。
您也可以以谓词的相反方向进行遍历,也就是说,使用一个回退遍历,从主语到宾语:
$foo <- a:predicate - *
当您从定义过的 $port 变量回退到与它间接相关的抽象 Web 服务资源时,您将会看到清单 3 中第 23 行的这个动作。接着,为了获取您正在寻找的代码模块名,您可以从该资源向前移到它的实现。
type() 函数检索所有给定的 <rdf:type> 资源的列表。filter() 函数会以列表作为开始,并根据一组规则不断细化。它只遍历满足所有条件的列表项。第 2 行是第一个参数,给出了初始列表,而其余 4 个参数分别从第 3 行、第 4 行、第 7 行和第 14 行开始,这些参数表示我们已经设定的条件(即,具有指定的 SOAP 动作、SOAP 端点、文档元素名和名称空间的描述)。
结束语
正如您所看到的,Web 服务和 RDF
方面的进展不仅为那些想要利用两者的开发者提供了更丰富的工具,而且双方努力之间的合作精神也更为完美。使用 SQL 查询,或对照一些 WSDL 数据绑定的 API
调用足以容易的复制我所演示的 WSDL 元数据的 RDF 查询,但是使用 RDF 的好处在于,我们可以混合 WSDL 和其它基于 RDF
的重要的元数据,包括内容描述和联合格式(例如 Prism 和 RSS)、私有简档(例如 P3P)以及其它新兴的 RDF 应用程序。Web
服务信息管理越一般化,改进集成就越容易提高效率。
以前在 IBM developerWorks
发表的相关文章
关于作者 Uche Ogbuji 是 Fourthought Inc. 的顾问兼创始人,该公司是专为企业知识管理应用提供 XML 解决方案的软件供应商和顾问。Fourthought 开发了 XML 中间件开放源代码的平台 4Suite。Ogbuji 先生是一名出生于尼日利亚的计算机工程师和作家,他生活和工作在美国科罗拉多州的博耳德。您可以通过 uche.ogbuji@fourthought.com 与 Ogbuji 先生联络。 |