Example #1
0
        private static RTMigrationItem CreateCachedCSSNode(
            RTMigrationSource migrationSource,
            string nodeUri,
            string path)
        {
            var nodeCache = RTMigrationItem.CreateRTMigrationItem(0, nodeUri, string.Empty);

            nodeCache.MigrationSource = migrationSource;
            nodeCache.ItemData        = path;
            return(nodeCache);
        }
        private RTConversionHistory UpdateGroupConvHist(
            RuntimeEntityModel context,
            RTSessionRun rtSessionRun,
            RTMigrationSource rtMigrationSource)
        {
            RTConversionHistory runTimeConverHistory = RTConversionHistory.CreateRTConversionHistory(
                DateTime.UtcNow,
                -1,
                false);

            runTimeConverHistory.SessionRun            = rtSessionRun;
            runTimeConverHistory.SourceMigrationSource = rtMigrationSource;

            context.AddToRTConversionHistorySet(runTimeConverHistory);
            return(runTimeConverHistory);
        }
        /// <summary>
        /// Saves the conversion history and associate it with a particular session run and migration source;
        /// Additionally, mark the Reflected Change Group (the delta table entry of this processed change group) to be sync-ed.
        /// </summary>
        /// <param name="sessionRunId">int.MinValue if sessionRunId is not available</param>
        /// <param name="migrationSourceId"></param>
        /// <param name="sessionId"></param>
        /// <param name="reflectedChangeGroupId"></param>
        /// <returns></returns>
        internal bool Save(
            int sessionRunId,
            Guid migrationSourceId,
            Guid sessionId,
            long?reflectedChangeGroupId)
        {
            if (string.IsNullOrEmpty(ChangeId))
            {
                return(false);
            }

            using (RuntimeEntityModel context = RuntimeEntityModel.CreateInstance())
            {
                if (ItemConversionHistory.Count > 0)
                {
                    var sessionRunQuery = (sessionRunId == int.MinValue)
                        ? from sr in context.RTSessionRunSet
                                          where sr.Config.LeftSourceConfig.MigrationSource.UniqueId.Equals(migrationSourceId) ||
                                          sr.Config.RightSourceConfig.MigrationSource.UniqueId.Equals(migrationSourceId)
                                          select sr
                        : context.RTSessionRunSet.Where(sr => sr.Id == sessionRunId);
                    if (sessionRunQuery.Count() == 0)
                    {
                        return(false);
                    }
                    RTSessionRun rtSessionRun = sessionRunQuery.First();

                    var migrationSourceQuery = context.RTMigrationSourceSet.Where(ms => ms.UniqueId.Equals(migrationSourceId));
                    if (migrationSourceQuery.Count() == 0)
                    {
                        return(false);
                    }
                    RTMigrationSource rtMigrationSource = migrationSourceQuery.First();

                    RTConversionHistory rtConvHist = UpdateGroupConvHist(context, rtSessionRun, rtMigrationSource);
                    UpdateItemConversionHistory(rtConvHist, context);
                }

                if (!sessionId.Equals(Guid.Empty) && reflectedChangeGroupId.HasValue)
                {
                    MarkDeltaTableSynced(context, sessionId, reflectedChangeGroupId.Value);
                }

                context.TrySaveChanges();
                return(true);
            }
        }
