Example #1
0
        public async Task WithAcknowledge()
        {
            TestHorseMq server = new TestHorseMq();
            await server.Initialize();

            int port = server.Start();

            HorseClient client1 = new HorseClient();
            HorseClient client2 = new HorseClient();

            client1.ClientId        = "client-1";
            client2.ClientId        = "client-2";
            client2.AutoAcknowledge = true;
            client1.ResponseTimeout = TimeSpan.FromSeconds(14);

            await client1.ConnectAsync("hmq://localhost:" + port);

            await client2.ConnectAsync("hmq://localhost:" + port);

            Assert.True(client1.IsConnected);
            Assert.True(client2.IsConnected);

            bool received = false;

            client2.MessageReceived += (c, m) => received = m.Source == "client-1";

            HorseMessage message = new HorseMessage(MessageType.DirectMessage, "client-2");

            message.SetStringContent("Hello, World!");

            HorseResult sent = await client1.SendAndGetAck(message);

            Assert.Equal(HorseResultCode.Ok, sent.Code);
            Assert.True(received);
        }
Example #2
0
        public async Task WithoutAnyResponse()
        {
            TestHorseMq server = new TestHorseMq();
            await server.Initialize();

            int port = server.Start();

            HorseClient client1 = new HorseClient();
            HorseClient client2 = new HorseClient();

            client1.ClientId = "client-1";
            client2.ClientId = "client-2";

            await client1.ConnectAsync("hmq://localhost:" + port);

            await client2.ConnectAsync("hmq://localhost:" + port);

            Assert.True(client1.IsConnected);
            Assert.True(client2.IsConnected);

            bool received = false;

            client2.MessageReceived += (c, m) => received = m.Source == "client-1";

            HorseMessage message = new HorseMessage(MessageType.DirectMessage, "client-2");

            message.SetStringContent("Hello, World!");

            HorseResult sent = await client1.SendAsync(message);

            Assert.Equal(HorseResultCode.Ok, sent.Code);
            await Task.Delay(1000);

            Assert.True(received);
        }
Example #3
0
        /// <summary>
        /// Pushes new message into the queue
        /// </summary>
        public Task <PushResult> Push(string message, bool highPriority = false)
        {
            HorseMessage msg = new HorseMessage(MessageType.QueueMessage, Name);

            msg.HighPriority = highPriority;
            msg.SetStringContent(message);
            return(Push(msg));
        }
Example #4
0
        public async Task PushWithCC()
        {
            TestHorseMq server = new TestHorseMq();
            await server.Initialize();

            int port = server.Start(300, 300);

            HorseClient producer = new HorseClient();
            await producer.ConnectAsync("hmq://localhost:" + port);

            Assert.True(producer.IsConnected);

            HorseClient consumer1 = new HorseClient();

            consumer1.ClientId = "consumer-1";
            await consumer1.ConnectAsync("hmq://localhost:" + port);

            HorseClient consumer2 = new HorseClient();

            consumer2.ClientId = "consumer-2";
            await consumer2.ConnectAsync("hmq://localhost:" + port);

            Assert.True(consumer1.IsConnected);
            Assert.True(consumer2.IsConnected);

            int consumer1Msgs = 0;
            int consumer2Msgs = 0;

            consumer1.MessageReceived += (c, m) => { consumer1Msgs++; };
            consumer2.MessageReceived += (c, m) => { consumer2Msgs++; };

            HorseResult joined1 = await consumer1.Queues.Subscribe("push-a", true);

            Assert.Equal(HorseResultCode.Ok, joined1.Code);

            HorseResult joined2 = await consumer2.Queues.Subscribe("push-a-cc", true);

            Assert.Equal(HorseResultCode.Ok, joined2.Code);

            HorseMessage msg = new HorseMessage(MessageType.QueueMessage, "push-a");

            msg.AddHeader(HorseHeaders.CC, "push-a-cc");
            msg.SetStringContent("Hello, World!");

            await producer.SendAsync(msg);

            await Task.Delay(1500);

            Assert.Equal(1, consumer1Msgs);
            Assert.Equal(1, consumer2Msgs);
        }
        public async Task CatchResponseMessages(bool enabled)
        {
            TestHorseMq server = new TestHorseMq();
            await server.Initialize();

            int port = server.Start();

            HorseClient client1 = new HorseClient();
            HorseClient client2 = new HorseClient();

            client1.ClientId = "client-1";
            client2.ClientId = "client-2";
            client1.CatchResponseMessages = enabled;

            await client1.ConnectAsync("hmq://localhost:" + port);

            await client2.ConnectAsync("hmq://localhost:" + port);

            Assert.True(client1.IsConnected);
            Assert.True(client2.IsConnected);

            bool responseCaught = false;

            client1.MessageReceived += (c, m) => responseCaught = true;
            client2.MessageReceived += async(c, m) =>
            {
                HorseMessage rmsg = m.CreateResponse(HorseResultCode.Ok);
                rmsg.SetStringContent("Response!");
                await((HorseClient)c).SendAsync(rmsg);
            };

            HorseMessage msg = new HorseMessage(MessageType.DirectMessage, "client-2");

            msg.WaitResponse = true;
            msg.SetStringContent("Hello, World!");

            HorseMessage response = await client1.Request(msg);

            await Task.Delay(500);

            Assert.NotNull(response);
            Assert.Equal(msg.MessageId, response.MessageId);
            Assert.Equal(enabled, responseCaught);
        }
