2006年 6月 28日 水曜日 前回のエントリで,SOAのレイヤ構成を想定したJava EE 5開発を試してみました。これにSOAを適用するとどのようなイメージになるのでしょうか?実際に,前回のアプリケーションをベースにSOAを試してみましょう。具体的には,リソースレイヤとサービスレイヤをそのまま使って,プロセスレイヤをBPELで実現します。
ただし,一気にそこまで行くのは大変なので,今回は,ひとまず簡単なプロセスを動かすところまでにしたいと思います。
【0. 前提条件】
必要なのは,前回と同じくNetBeans Enterprise Pack 5.5 EA版だけです。これには,SOA Starter Kitが含まれています。プラットフォームはJBIのオープンソース実装であるOpen ESBです。
【1. プロジェクトの作成,準備】
(1) プロジェクトの作成
[File]-[New Project]を選択すると,[New Project]ダイアログが起動します。
[Service Oriented Architecture]-[BPEL Module]を選択します。
としてプロジェクトを生成します。
PricingProcess_1.bpel, PricingProcess_1.wsdlが生成されます。
(2) WSDL,XMLスキーマの準備
このプロセスのエントリポイントをWebサービスとして定義するためのWSDL,XMLスキーマを準備します。前回のアプリケーションのBooksPricingProxessWebServiceBeanと同じWSDLとXMLスキーマを流用することにしましょう。
前回の最後の手順で使ったWebサービスのテスト画面にWSDLというリンクがあります。これをクリックしてWSDLを表示させてローカルに保存しましょう。(拡張子をwsdlにしましょう。)
こんな感じのWSDLになっているはずです。
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://ws/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" targetNamespace="http://ws/" name="BooksPricingProcessWebServiceBeanService">
<types>
<xsd:schema>
<xsd:import namespace="http://ws/" schemaLocation="http://xxx.xxx.xxx.xxx:8080/BooksPricingProcessWebServiceBeanService/BooksPricingProcessWebServiceBean/__container$publishing$subctx/META-INF/wsdl/BooksPricingProcessWebServiceBeanService_schema1.xsd" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"/>
</xsd:schema>
</types>
<message name="findBookPrice">
<part name="parameters" element="tns:findBookPrice"/>
</message>
<message name="findBookPriceResponse">
<part name="parameters" element="tns:findBookPriceResponse"/>
</message>
<portType name="BooksPricingProcessWebServiceBean">
<operation name="findBookPrice">
<input message="tns:findBookPrice"/>
<output message="tns:findBookPriceResponse"/>
</operation>
</portType>
<binding name="BooksPricingProcessWebServiceBeanPortBinding" type="tns:BooksPricingProcessWebServiceBean">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="findBookPrice">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="BooksPricingProcessWebServiceBeanService">
<port name="BooksPricingProcessWebServiceBeanPort" binding="tns:BooksPricingProcessWebServiceBeanPortBinding">
<soap:address location="http://xxx.xxx.xxx.xxx:8080/BooksPricingProcessWebServiceBeanService/BooksPricingProcessWebServiceBean" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"/>
</port>
</service>
</definitions>
それから,WSDLの最初の方でXMLスキーマをインポートしています。このURLをブラウザのアドレスバーにコピーして,XMLスキーマを表示させ,これもローカルに保存します。(拡張子をxsdにしましょう)
そして,WSDLを今回の環境に合わせて編集します。
編集後のWSDLはこんな感じになります。(変更箇所をBold体で示しています。)
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://ws/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" targetNamespace="http://ws/" name="BooksPricingProcessWebServiceBeanService" xmlns:plink="http://schemas.xmlsoap.org/ws/2004/03/partner-link/">
<types>
<xsd:schema>
<xsd:import namespace="http://ws/" schemaLocation="BooksPricingProcessWebServiceBeanService_schema1.xsd" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"/>
</xsd:schema>
</types>
<!-- 中略 -->
<service name="BooksPricingProcessWebServiceBeanService">
<port name="BooksPricingProcessWebServiceBeanPort" binding="tns:BooksPricingProcessWebServiceBeanPortBinding">
<soap:address
location="http://localhost:18181/PricingProcess/PricingProcess_1" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"/>
</port>
</service>
<plink:partnerLinkType name="BooksPricingProcessPartnerLinkType">
<plink:role name="provider" portType="tns:BooksPricingProcessWebServiceBean"/>
</plink:partnerLinkType>
</definitions>
【2. BPELの編集】
(1) WSDLのインポート
PricingProcess_1.bpelのNavigator画面で,[Imports]を右クリック,[Add Import]を選択して,編集したWSDLをインポートします。
(2) パートナーリンクの追加
右のパレットから,Partner LinkをDrag&Dropします。
としてPartnerLinkを追加します。
(3) Receive, Replyの設定
最初のアクティビティとしてReceive, 最後のアクティビティとしてReplyをDrag&Dropします。
BPEL Navigator画面で,Receive1を右クリック,[Edit]を選択すると,ReceiveのProperty Editorが起動します。
とします。
Receive1に関しては,ソースビューで属性としてcreateInstance="yes"を追加します。
<receive name="Receive1" partnerLink="PartnerLink1" operation="findBookPrice" portType="ns1:BooksPricingProcessWebServiceBean" variable="FindBookPriceIn1" createInstance="yes"/>
同様に,Reply1に関しても
と設定します。
(4) Assignの設定
Receive1とReply1の間にAssignをDrag&Dropします。最初から存在する空のアクティビティは削除します。
Assignは,変数に値をコピーするためのアクティビティです。NetBeans Enterprise PackにはMapperという機能があり,GUIでコピー内容を指定できます。メニュー[Window]-[Mapper]を選択すると,Mapperが起動されます。BPELエディタ上でAssign1を選択して,Assignの内容を設定しましょう。
例えば,FindBookPriceIn1のproductIdをFindBookPriceOut1のproductIdにコピーする場合には,Mapperの左から右へ線を引っ張るだけでO.K.です。
固定値を設定する場合には,Mapperのメニューから[string literal]あるいは[number literal]を選択して値を入力,右の該当箇所へ線を引っ張ります。
BPELエディタをソースビューに切り替えると,Assignの内容が確認できます。
<assign name="Assign1">
<copy>
<from>$FindBookPriceIn1.parameters/productId</from>
<to>$FindBookPriceOut1.parameters/return/productId</to>
</copy>
<copy>
<from>39.99</from>
<to>$FindBookPriceOut1.parameters/return/price</to>
</copy>
<copy>
<from>'Java EE and .NET Interoperability'</from>
<to>$FindBookPriceOut1.parameters/return/productName</to>
</copy>
</assign>
BPELやXPathの細かい文法を知らなくても編集できるのでとても便利です。
【3. 実行】
(1) Composite Applicationの作成
[File]-[New Project]を選択,[Service Oriented Architecture]-[Composite Application]を選択します。
として作成します。
次に,プロジェクト"PricingApp"を右クリック,[Add JBI Module]でプロジェクト"PricingProcess"を追加します。
(2) テストの作成
プロジェクト"PricingApp"の[Test]を右クリック,[Add Testcase]を選択します。Input.xmlのproductIdとして"SUNW-001"など適当な値を指定します。
(3) 実行
プロジェクト"PricingApp"をDeployして,テストを実行します。
どうですか?WSDLの準備がちょっと面倒ですが,後はとても簡単です。プラットフォームがJBIであることを意識する必要も無く,BPELを直接編集する必要もありません。