Wednesday, May 1, 2013

BizTalk ESB Toolkit Custom AdapterProvider and Endpoint Configuration

In my current project assignment, I needed MSMQ AdapterProvider for BizTalk ESB Toolkit and as usual before implementing myself I first searched it on bing and found the link of ESB extension which contains not only MSMQ adapter provider but also others adapter providers. The ESB extension is available on codeplex for ESB 2.0. I started browing the source code of the MSMQ adapter provider and realized that due to some issue MSMQ adapter endpoint configuration are not set if we use BaseAdapterProvider implementation and as a result certain methods were re-implemented in MSMQ provider. In order to find the root cause I started writing a new adapter provider for MSMQ. I thought of documenting this here. Following are the steps you need to follow to create the adapter provider, the amount of code you write is nothing, its all implemented in BaseAdapterProvider. Its all about configuration.


  1. Create a new C# project and add a reference to Microsoft.Practices.ESB.Adapter assembly which you can find in Microsoft ESB ToolKit 2.1\bin folder.
  2. Created a new class AdapterProvider and extended it from BaseAdapterProvider. BaseAdapterProvider class is abstract implementation of IAdapterProvider interface and provides all basic functionality.
  3. Override property AdapterName and return adapter name from it e.g. MSMQ
  4. Sign and Build your project and install the assembly in GAC
  5. Register your new adapter provider in ESB.Config file as follows:  adapterProvider name="MSMQ" type="ESB.Adapter.MSMQ.AdapterProvider, ESB.Adapter.MSMQ, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8c284297668e995a" moniker="MSMQ"
  6. At first you think that's it and now you can see your adapter provider in your resolver under the TransportName.
  7. If you just need the default basic properties on your adapter provider e.g. Transport Name, Transport Location then you do not need anything else. However if you click now on Endpoint Configuration option then you get an error as shown below:
  8. Endpoint configuration are nothing but message context properties and in order to set them for the adapter, you need to provide a manifest file. You can find inbuilt adapterprovider manifest file in folder C:\users\\AppData\Local\Microsoft\Visual Studio\10.0\Extensions\Microsoft\BizTalk ESB Toolkit Itinerary Designer\2.1.0.0. Their naming convention is PropertyManifest.xml
  9. In order to resolve the above I created a similar Manifest file and stored in same directory where others are and it fixed the above issue. Make sure you only include properties which are relevant to the adapter. The easy way to find this out is to go to BizTalk Admin Console-AllArtifacts-Schemas and select property schema for your adapter.
  10. Now you can also set Message context properties using Endpoint configuration.
  11. I then created a small sample which receive a file and send it to MSMQ and I started using the MSMQ adapter provider. In addition to Transport Name and Location, I also set two Endpoint configuration Transaction and MaximumReceivedMessage size and tested my application
  12. Nothing works at first attempt and it failed on my dynamic send port with error "The specified destination queue "" is transactional, and the message is being sent is non-transaction"
  13. This error essentially means message context properties are not set correctly by the adapter provider framework and I thought if I have registered my adapter provider correctly and implemented all required interfaces then it should work. This was the same issue faced by ESB extension authors on codeplex and they reimplemented some of BaseAdapterProvider methods to resolve the issue. However I thought it should work out of the box.
  14. So I digged in deeper and found an optional property adapterAssembly on http://technet.microsoft.com/en-us/library/ee236702(v=bts.10).aspx which can be set during AdapterProvider registration in ESB.config file and I tried setting this up with adapter assembly as mentioned on msdn. After setting this up my esb.config looks like as follows adapterProvider name="MSMQ" type="ESB.Adapter.MSMQ.AdapterProvider, ESB.Adapter.MSMQ, Version=1.0.0.0, Culture=neutral, PublicKeyToken=8c284297668e995a" moniker="MSMQ" adapterAssembly="Microsoft.BizTalk.Adapter.MSMQ.MsmqAdapter, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
  15. I again tested and it failed again with same error, I then looked inside ESB code using reflector and found that AdapterManager loads the assembly found in adapterAssembly parameter and it browse through all types of it to check if they are of MessageContextPropertyBase type which essentially mean if they are context properties. And I realized the actual adapter dll will not have the promoted properties it will rather be in MsmqAdapterProperties dll. I then replaced the adapterAssembly to following dll adapterAssembly="Microsoft.BizTalk.Adapter.MSMQ.MsmqAdapterProperties, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
  16. After this it started working successfully. So the key is adapterAssembly parameter in esb.config. By default when it is not supplied then AdapterManager loads the assembly Microsoft.BizTalk.GlobalPropertySchemas to look for context properties, i.e. endpointconfiguration properties

No comments: