public async Task Synchronize(ISynchronizationLogger logger, TContext synchronizationContext)
        {
            s_logger.InfoFormat("Entered. Syncstrategy '{0}' with Atype='{1}' and Btype='{2}'", _initialSyncStateCreationStrategy.GetType().Name, typeof(TAtypeEntity).Name, typeof(TBtypeEntity).Name);

            using (var totalProgress = _totalProgressFactory.Create())
            {
                var knownEntityRelations = _entityRelationDataAccess.LoadEntityRelationData()
                                           ?? new IEntityRelationData <TAtypeEntityId, TAtypeEntityVersion, TBtypeEntityId, TBtypeEntityVersion>[] { };

                var stateTokens = _stateTokenDataAccess.LoadKnownStateTokens();

                using (var interceptor = _synchronizationInterceptorFactory.Create())
                {
                    var aStatesTask = _atypeStateAwareEntityRepository.GetFullRepositoryState(knownEntityRelations.Select(r => r.AtypeId), stateTokens.AToken, synchronizationContext, logger.AGetVersionsEntityLogger);
                    var bStatesTask = _btypeStateAwareEntityRepository.GetFullRepositoryState(knownEntityRelations.Select(r => r.BtypeId), stateTokens.BToken, synchronizationContext, logger.BGetVersionsEntityLogger);

                    (var aStates, var newAToken) = await aStatesTask;
                    (var bStates, var newBToken) = await bStatesTask;

                    await Synchronize(
                        totalProgress,
                        knownEntityRelations,
                        aStates,
                        bStates,
                        logger,
                        synchronizationContext,
                        interceptor,
                        newEntityRelations => _entityRelationDataAccess.SaveEntityRelationData(newEntityRelations));

                    _stateTokenDataAccess.SaveKnownStateTokens(newAToken, newBToken);
                }
            }
            s_logger.DebugFormat("Exiting.");
        }
 /// <summary>
 /// Check exchange mailboxes subscriptions state. Starts exchange events service.
 /// Fail handler for mailboxes without subscription.
 /// </summary>
 /// <param name="userConnection"><see cref="UserConnection"/> instance.</param>
 /// <param name="parameters">Process parameters collection.</param>
 public void Execute(UserConnection userConnection, IDictionary <string, object> parameters)
 {
     _log = ClassFactory.Get <ISynchronizationLogger>(new ConstructorArgument("userId", userConnection.CurrentUser.Id));
     try {
         _log.InfoFormat("ListenerServiceFailJob started");
         if (!GetIsFeatureEnabled(userConnection, "ExchangeListenerEnabled"))
         {
             return;
         }
         UserConnection  = userConnection;
         ListenerManager = GetExchangeListenerManager();
         _log.DebugFormat("ListenerServiceFailJob: _listenerManager initiated");
         var mailboxes = GetMailboxesWithoutSubscriptions();
         ScheduleFailoverHandlers(mailboxes);
     } finally {
         int periodMin = Core.Configuration.SysSettings.GetValue(userConnection, "ListenerServiceFailJobPeriod", 1);
         if (periodMin == 0)
         {
             var schedulerWraper = ClassFactory.Get <IAppSchedulerWraper>();
             schedulerWraper.RemoveGroupJobs(ListenerServiceFailJobFactory.JobGroupName);
             _log.ErrorFormat("ListenerServiceFailJobPeriod is 0, ListenerServiceFailJob stopped");
         }
         _log.InfoFormat("ListenerServiceFailJob ended");
     }
 }
Esempio n. 3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ExchangeListenerManager"/> class.
 /// </summary>
 /// <param name="userConnection"><see cref="UserConnection"/> instance.</param>
 public ExchangeListenerManager(UserConnection userConnection)
 {
     UserConnection  = userConnection;
     _requestFactory = ClassFactory.Get <IHttpWebRequestFactory>();
     _mailboxService = ClassFactory.Get <IMailboxService>(new ConstructorArgument("uc", userConnection));
     _log            = ClassFactory.Get <ISynchronizationLogger>(new ConstructorArgument("userId", userConnection.CurrentUser.Id));
 }
 public async Task SynchronizePartial(
     IEnumerable <IIdWithHints <TAtypeEntityId, TAtypeEntityVersion> > aIds,
     IEnumerable <IIdWithHints <TBtypeEntityId, TBtypeEntityVersion> > bIds,
     ISynchronizationLogger logger)
 {
     await _inner.SynchronizePartial(aIds, bIds, logger, () => Task.FromResult(0), c => Task.FromResult(0));
 }
 public async Task SynchronizePartial(
     IEnumerable <IIdWithHints <TAtypeEntityId, TAtypeEntityVersion> > aIds,
     IEnumerable <IIdWithHints <TBtypeEntityId, TBtypeEntityVersion> > bIds,
     ISynchronizationLogger logger)
 {
     await _inner.SynchronizePartial(aIds, bIds, logger, _contextFactory.Create, _contextFactory.SynchronizationFinished);
 }
        public async Task Synchronize(ISynchronizationLogger logger, TContext synchronizationContext)
        {
            s_logger.InfoFormat("Entered. Syncstrategy '{0}' with Atype='{1}' and Btype='{2}'", _initialSyncStateCreationStrategy.GetType().Name, typeof(TAtypeEntity).Name, typeof(TBtypeEntity).Name);

            using (var totalProgress = _totalProgressFactory.Create())
            {
                var knownEntityRelations = _entityRelationDataAccess.LoadEntityRelationData()
                                           ?? new IEntityRelationData <TAtypeEntityId, TAtypeEntityVersion, TBtypeEntityId, TBtypeEntityVersion>[] { };

                using (var interceptor = _synchronizationInterceptorFactory.Create())
                {
                    var newAVersionsTask = _atypeRepository.GetAllVersions(knownEntityRelations.Select(r => r.AtypeId), synchronizationContext);
                    var newBVersionsTask = _btypeRepository.GetAllVersions(knownEntityRelations.Select(r => r.BtypeId), synchronizationContext);

                    var newAVersions = CreateDictionary(
                        await newAVersionsTask,
                        _atypeIdComparer);

                    var newBVersions = CreateDictionary(
                        await newBVersionsTask,
                        _btypeIdComparer);

                    await Synchronize(
                        totalProgress,
                        knownEntityRelations,
                        newAVersions,
                        newBVersions,
                        logger,
                        synchronizationContext,
                        interceptor,
                        newEntityRelations => _entityRelationDataAccess.SaveEntityRelationData(newEntityRelations));
                }
            }
            s_logger.DebugFormat("Exiting.");
        }
        public async Task Synchronize(ISynchronizationLogger logger)
        {
            var emailAddressCache = new EmailAddressCache();

            emailAddressCache.Items = _emailAddressCacheDataAccess.Load();

            using (var subLogger = logger.CreateSubLogger("Contacts"))
            {
                await _contactSynchronizer.Synchronize(subLogger, emailAddressCache);
            }

            var idsToQuery = emailAddressCache.GetIdsOfEntriesWithEmptyEmailAddress();

            if (idsToQuery.Length > 0)
            {
                await _loggingCardDavRepositoryDecorator.Get(idsToQuery, NullLoadEntityLogger.Instance, emailAddressCache);
            }
            var cacheItems = emailAddressCache.Items;

            _emailAddressCacheDataAccess.Save(cacheItems);

            var distListContext = new DistributionListSychronizationContext(cacheItems, _outlookSession);

            using (var subLogger = logger.CreateSubLogger("DistLists"))
            {
                await _distributionListSynchronizer.Synchronize(subLogger, distListContext);
            }
        }
        public async Task Synchronize(ISynchronizationLogger logger)
        {
            var synchronizationContext = await _contextFactory.Create();

            await _inner.Synchronize(logger, synchronizationContext);

            await _contextFactory.SynchronizationFinished(synchronizationContext);
        }
