示例#1
0
        public virtual ReadOnlyCollection <LinkChangeGroup> GenerateNextLinkDeltaSlice(
            LinkService linkService,
            int maxDeltaSliceSize)
        {
            try
            {
                var linkChangeGroups = new List <LinkChangeGroup>();

                if (null == ExtractLinkChangeActionsCallback)
                {
                    return(linkChangeGroups.AsReadOnly());
                }

                // load main Highwater Mark
                m_hwmLink.Reload();
                DateTime hwmLinkValue    = m_hwmLink.Value;
                string   hwmLinkValueStr = hwmLinkValue.ToString(CultureInfo.InvariantCulture);

                // load Work Items for extracting links
                string sourceId  = m_migrationSource.UniqueId;
                string storeName = m_migrationSource.WorkItemStore.StoreName;

                // Get items based on primary Highwater Mark
                TraceManager.TraceInformation(TfsWITAdapterResources.GettingModifiedItems, sourceId, storeName);
                IEnumerable <TfsMigrationWorkItem> items = m_migrationSource.WorkItemStore.GetItems(ref hwmLinkValueStr);
                TraceManager.TraceInformation(TfsWITAdapterResources.ReceivedModifiedItems, sourceId, storeName);

                // Record the updated HWM value
                DateTime newHwmLinkValue = Convert.ToDateTime(hwmLinkValueStr, CultureInfo.InvariantCulture);

                // store to be used to analyze deleted links
                WorkItemLinkStore store = new WorkItemLinkStore(new Guid(sourceId));

                // extract links
                var inMaxDeltaSliceSize = maxDeltaSliceSize;
                foreach (TfsMigrationWorkItem tfsMigrationWorkItem in items)
                {
                    if (tfsMigrationWorkItem.WorkItem == null)
                    {
                        continue;
                    }

                    TraceManager.TraceInformation("Generating linking delta for Work Item: {0}", tfsMigrationWorkItem.WorkItem.Id.ToString());
                    var perWorkItemlinkChangeGroups = new List <LinkChangeGroup>();
                    ExtractLinkChangeActionsCallback(tfsMigrationWorkItem, perWorkItemlinkChangeGroups, store);

                    if (perWorkItemlinkChangeGroups.Count == 0)
                    {
                        TraceManager.TraceInformation("Number of links: {0}", 0);
                        continue;
                    }

                    LinkChangeGroup consolidatedLinkChangeGroup = perWorkItemlinkChangeGroups[0];
                    for (int i = 1; i < perWorkItemlinkChangeGroups.Count; ++i)
                    {
                        foreach (LinkChangeAction action in perWorkItemlinkChangeGroups[i].Actions)
                        {
                            consolidatedLinkChangeGroup.AddChangeAction(action);
                        }
                    }
                    TraceManager.TraceInformation("Number of links: {0}", consolidatedLinkChangeGroup.Actions.Count.ToString());

                    // VERY IMPORTANT: use the RelatedArtifactsStore to detect link deletion
                    store.UpdatePerItemLinkChangeGroupsByCheckingRelatedItemRecords(
                        tfsMigrationWorkItem.Uri, consolidatedLinkChangeGroup, this);

                    if (consolidatedLinkChangeGroup.Actions.Count > 0)
                    {
                        linkChangeGroups.Add(consolidatedLinkChangeGroup);
                    }
                    maxDeltaSliceSize -= consolidatedLinkChangeGroup.Actions.Count;

                    if (maxDeltaSliceSize <= 0)
                    {
                        // size limit reached - persist groups to DB
                        linkService.AddChangeGroups(linkChangeGroups);
                        linkChangeGroups.Clear();
                        maxDeltaSliceSize = inMaxDeltaSliceSize;
                    }
                }

                // persist remaining groups to DB
                linkService.AddChangeGroups(linkChangeGroups);

                // clean up the returned link change group collection
                // when the caller (toolkit) receives an empty collection, it understands there is no more
                // delta to generate for the moment, and proceeds to next phase
                linkChangeGroups.Clear();

                // update primary Highwater Mark
                m_hwmLink.Update(newHwmLinkValue);
                TraceManager.TraceInformation("Persisted WIT linking HWM: {0}", Toolkit.Constants.HwmDeltaLink);
                TraceManager.TraceInformation(TfsWITAdapterResources.UpdatedHighWatermark, hwmLinkValueStr);

                return(linkChangeGroups.AsReadOnly());
            }
            catch (Exception exception)
            {
                ErrorManager errMgr = m_serviceContainer.GetService(typeof(ErrorManager)) as ErrorManager;
                errMgr.TryHandleException(exception);
                return(new List <LinkChangeGroup>().AsReadOnly());
            }
        }
