了解 Web 服务规范: 第 3 部分:统一描述、发现和集成 (UDDI) (1)

了解 Web 服务规范: 第 3 部分:统一描述、发现和集成 (UDDI) (1)

级别: 中级

Nicholas Chase ([email protected]), 顾问, Backstop Media

2006 年 11 月 05 日

面向服务的体系结构(Service-Oriented Architectures,SOA)当前强调的重点在 Web 服务上,但很容易被所传播的各种信息搞得昏头转向。本系列教程将对主要 Web 服务规范进行全面说明,从简单对象访问协议(Simple Object Access Protocol,SOAP)一直介绍到 WS Business Process Execution Language (WS-BPEL)。本教程是系列教程的第 3 部分,将说明统一描述、发现和集成 (UDDI) 的基本概念,并介绍如何使用 Java 应用程序访问它。

开始之前

本教程介绍统一描述、发现和集成 (UDDI)。UDDI 指定 Web 服务和其他公司信息的注册中心,旨在提供一种发现可使用的新 Web 服务并在理想的情况下实现操作自动化的方法。

本教程假定您熟悉 Web 服务和 SOAP 的一般概念。熟悉 WSDL 的相关知识也将有所帮助,但本教程中会对一般概念进行回顾。

为了理解本教程最后一部分给出的代码,您需要熟悉 Java,不过其中的概念与本教程的其他内容一样,适用于任何编程语言。

关于本系列

本系列教程以假想的报社 Daily Moon 为例,为了提高在竞争激烈的环境中的工作效率,其员工将使用各种 Web 服务来创建工作流系统,我们将在此过程中讲解各个 Web 服务基本概念。

第 1 部分说明了 Web 服务背后的基本概念,并演示了如何使用 SOAP(后续教程讨论的大部分内容的基础规范)来将 Classifieds Department 连接到内容管理系统。

第 2 部分进一步深入说明如何使用 Web 服务描述语言 (WSDL) 定义 Web 服务预期产生的消息,从而使团队更方便地创建服务以及连接到服务的客户机。

在第 3 部分中,团队希望准备一系列服务,并希望能方便地查找这些服务。与此对应,统一描述、发现和集成(Universal Description, Discovery and Integration,UDDI)提供了可用服务的可搜索注册中心,以便使自己的服务为其他人所注意。

第 4 部分和第 5 部分讨论 WS-Security 和 WS-Policy,将详细说明如何保证该报社的服务的安全,以及团队为了访问这些刚提供了安全保护的服务需要进行哪些更改。

第 6 部分重点讨论互操作性,因为必须从单个系统访问来自几个不同实现的服务。这一部分还将讨论 WS-I 证书中涉及的要求和测试。

最后,第 7 部分演示如何使用业务流程执行语言(Business Process Execution Language,WS-BPEL)来从各个服务创建复杂应用程序。

接下来让我们更为详细地了解一下本教程中将讨论的内容。





回页首


关于本教程

本系列的第 1 部分 介绍了 Web 服务,并强调了 SOAP 的重要性。这些内容是通过虚构的 Daily Moon 报社的 Classifieds Department 进行相关工作的过程说明的。在本系列的第 2 部分中,Classifieds Department 决定创建自己的服务,并使用 Web 服务描述语言 (WSDL) 记录其使用方式。在第 3 部分中,报社的发行人决定全面推行 Web 服务,并强制要求使用 UDDI 注册中心来记录所有可用服务。

在本教程中,您将了解以下内容:

  • 什么是 UDDI
  • UDDI 的用途
  • UDDI 数据的结构
  • 如何有效地使用 UDDI 表示 WSDL
  • 可以对 UDDI 数据执行的操作
  • 使用 Java 与 UDDI 注册表交互




回页首


先决条件

为了处理本教程中的代码,您需要有以下软件:

Apache Geronimo 或其他 UDDI 实现。为了处理本教程中的代码,您需要访问 UDDI 注册中心。为了实现此目标,所使用的注册中心类型并不重要,因为 UDDI 根本就是 Web 服务,应该可以从任何平台或语言进行访问,并能够访问任何平台或语言。既然这样,就可以使用我们在本系列的第 1 部分和第 2 部分使用的 Apache Geronimo 应用服务器(同时也是 IBM 的 WebSphere Community Edition 的基础),其中预安装了 Apache 的 UDDI 注册中心实现 jUDDI,并将其配置为基本安装的一部分。您可以从 Apache.org 下载 Apache Geronimo。有关安装 Geronimo 的更多信息,请参见本系列的第 1 部分。

