Wednesday, June 5, 2013

Jason: fallback behaviors

jason22_thumb4

When dealing with a third party toolkit/framework, such as Jason, it is really important to be able to instruct the toolkit to behave in some sort of default way if something is not provided/expected.

We spoke about validation but what if we would like to plug a default DataAnnotation validator that intercept all the incoming commands and handles all the applied attributes? Such as:

public sealed class ObjectDataAnnotationValidator : AbstractDataAnnotationValidator<Object>
{
}

the first thing to notice is that Jason supports inheritance so we can inject an AbstractDataAnnotationValidator<Object> to intercept _all_ the commands regardless of their type. We can instruct Jason to treat the above validator as a fallback validator if no validator, for the incoming command type, can be found in the following way:

var jasonConfig = new DefaultJasonServerConfiguration
(
  pathToScanForAssemblies: Path.Combine( AppDomain.CurrentDomain.BaseDirectory, "bin" ),
  assemblySelectPattern: assemblySelectPattern
)
{
  Container = new WindsorJasonContainerProxy( container ),
  TypeFilter = t => !t.Is<JasonToBusRepublishHandler>()
};

jasonConfig.AddEndpoint( new Jason.WebAPI.JasonWebAPIEndpoint()
{
    TypeNameHandling = TypeNameHandling.Objects,
    DefaultSuccessfulHttpResponseCode = System.Net.HttpStatusCode.Accepted
} )
.UsingAsFallbackCommandHandler<JasonToBusRepublishHandler>()
.UsingAsFallbackCommandValidator<ObjectDataAnnotationValidator>()
.Initialize();

The above snippet comes from a web application that is a mere frontend that receives commands from SPA client (Single Page Application) so the applications performs a basic validation and republish commands on the bus (using NServiceBus in this case), so we configure Jason to do 2 different things:

  1. if a command handler for the incoming command cannot be found use the JasonToBusRepublishHandler;
  2. Since we are using a bus to dispatch commands we are introducing delays, due the async nature of a bus, in the command handling pipeline thus we instruct Jason for WebAPI to return as success HTTP status code “Accepted” instead of the default HTTP-200;
  3. The last thing to notice is that in the configuration we are telling Jason to ignore (using the TypeFilter delegate) the JasonToBusRepublishHandler that should not be registered as a traditional handler in the Jason configuration;

.m

Tuesday, May 28, 2013

Jason: validation

jason[22]When you deal with command in a CQRS world using for example WebAPI as the transport, well HTTP as transport and WebAPI as host, and you use a toolkit as Jason to handle all the infrastructure what you immediately loose is the full control on the ApiController that handles http requests. Asp.NET WebAPI has an immersive and powerful pipeline where you can plug to add and change behaviors, but loosing control over the controller force you to fallback to the DelegatingHandler WebAPI extension point that is q raw low level, extremely powerful but too much low level for most of the application.

The first thing that comes in to my mind when I think to a command that travels on the wire and that will be handled server side is validation: I must validate the incoming command, period, something coming from the outside cannot be trusted, period #2.

Currently the only option is to validate the incoming command into the command handler itself:

public class MyCommandHandler : ICommandHandler<MyCommand>
{
  public object Execute( MyCommand command )
  {
    //Validate the command...
    //Handle the command here...
    Jason.Defaults.Response.Ok;
  }
}

Is it wrong? No, not really, but we are violating the Single Responsibility Principle, in the end the above class is a command handler not a command validator, isn’t it?

So…

Now if you drop, and register in the container, a class in your project like the following one:

class MyCommandValidator : AbstractValidator<MyCommand> 
{
    public MyCommandValidator()
    {
        this.AddRule(
            property: cmd => cmd.MyProperty,
            error: ctx => "MyProperty is required.",
            rule: ctx => !String.IsNullOrWhiteSpace( ctx.Entity.MyProperty ) );
    }
}

it will be automatically picked up by the infrastructure to validate the incoming MyCommand. By default if the validation fails an HTTP400 (Bad Request) will be returned to the client, with in the message all the details about the validation errors.

Please welcome DataAnnotation support

So, since we have in Asp.Net the support for DataAnnotations why not allow the developer to change the above code to:

class MyCommandValidator : AbstractDataAnnotationValidator<MyCommand> 
{
    public MyCommandValidator()
    {
        this.AddRule(
            property: cmd => cmd.MyProperty,
            error: ctx => "MyProperty is required.",
            rule: ctx => 
            {
                //complex rule that cannot be expressed with an attribute
                return true; //or false to indicate failure.
            } );
    }
}

And have the command defined as:

class MyCommand
{
    [Required]
    public String MyProperty{ get; set; }
}

Inheriting the validator from the AbstractDataAnnotationValidator<T> activates the DataAnnotation support thus we can decorate commands with the data annotations attributes and we can express complex rules using code as in the above sample.

.m

Wednesday, May 22, 2013

Expanding Radical IoC/DI support

We are pretty proud of the work we are doing with Radical and now we are even pretty happy with the overall architecture of the whole toolkit. The reason is pretty simple we have decided (due to some requests) to add support for 2 new Inversion of Control containers: Autofac and Unity.

