예제 #1
0
 public static LocalFolder Bind(MailboxSession mailboxSession, StoreId folderId)
 {
     return(LocalFolder.Bind(mailboxSession, folderId, delegate(LocalFolder folder)
     {
         folder.Initialize();
     }));
 }
예제 #2
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));
        }
예제 #3
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);
        }
예제 #4
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);
        }
예제 #5
0
        private bool Execute(MailboxSession mailboxSession, LocalFolder localFolder, ItemSynchronizer itemSynchronizer, Deadline processingDeadline)
        {
            SharingEngine.Tracer.TraceDebug <SharingEngine>(0L, "{0}: Starting synchrounous execution", this);
            this.Deadline = processingDeadline;
            bool flag = false;
            bool flag2;

            try
            {
                flag2 = this.SynchronizeFolder(mailboxSession, localFolder, itemSynchronizer);
                flag  = true;
            }
            finally
            {
                if (!flag)
                {
                    PerformanceCounters.FolderSynchronizationFailures.Increment();
                }
                else
                {
                    this.UpdateTimeBasedPerfCounters();
                }
            }
            if (flag2)
            {
                PerformanceCounters.FoldersProcessedSynchronously.Increment();
            }
            else
            {
                PerformanceCounters.SynchronizationTimeouts.Increment();
            }
            SharingEngine.Tracer.TraceDebug <SharingEngine>(0L, "{0}: Ended synchrounous execution", this);
            return(flag2);
        }
예제 #6
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);
         });
     }
 }
예제 #7
0
        private static LocalFolder BindToLocalFolder(MailboxSession mailboxSession, StoreId sharingFolderId)
        {
            LocalFolder result;

            try
            {
                result = LocalFolder.BindOnly(mailboxSession, sharingFolderId);
            }
            catch (ObjectNotFoundException ex)
            {
                SharingEngine.Tracer.TraceError <IExchangePrincipal, ObjectNotFoundException>(0L, "{0}: Failed to bind to local folder. Exception: {1}", mailboxSession.MailboxOwner, ex);
                throw new SharingFolderNotFoundException(ex);
            }
            return(result);
        }
예제 #8
0
        private static LocalFolder Bind(MailboxSession mailboxSession, StoreId folderId, LocalFolder.ProcessFolderDelegate processFolder)
        {
            SharingBindingManager sharingBindingManager      = new SharingBindingManager(mailboxSession);
            SharingBindingData    sharingBindingDataInFolder = sharingBindingManager.GetSharingBindingDataInFolder(folderId);

            if (sharingBindingDataInFolder == null)
            {
                LocalFolder.Tracer.TraceError <IExchangePrincipal, StoreId>(0L, "{0}: Unable to find the binding for folder {1}, fail sync", mailboxSession.MailboxOwner, folderId);
                throw new SubscriptionNotFoundException();
            }
            bool        flag        = false;
            Item        item        = null;
            Folder      folder      = null;
            LocalFolder localFolder = null;

            try
            {
                item        = LocalFolder.BindToBindingMessage(mailboxSession, sharingBindingDataInFolder.Id);
                folder      = Folder.Bind(mailboxSession, folderId, LocalFolder.extraProperties);
                localFolder = new LocalFolder(mailboxSession, folder, sharingBindingDataInFolder.RemoteFolderId, item);
                processFolder(localFolder);
                flag = true;
            }
            finally
            {
                if (!flag)
                {
                    if (localFolder != null)
                    {
                        localFolder.Dispose();
                    }
                    else
                    {
                        if (item != null)
                        {
                            item.Dispose();
                        }
                        if (folder != null)
                        {
                            folder.Dispose();
                        }
                    }
                    localFolder = null;
                }
            }
            return(localFolder);
        }
