tools/code/common/ProductGroup.cs (147 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.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace common;
public sealed record ProductGroupsUri : ResourceUri
{
public required ProductUri Parent { get; init; }
private static string PathSegment { get; } = "groups";
protected override Uri Value => Parent.ToUri().AppendPathSegment(PathSegment).ToUri();
public static ProductGroupsUri From(ProductName name, ManagementServiceUri serviceUri) =>
new() { Parent = ProductUri.From(name, serviceUri) };
}
public sealed record ProductGroupUri : ResourceUri
{
public required ProductGroupsUri Parent { get; init; }
public required GroupName Name { get; init; }
protected override Uri Value => Parent.ToUri().AppendPathSegment(Name.ToString()).ToUri();
public static ProductGroupUri From(GroupName name, ProductName productName, ManagementServiceUri serviceUri) =>
new()
{
Parent = ProductGroupsUri.From(productName, serviceUri),
Name = name
};
}
public sealed record ProductGroupsDirectory : ResourceDirectory
{
public required ProductDirectory Parent { get; init; }
private static string Name { get; } = "groups";
protected override DirectoryInfo Value =>
Parent.ToDirectoryInfo().GetChildDirectory(Name);
public static ProductGroupsDirectory From(ProductName name, ManagementServiceDirectory serviceDirectory) =>
new() { Parent = ProductDirectory.From(name, serviceDirectory) };
public static Option<ProductGroupsDirectory> TryParse(DirectoryInfo? directory, ManagementServiceDirectory serviceDirectory) =>
IsDirectoryNameValid(directory)
? from parent in ProductDirectory.TryParse(directory.Parent, serviceDirectory)
select new ProductGroupsDirectory { Parent = parent }
: Option<ProductGroupsDirectory>.None;
internal static bool IsDirectoryNameValid([NotNullWhen(true)] DirectoryInfo? directory) =>
directory?.Name == Name;
}
public sealed record ProductGroupDirectory : ResourceDirectory
{
public required ProductGroupsDirectory Parent { get; init; }
public required GroupName Name { get; init; }
protected override DirectoryInfo Value =>
Parent.ToDirectoryInfo().GetChildDirectory(Name.ToString());
public static ProductGroupDirectory From(GroupName name, ProductName productName, ManagementServiceDirectory serviceDirectory) =>
new()
{
Parent = ProductGroupsDirectory.From(productName, serviceDirectory),
Name = name
};
public static Option<ProductGroupDirectory> TryParse(DirectoryInfo? directory, ManagementServiceDirectory serviceDirectory) =>
from name in TryParseProductGroupName(directory)
from parent in ProductGroupsDirectory.TryParse(directory?.Parent, serviceDirectory)
select new ProductGroupDirectory
{
Parent = parent,
Name = name
};
internal static Option<GroupName> TryParseProductGroupName(DirectoryInfo? directory) =>
string.IsNullOrWhiteSpace(directory?.Name)
? Option<GroupName>.None
: GroupName.From(directory.Name);
}
public sealed record ProductGroupInformationFile : ResourceFile
{
public required ProductGroupDirectory Parent { get; init; }
private static string Name { get; } = "productGroupInformation.json";
protected override FileInfo Value =>
Parent.ToDirectoryInfo().GetChildFile(Name);
public static ProductGroupInformationFile From(GroupName name, ProductName productName, ManagementServiceDirectory serviceDirectory) =>
new()
{
Parent = ProductGroupDirectory.From(name, productName, serviceDirectory)
};
public static Option<ProductGroupInformationFile> TryParse(FileInfo? file, ManagementServiceDirectory serviceDirectory) =>
IsFileNameValid(file)
? from parent in ProductGroupDirectory.TryParse(file.Directory, serviceDirectory)
select new ProductGroupInformationFile { Parent = parent }
: Option<ProductGroupInformationFile>.None;
internal static bool IsFileNameValid([NotNullWhen(true)] FileInfo? file) =>
file?.Name == Name;
}
public sealed record ProductGroupDto
{
public static ProductGroupDto Instance { get; } = new();
}
public static class ProductGroupModule
{
public static IAsyncEnumerable<GroupName> ListNames(this ProductGroupsUri uri, HttpPipeline pipeline, CancellationToken cancellationToken)
{
var exceptionHandler = (HttpRequestException exception) =>
exception.StatusCode == HttpStatusCode.BadRequest
&& exception.Message.Contains("MethodNotAllowedInPricingTier", StringComparison.OrdinalIgnoreCase)
? AsyncEnumerable.Empty<GroupName>()
: throw exception;
return pipeline.ListJsonObjects(uri.ToUri(), cancellationToken)
.Select(jsonObject => jsonObject.GetStringProperty("name"))
.Select(GroupName.From)
.Catch(exceptionHandler);
}
public static IAsyncEnumerable<(GroupName Name, ProductGroupDto Dto)> List(this ProductGroupsUri productGroupsUri, HttpPipeline pipeline, CancellationToken cancellationToken) =>
productGroupsUri.ListNames(pipeline, cancellationToken)
.Select(name => (name, ProductGroupDto.Instance));
public static async ValueTask Delete(this ProductGroupUri uri, HttpPipeline pipeline, CancellationToken cancellationToken) =>
await pipeline.DeleteResource(uri.ToUri(), waitForCompletion: true, cancellationToken);
public static async ValueTask PutDto(this ProductGroupUri uri, ProductGroupDto dto, HttpPipeline pipeline, CancellationToken cancellationToken)
{
var content = BinaryData.FromObjectAsJson(dto);
await pipeline.PutContent(uri.ToUri(), content, cancellationToken);
}
public static IEnumerable<ProductGroupInformationFile> ListInformationFiles(ProductName productName, ManagementServiceDirectory serviceDirectory) =>
ListProductGroupsDirectories(productName, serviceDirectory)
.SelectMany(ListProductGroupDirectories)
.Select(directory => ProductGroupInformationFile.From(directory.Name, productName, serviceDirectory));
private static IEnumerable<ProductGroupsDirectory> ListProductGroupsDirectories(ProductName productName, ManagementServiceDirectory serviceDirectory) =>
ProductDirectory.From(productName, serviceDirectory)
.ToDirectoryInfo()
.ListDirectories("*")
.Where(ProductGroupsDirectory.IsDirectoryNameValid)
.Select(_ => ProductGroupsDirectory.From(productName, serviceDirectory));
private static IEnumerable<ProductGroupDirectory> ListProductGroupDirectories(ProductGroupsDirectory productGroupsDirectory) =>
productGroupsDirectory.ToDirectoryInfo()
.ListDirectories("*")
.Choose(directory => from name in ProductGroupDirectory.TryParseProductGroupName(directory)
select new ProductGroupDirectory { Name = name, Parent = productGroupsDirectory });
public static async ValueTask WriteDto(this ProductGroupInformationFile file, ProductGroupDto dto, CancellationToken cancellationToken)
{
var content = BinaryData.FromObjectAsJson(dto, JsonObjectExtensions.SerializerOptions);
await file.ToFileInfo().OverwriteWithBinaryData(content, cancellationToken);
}
public static async ValueTask<ProductGroupDto> ReadDto(this ProductGroupInformationFile file, CancellationToken cancellationToken)
{
var content = await file.ToFileInfo().ReadAsBinaryData(cancellationToken);
return content.ToObjectFromJson<ProductGroupDto>();
}
}