public IEricaMQ_MessageDTO PUT(IEricaMQ_MessageDTO message)
        {
            using (var dbContextTransaction = this.Database.BeginTransaction())
            {
                try
                {
                    EricaMQ_Message existingMessage = this.EricaMQ_Messages.Find(message.Id);

                    existingMessage.ModifiedDateTime             = DateTime.Now;
                    existingMessage.Sender                       = message.Sender;
                    existingMessage.Data                         = message.Data;
                    existingMessage.Context                      = message.Context;
                    existingMessage.AdapterAssemblyQualifiedName = message.AdapterAssemblyQualifiedName;
                    this.EricaMQ_Messages.Update(existingMessage);
                    this.SaveChanges();
                    dbContextTransaction.Commit();
                    return(existingMessage);
                }
                catch (Exception ex)
                {
                    dbContextTransaction.Rollback();
                    _logger.LogError(ex, ex.Message);
                    throw new ApplicationException(ex.Message, ex);
                }
            }
        }
        public object Consume(IEricaMQ_MessageDTO message)
        {
            //TODO: Add some filtering ???

            IEricaChats_MessageDTO ericaChatsMessage = JsonMarshaller.UnMarshall <EricaChats_MessageDTO>(message.Data);

            ericaChatsMessage.ChatMessageBody += " Consumed"; //NOTE: Just for testing
            //TODO: Add a Slack integration here :=)

            return(JsonMarshaller.Marshall(ericaChatsMessage));
        }
        public JsonResult Put(IEricaMQ_MessageDTO ericaMQ_Message)
        {
            try
            {
                var recipt = _ericaMQ_DBContext.PUT(ericaMQ_Message);
                NotifyConsumers(recipt);

                return(new JsonResult(recipt, new JsonSerializerSettings()
                {
                    TypeNameHandling = TypeNameHandling.Auto
                }));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, ex.Message);
                throw new ApplicationException(ex.Message, ex);
            }
        }
 public IEricaMQ_MessageDTO POST(IEricaMQ_MessageDTO message)
 {
     using (var dbContextTransaction = this.Database.BeginTransaction())
     {
         try
         {
             message.CreatedDateTime  = DateTime.Now;
             message.ModifiedDateTime = DateTime.Now;
             message.Id = 0;
             this.EricaMQ_Messages.Add((EricaMQ_Message)message); //NOTE: Use cast to tranform DTO into model
             this.SaveChanges();
             dbContextTransaction.Commit();
             return(message);
         }
         catch (Exception ex)
         {
             dbContextTransaction.Rollback();
             _logger.LogError(ex, ex.Message);
             throw new ApplicationException(ex.Message, ex);
         }
     }
 }
        public void TestPost()
        {
            try
            {
                IEricaMQ_MessageDTO ericaMQ_MessageDTO = new EricaMQ_Message();
                ericaMQ_MessageDTO.Context = "UnitTest";
                ericaMQ_MessageDTO.Data    = "UnitTest";
                ericaMQ_MessageDTO.Sender  = "UnitTest";
                string mqRequest             = JsonMarshaller.Marshall(ericaMQ_MessageDTO);
                HttpResponseMessage response = GetRequestResponse(mqRequest);
                Assert.IsTrue(response.IsSuccessStatusCode);
                string contentBody = GetContent(response);

                Assert.IsFalse(String.IsNullOrEmpty(contentBody));
                IEricaMQ_MessageDTO mqResponse = JsonMarshaller.UnMarshall <EricaMQ_Message>(contentBody);
                Assert.IsNotNull(mqResponse);
            }
            catch (Exception)
            {
                throw;
            }
        }
        public string Consume(IEricaMQ_MessageDTO message)
        {
            try
            {
                string consumedMessage = string.Empty;

                if (String.IsNullOrEmpty(message.AdapterAssemblyQualifiedName) == false)
                {
                    //Beautiful :=)
                    Type             adapterType        = Type.GetType(message.AdapterAssemblyQualifiedName);
                    MethodInfo       method             = typeof(UnityIOC).GetMethod("Resolve");
                    MethodInfo       boundGenericMethod = method.MakeGenericMethod(adapterType);
                    IConsumerAdapter consumerAdapter    = (IConsumerAdapter)boundGenericMethod.Invoke(_unityIOC, null);
                    consumedMessage = (string)consumerAdapter.Consume(message);
                }
                return(consumedMessage);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"Whoa, error trying to resolve this adapter type: {message.AdapterAssemblyQualifiedName}");
                throw new ApplicationException(ex.Message, ex);
            }
        }
        public void TestPut()
        {
            try
            {
                //POST
                IEricaMQ_MessageDTO ericaMQ_MessageDTO = new EricaMQ_Message();
                ericaMQ_MessageDTO.Context = "UnitTest";
                ericaMQ_MessageDTO.Data    = "UnitTest";
                ericaMQ_MessageDTO.Sender  = "UnitTest";
                string mqRequest             = JsonMarshaller.Marshall(ericaMQ_MessageDTO);
                HttpResponseMessage response = GetRequestResponse(mqRequest);
                Assert.IsTrue(response.IsSuccessStatusCode);
                string contentBody = GetContent(response);

                Assert.IsFalse(String.IsNullOrEmpty(contentBody));
                IEricaMQ_MessageDTO mqResponse = JsonMarshaller.UnMarshall <EricaMQ_Message>(contentBody);
                Assert.IsNotNull(mqResponse);

                //PUT
                string newData = "Love";
                mqResponse.Data = newData;

                string updatedJsonMqRequest = JsonMarshaller.Marshall(mqResponse);
                HttpResponseMessage updatedMqResponseMessage = GetRequestResponse(updatedJsonMqRequest, true);
                Assert.IsTrue(updatedMqResponseMessage.IsSuccessStatusCode);
                string updatedContentBody = GetContent(updatedMqResponseMessage);

                Assert.IsFalse(String.IsNullOrEmpty(updatedContentBody));
                IEricaMQ_MessageDTO updatedMqMessage = JsonMarshaller.UnMarshall <EricaMQ_Message>(updatedContentBody);
                Assert.IsNotNull(updatedMqMessage);
                Assert.AreEqual(newData, updatedMqMessage.Data);
            }
            catch (Exception)
            {
                throw;
            }
        }
 private void NotifyConsumers(IEricaMQ_MessageDTO message)
 {
     try
     {
         //NOTE: Notify the consumers using the type of the adapter stored on the message if one exists, otherwise just marshall the message
         // and send without passing through the adapter.
         if (string.IsNullOrEmpty(message.AdapterAssemblyQualifiedName))
         {
             _hubContext.Clients.Group(Constants_EricaMQ_Hub.GroupName_LatestMessage).SendAsync(Constants_EricaMQ_Hub.ClientEvent_ReceiveLatestMessage, JsonMarshaller.Marshall(message));
         }
         else
         {
             //TODO: Divide the Hub client groups into consumer types, i.e. EricaChatsReceiveLatestConsumedMessage. Then use the message.Context to branch and determine
             //the Hub Client Group
             string consumedMessage = _consumerAdapterFactory.Consume(message);
             _hubContext.Clients.Group(Constants_EricaMQ_Hub.GroupName_LatestMessage).SendAsync(Constants_EricaMQ_Hub.ClientEvent_ReceiveLatestConsumedMessage, consumedMessage);
         }
     }
     catch (Exception ex)
     {
         _logger.LogError(ex, ex.Message);
         throw new ApplicationException(ex.Message, ex);
     }
 }
        private async Task <JsonResult> ProcessRequest(IEricaChats_MessageDTO request)
        {
            try
            {
                IEricaMQ_MessageDTO mqMessage = await _ericaChatsSimpleProducerAdapter.Produce(request);

                string jsonMqMessage = JsonMarshaller.Marshall(mqMessage);
                IEricaChats_MessageDTO jsonRecipt = JsonMarshaller.UnMarshall <EricaChats_MessageDTO>(mqMessage.Data);

                var discover = await DiscoveryClient.GetAsync(Constants_IdentityServer.IdentityServerUrl);

                if (discover.IsError)
                {
                    throw new ApplicationException(discover.Error);
                }

                var tokenClient   = new TokenClient(discover.TokenEndpoint, Constants_IdentityServer.EricaMQProducer_Client, Constants_IdentityServer.EricaMQProducer_ClientSecret);
                var tokenResponse = await tokenClient.RequestClientCredentialsAsync(Constants_IdentityServer.EricaMQ_Api);

                if (tokenResponse.IsError)
                {
                    throw new ApplicationException(tokenResponse.Error);
                }

                var client = _httpClientFactory.CreateClient();
                client.SetBearerToken(tokenResponse.AccessToken);
                var content = new StringContent(jsonMqMessage, Encoding.UTF8, "application/json");
                Task <HttpResponseMessage> mqTask = client.PostAsync("http://localhost:80/api/ericamq", content);

                HttpResponseMessage mqResponse = null;
                string errorLog = string.Empty;
                await  mqTask;

                switch (mqTask.Status)
                {
                case TaskStatus.Faulted:
                    DateTime timeStamp = DateTime.Now;
                    errorLog = $"Error while Posting to EricaMQ at {timeStamp} - Details on next line \n {mqTask.Exception.Flatten().InnerException.Message}";
                    _logger.LogError(errorLog);
                    jsonRecipt.ErrorMessage = $"Could not post your request to the erica message queue. {timeStamp}";
                    break;

                case TaskStatus.RanToCompletion:
                    mqResponse = mqTask.Result;
                    if (mqResponse.IsSuccessStatusCode == false)
                    {
                        DateTime timeStampStatusCode = DateTime.Now;
                        jsonRecipt.ErrorMessage = errorLog = $"Your request to the EricaMQ returned a status code of {mqResponse.StatusCode} at time {timeStampStatusCode}";
                        _logger.LogError(errorLog);
                    }
                    break;
                }

                return(new JsonResult(jsonRecipt, new JsonSerializerSettings()
                {
                    TypeNameHandling = TypeNameHandling.Auto
                }));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, ex.Message);
                throw new ApplicationException(ex.Message, ex);
            }
        }
        public void TestGetLatestMessage()
        {
            try
            {
                TokenResponse tokenResponse     = null;
                var           tokenResponseTask = GetAccessToken();
                tokenResponseTask.Wait();
                switch (tokenResponseTask.Status)
                {
                case TaskStatus.Faulted:
                    throw new ApplicationException(tokenResponseTask.Exception.Flatten().InnerException.Message, tokenResponseTask.Exception.Flatten().InnerException);

                case TaskStatus.RanToCompletion:
                    tokenResponse = tokenResponseTask.Result;
                    break;
                }

                List <IEricaMQ_MessageDTO>    newMessagesList  = new List <IEricaMQ_MessageDTO>();
                List <IEricaChats_MessageDTO> newMessagesList2 = new List <IEricaChats_MessageDTO>();

                HubConnection connection = new HubConnectionBuilder()
                                           .WithUrl("http://localhost:80/api/ericamqhub",
                                                    options =>
                {
                    options.AccessTokenProvider = () => Task.FromResult(tokenResponse.AccessToken);
                }
                                                    )
                                           .Build();

                connection.On <string>(Constants_EricaMQ_Hub.ClientEvent_ReceiveLatestMessage, (message) =>
                {
                    IEricaMQ_MessageDTO mQ_MessageDTO = JsonMarshaller.UnMarshall <EricaMQ_Message>(message);
                    Assert.IsNotNull(mQ_MessageDTO);
                    newMessagesList.Add(mQ_MessageDTO);
                });

                connection.StartAsync().Wait();
                connection.InvokeAsync <bool>(Constants_EricaMQ_Hub.HubMethod_SubscribeToLatestMessage).Wait();

                TokenResponse tokenResponse2     = null;
                var           tokenResponseTask2 = GetAccessToken();
                tokenResponseTask2.Wait();
                switch (tokenResponseTask2.Status)
                {
                case TaskStatus.Faulted:
                    throw new ApplicationException(tokenResponseTask2.Exception.Flatten().InnerException.Message, tokenResponseTask2.Exception.Flatten().InnerException);

                case TaskStatus.RanToCompletion:
                    tokenResponse2 = tokenResponseTask2.Result;
                    break;
                }

                HubConnection connection2 = new HubConnectionBuilder()
                                            .WithUrl("http://localhost:80/api/ericamqhub",
                                                     options =>
                {
                    options.AccessTokenProvider = () => Task.FromResult(tokenResponse.AccessToken);
                }
                                                     )
                                            .Build();

                connection2.On <string>(Constants_EricaMQ_Hub.ClientEvent_ReceiveLatestConsumedMessage, (message) =>
                {
                    IEricaChats_MessageDTO mQ_MessageDTO2 = JsonMarshaller.UnMarshall <EricaChats_MessageDTO>(message);
                    Assert.IsNotNull(mQ_MessageDTO2);
                    newMessagesList2.Add(mQ_MessageDTO2);
                });

                connection2.StartAsync().Wait();
                connection2.InvokeAsync <bool>(Constants_EricaMQ_Hub.HubMethod_SubscribeToLatestMessage).Wait();

                while (newMessagesList.Count < 3 && newMessagesList2.Count < 3)
                {
                    //POST
                    IEricaChats_MessageDTO ericaChats = new EricaChats_MessageDTO();
                    ericaChats.ChatMessageID    = 123;
                    ericaChats.ChatChannelID    = 1;
                    ericaChats.ChatMessageBody  = "Jesus Loves You. ";
                    ericaChats.CreatedDateTime  = DateTime.Now;
                    ericaChats.ModifiedDateTime = DateTime.MinValue;
                    ericaChats.SenderUserName   = "******";

                    IEricaMQ_MessageDTO ericaMQ_MessageDTOConsume = new EricaMQ_Message();
                    ericaMQ_MessageDTOConsume.Context = "UnitTestLatest";
                    ericaMQ_MessageDTOConsume.Data    = JsonMarshaller.Marshall(ericaChats);
                    ericaMQ_MessageDTOConsume.Sender  = "UnitTestLatest";
                    ericaMQ_MessageDTOConsume.AdapterAssemblyQualifiedName = typeof(IEricaChatsSimpleConsumerAdapter).AssemblyQualifiedName;
                    string mqRequestConsume             = JsonMarshaller.Marshall(ericaMQ_MessageDTOConsume);
                    HttpResponseMessage responseConsume = null;
                    var requestConsumeTask = SendRequest(mqRequestConsume);
                    requestConsumeTask.Wait();
                    switch (requestConsumeTask.Status)
                    {
                    case TaskStatus.Faulted:
                        throw new ApplicationException(requestConsumeTask.Exception.Flatten().InnerException.Message, requestConsumeTask.Exception.Flatten().InnerException);

                    case TaskStatus.RanToCompletion:
                        responseConsume = requestConsumeTask.Result;
                        break;
                    }

                    Assert.IsTrue(responseConsume.IsSuccessStatusCode);

                    IEricaMQ_MessageDTO ericaMQ_MessageDTO = new EricaMQ_Message();
                    ericaMQ_MessageDTO.Context = "UnitTestLatest";
                    ericaMQ_MessageDTO.Data    = "UnitTestLatest";
                    ericaMQ_MessageDTO.Sender  = "UnitTestLatest";
                    string mqRequest             = JsonMarshaller.Marshall(ericaMQ_MessageDTO);
                    HttpResponseMessage response = null;
                    var requestTask = SendRequest(mqRequest);
                    requestTask.Wait();
                    switch (requestTask.Status)
                    {
                    case TaskStatus.Faulted:
                        throw new ApplicationException(requestTask.Exception.Flatten().InnerException.Message, requestTask.Exception.Flatten().InnerException);

                    case TaskStatus.RanToCompletion:
                        response = requestTask.Result;
                        break;
                    }
                    Assert.IsTrue(response.IsSuccessStatusCode);
                }

                connection.StopAsync();
                connection2.StopAsync();

                foreach (var message in newMessagesList)
                {
                    Assert.IsTrue(message.Id > 0);
                }

                foreach (var message in newMessagesList2)
                {
                    Assert.IsTrue(message.ChatMessageID > 0);
                }
            }
            catch (Exception)
            {
                throw;
            }
        }
        public void TestGetNewMessagesHub()
        {
            try
            {
                TokenResponse tokenResponse     = null;
                var           tokenResponseTask = GetAccessToken();
                tokenResponseTask.Wait();
                switch (tokenResponseTask.Status)
                {
                case TaskStatus.Faulted:
                    throw new ApplicationException(tokenResponseTask.Exception.Flatten().InnerException.Message, tokenResponseTask.Exception.Flatten().InnerException);

                case TaskStatus.RanToCompletion:
                    tokenResponse = tokenResponseTask.Result;
                    break;
                }

                List <IEricaMQ_MessageDTO>    newMessagesList        = new List <IEricaMQ_MessageDTO>();
                List <IEricaChats_MessageDTO> newMessagesListConsume = new List <IEricaChats_MessageDTO>();

                HubConnection connection = new HubConnectionBuilder()
                                           .WithUrl("http://localhost:80/api/ericamqhub", options =>
                {
                    options.AccessTokenProvider = () => Task.FromResult(tokenResponse.AccessToken);
                })
                                           .Build();

                connection.On <string>(Constants_EricaMQ_Hub.ClientEvent_ReceiveMessagesInRange, (message) =>
                {
                    IEricaMQ_MessageDTO mqMessage = JsonMarshaller.UnMarshall <EricaMQ_Message>(message);
                    Assert.IsNotNull(mqMessage);
                    newMessagesList.Add(mqMessage);
                });

                connection.On <string>(Constants_EricaMQ_Hub.ClientEvent_ReceiveConsumedMessagesInRange, (message) =>
                {
                    //NOTE: Client must know the expected type to be consumed
                    IEricaChats_MessageDTO mqMessage = JsonMarshaller.UnMarshall <EricaChats_MessageDTO>(message);
                    Assert.IsNotNull(mqMessage);
                    newMessagesListConsume.Add(mqMessage);
                });

                connection.StartAsync().Wait();


                IEricaChats_MessageDTO ericaChats = new EricaChats_MessageDTO();
                ericaChats.ChatMessageID    = 123;
                ericaChats.ChatChannelID    = 1;
                ericaChats.ChatMessageBody  = "Jesus Loves You. ";
                ericaChats.CreatedDateTime  = DateTime.Now;
                ericaChats.ModifiedDateTime = DateTime.MinValue;
                ericaChats.SenderUserName   = "******";

                IEricaMQ_MessageDTO ericaMQ_MessageDTO = new EricaMQ_Message();
                ericaMQ_MessageDTO.Context = "UnitTest-Consumed";
                ericaMQ_MessageDTO.Data    = JsonMarshaller.Marshall(ericaChats);
                ericaMQ_MessageDTO.Sender  = "UnitTest-Producer";
                ericaMQ_MessageDTO.AdapterAssemblyQualifiedName = typeof(IEricaChatsSimpleConsumerAdapter).AssemblyQualifiedName;
                string mqRequest             = JsonMarshaller.Marshall(ericaMQ_MessageDTO);
                HttpResponseMessage response = null;
                var requestTask = SendRequest(mqRequest);
                requestTask.Wait();
                switch (requestTask.Status)
                {
                case TaskStatus.Faulted:
                    throw new ApplicationException(requestTask.Exception.Flatten().InnerException.Message, requestTask.Exception.Flatten().InnerException);

                case TaskStatus.RanToCompletion:
                    response = requestTask.Result;
                    break;
                }

                DateTime afterTime = Convert.ToDateTime("2018-10-21 18:19:03.7618097");  //REMEMBER: Must choose this date wisely before running test (un-migrated data may cause test to fail)

                Task <string> messageTask = connection.InvokeAsync <string>(Constants_EricaMQ_Hub.HubMethod_GetMessagesInRange, afterTime, 200, DateTime.MaxValue);
                messageTask.Wait();
                switch (messageTask.Status)
                {
                case TaskStatus.Faulted:
                    throw new ApplicationException(messageTask.Exception.Flatten().InnerException.Message, messageTask.Exception.Flatten().InnerException);

                case TaskStatus.RanToCompletion:
                    afterTime = Convert.ToDateTime(messageTask.Result);
                    break;
                }

                afterTime = Convert.ToDateTime("2018-10-21 18:19:03.7618097"); //REMEMBER: Must choose this date wisely before running test (un-migrated data may cause test to fail)

                Task <string> messageTaskConsume = connection.InvokeAsync <string>(Constants_EricaMQ_Hub.HubMethod_ConsumeMessagesInRange, afterTime, 200, DateTime.MaxValue);
                messageTaskConsume.Wait();
                switch (messageTaskConsume.Status)
                {
                case TaskStatus.Faulted:
                    throw new ApplicationException(messageTaskConsume.Exception.Flatten().InnerException.Message, messageTaskConsume.Exception.Flatten().InnerException);

                case TaskStatus.RanToCompletion:
                    afterTime = Convert.ToDateTime(messageTaskConsume.Result);
                    break;
                }

                connection.StopAsync().Wait();

                foreach (var message in newMessagesList)
                {
                    Assert.IsTrue(message.Id > 0);
                }

                foreach (var message in newMessagesListConsume)
                {
                    Assert.IsTrue(message.ChatMessageID > 0);
                }
            }
            catch (Exception)
            {
                throw;
            }
        }