IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope: Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  Grid computing  >

OGSA-DAI 揭密,第 1 部分: 架构与数据库访问

开放网格服务架构 - 数据访问与集成

developerWorks
文档选项

未显示需要 JavaScript 的文档选项


级别: 初级

Neil Hardman (nhardman@uk.ibm.com), 软件工程师
Andrew Borley (borley@uk.ibm.com), IT 咨询专家
James Magowan (magowan@uk.ibm.com), IT 咨询专家

2004 年 2 月 01 日

本文探讨了开放网格服务架构 - 数据访问与集成(Open Grid Services Architecture - Data Access and Integration,OGSA-DAI)的内部机制,解释了这些机制之间,以及与用户应用程序之间的交互方式。这篇文章揭示了一些鲜为人知的特性,使您能够更好地理解 OGSA-DAI 的潜能。

简介


OGSA-DAI 是一种中间件,其设计目标是提供一种简便的方法,在网格环境中实现数据的访问和集成。这个项目参与的成员很多,您可以从 OSA-DAI 的 Web 站点上找到参与者的完整名单,网址在 http://www.ogsadai.org.uk。不过开发工作主要是在苏格兰的 EPCC以及英格兰的 IBM HursleyPark完成的。

我们使用的是来自 Globus Project 的 OGSA 参考实现,即 Globus Toolkit 3(GT3)。GT3 是基于 Java 的网格应用程序框架,它提供了一种环境,供网格应用程序注册其服务,维护其状态,并与其他应用程序进行通信。

在很多“Big Science”项目中,人们都需要一个中间件层来访问大量的并且基本上是静态的数据库,这就催生了 OGSA-DAI。OGSA-DAI的结构是一种工具箱,它具有一些扩展点,可供开发人员扩展其功能,以适应自身的特定需求。数据库管理系统便是一个很好的例子。我们目前支持的有关系数据库(通过 JDBC)和 XML 数据库(通过 XMLDB)。而当必要的时候,应用程序的开发人员也可以开发他们自己的数据库支持。

本文尝试向大家介绍 OGSA-DAI 中若干很少发布的片段,比如它的内部架构,以及其他一些用户可以访问到的更为公开的领域。当您阅读完本文之后,您可以更好地理解 OGSA-DAI 的工作原理,以及它为什么要设计成现在这种工作方式。我们也希望您能从本文中获得足够的信心,开始试用其中讨论到的一些工具,也可以通过扩展点来对平台进行扩展(OGSA-DAI 项目欢迎大家提供帮助)。





回页首


注册器、工厂、网格数据服务实例和执行文档


我们假设您对 OGSA 中的注册器、工厂、实例等概念已经很熟悉了。下面列出本文中用到的其他一些术语:

  • 网格数据服务(Grid Data Service,GDS)。通过这项服务可以访问某个数据资源(关系数据库或 XML 数据库,甚至是存储在普通文件中的数据)。
  • 工厂(Factory)。这项服务用于创建一个 GDS 实例,来访问特定的数据资源。
  • 服务组注册器(Service group registry)。这项服务用于找到您所需要的 GDS,也可以通过它找到用于创建所需 GDS 的工厂。
  • 执行 文档(Perform document)。一种 XML 格式的文档,用于定义要在 GDS 上执行的活动,如一条 SQL 查询,然后再定义如何将查询的结果传送给第三方。

我们也假定您对 OGSA-DAI 比较熟悉,至少已经下载安装,也用它访问过数据资源了。如果是这样的话,您就能够了解在设置工厂时进行的主要配置步骤。我们将工厂配置为实现下面的功能:

  • 用特定的网格数据服务组注册器对其自身进行注册。
  • 将自身连接到底层的数据资源上,其中包括下面的内容:
    • 可用的活动、模式以及实现类。
    • 资源的元数据,可以有两种形式:静态(写在配置文件中)或通过实现类 MetaDataExtractor 获取。
    • 驱动信息,其中包括数据资源的实现类,JDBC 驱动(或与之等价的对象),以及资源的 URI。

扩展点

在本文中,我们会谈到很多扩展点。要告诉 OGSA-DAI 使用您新创建的类,请您使用配置文件。

