コード例 #1
0
        /// <summary>
        /// Processes the client message which has multiple receivers (message by name or type)
        /// </summary>
        private async Task ProcessMultipleReceiverClientMessage(MqClient sender, List <MqClient> receivers, HorseMessage message)
        {
            if (receivers.Count < 1)
            {
                await sender.SendAsync(message.CreateResponse(HorseResultCode.NotFound));

                return;
            }

            foreach (MqClient receiver in receivers)
            {
                //check sending message authority
                foreach (IClientAuthorization authorization in _server.Authorizations)
                {
                    bool grant = await authorization.CanDirectMessage(sender, message, receiver);

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

                        return;
                    }
                }

                //send the message
                await receiver.SendAsync(message);
            }
        }
コード例 #2
0
        /// <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);
        }
コード例 #3
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));
        }
コード例 #4
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));
        }
コード例 #5
0
        /// <summary>
        /// Removes a channel with it's queues
        /// </summary>
        private async Task RemoveChannel(MqClient client, TmqMessage message)
        {
            if (_server.AdminAuthorization == null)
            {
                if (message.ResponseRequired)
                {
                    await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Unauthorized));
                }
                return;
            }

            Channel channel = _server.FindChannel(message.Target);

            if (channel == null)
            {
                await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.NotFound));

                return;
            }

            bool grant = await _server.AdminAuthorization.CanRemoveChannel(client, _server, channel);

            if (!grant)
            {
                if (message.ResponseRequired)
                {
                    await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Unauthorized));
                }

                return;
            }

            await _server.RemoveChannel(channel);
        }
コード例 #6
0
        /// <summary>
        /// Handles pushing a message into a queue
        /// </summary>
        private async Task HandlePush(MqClient client, TmqMessage message, ChannelQueue queue)
        {
            //check authority
            if (_server.Authorization != null)
            {
                bool grant = await _server.Authorization.CanMessageToQueue(client, queue, message);

                if (!grant)
                {
                    if (!string.IsNullOrEmpty(message.MessageId))
                    {
                        await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Unauthorized));
                    }
                    return;
                }
            }

            //prepare the message
            QueueMessage queueMessage = new QueueMessage(message);

            queueMessage.Source = client;

            //push the message
            PushResult result = await queue.Push(queueMessage, client);

            if (result == PushResult.StatusNotSupported)
            {
                await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Unacceptable));
            }
            else if (result == PushResult.LimitExceeded)
            {
                await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.LimitExceeded));
            }
        }
コード例 #7
0
        /// <summary>
        /// Removes a queue from a server
        /// </summary>
        private async Task RemoveQueue(MqClient client, HorseMessage message)
        {
            HorseQueue queue = _server.FindQueue(message.Target);

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

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

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

                    return;
                }
            }

            await _server.RemoveQueue(queue);

            if (message.WaitResponse)
            {
                await client.SendAsync(message.CreateResponse(HorseResultCode.Ok));
            }
        }
コード例 #8
0
ファイル: ClientMessageHandler.cs プロジェクト: ciker/twino
        /// <summary>
        /// Processes the client message which has multiple receivers (message by name or type)
        /// </summary>
        private async Task ProcessMultipleReceiverClientMessage(MqClient sender, List <MqClient> receivers, TmqMessage message)
        {
            if (receivers.Count < 1)
            {
                await sender.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.NotFound));

                return;
            }

            foreach (MqClient receiver in receivers)
            {
                //check sending message authority
                if (_server.Authorization != null)
                {
                    bool grant = await _server.Authorization.CanMessageToPeer(sender, message, receiver);

                    if (!grant)
                    {
                        await sender.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Unauthorized));

                        return;
                    }
                }

                //send the message
                await receiver.SendAsync(message);
            }
        }
コード例 #9
0
ファイル: ClientMessageHandler.cs プロジェクト: ciker/twino
        /// <summary>
        /// Processes the client message which has single receiver (message by unique id)
        /// </summary>
        private async Task ProcessSingleReceiverClientMessage(MqClient client, TmqMessage message)
        {
            //find the receiver
            MqClient other = _server.FindClient(message.Target);

            if (other == null)
            {
                await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.NotFound));

                return;
            }

            //check sending message authority
            if (_server.Authorization != null)
            {
                bool grant = await _server.Authorization.CanMessageToPeer(client, message, other);

                if (!grant)
                {
                    await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Unauthorized));

                    return;
                }
            }

            //send the message
            await other.SendAsync(message);
        }
