Overstanding the SO-Aware Test Workbench Test Types (part 1: Unit & Simple Load Testing)

Introduction

SO-Aware, allows you to create unit tests for WCF SOAP, and WCF REST based web services. These tests can be executed using the standard web based user interface that SO-Aware provides. The tests can also be executed using a PowerShell script. There is also a automated windows service that runs that can schedule a test to run every so often. The results of these tests are stored inside the SO-Aware repository.

After utilizing these testing features of SO-Aware, it became evident from our customers that there should be a Client Desktop form of this testing. Where a Client application can run these tests, and the results of these tests can be exported out into a format for inclusion into a reporting system like SQL Reporting services, where the results can be gathered and displayed using other tools.

The SO-Aware Test Workbench (TWB) is this client side application. TWB contains many different types of tests that a developer, architect, and IT administrator can use to stress test services in their enterprise. TWB, supports executing single unit tests, just like inside SO-Aware, Simple Load Tests, Linear Load Tests, Burst Load Tests, and SawTooth Load tests.

Each different type of test has a unique design pattern and purpose to allow you to determine different metrics and derive different information from the results. In these next series of blogs, I will explain what each test is designed to do, and explain in detail about each of the configurable parameters. I will also explain a few ways of how to interpret the results.

In this first posting, let’s discuss two tests: Unit Test and Simple Load testing. Before we delve into the specifics, I want to provide a baseline for comparison. If you want to do these same type of tests, I’d suggest you go and download SO-Aware and the SO-Aware Test Workbench now.

Just so that you know, all tests were performed on a VMWare virtual machine. The VM image was configured to have: 

  • 1 CPU with 8 cores (Intel i7 2GHz)
  • Running on a 256 GB SSD (100GB allocated to image on single drive: C:\)
  • RAM 4GB
  • Networking Shared
  • Windows Server 2008 R2 (SP1)
    • Web Role
    • AppFabric
    • Active Directory Domain Controller
    • File Application Server Role
  • SQL 2008 R2 (Installed and Running)
  • SharePoint 2010 (Installed and Running)
  • BizTalk Server 2010 (Installed not running)
  • VS.NET 2010 (SP1)

Services used in these tests are:

    1. SO-Aware Service Repository (REST registered endpoint)
    2. People Finder Service (AppFabric WCF Service as found in the SO-Aware SDK)

Now with all the logistical settings out the way… let’s continue on.

Unit Testing

The Unit testing feature of TWB allows you to run singular tests configured inside SO-Aware and export its results using PDF and Excel formats for inclusion into other reporting tools.

This test is designed to test the functionality of the service operation. It is a single test that allows you to obtain its execution time, success/fail status, and basic operation. B y right-clicking on any test, you can select Run Test and it will display the screen below with an option to change the registered message in SO-Aware, restore the original message and Run the single unit test.

image

Simple Load Test

The Simple Load test is designed to allow you to test the singular unit tests over and over again for a certain period of time. The concept here is that after you’ve run the unit test a few times, you should have a good feeling of how long that test runs. Now if you wanted to test that unit test with concurrency, that is… let’s say 10 of the same tests running at the same time for over 60 seconds, this is where the Simple Load test comes into play.

You can see the execution time, success/fail status and basic operation. Not only does the Simple load test allow you to test concurrency, you can also test redundancy to get an average execution time on the current hardware and software design, by executing it over and over again.

The parameters of the Simple Load test are:

Concurrency – how many threads to execute a single test on for concurrent processing

Delay (ms) – how long to wait for the concurrent tests to run. This value should be set high enough to allow the other concurrent test to load up and execute without affecting the previous tests. However setting this value to a lower value would simulate a constant (albeit linear) stress factor of concurrent tests that load on top of concurrent tests before the previous tests have had a chance to complete.

Duration (sec) – the number of seconds to continue running the concurrent tests.

Number of tests – the number of iterations to run the complete duration of concurrent tests.

clip_image002

In the above test, I executed the Get Services REST endpoint for a SO-Aware instance I have installed. Below are the first five results from the Excel exported results workbook.

Making sense out of the first five results in the table:

Second

Count

Average

Errors

Passed

Thread Count

0

37

89.81081081

0

37

10

1

38

60.92105263

0

38

10

2

42

39.61904762

0

42

10

3

38

46.05263158

0

38

10

4

42

50.26190476

0

42

10

5

42

43.80952381

0

42

10

Basically what this boils down to is this, up to the first second, we had 37 tests run concurrently, and out of all these tests, it took an average of .0089 seconds (89.81 ms) for all 37 tests to complete. This yields an average of 1 test every 2.42 milliseconds. During the 89ms, there was a max count of 10 threads that occurred during the processing of these tests. Another way of looking at it is that every 3.7 tests a new thread may have been spawned. – Ok Great…

Now within the next second (up to the 2nd Second), we had 1 more test get crammed into the process to total 38 test being run concurrently. It took 61 seconds, on average. This is a speed increase of 30%.

