Software Development

Paramore Brighter: The Russian Doll Model

I’ve mentioned a bit about the attributing the handler and the step and timing parameters, but I’ve not explained them properly in previous posts (“Retrying commands” mentions steps, and “Don’t Repeat Yourself” also mentions timings). So, I’ve created a small project to demonstrate what they mean and how it all operates.

The code for this post is available on GitHub.

If you just have the target handler, that is the handler that is directly tied to the Command that got Sent, without any decorations, then we won’t have to worry about the Russian Doll Model. There is only one handler, and it goes directly there. However, as soon as you start decorating your handler with other handlers it comes in to effect.

Timing

As the name suggests this affects when the decorated handler will run. Either before or after the target handler. However, handlers set to run “before” also get an opportunity to do things afterwards as well due to the Russian Doll model, as we’ll see.

The Before handler wraps the target handler, and the target handler wraps the After handler. At the very centre is the inner most After handler. Like this:

Russian Doll Model with Before and After handlers
Russian Doll Model with Before and After handlers

The red arrows in the diagram show the flow of the code. So, for a handler with a before and after decoration, the code will execute in the following order:

  • The “Before” timing Handle method
  • The Target Handle method
  • The “After” timing Handle method
  • The Target Handle method continued (after any call to the base.Handle())
  • The “Before” timing Handle method continued (after any call to the base.Handle())

Obviously, you do not have to call the base.Handler from your handler, but if you do that you break the Russian Doll Model, subsequent steps will not be called. Throwing an exception also will not call subsequent steps. According to Ian Cooper, the originator of the Paramore Brighter framework, “An exception is the preferred mechanism to exit a pipeline”.

Steps

If you have multiple decorators with the same timing, it may be important to let the framework know in which order to run them.

For Before handlers the steps ascend, so step 1, followed by step 2, followed by step 3, etc. For After handlers the steps descend, so step 3, followed by step 2, followed by step 1.

Russian Doll Model 7 Layers
7 Layer Russian Doll Model (3 Before, Target, and 3 After)

The red arrows in the diagram show the flow of the code. So, for a handler with three before and after decorations, the code will execute in the following order:

  • Step 1 for the “Before” timing Handle method
  • Step 2 for the “Before” timing Handle method
  • Step 3 for the “Before” timing Handle method
  • The Target Handle method
  • Step 3 for the “After” timing Handle method
  • Step 2 for the “After” timing Handle method
  • Step 1 for the “After” timing Handle method
  • Step 2 for the “After” timing Handle method continued (after any call to the base.Handle())
  • Step 3 for the “After” timing Handle method continued (after any call to the base.Handle())
  • The Target Handle method continued (after any call to the base.Handle())
  • Step 3 for the “Before” timing Handle method continued (after any call to the base.Handle())
  • Step 2 for the “Before” timing Handle method continued (after any call to the base.Handle())
  • Step 1 for the “Before” timing Handle method continued (after any call to the base.Handle())

Base Handler classes

You can, of course, create a class between RequestHandler and your own target handler class and this adds its own complexity to the model.

Any handler attributes added to the base class will be added to the pipeline and those handlers will be run for the time, and step they specify. Also, remember that the base class has its own Handle method which can have code before and and after the call to the base class’s implementation.

This can be seen in the sample project on GitHub, which you can download and experiment with to see how the code is executed.

Software Development

Paramore Brighter: DRY with Custom Decorated Command Handlers

You may wish to add similar functionality to many (or all) command handlers. The typical example is logging. You can decorate a command handler in a similar way to the policies I showed in previous posts to add common functionality. I’ve used this technique to guard the handler from invalid command arguments/parameters (essentially a validator), and for ensuring that we ping our APM (Application Performance Management) tool when a command completes. I’ll use the latter to demonstrate creating a custom decorator and handler to initiate this common code.

Paramore Brighter Command Processor will look for any attributes derived from RequestHandlerAttribute that are added to the Handle method on your command handler class. It will then use them to build a pipeline for your command.

So, in the example here, our attribute class looks like this:

public class HeartbeatAttribute : RequestHandlerAttribute
{
    public HeartbeatAttribute(int step, HandlerTiming timing = HandlerTiming.After) : base(step, timing)
    {
    }

    public override Type GetHandlerType()
    {
        return typeof(HeartbeatHandler<>);
    }
}

We are deriving from RequestHandlerAttribute, and it has an abstract method that you need to implement. GetHandlerType() returns the type of handler that needs to be instantiated to handle the common task.

