private async Task MigratePhase2()

in Common/Migration/Migrator.cs [59:113]


        private async Task MigratePhase2()
        {
            Logger.LogInformation("Starting migration phase 2");

            IEnumerable<WorkItemMigrationState> successfulWorkItemMigrationStates;

            // when skip existing config flag is on and this work item was existing, continue to next work item.
            if (context.Config.SkipExisting)
            {
                successfulWorkItemMigrationStates = context.WorkItemsMigrationState.Where(a => a.MigrationState == WorkItemMigrationState.State.Create);
            }
            else
            {
                // allow any Create, OR Existing with UpdatePhase2
                successfulWorkItemMigrationStates = context.WorkItemsMigrationState.Where(a => a.MigrationState == WorkItemMigrationState.State.Create || (a.MigrationState == WorkItemMigrationState.State.Existing && a.Requirement.HasFlag(WorkItemMigrationState.RequirementForExisting.UpdatePhase2)));
            }

            var phase2WorkItemsToUpdateCount = successfulWorkItemMigrationStates.Count();
            var totalNumberOfBatches = ClientHelpers.GetBatchCount(phase2WorkItemsToUpdateCount, Constants.BatchSize);

            if (phase2WorkItemsToUpdateCount == 0)
            {
                Logger.LogInformation(LogDestination.File, "No work items to process for phase 2");
                return;
            }

            await successfulWorkItemMigrationStates.Batch(Constants.BatchSize).ForEachAsync(context.Config.Parallelism, async (workItemMigrationStateBatch, batchId) =>
            {
                Logger.LogTrace(LogDestination.File, $"Reading Phase 2 source and target work items for batch {batchId} of {totalNumberOfBatches}");
                // make web call to get source and target work items
                IList<WorkItem> sourceWorkItemsInBatch = await WorkItemTrackingHelpers.GetWorkItemsAsync(context.SourceClient.WorkItemTrackingHttpClient, workItemMigrationStateBatch.Select(a => a.SourceId).ToList(), expand: WorkItemExpand.All);
                IList<WorkItem> targetWorkItemsInBatch = await WorkItemTrackingHelpers.GetWorkItemsAsync(context.TargetClient.WorkItemTrackingHttpClient, workItemMigrationStateBatch.Select(a => a.TargetId.Value).ToList(), expand: WorkItemExpand.Relations);

                IBatchMigrationContext batchContext = new BatchMigrationContext(batchId, workItemMigrationStateBatch);
                batchContext.SourceWorkItemIdToTargetWorkItemIdMapping = workItemMigrationStateBatch.ToDictionary(key => key.SourceId, value => value.TargetId.Value);

                foreach (var sourceWorkItem in sourceWorkItemsInBatch)
                {
                    int targetId = Migrator.GetTargetId(sourceWorkItem.Id.Value, workItemMigrationStateBatch);
                    batchContext.TargetIdToSourceWorkItemMapping.Add(targetId, sourceWorkItem);
                }

                Logger.LogTrace(LogDestination.File, $"Generating Phase 2 json patch operations for batch {batchId} of {totalNumberOfBatches}");
                var sourceIdToWitBatchRequests = await GenerateWitBatchRequestsForPhase2Batch(batchContext, batchId, workItemMigrationStateBatch, sourceWorkItemsInBatch, targetWorkItemsInBatch);

                Logger.LogTrace(LogDestination.File, $"Saving Phase 2 json patch operations for batch {batchId} of {totalNumberOfBatches}");

                var phase2ApiWrapper = new Phase2ApiWrapper();
                await phase2ApiWrapper.ExecuteWitBatchRequests(sourceIdToWitBatchRequests, context, batchContext);

                Logger.LogTrace(LogDestination.File, $"Completed Phase 2 for batch {batchId} of {totalNumberOfBatches}");
            });

            Logger.LogInformation("Completed migration phase 2");
        }