tools/code/publisher/WorkspacePolicyFragment.cs (241 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 PutWorkspacePolicyFragments(CancellationToken cancellationToken);
public delegate Option<(PolicyFragmentName Name, WorkspaceName WorkspaceName)> TryParseWorkspacePolicyFragmentName(FileInfo file);
public delegate bool IsWorkspacePolicyFragmentNameInSourceControl(PolicyFragmentName name, WorkspaceName workspaceName);
public delegate ValueTask PutWorkspacePolicyFragment(PolicyFragmentName name, WorkspaceName workspaceName, CancellationToken cancellationToken);
public delegate ValueTask<Option<WorkspacePolicyFragmentDto>> FindWorkspacePolicyFragmentDto(PolicyFragmentName name, WorkspaceName workspaceName, CancellationToken cancellationToken);
public delegate ValueTask PutWorkspacePolicyFragmentInApim(PolicyFragmentName name, WorkspacePolicyFragmentDto dto, WorkspaceName workspaceName, CancellationToken cancellationToken);
public delegate ValueTask DeleteWorkspacePolicyFragments(CancellationToken cancellationToken);
public delegate ValueTask DeleteWorkspacePolicyFragment(PolicyFragmentName name, WorkspaceName workspaceName, CancellationToken cancellationToken);
public delegate ValueTask DeleteWorkspacePolicyFragmentFromApim(PolicyFragmentName name, WorkspaceName workspaceName, CancellationToken cancellationToken);
internal static class WorkspacePolicyFragmentModule
{
public static void ConfigurePutWorkspacePolicyFragments(IHostApplicationBuilder builder)
{
CommonModule.ConfigureGetPublisherFiles(builder);
ConfigureTryWorkspaceParsePolicyFragmentName(builder);
ConfigureIsWorkspacePolicyFragmentNameInSourceControl(builder);
ConfigurePutWorkspacePolicyFragment(builder);
builder.Services.TryAddSingleton(GetPutWorkspacePolicyFragments);
}
private static PutWorkspacePolicyFragments GetPutWorkspacePolicyFragments(IServiceProvider provider)
{
var getPublisherFiles = provider.GetRequiredService<GetPublisherFiles>();
var tryParseName = provider.GetRequiredService<TryParseWorkspacePolicyFragmentName>();
var isNameInSourceControl = provider.GetRequiredService<IsWorkspacePolicyFragmentNameInSourceControl>();
var put = provider.GetRequiredService<PutWorkspacePolicyFragment>();
var activitySource = provider.GetRequiredService<ActivitySource>();
var logger = provider.GetRequiredService<ILogger>();
return async cancellationToken =>
{
using var _ = activitySource.StartActivity(nameof(PutWorkspacePolicyFragments));
logger.LogInformation("Putting workspace policy fragments...");
await getPublisherFiles()
.Choose(tryParseName.Invoke)
.Where(tag => isNameInSourceControl(tag.Name, tag.WorkspaceName))
.Distinct()
.IterParallel(put.Invoke, cancellationToken);
};
}
private static void ConfigureTryWorkspaceParsePolicyFragmentName(IHostApplicationBuilder builder)
{
AzureModule.ConfigureManagementServiceDirectory(builder);
builder.Services.TryAddSingleton(GetTryParseWorkspacePolicyFragmentName);
}
private static TryParseWorkspacePolicyFragmentName GetTryParseWorkspacePolicyFragmentName(IServiceProvider provider)
{
var serviceDirectory = provider.GetRequiredService<ManagementServiceDirectory>();
return file => tryParseFromInformationFile(file) | tryParseFromPolicyFile(file);
Option<(PolicyFragmentName Name, WorkspaceName WorkspaceName)> tryParseFromInformationFile(FileInfo file) =>
from informationFile in WorkspacePolicyFragmentInformationFile.TryParse(file, serviceDirectory)
select (informationFile.Parent.Name, informationFile.Parent.Parent.Parent.Name);
Option<(PolicyFragmentName Name, WorkspaceName WorkspaceName)> tryParseFromPolicyFile(FileInfo file) =>
from policyFile in WorkspacePolicyFragmentPolicyFile.TryParse(file, serviceDirectory)
select (policyFile.Parent.Name, policyFile.Parent.Parent.Parent.Name);
}
private static void ConfigureIsWorkspacePolicyFragmentNameInSourceControl(IHostApplicationBuilder builder)
{
CommonModule.ConfigureGetArtifactFiles(builder);
AzureModule.ConfigureManagementServiceDirectory(builder);
builder.Services.TryAddSingleton(GetIsPolicyFragmentNameInSourceControl);
}
private static IsWorkspacePolicyFragmentNameInSourceControl GetIsPolicyFragmentNameInSourceControl(IServiceProvider provider)
{
var getArtifactFiles = provider.GetRequiredService<GetArtifactFiles>();
var serviceDirectory = provider.GetRequiredService<ManagementServiceDirectory>();
return (name, workspaceName) =>
doesInformationFileExist(name, workspaceName)
|| doesPolicyFileExist(name, workspaceName);
bool doesInformationFileExist(PolicyFragmentName name, WorkspaceName workspaceName)
{
var artifactFiles = getArtifactFiles();
var informationFile = WorkspacePolicyFragmentInformationFile.From(name, workspaceName, serviceDirectory);
return artifactFiles.Contains(informationFile.ToFileInfo());
}
bool doesPolicyFileExist(PolicyFragmentName name, WorkspaceName workspaceName)
{
var artifactFiles = getArtifactFiles();
var policyFile = WorkspacePolicyFragmentPolicyFile.From(name, workspaceName, serviceDirectory);
return artifactFiles.Contains(policyFile.ToFileInfo());
}
}
private static void ConfigurePutWorkspacePolicyFragment(IHostApplicationBuilder builder)
{
ConfigureFindWorkspacePolicyFragmentDto(builder);
ConfigurePutWorkspacePolicyFragmentInApim(builder);
builder.Services.TryAddSingleton(GetPutWorkspacePolicyFragment);
}
private static PutWorkspacePolicyFragment GetPutWorkspacePolicyFragment(IServiceProvider provider)
{
var findDto = provider.GetRequiredService<FindWorkspacePolicyFragmentDto>();
var putInApim = provider.GetRequiredService<PutWorkspacePolicyFragmentInApim>();
var activitySource = provider.GetRequiredService<ActivitySource>();
return async (name, workspaceName, cancellationToken) =>
{
using var _ = activitySource.StartActivity(nameof(PutWorkspacePolicyFragment))
?.AddTag("workspace_policy_fragment.name", name)
?.AddTag("workspace.name", workspaceName);
var dtoOption = await findDto(name, workspaceName, cancellationToken);
await dtoOption.IterTask(async dto => await putInApim(name, dto, workspaceName, cancellationToken));
};
}
private static void ConfigureFindWorkspacePolicyFragmentDto(IHostApplicationBuilder builder)
{
AzureModule.ConfigureManagementServiceDirectory(builder);
CommonModule.ConfigureTryGetFileContents(builder);
builder.Services.TryAddSingleton(GetFindWorkspacePolicyFragmentDto);
}
private static FindWorkspacePolicyFragmentDto GetFindWorkspacePolicyFragmentDto(IServiceProvider provider)
{
var serviceDirectory = provider.GetRequiredService<ManagementServiceDirectory>();
var tryGetFileContents = provider.GetRequiredService<TryGetFileContents>();
return async (name, workspaceName, cancellationToken) =>
{
var informationFileDtoOption = await tryGetInformationFileDto(name, workspaceName, cancellationToken);
var policyContentsOption = await tryGetPolicyContents(name, workspaceName, cancellationToken);
return tryGetDto(informationFileDtoOption, policyContentsOption);
};
async ValueTask<Option<WorkspacePolicyFragmentDto>> tryGetInformationFileDto(PolicyFragmentName name, WorkspaceName workspaceName, CancellationToken cancellationToken)
{
var informationFile = WorkspacePolicyFragmentInformationFile.From(name, workspaceName, serviceDirectory);
var contentsOption = await tryGetFileContents(informationFile.ToFileInfo(), cancellationToken);
return from contents in contentsOption
select contents.ToObjectFromJson<WorkspacePolicyFragmentDto>();
}
async ValueTask<Option<BinaryData>> tryGetPolicyContents(PolicyFragmentName name, WorkspaceName workspaceName, CancellationToken cancellationToken)
{
var policyFile = WorkspacePolicyFragmentPolicyFile.From(name, workspaceName, serviceDirectory);
return await tryGetFileContents(policyFile.ToFileInfo(), cancellationToken);
}
Option<WorkspacePolicyFragmentDto> tryGetDto(Option<WorkspacePolicyFragmentDto> informationFileDtoOption, Option<BinaryData> policyContentsOption)
{
if (informationFileDtoOption.IsNone && policyContentsOption.IsNone)
{
return Option<WorkspacePolicyFragmentDto>.None;
}
var dto = informationFileDtoOption.IfNone(() => new WorkspacePolicyFragmentDto { Properties = new WorkspacePolicyFragmentDto.PolicyFragmentContract() });
policyContentsOption.Iter(contents => dto = dto with
{
Properties = dto.Properties with
{
Format = "rawxml",
Value = contents.ToString()
}
});
return dto;
}
}
private static void ConfigurePutWorkspacePolicyFragmentInApim(IHostApplicationBuilder builder)
{
AzureModule.ConfigureManagementServiceUri(builder);
AzureModule.ConfigureHttpPipeline(builder);
builder.Services.TryAddSingleton(GetPutWorkspacePolicyFragmentInApim);
}
private static PutWorkspacePolicyFragmentInApim GetPutWorkspacePolicyFragmentInApim(IServiceProvider provider)
{
var serviceUri = provider.GetRequiredService<ManagementServiceUri>();
var pipeline = provider.GetRequiredService<HttpPipeline>();
var logger = provider.GetRequiredService<ILogger>();
return async (name, dto, workspaceName, cancellationToken) =>
{
logger.LogInformation("Adding policy fragment {PolicyFragmentName} to workspace {WorkspaceName}...", name, workspaceName);
await WorkspacePolicyFragmentUri.From(name, workspaceName, serviceUri)
.PutDto(dto, pipeline, cancellationToken);
};
}
public static void ConfigureDeleteWorkspacePolicyFragments(IHostApplicationBuilder builder)
{
CommonModule.ConfigureGetPublisherFiles(builder);
ConfigureTryWorkspaceParsePolicyFragmentName(builder);
ConfigureIsWorkspacePolicyFragmentNameInSourceControl(builder);
ConfigureDeleteWorkspacePolicyFragment(builder);
builder.Services.TryAddSingleton(GetDeleteWorkspacePolicyFragments);
}
private static DeleteWorkspacePolicyFragments GetDeleteWorkspacePolicyFragments(IServiceProvider provider)
{
var getPublisherFiles = provider.GetRequiredService<GetPublisherFiles>();
var tryParseName = provider.GetRequiredService<TryParseWorkspacePolicyFragmentName>();
var isNameInSourceControl = provider.GetRequiredService<IsWorkspacePolicyFragmentNameInSourceControl>();
var delete = provider.GetRequiredService<DeleteWorkspacePolicyFragment>();
var activitySource = provider.GetRequiredService<ActivitySource>();
var logger = provider.GetRequiredService<ILogger>();
return async cancellationToken =>
{
using var _ = activitySource.StartActivity(nameof(DeleteWorkspacePolicyFragments));
logger.LogInformation("Deleting workspace policy fragments...");
await getPublisherFiles()
.Choose(tryParseName.Invoke)
.Where(policyFragment => isNameInSourceControl(policyFragment.Name, policyFragment.WorkspaceName) is false)
.Distinct()
.IterParallel(delete.Invoke, cancellationToken);
};
}
private static void ConfigureDeleteWorkspacePolicyFragment(IHostApplicationBuilder builder)
{
ConfigureDeleteWorkspacePolicyFragmentFromApim(builder);
builder.Services.TryAddSingleton(GetDeleteWorkspacePolicyFragment);
}
private static DeleteWorkspacePolicyFragment GetDeleteWorkspacePolicyFragment(IServiceProvider provider)
{
var deleteFromApim = provider.GetRequiredService<DeleteWorkspacePolicyFragmentFromApim>();
var activitySource = provider.GetRequiredService<ActivitySource>();
return async (name, workspaceName, cancellationToken) =>
{
using var _ = activitySource.StartActivity(nameof(DeleteWorkspacePolicyFragment))
?.AddTag("workspace_policy_fragment.name", name)
?.AddTag("workspace.name", workspaceName);
await deleteFromApim(name, workspaceName, cancellationToken);
};
}
private static void ConfigureDeleteWorkspacePolicyFragmentFromApim(IHostApplicationBuilder builder)
{
AzureModule.ConfigureManagementServiceUri(builder);
AzureModule.ConfigureHttpPipeline(builder);
builder.Services.TryAddSingleton(GetDeleteWorkspacePolicyFragmentFromApim);
}
private static DeleteWorkspacePolicyFragmentFromApim GetDeleteWorkspacePolicyFragmentFromApim(IServiceProvider provider)
{
var serviceUri = provider.GetRequiredService<ManagementServiceUri>();
var pipeline = provider.GetRequiredService<HttpPipeline>();
var logger = provider.GetRequiredService<ILogger>();
return async (name, workspaceName, cancellationToken) =>
{
logger.LogInformation("Removing policy fragment {PolicyFragmentName} from workspace {WorkspaceName}...", name, workspaceName);
await WorkspacePolicyFragmentUri.From(name, workspaceName, serviceUri)
.Delete(pipeline, cancellationToken);
};
}
}