ASP.Net Core base setup of Swashbuckle/Swagger OAS3 and API-Versioning – with a bit of touch-up

Previously…

… I wrote about how to generate Swagger/OAS 3 with versioning in an ASP.Net Core API.
But why stop there, lets do some touch-ups on that code.

First of all

This will build on the code from the previous blog-post.
I will include code for the accept header scenario, removing the parts needed for the separate header scenario. I will include all the classes that are needed for this.

Asumptions and nugets

Are the same as the previous blog post. Nothing has happened in this area since i wrote the last post.

Lets go to the code…

The steps needed are:

  • Add the classes needed to config the API-Version and Swagger.
  • Include method calls in the Startup class.

– ConfigureSwaggerOptions and the ISwaggerVersionInfoProvider

This interface and class lets us configure the options after the service has been resolved.

public interface ISwaggerVersionInfoProvider
{
    OpenApiInfo GetVersionInfo(ApiVersionDescription apiDescription);
}

/// <summary>
/// Configures the Swagger generation options.
/// </summary>
/// <remarks>This allows API versioning to define a Swagger document per API version after the
/// <see cref="IApiVersionDescriptionProvider"/> service has been resolved from the service container.</remarks>
public class ConfigureSwaggerOptions : IConfigureOptions<SwaggerGenOptions>
{
    readonly IApiVersionDescriptionProvider provider;

    /// <summary>
    /// Initializes a new instance of the <see cref="ConfigureSwaggerOptions"/> class.
    /// </summary>
    /// <param name="provider">The <see cref="IApiVersionDescriptionProvider">provider</see> used to generate Swagger documents.</param>
    public ConfigureSwaggerOptions(IApiVersionDescriptionProvider provider) => this.provider = provider;

    /// <inheritdoc />
    public void Configure(SwaggerGenOptions options)
    {
        // add a swagger document for each discovered API version
        // note: you might choose to skip or document deprecated API versions differently
        foreach (var description in provider.ApiVersionDescriptions)
        {
            options.SwaggerDoc(description.GroupName, CreateInfoForApiVersion(description));
        }

        // Add a custom operation filter which sets default values
        //options.OperationFilter<SwaggerDefaultValues>();

        // Integrate xml comments, add this when we have come that far.
        //options.IncludeXmlComments(XmlCommentsFilePath);

        // Describe all enums as strings instead of integers.
        //options.DescribeAllEnumsAsStrings();
    }

    // <summary>
    /// Creates an API-Version info object and fills it with data.
    /// </summary>
    /// <param name="description"></param>
    /// <returns>Returns an OpenApiInfo object with API-Version info.</returns>
    public static OpenApiInfo CreateInfoForApiVersion(this ApiVersionDescription description)
    {
        var info = new OpenApiInfo()
        {
            Title = $"Test API {description.ApiVersion}",
            Version = description.ApiVersion.ToString(),
            Description = "This is the swagger base info for API.",
            Contact = new OpenApiContact() { Name = "Contact Name", Email = "some@email.com" },
            //TermsOfService = "UnComment and put the URI here to the terms of service.",
            License = new OpenApiLicense() { Name = "MIT", Url = new Uri("https://opensource.org/licenses/MIT") }
        };

        if (description.IsDeprecated)
        {
            info.Description += " This API version has been deprecated.";
        }

        return info;
    }
}

– SwaggerGenerationSetupExtensionMethods

This one we know from the last post but there are some minor changes to it.
We have removed the CreateInfoForApiVersions method as it has been moved to the ConfigureSwaggerOptions class. You could probably remove the AddSwaggerGeneration and do all the configuration from the ConfigureSwaggerOptions class, but I am keeping it here for the time being.

/// <summary>
/// Extension methods for adding and configuring Swashbuckle/Swagger (OAS3) generation.
/// https://github.com/Microsoft/aspnet-api-versioning/wiki/Swashbuckle-Integration
/// </summary>
public static class SwaggerGenerationSetupExtensionMethods
{
    /// <summary>
    /// Adds and configures Swashbuckle/Swagger (OAS3) generation.
    /// </summary>
    /// <param name="services"></param>
    public static void AddSwaggerGeneration(this IServiceCollection services)
    {
        services.AddSwaggerGen(options =>
        {
            // Integrate xml comments, add this when we have come that far.
            //options.IncludeXmlComments(XmlCommentsFilePath);

            // Describe all enums as strings instead of integers.
            //options.DescribeAllEnumsAsStrings();
        });
    }

