BizTalk Data Services (RFID)

Greetings all,

It’s that time again where we at Tellago put out updates, code, utilities and you name it dealing with BizTalk. Last week a colleague of mine: Suresh, added to our already awesome framework: BizTalk Data Services. Suresh added the ability to query, and update RFID services and devices using a RESTful architecture in BizTalk Data Services.

When you get a chance download it and check it out!!!

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.

     

Using SO-Aware with BizTalk 2010 and ESB 2.1 part 1 of 2

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 using SO-Aware with BizTalk 2010 and ESB 2.1 section. 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, Activity Monitoring and last but not least Service Cataloging.

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 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 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.

 

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.

 

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.

 

Which leads us into the next discussion, using SO-Aware with BizTalk 2010 and ESB 2.1. First, for those that don’t know BizTalk and ESB 2.1, here’s a quick blurb from Microsoft’s web site on each technology:

  What is BizTalk?

BizTalk Server is Microsoft’s Integration and connectivity server solution. A mature product on its seventh release, BizTalk Server 2010 provides a solution that allows organizations to more easily connect disparate systems. Including over 25 multi-platform adapters and a robust messaging infrastructure, BizTalk Server provides connectivity between core systems both inside and outside your organization. In addition to integration functionality, BizTalk also provides strong durable messaging, a rules engine, EDI connectivity, Business Activity Monitoring (BAM), RFID capabilities and IBM Host/Mainframe connectivity.

What is BizTalk ESB 2.1?

The BizTalk ESB Toolkit is a collection of tools and libraries that extend BizTalk Server capabilities of supporting a loosely coupled and dynamic messaging architecture. It functions as middleware that provides tools for rapid mediation between services and their consumers. Enabling maximum flexibility at run time, the BizTalk ESB Toolkit simplifies loosely coupled composition of service endpoints and management of service interactions.

Using SO-Aware with BizTalk 2010

One of the main features of BizTalk Server is its adapter component design. BizTalk uses the Adapters to communicate to various systems, such as Line of Business systems, Databases, Mainframe Applications, and most notably Web Services. To be more specific on web services, BizTalk contains WCF adapters that facilitate communication to different types of web services: REST/ODATA and SOAP.  The more involved BizTalk becomes in integration solutions, the more WCF adapter, and Web services are used to compliment or run the entire solution.

Maintaining such as solution can easily become a maintenance nightmare. When a particular web service changes, or is versioned there are no tools that help keep track of this. Usually trying to remember all the configuration values are impossible, and the solution becomes brittle to the slightest change. SO-Aware easily alleviates this by Service Cataloging, Centralized Configuration, Dependency Modeling, and Dynamic Resolution.

With Service Cataloging, SO-Aware you can register the WCF Adapter configurations for Receive Locations (BizTalk as a Service Provider), and Web Service configurations that the WCF Adapters communicate with through Send Ports (BizTalk as a Service Consumer/client). Below is an example of what may be registered.

BizTalk WCF Adapters Cataloged

Centralized Configuration allows a BizTalk Architect to store configurations about WCF Adapter bindings (individual components that make up a complete communication channel for the WCF Adapter). Using the Centralized confguration of SO-Aware, you can store binding information, behavior information, extension information, security details, transport protocol information, line of business information and etc. We include binding and behavior templates that even provide a dynamic user interface  for configuring the commonly changed settings. This feature facilitates the use of BizTalk’s WCF LOB adapters such as SAP, Oracle and Oracle E-Business Suite, and SQL. Below is an example of registering the Oracle E-Business Suite LOB Adapter binding and  binding template.

image

With Dependency Modeling, you can quickly view which services depend on each other. A reason why this is important in BizTalk is simple. Say you have a business process flow that requires order information to be uploaded to two different web services in one atomic transaction, such as an Order Header Service and a Order Detail Service. This business process can be modeled using BizTalk’s Orchestration design. Below is an image depicting the business process flow.

image

When these services change later, who will remember that these services are dependent upon each other, and that this orchestration depends on both of these services? SO-Aware can easily depict this dependency:

image

Dynamic Resolution

