Beispiel #1
0
        /// <summary>
        /// Starts the endpoint and returns a reference to it.
        /// </summary>
        /// <param name="startableEndpoint">The startable endpoint.</param>
        /// <param name="serviceProvider">The container specific service provider factory.</param>
        /// <returns>A reference to the endpoint.</returns>
        public static Task <IEndpointInstance> Start(this IStartableEndpointWithExternallyManagedContainer startableEndpoint, IServiceProvider serviceProvider)
        {
            Guard.AgainstNull(nameof(startableEndpoint), startableEndpoint);
            Guard.AgainstNull(nameof(serviceProvider), serviceProvider);

            return(startableEndpoint.Start(new ServiceProviderAdapter(serviceProvider)));
        }
        public async Task Should_use_it_for_component_resolution()
        {
            var container = new AcceptanceTestingContainer();

            container.RegisterSingleton(typeof(MyComponent), myComponent);

            var result = await Scenario.Define <Context>()
                         .WithEndpoint <ExternallyManagedContainerEndpoint>(b =>
            {
                IStartableEndpointWithExternallyManagedContainer configuredEndpoint = null;

                b.ToCreateInstance(
                    config =>
                {
                    configuredEndpoint = EndpointWithExternallyManagedContainer.Create(config, new RegistrationPhaseAdapter(container));
                    return(Task.FromResult(configuredEndpoint));
                },
                    configured => configured.Start(new ResolutionPhaseAdapter(container))
                    )
                .When((e, c) =>
                {
                    c.BuilderWasResolvable = container.Build(typeof(IBuilder)) != null;

                    //use the session provided by configure to make sure its properly populated
                    return(configuredEndpoint.MessageSession.Value.SendLocal(new SomeMessage()));
                });
            })
                         .Done(c => c.Message != null)
                         .Run();

            Assert.AreEqual(result.Message, myComponent.Message);
            Assert.True(result.BuilderWasResolvable, "IBuilder should be resolvable in the container");
            Assert.False(container.WasDisposed, "Externally managed containers should not be disposed");
        }
Beispiel #3
0
 public NserviceBusEndpoint(string endPointName, IServiceCollection services)
 {
     endpointConfiguration = new EndpointConfiguration(endPointName);
     endpointConfiguration.UseTransport <LearningTransport>();
     startableEndPoint = EndpointWithExternallyManagedServiceProvider
                         .Create(endpointConfiguration, services);
 }
        public async Task Should_use_it_for_component_resolution()
        {
            var serviceCollection = new ServiceCollection();

            serviceCollection.AddSingleton(typeof(MyComponent), myComponent);

            var result = await Scenario.Define <Context>()
                         .WithEndpoint <ExternallyManagedContainerEndpoint>(b =>
            {
                IStartableEndpointWithExternallyManagedContainer configuredEndpoint = null;

                b.ToCreateInstance(
                    config =>
                {
                    configuredEndpoint = EndpointWithExternallyManagedContainer.Create(config, serviceCollection);
                    return(Task.FromResult(configuredEndpoint));
                },
                    configured => configured.Start(serviceCollection.BuildServiceProvider())
                    )
                .When((e, c) =>
                {
                    //use the session provided by configure to make sure its properly populated
                    return(configuredEndpoint.MessageSession.Value.SendLocal(new SomeMessage()));
                });
            })
                         .Done(c => c.MessageReceived)
                         .Run();

            Assert.NotNull(result.ServiceProvider, "IServiceProvider should be injectable");
            Assert.AreSame(myComponent, result.CustomService, "Should inject custom services");
        }
Beispiel #5
0
 public InProcessFunctionEndpoint(
     IStartableEndpointWithExternallyManagedContainer externallyManagedContainerEndpoint,
     ServiceBusTriggeredEndpointConfiguration configuration,
     IServiceProvider serviceProvider)
 {
     this.configuration = configuration;
     endpointFactory    = _ => externallyManagedContainerEndpoint.Start(serviceProvider);
 }
 public NServiceBusHostedService(IStartableEndpointWithExternallyManagedContainer startableEndpoint,
                                 IServiceProvider serviceProvider,
                                 ILoggerFactory loggerFactory,
                                 DeferredLoggerFactory deferredLoggerFactory,
                                 HostAwareMessageSession hostAwareMessageSession)
 {
     this.loggerFactory           = loggerFactory;
     this.deferredLoggerFactory   = deferredLoggerFactory;
     this.hostAwareMessageSession = hostAwareMessageSession;
     this.startableEndpoint       = startableEndpoint;
     this.serviceProvider         = serviceProvider;
 }