UDDI4J——为了访问注册中心,本教程说明了 UDDI4J 项目的使用方法;此项目提供了 UDDI 概念和 Java 代码间非常紧密的集成。可以从 Sourceforge.net 下载 UDDI4J。

Apache Axis2 或其他 SOAP 实现——可以手动创建 SOAP 消息,也可以手动对其进行解释,但手边如果有一个可用实现就会方便得多。您将使用的是 Apache Axis2,其中包含了各种 SOAP 相关的 API,可极大地简化您的工作。可以从 Apache.org 下载 Apache Axis2 。本教程使用的是 0.94 版,但应该也能使用更高版本。

Java 2 Standard Edition 的 1.4.x 版——所有这些工具都是基于 Java 的,本教程中将要构建的服务和客户机也是如此。可以从 Sun Developer Network 下载 J2SE SDK。Geronimo 将无法与 Java 1.5 一起正常使用。

另外,还需要 Web 浏览器和文本编辑器,但我想您已经有了这两个工具。如果愿意,还可以使用 Eclipse 之类的 IDE,但由于我们的重点是技术而不是工具,因此我将使用文本编辑器和命令行来编辑和编译文件。





回页首

概述

让我们看一看目前已经完成的工作。

已完成的工作

本系列教程逐步说明了虚构的 Daily Moon 报社的员工将其日常操作更改为基于 Web 服务的系统的过程。在第 1 部分中,Classifieds Department 通过与内容管理系统交互了解了 SOAP 的相关信息,在第 2 部分中,他们创建了自己的服务,并使用 Web 服务描述语言 (WSDL) 对其进行描述。现在,该报社的发行人 Rudy 对 Web 服务在其组织内的工作情况印象非常好,希望能更广泛地应用 Web 服务,甚至希望将其用于与其他组织进行交互。

为此,他要求 IT 人员 Gene 和 Francis 创建一个 Web 服务注册中心,以便能让其他部门更方便地找到为了将自己的操作过渡到 Web 服务而需要的构件。

Gene 和 Francis 认为最好的做法是实现统一描述、发现和集成 (UDDI) 注册中心,从而不仅能存储有关报社自己服务的信息,还能够与其他报社的注册中心进行交互。





回页首


WSDL 回顾

向 UDDI 注册中心注册服务的部分过程将涉及到对 WSDL 定义进行操作,因此在开始新项目前,Gene 重新分析了一下上个项目中的文件,以回顾 WSDL 的基本概念。请参见清单 1。


清单 1. WSDL 文件
                    
<wsdl:definitions xmlns:xs="http://www.w3.org/2001/XMLSchema" 
       xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
       xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
       xmlns:tns="http://www.daily-moon.com/classifieds"
       xmlns:ns1="http://org.apache.axis2/xsd" 
       targetNamespace="http://www.daily-moon.com/classifieds">

<wsdl:types>
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
         targetNamespace="http://org.apache.axis2/xsd" 
         elementFormDefault="unqualified" 
         attributeFormDefault="unqualified">

    <xs:element name="createNewAdRequest">
      <xs:complexType>
        <xs:sequence>
          <xs:element type="xs:string" name="content" />
          <xs:element type="xs:string" name="endDate" />
        </xs:sequence>
      </xs:complexType>
    </xs:element>

    <xs:element name="createNewAdResponse">
      <xs:complexType>
        <xs:sequence>
          <xs:element type="xs:int" name="newAdId" />
        </xs:sequence>
      </xs:complexType>
    </xs:element>
...
  </xs:schema>

</wsdl:types>

<wsdl:message name="createNewAdRequestMessage">
  <wsdl:part name="part1" element="ns1:createNewAdRequest" />
</wsdl:message>

<wsdl:message name="createNewAdResponseMessage">
  <wsdl:part name="part1" element="ns1:createNewAdResponse" />
</wsdl:message>

<wsdl:message name="getExistingAdsResponseMessage">
...
</wsdl:message>

