Пример #1
0
        private void ComputeDeltaPerRecordType(
            CQRecordFilter filter,
            string hwmTime)
        {
            CQRecordQueryBase recordQuery =
                CQRecordQueryFactory.CreatQuery(m_userSession, filter, hwmTime, this);

            foreach (OAdEntity record in recordQuery)
            {
                // HACK HACK
                if (record != null) // this if check is HACK
                {
                    try
                    {
                        ComputeDeltaPerRecord(record);
                    }
                    catch (Exception ex) // eating exception is HACK
                    {
                        TraceManager.TraceInformation(string.Format("Workaround for XML save exception : {0}",
                                                                    ex.Message));
                        TraceManager.TraceException(ex);
                    }
                }
                // HACK HACK
            }
        }
Пример #2
0
        /// <summary>
        /// Enumerate the diff items found based on the query passed in as well as the filterString and version passed
        /// to InitializeForDiff.  The return type is IEnumerable<> so that adapter implementations do not need download and keep
        /// all of the IWITDiffItems in memory at once.
        /// </summary>
        /// <param name="queryCondition">A string that specifies a query used to select a subset of the work items defined by
        /// the set that the filter string identified.</param>
        /// <returns>An enumeration of IWITDiffItems each representing a work item to be compared by the WIT Diff operation</returns>
        public IEnumerable <IWITDiffItem> GetWITDiffItems(string queryCondition)
        {
            if (m_getWITDiffItemsDone)
            {
                yield break;
            }

            if (m_cqRecordFilter is CQRecordStoredQueryFilter)
            {
                if (!string.IsNullOrEmpty(queryCondition))
                {
                    throw new NotImplementedException("Query conditions on the ServerDiff operation are not supported with ClearQuest stored queries are used");
                }
            }
            else
            {
                if (!string.IsNullOrEmpty(queryCondition))
                {
                    m_cqRecordFilter = new CQRecordFilter(m_cqRecordFilter.RecordType, m_cqRecordFilter.SelectFromTable, queryCondition);
                }
            }

            CQRecordQueryBase recordQuery = CQRecordQueryFactory.CreateQuery(m_userSession, m_cqRecordFilter, null, this);

            foreach (OAdEntity record in recordQuery)
            {
                if (record != null) // this if check is HACK
                {
                    OAdHistoryFields histFields = CQWrapper.GetHistoryFields(record);
                    int historyFldCount         = CQWrapper.HistoryFieldsCount(histFields);
                    yield return(new CQWITDiffItem(this, record, historyFldCount - 1));
                }
            }
            m_getWITDiffItemsDone = true;
        }
Пример #3
0
        public ChangeSummary GetSummaryOfChangesSince(string lastProcessedChangeItemId, List <string> filterStrings)
        {
            // lastProcessedChangeItemId is in a form such as "Defect:UCM0100019437:history:0"
            // Parse it and query for the record with that Id to get the time is was last changed
            string[]  identity            = UtilityMethods.ParseCQRecordMigrationItemId(lastProcessedChangeItemId);
            OAdEntity lastProcessedRecord = CQWrapper.GetEntity(m_userSession, identity[0], identity[1]);
            string    lastProcessedRecordAuthor;
            DateTime  lastProcessedRecordChangeDate;

            ClearQuestRecordItem.FindLastRevDtls(lastProcessedRecord, out lastProcessedRecordAuthor, out lastProcessedRecordChangeDate);

            string lastProcessedRecordChangeDateStr = lastProcessedRecordChangeDate.ToString("u").Replace("Z", ""); // using "ISO 8601" DateTime string format

            if (lastProcessedRecordChangeDateStr.LastIndexOf('.') >= 0)
            {
                lastProcessedRecordChangeDateStr = lastProcessedRecordChangeDateStr.Substring(0, lastProcessedRecordChangeDateStr.LastIndexOf('.')); // drop the millisec
            }

            ChangeSummary changeSummary = new ChangeSummary();

            changeSummary.ChangeCount = 0;
            changeSummary.FirstChangeModifiedTimeUtc = DateTime.MinValue;

            foreach (CQRecordFilter filter in m_filters)
            {
                CQRecordQueryBase recordQuery =
                    CQRecordQueryFactory.CreatQuery(m_userSession, filter, lastProcessedRecordChangeDateStr, this);

                foreach (OAdEntity record in recordQuery)
                {
                    // HACK HACK
                    if (record != null) // this if check is HACK
                    {
                        DateTime lastChangeDate;
                        string   lastAuthor;
                        ClearQuestRecordItem.FindLastRevDtls(record, out lastAuthor, out lastChangeDate);

                        // Make sure the lastChangeDate on this record is after the lastProcessedRecordChangeDate before counting it in the backclog
                        // because the query issued above is imprecise because the milliseconds are dropped
                        if (lastChangeDate > lastProcessedRecordChangeDate)
                        {
                            changeSummary.ChangeCount++;
                            DateTime lastChangeDateUtc = lastChangeDate.ToUniversalTime();
                            if (changeSummary.FirstChangeModifiedTimeUtc == DateTime.MinValue ||
                                lastChangeDateUtc < changeSummary.FirstChangeModifiedTimeUtc)
                            {
                                changeSummary.FirstChangeModifiedTimeUtc = lastChangeDateUtc;
                            }
                        }
                    }
                }
            }

            return(changeSummary);
        }
Пример #4
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());
            }
        }