现在,我们已经配置并启动了 OGSA-DAI,那么当我们使用客户机的时候会发生什么事情呢?一旦 OGSA-DAI 启动,工厂就随之启动,然后,用注册器将其注册,并能通过配置文件中的静态信息和配置文件提供的 MetaDataExtractor 类能访问到服务数据。工厂还将根据数据资源创建实现对象。然后,客户机确定在注册器中列出的众多工厂中应该使用哪一个。

一旦选定合适的工厂,客户机就请求工厂创建一个 GDS 实例,以访问特定的数据资源。现在,GDS已经准备好了,可以接收执行文档,运行数据库查询,传输查询结果,和传送数据。





回页首


引擎架构


设定引擎(我们就把它叫做引擎)是 OGSA-DAI的核心。它将执行文档发送到 GDS 上时 OGSA-DAI中发生的每一件事情都编排在一起。让我们看看这个引擎到底做了哪些工作,然后再深入探讨其工作原理。

当 GDS创建出来时,系统根据一些上下文信息和 GDS的配置(最初是从工厂的配置中来的)将引擎实例化。这个上下文信息包括:

  • 活动及其对应的 XML 模式与实现类的清单。
  • 角色映射清单,以及角色映射的详细信息。
  • 数据资源实现与数据资源有关的细节信息。

特异名称(Distinguished name,DN)

特异名称(DN)是一种符号,用于在 X509 凭证中唯一标识某个特定用户。典型的 DN 由用户名、组织名、国名组成,还可能包含其他一些附加信息。如: /c=UK/o=IBM/ou=HS&T/l=Winchester/cn=Neil Hardman .

  • c=UK :国名
  • o=IBM :组织名
  • ou=HS&T :组织单位
  • l=Winchester :位置
  • cn=Neil Hardman :一般的姓名

当 GDS 接收到一份执行文件时,它将这份文档与一些上下文信息(如从用户凭证中获取的 DN)一起传送到引擎中。然后,引擎对执行文档依次进行如下的处理:

  • 解析并验证执行文档。
  • 识别执行文档中指定的活动。
  • 创建这些活动的实现实例。
  • 创建这些活动之间管道的实例。
  • 创建活动处理器的实例并启动。
  • 用处理器处理这些活动,将产生的数据通过管道传递。
  • 将输出信息结合在一起,形成一份响应文档。
  • 将这份响应文档返回给 GDS,由后者返回客户机。
  • 在执行文档运行过程当中,您可以随时通过 OGSI 的服务数据获取活动的状态

我们设计的这个引擎可以一次处理一份执行文档。如果在一份执行文档运行期间又提交了另一份,那么就会返回一个 UserException 。当然了,这并不会妨碍您从一个工厂创建多个 GDS 实例,其中的每一个 GDS 实例都具有它自己的引擎,因此您可以同时运行多份执行文档。

如果画一张图来表示,我们得到的就是图 1所示的一些类:


图 1. 引擎架构
引擎架构

现在,根据上面所说的,我们要研究一下执行文档的详细运行过程。

设置


当执行文档发送到 GDS 上之后,GDS将其传给引擎,引擎再用引擎上下文中的活动模式对执行文档中的内容进行验证。然后,用执行文档中的相关数据和上下文中的信息创建活动实例(例如, sqlQueryStatement 活动需要角色映射器以及数据资源的实现信息来连接数据库,并执行查询)。引擎负责计算出每一个活动的输入和输出信息应该如何链接在一起,然后在这些活动之间设置缺省的管道。

一旦出现未链接的活动输出,引擎就创建 deliverToResponse 活动,这样,缺省的方式就是,由活动所产生的任何数据都同时返回到响应文档中。下一步,引擎创建活动处理器,负责管理活动的调用方式,最终,上下文信息被提供给活动,这样就可以选择非缺省的活动处理器或管道(如,inputStream活动使用的是 SynchronizedGrowablePipe )。

同步还是异步?


现在,所有的东西都设置好了,数据可以开始流动。如果引擎没有使用任何一个 deliverToResponse 活动(比如说,如果执行文档定义所有的数据都通过 deliverToURL 活动传递到第三方,如某台 FTP服务器),那么引擎就会启动一个新的线程,异步执行这些活动,然后将响应文档返回客户机。在这种情况下,响应文档仅仅包含一些简单的信息,用来指示执行文档就要开始执行了。否则,执行过程会立即开始,而且直到所有的活动都将其状态设置为Complete,或出错时,才会返回一个响应。


