private static ItemSynchronizer CreateItemSynchronizer(MailboxSession mailboxSession, LocalFolder localFolder) { IEnumerable <CultureInfo> preferredCultures = mailboxSession.MailboxOwner.PreferredCultures; CultureInfo cultureInfo = preferredCultures.Any <CultureInfo>() ? preferredCultures.First <CultureInfo>() : CultureInfo.CurrentCulture; SharingEngine.Tracer.TraceDebug <CultureInfo, IExchangePrincipal>(0L, "Culture {0} has been selected for mailbox {1}.", cultureInfo, mailboxSession.MailboxOwner); return(ItemSynchronizer.Create(localFolder, cultureInfo)); }
private bool TrySyncOneItem(MailboxSession mailboxSession, ItemSynchronizer itemSynchronizer, ItemType remoteItem) { SharingEngine.Tracer.TraceDebug <SharingEngine, string>((long)this.GetHashCode(), "{0}: Syncing item {1}", this, remoteItem.ItemId.Id); LocalizedException exception = null; try { Exception syncException = null; GrayException.MapAndReportGrayExceptions(delegate() { try { itemSynchronizer.Sync(remoteItem, mailboxSession, this.ExchangeService); } catch (FailedCommunicationException syncException) { FailedCommunicationException syncException = syncException; } catch (StorageTransientException syncException2) { FailedCommunicationException syncException = syncException2; } catch (ObjectNotFoundException syncException3) { FailedCommunicationException syncException = syncException3; } catch (RecurrenceException exception2) { exception = exception2; } catch (TimeZoneException exception3) { exception = exception3; } catch (ObjectValidationException syncException4) { FailedCommunicationException syncException = syncException4; } }); if (syncException != null) { SharingEngine.Tracer.TraceError <SharingEngine, Exception>((long)this.GetHashCode(), "{0}: Transient failure while syncing an item. Exception: {1}", this, syncException); throw new BatchSynchronizationFailedException(syncException); } } catch (GrayException exception) { GrayException exception4; exception = exception4; } if (exception != null) { SharingEngine.Tracer.TraceError <SharingEngine, string, LocalizedException>((long)this.GetHashCode(), "{0}: Error syncing item {1}. Exception: {2}", this, remoteItem.ItemId.Id, exception); SharingLog.LogEntry(mailboxSession, string.Format("Error syncing item - Subject: {0}, Id: {1}, Exception: {2}", remoteItem.Subject, remoteItem.ItemId.Id, exception)); return(false); } return(true); }
public static bool SyncFolder(MailboxSession mailboxSession, StoreId sharingFolderId, Deadline processingDeadline) { if (!SharingEngine.tracker.Start(mailboxSession.MailboxOwner.MailboxInfo.MailboxGuid, sharingFolderId)) { SharingEngine.Tracer.TraceError <StoreId>(0L, "{0}: Folder is already syncing", sharingFolderId); throw new PendingSynchronizationException(); } bool result = true; SharingEngine sharingEngine = null; LocalFolder localFolder = null; ItemSynchronizer itemSynchronizer = null; try { SharingLog.LogEntry(mailboxSession, "Starting sync for folder " + sharingFolderId); localFolder = SharingEngine.GetLocalFolder(mailboxSession, sharingFolderId); localFolder.UpdateLastAttemptedSyncTime(); itemSynchronizer = SharingEngine.CreateItemSynchronizer(mailboxSession, localFolder); sharingEngine = SharingEngine.Create(mailboxSession, sharingFolderId); result = sharingEngine.Execute(mailboxSession, localFolder, itemSynchronizer, processingDeadline); } catch (Exception arg) { SharingLog.LogEntry(mailboxSession, string.Format("Synchronization finished unexpectedly due to the following error: {0}, External Url {1}", arg, (sharingEngine != null && sharingEngine.ExchangeService != null) ? sharingEngine.ExchangeService.Url : "Not specified")); throw; } finally { SharingEngine.UnblockFolderSync(mailboxSession.MailboxOwner.MailboxInfo.MailboxGuid, sharingFolderId); if (itemSynchronizer != null) { itemSynchronizer = null; } if (localFolder != null) { localFolder.Dispose(); localFolder = null; } if (sharingEngine != null) { sharingEngine.Dispose(); } } return(result); }
private bool BatchSync(MailboxSession mailboxSession, LocalFolder localFolder, ItemSynchronizer itemSynchronizer) { List <ItemIdType> list = new List <ItemIdType>(); if (string.IsNullOrEmpty(this.SyncState)) { this.SyncState = localFolder.LoadSyncState(); } Changes changes = this.ExchangeService.GetChanges(128, this.SyncState); if (changes == null) { SharingEngine.Tracer.TraceDebug <LocalFolder>((long)this.GetHashCode(), "{0}: Unable to retrieve changes", localFolder); return(false); } SharingEngine.Tracer.TraceDebug <SharingEngine, int>((long)this.GetHashCode(), "{0}: Called SyncFolderItems. Got {1} changes", this, changes.Items.Length); foreach (ItemChange itemChange in changes.Items) { switch (itemChange.ChangeType) { case ItemChangeType.Create: case ItemChangeType.Update: list.Add(itemChange.Id); break; case ItemChangeType.Delete: { StoreId localIdFromRemoteId = localFolder.GetLocalIdFromRemoteId(itemChange.Id.Id); if (localIdFromRemoteId != null) { localFolder.SelectItemToDelete(localIdFromRemoteId); } break; } } } if (list.Count > 0) { SharingEngine.Tracer.TraceDebug <SharingEngine, int>((long)this.GetHashCode(), "{0}: Processing {1} creates/updates", this, list.Count); IEnumerable <ItemType> item = this.ExchangeService.GetItem(list.ToArray(), localFolder.Type); if (item != null) { int num = 0; foreach (ItemType remoteItem in item) { if (this.Deadline.IsOver) { SharingEngine.Tracer.TraceError <SharingEngine>((long)this.GetHashCode(), "{0}: run out of time for completing the sync", this); return(true); } if (!this.TrySyncOneItem(mailboxSession, itemSynchronizer, remoteItem)) { num++; SharingEngine.Tracer.TraceError <SharingEngine, int>((long)this.GetHashCode(), "{0}: Item failed to sync. Total number of failures during this batch: {1}.", this, num); if (num == 30) { SharingEngine.Tracer.TraceError <SharingEngine>((long)this.GetHashCode(), "{0}: Too many items have failed. Ending batch loop.", this); break; } } } SharingLog.LogEntry(mailboxSession, string.Format("Synchronized {0} out of {1} items during this batch.", list.Count - num, list.Count)); if (num == list.Count || num == 30) { SharingEngine.Tracer.TraceError <SharingEngine>((long)this.GetHashCode(), "{0}: Excessive errors while processing batch. Sync state will not be saved.", this); throw new BatchSynchronizationFailedException(); } } } localFolder.SaveSyncState(changes.SyncState); this.SyncState = changes.SyncState; return(changes.MoreChangesAvailable); }
private void EnforceLevelOfDetails(MailboxSession mailboxSession, LocalFolder localFolder, ItemSynchronizer itemSynchronizer) { if (this.OriginalLevelOfDetails > this.ActualLevelOfDetails) { SharingEngine.Tracer.TraceDebug <SharingEngine, SharingLevelOfDetails, SharingLevelOfDetails>((long)this.GetHashCode(), "{0}: Updating existing items due to permission changes. Original level: {1}. Actual level: {2}.", this, this.OriginalLevelOfDetails, this.ActualLevelOfDetails); localFolder.ProcessAllItems(delegate(StoreId localItemId) { itemSynchronizer.EnforceLevelOfDetails(mailboxSession, localItemId, this.ActualLevelOfDetails); }); } }
private bool SynchronizeFolderItems(MailboxSession mailboxSession, LocalFolder localFolder, ItemSynchronizer itemSynchronizer) { bool result = false; SharingEngine.Tracer.TraceDebug <SharingEngine>((long)this.GetHashCode(), "{0}: Start syncing folder", this); try { while (this.BatchSync(mailboxSession, localFolder, itemSynchronizer)) { if (this.Deadline.IsOver) { SharingEngine.Tracer.TraceDebug <SharingEngine>((long)this.GetHashCode(), "{0}: Timed out while syncing new items.", this); break; } } } finally { localFolder.DeleteSelectedItems(); } this.EnforceLevelOfDetails(mailboxSession, localFolder, itemSynchronizer); localFolder.SaveLevelOfDetails(this.ActualLevelOfDetails); SharingEngine.Tracer.TraceDebug <SharingEngine>((long)this.GetHashCode(), "{0}: End syncing folder", this); if (!this.Deadline.IsOver) { result = true; localFolder.UpdateLastSyncTimes(); SharingLog.LogEntry(mailboxSession, "Synchronization completed."); } return(result); }
private bool SynchronizeFolder(MailboxSession mailboxSession, LocalFolder localFolder, ItemSynchronizer itemSynchronizer) { BaseFolderType folder = this.GetFolder(mailboxSession, localFolder); this.ActualLevelOfDetails = new SharingLevelOfDetails(folder); this.OriginalLevelOfDetails = new SharingLevelOfDetails(localFolder.LoadLevelOfDetails()); if (this.OriginalLevelOfDetails == LevelOfDetails.None) { SharingEngine.Tracer.TraceDebug <SharingEngine, SharingLevelOfDetails>((long)this.GetHashCode(), "{0}: Access level changed from None to {1}. Saving the actual access level.", this, this.ActualLevelOfDetails); localFolder.SaveLevelOfDetails(this.ActualLevelOfDetails); } if (this.ActualLevelOfDetails == LevelOfDetails.None) { SharingEngine.Tracer.TraceDebug <LocalFolder>((long)this.GetHashCode(), "{0}: Permissions revoked for this folder.", localFolder); localFolder.DeleteAllItems(); localFolder.DeleteSyncState(); localFolder.SaveLevelOfDetails(this.ActualLevelOfDetails); SharingEngine.Tracer.TraceDebug <LocalFolder>((long)this.GetHashCode(), "{0}: All items have been deleted.", localFolder); SharingLog.LogEntry(mailboxSession, "User no longer has permissions to the publisher's folder. All items have been removed."); return(true); } if (this.ActualLevelOfDetails > this.OriginalLevelOfDetails) { SharingEngine.Tracer.TraceDebug <SharingEngine>((long)this.GetHashCode(), "{0}: Permission to the remote folder has increased. Resetting the sync state.", this); this.SyncState = null; localFolder.DeleteSyncState(); } SharingLog.LogEntry(mailboxSession, "Current permissions to the publisher's folder: " + this.ActualLevelOfDetails); return(this.SynchronizeFolderItems(mailboxSession, localFolder, itemSynchronizer)); }