Beispiel #1
0
        internal IQueryable <RTConflict> GetActiveConflicts(Guid sessionGroupUniqueId)
        {
            RuntimeEntityModel context = RuntimeEntityModel.CreateInstance();

            // hidden conflicts
            Guid chainOnBackloggedItemConflictTypeRefName = new ChainOnBackloggedItemConflictType().ReferenceName; // A7EFC8C6-A6CF-45e7-BFA6-471942A54F37
            Guid chainOnConflictConflictTypeRefName       = Constants.chainOnConflictConflictTypeRefName;          //F6BFB484-EE70-4ffc-AAB3-4F659B0CAF7F

            // runtime conflicts
            Guid witGeneralConflictTypeRefName = Constants.witGeneralConflictTypeRefName; //470F9617-FC96-4166-96EB-44CC2CF73A97
            Guid generalConflictTypeRefName    = new GenericConflictType().ReferenceName; // F6DAB314-2792-40D9-86CC-B40F5B827D86

            var conflictQuery =
                from c in context.RTConflictSet
                where (c.InCollection.SessionGroupRun.Config.SessionGroup.GroupUniqueId.Equals(sessionGroupUniqueId) ||
                       c.InCollection.SessionRun.SessionGroupRun.Config.SessionGroup.GroupUniqueId.Equals(sessionGroupUniqueId)) &&
                c.Status == 0 && // only search for active conflicts
                !c.ConflictType.ReferenceName.Equals(chainOnBackloggedItemConflictTypeRefName) &&
                !c.ConflictType.ReferenceName.Equals(chainOnConflictConflictTypeRefName) &&
                !c.ConflictType.ReferenceName.Equals(witGeneralConflictTypeRefName) &&
                !c.ConflictType.ReferenceName.Equals(generalConflictTypeRefName)
                select c;

            return(conflictQuery);
        }
        /// <summary>
        /// Determine if an action's source item is in backlog, if so, backlog the action
        /// </summary>
        /// <param name="conflictManager"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        private bool IsSourceWorkItemInBacklog(
            IMigrationAction action)
        {
            string sourceSideItemId = action.FromPath;

            Debug.Assert(!string.IsNullOrEmpty(sourceSideItemId), "Work Item Id is not available in conflict details");

            // look up in backlog db table
            bool workItemInBacklog = m_conflictManagerService.IsItemInBacklog(sourceSideItemId);

            if (workItemInBacklog)
            {
                MigrationConflict chainedConflict = new ChainOnBackloggedItemConflictType().CreateConflict(
                    ChainOnBackloggedItemConflictType.CreateConflictDetails(sourceSideItemId, action.Version),
                    ChainOnBackloggedItemConflictType.CreateScopeHint(sourceSideItemId),
                    action);

                // previous revision of the work item has conflict, push this revision to backlog as well
                m_conflictManagerService.BacklogUnresolvedConflict(m_conflictManagerService.SourceId, chainedConflict, true);
            }

            return(workItemInBacklog);
        }