Esempio n. 9
0
        public async Task SynchronizePartial(IEnumerable <IOutlookId> outlookIds, ISynchronizationLogger logger)
        {
            var idExtractor = new IdWithHintExtractor();

            foreach (var outlookId in outlookIds)
            {
                outlookId.Accept(idExtractor);
            }

            await _synchronizer.SynchronizePartial(idExtractor.Ids, new IIdWithHints <TBtypeEntityId, TBtypeEntityVersion>[] { }, logger);
        }
Esempio n. 10
0
        public async Task SynchronizeNoThrow(ISynchronizationLogger logger)
        {
            s_logger.InfoFormat("Entered. Syncstrategy '{0}' with Atype='{1}' and Btype='{2}'", _initialSyncStateCreationStrategy.GetType().Name, typeof(TAtypeEntity).Name, typeof(TBtypeEntity).Name);

            try
            {
                using (var totalProgress = _totalProgressFactory.Create())
                {
                    var knownEntityRelations = _entityRelationDataAccess.LoadEntityRelationData()
                                               ?? new IEntityRelationData <TAtypeEntityId, TAtypeEntityVersion, TBtypeEntityId, TBtypeEntityVersion>[] { };

                    using (var interceptor = _synchronizationInterceptorFactory.Create())
                    {
                        var synchronizationContext = await _contextFactory.Create();

                        var newAVersionsTask = _atypeRepository.GetAllVersions(knownEntityRelations.Select(r => r.AtypeId), synchronizationContext);
                        var newBVersionsTask = _btypeRepository.GetAllVersions(knownEntityRelations.Select(r => r.BtypeId), synchronizationContext);

                        var newAVersions = CreateDictionary(
                            await newAVersionsTask,
                            _atypeIdComparer);

                        var newBVersions = CreateDictionary(
                            await newBVersionsTask,
                            _btypeIdComparer);

                        using (var entityContainer = new EntityContainer(this, totalProgress, logger.ALoadEntityLogger, logger.BLoadEntityLogger))
                        {
                            var newEntityRelations = await Synchronize(
                                totalProgress,
                                knownEntityRelations,
                                newAVersions,
                                newBVersions,
                                entityContainer,
                                logger,
                                synchronizationContext,
                                interceptor);

                            _entityRelationDataAccess.SaveEntityRelationData(newEntityRelations);
                        }

                        await _contextFactory.SynchronizationFinished(synchronizationContext);
                    }
                }
            }
            catch (Exception x)
            {
                logger.LogAbortedDueToError(x);
                _exceptionLogger.LogException(x, s_logger);
            }

            s_logger.DebugFormat("Exiting.");
        }
        /// <summary>
        /// Creates user connection and starts <paramref name="emailsData"/> synchronization.
        /// </summary>
        /// <param name="emailsData"><see cref="LoadEmailCommand"/> instance.</param>
        public void ProcessLoadEmailCommand(LoadEmailCommand emailsData)
        {
            var userName       = emailsData.SubscriptionInfo.SysAdminUnit;
            var userConnection = CreateUserConnection(userName, emailsData.SubscriptionInfo.TimeZoneId);

            _log = ClassFactory.Get <ISynchronizationLogger>(new ConstructorArgument("userId", userConnection.CurrentUser.Id));
            _log.Info($"UserConnection for {emailsData.SubscriptionInfo.SysAdminUnit} created.");
            try {
                StartSynchronization(userConnection, emailsData);
            }
            finally {
                userConnection?.Close(SessionEndMethod.Logout, false);
            }
            _log.Info($"ProcessLoadEmailCommand for {emailsData.SubscriptionInfo.MailboxId} ended.");
        }
        /// <summary>
        /// Starts events subscription and email synchronization process for period.
        /// </summary>
        /// <param name="userConnection"><see cref="UserConnection"/> instance.</param>
        /// <param name="parameters">Parameters collection.</param>
        public void Execute(UserConnection userConnection, IDictionary <string, object> parameters)
        {
            _log = ClassFactory.Get <ISynchronizationLogger>(new ConstructorArgument("userId", userConnection.CurrentUser.Id));
            _log.DebugFormat("ListenerServiceFailHandler started");
            UserConnection = userConnection;
            if (!GetIsFeatureEnabled("ExchangeListenerEnabled"))
            {
                _log.DebugFormat("ExchangeListenerEnabled feature disabled, ListenerServiceFailHandler ended");
                return;
            }
            ListenerManager = GetExchangeListenerManager();
            _log.DebugFormat("ExchangeListenerManager created");
            Guid mailboxId = (Guid)parameters["MailboxId"];
            var  mailbox   = GetMailbox(mailboxId);

            StartSubscription(mailbox);
            _log.DebugFormat("Events subscription for {0} mailbox created", mailboxId);
            StartPeriodSyncJob(mailbox);
            _log.DebugFormat("Email synchronization process for {0} mailbox created", mailboxId);
            _log.DebugFormat("ListenerServiceFailHandler ended");
        }
        /// <inheritdoc cref="IJobExecutor.Execute(UserConnection userConnection, IDictionary{string, object})"/>
        public void Execute(UserConnection userConnection, IDictionary <string, object> parameters)
        {
            _log = ClassFactory.Get <ISynchronizationLogger>(new ConstructorArgument("userId", userConnection.CurrentUser.Id));
            var senderEmailAddress = parameters["SenderEmailAddress"].ToString();

            _log.Info($"ConnectionEventExecutor.Execute for {senderEmailAddress} started");
            var helper = ClassFactory.Get <ISynchronizationErrorHelper>
                             (new ConstructorArgument("userConnection", userConnection));
            var ignoreRetryCount = GetIgnoreRetryCount(parameters);

            if ((bool)parameters["Avaliable"])
            {
                helper.CleanUpSynchronizationError(senderEmailAddress);
            }
            else
            {
                helper.ProcessSynchronizationError(senderEmailAddress,
                                                   parameters["ExceptionClassName"].ToString(), parameters["ExceptionMessage"].ToString(), ignoreRetryCount);
            }
            _log.Info($"ConnectionEventExecutor.Execute for {senderEmailAddress} finished");
        }
            public void HandleException(Exception exception, ISynchronizationLogger logger)
            {
                PostponeIfRequired(exception);

                if (!_currentRunWasManuallyTriggered && IsWarning(exception))
                {
                    _successiveWarningsCount++;
                    if (_successiveWarningsCount > _maxSucessiveWarnings)
                    {
                        _successiveWarningsCount = 0;
                        LogError(exception, logger);
                    }
                    else
                    {
                        _currentSyncRunCausedWarning = true;
                        logger.LogAbortedDueToWarning(exception);
                        s_logger.Warn(exception);
                    }
                }
                else
                {
                    LogError(exception, logger);
                }
            }
 public async Task Synchronize(ISynchronizationLogger logger)
 {
     await _inner.Synchronize(logger, 0);
 }
 public Task SynchronizeNoThrow(ISynchronizationLogger logger)
 {
     return(Task.FromResult(0));
 }
 public Task SnychronizePartialNoThrow(IEnumerable <IOutlookId> outlookIds, ISynchronizationLogger logger)
 {
     return(Task.FromResult(0));
 }
 public Task SynchronizeNoThrow(ISynchronizationLogger logger)
 {
     _runCount++;
     return(Task.Run(() => FinishSynchronizationEvent.Wait()));
 }