The RequestHandlerAttribute class also takes two arguments for its constructor that you either need to capture from users of your attribute or supply yourself. It takes a step and a timing parameter. Since we’ve already talked about step in a previous post we’ll move on to talking about timing.

The two options for timing are Before and After. In the previous examples the timing has been implicitly set to Before because the handler needed perform actions before your target handler (the one that you decorated). If you set the timing to After it only actions after your target handler.

In the example here, the timing is set After because we want to make sure that the the handler completed correctly before our handler runs. So, if it throws an exception then our heartbeat handler won’t run. If you need to perform an action before and after, then set the timing to Before, and perform actions before the call to base.Handle() and after the call.

Our heartbeat handler looks like this:

public class HeartbeatHandler<TRequest> : RequestHandler<TRequest> where TRequest : class, IRequest
{
    public override TRequest Handle(TRequest command)
    {
        // We would probably call a heartbeat service at this point.
        // But for demonstration we'll just write to the console.

        Console.WriteLine($"Heartbeat pulsed for {command.GetType().FullName}");
        string jsonString = JsonConvert.SerializeObject(command);
        Console.WriteLine(jsonString);

        return base.Handle(command);
    }
}

The important thing, as will all handlers, is to remember the call to the base.Handle() which ensures the pipeline is continued.

The target handler decoration looks like this:

[FallbackPolicy(step:1, backstop:true, circuitBreaker:false)]
[UsePolicy(policy: "GreetingRetryPolicy", step:2)]
[Heartbeat(step:3)]
public override SalutationCommand Handle(SalutationCommand command)
{
    // Stuff to handle the command.

    return base.Handle(command);
}

The first two decorators are from previous posts (Retrying Commands and Implementing a fallback exception handler) while the third is our new decorator.

When run, you can see that if the service fails completely (i.e. all the retries failed) then the Heartbeat does not get run. However, if the command succeeds then the heartbeat handler is run. Our APM knows the command succeeded and can display that.

Remember

Remember to wire up the handler, as with all handlers, to your dependency injection framework, so that it can be correctly instantiated:

serviceCollection.AddScoped(typeof(HeartbeatHandler<>));
Software Development

Paramore Brighter with Quality of Service: Retrying Commands

Paramore Brighter supports Policies to maintain quality of service. This is useful when your command makes calls to external services, whether they are databases, web services, or any other end point that exists out of the process of your application. You can set up retry policies, circuit-breaker policies, and timeout policies. For this post, we’ll concentrate on setting up a retry policy.

The full code from this post is available on GitHub.com.

The SalutationHandler that we’ve been using in previous posts now emulates an external failure by throwing an exception in some cases. The policy handler will catch the exception and act on it, retrying the command if necessary.

Set up the policy

First off let’s set up the policy. In this case I’m going for an exponential backoff (doubling the wait time on each attempt) and it will perform a maximum of 4 attempts.

private static IAmAPolicyRegistry GetPolicies()
{
    var policyRegistry = new PolicyRegistry();

    // These are the default policies that must exist. 
    // We're not using them, so we're setting them to No-op
    policyRegistry.Add(CommandProcessor.RETRYPOLICY, Policy.NoOp());
    policyRegistry.Add(CommandProcessor.RETRYPOLICYASYNC, Policy.NoOpAsync());
    policyRegistry.Add(CommandProcessor.CIRCUITBREAKER, Policy.NoOp());
    policyRegistry.Add(CommandProcessor.CIRCUITBREAKERASYNC, Policy.NoOpAsync());
    
    // Sets up the policy that we're going to use 
    // for the SaluationHandler
    var greetingRetryPolicy = Policy
        .Handle<Exception>()
        .WaitAndRetry(new[]
        {
            TimeSpan.FromSeconds(1),
            TimeSpan.FromSeconds(2), 
            TimeSpan.FromSeconds(4) 
        }, (exception, timeSpan) =>
        {
            Console.WriteLine($" ** An error occurred: {exception.Message}");
            Console.WriteLine($" ** Waiting {timeSpan.Seconds} seconds until retry.");
        });

    policyRegistry.Add("GreetingRetryPolicy", greetingRetryPolicy);
    return policyRegistry;
}

The policies are defined using Polly, a .NET resilience and transient-fault-handling library.

The .Handle<Exception>() means the policy handles all exceptions. You might want it to be more specific for your use case. e.g. SqlException for database errors.

The WaitAndRetry(...) takes a set of timings (as TimeSpan objects) for how long to wait between attempts and an Action which is run between attempts. Although there are only 3 times here, it will make 4 attempts. Each time represents the amount of time after an attempt before retrying. The first attempt is performed immediately.