Example #6
0
        public async Task DisconnectDueToPingTimeout()
        {
            TestHorseMq server = new TestHorseMq();
            await server.Initialize();

            int port = server.Start();

            TcpClient client = new TcpClient();
            await client.ConnectAsync("127.0.0.1", port);

            NetworkStream stream = client.GetStream();

            stream.Write(PredefinedMessages.PROTOCOL_BYTES_V2);
            HorseMessage msg = new HorseMessage();

            msg.Type        = MessageType.Server;
            msg.ContentType = KnownContentTypes.Hello;
            msg.SetStringContent("GET /\r\nName: Test-" + port);
            msg.CalculateLengths();
            HmqWriter.Write(msg, stream);
            await Task.Delay(1000);

            Assert.Equal(1, server.ClientConnected);

            ThreadPool.UnsafeQueueUserWorkItem(async s =>
            {
                byte[] buffer = new byte[128];
                while (client.Connected)
                {
                    int r = await s.ReadAsync(buffer);
                    if (r == 0)
                    {
                        client.Dispose();
                        break;
                    }
                }
            }, stream, false);

            await Task.Delay(15000);

            Assert.False(client.Connected);
            Assert.Equal(1, server.ClientDisconnected);
        }
Example #7
0
        public async Task WithResponse()
        {
            TestHorseMq server = new TestHorseMq();
            await server.Initialize();

            int port = server.Start();

            HorseClient client1 = new HorseClient();
            HorseClient client2 = new HorseClient();

            client1.ClientId        = "client-1";
            client2.ClientId        = "client-2";
            client2.AutoAcknowledge = true;

            await client1.ConnectAsync("hmq://localhost:" + port);

            await client2.ConnectAsync("hmq://localhost:" + port);

            Assert.True(client1.IsConnected);
            Assert.True(client2.IsConnected);

            client2.MessageReceived += async(c, m) =>
            {
                if (m.Source == "client-1")
                {
                    HorseMessage rmsg = m.CreateResponse(HorseResultCode.Ok);
                    rmsg.SetStringContent("Hello, World Response!");
                    await((HorseClient)c).SendAsync(rmsg);
                }
            };

            HorseMessage message = new HorseMessage(MessageType.DirectMessage, "client-2");

            message.SetStringContent("Hello, World!");

            HorseMessage response = await client1.Request(message);

            Assert.NotNull(response);
            Assert.Equal(0, response.ContentType);
        }