Esempio n. 19
0
 public async Task SnychronizePartialNoThrow(IEnumerable <IIdWithHints <string, DateTime> > outlookIds, ISynchronizationLogger logger)
 {
     await _synchronizer.SynchronizePartialNoThrow(outlookIds, new IIdWithHints <TBtypeEntityId, TBtypeEntityVersion>[] { }, logger);
 }
        public async Task SynchronizePartial(IEnumerable <IIdWithHints <string, DateTime> > aIds, IEnumerable <IIdWithHints <WebResourceName, string> > bIds, ISynchronizationLogger logger)
        {
            var emailAddressCache = new EmailAddressCache();

            emailAddressCache.Items = _emailAddressCacheDataAccess.Load();

            using (var subLogger = logger.CreateSubLogger("Contacts"))
            {
                await _contactSynchronizer.Synchronize(subLogger, emailAddressCache);
            }

            _emailAddressCacheDataAccess.Save(emailAddressCache.Items);
        }
        public async Task SynchronizePartialNoThrow(
            IEnumerable <IIdWithHints <TAtypeEntityId, TAtypeEntityVersion> > aIds,
            IEnumerable <IIdWithHints <TBtypeEntityId, TBtypeEntityVersion> > bIds,
            ISynchronizationLogger logger)
        {
            s_logger.InfoFormat(
                "Entered partial. Syncstrategy '{0}' with Atype='{1}' and Btype='{2}'",
                _initialSyncStateCreationStrategy.GetType().Name,
                typeof(TAtypeEntity).Name,
                typeof(TBtypeEntity).Name);

            try
            {
                var knownEntityRelations = _entityRelationDataAccess.LoadEntityRelationData();

                if (knownEntityRelations == null)
                {
                    await SynchronizeNoThrow(logger);

                    return;
                }

                var requestedAIdsById = aIds.ToDictionary(e => e.Id, _atypeIdComparer);
                var requestedBIdsById = bIds.ToDictionary(e => e.Id, _btypeIdComparer);

                var aIdsWithAwarenessLevel = new List <IdWithAwarenessLevel <TAtypeEntityId> >();
                var bIdsWithAwarenessLevel = new List <IdWithAwarenessLevel <TBtypeEntityId> >();

                using (var totalProgress = _totalProgressFactory.Create())
                {
                    var entityRelationsToUse    = new List <IEntityRelationData <TAtypeEntityId, TAtypeEntityVersion, TBtypeEntityId, TBtypeEntityVersion> >();
                    var entityRelationsNotToUse = new List <IEntityRelationData <TAtypeEntityId, TAtypeEntityVersion, TBtypeEntityId, TBtypeEntityVersion> >();

                    foreach (var entityRelation in knownEntityRelations)
                    {
                        var isACausingSync = RemoveAFromRequestedAndCheckIfCausesSync(requestedAIdsById, entityRelation);
                        var isBCausingSync = RemoveBFromRequestedAndCheckIfCausesSync(requestedBIdsById, entityRelation);

                        if (isACausingSync || isBCausingSync)
                        {
                            aIdsWithAwarenessLevel.Add(new IdWithAwarenessLevel <TAtypeEntityId> (entityRelation.AtypeId, true));
                            bIdsWithAwarenessLevel.Add(new IdWithAwarenessLevel <TBtypeEntityId> (entityRelation.BtypeId, true));

                            entityRelationsToUse.Add(entityRelation);
                        }
                        else
                        {
                            entityRelationsNotToUse.Add(entityRelation);
                        }
                    }

                    aIdsWithAwarenessLevel.AddRange(requestedAIdsById.Where(kv => !(kv.Value.WasDeletedHint ?? false)).Select(kv => new IdWithAwarenessLevel <TAtypeEntityId> (kv.Key, false)));
                    bIdsWithAwarenessLevel.AddRange(requestedBIdsById.Where(kv => !(kv.Value.WasDeletedHint ?? false)).Select(kv => new IdWithAwarenessLevel <TBtypeEntityId> (kv.Key, false)));

                    if (aIdsWithAwarenessLevel.Count == 0 && bIdsWithAwarenessLevel.Count == 0)
                    {
                        s_logger.InfoFormat("Exiting partial since there is nothing to synchronize.");
                        return;
                    }

                    var synchronizationContext = await _contextFactory.Create();

                    Task <IReadOnlyList <EntityVersion <TAtypeEntityId, TAtypeEntityVersion> > > newAVersionsTask;
                    if (aIdsWithAwarenessLevel.Count > 0)
                    {
                        newAVersionsTask = _atypeRepository.GetVersions(aIdsWithAwarenessLevel, synchronizationContext);
                    }
                    else
                    {
                        newAVersionsTask = Task.FromResult <IReadOnlyList <EntityVersion <TAtypeEntityId, TAtypeEntityVersion> > > (new EntityVersion <TAtypeEntityId, TAtypeEntityVersion>[] { });
                    }

                    Task <IReadOnlyList <EntityVersion <TBtypeEntityId, TBtypeEntityVersion> > > newBVersionsTask;
                    if (bIdsWithAwarenessLevel.Count > 0)
                    {
                        newBVersionsTask = _btypeRepository.GetVersions(bIdsWithAwarenessLevel, synchronizationContext);
                    }
                    else
                    {
                        newBVersionsTask = Task.FromResult <IReadOnlyList <EntityVersion <TBtypeEntityId, TBtypeEntityVersion> > > (new EntityVersion <TBtypeEntityId, TBtypeEntityVersion>[] { });
                    }

                    var newAVersions = CreateDictionary(
                        await newAVersionsTask,
                        _atypeIdComparer);

                    var newBVersions = CreateDictionary(
                        await newBVersionsTask,
                        _btypeIdComparer);

                    using (var entityContainer = new EntityContainer(this, totalProgress, logger.ALoadEntityLogger, logger.BLoadEntityLogger))
                    {
                        var newEntityRelations = await Synchronize(
                            totalProgress,
                            entityRelationsToUse,
                            newAVersions,
                            newBVersions,
                            entityContainer,
                            logger,
                            synchronizationContext);

                        entityRelationsNotToUse.AddRange(newEntityRelations);

                        _entityRelationDataAccess.SaveEntityRelationData(entityRelationsNotToUse);
                    }
                }
            }
            catch (Exception x)
            {
                logger.LogAbortedDueToError(x);
                _exceptionLogger.LogException(x, s_logger);
            }

            s_logger.DebugFormat("Exiting.");
        }
        public async Task <bool> SynchronizePartial(
            IEnumerable <IIdWithHints <TAtypeEntityId, TAtypeEntityVersion> > aIds,
            IEnumerable <IIdWithHints <TBtypeEntityId, TBtypeEntityVersion> > bIds,
            ISynchronizationLogger logger,
            Func <Task <TContext> > contextFactoryAsync,
            Func <TContext, Task> syncronizationFinishedAsync)
        {
            s_logger.InfoFormat(
                "Entered partial. Syncstrategy '{0}' with Atype='{1}' and Btype='{2}'",
                _initialSyncStateCreationStrategy.GetType().Name,
                typeof(TAtypeEntity).Name,
                typeof(TBtypeEntity).Name);

            var knownEntityRelations = _entityRelationDataAccess.LoadEntityRelationData();

            if (knownEntityRelations == null)
            {
                var synchronizationContext = await contextFactoryAsync();
                await Synchronize(logger, synchronizationContext);
                await syncronizationFinishedAsync(synchronizationContext);

                return(true);
            }

            var requestedAIdsById = aIds.ToDictionary(e => e.Id, _atypeIdComparer);
            var requestedBIdsById = bIds.ToDictionary(e => e.Id, _btypeIdComparer);

            var aIdsWithAwarenessLevel = new List <IdWithAwarenessLevel <TAtypeEntityId> >();
            var bIdsWithAwarenessLevel = new List <IdWithAwarenessLevel <TBtypeEntityId> >();

            using (var totalProgress = _totalProgressFactory.Create())
            {
                var entityRelationsToUse    = new List <IEntityRelationData <TAtypeEntityId, TAtypeEntityVersion, TBtypeEntityId, TBtypeEntityVersion> >();
                var entityRelationsNotToUse = new List <IEntityRelationData <TAtypeEntityId, TAtypeEntityVersion, TBtypeEntityId, TBtypeEntityVersion> >();

                foreach (var entityRelation in knownEntityRelations)
                {
                    var isACausingSync = RemoveAFromRequestedAndCheckIfCausesSync(requestedAIdsById, entityRelation);
                    var isBCausingSync = RemoveBFromRequestedAndCheckIfCausesSync(requestedBIdsById, entityRelation);

                    if (isACausingSync || isBCausingSync)
                    {
                        aIdsWithAwarenessLevel.Add(new IdWithAwarenessLevel <TAtypeEntityId>(entityRelation.AtypeId, true));
                        bIdsWithAwarenessLevel.Add(new IdWithAwarenessLevel <TBtypeEntityId>(entityRelation.BtypeId, true));

                        entityRelationsToUse.Add(entityRelation);
                    }
                    else
                    {
                        entityRelationsNotToUse.Add(entityRelation);
                    }
                }

                aIdsWithAwarenessLevel.AddRange(requestedAIdsById.Where(kv => !(kv.Value.WasDeletedHint ?? false)).Select(kv => new IdWithAwarenessLevel <TAtypeEntityId>(kv.Key, false)));
                bIdsWithAwarenessLevel.AddRange(requestedBIdsById.Where(kv => !(kv.Value.WasDeletedHint ?? false)).Select(kv => new IdWithAwarenessLevel <TBtypeEntityId>(kv.Key, false)));

                if (aIdsWithAwarenessLevel.Count == 0 && bIdsWithAwarenessLevel.Count == 0)
                {
                    s_logger.InfoFormat("Exiting partial since there is nothing to synchronize.");
                    return(false);
                }

                using (var interceptor = _synchronizationInterceptorFactory.Create())
                {
                    var synchronizationContext = await contextFactoryAsync();

                    Task <IEnumerable <EntityVersion <TAtypeEntityId, TAtypeEntityVersion> > > aVersionsTask;
                    if (aIdsWithAwarenessLevel.Count > 0)
                    {
                        aVersionsTask = _atypeRepository.GetVersions(aIdsWithAwarenessLevel, synchronizationContext, logger.AGetVersionsEntityLogger);
                    }
                    else
                    {
                        aVersionsTask = Task.FromResult <IEnumerable <EntityVersion <TAtypeEntityId, TAtypeEntityVersion> > >(new EntityVersion <TAtypeEntityId, TAtypeEntityVersion>[] { });
                    }

                    Task <IEnumerable <EntityVersion <TBtypeEntityId, TBtypeEntityVersion> > > bVersionsTask;
                    if (bIdsWithAwarenessLevel.Count > 0)
                    {
                        bVersionsTask = _btypeRepository.GetVersions(bIdsWithAwarenessLevel, synchronizationContext, logger.BGetVersionsEntityLogger);
                    }
                    else
                    {
                        bVersionsTask = Task.FromResult <IEnumerable <EntityVersion <TBtypeEntityId, TBtypeEntityVersion> > >(new EntityVersion <TBtypeEntityId, TBtypeEntityVersion>[] { });
                    }

                    var aStates = VersionAwareEntityStateCollection <TAtypeEntityId, TAtypeEntityVersion> .Create(await aVersionsTask, _atypeIdComparer, _atypeVersionComparer);

                    var bStates = VersionAwareEntityStateCollection <TBtypeEntityId, TBtypeEntityVersion> .Create(await bVersionsTask, _btypeIdComparer, _btypeVersionComparer);

                    await Synchronize(
                        totalProgress,
                        entityRelationsToUse,
                        aStates,
                        bStates,
                        logger,
                        synchronizationContext,
                        interceptor,
                        newEntityRelations =>
                    {
                        entityRelationsNotToUse.AddRange(newEntityRelations);
                        _entityRelationDataAccess.SaveEntityRelationData(entityRelationsNotToUse);
                    });
                }
            }

            s_logger.DebugFormat("Exiting.");
            return(true);
        }
        private async Task Synchronize(
            ITotalProgressLogger totalProgress,
            IEnumerable <IEntityRelationData <TAtypeEntityId, TAtypeEntityVersion, TBtypeEntityId, TBtypeEntityVersion> > knownEntityRelations,
            IEntityStateCollection <TAtypeEntityId, TAtypeEntityVersion> aStates,
            IEntityStateCollection <TBtypeEntityId, TBtypeEntityVersion> bStates,
            ISynchronizationLogger logger,
            TContext synchronizationContext,
            ISynchronizationInterceptor <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity, TContext> interceptor,
            Action <List <IEntityRelationData <TAtypeEntityId, TAtypeEntityVersion, TBtypeEntityId, TBtypeEntityVersion> > > saveNewRelations)
        {
            var entitySynchronizationLoggerFactory = new SynchronizationLoggerBoundEntitySynchronizationLoggerFactory <TAtypeEntity, TBtypeEntity>(logger, _fullEntitySynchronizationLoggerFactory);

            using (IEntityContainer <TAtypeEntityId, TAtypeEntity, TContext> aEntities = new EntityContainer <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TContext>(_atypeRepository, _atypeIdComparer, _chunkSize, _chunkedExecutor))
                using (IEntityContainer <TBtypeEntityId, TBtypeEntity, TContext> bEntities = new EntityContainer <TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity, TContext>(_btypeRepository, _btypeIdComparer, _chunkSize, _chunkedExecutor))
                {
                    var entitySynchronizationContexts = await CreateEntitySyncStateContexts(aEntities, bEntities, knownEntityRelations, aStates, bStates, logger, synchronizationContext, interceptor);

                    var totalAJobs = new JobCount();
                    var totalBJobs = new JobCount();

                    try
                    {
                        var chunks = _entitySyncStateChunkCreator.CreateChunks(entitySynchronizationContexts, _atypeIdComparer, _btypeIdComparer).ToArray();


                        totalProgress.NotifyWork(chunks.Aggregate(0, (acc, c) => acc + c.AEntitesToLoad.Count + c.BEntitesToLoad.Count), chunks.Length);

                        foreach ((var aEntitesToLoad, var bEntitesToLoad, var currentBatch) in chunks)
                        {
                            var chunkLogger = totalProgress.StartChunk();

                            IReadOnlyDictionary <TAtypeEntityId, TAtypeEntity> aEntitiesById;
                            using (chunkLogger.StartARepositoryLoad(aEntitesToLoad.Count))
                            {
                                aEntitiesById = await aEntities.GetEntities(aEntitesToLoad, logger.ALoadEntityLogger, synchronizationContext);
                            }

                            IReadOnlyDictionary <TBtypeEntityId, TBtypeEntity> bEntitiesById;
                            using (chunkLogger.StartBRepositoryLoad(bEntitesToLoad.Count))
                            {
                                bEntitiesById = await bEntities.GetEntities(bEntitesToLoad, logger.BLoadEntityLogger, synchronizationContext);
                            }

                            currentBatch.ForEach(s => s.FetchRequiredEntities(aEntitiesById, bEntitiesById));
                            currentBatch.ForEach(s => s.Resolve());

                            // since resolve may change to an new state, required entities have to be fetched again.
                            // an state is allowed only to resolve to another state, if the following states requires equal or less entities!
                            currentBatch.ForEach(s => s.FetchRequiredEntities(aEntitiesById, bEntitiesById));

                            var aJobs = new JobList <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity>();
                            var bJobs = new JobList <TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity>();

                            currentBatch.ForEach(s => s.AddSyncronizationJob(aJobs, bJobs, entitySynchronizationLoggerFactory, synchronizationContext));

                            totalAJobs = totalAJobs.Add(aJobs.Count);
                            totalBJobs = totalBJobs.Add(bJobs.Count);

                            try
                            {
                                using (var progress = chunkLogger.StartProcessing(aJobs.TotalJobCount + bJobs.TotalJobCount))
                                {
                                    await _atypeWriteRepository.PerformOperations(aJobs.CreateJobs, aJobs.UpdateJobs, aJobs.DeleteJobs, progress, synchronizationContext);

                                    await _btypeWriteRepository.PerformOperations(bJobs.CreateJobs, bJobs.UpdateJobs, bJobs.DeleteJobs, progress, synchronizationContext);
                                }

                                currentBatch.ForEach(s => s.NotifyJobExecuted());
                            }
                            catch (Exception x)
                            {
                                if (_exceptionHandlingStrategy.DoesGracefullyAbortSynchronization(x))
                                {
                                    entitySynchronizationContexts.ForEach(s => s.Abort());
                                    SaveNewRelations(entitySynchronizationContexts, saveNewRelations);
                                }
                                throw;
                            }
                        }
                    }
                    finally
                    {
                        s_logger.InfoFormat($"A repository jobs: {totalAJobs}");
                        s_logger.InfoFormat($"B repository jobs: {totalBJobs}");
                        logger.LogJobs(totalAJobs.ToString(), totalBJobs.ToString());
                    }

                    SaveNewRelations(entitySynchronizationContexts, saveNewRelations);
                }
        }
 private static void LogError(Exception exception, ISynchronizationLogger logger)
 {
     logger.LogAbortedDueToError(exception);
     ExceptionHandler.Instance.LogException(exception, s_logger);
 }
 public Task SnychronizePartialNoThrow (IEnumerable<IOutlookId> outlookIds, ISynchronizationLogger logger)
 {
   return Task.FromResult (0);
 }
 public Task SynchronizeNoThrow (ISynchronizationLogger logger)
 {
   _runCount++;
   return Task.Run (() => FinishSynchronizationEvent.Wait());
 }
