Attention: We are retiring the ASP.NET Community Blogs. Learn more >

First Shadowfax 'Test Drive'

This is the first review of the Shadowfax Architecture in a “real life” environment like the migration project of the MBI – Microsoft Business Integrator architecture. This architecture provides a Framework for building enterprise distributed applications in a message based interlayer communication.

 

 

In the last 2 weeks I worked long hours in order to get the main subsystems migrated and a full prototype solution for testing the basic functionality. A brief overview of this work is expressed in the following lines. The overall experience was very pleasant and the final result was a cleaner and robust architecture then the original version.

 

 

The Project

 

 

The MBI architecture is currently installed on a large list of big to mid-sized clients along several Latin American countries and some strong constrains are paramount to respect in order to get a successful project. Here we have the main requirements for the new MBI version (3.0) called internally, “MBI powered by Shadowfax”.

 

 

  • All installed custom code (business actions, custom extensions, etc.) must be run without modifications or recompilation (just version binding redirection).

     

  • All public interfaces in MBI will be supported and some classes might be marked as “Obsolete” providing new functions that will use the Shadowfax infrastructure.

     

  • All main features of the current version of MBI shall be preserved and the new version will be enhanced with all the known features of WS and IIS, as well as all the features and goodies provided by Shadowfax.

     

With these main constraints at hand, we start building a prototype that contains the main base line architecture subsystems and as seen on the following diagram, we use extensive use of the double pipeline pattern. The picture shows one main Interface Pipeline for the security and exception handling functions, and three Implementation Pipelines for the different kind of Business Actions.

 

 

 

 

First of all, we choose the WS-InProc communications transports (WS for the Interface Pipeline and InProc for the Implementation Pipeline) with a subtle variation of the InProc Target. The new Target called “InProcAppDomain” will handle the communication with the Implementation Pipeline that might be “InProc” or “OutProc” via a Web Service Target or whatever dispatching transport we choose and this will depend on what application belongs the Action that we want to execute.

 

 

On the Interface Pipeline, we included the Security Handlers (Authentication and Authorization) as well as the handler that creates the MBI Command object that all the upstream subsystems will use in the call chain up to the Action (Business Action in Shadowfax jargon) execution. In front of these handlers we put one that will translate the old MBI exceptions into Shadowfax exceptions so we can receive on the client side the packed MBI exception and re throw it in order to comprise with the fist premise of backward compatibility state above.

 

 

On the Implementation Pipeline we put all the handlers that will translate and managed the MBI services and finally we implemented a new Business Action Target now called ActionTarget that will process the Action (aka Business Action) and pack the Response object into the Shadowfax payload.

 

 

With this nutshell overview, we’ll see the pros and cons that we found in the Shadowfax Architecture when building this new model.

 

 

The Goodies

 

 

  • Double Pipeline Pattern: We have done an extensive use of the pipeline extensibility model by refactoring many subsystems in Handlers and Targets as well. This promotes a very clean and very easy to extend model so we could achieve the majority of the backward compatibility tenets by just wrapping much of the functionality with the Handler-Target combination.

     

  • Instrumentation Events: We made use of al the EIF infrastructure built inside Shadowfax and hence we got all the out-of the box functionality provided. However, we have some nice to have issues listed in the next section.

     

  • FrameworkHelpers: This interface factory pattern proves to be very useful for all “helpers” like services that delivers Shadowfax as well as MBI, like Tracing, DB Connections, Date Services, Application Logging, etc.

     

The Nice-to-have

 

 

  • Handlers Inheritance: Unfortunately when the “sealed” modifier was removed from all Handlers (and every class as well) the private constructor left on many classes and the lack of virtual/protected members set mostly useless the possibility of inherit from the base out-of-the box provided handlers. Some refactoring here will quickly fix this issue.

     

  • One Time Call: On the StatefulAround Handler, there is an implicit rule that denies the possibility to call twice the same “nextHandler()” delegate. This rules was introduced to promote good programming practices (at least in this context usage) and assure that the call chain will never be called more then once, hence disabling any strange side effect that could arise. However, this behavior limits the flexibility that a custom code might need, for example, if you catch some kind of exception and you want to process the same chain but with some changes on the message. Actually you can solve this, locating the reprocessing code inside the Target (assuming you have a custom Target). In some scenarios, this solution might be suboptimal because you might be loosing some of the isolation provided by the Handler for that particular case. Perhaps with a careful refactoring of your code you might achieve the same result with a more “academic” solution (or more complex one) but you will have to take care of the costs related to this.

     

  • WS Interface Adapter: The Web Service Interface Adapter is implemented as a SoapExtension class. This is a very handy strategy because you only have to add the “WebServiceInterfaceAdapter” attribute to your WebMethod but you can’t control the Pipeline firing or the Soap Headers management process because all of this is done inside this class. If you want to customize all this behavior you should write a new SoapExtension class that mimics the adapter functionality. You might inherit from the provided adapter but this might not give you the expected results. Again, a refactoring work on this area should provide enhanced extensibility and customization.

     

  • RequestHeader and ResponseHeader: These objects carry the outbound message information that will be use by some handlers or by the pipeline itself. Basically this classes that inherits from the “SoapHeader” class, pack this info in a jagged object array of key/value pairs. Besides the lack of a typed interface (ok, this has the flexibility of accept any object) you have to pay the price of the boxing issue for Value Types. However if you just pass your own SoapHeader implementation, the Header processing inside the WebServiceInterfaceAdapter will correctly add your header to the Context object so you will be able to use it whenever you have access to the context instance (almost everywhere in Shadowfax).

     

  • Exceptions sent to the Client: There are is only one kind of exception that is returned to the client (with the WS Interface Transport): The SoapException (SE). With the help of the Exception Code provided by the SE, you could know if this exception originates from a Server technical exception or from a BusinessRule informative exception. In neither case you will be able to reconstruct in the client side the original exception except from the message property. It’s a good practice not to reveal any technical detail about the exception down to the client (security vulnerabilities and usability issues) and translate it to a more user friendly and useful message. But in some scenarios (like the one we have here), we want to preserve the original exception thrown on the Business Action and re throw it on the client. The current version does not provide any mechanism to do this (only sent the original message description) so we have to do some kind of a hack to solve this. We serialized and base64 encoded the original exception inside a BusinessRuleException message and we reverted the process on the client side, so we achieved the desired behavior. It might be interesting to provide the full BusinessRuleException transporting (Xml Serializing the BRE instance) so the client will receive this Xml serialized exception and use it to rebuild the original custom exception.

     

  • Custom Event Source: The EventPublisher class might provide an overload that let pass the event source as an argument or better yet use an abstract class so an application might override its behavior by changing the event source name. Another approach might be to take the event source name from configuration (EIF config or Shadowfax config file) instead of taking it from the resource file.

     

Note: This wish list is actually under revision in the current V2 of Shadowfax that has started a couple of weeks ago.

 

 

In this first review of the Shadowfax Architecture under certain constrains stated by the main goals of the MBI migration project, I showed how well (and how much of nice to have) adapts Shadowfax to an existing base line architecture that must preserve the existing client code base but at the same time make use of many of the features and enhancements that Shadowfax provides.

 

 

The opinions expressed herein are personal and do not necessarily reflect the position of neither my employee nor Microsoft.

 

 

3 Comments

Comments have been disabled for this content.