/// <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)); }
/// <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)); }
/// <summary> /// Pushes a message to a queue /// </summary> public async Task <HorseResult> Push(string queue, MemoryStream content, string messageId, bool waitAcknowledge, IEnumerable <KeyValuePair <string, string> > messageHeaders = null) { HorseMessage message = new HorseMessage(MessageType.QueueMessage, queue, 0); message.Content = content; message.WaitResponse = waitAcknowledge; if (!string.IsNullOrEmpty(messageId)) { message.SetMessageId(messageId); } if (messageHeaders != null) { foreach (KeyValuePair <string, string> pair in messageHeaders) { message.AddHeader(pair.Key, pair.Value); } } if (string.IsNullOrEmpty(message.MessageId) && waitAcknowledge) { message.SetMessageId(_client.UniqueIdGenerator.Create()); } return(await _client.WaitResponse(message, waitAcknowledge)); }
/// <summary> /// Publishes a byte array data to a router /// </summary> public async Task <HorseResult> Publish(string routerName, byte[] data, string messageId = null, bool waitForAcknowledge = false, ushort contentType = 0, IEnumerable <KeyValuePair <string, string> > messageHeaders = null) { HorseMessage msg = new HorseMessage(MessageType.Router, routerName, contentType); if (!string.IsNullOrEmpty(messageId)) { msg.SetMessageId(messageId); } else { msg.SetMessageId(_client.UniqueIdGenerator.Create()); } msg.WaitResponse = waitForAcknowledge; msg.Content = new MemoryStream(data); if (messageHeaders != null) { foreach (KeyValuePair <string, string> pair in messageHeaders) { msg.AddHeader(pair.Key, pair.Value); } } return(await _client.WaitResponse(msg, waitForAcknowledge)); }
/// <summary> /// Clears messages in a queue. /// Required administration permission. /// If server has no implementation for administration authorization, request is not allowed. /// </summary> public Task <HorseResult> ClearMessages(string queue, bool clearPriorityMessages, bool clearMessages) { if (!clearPriorityMessages && !clearMessages) { return(Task.FromResult(HorseResult.Failed())); } HorseMessage message = new HorseMessage(); message.Type = MessageType.Server; message.ContentType = KnownContentTypes.ClearMessages; message.SetTarget(queue); message.WaitResponse = true; message.SetMessageId(_client.UniqueIdGenerator.Create()); message.AddHeader(HorseHeaders.QUEUE_NAME, queue); if (clearPriorityMessages) { message.AddHeader(HorseHeaders.PRIORITY_MESSAGES, "yes"); } if (clearMessages) { message.AddHeader(HorseHeaders.MESSAGES, "yes"); } return(_client.WaitResponse(message, true)); }
/// <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)); }
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); }
/// <summary> /// Fills binary data to the queue /// </summary> public PushResult FillData(IEnumerable <byte[]> items, bool createAsSaved, bool highPriority) { 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 (byte[] item in items) { HorseMessage message = new HorseMessage(MessageType.QueueMessage, _queue.Name); message.HighPriority = highPriority; message.WaitResponse = _queue.Options.Acknowledge != QueueAckDecision.None; if (_queue.Options.UseMessageId) { message.SetMessageId(_queue.Server.MessageIdGenerator.Create()); } message.Content = new MemoryStream(item); message.Content.Position = 0; message.CalculateLengths(); QueueMessage qm = new QueueMessage(message, createAsSaved); if (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_DATA", e, $"QueueName:{_queue.Name}"); return(PushResult.Error); } }
/// <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); } }
/// <summary> /// Creates new Pull Request response message with no content /// </summary> internal static HorseMessage CreateNoContentPullResponse(HorseMessage request, string reason) { HorseMessage msg = new HorseMessage(MessageType.QueueMessage); msg.SetMessageId(request.MessageId); msg.SetTarget(request.Target); msg.ContentType = request.ContentType; msg.AddHeader(HorseHeaders.REQUEST_ID, request.MessageId); msg.AddHeader(HorseHeaders.NO_CONTENT, reason); return(msg); }
/// <summary> /// Removes a router. /// Returns success result if router doesn't exists. /// </summary> public async Task <HorseResult> Remove(string name) { HorseMessage message = new HorseMessage(); message.Type = MessageType.Server; message.ContentType = KnownContentTypes.RemoveRouter; message.SetTarget(name); message.WaitResponse = true; message.SetMessageId(_client.UniqueIdGenerator.Create()); return(await _client.WaitResponse(message, true)); }
/// <summary> /// Creates new router. /// Returns success result if router already exists. /// </summary> public async Task <HorseResult> Create(string name, RouteMethod method) { HorseMessage message = new HorseMessage(); message.Type = MessageType.Server; message.ContentType = KnownContentTypes.CreateRouter; message.SetTarget(name); message.WaitResponse = true; message.AddHeader(HorseHeaders.ROUTE_METHOD, Convert.ToInt32(method).ToString()); message.SetMessageId(_client.UniqueIdGenerator.Create()); return(await _client.WaitResponse(message, true)); }
/// <summary> /// Remove a binding from a router /// </summary> public async Task <HorseResult> RemoveBinding(string routerName, string bindingName) { HorseMessage message = new HorseMessage(); message.Type = MessageType.Server; message.ContentType = KnownContentTypes.RemoveBinding; message.SetTarget(routerName); message.WaitResponse = true; message.SetMessageId(_client.UniqueIdGenerator.Create()); message.AddHeader(HorseHeaders.BINDING_NAME, bindingName); return(await _client.WaitResponse(message, true)); }
/// <summary> /// Finds all queues in server /// </summary> public async Task <HorseModelResult <List <QueueInformation> > > List(string filter = null) { HorseMessage message = new HorseMessage(); message.Type = MessageType.Server; message.SetMessageId(_client.UniqueIdGenerator.Create()); message.ContentType = KnownContentTypes.QueueList; message.AddHeader(HorseHeaders.FILTER, filter); return(await _client.SendAndGetJson <List <QueueInformation> >(message)); }
/// <summary> /// Request a message from Pull queue /// </summary> public async Task <PullContainer> Pull(PullRequest request, Func <int, HorseMessage, Task> actionForEachMessage = null) { HorseMessage message = new HorseMessage(MessageType.QueuePullRequest, request.Queue); message.SetMessageId(_client.UniqueIdGenerator.Create()); message.AddHeader(HorseHeaders.COUNT, request.Count); if (request.ClearAfter == ClearDecision.AllMessages) { message.AddHeader(HorseHeaders.CLEAR, "all"); } else if (request.ClearAfter == ClearDecision.PriorityMessages) { message.AddHeader(HorseHeaders.CLEAR, "High-Priority"); } else if (request.ClearAfter == ClearDecision.Messages) { message.AddHeader(HorseHeaders.CLEAR, "Default-Priority"); } if (request.GetQueueMessageCounts) { message.AddHeader(HorseHeaders.INFO, "yes"); } if (request.Order == MessageOrder.LIFO) { message.AddHeader(HorseHeaders.ORDER, HorseHeaders.LIFO); } foreach (KeyValuePair <string, string> pair in request.RequestHeaders) { message.AddHeader(pair.Key, pair.Value); } PullContainer container = new PullContainer(message.MessageId, request.Count, actionForEachMessage); lock (PullContainers) PullContainers.Add(message.MessageId, container); HorseResult sent = await _client.SendAsync(message); if (sent.Code != HorseResultCode.Ok) { lock (PullContainers) PullContainers.Remove(message.MessageId); container.Complete("Error"); } return(await container.GetAwaitableTask()); }
/// <summary> /// Gets all consumers of queue /// </summary> public async Task <HorseModelResult <List <ClientInformation> > > GetConsumers(string queue) { HorseMessage message = new HorseMessage(); message.Type = MessageType.Server; message.SetTarget(queue); message.ContentType = KnownContentTypes.QueueConsumers; message.SetMessageId(_client.UniqueIdGenerator.Create()); message.AddHeader(HorseHeaders.QUEUE_NAME, queue); return(await _client.SendAndGetJson <List <ClientInformation> >(message)); }
/// <summary> /// Creates new response message, with no content, of the message. /// </summary> public static HorseMessage StatusResponse(HorseMessage request, ushort status) { HorseMessage response = new HorseMessage(); response.Type = MessageType.Response; response.SetMessageId(request.MessageId); response.ContentType = status; response.SetTarget(request.Type == MessageType.QueueMessage ? request.Target : request.Source); return(response); }
/// <summary> /// Unsubscribes from a queue /// </summary> public async Task <HorseResult> Unsubscribe(string queue, bool verifyResponse) { HorseMessage message = new HorseMessage(); message.Type = MessageType.Server; message.ContentType = KnownContentTypes.Unsubscribe; message.SetTarget(queue); message.WaitResponse = verifyResponse; if (verifyResponse) { message.SetMessageId(_client.UniqueIdGenerator.Create()); } return(await _client.WaitResponse(message, verifyResponse)); }
/// <summary> /// Updates queue options /// </summary> public async Task <HorseResult> SetOptions(string queue, Action <QueueOptions> optionsAction) { HorseMessage message = new HorseMessage(); message.Type = MessageType.Server; message.ContentType = KnownContentTypes.UpdateQueue; message.SetTarget(queue); message.WaitResponse = true; message.SetMessageId(_client.UniqueIdGenerator.Create()); message.AddHeader(HorseHeaders.QUEUE_NAME, queue); QueueOptions options = new QueueOptions(); optionsAction(options); message.Content = new MemoryStream(); await JsonSerializer.SerializeAsync(message.Content, options); return(await _client.WaitResponse(message, true)); }
/// <summary> /// Pushes clones of the message to cc queues /// </summary> private async Task PushOtherQueues(MqClient client, HorseMessage clone, List <string> ccList, List <KeyValuePair <string, string> > additionalHeaders) { for (int i = 0; i < ccList.Count; i++) { string cc = ccList[i]; string[] split = cc.Split(';'); if (split.Length < 1) { continue; } string queueName = split[0].Trim(); string messageId = null; if (split.Length > 1) { messageId = split[1]; } HorseQueue queue = await FindQueue(null, queueName, clone); if (queue == null) { continue; } HorseMessage msg = clone; if (i < ccList.Count - 1) { clone = clone.Clone(false, true, _server.MessageIdGenerator.Create(), additionalHeaders); } if (!string.IsNullOrEmpty(messageId)) { msg.SetMessageId(messageId); } _ = HandlePush(client, msg, queue, false); } }
/// <summary> /// Creates new queue in server /// </summary> public async Task <HorseResult> Create(string queue, Action <QueueOptions> optionsAction, string deliveryHandlerHeader = null, IEnumerable <KeyValuePair <string, string> > additionalHeaders = null) { HorseMessage message = new HorseMessage(); message.Type = MessageType.Server; message.ContentType = KnownContentTypes.CreateQueue; message.SetTarget(queue); message.WaitResponse = true; message.AddHeader(HorseHeaders.QUEUE_NAME, queue); if (!string.IsNullOrEmpty(deliveryHandlerHeader)) { message.AddHeader(HorseHeaders.DELIVERY_HANDLER, deliveryHandlerHeader); } if (additionalHeaders != null) { foreach (KeyValuePair <string, string> pair in additionalHeaders) { message.AddHeader(pair.Key, pair.Value); } } if (optionsAction != null) { QueueOptions options = new QueueOptions(); optionsAction(options); message.Content = new MemoryStream(); await JsonSerializer.SerializeAsync(message.Content, options); } message.SetMessageId(_client.UniqueIdGenerator.Create()); return(await _client.WaitResponse(message, true)); }
/// <summary> /// Subscribes to a queue /// </summary> public async Task <HorseResult> Subscribe(string queue, bool verifyResponse, IEnumerable <KeyValuePair <string, string> > headers = null) { HorseMessage message = new HorseMessage(); message.Type = MessageType.Server; message.ContentType = KnownContentTypes.Subscribe; message.SetTarget(queue); message.WaitResponse = verifyResponse; if (headers != null) { foreach (KeyValuePair <string, string> header in headers) { message.AddHeader(header.Key, header.Value); } } if (verifyResponse) { message.SetMessageId(_client.UniqueIdGenerator.Create()); } return(await _client.WaitResponse(message, verifyResponse)); }
public async Task ReloadAfterRestart() { await Task.Delay(500); ConfigurationFactory.Destroy(); RedeliveryService service = new RedeliveryService("data/reload-test.tdb.delivery"); await service.Load(); await service.Clear(); await service.Set("id", 4); await service.Close(); if (System.IO.File.Exists("data/config.json")) { System.IO.File.Delete("data/config.json"); } if (System.IO.File.Exists("data/reload-test.tdb")) { System.IO.File.Delete("data/reload-test.tdb"); } if (System.IO.File.Exists("data/reload-test.tdb.delivery")) { System.IO.File.Delete("data/reload-test.tdb.delivery"); } HorseServer server = new HorseServer(); PersistentDeliveryHandler handler = null; Func <DeliveryHandlerBuilder, Task <IMessageDeliveryHandler> > fac = async builder => { DatabaseOptions options = new DatabaseOptions { Filename = "data/reload-test.tdb", InstantFlush = true, CreateBackupOnShrink = false, ShrinkInterval = TimeSpan.FromSeconds(60) }; handler = (PersistentDeliveryHandler)await builder.CreatePersistentDeliveryHandler(o => { return(new PersistentDeliveryHandler(builder.Queue, options, DeleteWhen.AfterSend, ProducerAckDecision.None, true)); }); return(handler); }; HorseMq mq = server.UseHorseMq(cfg => cfg .AddPersistentQueues(q => q.KeepLastBackup()) .UseDeliveryHandler(fac)); HorseQueue queue = await mq.CreateQueue("reload-test", o => o.Status = QueueStatus.Push); HorseMessage msg = new HorseMessage(MessageType.QueueMessage, "reload-test"); msg.SetMessageId("id"); msg.SetStringContent("Hello, World!"); await queue.Push(msg); QueueMessage queueMsg = queue.Messages.FirstOrDefault(); await handler.BeginSend(queue, queueMsg); await handler.RedeliveryService.Close(); ConfigurationFactory.Destroy(); mq = server.UseHorseMq(cfg => cfg .AddPersistentQueues(q => q.KeepLastBackup()) .UseDeliveryHandler(fac)); await mq.LoadPersistentQueues(); HorseQueue queue2 = mq.FindQueue("reload-test"); Assert.NotNull(queue2); Assert.NotEmpty(queue2.Messages); QueueMessage loadedMsg = queue2.Messages.FirstOrDefault(); Assert.NotNull(loadedMsg); Assert.Equal(1, loadedMsg.DeliveryCount); }
public async Task InPersistentHandler() { ConfigurationFactory.Destroy(); PersistentDeliveryHandler handler = null; HorseServer server = new HorseServer(); HorseMq mq = server.UseHorseMq(cfg => cfg .AddPersistentQueues(q => q.KeepLastBackup()) .UseDeliveryHandler(async builder => { DatabaseOptions options = new DatabaseOptions { Filename = "redelivery-test.tdb", InstantFlush = true, CreateBackupOnShrink = false, ShrinkInterval = TimeSpan.FromSeconds(60) }; handler = new PersistentDeliveryHandler(builder.Queue, options, DeleteWhen.AfterSend, ProducerAckDecision.None, true); await handler.Initialize(); return(handler); })); HorseQueue queue = await mq.CreateQueue("test"); HorseMessage message = new HorseMessage(MessageType.QueueMessage, "test"); message.SetMessageId("id"); message.SetStringContent("Hello, World!"); QueueMessage queueMessage = new QueueMessage(message); await handler.BeginSend(queue, queueMessage); List <KeyValuePair <string, int> > deliveries = handler.RedeliveryService.GetDeliveries(); Assert.Single(deliveries); Assert.Equal("id", deliveries[0].Key); Assert.Equal(1, deliveries[0].Value); string header = message.FindHeader(HorseHeaders.DELIVERY); Assert.Null(header); await handler.BeginSend(queue, queueMessage); deliveries = handler.RedeliveryService.GetDeliveries(); Assert.Single(deliveries); Assert.Equal("id", deliveries[0].Key); Assert.Equal(2, deliveries[0].Value); header = message.FindHeader(HorseHeaders.DELIVERY); Assert.NotNull(header); Assert.Equal(2, Convert.ToInt32(header)); queueMessage.MarkAsSent(); await handler.EndSend(queue, queueMessage); deliveries = handler.RedeliveryService.GetDeliveries(); Assert.Empty(deliveries); }