public async Task<int> Retry(IncomingMessage message, TimeSpan delay, TransportTransaction transportTransaction)
        {
            var outgoingMessage = new OutgoingMessage(message.MessageId, new Dictionary<string, string>(message.Headers), message.Body);

            var currentDelayedRetriesAttempt = message.GetDelayedDeliveriesPerformed() + 1;

            outgoingMessage.SetCurrentDelayedDeliveries(currentDelayedRetriesAttempt);
            outgoingMessage.SetDelayedDeliveryTimestamp(DateTime.UtcNow);

            UnicastAddressTag messageDestination;
            List<DeliveryConstraint> deliveryConstraints = null;
            if (timeoutManagerAddress == null)
            {
                // transport supports native deferred messages, directly send to input queue with delay constraint:
                deliveryConstraints = new List<DeliveryConstraint>(1)
                {
                    new DelayDeliveryWith(delay)
                };
                messageDestination = new UnicastAddressTag(endpointInputQueue);
            }
            else
            {
                // transport doesn't support native deferred messages, reroute to timeout manager:
                outgoingMessage.Headers[TimeoutManagerHeaders.RouteExpiredTimeoutTo] = endpointInputQueue;
                outgoingMessage.Headers[TimeoutManagerHeaders.Expire] = DateTimeExtensions.ToWireFormattedString(DateTime.UtcNow + delay);
                messageDestination = new UnicastAddressTag(timeoutManagerAddress);
            }

            var transportOperations = new TransportOperations(new TransportOperation(outgoingMessage, messageDestination, deliveryConstraints: deliveryConstraints));

            await dispatcher.Dispatch(transportOperations, transportTransaction, new ContextBag()).ConfigureAwait(false);

            return currentDelayedRetriesAttempt;
        }
    TransportOperation RouteThroughLocalEndpointInstance(RoutingStrategy routingStrategy, IRoutingContext context)
    {
        Dictionary <string, string> headers = new Dictionary <string, string>(context.Message.Headers);
        AddressTag        originalTag       = routingStrategy.Apply(headers);
        UnicastAddressTag unicastTag        = originalTag as UnicastAddressTag;

        if (unicastTag == null)
        {
            MulticastAddressTag multicastTag = originalTag as MulticastAddressTag;
            if (multicastTag != null)
            {
                headers["$.store-and-forward.eventtype"] = multicastTag.MessageType.AssemblyQualifiedName;
            }
            else
            {
                throw new Exception("Unsupported type of address tag: " + originalTag.GetType().FullName);
            }
        }
        else
        {
            headers["$.store-and-forward.destination"] = unicastTag.Destination;
        }
        OutgoingMessage message = new OutgoingMessage(context.Message.MessageId, headers, context.Message.Body);

        return(new TransportOperation(message, new UnicastAddressTag(localAddress), DispatchConsistency.Default, context.Extensions.GetDeliveryConstraints()));
    }
        public async Task <int> Retry(IncomingMessage message, TimeSpan delay, TransportTransaction transportTransaction)
        {
            var outgoingMessage = new OutgoingMessage(message.MessageId, new Dictionary <string, string>(message.Headers), message.Body);

            var currentDelayedRetriesAttempt = message.GetDelayedDeliveriesPerformed() + 1;

            outgoingMessage.SetCurrentDelayedDeliveries(currentDelayedRetriesAttempt);
            outgoingMessage.SetDelayedDeliveryTimestamp(DateTime.UtcNow);

            UnicastAddressTag         messageDestination;
            List <DeliveryConstraint> deliveryConstraints = null;

            if (timeoutManagerAddress == null)
            {
                // transport supports native deferred messages, directly send to input queue with delay constraint:
                deliveryConstraints = new List <DeliveryConstraint>(1)
                {
                    new DelayDeliveryWith(delay)
                };
                messageDestination = new UnicastAddressTag(endpointInputQueue);
            }
            else
            {
                // transport doesn't support native deferred messages, reroute to timeout manager:
                outgoingMessage.Headers[TimeoutManagerHeaders.RouteExpiredTimeoutTo] = endpointInputQueue;
                outgoingMessage.Headers[TimeoutManagerHeaders.Expire] = DateTimeExtensions.ToWireFormattedString(DateTime.UtcNow + delay);
                messageDestination = new UnicastAddressTag(timeoutManagerAddress);
            }

            var transportOperations = new TransportOperations(new TransportOperation(outgoingMessage, messageDestination, deliveryConstraints: deliveryConstraints));

            await dispatcher.Dispatch(transportOperations, transportTransaction, new ContextBag()).ConfigureAwait(false);

            return(currentDelayedRetriesAttempt);
        }
Esempio n. 4
0
                protected override TransportOperations CreateMessage(MyContext context)
                {
                    var errorAddress = new UnicastAddressTag("error");

                    return(new TransportOperations(
                               new TransportOperation(CreateTransportMessage(1), errorAddress),
                               new TransportOperation(CreateTransportMessage(2), errorAddress),
                               new TransportOperation(CreateTransportMessage(3), errorAddress)
                               ));
                }
