Apache ODE で簡単な BPEL を実行

以下のサイトを参考にして、Apache ODE 1.2 上で簡単な BPEL(WS-BPEL)を実行してみた。

開発・実行環境は以下の通り。

最初、Eclipse 3.4(Ganymede) を使うつもりだったのだが、BPEL Visual Designer プラグインがインストールできなかったので、断念した。

事前準備

Apache ODE を Tomcat 上で実行させるには、Tomcat の webapps ディレクトリに apache-ode-war-1.2.zip ファイル内の ode.war ファイルを配置する。

今回は、Eclipse 上で Tomcat を起動するようにしたので、メニュー「File」->「New」->「Other」で追加した Server 設定の Server Locations/Server path で指定されているディレクトリ内の webapps に ode.war を配置した。

BPELWSDL ファイルの作成

Eclipse のメニュー「File」->「New」->「Other」で New BPEL Process File を選択し、BPEL Process Name 等の入力項目に値を入力すると、.bpel と .wsdl ファイルの雛型が生成されるので、これを編集する。

今回は、BPEL に Assign を追加して、入力値に " world!" 文字を加えたものを出力値に設定する処理を実装した。

BPEL ファイルの内容は以下のとおり。

SampleTest.bpel ファイル
<?xml version="1.0" encoding="UTF-8"?>
<bpws:process exitOnStandardFault="yes" name="SampleTest"
    suppressJoinFailure="yes" targetNamespace="http://fits/sample"
    xmlns:bpws="http://docs.oasis-open.org/wsbpel/2.0/process/executable" 
    xmlns:tns="http://fits/sample">

    <bpws:import importType="http://schemas.xmlsoap.org/wsdl/"
        location="SampleTest.wsdl" namespace="http://fits/sample"/>
    <bpws:partnerLinks>
        <bpws:partnerLink myRole="SampleTestProvider" name="client" partnerLinkType="tns:SampleTest"/>
    </bpws:partnerLinks>
    <bpws:variables>
        <bpws:variable messageType="tns:SampleTestRequestMessage" name="input"/>
        <bpws:variable messageType="tns:SampleTestResponseMessage" name="output"/>
    </bpws:variables>
    <bpws:sequence name="main">
        <bpws:receive createInstance="yes" name="receiveInput"
            operation="hello" partnerLink="client"
            portType="tns:SampleTest" variable="input"/>
        <bpws:assign name="Assign" validate="no">
            <bpws:copy>
                <bpws:from><![CDATA[concat($input.payload/tns:input, " world!")]]></bpws:from>
                <bpws:to part="payload" variable="output"/>
            </bpws:copy>
        </bpws:assign>
        <bpws:reply name="replyOutput" operation="hello"
            partnerLink="client" portType="tns:SampleTest" variable="output"/>
    </bpws:sequence>
</bpws:process>

variable 要素で のように記述されていると "$変数名" で参照することができる。
今回は messageType 属性で WSDL の message 要素を指定しているので "$変数名.part名/element名" つまり "$input.payload/tns:input" で値を参照している。


次に、WSDL に Binding と Service を加え、port を設定する。port の Address で指定した URL が BPEL サービスを公開する URL となるようなので http://localhost:8080/ode/processes/sample を設定。

なお、デフォルトでは WSDL ファイルの element 要素の type 属性の値は string となるが、クライアントの作成で不都合があったので xsd:string となるように調整した。

WSDL ファイルの内容は以下のとおり。