コード例 #10
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);
        }
コード例 #11
0
        /// <summary>
        /// Finds the channel and sends the information
        /// </summary>
        private async Task GetChannelInformation(MqClient client, TmqMessage message)
        {
            if (_server.AdminAuthorization == null)
            {
                if (message.ResponseRequired)
                {
                    await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Unauthorized));
                }

                return;
            }

            Channel channel = _server.FindChannel(message.Target);

            if (channel == null)
            {
                await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.NotFound));

                return;
            }

            bool grant = await _server.AdminAuthorization.CanReceiveChannelInfo(client, channel);

            if (!grant)
            {
                if (message.ResponseRequired)
                {
                    await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Unauthorized));
                }

                return;
            }

            ChannelInformation information = new ChannelInformation
            {
                Name   = channel.Name,
                Queues = channel.QueuesClone.Select(x => x.Id).ToArray(),
                AllowMultipleQueues = channel.Options.AllowMultipleQueues,
                AllowedQueues       = channel.Options.AllowedQueues,
                OnlyFirstAcquirer   = channel.Options.SendOnlyFirstAcquirer,
                RequestAcknowledge  = channel.Options.RequestAcknowledge,
                AcknowledgeTimeout  = Convert.ToInt32(channel.Options.AcknowledgeTimeout.TotalMilliseconds),
                MessageTimeout      = Convert.ToInt32(channel.Options.MessageTimeout.TotalMilliseconds),
                WaitForAcknowledge  = channel.Options.WaitForAcknowledge,
                HideClientNames     = channel.Options.HideClientNames,
                QueueLimit          = channel.Options.QueueLimit,
                ClientLimit         = channel.Options.ClientLimit,
                DestroyWhenEmpty    = channel.Options.DestroyWhenEmpty,
                ActiveClients       = channel.ClientsCount()
            };

            TmqMessage response = message.CreateResponse();

            message.ContentType = KnownContentTypes.ChannelInformation;
            await response.SetJsonContent(information);

            await client.SendAsync(response);
        }
コード例 #12
0
        /// <summary>
        /// Finds and subscribes to the queue and sends response
        /// </summary>
        private async Task Subscribe(MqClient client, HorseMessage message)
        {
            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 (message.WaitResponse)
                {
                    await client.SendAsync(message.CreateResponse(HorseResultCode.NotFound));
                }

                return;
            }

            QueueClient found = queue.FindClient(client.UniqueId);

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

                return;
            }

            QueueSubscriptionResult result = await queue.AddClient(client);

            if (message.WaitResponse)
            {
                switch (result)
                {
                case QueueSubscriptionResult.Success:
                    await client.SendAsync(message.CreateResponse(HorseResultCode.Ok));

                    break;

                case QueueSubscriptionResult.Unauthorized:
                    await client.SendAsync(message.CreateResponse(HorseResultCode.Unauthorized));

                    break;

                case QueueSubscriptionResult.Full:
                    await client.SendAsync(message.CreateResponse(HorseResultCode.LimitExceeded));

                    break;
                }
            }
        }
コード例 #13
0
        /// <summary>
        /// Finds and joins to channel and sends response
        /// </summary>
        private async Task JoinChannel(MqClient client, TmqMessage message)
        {
            Channel channel = _server.FindChannel(message.Target);

            //if auto creation active, try to create channel
            if (channel == null && _server.Options.AutoChannelCreation)
            {
                channel = _server.FindOrCreateChannel(message.Target);
            }

            if (channel == null)
            {
                if (message.ResponseRequired)
                {
                    await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.NotFound));
                }

                return;
            }

            ChannelClient found = channel.FindClient(client.UniqueId);

            if (found != null)
            {
                if (message.ResponseRequired)
                {
                    await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Ok));
                }

                return;
            }

            ClientJoinResult result = await channel.AddClient(client);

            if (message.ResponseRequired)
            {
                switch (result)
                {
                case ClientJoinResult.Success:
                    await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Ok));

                    break;

                case ClientJoinResult.Unauthorized:
                    await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Unauthorized));

                    break;

                case ClientJoinResult.Full:
                    await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.LimitExceeded));

                    break;
                }
            }
        }