Beispiel #7
0
 public NServiceBusService(IStartableEndpointWithExternallyManagedContainer startableEndpoint, IServiceProvider serviceProvider)
 {
     this.startableEndpoint = startableEndpoint;
     this.serviceProvider   = serviceProvider;
 }
Beispiel #8
0
        public static async Task <IEndpointInstance> Start(IStartableEndpointWithExternallyManagedContainer nsb)
        {
            BusOnline = false;
            Instance  = await nsb.Start(new Internal.ContainerAdapter(Configuration.Settings.Container)).ConfigureAwait(false);

            // Take IEndpointInstance and pull out the info we need for eventstore consuming

            // We want eventstore to push message directly into NSB
            // That way we can have all the fun stuff like retries, error queues, incoming/outgoing mutators etc
            // But NSB doesn't have a way to just insert a message directly into the pipeline
            // You can SendLocal which will send the event out to the transport then back again but in addition to being a
            // waste of time its not safe incase this instance goes down because we'd have ACKed the event now sitting
            // unprocessed on the instance specific queue.
            //
            // The only way I can find to call into the pipeline directly is to highjack these private fields on
            // the transport receiver.
            try
            {
                var receiveComponent = Instance.GetType()
                                       .GetField("receiveComponent", BindingFlags.Instance | BindingFlags.NonPublic)
                                       .GetValue(Instance);

                var receivers = (
                    (IEnumerable)
                    // ReSharper disable once PossibleNullReferenceException
                    receiveComponent.GetType()
                    .GetField("receivers", BindingFlags.Instance | BindingFlags.NonPublic)
                    .GetValue(receiveComponent)).Cast <object>();
                object main = null;
                foreach (var receiver in receivers)
                {
                    var id =
                        (string)
                        receiver.GetType()
                        .GetProperty("Id", BindingFlags.Public | BindingFlags.Instance)
                        .GetValue(receiver);
                    if (id.ToLower() == "main")
                    {
                        main = receiver;
                        break;
                    }
                }
                if (main == null)
                {
                    throw new InvalidOperationException("Could not find main receiver");
                }

                var pipelineExecutor =
                    main.GetType()
                    .GetField("pipelineExecutor", BindingFlags.Instance | BindingFlags.NonPublic)
                    .GetValue(main);
                var recoverabilityExecutor =
                    main.GetType()
                    .GetField("recoverabilityExecutor", BindingFlags.Instance | BindingFlags.NonPublic)
                    .GetValue(main);
                var mainPipeline = pipelineExecutor
                                   .GetType()
                                   .GetField("mainPipeline", BindingFlags.Instance | BindingFlags.NonPublic)
                                   .GetValue(pipelineExecutor);
                var behaviors = mainPipeline
                                .GetType()
                                .GetField("behaviors", BindingFlags.Instance | BindingFlags.NonPublic)
                                .GetValue(mainPipeline) as IBehavior[];

                var pipelineMethod = pipelineExecutor.GetType().GetMethod("Invoke", BindingFlags.Instance | BindingFlags.Public)
                                     .MakeFuncDelegateWithTarget <MessageContext, Task>(pipelineExecutor.GetType());

                OnMessage = (c) => pipelineMethod(pipelineExecutor, c);

                var recoverabilityMethod = recoverabilityExecutor.GetType()
                                           .GetMethod("Invoke", BindingFlags.Instance | BindingFlags.Public)
                                           .MakeFuncDelegateWithTarget <ErrorContext, Task <ErrorHandleResult> >(recoverabilityExecutor.GetType());

                OnError = (c) => recoverabilityMethod(recoverabilityExecutor, c);

                PushSettings = (PushRuntimeSettings)main.GetType()
                               .GetField("pushRuntimeSettings", BindingFlags.Instance | BindingFlags.NonPublic)
                               .GetValue(main);

                Logger.InfoEvent("Online", "NServiceBus is online");

                for (var i = 0; i < behaviors.Length; i++)
                {
                    Logger.DebugEvent("PipelineStep", "{Index}: {StepType}", i, behaviors[i].GetType().FullName);
                }

                BusOnline = true;
                return(Instance);
            }
            catch (Exception e)
            {
                throw new InvalidOperationException("Could not hack into NSB - event consumer won't work", e);
            }
        }
