예제 #1
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));
        }
예제 #2
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));
            }
        }
예제 #3
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));
        }
예제 #4
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);
        }
예제 #5
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);
            }
        }
예제 #6
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);
        }
예제 #7
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;
                }
            }
        }
예제 #8
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));
            }
        }
예제 #9
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);
        }
예제 #10
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);
        }
예제 #11
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);
            }
        }
예제 #12
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)));
     }
 }
예제 #13
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);
        }
        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}");
            }
        }
예제 #15
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));
        }
예제 #16
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);
        }
예제 #17
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));
        }
예제 #18
0
        /// <summary>
        /// Creates new queue and sends response
        /// </summary>
        private async Task UpdateQueue(MqClient client, HorseMessage message)
        {
            NetworkOptionsBuilder builder = await System.Text.Json.JsonSerializer.DeserializeAsync <NetworkOptionsBuilder>(message.Content);

            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.CanUpdateQueueOptions(client, queue, builder);

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

                    return;
                }
            }

            builder.ApplyToQueue(queue.Options);
            if (builder.Status.HasValue)
            {
                await queue.SetStatus(builder.Status.Value);
            }

            _server.OnQueueUpdated.Trigger(queue);

            //if creation successful, sends response
            if (message.WaitResponse)
            {
                await client.SendAsync(message.CreateResponse(HorseResultCode.Ok));
            }
        }
예제 #19
0
        /// <summary>
        /// Unsubscribes from the queue and sends response
        /// </summary>
        private async Task Unsubscribe(MqClient client, HorseMessage message)
        {
            HorseQueue queue = _server.FindQueue(message.Target);

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

                return;
            }

            bool success = await queue.RemoveClient(client);

            if (message.WaitResponse)
            {
                await client.SendAsync(message.CreateResponse(success ? HorseResultCode.Ok : HorseResultCode.NotFound));
            }
        }
예제 #20
0
        /// <summary>
        /// Handles pushing a message into a queue
        /// </summary>
        private async Task HandlePush(MqClient client, HorseMessage message, HorseQueue queue, bool answerSender)
        {
            //check authority
            foreach (IClientAuthorization authorization in _server.Authorizations)
            {
                bool grant = await authorization.CanMessageToQueue(client, queue, message);

                if (!grant)
                {
                    if (answerSender && !string.IsNullOrEmpty(message.MessageId))
                    {
                        await client.SendAsync(message.CreateResponse(HorseResultCode.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)
            {
                if (answerSender)
                {
                    await client.SendAsync(message.CreateResponse(HorseResultCode.Unauthorized));
                }
            }
            else if (result == PushResult.LimitExceeded)
            {
                if (answerSender)
                {
                    await client.SendAsync(message.CreateResponse(HorseResultCode.LimitExceeded));
                }
            }
        }
예제 #21
0
        /// <summary>
        /// Sends negative ack or failed response if client is pending ack or response
        /// </summary>
        private static Task SendResponse(RouterPublishResult result, MqClient client, HorseMessage message)
        {
            if (result == RouterPublishResult.OkAndWillBeRespond)
            {
                return(Task.CompletedTask);
            }

            bool positive = result == RouterPublishResult.OkWillNotRespond;

            if (message.WaitResponse)
            {
                HorseMessage response = positive
                                            ? message.CreateAcknowledge()
                                            : message.CreateResponse(HorseResultCode.NotFound);

                return(client.SendAsync(response));
            }

            return(Task.CompletedTask);
        }
예제 #22
0
        private async Task <HorseQueue> FindQueue(MqClient client, string name, HorseMessage message)
        {
            HorseQueue queue = _server.FindQueue(name);

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

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

                return(null);
            }

            return(queue);
        }
예제 #23
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);
                }
            }
        }
예제 #24
0
        public async Task <PullResult> Pull(QueueClient client, HorseMessage request)
        {
            QueueMessage message = _queue.FindNextMessage();

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

                return(PullResult.Empty);
            }

            if (message.CurrentDeliveryReceivers.Count > 0)
            {
                message.CurrentDeliveryReceivers.Clear();
            }

            ProcessingMessage = message;

            message.Decision = await _queue.DeliveryHandler.BeginSend(_queue, message);

            if (!await _queue.ApplyDecision(message.Decision, message))
            {
                return(PullResult.Success);
            }

            //call before send and check decision
            message.Decision = await _queue.DeliveryHandler.CanConsumerReceive(_queue, message, client.Client);

            if (!await _queue.ApplyDecision(message.Decision, message))
            {
                return(PullResult.Success);
            }

            //create delivery object
            MessageDelivery delivery = new MessageDelivery(message, client);

            //change to response message, send, change back to queue message
            message.Message.SetMessageId(request.MessageId);
            bool sent = await client.Client.SendAsync(message.Message);

            if (sent)
            {
                delivery.MarkAsSent();

                //do after send operations for per message
                _queue.Info.AddDelivery();
                message.Decision = await _queue.DeliveryHandler.ConsumerReceived(_queue, delivery, client.Client);

                //after all sending operations completed, calls implementation send completed method and complete the operation
                _queue.Info.AddMessageSend();

                if (!await _queue.ApplyDecision(message.Decision, message))
                {
                    return(PullResult.Success);
                }
            }
            else
            {
                message.Decision = await _queue.DeliveryHandler.ConsumerReceiveFailed(_queue, delivery, client.Client);

                if (!await _queue.ApplyDecision(message.Decision, message))
                {
                    return(PullResult.Success);
                }
            }

            message.Decision = await _queue.DeliveryHandler.EndSend(_queue, message);

            await _queue.ApplyDecision(message.Decision, message);

            return(PullResult.Success);
        }
예제 #25
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);
        }
예제 #26
0
        /// <summary>
        /// Creates new queue and sends response
        /// </summary>
        private async Task CreateQueue(MqClient client, HorseMessage message)
        {
            NetworkOptionsBuilder builder = null;

            if (message.Length > 0)
            {
                builder = await System.Text.Json.JsonSerializer.DeserializeAsync <NetworkOptionsBuilder>(message.Content);
            }

            HorseQueue queue = _server.FindQueue(message.Target);

            //if queue exists, we can't create. return duplicate response.
            if (queue != null)
            {
                if (message.WaitResponse)
                {
                    await client.SendAsync(message.CreateResponse(HorseResultCode.Duplicate));
                }

                return;
            }

            //check authority if client can create queue
            foreach (IClientAuthorization authorization in _server.Authorizations)
            {
                bool grant = await authorization.CanCreateQueue(client, message.Target, builder);

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

                    return;
                }
            }

            //creates new queue
            QueueOptions options = QueueOptions.CloneFrom(_server.Options);

            if (builder != null)
            {
                builder.ApplyToQueue(options);
            }

            queue = await _server.CreateQueue(message.Target, options, message, _server.DeliveryHandlerFactory, true, false);

            //if creation successful, sends response
            if (message.WaitResponse)
            {
                if (queue != null)
                {
                    await client.SendAsync(message.CreateResponse(HorseResultCode.Ok));
                }
                else
                {
                    await client.SendAsync(message.CreateResponse(HorseResultCode.Failed));
                }
            }
        }