Example #8
0
        public async Task SingleQueueSingleDirectResponseFromDirect()
        {
            TestHorseMq server = new TestHorseMq();
            await server.Initialize();

            int port = server.Start(300, 300);

            Router router = new Router(server.Server, "router", RouteMethod.Distribute);

            router.AddBinding(new QueueBinding("qbind-1", "push-a", 0, BindingInteraction.None));
            router.AddBinding(new DirectBinding("dbind-1", "client-1", 0, BindingInteraction.Response));
            server.Server.AddRouter(router);

            HorseClient producer = new HorseClient();
            await producer.ConnectAsync("hmq://localhost:" + port);

            Assert.True(producer.IsConnected);

            HorseClient client1 = new HorseClient();

            client1.ClientId = "client-1";
            await client1.ConnectAsync("hmq://localhost:" + port);

            client1.MessageReceived += (c, m) =>
            {
                HorseMessage response = m.CreateResponse(HorseResultCode.Ok);
                response.SetStringContent("Response");
                client1.SendAsync(response);
            };
            Assert.True(client1.IsConnected);

            HorseQueue queue1 = server.Server.FindQueue("push-a");

            HorseMessage message = await producer.Routers.PublishRequest("router", "Hello, World!");

            Assert.NotNull(message);
            Assert.Equal("Response", message.GetStringContent());
            Assert.Equal(1, queue1.MessageCount());
        }
        public async Task InPersistentHandler()
        {
            ConfigurationFactory.Destroy();
            PersistentDeliveryHandler handler = null;
            HorseServer server = new HorseServer();
            HorseMq     mq     = server.UseHorseMq(cfg => cfg
                                                   .AddPersistentQueues(q => q.KeepLastBackup())
                                                   .UseDeliveryHandler(async builder =>
            {
                DatabaseOptions options = new DatabaseOptions
                {
                    Filename             = "redelivery-test.tdb",
                    InstantFlush         = true,
                    CreateBackupOnShrink = false,
                    ShrinkInterval       = TimeSpan.FromSeconds(60)
                };

                handler = new PersistentDeliveryHandler(builder.Queue,
                                                        options,
                                                        DeleteWhen.AfterSend,
                                                        ProducerAckDecision.None,
                                                        true);
                await handler.Initialize();
                return(handler);
            }));

            HorseQueue queue = await mq.CreateQueue("test");

            HorseMessage message = new HorseMessage(MessageType.QueueMessage, "test");

            message.SetMessageId("id");
            message.SetStringContent("Hello, World!");
            QueueMessage queueMessage = new QueueMessage(message);

            await handler.BeginSend(queue, queueMessage);

            List <KeyValuePair <string, int> > deliveries = handler.RedeliveryService.GetDeliveries();

            Assert.Single(deliveries);
            Assert.Equal("id", deliveries[0].Key);
            Assert.Equal(1, deliveries[0].Value);

            string header = message.FindHeader(HorseHeaders.DELIVERY);

            Assert.Null(header);

            await handler.BeginSend(queue, queueMessage);

            deliveries = handler.RedeliveryService.GetDeliveries();
            Assert.Single(deliveries);
            Assert.Equal("id", deliveries[0].Key);
            Assert.Equal(2, deliveries[0].Value);

            header = message.FindHeader(HorseHeaders.DELIVERY);
            Assert.NotNull(header);
            Assert.Equal(2, Convert.ToInt32(header));

            queueMessage.MarkAsSent();

            await handler.EndSend(queue, queueMessage);

            deliveries = handler.RedeliveryService.GetDeliveries();
            Assert.Empty(deliveries);
        }