    /// <summary>
    /// Adds SwaggerUI and adds a API-Version for each discovered endpoint.
    /// </summary>
    /// <param name="app"></param>
    /// <param name="provider"></param>
    public static void UseSwaggerUIAndAddApiVersionEndPointBuilder(IApplicationBuilder app, IApiVersionDescriptionProvider provider)
    {
        app.UseSwaggerUI(c =>
        {
            // Build a swagger endpoint for each discovered API version
            foreach (var description in provider.ApiVersionDescriptions)
            {
                c.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
            }
        });
    }
}

– ApiVersionSetupExtensionMethods

This one is here with minor unimportant changes since last post.

public static class ApiVersionSetupExtensionMethods
{
    /// <summary>
    /// Adds API-Versioning with settings and API-Explorer with settings.
    /// </summary>
    /// <param name="services">The services collection to add to.</param>
    public static void AddApiVersioningAndExplorer(this IServiceCollection services)
    {
        // Add the versioned api explorer, which also adds IApiVersionDescriptionProvider service
        // Note: the specified format code will format the version as "'v'major[.minor][-status]"
        services.AddVersionedApiExplorer(
            options =>
            {
                options.GroupNameFormat = "'v'VVV";
            });

        services.AddApiVersioning(
            options =>
            {
                options.ReportApiVersions = true;

                // Use this if you would like to use the MediaType version header.
                // Eg: Header 'Accept: application/json; v=1.0'
                options.ApiVersionReader = new MediaTypeApiVersionReader();

                // This is set to true so that we can set what version to select (default version)
                // when no version has been selected.
                options.AssumeDefaultVersionWhenUnspecified = true;
                // And this is where we set how to select the default version. 
                options.ApiVersionSelector = new CurrentImplementationApiVersionSelector(options);
            });
    }
}

– Startup

The Startup class has one line changed since the last blog-post. The line where we include the new interface and class.

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Latest);

        services.AddApiVersioningAndExplorer();
        services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>();
        services.AddSwaggerGeneration();
    }



    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApiVersionDescriptionProvider provider)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseSwagger();
        app.UseSwaggerUIAndAddApiVersionEndPointBuilder(provider);
        app.UseMvc();
    }
}

Rounding off

This has been a touch-up post only. With very little info.
I will undoubtedly get back to this subject again…

ASP.Net Core base setup of Swashbuckle/Swagger OAS3 and API-Versioning

There are a lot of blog posts on API-Versioning like this and this.
Some people are even getting religious about it.
Because of all the existing posts I won’t go through that in this blog post. No more than saying that, I personally prefer including the versioning in the accept header, without using vendor specific custom media types. I’m not much for letting the version have its own header tag either.

// I like this
Header 'Accept: application/json; v=1.0'
// vs this
Header 'Accept: application/vnd.myapp.v1.user+json'
// or this
Header 'api-version: 1.0'

Love it or hate it, that is my preferred way.
So if I am not doing that, what is this blog post for then?
This blog post will show you how to easily setup API-Versioning and Swagger generation of OAS 3 in your ASP.Net Core API using Swashbuckle 5.0 (at the time of writing, this is in beta version) and Microsoft aspnet-api-versioning.

The assumptions

I am working from the assumption that you have created a basic startup project of .Net Core API and that you have at least a basic knowledge of .Net development and how to include nuget-packages.

What nugets you need to add

Microsoft.AspNetCore.Mvc.Versioning (3.1.1)
Microsoft.AspnetCore.MvcVersioning.ApiExplorer (3.1.0)
Swashbuckle.AspNetCore (5.0.0-beta)

Lets go to the code…

Getting this to work is fairly easy.
The following steps are needed:

  • Add the classes needed to config the API-Version and Swagger.
  • Include method calls in the Startup class.

So what are the classes needed to config?

Well I am fairly useless when it comes to naming stuff but I use 2 to 3 classes. 2 if I am doing versioning in the accept header and 3 if I am setting the version in a separate header. I will include both types and comment out the parts not needed for versioning in the accept header.

– ApiVersionSetupExtensionMethods

This static class only have one extension method that is used for the configuration of API-Versioning and it is pretty self explanatory, but I have kept and added some comments anyway.

