in tools/code/publisher/Api.cs [598:664]
private static DeleteApi GetDeleteApi(IServiceProvider provider)
{
var findDto = provider.GetRequiredService<FindApiInformationFileDto>();
var deleteFromApim = provider.GetRequiredService<DeleteApiFromApim>();
var activitySource = provider.GetRequiredService<ActivitySource>();
var logger = provider.GetRequiredService<ILogger>();
var taskDictionary = new ConcurrentDictionary<ApiName, AsyncLazy<Unit>>();
return deleteApi;
async ValueTask deleteApi(ApiName name, CancellationToken cancellationToken)
{
using var _ = activitySource.StartActivity(nameof(DeleteApi))
?.AddTag("api.name", name);
await taskDictionary.GetOrAdd(name,
name => new AsyncLazy<Unit>(async cancellationToken =>
{
await deleteApiInner(name, cancellationToken);
return Unit.Default;
}))
.WithCancellation(cancellationToken);
};
async ValueTask deleteApiInner(ApiName name, CancellationToken cancellationToken) =>
await ApiName.TryParseRevisionedName(name)
.Map(async api => await processRevisionedApi(api.RootName, api.RevisionNumber, cancellationToken))
.IfLeft(async _ => await processRootApi(name, cancellationToken));
async ValueTask processRootApi(ApiName name, CancellationToken cancellationToken) =>
await deleteFromApim(name, cancellationToken);
async ValueTask processRevisionedApi(ApiName name, ApiRevisionNumber revisionNumber, CancellationToken cancellationToken)
{
var rootName = ApiName.GetRootName(name);
var currentRevisionNumberOption = await tryGetRevisionNumberInSourceControl(rootName, cancellationToken);
await currentRevisionNumberOption.Match(// If the current revision in source control has a different revision number, delete this revision.
// We don't want to delete a revision if it was just made current. For instance:
// 1. Dev has apiA with revision 1 (current) and revision 2. Artifacts folder has:
// - /apis/apiA/apiInformation.json with revision 1 as current
// - /apis/apiA;rev=2/apiInformation.json
// 2. User makes revision 2 current in dev APIM.
// 3. User runs extractor for dev APIM. Artifacts folder has:
// - /apis/apiA/apiInformation.json with revision 2 as current
// - /apis/apiA;rev=1/apiInformation.json
// - /apis/apiA;rev=2 folder gets deleted.
// 4. User runs publisher to prod APIM. We don't want to handle the deletion of folder /apis/apiA;rev=2, as it's the current revision.
async currentRevisionNumber =>
{
if (currentRevisionNumber != revisionNumber)
{
await deleteFromApim(name, cancellationToken);
}
},
// If there is no current revision in source control, process the root API deletion
async () => await deleteApi(rootName, cancellationToken));
}
async ValueTask<Option<ApiRevisionNumber>> tryGetRevisionNumberInSourceControl(ApiName name, CancellationToken cancellationToken)
{
var dtoOption = await findDto(name, cancellationToken);
return dtoOption.Map(Common.GetRevisionNumber);
}
}