tools/code/publisher/ApiPolicy.cs (211 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 PutApiPolicies(CancellationToken cancellationToken); public delegate Option<(ApiPolicyName Name, ApiName ApiName)> TryParseApiPolicyName(FileInfo file); public delegate bool IsApiPolicyNameInSourceControl(ApiPolicyName name, ApiName apiName); public delegate ValueTask PutApiPolicy(ApiPolicyName name, ApiName apiName, CancellationToken cancellationToken); public delegate ValueTask<Option<ApiPolicyDto>> FindApiPolicyDto(ApiPolicyName name, ApiName apiName, CancellationToken cancellationToken); public delegate ValueTask PutApiPolicyInApim(ApiPolicyName name, ApiPolicyDto dto, ApiName apiName, CancellationToken cancellationToken); public delegate ValueTask DeleteApiPolicies(CancellationToken cancellationToken); public delegate ValueTask DeleteApiPolicy(ApiPolicyName name, ApiName apiName, CancellationToken cancellationToken); public delegate ValueTask DeleteApiPolicyFromApim(ApiPolicyName name, ApiName apiName, CancellationToken cancellationToken); internal static class ApiPolicyModule { public static void ConfigurePutApiPolicies(IHostApplicationBuilder builder) { CommonModule.ConfigureGetPublisherFiles(builder); ConfigureTryParseApiPolicyName(builder); ConfigureIsApiPolicyNameInSourceControl(builder); ConfigurePutApiPolicy(builder); builder.Services.TryAddSingleton(GetPutApiPolicies); } private static PutApiPolicies GetPutApiPolicies(IServiceProvider provider) { var getPublisherFiles = provider.GetRequiredService<GetPublisherFiles>(); var tryParseName = provider.GetRequiredService<TryParseApiPolicyName>(); var isNameInSourceControl = provider.GetRequiredService<IsApiPolicyNameInSourceControl>(); var put = provider.GetRequiredService<PutApiPolicy>(); var activitySource = provider.GetRequiredService<ActivitySource>(); var logger = provider.GetRequiredService<ILogger>(); return async cancellationToken => { using var _ = activitySource.StartActivity(nameof(PutApiPolicies)); logger.LogInformation("Putting API policies..."); await getPublisherFiles() .Choose(tryParseName.Invoke) .Where(policy => isNameInSourceControl(policy.Name, policy.ApiName)) .Distinct() .IterParallel(put.Invoke, cancellationToken); }; } private static void ConfigureTryParseApiPolicyName(IHostApplicationBuilder builder) { AzureModule.ConfigureManagementServiceDirectory(builder); builder.Services.TryAddSingleton(GetTryParseApiPolicyName); } private static TryParseApiPolicyName GetTryParseApiPolicyName(IServiceProvider provider) { var serviceDirectory = provider.GetRequiredService<ManagementServiceDirectory>(); return file => from policyFile in ApiPolicyFile.TryParse(file, serviceDirectory) select (policyFile.Name, policyFile.Parent.Name); } private static void ConfigureIsApiPolicyNameInSourceControl(IHostApplicationBuilder builder) { CommonModule.ConfigureGetArtifactFiles(builder); AzureModule.ConfigureManagementServiceDirectory(builder); builder.Services.TryAddSingleton(GetIsApiPolicyNameInSourceControl); } private static IsApiPolicyNameInSourceControl GetIsApiPolicyNameInSourceControl(IServiceProvider provider) { var getArtifactFiles = provider.GetRequiredService<GetArtifactFiles>(); var serviceDirectory = provider.GetRequiredService<ManagementServiceDirectory>(); return doesPolicyFileExist; bool doesPolicyFileExist(ApiPolicyName name, ApiName apiName) { var artifactFiles = getArtifactFiles(); var policyFile = ApiPolicyFile.From(name, apiName, serviceDirectory); return artifactFiles.Contains(policyFile.ToFileInfo()); } } private static void ConfigurePutApiPolicy(IHostApplicationBuilder builder) { ConfigureFindApiPolicyDto(builder); ConfigurePutApiPolicyInApim(builder); builder.Services.TryAddSingleton(GetPutApiPolicy); } private static PutApiPolicy GetPutApiPolicy(IServiceProvider provider) { var findDto = provider.GetRequiredService<FindApiPolicyDto>(); var putInApim = provider.GetRequiredService<PutApiPolicyInApim>(); var activitySource = provider.GetRequiredService<ActivitySource>(); return async (name, apiName, cancellationToken) => { using var _ = activitySource.StartActivity(nameof(PutApiPolicy)) ?.AddTag("api_policy.name", name) ?.AddTag("api.name", apiName); var dtoOption = await findDto(name, apiName, cancellationToken); await dtoOption.IterTask(async dto => await putInApim(name, dto, apiName, cancellationToken)); }; } private static void ConfigureFindApiPolicyDto(IHostApplicationBuilder builder) { AzureModule.ConfigureManagementServiceDirectory(builder); CommonModule.ConfigureTryGetFileContents(builder); builder.Services.TryAddSingleton(GetFindApiPolicyDto); } private static FindApiPolicyDto GetFindApiPolicyDto(IServiceProvider provider) { var serviceDirectory = provider.GetRequiredService<ManagementServiceDirectory>(); var tryGetFileContents = provider.GetRequiredService<TryGetFileContents>(); return async (name, apiName, cancellationToken) => { var contentsOption = await tryGetPolicyContents(name, apiName, cancellationToken); return from contents in contentsOption select new ApiPolicyDto { Properties = new ApiPolicyDto.ApiPolicyContract { Format = "rawxml", Value = contents.ToString() } }; }; async ValueTask<Option<BinaryData>> tryGetPolicyContents(ApiPolicyName name, ApiName apiName, CancellationToken cancellationToken) { var policyFile = ApiPolicyFile.From(name, apiName, serviceDirectory); return await tryGetFileContents(policyFile.ToFileInfo(), cancellationToken); } } private static void ConfigurePutApiPolicyInApim(IHostApplicationBuilder builder) { AzureModule.ConfigureManagementServiceUri(builder); AzureModule.ConfigureHttpPipeline(builder); builder.Services.TryAddSingleton(GetPutApiPolicyInApim); } private static PutApiPolicyInApim GetPutApiPolicyInApim(IServiceProvider provider) { var serviceUri = provider.GetRequiredService<ManagementServiceUri>(); var pipeline = provider.GetRequiredService<HttpPipeline>(); var logger = provider.GetRequiredService<ILogger>(); return async (name, dto, apiName, cancellationToken) => { logger.LogInformation("Putting policy {ApiPolicyName} for API {ApiName}...", name, apiName); await ApiPolicyUri.From(name, apiName, serviceUri) .PutDto(dto, pipeline, cancellationToken); }; } public static void ConfigureDeleteApiPolicies(IHostApplicationBuilder builder) { CommonModule.ConfigureGetPublisherFiles(builder); ConfigureTryParseApiPolicyName(builder); ConfigureIsApiPolicyNameInSourceControl(builder); ConfigureDeleteApiPolicy(builder); builder.Services.TryAddSingleton(GetDeleteApiPolicies); } private static DeleteApiPolicies GetDeleteApiPolicies(IServiceProvider provider) { var getPublisherFiles = provider.GetRequiredService<GetPublisherFiles>(); var tryParseName = provider.GetRequiredService<TryParseApiPolicyName>(); var isNameInSourceControl = provider.GetRequiredService<IsApiPolicyNameInSourceControl>(); var delete = provider.GetRequiredService<DeleteApiPolicy>(); var activitySource = provider.GetRequiredService<ActivitySource>(); var logger = provider.GetRequiredService<ILogger>(); return async cancellationToken => { using var _ = activitySource.StartActivity(nameof(DeleteApiPolicies)); logger.LogInformation("Deleting API policies..."); await getPublisherFiles() .Choose(tryParseName.Invoke) .Where(policy => isNameInSourceControl(policy.Name, policy.ApiName) is false) .Distinct() .IterParallel(delete.Invoke, cancellationToken); }; } private static void ConfigureDeleteApiPolicy(IHostApplicationBuilder builder) { ConfigureDeleteApiPolicyFromApim(builder); builder.Services.TryAddSingleton(GetDeleteApiPolicy); } private static DeleteApiPolicy GetDeleteApiPolicy(IServiceProvider provider) { var deleteFromApim = provider.GetRequiredService<DeleteApiPolicyFromApim>(); var activitySource = provider.GetRequiredService<ActivitySource>(); return async (name, apiName, cancellationToken) => { using var _ = activitySource.StartActivity(nameof(DeleteApiPolicy)) ?.AddTag("api_policy.name", name) ?.AddTag("api.name", apiName); await deleteFromApim(name, apiName, cancellationToken); }; } private static void ConfigureDeleteApiPolicyFromApim(IHostApplicationBuilder builder) { AzureModule.ConfigureManagementServiceUri(builder); AzureModule.ConfigureHttpPipeline(builder); builder.Services.TryAddSingleton(GetDeleteApiPolicyFromApim); } private static DeleteApiPolicyFromApim GetDeleteApiPolicyFromApim(IServiceProvider provider) { var serviceUri = provider.GetRequiredService<ManagementServiceUri>(); var pipeline = provider.GetRequiredService<HttpPipeline>(); var logger = provider.GetRequiredService<ILogger>(); return async (name, apiName, cancellationToken) => { logger.LogInformation("Deleting policy {ApiPolicyName} from API {ApiName}...", name, apiName); await ApiPolicyUri.From(name, apiName, serviceUri) .Delete(pipeline, cancellationToken); }; } }