public static class ApiVersionSetupExtensionMethods
{
    public static void AddApiVersioningAndExplorer(this IServiceCollection services)
    {
        // Add the versioned api explorer, which also adds IApiVersionDescriptionProvider service
        // Note: the specified format code will format the version as "'v'major[.minor][-status]"
        services.AddVersionedApiExplorer(
            options =>
            {
                options.GroupNameFormat = "'v'VVV";
            });

        services.AddApiVersioning(
            options =>
            {
                options.ReportApiVersions = true;

                    // Use this if you would like a new separate header to set the version in.
                    // Eg: Header 'api-version: 1.0'
                    //options.ApiVersionReader = new HeaderApiVersionReader("api-version");

                    // Use this if you would like to use the MediaType version header.
                    // Eg: Header 'Accept: application/json; v=1.0'
                    options.ApiVersionReader = new MediaTypeApiVersionReader();

                    // This is set to true so that we can set what version to select (default version)
                    // when no version has been selected.
                    options.AssumeDefaultVersionWhenUnspecified = true;
                    // And this is where we set how to select the default version. 
                    options.ApiVersionSelector = new CurrentImplementationApiVersionSelector(options);
            });
    }
}

– SwaggerGenerationSetupExtensionMethods

This class is of course used for configuring the swagger/OAS3 generation options. Once again i have kept and added comments to explain some of the stuff.

public static class SwaggerGenerationSetupExtensionMethods
{
    public static void AddSwaggerGeneration(this IServiceCollection services)
    {
        services.AddSwaggerGen(options =>
        {
            // Resolve the IApiVersionDescriptionProvider service
            // Note: that we have to build a temporary service provider here because one has not been created yet
            using (var serviceProvider = services.BuildServiceProvider())
            {
                var provider = serviceProvider.GetRequiredService<IApiVersionDescriptionProvider>();

                // Add a swagger document for each discovered API version
                // Note: you might choose to skip or document deprecated API versions differently
                foreach (var description in provider.ApiVersionDescriptions)
                {
                    options.SwaggerDoc(description.GroupName, description.CreateInfoForApiVersion());
                }
            }

            // Add a custom operation filter which sets default values if you are using a separate header for version
            //options.OperationFilter<SwaggerDefaultValues>();

            // Integrate xml comments, add this when we have come that far.
            //options.IncludeXmlComments(XmlCommentsFilePath);

            // Describe all enums as strings instead of integers.
            //options.DescribeAllEnumsAsStrings();
        });
    }

    public static OpenApiInfo CreateInfoForApiVersion(this ApiVersionDescription description)
    {
        var info = new OpenApiInfo()
        {
            Title = $"Test API {description.ApiVersion}",
            Version = description.ApiVersion.ToString(),
            Description = "This is the swagger base info for API.",
            Contact = new OpenApiContact() { Name = "Contact Name", Email = "some@email.com" },
            //TermsOfService = "UnComment and put the URI here to the terms of service.",
            License = new OpenApiLicense() { Name = "MIT", Url = new Uri("https://opensource.org/licenses/MIT") }
        };

        if (description.IsDeprecated)
        {
            info.Description += " This API version has been deprecated.";
        }

        return info;
    }

    public static void UseSwaggerUIAndAddApiVersionEndPointBuilder(this IApplicationBuilder app, IApiVersionDescriptionProvider provider)
    {
        app.UseSwaggerUI(c =>
        {
            // Build a swagger endpoint for each discovered API version
            foreach (var description in provider.ApiVersionDescriptions)
            {
                c.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
            }
        });
    }
}

– SwaggerDefaultValues

This final class is used to document the implicit API-version parameter.
In other words, setup some of the parameter descriptions and default values for the generated API-Version parameter. This class is only needed if you are setting the version in a separate header.

public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
    if (operation.Parameters == null)
    {
        return;
    }

    foreach (var parameter in operation.Parameters)
    {
        var description = context.ApiDescription
            .ParameterDescriptions
            .First(p => p.Name == parameter.Name);
        var routeInfo = description.RouteInfo;

        if (parameter.Description == null)
        {
            parameter.Description = description.ModelMetadata?.Description;
        }

        if (routeInfo == null)
        {
            continue;
        }

        if (parameter.In != ParameterLocation.Path && parameter.Schema.Default == null)
        {
            parameter.Schema.Default = new OpenApiString(routeInfo.DefaultValue.ToString());
        }

        parameter.Required |= !routeInfo.IsOptional;
    }
}

Include in Startup class

To conclude, lets use our config classes from the Startup class.
I have included the whole thing so there are no misunderstandings.

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

        services.AddApiVersioningAndExplorer();

        services.AddSwaggerGeneration();
    }



    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApiVersionDescriptionProvider provider)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseSwagger();
        app.UseSwaggerUIAndAddApiVersionEndPointBuilder(provider);
        app.UseMvc();
    }
}