在 OGSA-DAI 中,基本的数据单元就是块(block)。块是一些单独的Java对象(或是单独的对象或基本类型构成的数组)也就是说,活动可以将任何Java对象放置在其输出中,供后续活动消费,根据数据流中前面活动的情况,也可以接收一系列的输入块。在活动之间不存在类型检查,这就意味着活动需要对它们从输入中接收到的数据进行检查,看是否是预期的类型。否则,将抛出 ClassCastException

在实践中,与 OGSA-DAI一起提供的几乎所有活动都用 String 对象作为其输出类型,在本系列的第二部分中会提到几个例外的情况。

数据是如何流动的


数据在系统中的流动是通过一系列活动处理器进行协调的,每一个活动处理器管理数据链中的一个活动。这些活动本身通过管道链接在一起,可以提供活动内的数据通路。除了第一个和最后一个之外的每一个活动,都具有一个输入管道和一个输出管道。输出传递活动(如缺省的 deliverToResponse ,以及显式使用的 deliverToURL 活动,或是其他类似活动)负责通过使用一个特殊的处理器(即 RunAheadHandler )创建数据流的实例。处理器将在本文的第二部分中详细介绍。下面是数据流的情况:

  1. 输出活动处理器调用其活动的 processBlock 方法。
  2. 活动调用附加在其上的输入管道上的 next 方法,提供一个供处理的数据块。
  3. 如果在输入管道中没有数据块,那么该管道将调用给他提供数据的那个活动的处理器。
  4. 处理器再次调用它所管理的活动的 processBlock 方法。对于活动链中的每一个活动,都重复步骤 2、3、4。
  5. 这个过程一直持续到提供最初数据源的那个活动上,这个活动可能是数据库查询的结果,也可能是要从另一个系统传送数据过来。
  6. 当活动已经处理过,或是获取了一定的数据,它就会将这些数据块用 put 方法放置在其输出管道中。

最终,所有的数据都流过了整个系统,每一个活动(由最初的数据源开始启动)都将调用其附加的输出管道上的 close 方法。当后续活动试图从该管道拉数据的时候,将抛出 NoSuchElementException 异常,这就意味着已经没有数据了。

错误处理


如果在这个过程中产生一些错误,那么失败活动的状态就被置为Error(即可以在活动中显式设置,也可以通过处理器中实现的异常处理机制进行设置)。引擎会监视所有活动的状态,如果它发现了出错状态,就会中断处理过程,然后将状态和所有的错误消息都返回到响应文档中。如果活动是异步执行的,那么过程将停止,客户机可以通过查询 GDS 的引擎状态(已经发布为 OGSI 服务数据)来发现这个错误。

清除


如果出现了错误,或是所有的活动状态都设置为 Complete,这时引擎就知道处理过程已经结束,可以将其清除了。如果系统使用了 deliverToResponse 活动,那么就生成响应文档,发送回客户机。然后,系统将所有的数据丢弃,这样引擎就可以处理到达的下一个执行文档了。

一个实例


清单 1 中的实例处理一份发送到 GDS 的执行文档,这份执行文档用 sqlQueryStatement 活动对数据库进行查询。查询的结果将用 WebRowSet XML 格式表示(WebRowSet 将在本文的第二部分中详细讨论)。接下来,对那个 WebRowSet XML 文档应用一个 XSLT 样式表,用 xslTransform 活动将查询结果转换成一组由逗号分割开的变量。最后,转换的结果通过缺省的 deliverToResponse 活动传递回客户机,因为 xslTransform 活动的输出(本例中的名字叫做“ transformedData ”)没有链接到任何其他的活动上。

清单 1. 执行文档实例
<?xml version="1.0" encoding="UTF-8"?>

<gridDataServicePerform xmlns="....">

 

  <!-- sqlQueryStatement Activity performs the query -->

  <<span class="boldcode">sqlQueryStatement</span> name="statement">

    <expression>

      select * from littleblackbook where id=100

    </expression>

    <webRowSetStream name="<span class="boldcode">statementOutput</span>"/>

  </sqlQueryStatement>  

      

  <!-- xslTransform Activity transforms the results 

       of the query using the In-Line XSLT -->

  <<span class="boldcode">xslTransform</span> name="transform">

    <inputXSLT>

      <!-- This is an XSL-Transform that transforms the results

           of an SQL query into comma separated variables -->

      <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

        <xsl:output method="text" indent="yes"/>

        <xsl:template match="/">

          <xsl:for-each select="RowSet/data/row/col">

            <xsl:value-of select="."/> ,

          </xsl:for-each>      

        </xsl:template>

      </xsl:stylesheet>    

    </inputXSLT>

    <inputXML from="<span class="boldcode">statementOutput</span>"/>

    <output name="<span class="boldcode">transformedData</span>"/>

  </xslTransform>



