Example #1
0
        /// <summary>
        /// Removes a router with it's bindings
        /// </summary>
        private async Task RemoveRouter(MqClient client, HorseMessage message)
        {
            IRouter found = _server.FindRouter(message.Target);

            if (found == null)
            {
                await client.SendAsync(message.CreateResponse(HorseResultCode.Ok));

                return;
            }

            //check create queue access
            foreach (IClientAuthorization authorization in _server.Authorizations)
            {
                bool grant = await authorization.CanRemoveRouter(client, found);

                if (!grant)
                {
                    await client.SendAsync(message.CreateResponse(HorseResultCode.Unauthorized));

                    return;
                }
            }

            _server.RemoveRouter(found);
            await client.SendAsync(message.CreateResponse(HorseResultCode.Ok));
        }
        /// <summary>
        /// Reads a data message object from the stream
        /// </summary>
        public async Task <DataMessage> Read(Stream stream)
        {
            DataType type = ReadType(stream);
            string   id   = await ReadId(stream);

            if (string.IsNullOrEmpty(id))
            {
                return(new DataMessage(DataType.Empty, null));
            }

            if (type == DataType.Delete)
            {
                return(new DataMessage(DataType.Delete, id));
            }

            int size = await ReadLength(stream);

            if (size == 0)
            {
                return(new DataMessage(DataType.Empty, id));
            }

            HorseMessage msg = await _reader.Read(stream);

            return(new DataMessage(DataType.Insert, id, msg));
        }
Example #3
0
        /// <summary>
        /// Pushes a message to a queue
        /// </summary>
        public async Task <HorseResult> PushJson(string queue, object jsonObject, string messageId, bool waitAcknowledge,
                                                 IEnumerable <KeyValuePair <string, string> > messageHeaders = null)
        {
            TypeDeliveryDescriptor descriptor = _client.DeliveryContainer.GetDescriptor(jsonObject.GetType());
            HorseMessage           message    = descriptor.CreateMessage(MessageType.QueueMessage, queue, 0);

            if (!string.IsNullOrEmpty(messageId))
            {
                message.SetMessageId(messageId);
            }

            message.WaitResponse = waitAcknowledge;

            if (messageHeaders != null)
            {
                foreach (KeyValuePair <string, string> pair in messageHeaders)
                {
                    message.AddHeader(pair.Key, pair.Value);
                }
            }

            message.Serialize(jsonObject, _client.JsonSerializer);

            if (string.IsNullOrEmpty(message.MessageId) && waitAcknowledge)
            {
                message.SetMessageId(_client.UniqueIdGenerator.Create());
            }

            return(await _client.WaitResponse(message, waitAcknowledge));
        }
Example #4
0
        /// <summary>
        /// Gets queue.
        /// If it's not cached, finds and caches it before returns.
        /// </summary>
        /// <returns></returns>
        private async Task <HorseQueue> GetQueue(HorseMessage message)
        {
            if (_targetQueue != null)
            {
                return(_targetQueue);
            }

            string queueName = message.FindHeader(HorseHeaders.QUEUE_NAME);

            if (queueName == null)
            {
                return(null);
            }

            HorseQueue queue = Router.Server.FindQueue(queueName);

            if (queue != null)
            {
                _targetQueue = queue;
                return(_targetQueue);
            }

            _targetQueue = await Router.Server.CreateQueue(queueName, Router.Server.Options, message, null, true, true);

            return(_targetQueue);
        }
Example #5
0
        /// <summary>
        /// Sends the message to binding receivers
        /// </summary>
        public override Task <bool> Send(MqClient sender, HorseMessage message)
        {
            try
            {
                if (DateTime.UtcNow - _queueUpdateTime > _queueCacheDuration)
                {
                    RefreshQueueCache();
                }

                message.WaitResponse = Interaction == BindingInteraction.Response;

                switch (RouteMethod)
                {
                case RouteMethod.Distribute:
                    return(SendDistribute(message));

                case RouteMethod.OnlyFirst:
                    return(SendOnlyFirst(message));

                case RouteMethod.RoundRobin:
                    return(SendRoundRobin(message));

                default:
                    return(Task.FromResult(false));
                }
            }
            catch (Exception e)
            {
                Router.Server.SendError("BINDING_SEND", e, $"Type:Topic, Binding:{Name}");
                return(Task.FromResult(false));
            }
        }
