tools/code/publisher/ApiOperationPolicy.cs (213 lines of code) (raw):
using Azure.Core.Pipeline;
using common;
using LanguageExt;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace publisher;
public delegate ValueTask PutApiOperationPolicies(CancellationToken cancellationToken);
public delegate Option<(ApiOperationPolicyName Name, ApiOperationName OperationName, ApiName ApiName)> TryParseApiOperationPolicyName(FileInfo file);
public delegate bool IsApiOperationPolicyNameInSourceControl(ApiOperationPolicyName name, ApiOperationName operationName, ApiName apiName);
public delegate ValueTask PutApiOperationPolicy(ApiOperationPolicyName name, ApiOperationName operationName, ApiName apiName, CancellationToken cancellationToken);
public delegate ValueTask<Option<ApiOperationPolicyDto>> FindApiOperationPolicyDto(ApiOperationPolicyName name, ApiOperationName operationName, ApiName apiName, CancellationToken cancellationToken);
public delegate ValueTask PutApiOperationPolicyInApim(ApiOperationPolicyName name, ApiOperationPolicyDto dto, ApiOperationName operationName, ApiName apiName, CancellationToken cancellationToken);
public delegate ValueTask DeleteApiOperationPolicies(CancellationToken cancellationToken);
public delegate ValueTask DeleteApiOperationPolicy(ApiOperationPolicyName name, ApiOperationName operationName, ApiName apiName, CancellationToken cancellationToken);
public delegate ValueTask DeleteApiOperationPolicyFromApim(ApiOperationPolicyName name, ApiOperationName operationName, ApiName apiName, CancellationToken cancellationToken);
internal static class ApiOperationPolicyModule
{
public static void ConfigurePutApiOperationPolicies(IHostApplicationBuilder builder)
{
CommonModule.ConfigureGetPublisherFiles(builder);
ConfigureTryParseApiOperationPolicyName(builder);
ConfigureIsApiOperationPolicyNameInSourceControl(builder);
ConfigurePutApiOperationPolicy(builder);
builder.Services.TryAddSingleton(GetPutApiOperationPolicies);
}
private static PutApiOperationPolicies GetPutApiOperationPolicies(IServiceProvider provider)
{
var getPublisherFiles = provider.GetRequiredService<GetPublisherFiles>();
var tryParseName = provider.GetRequiredService<TryParseApiOperationPolicyName>();
var isNameInSourceControl = provider.GetRequiredService<IsApiOperationPolicyNameInSourceControl>();
var put = provider.GetRequiredService<PutApiOperationPolicy>();
var activitySource = provider.GetRequiredService<ActivitySource>();
var logger = provider.GetRequiredService<ILogger>();
return async cancellationToken =>
{
using var _ = activitySource.StartActivity(nameof(PutApiOperationPolicies));
logger.LogInformation("Putting API policies...");
await getPublisherFiles()
.Choose(tryParseName.Invoke)
.Where(policy => isNameInSourceControl(policy.Name, policy.OperationName, policy.ApiName))
.Distinct()
.IterParallel(async policy => await put(policy.Name, policy.OperationName, policy.ApiName, cancellationToken), cancellationToken);
};
}
private static void ConfigureTryParseApiOperationPolicyName(IHostApplicationBuilder builder)
{
AzureModule.ConfigureManagementServiceDirectory(builder);
builder.Services.TryAddSingleton(GetTryParseApiOperationPolicyName);
}
private static TryParseApiOperationPolicyName GetTryParseApiOperationPolicyName(IServiceProvider provider)
{
var serviceDirectory = provider.GetRequiredService<ManagementServiceDirectory>();
return file => from policyFile in ApiOperationPolicyFile.TryParse(file, serviceDirectory)
select (policyFile.Name, policyFile.Parent.Name, policyFile.Parent.Parent.Parent.Name);
}
private static void ConfigureIsApiOperationPolicyNameInSourceControl(IHostApplicationBuilder builder)
{
CommonModule.ConfigureGetArtifactFiles(builder);
AzureModule.ConfigureManagementServiceDirectory(builder);
builder.Services.TryAddSingleton(GetIsApiOperationPolicyNameInSourceControl);
}
private static IsApiOperationPolicyNameInSourceControl GetIsApiOperationPolicyNameInSourceControl(IServiceProvider provider)
{
var getArtifactFiles = provider.GetRequiredService<GetArtifactFiles>();
var serviceDirectory = provider.GetRequiredService<ManagementServiceDirectory>();
return doesPolicyFileExist;
bool doesPolicyFileExist(ApiOperationPolicyName name, ApiOperationName operationName, ApiName apiName)
{
var artifactFiles = getArtifactFiles();
var policyFile = ApiOperationPolicyFile.From(name, operationName, apiName, serviceDirectory);
return artifactFiles.Contains(policyFile.ToFileInfo());
}
}
private static void ConfigurePutApiOperationPolicy(IHostApplicationBuilder builder)
{
ConfigureFindApiOperationPolicyDto(builder);
ConfigurePutApiOperationPolicyInApim(builder);
builder.Services.TryAddSingleton(GetPutApiOperationPolicy);
}
private static PutApiOperationPolicy GetPutApiOperationPolicy(IServiceProvider provider)
{
var findDto = provider.GetRequiredService<FindApiOperationPolicyDto>();
var putInApim = provider.GetRequiredService<PutApiOperationPolicyInApim>();
var activitySource = provider.GetRequiredService<ActivitySource>();
return async (name, operationName, apiName, cancellationToken) =>
{
using var _ = activitySource.StartActivity(nameof(PutApiOperationPolicy))
?.AddTag("api_policy.name", name)
?.AddTag("api_operation.name", operationName)
?.AddTag("api.name", apiName);
var dtoOption = await findDto(name, operationName, apiName, cancellationToken);
await dtoOption.IterTask(async dto => await putInApim(name, dto, operationName, apiName, cancellationToken));
};
}
private static void ConfigureFindApiOperationPolicyDto(IHostApplicationBuilder builder)
{
AzureModule.ConfigureManagementServiceDirectory(builder);
CommonModule.ConfigureTryGetFileContents(builder);
builder.Services.TryAddSingleton(GetFindApiOperationPolicyDto);
}
private static FindApiOperationPolicyDto GetFindApiOperationPolicyDto(IServiceProvider provider)
{
var serviceDirectory = provider.GetRequiredService<ManagementServiceDirectory>();
var tryGetFileContents = provider.GetRequiredService<TryGetFileContents>();
return async (name, operationName, apiName, cancellationToken) =>
{
var contentsOption = await tryGetPolicyContents(name, operationName, apiName, cancellationToken);
return from contents in contentsOption
select new ApiOperationPolicyDto
{
Properties = new ApiOperationPolicyDto.ApiOperationPolicyContract
{
Format = "rawxml",
Value = contents.ToString()
}
};
};
async ValueTask<Option<BinaryData>> tryGetPolicyContents(ApiOperationPolicyName name, ApiOperationName operationName, ApiName apiName, CancellationToken cancellationToken)
{
var policyFile = ApiOperationPolicyFile.From(name, operationName, apiName, serviceDirectory);
return await tryGetFileContents(policyFile.ToFileInfo(), cancellationToken);
}
}
private static void ConfigurePutApiOperationPolicyInApim(IHostApplicationBuilder builder)
{
AzureModule.ConfigureManagementServiceUri(builder);
AzureModule.ConfigureHttpPipeline(builder);
builder.Services.TryAddSingleton(GetPutApiOperationPolicyInApim);
}
private static PutApiOperationPolicyInApim GetPutApiOperationPolicyInApim(IServiceProvider provider)
{
var serviceUri = provider.GetRequiredService<ManagementServiceUri>();
var pipeline = provider.GetRequiredService<HttpPipeline>();
var logger = provider.GetRequiredService<ILogger>();
return async (name, dto, operationName, apiName, cancellationToken) =>
{
logger.LogInformation("Putting policy {ApiOperationPolicyName} for operation {ApiOperationName} in API {ApiName}...", name, operationName, apiName);
await ApiOperationPolicyUri.From(name, operationName, apiName, serviceUri)
.PutDto(dto, pipeline, cancellationToken);
};
}
public static void ConfigureDeleteApiOperationPolicies(IHostApplicationBuilder builder)
{
CommonModule.ConfigureGetPublisherFiles(builder);
ConfigureTryParseApiOperationPolicyName(builder);
ConfigureIsApiOperationPolicyNameInSourceControl(builder);
ConfigureDeleteApiOperationPolicy(builder);
builder.Services.TryAddSingleton(GetDeleteApiOperationPolicies);
}
private static DeleteApiOperationPolicies GetDeleteApiOperationPolicies(IServiceProvider provider)
{
var getPublisherFiles = provider.GetRequiredService<GetPublisherFiles>();
var tryParseName = provider.GetRequiredService<TryParseApiOperationPolicyName>();
var isNameInSourceControl = provider.GetRequiredService<IsApiOperationPolicyNameInSourceControl>();
var delete = provider.GetRequiredService<DeleteApiOperationPolicy>();
var activitySource = provider.GetRequiredService<ActivitySource>();
var logger = provider.GetRequiredService<ILogger>();
return async cancellationToken =>
{
using var _ = activitySource.StartActivity(nameof(DeleteApiOperationPolicies));
logger.LogInformation("Deleting API policies...");
await getPublisherFiles()
.Choose(tryParseName.Invoke)
.Where(policy => isNameInSourceControl(policy.Name, policy.OperationName, policy.ApiName) is false)
.Distinct()
.IterParallel(async policy => await delete(policy.Name, policy.OperationName, policy.ApiName, cancellationToken), cancellationToken);
};
}
private static void ConfigureDeleteApiOperationPolicy(IHostApplicationBuilder builder)
{
ConfigureDeleteApiOperationPolicyFromApim(builder);
builder.Services.TryAddSingleton(GetDeleteApiOperationPolicy);
}
private static DeleteApiOperationPolicy GetDeleteApiOperationPolicy(IServiceProvider provider)
{
var deleteFromApim = provider.GetRequiredService<DeleteApiOperationPolicyFromApim>();
var activitySource = provider.GetRequiredService<ActivitySource>();
return async (name, operationName, apiName, cancellationToken) =>
{
using var _ = activitySource.StartActivity(nameof(DeleteApiOperationPolicy))
?.AddTag("api_policy.name", name)
?.AddTag("api_operation.name", operationName)
?.AddTag("api.name", apiName);
await deleteFromApim(name, operationName, apiName, cancellationToken);
};
}
private static void ConfigureDeleteApiOperationPolicyFromApim(IHostApplicationBuilder builder)
{
AzureModule.ConfigureManagementServiceUri(builder);
AzureModule.ConfigureHttpPipeline(builder);
builder.Services.TryAddSingleton(GetDeleteApiOperationPolicyFromApim);
}
private static DeleteApiOperationPolicyFromApim GetDeleteApiOperationPolicyFromApim(IServiceProvider provider)
{
var serviceUri = provider.GetRequiredService<ManagementServiceUri>();
var pipeline = provider.GetRequiredService<HttpPipeline>();
var logger = provider.GetRequiredService<ILogger>();
return async (name, operationName, apiName, cancellationToken) =>
{
logger.LogInformation("Deleting policy {ApiOperationPolicyName} from operation {ApiOperationName} in API {Apiname}...", name, operationName, apiName);
await ApiOperationPolicyUri.From(name, operationName, apiName, serviceUri)
.Delete(pipeline, cancellationToken);
};
}
}