示例#2
0
        public ReadOnlyCollection <LinkChangeGroup> GenerateNextLinkDeltaSlice(
            LinkService linkService,
            int maxDeltaSliceSize)
        {
            try
            {
                var linkChangeGroups = new List <LinkChangeGroup>();

                if (null == ExtractLinkChangeActionsCallback)
                {
                    return(linkChangeGroups.AsReadOnly());
                }

                // load high watermark; as for CQ, we store local time for queries
                m_hwmLink.Reload();
                DateTime hwmDeltaValue = m_hwmLink.Value;
                if (hwmDeltaValue.Equals(default(DateTime)))
                {
                    hwmDeltaValue = new DateTime(1900, 1, 1);
                }
                hwmDeltaValue = hwmDeltaValue.AddSeconds(-1);           // go back 1 second as we'll drop the millisec below

                string hwmDeltaValueStr = hwmDeltaValue.ToString(m_migrationContext.CQQueryDateTimeFormat, CultureInfo.InvariantCulture);

                // record current time to update HWM after processing
                DateTime newHwmValue = CQUtilityMethods.GetTimeForNewHighWaterMark(m_migrationContext.CQTimeOffsetFromServerHistoryTimesInMinutes);

                // store to be used for analysis
                WorkItemLinkStore store = new WorkItemLinkStore(m_configurationService.SourceId);

                // extract links
                var inMaxDeltaSliceSize = maxDeltaSliceSize;
                foreach (CQRecordFilter filter in m_filters)
                {
                    CQRecordQueryBase recordQuery = CQRecordQueryFactory.CreateQuery(m_userSession, filter, hwmDeltaValueStr, this);
                    foreach (ClearQuestOleServer.OAdEntity record in recordQuery)
                    {
                        // HACK HACK
                        if (record == null)
                        {
                            continue;
                        }
                        // HACK HACK

                        string recDispName = CQWrapper.GetEntityDisplayName(record);

                        TraceManager.TraceInformation("Generating linking delta for CQ Record: {0}", recDispName);

                        var perWorkItemlinkChangeGroups = new List <LinkChangeGroup>();
                        ExtractLinkChangeActionsCallback(m_userSession, record, perWorkItemlinkChangeGroups);

                        if (perWorkItemlinkChangeGroups.Count == 0)
                        {
                            TraceManager.TraceInformation("Number of links: {0}", 0);
                            continue;
                        }

                        LinkChangeGroup consolidatedLinkChangeGroup = perWorkItemlinkChangeGroups[0];
                        for (int i = 1; i < perWorkItemlinkChangeGroups.Count; ++i)
                        {
                            foreach (LinkChangeAction action in perWorkItemlinkChangeGroups[i].Actions)
                            {
                                consolidatedLinkChangeGroup.AddChangeAction(action);
                            }
                        }
                        TraceManager.TraceInformation("Number of links: {0}", consolidatedLinkChangeGroup.Actions.Count.ToString());

                        // VERY IMPORTANT STEP: update the link delta to store
                        string hostRecMigrItemId = UtilityMethods.CreateCQRecordMigrationItemId(record);
                        store.UpdatePerItemLinkChangeGroupsByCheckingRelatedItemRecords(
                            hostRecMigrItemId, consolidatedLinkChangeGroup, this);

                        if (consolidatedLinkChangeGroup.Actions.Count > 0)
                        {
                            linkChangeGroups.Add(consolidatedLinkChangeGroup);
                        }
                        maxDeltaSliceSize -= consolidatedLinkChangeGroup.Actions.Count;

                        if (maxDeltaSliceSize <= 0)
                        {
                            // size limit reached - persist groups to DB, then empty the slice and process next slice
                            linkService.AddChangeGroups(linkChangeGroups);
                            linkChangeGroups.Clear();
                            maxDeltaSliceSize = inMaxDeltaSliceSize;
                        }
                    }
                }

                // persist remaining groups to DB
                linkService.AddChangeGroups(linkChangeGroups);

                // clean up the returned link change group collection
                // when the caller (toolkit) receives an empty collection, it understands there is no more
                // delta to generate for the moment, and proceeds to next phase
                linkChangeGroups.Clear();

                // update primary Highwater Mark
                m_hwmLink.Update(newHwmValue);
                TraceManager.TraceInformation("Persisted CQ linking HWM: {0}", ClearQuestConstants.CqLinkHwm);
                TraceManager.TraceInformation("Updated CQ linking HWM: {0}", newHwmValue.ToString());

                return(linkChangeGroups.AsReadOnly());
            }
            catch (Exception exception)
            {
                // [teyang] TODO CONFLICT HANDLING

                //MigrationConflict genericeConflict = WitGeneralConflictType.CreateConflict(exception);
                //var conflictManager = m_conflictManager.GetService(typeof(ConflictManager)) as ConflictManager;
                //Debug.Assert(null != conflictManager);
                //List<MigrationAction> resolutionActions;
                //ConflictResolutionResult resolveRslt =
                //    conflictManager.TryResolveNewConflict(conflictManager.SourceId, genericeConflict, out resolutionActions);
                //Debug.Assert(!resolveRslt.Resolved);
                TraceManager.TraceException(exception);
                return(new List <LinkChangeGroup>().AsReadOnly());
            }
        }
