tools/code/common/ServicePolicy.cs (125 lines of code) (raw):
using Azure.Core.Pipeline;
using Flurl;
using LanguageExt;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
namespace common;
public sealed record ServicePolicyName : ResourceName
{
private ServicePolicyName(string value) : base(value) { }
public static ServicePolicyName From(string value) => new(value);
}
public sealed record ServicePoliciesUri : ResourceUri
{
public required ManagementServiceUri ServiceUri { get; init; }
private static string PathSegment { get; } = "policies";
protected override Uri Value => ServiceUri.ToUri().AppendPathSegment(PathSegment).ToUri();
public static ServicePoliciesUri From(ManagementServiceUri serviceUri) =>
new() { ServiceUri = serviceUri };
}
public sealed record ServicePolicyUri : ResourceUri
{
public required ServicePoliciesUri Parent { get; init; }
public required ServicePolicyName Name { get; init; }
protected override Uri Value => Parent.ToUri().AppendPathSegment(Name.ToString()).ToUri();
public static ServicePolicyUri From(ServicePolicyName name, ManagementServiceUri serviceUri) =>
new()
{
Parent = ServicePoliciesUri.From(serviceUri),
Name = name
};
}
public sealed record ServicePolicyFile : ResourceFile
{
public required ManagementServiceDirectory Parent { get; init; }
public required ServicePolicyName Name { get; init; }
protected override FileInfo Value =>
Parent.ToDirectoryInfo().GetChildFile($"{Name}.xml");
public static ServicePolicyFile From(ServicePolicyName name, ManagementServiceDirectory serviceDirectory) =>
new()
{
Parent = serviceDirectory,
Name = name
};
public static Option<ServicePolicyFile> TryParse(FileInfo? file, ManagementServiceDirectory serviceDirectory) =>
file is not null
&& file.Name.EndsWith(".xml", StringComparison.Ordinal)
&& file.Directory?.FullName == serviceDirectory.ToDirectoryInfo().FullName
? new ServicePolicyFile
{
Parent = serviceDirectory,
Name = ServicePolicyName.From(Path.GetFileNameWithoutExtension(file.Name))
}
: Option<ServicePolicyFile>.None;
}
public sealed record ServicePolicyDto
{
[JsonPropertyName("properties")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public required ServicePolicyContract Properties { get; init; }
public sealed record ServicePolicyContract
{
[JsonPropertyName("description")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public string? Description { get; init; }
[JsonPropertyName("format")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public string? Format { get; init; }
[JsonPropertyName("value")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public string? Value { get; init; }
}
}
public static class ServicePolicyModule
{
public static async ValueTask DeleteAll(this ServicePoliciesUri uri, HttpPipeline pipeline, CancellationToken cancellationToken) =>
await uri.ListNames(pipeline, cancellationToken)
.IterParallel(async name => await ServicePolicyUri.From(name, uri.ServiceUri)
.Delete(pipeline, cancellationToken),
cancellationToken);
public static IAsyncEnumerable<ServicePolicyName> ListNames(this ServicePoliciesUri uri, HttpPipeline pipeline, CancellationToken cancellationToken) =>
pipeline.ListJsonObjects(uri.ToUri(), cancellationToken)
.Select(jsonObject => jsonObject.GetStringProperty("name"))
.Select(ServicePolicyName.From);
public static IAsyncEnumerable<(ServicePolicyName Name, ServicePolicyDto Dto)> List(this ServicePoliciesUri servicePoliciesUri, HttpPipeline pipeline, CancellationToken cancellationToken) =>
servicePoliciesUri.ListNames(pipeline, cancellationToken)
.SelectAwait(async name =>
{
var uri = new ServicePolicyUri { Parent = servicePoliciesUri, Name = name };
var dto = await uri.GetDto(pipeline, cancellationToken);
return (name, dto);
});
public static async ValueTask<ServicePolicyDto> GetDto(this ServicePolicyUri uri, HttpPipeline pipeline, CancellationToken cancellationToken)
{
var contentUri = uri.ToUri().AppendQueryParam("format", "rawxml").ToUri();
var content = await pipeline.GetContent(contentUri, cancellationToken);
return content.ToObjectFromJson<ServicePolicyDto>();
}
public static async ValueTask Delete(this ServicePolicyUri uri, HttpPipeline pipeline, CancellationToken cancellationToken) =>
await pipeline.DeleteResource(uri.ToUri(), waitForCompletion: true, cancellationToken);
public static async ValueTask PutDto(this ServicePolicyUri uri, ServicePolicyDto dto, HttpPipeline pipeline, CancellationToken cancellationToken)
{
var content = BinaryData.FromObjectAsJson(dto);
await pipeline.PutContent(uri.ToUri(), content, cancellationToken);
}
public static IEnumerable<ServicePolicyFile> ListPolicyFiles(ManagementServiceDirectory serviceDirectory) =>
serviceDirectory.ToDirectoryInfo()
.ListFiles("*")
.Choose(file => ServicePolicyFile.TryParse(file, serviceDirectory));
public static async ValueTask WritePolicy(this ServicePolicyFile file, string policy, CancellationToken cancellationToken)
{
var content = BinaryData.FromString(policy);
await file.ToFileInfo().OverwriteWithBinaryData(content, cancellationToken);
}
public static async ValueTask<string> ReadPolicy(this ServicePolicyFile file, CancellationToken cancellationToken)
{
var content = await file.ToFileInfo().ReadAsBinaryData(cancellationToken);
return content.ToString();
}
}