diff --git a/tools/code/common/Gateway.cs b/tools/code/common/Gateway.cs index 1aa789c8..c4c6ea20 100644 --- a/tools/code/common/Gateway.cs +++ b/tools/code/common/Gateway.cs @@ -15,6 +15,8 @@ namespace common; public sealed record GatewayName : ResourceName { + public static GatewayName Managed { get; } = From("managed"); + private GatewayName(string value) : base(value) { } public static GatewayName From(string value) => new(value); @@ -119,6 +121,15 @@ public static Option TryParse(FileInfo? file, Management public sealed record GatewayDto { + public static GatewayDto Managed { get; } = new() + { + Properties = new GatewayContract + { + Description = null, + LocationData = null + } + }; + [JsonPropertyName("properties")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] public required GatewayContract Properties { get; init; } diff --git a/tools/code/extractor/Gateway.cs b/tools/code/extractor/Gateway.cs index 2e83cd1c..32bc8fa1 100644 --- a/tools/code/extractor/Gateway.cs +++ b/tools/code/extractor/Gateway.cs @@ -34,7 +34,10 @@ await list(cancellationToken) private async ValueTask ExtractGateway(GatewayName name, GatewayDto dto, CancellationToken cancellationToken) { - await writeArtifacts(name, dto, cancellationToken); + if (name != GatewayName.Managed) + { + await writeArtifacts(name, dto, cancellationToken); + } await extractGatewayApis(name, cancellationToken); } } @@ -42,7 +45,8 @@ private async ValueTask ExtractGateway(GatewayName name, GatewayDto dto, Cancell file sealed class ListGatewaysHandler(ManagementServiceUri serviceUri, HttpPipeline pipeline) { public IAsyncEnumerable<(GatewayName, GatewayDto)> Handle(CancellationToken cancellationToken) => - GatewaysUri.From(serviceUri).List(pipeline, cancellationToken); + GatewaysUri.From(serviceUri).List(pipeline, cancellationToken) + .Append((GatewayName.Managed, GatewayDto.Managed)); } file sealed class ShouldExtractGatewayHandler(ShouldExtractFactory shouldExtractFactory) diff --git a/tools/code/publisher/Api.cs b/tools/code/publisher/Api.cs index a06fc1a1..718385e5 100644 --- a/tools/code/publisher/Api.cs +++ b/tools/code/publisher/Api.cs @@ -25,7 +25,7 @@ namespace publisher; internal delegate Option FindApiAction(FileInfo file); -file delegate Option TryParseApiName(FileInfo file); +internal delegate Option TryParseApiName(FileInfo file); file delegate ValueTask ProcessApi(ApiName name, CancellationToken cancellationToken); diff --git a/tools/code/publisher/Common.cs b/tools/code/publisher/Common.cs index 2b5d2b9b..1676532f 100644 --- a/tools/code/publisher/Common.cs +++ b/tools/code/publisher/Common.cs @@ -15,6 +15,7 @@ using System.Collections.Frozen; using System.Diagnostics; using System.IO; +using System.Linq; using System.Reflection; using System.Threading; using System.Threading.Tasks; @@ -53,19 +54,43 @@ namespace publisher; file delegate ValueTask> TryGetFileContentsInCommit(FileInfo fileInfo, CommitId commitId, CancellationToken cancellationToken); -file sealed class GetPublisherFilesHandler(TryGetCommitId tryGetCommitId, ManagementServiceDirectory serviceDirectory) +file sealed class GetPublisherFilesHandler(TryGetCommitId tryGetCommitId, TryParseApiName tryParseApiName, ManagementServiceDirectory serviceDirectory) { - private readonly Lazy> lazy = new(() => GetPublisherFiles(tryGetCommitId, serviceDirectory)); + private readonly Lazy> lazy = new(() => GetPublisherFiles(tryGetCommitId, tryParseApiName, serviceDirectory)); public FrozenSet Handle() => lazy.Value; - private static FrozenSet GetPublisherFiles(TryGetCommitId tryGetCommitId, ManagementServiceDirectory serviceDirectory) => + private static FrozenSet GetPublisherFiles(TryGetCommitId tryGetCommitId, TryParseApiName tryParseApiName, + ManagementServiceDirectory serviceDirectory) => tryGetCommitId() - .Map(commitId => GetPublisherFiles(commitId, serviceDirectory)) - .IfNone(serviceDirectory.GetFilesRecursively); + .Map(commitId => GetPublisherFiles(commitId, tryParseApiName, serviceDirectory)) + .IfNone(() => + { + var managedGatewayApis = ApisDirectory.From(serviceDirectory).ToDirectoryInfo() + .ListDirectories("*") + .Map(info => + GatewayApiInformationFile.From(ApiName.From(info.Name), GatewayName.Managed, serviceDirectory) + .ToFileInfo()); + + return serviceDirectory.GetFilesRecursively().ToList() + .Concat(managedGatewayApis) + .ToFrozenSet(x => x.FullName); + }); + + private static FrozenSet GetPublisherFiles(CommitId commitId, TryParseApiName tryParseApiName, + ManagementServiceDirectory serviceDirectory) + { + var changedFiles = Git.GetChangedFilesInCommit(serviceDirectory.ToDirectoryInfo(), commitId).ToList(); - private static FrozenSet GetPublisherFiles(CommitId commitId, ManagementServiceDirectory serviceDirectory) => - Git.GetChangedFilesInCommit(serviceDirectory.ToDirectoryInfo(), commitId); + var managedGatewayApis = changedFiles.Map(x => tryParseApiName(x)) + .Filter(x => x.IsSome) + .Map(x => GatewayApiInformationFile.From(ApiName.GetRootName(x.ValueUnsafe()), GatewayName.Managed, serviceDirectory) + .ToFileInfo()); + + return changedFiles + .Concat(managedGatewayApis) + .ToFrozenSet(x => x.FullName); + } } file sealed class GetArtifactFilesHandler(TryGetCommitId tryGetCommitId, ManagementServiceDirectory serviceDirectory) diff --git a/tools/code/publisher/Gateway.cs b/tools/code/publisher/Gateway.cs index eed83e5e..23898f0d 100644 --- a/tools/code/publisher/Gateway.cs +++ b/tools/code/publisher/Gateway.cs @@ -93,6 +93,11 @@ public async ValueTask Handle(GatewayName name, CancellationToken cancellationTo private async ValueTask HandleInner(GatewayName name, CancellationToken cancellationToken) { + if (name == GatewayName.Managed) + { + return; + } + if (isNameInSourceControl(name)) { await put(name, cancellationToken); diff --git a/tools/code/publisher/GatewayApi.cs b/tools/code/publisher/GatewayApi.cs index 3a3b17b6..a3131e20 100644 --- a/tools/code/publisher/GatewayApi.cs +++ b/tools/code/publisher/GatewayApi.cs @@ -163,7 +163,7 @@ public async ValueTask Handle(ApiName name, GatewayApiDto dto, GatewayName gatew } } -file sealed class DeleteGatewayApiHandler(DeleteGatewayApiFromApim deleteFromApim) : IDisposable +file sealed class DeleteGatewayApiHandler(PutApi putApi, DeleteGatewayApiFromApim deleteFromApim) : IDisposable { private readonly GatewayApiSemaphore semaphore = new(); @@ -172,6 +172,11 @@ public async ValueTask Handle(ApiName name, GatewayName gatewayName, Cancellatio private async ValueTask Delete(ApiName name, GatewayName gatewayName, CancellationToken cancellationToken) { + if (gatewayName == GatewayName.Managed) + { + await putApi(name, cancellationToken); + } + await deleteFromApim(name, gatewayName, cancellationToken); }