级别: 中级 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) |
- 使用 GridFTP 控制和监视第三方文件传输。
- 指数补偿(Exponential back-off)。
- 全部传输或者全部不传输。
- 并行传输。
- TCP 缓冲区大小。
- 递归目录传输。
| 与 OGSI (GT3.2) 不存在向后兼容 | | 资源管理 | WS-GRAM |
- 改进任务性能:并行性、吞吐量和等待时间等。
- 改进可靠性/可恢复性。
- 支持 mpich-g2 任务,包括:
- 多任务提交。
- 在一个任务中协调处理。
- 在一个多任务的子任务之间进行协调。
| 该协议已经被修改成 WSRF 兼容的。该版本与以前的版本之间不存在向后兼容 | | 信息服务 | MDS4 |
索引服务
- 基于 WSRF 而不是 OGSI。
- 已经删除 Xindice 支持。
- 已经重构聚合的永久性配置。
全新的服务
- 触发器服务。
- 聚合器(Aggregator)。
- 归档服务。
| 与 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]
- 包含使用 XML 格式定义的状态数据。
- 具有一定的生命周期。
- 可以通过一个或多个 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 请求
图 2. 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。调用一个服务操作需要的步骤非常简单,如下所示:
- 获得服务地址的位置:
LIFServiceAddressingLocator locator = new LIFServiceAddressingLocator();
- 获得终点引用(EPR)和调用所需要的 Web 服务操作的端口:
EndpointReferenceType endpoint = new EndpointReferenceType();
endpoint.setAddress(new Address("http://localhost:8080/wdrf/services/MyService"));
LIFPortType port = locator.getLIFPortTypePort(endpoint);
-
调用需要的操作。例如,下面这个例子创建一个大整数因数分解(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 article | wsrf-source.zip | 500 KB | HTTP |
|---|
参考资料
- 您可以参阅本文在 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。 |
对本文的评价
|