Web Service Case Study:软件反馈跟踪平台
|
AMTeam.org WebServiceCaseStudy:软件反馈跟踪平台
柴晓路(fennivel@uddi-china.org)
ChiefSystemArchitect
2002年3月26日在我以前的developerWorks的专栏文章中,我已经系统地介绍了各种Web服务技术标准及其细节,然而Web服务并不仅仅是一种技术,更是一种应用框架,一种系统架构的方式,和一种应用的思想。所以从本次开始的"WebServiceCaseStudy"文章系列中,我将在每一篇文章中使用一个具体的应用实例,通过应用分析来详细阐述使用Web服务技术的好处和优越性,同时从Web服务的角度结合实例介绍各种Web服务技术在具体的项目中应该如何被使用。
本文是先前文章的一个延伸,通过一个软件反馈跟踪平台来考察如何具体设计一个Web服务应用,如何评估Web服务解决方案的适用性等。我将陆续推出这个文章系列,希望大家通过这个系列的文章,能够从实践中掌握Web服务构架。案例背景简介-软件反馈跟踪平台在本系列的第一篇文章中,我们将从软件行业自身的应用开始。我们知道,对于一个软件企业而言,不论是提供软件产品、还是提供软件解决方案,或是承接软件项目,对于用户反馈的获取都是非常重要的,这不仅是优质服务的必要保证,同时也是软件产品、解决方案升级换代的重要依据。在这样的应用背景下,用户反馈不仅仅包括用户对产品的意见,同时也包含软件产品的BUG自动报告,以及一些性能参数的采集等。当然其中的有些是需要客户授权进行的,比如性能参数收集等。首先,我们先来分析一下在这个应用背景下的角色及其对应的行为描述如下:软件公司:软件公司是生产软件、提供软件产品的企业。它对自己的软件产品的质量负有责任,对客户需要提供技术支持,同时在获取足够的反馈的前提下,需要即时地对自己的软件产品进行升级,或者开发新的软件产品,因此它需要即时地获取有关其提供的软件产品的各种反馈信息。客户:使用、消费软件产品的商业实体或个人。为了更好地接收软件公司的服务,它需要提供必要的和充分的软件使用反馈,反馈包括由客户的技术人员以描述方式提供,或通过软件产品的某种日志接口导出文件并提供给软件公司。通过对以上角色及其行为的分析,我们认为在最终的实现系统中概要层次上的对象主要就有这样几种:反馈信息分类目录,反馈信息分类目录由软件公司维护,所有的反馈信息都位于反馈信息分类目录的不同结点下分类组织。反馈信息,由客户或运行中的软件产品产生,经过反馈信息分类目录归类组织,由软件公司使用。用户,用户分两类,一类是客户用户(包括客户消费的软件产品中可能用到的用户),一类是软件公司用户,分别用于处理两类事务:软件公司用户的目录管理信息查询,以及客户用户的信息提交。系统构架概述Figure1.系统结构概述 应该说,这个系统还是比较简单的。其中,CatalogService管理所有各种类型的反馈信息,AuthenticationService负责用户登录和权限认证。CatalogService和AuthenticationService组成了服务平台。这个服务平台有两个标准客户端:UserClientModule是为使用软件的客户所准备的,主要是提交反馈信息用途,而AdministratorClientModule则是软件公司的管理模块,功能包括管理配置反馈信息目录(Catalog),查询浏览反馈信息目录以及进行用户管理。下面我花一点篇幅稍详细解析一下框架中的两个个主要服务:CatalogService和AuthenticationService。CatalogService根据前面的应用背景描述,CatalogService应当具备如下功能:类别(Category)管理,包括增加一个Category、删除一个Category、修改一个Category等;其中Category不光用于表示软件产品的分类,同时软件产品也将以叶子类别结点的形式出现。反馈数据管理,包括增加一则反馈数据、删除一个反馈数据、修改一个反馈数据、移动一个反馈数据(从一个Category下移动到另一个Category下)等;数据交换,包括单个类别下所有反馈数据的导入导出(ImportExport),单个反馈数据的导入导出,整个类别树的导入导出等;数据备份,整个目录下所有反馈数据的备份恢复等。AuthenticationService而AuthenticationService则相对简单,它的功能可描述如下:用户登录注销,完成用户登录服务和从服务注销的功能,这个功能是由用户使用的(包括管理员用户和一般用户)。权限审核,用户权限审核,为除AuthenticationService之外的服务提供权限审核功能。系统间的交互我们将以上功能各个模块的功能描述加以总结,去除内部实现的部分,我们可以发现在Internet上需要传输的数据也就是两类:目录和反馈数据。目录由多个目录结点组成,目录包含一个根结点,每个目录结点(除根结点以外)有一个父目录结点,一个目录结点可以包含多个子结点。一般而言目录的叶子结点是某个软件产品,而中间结点则是表示软件产品的分类。反馈数据总是从属于一个目录结点,一般来说主要的反馈数据,包括BUG报告,性能数据以及描述性反馈都是属于叶子结点,也就是软件产品的,不过在非叶子结点下也会包含一些描述性反馈数据。自具体定义中,我们需要先定义一个抽象反馈信息类,然后以这个类为基类,派生出BUG报告反馈类、性能数据反馈类以及描述性反馈类等。总之,在我们这个应用环境下,有两种数据是我们要主要关心的:目录和反馈数据。在系统之间交互数据是交互的第一层次:数据交换,然而对于Web服务而言,光光有数据交换是不够的,应当提供更高层次:服务集成的支持。因此,交互的内容不光包括互相交互的数据,同时应当包含对数据的操作(比如数据请求,数据添加,数据更新等等)。这些往往会对应于服务端的一个处理模块。无论是对数据的操作,还是数据本身,为了在系统与系统之间进行交互,尤其是异构平台之间,我们需要将所有的操作(服务调用)和操作的数据(服务调用的参数和返回值)进行规范化的描述,形成规范文档后发布以供所有需要参与互操作的系统共同遵守。为什么使用Web服务解决方案?我们知道,对于一个软件产品的信息采集系统而言,以下两个特性是不可缺少的:使用的方便性,我们知道在软件产品中的反馈数据采集模块,尤其是那些Bug报告模块或者是性能数据收集模块,需要嵌入在软件产品的代码中的,在嵌入的时候应当尽可能地简单和统一,这样才能保障软件产品的代码的可维护性。客户端模块的跨平台性,对于一个公司而言,它的软件产品可能是会跨越多个平台的,同时开发环境也不尽相同,如何能让客户端在各种平台下的软件产品中被嵌入,是一个非常重要的问题。同时,跨平台性这个特性还能使得这个平台能够拓展到ASP(ApplicationServiceProvider)的模式下,为多个软件企业服务,从而成为公共的网络服务平台。基于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"sAPI:这是类似传统含义的API定义,不过承载的介质是SOAPMessage,也就是说Programmer"sAPI是一组SOAPAPI,不同的API用于完成不同的服务调用,在这部分中需要定义不同的SOAPAPI的行为和实现的调用响应的功能描述;DataStructure:这部分定义了在SOAP消息中传输的参数数据和响应数据的XMLSchema,这部分为每个API补充的消息格式,同时为最终的API处理提供了数据层解析包装的规范。API设计原则简单性,由于这是一个对于公共开放的Web服务,它的API的设计首先应当是简单的,要被大量用户接受,要获得比较好的应用,那么API必须简单,没有哪个复杂难用的API会得到大家的广泛接受的。可扩展性,作为更新频率较高,开放性较强的Web服务,其API应当具有很好的向后扩展性,当应内部需求的改变或外部需求的改变的需要时,API将根据新的逻辑发生变化,此时不应当将API从根本上推翻重建,而应当具备增量式的可扩展的能力。高效性,API应该在坚持简单性的前提下,兼顾高效性,当某些组合操作应用地非常频繁的时候,我们应当为这样的组合操作调用设计一个只需一次交互的单一入口调用,这样能够提升外部应用的效率,同时减轻Web服务的负载。完备性,所谓完备性就是说整个API要覆盖所有需要对外公开的功能,这相对而言是最好实现的目标,只要设计阶段考虑得完备,就能达到完备性的要求。而且万一发现不完备的情况,修正起来也是相对容易的。DataStructure设计本系统的数据主要有两类:目录和反馈数据。首先,我们先来给出相对简单的目录XML数据结构定义。Category的具体描述格式:categorycategoryKey="…"parentCategoryKey="…" name……name description……description categorycategoryKey="…"parentCategoryKey="…"* category这是一个缩略版的目录数据格式定义,我们可以看到一个category可以包括0个或多个category,同时每个category具有两个子元素name和description分别描述这个类别结点的名称和描述,category还包含两个属性:categoryKey和parentCategoryKey,分别表示一个类别结点的UUID(唯一标识符)及其父类别结点的UUID。由一个根类别结点开始及其包含的所有子孙类别结点一起组成了我们的目录数据。在给出了目录的数据之后,我们再来定义反馈数据的数据结构:feedbackfeedbackKey="…"parentCategoryKey="…"type="…" name……name description……description dataBag fieldname="[fieldname]"……field* dataBag feedback其中,feedback元素的属性feedbackKey和parentCategoryKey分别表示当前feedback元素的UUID以及其所在类别结点的UUID。Name和description子元素与前面的含义是类似的。下面我们来介绍一下dataBag这个子元素,这是一个字段值的聚集,一个dataBag可以包含0个或多个字段。每个字段都是以fieldname="……"……field的形式出现的,可以想象,采用了诸如dataBag这样的数据聚集的描述方式,将使得这个系统的适用性非常强,可以适应大多数用户的特殊需求,用户可以在其中自由地定义字段并为字段赋上相关的字段值。对于系统的适应性和可扩展性,这样的数据描述方式是非常有效的,然而如此自由的描述方式,对于系统平台去检验这些字段的合法性(比如字段名有没有写错,字段值的类型是否正确等)却是非常不利的。鉴于合法性校验的考虑,我们认为,可以引入dataBagTemplate的概念,所谓dataBagTemplate就是一种预先定义好的在某个特定领域应用中使用的反馈信息数据的模版,这个模版定义了所有合法的字段,包括字段名称及其字段值类型。下面我们给出一个dataBagTemplate的例子:dataBagTemplatetemplateKey="…" fieldname="Applicationo"type="xs:string" fieldname="Module"type="xs:string" fieldname="Exception"type="xs:integer" fieldname="Description"type="xs:string" dataBagTemplate这个dataBagTemplate定义了三个字段,Application(应用名称)、Module(模块名称)、Exception(异常编号,注意这是整型字段)以及Description(错误描述),这个Template用于定义一般的错误报告的模版结构。由于使用了dataBagTemplate,我们需要更新反馈数据的数据结构:feedbackfeedbackKey="…"parentCategoryKey="…"type="…" name……name description……description dataBagtemplateKey="……" fieldname="[fieldname]"……field* dataBag feedback
| |