Beispiel #9
0
        public static Configure NServiceBus(this Configure config, EndpointConfiguration endpointConfig)
        {
            IStartableEndpointWithExternallyManagedContainer startableEndpoint = null;

            {
                var settings    = endpointConfig.GetSettings();
                var conventions = endpointConfig.Conventions();

                // set the configured endpoint name to the one NSB config was constructed with
                config.SetEndpointName(settings.Get <string>("NServiceBus.Routing.EndpointName"));

                conventions.DefiningCommandsAs(type => typeof(Messages.ICommand).IsAssignableFrom(type));
                conventions.DefiningEventsAs(type => typeof(Messages.IEvent).IsAssignableFrom(type));
                conventions.DefiningMessagesAs(type => typeof(Messages.IMessage).IsAssignableFrom(type));

                endpointConfig.AssemblyScanner().ScanAppDomainAssemblies = true;
                endpointConfig.EnableCallbacks();
                endpointConfig.EnableInstallers();

                endpointConfig.UseSerialization <Internal.AggregatesSerializer>();
                endpointConfig.EnableFeature <Feature>();
            }


            config.RegistrationTasks.Add(c =>
            {
                var container = c.Container;

                container.Register(factory => new Aggregates.Internal.DelayedRetry(factory.Resolve <IMetrics>(), factory.Resolve <IMessageDispatcher>()), Lifestyle.Singleton);

                container.Register <IEventMapper>((factory) => new EventMapper(factory.Resolve <IMessageMapper>()), Lifestyle.Singleton);

                container.Register <UnitOfWork.IDomain>((factory) => new NSBUnitOfWork(factory.Resolve <IRepositoryFactory>(), factory.Resolve <IEventFactory>(), factory.Resolve <IVersionRegistrar>()), Lifestyle.UnitOfWork);
                container.Register <IEventFactory>((factory) => new EventFactory(factory.Resolve <IMessageMapper>()), Lifestyle.Singleton);
                container.Register <IMessageDispatcher>((factory) => new Dispatcher(factory.Resolve <IMetrics>(), factory.Resolve <IMessageSerializer>(), factory.Resolve <IEventMapper>(), factory.Resolve <IVersionRegistrar>()), Lifestyle.Singleton);
                container.Register <IMessaging>((factory) => new NServiceBusMessaging(factory.Resolve <MessageHandlerRegistry>(), factory.Resolve <MessageMetadataRegistry>(), factory.Resolve <ReadOnlySettings>()), Lifestyle.Singleton);

                var settings = endpointConfig.GetSettings();

                settings.Set("Retries", config.Retries);
                settings.Set("SlowAlertThreshold", config.SlowAlertThreshold);
                settings.Set("CommandDestination", config.CommandDestination);

                // Set immediate retries to 0 - we handle retries ourselves any message which throws should be sent to error queue
                endpointConfig.Recoverability().Immediate(x =>
                {
                    x.NumberOfRetries(0);
                });

                endpointConfig.Recoverability().Delayed(x =>
                {
                    x.NumberOfRetries(0);
                });


                endpointConfig.MakeInstanceUniquelyAddressable(c.UniqueAddress);
                endpointConfig.LimitMessageProcessingConcurrencyTo(c.ParallelMessages);
                // NSB doesn't have an endpoint name setter other than the constructor, hack it in
                settings.Set("NServiceBus.Routing.EndpointName", c.Endpoint);

                startableEndpoint = EndpointWithExternallyManagedContainer.Create(endpointConfig, new Internal.ContainerAdapter());

                return(Task.CompletedTask);
            });

            // Split creating the endpoint and starting the endpoint into 2 seperate jobs for certain (MICROSOFT) DI setup

            config.SetupTasks.Add((c) =>
            {
                return(Aggregates.Bus.Start(startableEndpoint));
            });

            return(config);
        }
 public NServiceBusHostedService(IStartableEndpointWithExternallyManagedContainer startableEndpoint)
 {
     this.startableEndpoint = startableEndpoint;
 }