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."); }
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."); }
private async Task DeleteDuplicates() { var appointmentIdsWithIdenticalHashCode = _hashesById .GroupBy(p => p.Value) .Where(g => g.Count() > 1) .Select(g => g.Select(p => p.Key).ToArray()) .ToArray(); if (appointmentIdsWithIdenticalHashCode.Length == 0) { return; } var appointmentsById = (await _outlookRepository.Get( appointmentIdsWithIdenticalHashCode.SelectMany(l => l).ToArray(), NullLoadEntityLogger.Instance, NullEventSynchronizationContext.Instance)) .ToDictionary(e => e.Id, e => e.Entity); try { var relationsById = _entityRelationDataAccess.LoadEntityRelationData().ToDictionary(r => r.AtypeId); foreach (var ids in appointmentIdsWithIdenticalHashCode) { var appointments = GetAppointments(ids, appointmentsById).ToArray(); if (appointments.Length > 1) { var appointmentToKeep = appointments[0]; var appointmentToKeepData = GetDuplicationRelevantData(appointmentToKeep.Inner); foreach (var appointmentToDelete in appointments.Skip(1)) { if (GetDuplicationRelevantData(appointmentToDelete.Inner).Equals(appointmentToKeepData)) { s_logger.Info($"Deleting duplicate of '{appointmentToKeep.Inner.EntryID}'"); await DeleteAppointment(appointmentToDelete, relationsById); } } } } _entityRelationDataAccess.SaveEntityRelationData(relationsById.Values.ToList()); } finally { _outlookRepository.Cleanup(appointmentsById); } }
private async Task DeleteDuplicates() { var appointmentIdsWithIdenticalHashCode = GetAppointmentIdsWithIdenticalHashCode(); if (appointmentIdsWithIdenticalHashCode.Length == 0) { return; } var relationsById = _entityRelationDataAccess.LoadEntityRelationData().ToDictionary(r => r.AtypeId); foreach (var ids in appointmentIdsWithIdenticalHashCode) { var appointments = await GetAppointments(ids); if (appointments.Length > 1) { try { var appointmentToKeep = appointments[0]; var appointmentToKeepData = GetDuplicationRelevantData(appointmentToKeep.Inner); foreach (var appointmentToDelete in appointments.Skip(1)) { if (GetDuplicationRelevantData(appointmentToDelete.Inner).Equals(appointmentToKeepData)) { s_logger.Info($"Deleting duplicate of '{appointmentToKeep.Inner.EntryID}'"); await DeleteAppointment(appointmentToDelete, relationsById); } } } finally { _outlookRepository.Cleanup(appointments); } } } _entityRelationDataAccess.SaveEntityRelationData(relationsById.Values.ToList()); }
public void SaveEntityRelationData(List <IEntityRelationData <string, DateTime, Uri, string> > data) { _storageDataAccess.SaveEntityRelationData(data); }
public async Task <bool> Synchronize() { 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 cachedData = _entityRelationDataAccess.LoadEntityRelationData(); var aVersionsTask = _atypeRepository.GetVersions(); var bVersionsTask = _btypeRepository.GetVersions(); var aVersions = await aVersionsTask; var bVersions = await bVersionsTask; var atypeRepositoryVersions = CreateDictionary( aVersions, _atypeIdComparer); var btypeRepositoryVersions = CreateDictionary( bVersions, _btypeIdComparer); IReadOnlyDictionary <TAtypeEntityId, TAtypeEntity> aEntities = null; IReadOnlyDictionary <TBtypeEntityId, TBtypeEntity> bEntities = null; try { if (cachedData == null) { s_logger.Info("Did not find entity caches. Performing initial population"); totalProgress.NotifyLoadCount(atypeRepositoryVersions.Count, btypeRepositoryVersions.Count); using (totalProgress.StartARepositoryLoad()) { aEntities = CreateDictionary( await _atypeRepository.Get(atypeRepositoryVersions.Keys), _atypeIdComparer); } using (totalProgress.StartBRepositoryLoad()) { bEntities = CreateDictionary( await _btypeRepository.Get(btypeRepositoryVersions.Keys), _btypeIdComparer); } cachedData = _initialEntityMatcher.FindMatchingEntities( _entityRelationDataFactory, aEntities, bEntities, atypeRepositoryVersions, btypeRepositoryVersions); } var entitySyncStates = new EntitySyncStateContainer <TAtypeEntityId, TAtypeEntityVersion, TAtypeEntity, TBtypeEntityId, TBtypeEntityVersion, TBtypeEntity>(); var aDeltaLogInfo = new VersionDeltaLoginInformation(); var bDeltaLogInfo = new VersionDeltaLoginInformation(); foreach (var cachedEntityData in cachedData) { TAtypeEntityVersion repositoryAVersion; TBtypeEntityVersion repositoryBVersion; var repositoryAVersionAvailable = atypeRepositoryVersions.TryGetValue(cachedEntityData.AtypeId, out repositoryAVersion); var repositoryBVersionAvailable = btypeRepositoryVersions.TryGetValue(cachedEntityData.BtypeId, out repositoryBVersion); if (repositoryAVersionAvailable) { atypeRepositoryVersions.Remove(cachedEntityData.AtypeId); } if (repositoryBVersionAvailable) { btypeRepositoryVersions.Remove(cachedEntityData.BtypeId); } var entitySyncState = CreateInitialSyncState(cachedEntityData, repositoryAVersionAvailable, repositoryAVersion, repositoryBVersionAvailable, repositoryBVersion, aDeltaLogInfo, bDeltaLogInfo); entitySyncStates.Add(entitySyncState); } aDeltaLogInfo.IncAdded(atypeRepositoryVersions.Count); bDeltaLogInfo.IncAdded(btypeRepositoryVersions.Count); s_logger.InfoFormat("Atype delta: {0}", aDeltaLogInfo); s_logger.InfoFormat("Btype delta: {0}", bDeltaLogInfo); foreach (var newA in atypeRepositoryVersions) { entitySyncStates.Add(_initialSyncStateCreationStrategy.CreateFor_Added_NotExisting(newA.Key, newA.Value)); } foreach (var newB in btypeRepositoryVersions) { entitySyncStates.Add(_initialSyncStateCreationStrategy.CreateFor_NotExisting_Added(newB.Key, newB.Value)); } HashSet <TAtypeEntityId> aEntitesToLoad = new HashSet <TAtypeEntityId>(); HashSet <TBtypeEntityId> bEntitesToLoad = new HashSet <TBtypeEntityId>(); entitySyncStates.Execute(s => s.AddRequiredEntitiesToLoad(aEntitesToLoad.Add, bEntitesToLoad.Add)); if (aEntities == null && bEntities == null) { totalProgress.NotifyLoadCount(aEntitesToLoad.Count, bEntitesToLoad.Count); using (totalProgress.StartARepositoryLoad()) { aEntities = CreateDictionary( await _atypeRepository.Get(aEntitesToLoad), _atypeIdComparer); } using (totalProgress.StartBRepositoryLoad()) { bEntities = CreateDictionary( await _btypeRepository.Get(bEntitesToLoad), _btypeIdComparer); } } entitySyncStates.DoTransition(s => s.FetchRequiredEntities(aEntities, 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(aEntities, bEntities)); using (var progress = totalProgress.StartProcessing(entitySyncStates.Count)) { await entitySyncStates.DoTransition( async s => { var nextState = await s.PerformSyncActionNoThrow(); progress.Increase(); return(nextState); }); } var newData = new List <IEntityRelationData <TAtypeEntityId, TAtypeEntityVersion, TBtypeEntityId, TBtypeEntityVersion> >(); entitySyncStates.Execute(s => s.AddNewRelationNoThrow(newData.Add)); entitySyncStates.Dispose(); _entityRelationDataAccess.SaveEntityRelationData(newData); } finally { _atypeRepository.Cleanup(aEntities); _btypeRepository.Cleanup(bEntities); } } } catch (Exception x) { _exceptionLogger.LogException(x, s_logger); return(false); } s_logger.DebugFormat("Exiting."); return(true); }