示例#3
0
        public override System.Collections.ObjectModel.ReadOnlyCollection <LinkChangeGroup> GenerateNextLinkDeltaSlice(
            LinkService linkService,
            int maxDeltaSliceSize)
        {
            try
            {
                var linkChangeGroups = new List <LinkChangeGroup>();

                if (null == ExtractLinkChangeActionsCallback)
                {
                    return(linkChangeGroups.AsReadOnly());
                }

                // load main Highwater Mark
                m_hwmLink.Reload();
                DateTime hwmLinkValue = m_hwmLink.Value;
                // search back 60 seconds to deal with potential WIT race condition
                if (!hwmLinkValue.Equals(default(DateTime)))
                {
                    hwmLinkValue = hwmLinkValue.AddSeconds(-60);
                }
                string hwmLinkValueStr = hwmLinkValue.ToString(CultureInfo.InvariantCulture);

                // load Work Items for extracting links
                string sourceId  = m_migrationSource.UniqueId;
                string storeName = m_migrationSource.WorkItemStore.StoreName;

                // Get items based on primary Highwater Mark
                TraceManager.TraceInformation(TfsWITAdapterResources.GettingModifiedItems, sourceId, storeName);
                IEnumerable <TfsMigrationWorkItem> items = m_migrationSource.WorkItemStore.GetItems(ref hwmLinkValueStr);
                TraceManager.TraceInformation(TfsWITAdapterResources.ReceivedModifiedItems, sourceId, storeName);

                // Record the updated HWM value
                DateTime wiqlExecutionTime = Convert.ToDateTime(hwmLinkValueStr, CultureInfo.InvariantCulture);

                // store to be used to analyze deleted links
                WorkItemLinkStore store = new WorkItemLinkStore(new Guid(sourceId));

                // extract links
                DateTime lastWorkITemUpdateTime = DateTime.MinValue;
                var      inMaxDeltaSliceSize    = maxDeltaSliceSize;
                foreach (TfsMigrationWorkItem tfsMigrationWorkItem in items)
                {
                    if (tfsMigrationWorkItem.WorkItem == null)
                    {
                        continue;
                    }

                    TraceManager.TraceInformation("Generating linking delta for Work Item: {0}", tfsMigrationWorkItem.WorkItem.Id.ToString());
                    var detectedLinkChangeGroups = new List <LinkChangeGroup>();
                    ExtractLinkChangeActionsCallback(tfsMigrationWorkItem, detectedLinkChangeGroups, store);

                    if (detectedLinkChangeGroups.Count == 0)
                    {
                        TraceManager.TraceInformation("Number of links: {0}", 0);
                        continue;
                    }

                    Dictionary <string, LinkChangeGroup> perWorkItemConsolidatedLinkChangeGroup = new Dictionary <string, LinkChangeGroup>();
                    for (int i = 0; i < detectedLinkChangeGroups.Count; ++i)
                    {
                        foreach (LinkChangeAction action in detectedLinkChangeGroups[i].Actions)
                        {
                            if (!perWorkItemConsolidatedLinkChangeGroup.ContainsKey(action.Link.SourceArtifact.Uri))
                            {
                                var linkChangeGroup = new LinkChangeGroup(
                                    action.Link.SourceArtifactId, LinkChangeGroup.LinkChangeGroupStatus.Created, false);
                                perWorkItemConsolidatedLinkChangeGroup.Add(action.Link.SourceArtifact.Uri, linkChangeGroup);
                            }
                            perWorkItemConsolidatedLinkChangeGroup[action.Link.SourceArtifact.Uri].AddChangeAction(action);
                        }
                    }

                    // always make sure that the currently analyzed work item has a link change group to represent it
                    // even though the group can be empty
                    if (!perWorkItemConsolidatedLinkChangeGroup.ContainsKey(tfsMigrationWorkItem.Uri))
                    {
                        perWorkItemConsolidatedLinkChangeGroup.Add(
                            tfsMigrationWorkItem.Uri,
                            new LinkChangeGroup(TfsWorkItemHandler.IdFromUri(tfsMigrationWorkItem.Uri), LinkChangeGroup.LinkChangeGroupStatus.Created, false));
                    }


                    foreach (var workItemLinkGroup in perWorkItemConsolidatedLinkChangeGroup)
                    {
                        string workItemIdStr = TfsWorkItemHandler.IdFromUri(workItemLinkGroup.Key);
                        TraceManager.TraceInformation("Detected {0} links for Work Item '{1}'",
                                                      workItemLinkGroup.Value.Actions.Count, workItemIdStr);

                        if (workItemLinkGroup.Key.Equals(tfsMigrationWorkItem.Uri, StringComparison.OrdinalIgnoreCase))
                        {
                            // VERY IMPORTANT: use the RelatedArtifactsStore to detect link deletion
                            store.UpdatePerItemLinkChangeGroupsByCheckingRelatedItemRecords(
                                workItemLinkGroup.Key, workItemLinkGroup.Value, this);
                        }
                        else
                        {
                            store.UpdatePerItemLinkChangeGroupsByCheckingRelatedItemRecordsWithoutImplicitDelete(
                                workItemLinkGroup.Key, workItemLinkGroup.Value, this);
                        }

                        if (workItemLinkGroup.Value.Actions.Count > 0)
                        {
                            linkChangeGroups.Add(workItemLinkGroup.Value);
                        }
                        maxDeltaSliceSize -= workItemLinkGroup.Value.Actions.Count;

                        if (maxDeltaSliceSize <= 0)
                        {
                            // size limit reached - persist groups to DB
                            linkService.AddChangeGroups(linkChangeGroups);
                            linkChangeGroups.Clear();
                            maxDeltaSliceSize = inMaxDeltaSliceSize;
                        }
                    }

                    DateTime lastRevChangedDate = tfsMigrationWorkItem.WorkItem.ChangedDate;

                    if (lastWorkITemUpdateTime.CompareTo(lastRevChangedDate) <= 0)
                    {
                        lastWorkITemUpdateTime = lastRevChangedDate;
                    }
                }

                // persist remaining groups to DB
                linkService.AddChangeGroups(linkChangeGroups);

                // clean up the returned link change group collection
                // when the caller (toolkit) receives an empty collection, it understands there is no more
                // delta to generate for the moment, and proceeds to next phase
                linkChangeGroups.Clear();

                // update primary Highwater Mark
                //m_hwmLink.Update(newHwmLinkValue);

                string newHwmValueStr = hwmLinkValueStr;
                if (lastWorkITemUpdateTime.Equals(DateTime.MinValue))
                {
                    // no changes in this sync cycle, record the wiql query execution time
                    m_hwmLink.Update(wiqlExecutionTime);
                }
                else
                {
                    // hwm is recorded in UTC, so does the WIQL query asof time
                    lastWorkITemUpdateTime = lastWorkITemUpdateTime.ToUniversalTime();

                    if (lastWorkITemUpdateTime.CompareTo(wiqlExecutionTime) <= 0)
                    {
                        // last work item rev time is earlier than wiql query execution time, use it as hwm
                        m_hwmLink.Update(lastWorkITemUpdateTime);
                        newHwmValueStr = lastWorkITemUpdateTime.ToString();
                    }
                    else
                    {
                        m_hwmLink.Update(wiqlExecutionTime);
                    }
                }
                TraceManager.TraceInformation("Persisted WIT linking HWM: {0}", Toolkit.Constants.HwmDeltaLink);
                TraceManager.TraceInformation(TfsWITAdapterResources.UpdatedHighWatermark, newHwmValueStr);

                return(linkChangeGroups.AsReadOnly());
            }
            catch (Exception exception)
            {
                MigrationConflict genericeConflict = WitGeneralConflictType.CreateConflict(exception);
                var conflictManager = m_conflictManager.GetService(typeof(ConflictManager)) as ConflictManager;
                Debug.Assert(null != conflictManager);
                List <MigrationAction>   resolutionActions;
                ConflictResolutionResult resolveRslt =
                    conflictManager.TryResolveNewConflict(conflictManager.SourceId, genericeConflict, out resolutionActions);
                Debug.Assert(!resolveRslt.Resolved);
                return(new List <LinkChangeGroup>().AsReadOnly());
            }
        }