Beispiel #1
0
        internal static SagaChangeInitiator BuildSagaChangeInitiatorMessage(IReadOnlyDictionary <string, string> headers, string messageId, string messageType)
        {
            headers.TryGetValue(Headers.OriginatingMachine, out var originatingMachine);

            headers.TryGetValue(Headers.OriginatingEndpoint, out var originatingEndpoint);

            var timeSent = headers.TryGetValue(Headers.TimeSent, out var timeSentHeaderValue) ?
                           DateTimeOffsetHelper.ToDateTimeOffset(timeSentHeaderValue) :
                           DateTimeOffset.MinValue;

            var intent = headers.TryGetValue(Headers.MessageIntent, out var messageIntent) ? messageIntent : "Send"; // Just in case the received message is from an early version that does not have intent, should be a rare occasion.

            var isTimeoutMessage = headers.TryGetValue(Headers.IsSagaTimeoutMessage, out var isTimeout) && isTimeout.ToLowerInvariant() == "true";

            return(new SagaChangeInitiator
            {
                IsSagaTimeoutMessage = isTimeoutMessage,
                InitiatingMessageId = messageId,
                OriginatingMachine = originatingMachine,
                OriginatingEndpoint = originatingEndpoint,
                MessageType = messageType,
                TimeSent = timeSent.UtcDateTime,
                Intent = intent
            });
        }
Beispiel #2
0
        public async Task Should_contain_processing_stats_headers()
        {
            var now = DateTimeOffset.UtcNow;

            var context = await Scenario.Define <Context>()
                          .WithEndpoint <EndpointWithAuditOn>(b => b.When(session => session.SendLocal(new MessageToBeAudited())).DoNotFailOnErrorMessages())
                          .WithEndpoint <EndpointThatHandlesAuditMessages>()
                          .WithEndpoint <EndpointThatHandlesErrorMessages>()
                          .Done(c => c.IsMessageHandledByTheAuditEndpoint && c.IsMessageHandledByTheFaultEndpoint)
                          .Run();

            var processingStarted = DateTimeOffsetHelper.ToDateTimeOffset(context.Headers[Headers.ProcessingStarted]);
            var processingEnded   = DateTimeOffsetHelper.ToDateTimeOffset(context.Headers[Headers.ProcessingEnded]);
            var timeSent          = DateTimeOffsetHelper.ToDateTimeOffset(context.Headers[Headers.TimeSent]);
            var timeSentWhenFailedMessageWasSentToTheErrorQueue = DateTimeOffsetHelper.ToDateTimeOffset(context.FaultHeaders[Headers.TimeSent]);

            Assert.That(processingStarted, Is.EqualTo(now).Within(TimeSpan.FromSeconds(30)), nameof(processingStarted));
            Assert.That(processingEnded, Is.EqualTo(now).Within(TimeSpan.FromSeconds(30)), nameof(processingEnded));
            Assert.That(timeSent, Is.EqualTo(now).Within(TimeSpan.FromSeconds(30)), nameof(timeSent));
            Assert.That(timeSentWhenFailedMessageWasSentToTheErrorQueue, Is.EqualTo(now).Within(TimeSpan.FromSeconds(30)), nameof(timeSentWhenFailedMessageWasSentToTheErrorQueue));
            Assert.That(timeSent, Is.LessThanOrEqualTo(processingEnded), nameof(processingEnded));
            Assert.That(timeSent, Is.LessThanOrEqualTo(timeSentWhenFailedMessageWasSentToTheErrorQueue), nameof(timeSentWhenFailedMessageWasSentToTheErrorQueue));

            Assert.That(timeSentWhenFailedMessageWasSentToTheErrorQueue, Is.EqualTo(context.TimeSentOnTheFailingMessageWhenItWasHandled), nameof(timeSentWhenFailedMessageWasSentToTheErrorQueue));
            Assert.That(processingStarted, Is.LessThanOrEqualTo(processingEnded), nameof(processingStarted));
            Assert.IsTrue(context.IsMessageHandledByTheFaultEndpoint, nameof(context.IsMessageHandledByTheFaultEndpoint));
        }