<wsdl:portType name="ClassifiedServicePortType">

  <wsdl:operation name="createNewAd">
    <wsdl:input message="tns:createNewAdRequestMessage" />
    <wsdl:output message="tns:createNewAdResponseMessage" />
  </wsdl:operation>

  <wsdl:operation name="finalizeIssue">...</wsdl:operation>
  <wsdl:operation name="editExistingAd">...</wsdl:operation>
  <wsdl:operation name="getExistingAds">...</wsdl:operation>

</wsdl:portType>

<wsdl:binding name="ClassifiedServiceBinding" 
              type="tns:ClassifiedServicePortType">

  <soap:binding transport="http://schemas.xmlsoap.org/soap/http" 
                style="document" />

  <wsdl:operation name="createNewAd">
    <soap:operation soapAction="createNewAd" style="document" />
    <wsdl:input>
      <soap:body use="literal" 
                 namespace="http://ws.apache.org/axis2" />
    </wsdl:input>
    <wsdl:output>
      <soap:body use="literal" 
                 namespace="http://ws.apache.org/axis2" />
    </wsdl:output>
  </wsdl:operation>

  <wsdl:operation name="finalizeIssue">...</wsdl:operation>
  <wsdl:operation name="editExistingAd">...</wsdl:operation>
  <wsdl:operation name="getExistingAds">...</wsdl:operation>

</wsdl:binding>

<wsdl:service name="ClassifiedService">
  <wsdl:port name="ClassifiedServicePort" 
             binding="tns:ClassifiedServiceBinding">
    <soap:address location=
"http://www.daily-moon.com:8080/axis2/services/ClassifiedService" />
  </wsdl:port>
</wsdl:service>

</wsdl:definitions>

由于篇幅的原因,我们从此文档中删除了部分代码,但我们仍然能通过剩下的部分了解其一般概念。

首先看最下面,我们定义了实际的服务,可通过特定的位置对其进行访问,且实现了 ClassifiedServiceBinding 接口。该接口表示为绑定,指定在 ClassifiedServicePortType portType 中定义的操作。portType 使用在 types 部分中定义的元素定义输入和输出消息。

XML 客户机可以读取此信息,并将其用于访问 Web 服务。(或者,更为准确地说,Web 服务客户机生成工具可以读取此信息,然后生成可以访问 Web 服务的客户机。)





回页首


我们的目标

在本教程中,Gene 和 Francis 将 Daily Moon 的信息拆分为 UDDI 友好的结构,包括业务信息和服务信息。他们将使用其通过 UDDI4J 将报社的信息和服务输入 UDDI 注册中心。它们还将与另一个报社 Daily Star 的私有注册中心协同工作,以查找提供即时体育赛事比分的服务。

现在让我们看一看到底什么是 UDDI。





回页首

UDDI 简介

UDDI 基本上就是一个 Web 服务,但与 SOAP 和 WSDL 存在很大差异,最好在开始之前了解一些背景知识。

为何使用 UDDI?

当所有应用程序都位于本地时,要找到所需的功能会非常容易。不过,使用 Web 服务之类的分布式系统时,您不能获得中央注册中心的好处。分布式系统也容易发生更改。而这正是 UDDI 的用武之地。它旨在用于两个目的。最初形成时,它被认为是一种“通用业务注册中心”。其想法是,企业可以使用以下三种方法之一搜索合作伙伴:

  • “白页”:白页与电话簿中用于查找公司信息的白页类似。例如,如果您知道公司的名称,可以在其中查找公司的地址、如何进行联系,甚至还能够确定与组织中的哪个人联系。
  • “黄页”:同样,黄页与电话簿中的黄页一样,可以在其中根据分类查找公司。UDDI 指定了各种分类法,以供各个公司用于对自己进行分类。例如,如果您在查找体育用具,则可以查找其北美工业分类系统(North American Industry Classification System,NAICS)代码为 339920 的公司。
  • “绿页”:电话簿中没有绿页,但这里的想法是,公司可以使用此搜索方法来查找实现了特定服务的贸易合作伙伴。例如,可以搜索实现了使用邮政编码的距离计算功能的公司。

UDDI 同时也被认为是一种保持分布式应用程序长期运行的方法。其想法是这样的,可以缓存有关访问特定服务的信息,如果客户机崩溃,应用程序将自动回到注册中心并进行检查,以确定信息是否已更改。如果已更改,则可以直接在应用程序内进行更改(在理想的情况下将自动进行更改)并重试您的请求。





回页首


UDDI 的实际应用