The Action allows you to set up what you want to do between attempts. In this case, I’ve only had it output to the console. You may wish to log the error, or take other actions that might help it work.

Finally, we add the policy to the registry and give it a name, so we can refer to it on our Handle method in our command handler class.

In order for Brighter to be able to use this policy, the Handler for it needs to be registered in the IoC container.

serviceCollection.AddScoped(typeof(ExceptionPolicyHandler<>));

The Command Handler

It should be noted that the regardless of the number retries that are made, they are all processed through the same instance of the command handler. This may be important if you store state to do with the progress of the command. It also might be important in case any services you rely on that are injected into the command handler get left in an undefined state if things go wrong.

[FallbackPolicy(step:1, backstop:true, circuitBreaker:false)]
[UsePolicy(policy: "GreetingRetryPolicy", step:2)]
public override SalutationCommand Handle(SalutationCommand command)
{
    ...
}

We still have our fallback that we set up in the previous post on Paramore Brighter, but we now have a UsePolicy attribute. And since we have two attributes the Step argument now becomes important.

The command processor sets up the policy and command handlers like a Russian doll, with the command handler right in the middle. The outer handler (doll) is step 1, then the one inside that is step 2, and so on until you get to the actual command handler. So, in this case at the very outside is the FallbackPolicy and it only does its thing if it gets an exception, the UsePolicy will act on exceptions before the fallback sees them most of the time.

The UsePolicy attribute takes the name of the policy that we set up earlier when we were creating the policy registry.

Analysing the StackTrace

So, when we ask to greet “Voldemort” it will always fail. We get a stack trace that shows off the Russian Doll quite well.

System.ApplicationException: A death-eater has appeared.
   at QualityOfService.SalutationHandler.ThrowOnTheDarkLord(SalutationCommand command) in C:\dev\BrighterRecipes\src\quality-of-service\quality-of-service\SalutationHandler.cs:line 46
   at QualityOfService.SalutationHandler.Handle(SalutationCommand command) in C:\dev\BrighterRecipes\src\quality-of-service\quality-of-service\SalutationHandler.cs:line 21
   at Paramore.Brighter.RequestHandler`1.Handle(TRequest command)

The above is our SaulatationHandler, starting from the top where the exception is thrown, until the point that our code is called by Paramore Brighter itself.

   at Paramore.Brighter.Policies.Handlers.ExceptionPolicyHandler`1.<>n__0(TRequest command)
   at Paramore.Brighter.Policies.Handlers.ExceptionPolicyHandler`1.<>c__DisplayClass2_0.b__0()
   at Polly.Policy.<>c__DisplayClass33_0`1.b__0(Context ctx, CancellationToken ct)
   at Polly.Policy.<>c__DisplayClass42_0`1.b__0(Context ctx, CancellationToken ct)
   at Polly.RetrySyntax.<>c__DisplayClass19_0.b__1(Context ctx, CancellationToken ct)
   at Polly.Retry.RetryEngine.Implementation[TResult](Func`3 action, Context context, CancellationToken cancellationToken, IEnumerable`1 shouldRetryExceptionPredicates, IEnumerable`1 shouldRetryResultPredicates, Func`1 policyStateFactory)
   at Polly.RetrySyntax.<>c__DisplayClass19_1.b__0(Action`2 action, Context context, CancellationToken cancellationToken)
   at Polly.Policy.Execute[TResult](Func`3 action, Context context, CancellationToken cancellationToken)
   at Polly.Policy.Execute[TResult](Func`1 action)
   at Paramore.Brighter.Policies.Handlers.ExceptionPolicyHandler`1.Handle(TRequest command)
   at Paramore.Brighter.RequestHandler`1.Handle(TRequest command)

The above section is all part of the retry handler, as defined by the policy we set up. Most of this code is in Polly, which is the quality of service package that Brighter uses.

   at Paramore.Brighter.Policies.Handlers.FallbackPolicyHandler`1.CatchAll(TRequest command)
// The rest of this isn't really part of the exception 
// stack trace, but I wanted to show you where it came from.
   at Paramore.Brighter.Policies.Handlers.FallbackPolicyHandler`1.Handle(TRequest command)
   at Paramore.Brighter.CommandProcessor.Send[T](T command)
   at QualityOfService.Program.Main(String[] args)

Finally, the most outer of the handlers (which you cannot normally see all of because it has caught the exception in CatchAll) before handing it off to our fallback handler.

Misc

Setting file permissions on a remote machine with PowerShell

