예제 #1
0
        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();
        }
예제 #2
0
            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));
            }
예제 #3
0
            protected override void ConnectObservers(IBus bus)
            {
                base.ConnectObservers(bus);

                _observer = new SendObserver();

                bus.ConnectSendObserver(_observer);
            }
예제 #4
0
        // 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()));
        }
예제 #5
0
        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();
        }
예제 #6
0
            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;
                }
            }
예제 #7
0
            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;
                }
            }
예제 #8
0
            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);
                }
            }
예제 #9
0
            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));
                }
            }
예제 #10
0
            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));
                }
            }
예제 #11
0
            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>());
                    }
                }
            }
예제 #12
0
            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
                });
            }
예제 #13
0
        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();
        }
예제 #14
0
        // 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));
        }
예제 #15
0
        /// <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);
        }
예제 #16
0
        // 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()));
        }