当 Francis 想尝试统一业务注册中心(Universal Business Registry,UBR)时,发现它已不复存在了。事实上,在推出 UDDI 3.0 版时,UBR 已被其企业赞助商终止了。为什么呢?无论 UBR 的想法多么好,但事实是基本上没有人使用它。其原因是双方面的:首先,在 UBR 中几乎没有任何可用信息——除非希望使用的是实时股票行情服务(在此情况下可找到大量信息)。第二个原因是,通常公司并不会与不熟悉的组织开展业务。很少有组织通过自动搜索寻找贸易伙伴,然后在不进行大量前期工作的情况下直接向其开发系统。自动搜索和调用模型并没有实际的效用。

同时,这也受到 UDDI 在某种意义上有些超前的事实的阻碍。它设计为处理所有类型的服务,而不仅是 SOAP over HTTP,并没有提供使用 WSDL 定义的机制(至少尝试使用它的人这样认为)。

不过,这并不是说根本不会使用 UDDI。相反,实际上它更多地用作“私有注册中心”。各个公司创建自己的注册中心,并在其中输入自己的服务。UDDI 还可以用作内部的业务注册中心,就像 LDAP 的传统用法一样。

而且,随着从“只有 Web 服务”的思维方式转变为更多强调面向服务的体系结构(Service Oriented Architecture,SOA)的思维方式,这种处理 SOAP 之外的内容的能力可能具有极高的长期价值。





回页首


UDDI 数据结构

UDDI 注册中心中的信息包含五种不同类型:

  • businessEntity 或实际企业组织。这可以是整个组织,也可以为隶属部门或分支机构。
  • publisherAssertion 或各个 businessEntities 间的关系。publisherAssertions 必须由双方共同声明才有效(因此无法将自己声明为另一个公司的分支机构),除非两个实体都对发布者负责,或除非两个实体都由同一个用户帐户输入注册中心。
  • bindingTemplate,这对服务接口的规范非常重要。它可以由多个 businessServices 进行实现。
  • businessService 或业务提供的服务。虽然现在看起来有些简单,但在 UDDI 的世界中,这并不意味着它是 Web 服务。例如,可以实际将您的公司的电话服务支持(即用户实际拨打的电话号码以及其他相关的内容)指定为 UDDI 服务。当然,您并不会提供虚拟 WSDL 文档,但这将是您的公司提供的一个服务。
  • tModels 或元数据模型。研究了 UDDI 后,Francis 得出结论,tModel 可能是 UDDI 未达到预期目标的最大原因。作为服务的注册中心,您希望找到像 WSDL 一样直接为服务指定接口的方法。但是,正如所指出的,UDDI 并不是仅供用于 Web 服务,而是设计时包含了更大的灵活性。tModels 的确可帮助指向 XML 文档(我们稍后将证实这一点),但事实上旨在提供通过服务、业务或任何其他对象指定关于某个事项的信息的通用方法。

以上是 UDDI 的基本数据结构。现在让我们了解一下可以用于与 UDDI 交互的方法。





回页首


UDDI API

UDDI 被认为过于复杂,但其核心在于上述五种数据类型以及四个操作:findgetsavedelete。也就是说,UDDI 规范说明了可以对数据进行的以下操作:

  • find_xxfind_businessEntityfind_businessService 等方法提供了在 UDDI 注册中心中搜索记录的方法。这些方法返回用于标识对象的键。
  • get_xx:获得了标识对象的唯一键后,可以使用 get_businessServiceget_xx 方法来检索实际的对象本身。例如,get_businessService 将返回整个 businessService 对象,可从其中获得任何所需的信息。
  • save_xx:您可能已经猜到,这些方法会将信息添加到数据库,或更改数据库中已经存在的信息。
  • delete_xxdelete_bindingTemplatedelete_tModel 等方法获取对象的唯一键作为参数,然后将其从数据库中删除。这些方法的实际行为根据所删除的对象不同而有所变化。例如,由于数据库中的其他对象经常引用 tModels,因此并不能实际将其删除,而会将其隐藏。

几乎所有的 UDDI 都依赖于五个对象(businessServicebindingTemplatepublisherAssertionbusinessEntitytModel)与四个操作(findgetsavedelete)的这 20 个交叉方法。

现在让我们看一看此结构的实际情况。





回页首

你可能感兴趣的:(了解 Web 服务规范: 第 3 部分:统一描述、发现和集成 (UDDI) (1))