Esempio n. 5
0
 public void Enrich(Activity activity, IOutgoingPhysicalMessageContext context)
 {
     var routes = context.RoutingStrategies
                  .Select(r => r.Apply(context.Headers))
                  .Select(t => t switch
     {
         UnicastAddressTag u => u.Destination,
         MulticastAddressTag m => m.MessageType.FullName,
         _ => null
     })
Esempio n. 6
0
        Task DispatchEditedMessage(OutgoingMessage editedMessage, string address, IMessageHandlerContext context)
        {
            AddressTag destination          = new UnicastAddressTag(address);
            var        transportTransaction = context.Extensions.GetOrCreate <TransportTransaction>();

            return(dispatcher.Dispatch(
                       new TransportOperations(new TransportOperation(editedMessage, destination)),
                       transportTransaction,
                       new ContextBag()));
        }
        TransportOperation CreateReplyOperation(object message)
        {
            var outHeaders = new Dictionary <string, string>
            {
                { Headers.EnclosedMessageTypes, message.GetType().AssemblyQualifiedName },
            };

            var body = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message));

            var outgoingMessage     = new OutgoingMessage(Guid.NewGuid().ToString(), outHeaders, body);
            var replyToAddress      = new UnicastAddressTag(headers[Headers.ReplyToAddress]);
            var transportOperations = new TransportOperation(outgoingMessage, replyToAddress);

            return(transportOperations);
        }
Esempio n. 8
0
        public async Task Should_route_to_local_instance_if_requested_so()
        {
            var behavior = InitializeBehavior(sharedQueue: "MyLocalAddress", instanceSpecificQueue: "MyInstance");
            var options  = new SendOptions();

            options.RouteToThisInstance();

            var context = CreateContext(options);

            UnicastAddressTag addressTag = null;
            await behavior.Invoke(context, c =>
            {
                addressTag = (UnicastAddressTag)c.RoutingStrategies.Single().Apply(new Dictionary <string, string>());
                return(TaskEx.CompletedTask);
            });

            Assert.AreEqual("MyInstance", addressTag.Destination);
        }
Esempio n. 9
0
        public async Task Should_use_explicit_route_for_sends_if_present()
        {
            var behavior = InitializeBehavior();
            var options  = new SendOptions();

            options.SetDestination("destination endpoint");

            var context = CreateContext(options);

            UnicastAddressTag addressTag = null;
            await behavior.Invoke(context, c =>
            {
                addressTag = (UnicastAddressTag)c.RoutingStrategies.Single().Apply(new Dictionary <string, string>());
                return(TaskEx.CompletedTask);
            });

            Assert.AreEqual("destination endpoint", addressTag.Destination);
        }
