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

developerWorks 中国  >  Grid computing | SOA and Web services  >

Globus Toolkit 4 的预先体验版:WSRF

用于异构网格环境的有状态服务

developerWorks
文档选项

未显示需要 JavaScript 的文档选项

样例代码


级别: 中级

Vladimir Silva (vsilva@us.ibm.com), 普及式系统开发承包商, IBM

2004 年 11 月 18 日

即将发布的 Globus Toolkit 4 (GT4) (根据 Globus 的 Web 站点的通告,它将于 2005 年 1 月 31 日正式发布)的特性之一是新实现了 Web Services Resource Framework (WSRF) [1] 和 Service Notification (WSN) [2] 标准。GT4 提供了一个 API 来构建有状态的 Web 服务,其目标是分布式异构计算环境。本文旨在提供 GT4 所使用的新标准的说明,同时将给出一个实际的例子,让您体验如何为组织创建有状态的服务。

新组件:WS-Component

GT4 中新的 Web 服务组件有:

  • WS Authentication Authorization

    WS Authentication Authorization 取代了原来的 Grid Security Infrastructure (GSI),被再分为 Message(消息)级的安全性和 Authorization(授权)框架。Message 级安全性实现了两个标准:WS-Security 和 WS-SecureConversation。这两个标准提供 SOAP 消息加密、完整性和重放保护。

    Authorization Framework 是一个设计用来处理许多授权机制的组件,例如网格映射文件、访问控制列表(ACL)以及通过 SAML 协议处理用户授权。

  • WS Core

    WS Core 是对两个新标准的实现:WSRF 和 Web Services Notification (WSN)。其他新特性包括基于 Apache Tomcat 的 JNDI 注册项、HTTP/1.1 客户机服务器支持、进行 WS-Addressing 转换的 URI 解析器服务等。

  • C WS Core

    C 编程人员将非常喜欢这个组件:GT4 提供了一组使用 C 编写的基本工具集,可以用该工具集来创建启用 WSRF 的 Web 服务和客户机对 WS-Resource 和 WS-Notification 的确认。该组件中现有特性包括:

    • 独立的服务容器。
    • 在 C 应用程序中嵌入服务所使用的 API。
    • 在服务中管理资源所使用的 Resource API。
    • HTTP/1.1 客户机和服务器支持。
    • 直接从 WSDL 模式中生成纯 C 存根(阻塞的或异步的)。
    • 可动态加载的基于新的 Extension API 的 Operation Providers 和 Service Modules。




回页首


旧协议,新面孔

所有知名的 GT3 协议(资源管理使用的 WS-GRAM、数据管理使用的 RFT 以及信息服务使用的 MDS)都被重新设计为可以使用 WSRF 的。安全协议 GSI 现在称为 WS Authentication Authorization。下面的兼容矩阵总结了即将发布的 Globus Toolkit 主要协议的一些基本特性和兼容性问题。有关的更多信息,请参阅参考资料 [4]:

表 1. GT4 中的新协议

服务 协议 特性 向后兼容性
数据传输可靠文件传输(RFT)
  1. 使用 GridFTP 控制和监视第三方文件传输。
  2. 指数补偿(Exponential back-off)。
  3. 全部传输或者全部不传输。
  4. 并行传输。
  5. TCP 缓冲区大小。
  6. 递归目录传输。
与 OGSI (GT3.2) 不存在向后兼容
资源管理WS-GRAM
  1. 改进任务性能:并行性、吞吐量和等待时间等。
  2. 改进可靠性/可恢复性。
  3. 支持 mpich-g2 任务,包括:
    1. 多任务提交。
    2. 在一个任务中协调处理。
    3. 在一个多任务的子任务之间进行协调。
该协议已经被修改成 WSRF 兼容的。该版本与以前的版本之间不存在向后兼容
信息服务MDS4 索引服务
  1. 基于 WSRF 而不是 OGSI。
  2. 已经删除 Xindice 支持。
  3. 已经重构聚合的永久性配置。
全新的服务
  1. 触发器服务。
  2. 聚合器(Aggregator)。
  3. 归档服务。
与 GT3.2 的索引服务不兼容,因为该服务已经使用 WSRF 代替 OGSI,重新进行了建模





回页首


理解 WSRF

