예제 #1
0
        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));
        }
예제 #2
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);
        }
예제 #3
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);
        }
예제 #4
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);
        }
예제 #5
0
 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);
         });
     }
 }
예제 #6
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);
        }
예제 #7
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));
        }