Ejemplo n.º 1
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 async Task Message_should_be_processed_when_ignoringTTBRHeaders()
        {
            var context = await Scenario.Define <Context>()
                          .WithEndpoint <SomeEndpoint>(endpoint => endpoint
                                                       .CustomConfig(e =>
            {
                var transportConfig = (MsmqTransport)e.ConfigureTransport();
                transportConfig.IgnoreIncomingTimeToBeReceivedHeaders = true;
            })
                                                       .When(async(session, ctx) =>
            {
                var sendOptions = new SendOptions();
                sendOptions.RouteToThisEndpoint();
                sendOptions.SetHeader(Headers.TimeSent, DateTimeOffsetHelper.ToWireFormattedString(DateTime.UtcNow.AddSeconds(-10)));
                sendOptions.SetHeader(Headers.TimeToBeReceived, TimeSpan.FromSeconds(5).ToString());

                await session.Send(new SomeMessage(), sendOptions);
                ctx.WasSent = true;
            })
                                                       )
                          .Run(TimeSpan.FromSeconds(5));

            Assert.IsTrue(context.WasSent, "Message was sent");
            Assert.IsTrue(context.WasReceived, "Message was not processed");
        }
Ejemplo n.º 3
0
        public async Task Message_should_not_be_processed()
        {
            var tcs     = new Lazy <CancellationTokenSource>(() => new CancellationTokenSource(TimeSpan.FromSeconds(5)));
            var context = await Scenario.Define <Context>()
                          .WithEndpoint <SomeEndpoint>(endpoint => endpoint
                                                       .CustomConfig(e =>
            {
                var transportConfig = (MsmqTransport)e.ConfigureTransport();
                transportConfig.IgnoreIncomingTimeToBeReceivedHeaders = false;
            })
                                                       .When(async(session, ctx) =>
            {
                var sendOptions = new SendOptions();
                sendOptions.RouteToThisEndpoint();
                sendOptions.SetHeader(Headers.TimeSent, DateTimeOffsetHelper.ToWireFormattedString(DateTime.UtcNow.AddSeconds(-10)));
                sendOptions.SetHeader(Headers.TimeToBeReceived, TimeSpan.FromSeconds(5).ToString());

                await session.Send(new SomeMessage(), sendOptions);
                ctx.WasSent = true;
            })
                                                       )
                          .Done(c => tcs.Value.IsCancellationRequested) // wait at least 5 seconds to give the endpoint time to process any message
                          .Run();

            Assert.IsTrue(context.WasSent, "Message was sent");
            Assert.IsFalse(context.WasReceived, "Message was processed");
        }
        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);

            // ReSharper disable once ConditionIsAlwaysTrueOrFalse
            if (e.Data == null)
            // ReSharper disable HeuristicUnreachableCode
            {
                return;
            }
            // ReSharper restore HeuristicUnreachableCode
            foreach (DictionaryEntry entry in e.Data)
            {
                if (entry.Value == null)
                {
                    continue;
                }
                headers["NServiceBus.ExceptionInfo.Data." + entry.Key] = entry.Value.ToString();
            }
        }
Ejemplo n.º 5
0
        public async Task Should_honor_stored_delivery_constraints()
        {
            var messageId   = "id";
            var options     = new Dictionary <string, string>();
            var deliverTime = DateTimeOffset.UtcNow.AddDays(1);
            var maxTime     = TimeSpan.FromDays(1);

            options["Destination"] = "test";

            options["DeliverAt"]        = DateTimeOffsetHelper.ToWireFormattedString(deliverTime);
            options["DelayDeliveryFor"] = TimeSpan.FromSeconds(10).ToString();
            options["TimeToBeReceived"] = maxTime.ToString();

            fakeOutbox.ExistingMessage = new OutboxMessage(messageId, new[]
            {
                new NServiceBus.Outbox.TransportOperation("x", options, new byte[0], new Dictionary <string, string>())
            });

            var context = CreateContext(fakeBatchPipeline, messageId);

            await Invoke(context);

            Assert.True(fakeBatchPipeline.TransportOperations.First().DeliveryConstraints.TryGet(out DelayDeliveryWith delayDeliveryWith));
            Assert.AreEqual(TimeSpan.FromSeconds(10), delayDeliveryWith.Delay);

            Assert.True(fakeBatchPipeline.TransportOperations.First().DeliveryConstraints.TryGet(out DoNotDeliverBefore doNotDeliverBefore));
            Assert.AreEqual(deliverTime.ToString(), doNotDeliverBefore.At.ToString());

            Assert.True(fakeBatchPipeline.TransportOperations.First().DeliveryConstraints.TryGet(out DiscardIfNotReceivedBefore discard));
            Assert.AreEqual(maxTime, discard.MaxTime);

            Assert.Null(fakeOutbox.StoredMessage);
        }
