예제 #1
0
        async public Task <string> RetreiveInfo(object e)
        {
            // Get more info for the given item.  This will run on it's own thread
            // so that the main program can continue as usual (we won't hold anything up)

            NotificationInfo n = (NotificationInfo)e;

            var token = await RetreiveToken();

            var service = new EWService(token, true);

            service.SetImpersonation(ConnectingIdType.SmtpAddress, n.Mailbox);

            service.Current.Url        = n.Service.Url;
            service.Current.TraceFlags = TraceFlags.All;

            var ewsMoreInfoService = service.Current;


            string sEvent = "";

            if (n.Event is ItemEvent)
            {
                sEvent = n.Mailbox + ": Item " + (n.Event as ItemEvent).EventType.ToString() + ": " + MoreItemInfo(n.Event as ItemEvent, ewsMoreInfoService);
            }
            else
            {
                sEvent = n.Mailbox + ": Folder " + (n.Event as FolderEvent).EventType.ToString() + ": " + MoreFolderInfo(n.Event as FolderEvent, ewsMoreInfoService);
            }

            return(ShowEvent(sEvent));
        }
예제 #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);
            }
        }
예제 #3
0
        /// <summary>
        /// Read Queue for O365 Sync Folder events and write it to the database [preferably on a separate thread]
        /// </summary>
        /// <param name="queueConnection"></param>
        /// <returns></returns>
        public async System.Threading.Tasks.Task ReceiveQueueO365SyncFoldersAsync(string queueConnection)
        {
            Trace.WriteLine($"ReceiveQueueO365SyncFoldersAsync() starting");

            var token = await RetreiveToken();

            var EwsService = new EWService(token);

            var receiver = new MessageReceiver(queueConnection, SBQueueSyncO365, ReceiveMode.ReceiveAndDelete);

            _cancel.Token.Register(() => receiver.CloseAsync());


            var filterPropertyList = new List <PropertyDefinitionBase>()
            {
                AppointmentSchema.Location,
                ItemSchema.Subject,
                AppointmentSchema.Start,
                AppointmentSchema.End,
                AppointmentSchema.IsMeeting,
                AppointmentSchema.IsOnlineMeeting,
                AppointmentSchema.IsAllDayEvent,
                AppointmentSchema.IsRecurring,
                AppointmentSchema.IsCancelled,
                ItemSchema.IsUnmodified,
                AppointmentSchema.TimeZone,
                AppointmentSchema.ICalUid,
                ItemSchema.ParentFolderId,
                ItemSchema.ConversationId,
                AppointmentSchema.ICalRecurrenceId,
                EWSConstants.RefIdPropertyDef,
                EWSConstants.DatabaseIdPropertyDef
            };

            // With the receiver set up, we then enter into a simple receive loop that terminates
            using (var EwsDatabase = new EWSDbContext(EWSConstants.Config.Database))
            {
                // when the cancellation token if triggered.
                while (!_cancel.Token.IsCancellationRequested)
                {
                    try
                    {
                        // ask for the next message "forever" or until the cancellation token is triggered
                        var message = await receiver.ReceiveAsync();

                        if (message != null)
                        {
                            if (message.Label != null &&
                                message.ContentType != null &&
                                message.Label.Equals(SBMessageSyncO365, StringComparison.InvariantCultureIgnoreCase) &&
                                message.ContentType.Equals("application/json", StringComparison.InvariantCultureIgnoreCase))
                            {
                                // service bus
                                // #TODO: Read bus events from O365 and write to Database
                                var booking = JsonConvert.DeserializeObject <EWS.Common.Models.ChangeBooking>(Encoding.UTF8.GetString(message.Body));
                                Trace.WriteLine($"Msg received: {booking.SiteMailBox} status: {booking.EventType.ToString("f")}");

                                var eventType          = booking.EventType;
                                var itemId             = booking.ExchangeId;
                                var changeKey          = booking.ExchangeChangeKey;
                                var appointmentMailbox = booking.SiteMailBox;
                                try
                                {
                                    Appointment meeting = null;


                                    var dbroom = EwsDatabase.RoomListRoomEntities.Include(idxt => idxt.Appointments).FirstOrDefault(f => f.SmtpAddress == appointmentMailbox);


                                    if (eventType == ChangeType.Delete)
                                    {
                                        var entity = dbroom.Appointments.FirstOrDefault(f => f.BookingId == itemId);
                                        entity.IsDeleted          = true;
                                        entity.ModifiedDate       = DateTime.UtcNow;
                                        entity.SyncedWithExchange = true;
                                        entity.ExistsInExchange   = true;
                                    }
                                    else
                                    {
                                        var appointmentTime = EwsService.GetAppointment(ConnectingIdType.SmtpAddress, appointmentMailbox, itemId, filterPropertyList);

                                        if (!filterPropertyList.Any(fp => fp == AppointmentSchema.Recurrence))
                                        {
                                            filterPropertyList.Add(AppointmentSchema.Recurrence);
                                        }
                                        var parentAppointment = EwsService.GetParentAppointment(appointmentTime, filterPropertyList);
                                        meeting = parentAppointment.Item;

                                        var mailboxId  = parentAppointment.Organizer.Address;
                                        var refId      = parentAppointment.ReferenceId;
                                        var meetingKey = parentAppointment.MeetingKey;

                                        // TODO: move this to the ServiceBus Processing
                                        if ((!string.IsNullOrEmpty(refId) || meetingKey.HasValue) &&
                                            dbroom.Appointments.Any(f => f.BookingReference == refId || f.Id == meetingKey))
                                        {
                                            var entity = dbroom.Appointments.FirstOrDefault(f => f.BookingReference == refId || f.Id == meetingKey);

                                            entity.EndUTC               = meeting.End.ToUniversalTime();
                                            entity.StartUTC             = meeting.Start.ToUniversalTime();
                                            entity.ExistsInExchange     = true;
                                            entity.IsRecurringMeeting   = meeting.IsRecurring;
                                            entity.Location             = meeting.Location;
                                            entity.OrganizerSmtpAddress = mailboxId;
                                            entity.Subject              = meeting.Subject;
                                            entity.RecurrencePattern    = (meeting.Recurrence == null) ? string.Empty : meeting.Recurrence.ToString();
                                            entity.BookingReference     = refId;
                                            entity.BookingChangeKey     = changeKey;
                                            entity.BookingId            = itemId;
                                            entity.ModifiedDate         = DateTime.UtcNow;
                                            entity.SyncedWithExchange   = true;
                                        }
                                        else
                                        {
                                            var entity = new EntityRoomAppointment()
                                            {
                                                BookingReference     = refId,
                                                BookingId            = itemId,
                                                BookingChangeKey     = changeKey,
                                                EndUTC               = meeting.End.ToUniversalTime(),
                                                StartUTC             = meeting.Start.ToUniversalTime(),
                                                ExistsInExchange     = true,
                                                IsRecurringMeeting   = meeting.IsRecurring,
                                                Location             = meeting.Location,
                                                OrganizerSmtpAddress = mailboxId,
                                                Subject              = meeting.Subject,
                                                RecurrencePattern    = (meeting.Recurrence == null) ? string.Empty : meeting.Recurrence.ToString(),
                                                ModifiedDate         = DateTime.UtcNow
                                            };
                                            dbroom.Appointments.Add(entity);
                                        }
                                    }

                                    var appointmentsSaved = EwsDatabase.SaveChanges();
                                    Trace.WriteLine($"Saved {appointmentsSaved} rows");
                                }
                                catch (Exception dbex)
                                {
                                    Trace.WriteLine($"Error occurred in Appointment creation or Database change {dbex}");
                                }
                                finally
                                {
                                    //await receiver.CompleteAsync(message.SystemProperties.LockToken);
                                }
                            }
                            else
                            {
                                // purge / log it
                                await receiver.DeadLetterAsync(message.SystemProperties.LockToken);//, "ProcessingError", "Don't know what to do with this message");
                            }
                        }
                    }
                    catch (ServiceBusException e)
                    {
                        if (!e.IsTransient)
                        {
                            Trace.WriteLine(e.Message);
                            throw;
                        }
                    }
                }
            }
            await receiver.CloseAsync();
        }
