使用 uddi 的 web 服务描述和发现(第一部分)
karsten januszewski
microsoft corporation
2001年10月3日
查看和下载本文的源代码(英文)。简介
到目前为止,at your service 专栏已经介绍了如何建立 web 服务的实际案例:从最初的设计文档到业务关联,直至最终的部署。下一步就是要考虑如何发布 web 服务,以便感兴趣的客户能够轻松地发现该服务并将其应用到自己的应用中。现在已经有了实现这种要求的发现机制:通用说明、发现和集成 (uddi),这是业界支持跨技术、跨平台的 web 服务发现的第一步。
at your service 的作者诚恳地邀请我为专栏撰文,介绍 uddi 及其注册步骤,我非常乐于接受这项工作。首先我将从技术和业务两方面来介绍 uddi 的含义。随后我将讨论一下 uddi 和 web 服务说明语言 (wsdl) 之间的关系。最后,我将带您体验 uddi 的注册过程,并介绍一些充分发挥 uddi 潜力所需考虑的问题。在下一期专栏,即本文的第二部分中,我将介绍 at your service 小组是如何充分利用 uddi 的。uddi - web 服务的全球注册表
uddi 是一个公共的注册表,旨在以一种结构化的方式来保存有关各公司及其服务的信息。通过 uddi,人们可以发布和发现有关某个公司及其 web 服务的信息。这些数据使用标准的分类法进行分类,因此可以按分类来查询信息。最重要的是,uddi 包含有关公司服务的技术接口的信息。通过一套基于 soap 的 xml api 调用,用户可以在设计时和运行时与 uddi 进行交互以发现技术数据,从而调用和使用这些服务。通过这种方法,uddi 可以用作基于 web 服务的软件系统的基础结构。
为何使用 uddi?为何需要这种注册表?当我们面对具有数千甚至数百万个 web 服务的软件系统时,将面临以下的严峻挑战: - 如何发现 web 服务?
- 如何按照某种合理的方式分类信息?
- 对本地化有什么影响?
- 对专用技术有什么影响?如何保障发现机制的互操作性?
- 当应用依赖于某项 web 服务时,如何在运行时与该发现机制进行交互?
uddi 的出现正是为了应对这些挑战。为了解决这些问题,许多公司,其中包括 microsoft、ibm、sun、oracle、compaq、hp、intel、sap 以及三百多家其他公司(请参阅 uddi: community(英文)以获得这些公司的完整列表),共同制定了一种基于开放式标准和非专用技术的规范。该规范的 beta 版于 2000 年 12 月发布,正式产品于 2001 年 5 月推出。它是一个全球业务注册表,建立在多个运营商节点上,用户可以通过这些节点免费搜索和发布信息。
通过 web 服务的这种基础结构,现在就能够以一种通用的、与供应商完全无关的方式找到有关 web 服务的数据,而且数据一致并且可靠。使用可扩展的分类系统和标识,用户可以进行精确的分类查询。运行时 uddi 集成可以被合并到应用程序中去。因而大大繁荣了 web 服务软件环境。工作原理
uddi 数据存放在运营商(即承诺运营一个公共节点的公司)节点上。这种公共节点遵循 uddi.org 组织管理的规范。目前已经建立了两个遵循 uddi 规范版本 1 的公共节点:一个属于 microsoft;另一个属于 ibm。hp 也承诺将建立一个遵循规范版本 2 的节点。数据寄存运营商之间必须能通过安全通道复制数据,从而为整个 uddi 云团提供数据冗余。将数据发布到一个节点上后,通过复制,就可以在另一个节点上发现这些数据。目前,每隔 24 小时就进行一次复制;在将来,由于有更多的应用程序要依赖 uddi 数据,复制的时间间隔还将缩短。
值得一提的是,对于数据寄存运营商实现其节点的方式,不存在一些专用的要求,只要节点遵循 uddi 规范即可。例如,microsoft 的节点 http://uddi.microsoft.com/default.aspx(英文)完全用 c# 写成,并运行于 .net beta 2 公共语言运行时环境下。其代码基础充分利用了 .net 系统类提供的本地 soap 支持和序列化。在后端,microsoft 运营商节点使用 microsoft® sql server 2000 作为其数据仓库。而 ibm 使用其他技术来运行其节点!但是,这两个节点的行为是相同的,因为它们都遵循相同的一套基于 soap 的 xml api 调用。客户端工具可以和这些节点进行无缝的交互操作。因此,uddi 公共云团是一个最佳方案,它展示了 xml web 服务模型如何跨异类环境进行工作。
为了了解 uddi,下一步我们来看看 uddi 中存储的数据及其存储结构。uddi 相对来说是轻量的,它被设计为“注册表”,而不是“储备库”。两者之间的差别很微妙,但却很重要。注册表将用户重定向至资源,而储备库则完全是一个信息库。我们以 microsoft® windows® 注册表为例:它包含基本设置和参数,但最终把应用程序引导至资源或二进制代码。基于 prog id 搜索 com 组件时,将引导至一个 class id,然后通过 class id 再引导至二进制代码本身所在的位置。
uddi 的行为与之类似:与 windows 注册表一样,它依靠全局唯一标识符 (guid) 来搜索并定位资源。uddi 查询最终指向一个接口(.wsdl、.xsd 和 .dtd 文件等等),或指向其他服务器上的实现(例如 .asmx 或 .asp 文件)。uddi 因此可以回答以下问题: - “已经发布了哪些基于 wsdl 并是为指定行业建立的 web 服务接口?”
- “哪些公司已经为其中一个接口写好了实现?”
- “目前提供的 web 服务(以某种方式分类)有哪些?”
- “某个公司提供了哪些 web 服务?”
- “如果要使用某个公司的 web 服务,需要与谁联系?”
- “某个 web 服务的实现细节是什么?”
wsdl 和 uddi
wsdl 已成为 web 服务协议堆栈的重要组成部分。因此,有必要掌握 uddi 和 wsdl 如何协同工作,以及每个协议如何解决接口和实现这两个相对的概念。wsdl 和 uddi 都是为清楚说明抽象的元数据和具体实现之间的关系而设计的,了解为什么要这么划分是理解 wsdl 和 uddi 的基础。
例如,wsdl 明确区分消息和端口:消息(web 服务所需的语法和语义)始终是抽象的,而端口(调用 web 服务的网络地址)始终是具体的。在 wsdl 文件中不需要提供端口信息。wsdl 可以只包含抽象的接口信息,而不提供任何具体的实现数据。这样的 wsdl 文件被认为是有效的。这样,wsdl 文件便从实现中分离出来。
其重要意义之一在于:一个 wsdl 接口可以有多个实现。这种设计允许不同的系统为同一接口编写自己的实现,从而保证系统之间能进行对话。如果三个不同的公司实现了相同的 wsdl 文件,一个客户端软件根据这个 wsdl 接口创建了代理/存根代码,那么这个客户端软件就可以使用相同的代码基础与所有这三个实现进行通信,只要更改访问点即可。
uddi 通过 tmodel 的概念描绘了抽象和实现之间的这种区别。tmodel 结构(“技术模型”的简称)代表了技术指纹、接口和元数据的抽象类型。使用 tmodel 的必然结果是绑定模板,它是一个或多个 tmodel 的具体实现。在绑定模板内,要为 tmodel 的特定实现注册访问点。如同 wsdl 架构允许分离接口和实现一样,uddi 也提供了相似的机制,因为 tmodel 可以独立于引用它的绑定模板而单独发布。例如,某标准化组织或行业组织可能为特定行业发布规范接口,然后多个公司可以为该接口编写实现。因此,各个公司的实现都需要引用同一个 tmodel。wsdl 文件是 uddi tmodel 的完美示例。用 uddi 进行注册
发布到 uddi 是一个比较直接的过程。第一步是确定在 uddi 上为公司及其服务建立模型所需的基本信息。之后便可以进行实际注册。这可通过基于 web 的用户界面或编程两种方法完成。最后测试您的注册条目以确保注册正确,并且在不同类型的搜索和工具中都能按要求显示。步骤 1:为 uddi 条目建立模型
考虑上述数据模型,在建立 uddi 条目之前应准备好几个关键数据。 - 确定 web 服务实现所需使用的 tmodel(wsdl 文件)。
与开发 com 组件类似,开发 web 服务时可以使用现有的接口,也可以使用自己设计的接口。如果 web 服务基于现有 wsdl,则需要确定该 wsdl 文件是否已经在 uddi 上注册。如果是,就需要记录其名称和 tmodelkey,这是注册 wsdl 文件时 uddi 所生成的 guid。
另一方面,如果 web 服务所基于的 wsdl 文件尚未在 uddi 上注册,就需要准备创建一个新的 tmodel 来代表这个接口。此 tmodel 应具有统一资源标识符 (uri) 格式 (mycompany-com:samplewebservice-interface:v1) 的名称,并指向 wsdl 文件所在的位置。
如果 web 服务是 microsoft® visual studio® .net 服务,则可以使用 .asmx 文件(也就是:<http://www.mycompany.com/samplewebservice.asmx?wsdl>)中的查询字符串来生成 wsdl 说明。但是,visual studio .net 生成的 wsdl 文件与调用 web 服务的访问点紧密耦合在一起,如果 web 服务接口有多个实现,访问点可能就不适用了。如果不希望 wsdl 文件有多个实现,这就不是问题。 - 如果需要,可以用多种语言确定公司的名称和简介,以及公司 web 服务的主要联系方法。
uddi 支持 xml:lang 名称空间,它允许公司用多种语言提供公司简介。另外,uddi 还允许列出联系方式,包括电子邮件、电话和地址信息。联系列表用于列出公司内与 web 服务相关的资源。例如,如果有人想要使用您的 web 服务,并需要联系相应的业务关系经理,应该联系谁?使用公司的 web 服务时,有关技术问题和谁联系?该联系人也应该列出。 - 为公司确定适当的分类和标识。
通过 microsoft uddi 节点 http://uddi.microsoft.com/default.aspx(英文)浏览当前支持的 uddi 分类法。当前支持的分类法有北美行业分类系统 (naics)、通用标准产品和服务代码 (unspsc)、iso 3166、标准行业分类 (sic) 和 geoweb 地理分类。请选择一种最适于您的公司的分类。 - 确定公司通过 uddi 提供的 web 服务。
下一步,确定公司要在公共 uddi 节点上注册的 web 服务。这项服务有多个访问点吗?是否要给使用此 web 服务的客户提供其他必需的参数和信息?
注意,在 uddi 上注册 web 服务并不意味着每个人都有访问权。可以为 uddi 注册表条目依次设置安全、授权和身份验证。仅知道 web 服务的存在并不意味着就可以实际调用该服务。在授权访问 web 服务之前,公司之间通常需要进行一些额外的交流。 - 为服务确定适当的分类。
如同可以将公司分类一样,也可以将 web 服务分类。因此,公司可能按商业级别被分类为 naics: software publisher (51121),而其旅馆预约 web 服务的服务级别可能被分类为 naics: hotels and motels (72111)。
步骤 2:注册 uddi 条目
在完成建模之后,下一步就是注册您的公司。您需要获取一个可访问 uddi 注册表的帐号,这不能通过编程来完成,因为必须要同意“使用规定”声明。microsoft 节点使用 passport 进行验证,您需要获取一份 passport (http://www.passport.com/consumer/default.asp) (英文)来完成注册。
这里有两种选择:使用 microsoft 节点提供的 web 用户界面,或者通过使用 soap api 调用节点自身以编程进行注册。如果不希望更改注册表条目,或条目相对简单,则使用 web 用户界面就足够了。但是,如果希望频繁更新,或条目很复杂,请使用 microsoft uddi sdk 制作注册过程的脚本。另外,由于没有针对其他语言对 microsoft 用户界面进行本地化,所以如果想利用 uddi api 的多语言功能,需要通过编程的方法进行注册。注意:您可以在模拟环境中练习注册过程,地址是 http://test.uddi.microsoft.com/default.aspx(英文),这是实际投入使用节点的复本。这对于在正式使用之前熟悉注册过程很有帮助。
使用 microsoft 的 web 用户界面
使用 microsoft 的 web 用户界面来注册是一个相对直观的过程。首先导航至管理员页面 http://uddi.microsoft.com/administer.aspx(英文)。登录后,将显示注册 tmodel 和公司的选项。下面是继续操作时需要了解的几个事项: - 在注册服务之前,确保将 wsdl 文件注册为 tmodel,因为在以后的过程中会需要 tmodel。
- 将 wsdl 文档注册为 tmodel 时,应该使用“uddi 类型分类法”对 tmodel 分类。至少应将 wsdl 分类为“specification for a web service”(wsdlspec)。
使用这种分类方法,可以确保 tmodel 的分类符合“using wsdl in a uddi registry”最佳实践文档(英文)的原则。因为 tmodel 能包含对 wsdl 文件以外的文档的引用,所以给 tmodel 提供一些分类是很重要的。很多工具(例如 visual studio .net)靠这些分类来缩小查询的结果集。 - 将 wsdl 接口注册为 tmodel 后,需要给公司业务添加相应的联系信息以及分类信息。只要您认为合适,可以添加任意多的分类。
- 继续添加要通过 uddi 公开的 web 服务。因为服务可以有多种实现,所以需要给每个添加的服务添加一个绑定。对于每个绑定,需要提供 web 服务的访问点,即 <http://www.mycompany.com/samplewebservice.asmx>。
- 每个绑定都需要为所支持的接口创建一个引用。microsoft ui 将这些作为“规范签名”来调用。规范签名就是包含 wsdl 接口的 tmodel。microsoft ui 会提供一个屏幕,允许您基于其 urn 来搜索 tmodel。这个 tmodel 可以是在步骤 1 中注册的,也可以是别人注册的 wsdl 文件的 tmodel。
- 最后,系统会显示选项,要求提供一个关于特定 web 服务的概述文档的 http 地址,以及任何相关的实例参数。
使用 microsoft uddi .net sdk 编程进行注册
注册过程的另一种选择是通过编程进行注册。使用 microsoft uddi sdk 可以轻而易举地完成该过程。您必须使用 web ui 获取一个 uddi 帐号。完成该任务后,其余过程就交给脚本来处理。首先,下载并安装 uddi sdk,地址是 http://www.microsoft.com/downloads/release.asp?releaseid=30880(英文)。然后,使用 visual studio .net 创建一个新的 c# 控制台应用程序。添加一个对 microsoft uddi sdk dll 的引用,其默认安装位置是 c:/program files/microsoft uddi sdk/vs7/microsoft.uddi.sdk.dll。然后,在代码顶部添加一些名称空间引用:using microsoft.uddi;using microsoft.uddi.binding;using microsoft.uddi.business;using microsoft.uddi.service;using microsoft.uddi.servicetype;
在 static void main (string[] args) 函数中添加下列代码:// 您最好先运行这个程序,在 https://test.uddi.microsoft.com/publish// 上进行注册测试publish.url = "https://uddi.microsoft.com/publish";publish.user = "您的帐户";publish.password = "************";
这将为您的帐户建立身份验证。下一步,添加以下代码将 wsdl 文件发布为 tmodel:// 创建 tmodelsavetmodel stm = new savetmodel();stm.tmodels.add();stm.tmodels[0].name = "此处插入 urn";stm.tmodels[0].descriptions.add("zh","此处插入说明");stm.tmodels[0].overviewdoc.overviewurl = "此处插入 wsdl 的 url";// 下一行是给 tmodel 正确分类所必需的stm.tmodels[0].categorybag.add ( "uddi-org:types","wsdlspec","uuid:c1acf26d-9672-4404-9d70-39b756e62ab4" );string stmodelkey = "";// 发送到 udditry{ tmodeldetail tmd = stm.send(); stmodelkey = tmd.tmodels[0].tmodelkey; }catch (uddiexception ue){ console.writeline ( ue.message ); return;}catch (exception e){ console.writeline ( e.message ); return;}
成功保存后,uddi 将生成一个新的唯一的 tmodelkey,以后在 web 服务的绑定中需要用到它。下一步,创建公司条目:// 创建公司savebusiness sb = new savebusiness();sb.businessentities.add();sb.businessentities[0].name = "此处插入公司名称";sb.businessentities[0].descriptions.add("zh","此处插入说明");// 创建公司服务sb.businessentities[0].businessservices.add();sb.businessentities[0].businessservices[0].name = "此处插入服务名称";sb.businessentities[0].businessservices[0].descriptions.add("zh","此处插入服务说明");// 创建绑定模板sb.businessentities[0].businessservices[0].bindingtemplates.add();sb.businessentities[0].businessservices[0].bindingtemplates[0].description.add("zh","此处插入绑定说明");sb.businessentities[0].businessservices[0].bindingtemplates[0].accesspoint.text = "此处插入访问点";sb.businessentities[0].businessservices[0].bindingtemplates[0].accesspoint.urltype = microsoft.uddi.api.urltypeenum.http;// 创建 tmodel 实例信息sb.businessentities[0].businessservices[0].bindingtemplates[0].tmodelinstancedetail.tmodelinstanceinfos.add();sb.businessentities[0].businessservices[0].bindingtemplates[0].tmodelinstancedetail.tmodelinstanceinfos[0].descriptions.add("zh","此处插入说明");// 使用上面的 tmodelkey 字符串sb.businessentities[0].businessservices[0].bindingtemplates[0].tmodelinstancedetail.tmodelinstanceinfos[0].tmodelkey = stmodelkey;// 发送到 udditry{ businessdetail bd = sb.send(); // 显示 xml console.writeline ( bd );}catch (uddiexception ue){ console.writeline ( ue.message ); return;}catch (exception e){ console.writeline ( e.message ); return;}
此时,wsdl 定义和公司信息都已经保存到了 uddi 中。通过传递适当的键,以后您可以随时编辑这些条目。步骤 3:在 uddi 中搜索条目
在 uddi 中注册条目后,进行以下三种检查是比较有意义的。第一,使用 microsoft web 用户界面,根据名称和分类来搜索您的公司,确认其存在于返回的结果集中。第二,打开 visual studio .net 并确保它是通过“add web reference”对话框显示的。如果没有显示,则可能没有正确使用上述的 uddi-org:types 分类法对您的 tmodel 进行分类。您应该能将 web 服务添加到工程中,并基于 wsdl 文件生成代理代码。第三,等待 24 小时,您的条目将复制到 ibm 节点上,这可以通过其 ui 来查询,地址是 https://www-3.ibm.com/services/uddi/protect/find(英文)。总结
uddi 和 wsdl 作为免费的规范,可以帮助建立基于 web 服务的软件系统。wsdl 提供了与供应商无关的正式方法来定义 web 服务,这样便可以实现下一代远程过程调用。而 uddi 提供了一种广泛的、标准化的基础结构,允许人们去描述和发现 web 服务。这两个标准的结合将带来一个繁荣的 web 服务生态系统。
下周的专栏将向大家介绍 at your service 小组是如何在 uddi 中为 收藏服务(英文)进行建模和注册的。