要理解 WSRF 怎样才能提供有状态的服务,首先必须理解 Web 服务,并以标准的形式给出一种状态。"Web 服务是一个软件组件,它可以支持机器到机器的交互,具有使用机器适用的格式(WSDL)描述的网络地址接口。服务交互是使用 SOAP 消息描述的,通常由使用传输层协议(例如 HTTP 或其他 Web 标准)的 XML 序列化组成。" [3]。

面向服务的架构(Service Oriented Architecture,SOA) 定义了一个分布式系统,其中 Web Web 服务通过发送消息进行协调。Web 服务是无状态的,它们不用访问或使用输入消息中包含的信息就可以交换消息。

无状态的服务与有状态的服务的比较

有状态的(stateful) 服务是通过在交换的消息头中传播执行内容来访问(或操作)合乎逻辑的有状态资源的一种服务。通常,无状态的(stateless) 服务可以增强可靠性和可扩展性。(例如,在失败之后,服务可以重启,而不用关心之前的交互。可以根据系统的负载创建或销毁新的服务实例。)因此,在Web 服务社区中,通常认为无状态的服务是一种较好的工程实践。

然而,有些情况下则需要使用有状态的服务 —— 服务会根据交换的消息来操作有状态的资源。这来场景中包括服务间的交互。因此,"重要的是判断表示和操作状态的模式,并对其进行标准化,这样可以简化可互操作的服务的构建和使用。" [3 p 9]

WS-Resource

WS-Resource 被定义为由 Web 服务和有状态的资源(stateful resource) 构成的实体。有状态的资源可以在 Web 服务消息交换中使用。可以创建和销毁 WS-Resources,而且可以通过消息交换查询或更改其状态。

WS-Resource 有 4 个很重要的称为 ACID 特性的软件工程特性。在 Web Services Atomic Transaction 规范 [WS-AtomicTransaction] 中,对这些特性进行了介绍,如下所示:

  • 原子性(Atomicity): 在事务单元中,要么对有状态资源全部进行更新,要么全都不进行更新。
  • 一致性(Consistency): 有状态资源应该总能维护一致状态,即使失效之后也是如此。
  • 隔离性(Isolation): 应该在给定的事务单元中隔离对有状态资源的更新。
  • 持久性(Durability): 在事务单元中对有状态资源的更新是永久性的。
有状态资源

可以将有状态的资源定义为一个具有三种基本特性的组件:[3 p. 10]

  1. 包含使用 XML 格式定义的状态数据。
  2. 具有一定的生命周期。
  3. 可以通过一个或多个 Web 服务进行操作。

有状态资源的例子包括文件、Java 对象或数据库中的记录。有状态资源可以是复合资源(即可以包含其他资源),并且可以通过服务工厂(service factories)创建和销毁其实例。有状态资源的实例应该通过一个标识或资源标识符进行识别;此外,使用资源的应用程序可以分配其他标识或别名。

Web 服务和有状态资源之间的关系是通过资源模式(resource pattern)的概念进行定义的。资源模式定义了使有状态资源与 Web 服务的消息交换有关联的机制。如果资源在部署时就与服务相关,那么这种关系可以是静态的;如果资源是在消息交换时与服务是相关的,那么这种关系就是动态的。资源模式是使用诸如 XML、 WSDL 和 WS-Addressing 之类的标准实现的。

WS-Addressing

WS-Addressing 是用来标准化端点引用的一个结构。端点引用给出了部署在网络端点上的 Web 服务的地址。它表示为一个 XML 序列化(XML serialization),通常由创建新资源的 Web 服务请求返回。除了 Web 服务地址之外,端点引用还可能包含元数据,例如服务描述和引用属性(reference properties)


清单 1. WS-Addressing 端点引用
				
<wsa:EndpointReference>
	<!-- Web Service address over a network endpoint -->
	<wsa:Address>
		http://helloworld.com/myWebService
	</wsa:Address>

	<!-- Meta Data -->
	<!-- Endpoint reference properties -->
	<wsa:ReferenceProperties>
		<tns:resourceID> ID-12345 </tns:resourceID>
	</wsa:ReferenceProperties>
</wsa:EndpointReference>

端点引用的用法如下图所示,图中展示了创建一个名为 (LIFService, Lager Integer Factorization) 的 Web 服务使用的消息交换。


图 1. Web 服务创建 SOAP 请求
Web 服务创建 SOAP 请求

