Globus toolkit3.0

 

本文通过样本代码分三个部分来介绍 Globus 软件体系结构和编程模型:

1.        该工具箱的高级体系结构

2.        编程模型和工具

3.        通过使用自顶向下设计方法从 Web 服务描述语言(Web Services Description LanguageWSDL)开始创建简单的股票报价(Stock Quote网格服务。

 

 

GT3 软件体系结构模型


要讨论 Globus 工具箱中使用的软件框架,先要了解一下服务器端框架组件。

服务器端框架


1
用图示说明了服务器端的组件。

1. GT3 软件框架:服务器端体系结构组件

Globus GT3 alpha 3 OGSI 规范版本


Globus GT3 alpha 3
工具箱基于由 GGF OGSI WG 2003 2 19 日发布的 OGSI 草案。从那以后,对该规范进行了较大的更改。以前有一篇文章讨论了 OGSI 新规范的详细信息(请参阅 参考资料)。

1所示,服务器端框架的主要体系结构组件包括:

  • Web 服务引擎。该引擎由 Apache AXIS 框架软件提供,用于处理一般的 Web 服务行为、SOAP 消息处理、JAX-RPC 处理程序处理和 Web 服务配置。
  • Globus 容器框架。GT3 提供了一个容器,它通过唯一的实例句柄、实例资源库和生命周期管理(包括服务激活/钝化和软状态管理)来管理有状态的 Web 服务。

枢轴处理程序


枢轴处理程序负责创建 Web 服务实例并调用对服务的操作。根据 SQAP 消息的样式(文档/rpc),可以使用不同类型的处理程序。GT3 使用包装的样式消息传递,这是文档样式消息传递的特例,其中,每个参数都被单独捆绑和处理。由 GT3 提供的 RPCURIProvider AXIS 框架的 JavaProvider 的特例实现,它处理包装的消息并根据服务实例句柄连接容器资源库,查找正确的服务并调用对服务的操作。

目前,GT3 Apache AXIS 用作其 Web 服务引擎,Apache AXIS J2EE Web 容器中运行并提供 SOAP 消息侦听器(AXIS servlet)。它负责 SOAP 请求/响应序列化和反序列化、JAX-RPC 处理程序调用和网格服务配置。如 1 所示,GT3 容器向 AXIS 框架提供枢轴(pivot)处理程序来将请求消息传递给 Globus 容器。

这个容器体系结构用于管理 Web 服务的状态性质以及这些服务的生命周期(回想一下,网格服务实例是有状态的 Web 服务)。一旦服务工厂创建了网格服务实例,框架就为该实例创建唯一的网格服务句柄(GSH),然后向容器资源库注册该实例。该资源库拥有所有有状态的服务实例,由其它框架组件和处理程序与之连接来执行以下服务:

  • 标识服务和调用方法
  • 获取/设置服务特性(如实例 GSH GSR
  • 激活/钝化服务
  • 解析网格服务句柄以引用服务并持久存储它

客户机端框架


2
用图示说明了客户机端的组件。



下一节中的编程模型也参考该图。

2所示,Globus 使用标准的 JAX-RPC 客户机端编程模型和 AXIS 客户机端框架网格服务客户机。除了标准的 JAX-RPC 编程模型外,Globus 还在客户机端上提供许多助手类,以隐藏 OGSI 客户机端编程模型的细节。本文的编程模型一节将讨论这些助手类。

 

 

GT3 软件编程模型


该模型包含了在 GT3 中引入的服务器端和客户机端编程概念。

根据当前的 GT3 编程模型,服务实现了 WSDL 中为该服务定义的所有 portType。例如,如果股票报价服务支持由 OGSI 定义的 StockQuote portType 以及 NotificationSource portType GridService portType,那么该服务实现必须实现所有这些 portType(请参阅 清单 1)。

清单 1. 服务实现该服务所需的所有 portType

 

 

\** This is sample code **\

public class StockQuoteService implements StockPortType,

                              GridServicePortType, NotificationSourcePortType{

}

 

您可以通过委派模型(如下一节中所示)实现 portType 功能,以提供可插入性和可扩展性。下一节还将讨论在 GT3 中提供的用来实现 OGSI 行为的缺省框架类。

 

 

服务器端、基于委派的编程模型


GT3
基于委派的模型有助于为多个接口(portType)继承定义实现模型并有助于支持更容易的代码生成工具。这些委派框架作为服务创建/后创建(postCreate)操作的一部分创建,服务实现必要的 portType。服务负责将方法调用委派给相应的代表。这种灵活性有助于插入新的委派框架实现来获得不同质量的服务需求。

例如,您可以开发一个可伸缩的基于发布-订阅的通知系统,以代替缺省 GT3 框架提供的点对点通知框架。 3 显示了它的这种用法。



3 所示,您可以继承 ServiceSkeleton 实现(它提供缺省的网格服务行为),以通过插件通知委派框架来支持通知行为。另外,StockService 实现了 StockPortType,并通过继承 GT3 中提供的 NotificationServiceSkeleton 实现类实现了 NotificationSourcePortType

通常情况下,委派框架是在对服务实现执行创建/后创建调用期间创建的。如 清单 2 所示,通知服务框架类在 postCreate () 调用中创建了通知委派机制。

清单 2. 通知委派框架的创建

 

 

\** This is sample code **\

public void preCreate(ServiceProperties properties) throws

                                               GridServiceException {

          super.preCreate(properties);

          // creates the notification delegation skeleton

          this.notificationSkeleton = new

               NotificationSourceDelegationSkeleton(this);

          //set this as the default notification engine

          setNotificationEngine(this.notificationSkeleton);

}

 

缺省情况下,该服务实现由委派框架定义的 portType,并转发对实际委派提供程序的调用。 清单 3演示了如何在通知源“subscribe”调用中实现 portType

清单 3. 如何将方法委派从服务移到委派程序

 

 

\** This is sample code **\

public ServiceLocatorType

     subscribe(NotificationSourceSubscriptionType

                        notificationSourceSubscription)

                  throws RemoteException, GridServiceFault {

     return getNotificationEngine().subscribe

                         (notificationSourceSubscription);

}

 

 

GT3 提供的服务器端缺省实现类


作为服务器端框架的一部分,GT3 为网格服务行为(如服务、通知和持久存储框架)提供了许多缺省实现类。 4用图示说明了这些组件。



4 演示了工厂实现的类层次结构及其与 portType 的关系。GT3 核心通过 ServiceSkeleton 类为网格服务 portType 提供缺省实现,该类形成所有网格服务的基础类。通常,高级开发人员可以始终通过继承或替换缺省 ServiceSkeleton 类来插入他们的缺省实现。

GT3 服务数据管理类


服务数据是在 OGSI 规范中引入的核心概念之一,它们用来声明服务的状态,并可以通过已知的接口(findServiceData ?setServiceData)来访问这些状态,而这些接口被声明为 GridService portType 的一部分。Globus GT3 提供了一组丰富的功能来处理服务数据概念。

4 还显示了每个服务包含一个服务数据集,该数据集拥有服务数据对象。服务数据对象是服务数据值的 Java 包装器类。这些包装器包含服务数据的值,或者使用所提供的回调方法来获取值。该类提供了将值转换成 XML DOM 元素的机制(具体化方法),这对于 Query 执行程序很有用。

清单 4 显示了如何构造一个服务数据对象,然后向服务数据集注册它。该示例演示了如何为股票报价网格服务创建服务数据,并通过实现 ServiceDataValueCallback 接口来注册服务数据回调方法。(下面将更详细地讨论该示例。)

清单 4. 创建服务数据以实现服务数据值回调

 

 

\** This is sample code **\

public class StockQuoteService extends NotificationServiceSkeleton

                              implements StockPortType, ServiceDataValueCallback

{

         ServiceData stockData = null;

    StockDataElementType stockElement = null;

 

         public void postCreate(GridContext messageContext) throws

                            GridServiceException {

        super.postCreate(messageContext);

        try {

      // create a service data object with a unique name

          stockData = this.serviceData.create("StockServiceData");

     

                // registering a call back

                stockData.setCallback(this);

 

          stockElement = new StockDataElementType();

          StockDataType stockServiceData = new StockDataType();

     

                stockElement.setStockData(stockServiceData);

          stockData.setValue(stockElement);

 

          // add this service data object to the service data set

                this.serviceData.add(stockData);

       } catch (Exception e) {

       }

   }

   

 

   // This is the service data call back method

   public Object[] getServiceDataValues(QName qname) {

       Object[] ret = super.getServiceDataValues(qname);

          try {

               if (QNameUtils.equalsLocally(qname, stockData.getName())) {

             StockDataType stockServiceData = stockElement.getStockData();

             stockServiceData.setSymbol("ibm");

             stockServiceData.setQuote("93.33");

             // return the changed service values

              return new Object[]{stockServiceData};

             }

        } catch (Exception e) {

        }

        return ret;

     }

}

 

 

现在,客户机可以使用 findServiceData("StockServiceData") 调用来获取服务在运行时创建的服务数据。

 

 

客户机端编程模型


GT3
未在客户机端引入任何新的编程模型,而是使用了由 JAX-RPC .NET 驱动的 Web 服务编程模型。GT3 为客户机端开发人员提供了许多助手类来处理 OGSI 行为,如网格服务句柄(GSH)、网格服务引用(GSR)和开放内容可扩展性模型。句柄解析(GSH 解析)和 GSR 解引用可以使用帮助程序来指出正确的服务实例。

由该工具箱使用的 Java 编程模型概念和 GT3 助手类提供了以下各项:

1.        基于 JAX-RPC 的编程模型包括:

o        基于代理的静态客户机。 注:工具 GWSDL2Java WSDL2Java 创建了这些代理和助手类(定位器)。

o        动态的、基于代理的存根

o        动态调用接口(Dynamic Invocation InterfaceDII)。 注:JAX-RPC 规范(请参阅 参考资料)包含了有关该编程模型的更详细信息。

2.        GT3 提供了定位器类。

5用图示说明了定位器类。



5演示了客户机使用网格服务定位器类的情况。该定位器类使用 GSR HandleHelper 助手类来解析端点绑定。该定位器类为 getPortType() 操作提供下列参数之一:

  • 传递指向服务实例的 URL 端点地址。该功能与标准的 JAX-RPC 定位器类的功能相似。
  • 传递网格服务句柄(GSH)以获取网格服务引用(GSR)。
  • 传递服务终止引用,它是使用工厂的 createService 调用检索的。

客户机端网格服务定位器类


当您使用 GT3 提供的工具 GWSL2Java 来生成网格服务客户机端代理时,它生成两个定位器类。一个名为 "portType name"Locator.class,另一个是 "portTypename"GridLocator.class。建议使用第二个(字符串中包含 Grid 的类),因为它提供更多的帮助程序功能,包括句柄解析、基于 URL 的端点解析以及使用服务终止引用,您可以从 createService 工厂调用获取这些功能。

下一节将介绍 GT3 中的常用工具。

 

 

用于创建客户机端和服务器端构件的 GT3 工具


本节讨论三个工具:GSDL2JavaGenerateBinding GWSDL2Java

GSDL2Java


GSDL2Java
AXIS 提供的 WSDL2Java 工具的特例实现。客户机使用该工具来生成存根、绑定、服务接口、服务器端服务实现框架和客户机定位器类。还可以针对 WSDL 文件使用该工具来完成自顶向下的设计模型。

GenerateBinding


WSDL
文件可分成抽象 portType 表示和具体绑定表示。通常,客户机不需要关心具体绑定的生成。GT3 提供该工具为给定的 portType 生成必要的绑定信息。该工具使用的缺省值是“http”(作为传输绑定协议)、“document”(作为 SOAP 消息样式)和“literal”(作为编码方法)。这种灵活性有助于客户机设计 portType 定义,然后使用该工具来生成必要的绑定。

GWSDL2Java


GWSDL2Java
是一种需要详细讨论的有趣工具。如前一篇文章(请参阅 参考资料)中所讨论的那样,OGSI 允许对 portType 使用多重 portType 继承和开放内容模型。WSDL 1.1 中没有这种灵活性。因此,开发人员可以使用 OGSI 规范提供的 GWSDL 新的名称空间和 GWSDL portType 来创建这一多重继承和 portType 可扩展性模型。

WSDL 1.2 成为标准时,框架和工具将支持这一特性。然而,为了支持当前的 WSDL1.1 工具和框架,必须将多个 OGSI GWSDL portType 转换成基于 WSDL 1.1 的单个 portType 模型。这个工具用于将 GWSDL portType 定义转换成相应的 WSDL 1.1 定义。 6说明了这一转换。



6演示了通过使用 GWSDL2Java 工具如何将 GWSDL(通过具有多重继承的 TopPortType portType 来标识)转换成 WSDL 1.1 的单个 TopPortType portType 模型。

AXIS 部署文件:名称和位置


部署文件的缺省名称是 client-config.wsdd server-config.wsdd,分别用于客户机 Web 服务配置和服务器 Web 服务配置。可以通过向 Java 系统特性变量提供 axis.ServerConfigFile axis.ClientConfigFile 来覆盖这些缺省名称及其位置。例如,要使用名为 my-server-config.wsdd 的配置文件,应该提供 Java 系统特性(Daxis.ServerConfigFile=my-server-config.wsdd)。

作为一名开发人员,您应该知道这种转换的几个重要方面:

  • 新的 WSDL 端口类型被构造成包含 GWSDL 端口类型所具有的相同的操作,并包含扩展端口类型的所有操作。
  • 所有操作消息都要用最初定义的名称空间定义进行限定,这样才不可能发生操作重载。
  • WSDL portType 的名称与旧的 GWSDL portType 的名称相同。
  • 转换将旧的 GWSDL portType 保持为可扩展性元素,但不包含任何操作(可能只有服务数据)。

下一节讨论 GT3 软件所需的部署和配置。

 

 

部署配置


为网格服务和为 AXIS Web 服务提供的部署选项是相同的。AXIS 提供了两个特定于 Web 服务的部署描述符 server-config.wsdd client-config.wsdd。这些部署描述符基于 Web 服务部署描述符(Web Services Deployment DescriptorWSDD)模式。

下一节讨论网格服务所需的基本部署信息。

 

 

部署和配置信息


GT3
使用 AXIS WSDD 来配置 JAX-RPC 处理程序及这些处理程序所需的静态参数。通过设置服务名称、消息处理样式、枢轴处理程序、工厂和服务实例 Java 类信息来部署服务。服务注册静态类型映射信息,该信息是可选的,因为框架在运行时标识类型映射。

我们稍后将创建的样本股票报价网格服务说明了这种部署。部署代码如 清单 5所示,表 1 显示了所使用的参数的详细信息。

清单 5. StockQuote 网格服务的基本部署配置

 

 

\** This is sample code **\

<service name="samples/stock/StockFactoryService"

                                           provider="Handler" style="wrapped" >

         <parameter name="className"

                      value="org.globus.ogsa.impl.samples.stock.StockFactoryImpl"/>

         <parameter name="persistent" value="true"/>

         <parameter name="schemaPath"

                      value="schema/core/factory/factory_service.wsdl"/>

         <parameter name="instanceSchemaPath"

                      value="schema/samples/stock/stock_service.wsdl"/>

             <parameter name="handlerClass"     

                       value="org.globus.ogsa.handlers.RPCURIProvider“/>

         <parameter name="instanceLifecycle" value="persistent"/>

 </service>

 

清单 5 显示了该服务具有唯一的服务名称(服务的远程可访问名称)并使用包装的消息样式。它还显示提供程序是一个处理程序。表 1 列出了这些参数。

1. 部署和配置参数

参数

描述

className

该类实现如股票报价工厂服务之类的服务。

persistent

如果该属性值为真,那么它表示网格服务,该服务在容器启动时启动。

schemaPath

指向工厂的 WSDL 模式。

instanceSchemaPath

如果服务是由工厂创建的,那么它指向该服务的 WSDL 模式。

handlerClass

该处理程序指定在服务器端使用的分派器。AXIS 引擎分派对该分派器(枢轴处理程序)的调用。

instanceClass

要动态创建服务的服务类名。由 DynamicFactoryImpl 使用。该示例中未使用它是因为我们的服务是通过自己的工厂创建的。

instanceLifecycle

如果该特性为真,那么实例被保存到 WSDD 文件。

在介绍了大多数核心体系结构和编程细节之后,下一节将讨论编程细节。

 

 

使用自顶向下方法的网格服务实现样本


清单 6
通过使用自顶向下的设计方法来创建一个简单的股票报价网格服务。它显示了具有一个名为“getQuote”方法的 WSDL 文件的 StockQuote portType 定义,为了清晰起见,我删除了一些内容。

清单 6. StockQuote 服务 portType WSDL 文件

 

 

\** This is sample code **\

<definitions >

<types>

<xsd:schema >

      <xsd:complexType name="SymbolType">

         <xsd:sequence>

             <xsd:element name="symbol" type="xsd:string"/>

         </xsd:sequence>

    </xsd:complexType>

    <xsd:complexType name="QuoteType">

 

         <xsd:sequence>

             <xsd:element name="quote" type="xsd:float"/>

         </xsd:sequence>

    </xsd:complexType>

    <xsd:element name="getQuote" type="tns:SymbolType"/>

    <xsd:element name="getQuoteResponse" type="tns:QuoteType"/>

   

    <xsd:complexType name="StockDataElementType">

      <xsd:sequence>

        <xsd:element name="stockData" type="tns:StockDataType"/>

      </xsd:sequence>

    </xsd:complexType>

    <xsd:complexType name="StockDataType">

      <xsd:sequence>

         <xsd:element name="symbol" type="xsd:string"/>

         <xsd:element name="quote" type="xsd:float"/>

      </xsd:sequence>

    </xsd:complexType>

  </xsd:schema>

</types>

 

<message name="SymbolMessage">

   <part name="parameter" element="tns:getQuote"/>

</message>

<message name="QuoteMessage">

   <part name="parameter" element="tns:getQuoteResponse"/>

</message>

 

<portType name="StockPortType">

    <operation name="getQuote">

       <input message="tns:SymbolMessage"/>

       <output message="tns:QuoteMessage"/>

    </operation>

</portType>

 

<gsdl:serviceDataDescription name="StockDataElement"

                             <element="tns:StockDataType"

                             <minOccurs="1"

                             <maxOccurs="unbounded"

                             <mutability="mutable">

   <documentation>Service Data about stock (symbol and price).<documentation>

  

</gsdl:serviceDataDescription>

 

 

上面的代码通过使用文档/文字方法来构建网格服务。请注意 messagepart types 的定义。现在,您可以运行 GT3 工具 GenerateBinding 来生成服务和绑定 WSDL 文件。一旦创建了服务和绑定 WSDL 文件,就可以运行 GWSDL2Java 工具来生成必要的 Java 代码。该代码生成“StockPortType”接口,如 清单 7所示。Java 远程接口是它的基础接口,所以它抛出 java.rmi.RemoteException

清单 7. StockQuote 服务生成的 StockPortType portType 接口

 

 

\** This is sample code **\

public interface StockPortType extends java.rmi.Remote {

 public float getQuote(java.lang.String symbol) throws java.rmi.RemoteException;

}

 

一旦有了 StockPortType 接口,就可以通过实现这一接口来实现服务器端网格服务股票报价服务。下面 清单 8 中的样本代码演示了如何做到这一点。对于缺省网格服务行为,使用 ServiceSkeleton 类。

清单 8. StockQuote 服务实现

 

 

\** This is sample code **\

public class StockQuoteService extends ServiceSkeleton

                  implements StockPortType{

    public StockQuoteService() {

        super("Sample Stock Service");

    }

 

public void postCreate(GridContext messageContext) throws GridServiceException {

--

   }

    public float getQuote (String symbol) throws

          java.rmi.RemoteException {

    --

    }

}

 

接下来,创建网格服务工厂类,它又将创建股票服务,如 清单 9所示。

清单 9. 股票报价工厂实现

 

 

\** This is sample code **\

public class StockFactoryImpl extends FactoryServiceSkeleton {

    public StockFactoryImpl() {

        super("Sample Stock Service (Gateway to Live Service)");

    }

    public Object createServiceObject(CreationType creation) {

  return new StockQuoteService();

    }

}

 

 

正如您所看到的那样,股票报价服务实例创建在 createServiceObject(..) 方法调用中发生。

现在,我们已经准备好了可以部署到 AXIS 框架中的股票网格服务。为此,我们需要将部署信息添加到 server-config.wsdd 文件,如前面在部署和配置一节中描述的那样。一旦准备好了配置,就可以用 GT3 启动 J2EE/J2SE 容器,并且 AXIS Servlet 将等待来自客户机的 SOAP 消息请求,如 7所示。



7演示了通过两个不同的步骤创建并使用股票客户机。

步骤 1:使用股票工厂服务客户机创建 StockService,如 清单 10所示。

清单 10. 使用工厂定位器创建网格服务

 

 

\** This is sample code **\

FactoryServiceGridLocator factoryService = new

                      FactoryServiceGridLocator();

FactoryPortType factory = factoryService.getFactoryPort(new

                     HandleType(handle));

CreationType creation = new CreationType();

ServiceTerminationReferencesType refType=

                    factory.createService(creation);

ServiceLocatorType locator = refType.getReferences();

ExtensibilityType gsr = locator.getReferences()[0];

String locationURL = null;

if (gsr != null) {

        locationURL = AnyHelper.getAnyAsString(gsr);

} else {

       locationURL = locator.getHandle().getValue();

}

 

清单 10 演示了如何获得通过工厂创建的股票服务的网格服务句柄(GSH)。该 GSH 唯一地标识由工厂创建的股票服务。

步骤 2:现在使用步骤 1 中返回的 GSH 来对股票报价服务实例调用 getStock() 方法,如 清单 11所示。

清单 11. 调用网格服务上用 GSH 标识的方法

 

 

\** This is sample code **\

StockDefinitionServiceLocator stockService =

                              new StockDefinitionServiceLocator();

StockPortType stock = stockService.getStockDefinitionPort(new

URL(locationURL));

 

float quote = stock.getQuote(symbol);

 

 

更高级的客户机可以使用 findservicedata() 调用来获得与网格服务实例相关联的服务数据。 清单 12 演示了如何编写 findserviceData 操作来处理 ExtensibilityType 以及如何使用 GT3 提供的 AnyHelper 类来处理 xsd:any

清单 12. 如何对用 GSH 标识的网格服务使用 findserviceData() 操作

 

 

\** This is sample code **\

GridServiceLocator gridService = new GridServiceLocator();

GridServicePortType grid = gridService.getGridServicePort(new

                                  URL(url));

ExtensibilityType query = QueryHelper.getNameQuery("StockServiceData");

ExtensibilityType result = grid.findServiceData(query);

 

Element element = AnyHelper.getAnyAsElement(result);

                                  "or"

ServiceDataType data = (ServiceDataType)AnyHelper.getAny(result);

StockDataType value = (StockDataType)AnyHelper.getSingleAny(data);

 

至此,我们已经讨论了有关 GT3 的大多数基本概念。

 

原文地址:https://www.cnblogs.com/SlashOut/p/311719.html