Beispiel #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");
        }
Beispiel #2
0
        /// <summary>
        /// Poll localDB events and push service bus events to the Queue
        /// </summary>
        /// <param name="queueConnection"></param>
        /// <returns></returns>
        public async System.Threading.Tasks.Task SendQueueDatabaseChangesAsync(string queueConnection)
        {
            var sender = new MessageSender(queueConnection, SBQueueSyncDb);

            var token = await RetreiveToken();

            var EwsService = new EWService(token);

            EwsService.SetImpersonation(ConnectingIdType.SmtpAddress, MailboxOwner);

            // Poll the rooms to store locally
            var roomlisting = EwsService.GetRoomListing();

            using (var EwsDatabase = new EWSDbContext(EWSConstants.Config.Database))
            {
                foreach (var roomlist in roomlisting)
                {
                    foreach (var room in roomlist.Value)
                    {
                        EntityRoomListRoom databaseRoom = null;
                        if (EwsDatabase.RoomListRoomEntities.Any(s => s.SmtpAddress == room.Address))
                        {
                            databaseRoom = await EwsDatabase.RoomListRoomEntities.FirstOrDefaultAsync(f => f.SmtpAddress == room.Address);
                        }
                        else
                        {
                            databaseRoom = new EntityRoomListRoom()
                            {
                                SmtpAddress = room.Address,
                                Identity    = room.Address,
                                RoomList    = roomlist.Key
                            };
                            EwsDatabase.RoomListRoomEntities.Add(databaseRoom);
                        }
                    }
                }

                var roomchanges = await EwsDatabase.SaveChangesAsync();

                Trace.WriteLine($"Rooms {roomchanges} saved to database.");
            }

            var waitTimer = new TimeSpan(0, 5, 0);

            while (!_cancel.IsCancellationRequested)
            {
                var milliseconds = (int)waitTimer.TotalMilliseconds;

                // whatever you want to happen every 5 minutes
                Trace.WriteLine($"SendQueueDatabaseChangesAsync({MailboxOwner}) starting at {DateTime.UtcNow.ToShortTimeString()}");


                using (var EwsDatabase = new EWSDbContext(EWSConstants.Config.Database))
                {
                    var i        = 0;
                    var bookings = EwsDatabase.AppointmentEntities.Include(ictx => ictx.Room)
                                   .Where(w => !w.ExistsInExchange || !w.SyncedWithExchange || (w.DeletedLocally && !w.SyncedWithExchange));

                    foreach (var booking in bookings)
                    {
                        Microsoft.Exchange.WebServices.Data.EventType eventType = Microsoft.Exchange.WebServices.Data.EventType.Deleted;
                        if (!booking.ExistsInExchange)
                        {
                            eventType = Microsoft.Exchange.WebServices.Data.EventType.Created;
                        }
                        else if (!booking.SyncedWithExchange)
                        {
                            eventType = Microsoft.Exchange.WebServices.Data.EventType.Modified;
                        }

                        if (string.IsNullOrEmpty(booking.BookingReference))
                        {
                            booking.BookingReference = $"Ref{booking.Id.ToString().PadLeft(6, '0')}";
                        }

                        var ewsbooking = new EWS.Common.Models.UpdatedBooking()
                        {
                            DatabaseId        = booking.Id,
                            MailBoxOwnerEmail = booking.OrganizerSmtpAddress,
                            SiteMailBox       = booking.Room.SmtpAddress,
                            Subject           = booking.Subject,
                            Location          = booking.Location,
                            StartUTC          = booking.StartUTC,
                            EndUTC            = booking.EndUTC,
                            ExchangeId        = booking.BookingId,
                            ExchangeChangeKey = booking.BookingChangeKey,
                            BookingReference  = booking.BookingReference,
                            ExchangeEvent     = eventType
                        };

                        var message = new Message(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(ewsbooking)))
                        {
                            ContentType = "application/json",
                            Label       = SBMessageSyncDb,
                            MessageId   = i.ToString()
                        };

                        await sender.SendAsync(message);

                        Trace.WriteLine($"{++i}. Sent: Id = {message.MessageId} w/ Subject:{booking.Subject}");
                    }

                    Trace.WriteLine($"Sent {i} messages");
                }

                Trace.WriteLine($"Sleeping at {DateTime.UtcNow} for {milliseconds} milliseconds...");
                System.Threading.Thread.Sleep(milliseconds);
            }
        }