Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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));
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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);
        }
Ejemplo n.º 6
0
        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);
        }