protected override async Task Terminate(IInvokeHandlerContext context) { if (context.Extensions.TryGet(out ActiveSagaInstance saga) && saga.NotFound && saga.Metadata.SagaType == context.MessageHandler.Instance.GetType()) { return; } var messageHandler = context.MessageHandler; var startTime = DateTimeOffset.UtcNow; try { await messageHandler .Invoke(context.MessageBeingHandled, context) .ThrowIfNull() .ConfigureAwait(false); } catch (Exception e) { e.Data["Message type"] = context.MessageMetadata.MessageType.FullName; e.Data["Handler type"] = context.MessageHandler.HandlerType.FullName; e.Data["Handler start time"] = DateTimeOffsetHelper.ToWireFormattedString(startTime); e.Data["Handler failure time"] = DateTimeOffsetHelper.ToWireFormattedString(DateTimeOffset.UtcNow); throw; } }
protected override Task Terminate(ISubscribeContext context) { var eventType = context.EventType; var publisherAddresses = subscriptionRouter.GetAddressesForEventType(eventType); if (publisherAddresses.Count == 0) { throw new Exception($"No publisher address could be found for message type '{eventType}'. Ensure that a publisher has been configured for the event type and that the configured publisher endpoint has at least one known instance."); } var subscribeTasks = new List <Task>(publisherAddresses.Count); foreach (var publisherAddress in publisherAddresses) { Logger.Debug($"Subscribing to {eventType.AssemblyQualifiedName} at publisher queue {publisherAddress}"); var subscriptionMessage = ControlMessageFactory.Create(MessageIntentEnum.Subscribe); subscriptionMessage.Headers[Headers.SubscriptionMessageType] = eventType.AssemblyQualifiedName; subscriptionMessage.Headers[Headers.ReplyToAddress] = subscriberAddress; subscriptionMessage.Headers[Headers.SubscriberTransportAddress] = subscriberAddress; subscriptionMessage.Headers[Headers.SubscriberEndpoint] = subscriberEndpoint; subscriptionMessage.Headers[Headers.TimeSent] = DateTimeOffsetHelper.ToWireFormattedString(DateTimeOffset.UtcNow); subscriptionMessage.Headers[Headers.NServiceBusVersion] = GitVersionInformation.MajorMinorPatch; subscribeTasks.Add(SendSubscribeMessageWithRetries(publisherAddress, subscriptionMessage, eventType.AssemblyQualifiedName, context.Extensions)); } return(Task.WhenAll(subscribeTasks)); }
protected override async Task Terminate(IUnsubscribeContext context) { var eventType = context.EventType; var eventMetadata = messageMetadataRegistry.GetMessageMetadata(eventType); await subscriptionManager.Unsubscribe(eventMetadata, context.Extensions, context.CancellationToken).ConfigureAwait(false); var publisherAddresses = subscriptionRouter.GetAddressesForEventType(eventType); if (publisherAddresses.Count == 0) { return; } var unsubscribeTasks = new List <Task>(publisherAddresses.Count); foreach (var publisherAddress in publisherAddresses) { Logger.Debug("Unsubscribing to " + eventType.AssemblyQualifiedName + " at publisher queue " + publisherAddress); var unsubscribeMessage = ControlMessageFactory.Create(MessageIntentEnum.Unsubscribe); unsubscribeMessage.Headers[Headers.SubscriptionMessageType] = eventType.AssemblyQualifiedName; unsubscribeMessage.Headers[Headers.ReplyToAddress] = replyToAddress; unsubscribeMessage.Headers[Headers.SubscriberTransportAddress] = replyToAddress; unsubscribeMessage.Headers[Headers.SubscriberEndpoint] = endpoint; unsubscribeMessage.Headers[Headers.TimeSent] = DateTimeOffsetHelper.ToWireFormattedString(DateTimeOffset.UtcNow); unsubscribeMessage.Headers[Headers.NServiceBusVersion] = GitVersionInformation.MajorMinorPatch; unsubscribeTasks.Add(SendUnsubscribeMessageWithRetries(publisherAddress, unsubscribeMessage, eventType.AssemblyQualifiedName, context.Extensions, 0, context.CancellationToken)); } await Task.WhenAll(unsubscribeTasks).ConfigureAwait(false); }
public async Task Invoke(IIncomingPhysicalMessageContext context, Func <IIncomingPhysicalMessageContext, Task> next) { var state = new State(); var headers = context.Message.Headers; if (headers.TryGetValue(Headers.TimeSent, out var timeSentString)) { state.TimeSent = DateTimeOffsetHelper.ToDateTimeOffset(timeSentString); } state.ProcessingStarted = DateTimeOffset.UtcNow; context.Extensions.Set(state); var stopwatch = Stopwatch.StartNew(); try { await next(context).ConfigureAwait(false); } finally { stopwatch.Stop(); state.ProcessingEnded = state.ProcessingStarted + stopwatch.Elapsed; } }
protected override async Task Terminate(IInvokeHandlerContext context) { if (context.Extensions.TryGet(out ActiveSagaInstance saga) && saga.NotFound && saga.Metadata.SagaType == context.MessageHandler.Instance.GetType()) { return; } var messageHandler = context.MessageHandler; // Might as well abort before invoking the handler if we're shutting down context.CancellationToken.ThrowIfCancellationRequested(); var startTime = DateTimeOffset.UtcNow; try { await messageHandler .Invoke(context.MessageBeingHandled, context) .ThrowIfNull() .ConfigureAwait(false); } #pragma warning disable PS0019 // Do not catch Exception without considering OperationCanceledException - enriching and rethrowing catch (Exception ex) #pragma warning restore PS0019 // Do not catch Exception without considering OperationCanceledException { ex.Data["Message type"] = context.MessageMetadata.MessageType.FullName; ex.Data["Handler type"] = context.MessageHandler.HandlerType.FullName; ex.Data["Handler start time"] = DateTimeOffsetHelper.ToWireFormattedString(startTime); ex.Data["Handler failure time"] = DateTimeOffsetHelper.ToWireFormattedString(DateTimeOffset.UtcNow); ex.Data["Handler canceled"] = context.CancellationToken.IsCancellationRequested; throw; } }
public static void SetExceptionHeaders(Dictionary <string, string> headers, Exception e) { headers["NServiceBus.ExceptionInfo.ExceptionType"] = e.GetType().FullName; if (e.InnerException != null) { headers["NServiceBus.ExceptionInfo.InnerExceptionType"] = e.InnerException.GetType().FullName; } headers["NServiceBus.ExceptionInfo.HelpLink"] = e.HelpLink; headers["NServiceBus.ExceptionInfo.Message"] = e.GetMessage().Truncate(16384); headers["NServiceBus.ExceptionInfo.Source"] = e.Source; headers["NServiceBus.ExceptionInfo.StackTrace"] = e.ToString(); headers["NServiceBus.TimeOfFailure"] = DateTimeOffsetHelper.ToWireFormattedString(DateTimeOffset.UtcNow); if (e.Data == null) { return; } #pragma warning disable DE0006 foreach (DictionaryEntry entry in e.Data) #pragma warning restore DE0006 { if (entry.Value == null) { continue; } headers["NServiceBus.ExceptionInfo.Data." + entry.Key] = entry.Value.ToString(); } }
static bool HasReachedMaxTime(IncomingMessage message) { if (!message.Headers.TryGetValue(Headers.DelayedRetriesTimestamp, out var timestampHeader)) { return(false); } if (string.IsNullOrEmpty(timestampHeader)) { return(false); } try { var handledAt = DateTimeOffsetHelper.ToDateTimeOffset(timestampHeader); var now = DateTimeOffset.UtcNow; if (now > handledAt.AddDays(1)) { return(true); } } // this code won't usually throw but in case a user has decided to hack a message/headers and for some bizarre reason // they changed the date and that parse fails, we want to make sure that doesn't prevent the message from being // forwarded to the error queue. catch (Exception) { } return(false); }
protected override async Task Terminate(ISubscribeContext context) { var eventType = context.EventType; await subscriptionManager.Subscribe(eventType, context.Extensions).ConfigureAwait(false); var publisherAddresses = subscriptionRouter.GetAddressesForEventType(eventType); if (publisherAddresses.Count == 0) { return; } var subscribeTasks = new List <Task>(publisherAddresses.Count); foreach (var publisherAddress in publisherAddresses) { Logger.Debug($"Subscribing to {eventType.AssemblyQualifiedName} at publisher queue {publisherAddress}"); var subscriptionMessage = ControlMessageFactory.Create(MessageIntentEnum.Subscribe); subscriptionMessage.Headers[Headers.SubscriptionMessageType] = eventType.AssemblyQualifiedName; subscriptionMessage.Headers[Headers.ReplyToAddress] = subscriberAddress; subscriptionMessage.Headers[Headers.SubscriberTransportAddress] = subscriberAddress; subscriptionMessage.Headers[Headers.SubscriberEndpoint] = subscriberEndpoint; subscriptionMessage.Headers[Headers.TimeSent] = DateTimeOffsetHelper.ToWireFormattedString(DateTimeOffset.UtcNow); subscriptionMessage.Headers[Headers.NServiceBusVersion] = GitVersionInformation.MajorMinorPatch; subscribeTasks.Add(SendSubscribeMessageWithRetries(publisherAddress, subscriptionMessage, eventType.AssemblyQualifiedName, context.Extensions)); } await Task.WhenAll(subscribeTasks).ConfigureAwait(false); }
protected override async Task Terminate(ISubscribeContext context) { var subscribeTasks = new List <Task>(); foreach (var eventType in context.EventTypes) { try { var publisherAddresses = subscriptionRouter.GetAddressesForEventType(eventType); if (publisherAddresses.Count == 0) { throw new Exception($"No publisher address could be found for message type '{eventType}'. Ensure that a publisher has been configured for the event type and that the configured publisher endpoint has at least one known instance."); } foreach (var publisherAddress in publisherAddresses) { Logger.Debug($"Subscribing to {eventType.AssemblyQualifiedName} at publisher queue {publisherAddress}"); var subscriptionMessage = ControlMessageFactory.Create(MessageIntentEnum.Subscribe); subscriptionMessage.Headers[Headers.SubscriptionMessageType] = eventType.AssemblyQualifiedName; subscriptionMessage.Headers[Headers.ReplyToAddress] = subscriberAddress; subscriptionMessage.Headers[Headers.SubscriberTransportAddress] = subscriberAddress; subscriptionMessage.Headers[Headers.SubscriberEndpoint] = subscriberEndpoint; subscriptionMessage.Headers[Headers.TimeSent] = DateTimeOffsetHelper.ToWireFormattedString(DateTimeOffset.UtcNow); subscriptionMessage.Headers[Headers.NServiceBusVersion] = GitVersionInformation.MajorMinorPatch; subscribeTasks.Add(SendSubscribeMessageWithRetries(publisherAddress, subscriptionMessage, eventType.AssemblyQualifiedName, context.Extensions, 0, context.CancellationToken)); } } #pragma warning disable PS0019 // Do not catch Exception without considering OperationCanceledException - Tasks are not observed until below catch (Exception e) #pragma warning restore PS0019 // Do not catch Exception without considering OperationCanceledException { subscribeTasks.Add(Task.FromException(e)); } } var t = Task.WhenAll(subscribeTasks); try { await t.ConfigureAwait(false); } catch (Exception) { // if subscribing via SubscribeAll, throw an AggregateException if (context.Extensions.TryGet <bool>(MessageSession.SubscribeAllFlagKey, out var flag) && flag) { throw t.Exception; } // otherwise throw the first exception to not change exception behavior when calling subscribe. throw; } }
public Task Invoke(IAuditContext context, Func <IAuditContext, Task> next) { if (context.Extensions.TryGet(out ProcessingStatisticsBehavior.State state)) { context.AddAuditData(Headers.ProcessingStarted, DateTimeOffsetHelper.ToWireFormattedString(state.ProcessingStarted)); // We can't take the processing time from the state since we don't know it yet. context.AddAuditData(Headers.ProcessingEnded, DateTimeOffsetHelper.ToWireFormattedString(DateTimeOffset.UtcNow)); } return(next(context)); }
public Task Invoke(IRoutingContext context, Func <IRoutingContext, Task> next) { var message = context.Message; if (!message.Headers.ContainsKey(Headers.NServiceBusVersion)) { message.Headers[Headers.NServiceBusVersion] = GitVersionInformation.MajorMinorPatch; } if (!message.Headers.ContainsKey(Headers.TimeSent)) { message.Headers[Headers.TimeSent] = DateTimeOffsetHelper.ToWireFormattedString(DateTimeOffset.UtcNow); } return(next(context)); }
static List <DeliveryConstraint> DeserializeConstraints(Dictionary <string, string> options) { var constraints = new List <DeliveryConstraint>(4); if (options.TryGetValue("DeliverAt", out var deliverAt)) { constraints.Add(new DoNotDeliverBefore(DateTimeOffsetHelper.ToDateTimeOffset(deliverAt))); } if (options.TryGetValue("DelayDeliveryFor", out var delay)) { constraints.Add(new DelayDeliveryWith(TimeSpan.Parse(delay))); } if (options.TryGetValue("TimeToBeReceived", out var ttbr)) { constraints.Add(new DiscardIfNotReceivedBefore(TimeSpan.Parse(ttbr))); } return(constraints); }
static void SerializeDeliveryConstraint(DeliveryConstraint constraint, Dictionary <string, string> options) { if (constraint is DoNotDeliverBefore doNotDeliverBefore) { options["DeliverAt"] = DateTimeOffsetHelper.ToWireFormattedString(doNotDeliverBefore.At); return; } if (constraint is DelayDeliveryWith delayDeliveryWith) { options["DelayDeliveryFor"] = delayDeliveryWith.Delay.ToString(); return; } if (constraint is DiscardIfNotReceivedBefore discard) { options["TimeToBeReceived"] = discard.MaxTime.ToString(); return; } throw new Exception($"Unknown delivery constraint {constraint.GetType().FullName}"); }
public static void SetDelayedDeliveryTimestamp(this OutgoingMessage message, DateTimeOffset timestamp) { message.Headers[Headers.DelayedRetriesTimestamp] = DateTimeOffsetHelper.ToWireFormattedString(timestamp); }
protected override async Task Terminate(ISubscribeContext context) { var eventMetadata = new MessageMetadata[context.EventTypes.Length]; for (int i = 0; i < context.EventTypes.Length; i++) { eventMetadata[i] = messageMetadataRegistry.GetMessageMetadata(context.EventTypes[i]); } try { await subscriptionManager.SubscribeAll(eventMetadata, context.Extensions, context.CancellationToken).ConfigureAwait(false); } catch (AggregateException e) { if (context.Extensions.TryGet <bool>(MessageSession.SubscribeAllFlagKey, out var flag) && flag) { throw; } // if this is called from Subscribe, rethrow the expected single exception throw e.InnerException ?? e; } var subscribeTasks = new List <Task>(); foreach (var eventType in context.EventTypes) { try { var publisherAddresses = subscriptionRouter.GetAddressesForEventType(eventType); if (publisherAddresses.Count == 0) { continue; } foreach (var publisherAddress in publisherAddresses) { Logger.Debug($"Subscribing to {eventType.AssemblyQualifiedName} at publisher queue {publisherAddress}"); var subscriptionMessage = ControlMessageFactory.Create(MessageIntentEnum.Subscribe); subscriptionMessage.Headers[Headers.SubscriptionMessageType] = eventType.AssemblyQualifiedName; subscriptionMessage.Headers[Headers.ReplyToAddress] = subscriberAddress; subscriptionMessage.Headers[Headers.SubscriberTransportAddress] = subscriberAddress; subscriptionMessage.Headers[Headers.SubscriberEndpoint] = subscriberEndpoint; subscriptionMessage.Headers[Headers.TimeSent] = DateTimeOffsetHelper.ToWireFormattedString(DateTimeOffset.UtcNow); subscriptionMessage.Headers[Headers.NServiceBusVersion] = GitVersionInformation.MajorMinorPatch; subscribeTasks.Add(SendSubscribeMessageWithRetries(publisherAddress, subscriptionMessage, eventType.AssemblyQualifiedName, context.Extensions, 0, context.CancellationToken)); } } #pragma warning disable PS0019 // Do not catch Exception without considering OperationCanceledException - Tasks are not observed until below catch (Exception e) #pragma warning restore PS0019 // Do not catch Exception without considering OperationCanceledException { subscribeTasks.Add(Task.FromException(e)); } } var t = Task.WhenAll(subscribeTasks); try { await t.ConfigureAwait(false); } catch (Exception) { // if subscribing via SubscribeAll, throw an AggregateException if (context.Extensions.TryGet <bool>(MessageSession.SubscribeAllFlagKey, out var flag) && flag) { throw t.Exception; } // otherwise throw the first exception to not change exception behavior when calling subscribe. throw; } }