How the Scatter-Gather Sample Works
The sample application builds a set of SOAP headers containing the itinerary loaded from the Scatter-Gather itinerary file, loads the specified message file from disk, appends the itinerary headers to the message, and submits it to the ESB through an on-ramp for processing. If the itinerary generates a response, the application collects this and displays it in the application window.
To help you understand how the Itinerary service uses the itinerary information in a message, the following listing shows the sample itinerary configuration file named ScatterGatherItinerary.xml. The first section of this itinerary specifies two service invocation steps.
<Itinerary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" uuid="" beginTime="" completeTime="" state="Pending" isRequestResponse="false" xmlns="http://schemas.microsoft.biztalk.practices.esb.com/itinerary"> <ServiceInstance uuid="" name="ScatterGather" type="Orchestration" state="Pending" position="0" isRequestResponse="false" xmlns="" /> <Services xmlns=""> <Service uuid="" beginTime="" completeTime="" name="ScatterGather" type="Orchestration" state="Pending" isRequestResponse="false" position="0" serviceInstanceId="" /> </Services> <Services xmlns=""> <Service uuid="" beginTime="" completeTime="" name="DynamicTest" type="Messaging" state="Pending" isRequestResponse="false" position="1" serviceInstanceId="" /> </Services> </Itinerary> ...
Following the list of service invocation steps in the itinerary is the section containing details of the resolvers and connection strings that allow the Itinerary service to locate each service defined in the itinerary, as shown in the following XML.
<ResolverGroups xmlns=""> <Resolvers serviceId="ScatterGather0"><![CDATA[BRE:\\policy=ResolveEndPointScatterGather;version=;useMsg=;]]><![CDATA[UDDI3:\\serverUrl=http://localhost/uddi;bindingKey=uddi:esb:purchaseordersubmitorderservicebinding;credentialType=Ntlm]]></Resolvers> <Resolvers serviceId="DynamicTest1"><![CDATA[UDDI3:\\serverUrl=http://localhost/uddi;bindingKey=uddi:esb:orderfileservicebinding;credentialType=Ntlm]]> </Resolvers> </ResolverGroups>
In this example, the application executes the SubmitPOService Web service twice because both resolver connection strings resolve to the location of this service (http://localhost/ESB.CanadianServices/SubmitPOService.asmx). The message context specifies the Broker orchestration as the first itinerary service to activate, defined in the sample as the following.
(Microsoft.Practices.ESB.Itinerary.Schemas.ServiceName == "ScatterGather") && (Microsoft.Practices.ESB.Itinerary.Schemas.ServiceState == "Pending") && (Microsoft.Practices.ESB.Itinerary.Schemas.ServiceType == "Orchestration")
The Broker orchestration analyzes the settings for its itinerary step and retrieves a collection of resolvers associated with the itinerary step. For each of these resolvers, the orchestration uses the BizTalk ESB Toolkit Resolver and Adapter Framework to resolve the service endpoint. The Broker orchestration then activates n number of ServiceDispatcher orchestrations asynchronously (where n is the number of resolvers associated with the ScatterGather service in the itinerary) to dispatch the request message with following parameters:
- TransportLocation. The resolver populates this parameter.
- TransportType. The resolver populates this parameter.
- ResolverDictionary. This parameter contains a collection of resolver facts populated by the concrete resolver instance.
- InboundMessage. This parameter contains the original message that contains the itinerary.
- ServiceResponsePort. This parameter is the name of the self-correlating response port that will receive responses from the instances of the ServiceDispatcher orchestration.
Each instance of the ServiceDispatcher orchestration uses the ResolveMapScatterGather policy to resolve the Microsoft BizTalk map types for the request and response message, based on TransportType and TransportLocation properties. The orchestration instances use the resolved maps to transform the inbound message into the request message for the Web service call.
The ESB Adapter Manager sets the outbound transport context properties on the request message, which BizTalk then forwards to the solicit-response port named ServiceRequestPort.
When it receives a response message from a service, the ServiceDispatcher orchestration uses the resolved map information to transform the inbound response message to a canonical format. It then wraps the modified response within the ServiceResponse envelope and forwards it to the Broker orchestration through the self-correlating port. The Broker orchestration aggregates all incoming responses and prepares the final response message using GlobalBank.ESB.ScatterGather.Processes.AggregatingPipeline, as shown in the following code.
AggregatedResponse.Body = null; AggregatedResponse(*) = InboundMessage(*); Microsoft.XLANGs.Pipeline.XLANGPipelineManager.ExecuteSendPipeline( typeof(GlobalBank.ESB.ScatterGather.Processes.AggregatingPipeline), messageAggregator,AggregatedResponse);
This code wraps the entire batch of responses within a predefined envelope. The Broker orchestration then advances the itinerary to the DynamicTest itinerary step, as shown in the following code.
// Copy the context and advance the itinerary. OutboundMessage = AggregatedResponse.Body; OutboundMessage(*) = AggregatedResponse(*); // Advance the Itinerary to the next step. itinerary.Itinerary.Advance(OutboundMessage, itineraryStep);
Because the service type attribute named DynamicTest is set to Messaging, the ItineraryHelper class promotes the resolver properties into the context of the message named OutboundMessage. The Broker orchestration sends this message to a BizTalk direct-bound port. BizTalk then forwards the message to the dynamic send port represented by the ServiceName subscription, which is DynamicTest. This send port serializes the final aggregated response to the \Source\Samples\DynamicResolution\Test\Filedrop\Out folder.