SampleTest.wsdl ファイル
<?xml version="1.0"?>
<definitions name="SampleTest"
        targetNamespace="http://fits/sample"
        xmlns:tns="http://fits/sample"
        xmlns:plnk="http://docs.oasis-open.org/wsbpel/2.0/plnktype"
        xmlns="http://schemas.xmlsoap.org/wsdl/"
        xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
        xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" 
        xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <types>
        <schema attributeFormDefault="unqualified" 
                elementFormDefault="qualified" 
                targetNamespace="http://fits/sample" 
                xmlns="http://www.w3.org/2001/XMLSchema">

            <element name="SampleTestRequest">
                <complexType>
                    <sequence>
                        <element name="input" type="xsd:string"/>
                    </sequence>
                </complexType>
            </element>

            <element name="SampleTestResponse">
                <complexType>
                    <sequence>
                        <element name="result" type="xsd:string"/>
                    </sequence>
                </complexType>
            </element>
        </schema>
    </types>

    <message name="SampleTestRequestMessage">
        <part name="payload" element="tns:SampleTestRequest"/>
    </message>
    <message name="SampleTestResponseMessage">
        <part name="payload" element="tns:SampleTestResponse"/>
    </message>

    <!-- portType implemented by the SampleTest BPEL process -->
    <portType name="SampleTest">
        <operation name="hello">
            <input  message="tns:SampleTestRequestMessage" />
            <output message="tns:SampleTestResponseMessage"/>
        </operation>
    </portType>
  
    <plnk:partnerLinkType name="SampleTest">
        <plnk:role name="SampleTestProvider" portType="tns:SampleTest"/>
    </plnk:partnerLinkType>
    
    <binding name="SampleTestBinding" type="tns:SampleTest">
        <soap:binding style="document"
            transport="http://schemas.xmlsoap.org/soap/http">
        </soap:binding>
        <operation name="hello">
            <soap:operation soapAction="http://fits/sample/process"></soap:operation>
            <input>
                <soap:body use="literal"></soap:body>
            </input>
            <output>
                <soap:body use="literal"></soap:body>
            </output>
        </operation>
    </binding>

    <service name="SampleTestService">
        <port name="SamplePort" binding="tns:SampleTestBinding">
            <soap:address location="http://localhost:8080/ode/processes/sample" />
        </port>
    </service>
</definitions>

deploy ファイルの作成

Apache ODE にデプロイするための設定ファイルを deploy.xml として用意する。

  • process 要素で BPEL の process を指定
  • provide 要素で BPEL の partnerLink を指定
  • service 要素で WSDL の service と port を指定
deploy.xml
<?xml version="1.0" encoding="UTF-8"?>
<deploy xmlns="http://www.apache.org/ode/schemas/dd/2007/03"
    xmlns:pns="http://fits/sample" 
    xmlns:wns="http://fits/sample">
    <!-- BPEL の process 要素の name 属性の値を設定 -->
    <process name="pns:SampleTest">
        <active>true</active>
        <!-- BPEL の partnerLink 要素の name 属性の値を設定 -->
        <provide partnerLink="client">
            <!-- WSDL の service 要素の name 属性、
              port 要素の name 属性の値を設定 -->
            <service name="wns:SampleTestService" port="SamplePort"/>
        </provide>
    </process>
</deploy>

配置

作成した .bpel, .wsdl, deploy.xml ファイルを単一のディレクトリに配置して、そのディレクトリごと webapps/ode/WEB-INF/processes ディレクトリ(ode.war ファイル展開先の WEB-INF/processes)に配置すればデプロイが完了する。

  • sample ディレクトリ

動作確認

サービス一覧画面(http://localhost:8080/ode/services/listServices)でデプロイしたサービスが追加されていればデプロイ成功。

動作確認のため、SOAP クライアントを Ruby で作成して実行。(JRuby でも動作可)

sampleTest.rb
require 'soap/wsdlDriver'

wsdl = 'http://localhost:8080/ode/processes/sample?wsdl'

service = SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver
service.generate_explicit_type = true

#連想配列で入力値を定義
req = {"input" => "Hello"}

puts service.hello(req)

実行結果は以下のようになり、正常に動作していることを確認。

実行結果
>ruby sampleTest.rb
・・・
Hello world!

なお、Apache ODE にデプロイすると HTTP バインディングが自動的に追加されるようなので、以下のような URL にアクセスするだけで実行結果を取得することができる。

  • サービス公開URL/オペレーション名?パラメータ名=値&・・・

今回は、http://localhost:8080/ode/processes/sample/hello?input=test にアクセスして結果を確認。