Пример #1
0
        /// <summary>
        /// tăng view cho bài post
        /// </summary>
        /// <param name="postId"></param>
        public void UpdateViewPost(int postId)
        {
            var pst = db.Posts.Where(x => x.postid == postId).SingleOrDefault();

            pst.view = pst.view + 1;
            db.SaveChanges();
        }
Пример #2
0
 /// <summary>
 /// Tao Tag moi
 /// </summary>
 /// <param name="tagName"></param>
 /// <returns></returns>
 public bool CreateNewTag(string tagName)
 {
     try
     {
         var tag = new Tag()
         {
             tagname = tagName
         };
         db.Tags.Add(tag);
         db.SaveChanges();
         return(true);
     }
     catch (Exception)
     {
         return(false);
     }
 }
Пример #3
0
 public bool CreateNewAccount(UserAccount acc)
 {
     try
     {
         UserAccount newacc = new UserAccount()
         {
             email     = acc.email,
             password  = acc.password,
             username  = acc.username,
             roleid    = acc.roleid,
             facultyid = acc.facultyid
         };
         db.UserAccounts.Add(newacc);
         db.SaveChanges();
         return(true);
     }
     catch (Exception e)
     {
         return(false);
     }
 }
Пример #4
0
        /// <summary>
        /// Adds streamingsubscription to the GroupInfo
        /// </summary>
        /// <param name="context">Database context</param>
        /// <param name="Group"></param>
        /// <param name="smtpAddress"></param>
        /// <returns></returns>
        private StreamingSubscription AddSubscription(EWSDbContext context, GroupInfo Group, string smtpAddress)
        {
            StreamingSubscription subscription = null;

            if (_subscriptions.Any(email => email.SmtpAddress.Equals(smtpAddress)))
            {
                var email = _subscriptions.FirstOrDefault(s => s.SmtpAddress.Equals(smtpAddress));
                _subscriptions.Remove(email);
            }

            try
            {
                ExchangeService exchange = Group.ExchangeService;
                exchange.Credentials        = ServiceCredentials;
                exchange.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, smtpAddress);
                subscription = exchange.SubscribeToStreamingNotifications(new FolderId[] { WellKnownFolderName.Calendar },
                                                                          EventType.Created,
                                                                          EventType.Deleted,
                                                                          EventType.Modified,
                                                                          EventType.Moved,
                                                                          EventType.Copied);


                _traceListener.Trace("SyncProgram", $"CreateStreamingSubscriptionGrouping to room {smtpAddress} with SubscriptionId {subscription.Id}");


                var subscriptions = context.SaveChanges();
                _traceListener.Trace("SyncProgram", $"Streaming subscription persisted {subscriptions} persisted.");

                _subscriptions.Add(new SubscriptionCollection()
                {
                    SmtpAddress = smtpAddress,
                    Streaming   = subscription
                });
            }
            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 {smtpAddress} with MSG:{srex.Message}");
            }

            return(subscription);
        }
Пример #5
0
        /// <summary>
        /// Close connections and unsubscribe
        /// </summary>
        public void CloseConnections()
        {
            _traceListener.Trace("SyncProgram", $"ConsoleCtrlCheck CloseConnections at {DateTime.UtcNow}..");

            foreach (StreamingSubscriptionConnection connection in _connections.Values)
            {
                if (connection.IsOpen)
                {
                    connection.Close();
                }
            }

            // Unsubscribe all
            if (_subscriptions == null)
            {
                return;
            }


            using (EWSDbContext context = new EWSDbContext(EWSConstants.Config.Database))
            {
                var databaseItems = context.RoomListRoomEntities.ToList();

                try
                {
                    for (int i = _subscriptions.Count - 1; i >= 0; i--)
                    {
                        SubscriptionCollection subscriptionItem = _subscriptions[i];
                        var subscription = subscriptionItem.Streaming;
                        try
                        {
                            subscription.Unsubscribe();
                            _traceListener.Trace("SyncProgram", $"Unsubscribed from {subscriptionItem.SmtpAddress}");

                            if (databaseItems.Any(di => di.SmtpAddress == subscriptionItem.SmtpAddress))
                            {
                                var item = databaseItems.FirstOrDefault(di => di.SmtpAddress == subscriptionItem.SmtpAddress);
                                item.LastSyncDate = DateTime.UtcNow;
                            }
                        }
                        catch (Exception ex)
                        {
                            _traceListener.Trace("SyncProgram", $"Error when unsubscribing {subscriptionItem.SmtpAddress}: {ex.Message}");
                        }

                        _subscriptions.Remove(subscriptionItem);
                    }
                }
                catch (Exception subEx)
                {
                    _traceListener.Trace("SyncProgram", $"Failed in subscription disconnect {subEx.Message}");
                }
                finally
                {
                    var changes = context.SaveChanges();
                    _traceListener.Trace("SyncProgram", $"Subscription watermark sync changed {changes} rows.");
                }
            }

            _reconnect = false;
        }
Пример #6
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.");
                }
            }
        }
Пример #7
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");
        }
Пример #8
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();
        }
Пример #9
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();
        }