Example #4
0
        public ConflictRuleViewModel(RTConflict conflict, ApplicationViewModel appViewModel)
            : base(appViewModel)
        {
            m_conflict = conflict;
            base.Scope = m_conflict.ScopeHint;

            int migrationSourceId = (int)m_conflict.SourceSideMigrationSourceReference.EntityKey.EntityKeyValues.First().Value;

            if (!s_migrationSourceTable.ContainsKey(migrationSourceId))
            {
                lock (s_migrationSourceTable)
                {
                    if (!s_migrationSourceTable.ContainsKey(migrationSourceId))
                    {
                        m_conflict.SourceSideMigrationSourceReference.Load();
                        s_migrationSourceTable.Add(migrationSourceId, m_conflict.SourceSideMigrationSource);
                    }
                }
            }
            m_rtMigrationSource = s_migrationSourceTable[migrationSourceId];

            int conflictTypeId = (int)m_conflict.ConflictTypeReference.EntityKey.EntityKeyValues.First().Value;

            if (!s_conflictTypeTable.ContainsKey(conflictTypeId))
            {
                lock (s_conflictTypeTable)
                {
                    if (!s_conflictTypeTable.ContainsKey(conflictTypeId))
                    {
                        m_conflict.ConflictTypeReference.Load();
                        s_conflictTypeTable.Add(conflictTypeId, m_conflict.ConflictType);
                    }
                }
            }

            SetConflictManager(m_conflict.ScopeId, m_rtMigrationSource.UniqueId, s_conflictTypeTable[conflictTypeId].ReferenceName);
        }
        private bool updateConversionHistory(MigrationConflict conflict, ConflictResolutionRule rule)
        {
            if (!rule.DataFieldDictionary.ContainsKey(VCContentConflictUserMergeChangeAction.MigrationInstructionChangeId) ||
                !rule.DataFieldDictionary.ContainsKey(VCContentConflictUserMergeChangeAction.DeltaTableChangeId))
            {
                return(false);
            }
            string migrationInstructionName = rule.DataFieldDictionary[VCContentConflictUserMergeChangeAction.MigrationInstructionChangeId];
            string deltaTableName           = rule.DataFieldDictionary[VCContentConflictUserMergeChangeAction.DeltaTableChangeId];

            using (RuntimeEntityModel context = RuntimeEntityModel.CreateInstance())
            {
                ChangeGroup conflictChangeGroup = conflict.ConflictedChangeAction.ChangeGroup;
                Guid        deltaSideSourceId;

                // Mark all delta table entry as DeltaComplete
                var deltaTableEntries =
                    from d in context.RTChangeGroupSet
                    where d.SessionUniqueId == conflictChangeGroup.SessionId &&
                    d.Status == (int)ChangeStatus.DeltaPending
                    select d;
                foreach (RTChangeGroup deltaTableEntry in deltaTableEntries)
                {
                    deltaTableEntry.Status = (int)ChangeStatus.DeltaComplete;
                    deltaTableEntry.ContainsBackloggedAction = false;
                }

                // Mark all migration instruction entry as Complete
                var migrationInstructionEntries =
                    from d in context.RTChangeGroupSet
                    where d.SessionUniqueId == conflictChangeGroup.SessionId &&
                    (d.Status == (int)ChangeStatus.Pending || d.Status == (int)ChangeStatus.InProgress || d.Status == (int)ChangeStatus.PendingConflictDetection)
                    select d;
                foreach (RTChangeGroup migrationInstructionEntry in migrationInstructionEntries)
                {
                    migrationInstructionEntry.Status = (int)ChangeStatus.Complete;
                    migrationInstructionEntry.ContainsBackloggedAction = false;
                }

                // Mark the source side highwatermark
                var sourceSideHighWaterMark =
                    (from hwm in context.RTHighWaterMarkSet
                     where hwm.SessionUniqueId == conflictChangeGroup.SessionId &&
                     hwm.SourceUniqueId != conflictChangeGroup.SourceId &&
                     hwm.Name == Constants.HwmDelta
                     select hwm).First();
                Debug.Assert(sourceSideHighWaterMark != null, "Can't find the source side HWM");

                sourceSideHighWaterMark.Value = deltaTableName;
                deltaSideSourceId             = sourceSideHighWaterMark.SourceUniqueId;

                // Mark the target side highwatermark
                var targetHighWaterMark =
                    (from hwm in context.RTHighWaterMarkSet
                     where hwm.SessionUniqueId == conflictChangeGroup.SessionId &&
                     hwm.SourceUniqueId == conflictChangeGroup.SourceId &&
                     hwm.Name == Constants.HwmDelta
                     select hwm).First();
                Debug.Assert(targetHighWaterMark != null, "Can't find the target side HWM");

                targetHighWaterMark.Value = migrationInstructionName;

                // Create the conversion history entry
                RTConversionHistory conversionHistory = RTConversionHistory.CreateRTConversionHistory(
                    DateTime.UtcNow,
                    -1,
                    true);
                conversionHistory.Comment = rule.RuleDescription;

                var session =
                    (from s in context.RTSessionConfigSet
                     where s.SessionUniqueId == conflictChangeGroup.SessionId
                     select s).First();

                Debug.Assert(session != null, "Cannot find session in DB");

                RTSessionRun sessionRun =
                    (from sr in context.RTSessionRunSet
                     where sr.Id == session.Id
                     select sr).First();
                Debug.Assert(sessionRun != null, "Cannot find session run in DB");

                conversionHistory.SessionRun = sessionRun;

                RTMigrationSource migrationSource =
                    (from ms in context.RTMigrationSourceSet
                     where ms.UniqueId.Equals(conflictChangeGroup.SourceId)
                     select ms).First();
                Debug.Assert(migrationSource != null, "Cannot find the migration source to persist conversion history");

                RTMigrationSource deltaSideMigrationSource =
                    (from ms in context.RTMigrationSourceSet
                     where ms.UniqueId.Equals(deltaSideSourceId)
                     select ms).First();
                Debug.Assert(deltaSideMigrationSource != null, "Cannot find the migration source to persist conversion history");

                conversionHistory.SourceMigrationSource = migrationSource;

                context.AddToRTConversionHistorySet(conversionHistory);

                RTMigrationItem sourceItem = RTMigrationItem.CreateRTMigrationItem(0, deltaTableName, Constants.ChangeGroupGenericVersionNumber);
                sourceItem.MigrationSource = migrationSource;
                RTMigrationItem targetItem = RTMigrationItem.CreateRTMigrationItem(0, migrationInstructionName, Constants.ChangeGroupGenericVersionNumber);
                targetItem.MigrationSource = deltaSideMigrationSource;


                RTItemRevisionPair pair = RTItemRevisionPair.CreateRTItemRevisionPair(
                    sourceItem.Id, targetItem.Id);
                pair.LeftMigrationItem  = sourceItem;
                pair.RightMigrationItem = targetItem;
                pair.ConversionHistory  = conversionHistory;



                // Create a new HistoryNotFoundConflict Resolution Rule
                context.TrySaveChanges();
            }
            return(true);
        }
