Ejemplo n.º 1
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));
        }
Ejemplo n.º 2
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));
Ejemplo n.º 3
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));
        }
Ejemplo n.º 4
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);
        }
Ejemplo n.º 5
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));
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Adds new binding to a router
        /// </summary>
        /// <param name="routerName">Router name of the binding</param>
        /// <param name="type">Binding type</param>
        /// <param name="name">Binding name</param>
        /// <param name="target">Binding target. Queue name, tag name, direct receiver id, name, type, etc.</param>
        /// <param name="interaction">Binding interaction</param>
        /// <param name="bindingMethod">Binding method is used when multiple receivers available in same binding. It's used for Direct and Tag bindings.</param>
        /// <param name="contentType">Overwritten content type if specified</param>
        /// <param name="priority">Binding priority</param>
        /// <returns></returns>
        public async Task <HorseResult> AddBinding(string routerName,
                                                   BindingType type,
                                                   string name,
                                                   string target,
                                                   BindingInteraction interaction,
                                                   RouteMethod bindingMethod = RouteMethod.Distribute,
                                                   ushort?contentType        = null,
                                                   int priority = 1)
        {
            HorseMessage message = new HorseMessage();

            message.Type        = MessageType.Server;
            message.ContentType = KnownContentTypes.AddBinding;
            message.SetTarget(routerName);
            message.WaitResponse = true;
            message.SetMessageId(_client.UniqueIdGenerator.Create());
            BindingInformation info = new BindingInformation
            {
                Name        = name,
                Target      = target,
                Interaction = interaction,
                ContentType = contentType,
                Priority    = priority,
                BindingType = type,
                Method      = bindingMethod
            };

            message.Serialize(info, new NewtonsoftContentSerializer());
            return(await _client.WaitResponse(message, true));
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Publishes a JSON object to a router
        /// </summary>
        public async Task <HorseResult> PublishJson(string routerName,
                                                    object model,
                                                    string messageId        = null,
                                                    bool waitForAcknowledge = false,
                                                    ushort?contentType      = null,
                                                    IEnumerable <KeyValuePair <string, string> > messageHeaders = null)
        {
            TypeDeliveryDescriptor descriptor = _client.DeliveryContainer.GetDescriptor(model.GetType());
            HorseMessage           message    = descriptor.CreateMessage(MessageType.Router, routerName, contentType);

            if (!string.IsNullOrEmpty(messageId))
            {
                message.SetMessageId(messageId);
            }
            else
            {
                message.SetMessageId(_client.UniqueIdGenerator.Create());
            }

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

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

            return(await _client.WaitResponse(message, waitForAcknowledge));
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Gets connected instance list
        /// </summary>
        private async Task GetInstanceList(MqClient client, HorseMessage message)
        {
            foreach (IAdminAuthorization authorization in _server.AdminAuthorizations)
            {
                bool grant = await authorization.CanManageInstances(client, message);

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

                    return;
                }
            }

            List <NodeInformation> list = new List <NodeInformation>();

            //slave instances
            List <MqClient> slaves = _server.NodeManager.Clients.GetAsClone();

            foreach (MqClient slave in slaves)
            {
                list.Add(new NodeInformation
                {
                    IsSlave     = true,
                    Host        = slave.RemoteHost,
                    IsConnected = slave.IsConnected,
                    Id          = slave.UniqueId,
                    Name        = slave.Name,
                    Lifetime    = slave.ConnectedDate.LifetimeMilliseconds()
                });
            }

            //master instances
            foreach (HmqStickyConnector connector in _server.NodeManager.Connectors)
            {
                NodeOptions options = connector.Tag as NodeOptions;
                HorseClient c       = connector.GetClient();

                list.Add(new NodeInformation
                {
                    IsSlave     = false,
                    Host        = options?.Host,
                    IsConnected = connector.IsConnected,
                    Id          = c.ClientId,
                    Name        = options?.Name,
                    Lifetime    = Convert.ToInt64(connector.Lifetime.TotalMilliseconds)
                });
            }

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

            message.ContentType = KnownContentTypes.InstanceList;
            response.Serialize(list, _server.MessageContentSerializer);
            await client.SendAsync(response);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Triggers event and sends message to subscribers
        /// </summary>
        protected void Trigger(object model)
        {
            try
            {
                if (_subscribers.Count == 0)
                {
                    return;
                }

                HorseMessage message = new HorseMessage(MessageType.Event, Target);
                message.SetSource(Name);

                if (model != null)
                {
                    message.Serialize(model, _server.MessageContentSerializer);
                }

                byte[] data = HmqWriter.Create(message);

                List <MqClient> removing = null;

                lock (_subscribers)
                    foreach (MqClient subscriber in _subscribers)
                    {
                        //if client is disconnected, add it into removing list
                        if (!subscriber.IsConnected)
                        {
                            //removing list is created when it's needed
                            if (removing == null)
                            {
                                removing = new List <MqClient>();
                            }

                            removing.Add(subscriber);
                        }
                        else
                        {
                            _ = subscriber.SendAsync(data);
                        }
                    }

                //if there are some removing clients from subscribers list, remove them
                if (removing != null)
                {
                    lock (_subscribers)
                        foreach (MqClient remove in removing)
                        {
                            _subscribers.Remove(remove);
                        }
                }
            }
            catch (Exception e)
            {
                _server.SendError("EVENT_TRIGGER", e, $"Name:{Name}, Type:{GetType().Name}");
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Fills JSON object data to the queue.
        /// Creates new HorseMessage and before writing content and adding into queue calls the action.
        /// </summary>
        public PushResult FillJson <T>(IEnumerable <T> items, bool createAsSaved, Action <HorseMessage, T> action) where T : class
        {
            try
            {
                if (_queue.Status == QueueStatus.Stopped)
                {
                    return(PushResult.StatusNotSupported);
                }

                int max = _queue.PriorityMessagesList.Count + _queue.MessagesList.Count + items.Count();
                if (_queue.Options.MessageLimit > 0 && max > _queue.Options.MessageLimit)
                {
                    return(PushResult.LimitExceeded);
                }

                foreach (T item in items)
                {
                    HorseMessage message = new HorseMessage(MessageType.QueueMessage, _queue.Name);
                    message.WaitResponse = _queue.Options.Acknowledge != QueueAckDecision.None;

                    if (_queue.Options.UseMessageId)
                    {
                        message.SetMessageId(_queue.Server.MessageIdGenerator.Create());
                    }

                    action(message, item);
                    message.Serialize(item, _queue.Server.MessageContentSerializer);

                    QueueMessage qm = new QueueMessage(message, createAsSaved);

                    if (message.HighPriority)
                    {
                        lock (_queue.PriorityMessagesList)
                            _queue.PriorityMessagesList.AddLast(qm);
                    }
                    else
                    {
                        lock (_queue.MessagesList)
                            _queue.MessagesList.AddLast(qm);
                    }
                }

                _queue.Info.UpdateHighPriorityMessageCount(_queue.PriorityMessagesList.Count);
                _queue.Info.UpdateRegularMessageCount(_queue.MessagesList.Count);

                _ = _queue.Trigger();

                return(PushResult.Success);
            }
            catch (Exception e)
            {
                _queue.Server.SendError("FILL_JSON", e, $"QueueName:{_queue.Name}");
                return(PushResult.Error);
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Gets all connected clients
        /// </summary>
        public async Task GetClients(MqClient client, HorseMessage message)
        {
            foreach (IAdminAuthorization authorization in _server.AdminAuthorizations)
            {
                bool grant = await authorization.CanReceiveClients(client);

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

                    return;
                }
            }

            List <ClientInformation> list = new List <ClientInformation>();

            string filter = null;

            if (!string.IsNullOrEmpty(message.Target))
            {
                filter = message.Target;
            }

            foreach (MqClient mc in _server.Clients)
            {
                if (!string.IsNullOrEmpty(filter))
                {
                    if (string.IsNullOrEmpty(mc.Type) || !Filter.CheckMatch(mc.Type, filter))
                    {
                        continue;
                    }
                }

                list.Add(new ClientInformation
                {
                    Id              = mc.UniqueId,
                    Name            = mc.Name,
                    Type            = mc.Type,
                    IsAuthenticated = mc.IsAuthenticated,
                    Online          = mc.ConnectedDate.LifetimeMilliseconds(),
                });
            }

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

            message.ContentType = KnownContentTypes.ClientList;
            response.Serialize(list, _server.MessageContentSerializer);
            await client.SendAsync(response);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Sends all bindings of a router
        /// </summary>
        private async Task ListRouterBindings(MqClient client, HorseMessage message)
        {
            IRouter router = _server.FindRouter(message.Target);

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

                return;
            }

            List <BindingInformation> items = new List <BindingInformation>();

            foreach (Binding binding in router.GetBindings())
            {
                BindingInformation info = new BindingInformation
                {
                    Name        = binding.Name,
                    Target      = binding.Target,
                    Priority    = binding.Priority,
                    ContentType = binding.ContentType,
                    Interaction = binding.Interaction
                };

                if (binding is QueueBinding)
                {
                    info.BindingType = BindingType.Queue;
                }
                else if (binding is DirectBinding directBinding)
                {
                    info.Method      = directBinding.RouteMethod;
                    info.BindingType = BindingType.Direct;
                }
                else if (binding is TopicBinding topicBinding)
                {
                    info.Method      = topicBinding.RouteMethod;
                    info.BindingType = BindingType.Topic;
                }
                else if (binding is HttpBinding)
                {
                    info.BindingType = BindingType.Http;
                }

                items.Add(info);
            }

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

            response.Serialize(items, new NewtonsoftContentSerializer());
            await client.SendAsync(response);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Sends decision to all connected master nodes
        /// </summary>
        public void SendDecisionToNodes(QueueMessage queueMessage, Decision decision)
        {
            HorseMessage     msg   = new HorseMessage(MessageType.Server, null, 10);
            DecisionOverNode model = new DecisionOverNode
            {
                Queue       = Name,
                MessageId   = queueMessage.Message.MessageId,
                Acknowledge = decision.Acknowledge,
                Allow       = decision.Allow,
                PutBack     = decision.PutBack,
                SaveMessage = decision.SaveMessage
            };

            msg.Serialize(model, Server.MessageContentSerializer);
            Server.NodeManager.SendMessageToNodes(msg);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Gets active consumers of the queue
        /// </summary>
        public async Task GetQueueConsumers(MqClient client, HorseMessage message)
        {
            HorseQueue queue = _server.FindQueue(message.Target);

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

                return;
            }

            foreach (IAdminAuthorization authorization in _server.AdminAuthorizations)
            {
                bool grant = await authorization.CanReceiveQueueConsumers(client, queue);

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

                    return;
                }
            }

            List <ClientInformation> list = new List <ClientInformation>();

            foreach (QueueClient cc in queue.ClientsClone)
            {
                list.Add(new ClientInformation
                {
                    Id              = cc.Client.UniqueId,
                    Name            = cc.Client.Name,
                    Type            = cc.Client.Type,
                    IsAuthenticated = cc.Client.IsAuthenticated,
                    Online          = cc.JoinDate.LifetimeMilliseconds(),
                });
            }

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

            message.ContentType = KnownContentTypes.QueueConsumers;
            response.Serialize(list, _server.MessageContentSerializer);
            await client.SendAsync(response);
        }
Ejemplo n.º 15
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);
                }
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Finds all queues in the server
        /// </summary>
        private async Task GetQueueList(MqClient client, HorseMessage message)
        {
            foreach (IAdminAuthorization authorization in _server.AdminAuthorizations)
            {
                bool grant = await authorization.CanReceiveQueues(client);

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

                    return;
                }
            }

            List <QueueInformation> list = new List <QueueInformation>();

            foreach (HorseQueue queue in _server.Queues)
            {
                if (queue == null)
                {
                    continue;
                }

                string ack = "none";
                if (queue.Options.Acknowledge == QueueAckDecision.JustRequest)
                {
                    ack = "just";
                }
                else if (queue.Options.Acknowledge == QueueAckDecision.WaitForAcknowledge)
                {
                    ack = "wait";
                }

                list.Add(new QueueInformation
                {
                    Name                 = queue.Name,
                    Topic                = queue.Topic,
                    Status               = queue.Status.ToString().Trim().ToLower(),
                    PriorityMessages     = queue.PriorityMessagesList.Count,
                    Messages             = queue.MessagesList.Count,
                    Acknowledge          = ack,
                    AcknowledgeTimeout   = Convert.ToInt32(queue.Options.AcknowledgeTimeout.TotalMilliseconds),
                    MessageTimeout       = Convert.ToInt32(queue.Options.MessageTimeout.TotalMilliseconds),
                    HideClientNames      = queue.Options.HideClientNames,
                    ReceivedMessages     = queue.Info.ReceivedMessages,
                    SentMessages         = queue.Info.SentMessages,
                    Deliveries           = queue.Info.Deliveries,
                    NegativeAcks         = queue.Info.NegativeAcknowledge,
                    Acks                 = queue.Info.Acknowledges,
                    TimeoutMessages      = queue.Info.TimedOutMessages,
                    SavedMessages        = queue.Info.MessageSaved,
                    RemovedMessages      = queue.Info.MessageRemoved,
                    Errors               = queue.Info.ErrorCount,
                    LastMessageReceived  = queue.Info.GetLastMessageReceiveUnix(),
                    LastMessageSent      = queue.Info.GetLastMessageSendUnix(),
                    MessageLimit         = queue.Options.MessageLimit,
                    MessageSizeLimit     = queue.Options.MessageSizeLimit,
                    DelayBetweenMessages = queue.Options.DelayBetweenMessages
                });
            }

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

            message.ContentType = KnownContentTypes.QueueList;
            response.Serialize(list, _server.MessageContentSerializer);
            await client.SendAsync(response);
        }