Beispiel #3
0
        private void FlattenDeltaTable(
            List <string> outMappedWorkItemUpdates,
            Dictionary <string, List <MigrationAction> > outMappedAttachmentUpdates,
            bool getSourceSideCopyInMigrationInstructionTable)
        {
            Guid sourceId = getSourceSideCopyInMigrationInstructionTable ?
                            SourceSystemId : TargetSystemId;
            Guid targetId = getSourceSideCopyInMigrationInstructionTable ?
                            TargetSystemId : SourceSystemId;

            int pageNumber = 0;
            int pageSize   = 50;
            IEnumerable <ChangeGroup> changeGroups = null;

            do
            {
                changeGroups = getSourceSideCopyInMigrationInstructionTable ?
                               TargetChangeGroupService.NextMigrationInstructionTablePage(pageNumber++, pageSize, true, true)
                    : TargetChangeGroupService.NextDeltaTablePage(pageNumber++, pageSize, true);
                foreach (ChangeGroup changeGroupEntry in changeGroups)
                {
                    foreach (MigrationAction action in changeGroupEntry.Actions)
                    {
                        if (action.Action.Equals(WellKnownChangeActionId.SyncContext))
                        {
                            continue;
                        }

                        else if (action.Action == WellKnownChangeActionId.Add)
                        {
                            // do nothing for adding item, be it created by sync engine or not
                            continue;
                        }

                        else if (action.Action == WellKnownChangeActionId.Edit)
                        {
                            string sourceSideItemId = GetSourceWorkItemIdFromActionDescription(action.MigrationActionDescription);
                            string targetWorkItemId = TryGetTargetWorkItemId(
                                action.MigrationActionDescription,
                                sourceId,
                                getSourceSideCopyInMigrationInstructionTable);
                            if (string.IsNullOrEmpty(targetWorkItemId))
                            {
                                // the source work item has never been migrated yet
                                continue;
                            }

                            if (getSourceSideCopyInMigrationInstructionTable)
                            {
                                if (ConflictManager.IsItemInBacklog(sourceId, targetId, sourceSideItemId))
                                {
                                    // previous revision of the work item has conflict, push this revision to backlog as well
                                    string conflictDetails = ChainOnBackloggedItemConflictType.CreateConflictDetails(sourceSideItemId, action.Version);
                                    string scopeHint       = ChainOnBackloggedItemConflictType.CreateScopeHint(sourceSideItemId);

                                    if (changeGroupEntry.ReflectedChangeGroupId.HasValue)
                                    {
                                        // we reactivate the original delta entry and discard this migration instruction entry
                                        // and then backlog the delta entry, to preserve correct order of the revisions
                                        ChangeGroup deltaChangeGroupEntry = TargetChangeGroupService.ReactivateDeltaEntry(changeGroupEntry);

                                        if (null != deltaChangeGroupEntry)
                                        {
                                            MigrationConflict chainedConflict = new ChainOnBackloggedItemConflictType().CreateConflict(
                                                conflictDetails,
                                                scopeHint,
                                                deltaChangeGroupEntry.Actions.First());

                                            ConflictManager.BacklogUnresolvedConflict(ConflictManager.SourceId, chainedConflict, false);
                                            break;
                                        }
                                    }

                                    // if we can't find the original delta entry successfully, we block this migration instruction entry
                                    MigrationConflict conflict = new ChainOnBackloggedItemConflictType().CreateConflict(
                                        conflictDetails,
                                        scopeHint,
                                        action);

                                    ConflictManager.BacklogUnresolvedConflict(ConflictManager.SourceId, conflict, false);

                                    if (!m_conflictedWorkItems[targetId].Contains(targetWorkItemId))
                                    {
                                        // record the target-side work item to be in conflict
                                        m_conflictedWorkItems[targetId].Add(targetWorkItemId);
                                    }
                                    break;
                                }

                                if (!m_perMappedItemEdits.ContainsKey(m_targetToSourceWorkItemIdMapping[targetWorkItemId]))
                                {
                                    m_perMappedItemEdits.Add(m_targetToSourceWorkItemIdMapping[targetWorkItemId], new List <MigrationAction>());
                                }
                                m_perMappedItemEdits[m_targetToSourceWorkItemIdMapping[targetWorkItemId]].Add(action);
                            }
                            else
                            {
                                // check if the revision is a sync copy from the other side
                                if (TranslationService.IsSyncGeneratedAction(action, sourceId))
                                {
                                    continue;
                                }

                                if (m_conflictedWorkItems[sourceId].Contains(sourceSideItemId))
                                {
                                    string            conflictDetails = ChainOnBackloggedItemConflictType.CreateConflictDetails(sourceSideItemId, action.Version);
                                    string            scopeHint       = ChainOnBackloggedItemConflictType.CreateScopeHint(sourceSideItemId);
                                    MigrationConflict conflict        = new ChainOnBackloggedItemConflictType().CreateConflict(
                                        conflictDetails,
                                        scopeHint,
                                        action);

                                    ConflictManager.BacklogUnresolvedConflict(TargetSystemId, conflict, false);
                                    break;
                                }

                                if (!m_perMappedItemEditsTargetDelta.ContainsKey(targetWorkItemId))
                                {
                                    m_perMappedItemEditsTargetDelta.Add(targetWorkItemId, new List <MigrationAction>());
                                }
                                m_perMappedItemEditsTargetDelta[targetWorkItemId].Add(action);
                            }

                            // item is mapped to an item on target system
                            if (!outMappedWorkItemUpdates.Contains(targetWorkItemId))
                            {
                                outMappedWorkItemUpdates.Add(targetWorkItemId);
                            }
                        }

                        else if (action.Action == WellKnownChangeActionId.AddAttachment)
                        {
                            string targetWorkItemId = TryGetTargetWorkItemId(
                                action.MigrationActionDescription,
                                sourceId,
                                getSourceSideCopyInMigrationInstructionTable);

                            if (string.IsNullOrEmpty(targetWorkItemId))
                            {
                                continue;
                            }

                            if (!outMappedAttachmentUpdates.ContainsKey(targetWorkItemId))
                            {
                                outMappedAttachmentUpdates.Add(targetWorkItemId, new List <MigrationAction>());
                            }

                            List <MigrationAction> attachmentList = outMappedAttachmentUpdates[targetWorkItemId];

                            IMigrationFileAttachment sourceItem = action.SourceItem as IMigrationFileAttachment;
                            if (null == sourceItem)
                            {
                                throw new MigrationException(MigrationToolkitResources.InvalidSourceItemForAttachmentOperation);
                            }
                            if (!attachmentList.Contains(action))
                            {
                                attachmentList.Add(action);
                            }
                        }

                        else if (action.Action == WellKnownChangeActionId.DelAttachment)
                        {
                            // do nothing for now
                            continue;
                        }
                    }
                }
            }while (changeGroups.Count() > 0);
        }
