7.3.4. Service Composition

Service orchestration (with central coordinator) and service choreography (without central coordinator).

BPEL for orchestration. Primitive activities - wait for request, send reply, invoke service, assign variable, throw exception, delay. Structured activities - synchronous sequence, parallel flow, switch, while.

<process name="anExampleProcess">

  <!-- Partners of the example process -->
  <partnerLinks>
    <partnerLink name="client"
      partnerLinkType="aClientPort"
      myRole="aProviderRole"/>
    <partnerLink name="serverOne"
      partnerLinkType="aServerPort"
      myRole="aClientRole"
      partnerRole="aServerRole"/>
    <partnerLink name="serverTwo"
      partnerLinkType="aServerPort"
      myRole="aClientRole"
      partnerRole="aServerRole"/>
  </partnerLinks>

  <!-- Internal variables -->
  <variables>
    <variable name="ClientRequest" messageType="RequestMessage"/>
    <variable name="ServerOneResponse" messageType="ResponseMessage"/>
    <variable name="ServerTwoResponse" messageType="ResponseMessage"/>
    <variable name="ProviderResponse" messageType="ResponseMessage"/>
  </variables>

  <!-- Process definition -->
  <sequence>
    <!-- Get the request from the client -->
    <receive partnerLink="client"
      portType="aClientPort"
      operation="GetOffer"
      variable="ClientRequest"
      createInstance="yes"/>

    <!-- Forward the request to both servers -->
    <flow>
      <invoke partnerLink="serverOne"
        portType="aServerPort"
        operation="GetOffer"
        inputVariable="ClientRequest"
        outputVariable="ServerOneResponse"
      />
      <invoke partnerLink="serverTwo"
        ...
      />
    </flow>

    <!-- Create response from cheapest offer -->
    <switch>
      <case condition="bpws:getVariableData ('ServerOneResponse','price')
                       <
                       bpws:getVariableData ('ServerTwoResponse','price')">
        <assign>
          <copy>
            <from variable="ServerOneResponse"/>
            <to variable="ProviderResponse"/>
          </copy>
        </assign>
      </case>
      <otherwise>
        ...
      </otherwise>
    </switch>

    <!-- Return the response to the client -->
    <reply partnerLink="client"
      portType="aClientPort"
      operation="GetOffer"
      variable="ProviderResponse"/>
  </sequence>
</process>