Skip to content

Commit

Permalink
Allow operations control client to be configured via a callback (#153)
Browse files Browse the repository at this point in the history
* Add new options class and provide a callback to retrieve it, rather than requiring config to be provided immediately.

* Exception message tweak.

* Use string.IsNullOrEmpty rather than a simple null check to cater for configuration where the resource Id has been left as an empty string.
  • Loading branch information
jongeorge1 authored Aug 7, 2020
1 parent a39f7d0 commit ad6a121
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 43 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// <copyright file="OperationsControlClientServiceCollectionExtensions.cs" company="Endjin Limited">
// Copyright (c) Endjin Limited. All rights reserved.
// </copyright>

namespace Marain.Operations.Client.OperationsControl
{
using System;

/// <summary>
/// Settings for configuring the <see cref="MarainOperationsControl"/> service.
/// </summary>
public class MarainOperationsControlClientOptions
{
/// <summary>
/// Gets or sets the base URL of the operations control service.
/// </summary>
public Uri OperationsControlServiceBaseUri { get; set; }

/// <summary>
/// Gets or sets the resource ID to use when asking the Managed Identity system for a token with which to
/// communicate with the service. This is typically the App ID of the application created for securing access
/// to the operations control service.
/// </summary>
/// <remarks>
/// If this is null, no attempt will be made to secure communication with the operations control
/// service. This may be appropriate for local development scenarios.
/// </remarks>
public string ResourceIdForMsiAuthentication { get; set; }
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// <copyright file="OperationsControlClientServiceCollectionExtensions.cs" company="Endjin Limited">
// Copyright (c) Endjin Limited. All rights reserved.
// </copyright>

namespace Microsoft.Extensions.DependencyInjection
{
using System;
using Corvus.Identity.ManagedServiceIdentity.ClientAuthentication;
using Marain.Operations.Client.OperationsControl;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Rest;

/// <summary>
/// DI initialization for clients of the Operations control service.
/// </summary>
public static class OperationsControlClientServiceCollectionExtensions
{
/// <summary>
/// Adds the Operations control client to a service collection.
/// </summary>
/// <param name="services">The service collection.</param>
/// <param name="getOptions">A callback that can be used to retrieve options for the client.</param>
/// <returns>The modified service collection.</returns>
public static IServiceCollection AddOperationsControlClient(
this IServiceCollection services,
Func<IServiceProvider, MarainOperationsControlClientOptions> getOptions)
{
services.AddSingleton(sp =>
{
MarainOperationsControlClientOptions options = getOptions(sp);

if (options is null || options.OperationsControlServiceBaseUri == null)
{
throw new InvalidOperationException(
$"Cannot instantiate the Operations Control client without supplying a value for {nameof(MarainOperationsControlClientOptions.OperationsControlServiceBaseUri)}.");
}

return BuildOperationsControlClient(sp, options.OperationsControlServiceBaseUri, options.ResourceIdForMsiAuthentication);
});

return services;
}

/// <summary>
/// Adds the Operations control client to a service collection.
/// </summary>
/// <param name="services">The service collection.</param>
/// <param name="options">Options for the client.</param>
/// <returns>The modified service collection.</returns>
public static IServiceCollection AddOperationsControlClient(
this IServiceCollection services,
MarainOperationsControlClientOptions options)
{
return services.AddOperationsControlClient(_ => options);
}

/// <summary>
/// Adds the Operations control client to a service collection.
/// </summary>
/// <param name="baseUri">The base URI of the Operations control service.</param>
/// <param name="resourceIdForMsiAuthentication">
/// The resource id to use when obtaining an authentication token representing the
/// hosting service's identity. Pass null to run without authentication.
/// </param>
/// <returns>The modified service collection.</returns>
private static IMarainOperationsControl BuildOperationsControlClient(
IServiceProvider serviceProvider,
Uri baseUri,
string resourceIdForMsiAuthentication = null)
{
return string.IsNullOrEmpty(resourceIdForMsiAuthentication)
? new UnauthenticatedMarainOperationsControl(baseUri)
: new MarainOperationsControl(
baseUri,
new TokenCredentials(
new ServiceIdentityTokenProvider(
serviceProvider.GetRequiredService<IServiceIdentityTokenSource>(),
resourceIdForMsiAuthentication)));
}
}
}

0 comments on commit ad6a121

Please sign in to comment.