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 BaseFolderType GetFolder(MailboxSession mailboxSession, LocalFolder localFolder) { BaseFolderType folder; try { folder = this.ExchangeService.GetFolder(localFolder.RemoteFolderId); } catch (FailedCommunicationException ex) { SharingEngine.Tracer.TraceDebug <SharingEngine, FailedCommunicationException>((long)this.GetHashCode(), "{0}: GetFolder failed with the following exception: {1}", this, ex); SharingLog.LogEntry(mailboxSession, "GetFolder failed with the following exception: " + ex); SharingEngine.Tracer.TraceDebug <SharingEngine>((long)this.GetHashCode(), "{0}: Failure was due connection error which might indicate the EWS endpoint needs update", this); Uri uri; try { uri = this.Discover(); } catch (LocalizedException ex2) { SharingEngine.Tracer.TraceDebug <SharingEngine, LocalizedException>((long)this.GetHashCode(), "{0}: Unable to discover new EWS endpoint because of exception: {1}", this, ex2); throw new AutodiscoverFailedException(ex2, ex); } if (StringComparer.OrdinalIgnoreCase.Equals(uri.ToString(), this.ExchangeService.Url)) { SharingEngine.Tracer.TraceDebug <SharingEngine>((long)this.GetHashCode(), "{0}: EWS endpoint continues to be the same, failing with original exception", this); throw ex; } this.ExchangeService.Url = uri.ToString(); folder = this.ExchangeService.GetFolder(localFolder.RemoteFolderId); SharingLog.LogEntry(mailboxSession, "The Sharing Url for this subscription has been updated to " + uri); this.UpdateSubscriptionData(mailboxSession, uri); } return(folder); }
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)); }
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); }