Example #1
0
        /// <summary>
        /// Enable the synchronization of individual folders or Room[s]
        /// </summary>
        /// <param name="folderInfo"></param>
        public void ProcessChanges(EWSFolderInfo folderInfo)
        {
            bool moreChangesAvailable = false;

            _traceListener.Trace("SyncProgram", $"Entered ProcessChanges for {folderInfo.SmtpAddress} at {DateTime.UtcNow}");

            using (EWSDbContext context = new EWSDbContext(EWSConstants.Config.Database))
            {
                var room          = context.RoomListRoomEntities.FirstOrDefault(f => f.SmtpAddress.Equals(folderInfo.SmtpAddress));
                var email         = room.SmtpAddress;
                var syncState     = room.SynchronizationState;
                var syncTimestamp = room.SynchronizationTimestamp;

                try
                {
                    do
                    {
                        // Get all changes since the last call. The synchronization cookie is stored in the _SynchronizationState field.
                        _traceListener.Trace("SyncProgram", $"Sync changes {email} with timestamp {syncTimestamp}");

                        // Just get the IDs of the items.
                        // For performance reasons, do not use the PropertySet.FirstClassProperties.
                        var changes = folderInfo.Service.Current.SyncFolderItems(folderInfo.Folder, PropertySet.IdOnly, null, 512, SyncFolderItemsScope.NormalItems, syncState);

                        // Update the synchronization
                        syncState = changes.SyncState;

                        // Process all changes. If required, add a GetItem call here to request additional properties.
                        foreach (ItemChange itemChange in changes)
                        {
                            // This example just prints the ChangeType and ItemId to the console.
                            // A LOB application would apply business rules to each
                            _traceListener.Trace("SyncProgram", $"ChangeType = {itemChange.ChangeType} with ItemId {itemChange.ItemId.ToString()}");

                            // Send an item event you can bind to
                            var service = System.Threading.Tasks.Task.Run(async() =>
                            {
                                _traceListener.Trace("SyncProgram", "In Thread run await....");
                                await Messenger.SendQueueO365SyncFoldersAsync(queueSync, email, itemChange);
                            }, CancellationTokenSource.Token);
                            service.Wait();
                        }

                        // If more changes are available, issue additional SyncFolderItems requests.
                        moreChangesAvailable = changes.MoreChangesAvailable;

                        room.SynchronizationState     = syncState;
                        room.SynchronizationTimestamp = DateTime.UtcNow;

                        var roomchanges = context.SaveChanges();
                        _traceListener.Trace("SyncProgram", $"Room event folder sync {roomchanges} persisted.");
                    }while (moreChangesAvailable);
                }
                catch (Exception processEx)
                {
                    Trace.TraceError($"Failed to send queue {processEx.Message}");
                }
                finally
                {
                    room.SynchronizationState     = syncState;
                    room.SynchronizationTimestamp = DateTime.UtcNow;

                    var roomchanges = context.SaveChanges();
                    _traceListener.Trace("SyncProgram", $"Failed ProcessChanges({email}) folder sync {roomchanges} persisted.");
                }
            }
        }
Example #2
0
        /// <summary>
        /// Establish the connection
        /// </summary>
        /// <returns></returns>
        async private System.Threading.Tasks.Task RunAsync()
        {
            _traceListener = new ClassTraceListener();

            IsDisposed = false;

            EwsToken = await EWSConstants.AcquireTokenAsync();

            Messenger = new MessageManager(CancellationTokenSource);

            ServiceCredentials = new OAuthCredentials(EwsToken.AccessToken);

            _reconnect     = true;
            _groups        = new Dictionary <string, GroupInfo>();
            _mailboxes     = new Mailboxes(ServiceCredentials, _traceListener);
            _subscriptions = new List <SubscriptionCollection>();
            _connections   = new Dictionary <string, StreamingSubscriptionConnection>();


            var impersonationId = EWSConstants.Config.Exchange.ImpersonationAcct;

            try
            {
                var list = new List <EWSFolderInfo>();
                using (EWSDbContext context = new EWSDbContext(EWSConstants.Config.Database))
                {
                    foreach (var room in context.RoomListRoomEntities.Where(w => !string.IsNullOrEmpty(w.Identity)))
                    {
                        var mailboxId = room.SmtpAddress;

                        try
                        {
                            var roomService = new EWService(EwsToken);
                            roomService.SetImpersonation(ConnectingIdType.SmtpAddress, mailboxId);
                            var folderId = new FolderId(WellKnownFolderName.Calendar, mailboxId);
                            var info     = new EWSFolderInfo()
                            {
                                SmtpAddress = mailboxId,
                                Service     = roomService,
                                Folder      = folderId
                            };
                            list.Add(info);
                        }
                        catch (Exception srex)
                        {
                            _traceListener.Trace("SyncProgram", $"Failed to ProcessChanges{srex.Message}");
                            throw new Exception($"ProcessChanges for {mailboxId} with MSG:{srex.Message}");
                        }
                    }
                }

                // Parallel ForEach (on RoomMailbox Grouping and SyncFolders)
                await System.Threading.Tasks.Task.Run(() =>
                {
                    ParallelOptions options = new ParallelOptions
                    {
                        MaxDegreeOfParallelism = maxConcurrency
                    };

                    // Fireoff folder sync in background thread
                    Parallel.ForEach(list, options,
                                     (bodyInfo) =>
                    {
                        ProcessChanges(bodyInfo);
                    });
                });


                var tasks = new List <System.Threading.Tasks.Task>();


                if (EWSConstants.Config.Exchange.PullEnabled)
                {
                    // Upon completion tick repeater to poll subscriptions
                    tasks.Add(PullSubscriptionChangesAsync(impersonationId));
                }
                else
                {
                    // Upon completion kick of streamingsubscription
                    tasks.Add(CreateStreamingSubscriptionGroupingAsync(impersonationId));
                }

                System.Threading.Tasks.Task.WaitAll(tasks.ToArray());
            }
            catch (Exception ex)
            {
                Trace.TraceError(ex.Message);
            }
        }