Another option we have with BizTalk Server is using Dynamic Adapters. Dynamic adapters allow for runtime resolution of adapters such as WCF Adapters. This resolution can be performed in two BizTalk components: Orchestrations and pipeline components. Using SO-Aware, dynamic runtime resolution is very easy to do. SO-Aware yields a REST-ful interface to every aspect of its repository. This means that any component which supports invoking .Net code, such as BizTalk’s orchestrations and pipeline components do, will support querying SO-Aware for adapter configuration. Included in the SDK is an example of how to use a BizTalk Orchestration with Dynamic ports and adapters to implement a runtime resolution solution. Below is an example of code inside the BizTalk Orchestration of invoking dynamic runtime resolution.

image

In the above example, the ProcessOrderInformation Orchestration is dynamically resolving the OrderDetailPort  which is configured at runtime to send data to the OrderDetailService registered inside SO-Aware. At runtime, when BizTalk Receives an Order, it will split the order into a Header message and a Order Details message and send both messages to their respective services in one atomic transaction. The differenece being that the OrderDetailService’s binding, configuration, address, and transport protocol will be dynamically resolved using SO-Aware api calls. The Order Detail Service is registered inside the SO-Aware Repository and when queried will return the WCF service configuration details. Below are some depictions of the Order Detail Service SO-Aware registration.

image

 

image

Remember this example was using an Orchestration, however the same applies to BizTalk Pipeline components as well. In the next posting, I will discuss how SO-Aware can be utilized with ESB 2.1 and BizTalk 2010 together.

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!!!

Overstanding the ESB Itinerary Cache

Overstanding the ESB Itinerary Cache

If you Google-Bing the ESB Itinerary Cache you come across a definition of the likes: “ The itinerary cachingpipeline component for use in Solicit-Response send ports.”

and…

Messages submitted through the ESB itinerary on-ramp can be either a one-way or two-way (request-response) itinerary. To support request-response itineraries, the itinerary mechanism must provide caching for BizTalk dynamic Solicit-Response send ports.

The Itinerary Cache pipeline component persists the itinerary stored in the outbound message and reapplies it to the response message returned to the send port after the service call is complete. This allows the itinerary service to process and execute other services defined after the current service in the itinerary.

The ESB Itinerary Cache pipeline component caches the itinerary during the period that the message is in the Send Transmit pipeline process cycle. The component then retrieves the itinerary and writes it to a BizTalk context property in the inbound message after receipt during the Send Receive process cycle.”

The above definitions are taken directly from MSDN…

There is no need to further explain what this component is used for as the above definitions handle this nicely…

Question: How does this thingy-magiggy work???

Answer:Under the hood, the ESB ItineraryCache is a pipeline component that caches the Itinerary into a cache object defined the the Enterprise Library 4.1 caching application block mechanism upon sending the message, and retrieves the itinerary from the cache upon receiving the the message. Thus this component functions differently upon if the component is executed from a Send pipeline versus a Receive Pipeline.

The Default Mechanism:

By default this caching is done in memory and only caches your itinerary for 5 minutes. The Itinerary is stored and retrieved through the Cache object collection using the CorrelationContextPropertyName property which is set on the pipeline component property sheet. Again, by default the value for this property is the TransmitWorkID context property which can be found as a BizTalk system property.

What is interesting to note here, is that for every itinerary that is transmitted or received, this property must be promoted in order to write or read to the caching collection; along with the fact that the value for this property must be unique within a 5 minute time span, otherwise an non-unique key argument exception will be thrown. Also by default, this property is only promoted by BizTalk when the message is received from a 2-way Receive Port. This property is usually used in conjunction with the IsRequestResponse , the IsSolictResponse, the WasSolicitResponse , and the RouteDirectToTP BizTalk system properties to help correlate 2-way synchronous responses within BizTalk 2 way adapters, orchestrations, and other 2 way patterns. Thus, if you are not using a 2 way receive port, 2-way Receive Adapter, or Correlated 2 way design pattern, these properties, including the TransmitWorkID will not be promoted. This means that by default you won’t be able to use the itinerary caching component.

