/// <summary>
        /// Processes an Update to an Object and Notifies any Subscribers of the Update
        /// </summary>
        /// <param name="ObjectType"></param>
        /// <param name="ObjectId"></param>
        /// <param name="jsonObject"></param>
        /// <returns></returns>
        public async Task UpdateObject(string ObjectType, string ObjectId, string jsonObject)
        {
            logger.LogDebug($"Processing ({ObjectType},{ObjectId})");

            // Check for valid Metadata Type
            var objectTypes = await metadataStore.GetObjectTypesAsync();

            if (!objectTypes.Any(ot => ot.Equals(ObjectType, StringComparison.OrdinalIgnoreCase)))
            {
                logger.LogWarning($"Not a valid ObjectType");
                return;
            }

            // Update the Object
            var existingObject = await objectStore.GetObjectAsync(ObjectType, ObjectId);

            var storedObject  = EventStoreSerialization.DeSerializeObject(existingObject ?? "{}");
            var updatedObject = EventStoreSerialization.DeSerializeObject(jsonObject);

            storedObject["_id"] = ObjectId;
            foreach (var update in updatedObject)
            {
                storedObject[update.Key] = update.Value;
            }
            var newJson = EventStoreSerialization.SerializeObject(storedObject);
            await objectStore.SetObjectAsync(ObjectType, ObjectId, newJson);

            // Check for Subscribers
            var subscriptionDetails = await subscriberStore.GetSubscriptionsToObjectType(ObjectType);

            if (subscriptionDetails == null || subscriptionDetails.Count() == 0)
            {
                logger.LogWarning($"No Subscribers");
                return;
            }

            // Create Messages to Notify all Subscribers
            foreach (var subscriptionDetail in subscriptionDetails)
            {
                await subscriberQueueStore.EnqueueMessageAsync(new SubscriberMessage
                {
                    DestinationUri = new Uri(subscriptionDetail.BaseUri, subscriptionDetail.RelativePath),
                    SubscriberId   = subscriptionDetail.SubscriberId,
                    JsonBody       = newJson
                });
            }
        }
        public async Task <RegistrationResult> RegistrationRequest(HttpContext context)
        {
            // Some Quick Validations
            if (!context.Request.Method.Equals("post", StringComparison.OrdinalIgnoreCase))
            {
                logger.LogWarning("Invalid Method");
                return(RegistrationResult.Failure(HttpStatusCode.MethodNotAllowed, "Invalid Method"));
            }
            if (!context.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
            {
                logger.LogWarning("Invalid Content-Type");
                return(RegistrationResult.Failure(HttpStatusCode.UnsupportedMediaType, "Invalid Content-Type"));
            }

            using (StreamReader reader = new StreamReader(context.Request.Body, Encoding.UTF8, true, 1024, false))
            {
                var json = await reader.ReadToEndAsync();

                if (String.IsNullOrWhiteSpace(json))
                {
                    logger.LogWarning("Request had an Empty Body");
                    return(RegistrationResult.Failure(HttpStatusCode.BadRequest, "Invalid Body"));
                }
                var subscriber = EventStoreSerialization.DeSerializeObject <Subscriber>(json);
                if (subscriber == null)
                {
                    logger.LogWarning("Request did not match expected format for Subscribers.");
                    return(RegistrationResult.Failure(HttpStatusCode.BadRequest, "Invalid Body Format"));
                }

                // Store the Message and Trigger background processing
                await subscriberStore.AddSubscriberAsync(subscriber);

                logger.LogInformation($"Registered the Subscriber '{subscriber.SubscriberId}'");

                // Return a Success to the Middleware
                return(RegistrationResult.Success);
            }
        }
        /// <summary>
        /// Injests a Request into a <seealso cref="ServerEventMessage"/> and sends to the <seealso cref="IEventQueueStore"/>
        /// </summary>
        /// <param name="context"></param>
        /// <returns>Result from Injesting the Request</returns>
        public async Task <InjestionResult> InjestRequest(HttpContext context)
        {
            // Some Quick Validations
            if (!context.Request.Method.Equals("post", StringComparison.OrdinalIgnoreCase))
            {
                logger.LogWarning("Invalid Method");
                return(InjestionResult.Failure(HttpStatusCode.MethodNotAllowed, "Invalid Method"));
            }
            if (!context.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
            {
                logger.LogWarning("Invalid Content-Type");
                return(InjestionResult.Failure(HttpStatusCode.UnsupportedMediaType, "Invalid Content-Type"));
            }

            using (StreamReader reader = new StreamReader(context.Request.Body, Encoding.UTF8, true, 1024, false))
            {
                var json = await reader.ReadToEndAsync();

                if (String.IsNullOrWhiteSpace(json))
                {
                    logger.LogWarning("Request had an Empty Body");
                    return(InjestionResult.Failure(HttpStatusCode.BadRequest, "Invalid Body"));
                }
                var eventMessage = EventStoreSerialization.DeSerializeObject <ServerEventMessage>(json);
                if (eventMessage == null)
                {
                    logger.LogWarning("Request did not match expected format for Events.");
                    return(InjestionResult.Failure(HttpStatusCode.BadRequest, "Invalid Body Format"));
                }

                // Store the Message and Trigger background processing
                await eventQueueStore.EnqueueEventAsync(eventMessage);

                triggerService.ProcessingStart.Set();

                // Return a Success to the Middleware
                return(InjestionResult.Success);
            }
        }