tools/code/common/GatewayApi.cs (138 lines of code) (raw):

using Azure.Core.Pipeline; using Flurl; using LanguageExt; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace common; public sealed record GatewayApisUri : ResourceUri { public required GatewayUri Parent { get; init; } private static string PathSegment { get; } = "apis"; protected override Uri Value => Parent.ToUri().AppendPathSegment(PathSegment).ToUri(); public static GatewayApisUri From(GatewayName name, ManagementServiceUri serviceUri) => new() { Parent = GatewayUri.From(name, serviceUri) }; } public sealed record GatewayApiUri : ResourceUri { public required GatewayApisUri Parent { get; init; } public required ApiName Name { get; init; } protected override Uri Value => Parent.ToUri().AppendPathSegment(Name.ToString()).ToUri(); public static GatewayApiUri From(ApiName name, GatewayName gatewayName, ManagementServiceUri serviceUri) => new() { Parent = GatewayApisUri.From(gatewayName, serviceUri), Name = name }; } public sealed record GatewayApisDirectory : ResourceDirectory { public required GatewayDirectory Parent { get; init; } private static string Name { get; } = "apis"; protected override DirectoryInfo Value => Parent.ToDirectoryInfo().GetChildDirectory(Name); public static GatewayApisDirectory From(GatewayName name, ManagementServiceDirectory serviceDirectory) => new() { Parent = GatewayDirectory.From(name, serviceDirectory) }; public static Option<GatewayApisDirectory> TryParse(DirectoryInfo? directory, ManagementServiceDirectory serviceDirectory) => IsDirectoryNameValid(directory) ? from parent in GatewayDirectory.TryParse(directory.Parent, serviceDirectory) select new GatewayApisDirectory { Parent = parent } : Option<GatewayApisDirectory>.None; internal static bool IsDirectoryNameValid([NotNullWhen(true)] DirectoryInfo? directory) => directory?.Name == Name; } public sealed record GatewayApiDirectory : ResourceDirectory { public required GatewayApisDirectory Parent { get; init; } public required ApiName Name { get; init; } protected override DirectoryInfo Value => Parent.ToDirectoryInfo().GetChildDirectory(Name.ToString()); public static GatewayApiDirectory From(ApiName name, GatewayName gatewayName, ManagementServiceDirectory serviceDirectory) => new() { Parent = GatewayApisDirectory.From(gatewayName, serviceDirectory), Name = name }; public static Option<GatewayApiDirectory> TryParse(DirectoryInfo? directory, ManagementServiceDirectory serviceDirectory) => from name in TryParseGatewayApiName(directory) from parent in GatewayApisDirectory.TryParse(directory?.Parent, serviceDirectory) select new GatewayApiDirectory { Parent = parent, Name = name }; internal static Option<ApiName> TryParseGatewayApiName(DirectoryInfo? directory) => string.IsNullOrWhiteSpace(directory?.Name) ? Option<ApiName>.None : ApiName.From(directory.Name); } public sealed record GatewayApiInformationFile : ResourceFile { public required GatewayApiDirectory Parent { get; init; } private static string Name { get; } = "gatewayApiInformation.json"; protected override FileInfo Value => Parent.ToDirectoryInfo().GetChildFile(Name); public static GatewayApiInformationFile From(ApiName name, GatewayName gatewayName, ManagementServiceDirectory serviceDirectory) => new() { Parent = GatewayApiDirectory.From(name, gatewayName, serviceDirectory) }; public static Option<GatewayApiInformationFile> TryParse(FileInfo? file, ManagementServiceDirectory serviceDirectory) => IsFileNameValid(file) ? from parent in GatewayApiDirectory.TryParse(file.Directory, serviceDirectory) select new GatewayApiInformationFile { Parent = parent } : Option<GatewayApiInformationFile>.None; internal static bool IsFileNameValid([NotNullWhen(true)] FileInfo? file) => file?.Name == Name; } public sealed record GatewayApiDto { public static GatewayApiDto Instance { get; } = new(); } public static class GatewayApiModule { public static IAsyncEnumerable<ApiName> ListNames(this GatewayApisUri uri, HttpPipeline pipeline, CancellationToken cancellationToken) => pipeline.ListJsonObjects(uri.ToUri(), cancellationToken) .Select(jsonObject => jsonObject.GetStringProperty("name")) .Select(ApiName.From) .Where(ApiName.IsNotRevisioned); public static IAsyncEnumerable<(ApiName Name, GatewayApiDto Dto)> List(this GatewayApisUri gatewayApisUri, HttpPipeline pipeline, CancellationToken cancellationToken) => gatewayApisUri.ListNames(pipeline, cancellationToken) .Select(name => (name, GatewayApiDto.Instance)); public static async ValueTask Delete(this GatewayApiUri uri, HttpPipeline pipeline, CancellationToken cancellationToken) => await pipeline.DeleteResource(uri.ToUri(), waitForCompletion: true, cancellationToken); public static async ValueTask PutDto(this GatewayApiUri uri, GatewayApiDto dto, HttpPipeline pipeline, CancellationToken cancellationToken) { var content = BinaryData.FromObjectAsJson(dto); await pipeline.PutContent(uri.ToUri(), content, cancellationToken); } public static IEnumerable<GatewayApiInformationFile> ListInformationFiles(GatewayName gatewayName, ManagementServiceDirectory serviceDirectory) => ListGatewayApisDirectories(gatewayName, serviceDirectory) .SelectMany(ListGatewayApiDirectories) .Select(directory => GatewayApiInformationFile.From(directory.Name, gatewayName, serviceDirectory)); private static IEnumerable<GatewayApisDirectory> ListGatewayApisDirectories(GatewayName gatewayName, ManagementServiceDirectory serviceDirectory) => GatewayDirectory.From(gatewayName, serviceDirectory) .ToDirectoryInfo() .ListDirectories("*") .Where(GatewayApisDirectory.IsDirectoryNameValid) .Select(_ => GatewayApisDirectory.From(gatewayName, serviceDirectory)); private static IEnumerable<GatewayApiDirectory> ListGatewayApiDirectories(GatewayApisDirectory gatewayApisDirectory) => gatewayApisDirectory.ToDirectoryInfo() .ListDirectories("*") .Choose(directory => from name in GatewayApiDirectory.TryParseGatewayApiName(directory) select new GatewayApiDirectory { Name = name, Parent = gatewayApisDirectory }); public static async ValueTask WriteDto(this GatewayApiInformationFile file, GatewayApiDto dto, CancellationToken cancellationToken) { var content = BinaryData.FromObjectAsJson(dto, JsonObjectExtensions.SerializerOptions); await file.ToFileInfo().OverwriteWithBinaryData(content, cancellationToken); } public static async ValueTask<GatewayApiDto> ReadDto(this GatewayApiInformationFile file, CancellationToken cancellationToken) { var content = await file.ToFileInfo().ReadAsBinaryData(cancellationToken); return content.ToObjectFromJson<GatewayApiDto>(); } }