Web Service Case Study:软件反馈跟踪平台 来源: 时间:2002-08-26 09:29 作者:AMTeam.org Web Service Case Study:软件反馈跟踪平台
Chief System Architect 2002年3月26日 在我以前的developerWorks的专栏文章中,我已经系统地介绍了各种Web服务技术标准及其细节,然而Web服务并不仅仅是一种技术,更是一种应用框架,一种系统架构的方式,和一种应用的思想。所以从本次开始的
"Web Service Case Study"
文章系列中,我将在每一篇文章中使用一个具体的应用实例,通过应用分析来详细阐述使用Web服务技术的好处和优越性,同时从Web服务的角度结合实例介绍各种Web服务技术在具体的项目中应该如何被使用。 案例背景简介 - 软件反馈跟踪平台 在本系列的第一篇文章中,我们将从软件行业自身的应用开始。我们知道,对于一个软件企业而言,不论是提供软件产品、还是提供软件解决方案,或是承接软件项目,对于用户反馈的获取都是非常重要的,这不仅是优质服务的必要保证,同时也是软件产品、解决方案升级换代的重要依据。 在这样的应用背景下,用户反馈不仅仅包括用户对产品的意见,同时也包含软件产品的BUG自动报告,以及一些性能参数的采集等。当然其中的有些是需要客户授权方可进行的,比如性能参数收集等。 首先,我们先来分析一下在这个应用背景下的角色及其对应的行为描述如下: 软件公司:软件公司是生产软件、提供软件产品的企业。它对自己的软件产品的质量负有责任,对客户需要提供技术支持,同时在获取足够的反馈的前提下,需要即时地对自己的软件产品进行升级,或者开发新的软件产品,因此它需要即时地获取有关其提供的软件产品的各种反馈信息。 客户:使用、消费软件产品的商业实体或个人。为了更好地接收软件公司的服务,它需要提供必要的和充分的软件使用反馈,反馈包括由客户的技术人员以描述方式提供,或通过软件产品的某种日志接口导出文件并提供给软件公司。 通过对以上角色及其行为的分析,我们认为在最终的实现系统中概要层次上的对象主要就有这样几种: 反馈信息分类目录,反馈信息分类目录由软件公司维护,所有的反馈信息都位于反馈信息分类目录的不同结点下分类组织。 反馈信息,由客户或运行中的软件产品产生,经过反馈信息分类目录归类组织,由软件公司使用。 用户,用户分两类,一类是客户用户(包括客户消费的软件产品中可能用到的用户),一类是软件公司用户,分别用于处理两类事务:软件公司用户的目录管理/信息查询,以及客户用户的信息提交。 系统构架概述 Figure 1. 系统结构概述
下面我花一点篇幅稍详细解析一下框架中的两个个主要服务:Catalog Service和Authentication Service。 Catalog Service 根据前面的应用背景描述,Catalog Service应当具备如下功能: 类别(Category)管理,包括增加一个Category、删除一个Category、修改一个Category等;其中Category不光用于表示软件产品的分类,同时软件产品也将以叶子类别结点的形式出现。 反馈数据管理,包括增加一则反馈数据、删除一个反馈数据、修改一个反馈数据、移动一个反馈数据(从一个Category下移动到另一个Category下)等; 数据交换,包括单个类别下所有反馈数据的导入导出(Import/Export),单个反馈数据的导入导出,整个类别树的导入导出等; 数据备份,整个目录下所有反馈数据的备份/恢复等。 Authentication Service 而Authentication Service则相对简单,它的功能可描述如下: 用户登录/注销,完成用户登录服务和从服务注销的功能,这个功能是由用户使用的(包括管理员用户和一般用户)。 权限审核,用户权限审核,为除Authentication Service之外的服务提供权限审核功能。 系统间的交互 我们将以上功能各个模块的功能描述加以总结,去除内部实现的部分,我们可以发现在Internet上需要传输的数据也就是两类:目录和反馈数据。 目录由多个目录结点组成,目录包含一个根结点,每个目录结点(除根结点以外)有一个父目录结点,一个目录结点可以包含多个子结点。一般而言目录的叶子结点是某个软件产品,而中间结点则是表示软件产品的分类。 反馈数据总是从属于一个目录结点,一般来说主要的反馈数据,包括BUG报告,性能数据以及描述性反馈都是属于叶子结点,也就是软件产品的,不过在非叶子结点下也会包含一些描述性反馈数据。 自具体定义中,我们需要先定义一个抽象反馈信息类,然后以这个类为基类,派生出BUG报告反馈类、性能数据反馈类以及描述性反馈类等。 总之,在我们这个应用环境下,有两种数据是我们要主要关心的:目录和反馈数据。 在系统之间交互数据是交互的第一层次:数据交换,然而对于Web服务而言,光光有数据交换是不够的,应当提供更高层次:服务集成的支持。 因此,交互的内容不光包括互相交互的数据,同时应当包含对数据的操作(比如数据请求,数据添加,数据更新等等)。这些往往会对应于服务端的一个处理模块。 无论是对数据的操作,还是数据本身,为了在系统与系统之间进行交互,尤其是异构平台之间,我们需要将所有的操作(服务调用)和操作的数据(服务调用的参数和返回值)进行规范化的描述,形成规范文档后发布以供所有需要参与互操作的系统共同遵守。 为什么使用Web服务解决方案? 我们知道,对于一个软件产品的信息采集系统而言,以下两个特性是不可缺少的: 使用的方便性,我们知道在软件产品中的反馈数据采集模块,尤其是那些Bug报告模块或者是性能数据收集模块,需要嵌入在软件产品的代码中的,在嵌入的时候应当尽可能地简单和统一,这样才能保障软件产品的代码的可维护性。 客户端模块的跨平台性,对于一个公司而言,它的软件产品可能是会跨越多个平台的,同时开发环境也不尽相同,如何能让客户端在各种平台下的软件产品中被嵌入,是一个非常重要的问题。同时,跨平台性这个特性还能使得这个平台能够拓展到ASP(Application Service Provider)的模式下,为多个软件企业服务,从而成为公共的网络服务平台。 基于XML技术的Web服务正是解决这一问题的最佳手段。Web服务的使用将改变目前的开发模式和应用部署的费用规模。各种Web服务分别实现了一定的模块功能,通过将各种提供不同功能的Web服务进行组合和集成以创建动态应用。Web服务能够统一地封装信息、行为、数据表现以及商务流程,而无需考虑应用所在的环境是使用何种系统和设备。 从外部的使用者的角度而言,Web服务是一种部署在Web上的对象/组件,它具备以下特征: 完好的封装性,Web服务既然是一种部署在Web上的对象,自然具备对象的良好封装性,对于使用者而言,他能且仅能看到该对象提供的功能列表。 松散耦合,这一特征也是源于对象/组件技术,当一个Web服务的实现发生变更的时候,调用者是不会感到这一点的,对于调用者来说,只要Web服务的调用界面不变,Web服务的实现任何变更对他们来说都是透明的,甚至是当Web服务的实现平台从J2EE迁移到了.NET或者是相反的迁移流程,用户都可以对此一无所知。 使用协约的规范性,这一特征从对象而来,但相比一般对象其界面规范更加规范化和易于机器理解。首先,作为Web服务,对象界面所提供的功能应当使用标准的描述语言来描述(比如WSDL);其次,由标准描述语言描述的服务界面应当是能够被发现的,因此这一描述文档需要被存储在私有的或公共的注册库里面。同时,使用标准描述语言描述的使用协约将不仅仅是服务界面,它将被延伸到Web服务的聚合、跨Web服务的事务、工作流等,而这些又都需要服务质量(QoS)的保障。其次,我们知道安全机制对于松散耦合的对象环境的重要性,因此我们需要对诸如授权认证、数据完整性(比如签名机制)、消息源认证以及事务的不可否认性等运用规范的方法来描述、传输和交换。最后,在所有层次的处理都应当是可管理的,因此需要对管理协约运用同样的机制。 使用标准协议规范,作为Web服务,其所有公共的协约完全需要使用开放的标准协议进行描述、传输和交换。这些标准协议具有完全免费的规范,以便由任意方进行实现。一般而言,绝大多数规范将最终有W3C或OASIS作为最终版本的发布方和维护方。 高度可集成能力,由于Web服务采取简单的、易理解的标准Web协议作为组件界面描述和协同描述规范,完全屏蔽了不同软件平台的差异,无论是CORBA、DCOM还是EJB都可以通过这一种标准的协议进行互操作,实现了在当前环境下最高的可集成性。 Web服务的这些特点的的确确能够满足我们的这个反馈数据收集平台的需求,并且为这个反馈数据收集平台赋予了功能延伸和规模延伸的可能。 交互界面设计 之前,我们已经谈到了需要为我们自己开发的Web服务制订调用规范,那么调用规范该如何定义呢,从总体上来说,规范定义可以分为两部分: Programmer's API:这是类似传统含义的API定义,不过承载的介质是SOAP Message,也就是说Programmer's API是一组SOAP API,不同的API用于完成不同的服务调用,在这部分中需要定义不同的SOAP API的行为和实现的调用/响应的功能描述; Data Structure:这部分定义了在SOAP消息中传输的参数/数据和响应数据的XML Schema,这部分为每个API补充的消息格式,同时为最终的API处理提供了数据层解析/包装的规范。 API设计原则 简单性,由于这是一个对于公共开放的Web服务,它的API的设计首先应当是简单的,要被大量用户接受,要获得比较好的应用,那么API必须简单,没有哪个复杂难用的API会得到大家的广泛接受的。 可扩展性,作为更新频率较高,开放性较强的Web服务,其API应当具有很好的向后扩展性,当应内部需求的改变或外部需求的改变的需要时,API将根据新的逻辑发生变化,此时不应当将API从根本上推翻重建,而应当具备增量式的可扩展的能力。 高效性,API应该在坚持简单性的前提下,兼顾高效性,当某些组合操作应用地非常频繁的时候,我们应当为这样的组合操作调用设计一个只需一次交互的单一入口调用,这样能够提升外部应用的效率,同时减轻Web服务的负载。 完备性,所谓完备性就是说整个API要覆盖所有需要对外公开的功能,这相对而言是最好实现的目标,只要设计阶段考虑得完备,就能达到完备性的要求。而且万一发现不完备的情况,修正起来也是相对容易的。 Data Structure设计 本系统的数据主要有两类:目录和反馈数据。首先,我们先来给出相对简单的目录XML数据结构定义。 Category的具体描述格式: <category categoryKey="…" parentCategoryKey="…"> 这是一个缩略版的目录数据格式定义,我们可以看到一个category可以包括0个或多个category,同时每个category具有两个子元素name和description分别描述这个类别结点的名称和描述,category还包含两个属性:categoryKey和parentCategoryKey,分别表示一个类别结点的UUID(唯一标识符)及其父类别结点的UUID。由一个根类别结点开始及其包含的所有子孙类别结点一起组成了我们的目录数据。 在给出了目录的数据之后,我们再来定义反馈数据的数据结构: <feedback feedbackKey="…" parentCategoryKey="…"
type="…"> 其中,feedback元素的属性feedbackKey和parentCategoryKey分别表示当前feedback元素的UUID以及其所在类别结点的UUID。Name和description子元素与前面的含义是类似的。下面我们来介绍一下dataBag这个子元素,这是一个字段值的聚集,一个dataBag可以包含0个或多个字段。每个字段都是以<field name="……">……</field>的形式出现的, 可以想象,采用了诸如dataBag这样的数据聚集的描述方式,将使得这个系统的适用性非常强,可以适应大多数用户的特殊需求,用户可以在其中自由地定义字段并为字段赋上相关的字段值。对于系统的适应性和可扩展性,这样的数据描述方式是非常有效的,然而如此自由的描述方式,对于系统平台去检验这些字段的合法性(比如字段名有没有写错,字段值的类型是否正确等)却是非常不利的。 鉴于合法性校验的考虑,我们认为,可以引入dataBag Template的概念,所谓dataBag Template就是一种预先定义好的在某个特定领域应用中使用的反馈信息数据的模版,这个模版定义了所有合法的字段,包括字段名称及其字段值类型。下面我们给出一个dataBag Template的例子: <dataBagTemplate templateKey="…"> 这个dataBag Template定义了三个字段,Application(应用名称)、Module(模块名称)、Exception(异常编号,注意这是整型字段)以及Description(错误描述),这个Template用于定义一般的错误报告的模版结构。 由于使用了dataBag Template,我们需要更新反馈数据的数据结构: <feedback feedbackKey="…" parentCategoryKey="…"
type="…"> 如此,系统平台就可以利用templateKey找到相应的dataBag Template,从而进行数据校验。需要注意的是,databag Template并不在系统的一般交互中被传输,它是作为系统的插件安装在平台系统或者客户端中的,也就是说,当平台系统接收到反馈数据XML文档后,从这个文档中获得templateKey,然后通过templateKey在系统中查找,看看这个对应的dataBag Template是否已经被安装(导入)进平台,如果已经安装了,那么就按照这个Template来校验合法性,如果尚则安装,则可以选择报错,或忽略合法性校验。 Catalog Service API设计 Catalog Service的API设计如下: save_category:
保存category,在这个API调用中,包含了更新和新建的操作,同时category的迁移也可以通过这个API来完成。
由于我们先前已经确定了category和feedback这两个实体的数据结构的XML描述格式,那么下面我们就可以来定义API消息了。在这里,我们仅仅定义一个消息save_feedback,其他的消息则可以类似推得。 save_feedback 用于提交反馈数据,使用这个API调用,可以完成对反馈数据的更新、新建和迁移的操作。一般来说对于普通用户,仅仅可以新建反馈数据(提交新的反馈数据),而不能进行更新和迁移等操作。 <save_feedback> 在上述的语法描述中,大家应该可以发现,save_feedback能够用于保存一个或多个feedback反馈数据,这样的设计是为了达到高效性的设计目标。 当整个消息中的任意一个feedback所属的表示自身实体的键值feedbackKey为空,即表示这是一个新增的feedback,需要被插入到数据库中,在返回消息中,将回送这些元素的键值。 当消息中任意一个feedback的parentCategoryKey没有发生更改时,表明是要更新该元素的信息。而若parentCategoryKey发生更改的时候,表明该元素将从之前的由原有parentCategoryKey所标识的category结点下被迁移到由新的parentCategoryKey所标识的category结点下。当然如果包含了数据更新操作,同样会实施该数据更新操作。 细心的读者一定已经发现了在这个消息中,有一个authInfo元素,这是一个用于权限检验的授权令牌。用户通过向Authentication Service登录而获得这个令牌,当Catalog Service得到这个令牌后,则是向Authentication Service询问令牌的合法性,如果合法方能执行相应的消息,用户在交互完毕之后,应向Authentication Service注销令牌。 save_feedback消息调用的返回是一个或多个完整的被接受的feedback信息,与提交的信息的差别就是仅有概要信息,没有详细信息,同时原先空着的键值都被填上Web服务所指派的键值。下面是一个返回消息的例子: <result> Web服务实现 在本文的前面的内容中,我们已经设计了这个软件反馈跟踪平台的实现方案,并着重地讨论了服务组件的Web服务界面,下面我将依靠一些实践来进一步介绍Web服务技术系列中的XML Schema、SOAP、WSDL、UDDI等在服务实现的过程中是如何被一一使用的。 在这部分中,我将把save_feedback这个SOAP API拿出来,看看在具体的实现上,应当如何对这个消息使用W3C XML Schema进行建模,在具体的服务交互中,SOAP消息的格式是如何的,如果使用WSDL将基于该消息调用的Web服务进行规范描述并交付调用者,以及如何将这个Web服务连同它的WSDL规范化描述文件一起发布到UDDI注册中心中去。 XML Schema数据建模 一个XML Schema文档中的定义通常分为两部分,型(Type)定义和元素(Element)定义。下面我们结合save_feedback具体的XML Schema定义来说明如何使用XML Schema来进行模式定义。 save_feedback的XML Schema描述定义: <?xml version="1.0" encoding="UTF-8"?> 在这个模式文档中,以此非别定义了save_feedback元素、save_feedback类型、feedbackType类型和dataBagType类型。其中,save_feedback元素的类型是save_feedback类型,而在save_feedback类型定义中引用了feedbackType类型定义,同时feedbackType类型定义中使用了dataBagType类型定义。 SOAP消息示例 有了XML Schema之后,我们就可以参照XML Schema在Web服务实现时使用SOAP进行互相通信了。以下是一个save_feedback的调用例子,在例子中使用了SOAP HTTP Binding(使用的SOAP规范的版本是1.2),假设目标Web服务被部署在假象的www.sagitta.com,而调用的Web服务的入口位置将是http://www.sagitta.com/feedback/。 在这个消息中,将在一个现有的category中添加一个新的feedback。 POST /catalog HTTP/1.1 <?xml version="1.0" encoding="UTF-8"
?> 从中我们可以看到在save_feedback元素后面带了一个xmlns的修饰"http://www.sagitta.com/schema/"。这个URI唯一表示了该元素及其所有子元素的的命名空间。同时通过这个URL可以获得这些元素的Schema定义。 使用W3C XML Schema描述的XML文档的模式定义在整个Web服务的技术系列中处于一个支持工具的地位。W3C XML Schema是任何类型的XML文档的建模工具。在Web服务体系中,无论在SOAP消息的表示上,还是在WSDL的界面描述上,XML Schema都是不可缺少的重要工具和底层支持。 WSDL服务描述 对SOAP API消息完成Schema建模之后,一方面这个数据模型可以由SOAP Interface来使用,当发生具体调用时可以使用这个数据模型来处理传入的参数并生成传出的参数。同时,利用这个数据模型,我们可以生成相应的WSDL描述,从而将这个Web服务的接口文档发布给使用者,该接口文档是具备被程序自动处理的能力的。 一般来说,有了XML Schema,WSDL文档的生成是非常方便的,我们在各个平台上都有丰富的工具可以使用,这里就不给出具体的WSDL文档了。 UDDI服务发布 由于我们在设计这个软件反馈跟踪平台的一开始,就致力于将它往公共平台或者是可重用平台的方向发展,为了使更多的潜在用户能够发现这个Web服务,同时也为了加强这个Web服务的互操作能力和灾难恢复时的连接保持能力,我们需要使用UDDI SDK将这个Web服务注册到UDDI注册中心中去。 我们之前已经注册了一个businessEntity,叫做www.sagitta.com,一个在线服务提供商,这个businessEntity的键值是"434554F4-6E17-1342-EA41-36E642531DA1",那么我们要在这个businessEntity下注册一个businessService,以用于描述我们的这个Feedback Service。同时我们也预先注册了一个Service Type(tModel),这个tModel描述了我们这个需要发布的Web服务的调用规范,具体内容是我们先前已经生成的WSDL文档,在UDDI中,注册的是这个描述文档的链接URL。 businessService注册的SOAP消息如下,其中使用了Microsoft的test.uddi.microsoft.com站点,因此authInfo中可以填入测试用的"udditest"。 <?xml version="1.0" encoding="UTF-8"?> 通过上述的API调用,我们就已经把这个服务注册进了UDDI注册中心,其中bindingTemplate的accessPoint是服务的入口。 潜在的使用者可以通过查询UDDI注册中心找到这个Web服务,通过overviewURL中保存的URL找到服务的描述,然后通过accessPoint所指定的访问地址来访问这个服务。 当发生紧急服务崩溃的时候,Web服务可能被迁移到另一台主机上,IP地址,甚至是访问的URL都可能有很大变化,此时原先的集成的连接将不再工作。但是由于UDDI注册的存在,我们可以通过自动化的程序手段来解决这个问题,使得类似的服务灾难恢复的过程非常迅速。 具体的流程一般是: 当恢复的服务启动后,自动去更新UDDI注册中心上的数据,将访问入口修改到新的URL位置; 连入的客户端系统当发现无法访问最终服务的时候,将会定期去查询UDDI注册中心,看看新的BindingTemplate数据和本地缓存的有没有差别,如果有的话,就下载到本地,重新建立服务绑定,完成服务连接的迁移。 遗留的问题 这里给出了软件反馈跟踪平台的简要设计,而关于一些更深入的功能和实现上的一些考虑,我想就留给广大读者,下面,我谨提出两个可能的问题: 在dataBag Template的设计中,如果用户认为类似关系数据库的平坦的数据结构尚不能满足需要,而需要有层次性的数据结构来支持,我们应该如何更新dataBag Template的设计? 在具体实现中,尤其是在大规模使用的公共平台实现中,如果访问量大幅度增大,应该如何对实施架构的部署进行进一步设计? 大家对于这两个问题的任何建议以及大家想到的其他可能的问题,都欢迎来到"http://forum.uddi-china.org/cgi-bin/topic.cgi?forum=15&topic=7&show="提出意见或给出评论。 小结 在本系列下一篇文章中,我将围绕一个认证考试申请系统展开设计和讨论,这与本文的系统不同,主要是面向B2C模式的应用,着眼点在于如何将系统的Client插入到尽可能多的公共平台、桌面系统中去,同时借助这个Case Study,我将着重讲解在Web服务设计的时候,如何有效地使用XML Schema设计系统中使用的XML数据模式。 参考资料
作者简介
|
||
关键词:
|
相关文章 |