Posts tagged SOA

Put Up your Shields: Shielding Exceptions in WCF Services

When using services an important best practice is to keep details of exceptions from leaking beyond the service boundary.  Letting such details out of the boundary could create unnecessary coupling between the service callers and the service and would expose internal details of the service that you may wish to keep hidden.

Microsoft Patterns & Practices Enterprise Library (EL) provides an extension to the Exception Handling Application Block that hooks directly into WCF to provide the capability to replace service exceptions with custom faults.

Configuring Shielding

Exception shielding requires you to configure a Exception Handling Application Block with an exception policy.  The policy consists of the exceptions you want to handle and a post-handling action for each exception.  To work with the WCF Exception Shielding you need to set each exceptions post-handling action to ThrowNewException.

image

Once you have your basic policy set up you need to add a Fault Contract Exception Handler to each exception in your policy.

image

You can map properties from the exception thrown to the Fault you return.  This is set up in the PropertyMapping as the following screenshot indicates.  Source represents the source property on the Exception and Name is the property name on your fault to map to the source.  In this case the WidgetNotFoundException has a “Message” property which we will map to the “Details” property on our WidgetNotFoundFault.

image

Lastly, you need to mark your Service Class with the ExceptionShielding Attribute and give it the name of your exception policy.

image

Once everything is wired up you can test the service to see your exceptions get replaced by the fault contract types. 

A Quick Integration Test

When I fired up the service in Visual Studio 2010 and used the WCF Test Client, I ran a quick test to find a widget with the name of “Whatzit”.  The service had something to say about that request:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header />
  <s:Body>
    <s:Fault>
      <faultcode>s:Client</faultcode>
      <faultstring xml:lang="en-US">Widget Whatzit not found!</faultstring>
      <detail>
        <WidgetNotFoundFault           xmlns="http://schemas.datacontract.org/2004/07/ExceptionShieldingService2"
          xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
          <Details>Widget Whatzit not found!</Details>
        </WidgetNotFoundFault>
      </detail>
    </s:Fault>
  </s:Body>
</s:Envelope>