Beispiel #4
0
        private void TryResolvePerWorkItemConflicts(
            string targetWiId)
        {
            string sourceSideItemId = m_targetToSourceWorkItemIdMapping[targetWiId];

            TraceManager.TraceInformation("Edit/Edit conflicted work item: {0}", sourceSideItemId);

            int  editeditConflictId         = int.MinValue;
            bool previousConflictIsResolved = true;

            foreach (var migrInstrActionFromSource in m_perMappedItemEdits[sourceSideItemId])
            {
                if (!previousConflictIsResolved)
                {
                    // previous revision of the work item has conflict, push *this revision to backlog as well
                    // *: this revision (migration instruction) will be obsoleted and the corresponding delta entry reactived
                    ChangeGroup migrationInstructionEntry = migrInstrActionFromSource.ChangeGroup;
                    ChangeGroup entryToBlock = null;
                    if (migrationInstructionEntry.ReflectedChangeGroupId.HasValue)
                    {
                        entryToBlock = TargetChangeGroupService.ReactivateDeltaEntry(migrationInstructionEntry);
                    }

                    if (entryToBlock == null)
                    {
                        entryToBlock = migrationInstructionEntry;
                    }

                    if (entryToBlock.Actions.Count <= 0)
                    {
                        continue;
                    }

                    // an edit/edit conflict must have been backlogged already
                    Debug.Assert(editeditConflictId != int.MinValue, "Edit/edit conflict Id is not available");

                    string            conflictDetails = ChainOnBackloggedItemConflictType.CreateConflictDetails(sourceSideItemId, migrInstrActionFromSource.Version);
                    string            scopeHint       = ChainOnBackloggedItemConflictType.CreateScopeHint(sourceSideItemId);
                    MigrationConflict chainedConflict = new ChainOnBackloggedItemConflictType().CreateConflict(conflictDetails, scopeHint, entryToBlock.Actions.First());
                    ConflictManager.BacklogUnresolvedConflict(ConflictManager.SourceId, chainedConflict, false);
                }
                else
                {
                    ChangeGroup sourceGroupForResolution = null;
                    if (migrInstrActionFromSource.ChangeGroup.ReflectedChangeGroupId.HasValue)
                    {
                        sourceGroupForResolution = TargetChangeGroupService.ReactivateDeltaEntry(migrInstrActionFromSource.ChangeGroup);
                    }

                    if (sourceGroupForResolution == null)
                    {
                        sourceGroupForResolution = migrInstrActionFromSource.ChangeGroup;
                    }
                    ConflictResolutionResult resolutionResult = TryResolveSingleRevConflict(sourceSideItemId,
                                                                                            sourceGroupForResolution.Actions.First(),
                                                                                            targetWiId,
                                                                                            m_perMappedItemEditsTargetDelta[targetWiId]);
                    previousConflictIsResolved = resolutionResult.Resolved;

                    if (previousConflictIsResolved)
                    {
                        // conflict is auto-resolved,
                        // obsolete the reactivated delta entry and reactivate the migration instruction
                        if (sourceGroupForResolution.Status != ChangeStatus.Skipped &&
                            sourceGroupForResolution != migrInstrActionFromSource.ChangeGroup)
                        {
                            TargetChangeGroupService.ReactivateMigrationInstruction(migrInstrActionFromSource.ChangeGroup,
                                                                                    sourceGroupForResolution);
                        }

                        continue;
                    }
                    else
                    {
                        // save the persisted unresolved conflict id, so that the following changes can "chain-on" it
                        editeditConflictId = resolutionResult.ConflictInternalId;
                    }
                }
            }

            if (!previousConflictIsResolved)
            {
                bool chainOnBackloggedItemConflictIsCreated = false;
                foreach (var targetAction in m_perMappedItemEditsTargetDelta[targetWiId])
                {
                    Debug.Assert(editeditConflictId != int.MinValue, "Edit/edit conflict Id is not available");
                    MigrationConflict chainedConflict = new ChainOnConflictConflictType().CreateConflict(
                        ChainOnConflictConflictType.CreateConflictDetails(editeditConflictId),
                        ChainOnConflictConflictType.CreateScopeHint(editeditConflictId),
                        targetAction);
                    // action is from the target system, use the TargetSystem migration source Id
                    ConflictManager.BacklogUnresolvedConflict(TargetSystemId, chainedConflict, false);

                    if (!chainOnBackloggedItemConflictIsCreated)
                    {
                        string            conflictDetails = ChainOnBackloggedItemConflictType.CreateConflictDetails(targetWiId, targetAction.Version);
                        string            scopeHint       = ChainOnBackloggedItemConflictType.CreateScopeHint(sourceSideItemId);
                        MigrationConflict conflict        = new ChainOnBackloggedItemConflictType().CreateConflict(conflictDetails, scopeHint, targetAction);
                        ConflictManager.BacklogUnresolvedConflict(TargetSystemId, conflict, false);

                        chainOnBackloggedItemConflictIsCreated = true;
                    }
                }
            }
        }