tools/code/publisher/PolicyFragment.cs (242 lines of code) (raw):
using Azure.Core.Pipeline;
using common;
using LanguageExt;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace publisher;
public delegate ValueTask PutPolicyFragments(CancellationToken cancellationToken);
public delegate Option<PolicyFragmentName> TryParsePolicyFragmentName(FileInfo file);
public delegate bool IsPolicyFragmentNameInSourceControl(PolicyFragmentName name);
public delegate ValueTask PutPolicyFragment(PolicyFragmentName name, CancellationToken cancellationToken);
public delegate ValueTask<Option<PolicyFragmentDto>> FindPolicyFragmentDto(PolicyFragmentName name, CancellationToken cancellationToken);
public delegate ValueTask PutPolicyFragmentInApim(PolicyFragmentName name, PolicyFragmentDto dto, CancellationToken cancellationToken);
public delegate ValueTask DeletePolicyFragments(CancellationToken cancellationToken);
public delegate ValueTask DeletePolicyFragment(PolicyFragmentName name, CancellationToken cancellationToken);
public delegate ValueTask DeletePolicyFragmentFromApim(PolicyFragmentName name, CancellationToken cancellationToken);
internal static class PolicyFragmentModule
{
public static void ConfigurePutPolicyFragments(IHostApplicationBuilder builder)
{
CommonModule.ConfigureGetPublisherFiles(builder);
ConfigureTryParsePolicyFragmentName(builder);
ConfigureIsPolicyFragmentNameInSourceControl(builder);
ConfigurePutPolicyFragment(builder);
builder.Services.TryAddSingleton(GetPutPolicyFragments);
}
private static PutPolicyFragments GetPutPolicyFragments(IServiceProvider provider)
{
var getPublisherFiles = provider.GetRequiredService<GetPublisherFiles>();
var tryParseName = provider.GetRequiredService<TryParsePolicyFragmentName>();
var isNameInSourceControl = provider.GetRequiredService<IsPolicyFragmentNameInSourceControl>();
var put = provider.GetRequiredService<PutPolicyFragment>();
var activitySource = provider.GetRequiredService<ActivitySource>();
var logger = provider.GetRequiredService<ILogger>();
return async cancellationToken =>
{
using var _ = activitySource.StartActivity(nameof(PutPolicyFragments));
logger.LogInformation("Putting policy fragments...");
await getPublisherFiles()
.Choose(tryParseName.Invoke)
.Where(isNameInSourceControl.Invoke)
.Distinct()
.IterParallel(put.Invoke, cancellationToken);
};
}
private static void ConfigureTryParsePolicyFragmentName(IHostApplicationBuilder builder)
{
AzureModule.ConfigureManagementServiceDirectory(builder);
builder.Services.TryAddSingleton(GetTryParsePolicyFragmentName);
}
private static TryParsePolicyFragmentName GetTryParsePolicyFragmentName(IServiceProvider provider)
{
var serviceDirectory = provider.GetRequiredService<ManagementServiceDirectory>();
return file => tryParseFromInformationFile(file) | tryParseFromPolicyFile(file);
Option<PolicyFragmentName> tryParseFromInformationFile(FileInfo file) =>
from informationFile in PolicyFragmentInformationFile.TryParse(file, serviceDirectory)
select informationFile.Parent.Name;
Option<PolicyFragmentName> tryParseFromPolicyFile(FileInfo file) =>
from policyFile in PolicyFragmentPolicyFile.TryParse(file, serviceDirectory)
select policyFile.Parent.Name;
}
private static void ConfigureIsPolicyFragmentNameInSourceControl(IHostApplicationBuilder builder)
{
CommonModule.ConfigureGetArtifactFiles(builder);
AzureModule.ConfigureManagementServiceDirectory(builder);
builder.Services.TryAddSingleton(GetIsPolicyFragmentNameInSourceControl);
}
private static IsPolicyFragmentNameInSourceControl GetIsPolicyFragmentNameInSourceControl(IServiceProvider provider)
{
var getArtifactFiles = provider.GetRequiredService<GetArtifactFiles>();
var serviceDirectory = provider.GetRequiredService<ManagementServiceDirectory>();
return name =>
doesInformationFileExist(name)
|| doesPolicyFileExist(name);
bool doesInformationFileExist(PolicyFragmentName name)
{
var artifactFiles = getArtifactFiles();
var informationFile = PolicyFragmentInformationFile.From(name, serviceDirectory);
return artifactFiles.Contains(informationFile.ToFileInfo());
}
bool doesPolicyFileExist(PolicyFragmentName name)
{
var artifactFiles = getArtifactFiles();
var policyFile = PolicyFragmentPolicyFile.From(name, serviceDirectory);
return artifactFiles.Contains(policyFile.ToFileInfo());
}
}
private static void ConfigurePutPolicyFragment(IHostApplicationBuilder builder)
{
ConfigureFindPolicyFragmentDto(builder);
ConfigurePutPolicyFragmentInApim(builder);
builder.Services.TryAddSingleton(GetPutPolicyFragment);
}
private static PutPolicyFragment GetPutPolicyFragment(IServiceProvider provider)
{
var findDto = provider.GetRequiredService<FindPolicyFragmentDto>();
var putInApim = provider.GetRequiredService<PutPolicyFragmentInApim>();
var activitySource = provider.GetRequiredService<ActivitySource>();
return async (name, cancellationToken) =>
{
using var _ = activitySource.StartActivity(nameof(PutPolicyFragment))
?.AddTag("policy_fragment.name", name);
var dtoOption = await findDto(name, cancellationToken);
await dtoOption.IterTask(async dto => await putInApim(name, dto, cancellationToken));
};
}
private static void ConfigureFindPolicyFragmentDto(IHostApplicationBuilder builder)
{
AzureModule.ConfigureManagementServiceDirectory(builder);
CommonModule.ConfigureTryGetFileContents(builder);
OverrideDtoModule.ConfigureOverrideDtoFactory(builder);
builder.Services.TryAddSingleton(GetFindPolicyFragmentDto);
}
private static FindPolicyFragmentDto GetFindPolicyFragmentDto(IServiceProvider provider)
{
var serviceDirectory = provider.GetRequiredService<ManagementServiceDirectory>();
var tryGetFileContents = provider.GetRequiredService<TryGetFileContents>();
var overrideFactory = provider.GetRequiredService<OverrideDtoFactory>();
var overrideDto = overrideFactory.Create<PolicyFragmentName, PolicyFragmentDto>();
return async (name, cancellationToken) =>
{
var informationFileDtoOption = await tryGetInformationFileDto(name, cancellationToken);
var policyContentsOption = await tryGetPolicyContents(name, cancellationToken);
return tryGetDto(name, informationFileDtoOption, policyContentsOption);
};
async ValueTask<Option<PolicyFragmentDto>> tryGetInformationFileDto(PolicyFragmentName name, CancellationToken cancellationToken)
{
var informationFile = PolicyFragmentInformationFile.From(name, serviceDirectory);
var contentsOption = await tryGetFileContents(informationFile.ToFileInfo(), cancellationToken);
return from contents in contentsOption
select contents.ToObjectFromJson<PolicyFragmentDto>();
}
async ValueTask<Option<BinaryData>> tryGetPolicyContents(PolicyFragmentName name, CancellationToken cancellationToken)
{
var policyFile = PolicyFragmentPolicyFile.From(name, serviceDirectory);
return await tryGetFileContents(policyFile.ToFileInfo(), cancellationToken);
}
Option<PolicyFragmentDto> tryGetDto(PolicyFragmentName name, Option<PolicyFragmentDto> informationFileDtoOption, Option<BinaryData> policyContentsOption)
{
if (informationFileDtoOption.IsNone && policyContentsOption.IsNone)
{
return Option<PolicyFragmentDto>.None;
}
var dto = informationFileDtoOption.IfNone(() => new PolicyFragmentDto { Properties = new PolicyFragmentDto.PolicyFragmentContract() });
policyContentsOption.Iter(contents => dto = dto with
{
Properties = dto.Properties with
{
Format = "rawxml",
Value = contents.ToString()
}
});
return overrideDto(name, dto);
}
}
private static void ConfigurePutPolicyFragmentInApim(IHostApplicationBuilder builder)
{
AzureModule.ConfigureManagementServiceUri(builder);
AzureModule.ConfigureHttpPipeline(builder);
builder.Services.TryAddSingleton(GetPutPolicyFragmentInApim);
}
private static PutPolicyFragmentInApim GetPutPolicyFragmentInApim(IServiceProvider provider)
{
var serviceUri = provider.GetRequiredService<ManagementServiceUri>();
var pipeline = provider.GetRequiredService<HttpPipeline>();
var logger = provider.GetRequiredService<ILogger>();
return async (name, dto, cancellationToken) =>
{
logger.LogInformation("Putting policy fragment {PolicyFragmentName}...", name);
await PolicyFragmentUri.From(name, serviceUri)
.PutDto(dto, pipeline, cancellationToken);
};
}
public static void ConfigureDeletePolicyFragments(IHostApplicationBuilder builder)
{
CommonModule.ConfigureGetPublisherFiles(builder);
ConfigureTryParsePolicyFragmentName(builder);
ConfigureIsPolicyFragmentNameInSourceControl(builder);
ConfigureDeletePolicyFragment(builder);
builder.Services.TryAddSingleton(GetDeletePolicyFragments);
}
private static DeletePolicyFragments GetDeletePolicyFragments(IServiceProvider provider)
{
var getPublisherFiles = provider.GetRequiredService<GetPublisherFiles>();
var tryParseName = provider.GetRequiredService<TryParsePolicyFragmentName>();
var isNameInSourceControl = provider.GetRequiredService<IsPolicyFragmentNameInSourceControl>();
var delete = provider.GetRequiredService<DeletePolicyFragment>();
var activitySource = provider.GetRequiredService<ActivitySource>();
var logger = provider.GetRequiredService<ILogger>();
return async cancellationToken =>
{
using var _ = activitySource.StartActivity(nameof(DeletePolicyFragments));
logger.LogInformation("Deleting policy fragments...");
await getPublisherFiles()
.Choose(tryParseName.Invoke)
.Where(name => isNameInSourceControl(name) is false)
.Distinct()
.IterParallel(delete.Invoke, cancellationToken);
};
}
private static void ConfigureDeletePolicyFragment(IHostApplicationBuilder builder)
{
ConfigureDeletePolicyFragmentFromApim(builder);
builder.Services.TryAddSingleton(GetDeletePolicyFragment);
}
private static DeletePolicyFragment GetDeletePolicyFragment(IServiceProvider provider)
{
var deleteFromApim = provider.GetRequiredService<DeletePolicyFragmentFromApim>();
var activitySource = provider.GetRequiredService<ActivitySource>();
return async (name, cancellationToken) =>
{
using var _ = activitySource.StartActivity(nameof(DeletePolicyFragment))
?.AddTag("policy_fragment.name", name);
await deleteFromApim(name, cancellationToken);
};
}
private static void ConfigureDeletePolicyFragmentFromApim(IHostApplicationBuilder builder)
{
AzureModule.ConfigureManagementServiceUri(builder);
AzureModule.ConfigureHttpPipeline(builder);
builder.Services.TryAddSingleton(GetDeletePolicyFragmentFromApim);
}
private static DeletePolicyFragmentFromApim GetDeletePolicyFragmentFromApim(IServiceProvider provider)
{
var serviceUri = provider.GetRequiredService<ManagementServiceUri>();
var pipeline = provider.GetRequiredService<HttpPipeline>();
var logger = provider.GetRequiredService<ILogger>();
return async (name, cancellationToken) =>
{
logger.LogInformation("Deleting policy fragment {PolicyFragmentName}...", name);
await PolicyFragmentUri.From(name, serviceUri)
.Delete(pipeline, cancellationToken);
};
}
}