コード例 #14
0
        /// <summary>
        /// Removes a queue from a channel
        /// </summary>
        private async Task RemoveQueue(MqClient client, TmqMessage message)
        {
            if (_server.AdminAuthorization == null)
            {
                if (message.ResponseRequired)
                {
                    await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Unauthorized));
                }

                return;
            }

            Channel channel = _server.FindChannel(message.Target);

            if (channel == null)
            {
                await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.NotFound));

                return;
            }

            byte[] bytes = new byte[2];
            await message.Content.ReadAsync(bytes);

            ushort contentType = BitConverter.ToUInt16(bytes);

            ChannelQueue queue = channel.FindQueue(contentType);

            if (queue == null)
            {
                await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.NotFound));

                return;
            }

            bool grant = await _server.AdminAuthorization.CanRemoveQueue(client, queue);

            if (!grant)
            {
                if (message.ResponseRequired)
                {
                    await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Unauthorized));
                }

                return;
            }

            await channel.RemoveQueue(queue);

            if (message.ResponseRequired)
            {
                await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Ok));
            }
        }
コード例 #15
0
        /// <summary>
        /// Clears messages in a queue
        /// </summary>
        private async Task ClearMessages(MqClient client, HorseMessage message)
        {
            HorseQueue queue = _server.FindQueue(message.Target);

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

                return;
            }

            string prio      = message.FindHeader(HorseHeaders.PRIORITY_MESSAGES);
            string msgs      = message.FindHeader(HorseHeaders.MESSAGES);
            bool   clearPrio = !string.IsNullOrEmpty(prio) && prio.Equals("yes", StringComparison.InvariantCultureIgnoreCase);
            bool   clearMsgs = !string.IsNullOrEmpty(msgs) && msgs.Equals("yes", StringComparison.InvariantCultureIgnoreCase);

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

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

                    return;
                }
            }

            if (clearPrio && clearMsgs)
            {
                queue.ClearAllMessages();
            }
            else if (clearPrio)
            {
                queue.ClearHighPriorityMessages();
            }
            else if (clearMsgs)
            {
                queue.ClearRegularMessages();
            }

            //if creation successful, sends response
            if (message.WaitResponse)
            {
                await client.SendAsync(message.CreateResponse(HorseResultCode.Ok));
            }
        }
コード例 #16
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);
        }
コード例 #17
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);
        }
コード例 #18
0
ファイル: ClientMessageHandler.cs プロジェクト: ciker/twino
        public async Task Handle(MqClient client, TmqMessage message)
        {
            if (string.IsNullOrEmpty(message.Target))
            {
                return;
            }

            if (message.Target.StartsWith("@name:"))
            {
                List <MqClient> receivers = _server.FindClientByName(message.Target.Substring(6));
                if (receivers.Count > 0)
                {
                    if (message.FirstAcquirer)
                    {
                        MqClient first = receivers.FirstOrDefault();
                        receivers.Clear();
                        receivers.Add(first);
                    }

                    await ProcessMultipleReceiverClientMessage(client, receivers, message);
                }
                else if (message.ResponseRequired)
                {
                    await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.NotFound));
                }
            }
            else if (message.Target.StartsWith("@type:"))
            {
                List <MqClient> receivers = _server.FindClientByType(message.Target.Substring(6));
                if (receivers.Count > 0)
                {
                    if (message.FirstAcquirer)
                    {
                        MqClient first = receivers.FirstOrDefault();
                        receivers.Clear();
                        receivers.Add(first);
                    }

                    await ProcessMultipleReceiverClientMessage(client, receivers, message);
                }
                else if (message.ResponseRequired)
                {
                    await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.NotFound));
                }
            }
            else
            {
                await ProcessSingleReceiverClientMessage(client, message);
            }
        }