图 2. Web 服务创建 SOAP 响应
Web 服务创建 SOAP 响应

WS-Resource 生命周期

生命周期被定义为 WS-Resource 创建与销毁之间的时间间隔,它要考虑以下因素:

创建

有状态资源通常是由资源工厂创建的。创建调用(creation call)将返回一个指向新的有状态资源的端点引用。

销毁

定义销毁有状态资源以及刷新系统资源的方法。

资源标识符

有状态资源至少必须有一个资源标识符。该标识符是作为端点引用的一部分返回的,可用于分布式系统中的其他 Web 服务。

WS-Resource 属性

WS-Resource 属性定义了用来通过 Web 服务接口操作 WS-Resource 状态的结构。资源属性映射为资源状态中的一个单独组件。

WS-Resource 安全性

安全性是通过 WS-Policy 和 WS-SecurityPolicy 规范定义的,这两个规范是 Web 服务安全性目标的一部分。它们描述了用来在客户机和 Web 服务之间安全交换信息所使用的策略集。





回页首


实际的 WSRF 服务:大整数因数分解(LIF)

第一个启用 WSRF 的 Web 服务使用二次方程式过滤实现大整数因数分解算法。这是解密学中常见的一个问题,目前大部分安全通信都是基于很难分解大素数(即超过 100 个数字的素数)这一事实而进行的。

Web 服务描述 (WSDL) 文件

所有 Web 服务的接口都是使用 WSDL (Web 服务描述语言) 描述的。WSDL 允许您定义 Web 服务对外提供的操作,以及需要访问的网络端点。这种特殊的服务提供一种称为因子(factor)的操作,它可以接受一个字符串作为参数,并返回一个字符串作为结果。


清单 2. 大整数的因数分解 Web 服务描述文件
				
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="LIF"
    targetNamespace="http://lif.com"
    xmlns:tns="http://lif.com"
    xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:gtwsdl="http://www.globus.org/namespaces/2004/01/GTWSDLExtensions"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:wsrlw=
"http://docs.oasis-open.org/wsrf/2004/06/
	wsrf-WS-ResourceLifetime-1.2-draft-01.wsdl"
    xmlns:wsrp=
"http://docs.oasis-open.org/wsrf/2004/06/
	wsrf-WS-ResourceProperties-1.2-draft-01.xsd"
    xmlns:wsrpw=
"http://docs.oasis-open.org/wsrf/2004/06/
	wsrf-WS-ResourceProperties-1.2-draft-01.wsdl"
    xmlns:wsntw=
"http://docs.oasis-open.org/wsn/2004/06/
	wsn-WS-BaseNotification-1.2-draft-01.wsdl"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <!-- LIF (Large Integer Factorization) Web Service description file -->
    <wsdl:import
        namespace=
"http://docs.oasis-open.org/wsrf/2004/06/
	wsrf-WS-ResourceProperties-1.2-draft-01.wsdl"
        location="../../../wsrf/properties/WS-ResourceProperties.wsdl" />

    <wsdl:import
        namespace=
"http://docs.oasis-open.org/wsrf/2004/06/
	wsrf-WS-ResourceLifetime-1.2-draft-01.wsdl"
        location="../../../wsrf/lifetime/WS-ResourceLifetime.wsdl" />

    <wsdl:import
        namespace=