Rounding off

There are other ways in witch to do this and there are definitely a lot more configuration options to use/include if needed. But this should get you started.
I will probably get back to this topic again…

How to throttle a Azure Function hosted on a consumption plan

Have you ever tried to throttle a Function that is hosted on a consumption plan?
Well if you have, then you know of some of the problems that you run into.
Given a Durable Function that does a fan-out and gets data from an API that needed throtteling, this is what I came up with.

Now the first thing I tried is of course to look at any way in the function settings to limit this, and this is what I found when checking out the host.JSON reference on microsoft docs.

"http": {
        "routePrefix": "api",
        "maxOutstandingRequests": 200,
        "maxConcurrentRequests": 100,
        "dynamicThrottlesEnabled": true
    }

When scrolling through, I found maxConcurrentRequests among others. Now this looked promising but when I researched it, I found that it does not really do the trick when using the consumption plan. That is because of the nature of the consumption plan, it auto scales, and the setting is per instance. In other words for every server it scales out to, it will set the maxConcurrentRequests.

OK, what now?
Well then I found this little beauty:

"WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT" : 1

The WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT is an application setting that at the moment is in preview, but will work for this solution.

After having made shure that the application can not scale out dynamicly, I needed to constrain the number of active requests or active calls to the API. Luckily Durable Functions had the answer to that giving me the possibility to set the maxConcurrentActivityFunctions making it possible for me to limit traffic to my API.

"durableTask": {
    "maxConcurrentActivityFunctions": 10,
    "maxConcurrentOrchestratorFunctions": 1
  }

I did not explore if a combination of 
WEBSITE_MAX_DYNAMIC_APPLICATION_SCALE_OUT and 
maxConcurrentRequests could be used. But as the given solution fit my needs…
I also did not look at changing the PartitionCount setting.
I may take a look at these another time.

Dynamically load and unload plugins with MEF

I wrote this many years ago and it has just been laying around since then without being published. In other words, everything below this point is old and unedited since i wrote it back then.

This article is a “Dynamic load and unload of plugins – in 20 minutes”.
The idea is that it is that you should be able to go through this article in 20 minutes (or less) and find out if it is applicable to what you want to achieve. If you do not know how MEF (Managed Extensibility Framework) works please get up to speed and then come back to this article. 
NOTE: This is not production code, it is there only as an example to show how it can be done. It is “as is” and I leave no warranties.

Short background. 
A little while back, I found myself needing to implement plugins to achieve the wanted functionality of a project. But as the application was a server service and should not be stopped, I needed my plugins to be able to load and unload while the application was running. 
While searching online I found some different ways to do this. 
I had looked at MEF (…) earlier for the “plugin functionality”, but wanted to see what was out there. 
Deciding to use MEF I now wanted to see if anyone hade done dynamic loading and unloading before (why invent the wheel…). I found some examples but most of them talked about it not being straight forward, since the loaded assemblies files are locked. And to get around that you could among other ways use “shadow copy”. If you want to look at those ways to do it, just search online and you will easily find examples or forum answers on how to do it. 
But I wanted an “uncomplicated” way and my logic told me to go another way.

Lets get to the point! 
My thought was simple: I should be able to read the assemblies into memory and then load them into the application. This would make it so that I could add or remove the plugin assembly files without shutting down my application. It also meant I did not need to be reliant on other functionality or 3:rd party libraries for it to work.

To make it simple I have rewritten the code to make it as simple as possible.

Start by writing the interface for the plugin. Put it in an assembly that is going to be referenced by both the application and the plugin.

//Interface that both application and plugin assembly needs to know.
[InheritedExport(typeof(IAutomationPlugin))]
public interface IAutomationPlugin
{
    string Name { get; }
    void DoPluginStuff();
}

Reference and implement the interface in an assembly. Do not reference the application.

//The plugin functionality that resides in the plugin assembly that is loaded by MEF
public class Executer : IAutomationPlugin
{
    private const string _name = "SomePluginName";

    public string Name
    {
        get { return _name; }
    }

    public void DoPluginStuff()
    {
        //Do plugin stuff 
    }
}

Now create the application and reference the interface. 
After that you can add the functionality for loading the plugin assemblies into memory. 
When doing this it is a good idea to check so that you do not load all .dll files in the folder into memory. 
But i leave that up to you.

