Introduction
In the first part of the article, we discussed the advantages and disadvantages of Dynamic Send Ports and we introduced two custom components that allow, respectively, to use Static Send Ports instead of Dynamic Send Port with an ESB Itinerary and to speed up message transformation. In this post I will move into detailing the test scenarios that I built to measure and compare performance of standard and custom Routing and Transform Services, while in the third part I’ll provide results and I’ll show how using profiling tools (Visual Studio Profiler and SQL Server Profiler) to narrow down and determine the cause of performance problems.
Test Use Cases
In order to verify that my custom Routing and Transform components were working properly and to measure and compare performance with those of the equivalent Routing and Transform services provided out-of-the-box by the ESB Toolkit 2.0, I created 3 different scenarios composed of 8 test use cases all belonging to the same BizTalk application called ESB.Itinerary.Services. A secondary objective was to observe and analyze the runtime behavior of Dynamic Send Ports in order to verify that certain Adapters like the WCF-Custom Adapter behave in a different way with respect to when they run in Static Send Port. In order to generate traffic against test use cases, I used Visual Studio 2008 Test Edition. For more information on this topic, you can review the following article:
-
“Using Visual Studio 2005/2008 To Generate Load Against a Two-Way Request-Response WCF Receive Location” available on my blog.
Note |
Scenario 1
The main objective of the first scenario was measuring the performance of the 4 possible combinations of the custom and out-of-the-box (here indicated with the prefix OOB) Routing and Transform services and observe the runtime behavior of the WCF-Custom Adapter and SqlBinding when used with either a Dynamic or Static Send Port. To this purpose, I used the Northwind database that is available on CodePlex along with the other SQL Server code samples. In particular, I created a new stored procedure called CustomersByCountry whose T-SQL code is shown below:
CustomersByCountry Stored Procedure
USE [Northwind] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO IF OBJECT_ID('CustomersByCountry') > 0 DROP PROCEDURE CustomersByCountry GO CREATE PROCEDURE [dbo].CustomersByCountry @Country nvarchar(15) = 'ALL' AS IF @Country = 'ALL' SELECT [CustomerID] ,[CompanyName] ,[ContactName] ,[ContactTitle] ,[Address] ,[City] ,[Region] ,[PostalCode] ,[Country] ,[Phone] ,[Fax] FROM [Northwind].[dbo].[Customers] ORDER BY [CompanyName] ELSE SELECT [CustomerID] ,[CompanyName] ,[ContactName] ,[ContactTitle] ,[Address] ,[City] ,[Region] ,[PostalCode] ,[Country] ,[Phone] ,[Fax] FROM [Northwind].[dbo].[Customers] WHERE [Country] = @Country ORDER BY [CompanyName] GO |
As you can easily note, the stored procedure returns the customers belonging to a certain country or all customers if the @Country is NULL or equal to ‘ALL’.
All the 4 test use cases of the first scenario implement the same pattern:
-
A client application sends a request message to a WCF-NetTcp Receive Location.
-
The incoming message is transformed in the format expected by the WCF-SQL Adapter and routed to a WCF-Custom Send Port.
-
The WCF-SQL Adapter invokes the CustomersByCountry stored procedure.
-
The response message is transformed and returned back to the caller.
The following figure shows the map used by all the test cases of Scenario 1 to transform the response message from the native WCF-SQL format to a canonical format. I intentionally used the Uppercase, String Left Trim and String Right Trim Functoids to increase the complexity of the map.
CustomersByCountryResponseToCustomersResponse Map
OOBRoutingOOBTransform Test Case
The first test use case represents the typical flows modeled with the ESB Toolkit where the Transform and Routing services against the inbound request message are run within the On-Ramp Port. As the name of the use case suggests, all the Transform and Routing components utilized by this test are those provided out-of-the-box by the ESB Toolkit 2.0.
Itinerary
The following figure depicts the Itinerary used by the OOBRoutingOOBTransform test use case:
As mentioned above, the Transform and Routing services are both applied to the inbound message within the OnRamp Receive Location. The following picture shows how the STATIC Route Resolver used by the RouteRequest service has been configured:In particular, the Action property contains the name of the target stored procedure while the Endpoint Configuration property has been configured as follows:
|
Architecture
The following figure depicts the architecture of the OOBRoutingOOBTransform test use case.
Message Flow
-
A Two-Way WCF-NetTcp Receive Location receives an XML request document from Visual Studio 2008 Load Test.
-
The ESB Itinerary Selector pipeline component running within the ItinerarySelectReceivePassthrough pipeline retrieves the OOBRoutingOOBTransform Itinerary from the EsbItineraryDb or from the in-process cache and copies it in the ItineraryHeader context property. The ESB Dispatcher pipeline component executes in sequence the standard Transform Service and Routing Service and then advances the Itinerary to the next step. In particular, the Transform Service maps the incoming message to the format expected by the WCF-SQL Adapter, and the Routing Service changes the value of the OutboundTransportLocation, OutboundTransportType and Action context properties using the data defined in the STATIC Route Resolver.
-
The Message Agent submits the incoming message to the MessageBox (BizTalkMsgBoxDb).
-
The message is retrieved by a Two-Way Dynamic Send Port that uses the WCF-Custom Adapter.
-
The ESB Dispatcher pipeline component running within the ItinerarySendPassthrough pipeline retrieves the Itinerary from the ItineraryHeader context property and advances this latter to the next step.
-
The WCF-SQL (WCF-Custom + SqlBinding) Adapter invokes the CustomersByCountry stored procedure.
-
The WCF-SQL (WCF-Custom + SqlBinding) Adapter retrieves result data from SQL Server and prepares a response message.
-
The ESB Itinerary Cache component running within the ItinerarySendReceivePassthrough receive pipeline retrieves the Itinerary from the cache, and the ESB Dispatcher component executes the TransformResponse Itinerary step. This latter applies the map indicated by the STATIC Map Resolver to the response message using the standard Transform Service.
-
The Message Agent submits the response message to the MessageBox (BizTalkMsgBoxDb).
-
The message is retrieved by the WCF-NetTcp Receive Location that is synchronously waiting for the response document.
-
The PassThruTransmit send pipeline is executed by the WCF-NetTcp Receive Location.
-
The response message is finally returned to the original caller.
Note The ItinerarySendReceivePassthrough is a custom receive pipeline that was created as an optimization to specifically eliminate the XmlReceive component which is instead present in the ItinerarySendReceive provided out-of-the-box by the ESB Toolkit 2.0. The pipeline contains just the following components:
|
OOBRoutingCustomTransform Test Case
Compared to the first one, the second test case continues to use the default Routing Service provided out-of-the-box by the ESB Toolkit, but replaces the original Transform Service with my custom version that uses the XslCompiledTransform class.
Itinerary
The following figure depicts the Itinerary used by the OOBRoutingOOBTransform test use case:
The Transform and Routing services are both executed against the request message within the OnRamp Receive Location. In particular, the following picture shows the configuration of the TransformRequest service:
Architecture
The following figure depicts the architecture of the OOBRoutingCustomTransform test use case.
Message Flow
-
A Two-Way WCF-NetTcp Receive Location receives an XML request document from Visual Studio 2008 Load Test.
-
The ESB Itinerary Selector pipeline component running within the ItinerarySelectReceivePassthrough pipeline retrieves the OOBRoutingCustomTransform Itinerary from the EsbItineraryDb or from the in-process cache and copies it in the ItineraryHeader context property. The ESB Dispatcher pipeline component executes in sequence the custom Transform Service and the standard Routing Service and then advances the Itinerary to the next step. In particular, the Transform Service maps the incoming message to the format expected by the WCF-SQL Adapter, and the Routing Service changes the value of the OutboundTransportLocation, OutboundTransportType and Action context properties using the data defined in the STATIC Route Resolver.
-
The Message Agent submits the incoming message to the MessageBox (BizTalkMsgBoxDb).
-
The message is retrieved by a Two-Way Dynamic Send Port that uses the WCF-Custom Adapter.
-
The ESB Dispatcher pipeline component running within the ItinerarySendPassthrough pipeline retrieves the Itinerary from the ItineraryHeader context property and advances this latter to the next step.
-
The WCF-SQL (WCF-Custom + SqlBinding) Adapter invokes the CustomersByCountry stored procedure.
-
The WCF-SQL (WCF-Custom + SqlBinding) Adapter retrieves result data from SQL Server and prepares a response message.
-
The ESB Itinerary Cache component running within the ItinerarySendReceivePassthrough receive pipeline retrieves the Itinerary from the cache, and the ESB Dispatcher component executes the TransformResponse Itinerary step. This latter applies the map indicated by the STATIC Map Resolver to the response message using the custom Transform Service.
-
The Message Agent submits the response message to the MessageBox (BizTalkMsgBoxDb).
-
The message is retrieved by the WCF-NetTcp Receive Location that is synchronously waiting for the response document.
-
The PassThruTransmit send pipeline is executed by the WCF-NetTcp Receive Location.
-
The response message is finally returned to the original caller.
CustomRoutingOOBTransform Test Case
The third test case uses my custom Routing Service along with a Two-Way WCF-Custom Static Send Port, while for mapping, it uses the original Transform Service provided out-of-the-box by the ESB Toolkit.
Itinerary
The following figure depicts the Itinerary used by the CustomRoutingOOBTransform test use case:
Note that while the TransformRequest step continues to be executed on the OnRamp Receive Location, the RouteRequest step is now executed on the OffRamp Port. However, the definition of the STATIC Route Resolver was not changed. The WCF-Custom Static Send Port used by the use case has been configured to use the sqlBinding. The following figure shows the General Tab of the WCF-Custom Adapter configuration:
Note that the Address (URI) and Action fields have not been properly configured on the Static Send Port to invoke the CustomersByCountry stored procedure on SQL Server because it’s the responsibility of the RouteRequest Itinerary step to perform this operation at runtime.
Architecture
The following figure depicts the architecture of the CustomRoutingOOBTransform test use case.
Message Flow
-
A Two-Way WCF-NetTcp Receive Location receives an XML request document from Visual Studio 2008 Load Test.
-
The ESB Itinerary Selector pipeline component running within the ItinerarySelectReceivePassthrough pipeline retrieves the CustomRoutingOOBTransform Itinerary from the EsbItineraryDb or from the in-process cache and copies it in the ItineraryHeader context property. The ESB Dispatcher pipeline component executes the standard Transform Service and then advances the Itinerary to the next step. In particular, the Transform Service maps the incoming message to the format expected by the WCF-SQL Adapter.
-
The Message Agent submits the incoming message to the MessageBox (BizTalkMsgBoxDb).
-
The message is retrieved by a Two-Way Dynamic Send Port that uses the WCF-Custom Adapter.
-
The ESB Dispatcher pipeline component running within the ItinerarySendPassthrough pipeline retrieves the Itinerary from the ItineraryHeader context property, executes the custom RouteRequest Itinerary step and finally advances the Itinerary to the next step. In particular, the custom Routing Service changes the value of the OutboundTransportLocation and Action context properties using the data defined in the STATIC Route Resolver.
-
The WCF-SQL (WCF-Custom + SqlBinding) Adapter invokes the CustomersByCountry stored procedure.
-
The WCF-SQL (WCF-Custom + SqlBinding) Adapter retrieves result data from SQL Server and prepares a response message.
-
The ESB Itinerary Cache component running within the ItinerarySendReceivePassthrough receive pipeline retrieves the Itinerary from the cache, and the ESB Dispatcher component executes the TransformResponse Itinerary step. This latter applies the map indicated by the STATIC Map Resolver to the response message using the standard Transform Service.
-
The Message Agent submits the response message to the MessageBox (BizTalkMsgBoxDb).
-
The message is retrieved by the WCF-NetTcp Receive Location that is synchronously waiting for the response document.
-
The PassThruTransmit send pipeline is executed by the WCF-NetTcp Receive Location.
-
The response message is finally returned to the original caller.
CustomRoutingCustomTransform Test Case
The fourth test case uses both my custom Routing and Transform components along with a Two-Way WCF-Custom Static Send Port.
Itinerary
The following figure depicts the Itinerary used by the CustomRoutingCustomTransform test use case:
This Itinerary is identical to the one used by the CustomRoutingOOBTransform test case with the exception of the Transform service that has been replaced by my custom TransformService component.
Architecture
The following figure depicts the architecture of the CustomRoutingCustomTransform test use case.
Message Flow
-
A Two-Way WCF-NetTcp Receive Location receives an XML request document from Visual Studio 2008 Load Test.
-
The ESB Itinerary Selector pipeline component running within the ItinerarySelectReceivePassthrough pipeline retrieves the CustomRoutingCustomTransform Itinerary from the EsbItineraryDb or from the in-process cache and copies it in the ItineraryHeader context property. The ESB Dispatcher pipeline component executes the custom Transform Service and then advances the Itinerary to the next step. In particular, the Transform Service maps the incoming message to the format expected by the WCF-SQL Adapter.
-
The Message Agent submits the incoming message to the MessageBox (BizTalkMsgBoxDb).
-
The message is retrieved by a Two-Way Dynamic Send Port that uses the WCF-Custom Adapter.
-
The ESB Dispatcher pipeline component running within the ItinerarySendPassthrough pipeline retrieves the Itinerary from the ItineraryHeader context property, executes the custom RouteRequest Itinerary step and finally advances the Itinerary to the next step. In particular, the custom Routing Service changes the value of the OutboundTransportLocation and Action context properties using the data defined in the STATIC Route Resolver.
-
The WCF-SQL (WCF-Custom + SqlBinding) Adapter invokes the CustomersByCountry stored procedure.
-
The WCF-SQL (WCF-Custom + SqlBinding) Adapter retrieves result data from SQL Server and prepares a response message.
-
The ESB Itinerary Cache component running within the ItinerarySendReceivePassthrough receive pipeline retrieves the Itinerary from the cache, and the ESB Dispatcher component executes the TransformResponse Itinerary step. This latter applies the map indicated by the STATIC Map Resolver to the response message using the custom Transform Service.
-
The Message Agent submits the response message to the MessageBox (BizTalkMsgBoxDb).
-
The message is retrieved by the WCF-NetTcp Receive Location that is synchronously waiting for the response document.
-
The PassThruTransmit send pipeline is executed by the WCF-NetTcp Receive Location.
-
The response message is finally returned to the original caller.
Scenario 2
The main objective of the second scenario was measuring the performance and comparing the runtime behavior of the standard message routing pattern, based on the use of Dynamic Send Ports, with the custom message routing pattern, based on the use of Static Send Ports, without message mapping. This time the target system was represented by a WCF service called CalculatorService that runs within IIS 7.5 and exposes a NetTcpBinding-based endpoint. This latter exposes a single method called Calculate which receives a request message like the one depicted in the figure below:
CalculatorRequest Message
<CalculatorRequest xmlns="http://microsoft.biztalk.cat/10/samples/esb/calculatorrequest"> <Operations> <Operation> <Operator>+</Operator> <Operand1>82</Operand1> <Operand2>18</Operand2> </Operation> <Operation> <Operator>-</Operator> <Operand1>30</Operand1> <Operand2>12</Operand2> </Operation> <Operation> <Operator>*</Operator> <Operand1>25</Operand1> <Operand2>8</Operand2> </Operation> <Operation> <Operator>\</Operator> <Operand1>100</Operand1> <Operand2>25</Operand2> </Operation> </Operations> </CalculatorRequest> |
and returns a response message that contains the result of each operation:
CalculatorResponse Message
<CalculatorResponse xmlns="http://microsoft.biztalk.cat/10/samples/esb/calculatorresponse"> <Results xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <Result> <Value>100</Value> <Error>None</Error> </Result> <Result> <Value>18</Value> <Error>None</Error> </Result> <Result> <Value>200</Value> <Error>None</Error> </Result> <Result> <Value>4</Value> <Error>None</Error> </Result> </Results> </CalculatorResponse> |
For you convenience, I’m including the code of the CalculatorService below:
CalculatorService Class
#region Copyright //------------------------------------------------- // Author: Paolo Salvatori // Email: [email protected] // History: 2010-06-22 Created //------------------------------------------------- #endregion #region Using Directives using System; using System.Diagnostics; using System.ServiceModel; using System.Transactions; using System.Configuration; #endregion namespace Microsoft.BizTalk.CAT.ESB.Services { [ServiceContract(Namespace = "http://microsoft.biztalk.cat/10/samples/esb/calculatorservice")] public interface ICalculator { #region Contract Operations [OperationContract(Action = "Calculate", ReplyAction = "CalculateResponse")] CalculatorResponse Calculate(CalculatorRequest request); #endregion } // Service class which implements the service contract. [ServiceBehavior(InstanceContextMode=InstanceContextMode.Single, ConcurrencyMode=ConcurrencyMode.Multiple)] public class CalculatorService : ICalculator { #region Public Methods [OperationBehavior] public CalculatorResponse Calculate(CalculatorRequest request) { CalculatorResponse response = new CalculatorResponse(); Operation operation = null; string error = null; double value = 0; try { if (request != null && request.Operations != null && request.Operations.Count > 0) { for (int i = 0; i < request.Operations.Count; i++) { operation = (Operation)request.Operations[i]; error = "None"; value = 0; switch (operation.Operator) { case "+": value = operation.Operand1 + operation.Operand2; break; case "-": value = operation.Operand1 - operation.Operand2; break; case "*": case "x": value = operation.Operand1 * operation.Operand2; break; case "/": case "\\": case ":": value = operation.Operand1 / operation.Operand2; break; default: error = string.Format("Unknown Operator: {0}", operation.Operator); break; } response.Results.Add(new Result(value, error)); } } } catch (Exception ex) { Trace.WriteLine(string.Format("[CalculatorService] Exception: [{0}]", ex.Message)); throw; } return response; } #endregion } } |
OOBRoutingNoTransform Test Case
This test case uses a simple Itinerary where the Routing Service is defined on the OnRamp Port, while a Dynamic Send Port is used to communicate with the underlying WCF service. No message transformation is carried out by this test case.
Itinerary
The following figure depicts the Itinerary used by the OOBRoutingNoTransform test use case:
The standard Routing service is executed within the OnRamp Receive Location. No transformation is applied to either the request or response message. The following picture shows how the STATIC Route Resolver used by the RouteRequest service has been configured:
In particular, the Action property contains the Action of the target method exposed by the CalculatorService while the Endpoint Configuration property has been configured as follows:
BindingType=netTcpBinding& |
Note
|
Architecture
The following figure depicts the architecture of the OOBRoutingNoTransform test use case.
Message Flow
-
A Two-Way WCF-NetTcp Receive Location receives an XML request document from Visual Studio 2008 Load Test.
-
The ESB Itinerary Selector pipeline component running within the ItinerarySelectReceivePassthrough pipeline retrieves the OOBRoutingNoTransform Itinerary from the EsbItineraryDb or from the in-process cache and copies it in the ItineraryHeader context property. The ESB Dispatcher pipeline component executes the standard Routing Service and then advances the Itinerary to the next step. In particular, the Routing Service changes the value of the OutboundTransportLocation, OutboundTransportType and Action context properties using the data defined in the STATIC Route Resolver.
-
The Message Agent submits the incoming message to the MessageBox (BizTalkMsgBoxDb).
-
The message is retrieved by a Two-Way Dynamic Send Port that uses the WCF-Custom Adapter.
-
The ESB Dispatcher pipeline component running within the ItinerarySendPassthrough pipeline retrieves the Itinerary from the ItineraryHeader context property and advances this latter to the next step.
-
The WCF-Custom Adapter + NetTcpBinding invokes the Calculate method exposed by the CalculatorService.
-
The WCF-Custom Adapter + NetTcpBinding retrieves result data and prepares a response message.
-
The ESB Itinerary Cache component running within the ItinerarySendReceivePassthrough receive pipeline retrieves the Itinerary from the cache, but the ESB Dispatcher component does not execute any services.
-
The Message Agent submits the response message to the MessageBox (BizTalkMsgBoxDb).
-
The message is retrieved by the WCF-NetTcp Receive Location that is synchronously waiting for the response document.
-
The PassThruTransmit send pipeline is executed by the WCF-NetTcp Receive Location.
-
The response message is finally returned to the original caller.
CustomRoutingNoTransform Test Case
This use case adopts my custom Routing Service along with a Two-Way WCF-Custom Static Send Port. Once again, no message transformation is carried out by this test case.
Itinerary
The following figure depicts the Itinerary used by the CustomRoutingNoTransform test use case:
With respect to the preceding test case, this time the Itinerary makes use of the custom Routing Service and the RouteRequest step is now run to the OffRamp Port. However, the definition of the STATIC Route Resolver was not changed.
Architecture
The following figure depicts the architecture of the CustomRoutingNoTransform test use case.
Message Flow
-
A Two-Way WCF-NetTcp Receive Location receives an XML request document from Visual Studio 2008 Load Test.
-
The ESB Itinerary Selector pipeline component running within the ItinerarySelectReceivePassthrough pipeline retrieves the CustomRoutingCustomTransform Itinerary from the EsbItineraryDb or from the in-process cache and copies it in the ItineraryHeader context property. The ESB Dispatcher pipeline component advances the Itinerary to the next step without executing any services.
-
The Message Agent submits the incoming message to the MessageBox (BizTalkMsgBoxDb).
-
The message is retrieved by a Two-Way Dynamic Send Port that uses the WCF-Custom Adapter.
-
The ESB Dispatcher pipeline component running within the ItinerarySendPassthrough pipeline retrieves the Itinerary from the ItineraryHeader context property, executes the custom RouteRequest Itinerary step and finally advances the Itinerary to the next step. In particular, the custom Routing Service changes the value of the OutboundTransportLocation and Action context properties using the data defined in the STATIC Route Resolver.
-
The WCF-Custom Adapter + NetTcpBinding invokes the Calculate method exposed by the CalculatorService.
-
The WCF-Custom Adapter + NetTcpBinding retrieves result data and prepares a response message.
-
The ESB Itinerary Cache component running within the ItinerarySendReceivePassthrough receive pipeline retrieves the Itinerary from the cache, but the ESB Dispatcher component does not execute any services.
-
The Message Agent submits the response message to the MessageBox (BizTalkMsgBoxDb).
-
The message is retrieved by the WCF-NetTcp Receive Location that is synchronously waiting for the response document.
-
The PassThruTransmit send pipeline is executed by the WCF-NetTcp Receive Location.
-
The response message is finally returned to the original caller.
Scenario 3
The third scenario has been specifically created to measure and compare the performance of the standard and custom Transform Service when processing a medium-sized message (80 KB) with a map of average complexity. To this purpose, I reused the CalculatorRequest and CalculatorResponse messages that I exploited in the previous Scenario, but this time calculations are performed by the map shown in the figure below rather than by the WCF CalculatorService.
CalculatorRequestToCalculatorResponse Map
Note: The map has 4 pages, one for each possible math operation.
Then I created 2 different use cases, one using the standard Transform Service while the other uses my custom Transform Service.
SimpleRoutingSlipOOBTransform Test Case
This use case implements a one-way flow and uses a simple Itinerary where both the standard Transform and Routing Service are defined on the OnRamp Port. Therefore, at runtime, all the message processing happens within the One-Way WCF Receive location, while a One-Way Dynamic Send Port is simply used to write the response message to an output folder.
Itinerary
The following figure depicts the Itinerary used by the SimpleRoutingSlipOOBTransform test use case:
The TransformService step has been configured to use the standard Transform Service provided out-of-the-box by the ESB Toolkit, while the ROUTE Static Resolver used by the RouteMessage step has been configured to write the transformed message to a certain folder, as shown by the following picture:
Architecture
The following figure depicts the architecture of the SimpleRoutingSlipOOBTransform test use case.
Message Flow
-
A One-Way WCF-NetTcp Receive Location receives an XML request document from Visual Studio 2008 Load Test.
-
The ESB Itinerary Selector pipeline component running within the ItinerarySelectReceivePassthrough pipeline retrieves the SimpleRoutingSlipOOBTransform Itinerary from the EsbItineraryDb or from the in-process cache and copies it in the ItineraryHeader context property. The ESB Dispatcher pipeline component executes in sequence the standard Transform Service and the standard Routing Service and then advances the Itinerary to the next step. In particular, the standard Transform Service executes the CalculatorRequestToCalculatorResponse map to transform the inbound CalculatorRequest message into a CalculatorResponse document, and the Routing Service changes the value of the OutboundTransportLocation, OutboundTransportType and Action context properties using the data defined in the STATIC Route Resolver.
-
The Message Agent submits the incoming message to the MessageBox (BizTalkMsgBoxDb).
-
The message is retrieved by a One-Way Dynamic Send Port that uses the FILE Adapter.
-
The ESB Dispatcher pipeline component running within the ItinerarySendPassthrough pipeline retrieves the Itinerary from the ItineraryHeader context property but it does not execute any services.
-
The Send Handler of the FILE Adapter finally writes the message to the output folder indicated in the Itinerary.
SimpleRoutingSlipCustomTransform Test Case
This use case is identical to the previous one except that the original Transform Service provided out-of-the-box by the ESB Toolkit has been replaced with my custom Transform Service.
Itinerary
The following figure depicts the Itinerary used by the SimpleRoutingSlipCustomTransform test use case:
The TransformService step has been configured to use the custom Transform Service in place of the one provided out-of-the-box by the ESB Toolkit, while the ROUTE Static Resolver used by the RouteMessage step was not changed with respect to the previous use case.
Note |
Architecture
The following figure depicts the architecture of the SimpleRoutingSlipCustomTransform test use case.
Message Flow
-
A One-Way WCF-NetTcp Receive Location receives an XML request document from Visual Studio 2008 Load Test.
-
The ESB Itinerary Selector pipeline component running within the ItinerarySelectReceivePassthrough pipeline retrieves the SimpleRoutingSlipCustomTransform Itinerary from the EsbItineraryDb or from the in-process cache and copies it in the ItineraryHeader context property. The ESB Dispatcher pipeline component executes in sequence the custom Transform Service and the standard Routing Service and then advances the Itinerary to the next step. In particular, the custom Transform Service compiles or retrieves from the internal cache the CalculatorRequestToCalculatorResponse map and uses it to transform the inbound CalculatorRequest message into a CalculatorResponse document, and the Routing Service changes the value of the OutboundTransportLocation, OutboundTransportType and Action context properties using the data defined in the STATIC Route Resolver.
-
The Message Agent submits the incoming message to the MessageBox (BizTalkMsgBoxDb).
-
The message is retrieved by a One-Way Dynamic Send Port that uses the FILE Adapter.
-
The ESB Dispatcher pipeline component running within the ItinerarySendPassthrough pipeline retrieves the Itinerary from the ItineraryHeader context property but it does not execute any services.
-
The Send Handler of the FILE Adapter finally writes the message to the output folder indicated in the Itinerary.
In the next episode of the series we will walk through performance tests results. Stay tuned for Part 3!
Code
You can immediately download the code of the custom ESB services and test cases here. As always, you are kindly invited to provide feedbacks and comments.