Tuesday, March 07, 2017

Writing plugins for Octopus

Following on from my previous post about writing plug-ins, here’s the next installment of what may or may not become an irregular feature.

I’ve been using Octopus Deploy at work for several years now, and it is a great tool for automating the deployment of software; in my case, it turned a 20-page manual checklist that took 40 minutes to work through into a five minute fire-and-forget exercise. However, there are still little steps here and there that can’t be automated out-of-the-box, and that’s where we pick up our story.

We track our work-in-progress using JIRA, and one of those tedious post-release tasks is to update all the tickets, setting their status to Released and so on. So, given that JIRA exposes an API, and Octopus supports custom steps or step templates written in Powershell, why not combine the two and cross another manual step off the list?!

Show me the code!

Actually, I’m not going to post any code snippets this time – rather, I’ve published the source code to GitHub (something else I’m learning, after 15 years of Subversion), so go ahead and fork it. There’s not a whole lot of error handling in there at the moment, but it seems to do the trick. There are two files:

  • the original Powershell file, which you can open up and run in the Powershell IDE;
  • the Octopus Deploy step template, which wraps up the Powershell in a bit and parameterises it to make the code more reusable

Tuesday, February 14, 2017

Writing plugins for Exceptionless

Exceptionless is one of those tools that no developer should be without; it integrates with your application (currently .NET and NodeJS platforms are supported, with the promise of more to come), captures your unhandled exceptions, and provides you all sorts of tools to manage these exceptions.

The project itself is open source, and you can set up your own on-premise server to run the service, or you can use their cloud service if you don’t want the hassle of maintaining YADS (Yet Another D**n Server).
Their support is also very good; I’ve been working on a number of different scenarios (e.g. creating custom reports using the API to query for data, at least until they implement custom dashboards). The scenario that prompted this post was simple – when we deploy a new version of our API, we run a suite of automated regression tests to make sure we haven’t broken anything for our customers, but these regression tests include a large number of expected failure tests, which result in a large number of false positives being reported. So time to break open the coding tools and fix that…

Show me the code

The Exceptionless client provides a number of extension points, and after talking to Blake Niemyjski, who seems to be the main point of contact for enquiries, I whipped up the following plugin:
[Priority(5)]
public class SquelchExpectedExceptionsPlugin : IEventPlugin
{
    public void Run(EventPluginContext context)
    {
        var exception = context.ContextData.GetException();
        var httpContext = context.ContextData.GetHttpContext();

        if (ApiExceptionClassifier.IsAnExpectedException(exception, httpContext.Request.Headers))
        {
            context.Cancel = true;
        }
    }
}

internal static class ExceptionlessExtensions
{
    internal static HttpActionContext GetHttpContext(this IDictionary<string, object> data)
    {
        if (!data.ContainsKey("HttpActionContext")) return null;
        return data["HttpActionContext"] as HttpActionContext;
    }

    internal static Exception GetException(this IDictionary<string, object> data)
    {
        if (!data.ContainsKey("@@_Exception")) return null;
        return data["@@Exception"] as Exception;
    }

I had to add the extension methods as these are currently internal to the Exceptionless.Net library, while the ApiExceptionClassifier is a bit of business logic which checks for a specific header the the request to determine what sort of HTTP status code a given exception should result in (e.g. we want all ValidationExceptions to result in a 400 Bad Request). The plugin priority needs to be set to a low value so that it gets executed as early as possible – there’s not much point in gathering all sorts of data if we’re just going to throw it all away when the Cancel method gets called.
Once that was done, all that is left is to register the plugin in the API’s startup routine:
ExceptionlessClient.Default.Configuration.AddPlugin<SquelchExpectedExceptionsPlugin>();
And now, my regression tests don’t fill the Exceptionless reports with noise, unless an actual exception occurs during the process.

Back from hiatus

It’s been quite a while since I last posted, so it’s probably about time I got back into the habit. More to follow shortly!