I will be away for a few weeks on a rather long holiday. I have quite a few things planned for next year involving BizTalk, WCF, RFID, and the Connected Systems community here in New Zealand so watch this space. Happy holidays everyone!
November 23, 2007
November 21, 2007
Test a BizTalk orchestration exposed as a SOAP web service using a WCF Port
So you have an orchestration that has been exposed as a web service using BizTalk’s Web Publishing Wizard. It created the proxy files, the virtual directory and the web application, and you have a receive port configured with the SOAP adapter. In my case this was part of an upgrade from BizTalk 2004 to BizTalk 2006 R2. We won’t be upgrading the adapters for now, but that doesn’t mean we can’t test this with a BizTalk send port using WCF, does it? Here are the few things I had to do to get it working:
- We had a few elements in the schema being received by the orchestration that had an enumeration restriction. I had to browse to where the web service proxy files were created, opened DataTypes.cs under the App_Code folder, and remove “AnonymousType=true” on the enumerated fields. If you don’t do this it will show the elements as expecting a “bytes” type instead of an enumeration of strings.
- I created a file receive port and location using the passthrough pipeline and a send port with a passthrough pipeline using the WCF BasicHTTP adapter:
- Paste the URI of the web service into the BasicHTTP “Address URI”. Example:
http://localhost/Order_Proxy/OrderOrchestration_OrderServicePort.asmx
- On the BasicHTTP “SOAP Action header” paste the soap action that you can get from when you browse to the web service, example:
http://OrderTest/OrderOrchestration_OrderServicePort/OrderServiceOperation
- As a last step, I added the operation to the root node of the test file.
For example, the instance of the schema expected by the SOAP receive port is:
<Order xmlns=”http://OrderTest“>
<OrderHeader xmlns=”">
<OrderName>string</OrderName>
…
</OrderHeader>
<Order>
And the SOAP operation page shows that the web service expects something like:
<OrderServiceOperation xmlns=”http://OrderTest“>
<Order>
<OrderHeader xmlns=”">
…
</OrderHeader>
</Order>
</OrderServiceOperation>
So I used a file like this to test it:
<OrderServiceOperation xmlns=”http://OrderTest“ xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xmlns:xsd=”http://www.w3.org/2001/XMLSchema“>
<Order>
<OrderHeader xmlns=”">
…
</OrderHeader>
</Order>
</OrderServiceOperation>
When I drop the test message it is picked up by the passthrough receive port, picked up by the WCF send port and sent to the web service which then kicks off an instance of the orchestration! Cool.
A friend from work also pointed me to this great post by the WCF Adapter master Sonu Arora: Consume WCF Service Wizard generates port binding configuration files for import into BizTalk Server. This way you can’t get the binding wrong!
As a little side note mini hidden blog post:
To debug a custom pipeline component used inside one of the normal isolated host adapters (SOAP, HTTP, WCF), I had to do the following: update the output of the pipeline component project to the BizTalk pipeline components folder. Make sure no process is using the pipeline component (restart IIS and its application pools and restart BizTalk host instances). Add a breakpoint to your code. Rebuild the project. From the debug menu inside visual studio, attach to the w3wp.exe process (you might have to put a file through first so the process starts before you can attach to it).
November 5, 2007
LoadGen 2007 and a Simple BizTalk WCF Test
A quiet release by Microsoft this month was the new version of its free BizTalk performance and stress test tool – Microsoft BizTalk LoadGen 2007.
Come to think about it BizTalk LoadGen 2004 unfortunately also never got much praise, even though it is used quite a lot by Microsoft to test BizTalk. You can use it to generate messages and perform stress and performance tests on your BizTalk Server and other servers.
The tool in a nutshell is a command line utility called LoadGenConsole.exe that takes an XML configuration file and generates the load tests described in the configuration file. The 2007 version of LoadGen can be used to simulate load in several types of transport (file, HTTP, MQSeries, MSMQ, SOAP, WSE, WSS, WCF) and to monitor certain types of systems (file, MQSeries, MSMQ, MSMQ Large files, performance counters, SQL Server).
I created a simple BizTalk solution that consists of two schemas, PO and POAck, a map, and an orchestration that exposes a port with a public Receive-Send port type.
The map copies the purchase order number and datetime to POAck, and determines if the purchase order is accepted or not based on the total price of the PO: if the total is less than or equal to 1000 it’s accepted otherwise rejected. The map looks like this:

The scripting functoid is an Inline C# containing this in the script:
public string POAckStatus(bool lowPrice)
{
if (lowPrice == true)
return “Accepted”;
else
return “Rejected”;
}
The orchestration is also very simple, receiving a PO, calling the map and returning the POAck. The only little trick is to make sure the port type is Public otherwise we won’t be able to expose the orchestration as a WCF service. Here is how it looks like in the designer:

