by community-syndication | Jul 13, 2010 | BizTalk Community Blogs via Syndication
Are you missing the old WF 3.0 State Machine in .NET 4? Good news! The team has released some new activity packs on Codeplex at wf.codeplex.com
In this episode Guang Yang will show us
- WF State Machine Activity Pack CTP 1
- WF ADO.NET Activity Pack CTP 1
by community-syndication | Jul 13, 2010 | BizTalk Community Blogs via Syndication
Earlier today we shipped the beta of the Windows Phone 7 Developer Tools. You can download them here.

What is included in the Windows Phone Developer Tools
The Windows Phone Developer Tools Beta includes:
- Visual Studio 2010 Express for Windows Phone – a new free, express edition of Visual Studio 2010
- Express Blend for Windows Phone – a new free, edition of Blend focused on Windows Phone 7 development
- Silverlight for Windows Phone 7
- XNA Game Studio for Windows Phone 7
Integrated with the development tools is a phone emulator that enables you to easily develop and test Windows Phone 7 applications on your laptop or desktop machine – without requiring a phone device. It is hardware accelerated, supports multi-touch events on multi-touch capable monitors, and provides a really easy way to debug and try out your phone applications.
Devices for Developers
In addition to testing applications within the emulator, we are also this month starting to ship pre-release phones to developers. You can learn more about this program and sign-up to receive one from this blog post from the Windows Phone 7 team.
Learning More
I previously blogged a nice step-by-step tutorial that covers how to build a Twitter search application using Visual Studio 2010 Express for Windows Phone. It provides a nice introduction on how you can easily use Silverlight and the Visual Studio Tools for Windows Phone to quickly build applications. You can read and follow the tutorial here.
Read today’s blog post from the Windows Phone 7 team which provides more details on today’s release. It also mentions two new Silverlight controls – a Panorama and Pivot control – which will enable you to easily implement the new Windows Phone 7 navigation style. These controls are not implemented in today’s beta, but will be released as an update in a few weeks.
If you have used the previous Windows Phone 7 CTPs, also make sure to read Jaime’s Migrating Applications from the Windows Phone April CTP Refresh to the Beta blog post. It provides a wealth of details on how to update code that you’ve already written.
Hope this helps,
Scott
P.S. In addition to blogging, I am also now using Twitter for quick updates and to share links. Follow me at: twitter.com/scottgu
by community-syndication | Jul 12, 2010 | BizTalk Community Blogs via Syndication
[Source: http://geekswithblogs.net/EltonStoneman]
EC2 Overview
Elastic Cloud Compute (EC2) from Amazon Web Services (AWS) lets you rent a virtual PC in the cloud. You have full admin access to the machine, and the service supports load balancing across instances and DNS lookups. The service is perfect for setting up short-term test rigs, and scalable production apps alike.
Windows Server-based EC2 instances use Elastic Block Storage (EBS) for their C drives, so any changes made on disk are persistent when the instance is stopped. AWS have a suite of base Windows images, so you can go from zero to logged in as Administrator in under 30 minutes.
You’re charged for the amount of computing time you use, so there’s a use-case for scenarios where multiple users need occasional access to a shared computer at different times. You can set up an instance, install whatever software you need, and create user accounts. You can start the instance when you need to use it, Remote Desktop into the box, use the shared resources, log out and stop the instance. This sort of usage is very cost-effective – at 2010 prices, something under %u00a33 per month to rent the storage, then under 10 pence per hour for a small compute instance.
EC2 Instance Management
Stopping and starting instances is simple with the AWS Management Console:
But that gives you access to all instances in your account, requires a technical understanding of AWS and doesn’t have an option to stop instances after a certain time. Which is where my EC2 Launcher on github comes in:
The tool is configured for a single EC2 instance and hides away all the AWS internals. When you click Start it launches the configured instance, retrieves the public DNS name and starts an RDP session. When you’re finished click Stop, or use the option to stop the PC automatically after a set time.
Using EC2 Launcher
EC2 Launcher requires Microsoft’s .NET Framework 4.0.
Download the Windows Installer MSI from github here: EC2 Launcher v1.0.0. Run the installer and then launch the app from All Programs/Sixeyed/EC2 Launcher.
When you first run the app, it needs to be configured with the ID of the instance you want to launch, and with the AWS Access Identifiers (passphrases which are specific to your AWS account – you’ll need to set them up here). Click Configure to add the details:
The keys are encrypted and saved in the file Sixeyed.EC2Launcher.exe.config – but the encryption technique is very basic, so don’t rely on it. The other config values aren’t encrypted so you can change them. The main ones are:
- PCName – to give the PC a friendly name in the launcher
- ServiceUrl – the location for the AWS Availability Zone where your instance is hosted. This needs to be correct for the region where your instance lives, otherwise it won’t be found – e.g. the default https://eu-west-1.ec2.amazonaws.com is for instances hosted in EU West.
Worth noting that when you start an instance it sometimes takes a minute or two for it to be ready to accept RDP requests, so if you have a failure message, you can retry connection with the “Launch Remote Desktop” button.
by community-syndication | Jul 12, 2010 | BizTalk Community Blogs via Syndication
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:
|
Note All the Receive Locations used by test cases have been configured to run within a different host (BizTalkServerReceiveHost64) other than the host (BizTalkServerSendHost64) used to execute Send Ports.
|
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:
BindingConfiguration=<binding name="sqlBinding" maxConnectionPoolSize="1000" useAmbientTransaction="false" />& BindingType=sqlBinding& IsFault=true& PropagateFaultMessage=true& EnableTransaction=false
|
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:
- ESB Itinerary Cache
- ESB Dispatcher
|
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& BindingConfiguration=<binding name="netTcpBinding" transferMode="Buffered" maxConnections="200"><security mode="None"/></binding>& IsFault=true& PropagateFaultMessage=true& EnableTransaction=false
|
|
Note Regardless if transactions are enabled and used when invoking an underlying system (SQL database or WCF service) using a WCF-Custom Dynamic Send Port and regardless the binding being used (SqlBinding, NetTcpBinding, etc.), it’s extremely important that you explicitly set the EnableTransaction property to false or true, otherwise the WCF-Custom Adapter will try to determine (checking whether the actual binding includes the TransactionFlowElement binding element), at runtime whether a System.Transactions TransactionScope was required when sending a message over a channel. For more information you can read Mustansir’s post. I run a test to measure the impact of defining or not defining the EnableTransaction property.
- OOBRoutingNoTransform without EnableTransaction specified: 9.33 messages/sec
- OOBRoutingNoTransform with EnableTransaction explicitly set to false: 12.00 messages/sec
|
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 If you use a Microsoft.BizTalk.CAT.ESB.Itinerary.Services.Transform custom service within an Itinerary along with a STATIC Resolver and you receive the error ‘Transport Name’ property value should not be empty or null in resolver ‘<Resolver Name>’ when you try to validate or export the Itinerary, just select (None) as Transport Location on the STATIC Resolver configuration.
|
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.
by community-syndication | Jul 12, 2010 | BizTalk Community Blogs via Syndication
Breeze SharePoint 2010 Bootcamp
The
Breeze SharePoint 2010 Bootcamp is here!
Breeze
SharePoint 2010 Bootcamps – Building Real World Solutions
The
eagerly anticipated SharePoint 2010 Bootcamps are underway in Australia, and here’s
what some of the excitement is about. Technical training this year is all about value
for money. After the change in the economy, customers are more careful about where
their training budget is being allocated. This year, customers need technical training
that is relevant and an investment to their business. They are looking for knowledge
that will improve business efficiencies, provide real world scenarios and give students
the confidence to be hands-on when they leave the classroom.
The new Breeze SharePoint 2010 Bootcamp has been designed to provide just that. Our
customers asked for an in-depth, technical, customized course that, if they were to
spend $$s on just one SharePoint 2010
course this year, would give them enough knowledge of the technology to build real
world solutions.
These
bootcamps have been written for the ITPro & Developer who need to upgrade their
SharePoint skills, or are just starting out with SharePoint 2010.
Be ready to roll up your sleeves and start your adventure here.
Sydney:
2nd August 2010
Price:
$3450 ex GST
Register
NOW: info {at} breeze {d.o.t.} net
*Quote
this blog article to receive a special promotion.
Enjoy,
Mick.
p.s. anyone seen the octopusI’ve got destiny with it.
by community-syndication | Jul 11, 2010 | BizTalk Community Blogs via Syndication
Discover how to use Inversion of Control and Dependency Injection to enhance your web application’s Multi-Tenant Application.
by community-syndication | Jul 11, 2010 | BizTalk Community Blogs via Syndication
[Source: http://geekswithblogs.net/EltonStoneman]
Normal
0
false
false
false
EN-US
X-NONE
X-NONE
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:”Table Normal”;
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-parent:””;
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin-top:0cm;
mso-para-margin-right:0cm;
mso-para-margin-bottom:10.0pt;
mso-para-margin-left:0cm;
mso-pagination:widow-orphan;
font-size:11.0pt;
mso-bidi-font-size:10.0pt;
font-family:”Calibri”,”sans-serif”;
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:”Times New Roman”;
mso-bidi-theme-font:minor-bidi;}
LINQ to Entities doesn’t contain a definition for Contains(), so you have a couple of options where you want to write a LINQ query which operates like a WHERE IN() clause in SQL.
The first option is an extension to ObjectQuery which lets you specify a collection to use as selection criteria, something like the WhereIn extension suggested on StackOverflow. This lets you write code like this:
var ids = new string[] { “3012472”, “3012473”, “3012474”, “3012475” };
var query = context.Employee
.WhereIn(e => e.EmployeeId, ids)
.OrderBy(e => e.EmployeeId);
There are a couple of issues with the extension code suggested though – the first is that if the collection is empty, the WhereIn doesn’t add any criteria, so the original query is run in full. In SQL if you have an empty WHERE IN() clause, you’ll get no results so I’d prefer WhereIn to behave in the same way.
More importantly, there’s a limit to how big a collection WhereIn can cope with. Pass it anything over about 3,000 items and it’ll bomb out with a nasty StackOverflowException, which will likely take out your AppDomain and not give you any notification.
An amended WhereIn addresses the first issue and prevents the second:
/// <summary>
/// Adds an equivalent SQL WHERE IN() clause to the query, restricting results to a given range
/// </summary>
/// <typeparam name=”TEntity”>Type of entity to query</typeparam>
/// <typeparam name=”TValue”>Type of value to query against</typeparam>
/// <param name=”query”>Existing query</param>
/// <param name=”selector”>Expression to retrieve query field</param>
/// <param name=”collection”>Collection of values to limit query</param>
/// <returns>Query with added WHERE IN() clause</returns>
public static IQueryable<TEntity> WhereIn<TEntity, TValue>
(
this ObjectQuery<TEntity> query,
Expression<Func<TEntity, TValue>> selector,
IEnumerable<TValue> collection
)
{
ParameterExpression p = selector.Parameters.Single();
//if there are no elements to the WHERE clause,
//we want no matches:
if (!collection.Any()) return query.Where(x=>false);
if (collection.Count() > 3000) //could move this value to config
throw new ArgumentException(“Collection too large – execution will cause stack overflow”, “collection”);
IEnumerable<Expression> equals = collection.Select(value =>
(Expression)Expression.Equal(selector.Body,
Expression.Constant(value, typeof(TValue))));
Expression body = equals.Aggregate((accumulate, equal) =>
Expression.Or(accumulate, equal));
return query.Where(Expression.Lambda<Func<TEntity, bool>>(body, p));
}
This is fine for cases where your criteria are known at design-time, or are predictably small – e.g. limiting to a set of statuses. For scenarios where the criteria are large or unknown, the better option is to use a LINQ subquery. The syntax seems backwards but is straightforward when you get used to it.
This query looks for any customers who have placed an order in a given date range, and then returns all their orders – irrespective of the order date:
var query = from o in context.Orders
let recent = context.Orders.Where(o => o.OrderDate > selectionDate)
where recent.Any(x => x.CustomerId == o.CustomerId)
select o;
The let defines the subquery to gets a list of orders restricted by date, and the Any() matches the outer query to the subquery on customer ID. This will produce a single SQL statement which will be as efficient as your schema allows, but it will cope with any quantity of restriction criteria.
by community-syndication | Jul 10, 2010 | BizTalk Community Blogs via Syndication
I was putting together a demo of this concept for a class I am teaching in Port Moresby this week.
Using this technique you can have multiple implemenations of an interface, while the client application can be written to be completely agnositic about the implementation.
Here we use Activator.CreateInstance to late bind the implementation class.
Here’s the interface:
public interface IErrorLog
{
void LogMessage(string message, string location);
string DisplayLog(string location);
}
Here’s a text file implementation:
using System;
using System.Text;
using System.IO;
public class LogToFile : IErrorLog{
public void LogMessage(string message, string location){
FileStream fs = new FileStream(location, FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter w = new StreamWriter(fs);
//Set the file pointer to the end.
w.BaseStream.Seek(0, SeekOrigin.End);
Log(message, w);
w.Close(); //Close the writer and underlying file.
}
public string DisplayLog(string location){
FileStream fs = new FileStream(location, FileMode.OpenOrCreate, FileAccess.Read);
StreamReader r = new StreamReader(fs);
r.BaseStream.Seek(0, SeekOrigin.Begin);
StringBuilder sb = new StringBuilder();
//While not at the end of the file, write to standard output.
while (r.Peek() > -1) {
sb.Append(r.ReadLine());
sb.Append(“\n”);
}
r.Close();
return sb.ToString();
}
private void Log(string logMessage, StreamWriter w){
w.WriteLine(“{0}, {1}, {2}”, DateTime.Now.ToString(“d/M/yyyy”), DateTime.Now.ToString(“HH:mm”), logMessage);
w.Flush();
}
}
Here’s a database implementation:
using System;
using System.Data;
using System.Data.SqlClient;
public class LogToDB : IErrorLog{
public void LogMessage(string message, string location){
SqlConnection cn = new SqlConnection(location);
cn.Open();
Log(message, cn);
cn.Close();
}
public string DisplayLog(string location){
SqlConnection cn = new SqlConnection(location);
SqlDataReader dr;
SqlCommand cmd = new SqlCommand();
string strLog = “”;
cn.Open();
cmd.CommandText = “select * from LogTable”;
cmd.Connection = cn;
dr = cmd.ExecuteReader();
while (dr.Read()){
strLog = strLog + Convert.ToDateTime(dr[0]).ToString(“d/M/yyyy”)
+ “, ” + Convert.ToDateTime(dr[1]).ToString(“HH:mm”)
+ “, ” + dr[2].ToString() + “\n”;
}
cn.Close();
return strLog;
}
private void Log(string logMessage, SqlConnection cn){
try{
SqlCommand cmd = new SqlCommand();
cmd.CommandText = “INSERT INTO LogTable(LogDate, LogTime, LogMessage)”
+ ” VALUES(‘” + System.DateTime.Now.ToString(“M/d/yyyy”)
+ “‘, ‘”
+ DateTime.Now.ToShortTimeString() + “‘, ‘”
+ logMessage + “‘)”;
cmd.Connection = cn;
cmd.ExecuteNonQuery();
}
catch (SqlException eException) {
foreach(SqlError eErr in eException.Errors){
System.Windows.Forms.MessageBox.Show(eErr.Message);
}
}
}
}
Here’s the app.config file, where we can specify which implementation or client will spin up:
<?xml version=”1.0″ encoding=”utf-8″ ?>
<configuration>
<appSettings>
<add key=”Type”
value=”LogToDB”/>
<add key=”Location”
value=”Data Source=.;Integrated Security=SSPI;Initial Catalog=LogDB”/>
<!–
<add key=”Type”
value=”LogToFile”/>
<add key=”Location”
value=”c:\testlog.txt”/>
–>
</appSettings>
</configuration>
And here’s out client application. Note there is no hard coding of any implementation classes here. Beauty, eh?
public IErrorLog ErrLog;
public string LogLocation;
private void Form1_Load(object sender, EventArgs e)
{
string logType = ConfigurationManager.AppSettings[“Type”];
LogLocation = ConfigurationManager.AppSettings[“Location”];
//late binding
ObjectHandle handle = Activator.CreateInstance(
“WindowsApplication1”, logType);
ErrLog = handle.Unwrap() as IErrorLog;
}
private void btnLogMessage_Click(object sender, System.EventArgs e)
{
ErrLog.LogMessage(txtMessage.Text.ToString(), LogLocation);
}
private void btnDisplayLog_Click(object sender, System.EventArgs e)
{
MessageBox.Show(ErrLog.DisplayLog(LogLocation));
}
by community-syndication | Jul 9, 2010 | BizTalk Community Blogs via Syndication
One StreamInsight usage scenario frequently discussed by the product team involves sending a subset of events (or aggregated complex events) to the Enterprise Service Bus for additional processing and distribution. As I’ve mentioned before, StreamInsight doesn’t come with any out-of-the-box adapters. So if you want to make this usage scenario a reality, it’s up to […]
by community-syndication | Jul 9, 2010 | BizTalk Community Blogs via Syndication
Here is the latest in my link-listing series. Also check out my VS 2010 and .NET 4 series and ASP.NET MVC 2 series for other on-going blog series I’m working on.
[In addition to blogging, I am also now using Twitter for quick updates and to share links. Follow me at: twitter.com/scottgu]
ASP.NET
ASP.NET MVC
jQuery
Silverlight and WPF
Visual Studio 2010
Hope this helps,
Scott