You can also test this using something like MSTest and decorating your integration test with [ExcpectedException(typeof(FaultContract<MyServiceReference.MyFaultType>)].  Just point the FaultContract<TDetail> to the type from your ServiceReference.  You can’t test fault contracts (to my knowledge) by calling the service imlementation class directly, you’ll need to do this by adding a service reference and calling the service that way.

Tips & Common Errors

After setting up a few of these I have run into some configuration problems which seem to be the most common issue hit with any of the EL blocks.

  • Use the Enterprise Library “Load from assembly” option to select your Exception and Fault Contract types.  EL seems particularly sensitive to using the fully-qualified assembly name including version & public key token.
  • Turn on some type of logging while testing your policy.  This will help you troubleshoot problems with the policy (mismatched types, etc).
  • “The current build operation (…) failed: Value cannot be null” Parameter name: faultContractType – This error stems from EL not being able to resolve your Fault Contract Type.  This is typically due to a bad mapping of your Fault Contract Type.  Check the Type Name, Assembly and version info to make sure it is correct.  Your best bet is to use the EL Config Editor to browse and select your fault type.

What Do You Call It? Naming WCF Operations & Messages

WCF is a great addition to the .NET framework.  Like all parts of the framework it introduces a lot of new concepts to learn.  Sometimes it’s hard to separate those technical concepts from the decisions like, “What is the best way to architect this service” or “How should I name things?”

Simon Segal, a fellow .NET and SOA junkie posted back in November about how he names operations and messages within WCF and the nServiceBus framework (an open-source Enterprise Service Bus).  Simon, like I do, follows a convention of naming in relation to the business events the operations and messages represent.

When it comes to naming operations we not only imply some intent of the operation we also imply what data might be needed.  When designing services that are more coarsely grained you often run into issues with what data is really required for the service to perform its work.  Simon linked to an article from Thomas Erl, a respected authority on SOA, in which Thomas made the following statement (my emphasis):

Although it is practical and extensible, the use of optional parameters should be limited within Web services. Optional parameters can lead to convoluted service interface designs and a myriad of confusing data exchange scenarios. Additionally, the extent to which optional values can be accommodated is often limited by the underlying XML schemas that define the message structures. Standardized schemas that represent established corporate documents may impose rigid data structures.

Coming from the NIEM world I often emphasized that data exchanges only need 80% of what we think is needed.  There were times when people would want to exchange flags or indicators that could be derived from other fields or were not necessarily needed at all.  Any time we strayed away from the 80% the services became more difficult to consume and maintain.

Let’s Look at An Example

Factoring all of this in, let’s consider an example of how we might name service operations and messages.

Definitions:
Service Operation – A method you call on a service. 
Message – An input/output of a call to a service operation.
Message Parts – Data elements that are included in the message.

Problem: You need to name messages and service operations for a service that will allow customers to place orders for widgets.  This service should also allow orders to be cancelled.  Orders consist of a unique ID, a customer Id, and widgets. 

Request/Response example:

  • Service Operation PlaceWidgetOrder, Message: PlaceWidgetOrderRequest, Message Parts: WidgetOrder (Id, Customer Id, Widgets[] (or WidgetCollection))
  • Service Operation CancelWidgetOrder, Message: CancelWidgetOrderRequest, Message Parts: OrderId

Event-Driven example:

  • Service Operation: CustomerPlacedWidgetOrder, Message: CustomerPlacedWidgetOrderMessage, Message Parts: same as request/response example
  • Service Operation: CustomerCancelledWidgetOrder, Message: CustomerCancelledWidgetOrderMessage, Message Parts: same as request/response example

Notice the difference between the two styles.  In the event-driven style we talk about something that has happened (or is happening) and in the Request/Response style we talk in terms of what we want to do.  Each style has it’s merit and the style you choose will depend on the situation and the maturity of the partners involved in the service collaboration/data exchange.

Also notice that the event-driven example does not imply any type of response to the operation.  Typically event-driven systems will be asynchronously designed and the service operations will reflect that.

Why Messages?

Messages allow us to encapsulate the data needed for the domain as well as data we may need because of technical requirements.  Technical requirements may dictate that we have to log messages or protect messages in other ways (which could require message IDs, encryption keys, etc).  By encapsulating data in a message we also leave room to include the technical requirements within the same message and keep our domain model free of technical bits that aren’t really part of the domain.

How do you name your service operations and messages?

Simon and I would love to hear.  Leave a comment or tweet it!

Take Control of Messages in WCF

With WCF you can control many aspects of how service behave and how you interact with them.  Let’s take a look at Data & Message Contracts and how each behaves on the wire.

Data Contracts – The Basics

Data contracts are the default method for serializing in WCF.  To leverage data contracts you simply markup the classes you wish to expose from the service with the DataContractAttribute.  The data contract serializer does not support all the features of Xml Serialization which yields some performance boosts.  However, the data contract serializer has some default behaviors which may not suit your needs.

The Contract

 [DataContract]
    public class CompositeType
    {
        bool boolValue = true;
        string stringValue = "Hello ";

        [DataMember]
        public bool BoolValue
        {
            get { return boolValue; }
            set { boolValue = value; }
        }

        [DataMember]
        public string StringValue
        {
            get { return stringValue; }
            set { stringValue = value; }
        }
    }

The SOAP Message

Request (Showing soap:body only)

<s:Body>
<GetDataUsingDataContract xmlns="http://tempuri.org/">
<composite xmlns:a="http://schemas.datacontract.org/2004/07/ContractExamples" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:BoolValue>true</a:BoolValue>
<a:StringValue>Hello Service!</a:StringValue>
</composite>
</GetDataUsingDataContract>
</s:Body>

Response

<s:Body>
<GetDataUsingDataContractResponse xmlns="http://tempuri.org/">
<GetDataUsingDataContractResult xmlns:a="http://schemas.datacontract.org/2004/07/ContractExamples" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:BoolValue>true</a:BoolValue>
<a:StringValue>Hello Service!Suffix</a:StringValue>
</GetDataUsingDataContractResult>
</GetDataUsingDataContractResponse>
</s:Body>

With the data contract, notice how our messages are actually wrapped in an outer element in the Xml.  For the request, the CompositeType is wrapped in a “GetDataUsingDataContract” element which is derived from the operation name.  The response is where it is interesting, our message is actually double wrapped. 

How do we change this default behavior?  Enter Message Contracts.

Message Contracts – For Control Freaks

Message contracts are another way to work with WCF to take more control of how the messages are serialized in the SOAP envelope.  These can be a key strategy to creating services that can support better interoperability with other stacks such as Java.  You define message contracts with the MessageContractAttribute.

The Message Contract

     [MessageContract(IsWrapped=true, WrapperNamespace=http://christopherDeweese.com/WCF/Examples)]
    public class CompositeTypeRequest
    {
        [MessageBodyMember]
        public CompositeType CompositeData { get; set; }
    }

    [MessageContract(IsWrapped=true, WrapperNamespace=http://christopherDeweese.com/WCF/Examples)]
    public class CompositeTypeResponse
    {
        [MessageBodyMember]
        public CompositeType CompositeData { get; set; }
    }

Here we have defined a request and a response message which contains our CompositeType.  What result does this yield?

The SOAP Message

Request

<s:Body>
<CompositeTypeRequest xmlns="http://christopherDeweese.com/WCF/Examples">
<CompositeData xmlns="http://tempuri.org/" xmlns:a="http://schemas.datacontract.org/2004/07/ContractExamples" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:BoolValue>true</a:BoolValue>
<a:StringValue>Hello Service with messages! </a:StringValue>
</CompositeData>
</CompositeTypeRequest>
</s:Body>

Response

<s:Body>
<CompositeTypeResponse xmlns="http://christopherDeweese.com/WCF/Examples">
<CompositeData xmlns="http://tempuri.org/" xmlns:a="http://schemas.datacontract.org/2004/07/ContractExamples" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:BoolValue>true</a:BoolValue>
<a:StringValue>Hello Service with messages! Suffix</a:StringValue>
</CompositeData>
</CompositeTypeResponse>
</s:Body>

A Little ‘Philosophy’

In past posts on services I’ve discussed the opinion that you interact with services through messages.  Encapsulating inputs and outputs to the service using messages allows for a clearer semantic representation of the what the capabilities the service provides access to.

Using Message contracts in WCF lets you explicitly control how the messages are serialized and allows you to build services from canonical data models created in raw Xml.  This also provides the greatest interoperability and you don’t have to deal with the default behaviors of the data contract serializer.

Final Thought

You may not always need this type of control.  For instance if your service is only being consumed by other .NET clients the messages may not be that important to you.  But if you are designing services for an Enterprise SOA, then message contracts will be a great help.

Integrating Existing Systems With NIEM Using SOA – Follow Up

As I mentioned in the beginning of the presentation, what I presented was based off my experiences and opinions and was subject to change and during the great Q&A and discussion, I received some great feedback and experiences from others that helped refine and redirect a few opinions I expressed.

Regarding adapters and whether they belong to the bus or to the systems being adapted for the bus – I see a case for both, but, I think that ultimately when you reach a point that you are adapting so many systems and doing so many transformations it makes more sense for those to be a concern for the bus.  Maintaining that many adapters in individual systems would become a burden over time; something that only experience would teach you and it’s an experience I’ve not yet had and may not at this point.

Thank you to everyone who attended and stayed for the Q&A.  I got a lot out of the Q&A and definitely have a lot more to learn.  This was something different for me to present because I know where I think projects could’ve been done better if I had accepted the bus as a viable solution and if I had the lens of designing systems to be more event-driven.  I wanted to share that perspective but also open up to other perspectives because that is where I think the sharing of experience really provides value to all.  Thanks to the 4B Track Lead Anthony Hoang of DHS for the humbling introduction and coaching prior to the presentation.

Many props to guys like Dru Sellers, Udi Dahan, and Chris Patterson who have helped shape some of my thinking on the bus and events.  Definitely check out their projects, Mass Transit and NServiceBus, as real solutions for those of you on the .NET side of the fence who need a functional bus to enable your EDA.

Here are the slides – I know the conference staff will post them, but I caved in and paid for Internet in the room so I’m going to use up all the bandwidth I can :)

Service-Oriented, Event-Driven Part 2: Autonomous Services

Last time we looked at events, notable changes in state, that can be used to notify other systems who may be interested in the event.  We ended with some pseudo code showing examples of how it might look and finally with some thoughts on coupling, which is where we slide into part two.

What is an autonomous service?  Firstly, let’s define autonomous – via Bing:

- self-governing: politically independent and self-governing
- able to choose: able to make decisions and act on them as a free and independent moral agent
- self-sufficient: existing, reacting, or developing as an independent, self-regulating organism

When we talk about autonomous services, what we mean are services that are self-governing, self-sufficient, and able to choose.  Autonomous services are the gate-keepers to systems of record and exist on their own.  Back to our pizza example we could feasibly have a kitchen service that exists on it’s own, independent of any specific order service.  To put it Vegas style, “What happens in the Kitchen Management Service, stays in the Kitchen Management Service” (except when it’s an event we want people to know about…more on that later).

Autonomous services will be focused to a particular set of related tasks such as our Kitchen Management Service which monitors orders in being cooked and stock levels of products.  I lean towards looking at a service through a single responsibility lens.  The more focused you keep that service, the cleaner the abstraction remains and the easier it will be to integrate in an environment of collaborating services.

Autonomous services are self-contained and therefore internal implementations can change as needed.  By keeping services focused and isolated we can reduce the coupling between other collaborating services or systems.  The only thing an autonomous service must do is fulfill it’s contract.  The contract is the definition of the abstraction the service is representing.  Typically this is a WSDL in the web service world along with the accompanying schemas.  But what we’re talking about here aren’t request-response services, so how does the contract apply in an event driven world?

This question opens the door to what we will explore in Part 3 of Service Oriented, Event Driven: Collaborating Services.  Stay tuned!

Service-Oriented, Event-Driven Part 1: Events

The real-world does not follow a linear, step-by-step process in order for things to occur.  We may rationalize and tell ourselves that things happen in sequence and that ‘c’ won’t happen before ‘b’.  We model our systems this way and we code this way because we view the world through this lens.  I am beginning to fully believe that we must shatter this lens, because it colors the world with a perspective that doesn’t fit.

The real-world is disorderly, it is chaotic, and it is made up events – notable changes in state – that we must react to.  The traffic light turns green, so you go, except the car in front of us isn’t going so now you can’t go. You order coffee and wait, and then the guy behind you gets his coffee first with yours ready a moment later.

Integrating systems using the lens of events is key to success, especially when the systems you are integrating are not yours or they belong to an entire other organization.  This is where a firm understanding of the information being exchanged as well as when it will be exchanged becomes key.

Udi Dahan posted an article titled “Don’t Delete – Just Don’t” a few weeks back.  In that article Udi explores soft deletes versus hard deletes, but he also raises another interesting thought that I’d like to build on.  Our systems maintain the state of records over time.  That state can be things like “entered”, “active”, “inactive”, “accepted”, “denied”, and whatever the business case may be.  As I have already described events as notable changes in state, so what if we start looking at our systems records and the notable changes in state, what would we see?

Dru Sellers frames this in “Events Are Awesome” where he writes:

“I have also started to think about what it would mean to develop a system ‘event first’, and then you can look at what needs to be done when these events happen. It builds completely different systems, based on some initial drawings.”

Over the last few weeks I have been thinking about the same thing.  So let’s hop on the example bus and see where it takes us.

Suppose we run a pizza delivery business and we’re going to automate what has been a manual process.  At a high-level, we could see a few processes we need: Customers should be able to place orders, the kitchen needs to be able to be notified of orders so they can cook them, the delivery supervisor needs to know where orders are going so drivers can be scheduled, and the store manager needs to know about the volume of orders so that the financials can be reviewed.  Skipping through the normal business analysis that needs to take place, we’ll say that we end up with four systems, each with a distinct job. 

  • The order system processes, validates, and accepts pizza orders from customers.
  • The kitchen management system accepts orders, verifies stock levels, and notifies the cooks so the order can be prepared.
  • The delivery scheduling system accepts orders, determines the route, and schedules a driver to deliver the order.
  • The financial system accepts orders and records details about the underlying transaction amounts.

If we examine the order system using the events lens we can come up with some notable events: “Customer Submitted Order”, “Order Validated”, “Order Accepted”.  With each one of these events a notable change in state has occurred and the information about that order should be communicated.  For example, the delivery scheduling system might want to know about orders when they are validated because it takes longer to schedule a driver, whereas the kitchen management system might not want to know about orders until they are accepted so that ingredients are not used too soon in the process.

You may argue that this is not much different than procedural thinking.  We could just code something to the effect of:

if (order.status == validated) {SendOrderToDeliverySystem(order);}

While that one line of code may be the simplest thing that could possibly work, what have we done?  In essence, we have now coupled our order system to the delivery system.  And this is where procedural thought begins to break down because that line of code is so specific that when we need to change it, the change has an effect that we may not fully understand especially because over time code becomes more complex as systems are expected to do more.

Consider the case where now the Kitchen System wants to know about orders when they are validated instead of accepted.  We now have to refactor our one liner to something like:

if (order.status == validated)
{
SendOrderToDeliverySystem(order);
SendOrderToKitchenSystem(order);
}

Now consider if we used the .NET Framework’s notion of events:

public delegate void OrderValidatedEventHandler(PizzaOrder order);
public event OrderValidatedEventHandler OrderValidated;

…{ //more code and curly braces }

if (order.status == validated && OrderValidated != null) {OrderValidated(order);}

If all of our systems were implemented as components with references to each other we could hook onto these events and reduce our codebase.  But even then we still have a problem – coupling.  Using direct references is a form of coupling that ties those components together.  We can use Dependency Injection to reduce that, but then we still have the question to answer – what if each of our 4 systems comes from a different vendor?

In Part 2, we will discuss autonomous services and why we want to reduce coupling.

Dude, where’s my message? WCF and Bringing Messages Back From The Dead (-Letter Queue)

Last week while researching an issue with one of our systems I discovered that six days worth of messages were missing from a queue.  After the initial panic we started researching.  One of my colleagues discovered the Transactional Dead-Letter queue had a large amount of messages piled up in it.  I had read some about that queue but never really dug into it.  This gem of an article got me started on a path that would ultimately lead to a best of breed type solution.

The solution from Billy Dunlop’s article has you change the ServiceBehavior AddressFilterMode to "Any".  What this does is allows your queued service to receive messages destined for any endpoint, so long as the message body is what it expects.  I have used this in the past for poison queues and it made perfect sense here.  However, we had one other problem.  Some of the messages in the dead-letter queue were for other queued services and simply changing one of our services to use the dead letter queue as it’s endpoint would not work right.  The solution is to use a more generic contract similar to the WCF Message Router covered in this MSDN article.

I took the router approach and created a router service and console application to host it.  For work I did all this in VB.NET.  As a tribute to my very good friend David Risko I spent the weekend rewriting the whole thing in C#.  This was my first shot at writing something from scratch in C#, so if you see something that could be condensed or written in a more clear manner please do let me know.

The default Time-to-live on the NetMsmqBinding is 1 day.  This can be adjusted in configuration or through code when you create the binding.  As a simple test you can create a NetMsmq service client and set your binding time-to-live to something ridiculous like 30 seconds (it’s a time span so you can do this with TimeSpan.FromSeconds(int)).  Watch the message hit your transactional queue and refresh and after 30 seconds, *poof*, message gone and you can now find it in your Transactional Dead-Letter queue.

Feel free to follow the code below or download the .ZIP file with the solution.  The solution was created in Visual Studio 2008 SP1.

On to the code!

The contracts – included are the Service Contract  which will be used by the router service and the Channel contract which will be used by the MessageRouter class to resend the message to it’s intended destination.  The service contract uses System.ServiceModel.Channels.Message as it’s input message.  This allows the router to receive any WCF message for any service without having to understand the body.  This is a hugely powerful ability that should be used with great care.

namespace CD.ServiceModel.NetMsmqRouter.Contracts
{
   
/// <summary>
    ///
Service contract interface for the message router service.
  
/// </summary>
   
[System.ServiceModel.ServiceContract]
    public interface
IMessageRouterService
   
{
        [System.ServiceModel.OperationContract(IsOneWay=true,Action="*")]
        void Route(System.ServiceModel.Channels.Message message);
    }

    public interface IMessageRouterChannel : System.ServiceModel.IClientChannel,IMessageRouterService
   
{

    }
}

The biggest piece I had to get my head around when learning WCF was the notion of the contract.  The same interface will be implemented by both the service and client but each one implements it differently.  The service implements it from the perspective of receiving the message and the client implements it from the perspective of sending the message.

Next up is the service implementation.  Pretty straight forward and it does two things – uses the MessageWriter class to save the message to disk (in case something really bad happens) and then uses the MessageRouter class to send the message to it’s original intended destination.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CD.ServiceModel.NetMsmqRouter.Service
{
    [System.ServiceModel.ServiceBehavior(AddressFilterMode = System.ServiceModel.AddressFilterMode.Any,        ValidateMustUnderstand = false)]
    public class RouterService : Contracts.IMessageRouterService
    {
        private MessageWriter _writer;
        private MessageRouter _router;

        /// <summary>
        /// Initializes a new instance of the RouterService class.
        /// </summary>
        public RouterService()
        {
            _writer = new MessageWriter(Properties.Settings.Default.MessageWriterPath);
            _router = new MessageRouter(Properties.Settings.Default.NetMsmqBindingConfigurationName);
        }

        #region IMessageRouterService Members

        [System.ServiceModel.OperationBehavior(TransactionAutoComplete = true, TransactionScopeRequired = true)]
        public void Route(System.ServiceModel.Channels.Message message)
        {
            try
            {
                System.Diagnostics.Trace.WriteLine("----- Message Received -----");
                System.ServiceModel.Channels.MessageBuffer messageCopyToWrite = message.CreateBufferedCopy(Int32.MaxValue);
                _writer.Write(messageCopyToWrite);
                _router.RouteMessage(messageCopyToWrite.CreateMessage());
                System.Diagnostics.Trace.WriteLine("----- Message Processing Complete -----");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine(ex.ToString());
                throw;
            }
        }

        #endregion
    }
}

The service is geared to work with the Transactional Dead-Letter queue which is why the Route method is marked up with the TransactionAutoComplete and TransactionScopeRequired attributes.  Within the try/catch block the service does not handle the exception in order to facilitate the aborting of the transaction scope the message is received under and this is the recommended pattern when you use TransactionAutoComplete = true.  If we did not throw here the scope would complete and the message would be lost if it was not routed to it’s original queue.

The message writer class has one responsibility – write the message to the path supplied in it’s constructor.  The message router class is the one we’ll focus on next as it is responsible for taking the original message and routing it to the messages original destination:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Transactions;

namespace CD.ServiceModel.NetMsmqRouter.Service
{
    /// <summary>
    /// Routes a message to its original destination
    /// </summary>
    internal class MessageRouter
    {
        private string _bindingConfigurationName;

        /// <summary>
        /// Creates a new instance of the message router class.
        /// </summary>
        /// <param name="bindingConfigurationName"></param>
        public MessageRouter(string bindingConfigurationName)
        {
            _bindingConfigurationName = bindingConfigurationName;
        }

        /// <summary>
        /// Gets an instance of the NetMsmqBinding
        /// </summary>
        /// <returns></returns>
        /// <remarks>Returns the default binding if no configuration name was specified.</remarks>
        private NetMsmqBinding GetBinding()
        {
            if (!string.IsNullOrEmpty(_bindingConfigurationName))
            {
                return new NetMsmqBinding(_bindingConfigurationName);
            }
            else
            {
                return new NetMsmqBinding();
            }
        }

        /// <summary>
        /// Returns an instance of a Contracts.IMessageRouterChannel
        /// </summary>
        /// <param name="binding"></param>
        /// <param name="address"></param>
        /// <returns></returns>
        private Contracts.IMessageRouterChannel GetChannel(NetMsmqBinding binding, string address)
        {
            return new ChannelFactory<Contracts.IMessageRouterChannel>(binding, address).CreateChannel();
        }

        /// <summary>
        /// Routes the message to its destination uri.
        /// </summary>
        /// <param name="message">The message to send</param>
        public void RouteMessage(System.ServiceModel.Channels.Message message)
        {
            System.Diagnostics.Trace.WriteLine(String.Format("Message destination: {0}", message.Headers.To.ToString()));
            Uri destinationUri = message.Headers.To;
            System.ServiceModel.NetMsmqBinding binding = GetBinding();
            using (Contracts.IMessageRouterChannel channel = GetChannel(binding, destinationUri.ToString()))
            {
                using (System.Transactions.TransactionScope scope =                    new System.Transactions.TransactionScope(TransactionScopeOption.RequiresNew))
                {
                    try
                    {
                        channel.Route(message);
                        scope.Complete();
                    }
                    catch (Exception ex)
                    {
                        Trace.WriteLine(String.Format("**** Error ****\n{0}", ex.ToString()));
                        channel.Abort();
                        throw;
                    }
                }
            }
        }

    }
}

All that is left is to wire up the service in the console host and then add the proper configuration elements.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using CD.ServiceModel.NetMsmqRouter;

namespace RouterServiceConsoleHost
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Diagnostics.Trace.Listeners.Add(new System.Diagnostics.TextWriterTraceListener(Console.Out));
            System.Diagnostics.Trace.AutoFlush = true;
            System.Diagnostics.Trace.WriteLine("Starting service.");
            StartServiceHost(typeof(CD.ServiceModel.NetMsmqRouter.Service.RouterService));
        }

        public static void StartServiceHost(Type serviceType)
        {
            using (System.ServiceModel.ServiceHost serviceHost = new System.ServiceModel.ServiceHost(serviceType))
            {
                serviceHost.Open();

                Trace.WriteLine("Service started...press <Enter> to exit");
                Trace.WriteLine("");
                Trace.WriteLine("");

                Console.ReadLine();
                if (serviceHost.State == System.ServiceModel.CommunicationState.Faulted)
                {
                    serviceHost.Abort();
                }
                serviceHost.Close();
            }

        }
    }
}

And the configuration:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
      <section name="CD.ServiceModel.NetMsmqRouter.Service.Properties.Settings"  type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </sectionGroup>
  </configSections>
  <applicationSettings>
    <CD.ServiceModel.NetMsmqRouter.Service.Properties.Settings>
      <setting name="MessageWriterPath" serializeAs="String">
        <value>C:\Users\Chris\Desktop\RecoveryRouter\</value>
      </setting>
      <setting name="NetMsmqBindingConfigurationName" serializeAs="String">
        <value>RecoveryRouterNetMsmqBinding</value>
      </setting>
    </CD.ServiceModel.NetMsmqRouter.Service.Properties.Settings>
  </applicationSettings>
  <system.serviceModel>
    <bindings>
      <netMsmqBinding>
        <binding name="RecoveryRouterNetMsmqBinding" maxReceivedMessageSize="4194304" maxRetryCycles="2" receiveRetryCount="1" timeToLive="1">
          <readerQuotas maxStringContentLength="4194304"/>
          <security mode="None">
            <transport msmqProtectionLevel="None"/>
          </security>
        </binding>
      </netMsmqBinding>
    </bindings>
    <services>
      <service name="CD.ServiceModel.NetMsmqRouter.Service.RouterService">
        <endpoint address="net.msmq://localhost/system$;DeadXact" binding="netMsmqBinding" bindingConfiguration="RecoveryRouterNetMsmqBinding" name="RecoveryRouterService" contract="CD.ServiceModel.NetMsmqRouter.Contracts.IMessageRouterService"/>
      </service>
    </services>
  </system.serviceModel>
</configuration>
Technorati Tags: ,

Exposing Services: Some Principles Revisited

In my opinion the principles driving service oriented architecture are a great evolution of software design.  I have been working to apply many of those principles in work we are doing to update our core offerings as services.  While the principles are widely published I wanted to add some of my own value to them from recent experience and reflection.

Services should enable business processes. If process can’t be completed "on paper" or no one understands it exposing it as a service may not be successful.  Services should expose that business process in a meaningful way that replicates the paper process as closely as possible.

Services aid in loose coupling between systems.  By exposing services with standard contracts that represent their messages in a canonical format you reduce coupling between systems.  The schemas and WSDL become the contract by which clients and the service communicate.  As long as that contract is not violated the service can do whatever is necessary to fill requests.  Changes to data stores or processes should have no impact on those contracts.

Services exchange messages. I have seen several services which were passing encrypted byte arrays that were strings which were cast into a byte array, encrypted, and serialized  by the service then deserialized, decrypted, and cast into a string and transformed to an XML document on the receiving end.  While this offers security through obscurity it violates other principles including meta data exchange and contract first design which uses that meta data so all clients know what messages to expect.  Services should use messages that are exposed in a canonical format via schemas and WSDL’s (for web services).

Messages should contain all the elements required to complete the business process.  This is a great principle I found via Nicholas Allen’s Indigo Blog in a white paper published by Ythos.  This will allow you the most flexibility in situations where that message will be routed to several services to fulfill the business process.  In a real world context I can think of few, if any, processes where you fill out multiple parts of a form and send it to different entities for processing.  The form contains all the data needed and you send to one place and are not concerned if it needs to be routed to several locations to complete your request.

If systems need data from each other they should ask for it.  This is one of my favorite principles gleaned from Clint Edmonson.  The simplicity of this principle is also its source of elegance.  A good service offers meaningful ways for clients to request the data that service knows about.  The requests should require minimal amounts of "state" or "context" and be flexible to allow for data to be requested multiple times if one attempt fails.

Exposing processes as services lets you focus on the process and build several different UI’s to consume those services.  I have not yet reached a point where this is a reality at my employer but we are very close to getting there.  As you build more services and more processes are enabled in standard ways you can begin to design different types of UI’s to interact with those services.  Do you have a core service exposed as a web service using SOAP but are concerned that is too much lifting for your AJAX clients?  No problem, expose a wrapper service that uses REST and a lighter message format and have that translate to your internal web service.  This keeps your functionality in a central location but has the flexibility to meet special needs for clients.

These are some practical things I and others have been working to apply with great success.  A key to building an SOA from the ground up is to start with simple services and keep them simple.  The trick is to keep an eye to the future and be sure your services will be governable and promote reuse of data models, etc.  While a ground up approach is not always the best in some situations that is where the call to services needs to begin.  Good architects will be looking out for what will better align IT with the business, add value to the processes, and save on costs due to a more maintainable infrastructure.

Push Versus Pull Interfaces

The best analogies for technical things most often come from the completely non-technical sources.  This post on the Four Hour Work Week blog really resonated with me, especially given some of my current projects.

Push versus pull describes the fundamental choice that must often be made when integrating two (or more) connected systems.  I have struggled with this many times and have found myself over complicating things by coming up with elegant strategies to push data from system A to B and C and so on.  While doing so was leveraging appropriate technologies a simpler answer was staring at me the whole time.

Early on I had developed two interfaces which were pull based.  You want this data, come get it and I’ll give you the data you asked and nothing more.  Simple and effective though it put the burden on consumers to come get it.

Neither of those interfaces has failed to date (we have had problems with how they were integrated in a few systems).

In the course of some new projects I was tempted into over complicating them because I had modeled the whole scenario as pushing a message through our systems.  Thanks to some insightful tutelage from Clint Edmonson he pointed me right back to my pull model and reminded me of a quote I am very fond of.

"Doing old things in new ways"

A fundamental principle Clint teaches is that if systems need data from each other, they should ask for it.  This is some what of a reversal of the legacy approach where systems would often send data to another system that it knew needed it.

Take an example where you have a sales system that needs to get information from n number of vendors.  You could have an FTP site or web service where everyone can send their data.  That should work fine, until you really try it.  Then you end up with n number of file formats and n number of incoming FTP connections, user accounts, etc.  It’s a mess to maintain; ask anyone who has to.

What if you reversed that?  What if your company came up with a simple web service definition and each vendor put an instance of that service up and provided their data in the format specified by the web service?  Then your sales system simply has to go down its list of vendors and call them up to get the data?

Perfect, no problems ever.  Right?  Not quite.  Every solution will, hopefully, present you with new or different problems which hopefully have simpler solutions than problems created by other choices.

I mentioned all of this without bringing up publish/subscribe but that is the core of what we’re talking about here.  You have publishers of data and subscribers to that data.  The publisher provides a consistent, well-defined method of getting that data and subscribers come and get it.  It solves a lot of problems.  Service down, no problem, subscribers can catch up later.  Something out of sync, not a problem, the publisher can resend something if needed.

Push versus pull?  Right now I think things should lean towards pull.  It was a good enough model that the Department of Justice began developing WSDLs and asking partners to put up web services that met the specifications of that WSDL so they could come and get from those partners.  To date it has been very successful, at least in our implementation.