We are proud because it has been a really easy task, that does not require any change to the toolkit proving that the architectural choices made some years ago to isolate the IoC infrastructure were pretty good choices.

We have now support for: Windsor, Puzzle (Radical built-in IoC container), Autofac and Unity (both v2 and v3).

Nuget packages:

.m

Monday, May 6, 2013

NServiceBus: error queues

NServiceBus has the concept of error queue, that is used, as the name implies, when an error occurs; given this behavior the debate should move to:

What is an error?

Many things can be categorized as an error:

  • pure bugs such as unhandled exceptions;
  • validation failures: the incoming message does not satisfies the business validation rules;
  • security violations: the incoming message, due the current security context, cannot be handled;
  • etc.;

What we get for free in NServiceBus is that if our message handler does something like this:

class SampleHandler : IHandleMessages<SampleMessage>
{
    public void Handle( SampleMessage message )
    {
        if( !this.IsValid( message ) )
        {
             throw new ArgumentException( "Invalid message" );
        }

        //message handling if validation succeed
    }
}

and an invalid message comes in the retry logic retries for 5 times (by default) and then if the message is still invalid moves the message to the error queue.

But…

Some legitimate questions arise from the above sample:

  1. is it possible that if message A is considered invalid at the first attempt can be considered valid at a subsequent attempt?
  2. is a validation failure the same as an unhandled exception?
  3. does it make sense to have message failed due to a validation failure in the same can as a message failed due to a bug?
    do they have the same business meaning?

Do all the above questions mean that the default NServiceBus behavior is wrong? absolutely not, period.

The above questions simply put evidence on the fact that every little thing that happens in the world we are modeling has a meaning, from the business perspective, and that meaning must be magnified to deeply understand how to treat it.

Next time we’ll see how we can leverage the message handling pipeline to change the default above behavior to satisfy our needs.

.m

Friday, May 3, 2013

RavenDB: Worker Role vs. Virtual Machine

We have seen that in order to deploy RavenDB on Windows Azure we 2 main options:

Which is the best bet?

Now that Azure Virtual Machines are a fully supported feature I have to say that they are the preferred solution, or even the only real solution.

Why?

Control is the keyword. Scaling a database is not just a matter of adding power (vertical scaling) or instances (horizontal scaling), scaling a database requires full control over the scaling topology and the Azure worker roles are not thought with control over topology in mind, it is simply not their role to give us control, they are here to give us a really, and powerful, easy way to scale.

Worker roles live behind, and there is no way to avoid this, a network load balancer that hides from the outside the roles topology, preventing upfront to have a master-slave relation within database instances hosted in different role instances.

The only concrete way to host RavenDB (any db?) is to have full control over the network topology, and have full knowledge of the topology from the client perspective, for example we need to know that from a certain point on we are connected to a slave and not anymore to the master, and to have full control we need to leverage the power of the Azure Virtual Machines where we can do quite all we want in term of machine configuration and of network configuration.

Without loosing to much in term of time-to-react to scale requests, like we already said.

.m

Tuesday, April 30, 2013

NServiceBus, Windsor and message scopes

if you are working with NServiceBus, using as backend IoC container Castle Windsor, remember that under the hood NServiceBus utilizes the Windsor scope feature to create a scope “around” messages in order to isolate dependencies required by each message handler.

In this case if you need to have a component, registered in Windsor, that has its lifestyle bound to the message lifecycle it is enough to register the component using the “LifestyleScope”:

container.Register
(
    Component.For<MyAmazingComponent>().LifestyleScoped()
);

.m

Thursday, April 18, 2013

Jason v0.2.1.0: retry policies

As promised here we are :-)

One of our customer, using Jason, has a requirement to implement the concept of retry during the standard command execution flow. basically they have a situation where some infrastructure/transient exceptions can be raised during the command execution request and they want to be able to retry without bothering the client if not needed.

Retry Policy

In Jason v0.2.1.0, at the time of this writing in beta, we introduced the concept of retry policy; a retry policy is something that implements the ICommandExecutionRetryPolicy interface:

public interface ICommandExecutionRetryPolicy
{
    object Execute( Object command, Func<ICommandHandler> handlerFactory );
}

And can be injected into the Jason configuration in the following way:

jasonConfig.UsingAsRetryPolicy<MyCustomPolicy>();

Where MyCustomPolicy is a class that implements ICommandExecutionRetryPolicy. In the above sample the policy is registered in the container at initialization time and used by the various Jason entry point to handle all the retry logic.

There is one built-in retry policy in Jason that can be used to handle retries in case of failure:

jasonConfig.UsingAsRetryPolicy( new DelegateCommandExecutionRetryPolicy()
{
    DefaultRetryDelay = 200,
    ShouldRetry = e => e.Retry = ( e.Error is NotSupportedException && e.CurrentRetryCount < 5 )
} );

In this case the policy is still registered in the container using the supplied instance, at runtime if a failure occurs the policy is queried to determine if a retry should be attempted.

.m