tools/code/publisher/WorkspaceBackend.cs (200 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 PutWorkspaceBackends(CancellationToken cancellationToken);
public delegate ValueTask DeleteWorkspaceBackends(CancellationToken cancellationToken);
public delegate Option<(BackendName Name, WorkspaceName WorkspaceName)> TryParseWorkspaceBackendName(FileInfo file);
public delegate bool IsWorkspaceBackendNameInSourceControl(BackendName name, WorkspaceName workspaceName);
public delegate ValueTask PutWorkspaceBackend(BackendName name, WorkspaceName workspaceName, CancellationToken cancellationToken);
public delegate ValueTask<Option<WorkspaceBackendDto>> FindWorkspaceBackendDto(BackendName name, WorkspaceName workspaceName, CancellationToken cancellationToken);
public delegate ValueTask PutWorkspaceBackendInApim(BackendName name, WorkspaceBackendDto dto, WorkspaceName workspaceName, CancellationToken cancellationToken);
public delegate ValueTask DeleteWorkspaceBackend(BackendName name, WorkspaceName workspaceName, CancellationToken cancellationToken);
public delegate ValueTask DeleteWorkspaceBackendFromApim(BackendName name, WorkspaceName workspaceName, CancellationToken cancellationToken);
internal static class WorkspaceBackendModule
{
public static void ConfigurePutWorkspaceBackends(IHostApplicationBuilder builder)
{
CommonModule.ConfigureGetPublisherFiles(builder);
ConfigureTryParseWorkspaceBackendName(builder);
ConfigureIsWorkspaceBackendNameInSourceControl(builder);
ConfigurePutWorkspaceBackend(builder);
builder.Services.TryAddSingleton(GetPutWorkspaceBackends);
}
private static PutWorkspaceBackends GetPutWorkspaceBackends(IServiceProvider provider)
{
var getPublisherFiles = provider.GetRequiredService<GetPublisherFiles>();
var tryParseName = provider.GetRequiredService<TryParseWorkspaceBackendName>();
var isNameInSourceControl = provider.GetRequiredService<IsWorkspaceBackendNameInSourceControl>();
var put = provider.GetRequiredService<PutWorkspaceBackend>();
var activitySource = provider.GetRequiredService<ActivitySource>();
var logger = provider.GetRequiredService<ILogger>();
return async cancellationToken =>
{
using var _ = activitySource.StartActivity(nameof(PutWorkspaceBackends));
logger.LogInformation("Putting workspace backends...");
await getPublisherFiles()
.Choose(tryParseName.Invoke)
.Where(resource => isNameInSourceControl(resource.Name, resource.WorkspaceName))
.Distinct()
.IterParallel(put.Invoke, cancellationToken);
};
}
private static void ConfigureTryParseWorkspaceBackendName(IHostApplicationBuilder builder)
{
AzureModule.ConfigureManagementServiceDirectory(builder);
builder.Services.TryAddSingleton(GetTryParseWorkspaceBackendName);
}
private static TryParseWorkspaceBackendName GetTryParseWorkspaceBackendName(IServiceProvider provider)
{
var serviceDirectory = provider.GetRequiredService<ManagementServiceDirectory>();
return file => from informationFile in WorkspaceBackendInformationFile.TryParse(file, serviceDirectory)
select (informationFile.Parent.Name, informationFile.Parent.Parent.Parent.Name);
}
private static void ConfigureIsWorkspaceBackendNameInSourceControl(IHostApplicationBuilder builder)
{
CommonModule.ConfigureGetArtifactFiles(builder);
AzureModule.ConfigureManagementServiceDirectory(builder);
builder.Services.TryAddSingleton(GetIsWorkspaceBackendNameInSourceControl);
}
private static IsWorkspaceBackendNameInSourceControl GetIsWorkspaceBackendNameInSourceControl(IServiceProvider provider)
{
var getArtifactFiles = provider.GetRequiredService<GetArtifactFiles>();
var serviceDirectory = provider.GetRequiredService<ManagementServiceDirectory>();
return doesInformationFileExist;
bool doesInformationFileExist(BackendName name, WorkspaceName workspaceName)
{
var artifactFiles = getArtifactFiles();
var informationFile = WorkspaceBackendInformationFile.From(name, workspaceName, serviceDirectory);
return artifactFiles.Contains(informationFile.ToFileInfo());
}
}
private static void ConfigurePutWorkspaceBackend(IHostApplicationBuilder builder)
{
ConfigureFindWorkspaceBackendDto(builder);
ConfigurePutWorkspaceBackendInApim(builder);
builder.Services.TryAddSingleton(GetPutWorkspaceBackend);
}
private static PutWorkspaceBackend GetPutWorkspaceBackend(IServiceProvider provider)
{
var findDto = provider.GetRequiredService<FindWorkspaceBackendDto>();
var putInApim = provider.GetRequiredService<PutWorkspaceBackendInApim>();
var activitySource = provider.GetRequiredService<ActivitySource>();
return async (name, workspaceName, cancellationToken) =>
{
using var _ = activitySource.StartActivity(nameof(PutWorkspaceBackend))
?.AddTag("workspace.name", workspaceName)
?.AddTag("workspace_backend.name", name);
var dtoOption = await findDto(name, workspaceName, cancellationToken);
await dtoOption.IterTask(async dto => await putInApim(name, dto, workspaceName, cancellationToken));
};
}
private static void ConfigureFindWorkspaceBackendDto(IHostApplicationBuilder builder)
{
AzureModule.ConfigureManagementServiceDirectory(builder);
CommonModule.ConfigureTryGetFileContents(builder);
builder.Services.TryAddSingleton(GetFindWorkspaceBackendDto);
}
private static FindWorkspaceBackendDto GetFindWorkspaceBackendDto(IServiceProvider provider)
{
var serviceDirectory = provider.GetRequiredService<ManagementServiceDirectory>();
var tryGetFileContents = provider.GetRequiredService<TryGetFileContents>();
return async (name, workspaceName, cancellationToken) =>
{
var informationFile = WorkspaceBackendInformationFile.From(name, workspaceName, serviceDirectory);
var contentsOption = await tryGetFileContents(informationFile.ToFileInfo(), cancellationToken);
return from contents in contentsOption
select contents.ToObjectFromJson<WorkspaceBackendDto>();
};
}
private static void ConfigurePutWorkspaceBackendInApim(IHostApplicationBuilder builder)
{
AzureModule.ConfigureManagementServiceUri(builder);
AzureModule.ConfigureHttpPipeline(builder);
builder.Services.TryAddSingleton(GetPutWorkspaceBackendInApim);
}
private static PutWorkspaceBackendInApim GetPutWorkspaceBackendInApim(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 backend {BackendName} to workspace {WorkspaceName}...", name, workspaceName);
var resourceUri = WorkspaceBackendUri.From(name, workspaceName, serviceUri);
await resourceUri.PutDto(dto, pipeline, cancellationToken);
};
}
public static void ConfigureDeleteWorkspaceBackends(IHostApplicationBuilder builder)
{
CommonModule.ConfigureGetPublisherFiles(builder);
ConfigureTryParseWorkspaceBackendName(builder);
ConfigureIsWorkspaceBackendNameInSourceControl(builder);
ConfigureDeleteWorkspaceBackend(builder);
builder.Services.TryAddSingleton(GetDeleteWorkspaceBackends);
}
private static DeleteWorkspaceBackends GetDeleteWorkspaceBackends(IServiceProvider provider)
{
var getPublisherFiles = provider.GetRequiredService<GetPublisherFiles>();
var tryParseName = provider.GetRequiredService<TryParseWorkspaceBackendName>();
var isNameInSourceControl = provider.GetRequiredService<IsWorkspaceBackendNameInSourceControl>();
var delete = provider.GetRequiredService<DeleteWorkspaceBackend>();
var activitySource = provider.GetRequiredService<ActivitySource>();
var logger = provider.GetRequiredService<ILogger>();
return async cancellationToken =>
{
using var _ = activitySource.StartActivity(nameof(DeleteWorkspaceBackends));
logger.LogInformation("Deleting workspace backends...");
await getPublisherFiles()
.Choose(tryParseName.Invoke)
.Where(resource => isNameInSourceControl(resource.Name, resource.WorkspaceName) is false)
.Distinct()
.IterParallel(delete.Invoke, cancellationToken);
};
}
private static void ConfigureDeleteWorkspaceBackend(IHostApplicationBuilder builder)
{
ConfigureDeleteWorkspaceBackendFromApim(builder);
builder.Services.TryAddSingleton(GetDeleteWorkspaceBackend);
}
private static DeleteWorkspaceBackend GetDeleteWorkspaceBackend(IServiceProvider provider)
{
var deleteFromApim = provider.GetRequiredService<DeleteWorkspaceBackendFromApim>();
var activitySource = provider.GetRequiredService<ActivitySource>();
return async (name, workspaceName, cancellationToken) =>
{
using var _ = activitySource.StartActivity(nameof(DeleteWorkspaceBackend))
?.AddTag("workspace.name", workspaceName)
?.AddTag("workspace_backend.name", name);
await deleteFromApim(name, workspaceName, cancellationToken);
};
}
private static void ConfigureDeleteWorkspaceBackendFromApim(IHostApplicationBuilder builder)
{
AzureModule.ConfigureManagementServiceUri(builder);
AzureModule.ConfigureHttpPipeline(builder);
builder.Services.TryAddSingleton(GetDeleteWorkspaceBackendFromApim);
}
private static DeleteWorkspaceBackendFromApim GetDeleteWorkspaceBackendFromApim(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 backend {BackendName} from workspace {WorkspaceName}...", name, workspaceName);
var resourceUri = WorkspaceBackendUri.From(name, workspaceName, serviceUri);
await resourceUri.Delete(pipeline, cancellationToken);
};
}
}