Esempio n. 27
0
 public SynchronizationLoggerBoundEntitySynchronizationLoggerFactory(ISynchronizationLogger synchronizationLogger, IFullEntitySynchronizationLoggerFactory <TAtypeEntityId, TAtypeEntity, TBtypeEntityId, TBtypeEntity> entitySynchronizationLoggerFactory)
 {
     _entitySynchronizationLoggerFactory = entitySynchronizationLoggerFactory ?? throw new ArgumentNullException(nameof(entitySynchronizationLoggerFactory));
     _synchronizationLogger = synchronizationLogger ?? throw new ArgumentNullException(nameof(synchronizationLogger));
 }
 public Task SnychronizePartialNoThrow(IEnumerable <IIdWithHints <string, DateTime> > outlookIds, ISynchronizationLogger logger)
 {
     return(Task.FromResult(0));
 }
 public async Task SnychronizePartialNoThrow (IEnumerable<string> outlookIds, ISynchronizationLogger logger)
 {
   await _synchronizer.SynchronizePartialNoThrow (outlookIds, new Uri[] { }, logger);
 }
        private async Task <IReadOnlyList <IEntitySyncStateContext <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity, TContext> > > CreateEntitySyncStateContexts(
            IEntityContainer <TAtypeEntityId, TAtypeEntity, TContext> aEntities,
            IEntityContainer <TBtypeEntityId, TBtypeEntity, TContext> bEntities,
            IEnumerable <IEntityRelationData <TAtypeEntityId, TAtypeEntityVersion, TBtypeEntityId, TBtypeEntityVersion> > knownEntityRelations,
            IEntityStateCollection <TAtypeEntityId, TAtypeEntityVersion> aStates,
            IEntityStateCollection <TBtypeEntityId, TBtypeEntityVersion> bStates,
            ISynchronizationLogger logger,
            TContext synchronizationContext,
            ISynchronizationInterceptor <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity, TContext> interceptor)
        {
            var entitySynchronizationContexts = new List <IEntitySyncStateContext <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity, TContext> >();

            var aDeltaLogInfo = new VersionDeltaLoginInformation();
            var bDeltaLogInfo = new VersionDeltaLoginInformation();

            foreach (var knownEntityRelationData in knownEntityRelations)
            {
                (var aState, var aRepositoryVersion) = aStates.RemoveState(knownEntityRelationData.AtypeId, knownEntityRelationData.AtypeVersion);
                (var bState, var bRepositoryVersion) = bStates.RemoveState(knownEntityRelationData.BtypeId, knownEntityRelationData.BtypeVersion);

                entitySynchronizationContexts.Add(new EntitySyncStateContext <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity, TContext>(
                                                      CreateInitialSyncState(knownEntityRelationData, aState, bState, aRepositoryVersion, bRepositoryVersion, aDeltaLogInfo, bDeltaLogInfo)));
            }

            var newAVersions = aStates.DisposeAndGetLeftovers();
            var newBVersions = bStates.DisposeAndGetLeftovers();

            await _atypeRepository.VerifyUnknownEntities(newAVersions, synchronizationContext);

            await _btypeRepository.VerifyUnknownEntities(newBVersions, synchronizationContext);

            if (newAVersions.Count > 0 && newBVersions.Count > 0)
            {
                s_logger.Info($"Performing entity matching with {newAVersions.Count} Atype and {newBVersions.Count} Btype entities.");

                var matchingEntites = _initialEntityMatcher.FindMatchingEntities(
                    _entityRelationDataFactory,
                    await aEntities.GetTransformedEntities(newAVersions.Keys, logger.ALoadEntityLogger, synchronizationContext, e => _aMatchDataFactory.CreateMatchData(e.Entity)),
                    await bEntities.GetTransformedEntities(newBVersions.Keys, logger.BLoadEntityLogger, synchronizationContext, e => _bMatchDataFactory.CreateMatchData(e.Entity)),
                    newAVersions,
                    newBVersions);

                foreach (var knownEntityRelationData in matchingEntites)
                {
                    newAVersions.Remove(knownEntityRelationData.AtypeId);
                    newBVersions.Remove(knownEntityRelationData.BtypeId);
                    var entitySyncState = _initialSyncStateCreationStrategy.CreateFor_Unchanged_Unchanged(knownEntityRelationData);
                    entitySynchronizationContexts.Add(new EntitySyncStateContext <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity, TContext>(entitySyncState));
                    aDeltaLogInfo.IncUnchanged();
                    bDeltaLogInfo.IncUnchanged();
                }

                s_logger.Info("Entity matching finished.");
            }

            foreach (var newA in newAVersions)
            {
                var syncState = _initialSyncStateCreationStrategy.CreateFor_Added_NotExisting(newA.Key, newA.Value);
                entitySynchronizationContexts.Add(new EntitySyncStateContext <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity, TContext>(syncState));
            }

            foreach (var newB in newBVersions)
            {
                var syncState = _initialSyncStateCreationStrategy.CreateFor_NotExisting_Added(newB.Key, newB.Value);
                entitySynchronizationContexts.Add(new EntitySyncStateContext <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity, TContext>(syncState));
            }

            interceptor.TransformInitialCreatedStates(entitySynchronizationContexts, _syncStateFactory);

            // all the leftovers in newAVersions and newBVersions must be the added ones
            aDeltaLogInfo.IncAdded(newAVersions.Count);
            bDeltaLogInfo.IncAdded(newBVersions.Count);
            s_logger.InfoFormat("Atype delta: {0}", aDeltaLogInfo);
            s_logger.InfoFormat("Btype delta: {0}", bDeltaLogInfo);
            logger.LogDeltas(aDeltaLogInfo, bDeltaLogInfo);

            return(entitySynchronizationContexts);
        }
 public Task SynchronizeNoThrow (ISynchronizationLogger logger)
 {
   return _synchronizer.SynchronizeNoThrow (logger);
 }
 public Task SynchronizeNoThrow (ISynchronizationLogger logger)
 {
   return Task.FromResult (0);
 }
 public Task SnychronizePartialNoThrow (IEnumerable<string> outlookIds, ISynchronizationLogger logger)
 {
   throw new NotImplementedException();
 }