public static AggregateCatalog LoadPluginsToMemory(string pluginPath)
{
    if (!Directory.Exists(pluginPath))
    {
        return null;
    }

    var files = Directory.GetFiles(engine.PluginPath, "*.dll");
    var aggregateCatalog = new AggregateCatalog();

    foreach (var file in files)
    {
        try
        {
            var ms = new MemoryStream();
            var fs = new FileStream(file, FileMode.Open, FileAccess.Read);
            var bytes = new byte[fs.Length];
            fs.Read(bytes, 0, (int) fs.Length);
            ms.Write(bytes, 0, (int) fs.Length);
            fs.Close();
            ms.Close();
            var assemblyCatalog = new AssemblyCatalog(Assembly.Load (ms.ToArray ()));
            aggregateCatalog.Catalogs.Add(assemblyCatalog);
        }
        catch(Exception)
        {
            throw;
        }
    }
    return aggregateCatalog;
}

Once you have this, reloading plugins is simple. 
I went with a cycle plugins that dumps all plugins and loads the plugins that are in the plugin folder. 
This way to remove a plugin i only needed to delete the assembly file and cycle plugins.

public void CyclePlugins()
{
    //Plugins is a List<IAutomationPlugin> so to remove you just clear the list 
    Plugins.Clear();

    ImportPlugins();
}

End notes. 
As I said from the beginning, this may not be the best way and there are some things you need to be cautious of. One of those things has to do with memory concerns. But all the concerns there may be I leave up to you. As it is better if you check all the aspects your self, so that you know all the aspects and ramifications of doing this implementation.

Log Analytics chart with labels and all using summarize and by

To create a chart showing requests and the average duration of requests, grouping the results per second based on the timestamp. This is how i did it…

requests
| where timestamp > datetime(2018-11-16T16:00:00+1)
| where name contains"GetData"
| order by timestamp desc
| summarize RequestsPerSec = count(), AvgReqDurationPerSec = avg(duration/1000) by bin(timestamp, 1s)
| render areachart kind=stacked

So the first four lines are pretty self-explanatory.
Lets have a look at the line that starts with summarize.
The RequestPerSec is the name of the column where we store the count of rows. If we had not given it that name, it would have defaulted to count_.
The AvgReqDurationPerSec holds the average duration in seconds (defaulted to avg_). As the duration is in milliseconds we therefor devide it by 1000 to get it in seconds. We then use the by bin(timestamp, 1s) to group it in seconds using the timestamp.
To end it of we tell Log Analytics to render  the table as a stacked area-chart.

A fist-bump and a hug

The following story may sound like a puff-piece, but I assure you, it is not meant to be one.

I had just traveled 5 hours and was walking into the hotel where me and my colleagues were staying for the conference.
Hitting the lobby I see one of the founders of the firm I work for and beside him the CEO.
Walking up to them, they both smile. The co-founder opens his arms and gives me a hug that I accept awkwardly. The CEO fist-bumps me and we talk a bit.

Looking back at how awkward the hug and fist-bump was I stop to think why?

The only reason they were awkward was that it had never happened to me before. That someone in a high position, within a company that I was working for, ignored the divide between worker and boss. It was awkward but made me feel welcome by being genuinely natural and open.
Now you are probably thinking, so what, why should I care, it is not important.
But for me this is an example of saying you care and showing you care, leading by example. This carries on to management further down the chain and they also behave in the same way. All managers in the company, that I have been in contact with, have shown that they genuinely care.

But what is so important about that?
Our company wants the employee’s to feel comfortable, relaxed and safe. Safe to talk about the good and the bad, to be open. Safe to make mistakes. Safe to develop their craft. The type of safety you get in a family. Without judgement or being discouraged. Because that way a person can grow so much more. Become what they strive for. The best they can be.

So this is not a puff-piece? -You say…
Nope! What I am trying to point out is a fundamental way of running a company. Especially a tech-consultancy company. A way to get the best out of your employees. The hug and the fist-bump is just small details. But they show the natural commitment to the company way of being.
And that is the important part!
I have worked at many different firms, and this is not about them being bad, because they weren’t! It’s about what I feel is the best way of running this type of company when it comes to the relationship between managers and employees. Building trust and understanding.

The Journey Begins

Thanks for joining me!

Let’s keep this as a first blog post, the day I created this blog…

This is a place for me, to keep my stupid stuff and thoughts.
The nullable.
If you like it great 🙂

Good company in a journey makes the way seem shorter. — Izaak Walton

post