Applying the Web services invocation framework
Calling services independent of protocols
獨立于協議的服務調用
Paul Fremantle (pzf@uk.ibm.com)
Senior Software Engineer, IBM Application and Integration Middleware
01 Jun 2002
Web
服務調用框架,提供了一種與傳輸協議和服務所在地無關的
web
服務調用方式。某種程度上可以把
WSIF
叫做不基于
SOAP
的簡單應用開發。了解
Apache Software Group
發布
WSIF
的最新變化。
?
Introduction
Web
服務調用框架(
WFIS
)是一種用來調用
Web
服務的簡單的
Java API
,而且不論服務在何時何地被提供。它把開發者,從必須為一些特定的傳輸協議和服務環境提供服務的束縛中解放出來。因此,它提供一個
API
提供獨立綁定,來訪問各種
Web
服務。它允許無存根或完全動態地調用
Web
服務,這是基于一種在運行時檢查服務元數據的技術。它也允許允許在運行時插入一個升級的任務綁定。如果你使用的
WSIF
提供者允許,也可以實時插入一個新的綁定。它也能選擇一個綁定延來期調用服務,直到運行時再綁定。最后,它是基于
WSDL
的,所以他可以調用任何
WSDL
中描述的服務。
WSIF
最初發布在
2001
年
10
月份的
alphaWorks
。
AlphaWorks
自從被發布以來被下載了
4000
多次。
WSIF
的創立者之一寫了兩篇很優秀的文章,來描述其建立
WSIF
的動機和它的使用,推薦大家讀一下
(See Web service invocation sans SOAP, Part 1 and 2 )
。
這篇文章符合
Apache
軟件基金會對
WSIF
捐贈要求。
WSIF
源碼是由
Apache XML
項目捐贈,并且在
Axis work
贊助下完成。可以在
Apache CVS
目錄下獲得,目錄名是
xml-axis-wsif
。代碼在
http://cvs.apache.org/viewcvs.cgi/xml-axis-wsif
。
在這篇文章中,我將關注
WSIF
的
Motivation
,使用和構架。自從
alphaWorks
發布后
WSIF
的變化就被總結概括,這篇文章也包含一些實驗性的和未來的觀點。但是在此之前,我將快速的回故一下
WSDL
。
?
Some background on WSDL
Web
服務描述語言(
WSDL
)從一開始就具有可擴展性。在
WSIF
中,設計者把接口和服務執行分離。
?
在
WSDL
中一個服務被清楚地定義為三個部分:
1.
The PortType
它定義了服務提供的抽象接口。一個
PortType
定義了一系列操作。每個操作能被
In-Out
(請求-響應),
In-only
,
Out-only,
和
Out-in
(征求-響應)。每個操作都定義了輸入或輸出消息。一個消息被定義為一系列部分(
part
),每個部分包含一個
Schema
定義類型。
2.
The Binding
一個綁定定義了抽象
PortType
與一個服務的數據格式和協議是如何映射的。例如,
SOAP
綁定定義了編碼方式,
SOAP Action header
,
body
的名字空間(目標
URI
)等等。
3.
The port
它定義了服務所在的實際位置(
endpoint
),比如,在
SOAP
服務器上可獲得的
HTTP URL
。
?
現在的
WSDL
,每個
port
有且只有一個綁定,每個綁定只有一個
PortType
。相反(更重要的是),每一個服務(
PortType
)能包含多個端口,每個端口代表一種可以供選擇的位置和綁定用以訪問那個服務。
當我們設計
WSIF
時我們先把它做為
WSDL
的鏡像,因為我們需要基于
WSDL
的
API
而不是直接基于
SOAP
。
WSIF
是一個框架有效地支持傳輸和格式化。
WSIF
中的
provider
支持
SOAP
。
?
WSDL
加上了可擴展元素后,和
SOAP
相比,它能夠建立其它的服務。典型地,
web
服務是用已有的應用組建構造,比如
JAVA
類,企業級
JAVA BEAN
,或
COM
對象。這些組件有時被封裝成應用程序運行在特定的系統,比如大型機事務處理系統。通過擴展
WSDL
來描述已有的組件模型,我們能獲取被暴露的
SOAP
-
available
服務和下面的組件之間的繼承關系,
…..
。事實上,為已存在的組件加上可擴展元素有更多的用途——它為已有的組件模型加上了面向服務構架的描述能力。
?
Motivation for WSIF
提出
WSIF
的動機是我們希望看到“面向構架的服務”應用更加廣泛,而不是僅僅的
SOAP
。現在,有大量不同的協議,傳輸和分布式計算技術能夠提供比
SOAP
更多的東西,尤其是在管理,交易安全,和服務質量(
QoS
)方面。而
SOAP
之所以能夠后來居上,主要是原因是資金投入。許多公司已經投入了大量資金在的技術上,比如
CORBA
,他們當然希望能夠繼續使用這些技術。另一方面,使用
SOAP
的
Web
服務有一個獨特的優勢——描述和發現的構架。任何人都可以從
UDDI
目錄或一個
inspection
文檔中下載
WSDL
文檔,并且使用一個普通的工具生成的代碼就可以使用服務,不論服務是在局域網還是通過
Internet
。腳本語言的使用也使其它工具得到發展——比如一些組成和設計服務的語言(
XLANG
和
WSFL
)。
We really wanted to make the extensibility and structure of WSDL real. WSDL allows us to describe existing systems using extensibility elements. For example, we have written WSDL extensions to describe transactions in CICS and IMS using connectors, calls to remote stateless session Enterprise JavaBeans, as well as SOAP and non-SOAP messages over JMS-based messaging systems. However, while describing things is useful, it isn't as useful as executing them.
?
現在,
WSDL
不僅僅是一個描述層——它已經用于一些工具中,這些工具使用
WSDL
描述來生成訪問服務的存根。所以,如果我們為非
SOAP
系統加上描述,我們將失去那些好處。
WSIF
是一個可插入的框架,它允許
provider
插入。一個
provider
就是一段代碼,它支持
WSDL
擴展,并且通過特定的執行可以調用服務。這就意味著客戶端的代碼是和(服務器端)執行無關的,它僅僅依賴服務的
PortType
。
WSIF
同時也支持延遲綁定,即一個新的
Provider
和描述可在運行時獲得,而已有的客戶端可使用這個新的
implementation
。最后,
WSIF
允許客戶端為
infrastructure
和
runtime
代理端口的選擇,這使用戶在服務質量特性和商務策略的基礎上選擇
implementation
。
?
WSDL
的結構允許一個
Web
服務有多個
implementation
,多個端口共享一個
PortType
。換句話說,
WSDL
允許同樣的端口綁定到
SOAP
和
IIOP
。我們希望我們的
API
允許同樣的客戶端代碼訪問任何可以獲得的綁定——如果代碼為
PortType
而寫,那么它在端口和綁定被使用時應該能被部署或配置(或代碼選擇)。
?
我們為
WSIF
提出了一下要求,它必須:
1.
Support any valid WSDL extensions.
支持任何合法的
WSDL
擴展。
2.
Support dynamic invocation of WSDL-described services.
支持
WSDL
—描述服務的動態調用。
3.
Support an API based on WSDL PortTypes.
支持基于
WSDL
端口類型的
API
。
4.
Allow late binding to different formats and transports.
允許延遲綁定不同的數據格式和傳輸。
5.
Support both compiled and dynamic approaches.
支持編譯和動態
approaches
。
6.
Support minimum code deployment scenarios (n providers, no per-service code).
支持最小代碼部署方案(
n provider
,
no persevice
代碼)。
7.
Support different in-memory representations of service request data.
?
WSIF usage
WSIF
的用法有兩種:基于存根的模型和動態調用接口(
DII
)。
Stub model
基于存根的模型允許使用者使用泛型編程模型,調用服務器上的業務函數。從 WSDL接口到JAVA定義接口的映射已經被規范花——在JAX-RPC標準中。有些人試圖通過JCP/JSR過程把WSIF模型有JAX-RPC整合起來,但是從這個角度上看WSIF總是顯得太試驗化了。我們所能做的只能是松散的整合。JAX-RPC定義了服務定義接口(SDI)——存根的業務接口。WSIF也定義了一個接口想JAX-RPC一樣來使用同樣的SDI。所以,盡管WSIF和JAX-RPC不能共享接口,他們卻共享工具(比如,Axis WSDL2Java)。Listing 1是一個存根模型的例子。
WSIFService?sq?
=
?ServiceFactory.newInstance().getService(
"
http://my.com/svcs/stockquote.wsdl
"
);?
MyService?mySvcStub?
=
?sq.getStub(
"
soap
"
,?MyService.
class
);?
mySvcStub.myMethod();?
Dynamic invocation interface
DII
和WSDL十分相近。在WSDL中,每個操作都有一個輸入消息和可選的輸出或錯誤消息。在WSIF中,我們劃分了相似的層次。基本上是對應的。事實上,我們的第一次迭代是一一對應的,但是我們歸納的更有邏輯性更(簡便)簡單。對應關系如Table 1: Correspondence of WSDL and WSIF entities所示。
Table 1: Correspondence of WSDL and WSIF entities
WSDL
|
WSIF
|
(WSIL/UDDI)
|
WSIFServiceFactory or JNDI
|
Service
|
WSIFService
|
Port
|
WSIFPort
|
Binding
|
(
無對應項)
|
Operation
|
WSIFOperation
|
Message
|
WSIFMessage
|
Part
|
(
無對應項)
|
使用DII你需要:
-
Select a port.
選擇一個端口
-
Create an operation.
建立一個操作
-
Create and populate the in-message.
建立并組裝輸入消息。
-
Execute the operation.
執行操作
-
Read the response data from the out-message.
從輸出消息中讀取響應數據。
一個簡單的例子如 Listing 2所示。
WSIFService?sq?
=
?ServiceFactory.newInstance().getService(
"
http://my.com/svcs/stockquote.wsdl
"
);?