After deploying the solution, I fired up the BizTalk WCF Service Publishing Wizard and:
- Selected WCF-BasicHttp as the transport type
- Selected for it to create BizTalk receive locations on the application where the BizTalk solution was deployed
- Selected “Publish BizTalk orchestrations as WCF service”
- Browsed to my solution’s DLL, selected the Port_ProcessPO as the port to export
- Chose http://BTLoadGen2007WcfTest/ as the target namespace
- Chose http://localhost/BTLoadGen2007WcfTest as the location
And voila! The wizard creates the service in IIS and creates the receive port in the BizTalk orchestration. After this I had to bind the orchestration to the new port, start the orchestration and port, configure permissions on the new IIS virtual directory created by the wizard, and enable the WCF performance counters on the service.
To enable the WCF performance counters on the service you edit the Web.config file created by the wizard and add the following line inside the <System.ServiceModel> node:
<diagnostics performanceCountersEnabled=“All“ />
[EDIT] The above is for WCF 3.0. If you are using WCF 3.5 then add the following line to web.config:
<diagnostics performanceCounters=“All“ />
Then restart the BizTalk host so that the counters show up on the performance counters. Now that I have the orchestration exposed as a WCF service I can look into how to use LoadGen 2007 to test it. LoadGen lets you either submit the same file over and over again for each test or you can create a template file with fields that it modifies for each file. There are a lot of configuration options so make sure you review the help that comes with the product. The template file I created, called LoadGen2007WcfTestSample.xml, was:
<ns0:PO DateTime=“DateTime_0“ xmlns:ns0=“http://BTLoadGen2007WcfTest/PO“>
<PONum>PONum_0</PONum>
<Item>
<Id>Id_0</Id>
<Description>Static Description</Description>
<Quantity>Quantity_0</Quantity>
<Price>Price_0</Price>
<UOM>Static UOM</UOM>
</Item>
</ns0:PO>
To then get LoadGen to populate the fields with values ending with “_0′ on the file above with proper values during the test I created a file that controls the message creation. I called it LoadGen2007WcfTestMessageCreator.xml, and its contents are:
<MessageCreator SourceFilePath=“C:\Program Files\LoadGen\Bins\LoadGen2007WcfTestSample.xml“ OutEncoding=“utf-8“>
<Field>
<InitialValue>PONum_0</InitialValue>
<DataType>Integer</DataType>
<InputFilePath></InputFilePath>
<ContentMinSize>1</ContentMinSize>
<ContentMaxSize>2000</ContentMaxSize>
<AllowDuplicates>True</AllowDuplicates>
</Field>
<Field>
<InitialValue>Id_0</InitialValue>
<DataType>Guid</DataType>
<InputFilePath></InputFilePath>
<ContentMinSize>1</ContentMinSize>
<ContentMaxSize>1024</ContentMaxSize>
<AllowDuplicates>True</AllowDuplicates>
</Field>
<Field>
<InitialValue>Quantity_0</InitialValue>
<DataType>Integer</DataType>
<InputFilePath></InputFilePath>
<ContentMinSize>1</ContentMinSize>
<ContentMaxSize>50</ContentMaxSize>
<AllowDuplicates>True</AllowDuplicates>
</Field>
<Field>
<InitialValue>Price_0</InitialValue>
<DataType>Integer</DataType>
<InputFilePath></InputFilePath>
<ContentMinSize>1</ContentMinSize>
<ContentMaxSize>2000</ContentMaxSize>
<AllowDuplicates>False</AllowDuplicates>
</Field>
<Field>
<InitialValue>DateTime_0</InitialValue>
<DataType>Timestamp</DataType>
<InputFilePath></InputFilePath>
<ContentMinSize></ContentMinSize>
<ContentMaxSize></ContentMaxSize>
<AllowDuplicates>True</AllowDuplicates>
</Field>
</MessageCreator>
This configuration file tells LoadGen to search for the string in the InitialValue element and replace it for the random value based on the rest of the parameters under Field (that’s right, you put the string for it to search and replace, not the name of the XML node on your template file). Two more steps to go: configure LoadGen with an endpoint to our WCF service and create the actual load test configuration file. To configure LoadGen to work with WCF you must edit the LoadGenConsole.config file and add a <System.ServiceModel> element under <Configuration>. For my test I added the following:
<system.serviceModel>
<client>
<endpoint name=“LoadGen2007WcfTestPOProcessEndpoint“
address=“http://localhost//BTLoadGen2007WcfTest/LoadGen2007WcfTest_POProcess_Port_ProcessPO.svc“
binding=“basicHttpBinding“
bindingConfiguration=“LoadGen2007WcfTestPOProcessBinding“
contract=“WcfTransport.IChannelAsyncNonTransactional“/>
</client>
<bindings>
<basicHttpBinding>
<binding name=“LoadGen2007WcfTestPOProcessBinding“
openTimeout=“23:59:59“ receiveTimeout=“23:59:59“ closeTimeout=“23:59:59“ sendTimeout=“23:59:59“>
<security mode=“None“>
</security>
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
Finally, we must create the configuration file that gets passed to the command line tool containing sections detailing the work LoadGen should do. I called the file LoadGen2007WcfTestConfig.xml and it contains:
<LoadGenFramework>
<CommonSection>
<LoadGenVersion>2</LoadGenVersion>
<SleepInterval>2000</SleepInterval>
<OptimizeLimitFileSize>204800</OptimizeLimitFileSize>
<NumThreadsPerSection>5</NumThreadsPerSection>
<RetryInterval>1000</RetryInterval>
<StopMode Mode=“Time“>
<TotalTime>300</TotalTime>
</StopMode>
</CommonSection>
<Section Name=“LoadGen2007WcfTest“>
<Transport Name=“LoadGen2007WcfTest“>
<Assembly>WcfTransport.dll/WcfTransport.WcfTransport</Assembly>
</Transport>
<SrcFilePath>C:\Program Files\LoadGen\Bins\LoadGen2007WcfTestSample.xml</SrcFilePath>
<LotSizePerInterval>20</LotSizePerInterval>
<DstLocation>
<Parameters>
<ClientType>WcfTwoWays</ClientType>
<Transactional>False</Transactional>
<ClientEndPointName>LoadGen2007WcfTestPOProcessEndpoint</ClientEndPointName>
<IsSynchronous>False</IsSynchronous>
<MessageAutoGenerate>False</MessageAutoGenerate>
<LogReqMessage>True</LogReqMessage>
<LogRespMessage>True</LogRespMessage>
</Parameters>
</DstLocation>
<MessageCreator Mode=“Asynchronous“>
<SleepInterval>2000</SleepInterval>
<QueueLength>1000</QueueLength>
<Assembly>CustomMC.dll/CustomMC.CustomMC</Assembly>
<TemplateFilePath>C:\Program Files\LoadGen\Bins\LoadGen2007WcfTestMessageCreator.xml</TemplateFilePath>
</MessageCreator>
</Section>
</LoadGenFramework>
This file tells LoadGen to create five threads that will try to generate up to 20 messages (LotSizePerInterval) every 2 seconds (SleepInterval) over a period of five minutes (StopMode=Time, TotalTime = 300). LoadGen also installs a few performance counters for each of its supported transports and monitors. For the WCF adapter it adds “Messages sent/sec” and “Total Messages sent to the target”. For this test I chose to monitor:
- LoadGen:WcfTransport
- “Messages sent/sec” – LoadGen’s count of messages it sent
- XLANG/s Orchestrations
- “Orchestrations created/sec”
- “Orchestrations completed/sec”
- BizTalk:Message Box:Host Counters
- “Host Queue – Length” – BizTalk queue
- BizTalk:Message Agent
- “Message delivery throttling state” – Outbound throttling
- “Message publishing throttling state” – Inbound throttling
- ServiceModelService 3.0.0.0
- “Calls Outstanding” – Calls to the Service being processed
- “Calls per Second” for my WCF service
These give me an overview of how BizTalk is keeping up with LoadGen. Note that the LoadGen test has to be running before the instance of the performance counter can be selected, so fire up the LoadGen test first then add the performance counter to the counter log.
Finally, on to the test! I started the performance counter log and ran the LoadGen test by firing up the command prompt and ran it passing the configuration XML as a parameter:

As you can see after five minutes it sent an average of 25.1 messages per second to the Orchestration exposed as a WCF Service on my virtual machine, totaling at 7606 messages. Not bad! The throttling counters show message publishing and delivery throttling were enabled about 5 times for a second or two during the test, and the host queue never went over 14. Since there was some throttling BizTalk keeps processing the last messages for about 30 seconds after LoadGen finishes the test.
The only issue I found is with the request messages logged (enabled by adding <LogReqMessage>True</LogReqMessage> to the DSTLocation part of the configuration file). It logs the template file with the _0 values for each message sent instead of the actual message generated by the message creator. I turned on message tracking in BizTalk and I can see the messages sent to BizTalk are populated correctly, as below, so the request message tracking with WCF and message creator seems to have a bug:
<ns0:PO DateTime=“Mon, 05 Nov 2007 10:22:35:406014“ xmlns:ns0=“http://BTLoadGen2007WcfTest/PO“>
<PONum>108</PONum>
<Item>
<Id>3ba6047d-1ed9-4efe-a338-5088dfb2774c</Id>
<Description>Static Description</Description>
<Quantity>37</Quantity>
<Price>939</Price>
<UOM>Static UOM</UOM>
</Item>
</ns0:PO>
And here is the POAck message generated by in response:
<s:Envelope xmlns:s=“http://schemas.xmlsoap.org/soap/envelope/“>
<s:Body>
<ns0:POAck xmlns:ns0=“http://BTLoadGen2007WcfTest/POAck“>
<PONum>108</PONum>
<PODateTime>Mon, 05 Nov 2007 11:06:31:739888</PODateTime>
<Status>Rejected</Status>
<POTotalPrice>1062</POTotalPrice>
</ns0:POAck>
</s:Body>
</s:Envelope>
In conclusion, LoadGen is no comparison to Visual Studio Load Tests, as expected, but is still a very powerful (and free) tool for testing your BizTalk solutions. It is great to determine the throughput and capacity of your solution. Also, if combined with BizUnit, you can implement a serious BizTalk automated testing environment.
As a leaving note, don’t overlook the fact that you can also use this tool to test other solutions that use WCF, HTTP, SOAP, file pickups, etc. It isn’t restricted only to BizTalk testing.

RSS

