private void ConfigureMassTransit(IServiceCollection services, ContainerBuilder containerBuilder) { services.AddScoped <IHostedService, MassTransitHostedService>(); //services.AddScoped<UserCheckoutAcceptedIntegrationEventHandler>(); containerBuilder.Register(c => { var busControl = Bus.Factory.CreateUsingRabbitMq(sbc => { var host = sbc.Host(new Uri(Configuration["EventBus:Uri"]), h => { h.Username(Configuration["EventBus:Username"]); h.Password(Configuration["EventBus:Password"]); }); /*sbc.ReceiveEndpoint(host, "basket_checkout_queue", e => * { * e.Consumer<UserCheckoutAcceptedIntegrationEventHandler>(c); * });*/ sbc.UseExtensionsLogging(_loggerFactory); }); var consumeObserver = new ConsumeObserver(_loggerFactory.CreateLogger <ConsumeObserver>()); busControl.ConnectConsumeObserver(consumeObserver); var sendObserver = new SendObserver(_loggerFactory.CreateLogger <SendObserver>()); busControl.ConnectSendObserver(sendObserver); return(busControl); }) .As <IBusControl>() .As <IPublishEndpoint>() .SingleInstance(); }
public async Task Should_trigger_the_send_message_observer_for_both_messages() { var observer = new SendObserver(this); var mediator = MassTransit.Bus.Factory.CreateMediator(cfg => { }); mediator.ConnectSendObserver(observer); TaskCompletionSource <ConsumeContext <PingMessage> > received = GetTask <ConsumeContext <PingMessage> >(); var handle = mediator.ConnectHandler <PingMessage>(x => { received.SetResult(x); return(x.RespondAsync(new PongMessage())); }); await mediator.Send(new PingMessage()); await received.Task; handle.Disconnect(); await observer.PreSent; await observer.PostSent; Assert.That(observer.PreSentCount, Is.EqualTo(2)); Assert.That(observer.PostSentCount, Is.EqualTo(2)); }
protected override void ConnectObservers(IBus bus) { base.ConnectObservers(bus); _observer = new SendObserver(); bus.ConnectSendObserver(_observer); }
// This method gets called by the runtime. Use this method to add services to the container. public IServiceProvider ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); services.Configure <PaymentSettings>(Configuration); services.AddEntityFrameworkNpgsql().AddDbContext <PaymentContext>(options => { options.UseNpgsql(Configuration["ConnectionString"], npgsqlOptionsAction: sqlOptions => { sqlOptions.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name); //Configuring Connection Resiliency: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency sqlOptions.EnableRetryOnFailure(maxRetryCount: 5); }); // Changing default behavior when client evaluation occurs to throw. // Default in EF Core would be to log a warning when client evaluation is performed. options.ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning)); //Check Client vs. Server evaluation: https://docs.microsoft.com/en-us/ef/core/querying/client-eval }); var containerBuilder = new ContainerBuilder(); services.AddScoped <IHostedService, MassTransitHostedService>(); services.AddScoped <OrderStatusChangedToStockConfirmedIntegrationEventHandler>(); containerBuilder.Register(c => { var busControl = Bus.Factory.CreateUsingRabbitMq(sbc => { var host = sbc.Host(new Uri(Configuration["EventBusConnection"]), h => { h.Username(Configuration["EventBusUserName"]); h.Password(Configuration["EventBusPassword"]); }); sbc.ReceiveEndpoint(host, "validate_payment_queue", e => { e.Consumer <OrderStatusChangedToStockConfirmedIntegrationEventHandler>(c); }); sbc.UseExtensionsLogging(_loggerFactory); }); var consumeObserver = new ConsumeObserver(_loggerFactory.CreateLogger <ConsumeObserver>()); busControl.ConnectConsumeObserver(consumeObserver); var sendObserver = new SendObserver(_loggerFactory.CreateLogger <SendObserver>()); busControl.ConnectSendObserver(sendObserver); return(busControl); }) .As <IBusControl>() .As <IPublishEndpoint>() .SingleInstance(); containerBuilder.Populate(services); return(new AutofacServiceProvider(containerBuilder.Build())); }
private void ConfigureMassTransit(IServiceCollection services, ContainerBuilder containerBuilder) { services.AddScoped <IHostedService, MassTransitHostedService>(); services.AddScoped <UserCheckoutAcceptedIntegrationEventHandler>(); containerBuilder.Register(c => { var busControl = Bus.Factory.CreateUsingRabbitMq(sbc => { var host = sbc.Host(new Uri(Configuration["EventBusConnection"]), h => { h.Username(Configuration["EventBusUserName"]); h.Password(Configuration["EventBusPassword"]); }); sbc.ReceiveEndpoint(host, "basket_checkout_queue", e => { e.Consumer <UserCheckoutAcceptedIntegrationEventHandler>(c); }); sbc.ReceiveEndpoint(host, "stock_confirmed_queue", e => { }); sbc.ReceiveEndpoint(host, "stock_rejected_queue", e => { }); sbc.ReceiveEndpoint(host, "payment_succeded_queue", e => { }); sbc.ReceiveEndpoint(host, "payment_failed_queue", e => { }); sbc.ReceiveEndpoint(host, "graceperiod_confirmed_queue", e => { }); sbc.ReceiveEndpoint(host, "order_validation_state", e => { e.UseRetry(x => { x.Handle <DbUpdateConcurrencyException>(); x.Interval(5, TimeSpan.FromMilliseconds(100)); }); // Add the retry middleware for optimistic concurrency e.StateMachineSaga(new GracePeriodStateMachine(c.Resolve <IAggregateStore>()), new InMemorySagaRepository <GracePeriod>()); }); sbc.UseExtensionsLogging(_loggerFactory); sbc.UseInMemoryScheduler(); }); var consumeObserver = new ConsumeObserver(_loggerFactory.CreateLogger <ConsumeObserver>()); busControl.ConnectConsumeObserver(consumeObserver); var sendObserver = new SendObserver(_loggerFactory.CreateLogger <SendObserver>()); busControl.ConnectSendObserver(sendObserver); return(busControl); }) .As <IBusControl>() .As <IPublishEndpoint>() .SingleInstance(); }
public async Task Should_invoke_the_observer_prior_to_send() { var observer = new SendObserver(); using (InputQueueSendEndpoint.ConnectSendObserver(observer)) { await InputQueueSendEndpoint.Send(new PingMessage()); await observer.PreSent; } }
public async Task Should_invoke_the_exception_after_send_failure() { var observer = new SendObserver(); using (InputQueueSendEndpoint.ConnectSendObserver(observer)) { Assert.That( async() => await InputQueueSendEndpoint.Send(new PingMessage(), Pipe.Execute <SendContext>(x => x.Serializer = null)), Throws.TypeOf <SerializationException>()); await observer.SendFaulted; } }
public async Task Should_not_invoke_post_sent_on_exception() { var observer = new SendObserver(); using (InputQueueSendEndpoint.ConnectSendObserver(observer)) { Assert.That(async() => await InputQueueSendEndpoint.Send(new PingMessage(), Pipe.Execute <SendContext>(x => x.Serializer = null)), Throws.TypeOf <SerializationException>()); await observer.SendFaulted; observer.PostSent.Status.ShouldBe(TaskStatus.WaitingForActivation); } }
public async Task Should_invoke_the_observer_prior_to_send() { var observer = new SendObserver(this); using (InputQueueSendEndpoint.ConnectSendObserver(observer)) { await InputQueueSendEndpoint.Send(new PingMessage()); await observer.PreSent; Assert.That(observer.PreSentCount, Is.EqualTo(1)); Assert.That(observer.PostSentCount, Is.EqualTo(1)); } }
public async Task Should_invoke_the_observer_after_send() { var observer = new SendObserver(this); using (Bus.ConnectSendObserver(observer)) { await InputQueueSendEndpoint.Send(new PingMessage(), context => context.ResponseAddress = BusAddress); await observer.PreSent; await observer.PostSent; await observer.SendFaulted; Assert.That(observer.PreSentCount, Is.EqualTo(2)); Assert.That(observer.PostSentCount, Is.EqualTo(1)); Assert.That(observer.SendFaultCount, Is.EqualTo(1)); } }
public async Task Should_not_invoke_the_send_observer_prior_to_send() { var observer = new PublishObserver(this); using (Bus.ConnectPublishObserver(observer)) { var sendObserver = new SendObserver(this); using (Bus.ConnectSendObserver(sendObserver)) { await Bus.Publish(new PingMessage()); await observer.PreSent; Assert.That(async() => await sendObserver.PreSent.OrTimeout(s: 5), Throws.TypeOf <TimeoutException>()); } } }
public async Task Setup() { _consumer = Harness.Consumer <TestCommandConsumer>(); await Harness.Start(); _publish = new PublishObserver(Harness); Harness.Bus.ConnectPublishObserver(_publish); _send = new SendObserver(Harness); Harness.Bus.ConnectSendObserver(_send); _correlationId = NewId.NextGuid(); await Harness.Bus.Publish <TestEvent>(new { CorrelationId = _correlationId }); }
public static void Main(string[] args) { Console.Title = "Masstransit Observer Publisher"; var bus = Bus.Factory.CreateUsingRabbitMq(cfg => { var host = cfg.Host(new Uri("rabbitmq://192.168.80.71/EDCVHOST"), hst => { hst.Username("admin"); hst.Password("edison"); }); }); var observer1 = new SendObserver(); var handle1 = bus.ConnectSendObserver(observer1); var observer2 = new PublishObserver(); var handle2 = bus.ConnectPublishObserver(observer2); bus.Start(); do { Console.WriteLine("Presss q if you want to exit this program."); string message = Console.ReadLine(); if (message.ToLower().Equals("q")) { break; } bus.Publish(new TestMessage { MessageId = 10001, Content = message, Time = DateTime.Now }); } while (true); bus.Stop(); }
// This method gets called by the runtime. Use this method to add services to the container. public IServiceProvider ConfigureServices(IServiceCollection services) { // Add framework services. services.AddMvc(options => { options.Filters.Add(typeof(HttpGlobalExceptionFilter)); options.Filters.Add(typeof(ValidateModelStateFilter)); }).AddControllersAsServices(); ConfigureAuthService(services); services.Configure <BasketSettings>(Configuration); //By connecting here we are making sure that our service //cannot start until redis is ready. This might slow down startup, //but given that there is a delay on resolving the ip address //and then creating the connection it seems reasonable to move //that cost to startup instead of having the first request pay the //penalty. services.AddSingleton <ConnectionMultiplexer>(sp => { var settings = sp.GetRequiredService <IOptions <BasketSettings> >().Value; var configuration = ConfigurationOptions.Parse(settings.ConnectionString, true); configuration.ResolveDns = true; return(ConnectionMultiplexer.Connect(configuration)); }); services.AddCors(options => { options.AddPolicy("CorsPolicy", policyBuilder => policyBuilder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials()); }); services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>(); services.AddTransient <IBasketRepository, RedisBasketRepository>(); services.AddTransient <IIdentityService, IdentityService>(); services.AddOptions(); // Configurar MassTransit services.AddScoped <IHostedService, MassTransitHostedService>(); services.AddScoped <ProductPriceChangedIntegrationEventHandler>(); services.AddScoped <OrderStartedIntegrationEventHandler>(); var builder = new ContainerBuilder(); builder.Register(c => { var busControl = Bus.Factory.CreateUsingRabbitMq(sbc => { var host = sbc.Host(new Uri(Configuration["EventBusConnection"]), h => { h.Username(Configuration["EventBusUserName"]); h.Password(Configuration["EventBusPassword"]); }); sbc.ReceiveEndpoint(host, "price_updated_queue", e => { e.Consumer <ProductPriceChangedIntegrationEventHandler>(c); }); sbc.ReceiveEndpoint(host, "order_started_queue", e => { e.Consumer <OrderStartedIntegrationEventHandler>(c); }); sbc.UseExtensionsLogging(_loggerFactory); }); var consumeObserver = new ConsumeObserver(_loggerFactory.CreateLogger <ConsumeObserver>()); busControl.ConnectConsumeObserver(consumeObserver); var sendObserver = new SendObserver(_loggerFactory.CreateLogger <SendObserver>()); busControl.ConnectSendObserver(sendObserver); return(busControl); }) .As <IBusControl>() .As <IPublishEndpoint>() .SingleInstance(); services.AddTransient <IValidator <CustomerBasket>, CustomerBasketValidator>(); builder.Populate(services); var container = builder.Build(); // Create the IServiceProvider based on the container. return(new AutofacServiceProvider(container)); }
/// <summary> /// Use MassTransit for message bus. /// </summary> /// <param name="configuration"></param> /// <param name="assembles"></param> /// <param name="endpointName"></param> /// <param name="retry"></param> /// <param name="isTransaction">Encapsulate the pipe behavior in a transaction</param> /// <param name="prefetchCount">Specify the maximum number of concurrent messages that are consumed</param> /// <returns></returns> public static Configurations.Configuration UseMassTransit( this Configurations.Configuration configuration, Assembly[] assembles = null, string endpointName = "", int retry = 0, bool isTransaction = false, ushort prefetchCount = 16) { var objectContainer = new AutofacObjectContainer(); string assemblyName = Assembly.GetCallingAssembly().GetName().Name; if (string.IsNullOrEmpty(endpointName)) { endpointName = assemblyName + "-" + Environment.MachineName; } Configurations.Configuration.Instance.Setting.EndPoint = endpointName; if (objectContainer != null) { var container = objectContainer.Container; var builder = new ContainerBuilder(); //consumer 不能加component,不然会注册2次 if (assembles != null) { foreach (var ass in assembles) { try { builder.RegisterConsumers(ass); } catch (ReflectionTypeLoadException loadException) { //目前写死判断,少dll报错,多dll跳过 var message = string.Join(",", loadException.LoaderExceptions.Select(c => c.Message).Distinct()); if (message.Contains("系统找不到指定的文件")) { throw new ApplicationException(message); } } } } var clusterHosts = configuration.Setting.TransportIp.Split(','); //var clusterHosts = "10.3.80.41"; builder.Register(context => { var busControl = Bus.Factory.CreateUsingRabbitMq(cfg => { configuration.Setting.TransportHost = string.Format("rabbitmq://{0}/{1}", clusterHosts[0], string.IsNullOrEmpty(configuration.Setting.TransportVirtualHost) ? "" : configuration.Setting.TransportVirtualHost + "/"); var host = cfg.Host(new Uri(configuration.Setting.TransportHost), h => { h.Username(configuration.Setting.TransportUserName); h.Password(configuration.Setting.TransportPassword); if (clusterHosts.Length > 0) { h.UseCluster(c => { foreach (var clusterHost in clusterHosts) { c.Node(clusterHost); } }); } }); //以机器名为消息总线队列名的方式暂保留 var endpointNames = new ArrayList { endpointName }; //分公司标识作为消息总线队列名 var branchs = CommonX.Configurations.Configuration.Instance.Setting.Branch?.Split(','); if (branchs != null && branchs.Length > 0) { foreach (var branchId in branchs) { string name = assemblyName + "-" + branchId; endpointNames.Add(name); } } //绑定消息总线 foreach (var a in endpointNames) { cfg.ReceiveEndpoint(host, a.ToString(), ec => { if (retry > 0) { ec.UseRetry(x => x.Incremental(retry, new TimeSpan(0, 0, 5), new TimeSpan(0, 0, 5))); } if (isTransaction) { ec.UseTransaction(x => { x.Timeout = TimeSpan.FromSeconds(300); }); } cfg.PrefetchCount = prefetchCount; ec.LoadFrom(context); }); } cfg.ConfigureJsonSerializer(c => new JsonSerializerSettings() { Converters = new List <JsonConverter> { new IsoDateTimeConverter(), new StringEnumConverter { CamelCaseText = true } }, ReferenceLoopHandling = ReferenceLoopHandling.Ignore, //NullValueHandling = NullValueHandling.Ignore }); }); return(busControl); }) .SingleInstance() .As <IBusControl>() .As <global::MassTransit.IBus>(); builder.Update(container); var bc = container.Resolve <IBusControl>(); configuration.SetDefault <IBus, MassTransitBus>(new MassTransitBus(bc)); var log = ObjectContainer.Current.BeginLifetimeScope(); var receiveObserver = new ReceiveObserver(log.Resolve <ILoggerFactory>().Create(typeof(ReceiveObserver))); //var receiveObserver = new ReceiveObserver(); var receiveHandle = bc.ConnectReceiveObserver(receiveObserver); var publishObserver = new PublishObserver(); var publishHandle = bc.ConnectPublishObserver(publishObserver); var sendObserver = new SendObserver(); var shendHandle = bc.ConnectSendObserver(sendObserver); //var result = bc.GetProbeResult(); //Console.WriteLine(result.ToJsonString()); ObjectContainer.Current.RegisterGeneric(typeof(ServiceBus.IRequestClient <,>), typeof(CommonX.ServiceBus.MassTransit.Impl.RequestClient <,>), LifeStyle.Transient); bc.Start(); } return(configuration); }
// This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public IServiceProvider ConfigureServices(IServiceCollection services) { services.AddScoped <IHostedService, MassTransitHostedService>(); services.AddScoped <OrderStatusChangedToAwaitingValidationIntegrationEventHandler>(); services.AddScoped <OrderStatusChangedToCancelledIntegrationEventHandler>(); services.AddScoped <OrderStatusChangedToPaidIntegrationEventHandler>(); services.AddScoped <OrderStatusChangedToShippedIntegrationEventHandler>(); services.AddScoped <OrderStatusChangedToStockConfirmedIntegrationEventHandler>(); services.AddScoped <OrderStatusChangedToSubmittedIntegrationEventHandler>(); services.AddScoped <AccountDepositIntegrationEventHandler>(); services.AddCors(options => { options.AddPolicy("CorsPolicy", builder => builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials()); }); if (Configuration.GetValue <string>("IsClusterEnv") == bool.TrueString) { services .AddSignalR() .AddRedis(Configuration["SignalrStoreConnectionString"]); } else { services.AddSignalR(); } ConfigureAuthService(services); services.AddOptions(); //configure autofac var container = new ContainerBuilder(); container.Register(c => { var busControl = Bus.Factory.CreateUsingRabbitMq(sbc => { var host = sbc.Host(new Uri(Configuration["EventBusConnection"]), h => { h.Username(Configuration["EventBusUserName"]); h.Password(Configuration["EventBusPassword"]); }); sbc.ReceiveEndpoint(host, "order_awaitingvalidation_signalr_queue", e => { e.Consumer <OrderStatusChangedToAwaitingValidationIntegrationEventHandler>(c); }); sbc.ReceiveEndpoint(host, "order_cancelled_signalr_queue", e => { e.Consumer <OrderStatusChangedToCancelledIntegrationEventHandler>(c); }); sbc.ReceiveEndpoint(host, "order_paid_signalr_queue", e => { e.Consumer <OrderStatusChangedToPaidIntegrationEventHandler>(c); }); sbc.ReceiveEndpoint(host, "order_shipped_signalr_queue", e => { e.Consumer <OrderStatusChangedToShippedIntegrationEventHandler>(c); }); sbc.ReceiveEndpoint(host, "order_stockconfirmed_signalr_queue", e => { e.Consumer <OrderStatusChangedToStockConfirmedIntegrationEventHandler>(c); }); sbc.ReceiveEndpoint(host, "order_submitted_signalr_queue", e => { e.Consumer <OrderStatusChangedToSubmittedIntegrationEventHandler>(c); }); sbc.ReceiveEndpoint(host, "payment_amount_deposit", e => { e.Consumer <AccountDepositIntegrationEventHandler>(c); }); sbc.UseExtensionsLogging(_loggerFactory); }); var consumeObserver = new ConsumeObserver(_loggerFactory.CreateLogger <ConsumeObserver>()); busControl.ConnectConsumeObserver(consumeObserver); var sendObserver = new SendObserver(_loggerFactory.CreateLogger <SendObserver>()); busControl.ConnectSendObserver(sendObserver); return(busControl); }) .As <IBusControl>() .As <IPublishEndpoint>() .SingleInstance(); container.Populate(services); return(new AutofacServiceProvider(container.Build())); }