コード例 #19
0
        public async Task Handle(MqClient client, TmqMessage message)
        {
            //find channel and queue
            Channel channel = _server.FindChannel(message.Target);

            //if auto creation active, try to create channel
            if (channel == null && _server.Options.AutoChannelCreation)
            {
                channel = _server.FindOrCreateChannel(message.Target);
            }

            if (channel == null)
            {
                if (!string.IsNullOrEmpty(message.MessageId))
                {
                    await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.NotFound));
                }
                return;
            }

            ChannelQueue queue = channel.FindQueue(message.ContentType);

            //if auto creation active, try to create queue
            if (queue == null && _server.Options.AutoQueueCreation)
            {
                queue = await channel.FindOrCreateQueue(message.ContentType);
            }

            if (queue == null)
            {
                if (!string.IsNullOrEmpty(message.MessageId))
                {
                    await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.NotFound));
                }
                return;
            }

            //consumer is trying to pull from the queue
            //in false cases, we won't send any response, cuz client is pending only queue messages, not response messages
            if (message.Length == 0 && message.ResponseRequired)
            {
                await HandlePullRequest(client, message, channel, queue);
            }

            //message have a content, this is the real message from producer to the queue
            else
            {
                await HandlePush(client, message, queue);
            }
        }
コード例 #20
0
        public async Task Handle(MqClient client, HorseMessage message, bool fromNode)
        {
            if (string.IsNullOrEmpty(message.Target))
            {
                return;
            }

            if (message.Target.StartsWith("@name:"))
            {
                List <MqClient> receivers = _server.FindClientByName(message.Target.Substring(6));
                if (receivers.Count > 0)
                {
                    if (message.HighPriority && receivers.Count > 1)
                    {
                        MqClient first = receivers.FirstOrDefault();
                        receivers.Clear();
                        receivers.Add(first);
                    }

                    await ProcessMultipleReceiverClientMessage(client, receivers, message);
                }
                else if (message.WaitResponse)
                {
                    await client.SendAsync(message.CreateResponse(HorseResultCode.NotFound));
                }
            }
            else if (message.Target.StartsWith("@type:"))
            {
                List <MqClient> receivers = _server.FindClientByType(message.Target.Substring(6));
                if (receivers.Count > 0)
                {
                    if (message.HighPriority)
                    {
                        MqClient first = receivers.FirstOrDefault();
                        receivers.Clear();
                        receivers.Add(first);
                    }

                    await ProcessMultipleReceiverClientMessage(client, receivers, message);
                }
                else if (message.WaitResponse)
                {
                    await client.SendAsync(message.CreateResponse(HorseResultCode.NotFound));
                }
            }
            else
            {
                await ProcessSingleReceiverClientMessage(client, message);
            }
        }
コード例 #21
0
 public Task Handle(MqClient client, HorseMessage message, bool fromNode)
 {
     try
     {
         return(HandleUnsafe(client, message));
     }
     catch (OperationCanceledException)
     {
         return(client.SendAsync(message.CreateResponse(HorseResultCode.LimitExceeded)));
     }
     catch (DuplicateNameException)
     {
         return(client.SendAsync(message.CreateResponse(HorseResultCode.Duplicate)));
     }
 }
コード例 #22
0
 public async Task Handle(MqClient client, TmqMessage message)
 {
     try
     {
         await HandleUnsafe(client, message);
     }
     catch (OperationCanceledException)
     {
         await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.LimitExceeded));
     }
     catch (DuplicateNameException)
     {
         await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Duplicate));
     }
 }