예제 #4
0
        /// <summary>
        /// Read Queue for Database Changes [preferably on a separate thread] and Store in Office 365
        /// </summary>
        /// <param name="queueConnection"></param>
        /// <returns></returns>
        public async System.Threading.Tasks.Task ReceiveQueueDatabaseChangesAsync(string queueConnection)
        {
            var token = await RetreiveToken();

            var EwsService = new EWService(token);


            var propertyIds = new List <PropertyDefinitionBase>()
            {
                ItemSchema.Subject,
                AppointmentSchema.Location,
                AppointmentSchema.Start,
                AppointmentSchema.End,
                EWSConstants.RefIdPropertyDef,
                EWSConstants.DatabaseIdPropertyDef
            };

            var receiver = new MessageReceiver(queueConnection, SBQueueSyncDb, ReceiveMode.ReceiveAndDelete);

            _cancel.Token.Register(() => receiver.CloseAsync());

            // when the cancellation token if triggered.
            while (!_cancel.Token.IsCancellationRequested)
            {
                // whatever you want to happen every 5 minutes
                Trace.WriteLine($"ReceiveQueueDatabaseChangesAsync({MailboxOwner}) starting at {DateTime.UtcNow.ToShortTimeString()}");


                // With the receiver set up, we then enter into a simple receive loop that terminates
                using (var _context = new EWSDbContext(EWSConstants.Config.Database))
                {
                    try
                    {
                        // ask for the next message "forever" or until the cancellation token is triggered
                        var message = await receiver.ReceiveAsync();

                        if (message != null)
                        {
                            if (message.Label != null &&
                                message.ContentType != null &&
                                message.Label.Equals(SBMessageSyncDb, StringComparison.InvariantCultureIgnoreCase) &&
                                message.ContentType.Equals("application/json", StringComparison.InvariantCultureIgnoreCase))
                            {
                                // service bus
                                // #TODO: Read bus events from database and write to O365
                                var booking = JsonConvert.DeserializeObject <EWS.Common.Models.UpdatedBooking>(Encoding.UTF8.GetString(message.Body));
                                Trace.WriteLine($"Msg received: {booking.SiteMailBox} - {booking.Subject}. Cancel status: {booking.ExchangeEvent.ToString("f")}");

                                var eventType   = booking.CancelStatus;
                                var eventStatus = booking.ExchangeEvent;
                                var itemId      = booking.ExchangeId;
                                var changeKey   = booking.ExchangeChangeKey;

                                var appointmentMailbox = booking.SiteMailBox;
                                try
                                {
                                    Appointment meeting = null;

                                    if (!string.IsNullOrEmpty(itemId))
                                    {
                                        var exchangeId = new ItemId(itemId);


                                        if (eventStatus == EventType.Deleted)
                                        {
                                        }
                                        else
                                        {
                                            if (string.IsNullOrEmpty(booking.BookingReference))
                                            {
                                                booking.BookingReference = $"Ref{booking.DatabaseId.ToString().PadLeft(6, '0')}";
                                            }

                                            EwsService.SetImpersonation(ConnectingIdType.SmtpAddress, booking.MailBoxOwnerEmail);

                                            var subAppointment = EwsService.GetAppointment(ConnectingIdType.SmtpAddress, booking.SiteMailBox, exchangeId, propertyIds);

                                            var parentAppt = EwsService.GetParentAppointment(subAppointment, propertyIds);

                                            meeting          = parentAppt.Item;
                                            meeting.Subject  = booking.Subject;
                                            meeting.Start    = booking.StartUTC;
                                            meeting.End      = booking.EndUTC;
                                            meeting.Location = booking.Location;
                                            //meeting.ReminderDueBy = DateTime.Now;
                                            meeting.SetExtendedProperty(EWSConstants.RefIdPropertyDef, booking.BookingReference);
                                            meeting.SetExtendedProperty(EWSConstants.DatabaseIdPropertyDef, booking.DatabaseId);
                                            meeting.Update(ConflictResolutionMode.AutoResolve, SendInvitationsOrCancellationsMode.SendOnlyToChanged);

                                            // Verify that the appointment was created by using the appointment's item ID.
                                            var item = Item.Bind(EwsService.Current, meeting.Id, new PropertySet(propertyIds));
                                            Trace.WriteLine($"Appointment modified: {item.Subject} && ReserveRoomAsync({booking.Location}) completed");

                                            if (item is Appointment)
                                            {
                                                Trace.WriteLine($"Item is Appointment");
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if (string.IsNullOrEmpty(booking.BookingReference))
                                        {
                                            booking.BookingReference = $"Ref{booking.DatabaseId.ToString().PadLeft(6, '0')}";
                                        }

                                        EwsService.SetImpersonation(ConnectingIdType.SmtpAddress, booking.MailBoxOwnerEmail);

                                        meeting = new Appointment(EwsService.Current);
                                        meeting.Resources.Add(booking.SiteMailBox);
                                        meeting.Subject  = booking.Subject;
                                        meeting.Start    = booking.StartUTC;
                                        meeting.End      = booking.EndUTC;
                                        meeting.Location = booking.Location;
                                        //meeting.ReminderDueBy = DateTime.Now;
                                        meeting.SetExtendedProperty(EWSConstants.RefIdPropertyDef, booking.BookingReference);
                                        meeting.SetExtendedProperty(EWSConstants.DatabaseIdPropertyDef, booking.DatabaseId);
                                        meeting.Save(SendInvitationsMode.SendOnlyToAll);

                                        // Verify that the appointment was created by using the appointment's item ID.
                                        var item = Item.Bind(EwsService.Current, meeting.Id, new PropertySet(propertyIds));
                                        Trace.WriteLine($"Appointment created: {item.Subject} && ReserveRoomAsync({booking.Location}) completed");

                                        if (item is Appointment)
                                        {
                                            Trace.WriteLine($"Item is Appointment");
                                        }
                                    }

                                    // this should exists as this particular message was sent by the database
                                    var dbAppointment = _context.AppointmentEntities.FirstOrDefault(a => a.Id == booking.DatabaseId);
                                    if (dbAppointment != null)
                                    {
                                        dbAppointment.ExistsInExchange   = true;
                                        dbAppointment.SyncedWithExchange = true;
                                        dbAppointment.ModifiedDate       = DateTime.UtcNow;

                                        if (meeting != null)
                                        {
                                            dbAppointment.BookingId        = meeting.Id.UniqueId;
                                            dbAppointment.BookingChangeKey = meeting.Id.ChangeKey;
                                        }
                                        else
                                        {
                                            dbAppointment.IsDeleted = true;
                                        }

                                        if (string.IsNullOrEmpty(dbAppointment.BookingReference) ||
                                            !dbAppointment.BookingReference.Equals(booking.BookingReference))
                                        {
                                            dbAppointment.BookingReference = booking.BookingReference;
                                        }
                                    }

                                    var appointmentsSaved = _context.SaveChanges();
                                    Trace.WriteLine($"Saved {appointmentsSaved} rows");
                                }
                                catch (Exception dbex)
                                {
                                    Trace.WriteLine($"Error occurred in Appointment creation or Database change {dbex}");
                                }
                                finally
                                {
                                    //await receiver.CompleteAsync(message.SystemProperties.LockToken);
                                }
                            }
                            else
                            {
                                // purge / log it
                                await receiver.DeadLetterAsync(message.SystemProperties.LockToken);//, "ProcessingError", "Don't know what to do with this message");
                            }
                        }
                    }
                    catch (ServiceBusException e)
                    {
                        if (!e.IsTransient)
                        {
                            Trace.WriteLine(e.Message);
                            throw;
                        }
                    }
                }
            }
            await receiver.CloseAsync();
        }