"http://docs.oasis-open.org/wsn/2004/06/
	wsn-WS-BaseNotification-1.2-draft-01.wsdl"
        location="../../../wsrf/notification/WS-BaseN.wsdl" />

    <types>
        <xsd:schema targetNamespace="http://lif.com"
            xmlns:tns="http://lif.com"
            xmlns:xsd="http://www.w3.org/2001/XMLSchema">

            <xsd:import
                namespace=
                "http://schemas.xmlsoap.org/ws/2004/03/addressing"
                schemaLocation="../../../ws/addressing/WS-Addressing.xsd"
                />

            <xsd:element name="createLIF">
                <xsd:complexType/>
            </xsd:element>

            <xsd:element name="createLIFResponse">
               <xsd:complexType>
                 <xsd:sequence>
                   <xsd:element ref="wsa:EndpointReference"/>
                 </xsd:sequence>
              </xsd:complexType>
            </xsd:element>

            <xsd:element name="factor" type="xsd:string"/>
            <xsd:element name="factorResponse" type="xsd:string"/>

            <xsd:element name="Value" type="xsd:int"/>

            <xsd:element name="LIFRP">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element ref="tns:Value"
                            minOccurs="1" maxOccurs="1"/>
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>

        </xsd:schema>
    </types>

    <message name="CreateLIFRequest">
        <part name="request" element="tns:createLIF"/>
    </message>
    <message name="CreateLIFResponse">
        <part name="response" element="tns:createLIFResponse"/>
    </message>

    <!-- factor operation input/output arguments -->
    <!-- Input is a string argument-->
    <message name="FactorInputMessage">
        <part name="parameters" element="tns:factor"/>
    </message>
    <!-- Output is a string value -->
    <message name="FactorOutputMessage">
        <part name="parameters" element="tns:factorResponse"/>
    </message>

    <portType name="LIFPortType"
        gtwsdl:implements="wsntw:NotificationProducer
                           wsrlw:ImmediateResourceTermination
                           wsrlw:ScheduledResourceTermination"
        wsrp:ResourceProperties ="tns:LIFRP">

        <!-- Operation invoked when creating the web service -->
        <operation name="createLIF">
            <input message="tns:CreateLIFRequest"/>
            <output message="tns:CreateLIFResponse"/>
        </operation>

        <!-- Factorization operation (factor) -->
        <operation name="factor">
            <input message="tns:FactorInputMessage"/>
            <output message="tns:FactorOutputMessage"/>
        </operation>
		
    </portType>
</definitions>





回页首


资源实现

WSRF 服务中的资源被用来通过客户机与 Web 服务之间交换的消息来维护服务调用的状态。以下这个例子使用一个称为 LIF (Large Integer Factors)的资源来保存因数分解操作的结果。


清单 3. WSRF 有状态资源实现的例子
				
/**
 * Large Integer Factorization (LIF) WSRF Service
 * Description: A WSRF Service for large integer factorization
 *
 * @author Vladimir Silva
 */
package org.globus.wsrf.samples.lif;

import java.util.Calendar;

import javax.xml.namespace.QName;

import org.globus.wsrf.ResourceIdentifier;
import org.globus.wsrf.ResourceProperties;
import org.globus.wsrf.ResourceProperty;
import org.globus.wsrf.ResourcePropertySet;
import org.globus.wsrf.Topic;
import org.globus.wsrf.TopicList;
import org.globus.wsrf.TopicListAccessor;
import org.globus.wsrf.ResourceLifetime;
import org.globus.wsrf.WSRFConstants;
import org.globus.wsrf.impl.ReflectionResourceProperty;
import org.globus.wsrf.impl.ResourcePropertyTopic;
import org.globus.wsrf.impl.SimpleResourcePropertySet;
import org.globus.wsrf.impl.SimpleTopicList;
import org.globus.wsrf.impl.SimpleTopic;
import org.globus.wsrf.impl.SimpleResourceProperty;

/**
 * LIF Resource Implementation
 * A LIF resource is used to save the value of a specific
 * factorization
 */