예제 #9
0
        private void SafeUpdateBindingItem(Action <Item> stampBindingItem)
        {
            stampBindingItem(this.binding);
            ConflictResolutionResult conflictResolutionResult = this.binding.Save(SaveMode.ResolveConflicts);

            if (conflictResolutionResult.SaveStatus == SaveResult.IrresolvableConflict)
            {
                LocalFolder.Tracer.TraceDebug <LocalFolder>((long)this.GetHashCode(), "{0}: Conflict occurs when saving the binding message. Reload and try saving again.", this);
                StoreObjectId objectId = this.binding.Id.ObjectId;
                this.binding.Dispose();
                this.binding = LocalFolder.BindToBindingMessage(this.mailboxSession, objectId);
                this.binding.OpenAsReadWrite();
                stampBindingItem(this.binding);
                this.binding.Save(SaveMode.NoConflictResolution);
            }
            this.binding.Load();
        }
예제 #10
0
        public static ItemSynchronizer Create(LocalFolder localFolder, CultureInfo clientCulture)
        {
            switch (localFolder.Type)
            {
            case StoreObjectType.CalendarFolder:
                ItemSynchronizer.Tracer.TraceDebug(0L, "ItemSynchronizer.Create: Creating synchronizer for Calendar folder.");
                return(new CalendarItemSynchronizer(localFolder, clientCulture));

            case StoreObjectType.ContactsFolder:
                ItemSynchronizer.Tracer.TraceDebug(0L, "ItemSynchronizer.Create: Creating synchronizer for Contacts folder.");
                return(new ContactItemSynchronizer(localFolder));

            default:
                ItemSynchronizer.Tracer.TraceWarning <StoreObjectType>(0L, "ItemSynchronizer.Create: No custom synchronizer for type {0}. Creating default synchronizer.", localFolder.Type);
                return(new DefaultItemSynchronizer(localFolder));
            }
        }
예제 #11
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);
        }
예제 #12
0
 public ItemSynchronizer(LocalFolder localFolder)
 {
     this.localFolder = localFolder;
 }
예제 #13
0
 public CalendarItemSynchronizer(LocalFolder localFolder, CultureInfo clientCulture) : base(localFolder)
 {
     this.appointmentTranslator = new AppointmentTranslator(clientCulture);
 }
 public ContactItemSynchronizer(LocalFolder localFolder) : base(localFolder)
 {
 }
예제 #15
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));
        }
예제 #16
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);
        }
예제 #17
0
 public static LocalFolder BindOnly(MailboxSession mailboxSession, StoreId folderId)
 {
     return(LocalFolder.Bind(mailboxSession, folderId, delegate(LocalFolder folder)
     {
     }));
 }
        public void CreateAppointment(ExchangeService exchangeService, MailboxSession session, CalendarItemType remoteItem, LocalFolder localFolder)
        {
            AppointmentTranslator.Tracer.TraceDebug <AppointmentTranslator, string>((long)this.GetHashCode(), "{0}: Creating appointment {1}", this, remoteItem.ItemId.Id);
            CalendarItem calendarItem = CalendarItem.Create(session, localFolder.Id);
            bool         flag         = false;

            try
            {
                this.UpdateAppointment(exchangeService, session, remoteItem, calendarItem);
                flag = true;
            }
            catch (LastOccurrenceDeletionException arg)
            {
                AppointmentTranslator.Tracer.TraceDebug <AppointmentTranslator, string, LastOccurrenceDeletionException>((long)this.GetHashCode(), "{0}: All occurrences in the series were deleted - {1}, Error - {2}, We will delete the local item because there are no instances.", this, remoteItem.ItemId.Id, arg);
                localFolder.SelectItemToDelete(calendarItem.Id.ObjectId);
                flag = true;
            }
            finally
            {
                if (!flag && calendarItem.Id != null)
                {
                    localFolder.SelectItemToDelete(calendarItem.Id.ObjectId);
                }
                calendarItem.Dispose();
            }
        }
예제 #19
0
 public DefaultItemSynchronizer(LocalFolder localFolder) : base(localFolder)
 {
 }