On the next second (up to the 3rd second), we had 4 more test get added totaling 42 tests. These test ran the quickest at a blazing 40ms. That’s an average of 1 test every 0.94 ms which is .000094 seconds. Remember 2GHz is 2 billion ticks per second, and depending on the CPU architecture (# of Cores/RISC/CISC etc) different sets of instructions may execute on 1 tick (clock cycle).

On the fourth and fifth seconds the median appears to have been reached ranging from 43 – 53 milliseconds easily of 38 -42 tests, while taking the median of those ranges yields 50ms per grouping of 40 tests.

Simple Load tests help you determine how fast your service/operation will run with the same operation running at the same time. It will also allow you to see the fastest and slowest times on a given hardware design. This test will also allow you to see how many threads will yield performance degradation for a given operation. Hopefully this is enough to get you started on executing Unit Tests and Simple Load tests using the TWB. In the next posting I will talk about Linear Load Tests, so start testing your services today!!!

Advertisements

Monitoring a BizTalk WCF Receive Location with SO-Aware

As a quick start, for those that don’t know, SO-Aware is a service metadata repository, very similar to UDDI, except without the complexity, all based on a REST-ful architecture. If you do know, you can skip to Monitoring a BizTalk WCF Receive Location section. (UPDATE: you can also view a video on the webinar explaining and demoing this here.) It supports registry of SOAP, REST, and OData based services, written using Microsoft’s WCF technology stack, as well and Java based web services. However, that’s not all. SO-Aware has five major capability buckets: Centralized Configuration, Service Testing, Dependency Modeling, Service Cataloging and last but not least Activity Monitoring.

Centralized Configuration

Centralized Configuration allows you take full advantage of Microsoft’s WCF based services, by containing a central repository database for all WCF Configurations. This feature allows you to allows you to store and retrieve all information pertaining to WCF configurations. You can retrieve endpoints, bindings, behaviors, Url’s, security information, just to name a few. You can also dynamically change your bindings and configurations so that all you existing services can point to this central location for your configuration.

Service Testing

Service Testing allows you to test registered services. One derived idea about Service Cataloging and Centralized Configuration, is that if SO-Aware knows about your service and communication protocol, then testing becomes simple. It’s simple because if you registered any security, binding, message type format information about the service, then all SO-Aware needs to do is query this information and build the communication stack and messages to send to the service for testing. What better tool to test than the one that understands how to communicate with the Service.

Dependency Modeling

Dependency Modeling allows you to build a diagram of service versions, and the dependencies of the service version. Thus if you needed to see which services depended each other, you have a view into this.

Service Cataloging

Service Cataloging allows you to store and retrieve custom metadata about Services, Service Versions, and environment details. Using these features, allow you to query the catalog for information about services, and service versions dynamically.

Activity Monitoring

Activity Monitoring allows you see tracked events and aggregations about registered services, such which operations were invoked, and how many services were sent message over a period of time, and many other dimensions and measurements.

What is BizTalk Server?

BizTalk Server is one of Microsoft’s flagship products for System Integration, message brokering, and service bus designs. It comes packed with a collection of tools and libraries that extend normal middleware Server capabilities by supporting a loosely coupled and dynamic messaging architecture. It functions as middleware server product that provides rapid mediation between services, endpoints, line of business systems and their consumers. Enabling maximum flexibility at run time, BizTalk Server simplifies loosely coupled composition of service endpoints and management of service interactions. There are many components that allows BizTalk Server solutions to be agile in its execution. For example, BizTalk Server contains Adapters which are connectors into different systems and protocols. It also contains Maps, which are Xml stylesheet transformation documents that have been precompiled to transform documents from one format into another. There are Pipelines which are components that allow you to translate and convert one file into another such as a Adobe PDF document into a comma separated text file. There are also Schemas which support validation of different messages, both xml and non xml. Lastly there are Orchestrations which are graphically modeled business processes that support long running transactions, compensation models, error handling, correlation, and custom logic flow.

Adapters in BizTalk are one of the key components for communicating with BizTalk Server. There are sending adapters and receiving adapters. There’s an adapter for practically every protocol that exists such as ftp, http, smtp, tcp, ftps (new in 2010), Msmq and others. There are application type of adapters that adhere to the rules and policies of Line of Business applications, such as SharePoint, SAP, Oracle E-Business Suite, and other CRM applications. There are even adapters for databases such as SQL, Oracle, and DB2. When developing solutions with BizTalk Adapters are usually configured statically and there’s little room for agility. Thus BizTalk supports the notion of Dynamic adapters for sending data. These adapters are configured at runtime, which will yield great agile solutions, at the sacrifice of High performance. There are also Dynamic adapters which require turn static BizTalk Server solutions into dynamic ones, along the Microsoft ESB toolkit, which can make everything in the BizTalk arena agile.

BizTalk Server also contains Monitoring capabilities. Every message and process that is run within BizTalk Server can be monitored using its internal Tracking system. As well as using a more open consumer business process driven ones entitled BAM, business activity monitoring. BizTalk has the capability to automatically monitor ports, receive locations, pipelines, maps, validation attempts, business rules, orchestrations and adapters. Using BAM, architects and developers can create custom monitoring scopes, and key performance indicators, for tracking and monitoring specific business requirements and processes. This leads us to why SO-Aware and what benefits can we discover when using SO-Aware to monitor BizTalk.

Monitoring using SO-Aware

BizTalk Server contains WCF Adapters, which provide limitless range of possibilities for communication protocols, and access to various endpoint systems. What I’m trying to say here is that through the use of WCF Adapters, any and every system can potentially be accessed and communicated to. To support this claim, Microsoft released the Microsoft WCF LOB Adapter SDK. This SDK is a framework that makes it easy for developers to create “Adapters” or better put, wcf channels to connect any type of system. These channels can be used with BizTalk, and regular .Net Applications. To go along with the SDK, Microsoft released some Production ready, sample Adapters based off this framework, called the Microsoft BizTalk Adapter Pack . Here’s the interesting kicker… The BizTalk Monitoring architecture was not updated sufficiently to handle these new additions to the BizTalk arena.

To Monitor these WCF Adapters, you have a few options:

  1. Use the WCF Message logging and Activity Tracing capabilities, which can log, messages, operations, actions, instances, events and everything related WCF services. To View these traces and logs by default, you need to use the WCF Trace Viewer application provided with the .Net Framework SDK. This is your standard WCF Tracing capability. It is not tied to BizTalk in any shape, form or fashion. One nice thing about using the WCF Message logging and tracing is the ability to control where the logs and traces are written, how much data is written, and the ability to view this information RAW as it’s being recorded. Of course each pro has a con associated with it. The downside is that to turn on WCF tracing requires you to modify the BizTalk configuration file, and it will record messages for ALL WCF Adapters – Send and Receive. Thus if you have and large amount of Adapters being used, your traces can become convoluted very quickly, and fill up your trace/log repository very fast. Along with this, the traces and logs may be a little cryptic by default, unless you create your own logger and format the results accordingly.
  2. Use BAM WCF Interceptors to log custom KPI’s to BAM tables, and create a custom view to see the results. This second option uses the only real updated portion of BizTalk to handle these new WCF Adapter features: WCF Interceptors. The main issue here is that configuring the WCF Interceptor tracking profile (WCF Interceptor configuration file), is a very tedious and complex process. As of this writing there is no graphical User interface for configuring it, like the BAM model in Excel. Thus this process is prone to trial and error. It’s a very powerful enhancement, however just not feasible in the quick development turn around times needed in Today’s market. Let’s put it this way, it took me a month to get the very basics down, after having to deal with reverse polish notation, and Interceptor configuration files. However once you understand it, it too has a limitless range of possibilities. Thus for this option, I’d say a big *PRO*, with the downside of complexity, time to configure and brittleness.
  3. Use the WCF Extension model through behaviors (which is what BAM WCF Interceptors is, an Endpoint Behavior) to create a custom Behavior to monitor anything and everything related to WCF Services/LOB Adapter channels. The third option, is the exact same as the second option, the only difference is, you must build your own tracking logic, message logging, tracing and etc. Thus the time taken to invest in this option will outweigh both the previous two option multiplied together, in the long run, you will have complete control over it’s complexity, and brittleness.

We at Tellago Studios, have made it very easy for you to monitor these WCF Adapters. We followed the 3rd option of creating our own custom WCF Service Behavior. This behavior supports logging messages, actions, operations, and also providing basic metrics such as number of operations called, number of errors over a specific period of time. When you configure the usage of the behavior for a WCF Receive location, we track these details, and provide a meaningful user interface to see the results.

Inside the SO-Aware Portal, Clicking on the Monitoring tab reveals this content:

Figure 1: Monitoring BizTalk Receive Locations

Figure 2: Viewing a BizTalk Orchestration published as WCF Receive Location Service

Figure 3: Request/Response

Figure 4: Request Message Body and Header Details

 

So How Easy is it for you to monitor the BizTalk WCF Adapters?

Well the answer is as easy as adding a Service Behavior to the service. BizTalk Server WCF Adapters, provide two ways of adding a service behavior to a service depending on where the service is being hosted. BizTalk Server WCF Adapter Services can be hosted inside of the BizTalk Process: BTSNTSVC.exe, or inside an isolated host instance: IIS (w3wp.exe). These hosted services only apply to BizTalk Receive locations, as BizTalk WCF Send adapters don’t host services, they just create Channel factories for sending messages to other endpoints.

Basic Steps:

  1. Install the SO-Aware Monitoring Behavior.
  2. Register your WCF Receive Location inside SO-Aware; register the service name, and service version, pointing to the correct location of the WSDL
  3. Turn on a tracking profile for the registered service version such as VerboseSoap

Figure 5: Registered BizTalk Orchestration published as a WCF Service Receive Location in SO-Aware

  1. Verify the SO-Aware Windows Host is started and running:

Figure 6: SO-Aware Windows Host

 

  1. Configure the Inprocess or Isolated Process Receive Location to use the SO-Aware Monitoring Behavior, and you’re done.

     

Installing the SO-Aware Monitoring Behavior

  1. The monitoring behavior can be found in the SO-Aware SDK.
  2. To install, GAC the Tellago.ServiceModel.Governance.Monitoring.Client, Version=1.1.0.0, Culture=neutral, PublicKeyToken=68f3f79a5464509d
    assembly; This assembly can be found inside the Reference Assemblies folder (C:\Program Files (x86)\Tellago Studios\SO-Aware\SDK\Reference Assemblies – by default).
  3. Register this behavior inside the Machine Configuration file (Both 32bit and 64bit, if on a 64bit machine).
  4. You can register the behavior with this syntax inside the <behaviorExtensions> section. (Note: this must be inside both 32bit and 64bit machine configuration files for 64bit systems).

 

Web.Config – Behavior Extension Registration

 

<add
name=SOAwareServiceMonitoring
type=Tellago.ServiceModel.Governance.Monitoring.MessageTrackingBehaviorElement, Tellago.ServiceModel.Governance.Monitoring.Client, Version=1.1.0.0, Culture=neutral, PublicKeyToken=68f3f79a5464509d />

 

 

 

Adding the SO-Aware Monitoring Behavior To an InProcess BizTalk WCF Receive Location

  1. Open up the BizTalk Administration Console, navigate to the registered WCF Receive Location. Change the WCF Adapter to use the WCF –Custom adapter.
  2. Configure the WCF Custom adapter to use the same binding and settings as the previous WCF Receive location.
  3. Click on the Behaviors and Add the SoAwareMonitoring Behavior.
  4. Configuring the Behavior is simple, set the serviceVersion and soAwareConfigurationCategory properties.
  5. The serviceVersion property is set to a registered Service Name appended with the “(1.0)” version number such as this:

Figure 7: Configuring the SO-Aware Service Monitoring Behavior

  1. The soAwareConfigurationCategory property is the name of the environment, if any such as Production or QA.
  2. Last, open up the BizTalk configuration file: BTSNTSVC.exe.config and add these two xml configuration entries:

 

BTSNTSVC.exe.config – Register Service Repository section inside Config Sections

 

<configSections >

<section
name=serviceRepository
type=Tellago.ServiceModel.Governance.ServiceConfiguration.ServiceRepositoryConfigurationSection, Tellago.ServiceModel.Governance.ServiceConfiguration, Version=1.1.0.0, Culture=neutral, PublicKeyToken=68f3f79a5464509d/>

</configSections>

 

 

 

BTSNTSVC.exe.config – Configure serviceRepository section to point to SO-Aware URL

 

<serviceRepository
url=http://localhost:8090/So-Aware/ServiceRepository.svc>

</serviceRepository>

 

 

 

  1. Save and you’re done.

 

Adding the SO-Aware Monitoring Behavior To an Isolated Process such as IIS for a BizTalk Receive Location

  1. Open up the web.config file for the IIS Virtual Directory hosting the BizTalk Receive Location.
  2. Add these sections to your web config file:

 

web.config – Register Service Repository section inside Config Sections

 

<configSections >

<section
name=serviceRepository
type=Tellago.ServiceModel.Governance.ServiceConfiguration.ServiceRepositoryConfigurationSection, Tellago.ServiceModel.Governance.ServiceConfiguration, Version=1.1.0.0, Culture=neutral, PublicKeyToken=68f3f79a5464509d/>

</configSections>

 

 

 

web.config – Configure serviceRepository section to point to SO-Aware URL

 

<serviceRepository
url=http://localhost:8090/So-Aware/ServiceRepository.svc>

</serviceRepository>

 

 

 

  1. Add the Behavior to the WCF Service:

 

web.config – Register Service Repository section inside Config Sections

 

<serviceBehaviors>

<behavior
name=ServiceBehaviorConfiguration>

<serviceDebug
httpHelpPageEnabled=true
httpsHelpPageEnabled=false
includeExceptionDetailInFaults=true />

<serviceMetadata
httpGetEnabled=true
httpsGetEnabled=false />

         <SOAwareServiceMonitoring
serviceVersion=BtsOrchSample(1.0) />

</behavior>

</serviceBehaviors>

 

 

 

  1. Configuring the Behavior is simple, set the serviceVersion and soAwareConfigurationCategory properties to the registered services inside SO-Aware.
  2. Save and you’re done.

     

Introducing SO-Aware

Some of you know that we’ve been working double time, once as a consultant developing and implementing SOA based solutions, and another as a developer creating a developing a REST based registry called: “SO-Aware“. Well I’d like to introduce you to our newest product here at Tellago Studios, Inc.

SO-Aware

What is SO-Aware? Well the answer lies in the story behind how and why we created it.

The answer is simple: we basically got tired of going into clients and hearing the same questions over and over again. These questions were “Which service does so and so? where does it reside? Is it behind the Firewall? Is there security implemented on it? Who built that service when we already have one that does that? How do we version this service because the old version doesn’t support this, and that, but the new one needs to? What other services depend on that one?
What’s OData, and how do we integrate it? Can we govern our REST endpoints? and on and on… I hope you get the picture…

We decided to put our heads down for while, work a double shift if you call it that, and answer those questions with a product you can download today, for free!!! called SO-Aware

I’ll let the product speak for itself, in the meantime, download it, check it out, and use it. Leave feedback so we can make it better.

Attaching an ESB 2.0 Itinerary To WCF Message Header

Attaching an ESB 2.0 Itinerary To WCF Message Header

Yesterday I was building a unit test to test an Http Adapter provider ( http://esbextlibrary.codeplex.com ) that we needed for communication with a Http based endpoint; and before you go down the road of why use HTTP Adapter vs the WCF Adapter and all its endless possibilities, the HTTP Legacy adapter didn’t have issues with badly formed messages like the WCF Adapter did.

When building the unit test, I wanted to use the ESB WCF Generic on ramps, and the WCF Adapter to send a message into the ESB. For those that don’t know this, there is a sample test client that comes with the ESB Samples. This test client contains code to embed an Itinerary and send this itinerary using a SOAP header. The sample also contains code to send to an ASMX web service, and a WCF service. In my opinion the samples are fairly cumbersome and awkward in regards to sending an itinerary into the ESB. Also, keep in mind that this test client was built for ESB 1.0, and ASMX focused doesn’t really take WCF and it’s power into account.

Thus the reasoning for this post…. I wanted to show that there are other ways accomplish this same goal, however using WCF, and the WCF InboundHeaders promoted property.

Let’s say I have an itinerary that looks as simple as this:

This itinerary uses a custom Http Adapter provider through the Resolve_Http_Endpoint resolver configuration to send in the message using the BizTalk HTTP Adapter.

To embed this itinerary into a WCF message, I’ll need to export this itinerary as XML and get the Itinerary content as such:

<Itinerary xmlns:xsi=\”http://www.w3.org/2001/XMLSchema-instance\” xmlns:xsd=\”http://www.w3.org/2001/XMLSchema\” uuid=\”\” beginTime=\”\” completeTime=\”\” state=\”Pending\” isRequestResponse=\”false\” servicecount=\”1\” name=\”HttpLegacyItinerary\” version=\”1.0\” xmlns=\”http://schemas.microsoft.biztalk.practices.esb.com/itinerary\”><BizTalkSegment interchangeId=\”\” epmRRCorrelationToken=\”\” receiveInstanceId=\”\” messageId=\”\” xmlns=\”\” /><ServiceInstance name=\”DTSTwoWaySyncResponse\” type=\”Messaging\” state=\”Pending\” position=\”0\” isRequestResponse=\”true\” xmlns=\”\” /><Services xmlns=\”\”><Service uuid=\”dde8337957054bb79fbdb8be148d5c02\” beginTime=\”\” completeTime=\”\” name=\”DTSTwoWaySyncResponse\” type=\”Messaging\” state=\”Pending\” isRequestResponse=\”true\” position=\”0\” serviceInstanceId=\”\” /></Services><ResolverGroups xmlns=\”\”><Resolvers serviceId=\”DTSTwoWaySyncResponse0\”>&lt;![CDATA[STATIC:\\transportType=HTTP;transportLocation=http_legacy://localhost/MyApp/default.aspx;action=;endpointConfig=RequestTimeout=30&amp;ResponseStatusCode=200;jaxRpcResponse=false;messageExchangePattern=;targetNamespace=;transformType=;]]&gt;</Resolvers></ResolverGroups></Itinerary>

Now that I have the itinerary content, I can use one of the Generic WCF Onramps, or create my own, which is actually what I did. To create your own WCF Generic on ramp:

  1. Create a BizTalk Receive Location inside the ESB BizTalk Application using the BizTalk Admin Console.

  2. Configure the Receive Location to use a WCF-Custom adapter. I choose to use the netTCP Binding with all the default settings. The Uri for this adapter was set to: net.tcp://localhost:8888/ReceiveMsg/service.svc

  3. Configure the Receive Location to use the ItineraryReceivePassthrough pipeline with all the defaults.

  4. Create a Dynamic Send port that matches the filter expressions you created inside the Itinerary. Mine were set to

    1. … ServiceName=DTSTwoWaySyncResponse

    2. … ServiceType=Messaging

    3. … ServiceState=Pending

    4. … IsRequestResponse=True

After I configured all the BizTalk receive and send ports, I needed the client code in my unit test project to invoke and send the test message to the WCF Generic on ramp, along with the attached itinerary as a Soap header (WCF Message Header).

To Configure a client with the message header I created a unit test with a method marked up with the [TestMethod] attribute and added the following code:

NetTcpBinding b = new NetTcpBinding ();

EndpointAddress epa = new EndpointAddress ( “net.tcp://localhost:8888/ReceiveMsg/service.svc” );

IBizTalkReceiveLocation proxy = ChannelFactory < IBizTalkReceiveLocation >.CreateChannel(b, epa);

Message msg = Message .CreateMessage( MessageVersion .Default, “SendToBizTalk” ,

XmlTextReader .Create(

new StringReader (

“<?xml version=\”1.0\” ?><TestMessage>Post To Http Adapter</TestMessage>” )));

Write_ItineraryTo_WCF_InboundHeaders( ref msg);

proxy.SendToBizTalk(msg);

The Method of interest here is the “ Write_ItineraryTo_WCF_InboundHeaders(ref msg);” line of code.

This method is outlined here:

private void Write_ItineraryTo_WCF_InboundHeaders( ref Message wcfMessage)

{

// code taken from msdn: http://technet.microsoft.com/en-us/library/bb246105%28BTS.20%29.aspx

//const string PropertiesToPromoteKey = “http://schemas.microsoft.com/BizTalk/2006/01/Adapters/WCF-properties/Promote&#8221;;

const string PropertiesToWriteKey = http://schemas.microsoft.com/BizTalk/2006/01/Adapters/WCF-properties/WriteToContext&#8221; ;

//XmlQualifiedName propItinerary = new XmlQualifiedName(“Itinerary”, “http://schemas.microsoft.biztalk.practices.esb.com/itinerary&#8221;);

XmlQualifiedName writeItinerary = new XmlQualifiedName ( “Itinerary” , http://schemas.microsoft.biztalk.practices.esb.com/itinerary&#8221; );

//Create a List of KeyValuePairs that indicate properties to be promoted to BizTalk message context.

//A Property Schema must be deployed and string values have a limit of 256 characters

//List<KeyValuePair<XmlQualifiedName, object>> promoteProps = new List<KeyValuePair<XmlQualifiedName, object>>();

//promoteProps.Add(new KeyValuePair<XmlQualifiedName, object>(propItinerary , HttpLegacyItinerary ));

//wcfMessage.Properties[PropertiesToPromoteKey] = promoteProps;

//Create a List of KeyValuePairs that indicate properties to be written to BizTalk message context

KeyValuePair < XmlQualifiedName , object > pair = new KeyValuePair < XmlQualifiedName , object >(writeItinerary,

HttpLegacyItinerary);

List < KeyValuePair < XmlQualifiedName , object >> writeProps = new List < KeyValuePair < XmlQualifiedName , object >>();

writeProps.Add(pair);

XmlSerializer ser = new XmlSerializer ( typeof ( Itinerary ), http://schemas.microsoft.biztalk.practices.esb.com/itinerary&#8221; );

//XmlSerializerNamespaces ns = new XmlSerializerNamespaces();

//ns.Add(“itin”, “http://schemas.microsoft.biztalk.practices.esb.com/itinerary&#8221;);

Itinerary itin =

( Itinerary )ser.Deserialize( XmlDictionaryReader .Create( new StringReader (HttpLegacyItinerary)));

MessageHeader header = MessageHeader .CreateHeader( “Esb” , “” , itin, new myItinerary (itin, “i” , http://schemas.microsoft.biztalk.practices.esb.com/itinerary&#8221; ));

// code for testing the Itinerary pipeline component…

//string str2 = header.ToString(); // .Replace(“\r\n”, “”);

//string pattern = “<[a-zA-Z0-9]:Itinerary.*?</[a-zA-Z0-9]:Itinerary>”;

//string str = Regex.Match(str2, pattern).Value;

wcfMessage.Headers.Add(header);

wcfMessage.Properties.Add(PropertiesToWriteKey, writeProps);

//wcfMessage.Properties[PropertiesToWriteKey] = writeProps;

}

This method takes the itinerary content as a string, and deserializes it into an actual Itinerary class from the ESB Itinerary OM v1.0 assembly. This class then used to create a WCF Message header using the MessageHeader.Create static method call.

There’s one major note here to pay attention to…

The ESB Itinerary pipeline Component that is used with the ItineraryReceivePassthrough pipeline retrieves the Itinerary from a SOAP 1.x message header which is written (not distinguished/nor promoted) into the BizTalk Message context by either the SOAP adapter, or the WCF Adapter. When using the SOAP legacy adapter in BizTalk, SOAP headers are automatically written to the message context, again I must stress, that they are written, not promoted, nor distinguished. This means that the values are not available to orchestrations, nor routing capabilities by default. To get these values promoted, then you have to deploy a property schema with the correct SOAP target namespace. For WCF adapters, however, to get the headers promoted or written you must follow this msdn article:

http://technet.microsoft.com/en-us/library/bb246105%28BTS.20%29.aspx

The component uses a regular expression in order to find the itinerary inside the Soap Headers content. The Regular expression is: string pattern = “<[a-zA-Z0-9]:Itinerary.*?</[a-zA-Z0-9]:Itinerary>”;

What this regular expression tells us is that we must take care to add a prefix qualifier with exactly 1 character to the Itinerary Message Header, otherwise, your itinerary will not be found. Also make sure that you don’t use the “ a” prefix qualifier, as this is already take by WCF and SOAP specifics. Thus any other value will do fine.

Well in order to do this I had to use the overridden MessageHeader.Create() static method, which supports the use of a custom XmlObjectSerializer. This will allow me to control the serialization of the ESB Itinerary so that I may achieve this functionality. This is outlined in the following code:

publicclassmyItinerary:XmlObjectSerializer

{

private Itinerary itin = null ;

private XmlSerializerNamespaces ns = null ;

private XmlSerializer ser = null ;

public myItinerary( Itinerary itin, string prefix, string nameSpace)

{

this .itin = itin;

ns = new XmlSerializerNamespaces ();

ns.Add(prefix, nameSpace);

ser = new XmlSerializer ( typeof ( Itinerary ), http://schemas.microsoft.biztalk.practices.esb.com/itinerary&#8221; );

}

public override bool IsStartObject( XmlDictionaryReader reader)

{

return true ;

}

public override object ReadObject( XmlDictionaryReader reader, bool verifyObjectName)

{

return ser.Deserialize(reader);

}

public override void WriteEndObject( XmlDictionaryWriter writer)

{

}

public override void WriteObjectContent( XmlDictionaryWriter writer, object graph)

{

ser.Serialize(writer , this .itin, this .ns);

}

public override void WriteStartObject( XmlDictionaryWriter writer, object graph)

{

}

}

This custom XmlObjectSerializer class just uses the XmlSerializer behind the scenes, and a XmlSerializerNamespaces instance to add the prefix and namespace setting when serializing the Itinerary ESB OM v1.0 class back into the message stream with a single character prefix qualifier.

After all this was done, I was able to send the test message into the WCF Channel, with the attached WCF Message Header containing the ESB 2.0 strict Itinerary.

Case Closed!!!

64Bit – WCF Custom Isolated – REST – “504” response

Tonight my fellow Tellago-ans, and I ran into a issue using the WCF-CustomIsolated Adapter on Windows Server 2008 64bit.

We were trying to use the .Net 3.5 bindings/REST styled architecture to support HTTPv1.1 Posts into BizTalk using the WCF CustomIsolated Adapter. In our lab and development environments, process worked like a charm. We used HTTP Fiddler to test the data and message flow. Here’s an example of what I mean:

In the above screen shot, we have configured a WCF-CustomIsolated adapter to use the .Net 3.5 WebHTTPBinding. (Instructions on how to do this can be found in Adrian’s blog). When using Fiddler, we can easily make posts into the BizTalk Server:

And our response we would receive would be something similar to this:

 

However upon moving our solution to a 64bit BizTalk Server running on IIS 7.0 (64bit Mode), the HTTP Post no longer worked. We started receiving “504” gateway issues.

Now oddly enough these servers were behind a firewall; we did need VPN accounts and software to access these servers; and also to mention, to get any internet access we went through a web proxy. This would lead any logically thinking person to believe the problem lie in one of these culprits: Firewall, VPN, or proxy…

Not so fast says the turtle!!!

Well, we started looking more into this and turned on WCF Tracing and looking into the Event Viewer and saw that we were receiving a weird WCF error. The error was:

The adapter “WCF-CustomIsolated” raised an error message. Details “System.XmlXmlException: Unexpected end of file.

At System.Xml.EncodingStreamWrapper.ProcessBuffer(Byte[] buffer, Int32 offset, Int32 count, Encoding encoding)…

(and on and on…)

 

We did not have a malformed message, after all it was Http Fiddler and we were just typing in a dummy xml message like “<Blah/>” and the WCF Adapter was failing horribly on the 64bit machine, where as the 32bit machine ran like charm… We started to think maybe it was an encoding issue, or something…

So Here’s the WTF for the day!!!

It turns out the issue lie in the fact that the WebHttpBinding element by default utilizes the transferMode set to Buffered.

Apparently there is an issue when trying to use this setting on a win64 bit OS, with IIS 7.0 in 64bit mode, with BizTalk WCF-CustomIsolated adapters… Our fix:

You guessed it: set the transferMode property to Streamed issue resolved.

Adding Transactional Support to a Custom WCF LOB Adapter

 

Building a custom WCF LOB Adapter is rather simple, after you’ve stepped through the process once or twice. As a matter of fact, there are many blogs, and references that step you through it, one such as this: http://geekswithblogs.net/michaelstephenson/archive/2009/02/10/129302.aspx, and references here: http://blogs.msdn.com/sonuarora/archive/tags/_2600_quot_3B00_WCF+LOB+Adapter+SDK_2600_quot_3B00_/default.aspx. I also suggest a good thorough reading of the BizTalk WCF Adapters and the WCF LOB Adapter pack here: http://www.microsoft.com/downloads/details.aspx?FamilyID=45537d57-cbbf-423e-b083-f71e07e4ae47&displaylang=en

 

The WCF LOB Adapter SDK is the framework that you can use to build WCF LOB Adapters for Sending and Receiving messages to LOB Systems. One thing I noticed that was missing in most of the documentation on MSDN, blogs, and forums, was an answer to some common questions: exactly how do you add Transactional support to a WCF Custom LOB Adapter? And when adding Transactional support to the adapter how does it work with BizTalk? Isn’t all this just built in? Are there any special steps you need to take or be aware of? – Hence the purpose of this blog.

Before I get into the nuts and bolts of this, I’d suggest you read a little on Transactions in WCF: http://msdn.microsoft.com/en-us/library/ms733904.aspx, as well as things to consider when using WCF LOB Adapter with BizTalk: http://blogs.msdn.com/adapters/archive/2009/03/12/things-to-consider-when-writing-wcf-lob-adapters-for-consumption-through-biztalk.aspx

Now after a refresh of Transactions with WCF, we understand that when we speak of transactions WCF Supports two transaction protocols: WS-AtomicTransactions, and Microsoft Based (DTC) OleDb transactions. The main difference between these two transaction types is the purpose and implementation of each. The Purpose of the WS-AtomicTransactions is to support interoperability between Non Microsoft databases such as Oracle, DB2, MySql and etc. However, for this to work, the implementation of such protocol requires that non Microsoft database also support and understand the WS-AT protocol, otherwise it is a mute point, and in some circles a “pipe dream” that will never come true. Unfortunately, this blog is not about which non Microsoft databases support WS-AT and the specifics of such protocol, nor is it about using the second natively supported OleTransaction protocol. To continue, the OleTransaction protocol is used specifically for Microsoft based distributed databases that utilize the Microsoft Distributed Transaction Coordinator (MS DTC), and this includes BizTalk SQL databases. The implementation of this protocol uses the native OleDb api’s to communicate with the MS DTC and databases enlisted within the transaction. Now that you remember there are these two major types of transactional support for WCF, we have to determine which of these two transaction types we would like to support in the Custom Adapter. Supporting one or the other, and possibly both dictates exactly which components need to be implemented, and what properties are available at runtime within the adapter.

There are many settings and options between both transactional protocols in WCF, however the main configuration for enabling transactions within WCF is through its transaction flow settings. In WCF, these settings are expressed using a number of different options. They are controlled through a combination of attributes, bindings, and configuration settings. For example, the Transaction Flow settings are compiled using the intersection of the following three values:

  1. Transaciton Flow Attribute: [TransactionFlow(TransactionFlowOption.Mandatory| TransactionFlowOption.Allowed| TransactionFlowOption.NotAllowed)]
  2. The TransactionFlow property on a standard binding: true|false
  3. The TransactionFlowProtocol property in the specific binding: WS-AtomicTransaction Protocol or OleTransactions Protocol

These three settings dictate to WCF if a transaction flow is required, supported or not allowed for a particular operation, if the transaction context and information will actually be flowed across the wire, and which transaction protocol format to use for flowing the transaction information across the wire, respectively. There is one major expected caveat here, in that when the WCF Operation transaction flow attribute uses Mandatory or Allowed, the operation can not be “One-way” or marked with the “One-Way” attribute: [IsOneWay=true]. This should make perfect sense, because we are requiring or supporting transactions, thus a Positive or Negative Synchronous acknowledgement must be returned to the original caller informing them that the process completed. In the “One-Way” scenario, there is no response, it is for the most part Asynchronous, thus there is no way to inform the original caller that the process completed. I hope this is clear, because this launches us into the next section… How to implement all this with the WCF LOB Adapter, and how BizTalk Adpaters work with this.

For those following up until now, you know we have the 3 values which need to be configured to support transactions. However, for those of you who have already built custom LOB Adapters, you may have noticed that the WCF LOB Adapter framework SDK does not provide a way to simply add a Transaction Flow attribute, nor does the adapter generated wizard provide a property, setting, or class that can set any of these three values. Not to mention, the framework produces different classes depending on if we want to support Inbound (“Receive”) adapters, Outbound (“Send”) adapters, Inbound-Outbound (“Solicit-Request”) adapters, and Outbound-Inbound (“Request-Response”) adapters, as well as asynchronous vs synchronous handlers

Let’s address these three settings one at a time to get a full overstanding of how this works…

  1. Using the Transaction Flow attribute with WCF Custom LOB Adapters.
    1. To understand this attribute I will show it in an example:

      Utilizing this attribute is usually done inside a Class or Interface, marked as the Service contract as below:

       

      [ServiceContract(Namespace=”http://www.microsoft.com/biztalk/2006/r2/wcf-adapter&#8221;)]

      public interface ITwoWayAsyncVoidTxn

      {

      // Methods


      [TransactionFlow(TransactionFlowOption.Mandatory), OperationContract(AsyncPattern=true, IsOneWay=false, Action="*", ReplyAction="*")]

      IAsyncResult BeginTwoWayMethod(Message message, AsyncCallback callback, object state);


      [TransactionFlow(TransactionFlowOption.Mandatory), OperationContract(IsOneWay=false, Action="BizTalkSubmit")]

      void BizTalkSubmit(Message

      message);

      void EndTwoWayMethod(IAsyncResult result);

      }

       

       

      In the above example, we have an interface named: ITwoWayAsyncVoidTxn, which is a service contract for the BizTalkServiceInstance that we will discuss later. This service contract outlines that the BeginTwoWayMethod, and BizTalkSubmit operations require a mandatory Transaction context and information be flowed into the Service. Specifically what this means is that the when a client is trying to discover or communicate with one of these two operations, the WCF Service description will contain a policy assertion that mandates communication to this operation requires a transaction soap header be sent and it must be understood.

       

      Adding this type of transaction flow attribute is done when designing the Service Contract. Once this is accomplished, the Service which implements this contract can be instantiated and run within the confines of the Service Host application. Normally the host will be an IIS Web Site, or custom built Host such as a windows background service, or command line application. Hosting this adapter inside a BizTalk Runtime is completely different which I’ll discuss later.

       

      Now you may be wondering, how do we specify a service contract inside the WCF LOB Custom Adapter? There is no place to create a Service Contract, specifying the operations which will support transactions at least not like the example above. If you recall, the LOB Adapter framework, provides a set of classes that you implement to handle inbound and outbound operations. Basically these classes pass in a collection of action values you can use to determine which operation to invoke, however the programming model is unlike the normal WCF programming model. The WCF LOB Adapter programming model is focused on three to four major components: The Connection to the System, The Binding settings, The Metadata Resolution, and the actual implementation to send and retrieve the data.

       

      When our WCF LOB Adapter is hosted inside the out of the box (OOB) IIS Hosting options, the best we can do is use the MetadataResolverHandler class that the framework provides, and a custom WSDL exporter class we would have to create, to yield the correct policy assertions. However, if you create or extend the OOB IIS Hosting options, such as creating your own ServiceHost class, and even create your own host altogether, adding the Transaction flow attribute is rather simple. Below is an example on how to add the transactionflow attribute to an operation inside a custom ServiceHost class:

       

      public class MyCustomServiceHost : ServiceHostBase

      {

       

      protected override System.ServiceModel.Description.ServiceDescription CreateDescription(out IDictionary<string, System.ServiceModel.Description.ContractDescription> implementedContracts)

      {

      implementedContracts = new Dictionary<string, ContractDescription>();

      ContractDescription contractDesc = new ContractDescription(“myCustomDescription”);

      contractDesc.Operations.Add(new OperationDescription(“BizTalkSubmit”, contractDesc));

      contractDesc.Operations[0].Behaviors.Add(new TransactionFlowAttribute(TransactionFlowOption.Mandatory));

       

      KeyedByTypeCollection<IServiceBehavior> behaviors = new KeyedByTypeCollection<IServiceBehavior>();

      behaviors.Add(new ServiceDebugBehavior() { IncludeExceptionDetailInFaults = true });

       

      ServiceEndpoint ep = new ServiceEndpoint(contractDesc );

      List<ServiceEndpoint> endpoints = new List<ServiceEndpoint>();

       

      endpoints.Add(ep);

      string serviceName = “MyCustomService”;

      string serviceNamespace = “http://tempuri.org&#8221;;

      Type serviceType = typeof(AddingTransactionFlow.Service1);

      ServiceDescription desc = new ServiceDescription(endpoints) { Behaviors = behaviors, Endpoints = endpoints, Name=serviceName, ServiceType=serviceType, Namespace=serviceNamespace };

       

      }

      }

       

       

      Now, I must stress, that adding the transaction flow attribute is only for the contracts to assert the notion that transaction are required, when using your WCF LOB Adapter inside IIS or a custom host. In reality, if you don’t need to assert that the transaction context is flowed from client to adapter then for the most part, the above is a mute point.

       

      So What about BizTalk Server Adapters, and its runtime environment?

       

      Good question. When our WCF LOB Adapter is hosted inside the BizTalk Runtime, it will run as apart of the WCF Custom adapter. What’s interesting to note here is that the WCF Custom Adapter (both send and receive) are built using a generic messaging pattern. This means is that there is no need to create a special service contract in code, because the WCF Custom Adapter utilizes five different generic service contracts to handle all possible scenarios. (Read here: http://www.biztalkgurus.com/newsletter/TheBizTalker-volume-12.html for more information.)

       

      On the receiving side of things, BizTalk creates a custom ServiceHost Class named BtsServiceHost that instantiates the BiztalkServiceInstance. The Service Host base class implements a method called CreateImplementedContract which basically checks to see if the BizTalk Receive Port/Receive Location configured pair is a 2 –way port or not, or if the configuration does not contains any Reply or Duplex binding elements, or if any transactions settings are configured in the adapter, or if an transaction flow binding element is in the binding configuration. Based on these options, the method returns the correct associated Interface with the correct behaviors and settings. For example, if the WCF Custom adapter is configured to use a WCF binding that contains a transaction flow binding element, and it also contains a binding element which implements one of the WCF IReply, IDuplex, or IReplySession Channel interfaces then the ITwoWayAsyncVoidTxn interface is selected. In a nutshell, if the receive location is configured as a transactional receive, then the ITwoWayAsyncVoidTxn interface is returned, otherwise one of the other four remaining interaces are returned. Notice that the ITwoWayAsyncVoidTxn, interface is decorated with the TransactionFlow attribute as outlined above.

       

      So What does this mean for my custom LOB Adapter when hosted in BizTalk?

       

      This is another good question. What this means is that when building a custom LOB Adapter, if you want the BizTalk WCF Custom Adapter to use the service contract with the TransactionFlow Attribute, just add a transaction flow binding element to the binding collection.

       

      // Inside the xxxAdapterBinding class …..

      // Override the CreateBindingElements

      #region Public Methods

       

      /// <summary>

      /// Creates a clone of the existing BindingElement and returns it

      /// </summary>

      public override BindingElementCollection CreateBindingElements()

      {

      if (null == bindingElements)

      {

      bindingElements = new BindingElementCollection();

      //Only create once

      if (this.transactional)

      bindingElements.Add(new System.ServiceModel.Channels.TransactionFlowBindingElement());

      bindingElements.Add(this.BindingElement);

      }

      return bindingElements.Clone();

      }

       

      #endregion Public Methods

       

       

      In the example above, I have overridden the CreateBindingElements() method of the xxxAdapterBinding class that gets created as a part of the WCF LOB Adapter Framework SDK. In this method, I check a public property transactional which is set on the adapter binding, to determine if I need to add the transaction flow binding element to the collection. After doing this, when this adapter is configured for use with the WCF Custom Adapter inside BizTalk, it will be considered a “transacted binding” in effect telling the BtsServiceHost base class to create a Service Instance of type ITwoWayAsyncVoidTxc. – exactly what we want!!! Now to the next section, TransactionFlow Property.

       

  2. Using the TransactionFlow property in a custom WCF LOB Adapter.

     

    The TransactionFlow property is a Boolean property that must be set on one of the standard OOB bindings, such as the NetTcpBinding, or the WsHttpBinding. If you are not encompassing any of these bindings inside your WCF LOB Adapter, then adding a transactionFlow binding element as outlined in the previous section is good enough.

     

  3. Choosing a TransactionFlowProtocol in a custom WCF LOB Adapter.

     

    The TransactionFlow Protocol is an enumeration that outlines the format of the transaction information you are flowing across the wire. It comes in three flavors:

    1. OleTransactions
    2. WSAtomicTransaction11
    3. WSAtomicTransactionOctober2004

    These values are set on the TransactionFlow binding element added to the binding elements from previous sections. The value you select mostly depends on the underlying database you are using for Atomic transaction support. If it’s a Microsoft based database or MS DTC managed resource (such as MSMQ, or Exchange), then you’re going to use OleTransactions. Other than that you’ll need to consult the third party database/resource to determine which WS-AT protocol they support.

     

After you have configured the three main settings for WCF to support transactions should be good to go… You have done everything you need to add support to a custom WCF LOB Adapter, however, there are a couple of small caveats that you should be aware of especially when working with the BizTalk WCF Receive Adapter.

BizTalk WCF Receive adapters in general connect to some endpoint, retrieve the message, and then submit the message into the BizTalk Message Box database. Throughout this whole process we never mention how this works from an atomic transactional perspective. When you have a WCF Custom LOB Adapter that needs to support atomic transactions, from the endpoint into the BizTalk SQL Messagebox database, you need to be aware that the atomic transaction will only work if:

  1. All the above are followed.
  2. You implement the TryReceive() method of the Asynchronous or Synchronous Inbound Handler.
  3. You configure the AdapterSettings to support transacted inbound channels, and you list the inbound channels the adapter will support.

Why do we need to implement the TryReceive() synchronous method in the Asynchronous handler?

First off, in a true atomic transaction which follows the ACID characteristics, we cannot have an inconsistent state outside the context of the current transaction. In BizTalk WCF Custom Adapters, this is enforced by invoking the synchronous, thread blocking form of the xxxReceive() method, aka TryReceive(). It doesn’t matter if you have implemented the Asynchronous handlers, nor the Synchronous handlers. Behind the scenes the code just calls the “syncHandler.TryReceive()” method. It just so happens that the “syncHandler” object is set to the AsyncHandler class if you have implemented the AsynchronousHandlers. Below is an example of the implementation:

    

Try

{

IAsyncInboundHandler listenerAsyncHandler = this.channelListener.ListenerAsyncHandler;

if (listenerAsyncHandler != null)

{

IInboundReply reply;

flag = listenerAsyncHandler.TryReceive(helper.RemainingTimeout, out message, out reply);

}

Else

{

return true;

}

}

catch (Exception exception)

{

 

 

How do I configure AdapterSettings?

To configure the adapter settings class, you access the AdapterSettings instance from the xxxAdapter class created from the WCF LOB Adapter SDK framework. The AdapterSettings class instance can be found as the Settings property available on the xxxAdapter class. This class contains settings about the Connection Pool, Messaging settings, Metadata Settings, and Cache Settings. Specifically, the WCF LOB Adapter framework uses the Adapter class as the base class, which derives from the TransportBindingElement, and implements the ITransactedBindingElement. This interface helps determine if a custom Adapter supports atomic transaction receiving through the TransactedReceiveEnabled property. By default, this property in the base Adapter class simply returns:

 

return this.Settings.Messaging.SupportsTransactedInbound;

 

 

In order for your adapter to work as expected this last piece of information needs to fall in place. Here’s an example in a custom xxxAdapter class constructor:

 

/// <summary>

/// Initializes a new instance of the CustomAdapter class with a binding

/// </summary>

public CustomAdapter(CustomAdapter binding)

: base(binding)

{

this.EnableConnectionPooling = binding.EnableConnectionPooling;

this.MaxConnectionsPerSystem = binding.MaxConnectionsPerSystem;

this.MaxAvailableConnections = binding.MaxAvailableConnections;

this.HandlersShareSameConnection = binding.HandlersShareSameConnection;

this.transactional = binding.transactional;

this.pollingInterval = binding.pollingInterval;

if (binding.transactional)

{

Settings.Messaging.SupportsTransactedInbound = true;

Settings.Messaging.SupportedInboundChannels = SupportedInboundChannels.IInputChannel;

}

 

if (binding.enableConnectionPooling )

{

Settings.ConnectionPool.EnablePooling = true;

Settings.ConnectionPool.HandlersShareSameConnection = binding.handlersShareSameConnection;

}


 

}

 

 

I hope this document helps in explaining how to support transactions in WCF LOB Custom Adapters…

Happy Coding!

Configuring a Custom WCF LOB Adapter with ESB 2.0 Toolkit

This post will show how to use BizTalk ESB toolkit 2.0 with the BRE Resolver for setting a custom WCF Adapter setting. In one of my current projects, my team and I were faced with creating some custom WCF LOB Adapters to communicate with various servers. Some of these servers were running on Unix based OS’s and even still others were proprietary and used serial line based communication protocols. In our implementation, we used BizTalk 2009 and the ESB toolkit 2.0 to create a massive ESB to send data to these systems. The interesting part about this does not rely in the fact that the systems we were communicating with were proprietary that warrants a separate blog posting about its trials and tribulations. The most intriguing part was that we had to support dynamic endpoints. We had to support ever changing Adapters, endpoints and worry about the addition of new systems coming online within months of going to production. By the way, all of this had to be accomplished without affecting the current production running solution. So, how do we accomplish this???

 

As we started to dive into the agile challenge at hand, we discovered that the overall concept of this project was using a Controller pattern. This is where commands are sent from “Controller” to client listeners. In our implementation, the Controller sent the command to the ESB, and it acted as a second “Controller” where it routed, transformed, duplicated, filtered, and suppressed the commands to various client listeners.

Figure 1 ESB Controller Pattern

We accomplished the routing, and transformation using BizTalk Business Rules Engine (BRE). The ESB toolkit 2.0 allows BizTalk Server to become an ESB, and within it there is a BRE resolver who uses the BRE to determine which transformation to apply, and which endpoint to send the information to. Using the BRE Resolver to determine a map is outlined in various blog postings, as well as samples inside the ESB 2.0 toolkit documentation so I won’t drill into the details on that. In addition to this, using the BRE Resolver to select a particular send Adapter (endpoint) in BizTalk is also outlined in various blogs and sample documentation, again I will not delve into that. However, using the BRE Resolver to configure a custom WCF LOB Adapter is not covered, and I have found it wanting on various blogs; thus the reasoning for this article.

In order to use the BRE Resolver to configure your send adapter, it is always best to verify the WCF LOB Adapter is successfully running and configured correctly using a Static Send port. Once this is done, this takes most of the guess work involved in dynamically setting it up.

In our example, we built a generic adapter around set of patterns we discovered when communicating to the various endpoints using Managed Extension Framework (MEF). I’ll blog on this in another posting. To continue, we have a custom WCF LOB Adapter called “Generic” which uses a MEF component to invoke the endpoint using any particular protocol needed.

Figure 2 Static Configuration of Send Port

To statically configure this, we use a WCF-Custom adapter, the genericAdapterBinding created using the WCF LOB Adapter framework, a Soap Action header of deleteCustomers, and an Uri set to generic://MefEndpointProcessor/MefSsoKey. Just for explanation of the Uri, the MefEndpointProcessor is the name of the MEF endpoint processor to use for a particular endpoint, and the MefSsoKey is a SSO Key used within the SSO Configuration database to retrieve any custom connection settings for the endpoint/server we are sending to.

Once we have configured this statically and it works, we’re ready to move on to the more interesting part, how to configure this using the BRE Resolver inside a Business rule and thus fulfill our requirement of adding endpoints dynamically without affecting the overall system at production time.

The steps to configure the WCF Custom Adapter at a high level are rather easy.

  1. First we need an itinerary which will use the ESB BRE Resolver, so create an Itinerary that receives the message from an OnRamp.
  2. Specify the Itinerary Service routing step to route the message.
  3. Within the Itinerary routing step, create a BRE Resolver to resolve the send adapter promoted properties to use for routing to the WCF Custom adapter.
  4. Create an Off Ramp extender, and an Off Ramp, specify the dynamic port for the off ramp.

To resolve the WCF Custom adapter dynamically, configure the BRE Resolver to use a policy which contains a set of rules that have actions that configure the endpoint settings.

Figure 3 BRE Policy for configuring WCF Custom LOB Adapter

The first step in creating a BRE rule to configure the endpoint is to create a policy, and add a rule to the policy using the BRE Composer. In our example our policy is named Tellago.Demos.ESB.BRE.

There are 2 rules within the policy, one named: isActionITV and the other isNOTActionITV. These rules check the incoming command message from the “Controller” to determine who to send the message to. If the action is set to ITV then the action that executes are a series of steps to configure the WCF Custom adapter to send it to the ITV Mef Processor, for transmission to the ITV endpoint.

The next step is to configure the actions within the rules. When using the ESB 2.0 toolkit, there are a set of vocabulary definitions installed that populate a dictionary collection of key=value pairs. These keyed items that need values populated are:

  • Endpoint Config
  • Endpoint Fix JAX RPC
  • Endpoint Message Exchange Pattern
  • Endpoint Outbound Transport Location
  • Endpoint Outbound Transport Type
  • Endpoint Target Namespace
  • Endpoint Transport Namespace
  • Endpoint WCF Action

The items in the collection we are interested in are the Endpoint Config, Transport Location, Transport Type, Target Namespace, Transport Namespace and WCF Action. Once these items are populated with values after the rules execute, the ESB uses the Adapter provider to promote the associated items in the collection for the dynamic configuration of the send port. In our example, the WCF adapter provider will be used to promote binding type and configuration, WCF action, namespaces and transport Uri values.

Specifically the WCF adapter type will be WCF-Custom; the transport location will be set to generic://MefEndpointProcessor/MefSsoKey; the WCF binding information will be set to <genericAdapterBinding><binding name=”genericAdapterBinding” /></genericAdapterBinding> (even though you only set the <binding…> portion of it and leave off the <genericAdapterBinding> section inside the rule); the namespace for the message will be set to http://Tellago.Demos.Schemas.EsbBreCommand; the WCF Action will be set to deleteCustomers.

When using the WCF Custom LOB Adapter, the WCF Adapter type must be set to WCF-Custom any other value will yield an incorrect configuration. The Transport location should be set to the Uri which the Custom adapter is expecting. The Endpoint Config is a set of values that support setting WCF behaviors, binding information, and any other custom information for WCF to run. To complete the configuration, WCF also requires the namespace of the message, and action to be set to a non-empty string value.

After you’ve completed all these steps, test it out you’ll be pleasantly surprised by the agility of the solution.

Happy ESB’ng