tools/code/extractor/Product.cs (115 lines of code) (raw):

using Azure.Core.Pipeline; using common; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace extractor; public delegate ValueTask ExtractProducts(CancellationToken cancellationToken); public delegate IAsyncEnumerable<(ProductName Name, ProductDto Dto)> ListProducts(CancellationToken cancellationToken); public delegate ValueTask WriteProductArtifacts(ProductName name, ProductDto dto, CancellationToken cancellationToken); public delegate ValueTask WriteProductInformationFile(ProductName name, ProductDto dto, CancellationToken cancellationToken); internal static class ProductModule { public static void ConfigureExtractProducts(IHostApplicationBuilder builder) { ConfigureListProducts(builder); ConfigureWriteProductArtifacts(builder); ProductPolicyModule.ConfigureExtractProductPolicies(builder); ProductGroupModule.ConfigureExtractProductGroups(builder); ProductTagModule.ConfigureExtractProductTags(builder); ProductApiModule.ConfigureExtractProductApis(builder); builder.Services.TryAddSingleton(GetExtractProducts); } private static ExtractProducts GetExtractProducts(IServiceProvider provider) { var list = provider.GetRequiredService<ListProducts>(); var writeArtifacts = provider.GetRequiredService<WriteProductArtifacts>(); var extractPolicies = provider.GetRequiredService<ExtractProductPolicies>(); var extractGroups = provider.GetRequiredService<ExtractProductGroups>(); var extractTags = provider.GetRequiredService<ExtractProductTags>(); var extractApis = provider.GetRequiredService<ExtractProductApis>(); var activitySource = provider.GetRequiredService<ActivitySource>(); var logger = provider.GetRequiredService<ILogger>(); return async cancellationToken => { using var _ = activitySource.StartActivity(nameof(ExtractProducts)); logger.LogInformation("Extracting products..."); await list(cancellationToken) .IterParallel(async resource => await extractProduct(resource.Name, resource.Dto, cancellationToken), cancellationToken); }; async ValueTask extractProduct(ProductName name, ProductDto dto, CancellationToken cancellationToken) { await writeArtifacts(name, dto, cancellationToken); await extractPolicies(name, cancellationToken); await extractGroups(name, cancellationToken); await extractTags(name, cancellationToken); await extractApis(name, cancellationToken); } } private static void ConfigureListProducts(IHostApplicationBuilder builder) { ConfigurationModule.ConfigureFindConfigurationNamesFactory(builder); AzureModule.ConfigureManagementServiceUri(builder); AzureModule.ConfigureHttpPipeline(builder); builder.Services.TryAddSingleton(GetListProducts); } private static ListProducts GetListProducts(IServiceProvider provider) { var findConfigurationNamesFactory = provider.GetRequiredService<FindConfigurationNamesFactory>(); var serviceUri = provider.GetRequiredService<ManagementServiceUri>(); var pipeline = provider.GetRequiredService<HttpPipeline>(); var findConfigurationNames = findConfigurationNamesFactory.Create<ProductName>(); return cancellationToken => findConfigurationNames() .Map(names => listFromSet(names, cancellationToken)) .IfNone(() => listAll(cancellationToken)); IAsyncEnumerable<(ProductName, ProductDto)> listFromSet(IEnumerable<ProductName> names, CancellationToken cancellationToken) => names.Select(name => ProductUri.From(name, serviceUri)) .ToAsyncEnumerable() .Choose(async uri => { var dtoOption = await uri.TryGetDto(pipeline, cancellationToken); return dtoOption.Map(dto => (uri.Name, dto)); }); IAsyncEnumerable<(ProductName, ProductDto)> listAll(CancellationToken cancellationToken) { var productsUri = ProductsUri.From(serviceUri); return productsUri.List(pipeline, cancellationToken); } } private static void ConfigureWriteProductArtifacts(IHostApplicationBuilder builder) { ConfigureWriteProductInformationFile(builder); builder.Services.TryAddSingleton(GetWriteProductArtifacts); } private static WriteProductArtifacts GetWriteProductArtifacts(IServiceProvider provider) { var writeInformationFile = provider.GetRequiredService<WriteProductInformationFile>(); return async (name, dto, cancellationToken) => await writeInformationFile(name, dto, cancellationToken); } private static void ConfigureWriteProductInformationFile(IHostApplicationBuilder builder) { AzureModule.ConfigureManagementServiceDirectory(builder); builder.Services.TryAddSingleton(GetWriteProductInformationFile); } private static WriteProductInformationFile GetWriteProductInformationFile(IServiceProvider provider) { var serviceDirectory = provider.GetRequiredService<ManagementServiceDirectory>(); var logger = provider.GetRequiredService<ILogger>(); return async (name, dto, cancellationToken) => { var informationFile = ProductInformationFile.From(name, serviceDirectory); logger.LogInformation("Writing product information file {ProductInformationFile}...", informationFile); await informationFile.WriteDto(dto, cancellationToken); }; } }