Recently I needed to set some file permissions on a remote machine. Previously I’d done this relatively easily through a share as the user account I was using also had administrator rights on the other side and I was dealing with domain accounts. However, this did not work for a user that was local to the remote machine.

So, I creates a small PowerShell function to remotely set the user to a local (or any domain) account. (This also works for virtual accounts like IIS AppPool/ users)

function Add-RemoteAcl
(
    [string]$computerName,
    [string]$directory,
    [string]$user,
    [string]$permission
)
{
    $session = New-PSSession -ComputerName $computerName;
    Invoke-Command -Session $session -Args $directory, $user, $permission -ScriptBlock {
        param([string]$directory,[string]$user,[string]$permission)
        $acl = Get-Acl $directory;
        $accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($user, $permission, "ContainerInherit, ObjectInherit", "None", "Allow");
        if ($accessRule -eq $null){
            Throw "Unable to create the Access Rule giving $permission permission to $user on $directory";
        }
        $acl.AddAccessRule($accessRule)
        Set-Acl -aclobject $acl $directory
    };
    Remove-PSSession $session;
}

To run the PowerShell remotely, first of all, I create a new PowerShell session on the remote machine with New-PSSession, then I run a script in that session with Invoke-Command, and finally I clean up with Remove-PSSession to end the remote session.

Bear in mind that you will need the appropriate permissions on the remote machine for whatever actions you want to take.

Invoke-Command

This is where all the work is done. You can pass a session to Invoke-Command, and you can also pass an ArgumentList to pass in to the command. This gives it some fantastic abilities.

Be aware that variables that exist outside the script block are not visible within the script block, you have to pass them as an ArgumentList (alias Args), and the script block has to pick them up. Hence the code above starts the script block with a params section in order to pick up the values passed as the Args.

Setting the file permissions

In order to add new rules to an ACL you have to Get-Acl to get the existing set of rules, create the new FileSystemAccessRule for the permission you want to grant, then AddAccessRule to the ACL you retrieved, and finally Set-Acl to persist the addition.

If you were just to create the new rule and set that, then all the existing rules would be replaced with the one rule that was just created.

Misc

IIS Administration file access

If you are using the IIS Administration ReST API to manage IIS, one thing that is not immediately obvious is that if you put your websites outside of %systemdrive%\inetpub you won’t be able to access them through the API. e.g. You won’t be able to set the physical path of a website to a location outwith %systemdrive%\inetpub.

If you do try to set the file outwith the default location, then you will get an 403 error from the API with a JSON response that looks like this:

{
    "title":"Forbidden",
    "name":"physical_path",
    "detail":"C:\\www\\MyWebSite",
    "status":403
}

So, you need to update its settings file (in my case, located at C:\Program Files\IIS Administration\2.2.0\Microsoft.IIS.Administration\config\appsettings.json) to include a files section. The files section is at the same level as security, logging, cors, etc.

e.g.

  "files": {
    "locations": [
      {
        "alias": "www",
        "path": "c:\\www",
        "claims": [
          "read"
        ]
      }
    ]
  }

This will allow websites/web-applications to be located in C:\www

Remember to restart the “Microsoft IIS Administration” Service after making changes to the appsettings.json file so that it will be picked up.

Restarting Microsoft IIS Administration Service
Restart Microsoft IIS Administration Service

You can also check which files IIS Administration has access to through the API. The end-point is /api/files/ and, if there are no files set up it will show an empty JSON array for the files part of the result.

API Result showing empty files section
API Result showing empty files section

Once the files section is added to the appsettings.json file and the Microsoft IIS Administration service is restarted, the API will show which files the API can access.

Populated file section in the IIS Administration API
Populated file section in the IIS Administration API

Finally, if you are having difficulty saving the appsettings.json file, read how to take ownership of a file in order to be able to be able to write to it.

Updates

Updated 14/March/2018: Note to restart the Windows Service; Show what files are available through the API; formatting.

Misc

Taking ownership of a file

I’m currently looking at using IIS Administration as a way to automate some deployment tasks. However, the way it got installed, it’s appsettings.json file could not be written to, even when running the text editor as Administrator.

It turns out, SYSTEM had full control of the file, and the installer configured it to only allow me to access the ReST API, yet I needed a deployment script running from the Continuous Delivery server to be able to access IIS Administration, so I needed to modify the settings file, somehow.

To take ownership – The quick guide

So, to take ownership of the appsettings.json file, what I needed was to run two commands at command prompt running as Administrator.

takeown /f "appsettings.json" /a

icacls "appsettings.json" /grant administrators:F /c /l

TAKEOWN

/f [filename] : Specifies the file or directory name, can contain wildcards.