Esempio n. 10
0
        public async Task Should_use_router_to_route()
        {
            var logicalRouter = new FakeRouter {
                FixedDestination = new UnicastRoutingStrategy("LogicalAddress")
            };

            var behavior = InitializeBehavior(logicalRouter);

            var context = CreateContext();

            UnicastAddressTag addressTag = null;
            await behavior.Invoke(context, c =>
            {
                addressTag = (UnicastAddressTag)c.RoutingStrategies.Single().Apply(new Dictionary <string, string>());
                return(Task.CompletedTask);
            });

            Assert.AreEqual("LogicalAddress", addressTag.Destination);
        }
        public override void OnStartActivity(Activity activity, object payload)
        {
            if (!(payload is IOutgoingPhysicalMessageContext context))
            {
                return;
            }

            activity.SetKind(ActivityKind.Producer);

            context.Headers.TryGetValue(Headers.MessageIntent, out var intent);

            var routes = context.RoutingStrategies
                         .Select(r => r.Apply(context.Headers))
                         .Select(t => t switch
            {
                UnicastAddressTag u => u.Destination,
                MulticastAddressTag m => m.MessageType.Name,
                _ => null
            })
Esempio n. 12
0
        async Task RawSending(IDispatchMessages dispatcher)
        {
            #region DispatcherRawSending

            Dictionary <string, string> headers         = new Dictionary <string, string>();
            OutgoingMessage             outgoingMessage = new OutgoingMessage("MessageId", headers, new byte[]
            {
            });
            NonDurableDelivery[] constraints =
            {
                new NonDurableDelivery()
            };
            UnicastAddressTag   address            = new UnicastAddressTag("Destination");
            TransportOperation  transportOperation = new TransportOperation(outgoingMessage, address, DispatchConsistency.Default, constraints);
            TransportOperations operations         = new TransportOperations(transportOperation);
            await dispatcher.Dispatch(operations, new ContextBag());

            #endregion
        }
Esempio n. 13
0
        public async Task Should_route_using_the_mappings_if_no_destination_is_set()
        {
            var router = new FakeSendRouter
            {
                FixedDestination = new UnicastRoutingStrategy("MappedDestination")
            };
            var behavior = InitializeBehavior(router: router);
            var options  = new SendOptions();

            var context = CreateContext(options);

            UnicastAddressTag addressTag = null;
            await behavior.Invoke(context, c =>
            {
                addressTag = (UnicastAddressTag)c.RoutingStrategies.Single().Apply(new Dictionary <string, string>());
                return(TaskEx.CompletedTask);
            });

            Assert.AreEqual("MappedDestination", addressTag.Destination);
        }
Esempio n. 14
0
        public async Task Should_use_explicit_route_for_replies_if_present()
        {
            var behavior = new UnicastReplyRouterConnector();
            var options  = new ReplyOptions();

            options.SetDestination("CustomReplyToAddress");

            var context = CreateContext(new OutgoingLogicalMessage(typeof(MyReply), new MyReply()));

            context.Extensions = options.Context;

            UnicastAddressTag addressTag = null;
            await behavior.Invoke(context, c =>
            {
                addressTag = (UnicastAddressTag)c.RoutingStrategies.Single().Apply(new Dictionary <string, string>());
                return(TaskEx.CompletedTask);
            });

            Assert.AreEqual("CustomReplyToAddress", addressTag.Destination);
        }
Esempio n. 15
0
        public async Task <int> Retry(IncomingMessage message, TimeSpan delay, TransportTransaction transportTransaction, CancellationToken cancellationToken = default)
        {
            var outgoingMessage = new OutgoingMessage(message.MessageId, new Dictionary <string, string>(message.Headers), message.Body);

            var currentDelayedRetriesAttempt = message.GetDelayedDeliveriesPerformed() + 1;

            outgoingMessage.SetCurrentDelayedDeliveries(currentDelayedRetriesAttempt);
            outgoingMessage.SetDelayedDeliveryTimestamp(DateTimeOffset.UtcNow);

            var dispatchProperties = new DispatchProperties
            {
                DelayDeliveryWith = new DelayDeliveryWith(delay)
            };
            var messageDestination = new UnicastAddressTag(endpointInputQueue);

            var transportOperations = new TransportOperations(new TransportOperation(outgoingMessage, messageDestination, dispatchProperties));

            await dispatcher.Dispatch(transportOperations, transportTransaction, cancellationToken).ConfigureAwait(false);

            return(currentDelayedRetriesAttempt);
        }
Esempio n. 16
0
        public async Task Should_default_to_reply_address_of_incoming_message_for_replies()
        {
            var behavior = new UnicastReplyRouterConnector();

            var context = CreateContext(new OutgoingLogicalMessage(typeof(MyReply), new MyReply()));

            context.Extensions.Set(new IncomingMessage(
                                       "id",
                                       new Dictionary <string, string>
            {
                { Headers.ReplyToAddress, "ReplyAddressOfIncomingMessage" }
            },
                                       new byte[0]));

            UnicastAddressTag addressTag = null;
            await behavior.Invoke(context, c =>
            {
                addressTag = (UnicastAddressTag)c.RoutingStrategies.Single().Apply(new Dictionary <string, string>());
                return(TaskEx.CompletedTask);
            });

            Assert.AreEqual("ReplyAddressOfIncomingMessage", addressTag.Destination);
        }
Esempio n. 17
0
        public async Task RawSending()
        {
            IDispatchMessages dispatcher = null;

            #region DispatcherRawSending

            var headers         = new Dictionary <string, string>();
            var outgoingMessage = new OutgoingMessage("MessageId", headers, new byte[]
            {
            });
            var constraints = new[]
            {
                new NonDurableDelivery()
            };
            UnicastAddressTag         address                             = new UnicastAddressTag("Destination");
            TransportOperation        transportOperation                  = new TransportOperation(outgoingMessage, address, DispatchConsistency.Default, constraints);
            UnicastTransportOperation unicastTransportOperation           = new UnicastTransportOperation(outgoingMessage, "destination");
            IEnumerable <MulticastTransportOperation> multicastOperations = Enumerable.Empty <MulticastTransportOperation>();
            UnicastTransportOperation[] unicastOperations                 = { unicastTransportOperation };
            TransportOperations         operations                        = new TransportOperations(multicastOperations, unicastOperations);
            await dispatcher.Dispatch(operations, new ContextBag());

            #endregion
        }
Esempio n. 18
0
        async Task RawSending(IDispatchMessages dispatcher)
        {
            #region DispatcherRawSending

            var headers         = new Dictionary <string, string>();
            var outgoingMessage = new OutgoingMessage("MessageId", headers, new byte[]
            {
            });
            var constraints = new List <DeliveryConstraint>
            {
                new NonDurableDelivery()
            };
            var address   = new UnicastAddressTag("Destination");
            var operation = new TransportOperation(
                message: outgoingMessage,
                addressTag: address,
                requiredDispatchConsistency: DispatchConsistency.Default,
                deliveryConstraints: constraints);
            var operations = new TransportOperations(operation);
            await dispatcher.Dispatch(operations, new TransportTransaction(), new ContextBag())
            .ConfigureAwait(false);

            #endregion
        }