Ejemplo n.º 6
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);
        }
        static string ValueToString(object value)
        {
            if (value is byte[] bytes)
            {
                return(Encoding.UTF8.GetString(bytes));
            }

            if (value is Dictionary <string, object> dictionary)
            {
                var sb = new StringBuilder();

                foreach (var kvp in dictionary)
                {
                    sb.Append(kvp.Key);
                    sb.Append("=");
                    sb.Append(ValueToString(kvp.Value));
                    sb.Append(",");
                }

                if (sb.Length > 0)
                {
                    sb.Remove(sb.Length - 1, 1);
                }

                return(sb.ToString());
            }

            if (value is List <object> list)
            {
                var sb = new StringBuilder();

                foreach (var entry in list)
                {
                    sb.Append(ValueToString(entry));
                    sb.Append(";");
                }

                if (sb.Length > 0)
                {
                    sb.Remove(sb.Length - 1, 1);
                }

                return(sb.ToString());
            }

            if (value is global::RabbitMQ.Client.AmqpTimestamp timestamp)
            {
                return(DateTimeOffsetHelper.ToWireFormattedString(UnixEpoch.AddSeconds(timestamp.UnixTime)));
            }

            return(value?.ToString());
        }
Ejemplo n.º 8
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);
        }
        public void ShouldCapTheRetryMaxTimeTo24Hours()
        {
            var now       = DateTime.UtcNow;
            var baseDelay = TimeSpan.FromSeconds(10);

            var policy = CreatePolicy(maxImmediateRetries: 0, maxDelayedRetries: 2, delayedRetryDelay: baseDelay);

            var moreThanADayAgo = now.AddHours(-24).AddTicks(-1);
            var headers         = new Dictionary <string, string>
            {
                { Headers.DelayedRetriesTimestamp, DateTimeOffsetHelper.ToWireFormattedString(moreThanADayAgo) }
            };

            var errorContext = CreateErrorContext(headers: headers);

            var result = policy(errorContext);

            Assert.IsInstanceOf <MoveToError>(result);
        }
        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);

            foreach (DictionaryEntry entry in e.Data)
            {
                if (entry.Value == null)
                {
                    continue;
                }
                headers["NServiceBus.ExceptionInfo.Data." + entry.Key] = entry.Value.ToString();
            }
        }
Ejemplo n.º 11
0
        void SendToDelayedDeliveryQueue(TransportTransaction transaction, UnicastTransportOperation transportOperation)
        {
            onSendCallback?.Invoke(transaction, transportOperation);
            var message = transportOperation.Message;

            transportOperation.Properties[TimeoutDestination] = transportOperation.Destination;
            DateTimeOffset deliverAt;

            if (transportOperation.Properties.DelayDeliveryWith != null)
            {
                deliverAt = DateTimeOffset.UtcNow + transportOperation.Properties.DelayDeliveryWith.Delay;
            }
            else // transportOperation.Properties.DoNotDeliverBefore != null
            {
                deliverAt = transportOperation.Properties.DoNotDeliverBefore.At;
            }

            transportOperation.Properties[TimeoutDestination] = transportOperation.Destination;
            transportOperation.Properties[TimeoutAt]          = DateTimeOffsetHelper.ToWireFormattedString(deliverAt);

            var destinationAddress = MsmqAddress.Parse(timeoutsQueue);

            foreach (var kvp in transportOperation.Properties)
            {
                //Use add to force exception if user adds a custom header that has the same name as the prefix + property name
                transportOperation.Message.Headers.Add($"{MsmqUtilities.PropertyHeaderPrefix}{kvp.Key}", kvp.Value);
            }

            try
            {
                using (var q = new MessageQueue(destinationAddress.FullPath, false, transportSettings.UseConnectionCache, QueueAccessMode.Send))
                {
                    using (var toSend = MsmqUtilities.Convert(message))
                    {
                        toSend.UseDeadLetterQueue = true; //Always used DLQ for delayed messages
                        toSend.UseJournalQueue    = transportSettings.UseJournalQueue;

                        if (transportOperation.RequiredDispatchConsistency == DispatchConsistency.Isolated)
                        {
                            q.Send(toSend, string.Empty, GetIsolatedTransactionType());
                            return;
                        }

                        if (TryGetNativeTransaction(transaction, out var activeTransaction))
                        {
                            q.Send(toSend, string.Empty, activeTransaction);
                            return;
                        }

                        q.Send(toSend, string.Empty, GetTransactionTypeForSend());
                    }
                }
            }
            catch (MessageQueueException ex)
            {
                if (ex.MessageQueueErrorCode == MessageQueueErrorCode.QueueNotFound)
                {
                    throw new QueueNotFoundException(timeoutsQueue, $"Failed to send the message to the local delayed delivery queue [{timeoutsQueue}]: queue does not exist.", ex);
                }

                ThrowFailedToSendException(timeoutsQueue, ex);
            }
            catch (Exception ex)
            {
                ThrowFailedToSendException(timeoutsQueue, ex);
            }
        }