次に内部フローを定義する。まず、ここでは、登場人物(旅行者、旅行業者、航空会社)をサービス・プロバイダという位置付けで定義している。それぞれ、travelerType、agentFlow、airlineFlowという名前になっている。
ソースコード 3 サービス・プロバイダの定義
<definitions name="totalTravelPortTypes" targetNamespace=
"http://www.TravelLuck.com/WebServices/Messages/TotalTravel"
xmlns:tio=
"http://www.TravelLuck.com/WebServices/Messages/TotalTravel"
xmlns="">
<serviceProviderType name="airlineFlow">
<portType name="tio:ticketHandler"/>
<portType name="tio:ticketDelivery"/>
</serviceProviderType>
<serviceProviderType name="agentFlow">
<portType name="tio:tripHandler"/>
<portType name="tio:ticketRequester"/>
</serviceProviderType>
<serviceProvider name="travelerType">
<portType name="tio:ticketBuyer"/>
</serviceProvider> |
次に、airlineFlowのフロー・モデルを見てみよう。
ソースコード4 airlineFlowのフロー・モデル定義
<!--===========================================================
-->
<!-- definition of bookTickets flow model -->
<!-- using airlineFlow serviceProviderType -->
<!--===========================================================
-->
<flowModel name="bookTickets"
serviceProviderType="airlineFlow"> ……(1)
<flowSource name="ticketFlowSource">
<output name="processInstanceData"
message="tio:receivedTicketOrder"/> ……(2)
</flowSource>
<serviceProvider name="agent" type="agentFlow"/>
<serviceProvider name="traveler" type="travelerType"/>
<export lifecycleAction="spawn"> ……(3)
<target portType="tio:ticketHandler"
operation="receiveTicketOrder"> ……(4)
<map sourceMessage="receiveTicketOrderInput"
targetMessage="processInstanceData" targetPart="request"/>
<map sourceMessage="processInstanceData"
sourcePart="airlineWorkId" targetMessage="receiveTicketOrderOutput"
targetPart="airlineWorkId"/>
</target>
</export>
<activity name="reserveSeats">
:
</activity>
<activity name="chargeCreditCard"
>
:
</activity>
<activity name="confirmFlights" >
:
</activity>
<activity name="issueETicket">
:
</activity>
<datalink name="gT-rS-data" source= "ticketFlowSource"
target="reserveSeats"/>
<controlLink name="rS-cC" source="reserveSeats"
target="chargeCreditCard"/>
:
:
</flowModel>
|
このフロー・モデルは、airlineFlowが持つ「bookTicket(チケットの予約)」(1)というフローだ。このフローは、「receivedTicketOrder」というデータタイプから始まることを示しており(2)、最初のアクティビティは、receiveTicketOrderから始まり(4)、spawnで定義されている(3)。
その後アクティビティが4つ(reserveSeats、chargeCreditCard、confirmFlight、issueETicket)定義され、それぞれの間を「データの流れ」と「処理の流れ」でつなぐための定義が「controlLink」、「dataLink」として定義されている。このほか、同様にAgentのフロー・モデルも定義される。
グローバル・モデルは、ここまでに定義されてきたサービス・プロバイダ「agentFlow」と「airlineFlow」同士をつなぎ合わせて、さらに大きなサービス・プロバイダ「agentNAirlineFlow」にしてしまおうという定義である。
このサービス・プロバイダは「tripNTicketHandler(旅行とチケット取り扱い業者)」という新しいポート・タイプを持っており、receiveTripOrder、sendItinerary、sendETicketsという操作が定義されている。そして、それぞれの操作は中に含まれる2つのサービス・プロバイダから「export」指定によりマッピングされる、という具合である。
中に含まれる2つのサービス・プロバイダが持つ、エクスポートされないポートに関しては、後半でplugLink要素でお互いが接続されているのが分かるだろうか。
ソースコード 5 グローバル・モデル
<definitions name="totalTravelPortTypes" targetNamespace=
"http://www.TravelLuck.com/WebServices/Messages/TotalTravel"
xmlns:tio= "http://www.TravelLuck.com/WebServices/Messages/TotalTravel"
xmlns="">
<!--========================================================= -->
<!-- This is the working AgentNAirline porttype in WSDL -->
<!--========================================================= -->
<portType name="tripNTicketHandler">
<operation name="receiveTripOrder">
<input name="receiveRequest"
message="tio:tripOrderMsg"/>
<output name="returnResponse"
message="tio:tripOrderAck"/>
</operation>
<operation name="sendItinerary">
<output name="sendMessage" message="tio:Itinerary"/>
</operation>
<operation name="sendETickets">
<input name="sendMessage" message="tio:ETickets"
/>
</operation>
</portType> |
まず、別々のサービス・プロバイダが持っている「receiveTripOrder」、「sendItinerary」、「sendETicket」を貼り合わせて、新しいポートタイプ「tripNTicketHandler」を定義する。
<!--=========================================================
-->
<!-- definition of agentNAirlineFlow serviceProviderType -->
<!--========================================================= -->
<serviceProviderType name="agentNAirlineFlow">
<portType name="tio:tripNTicketHandler">
</serviceProviderType> |
次に、このポートを持っている新たなサービス・プロバイダ「agentNAirlineFlow」を定義する。これが、AgentとAirlineを合体させた複合Webサービスを表現する。
<!--=========================================================
-->
<!-- definition of bookTripNTickets composition -->
<!-- using agentFlow serviceProviderType -->
<!--========================================================= -->
<globalModel name="bookTripNTickets" serviceproviderType="agentNAirlineFlow">
<serviceProvider name="travelAgent" serviceProviderType="tio:agentFlow">
<export>
<source portType="tio:tripHandler"
operation="sendItinerary"/>
<target portType="tio:tripNTicketHandler"
operation="sendItinerary"/>
</export>
<export>
<source portType="tio:tripHandler"
operation="receiveTripOrder"/>
<target portType="tio:tripNTicketHandler"
operation="receiveTripOrder"/>
</export>
<locator type="static" service="Traveluck.com"/>
</serviceProvider>
<serviceProvider name="airline" serviceProviderType="tio:airlineFlow">
<export>
<source portType="tio:ticketDelivery"
operation="sendETicket"/>
<target portType="tio:tripNTicketHandler"
operation="sendETickets"/>
</export>
</serviceProvider>
<plugLink>
<source serviceProvider="airline"
portType="tio:ticketHandler" operation="sendConfirmation"/>
<target serviceProvider="travelAgent"
portType="tio:tripHandler" operation="waitForConfirmation"/>
</plugLink>
<plugLink>
<source serviceProvider="travelAgent"
portType="tio:tripHandler" operation="requestTicketOrder"/>
<target serviceProvider="airline"
portType="tio:ticketHandler" operation="receiveTicketOrder"/>
</plugLink>
</globalModel>
</definitions> |
新しく作成されたサービス・プロバイダ「tripNTicketHandler」は、それ自体新たなグローバル・モデルを作るときのインプットにすることができ、さらに大きなサービス・プロバイダを定義することも可能だ。
サービス・プロバイダとして定義された複合Webサービスは、検索対象としてUDDIなどに登録することができると考えられる。
以上のような定義で、複数のWebサービスを「コンポーネント」として組み立て、その定義をXMLドキュメントで表すことができるようになる。これがWSFLが行おうとしていることである。
定義されたWSFLはどのように使われるか、ということに関してはまだ具体的ではないが、Webサービスを統合するワークフロー・エンジンの定義に使われたり、浅い意味ではあるが、簡単なセマンティクスの定義といえないこともない。複雑なWebサービスを作り上げていく、将来のテクノロジといえるだろう。