Example #6
0
        /// <summary>
        /// Reads Clear header value and returns as enum
        /// </summary>
        private static ClearDecision FindClearDecision(HorseMessage request)
        {
            string clearStr = request.FindHeader(HorseHeaders.CLEAR);

            if (string.IsNullOrEmpty(clearStr))
            {
                return(ClearDecision.None);
            }

            clearStr = clearStr.Trim();

            if (clearStr.Equals("all", StringComparison.InvariantCultureIgnoreCase))
            {
                return(ClearDecision.All);
            }

            if (clearStr.Equals("high-priority", StringComparison.InvariantCultureIgnoreCase))
            {
                return(ClearDecision.HighPriority);
            }

            if (clearStr.Equals("default-priority", StringComparison.InvariantCultureIgnoreCase))
            {
                return(ClearDecision.DefaultPriority);
            }

            return(ClearDecision.None);
        }
Example #7
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 #8
0
        /// <summary>
        /// Sends a request to target with a JSON model, waits response
        /// </summary>
        public async Task <HorseResult <TResponse> > RequestJson <TResponse>(string target, ushort?contentType, object model,
                                                                             IEnumerable <KeyValuePair <string, string> > messageHeaders = null)
        {
            TypeDeliveryDescriptor descriptor = _client.DeliveryContainer.GetDescriptor(model.GetType());
            HorseMessage           message    = descriptor.CreateMessage(MessageType.DirectMessage, target, contentType);

            message.Serialize(model, _client.JsonSerializer);

            if (messageHeaders != null)
            {
                foreach (KeyValuePair <string, string> pair in messageHeaders)
                {
                    message.AddHeader(pair.Key, pair.Value);
                }
            }

            HorseMessage responseMessage = await _client.Request(message);

            if (responseMessage.ContentType == 0)
            {
                TResponse response = responseMessage.Deserialize <TResponse>(_client.JsonSerializer);
                return(new HorseResult <TResponse>(response, message, HorseResultCode.Ok));
            }

            return(new HorseResult <TResponse>(default, responseMessage, (HorseResultCode)responseMessage.ContentType));
Example #9
0
        /// <summary>
        /// Sends a JSON message by full name
        /// </summary>
        public async Task <HorseResult> SendJsonById <T>(string id, ushort contentType, T model, bool waitAcknowledge,
                                                         IEnumerable <KeyValuePair <string, string> > messageHeaders = null)
        {
            HorseMessage message = new HorseMessage();

            message.SetTarget(id);
            message.Type        = MessageType.DirectMessage;
            message.ContentType = contentType;
            message.Serialize(model, _client.JsonSerializer);

            if (messageHeaders != null)
            {
                foreach (KeyValuePair <string, string> pair in messageHeaders)
                {
                    message.AddHeader(pair.Key, pair.Value);
                }
            }

            if (waitAcknowledge)
            {
                return(await _client.SendAndGetAck(message));
            }

            return(await _client.SendAsync(message));
        }
Example #10
0
        /// <summary>
        /// Sends a JSON message by full name
        /// </summary>
        public async Task <HorseResult> SendJson <T>(T model, bool waitAcknowledge, IEnumerable <KeyValuePair <string, string> > messageHeaders = null)
        {
            TypeDeliveryDescriptor descriptor = _client.DeliveryContainer.GetDescriptor(model.GetType());
            HorseMessage           message    = descriptor.CreateMessage(MessageType.DirectMessage, null, null);

            if (string.IsNullOrEmpty(message.Target))
            {
                return(new HorseResult(HorseResultCode.SendError));
            }

            message.WaitResponse = waitAcknowledge;
            message.Serialize(model, _client.JsonSerializer);

            if (messageHeaders != null)
            {
                foreach (KeyValuePair <string, string> pair in messageHeaders)
                {
                    message.AddHeader(pair.Key, pair.Value);
                }
            }

            if (waitAcknowledge)
            {
                return(await _client.SendAndGetAck(message));
            }

            return(await _client.SendAsync(message));
        }
Example #11
0
        /// <summary>
        /// Sends a memory stream message by full name
        /// </summary>
        private async Task <HorseResult> SendById(string id, ushort contentType, MemoryStream content, bool waitAcknowledge,
                                                  IEnumerable <KeyValuePair <string, string> > messageHeaders = null)
        {
            HorseMessage message = new HorseMessage();

            message.SetTarget(id);
            message.ContentType = contentType;
            message.Content     = content;
            message.Type        = MessageType.DirectMessage;

            if (messageHeaders != null)
            {
                foreach (KeyValuePair <string, string> pair in messageHeaders)
                {
                    message.AddHeader(pair.Key, pair.Value);
                }
            }

            if (waitAcknowledge)
            {
                return(await _client.SendAndGetAck(message));
            }

            return(await _client.SendAsync(message));
        }
Example #12
0
        public async Task Handle(MqClient client, HorseMessage message, bool fromNode)
        {
            HorseQueue queue = await FindQueue(client, message.Target, message);

            if (queue == null)
            {
                return;
            }

            //if there is at least one cc header
            //we need to create a clone of the message
            //clone does not have cc headers but others
            HorseMessage  clone  = null;
            List <string> ccList = null;
            List <KeyValuePair <string, string> > additionalHeaders = null;

            if (message.HasHeader && message.FindHeader(HorseHeaders.CC) != null)
            {
                additionalHeaders = message.Headers.Where(x => !x.Key.Equals(HorseHeaders.CC, StringComparison.InvariantCultureIgnoreCase)).ToList();
                ccList            = new List <string>(message.Headers.Where(x => x.Key.Equals(HorseHeaders.CC, StringComparison.InvariantCultureIgnoreCase)).Select(x => x.Value));
                clone             = message.Clone(false, true, _server.MessageIdGenerator.Create(), additionalHeaders);
            }

            await HandlePush(client, message, queue, true);

            //if there are cc headers, we will push the message to other queues
            if (clone != null)
            {
                await PushOtherQueues(client, clone, ccList, additionalHeaders);
            }
        }
        public async Task Handle(MqClient client, HorseMessage message, bool fromNode)
        {
            try
            {
                HorseQueue queue = _server.FindQueue(message.Target);

                //if auto creation active, try to create queue
                if (queue == null && _server.Options.AutoQueueCreation)
                {
                    QueueOptions options = QueueOptions.CloneFrom(_server.Options);
                    queue = await _server.CreateQueue(message.Target, options, message, _server.DeliveryHandlerFactory, true, true);
                }

                if (queue == null)
                {
                    if (!string.IsNullOrEmpty(message.MessageId))
                    {
                        await client.SendAsync(message.CreateResponse(HorseResultCode.NotFound));
                    }

                    return;
                }

                await HandlePullRequest(client, message, queue);
            }
            catch (Exception e)
            {
                _server.SendError("PULL_REQUEST", e, $"QueueName:{message.Target}");
            }
        }
Example #14
0
        /// <summary>
        /// Sends all routers
        /// </summary>
        private async Task ListRouters(MqClient client, HorseMessage message)
        {
            List <RouterInformation> items = new List <RouterInformation>();

            foreach (IRouter router in _server.Routers)
            {
                RouterInformation info = new RouterInformation
                {
                    Name      = router.Name,
                    IsEnabled = router.IsEnabled
                };

                if (router is Router r)
                {
                    info.Method = r.Method;
                }

                items.Add(info);
            }

            HorseMessage response = message.CreateResponse(HorseResultCode.Ok);

            response.Serialize(items, new NewtonsoftContentSerializer());
            await client.SendAsync(response);
        }
Example #15
0
        /// <summary>
        /// Pushes new message into the queue
        /// </summary>
        public Task <PushResult> Push(HorseMessage message)
        {
            message.Type = MessageType.QueueMessage;
            message.SetTarget(Name);

            return(Push(new QueueMessage(message), null));
        }
        public Task Consume(HorseMessage message, string serializedException, HorseClient client)
        {
            Exception exception = JsonConvert.DeserializeObject <Exception>(serializedException);

            Console.WriteLine(exception.Message);
            return(Task.CompletedTask);
        }
Example #17
0
 /// <summary>
 /// Sends a message to connected master nodes
 /// </summary>
 public void SendMessageToNodes(HorseMessage message)
 {
     foreach (HmqStickyConnector connector in Connectors)
     {
         _ = connector.GetClient()?.SendAsync(message);
     }
 }
Example #18
0
        internal Task TriggerEvents(HorseClient client, HorseMessage message)
        {
            string eventName = message.Source;
            string queue     = message.Target;

            List <EventDescriptor> list = _descriptors[eventName];
            EventDescriptor        descriptor;

            lock (list)
                descriptor = list.FirstOrDefault(x => x.Queue == queue);

            if (descriptor == null)
            {
                return(Task.CompletedTask);
            }

            List <Delegate> methods;

            lock (descriptor.Methods)
                methods = new List <Delegate>(descriptor.Methods);

            object param = message.Deserialize(descriptor.ParameterType, client.JsonSerializer);

            foreach (var m in methods)
            {
                m.DynamicInvoke(param);
            }

            return(Task.CompletedTask);
        }
Example #19
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 #20
0
        /// <summary>
        /// Sends negative ack
        /// </summary>
        protected Task SendNegativeAck(HorseMessage message, HorseClient client, Exception exception)
        {
            string reason;

            switch (NackReason)
            {
            case NackReason.Error:
                reason = HorseHeaders.NACK_REASON_ERROR;
                break;

            case NackReason.ExceptionType:
                reason = exception.GetType().Name;
                break;

            case NackReason.ExceptionMessage:
                reason = exception.Message;
                break;

            default:
                reason = HorseHeaders.NACK_REASON_NONE;
                break;
            }

            return(client.SendNegativeAck(message, reason));
        }
Example #21
0
        /// <summary>
        /// Sends the message to binding receivers
        /// </summary>
        public override async Task <bool> Send(MqClient sender, HorseMessage message)
        {
            try
            {
                HorseQueue queue = await GetQueue(message);

                if (queue == null)
                {
                    return(false);
                }

                string messageId = Interaction == BindingInteraction.None
                                       ? Router.Server.MessageIdGenerator.Create()
                                       : message.MessageId;

                HorseMessage msg = message.Clone(true, true, messageId);

                msg.Type = MessageType.QueueMessage;
                msg.SetTarget(Target);
                msg.WaitResponse = Interaction == BindingInteraction.Response;

                QueueMessage queueMessage = new QueueMessage(msg);
                queueMessage.Source = sender;

                PushResult result = await queue.Push(queueMessage, sender);

                return(result == PushResult.Success);
            }
            catch (Exception e)
            {
                Router.Server.SendError("BINDING_SEND", e, $"Type:AutoQueue, Binding:{Name}");
                return(false);
            }
        }
Example #22
0
        /// <summary>
        /// Pushes a message to router
        /// </summary>
        public Task <RouterPublishResult> Publish(MqClient sender, HorseMessage message)
        {
            try
            {
                if (!IsEnabled)
                {
                    return(Task.FromResult(RouterPublishResult.Disabled));
                }

                if (Bindings.Length == 0)
                {
                    return(Task.FromResult(RouterPublishResult.NoBindings));
                }

                switch (Method)
                {
                case RouteMethod.Distribute:
                    return(Distribute(sender, message));

                case RouteMethod.OnlyFirst:
                    return(OnlyFirst(sender, message));

                case RouteMethod.RoundRobin:
                    return(RoundRobin(sender, message));

                default:
                    return(Task.FromResult(RouterPublishResult.Disabled));
                }
            }
            catch (Exception e)
            {
                Server.SendError("PUBLISH", e, $"Router:{Name}, Binding:{Name}");
                return(Task.FromResult(RouterPublishResult.NoBindings));
            }
        }
Example #23
0
        private async Task <bool> SendRoundRobin(HorseMessage message)
        {
            Interlocked.Increment(ref _roundRobinIndex);
            int i = _roundRobinIndex;

            if (i >= _queues.Length)
            {
                _roundRobinIndex = 0;
                i = 0;
            }

            if (_queues.Length == 0)
            {
                return(false);
            }

            HorseQueue queue = Router.Server.FindQueue(message.Target);

            if (queue == null)
            {
                if (!Router.Server.Options.AutoQueueCreation)
                {
                    return(false);
                }

                queue = await Router.Server.CreateQueue(message.Target, Router.Server.Options, message, Router.Server.DeliveryHandlerFactory, true, true);
            }

            QueueMessage queueMessage = new QueueMessage(message);

            queue.AddMessage(queueMessage);
            return(true);
        }
Example #24
0
        /// <summary>
        /// Sends the message to only first binding
        /// </summary>
        private async Task <RouterPublishResult> OnlyFirst(MqClient sender, HorseMessage message)
        {
            int  index = 0;
            bool sent;
            RouterPublishResult result = RouterPublishResult.NoReceivers;

            do
            {
                if (index >= Bindings.Length)
                {
                    return(RouterPublishResult.NoReceivers);
                }

                Binding binding = Bindings[index];
                sent = await binding.Send(sender, message);

                if (sent)
                {
                    result = binding.Interaction != BindingInteraction.None
                                 ? RouterPublishResult.OkAndWillBeRespond
                                 : RouterPublishResult.OkWillNotRespond;
                }

                index++;
            }while (!sent);

            return(result);
        }
        /// <summary>
        /// Processes the client message which has single receiver (message by unique id)
        /// </summary>
        private async Task ProcessSingleReceiverClientMessage(MqClient client, HorseMessage message)
        {
            //find the receiver
            MqClient other = _server.FindClient(message.Target);

            if (other == null)
            {
                await client.SendAsync(message.CreateResponse(HorseResultCode.NotFound));

                return;
            }

            //check sending message authority
            foreach (IClientAuthorization authorization in _server.Authorizations)
            {
                bool grant = await authorization.CanDirectMessage(client, message, other);

                if (!grant)
                {
                    await client.SendAsync(message.CreateResponse(HorseResultCode.Unauthorized));

                    return;
                }
            }

            //send the message
            await other.SendAsync(message);
        }
Example #26
0
        /// <summary>
        /// Distributes the message to all bindings
        /// </summary>
        private async Task <RouterPublishResult> Distribute(MqClient sender, HorseMessage message)
        {
            RouterPublishResult result = RouterPublishResult.NoReceivers;

            foreach (Binding binding in Bindings)
            {
                bool oldWaitResponse = message.WaitResponse;
                bool sent            = await binding.Send(sender, message);

                message.WaitResponse = oldWaitResponse;
                if (sent)
                {
                    if (binding.Interaction != BindingInteraction.None)
                    {
                        result = RouterPublishResult.OkAndWillBeRespond;
                    }

                    else if (result == RouterPublishResult.NoReceivers)
                    {
                        result = RouterPublishResult.OkWillNotRespond;
                    }
                }
            }

            return(result);
        }
Example #27
0
        /// <summary>
        /// Clears messages in a queue.
        /// Required administration permission.
        /// If server has no implementation for administration authorization, request is not allowed.
        /// </summary>
        public Task <HorseResult> ClearMessages(string queue, bool clearPriorityMessages, bool clearMessages)
        {
            if (!clearPriorityMessages && !clearMessages)
            {
                return(Task.FromResult(HorseResult.Failed()));
            }

            HorseMessage message = new HorseMessage();

            message.Type        = MessageType.Server;
            message.ContentType = KnownContentTypes.ClearMessages;
            message.SetTarget(queue);
            message.WaitResponse = true;
            message.SetMessageId(_client.UniqueIdGenerator.Create());
            message.AddHeader(HorseHeaders.QUEUE_NAME, queue);

            if (clearPriorityMessages)
            {
                message.AddHeader(HorseHeaders.PRIORITY_MESSAGES, "yes");
            }

            if (clearMessages)
            {
                message.AddHeader(HorseHeaders.MESSAGES, "yes");
            }

            return(_client.WaitResponse(message, true));
        }
Example #28
0
        /// <summary>
        /// Sends the message to only one binding within round robin algorithm
        /// </summary>
        private async Task <RouterPublishResult> RoundRobin(MqClient sender, HorseMessage message)
        {
            int len = Bindings.Length;

            for (int i = 0; i < len; i++)
            {
                Interlocked.Increment(ref _lastRoutedIndex);
                if (_lastRoutedIndex >= Bindings.Length)
                {
                    Interlocked.Exchange(ref _lastRoutedIndex, 0);
                }

                Binding binding      = Bindings[_lastRoutedIndex];
                bool    waitResponse = message.WaitResponse;
                bool    sent         = await binding.Send(sender, message);

                message.WaitResponse = waitResponse;
                if (sent)
                {
                    return(binding.Interaction != BindingInteraction.None
                               ? RouterPublishResult.OkAndWillBeRespond
                               : RouterPublishResult.OkWillNotRespond);
                }
            }

            return(RouterPublishResult.NoReceivers);
        }
Example #29
0
        /// <summary>
        /// Pushes a message to a queue
        /// </summary>
        public async Task <HorseResult> Push(string queue, MemoryStream content, string messageId, bool waitAcknowledge,
                                             IEnumerable <KeyValuePair <string, string> > messageHeaders = null)
        {
            HorseMessage message = new HorseMessage(MessageType.QueueMessage, queue, 0);

            message.Content      = content;
            message.WaitResponse = waitAcknowledge;

            if (!string.IsNullOrEmpty(messageId))
            {
                message.SetMessageId(messageId);
            }

            if (messageHeaders != null)
            {
                foreach (KeyValuePair <string, string> pair in messageHeaders)
                {
                    message.AddHeader(pair.Key, pair.Value);
                }
            }

            if (string.IsNullOrEmpty(message.MessageId) && waitAcknowledge)
            {
                message.SetMessageId(_client.UniqueIdGenerator.Create());
            }

            return(await _client.WaitResponse(message, waitAcknowledge));
        }
Example #30
0
        /// <summary>
        /// Creates new router
        /// </summary>
        private async Task CreateRouter(MqClient client, HorseMessage message)
        {
            IRouter found = _server.FindRouter(message.Target);

            if (found != null)
            {
                await client.SendAsync(message.CreateResponse(HorseResultCode.Ok));

                return;
            }

            string      methodHeader = message.FindHeader(HorseHeaders.ROUTE_METHOD);
            RouteMethod method       = RouteMethod.Distribute;

            if (!string.IsNullOrEmpty(methodHeader))
            {
                method = (RouteMethod)Convert.ToInt32(methodHeader);
            }

            //check create queue access
            foreach (IClientAuthorization authorization in _server.Authorizations)
            {
                bool grant = await authorization.CanCreateRouter(client, message.Target, method);

                if (!grant)
                {
                    await client.SendAsync(message.CreateResponse(HorseResultCode.Unauthorized));

                    return;
                }
            }

            _server.AddRouter(message.Target, method);
            await client.SendAsync(message.CreateResponse(HorseResultCode.Ok));
        }