Пример #1
0
        /// <summary>
        /// Creates pull subscriptions for all rooms and waits on timer delay to pull subscriptions
        /// </summary>
        /// <param name="mailboxOwner"></param>
        /// <returns></returns>
        private async System.Threading.Tasks.Task PullSubscriptionChangesAsync(string mailboxOwner)
        {
            _traceListener.Trace("SyncProgram", $"PullSubscriptionChangesAsync({mailboxOwner}) starting");

            var service = new EWService(EwsToken);

            service.SetImpersonation(ConnectingIdType.SmtpAddress, mailboxOwner);

            if (_subscriptions == null)
            {
                _subscriptions = new List <SubscriptionCollection>();
            }

            var EwsService = new EWService(EwsToken);

            EwsService.SetImpersonation(ConnectingIdType.SmtpAddress, mailboxOwner);

            // Retreive and Store PullSubscription Details
            using (var _context = new EWSDbContext(EWSConstants.Config.Database))
            {
                foreach (var room in _context.RoomListRoomEntities.Where(w => !string.IsNullOrEmpty(w.Identity)))
                {
                    EntitySubscription dbSubscription = null;
                    string             watermark      = null;
                    if (_context.SubscriptionEntities.Any(rs => rs.SmtpAddress == room.SmtpAddress))
                    {
                        dbSubscription = _context.SubscriptionEntities.FirstOrDefault(rs => rs.SmtpAddress == room.SmtpAddress);
                        watermark      = dbSubscription.Watermark;
                    }
                    else
                    {
                        // newup a subscription to track the watermark
                        dbSubscription = new EntitySubscription()
                        {
                            LastRunTime = DateTime.UtcNow,
                            SmtpAddress = room.SmtpAddress
                        };
                        _context.SubscriptionEntities.Add(dbSubscription);
                    }

                    try
                    {
                        var roomService  = new EWService(EwsToken);
                        var subscription = roomService.CreatePullSubscription(ConnectingIdType.SmtpAddress, room.SmtpAddress, pollingTimeout, watermark);

                        // close out the old subscription
                        dbSubscription.PreviousWatermark = (!string.IsNullOrEmpty(watermark)) ? watermark : null;
                        dbSubscription.Watermark         = subscription.Watermark;


                        _traceListener.Trace("SyncProgram", $"ListenToRoomReservationChangesAsync.Subscribed to room {room.SmtpAddress}");
                        _subscriptions.Add(new SubscriptionCollection()
                        {
                            Pulling     = subscription,
                            SmtpAddress = room.SmtpAddress
                        });

                        var rowChanged = _context.SaveChanges();
                        _traceListener.Trace("SyncProgram", $"Pull subscription persisted {rowChanged} rows");
                    }
                    catch (Microsoft.Exchange.WebServices.Data.ServiceRequestException srex)
                    {
                        _traceListener.Trace("SyncProgram", $"Failed to provision subscription {srex.Message}");
                        throw new Exception($"Subscription could not be created for {room.SmtpAddress} with MSG:{srex.Message}");
                    }
                }
            }


            try
            {
                var waitTimer = new TimeSpan(0, 5, 0);
                while (!CancellationTokenSource.IsCancellationRequested)
                {
                    var milliseconds = (int)waitTimer.TotalMilliseconds;

                    using (var _context = new EWSDbContext(EWSConstants.Config.Database))
                    {
                        foreach (var item in _subscriptions)
                        {
                            bool?ismore = default(bool);
                            do
                            {
                                PullSubscription subscription = item.Pulling;
                                var events    = subscription.GetEvents();
                                var watermark = subscription.Watermark;
                                ismore = subscription.MoreEventsAvailable;
                                var email        = item.SmtpAddress;
                                var databaseItem = _context.SubscriptionEntities.FirstOrDefault(rs => rs.SmtpAddress == email);

                                // pull last event from stack TODO: need heuristic for how meetings can be stored
                                var filteredEvents = events.ItemEvents.OrderBy(x => x.TimeStamp);
                                foreach (ItemEvent ev in filteredEvents)
                                {
                                    var itemId = ev.ItemId;
                                    try
                                    {
                                        // Send an item event you can bind to
                                        await Messenger.SendQueueO365ChangesAsync(queueSubscription, email, ev);
                                    }
                                    catch (ServiceResponseException ex)
                                    {
                                        _traceListener.Trace("SyncProgram", $"ServiceException: {ex.Message}");
                                        continue;
                                    }
                                }


                                databaseItem.Watermark   = watermark;
                                databaseItem.LastRunTime = DateTime.UtcNow;

                                // Save Database changes
                                await _context.SaveChangesAsync();
                            }while (ismore == true);
                        }
                    }

                    _traceListener.Trace("SyncProgram", $"Sleeping at {DateTime.UtcNow} for {milliseconds} milliseconds...");
                    System.Threading.Thread.Sleep(milliseconds);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            _traceListener.Trace("SyncProgram", $"PullSubscriptionChangesAsync({mailboxOwner}) exiting");
        }
Пример #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);
            }
        }