BizTalk Handling of Exceptions in One-Way Web Services

I’m currently working on the design of the “fan out” process from our ERP system (SAP) and we’ve had lots of discussions around asynchronous services and exception handling.

The pattern we’ve started with is that BizTalk receives the message from SAP and fans it out using one-way send ports (and web services) to each interested subscriber. However, some folks have expressed concern about how exceptions within the various services get handled. In a true one-way architecture, BizTalk is never alerted that the service failed, and the service owner is responsible for gracefully handling all exceptions.

If a .NET developer builds a very plain web service, their web method may be something like this:

[WebMethod]
public void DoSomethingCool(CoolObject co) {   throw new Exception(“bad moon rising”);

}

So what does this actually generate? If you look, the actual contract generated from this yields a response message!

You can see there that the service caller would expect a confirmation message back. If BizTalk calls this service, even from a one-way send port, it will wait for this response message. For the service above that fails, BizTalk shows the following result:

The proper way (as opposed to the lazy way above) to build a one-way .NET web service is to add the attribute tag below.

[SoapDocumentMethod(OneWay = true)]
[WebMethod]
public void DoSomethingCool(CoolObject co) {   throw new Exception(“bad moon rising”);

}

If you build THIS service, then the contract looks like this …

Notice that the only response BizTalk (or any caller) is expecting is a HTTP 200 response. If anything besides the base connection fails, BizTalk won’t know or care. If I call the service now, there is no indication (Event Log, Suspended Messages) that anything went wrong.

The first web service above is the equivalent of writing the web method as such …

[SoapDocumentMethod(OneWay = false)]
[WebMethod]
public void DoSomethingCool(CoolObject co) {   throw new Exception(“bad moon rising”);

}

Setting OneWay=false would force this method to return a response message. So what does this response message REALLY look like? I traced the web service call, and indeed, you get a DoSomethingCoolResponse message that is apparently just eaten up by BizTalk (no need to subscribe to the response) …

Now what if the web service times out on these “fake” one way calls? Would BizTalk really raise an error, or would it simply say “ok, I sent it, never got a response, but that’s cool.” I added a 2 minute “sleep” to my service and tried it out. Sure enough, BizTalk DID suspend the message (or set it for retry, depending on your settings).

The only exception that will cause either a two-way OR one-way service to suspend is if the connection fails. If I shut down the web server, calling either type of service results in a suspended (or retry) message like so …

While it’s super that a service that returns no data can still return a basic success acknowledgement, there are broad implications that need to be thought out. Do you really want BizTalk to catch an exception thrown by your service? If the code is bad, all the retries are going to fail anyway. What about keeping messages in order? Do you really want to use “ordered delivery” and thus block all messages following the “bad” service call? I’m a bigger fan of letting the service itself catch the exception, log the ID of the object coming in, and on a scheduled basis, go retrieve the actual data from the system of record, vs. trying to make BizTalk keep things all synchronized.

Any architecture experiences with one-way services or patterns you wish to share? Talk to me.

Technorati Tags:



Categories: .NET, BizTalk, SOA

3 replies

  1. Hi,

    I worked with one-way web methods long time ago in asmx world (without WSE). Here is what I found:

    When you have a one-way web method that takes a complex object, the client side will not get the control back until the complex object is completly read on the server side. I was debugging both client and server portions in the visual studio 2002 (?) at the time. I was copying complex object information into an internal object. As soon as the I stepped over the code that read the last property in the complex object, the client code proceeded to the next statement after the web service all. So it was possible to get exceptions even in one-way service calls if the information from client is not read fully in the service side code (at least in asmx implementation).

    As for WCF, Juval Lowy wrote an article on this subject in MSDN magazie. Check out his article at: http://msdn.microsoft.com/msdnmag/issues/06/10/WCFEssentials/

    Hope that helps…!

  2. Thanks for the comment. Interesting.

Trackbacks

  1. Calling Java One-Way, with or without Exception Handling, in BizTalk « Victor Fehlberg’s Tech Postings

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: