Sunday, September 14, 2008

Using Com Aggregation to help Web Services

Some times ago, I was consulting for a project for a friend that tried to use the SOA approach to expose functionality to the client using Web Services. The functionality is currently implemented as a bunch of .Net components that uses a COM connector component, provided by the vendor of their remote system; pretty much like Microsoft Dynamic AX connector and SAP connector.

Instead of having these components deployed to the desktop, they wanted to place them on a IIS and exposing them as ASMX web services. Things worked fine but performance sucked.

They approach the vendor for help and was told to redevelop the entire stuff using the vendor preferred Web Services. Sounds familiar? That meant tossing out years of work.

So I had a look it and recognise that it was the classic problem of Apartment mismatch with the Service component living in MTA while that STA connector is hosted in a STA resulting in serializing all calls to the STA. I therefore recommended them to follow my recipe for constructing multiple-STA servers.

In a haste, I suggested them to incorporate the interop assembly for the aggregator as well as that of the aggregatee and to alter their construction logic, assuming their connector is called SXServer and the aggregator is called AggregateSXServer, from

IServerObject svr = new SXServerLib.SXServerClass();
to
   IServerObject svr =
(IServerObject) AggregateSXServerLib.AggregateSXServerClass();

This worked like a charm alleviating the performance bottleneck except that I now believe that may be I do not need so much changes. There are a couple of techniques I can investigate.

Using Com Emulation
There is a technique that may offer a possibility of enlisting the aggregator without needing to touch the client code. This is known as Com Emulation technique. This technique allows silent redirection of CLSID_ORIGINAL to CLSID_NEWONE by means of a special registry key in the COM registry called TreatAs.

So it sounds like the right stuff to allow me to redirect coclass creation for CLSID_SXServer to CLSID_AggregateSXServer without requiring the rebuild of the web services components. However, it appears that this technique does not support aggregatable component. Even when creating object for IUnknown, the use of TreatAs returns E_NOINTERFACE. Weird.

Anyway that can be left for another day's challenge.

What is the minimal change required in the .Net solution?
So the next investigation is what is the minimal amount of changes require to the .Net solution. In the past, I recommended the inclusion of the interop assemblies for the aggregator as well as the aggregatee. Do I need all that? I know at a minimum I need the interop assembly of the aggregatee because I need to use those interfaces. Do I need that of the aggregator?

It turns out not if we are happy to replace the use of new operator and replacing that with the Activator call. So instead of
   IServerObject svr = new SXServerLib.SXServerClass();
We can change it to:
  IServerObject svr =
(IServerObject)Activator.CreateInstance
( Type.GetTypeFromCLSID
( new Guid( "6E537ABD-96B0-4BBC-9F1C-00924FBF1FB1" ) ) );
This is change is more than cosmetic as it can:
1) let you switch dynamically by providing that Guid as a string from anywhere: from config file or other means. Kind of home-made COM emulation.
2) It also means that you do not have to include and ship the interop assembly of the aggregator. A big plus!

Hence this is purely code changes and no need to add anything to the project references. Why I didn't think of this in the first place?

Of course when we approached the vendor with our solution, they were less than please because this had ruined their chance of selling their Web Service to my friend; no more upgrade fees, etc.

This kind of attitude is a clear sign of customer-neglect and exploitation. Instead of helping their users to make the best of their product, they were out there to take advantage of their customers ignorance of technology. Shame.

My help, utilising the COM technology and requiring no proprietary materials have, now stopped the exploitation dead in its track allowing my friend to continue with their SOA initiative without incurring great loss of discarding current implementation. This is a good design and provides an invaluable service. Any fool can recommend a rebuild approach as that does not need in-depth understanding of technology and design; recommending rebuild is a no brainer.

Incidentally, there is nothing in SOA definitions that say COM cannot be used to implement a SOA provider. After all the whole premise of SOA is to hide the implementation infrastructure. Requiring someone to up root one's design to chain in a vendor's SOA smacks a total misunderstanding of the SOA design philosophy and explotation. Don't you think so?

No comments:

Post a Comment