private static DeleteApi GetDeleteApi()

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);
        }
    }