public class LIF
   implements
   ResourceLifetime,
   ResourceIdentifier,
   ResourceProperties,
   TopicListAccessor {

   public static final QName KEY =
      new QName("http://lif.com", "LIFKey");
   public static final QName RP_SET =
      new QName("http://lif.com", "LIF");
   public static final QName VALUE =
      new QName("http://lif.com", "Value");

   private ResourcePropertySet propSet;
   private TopicList topicList;

   protected Calendar terminationTime = null;
   protected Object key;
   protected ResourceProperty value;

   /**
    * initialize Resource
    * @param key
    */
   protected void initialize(Object key) {
      this.key = key;
      this.propSet = new SimpleResourcePropertySet(RP_SET);
      this.topicList = new SimpleTopicList(this);
      ResourceProperty prop = null;

      try {
         this.value =
            new ResourcePropertyTopic(
            new SimpleResourceProperty(VALUE));
         this.propSet.add(this.value);
         this.topicList.addTopic( (Topic)this.value);
         this.value.add(new String());

         prop =
            new ReflectionResourceProperty(
            WSRFConstants.TERMINATION_TIME,
            this);
         this.propSet.add(prop);
         this.topicList.addTopic(
            new SimpleTopic(WSRFConstants.
                            TERMINATION_TOPIC));

         prop =
            new ReflectionResourceProperty(
            WSRFConstants.CURRENT_TIME,
            this);
         this.propSet.add(prop);
      }
      catch (Exception e) {
         throw new RuntimeException(e.getMessage());
      }
   }

   public ResourcePropertySet getResourcePropertySet() {
      return this.propSet;
   }

   public TopicList getTopicList() {
      return this.topicList;
   }

   /*
    * Methods to get or set the value of the resource
    */
   public String getValue(int idx) {
      return ( (String)this.value.get(idx));
   }

   public void setValue(String value) {
      this.value.set(0, value);
   }

   /**
    * Called when a new LIF resource is created.
    *
    * @return the resource key
    */
   public Object create() throws Exception {
      // just an example, might be a file already...
      this.key = new Integer(hashCode());
      initialize(key);
      return key;
   }

   public Object getID() {
      return this.key;
   }

   /* Service Lifetime Management methods
    *  (non-Javadoc)
    * @see org.globus.wsrf.ResourceLifetime
    #setTerminationTime(java.util.Calendar)
    */
   public void setTerminationTime(Calendar time) {
      this.terminationTime = time;
   }

   /*
    *  (non-Javadoc)
    * @see org.globus.wsrf.ResourceLifetime
    * #getTerminationTime()
    */
   public Calendar getTerminationTime() {
      return this.terminationTime;
   }

   public Calendar getCurrentTime() {
      return Calendar.getInstance();
   }
}





回页首


服务实现

服务实现包括 Web 服务对外界提供的操作。在这个特殊的例子中,对外提供了两项操作:

  • createLIF:在创建 Web 服务的实例时调用。其主要作用是创建一个使用资源关键字标识的有状态资源,并创建在响应消息中返回的端点引用。
  • Factor:该操作被用来通过二次方程式过滤算法对大整数进行因数分解。这项操作使用有状态资源来存储结果。

清单 4. 服务实现
				
package org.globus.wsrf.samples.lif;

import java.rmi.RemoteException;
import org.apache.axis.message.addressing.EndpointReferenceType;

import org.globus.wsrf.ResourceContext;
import org.globus.wsrf.ResourceKey;
import org.globus.wsrf.utils.AddressingUtils;

import com.lif._createLIF;
import com.lif._createLIFResponse;

import javax.math.factorization.Factorizer;
import java.math.BigInteger;

/**
 * Large Integer Factorization (LIF) WSRF Service
 * Description: A WSRF Service for large integer factorization
 *
 * Service Implementation
 * @author Vladimir Silva
 */
public class LIFService {
   ResourceKey key = null;