Example #6
0
        /// <summary>
        /// Update the conversion history with the given migration instruction and delta table entry. This will add the entry to conversion history and remove all pending change groups.
        /// </summary>
        /// <param name="migrationInstructionName"></param>
        /// <param name="deltaTableName"></param>
        /// <param name="comment"></param>
        /// <returns></returns>
        public override bool UpdateConversionHistoryAndRemovePendingChangeGroups(string migrationInstructionName, string deltaTableName, string comment)
        {
            if (string.IsNullOrEmpty(migrationInstructionName) || (string.IsNullOrEmpty(deltaTableName)))
            {
                return(false);
            }

            using (RuntimeEntityModel context = RuntimeEntityModel.CreateInstance())
            {
                Guid deltaSideSourceId;
                Guid sessionId = new Guid(Session.SessionUniqueId);

                // Mark all delta table entry as DeltaComplete
                var deltaTableEntries =
                    from d in context.RTChangeGroupSet
                    where d.SessionUniqueId == sessionId &&
                    d.Status == (int)ChangeStatus.DeltaPending
                    select d;
                foreach (RTChangeGroup deltaTableEntry in deltaTableEntries)
                {
                    deltaTableEntry.Status = (int)ChangeStatus.DeltaComplete;
                    deltaTableEntry.ContainsBackloggedAction = false;
                }

                // Mark all migration instruction entry as Complete
                var migrationInstructionEntries =
                    from d in context.RTChangeGroupSet
                    where d.SessionUniqueId == sessionId &&
                    (d.Status == (int)ChangeStatus.Pending || d.Status == (int)ChangeStatus.InProgress || d.Status == (int)ChangeStatus.PendingConflictDetection)
                    select d;
                foreach (RTChangeGroup migrationInstructionEntry in migrationInstructionEntries)
                {
                    migrationInstructionEntry.Status = (int)ChangeStatus.Complete;
                    migrationInstructionEntry.ContainsBackloggedAction = false;
                }

                // Mark the source side highwatermark
                var sourceSideHighWaterMark =
                    (from hwm in context.RTHighWaterMarkSet
                     where hwm.SessionUniqueId == sessionId &&
                     hwm.SourceUniqueId != SourceId &&
                     hwm.Name == Constants.HwmDelta
                     select hwm).First();
                Debug.Assert(sourceSideHighWaterMark != null, "Can't find the source side HWM");

                sourceSideHighWaterMark.Value = deltaTableName;
                deltaSideSourceId             = sourceSideHighWaterMark.SourceUniqueId;

                // Mark the target side highwatermark
                var targetHighWaterMark =
                    (from hwm in context.RTHighWaterMarkSet
                     where hwm.SessionUniqueId == sessionId &&
                     hwm.SourceUniqueId == SourceId &&
                     hwm.Name == Constants.HwmDelta
                     select hwm).First();
                Debug.Assert(targetHighWaterMark != null, "Can't find the target side HWM");

                targetHighWaterMark.Value = migrationInstructionName;

                // Prepare to create the conversion history entry (unless a matching one exists)
                RTMigrationSource migrationSource =
                    (from ms in context.RTMigrationSourceSet
                     where ms.UniqueId.Equals(SourceId)
                     select ms).First();
                Debug.Assert(migrationSource != null, "Cannot find the migration source to persist conversion history");

                RTMigrationSource deltaSideMigrationSource =
                    (from ms in context.RTMigrationSourceSet
                     where ms.UniqueId.Equals(deltaSideSourceId)
                     select ms).First();
                Debug.Assert(deltaSideMigrationSource != null, "Cannot find the migration source to persist conversion history");

                // A MigrationItem row may already exist; if so use it
                bool sourceMigrationItemExists;
                var  sourceItemQuery = (from mi in context.RTMigrationItemSet
                                        where mi.MigrationSource.UniqueId.Equals(migrationSource.UniqueId) &&
                                        mi.ItemId == deltaTableName &&
                                        mi.ItemVersion == Constants.ChangeGroupGenericVersionNumber
                                        select mi);
                RTMigrationItem sourceItem;
                if (sourceItemQuery.Count() > 0)
                {
                    sourceItem = sourceItemQuery.First();
                    sourceMigrationItemExists = true;
                }
                else
                {
                    sourceItem = RTMigrationItem.CreateRTMigrationItem(0, deltaTableName, Constants.ChangeGroupGenericVersionNumber);
                    sourceItem.MigrationSource = migrationSource;
                    sourceMigrationItemExists  = false;
                }

                // A MigrationItem row may already exist; if so use it
                bool targetMigrationItemExists;
                var  targetItemQuery = (from mi in context.RTMigrationItemSet
                                        where mi.MigrationSource.UniqueId.Equals(deltaSideMigrationSource.UniqueId) &&
                                        mi.ItemId == migrationInstructionName &&
                                        mi.ItemVersion == Constants.ChangeGroupGenericVersionNumber
                                        select mi);
                RTMigrationItem targetItem;
                if (targetItemQuery.Count() > 0)
                {
                    targetItem = targetItemQuery.First();
                    targetMigrationItemExists = true;
                }
                else
                {
                    targetItem = RTMigrationItem.CreateRTMigrationItem(0, migrationInstructionName, Constants.ChangeGroupGenericVersionNumber);
                    targetItem.MigrationSource = deltaSideMigrationSource;
                    targetMigrationItemExists  = false;
                }

                // If both the source and target migration items exist in the DB, there is no need to create a duplicate conversion
                // history record, and attempting to do so will cause a constraint violation.
                if (!sourceMigrationItemExists || !targetMigrationItemExists)
                {
                    // Create the conversion history entry
                    RTConversionHistory conversionHistory = RTConversionHistory.CreateRTConversionHistory(
                        DateTime.UtcNow,
                        -1,
                        true);
                    conversionHistory.Comment = comment;

                    var session =
                        (from s in context.RTSessionConfigSet
                         where s.SessionUniqueId == sessionId
                         select s).First();

                    Debug.Assert(session != null, "Cannot find session in DB");

                    RTSessionRun sessionRun =
                        (from sr in context.RTSessionRunSet
                         where sr.Id == session.Id
                         select sr).First();
                    Debug.Assert(sessionRun != null, "Cannot find session run in DB");

                    conversionHistory.SessionRun            = sessionRun;
                    conversionHistory.SourceMigrationSource = migrationSource;
                    context.AddToRTConversionHistorySet(conversionHistory);

                    RTItemRevisionPair pair = RTItemRevisionPair.CreateRTItemRevisionPair(
                        sourceItem.Id, targetItem.Id);
                    pair.LeftMigrationItem  = sourceItem;
                    pair.RightMigrationItem = targetItem;
                    pair.ConversionHistory  = conversionHistory;
                }

                // Create a new HistoryNotFoundConflict Resolution Rule
                context.TrySaveChanges();
            }
            return(true);
        }
        public Endpoint(
            MonitorWatcher watcher,
            RuntimeEntityModel context,
            RTSession rtSession,
            RTMigrationSource rtMigrationSource,
            bool isRightMigrationSource,
            RTMigrationSource peerMigrationSource)
        {
            m_monitorWatcher = watcher;

            // TODO: Consider moving all of this initialization code to a new EndpointContext class that contains everything that the
            // Poll() method needs to do its job, and then have MonitorWatcher.GetEndpoints() pass the EndpointContext object as the single
            // arg to this constructor.

            this.Context                = context;
            this.RTMigrationSource      = rtMigrationSource;
            this.IsRightMigrationSource = isRightMigrationSource;
            this.PeerRTMigrationSource  = peerMigrationSource;

            BusinessModelManager businessModelManager = new BusinessModelManager();

            if (rtSession.SessionGroup == null)
            {
                rtSession.SessionGroupReference.Load();
            }

            Config = businessModelManager.LoadConfiguration(rtSession.SessionGroup.GroupUniqueId);
            if (Config == null)
            {
                throw new ApplicationException(
                          String.Format(CultureInfo.InvariantCulture, MigrationToolkitResources.SessionGroupNotFound,
                                        rtSession.SessionGroup.GroupUniqueId.ToString()));
            }

            // TODO: Modify ProdviderManager to take a constructor that does not require a Config and that just loads
            // all providers in the Plugins directory, then move this code up to the MonitorWatcher constructor and pass the
            // providerHandlers down as another argument to this constructor
            ProviderManager providerManager = new ProviderManager(Config);
            Dictionary <Guid, ProviderHandler> providerHandlers = providerManager.LoadProvider(new DirectoryInfo(Constants.PluginsFolderName));

            ProviderHandler providerHandler;

            if (!providerHandlers.TryGetValue(this.RTMigrationSource.UniqueId, out providerHandler))
            {
                throw new Exception(string.Format(CultureInfo.InvariantCulture,
                                                  MigrationToolkitResources.ProviderHandlerNotLoadedForMigrationSouce,
                                                  this.RTMigrationSource.FriendlyName));
            }

            Debug.Assert(providerHandler.Provider != null);
            SyncMonitorProvider = providerHandler.Provider.GetService(typeof(ISyncMonitorProvider)) as ISyncMonitorProvider;
            if (SyncMonitorProvider == null)
            {
                throw new NotImplementedException(string.Format(CultureInfo.InvariantCulture,
                                                                MigrationToolkitResources.ProviderDoesNotImplementISyncMonitor,
                                                                providerHandler.ProviderName));
            }

            // Find the Session object corresponding to the RTSession
            if (Config.SessionGroup != null && Config.SessionGroup.Sessions != null)
            {
                foreach (var aSession in Config.SessionGroup.Sessions.Session)
                {
                    if (string.Equals(aSession.SessionUniqueId, rtSession.SessionUniqueId.ToString(), StringComparison.Ordinal))
                    {
                        Session = aSession;
                        break;
                    }
                }
            }
            if (Session == null)
            {
                throw new Exception(string.Format(CultureInfo.InvariantCulture,
                                                  MigrationToolkitResources.SessionNotFoundForMigrationSource,
                                                  rtSession.SessionGroup.GroupUniqueId.ToString(), RTMigrationSource.FriendlyName));
            }

            Guid migrationSourceGuid = new Guid(isRightMigrationSource ? Session.RightMigrationSourceUniqueId : Session.LeftMigrationSourceUniqueId);

            Microsoft.TeamFoundation.Migration.BusinessModel.MigrationSource migrationSource = Config.GetMigrationSource(migrationSourceGuid);
            Session.MigrationSources.Add(migrationSourceGuid, migrationSource);

            var serviceContainer = new ServiceContainer();

            serviceContainer.AddService(typeof(ITranslationService), new SyncMonitorTranslationService(Session));
            // We pass null for the global Configuration to the ConfigurationService constructor because its not handy and not needed in this context
            serviceContainer.AddService(typeof(ConfigurationService), new ConfigurationService(null, Session, migrationSourceGuid));
            SyncMonitorProvider.InitializeServices(serviceContainer);
            SyncMonitorProvider.InitializeClient(migrationSource);

            int filterPairIndex = IsRightMigrationSource ? 1 : 0;

            foreach (var filterPair in Session.Filters.FilterPair)
            {
                if (!filterPair.Neglect)
                {
                    m_filterStrings.Add(VCTranslationService.TrimTrailingPathSeparator(filterPair.FilterItem[filterPairIndex].FilterString));
                }
            }
        }