Esempio n. 34
0
 public Task SynchronizeNoThrow(ISynchronizationLogger logger)
 {
     return(_synchronizer.SynchronizeNoThrow(logger));
 }
        private async Task <List <IEntityRelationData <TAtypeEntityId, TAtypeEntityVersion, TBtypeEntityId, TBtypeEntityVersion> > > Synchronize(
            ITotalProgressLogger totalProgress,
            IEnumerable <IEntityRelationData <TAtypeEntityId, TAtypeEntityVersion, TBtypeEntityId, TBtypeEntityVersion> > knownEntityRelations,
            Dictionary <TAtypeEntityId, TAtypeEntityVersion> newAVersions,
            Dictionary <TBtypeEntityId, TBtypeEntityVersion> newBVersions,
            EntityContainer entityContainer,
            ISynchronizationLogger logger,
            TContext synchronizationContext)
        {
            var entitySyncStates = new EntitySyncStateContainer <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity>();

            var aDeltaLogInfo = new VersionDeltaLoginInformation();
            var bDeltaLogInfo = new VersionDeltaLoginInformation();

            foreach (var knownEntityRelationData in knownEntityRelations)
            {
                TAtypeEntityVersion newAVersion;
                TBtypeEntityVersion newBVersion;

                var newAVersionAvailable = newAVersions.TryGetValue(knownEntityRelationData.AtypeId, out newAVersion);
                var newBVersionAvailable = newBVersions.TryGetValue(knownEntityRelationData.BtypeId, out newBVersion);

                if (newAVersionAvailable)
                {
                    newAVersions.Remove(knownEntityRelationData.AtypeId);
                }

                if (newBVersionAvailable)
                {
                    newBVersions.Remove(knownEntityRelationData.BtypeId);
                }

                var entitySyncState = CreateInitialSyncState(knownEntityRelationData, newAVersionAvailable, newAVersion, newBVersionAvailable, newBVersion, aDeltaLogInfo, bDeltaLogInfo);

                entitySyncStates.Add(entitySyncState);
            }

            HashSet <TAtypeEntityId> aEntitesToLoad = new HashSet <TAtypeEntityId>();
            HashSet <TBtypeEntityId> bEntitesToLoad = new HashSet <TBtypeEntityId>();

            entitySyncStates.Execute(s => s.AddRequiredEntitiesToLoad(aEntitesToLoad.Add, bEntitesToLoad.Add));

            if (newAVersions.Count > 0 && newBVersions.Count > 0)
            {
                foreach (var newA in newAVersions)
                {
                    aEntitesToLoad.Add(newA.Key);
                }

                foreach (var newB in newBVersions)
                {
                    bEntitesToLoad.Add(newB.Key);
                }

                await entityContainer.FillIfEmpty(aEntitesToLoad, bEntitesToLoad, synchronizationContext);

                var newAtypeEntities = GetSubSet(entityContainer.AEntities, newAVersions.Keys, _atypeIdComparer);
                var newBtypeEntities = GetSubSet(entityContainer.BEntities, newBVersions.Keys, _btypeIdComparer);

                var matchingEntites = _initialEntityMatcher.FindMatchingEntities(
                    _entityRelationDataFactory,
                    newAtypeEntities,
                    newBtypeEntities,
                    newAVersions,
                    newBVersions);

                foreach (var knownEntityRelationData in matchingEntites)
                {
                    newAVersions.Remove(knownEntityRelationData.AtypeId);
                    newBVersions.Remove(knownEntityRelationData.BtypeId);
                    var entitySyncState = _initialSyncStateCreationStrategy.CreateFor_Unchanged_Unchanged(knownEntityRelationData);
                    entitySyncStates.Add(entitySyncState);
                }

                foreach (var newA in newAVersions)
                {
                    var syncState = _initialSyncStateCreationStrategy.CreateFor_Added_NotExisting(newA.Key, newA.Value);
                    entitySyncStates.Add(syncState);
                }

                foreach (var newB in newBVersions)
                {
                    var syncState = _initialSyncStateCreationStrategy.CreateFor_NotExisting_Added(newB.Key, newB.Value);
                    entitySyncStates.Add(syncState);
                }
            }
            else
            {
                foreach (var newA in newAVersions)
                {
                    var syncState = _initialSyncStateCreationStrategy.CreateFor_Added_NotExisting(newA.Key, newA.Value);
                    syncState.AddRequiredEntitiesToLoad(aEntitesToLoad.Add, bEntitesToLoad.Add);
                    entitySyncStates.Add(syncState);
                }

                foreach (var newB in newBVersions)
                {
                    var syncState = _initialSyncStateCreationStrategy.CreateFor_NotExisting_Added(newB.Key, newB.Value);
                    syncState.AddRequiredEntitiesToLoad(aEntitesToLoad.Add, bEntitesToLoad.Add);
                    entitySyncStates.Add(syncState);
                }

                await entityContainer.FillIfEmpty(aEntitesToLoad, bEntitesToLoad, synchronizationContext);
            }

            // all the leftovers in newAVersions and newBVersions must be the added ones
            aDeltaLogInfo.IncAdded(newAVersions.Count);
            bDeltaLogInfo.IncAdded(newBVersions.Count);
            s_logger.InfoFormat("Atype delta: {0}", aDeltaLogInfo);
            s_logger.InfoFormat("Btype delta: {0}", bDeltaLogInfo);
            logger.LogDeltas(aDeltaLogInfo, bDeltaLogInfo);


            entitySyncStates.DoTransition(s => s.FetchRequiredEntities(entityContainer.AEntities, entityContainer.BEntities));
            entitySyncStates.DoTransition(s => s.Resolve());

            // since resolve may change to an new state, required entities have to be fetched again.
            // an state is allowed only to resolve to another state, if the following states requires equal or less entities!
            entitySyncStates.DoTransition(s => s.FetchRequiredEntities(entityContainer.AEntities, entityContainer.BEntities));

            var aJobs = new JobList <TAtypeEntity, TAtypeEntityId, TAtypeEntityVersion>();
            var bJobs = new JobList <TBtypeEntity, TBtypeEntityId, TBtypeEntityVersion>();

            entitySyncStates.Execute(s => s.AddSyncronizationJob(aJobs, bJobs, logger.CreateEntitySynchronizationLogger()));

            using (var progress = totalProgress.StartProcessing(aJobs.TotalJobCount + bJobs.TotalJobCount))
            {
                await _atypeWriteRepository.PerformOperations(aJobs.CreateJobs, aJobs.UpdateJobs, aJobs.DeleteJobs, progress, synchronizationContext);

                await _btypeWriteRepository.PerformOperations(bJobs.CreateJobs, bJobs.UpdateJobs, bJobs.DeleteJobs, progress, synchronizationContext);
            }

            entitySyncStates.DoTransition(s => s.NotifyJobExecuted());

            var newEntityRelations = new List <IEntityRelationData <TAtypeEntityId, TAtypeEntityVersion, TBtypeEntityId, TBtypeEntityVersion> >();

            entitySyncStates.Execute(s => s.AddNewRelationNoThrow(newEntityRelations.Add));

            entitySyncStates.Dispose();


            return(newEntityRelations);
        }
 public Task SnychronizePartialNoThrow(IEnumerable <IIdWithHints <string, DateTime> > outlookIds, ISynchronizationLogger logger)
 {
     throw new NotImplementedException();
 }