WSFLの概要を、仕様書の付録Dにある図を使って、簡単に解説していこう。
図1 チケット・オーダーのサンプル(WSDL仕様Appendix.Dから引用)
サンプルのWSFLは非常に長いので、本稿ではすべてを引用しない。詳細に知りたい方は、原文をご参照いただきたい。
この図では、旅行者が旅行会社を通して航空券を入手する流れを定義している。旅行者(Traveler)が旅行の申し込み(TripOrder)を旅行会社(Agent)に渡すと、旅程(Leg)が決定され、航空会社(AirLine)にチケットの注文(TicketOrder)が出る。航空会社から席の確認(Confirm)が旅行会社に戻り、チケット(eTicket)が旅行者に戻されると同時に、旅行会社から旅程表(Itinerary)が送信される、という流れである。
図中の色の付いた丸(●●●)は、アクティビティ(activity)と呼ばれ、これ自体がそれぞれWebサービスとして位置付けられる。複数のWebサービスの処理をつなぎ合わせていく。
このようなビジネスプロセスをWSFLで定義するため、このサンプルでは以下のステップを踏んでいる。
- 取り交わされるメッセージ(図中の封筒や、アクティビティの間を流れるメッセージ)を定義。
- WSDLでポート・タイプを決定(破線矢印)。
- 旅行会社と航空会社がそれぞれどのようなビジネスプロセスを行うかを「フロー・モデル」で定義。
- 旅行会社と航空会社の複合Webサービスが、どのように組み立てられるかを「グローバル・モデル」で定義。
それぞれのステップの内容を紹介していこう。
メッセージは、WSDLのmessage要素を使って定義する。長いので、Trip Orderに使われるメッセージに関連するところをサンプルコードから抜き出してみよう。重要なところは太字になっている。
ソースコード1 メッセージの定義(WSFL仕様から抜粋)
<?xml version="1.0"?>
<definitions name="totalTravel" targetNamespace=
"http://www.TravelLuck.com/WebServices/Messages/TotalTravel"
xmlns:tio=
"http://www.TravelLuck.com/WebServices/Messages/TotalTravel"
xmlns="">
<types>
<schema
xmlns= "http://www.w3.org/2000/10/XMLSchema"
targetNamespace =
"http://www.TravelLuck.com/WebServices/Messages/TotalTravel"
xmlns:tio=
"http://www.TravelLuck.com/WebServices/Messages/Totaltravel">
<element name="CreditCard">
<complexType>
<sequence>
<element name="CardNumber"
type="nonNegativeInteger"/>
<element name="ExpiryDate"
type="month"/>
<element name="Company"
type="string"/>
</sequence>
</complexType>
</element>
<complexType name="BaseAddress">
<sequence>
<element name="Street" type="string"/>
<element name="City" type="string"/>
<element name="State" type="string"/>
<element name="ZIP" type="nonNegativeInteger"/>
</sequence>
</complexType>
:
<complexType name="Person">
<sequence>
<element name="FirstName" type="string"/>
<element name="LastName" type="string"/>
<element name="Address" type="tio:Address"/>
<element name="BirthDate" type="date"/>
</sequence>
</complexType>
<element name="Participants" type="tio:Person"
minOccurs="1" maxOccurs="unbounded"/>
<element name="Recipient" type="tio:Person"/>
<element name="Journey">
:
<sequence>
<element name="Location" type="string"/>
<element name="Begin" type="date"/>
<element name="End" type="date"/>
</sequence>
:
</element>
<!--==========================================================
-->
<!-- tripOrder is the basic "where to" information supplied
by -->
<!-- the traveller to the travel agent -->
<!--==========================================================
-->
<element name="tripOrder">
<complexType>
<all>
<element ref="tio:Journey"/>
<element ref="tio:CreditCard"/>
<element ref="tio:Recipient"/>
</all>
</complexType>
</element>
:
</definitions> |
旅行の申し込みは、メッセージ(tripOrderMsg)と返答(tripOrderAck)からなる。それぞれは、tripOrderと、WSFLが定義しているFlowInstanceIdを中身として持っている。メッセージに含まれるtripOrderは、それより前の「types/schema」以下の要素で定義されている。
tripOrderはそれぞれ「Journey」「CreditCard」「Recipient(受取者)」を中に持っており、その中身もリストを上に追っていくと見つかる。原文を見ていただくと分かるが、フローの内側で使われるメッセージやタイプもこの中で定義している。
次もWSDLを使う。WSDLによって、先ほどのメッセージをやりとりする部分をポート・タイプとして定義していく。
ソースコード2 ポートタイプの定義(WSFL仕様から抜粋)
<definitions name="totalTravelPortTypes"
targetNamespace=
"http://www.TravelLuck.com/WebServices/Messages/TotalTravel"
xmlns:tio=
"http://www.TravelLuck.com/WebServices/Messages/TotalTravel"
xmlns="">
<!--========================================================= -->
<!-- These are the standalone TravelAgent interfaces -->
<!--========================================================= -->
<portType name="tripHandler">
<operation name="receiveTripOrder">
<input name="receiveTripOrderInput"
message="tio:tripOrderMsg"/>
<output name="receiveTripOrderOutput"
message="tio:tripOrderAck"/>
</operation>
<operation name="sendItinerary">
<output name="sendItineraryOutput"
message="tio:itineraryMsg" />
</operation>
</portType>
<portType name="ticketRequester">
<operation name="requestTicketOrder">
<output name="requestTicketOrderOutput"
message="tio:ticketOrderMsg" />
<input name="requestTicketOrderInput"
message="tio:ticketOrderAck" />
</operation>
<operation name="waitForConfirmation">
<input name="waitForConfirmationInput"
message="tio:confirmationMsg" />
</operation>
</portType>
<!--============================================================
-->
<!--This is the standalone Airline interface -->
<!--============================================================
-->
<portType name="ticketHandler">
<operation name="receiveTicketOrder">
<input name="receiveTicketOrderInput"
message="tio:ticketOrderMsg"/>
<output name="receiveTicketOrderOutput"
message="tio:ticketOrderAck"/>
</operation>
<operation name="sendConfirmation">
<ouput name="sendConfirmationOutput"
message="tio:confirmationMsg"/>
</operation>
</portType>
<portType name="ticketDelivery">
<operation name="sendETicket">
<output name="sendETicketOutput"
message="tio:eTicketMsg"/>
</operation>
</portType>
<!--============================================================
-->
<!--This is the interface required from a ticketBuyer -->
<!--============================================================
-->
<portType name="ticketBuyer">
<operation name="sendTripOrder">
<output message="tio:tripOrderMsg"/>
<input message="tio:tripOrderAck"/>
</operation>
<operation name="receiveETicket">
<input message="tio:eTicketMes"/>
</operation>
<operation name="receiveItinerary">
<input message="tio:itineraryMsg"/>
</operation>
</portType>
</definitions> |
この定義を、下の図に示した。旅行会社(Agent)の左側を「旅行取り扱い業者(tripHandler)」、右側を「チケット要求者」としている。同様に、航空会社の左側を「チケット取り扱い業者(ticketHandler)」、配送部分を「チケット配送業者(ticketDelivery)」としている。さらに、購入者の右側を「チケット購入者(ticketBuyer)」として定義した。
図2 PortTypeの定義