</gridDataServicePerform>
                

当引擎接收到这份文档,并验证完毕之后,它将两个经过命名的活动及与之关联的处理器实例化。然后在活动之间创建管道。这时,引擎发现 sqlQueryStatement 活动的输出链接到 xslTransform 活动(名为“ statementOutput ”)的输入。引擎还意识到 xslTransform 活动具有悬空的输出(名为“ transformedData ”),因此就实例化一个 deliverToResponse 活动及其处理器和管道。

因为 deliverToResponse 是一个输出活动,因此与之相关的处理器设置为 RunAheadHandler 。其他处理器关联的是缺省的 CallThroughPipeSimpleHandlerRunAheadHandler 负责启动整个过程,数据流从 sqlQueryStatement 活动所查询的数据库,经过 xslTransform 活动,进入 deliverToResponse 活动,在这里,数据块被合并到响应文档中,返回客户机。如清单 2 所示。

清单 2.响应文档实例


<gridDataServiceResponse xmlns="http://ogsadai.org.uk/namespaces/2003/07/gds/types">

  <result name="statement" status="COMPLETE"/>

  <result name="transform" status="COMPLETE"/>

  <result name="transformedData" status="COMPLETE">

    <![CDATA[101 , 

             Andrew Borley , 

             754 Palansuriya Crescent, 

             Edinburgh , 

             0915084840 , ]]>

  </result>

</gridDataServiceResponse>
                

为了重用我们前面画的那幅图,现在的架构看起来应该是图2 的样子。



图 2.上例中的引擎架构
例子引擎架构




回页首


数据库访问


我们受已有技术的影响很深,也不想只是为了访问数据库就发明新的解决方案。无论从哪个角度看,OGSA-DAI的访问方式都应该和在网格环境之外访问数据库的方式尽可能相似。在这样的方式下,我们可以看到将数据库加入网格所带来的所有好处,也几乎没有花费什么代价来重新编写代码,更没有重新构造整个解决方案的架构。本节的UML 图尚未完成,仅仅是方便解释问题。

现在,我们已经有了一个执行文档,并将其发送到引擎中,引擎为我们构造了一串活动,并用管道将这些活动连接起来。那么,这些活动该如何与 DBMS 交互,来访问数据库中的数据呢?让我们一起揭示事实的真相。

不论您使用的查询语言是 XPath、XUpdate、还是 SQL,所使用的类集合以及这些类之间的关系都比较相似。所以,我们在这里只考虑通过 JDBC 连接 DBMS 执行 SQL 的情况,但是我们也会指出扩展点。这里所举的例子应该能够引导您编写出在 XMLDB 上用 XPath、XUpdate 访问 XML DBMS 的代码,并告诉您如何编写自己的活动,以便与后端的数据资源进行交互。

我们要讨论的类如下所示:

  • uk.org.ogsadai.porttype.gds.activity.sql
    • SQLActivity
    • RelationalResourceManagementActivity
    • SQLBulkLoadRowSetActivity
    • SQLQueryStatementActivity
    • SQLStoredProcedureActivity
    • SQLUpdateStatementActivity
  • uk.org.ogsadai.porttype.gds.dataresource
    • DatabaseMetaDataExtractor
    • DataResourceImplementation
    • JDBCDataResource
    • MetaDataExtractor
    • SimpleJDBCDataResourceImplementation
    • SimpleJDBCMetaDataExtractor

GDS是专门为访问特定的数据资源设计的,这种数据资源从物理上讲存在相互独立的任意GDS。因此这就意味着代表数据资源的对象应该与工厂紧密相关。在与特定数据交互的过程中,会存在一个对象,用来在每个工厂的基础上管理或缓存连接。GDS并不是孤立地管理它与数据库的交互。与此相反,每一个 GDS都使用工厂类提供的 DataResourceImplementation来管理连接。同一个工厂生成的多个访问同一数据资源的 GDS都用同一个 DataResourceImplementation 对象来处理连接。

