예제 #1
0
        protected override void SubmitLinkChangesWithUpdateDoc(
            LinkChangeGroup linkChanges,
            ServiceContainer serviceContainer,
            TfsLinkingProviderBase.LinkSubmissionPhase submissionPhase)
        {
            ConfigurationService configService      = serviceContainer.GetService(typeof(ConfigurationService)) as ConfigurationService;
            ITranslationService  translationService = serviceContainer.GetService(typeof(ITranslationService)) as ITranslationService;

            bool nonWorkItemLinkChangesAllSubmitted = SubmitNonWorkItemLinkChanges(
                linkChanges, serviceContainer, configService, translationService, submissionPhase);
            bool workItemLinkChangesAllSubmitted = SubmitWorkItemLinkChanges(
                linkChanges, serviceContainer, configService, translationService, submissionPhase);

            linkChanges.Status = (nonWorkItemLinkChangesAllSubmitted && workItemLinkChangesAllSubmitted && AllActionSubmitted(linkChanges))
                                     ? LinkChangeGroup.LinkChangeGroupStatus.Completed
                                     : LinkChangeGroup.LinkChangeGroupStatus.ReadyForMigration;
        }
        protected override void SubmitLinkChangesWithUpdateDoc(
            LinkChangeGroup linkChanges,
            ServiceContainer serviceContainer,
            TfsLinkingProviderBase.LinkSubmissionPhase submissionPhase)
        {
            ConfigurationService configService      = serviceContainer.GetService(typeof(ConfigurationService)) as ConfigurationService;
            ITranslationService  translationService = serviceContainer.GetService(typeof(ITranslationService)) as ITranslationService;

            if (m_hwmSubmittedLinkChangeId == null)
            {
                m_hwmSubmittedLinkChangeId = new HighWaterMark <long>(TfsConstants.HwmSubmittedLinkChangeId);
                configService.RegisterHighWaterMarkWithSession(m_hwmSubmittedLinkChangeId);
            }

            bool nonWorkItemLinkChangesAllSubmitted = SubmitNonWorkItemLinkChanges(
                linkChanges, serviceContainer, configService, translationService, submissionPhase);
            bool workItemLinkChangesAllSubmitted = SubmitWorkItemLinkChanges(
                linkChanges, serviceContainer, configService, translationService, submissionPhase);

            linkChanges.Status = (nonWorkItemLinkChangesAllSubmitted && workItemLinkChangesAllSubmitted && AllActionSubmitted(linkChanges))
                                     ? LinkChangeGroup.LinkChangeGroupStatus.Completed
                                     : LinkChangeGroup.LinkChangeGroupStatus.ReadyForMigration;
        }
        protected bool SubmitNonWorkItemLinkChanges(
            LinkChangeGroup linkChanges,
            ServiceContainer serviceContainer,
            ConfigurationService configService,
            ITranslationService translationService,
            TfsLinkingProviderBase.LinkSubmissionPhase submissionPhase)
        {
            // group non-WorkItemLink changes by work item Id
            Dictionary <int, List <LinkChangeAction> > perWorkItemLinkChanges = RegroupLinkChangeActions(linkChanges);
            var orderedWorkitemId = new Dictionary <int, int>();
            int index             = 0;

            foreach (int workItemId in perWorkItemLinkChanges.Keys)
            {
                orderedWorkitemId.Add(index++, workItemId);
            }

            // batch-submit links of each work item
            var updateDocs = new List <XmlDocument>(perWorkItemLinkChanges.Count);

            foreach (var perWorkItemLinkChange in perWorkItemLinkChanges)
            {
                if (perWorkItemLinkChange.Value.Count == 0)
                {
                    continue;
                }

                WorkItem workItem = WorkItemStore.GetWorkItem(perWorkItemLinkChange.Key);

                var tfsUpdateDocument = InitializeUpdateDocument();
                tfsUpdateDocument.CreateWorkItemUpdateDoc(workItem);
                bool hasNonWorkItemLinkChanges = false;
                foreach (LinkChangeAction linkChangeAction in perWorkItemLinkChange.Value)
                {
                    if (linkChangeAction.Status != LinkChangeAction.LinkChangeActionStatus.ReadyForMigration ||
                        linkChangeAction.IsConflicted ||
                        linkChangeAction.Link.LinkType is WorkItemLinkTypeBase)
                    {
                        continue;
                    }

                    if (!ProcessActionInCurrentSubmissionPhase(linkChangeAction, submissionPhase))
                    {
                        continue;
                    }

                    hasNonWorkItemLinkChanges = true;
                    var handler = linkChangeAction.Link.LinkType as ILinkHandler;
                    Debug.Assert(null != handler);
                    handler.UpdateTfs(tfsUpdateDocument, linkChangeAction);
                }

                if (hasNonWorkItemLinkChanges)
                {
                    updateDocs.Add(tfsUpdateDocument.UpdateDocument);
                }
            }

            if (updateDocs.Count == 0)
            {
                return(true);
            }

            UpdateResult[] results = TfsBatchUpdateHelper.Submit(Core, WorkItemServer, updateDocs.ToArray());

            if (results.Length != updateDocs.Count)
            {
                throw new SynchronizationEngineException("Wrong number of link update results.");
            }

            bool succeeded = true;

            for (int i = 0; i < results.Length; ++i)
            {
                UpdateResult rslt = results[i];

                if (rslt.Exception != null &&
                    !rslt.Exception.Message.Contains("The specified link already exists"))
                {
                    TraceManager.TraceError(rslt.Exception.ToString());
                    succeeded = false;
                    // TODO
                    // Try resolve conflict and push to backlog if resolution fails
                    foreach (LinkChangeAction action in perWorkItemLinkChanges[orderedWorkitemId[i]])
                    {
                        action.IsConflicted = true;
                    }
                }
                else
                {
                    foreach (LinkChangeAction action in perWorkItemLinkChanges[orderedWorkitemId[i]])
                    {
                        if (ProcessActionInCurrentSubmissionPhase(action, submissionPhase))
                        {
                            MarkLinkChangeActionCompleted(action);
                        }
                    }

                    if (rslt.Exception == null)
                    {
                        UpdateLinkConversionHistory(configService, translationService, rslt, perWorkItemLinkChanges[orderedWorkitemId[i]]);
                    }
                    else if (rslt.Exception.Message.Contains("The specified link already exists"))
                    {
                        WorkItemLinkStore relatedArtifactsStore = new WorkItemLinkStore(configService.SourceId);
                        relatedArtifactsStore.UpdateSyncedLinks(perWorkItemLinkChanges[orderedWorkitemId[i]]);
                    }
                }
            }
            return(succeeded);
        }
        private bool SubmitWorkItemLinkChanges(
            LinkChangeGroup linkChanges,
            ServiceContainer serviceContainer,
            ConfigurationService configService,
            ITranslationService translationService,
            TfsLinkingProviderBase.LinkSubmissionPhase submissionPhase)
        {
            var linkChangeActions = ExtractWorkItemLinkChanges(linkChanges);

            if (linkChangeActions.Count == 0)
            {
                return(true);
            }

            ConflictManager conflictManageer         = serviceContainer.GetService(typeof(ConflictManager)) as ConflictManager;
            var             updatedocsForEditLinks   = new List <XmlDocument>(linkChangeActions.Count);
            var             updateDocsForAddLinks    = new List <XmlDocument>(linkChangeActions.Count);
            var             updateDocsForDeleteLinks = new List <XmlDocument>(linkChangeActions.Count);
            Dictionary <int, LinkChangeAction> docForEditlinksToActionMap   = new Dictionary <int, LinkChangeAction>();
            Dictionary <int, LinkChangeAction> docForAddlinksToActionMap    = new Dictionary <int, LinkChangeAction>();
            Dictionary <int, LinkChangeAction> docForDeletelinksToActionMap = new Dictionary <int, LinkChangeAction>();

            for (int i = 0; i < linkChangeActions.Count; ++i)
            {
                if (linkChangeActions[i].Status != LinkChangeAction.LinkChangeActionStatus.ReadyForMigration ||
                    linkChangeActions[i].IsConflicted)
                {
                    continue;
                }

                if (!ProcessActionInCurrentSubmissionPhase(linkChangeActions[i], submissionPhase))
                {
                    continue;
                }

                var tfsUpdateDocument = InitializeUpdateDocument();

                var handler = linkChangeActions[i].Link.LinkType as ILinkHandler;
                Debug.Assert(null != handler);

                handler.UpdateTfs(tfsUpdateDocument, linkChangeActions[i]);

                if (linkChangeActions[i].ChangeActionId.Equals(WellKnownChangeActionId.Add))
                {
                    docForAddlinksToActionMap.Add(updateDocsForAddLinks.Count, linkChangeActions[i]);
                    updateDocsForAddLinks.Add(tfsUpdateDocument.UpdateDocument);
                }
                else if (linkChangeActions[i].ChangeActionId.Equals(WellKnownChangeActionId.Delete))
                {
                    docForDeletelinksToActionMap.Add(updateDocsForDeleteLinks.Count, linkChangeActions[i]);
                    updateDocsForDeleteLinks.Add(tfsUpdateDocument.UpdateDocument);
                }
                else if (linkChangeActions[i].ChangeActionId.Equals(WellKnownChangeActionId.Edit))
                {
                    docForEditlinksToActionMap.Add(updatedocsForEditLinks.Count, linkChangeActions[i]);
                    updatedocsForEditLinks.Add(tfsUpdateDocument.UpdateDocument);
                }
                else
                {
                    TraceManager.TraceVerbose("Change action '{0}' in Link Change Group '{1}' is not supported.",
                                              linkChangeActions[i].ChangeActionId.ToString(), linkChanges.GroupName);
                    linkChangeActions[i].Status = LinkChangeAction.LinkChangeActionStatus.Completed;
                }
            }

            bool succeeded = true;

            if (updatedocsForEditLinks.Count > 0)
            {
                succeeded &= SubmitBatchedAddOrDeleteLinkChanges(
                    updatedocsForEditLinks, docForEditlinksToActionMap, translationService, configService, conflictManageer);
            }
            if (updateDocsForDeleteLinks.Count > 0)
            {
                succeeded &= SubmitBatchedAddOrDeleteLinkChanges(
                    updateDocsForDeleteLinks, docForDeletelinksToActionMap, translationService, configService, conflictManageer);
            }
            if (updateDocsForAddLinks.Count > 0)
            {
                succeeded &= SubmitBatchedAddOrDeleteLinkChanges(
                    updateDocsForAddLinks, docForAddlinksToActionMap, translationService, configService, conflictManageer);
            }
            return(succeeded);
        }