   /**
    * OPERATION1: Fires when the Web service is created.
    * Creates a stateful resource (identified by a key)
    * and endpoint reference (EPR) which is returned
    * @param request
    * @return Response object containing an endpoint reference (EPR)
    * @throws RemoteException
    */
   public _createLIFResponse createLIF(_createLIF request) throws
      RemoteException {
      ResourceContext ctx = null;
      LIFHome home = null;

      /*
       * Create a Resource...
       */
      try {
         ctx = ResourceContext.getResourceContext();
         home = (LIFHome) ctx.getResourceHome();
         key = home.create();
      }
      catch (RemoteException e) {
         throw e;
      }
      catch (Exception e) {
         throw new RemoteException(", e);
      }

      /*
       * Add an endpoint reference to the response
       */
      EndpointReferenceType epr = null;
      try {
         epr = AddressingUtils.createEndpointReference(ctx, key);
      }
      catch (Exception e) {
         throw new RemoteException(", e);
      }

      _createLIFResponse response = new _createLIFResponse();
      response.setEndpointReference(epr);

      return response;
   }

   /**
    * OPERATION2: Find factors operation
    * @param largeInteger Large prime/integer string to be factored
    * @return Result of the form: f1^p1 * f2^p2 ... fn^pn
    * @throws RemoteException
    */
   public String factor(String largeInteger) 
   	throws RemoteException 
	{
      /*
       * Retrieve resource
       */
      Object resource = null;
      try {
         resource = ResourceContext.getResourceContext().
            getResource();
      }
      catch (RemoteException e) {
         throw e;
      }
      catch (Exception e) {
         throw new RemoteException(", e);
      }
      LIF lif = (LIF) resource;

      /*
       * Use a quadratic sieve to find factors
       */
      Factorizer f;
      try {
         // Factorize number, Timeout = 10 secs, verbose = false
         f = new Factorizer(new BigInteger(largeInteger), 10, false);
         f.factor();
      }
      catch (Exception ex) {
         throw new RemoteException("Factorizer", ex);
      }

      // save factors within the LIF resource
      lif.setValue(f.factorsAsString());
      return f.factorsAsString();
   }
}





回页首


服务的客户机

实现过程的最后一个步骤是编写服务客户机程序,调用这项服务。Globus 提供了处理大部分底层的工作的 API。调用一个服务操作需要的步骤非常简单,如下所示:

  1. 获得服务地址的位置:
    LIFServiceAddressingLocator locator = new LIFServiceAddressingLocator();
  2. 获得终点引用(EPR)和调用所需要的 Web 服务操作的端口:
    EndpointReferenceType endpoint = new EndpointReferenceType();
    endpoint.setAddress(new Address("http://localhost:8080/wdrf/services/MyService"));
    LIFPortType port = locator.getLIFPortTypePort(endpoint);
    		
  3. 调用需要的操作。例如,下面这个例子创建一个大整数因数分解(LIF)服务的实例:_createLIFResponse createResponse = port.createLIF(new _createLIF()); endpoint = createResponse.getEndpointReference();

完整的过程如下列这项服务的客户机程序所示:


清单 6. Web 服务客户机程序
				
package org.globus.wsrf.samples.lif.client;

/**
 * <p>Title: LIF (Large Integer Factorization) WSRF Service</p>
 * <p>Description: Large Integer Factorization service for GT4</p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: </p>
 * @author Vladimir Silva
 * @version 1.0
 */

import java.util.List;

import org.apache.axis.message.addressing.Address;
import org.apache.axis.message.addressing.EndpointReferenceType;
import org.globus.wsrf.NotificationConsumerManager;

import com.lif.LIFPortType;
import com.lif._createLIF;
import com.lif._createLIFResponse;
import com.lif.service.LIFServiceAddressingLocator;

import org.oasis.wsrf.lifetime._Destroy;

import javax.xml.rpc.Stub;
import org.globus.wsrf.impl.security.authentication.Constants;
import org.globus.wsrf.impl.security.authorization.SelfAuthorization;

import org.globus.wsrf.client.BaseClient;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.CommandLine;

/**
 * Large Integer Factorization (LIF) WSRF Service
 * Description: A WSRF Service for large integer factorization
 *
 * This class is used to create a resource which will be used
 * to save the result of a given factorization
 *
 * @author Vladimir Silva
 */
public class FactorClient
   extends BaseClient {
   public static void main(String[] args) {
      FactorClient client = new FactorClient();

      // client takes 1 arg : large integer
      client.setCustomUsage("{large integer}");

      LIFServiceAddressingLocator locator =
         new LIFServiceAddressingLocator();

      // GSI Secure Conversation, signature, 
	  // without delegation, self authz.
      String CLIENT_DESC =
         "org/globus/wsrf/samples/lif/client/client-security-config.xml";
      NotificationConsumerManager consumer = null;

      // large number to factor
      String largeInt;

      try {
         // Parse arguments: 1 arg => large number
         CommandLine line = client.parse(args);
         List options = line.getArgList();

         if (options == null || options.isEmpty()) {
            throw new ParseException("Expected large integer argument");
         }

         // get number to factor from cmd line
         largeInt = (String) options.get(0);

         // Service URL
         String servURL = line.getOptionValue("s");

         if (servURL == null) {
            servURL = "http://localhost:8080/wsrf/services/LIFService";

            // Use security? (Use security if the Service URL contains
            // Secure e.g SecureLIFService
         }
         boolean secure = (servURL.indexOf("Secure") > 0) ? true : false;

         //System.out.println("LIF service URL: " + servURL +
         //" Number:" + largeInt + " Secure:" + secure);

         // STEP1: Obtain a SOAP endpoint reference (EPR)
         // Contains the service URL and metadata
         // such as resource properties)
         EndpointReferenceType endpoint = new EndpointReferenceType();
         endpoint.setAddress(new Address(servURL));

         // STEP2: Obtain a Port (using the EPR) to create a
         // web service instance
         LIFPortType port = locator.getLIFPortTypePort(endpoint);

         if (secure) {
            ( (Stub) port)._setProperty(
               Constants.CLIENT_DESCRIPTOR_FILE,
               CLIENT_DESC);
         }

         // Create lif (Large Integer factorizer) resource
         // Returns the EPR of the new instance
         _createLIFResponse createResponse = 
		 	port.createLIF(new _createLIF());
         endpoint = createResponse.getEndpointReference();

         // STEP3: Use the new EPR to obtain a second Port used to 
         // factor the number
         LIFPortType factorPort = locator.getLIFPortTypePort(endpoint);

         if (secure) {
            // Secure message
            ( (Stub) factorPort)._setProperty(
               Constants.GSI_SEC_MSG,
               Constants.SIGNATURE);
            ( (Stub) factorPort)._setProperty(
               Constants.AUTHORIZATION,
               new SelfAuthorization());
         }

         // Show factorization result
         System.out.println(largeInt + "=" +
                            factorPort.factor(largeInt));

         // STEP3: Use the EPR to obtain a third port 
		 // to destroy the service
         LIFPortType destroyPort = locator.getLIFPortTypePort(endpoint);
         if (secure) {
            ( (Stub) destroyPort)._setProperty(
               Constants.CLIENT_DESCRIPTOR_FILE,
               CLIENT_DESC);
         }
         // Destroy the lif resource
         destroyPort.destroy(new _Destroy());

      }
      catch (Exception e) {
         e.printStackTrace();
      }
   }
}





回页首


启用安全性

如果需要在服务中启用安全性,那么还需要其他一些步骤和文件。例如,在上面例子中,必须编写资源类和服务实现文件的启用服务安全性的版本。还需要一个用于该服务的安全配置 XML 文件,此外,还必须启用客户机程序来获得安全性。为了简单起见,安全服务将在以后介绍。不过,本文提供的源代码中包含了启用安全性的文件。





回页首


构建和部署

Globus 通过使用一组非常有用的 ant 脚本,让服务的构建和部署变得非常简单。因此,要对构建和部署(假设已经拥有正确的文件)服务,只需运行下面的命令即可:

要部署(在项目目录中)服务,请执行以下命令:
		set GLOBUS_LOCATION=[WSRF_CONTAINER_LOCATION]
		ant deploy

	要卸载服务,请执行以下命令:
		ant undeploy




回页首


运行时测试

一旦成功部署服务之后,就可以在 $GLOBUS_LOCATION/bin 目录中启动 WSRF 容器并执行下面的命令来运行服务:lif-client -s http://localhost:8080/wsrf/services/LIFService [number],如图 3 所示:


图 3. 服务测试
服务测试




回页首


结束语

即将发布的 Globus Toolkit 合并了最新的 Web 服务规范,而没有妥协支持原来的协议。本文的目的是采用一个真实的网格服务的例子,让您尽早地了解这些新规范。本文将让您体验如何在您的组织中完成服务实现。






回页首


下载

描述名字大小下载方法
Source code for this articlewsrf-source.zip500 KBHTTP
关于下载方法的信息


参考资料

  • 您可以参阅本文在 developerWorks 全球站点上的 英文原文

  • 下载本文中使用的源代码

  • 有关 WSRF 的更多信息,请参阅 OASIS Web Services Resource Framework Technical Committee。

  • 此外,请阅读有关 OASIS Web Services 的通告。

  • 关于背景信息,请参阅 Modeling Stateful Resources with Web Services,作者是 Foster、Frey、Graham、Tuecke、Czajkowski、Ferguson、Leyman 和 Nally 等。Computer Associates International, Inc.、Fujitsu Limited, Hewlett-Packard Development Company、International Business Machines Corporation 以及 The University of Chicago 2003-2004 年版权所有。


关于作者

Vladimir Silva 出生于厄瓜多尔的首都基多。他于 1994 年在 Polytechnic Institute of the Army 获得系统分析师学位。同年,他作为交换学生来到美国,在 Middle Tennessee State University 攻读计算机科学硕士学位。毕业之后,他加入了 IBM“Web-Ahead”技术智囊团。他的兴趣包括网格计算、神经网络以及人工智能。他还拥有众多的 IT 认证,其中包括 OCP、MCSD 和 MCP。




对本文的评价

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

建议?




回页首


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