public Task Route(InboundBrokeredMessage inboundBrokeredMessage, TransactionContext transactionContext, ReplyToRoutingContext destinationRouterContext) { if (destinationRouterContext is null) { //TODO: log return(Task.CompletedTask); } try { var outbound = new OutboundBrokeredMessage(_messageIdGenerator?.GenerateId(inboundBrokeredMessage.Body).ToString(), inboundBrokeredMessage.Body, (IDictionary <string, object>)inboundBrokeredMessage.MessageContext, destinationRouterContext?.DestinationPath, inboundBrokeredMessage.BodyConverter); outbound.MessageContext[MessageContext.ReplyToGroupId] = destinationRouterContext.ReplyToGroupId; return(_router.Route(outbound, transactionContext)); } catch (Exception e) { throw new ReplyToRoutingExceptions(destinationRouterContext, e); } }
public Task SendToOutbox(OutboundBrokeredMessage outboundBrokeredMessage, TransactionContext transactionContext, CancellationToken cancellationToken = default) { Guid transactionId = Guid.NewGuid(); if (transactionContext != null) { transactionContext.Container.TryGet <IPersistanceTransaction>(out var transaction); transactionId = transaction?.TransactionId ?? transactionId; } var outboxMessage = new OutboxMessage { MessageId = outboundBrokeredMessage.MessageId, MessageContext = JsonConvert.SerializeObject(outboundBrokeredMessage.MessageContext), Destination = outboundBrokeredMessage.Destination, MessageBody = outboundBrokeredMessage.Stringify(), MessageContentType = outboundBrokeredMessage.ContentType, SentToOutboxAtUtc = DateTime.UtcNow, ProcessedFromOutboxAtUtc = null, BatchId = transactionId }; _logger.LogTrace($"Outbox message created for message with id: '{outboxMessage.MessageId}'"); if (!_outbox.TryAdd(outboxMessage.MessageId, outboxMessage)) { var error = $"Unable to add brokered message with id: '{outboxMessage.MessageId}' to the in memory outbox."; _logger.LogError(error); throw new InvalidOperationException(error); } _logger.LogTrace($"Outbox message with id: '{outboxMessage.MessageId}' added to the in memory outbox."); return(Task.CompletedTask); }
public static Message AsAzureServiceBusMessage(this OutboundBrokeredMessage brokeredMessage) { var message = new Message(brokeredMessage.Body) { MessageId = string.IsNullOrWhiteSpace(brokeredMessage.MessageId) ? Guid.NewGuid().ToString() : brokeredMessage.MessageId, CorrelationId = brokeredMessage.CorrelationId, ContentType = brokeredMessage.ContentType, Label = brokeredMessage.GetSubject(), ReplyTo = brokeredMessage.GetReplyToAddress(), ReplyToSessionId = brokeredMessage.GetReplyToGroupId(), SessionId = brokeredMessage.GetGroupId(), PartitionKey = brokeredMessage.GetPartitionKey(), ViaPartitionKey = brokeredMessage.GetViaPartitionKey(), To = brokeredMessage.GetToAddress() } .WithUserProperties(brokeredMessage.MessageContext); if (brokeredMessage.GetTimeToLive() != null) { message.TimeToLive = brokeredMessage.GetTimeToLive().Value; } if (brokeredMessage.GetScheduledEnqueueTimeUtc() != null) { message.ScheduledEnqueueTimeUtc = brokeredMessage.GetScheduledEnqueueTimeUtc().Value; } return(message); }
public static Message AsAzureServiceBusMessage(this OutboundBrokeredMessage brokeredMessage) { var message = new Message(brokeredMessage.Body) { CorrelationId = brokeredMessage.GetCorrelationId(), ContentType = brokeredMessage.GetContentType(), Label = brokeredMessage.GetSubject(), ReplyTo = brokeredMessage.GetReplyToAddress(), ReplyToSessionId = brokeredMessage.GetReplyToGroupId(), SessionId = brokeredMessage.GetGroupId(), PartitionKey = brokeredMessage.GetPartitionKey(), ViaPartitionKey = brokeredMessage.GetViaPartitionKey(), To = brokeredMessage.GetToAddress() } .WithHashedBodyMessageId(brokeredMessage.MessageId) .WithUserProperties(brokeredMessage.ApplicationProperties); if (brokeredMessage.GetTimeToLive() != null) { message.TimeToLive = brokeredMessage.GetTimeToLive().Value; } if (brokeredMessage.GetScheduledEnqueueTimeUtc() != null) { message.ScheduledEnqueueTimeUtc = brokeredMessage.GetScheduledEnqueueTimeUtc().Value; } return(message); }
/// <summary> /// Routes an <see cref="OutboundBrokeredMessage"/> to the receiver via the message broker infrastructure. /// </summary> /// <param name="outboundBrokeredMessage">The outbound brokered message to be routed to the destination receiver</param> /// <param name="transactionContext">The contextual transaction information to be used while routing the message to its destination</param> /// <returns>An awaitable <see cref="Task"/></returns> public Task Route(OutboundBrokeredMessage outboundBrokeredMessage, TransactionContext transactionContext) { if (string.IsNullOrWhiteSpace(outboundBrokeredMessage.Destination)) { throw new ArgumentNullException(nameof(outboundBrokeredMessage.Destination), $"Unable to route message with no destination path specified"); } return(_brokeredMessageInfrastructureDispatcher.Dispatch(outboundBrokeredMessage, transactionContext)); }
public async Task SendToOutbox(OutboundBrokeredMessage outboundBrokeredMessage, TransactionContext transactionContext) { var outbox = _context.Set <OutboxMessage>(); await SendToOutbox(outbox, outboundBrokeredMessage, transactionContext); await _context.SaveChangesAsync(); _logger.LogTrace($"Outbox message added to outbox. Id: '{outboundBrokeredMessage.MessageId}'"); }
public static object GetApplicationPropertyByKey(this OutboundBrokeredMessage outboundBrokeredMessage, string key) { if (outboundBrokeredMessage.ApplicationProperties.TryGetValue(key, out var output)) { return(output); } else { return(null); } }
public Task Dispatch(OutboundBrokeredMessage brokeredMessage, TransactionContext transactionContext) { if (brokeredMessage == null) { throw new ArgumentNullException(nameof(brokeredMessage), $"An outgoing message is required."); } if (string.IsNullOrWhiteSpace(brokeredMessage.Destination)) { throw new ArgumentNullException(nameof(brokeredMessage.Destination), $"A destination is required."); } return(Dispatch(new[] { brokeredMessage }, transactionContext)); }
/// <summary> /// Forwards an inbound brokered message to a destination /// </summary> /// <param name="inboundBrokeredMessage">The inbound brokered message to be forwarded to a receiver</param> /// <param name="forwardDestination">The destination path to forward the inbound brokered message to</param> /// <param name="transactionContext">The transactional information to use while routing</param> /// <returns>An awaitable <see cref="Task"/></returns> public Task Route(InboundBrokeredMessage inboundBrokeredMessage, string forwardDestination, TransactionContext transactionContext) { if (inboundBrokeredMessage is null) { throw new ArgumentNullException(nameof(inboundBrokeredMessage), $"An {typeof(InboundBrokeredMessage).Name} is required to be routed to the destination."); } if (string.IsNullOrWhiteSpace(forwardDestination)) { return(Task.CompletedTask); } var outboundMessage = OutboundBrokeredMessage.Forward(inboundBrokeredMessage, forwardDestination) .RefreshTimeToLive(); return(_router.Route(outboundMessage, transactionContext)); }
public async Task Process(OutboxMessage message, CancellationToken cancellationToken = default) { try { IDictionary <string, object> messageContext = new Dictionary <string, object>(); if (!string.IsNullOrWhiteSpace(message.MessageContext)) { messageContext = JsonConvert.DeserializeObject <IDictionary <string, object> >(message.MessageContext); } var contentType = message.MessageContentType; if (string.IsNullOrWhiteSpace(message.MessageContentType)) { contentType = (string)messageContext[MessageContext.ContentType]; _logger.LogTrace($"Outbox message did not contain content type. Retrieved from message context."); } messageContext.TryGetValue(MessageContext.InfrastructureType, out var infra); var dispatcherInfrastructure = _infrastructureProvider.GetDispatcher((string)infra); if (string.IsNullOrWhiteSpace(contentType)) { _logger.LogTrace($"No content type set in outbox message or message context. Unable to dispatch message."); throw new ArgumentNullException(nameof(contentType), "A content type is required to serialize and send brokered message."); } var converter = _bodyConverterFactory.CreateBodyConverter(contentType); var outbound = new OutboundBrokeredMessage(message.MessageId, converter.GetBytes(message.MessageBody), messageContext, message.Destination, converter); _logger.LogTrace($"Processing message '{message.MessageId}' from outbox."); await((IUnitOfWork)_brokeredMessageOutbox).ExecuteAsync(async ct => { await _brokeredMessageOutbox.UpdateProcessedDate(message, ct); await dispatcherInfrastructure.Dispatch(outbound, null); _logger.LogTrace($"Message '{message.MessageId}' dispatched to messaging infrastructure from outbox."); }, null, cancellationToken); } catch (Exception e) { _logger.LogError(e, $"Unable to process outbox message with id '{message.Id}'"); } }
/// <summary> /// Forwards an inbound brokered message to a destination /// </summary> /// <param name="inboundBrokeredMessage">The inbound brokered message to be forwarded to a receiver</param> /// <param name="forwardDestination">The destination path to forward the inbound brokered message to</param> /// <param name="transactionContext">The transactional information to use while routing</param> /// <returns>An awaitable <see cref="Task"/></returns> public Task Route(InboundBrokeredMessage inboundBrokeredMessage, string forwardDestination, TransactionContext transactionContext) { if (inboundBrokeredMessage is null) { throw new ArgumentNullException(nameof(inboundBrokeredMessage), $"An {typeof(InboundBrokeredMessage).Name} is required to be routed to the destination."); } if (string.IsNullOrWhiteSpace(forwardDestination)) { return(Task.CompletedTask); } var outboundMessage = new OutboundBrokeredMessage(_messageIdGenerator?.GenerateId(inboundBrokeredMessage.Body).ToString(), inboundBrokeredMessage.Body, (IDictionary <string, object>)inboundBrokeredMessage.MessageContext, forwardDestination, inboundBrokeredMessage.BodyConverter); return(_router.Route(outboundMessage, transactionContext)); }
public Task Route(InboundBrokeredMessage inboundBrokeredMessage, TransactionContext transactionContext, ReplyToRoutingContext destinationRouterContext) { if (destinationRouterContext is null) { //TODO: log return(Task.CompletedTask); } try { var outbound = OutboundBrokeredMessage.Forward(inboundBrokeredMessage, destinationRouterContext?.DestinationPath); outbound.ApplicationProperties[ApplicationProperties.ReplyToGroupId] = destinationRouterContext.ReplyToGroupId; return(_router.Route(outbound, transactionContext)); } catch (Exception e) { throw new ReplyToRoutingExceptions(destinationRouterContext, e); } }
private async Task SendToOutbox(DbSet <OutboxMessage> outbox, OutboundBrokeredMessage outboundBrokeredMessage, TransactionContext transactionContext) { var currentTransaction = transactionContext?.Container.GetOrAdd <IPersistanceTransaction>(); Guid transactionId = currentTransaction?.TransactionId ?? Guid.Empty; //TODO: trim the OutboxMessage object down. likely dont need Body, etc. var outboxMessage = new OutboxMessage { MessageId = outboundBrokeredMessage.MessageId, StringifiedApplicationProperties = JsonConvert.SerializeObject(outboundBrokeredMessage.ApplicationProperties), Body = outboundBrokeredMessage.Body, Destination = outboundBrokeredMessage.Destination, StringifiedMessage = outboundBrokeredMessage.Stringify(), SentToOutboxAtUtc = DateTime.UtcNow, ProcessedFromOutboxAtUtc = null, BatchId = transactionId }; _logger.LogTrace($"Outbox message created for message with id: '{outboxMessage.MessageId}'"); await outbox.AddAsync(outboxMessage); }
private async Task SendToOutboxImpl(DbSet <OutboxMessage> outbox, OutboundBrokeredMessage outboundBrokeredMessage, TransactionContext transactionContext, CancellationToken cancellationToken = default) { var currentTransaction = transactionContext?.Container.GetOrDefault <IPersistanceTransaction>(); Guid transactionId = currentTransaction?.TransactionId ?? Guid.Empty; var outboxMessage = new OutboxMessage { MessageId = outboundBrokeredMessage.MessageId, MessageContext = JsonConvert.SerializeObject(outboundBrokeredMessage.MessageContext), Destination = outboundBrokeredMessage.Destination, MessageBody = outboundBrokeredMessage.Stringify(), MessageContentType = outboundBrokeredMessage.ContentType, SentToOutboxAtUtc = DateTime.UtcNow, ProcessedFromOutboxAtUtc = null, BatchId = transactionId }; _logger.LogTrace($"Outbox message created. MessageId: '{outboxMessage.MessageId}', BatchId: {outboxMessage.BatchId}"); await outbox.AddAsync(outboxMessage, cancellationToken).ConfigureAwait(false); _logger.LogTrace($"Outbox message added to outbox. MessageId: '{outboxMessage.MessageId}', BatchId: {outboxMessage.BatchId}"); }
/// <summary> /// Routes a brokered message to a brokered message receiver responsible for compensating a received message /// </summary> /// <param name="inboundBrokeredMessage">The inbound brokered message to be routed to the compensation destination</param> /// <param name="transactionContext">The transaction information that was received with <paramref name="inboundBrokeredMessage"/></param> /// <param name="destinationRouterContext">The <see cref="CompensationRoutingContext"/> containing contextual information describing the compensating action</param> /// <exception cref="CompensationRoutingException">An exception containing contextual information describing the failure during compensation and routing details</exception> /// <returns>An awaitable <see cref="Task"/></returns> public Task Route(InboundBrokeredMessage inboundBrokeredMessage, TransactionContext transactionContext, CompensationRoutingContext destinationRouterContext) { if (destinationRouterContext is null) { //TODO: log return(Task.CompletedTask); } try { if (destinationRouterContext is null) { throw new ArgumentNullException(nameof(destinationRouterContext), $"A '{typeof(CompensationRoutingContext).Name}' is required to route a compensation message"); } if (string.IsNullOrWhiteSpace(destinationRouterContext.CompensateDetails)) { throw new ArgumentNullException(nameof(destinationRouterContext.CompensateDetails), $"A compensation reason is required to route a compensation message"); } if (string.IsNullOrWhiteSpace(destinationRouterContext.CompensateDescription)) { throw new ArgumentNullException(nameof(destinationRouterContext.CompensateDescription), $"A compensation description is required to route a compensation message"); } var outbound = OutboundBrokeredMessage.Forward(inboundBrokeredMessage, destinationRouterContext.DestinationPath) .WithFailureDetails(destinationRouterContext.CompensateDetails) .WithFailureDescription(destinationRouterContext.CompensateDescription) .SetFailure(); return(_router.Route(outbound, transactionContext)); } catch (Exception causeOfRoutingFailure) { throw new CompensationRoutingException(destinationRouterContext, causeOfRoutingFailure); } }
public static OutboundBrokeredMessage WithPartitionKey(this OutboundBrokeredMessage outboundBrokeredMessage, string partitionKey) { outboundBrokeredMessage.ApplicationProperties[ASBHeaders.PartitionKey] = partitionKey; return(outboundBrokeredMessage); }
public static string GetToAddress(this OutboundBrokeredMessage outboundBrokeredMessage) { return((string)outboundBrokeredMessage.GetApplicationPropertyByKey(ASBHeaders.To)); }
public static OutboundBrokeredMessage WithTo(this OutboundBrokeredMessage outboundBrokeredMessage, string to) { outboundBrokeredMessage.ApplicationProperties[ASBHeaders.To] = to; return(outboundBrokeredMessage); }
public static DateTime?GetScheduledEnqueueTimeUtc(this OutboundBrokeredMessage outboundBrokeredMessage) { return((DateTime?)outboundBrokeredMessage.GetApplicationPropertyByKey(ASBHeaders.ScheduledEnqueueTimeUtc)); }
public static OutboundBrokeredMessage WithScheduledEnqueueTimeUtc(this OutboundBrokeredMessage outboundBrokeredMessage, DateTime scheduledEnqueueTimeUtc) { outboundBrokeredMessage.ApplicationProperties[ASBHeaders.ScheduledEnqueueTimeUtc] = scheduledEnqueueTimeUtc; return(outboundBrokeredMessage); }
public Task Dispatch(OutboundBrokeredMessage brokeredMessage, TransactionContext transactionContext) => Dispatch(new[] { brokeredMessage }, transactionContext);
private Task <Guid> BeginConversation(SqlConnection connection, SqlTransaction transaction, OutboundBrokeredMessage brokeredMessage, object initiatorService, object serviceContractName) => new BeginDialogConversationCommand(connection, brokeredMessage.Destination, (string)initiatorService, (string)serviceContractName, _options.ConversationLifetimeInSeconds, transaction: transaction).ExecuteAsync();
public static string GetPartitionKey(this OutboundBrokeredMessage outboundBrokeredMessage) { return((string)outboundBrokeredMessage.GetApplicationPropertyByKey(ASBHeaders.PartitionKey)); }
public static string GetSubject(this OutboundBrokeredMessage outboundBrokeredMessage) => outboundBrokeredMessage.GetMessageContextByKey <string>(MessageContext.Subject);
public static string GetGroupId(this OutboundBrokeredMessage outboundBrokeredMessage) => outboundBrokeredMessage.GetMessageContextByKey <string>(MessageContext.GroupId);
public static string GetToAddress(this OutboundBrokeredMessage outboundBrokeredMessage) => (string)outboundBrokeredMessage.GetMessageContextByKey(ASBMessageContext.To);
public static string GetPartitionKey(this OutboundBrokeredMessage outboundBrokeredMessage) => outboundBrokeredMessage.GetMessageContextByKey <string>(ASBMessageContext.PartitionKey);
public static OutboundBrokeredMessage WithPartitionKey(this OutboundBrokeredMessage outboundBrokeredMessage, string partitionKey) { outboundBrokeredMessage.MessageContext[ASBMessageContext.PartitionKey] = partitionKey; return(outboundBrokeredMessage); }
public static string GetReplyToAddress(this OutboundBrokeredMessage outboundBrokeredMessage) => outboundBrokeredMessage.GetMessageContextByKey <string>(MessageContext.ReplyToAddress);
private Task SendMessageOnConversation(SqlConnection connection, SqlTransaction transaction, OutboundBrokeredMessage brokeredMessage, string messageTypeName, Guid newConvHandle) { byte[] message = brokeredMessage.Body; if (messageTypeName == ServicesMessageTypes.ChatterBrokeredMessageType) { var bodyConverter = _bodyConverterFactory.CreateBodyConverter(_options.MessageBodyType); message = bodyConverter.Convert(brokeredMessage); } return(new SendOnConversationCommand(connection, newConvHandle, message, transaction, _options.CompressMessageBody, messageTypeName).ExecuteAsync()); }