private static DeleteWorkspaceApi GetDeleteWorkspaceApi()

in tools/code/publisher/WorkspaceApi.cs [588:653]


    private static DeleteWorkspaceApi GetDeleteWorkspaceApi(IServiceProvider provider)
    {
        var findDto = provider.GetRequiredService<FindWorkspaceApiDto>();
        var deleteFromApim = provider.GetRequiredService<DeleteWorkspaceApiFromApim>();
        var activitySource = provider.GetRequiredService<ActivitySource>();
        var logger = provider.GetRequiredService<ILogger>();

        var taskDictionary = new ConcurrentDictionary<(ApiName, WorkspaceName), AsyncLazy<Unit>>();

        return async (name, workspaceName, cancellationToken) =>
        {
            using var _ = activitySource.StartActivity(nameof(DeleteWorkspaceApi))
                                       ?.AddTag("workspace.name", workspaceName)
                                       ?.AddTag("workspace_api.name", name);

            await taskDictionary.GetOrAdd((name, workspaceName),
                                          pair => new AsyncLazy<Unit>(async cancellationToken =>
                                          {
                                              var (name, workspaceName) = pair;
                                              await deleteApiInner(name, workspaceName, cancellationToken);
                                              return Unit.Default;
                                          }))
                                .WithCancellation(cancellationToken);
        };

        async ValueTask deleteApiInner(ApiName name, WorkspaceName workspaceName, CancellationToken cancellationToken)
        {
            if (await isApiRevisionNumberCurrentInSourceControl(name, workspaceName, cancellationToken))
            {
                logger.LogInformation("API {ApiName} in workspace {WorkspaceName} is the current revision in source control. Skipping deletion...", name, workspaceName);
                return;
            }

            await deleteFromApim(name, workspaceName, cancellationToken);
        }

        /// <summary>
        /// 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 ValueTask<bool> isApiRevisionNumberCurrentInSourceControl(ApiName name, WorkspaceName workspaceName, CancellationToken cancellationToken) =>
            await ApiName.TryParseRevisionedName(name)
                         .Match(async _ => await ValueTask.FromResult(false),
                                async api =>
                                {
                                    var (rootName, revisionNumber) = api;
                                    var sourceControlRevisionNumberOption = await tryGetRevisionNumberInSourceControl(rootName, workspaceName, cancellationToken);
                                    return sourceControlRevisionNumberOption
                                           .Map(sourceControlRevisionNumber => sourceControlRevisionNumber == revisionNumber)
                                           .IfNone(false);
                                });

        async ValueTask<Option<ApiRevisionNumber>> tryGetRevisionNumberInSourceControl(ApiName name, WorkspaceName workspaceName, CancellationToken cancellationToken)
        {
            var dtoOption = await findDto(name, workspaceName, cancellationToken);

            return dtoOption.Map(Common.GetRevisionNumber);
        }
    }