Beispiel #3
0
        public async Task Should_update_retry_headers_when_present()
        {
            var delayedRetryExecutor     = CreateExecutor();
            var originalHeadersTimestamp = DateTimeOffsetHelper.ToWireFormattedString(new DateTime(2012, 12, 12, 0, 0, 0, DateTimeKind.Utc));

            var incomingMessage = CreateMessage(new Dictionary <string, string>
            {
                { Headers.DelayedRetries, "2" },
                { Headers.DelayedRetriesTimestamp, originalHeadersTimestamp }
            });

            var now = DateTime.UtcNow;
            await delayedRetryExecutor.Retry(incomingMessage, TimeSpan.Zero, new TransportTransaction(), default);

            var outgoingMessageHeaders = dispatcher.UnicastTransportOperations.Single().Message.Headers;

            Assert.AreEqual("3", outgoingMessageHeaders[Headers.DelayedRetries]);
            Assert.AreEqual("2", incomingMessage.Headers[Headers.DelayedRetries]);

            var utcDateTime = DateTimeOffsetHelper.ToDateTimeOffset(outgoingMessageHeaders[Headers.DelayedRetriesTimestamp]);
            // the serialization removes precision which may lead to now being greater than the deserialized header value
            var adjustedNow = DateTimeOffsetHelper.ToDateTimeOffset(DateTimeOffsetHelper.ToWireFormattedString(now));

            Assert.That(utcDateTime, Is.GreaterThanOrEqualTo(adjustedNow));
            Assert.AreEqual(originalHeadersTimestamp, incomingMessage.Headers[Headers.DelayedRetriesTimestamp]);
        }
 public Task Handle(TestCommand message, IMessageHandlerContext context)
 {
     testContext.CommandHandled = true;
     testContext.TimeSent       = DateTimeOffsetHelper.ToDateTimeOffset(context.MessageHeaders[Headers.TimeSent]);
     testContext.MessageId      = context.MessageId;
     return(Task.FromResult(0));
 }
Beispiel #5
0
        public void When_converting_string_with_invalid_characters_should_throw()
        {
            var dateString = "201j-08-16 10:06:20:123456 Z";

            var exception = Assert.Throws <FormatException>(() => DateTimeOffsetHelper.ToDateTimeOffset(dateString));

            Assert.AreEqual(exception.Message, "String was not recognized as a valid DateTime.");
        }
Beispiel #6
0
                public Task Handle(MessageThatFails message, IMessageHandlerContext context)
                {
                    testContext.TimeSentOnTheFailingMessageWhenItWasHandled = DateTimeOffsetHelper.ToDateTimeOffset(context.MessageHeaders[Headers.TimeSent]);
                    testContext.FaultHeaders = context.MessageHeaders.ToDictionary(x => x.Key, x => x.Value);
                    testContext.IsMessageHandledByTheFaultEndpoint = true;

                    return(Task.FromResult(0));
                }
Beispiel #7
0
        public void When_roundtripping_constructed_date_should_be_equal()
        {
            var date       = new DateTimeOffset(2016, 8, 29, 16, 37, 25, 75, TimeSpan.Zero);
            var dateString = DateTimeOffsetHelper.ToWireFormattedString(date);
            var result     = DateTimeOffsetHelper.ToDateTimeOffset(dateString);

            Assert.AreEqual(date, result);
        }
Beispiel #8
0
        static bool TryGetTimeSent(Dictionary <string, string> headers, out DateTimeOffset timeSent)
        {
            if (headers.TryGetValue(Headers.TimeSent, out var timeSentString))
            {
                timeSent = DateTimeOffsetHelper.ToDateTimeOffset(timeSentString);
                return(true);
            }

            timeSent = DateTimeOffset.MinValue;
            return(false);
        }
    public static bool TryGetTimeSent(this ReceivePipelineCompleted completed, out DateTimeOffset timeSent)
    {
        var headers = completed.ProcessedMessage.Headers;

        if (headers.TryGetValue(Headers.TimeSent, out var timeSentString))
        {
            timeSent = DateTimeOffsetHelper.ToDateTimeOffset(timeSentString);
            return(true);
        }
        timeSent = DateTimeOffset.MinValue;
        return(false);
    }
    public static bool TryGetDeliverAt(this ReceivePipelineCompleted completed, out DateTimeOffset deliverAt)
    {
        var headers = completed.ProcessedMessage.Headers;

        if (headers.TryGetValue(Headers.DeliverAt, out var deliverAtString))
        {
            deliverAt = DateTimeOffsetHelper.ToDateTimeOffset(deliverAtString);
            return(true);
        }
        deliverAt = DateTimeOffset.MinValue;
        return(false);
    }
        public void ToDateTimeOffsetTest(object value, bool expected)
        {
            var actual          = DateTimeOffsetHelper.ToDateTimeOffset(value);
            var isDefaultResult = actual == default(DateTimeOffset);

            if (!isDefaultResult)
            {
                actual          = DateTimeOffsetHelper.ToDateTimeOffset(value);
                isDefaultResult = actual == default(DateTimeOffset);
            }

            Assert.Equal(expected, isDefaultResult);
        }
        public void GetClosestUtcZeroTimeTest(object value)
        {
            var dateTimeOffset = DateTimeOffsetHelper.ToDateTimeOffset(value);

            var actual = DateTimeOffsetHelper.GetClosestUtcZeroTime(dateTimeOffset.DateTime);

            Assert.Equal(dateTimeOffset.Year, actual.Year);
            Assert.Equal(dateTimeOffset.Month, actual.Month);
            Assert.Equal(dateTimeOffset.Day, actual.Day);
            Assert.Equal(dateTimeOffset.Year, actual.Year);
            Assert.Equal(dateTimeOffset.Hour, actual.Hour);
            Assert.Equal(dateTimeOffset.Minute, actual.Minute);
            Assert.Equal(dateTimeOffset.Second, actual.Second);
        }
        public void Should_rethrow_exception_with_additional_data()
        {
            var thrownException = new InvalidOperationException();
            var terminator      = new InvokeHandlerTerminator();
            var messageHandler  = CreateMessageHandler((i, m, ctx) => throw thrownException, new FakeMessageHandler());
            var behaviorContext = CreateBehaviorContext(messageHandler);

            var caughtException = Assert.ThrowsAsync <InvalidOperationException>(async() => await terminator.Invoke(behaviorContext, _ => Task.CompletedTask));

            Assert.AreSame(thrownException, caughtException);
            Assert.AreEqual("System.Object", caughtException.Data["Message type"]);
            Assert.AreEqual("NServiceBus.Core.Tests.Pipeline.Incoming.InvokeHandlerTerminatorTest+FakeMessageHandler", caughtException.Data["Handler type"]);
            Assert.That(DateTimeOffsetHelper.ToDateTimeOffset((string)caughtException.Data["Handler start time"]), Is.EqualTo(DateTimeOffset.UtcNow).Within(TimeSpan.FromSeconds(5)));
            Assert.That(DateTimeOffsetHelper.ToDateTimeOffset((string)caughtException.Data["Handler failure time"]), Is.EqualTo(DateTimeOffset.UtcNow).Within(TimeSpan.FromSeconds(5)));
        }
Beispiel #14
0
        public void When_roundtripping_UtcNow_should_be_accurate_to_microseconds()
        {
            var date       = DateTimeOffset.UtcNow;
            var dateString = DateTimeOffsetHelper.ToWireFormattedString(date);
            var result     = DateTimeOffsetHelper.ToDateTimeOffset(dateString);

            Assert.AreEqual(date.Year, result.Year);
            Assert.AreEqual(date.Month, result.Month);
            Assert.AreEqual(date.Day, result.Day);
            Assert.AreEqual(date.Hour, result.Hour);
            Assert.AreEqual(date.Minute, result.Minute);
            Assert.AreEqual(date.Second, result.Second);
            Assert.AreEqual(date.Millisecond, result.Millisecond);
            Assert.AreEqual(date.Microseconds(), result.Microseconds());
            Assert.AreEqual(date.Offset, result.Offset);
        }
Beispiel #15
0
        public void When_converting_string_should_be_accurate_to_microseconds()
        {
            var dateString = "2016-08-16 10:06:20:123456 Z";
            var date       = DateTimeOffset.ParseExact(dateString, "yyyy-MM-dd HH:mm:ss:ffffff Z", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
            var result     = DateTimeOffsetHelper.ToDateTimeOffset(dateString);

            Assert.AreEqual(date.Year, result.Year);
            Assert.AreEqual(date.Month, result.Month);
            Assert.AreEqual(date.Day, result.Day);
            Assert.AreEqual(date.Hour, result.Hour);
            Assert.AreEqual(date.Minute, result.Minute);
            Assert.AreEqual(date.Second, result.Second);
            Assert.AreEqual(date.Millisecond, result.Millisecond);
            Assert.AreEqual(date.Microseconds(), result.Microseconds());
            Assert.AreEqual(date.Offset, result.Offset);
        }
Beispiel #16
0
    public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
    {
        var exception = logEvent.Exception;

        if (exception is null)
        {
            return;
        }

        if (exception.TryReadData("Message type", out string messageType))
        {
            logEvent.AddPropertyIfAbsent(
                new("IncomingMessageType", new ScalarValue(messageType)));
        }

        if (exception.TryReadData("Message ID", out string incomingMessageId))
        {
            logEvent.AddPropertyIfAbsent(
                new("IncomingMessageId", new ScalarValue(incomingMessageId)));
        }

        if (exception.TryReadData("Transport message ID", out string incomingTransportMessageId))
        {
            logEvent.AddPropertyIfAbsent(
                new("IncomingTransportMessageId", new ScalarValue(incomingTransportMessageId)));
        }

        if (exception.TryReadData("Handler start time", out string handlerStartTime))
        {
            logEvent.AddPropertyIfAbsent(
                new("HandlerStartTime", new ScalarValue(DateTimeOffsetHelper.ToDateTimeOffset(handlerStartTime))));
        }

        if (exception.TryReadData("Handler failure time", out string handlerFailureTime))
        {
            logEvent.AddPropertyIfAbsent(
                new("HandlerFailureTime", new ScalarValue(DateTimeOffsetHelper.ToDateTimeOffset(handlerFailureTime))));
        }

        if (exception.TryReadData("Handler type", out string handlerType))
        {
            logEvent.AddPropertyIfAbsent(new("HandlerType", new ScalarValue(handlerType)));
        }

        if (exception.TryReadData("ExceptionLogState", out ExceptionLogState logState))
        {
            logEvent.AddPropertyIfAbsent(
                new("ProcessingEndpoint", new ScalarValue(logState.ProcessingEndpoint)));
            if (logState.CorrelationId is not null)
            {
                logEvent.AddPropertyIfAbsent(
                    new("CorrelationId", new ScalarValue(logState.CorrelationId)));
            }

            if (logState.ConversationId is not null)
            {
                logEvent.AddPropertyIfAbsent(
                    new("ConversationId", new ScalarValue(logState.ConversationId)));
            }

            if (logState.IncomingMessage is not null)
            {
                if (Log.BindProperty("IncomingMessage", logState.IncomingMessage, true, out var messageProperty))
                {
                    logEvent.AddPropertyIfAbsent(messageProperty);
                }
            }

            if (Log.BindProperty("IncomingHeaders", logState.IncomingHeaders, true, out var headersProperty))
            {
                logEvent.AddPropertyIfAbsent(headersProperty);
            }
        }
    }
Beispiel #17
0
        async Task TimeoutReceived(MessageContext context, CancellationToken cancellationToken)
        {
            if (!context.Headers.TryGetValue(MsmqUtilities.PropertyHeaderPrefix + MsmqMessageDispatcher.TimeoutDestination, out var destination))
            {
                throw new Exception("This message does not represent a timeout");
            }

            if (!context.Headers.TryGetValue(MsmqUtilities.PropertyHeaderPrefix + MsmqMessageDispatcher.TimeoutAt, out var atString))
            {
                throw new Exception("This message does not represent a timeout");
            }

            var id = context.NativeMessageId; //Use native message ID as a key in the delayed delivery table
            var at = DateTimeOffsetHelper.ToDateTimeOffset(atString);

            var message = context.Extensions.Get <System.Messaging.Message>();

            var diff = DateTime.UtcNow - at;

            if (diff.Ticks > 0) // Due
            {
                dispatcher.DispatchDelayedMessage(id, message.Extension, context.Body, destination, context.TransportTransaction);
            }
            else
            {
                var timeout = new DelayedMessage
                {
                    Destination = destination,
                    MessageId   = id,
                    Body        = context.Body.ToArray(),
                    Time        = at.UtcDateTime,
                    Headers     = message.Extension
                };

                try
                {
                    using (var tx = new TransactionScope(txOption, transactionOptions, TransactionScopeAsyncFlowOption.Enabled))
                    {
                        await storage.Store(timeout, cancellationToken).ConfigureAwait(false);

                        tx.Complete();
                    }

                    storeCircuitBreaker.Success();
                }
                catch (OperationCanceledException) when(cancellationToken.IsCancellationRequested)
                {
                    //Shutting down
                    return;
                }
                catch (Exception e)
                {
                    await storeCircuitBreaker.Failure(e, cancellationToken).ConfigureAwait(false);

                    throw new Exception("Error while storing delayed message", e);
                }

#pragma warning disable PS0022 // A DateTime should not be implicitly cast to a DateTimeOffset
                poller.Signal(timeout.Time);
#pragma warning restore PS0022 // A DateTime should not be implicitly cast to a DateTimeOffset
            }
        }