コード例 #23
0
        /// <summary>
        /// Routes message to it's type handler
        /// </summary>
        private async Task RouteToHandler(MqClient mc, TmqMessage message, IConnectionInfo info)
        {
            switch (message.Type)
            {
            //client sends a queue message in a channel
            case MessageType.Channel:
                await _instanceHandler.Handle(mc, message);

                await _channelHandler.Handle(mc, message);

                break;

            //clients sends a message to another client
            case MessageType.Client:
                await _instanceHandler.Handle(mc, message);

                await _clientHandler.Handle(mc, message);

                break;

            //client sends an acknowledge message of a message
            case MessageType.Acknowledge:
                await _instanceHandler.Handle(mc, message);

                await _acknowledgeHandler.Handle(mc, message);

                break;

            //client sends a response message for a message
            case MessageType.Response:
                await _instanceHandler.Handle(mc, message);

                await _responseHandler.Handle(mc, message);

                break;

            //client sends a message to the server
            //this message may be join, header, info, some another server message
            case MessageType.Server:
                await _serverHandler.Handle(mc, message);

                break;

            //if client sends a ping message, response with pong
            case MessageType.Ping:
                await mc.SendAsync(PredefinedMessages.PONG);

                break;

            //client sends PONG message
            case MessageType.Pong:
                mc.KeepAlive();
                break;

            //close the client's connection
            case MessageType.Terminate:
                mc.Disconnect();
                break;
            }
        }
コード例 #24
0
        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}");
            }
        }
コード例 #25
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);
        }
コード例 #26
0
        /// <summary>
        /// Creates new binding for a router
        /// </summary>
        private async Task CreateRouterBinding(MqClient client, HorseMessage message)
        {
            IRouter router = _server.FindRouter(message.Target);

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

                return;
            }

            BindingInformation info = message.Deserialize <BindingInformation>(new NewtonsoftContentSerializer());

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

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

                    return;
                }
            }

            switch (info.BindingType)
            {
            case BindingType.Direct:
                router.AddBinding(new DirectBinding(info.Name, info.Target, info.ContentType, info.Priority, info.Interaction, info.Method));
                break;

            case BindingType.Queue:
                router.AddBinding(new QueueBinding(info.Name, info.Target, info.Priority, info.Interaction));
                break;

            case BindingType.Http:
                router.AddBinding(new HttpBinding(info.Name, info.Target, (HttpBindingMethod)(info.ContentType ?? 0), info.Priority, info.Interaction));
                break;

            case BindingType.Topic:
                router.AddBinding(new TopicBinding(info.Name, info.Target, info.ContentType ?? 0, info.Priority, info.Interaction, info.Method));
                break;
            }

            await client.SendAsync(message.CreateResponse(HorseResultCode.Ok));
        }
コード例 #27
0
        private static async Task SendResponse(MqClient client, HorseMessage message, bool successful)
        {
            ushort       contentType = successful ? (ushort)HorseResultCode.Ok : (ushort)HorseResultCode.Failed;
            HorseMessage response    = new HorseMessage(MessageType.Response, client.UniqueId, contentType);

            response.SetMessageId(message.MessageId);
            await client.SendAsync(response);
        }
コード例 #28
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);
        }
コード例 #29
0
        /// <summary>
        /// Removes a router with it's bindings
        /// </summary>
        private async Task RemoveRouterBinding(MqClient client, HorseMessage message)
        {
            IRouter router = _server.FindRouter(message.Target);

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

                return;
            }

            string name = message.FindHeader(HorseHeaders.BINDING_NAME);

            if (string.IsNullOrEmpty(name))
            {
                await client.SendAsync(message.CreateResponse(HorseResultCode.NotFound));

                return;
            }

            Binding[] bindings = router.GetBindings();
            Binding   binding  = bindings.FirstOrDefault(x => x.Name == name);

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

                return;
            }

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

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

                    return;
                }
            }

            router.RemoveBinding(binding);
            await client.SendAsync(message.CreateResponse(HorseResultCode.Ok));
        }
コード例 #30
0
        /// <summary>
        /// Gets all connected clients
        /// </summary>
        public async Task GetClients(MqClient client, TmqMessage message)
        {
            if (_server.AdminAuthorization == null)
            {
                if (message.ResponseRequired)
                {
                    await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Unauthorized));
                }

                return;
            }

            bool grant = await _server.AdminAuthorization.CanReceiveClients(client);

            if (!grant)
            {
                if (message.ResponseRequired)
                {
                    await client.SendAsync(MessageBuilder.ResponseStatus(message, KnownContentTypes.Unauthorized));
                }

                return;
            }

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

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

            TmqMessage response = message.CreateResponse();

            message.ContentType = KnownContentTypes.ClientList;
            await response.SetJsonContent(list);

            await client.SendAsync(response);
        }