Another note to take interest in is that when using this caching component, upon transmission (sending) of the message, the component will only write the itinerary into the cache if a few conditions are met:

  1. The ESB determines that the direction of the message flow is a true “SendTransmit”. How the ESB Determines this condition is using two branches. The first branch checks to see if the IsRequestResponse property is true. If so, the ESB continues to check for conditions that do not satisfy the Receive Transmit (the sending side of a 2 way receive port), or Receive Inbound (the receiving side of the 2-way receive port). The Receiving Transmit conditions are simply checked against the Send Port Name being promoted and WasSolicitResponse containing any value; whereas the Receiving Inbound conditions are checked against the Receive Port Name being promoted. If these cases are not true, ESB checks for the IsSolicitResponse = true , which determines that the message direction is a true “SendTransmit”. The second branch checks for the case of IsRequestResponse = false. If the Receive Port Name, and Send Port Names are not promoted, nor is the WasSolicitResponse = true, then the ESB checks for the Send Port ID property to be promoted, in which signals the message direction to be a true “SendTransmit”
  2. BizTalk has properly promoted the BTS.IsRequestResponse or the ESB Itinerary.IsRequestResponse properties to true. This is done again by using a 2 -way Receive Port, or using an Itinerary, Itinerary Routing shape, Off Ramp or Off Ramp extender and setting its IsRequestResponse property to “ true”, and in some cases, all of the shapes in question must have these properties to “true”.

  3. When writing the Itinerary to the cache, the CorrelationContextPropertyName value exists.

  4. When writing the Itinerary to the cache, a duplicate does not already exist for the CorrelationContextPropertyName value.

Upon receiving the message, the same type of checks are also evaluated when trying to retrieve the itinerary from the cache:

  1. When reading from the cache, the CorrelationContextPropertyName value must exist.

  2. The ESB determines that the direction of the message flow is a true “SendInbound”. How the ESB Determines this condition is also using two branches. The first branch is exactly like the “SendTransmit” logic, the only exception being ESB does NOT check for the IsSolicitResponse = true; however does check to see if the Send Port Name is promoted, which determines that the message direction is a true “SendInbound”. The second branch is also similar to the “SendTransmit” with the only exception being the if the Send Port Name is promoted, the message direction is considered a true “SendInbound” .

If you don’t want to be subjected to using 2-way receive ports, or you want to use this Caching mechanism outside the scopes of a 2-way Send port (i.e. a 2-way Asynchronous design pattern), you can use a custom CorrelationContextPropertyName , and Namespace setting, and override the default IsRequestResponse , WasSolicitResponse , and optionally RouteDirectToTP (for sending back to the original caller), system properties. If you’ve read above, you should have a basic overstanding of how the Itinerary Cache works, which should allow you to be dangerous in how to model 2 way Itineraries. See a future post on this…

Extending the Default Caching Mechanism:

Extending the default Itinerary Caching component is as simple as changing the default CorrelationContextPropertyName , or changing the Timeout property, Creating a custom Itinerary Caching component, or even the default Caching manager.

If you don’t want to be subjected to using 2-way receive ports, or you want to use this Caching mechanism outside the scopes of a 2-way Send port (i.e. a 2-way Asynchronous design pattern), you can use a custom CorrelationContextPropertyName , and Namespace setting, and override the default IsRequestResponse , WasSolicitResponse , and optionally RouteDirectToTP (for sending back to the original caller), system properties. If you’ve read above, you should have a basic overstanding of how the Itinerary Cache works, which should allow you to be dangerous in how to model 2 way Itineraries. See a future post on this…

Routing 2-way Synchronous response to endpoints other than the initiator

Routing 2-way Synchronous response to endpoints other than the initiator

Recently, in our implementation of an ESB 2.0 BizTalk 2009 solution, a requirement popped up where an endpoint initiates a request to a synchronous system, and the system responds back with a response. In typical development practices, this is referred to a request/response or client/server pattern. You may say to yourself, “big deal, this is easy…” In a normal solution, the response is routed back to the initiator of the request. Lo and behold, we came across a scenario, where the response needs to be routed to other endpoints based on fairly complex rules and processes; not the original caller (initiator), hence the purpose of this blog entry.

