Building your own Adapter. Serious Pitfals / Adapter WOES !!

March 31, 2009 / Comments Off on Building your own Adapter. Serious Pitfals / Adapter WOES !!

This blog post is about several experiences I had when building my own Sybase adapter.

Normally i would suggest to the customer that they should buy an adapter, but in this case that was not possible since the only good working Adapter for Sybase was produced by TopXML and they vanished from this globe…. So I had to start building my own.

If you do a couple of searches on google you will probably find the BizTalk Adapter Wizard on codeplex. This is a good start cause it helps you a great deal in getting the framework four your adapter up and running in no time. However there are some dangers involved in using the wizard. One of the problems caused by the Adapter Wizard is the dreaded “The transport proxy method DeleteMessage() failed for adapter XYZ (Bug in Codeplex Adapter Wizard)” message wich I blogged about previously.

To describe this problem in the shortest possible form I could say, it copies ALL of the context from the message beeing send to the response message (request response port) so everything, messageID and stuff are all exactly the same. At a point in time BizTalk wants to delete a message with a specific ID and it finds two messages with that ID. This will probably result in several strange messages in the eventlog and sometimes even cycle your complete BizTalk Server. This is not the behaviour that you want.

Fortunately the solution is pretty simple, If you look at the generated code you will see a method named BuildResponseMessage. In this method the copying of the context is done. Simply remove the last statement from the method (btsResponse.Context = context😉 and your adapter is cured from this obscure problem.

Then I thought everything would run well and I started to submit Loads of requests against my new adapter. And that’s when the problems really started. To explain a littlebit what happened i have to explain what I did as the first step in my Adapter.

The first thing my adapter would do is read the incoming stream (from the pipeline) and load that up into a XML document. And i could see that stap failing in high volume scenario’s. I would see this step fail with several errors in the eventlog. Errors i saw in the eventlog were:

  • There are multiple root elements
  • Root element is missing
  • Tag is missing
  • And many more variants

This was pretty obscure cause I was sending the same XML file (via passthrough pipelines) in a high volume. And all my XML files were correct. !! This made me believe there was something wrong with BizTalk cause my streams that should contain valid XML were all messed up…

So I had a look at the HTTP adapter that comes with the SDK and I compiled it and set it up so it would call a web service over HTTP. And for sure within an hour i was up and running and my webservice gave the correct response. Again all with passthrough pipelines so BizTalk should not touch the message at all. And When i ran a High Volume of messages over this new connectio i got EXACTLY the same problem. So now i knew it was not my code messing stuff up, but it was some more generic problem.

Since I am not the right developer to look at the inner workings of the adapterframework, I called MS for help. At first they were reulctant to help, (cause they were just samples). After some help from the guys from MS Netherland the issue was pushed through and and the guys from MS finally came through with a solution. It took quite some time for MS to solve this one and I guess they are probably the ony people on earth who could have solved the problem….

So here is what they changed: (Original First)

        public override IBaseMessage ProcessMessage(IBaseMessage message)
        {
                this.solicitMsg = message;
                HttpAdapterProperties props = new HttpAdapterProperties(message, this.propertyNamespace);
                IBaseMessage responseMsg = null;
                if (props.IsTwoWay)
                {
                    WebResponse response = SendHttpRequest(this.solicitMsg, props);
                    responseMsg = BuildResponseMessage(response);
                }
                else
                {
                    WebResponse response = SendHttpRequest(this.solicitMsg, props);
                    response.Close();
                }
                return responseMsg;
            }
        }

 They changed it into :

        public override IBaseMessage ProcessMessage(IBaseMessage message)
        {
                HttpAdapterProperties props = new HttpAdapterProperties(message, this.propertyNamespace);
                IBaseMessage responseMsg = null;
                if (props.IsTwoWay)
                {
                    WebResponse response = SendHttpRequest(message, props);
                    responseMsg = BuildResponseMessage(response);
                }
                else
                {
                    WebResponse response = SendHttpRequest(message, props);
                    response.Close();
                }
 
                return responseMsg;
        }

After applying this change the HTTP adapter would immediately work as expected. So I tried the change in my own Sybase adapter and BINGO…. everything worked as expected.

So I have learned a lot from building this adapter. Some TakeAway’s

  • Really stress test your adapters (With100 messages everything would run fine ..)
  • If you have done the first step, multiply the number of messages with 10 and see what happens…
  • Codeplex and stuff to make you more productive are nice, but they have bugs in them as well..
  • Samples from MS are not flawless either. (Expect an update from MS in the future)

So with this post I hope to help several people who have run into problems when creating custom BizTalk adapters….

The only thing I really don’t get is why this code change would have such a dramatic impact…..

 

  • Recent Posts
  • Recent Comments
  • Archives
  • Categories
  • Meta