public void When_multiple_dynamic_instances_for_logical_endpoints_should_round_robin()
        {
            var sales        = "Sales";
            var routingTable = new UnicastRoutingTable();

            routingTable.AddOrReplaceRoutes("A", new List <RouteTableEntry>
            {
                new RouteTableEntry(typeof(MyMessage), UnicastRoute.CreateFromEndpointName(sales))
            });

            var endpointInstances = new EndpointInstances();

            endpointInstances.AddOrReplaceInstances("A", new List <EndpointInstance>
            {
                new EndpointInstance(sales, "1"),
                new EndpointInstance(sales, "2"),
            });

            var context = CreateContext(new SendOptions(), new MyMessage());

            var router = CreateRouter(routingTable: routingTable, instances: endpointInstances);
            var route1 = router.Route(context);
            var route2 = router.Route(context);
            var route3 = router.Route(context);

            Assert.AreEqual("Sales-1", ExtractDestination(route1));
            Assert.AreEqual("Sales-2", ExtractDestination(route2));
            Assert.AreEqual("Sales-1", ExtractDestination(route3));
        }
        public void When_multiple_dynamic_instances_for_local_endpoint_and_instance_selected_should_not_round_robin()
        {
            var routingTable = new UnicastRoutingTable();

            routingTable.AddOrReplaceRoutes("A", new List <RouteTableEntry>
            {
                new RouteTableEntry(typeof(MyMessage), UnicastRoute.CreateFromEndpointName("Endpoint"))
            });

            var endpointInstances = new EndpointInstances();

            endpointInstances.AddOrReplaceInstances("A", new List <EndpointInstance>
            {
                new EndpointInstance("Endpoint", "1"),
                new EndpointInstance("Endpoint", "2"),
            });

            var options = new SendOptions();

            options.RouteToSpecificInstance("2");

            var context = CreateContext(options, new MyMessage());

            var router = CreateRouter(routingTable: routingTable, instances: endpointInstances);
            var route1 = router.Route(context);
            var route2 = router.Route(context);
            var route3 = router.Route(context);

            Assert.AreEqual("Endpoint-2", ExtractDestination(route1));
            Assert.AreEqual("Endpoint-2", ExtractDestination(route2));
            Assert.AreEqual("Endpoint-2", ExtractDestination(route3));
        }
        public void When_routing_to_specific_instance_should_select_appropriate_instance()
        {
            var table     = new UnicastRoutingTable();
            var instances = new EndpointInstances();

            table.AddOrReplaceRoutes("A", new List <RouteTableEntry>
            {
                new RouteTableEntry(typeof(MyMessage), UnicastRoute.CreateFromEndpointName("Endpoint"))
            });
            instances.AddOrReplaceInstances("A", new List <EndpointInstance>
            {
                new EndpointInstance("Endpoint", "1"),
                new EndpointInstance("Endpoint", "2"),
                new EndpointInstance("Endpoint", "3")
            });
            var router  = CreateRouter(routingTable: table, instances: instances);
            var options = new SendOptions();

            options.RouteToSpecificInstance("2");

            var context = CreateContext(options);

            var route = router.Route(context);

            Assert.AreEqual("Endpoint-2", ExtractDestination(route));
        }
    async Task UpdateCaches(EndpointInstance instanceName, Type[] handledTypes, Type[] publishedTypes)
    {
        var newInstanceMap  = BuildNewInstanceMap(instanceName);
        var newEndpointMap  = BuildNewEndpointMap(instanceName.Endpoint, handledTypes, endpointMap);
        var newPublisherMap = BuildNewPublisherMap(instanceName, publishedTypes, publisherMap);

        LogChangesToEndpointMap(endpointMap, newEndpointMap);
        LogChangesToInstanceMap(instanceMap, newInstanceMap);
        var toSubscribe = LogChangesToPublisherMap(publisherMap, newPublisherMap).ToArray();

        #region AddOrReplace

        routingTable.AddOrReplaceRoutes("AutomaticRouting", newEndpointMap.Select(
                                            x => new RouteTableEntry(x.Key, UnicastRoute.CreateFromEndpointName(x.Value))).ToList());

        publishers.AddOrReplacePublishers("AutomaticRouting", newPublisherMap.Select(
                                              x => new PublisherTableEntry(x.Key, PublisherAddress.CreateFromEndpointName(x.Value))).ToList());

        endpointInstances.AddOrReplaceInstances("AutomaticRouting", newInstanceMap.SelectMany(x => x.Value).ToList());

        #endregion

        instanceMap  = newInstanceMap;
        endpointMap  = newEndpointMap;
        publisherMap = newPublisherMap;

        foreach (var type in toSubscribe.Intersect(messageTypesHandledByThisEndpoint))
        {
            await messageSession.Subscribe(type)
            .ConfigureAwait(false);
        }
    }
 protected override Task OnStart(IMessageSession session)
 {
     timer = new Timer(_ =>
     {
         routeTable.AddOrReplaceRoutes("MySource", LoadRoutes());
     }, null, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(30));
     return(Task.FromResult(0));
 }
예제 #6
0
        public void When_routes_are_ambiguous_should_throw_exception()
        {
            var routingTable      = new UnicastRoutingTable();
            var lowPriorityRoute  = UnicastRoute.CreateFromEndpointName("Endpoint1");
            var highPriorityRoute = UnicastRoute.CreateFromEndpointName("Endpoint2");

            routingTable.AddOrReplaceRoutes("key2", new List <RouteTableEntry>()
            {
                new RouteTableEntry(typeof(Command), highPriorityRoute),
            });

            Assert.That(() =>
            {
                routingTable.AddOrReplaceRoutes("key1", new List <RouteTableEntry>()
                {
                    new RouteTableEntry(typeof(Command), lowPriorityRoute),
                });
            }, Throws.Exception);
        }
예제 #7
0
        public void When_group_exists_should_replace_existing_routes()
        {
            var routingTable = new UnicastRoutingTable();
            var oldRoute     = UnicastRoute.CreateFromEndpointName("Endpoint1");
            var newRoute     = UnicastRoute.CreateFromEndpointName("Endpoint2");

            routingTable.AddOrReplaceRoutes("key", new List <RouteTableEntry>()
            {
                new RouteTableEntry(typeof(Command), oldRoute),
            });

            routingTable.AddOrReplaceRoutes("key", new List <RouteTableEntry>()
            {
                new RouteTableEntry(typeof(Command), newRoute),
            });

            var retrievedRoute = routingTable.GetRouteFor(typeof(Command));

            Assert.AreSame(newRoute, retrievedRoute);
        }
예제 #8
0
 protected override Task OnStart(IMessageSession session)
 {
     timer = new Timer(
         callback: _ =>
     {
         routeTable.AddOrReplaceRoutes("MySource", LoadRoutes());
     },
         state: null,
         dueTime: TimeSpan.FromSeconds(30),
         period: TimeSpan.FromSeconds(30));
     return(Task.CompletedTask);
 }
 public void Apply(UnicastRoutingTable unicastRoutingTable, Conventions conventions)
 {
     var entries = new Dictionary<Type, RouteTableEntry>();
     foreach (var source in routeSources.OrderBy(x => x.Priority)) //Higher priority routes sources override lower priority.
     {
         foreach (var route in source.GenerateRoutes(conventions))
         {
             entries[route.MessageType] = route;
         }
     }
     unicastRoutingTable.AddOrReplaceRoutes("EndpointConfiguration", entries.Values.ToList());
 }