As a BizTalk Developer, you say the above is not a problem. Why? Because BizTalk can handle designs like this with ease, using orchestrations, static send ports with unique filter expressions, and even orchestrations with dynamic send ports. You can actually put the complex logic, rules and processes inside custom components, or the Business Rules Engine (BRE) within orchestrations or even pipeline components. However if we’re staying true to the Agile game, and we want to build a architecturally sound ESB, using the normal BizTalk approach doesn’t fit the bill, in other words, it won’t work. The reasons why are simple, we either loose Agility, gain invisibility, create a mystery black box with custom code, or have increasingly complex algorithms which are prone to break and miss the agile mark altogether. The goal here is to think about BizTalk 2009 and the ESB 2.0 toolkit as a set of capabilities and then model the capabilities to generate the result you want.

Question: So now what capabilities do we need?

Answer: We want the ability to design steps or process flow which accepts a message from an initiator, and then based off of some rules, dynamically determine the 2 way service, retrieve the response and through more rules dynamically send the response to another endpoint who is not the initiator.

Question: So which capabilities match BizTalk and ESB?

Answer: The capabilities to design steps and process flows are the Itineraries pattern of ESB. The BizTalk Business Rules Engine incorporates the complex logic. The ESB Resolvers assist to resolve logic, and endpoint addresses, such as the 2 way service to invoke, and the resulting endpoint to send the responses to. In addition to the resolvers, BizTalk provides WCF Adapters to send and receive the request/response and results.

Question: So how do we do this?

Answer: You model an itinerary in BizTalk 2009’s ESB 2.0 using the Itinerary designer that accepts a message from a caller (initiator), and then sends the request to a 2-way Synchronous Endpoint, which then blocks (correlates automatically for the response) and then sends the Response to a completely different endpoint based off of a Business rule.

Question: Is this easy?

