tools/code/publisher/ApiTag.cs (200 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 PutApiTags(CancellationToken cancellationToken); public delegate Option<(TagName Name, ApiName ApiName)> TryParseApiTagName(FileInfo file); public delegate bool IsApiTagNameInSourceControl(TagName name, ApiName apiName); public delegate ValueTask PutApiTag(TagName name, ApiName apiName, CancellationToken cancellationToken); public delegate ValueTask<Option<ApiTagDto>> FindApiTagDto(TagName name, ApiName apiName, CancellationToken cancellationToken); public delegate ValueTask PutApiTagInApim(TagName name, ApiTagDto dto, ApiName apiName, CancellationToken cancellationToken); public delegate ValueTask DeleteApiTags(CancellationToken cancellationToken); public delegate ValueTask DeleteApiTag(TagName name, ApiName apiName, CancellationToken cancellationToken); public delegate ValueTask DeleteApiTagFromApim(TagName name, ApiName apiName, CancellationToken cancellationToken); internal static class ApiTagModule { public static void ConfigurePutApiTags(IHostApplicationBuilder builder) { CommonModule.ConfigureGetPublisherFiles(builder); ConfigureTryApiParseTagName(builder); ConfigureIsApiTagNameInSourceControl(builder); ConfigurePutApiTag(builder); builder.Services.TryAddSingleton(GetPutApiTags); } private static PutApiTags GetPutApiTags(IServiceProvider provider) { var getPublisherFiles = provider.GetRequiredService<GetPublisherFiles>(); var tryParseName = provider.GetRequiredService<TryParseApiTagName>(); var isNameInSourceControl = provider.GetRequiredService<IsApiTagNameInSourceControl>(); var put = provider.GetRequiredService<PutApiTag>(); var activitySource = provider.GetRequiredService<ActivitySource>(); var logger = provider.GetRequiredService<ILogger>(); return async cancellationToken => { using var _ = activitySource.StartActivity(nameof(PutApiTags)); logger.LogInformation("Putting API tags..."); await getPublisherFiles() .Choose(tryParseName.Invoke) .Where(tag => isNameInSourceControl(tag.Name, tag.ApiName)) .Distinct() .IterParallel(put.Invoke, cancellationToken); }; } private static void ConfigureTryApiParseTagName(IHostApplicationBuilder builder) { AzureModule.ConfigureManagementServiceDirectory(builder); builder.Services.TryAddSingleton(GetTryParseApiTagName); } private static TryParseApiTagName GetTryParseApiTagName(IServiceProvider provider) { var serviceDirectory = provider.GetRequiredService<ManagementServiceDirectory>(); return file => from informationFile in ApiTagInformationFile.TryParse(file, serviceDirectory) select (informationFile.Parent.Name, informationFile.Parent.Parent.Parent.Name); } private static void ConfigureIsApiTagNameInSourceControl(IHostApplicationBuilder builder) { CommonModule.ConfigureGetArtifactFiles(builder); AzureModule.ConfigureManagementServiceDirectory(builder); builder.Services.TryAddSingleton(GetIsTagNameInSourceControl); } private static IsApiTagNameInSourceControl GetIsTagNameInSourceControl(IServiceProvider provider) { var getArtifactFiles = provider.GetRequiredService<GetArtifactFiles>(); var serviceDirectory = provider.GetRequiredService<ManagementServiceDirectory>(); return doesInformationFileExist; bool doesInformationFileExist(TagName name, ApiName apiName) { var artifactFiles = getArtifactFiles(); var tagFile = ApiTagInformationFile.From(name, apiName, serviceDirectory); return artifactFiles.Contains(tagFile.ToFileInfo()); } } private static void ConfigurePutApiTag(IHostApplicationBuilder builder) { ConfigureFindApiTagDto(builder); ConfigurePutApiTagInApim(builder); builder.Services.TryAddSingleton(GetPutApiTag); } private static PutApiTag GetPutApiTag(IServiceProvider provider) { var findDto = provider.GetRequiredService<FindApiTagDto>(); var putInApim = provider.GetRequiredService<PutApiTagInApim>(); var activitySource = provider.GetRequiredService<ActivitySource>(); return async (name, apiName, cancellationToken) => { using var _ = activitySource.StartActivity(nameof(PutApiTag)) ?.AddTag("api_tag.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 ConfigureFindApiTagDto(IHostApplicationBuilder builder) { AzureModule.ConfigureManagementServiceDirectory(builder); CommonModule.ConfigureTryGetFileContents(builder); builder.Services.TryAddSingleton(GetFindApiTagDto); } private static FindApiTagDto GetFindApiTagDto(IServiceProvider provider) { var serviceDirectory = provider.GetRequiredService<ManagementServiceDirectory>(); var tryGetFileContents = provider.GetRequiredService<TryGetFileContents>(); return async (name, apiName, cancellationToken) => { var informationFile = ApiTagInformationFile.From(name, apiName, serviceDirectory); var contentsOption = await tryGetFileContents(informationFile.ToFileInfo(), cancellationToken); return from contents in contentsOption select contents.ToObjectFromJson<ApiTagDto>(); }; } private static void ConfigurePutApiTagInApim(IHostApplicationBuilder builder) { AzureModule.ConfigureManagementServiceUri(builder); AzureModule.ConfigureHttpPipeline(builder); builder.Services.TryAddSingleton(GetPutApiTagInApim); } private static PutApiTagInApim GetPutApiTagInApim(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("Adding tag {TagName} to API {ApiName}...", name, apiName); await ApiTagUri.From(name, apiName, serviceUri) .PutDto(dto, pipeline, cancellationToken); }; } public static void ConfigureDeleteApiTags(IHostApplicationBuilder builder) { CommonModule.ConfigureGetPublisherFiles(builder); ConfigureTryApiParseTagName(builder); ConfigureIsApiTagNameInSourceControl(builder); ConfigureDeleteApiTag(builder); builder.Services.TryAddSingleton(GetDeleteApiTags); } private static DeleteApiTags GetDeleteApiTags(IServiceProvider provider) { var getPublisherFiles = provider.GetRequiredService<GetPublisherFiles>(); var tryParseName = provider.GetRequiredService<TryParseApiTagName>(); var isNameInSourceControl = provider.GetRequiredService<IsApiTagNameInSourceControl>(); var delete = provider.GetRequiredService<DeleteApiTag>(); var activitySource = provider.GetRequiredService<ActivitySource>(); var logger = provider.GetRequiredService<ILogger>(); return async cancellationToken => { using var _ = activitySource.StartActivity(nameof(DeleteApiTags)); logger.LogInformation("Deleting API tags..."); await getPublisherFiles() .Choose(tryParseName.Invoke) .Where(tag => isNameInSourceControl(tag.Name, tag.ApiName) is false) .Distinct() .IterParallel(delete.Invoke, cancellationToken); }; } private static void ConfigureDeleteApiTag(IHostApplicationBuilder builder) { ConfigureDeleteApiTagFromApim(builder); builder.Services.TryAddSingleton(GetDeleteApiTag); } private static DeleteApiTag GetDeleteApiTag(IServiceProvider provider) { var deleteFromApim = provider.GetRequiredService<DeleteApiTagFromApim>(); var activitySource = provider.GetRequiredService<ActivitySource>(); return async (name, apiName, cancellationToken) => { using var _ = activitySource.StartActivity(nameof(DeleteApiTag)) ?.AddTag("api_tag.name", name) ?.AddTag("api.name", apiName); await deleteFromApim(name, apiName, cancellationToken); }; } private static void ConfigureDeleteApiTagFromApim(IHostApplicationBuilder builder) { AzureModule.ConfigureManagementServiceUri(builder); AzureModule.ConfigureHttpPipeline(builder); builder.Services.TryAddSingleton(GetDeleteApiTagFromApim); } private static DeleteApiTagFromApim GetDeleteApiTagFromApim(IServiceProvider provider) { var serviceUri = provider.GetRequiredService<ManagementServiceUri>(); var pipeline = provider.GetRequiredService<HttpPipeline>(); var logger = provider.GetRequiredService<ILogger>(); return async (name, apiName, cancellationToken) => { logger.LogInformation("Removing tag {TagName} from API {ApiName}...", name, apiName); await ApiTagUri.From(name, apiName, serviceUri) .Delete(pipeline, cancellationToken); }; } }