所有这一切,意味着上面那些类可以划分为三组:

  • DataResourceImplementation 类,负责处理 JDBC 连接、驱动程序、角色映射以及访问 DBMS。
  • 活动类,负责接受 SQL,并用 JDBC 连接将这个 SQL 传递给 DBMS,然后对返回的结果进行格式化。
  • MetaDataExtractor 类,发布与 DataResource 有关的服务数据,以便在注册器或工厂服务中选择正确的数据资源。

DataResourceImplementation类


JDBCDataResource getDriverClass 方法

在开发过程中,我们发现各种不同的数据库驱动中都存在一些很有意思的属性。我们创建了一个方法,称为 getDriverClass ,用于找到驱动的类,并允许我们正确切换驱动的各种行为。


图 3.展示 DataResourceImplementations 的 UML 模型
数据资源实现

DataResourceImplementation类掌管连接的处理和角色映射。前面提到,它们在配置文件中与数据资源相匹配,并为希望自己编写 DataResourceImplementation 的人们提供扩展点。活动类应该仅仅依赖相关接口中的方法。

Connection_Pooling_sidebar"> 连接池
尽管OGSA-DAI 架构可以支持连接池,但是已经交付的代码中包含的 DataResourceImplementation 类中不包含连接池的实现。您可以根据上面的图 3 所示实现连接池。

如果您想要创建 MyPoolingJDBCDataResourceImplementation ,那么有两种方法可供选择:

  • 我们可以从已经写好的 SimpleJDBCDataResourceImplementation 类继承,并覆盖 getConnectionreturnConnection 方法。
  • 我们可以从抽象的 DataResourceImplementation 类继承,通过实现其中的 JDBCDataResource 接口来创建自己的类。重要的是 JDBCDataResource 接口。SQL 活动正是用这个接口获取并返回数据库连接的。

一旦您编写好这个新类,剩下的唯一问题就是替换 OGSA-DAI 配置文件,让某个数据资源使用这个 MyPoolingJDBCDataResourceImplementation 。(当然了,OGSA-DAI 项目非常欢迎您提供关于实现连接池的反馈信息和代码。)

对关系型访问而言, SQLActivity (下面会谈到)将通过 JDBCDataResourcegetConnection 方法获取一个 JDBC连接。实现的方法是将凭证作为参数传递。 DataResourceImplementation 类提供的 mapCertificate 方法可以用于将这些凭证映射为数据库角色(根据角色映射器获取用户名和口令)。现在,我们已经用 mapCertificate 方法获得了用户 ID和口令,也从配置文件中获得了 URI,必要的条件都已经具备,可以创建JDBC 连接了。

目前,编写自己的 XMLDB DataResourceImplementation 只有一种方法,就是对 SimpleXMLDataResourceImplementation 进行扩展,因为还没有定义 XMLDBResource 接口。

活动类



图 4.展示 SQL 活动的 UML 模型
SQL 活动

所有其他的 SQL 活动都要扩展抽象的 SQLActivity 类。这个抽象类中包含受保护的方法,我们可以用这些方法从活动中获取输入和输出信息。在这样的环境中,输入可以是值(由执行文档提供),也可以是引用(从其他活动中流入),目前还可以作为 SQL 参数、SQL 表达式以及存储过程名称等的响应。输出当然是 ResultSet,根据活动的类型不同,也可能是被更新的记录数目。

允许从流输入数据,特别是允许从同一个流获得多个输入,这种情况可能导致无法预计的结果。流中的值出现的顺序变得很重要,因为活动读取流中数据的顺序要与输入数据在活动元素中的声明顺序保持一致。

在元素顺序的这个问题上有一种例外情况,即,命令(SQL 表达式或存储过程名)。命令必须总是流中的第一个项。提出这样要求的原因有两点:

  • SQL 活动元素只允许在 SQLParameters 之后和结果流之前声明命令。
  • 直到发现了命令之后, SQLParameters 才是有意义的,也才是有用的。

这些到底是什么意思呢?图 5 给出了解释。


图 5.从单一流获得多项输入
SQL 活动流例子