Answer: Yep Follow these high level steps:

  1. Create an Itinerary using the ESB Itinerary Designer.

  2. Configure the Itinerary to use a 2-way Receive Port, even though you will use a 1-way receive port in production.

  3. Configure the Itinerary to be a Request/Response Itinerary, which is to say verify the IsRequestResponse = true. (See the Itinerary Cache Post for more info on this… https://dgoins.wordpress.com/2010/02/22/overstanding-the-esb-itinerary-cache-2/)

  4. Model the itinerary with with the call the the synchronous request/response endpoint.

  5. Within your steps, use the BRE Resolver to determine maps, and endpoint addresses for the configuration of which synchronous endpoint to send the request to.

  6. Optionally: Use the Service Broker shape to route to different endpoints based off of promoted properties from the response.

  7. Lastly, use a Business Rule Resolver to dynamically determine the resulting endpoint configurations.

Below is an example of an Itinerary which uses Business Rules to invoke a Synchronous endpoint and routes the results to another endpoint which is not the initiator.

Explanation of Itinerary:

The above image can be read following the directions of the arrows, starting with the upper Left shape named: ReceiveMsg . This first shape signifies an ESB OnRamp, which equates to a BizTalk Physical receive port.

The next shape: MapToCanonical represents an ESB Messaging Step. Messaging steps are processes or components that are destined to execute inside of pipelines. These pipelines are configured with ESB based pipeline components such as the ESB Dispathcher, which understand the Itinerary step mechanism to execute ESB Itinerary steps. In the above example, the MapToCanonical step uses a Transform based ESB Step process to execute a BizTalk transformation (Map) to convert the message received from the OnRamp into a canonical message format. The map which executes is determined by the ESB Resolver: SetMapToCanonical . This resolver utilizes the BRE Resolver to execute and evaluate complex logic using the BizTalk Business Rules Engine (BRE) to choose the correct map for transformation.

The next step: RouteToEndPoint is another ESB messaging step, which utilizes the ESB Routing process to promote properties and publish the message to the BizTalk Message box. This step is configured to use the BRE Resolver named: GetURI . This resolver executes business logic and evaluate rules to determine the URI address, and Send adapter to send the request to.

The next step: PushToMsgBox, is an off ramp extender shape which gathers more promoted property information from the actual ESB OffRamp: SendToEndPoint (BizTalk Physical Send Port). Here’s an interesting point to note, remember that the ESB Itinerary pattern is just a model to design steps as in the order of execution, not the actual process such as an orchestration. As we define our steps, BizTalk needs to know where these ordered steps should execute. In other words, when we use “Messaging Steps” these obviously execute inside Messaging components of BizTalk, hence pipelines stages. However, for BizTalk we have two sides of the messaging system. BizTalk has a messaging stack before saving to the Message Box (Receive Pipelines), and a stack after the Message Box (Send Pipeline). In the design above, the PushToMsgBox off ramp extender is used to signify all steps after this will execute in the Send Handler (Send pipeline stages).

The next step after the off ramp extender is the MapToEndPoint step. This step, again is a messaging step which uses the BRE Resolver named: SetMapToEndPoint , will be executed after the message is published to the BizTalk Message box, and inside the send pipeline associated with the send port configured through Off Ramp: SendToEndPoint .

The next step is the SendToEndPoint ESB Off Ramp. This Off Ramp is configured to use a 2-way Solicit-Response dynamic send port. From a BizTalk perspective, the 2-way dynamic send port is configured to use a send pipeline which contains the ESB Dispatcher pipeline component, and the ESB Itinerary Cache pipeline component. The receive pipeline is configured to use the ESB Itinerary Cache, Xml Disassembler, and the ESB Dispatcher components respectively. The 2-way send port is also configured with the 4 basic ESB promoted properties within the Filter expression. Screen shots of the various properties and values are provided below.

The next step is MapResponseToCanonical . Notice here that the messaging step is set to run in the Receive Handler (Receive Pipeline) of the SendToEndPoint off ramp. This means that this step runs on the receiving side of the 2-way dynamic send port. This step is configured to use the ESB Transformation service, and the BRE Resolver to again determine which map to use for transformation. This step transforms the reponse to a canonical format to eventually publish back to the Message Box.

The next step is RouteResponseToEndPoint, just like step before, this step also is configured to execute in the Receive Handler of the SendToEndPoint off ramp. Which also means it will execute on the receiving side of the 2-way dynamic send port. This step is also configured to use the ESB Routing service and again the BRE Resolver to determine the Endpoint URI and adapter to use to send the final response.

The next step is PushResponseToMsgBox. This step is an off ramp extender which signifies that the remaining steps will be executed after the message is published to the Message Box, along with any other special properties that need to be promoted.

The next step is MapResponseToEndPoint, this step is a messaging step which again uses the ESB Routing Service and the BRE Resolver to determine the Uri address and BizTalk Send adapter settings to use for sending the response.

The last step is SendResponseToEndPoint, this is the Off Ramp which points to a simple Dynamic Send port for actually sending the response from BizTalk.

64 Bit ESB/BizTalk Lessons Learned

As some of you are well aware of. We at Tellago (http://www.tellago.com) are implementing a major ESB 2.0/BizTalk 2009 (64 bit) solution. This blog posts servers as a reminder of the configurations, issues, and *gotchas* we have identified thus far. So this list will be a living list J

  1. Beware of the applications that are really 32bit running on a 64bit host. Use the Task Manager to check to see if it’s a 32bit or 64bit process
    1. For example when configuring behaviors or anything that is done in a configuration file for any normal WCF Service using the SvcUtility (which is a 32bit process), the settings need to be applied in the 32bit configuration file to see it, as well as in the 64bit configuration file locations. *Twice as nice* – yeah
    2. Locations to be aware of for the Machine Config:
      1. %windows%\Microsoft.Net\v.x.x\Framework64\Config
      2. %windows%\Microsoft.Net\v.x.x\Framework\Config
    3. Another example is when configuring a WCF Custom adapter using the BizTalk Admin Console (32bit process) reads the Machine configuration from the 32 bit location as outlined above instead of the 64 bit locaiton, however the runtime reads it from the 64 bit location *gotcha*!!! Thus any behaviors or custom bindings needs to be configured in both the 32bit and 64bit machine configuration files…. !!!
  2. When using The BRE with classes that use static methods the Registry location has changed for 64 bit it’s now in the Wow6432Node… however the StaticSupport value is a DWORD(32 bit) not 64bit… *Gotcha*!!!
    1. Static Support:
      1. HKLM\Software\Wow6432Node\Microsoft\BusinessRules\3.0\
      2. Value to set: StaticSupport DWORD (32bit) 1
  3. When configuring WCF Custom Isolated URL’s in IIS 7.0 64bit: Don’t copy paste Urls, manually type them in. *gotcha*!!!
  4. For BizTalk configuration, trace sources, SVC traces and etc… change the BizTalk 64bit exe configuration file.
  5. When running WCF-CustomIsolated, and IIS 7.0 applications, verify that the assemblies running in this space are not limited to 32bit hosts, if so, run the application pool as a 32 bit host only mode.
  6. Beware of using the BizTalkExplorerOM classes in components, by default this library does not support 64 bit. To use any of this library, you must run it in a 32 bit Default Host, or recompile the component that uses this library with the 32bit compile option in VS.NET; just make sure you change it from the default *any* compile option. There is an MSDN article on this I’ll post it later…
  7. MIME Decoder only supports 32 bit. Thus you’ll need to run this in the 32bit Host instance
  8. SQL Adapter (Not WCF-SQL Adapter with the WCF LOB Adapter Kit) only supports 32bit Host Instance
  9. Beware of using Dynamic Send Ports with a 32 bit default host. All dynamically configured adapters will use the Default Host Instance for that 32bit Default Host. There is no way to dynamically configure which Host a dynamic adapter will use.

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!

What Happened to the ESB MSMQ Adapter Provider?

In our current, project we built an itinerary that utilized the Business Rules Engine (BRE) to set an endpoint to the MSMQ Adapter. Lo and behold, there was no MSMQ Adapter provider, until now, Below is our source code for cheating the Adapter Provider framework for building a custom MSMQ Adapter Provider. The code was simple and to the point. No explanation necessary…

Source Code:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Microsoft.Practices.ESB.Adapter;

using Microsoft.BizTalk.Message.Interop;

 

 

namespace Tellago.ESB.AdapterProviders

{

/// <summary>

/// Ths class implements IAdapterProvider for setting the context properties of

/// the BTS MSMQ adapter. Loaded by the AdapterMgr class

/// </summary>

public class MSMQAdapterProvider : BaseAdapterProvider

{

public override string AdapterName

{

get { return “MSMQ”; }

}

 

public override void SetEndpoint(Dictionary<string, string> ResolverDictionary, IBaseMessageContext msg)

{

base.SetEndpoint(ResolverDictionary, msg);

}

 

public override string AdapterContextPropertyNamespace

{

get

{

return “http://schemas.microsoft.com/BizTalk/2003/msmq-properties&#8221;;

}

}

 

protected override void SetEndpointContextProperties(IBaseMessageContext pipelineContext, string endpointConfig)

{

base.SetEndpointContextProperties(pipelineContext, endpointConfig);

 

string[] properties = endpointConfig.Split(new char[] { ‘&’ }, StringSplitOptions.RemoveEmptyEntries);

 

foreach (string property in properties)

{

string[] data = property.Split(new char[] { ‘=’ }, StringSplitOptions.RemoveEmptyEntries);

string key = data[0];

string value = data.Length < 2 ? “” : data[1];

 

pipelineContext.Write(key, this.AdapterContextPropertyNamespace, value);

}

}

 

public override void SetEndpoint(Dictionary<string, string> ResolverDictionary, Microsoft.XLANGs.BaseTypes.XLANGMessage message)

{

base.SetEndpoint(ResolverDictionary, message);

}

 

protected override void SetEndpointContextProperties(Microsoft.XLANGs.BaseTypes.XLANGMessage message, string endpointConfig)

{

base.SetEndpointContextProperties(message, endpointConfig);

}

 

protected override void SetContextProperties(IBaseMessageContext pipelineContext, Dictionary<string, string> ResolverDictionary)

{

base.SetContextProperties(pipelineContext, ResolverDictionary);

}

 

protected override void SetContextProperties(Microsoft.XLANGs.BaseTypes.XLANGMessage message, Dictionary<string, string> ResolverDictionary)

{

base.SetContextProperties(message, ResolverDictionary);

}

}

}

Steps to use:

1. Rebuild and GAC this project

2. Open the ESB.Config file from the install folder

Add the following line in the Adapter Providers section:

    <adapterProvider name=”MSMQ” type=”Tellago.ESB.AdapterProviders.MSMQAdapterProvider, Tellago.ESB.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c0eafbe4dc54c287″ moniker=”msmq” />

    

Happy ESBng!!!