WSIFPort?defPort?
=
?sq.getPort();?

WSIFOperation?getQ?
=
?defPort.createOperation(
"
getQuote
"
);?

WSIFMessage?inMessage?
=
?getQ.createInputMessage();?

inMessage.setStringPart(
"
symbol
"
,?
"
IBM
"
);?


?

getQ.executeRequestResponse(inMessage,?outMsg,?fltMsg);?

outMessage.getFloatPart(
"
value
"
);?

AlphaWorks發布的WSIF的特性之一是有一個命令行參數工具——Dynamic Invoker,這個工具能調用任何接口具有簡單類型的Web服務。我們通常請求的服務是,參數使用了復雜類型的動態調用服務。WSIF就是基于這個思想設計的,但是對于第一次迭代我們僅僅支持使用JavaBean組件的服務,所以如果沒有先產生一個合適的JavaBean組件,你將不能調用服務。作為補救,我們開發了一系列的名為JROM的類(起初它是支持Java記錄對象模型(JROM),由Jay-Rom聲明,但是現在它僅僅是個名字而已)。JROM是一個抽象的樹狀結構,這種結構能代表內存中很多schema復雜類型。JROM作為輕量級的DOM,它的樹裝結構的每個葉子節點都是一個基本類型(不像DOM都是字符串)。
通過和WSIF一起使用JROM,動態調用甚至容許在Classpath中沒有與Schema復雜類型相匹配的Java類型。這是一種十分有力的方式,尤其是在建立一個動態web服務系統時,如網關,流引擎,測試客戶端。不是所有的Provider都支持JROM,但是我們在ApacheSOAP Provider中加入了對JROM的支持。
JROM
不是WSIF開源項目發布的一部分,但是它可以從alphaWorks中獲得,見 www.alphaworks.ibm.com/tech/jrom.
WSIF architecture
WSIF
的架構是基于一些工廠類的。使用工廠類的原因是,這樣可以隱藏對象是所使用的是“靜態”還是“動態”。在靜態的情況下,對象被創建以提供特定的端口,消息或操作。靜態時implementation可以快速建立。在動態情況下,對象使用WSDL描述在運行時控制特定的端口,操作或消息傳遞。目前WSIF主要用于動態對象,就像我們最初怎樣設計它們的一樣。我們把WSIF分為不同的動態度。
Fully dynamic architecture
完全動態架構
在流控制引擎中可能用到,流的描述作為一個XML文檔被提供。流引擎在發送消息給其他的操作之前處理消息,以聚合成一個新的服務。被部署的代碼是每個綁定類型一個Provider。因此,這是一個b結構,b是一些不同的WSDL綁定擴展。
Semi-dynamic architecture
半綁定構架
定義了PortType的消息被靜態編譯,但是綁定本身是動態的。這就要求代碼部署基于PortType,且每個綁定一個Provider。因此,這是一個p+b結構,其中p是一些PorType,b是一些WSDL綁定。當接口變化時,編譯的消息必須被部署。
Static architecture
靜態構架
WSDL
綁定和端口都是靜態編譯。在這種情況下,在tooling time被定義的默認端口被編譯。代碼部署是每個綁定實例一個實體,因此,可看作是p×b 結構。
Changes since the alphaWorks release
自alphaworks發布后的變化
There are a number of changes since the alphaWorks release. You are encouraged to look at the open source code tree yourself. The main changes are:
-
Simplification of the WSIFMessage and WSIFPart model. We removed the WSIFPart interface and merged it into WSIFMessage. In order to capture different styles of using WSIFMessage, we added a method getRepresentationStyle().
-
Renaming of the PortFactory object to Service.
-
Addition of a ServiceFactory interface.
-
Change from using the PortTypeCompiler to using the J2SE 1.3 dynamic proxy support.
-
Addition of new bindings and transports -- SOAP over JMS, EJB binding, Apache Axis-based SOAP provider.
-
Support for tracing and logging activity.
-
Support for dynamic registration of new providers using the J2SE JAR service provider spec (see Resources).
Experimental additions to WSIF
目前WSIF有許多研究領域,異步請求-響應消息和context-aware消息是其中的兩個。
Asynchronous request-response
現在有一個異步請求-響應模型,響應(response)在由請求引發的不同運行線程中被處理。為了支持它,請求者注冊一個返回對象或句柄,它們在響應到達時被調用。
當請求消息被發送之后,句柄對象被傳遞給WSIFOperation。WSIF提供一個相關的服務來存儲句柄而不是提供一個identifier。WSIFOperation調用WSIF相關的服務,這個服務存儲了服務本身和請求句柄使用的相應的ID。這都發生當前事務的內部。如果用戶請求指定了一個事務隊列,那么這些工作在當前事務內完成。
WSIFOperation
和WSIFResponseHandle對象是序列化的,所以句柄對象的狀態能被保持,即使萬一在響應和請求時系統出錯也可以被保持。相應的服務也是可插入的,而其他的特性,比如原子事務和持續性都能保證高可靠性。
當某個延遲端口響應到來時,監聽線程將捕獲它并傳遞給用作存儲的WSIFOperation。操作包括把響應散列成WSIFMessage邏輯,并執行句柄函數executeAsyncResponse(),此函數以outMessage為參數。監聽線程運行在不同事務上,這些事務源自原始的請求。響應也因此把事務和請求分割開來。
例如, Listing 3顯示了一個句柄如何通過實現(implement)接口類WSIFResponseHandler而來。此Handler是用來解釋響應消息和使用響應值的。
Listing 3. Implementing an asynchronous handler in WSIF
public
?
class
?QuoteHandler?
implements
?WSIFResponseHandler??
{??????????

protected
?String?symbol?
=
?
null
;?
//
?local?storage?of?the?symbol?we?wanted?quoted
public
?
void
?setSymbol(String?value)?
{?symbol?
=
?value?}
;????


public
?
void
?executeAsyncResponse(WSIFMessage?out,?WSIFMessage?fault)?
{
//
?this?simplified?example?assumes?no?failures?and?that?the?symbol?has?been?set?correctly?
float
?quoteValue?
=
?out.getPart?(
"
quote
"
);
updateQuoteDB(symbol,?quoteValue);
}
?

服務調用如 Listing 4示:
Listing 4. Invoking a service asynchronously with WSIF
String?symbol?
=
?
"
IBM
"
;?

QuoteHandler?quoteHandler?
=
?
new
?QuoteHandler();?

quoteHandler.setSymbol(symbol);?
//
?the?handler?needs?to?knowthe?symbol?when?it?gets?executed?later.???
WSIFMessage?inMessage;?

WSIFOperation?quoteOperation;?


?

inMessage.setXXXPart(
)?
//
?set?up?inMessage?for?invocation?
quoteOperation.executeAsyncRequestResponse(inMessage,?quoteHandler);?
Content-aware message內容-提醒消息
我們也希望支持設定和使用上下文。W3C的web服務工作小組也就這個主題討論過,但是沒有規定語法和語義。
例如,一個SOAP/HTTP端口可能要求得到HTTP用戶名和密碼。這些信息對于服務調用來說十分特殊,但是通常又并非是服務參數的一部分。在總體上,上下文被定義成一系列name-value對。但是,Web服務需要使用XML schema類型定義數據類型,用“name-value對”表示上下文的方法可用表示
WSIFMessage
的方法來替代——即一組被命名的Part,每個part等價于一個XML Schema類型實例。這雖然稍稍超出了使用屬性的概念,但是更多的保持了WSDL和WSIF的特點。
The methods setContext() and getContext() on a WSIFPort and WSIFOperation allow the application programmer or stub to pass context information to the binding. The Port implementation may use this context -- for example to update a SOAP header. There is no definition of how a Port may utilize the context.
WSIFPort
和
WSIFOperation
上的
setContext()
和
getContext()
函數允許應用程序員或者存根通過上下文信息綁定。
Port
的實現也會用到這些上下文——比如升級一個
SOAP
頭。但
Port
怎樣使用上下文沒有定義。
Ideas for the future
There are a number of areas in WSIF we would like to see work on to improve its functionality and usefulness. First, we would like to have refactoring capabilities to separate the transport from message formatting. We have defined a WSIFFormatter class to allow access to and conversion of the data into a native format.
Next, an abstract tree representation of the data in a a message would be useful. Currently, we mainly use compiled classes from the schema to carry the service parameters in WSIFMessage. However, in one implementation of WSIF, the Web Services Gateway (see Resources), we use an abstract tree notation called JROM that closely maps to an XML Schema.
We would also like to see more and better providers for the many types of transports and object systems that exist. Finally, an implementation of WSIF in C or C++ would certainly be helpful to developers creating services in those languages.
Summary
小結
WSIF
是一個開源的面向服務的框架,它允許SOAP和非SOAP服務在WSDL中定義并用普通的方式調用。WSIF定義了可插入的接口(Provider接口)來支持新的傳輸和協議。通過支持代理接口和動態調用接口,WSIF能夠使最終用戶和系統軟件開發者這使用多種些協議支持WSIF提供的接口。WSIF支持延遲綁定,這樣服務可以被重新綁定到一個新的協議上而不需要改變代碼。The open source WSIF codebase includes providers for Java, EJB, and SOAP (over HTTP and JMS). WSIF has been used in WebSphere Enterprise Edition 4.1 and Versata's Logic Server WebServices Add-On.
Acknowledgments
The main contributors to the WSIF release, in alphabetical order, are: Aleksander A. Slominski, Anthony Elder, Dieter Koenig, Gerhard Pfau, Jeremy Hughes, Mark Whitlock, Matthew J. Duftler, Michael Beisiegel, Nirmal Mukhi, Owen Burroughs, Paul Fremantle, Piotr Przybylski, and Sanjiva Weerawarana
Resources
About the author Paul Fremantle is an architect in IBM's Hursley Laboratory, working on Web services components in IBM WebSphere Application Server, as well as open source projects such as WSDL4J and WSIF. Paul is the co-lead of the Java standard JSR110: Java APIs for WSDL. Paul previously worked as a WebSphere specialist in the software group and as an architect in IBM Global Services. Before joining IBM, Paul worked as a consultant in the pharmaceutical industry. His publications include articles on porting EJBs from WebLogic to WebSphere, and a Redbook, "The XML Files: Using XML and XSL in WebSphere." Paul has presented at ApacheCon, XML Europe, Software Architecture, and other industry conferences. He has an M.A. in Mathematics and Philosophy and an M.Sc in Computation from OxfordUniversity. You can contact Paul at pzf@uk.ibm.com.
|
轉載自:http://it.jiulove.com/inc/news/20050731/11292026111.asp