结果就是,您不必仅仅为了在 SQL 活动使用数据项之前改变它们在流中出现的顺序而设置一个转换程序。这样,如果您使用的数据项在流中出现的顺序是参数 1、参数 3、参数 2、参数 1、参数 3、参数 2......,那么,只要您保证在 SQL 活动中用相同的顺序声明 SQLParameters (即 1、3、2),那么您就可以直接将这个流传递给 SQL 活动了。

设置好活动之后,我们就知道需要什么样的输入信息,也知道输出信息将去往何处。在整个处理过程中,我们都将实施跟踪,看连接是否保持打开状态。这种跟踪机制使我们能够在操作完成的时候将连接返回,并在适当的场合重新利用这个连接(比如在prepared statement 中)。

SQL 活动中的处理可以分为三个阶段:

  • startProcessing 获得连接,设置下一条语句。根据活动的不同,连接可能会设置为只读。
  • getResult 从输出流中获得下一个数据块。由于执行语句的结果可能是 ResultSet,这样就对应多个数据块,因此调用这个方法并不总会执行一条语句(当然了,第一次调用的时候肯定会执行语句的)。
  • endProcessing 结束输出流,并返回连接。然而,如果活动对应于 prepared statement,我们将选择保持连接,并允许重用该活动。

XMLDB 活动几乎与此相同,它们是通过扩展 XMLDBactivity 类以及一个扩展包( uk.org.ogsadai.porttype.gds.activity.xmldb.commands )实现的。这个包中包含的代码可以使抽象的 XMLDBCommandActivity 变为可扩展的,并提供不同的 XMLDB命令。 xmlCollectionManagementxmlResourceManagement 活动是从 XMLDBCommandActivity 继承得来。

您可以开发新的活动来满足 Oracle 之类特定 DBMS的需求。

MetaDataExtractor类



图 6.用 UML 模型展示 MetaDataExtractor
Meta Data Extractor

您该如何发现 GDS 的元数据呢?比如说,您该如何决定其中存在哪个表或字段呢?

我们假设您理解了网格服务和 Globus Toolkit 3,因此,答案当然就是与 GDS 相关的服务数据。我们不想在 DBMS 之外保存与该数据库有关的字段的服务数据。因此,OGSA-DAI 使用了 GT3 的 ServiceDataValueCallBack 接口,这样就能根据需要,通过 MetaDataExtractor 类来发现这些数据。





回页首


第 2 部分内容简介


OGSA-DAI 揭密的第 2 部分中,我们将对活动处理器、管道以及角色映射等进行十分详细的探讨,还深入介绍如何处理结果。我们甚至还会提供一些代码实例(我们就是喜欢代码!)。



参考资料



作者简介

Neil Hardman

Neil 18 年以来一直是专业的软件开发工程师,在 IBM 工作了 15 年。他曾经开发 IBM 若干关键中间件产品,包括 IBM CICS for OS/2 以及 MQ Series Everyplace。他也花了几年的时间为世界范围内的客户提供中间件服务,最近,他正致力于开发指纹识别系统、Internet 银行,当然也包括网格。Neil 是 OGSA-DAI 项目的开发组长。


Andrew Borley

Andrew 四年以来一直在 IBM 的 Hursley Services and Technology 部门从事新技术的用户推广工作。他从 2001 年以来一直参与开发 WebSphere MQ Everyplace 和 Web 服务项目。最近,他致力于网格计算项目,特别是 OGSA-DAI,在其中,他领导着数据传送方面的开发,同时也担任 IBM 的首席测试人员。


James Magowan

James 在 IBM 致力于前沿用户项目的工作已经有六年了。他一直从事高性能计算和大型 RS/6000 SP 系列的基准测试、安装、调优、疑难解答等工作,而且在 IBM 制定 Linux 战略之前就从事 Linux 群集的研究。从 2001 年 1 月起,他开始研究网格计算,参与的工作有 European DataGrid 和 OGSA-DAI,同时为 Global Grid Forum 做出了很多贡献,还领导其中的两个工作组。在 OGSA-DAI 中,他领导了数据库访问的开发,还在架构组中做了一些工作。2003 年 10 月,他向 GGF 9 提交了关系数据服务规范。




对本文的评价

太差! (1)
需提高 (2)
一般;尚可 (3)
好文章 (4)
真棒!(5)

建议?







回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款