/a : Optional, gives the ownership to the Administrators group, rather than the current user.

 

ICACLS

/grant [sid]:[permission] : Where sid is the name of the user or group, and [permission] is the permission set, in this case F for “full access”

/C : Indicates to continue on error

/L : Indicates the operation will run on the symbolic link itself, rather than the target of the link.

Software Development

Paramore Brighter: Implementing a fallback exception handler

So far in this series, we have a basic command processor set up and able to dispose of resources. But what happens when things go wrong? The command processor has a fallback mechanism to handle exceptions that are not caught.

To add this functionality all you need to do is to decorate your handler with a fallback policy attribute, add the Fallback handler into your Dependency Injection framework, and then override the Fallback method.

To add the Fallback handler to .NET Core’s Dependency Injection framework we add

serviceCollection.AddScoped(typeof(FallbackPolicyHandler<>));

to the BuildServiceProvider method. The typeof variant of AddScoped allows a more general type to be expressed. Otherwise, we’d have to add a fallback policy handler for each command.

Our little salutation handler now looks like this:

[FallbackPolicy(backstop:true, circuitBreaker:false, step:1)]
public override SalutationCommand Handle(SalutationCommand command)
{
    Console.WriteLine($"Greetings, {command.Name}.");
    ThrowOnTheDarkLord(command);
    return base.Handle(command);
}

(If you’ve not read Harry Potter, the reference is that if you use He-who-must-not-be-named’s name, then a death eater will appear and take you away. So if we use The Dark Lord’s name we’re throwing an exception)

Back to the code: The first line is the attribute decoration. In this case we say we have a fallback policy that acts as a backstop for any unhandled exception (backstop:true). We’ve not covered the Circuit Breaker so we’re not interested in that for the moment (circuitBreaker:false), and we’ve also not covered what happens if you have multiple attributes (step:1) so we’ll leave that as step 1 (of 1). I’ll come back to those things later.

Now, if we put “Voldemort” in as the Name in the command, it will throw an exception. So we have to handle that somehow. The RequestHandler class has a Fallback method which you can override in your derived handler class.

public override SalutationCommand Fallback(SalutationCommand command)
{
    if (this.Context.Bag
            .ContainsKey(FallbackPolicyHandler<SalutationCommand>
                         .CAUSE_OF_FALLBACK_EXCEPTION))
    {
        Exception exception = (Exception)this.Context
                              .Bag[FallbackPolicyHandler
                                   .CAUSE_OF_FALLBACK_EXCEPTION];
        Console.WriteLine(exception);
    }
    return base.Fallback(command);
}

What is happening here is that we are retrieving the Exception from the Context‘s Bag, which is just a Dictionary. Then we can do what we want with the Exception. In this simple example, I’m just writing it to the console, but you’ll most likely want to do something more with it in your application.

As you can see, this is a bit on the clunky side, so where I’ve used Brighter before, I’ve tended to introduce a class between RequestHandler and the specific handler to put in some things that help clean things up.

In this case the MyRequestHandler class looks like this:

public class MyRequestHandler<TCommand> 
             : RequestHandler<TCommand> where TCommand : class, IRequest
{
    public override TCommand Fallback(TCommand command)
    {
        if (this.Context.Bag
            .ContainsKey(FallbackPolicyHandler
                .CAUSE_OF_FALLBACK_EXCEPTION))
        {
            Exception exception = (Exception)this.Context
                .Bag[FallbackPolicyHandler
                    .CAUSE_OF_FALLBACK_EXCEPTION];
            return base.Fallback(ExceptionFallback(command, exception));
        }
        return base.Fallback(command);
    }

    public virtual TCommand ExceptionFallback(TCommand command, Exception exception)
    {
        // If exceptions need to be handled, 
        // this should be implemented in a derived class
        return command;
    }
}

At the top we can see that instead of a specific command we still have the generic TCommand, which needs to be a class and derived from IRequest. That wasn’t seen in the specific command handler because the explicit command already has these properties, so we didn’t need to express them again.

The Fallback method now contains the code that extracts the exception from the Context and calls ExceptionFallback. In this class ExceptionFallback does nothing except return the command back. When we implement it in our SalutationHandler, the code for handling the exception now looks like this:

public override SalutationCommand ExceptionFallback(SalutationCommand command, Exception exception)
{
    Console.WriteLine(exception);
    return base.ExceptionFallback(command, exception);
}

And that is so much nicer to read. We’ve extracted away the plumbing of retrieving the exception to the newly introduced base class and our command handler looks much neater as a result.

To view the source as a whole, see it on GitHub.