Example #10
0
        public override async Task Execute(HorseClient client, HorseMessage message, object model)
        {
            Exception        exception       = null;
            IConsumerFactory consumerFactory = null;
            bool             respond         = false;

            try
            {
                TRequest requestModel = (TRequest)model;
                IHorseRequestHandler <TRequest, TResponse> handler;

                if (_handler != null)
                {
                    handler = _handler;
                }
                else if (_handlerFactoryCreator != null)
                {
                    consumerFactory = _handlerFactoryCreator();
                    object consumerObject = await consumerFactory.CreateConsumer(_handlerType);

                    handler = (IHorseRequestHandler <TRequest, TResponse>)consumerObject;
                }
                else
                {
                    throw new ArgumentNullException("There is no consumer defined");
                }

                try
                {
                    TResponse responseModel = await Handle(handler, requestModel, message, client);

                    HorseResultCode code            = responseModel is null ? HorseResultCode.NoContent : HorseResultCode.Ok;
                    HorseMessage    responseMessage = message.CreateResponse(code);

                    if (responseModel != null)
                    {
                        responseMessage.Serialize(responseModel, client.JsonSerializer);
                    }

                    respond = true;
                    await client.SendAsync(responseMessage);
                }
                catch (Exception e)
                {
                    ErrorResponse errorModel = await handler.OnError(e, requestModel, message, client);

                    if (errorModel.ResultCode == HorseResultCode.Ok)
                    {
                        errorModel.ResultCode = HorseResultCode.Failed;
                    }

                    HorseMessage responseMessage = message.CreateResponse(errorModel.ResultCode);

                    if (!string.IsNullOrEmpty(errorModel.Reason))
                    {
                        responseMessage.SetStringContent(errorModel.Reason);
                    }

                    respond = true;
                    await client.SendAsync(responseMessage);

                    throw;
                }
            }
            catch (Exception e)
            {
                if (!respond)
                {
                    try
                    {
                        HorseMessage response = message.CreateResponse(HorseResultCode.InternalServerError);
                        await client.SendAsync(response);
                    }
                    catch
                    {
                    }
                }

                await SendExceptions(message, client, e);

                exception = e;
            }
            finally
            {
                if (consumerFactory != null)
                {
                    consumerFactory.Consumed(exception);
                }
            }
        }
Example #11
0
        public async Task ReloadAfterRestart()
        {
            await Task.Delay(500);

            ConfigurationFactory.Destroy();
            RedeliveryService service = new RedeliveryService("data/reload-test.tdb.delivery");
            await service.Load();

            await service.Clear();

            await service.Set("id", 4);

            await service.Close();

            if (System.IO.File.Exists("data/config.json"))
            {
                System.IO.File.Delete("data/config.json");
            }

            if (System.IO.File.Exists("data/reload-test.tdb"))
            {
                System.IO.File.Delete("data/reload-test.tdb");
            }

            if (System.IO.File.Exists("data/reload-test.tdb.delivery"))
            {
                System.IO.File.Delete("data/reload-test.tdb.delivery");
            }

            HorseServer server = new HorseServer();
            PersistentDeliveryHandler handler = null;
            Func <DeliveryHandlerBuilder, Task <IMessageDeliveryHandler> > fac = async builder =>
            {
                DatabaseOptions options = new DatabaseOptions
                {
                    Filename             = "data/reload-test.tdb",
                    InstantFlush         = true,
                    CreateBackupOnShrink = false,
                    ShrinkInterval       = TimeSpan.FromSeconds(60)
                };

                handler = (PersistentDeliveryHandler)await builder.CreatePersistentDeliveryHandler(o =>
                {
                    return(new PersistentDeliveryHandler(builder.Queue,
                                                         options,
                                                         DeleteWhen.AfterSend,
                                                         ProducerAckDecision.None,
                                                         true));
                });

                return(handler);
            };

            HorseMq mq = server.UseHorseMq(cfg => cfg
                                           .AddPersistentQueues(q => q.KeepLastBackup())
                                           .UseDeliveryHandler(fac));

            HorseQueue queue = await mq.CreateQueue("reload-test",
                                                    o => o.Status = QueueStatus.Push);

            HorseMessage msg = new HorseMessage(MessageType.QueueMessage, "reload-test");

            msg.SetMessageId("id");
            msg.SetStringContent("Hello, World!");
            await queue.Push(msg);

            QueueMessage queueMsg = queue.Messages.FirstOrDefault();
            await handler.BeginSend(queue, queueMsg);

            await handler.RedeliveryService.Close();

            ConfigurationFactory.Destroy();

            mq = server.UseHorseMq(cfg => cfg
                                   .AddPersistentQueues(q => q.KeepLastBackup())
                                   .UseDeliveryHandler(fac));

            await mq.LoadPersistentQueues();

            HorseQueue queue2 = mq.FindQueue("reload-test");

            Assert.NotNull(queue2);
            Assert.NotEmpty(queue2.Messages);
            QueueMessage loadedMsg = queue2.Messages.FirstOrDefault();

            Assert.NotNull(loadedMsg);
            Assert.Equal(1, loadedMsg.DeliveryCount);
        }