tools/code/extractor/Gateway.cs (113 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.Net; using System.Net.Http; using System.Threading; using System.Threading.Tasks; namespace extractor; public delegate ValueTask ExtractGateways(CancellationToken cancellationToken); public delegate IAsyncEnumerable<(GatewayName Name, GatewayDto Dto)> ListGateways(CancellationToken cancellationToken); public delegate ValueTask WriteGatewayArtifacts(GatewayName name, GatewayDto dto, CancellationToken cancellationToken); public delegate ValueTask WriteGatewayInformationFile(GatewayName name, GatewayDto dto, CancellationToken cancellationToken); internal static class GatewayModule { public static void ConfigureExtractGateways(IHostApplicationBuilder builder) { ConfigureListGateways(builder); ConfigureWriteGatewayArtifacts(builder); GatewayApiModule.ConfigureExtractGatewayApis(builder); builder.Services.TryAddSingleton(GetExtractGateways); } private static ExtractGateways GetExtractGateways(IServiceProvider provider) { var list = provider.GetRequiredService<ListGateways>(); var writeArtifacts = provider.GetRequiredService<WriteGatewayArtifacts>(); var extractGatewayApis = provider.GetRequiredService<ExtractGatewayApis>(); var activitySource = provider.GetRequiredService<ActivitySource>(); var logger = provider.GetRequiredService<ILogger>(); return async cancellationToken => { using var _ = activitySource.StartActivity(nameof(ExtractGateways)); logger.LogInformation("Extracting gateways..."); await list(cancellationToken) .IterParallel(async resource => await extractGateway(resource.Name, resource.Dto, cancellationToken), cancellationToken); }; async ValueTask extractGateway(GatewayName name, GatewayDto dto, CancellationToken cancellationToken) { await writeArtifacts(name, dto, cancellationToken); await extractGatewayApis(name, cancellationToken); } } private static void ConfigureListGateways(IHostApplicationBuilder builder) { ConfigurationModule.ConfigureFindConfigurationNamesFactory(builder); AzureModule.ConfigureManagementServiceUri(builder); AzureModule.ConfigureHttpPipeline(builder); builder.Services.TryAddSingleton(GetListGateways); } private static ListGateways GetListGateways(IServiceProvider provider) { var findConfigurationNamesFactory = provider.GetRequiredService<FindConfigurationNamesFactory>(); var serviceUri = provider.GetRequiredService<ManagementServiceUri>(); var pipeline = provider.GetRequiredService<HttpPipeline>(); var findConfigurationNames = findConfigurationNamesFactory.Create<GatewayName>(); return cancellationToken => findConfigurationNames() .Map(names => listFromSet(names, cancellationToken)) .IfNone(() => listAll(cancellationToken)); IAsyncEnumerable<(GatewayName, GatewayDto)> listFromSet(IEnumerable<GatewayName> names, CancellationToken cancellationToken) => names.Select(name => GatewayUri.From(name, serviceUri)) .ToAsyncEnumerable() .Choose(async uri => { var dtoOption = await uri.TryGetDto(pipeline, cancellationToken); return dtoOption.Map(dto => (uri.Name, dto)); }) // Handle scenarios where the SKU doesn't support gateways .Catch((HttpRequestException exception) => exception.StatusCode == HttpStatusCode.InternalServerError && exception.Message.Contains("Request processing failed", StringComparison.OrdinalIgnoreCase) ? AsyncEnumerable.Empty<(GatewayName, GatewayDto)>() : throw exception); IAsyncEnumerable<(GatewayName, GatewayDto)> listAll(CancellationToken cancellationToken) { var gatewaysUri = GatewaysUri.From(serviceUri); return gatewaysUri.List(pipeline, cancellationToken); } } private static void ConfigureWriteGatewayArtifacts(IHostApplicationBuilder builder) { ConfigureWriteGatewayInformationFile(builder); builder.Services.TryAddSingleton(GetWriteGatewayArtifacts); } private static WriteGatewayArtifacts GetWriteGatewayArtifacts(IServiceProvider provider) { var writeInformationFile = provider.GetRequiredService<WriteGatewayInformationFile>(); return async (name, dto, cancellationToken) => await writeInformationFile(name, dto, cancellationToken); } private static void ConfigureWriteGatewayInformationFile(IHostApplicationBuilder builder) { AzureModule.ConfigureManagementServiceDirectory(builder); builder.Services.TryAddSingleton(GetWriteGatewayInformationFile); } private static WriteGatewayInformationFile GetWriteGatewayInformationFile(IServiceProvider provider) { var serviceDirectory = provider.GetRequiredService<ManagementServiceDirectory>(); var logger = provider.GetRequiredService<ILogger>(); return async (name, dto, cancellationToken) => { var informationFile = GatewayInformationFile.From(name, serviceDirectory); logger.LogInformation("Writing gateway information file {GatewayInformationFile}...", informationFile); await informationFile.WriteDto(dto, cancellationToken); }; } }