Example #8
0
 public OneWaySessionViewModel(RTSessionConfig session, RTMigrationSource source, RTMigrationSource target)
 {
     Session = session;
     Source  = source;
     Target  = target;
 }
Example #9
0
 public LightWeightSource(RTMigrationSource source)
 {
     FriendlyName = source.FriendlyName;
     UniqueId     = source.UniqueId;
 }
Example #10
0
 public MigrationSourceViewModel(RTMigrationSource migrationSource)
 {
     m_migrationSource = migrationSource;
 }
        /// <summary>
        /// Get a list of migration sources and their high water marks from the database
        /// </summary>
        /// <returns></returns>
        private Dictionary <string, Endpoint> GetActiveEndpoints(RuntimeEntityModel context)
        {
            // TODO: Once a session completes, we should report one more row in LATENCY_DATA that shows that there is no
            // longer any backlog.    This means that we need to save the list of endPoints from the previous call to EndPoints
            // and include them as well as the ones that are currently active.

            int sessionsBeingMonitored = 0;
            Dictionary <string, Endpoint> endpoints = new Dictionary <string, Endpoint>();

            // Find all the sessions that are not in the Completed State
            var sessionQuery =
                (from rtSession in context.RTSessionSet
                 where rtSession.State != (int)BusinessModelManager.SessionStateEnum.Completed
                 select rtSession);

            foreach (RTSession rtSession in sessionQuery)
            {
                // For a uni-directional migration or sync, we only want to monitor the source side
                // so we need to determine the WorkflowType
                rtSession.SessionGroupReference.Load();
                Debug.Assert(rtSession.SessionGroup != null);
                bool isUniDirectional = IsSessionUniDirectional(context, rtSession.SessionGroup);

                rtSession.LeftMigrationSourceReference.Load();
                Debug.Assert(rtSession.LeftMigrationSource != null);
                rtSession.RightMigrationSourceReference.Load();
                Debug.Assert(rtSession.RightMigrationSource != null);

                bool sessionEndpointAdded   = false;
                bool isRightMigrationSource = false;
                RTMigrationSource[] migrationSources;


                if (isUniDirectional)
                {
                    migrationSources = new RTMigrationSource[1] {
                        rtSession.LeftMigrationSource
                    };
                }
                else
                {
                    migrationSources = new RTMigrationSource[2] {
                        rtSession.LeftMigrationSource, rtSession.RightMigrationSource
                    };
                }

                foreach (RTMigrationSource migrationSource in migrationSources)
                {
                    try
                    {
                        if (migrationSource == null)
                        {
                            LogError(String.Format(CultureInfo.InvariantCulture,
                                                   "Session {0} found with a null value for the {1} migration source (ignoring)",
                                                   rtSession.SessionUniqueId, isRightMigrationSource ? "right" : "left"));
                            continue;
                        }
                        LogVerbose(String.Format(CultureInfo.InvariantCulture,
                                                 "Found active migration source '{0}' for session with Id: {1}",
                                                 migrationSource.FriendlyName, rtSession.SessionUniqueId));

                        RTMigrationSource peerMigrationSource = isRightMigrationSource ?
                                                                rtSession.LeftMigrationSource : rtSession.RightMigrationSource;
                        Endpoint endpoint = new Endpoint(this, context, rtSession, migrationSource, isRightMigrationSource, peerMigrationSource);
                        if (endpoints.ContainsKey(endpoint.UniqueId))
                        {
                            LogWarning("Skipping endpoint with same Id as endpoint previously found: " + endpoint.UniqueId);
                            continue;
                        }
                        endpoints.Add(endpoint.UniqueId, endpoint);

                        if (!sessionEndpointAdded)
                        {
                            sessionsBeingMonitored++;
                            sessionEndpointAdded = true;
                        }

                        LogVerbose(String.Format(CultureInfo.InvariantCulture,
                                                 "Successfully initialized monitoring for migration source '{0}'",
                                                 migrationSource.FriendlyName));
                    }
                    catch (NotImplementedException)
                    {
                        // It's OK for an adapter to not implement the ISyncMonitorProvider interface
                        LogInfo(String.Format(CultureInfo.InvariantCulture,
                                              "Skipping monitoring for endpoint '{0}' because the adapter does not implement the ISyncMonitorProvider interface",
                                              migrationSource.FriendlyName));
                    }
                    catch (Exception ex)
                    {
                        LogWarning(String.Format(CultureInfo.InvariantCulture,
                                                 "Unable to setup monitoring for endpoint '{0}': {1}",
                                                 migrationSource.FriendlyName, ex.ToString()));
                    }
                    // Will be true 2nd time through foreach for the session.RightMigrationSource
                    isRightMigrationSource = true;
                }
            }

            if (endpoints.Count > 0)
            {
                LogInfo(String.Format(CultureInfo.InvariantCulture,
                                      MigrationToolkitResources.SyncMonitorCollectingBacklogData,
                                      endpoints.Count, sessionsBeingMonitored));
            }
            else
            {
                LogVerbose(MigrationToolkitResources.SyncMonitorNoActiveSessions);
            }

            return(endpoints);
        }