예제 #10
0
        public void Apply(UnicastRoutingTable unicastRoutingTable, Conventions conventions)
        {
            var entries = new Dictionary <Type, RouteTableEntry>();

            foreach (var source in routeSources.OrderBy(x => x.Priority)) //Higher priority routes sources override lower priority.
            {
                foreach (var route in source.GenerateRoutes(conventions))
                {
                    entries[route.MessageType] = route;
                }
            }
            unicastRoutingTable.AddOrReplaceRoutes("EndpointConfiguration", entries.Values.ToList());
        }
 protected override Task OnStart(IMessageSession session)
 {
     timer = new Timer(_ =>
     {
         try
         {
             routeTable.AddOrReplaceRoutes("MySource", LoadRoutes());
         }
         catch (Exception ex)
         {
             criticalError.Raise("Ambiguous route detected", ex);
         }
     }, null, TimeSpan.FromSeconds(30), TimeSpan.FromSeconds(30));
     return(Task.FromResult(0));
 }
        public void When_route_with_endpoint_instance_routes_to_instance()
        {
            var routingTable = new UnicastRoutingTable();

            routingTable.AddOrReplaceRoutes("A", new List <RouteTableEntry>
            {
                new RouteTableEntry(typeof(MyMessage), UnicastRoute.CreateFromEndpointInstance(new EndpointInstance("Endpoint", "2")))
            });

            var context = CreateContext(new SendOptions(), new MyMessage());

            var router = CreateRouter(routingTable: routingTable);
            var route  = router.Route(context);

            Assert.AreEqual("Endpoint-2", ExtractDestination(route));
        }
        public void When_route_with_physical_address_routes_to_physical_address()
        {
            var routingTable = new UnicastRoutingTable();

            routingTable.AddOrReplaceRoutes("A", new List <RouteTableEntry>
            {
                new RouteTableEntry(typeof(MyMessage), UnicastRoute.CreateFromPhysicalAddress("Physical"))
            });

            var context = CreateContext(new SendOptions(), new MyMessage());

            var router = CreateRouter(routingTable: routingTable);
            var route  = router.Route(context);

            Assert.AreEqual("Physical", ExtractDestination(route));
        }
        public void When_routing_command_to_logical_endpoint_without_configured_instances_should_route_to_a_single_destination()
        {
            var logicalEndpointName = "Sales";
            var routingTable        = new UnicastRoutingTable();

            routingTable.AddOrReplaceRoutes("A", new List <RouteTableEntry>
            {
                new RouteTableEntry(typeof(MyMessage), UnicastRoute.CreateFromEndpointName(logicalEndpointName))
            });

            var context = CreateContext(new SendOptions(), new MyMessage());

            var router = CreateRouter(routingTable: routingTable);
            var route  = router.Route(context);

            Assert.AreEqual(logicalEndpointName, ExtractDestination(route));
        }
예제 #15
0
 protected override Task OnStart(IMessageSession session)
 {
     timer = new Timer(
         callback: _ =>
     {
         try
         {
             routeTable.AddOrReplaceRoutes("MySource", LoadRoutes());
         }
         catch (Exception exception)
         {
             criticalError.Raise("Ambiguous route detected", exception);
         }
     },
         state: null,
         dueTime: TimeSpan.FromSeconds(30),
         period: TimeSpan.FromSeconds(30));
     return(Task.CompletedTask);
 }
        public void When_routing_to_specific_instance_should_throw_when_route_for_given_type_points_to_physical_address()
        {
            var table = new UnicastRoutingTable();

            table.AddOrReplaceRoutes("A", new List <RouteTableEntry>
            {
                new RouteTableEntry(typeof(MyMessage), UnicastRoute.CreateFromPhysicalAddress("PhysicalAddress"))
            });
            var router  = CreateRouter(routingTable: table);
            var options = new SendOptions();

            options.RouteToSpecificInstance("instanceId");

            var context = CreateContext(options);

            var exception = Assert.Throws <Exception>(() => router.Route(context));

            StringAssert.Contains("Routing to a specific instance is only allowed if route is defined for a logical endpoint, not for an address or instance.", exception.Message);
        }
예제 #17
0
        static void UpdateRoutingTable(DatabaseReader databaseReader, string connectionString, UnicastRoutingTable routingTable, UnicastSubscriberTable subscriberTable, bool nativeSends, bool nativePublishes)
        {
            try
            {
                var endpoints = databaseReader.GetEndpoints(connectionString);

                var commandRoutes = new List <RouteTableEntry>();
                var eventRoutes   = new List <RouteTableEntry>();

                foreach (var endpoint in endpoints)
                {
                    var route = UnicastRoute.CreateFromEndpointName(endpoint.LogicalEndpointName);
                    foreach (var commandType in endpoint.Commands)
                    {
                        if (nativeSends)
                        {
                            _log.Warn($"Selected transport uses native command routing. Route for {commandType.FullName} to {endpoint.LogicalEndpointName} configured in database will be ignored.");
                        }
                        commandRoutes.Add(new RouteTableEntry(commandType, route));
                    }

                    foreach (var eventType in endpoint.Events)
                    {
                        if (nativePublishes)
                        {
                            _log.Warn($"Selected transport uses native event routing. Route for {eventType.FullName} to {endpoint.LogicalEndpointName} configured in database will be ignored.");
                        }
                        eventRoutes.Add(new RouteTableEntry(eventType, route));
                    }
                }

                routingTable.AddOrReplaceRoutes("DatabaseBasedRouting", commandRoutes);
                subscriberTable.AddOrReplaceRoutes("DatabaseBasedRouting", eventRoutes);

                _log.Debug($"Updated routing information from database");
            }
            catch (Exception e)
            {
                _log.Error($"Failed to update routing information from database. The last valid routing configuration will be used instead.", e);
                throw;
            }
        }
예제 #18
0
        static void UpdateRoutingTable(XmlRoutingFileParser routingFileParser, XmlRoutingFileAccess routingFile, UnicastRoutingTable routingTable, UnicastSubscriberTable subscriberTable, bool nativeSends, bool nativePublishes)
        {
            try
            {
                var endpoints = routingFileParser.Parse(routingFile.Read());

                var commandRoutes = new List <RouteTableEntry>();
                var eventRoutes   = new List <RouteTableEntry>();

                foreach (var endpoint in endpoints)
                {
                    var route = UnicastRoute.CreateFromEndpointName(endpoint.LogicalEndpointName);
                    foreach (var commandType in endpoint.Commands)
                    {
                        if (nativeSends)
                        {
                            log.Warn($"Selected transport uses native command routing. Route for {commandType.FullName} to {endpoint.LogicalEndpointName} configured in {routingFile.FileUri} will be ignored.");
                        }
                        commandRoutes.Add(new RouteTableEntry(commandType, route));
                    }

                    foreach (var eventType in endpoint.Events)
                    {
                        if (nativePublishes)
                        {
                            log.Warn($"Selected transport uses native event routing. Route for {eventType.FullName} to {endpoint.LogicalEndpointName} configured in {routingFile.FileUri} will be ignored.");
                        }
                        eventRoutes.Add(new RouteTableEntry(eventType, route));
                    }
                }

                routingTable.AddOrReplaceRoutes("FileBasedRouting", commandRoutes);
                subscriberTable.AddOrReplaceRoutes("FileBasedRouting", eventRoutes);

                log.Debug($"Updated routing information from {routingFile.FileUri}");
            }
            catch (Exception e)
            {
                log.Error($"Failed to update routing information from {routingFile.FileUri}. The last valid routing configuration will be used instead.", e);
                throw;
            }
        }
        internal void Apply(Publishers publishers, UnicastRoutingTable unicastRoutingTable, Func <string, string> makeCanonicalAddress, Conventions conventions)
        {
            var routeTableEntries     = new Dictionary <Type, RouteTableEntry>();
            var publisherTableEntries = new List <PublisherTableEntry>();

            foreach (var m in this.Cast <MessageEndpointMapping>().OrderByDescending(m => m))
            {
                m.Configure((type, endpointAddress) =>
                {
                    if (!conventions.IsMessageType(type))
                    {
                        return;
                    }
                    var canonicalForm = makeCanonicalAddress(endpointAddress);
                    var baseTypes     = GetBaseTypes(type, conventions);

                    RegisterMessageRoute(type, canonicalForm, routeTableEntries, baseTypes);
                    RegisterEventRoute(type, canonicalForm, publisherTableEntries, baseTypes);
                });
            }

            publishers.AddOrReplacePublishers("MessageEndpointMappings", publisherTableEntries);
            unicastRoutingTable.AddOrReplaceRoutes("MessageEndpointMappings", routeTableEntries.Values.ToList());
        }
예제 #20
0
        void UpdateRoutes()
        {
            var entries = routeState.Values.Select(r => r.CreateEntry()).ToList();

            routingTable.AddOrReplaceRoutes("NServiceBus.Router.Migrator", entries);
        }
        internal void Apply(Publishers publishers, UnicastRoutingTable unicastRoutingTable, Func<string, string> makeCanonicalAddress, Conventions conventions)
        {
            var routeTableEntries = new Dictionary<Type, RouteTableEntry>();
            var publisherTableEntries = new List<PublisherTableEntry>();

            foreach (var m in this.Cast<MessageEndpointMapping>().OrderByDescending(m => m))
            {
                m.Configure((type, endpointAddress) =>
                {
                    if (!conventions.IsMessageType(type))
                    {
                        return;
                    }
                    var canonicalForm = makeCanonicalAddress(endpointAddress);
                    var baseTypes = GetBaseTypes(type, conventions);

                    RegisterMessageRoute(type, canonicalForm, routeTableEntries, baseTypes);
                    RegisterEventRoute(type, canonicalForm, publisherTableEntries, baseTypes);
                });
            }

            publishers.AddOrReplacePublishers("MessageEndpointMappings", publisherTableEntries);
            unicastRoutingTable.AddOrReplaceRoutes("MessageEndpointMappings", routeTableEntries.Values.ToList());
        }