public void WhenPublishingEventShouldResultInLogEntriesCountOfOne()
        {
            // Arrange
            using (var context = new AuditLogContext(_options))
            {
                var repository    = new AuditLogRepository(context);
                var eventListener = new AuditLogEventListener(repository);
                using var eventBus = new EventBusBuilder()
                                     .FromEnvironment()
                                     .CreateEventBus(new ConnectionFactory())
                                     .AddEventListener(eventListener, "#");

                var awaitHandle = new ManualResetEvent(false);

                // Act
                PublishMessage(eventBus);
                awaitHandle.WaitOne(1000);
            }

            // Assert
            using (var context = new AuditLogContext(_options))
            {
                Assert.AreEqual(1, context.LogEntries.Count());
                Assert.IsTrue(context.LogEntries.Any(entry => entry.EventJson.Contains("Hello world")));
            }
        }
    public static EventBusBuilder WithRabbitMQ(this EventBusBuilder builder, Action <RabbitMQOptions> configureOptions)
    {
        builder.Services.Configure(configureOptions);
        builder.Services.TryAddSingleton <IEventBus, EventBus>();

        return(builder);
    }
        /// <summary>
        /// 添加事件消息总线
        /// </summary>
        /// <param name="services"></param>
        /// <param name="configuration"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public static IEventBusBuilder AddEventBus(this IServiceCollection services, IConfiguration configuration, Action <IEventBusBuilder> action)
        {
            var builder = new EventBusBuilder(services, configuration);

            action(builder);
            return(builder);
        }
示例#4
0
    public static EventBusBuilder WithEntityFrameworkCore <TContext>(this EventBusBuilder builder)
        where TContext : DbContext
    {
        builder.Services.TryAddScoped <IEventPublishedRepository, EventPublishedRepository <TContext> >();
        builder.Services.TryAddScoped <IEventSubscribedRepository, EventSubscribedRepository <TContext> >();

        return(builder);
    }
示例#5
0
        public static IServiceCollection AddEventBus(this IServiceCollection engine, Action <EventBusBuilder> builderAct)
        {
            var builder = new EventBusBuilder();

            builder.Engine = engine;
            builderAct(builder);
            return(engine);
        }
        /// <summary>
        /// 添加事件消息总线
        /// </summary>
        /// <param name="services"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public static IEventBusBuilder AddEventBus(this IServiceCollection services, Action <IEventBusBuilder> action)
        {
            var service       = services.First(x => x.ServiceType == typeof(IConfiguration));
            var configuration = (IConfiguration)service.ImplementationInstance;
            var builder       = new EventBusBuilder(services, configuration);

            action(builder);
            return(builder);
        }
        /// <summary>
        /// 添加事件消息总线
        /// </summary>
        /// <param name="services"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public static IEventBusBuilder AddEventBus(this IServiceCollection services, Action <IEventBusBuilder> action)
        {
            var service       = services.First(x => x.ServiceType == typeof(IConfiguration));
            var configuration = services.BuildServiceProvider().GetRequiredService <IConfiguration>();
            var builder       = new EventBusBuilder(services, configuration);

            action(builder);
            return(builder);
        }
示例#8
0
 public static EventBusBuilder AddRabbitMq(this EventBusBuilder eventBusBuilder, Action <EventBusRabbitMqOptions> configure = null)
 {
     eventBusBuilder.Services.AddSingleton <IEventBus, EventBusRabbitMq>();
     if (configure == null)
     {
         return(eventBusBuilder);
     }
     eventBusBuilder.Services.Configure(configure);
     return(eventBusBuilder);
 }
示例#9
0
 public static EventBusBuilder AddSqlServer(this EventBusBuilder builder,
                                            Action <EventBusSqlServerOptions> options)
 {
     builder.Service.TryAddSingleton <IStorage, SqlServerStorage>();
     builder.Service.TryAddTransient <ITransaction, SqlServerTransaction>();
     if (options != null)
     {
         builder.Service.Configure(options);
     }
     return(builder);
 }
示例#10
0
        public void FromEnvironmentShouldExtractExchangeName()
        {
            // Arrange
            IEventBusBuilder builder = new EventBusBuilder();

            // Act
            var result = builder.FromEnvironment();

            // Assert
            Assert.AreEqual("TestExchangeName", result.ExchangeName);
        }
示例#11
0
        public void FromEnvironmentShouldExtractPassword()
        {
            // Arrange
            IEventBusBuilder builder = new EventBusBuilder();

            // Act
            var result = builder.FromEnvironment();

            // Assert
            Assert.AreEqual("TestPassword", result.Password);
        }
示例#12
0
        public void FromEnvironmentShouldExtractPort()
        {
            // Arrange
            IEventBusBuilder builder = new EventBusBuilder();

            // Act
            var result = builder.FromEnvironment();

            // Assert
            Assert.AreEqual(5000, result.Port);
        }
示例#13
0
        public void FromEnvironmentShouldReturnInstanceOfTypeIEventBusBuilder()
        {
            // Arrange
            IEventBusBuilder builder = new EventBusBuilder();

            // Act
            var result = builder.FromEnvironment();

            // Assert
            Assert.IsInstanceOfType(result, typeof(IEventBusBuilder));
        }
示例#14
0
 public static EventBusBuilder AddMysql(this EventBusBuilder builder,
                                        Action <EventBusMysqlOptions> options = null)
 {
     builder.Service.TryAddSingleton <IStorage, MysqlStorage>();
     builder.Service.TryAddTransient <ITransaction, MysqlTransaction>();
     if (options != null)
     {
         builder.Service.Configure(options);
     }
     return(builder);
 }
示例#15
0
        public void FromEnvironmentShouldThrowExceptionIfExchangeNameEnvironmentVariableIsNull()
        {
            // Arrange
            Environment.SetEnvironmentVariable("EXCHANGE_NAME", null);
            IEventBusBuilder builder = new EventBusBuilder();

            // Act
            var result = Assert.ThrowsException <InvalidEnvironmentException>(() => builder.FromEnvironment());

            // Assert
            Assert.AreEqual("Environment variable [EXCHANGE_NAME] can not be null", result.Message);
        }
        public void HandleShouldBeCalledOnCommandHandlerWhenMessageIsSend()
        {
            // Arrange
            var commandListenerMock = new Mock <ICommandListener>();

            using var eventBus = new EventBusBuilder()
                                 .FromEnvironment()
                                 .CreateEventBus(new ConnectionFactory())
                                 .AddCommandListener(commandListenerMock.Object, "AuditLog");
            var awaitHandle = new ManualResetEvent(false);

            // Act
            eventBus.PublishCommand(new ReplayEventsCommand());
            awaitHandle.WaitOne(1000);

            // Assert
            commandListenerMock.Verify(mock => mock.Handle(It.IsAny <object>(), It.IsAny <BasicDeliverEventArgs>()));
        }
示例#17
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="serviceScopeFactory"></param>
        /// <param name="busOptionsAccessor"></param>
        /// <param name="transportOptionsAccessor"></param>
        /// <param name="loggerFactory"></param>
        public EventBusTransportBase(IServiceScopeFactory serviceScopeFactory,
                                     IOptions <EventBusOptions> busOptionsAccessor,
                                     IOptions <TTransportOptions> transportOptionsAccessor,
                                     ILoggerFactory loggerFactory)
        {
            this.serviceScopeFactory = serviceScopeFactory ?? throw new ArgumentNullException(nameof(serviceScopeFactory));
            BusOptions       = busOptionsAccessor?.Value ?? throw new ArgumentNullException(nameof(busOptionsAccessor));
            TransportOptions = transportOptionsAccessor?.Value ?? throw new ArgumentNullException(nameof(transportOptionsAccessor));

            // Create a well-scoped logger
            var categoryName = $"{LogCategoryNames.Transports}.{GetType().Name}";

            categoryName = CategoryNamePattern.Replace(categoryName, string.Empty); // remove trailing "Transport"
            Logger       = loggerFactory?.CreateLogger(categoryName) ?? throw new ArgumentNullException(nameof(loggerFactory));

            // Get the name of the transport
            Name = EventBusBuilder.GetTransportName(GetType());
        }
示例#18
0
        public void CreateEventBusShouldCreateEventBusWithExchangeName()
        {
            // Arrange
            var modelMock      = new Mock <IModel>();
            var model          = modelMock.Object;
            var connectionMock = new Mock <IConnection>();
            var connection     = connectionMock.Object;
            var factoryMock    = new Mock <IConnectionFactory>();
            var factory        = factoryMock.Object;

            connectionMock.Setup(mock => mock.CreateModel()).Returns(model);
            factoryMock.Setup(mock => mock.CreateConnection()).Returns(connection);
            IEventBusBuilder builder = new EventBusBuilder();

            // Act
            var result = builder.FromEnvironment().CreateEventBus(factory);

            // Assert
            Assert.AreEqual("TestExchangeName", result.ExchangeName);
        }
示例#19
0
 public static EventBusBuilder UseCap <Ef>(this EventBusBuilder builder, IConfiguration configuration)
     where Ef : DbContext
 {
     ServiceCollection = builder.Engine;
     builder.Engine.AddCap(options =>
     {
         options.UseRabbitMQ(opt => {
             opt.HostName = configuration.GetSection("cap:mqHost").Value;
             opt.UserName = configuration.GetSection("cap:mqUserName").Value;
             opt.Password = configuration.GetSection("cap:mqPassWord").Value;
             opt.Port     = configuration.GetSection("cap:mqPort").Value.ToInt();
         });
         options.UseEntityFramework <Ef>(opt =>
         {
             opt.TableNamePrefix = configuration.GetSection("cap:pre").Value;
         });
         options.RegisterExtension(new CapOptionsExtension());
     });
     builder.Engine.AddScoped <IPublish, CapPublish>();
     return(builder);
 }
示例#20
0
        public void CreateEventBusShouldDeclareExchange()
        {
            // Arrange
            var modelMock      = new Mock <IModel>();
            var model          = modelMock.Object;
            var connectionMock = new Mock <IConnection>();
            var connection     = connectionMock.Object;
            var factoryMock    = new Mock <IConnectionFactory>();
            var factory        = factoryMock.Object;

            connectionMock.Setup(mock => mock.CreateModel()).Returns(model);
            factoryMock.Setup(mock => mock.CreateConnection()).Returns(connection);
            IEventBusBuilder builder = new EventBusBuilder();

            // Act
            builder.FromEnvironment().CreateEventBus(factory);

            // Assert
            connectionMock.Verify(mock => mock.CreateModel());
            modelMock.Verify(mock => mock.ExchangeDeclare("TestExchangeName", ExchangeType.Topic, false, false, null));
        }
        /// <summary>
        /// Add EventBus related stuff to IoC
        /// </summary>
        /// <param name="services">The services</param>
        /// <param name="configureSettings">Action to be able to configure the event bus</param>
        /// <returns></returns>
        public static IEventBusBuilder AddEventBus(this IServiceCollection services, Action <ServiceBusSettings> configureSettings = null)
        {
            var settings = new ServiceBusSettings();

            configureSettings?.Invoke(settings);

            var builder = new EventBusBuilder(services, settings);

            services.AddSingleton(settings);
            services.AddMassTransit();
            services.AddSingleton(provider => EventBusFactory.Build(cfg =>
            {
                cfg.Host(new Uri(settings.ConnectionString), h =>
                {
                    h.Username(settings.UserName);
                    h.Password(settings.Password);
                });
            }));

            builder.AddEventPublisher();
            return(builder);
        }
示例#22
0
 public static EventBusBuilder AddLocal(this EventBusBuilder eventBusBuilder)
 {
     eventBusBuilder.Services.AddSingleton <IEventBus, EventBusLocal>();
     return(eventBusBuilder);
 }
示例#23
0
 public static EventBusBuilder AddLocalMq(this EventBusBuilder builder)
 {
     builder.Service.TryAddSingleton <IMessagePublisher, LocalMessagePublisher>();
     builder.Service.TryAddSingleton <IMessageSubscribe, LocalMessageSubscribe>();
     return(builder);
 }
示例#24
0
 public EventBus(EventBusBuilder builder)
 {
     _eventAndHandlerMapping = new Dictionary <string, object>();
     taskFactory             = new TaskFactory();
     m_context = builder.context;
 }
示例#25
0
        public static void Main(string[] args)
        {
            var logLevel = Environment.GetEnvironmentVariable("LOG_LEVEL") ??
                           throw new InvalidEnvironmentException(
                                     "Environment variable [LOG_LEVEL] was not provided.");

            Enum.TryParse(logLevel, true, out LogLevel result);

            var loggerFactory = LoggerFactory.Create(builder => builder.SetMinimumLevel(result).AddConsole());

            AuditLogLoggerFactory.LoggerFactory = loggerFactory;

            var logger = loggerFactory.CreateLogger("Program");

            try
            {
                var connectionString = Environment.GetEnvironmentVariable("CONNECTION_STRING") ??
                                       throw new InvalidEnvironmentException(
                                                 "Environment variable [CONNECTION_STRING] was not provided.");

                var options = new DbContextOptionsBuilder <AuditLogContext>()
                              .UseMySql(connectionString)
                              .Options;
                using var context = new AuditLogContext(options);

                var       createdAndSeeded = false;
                const int waitTime         = 1000;
                while (!createdAndSeeded)
                {
                    try
                    {
                        context.Database.EnsureCreated();
                        createdAndSeeded = true;
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                        Thread.Sleep(waitTime);
                    }
                }

                var repository        = new AuditLogRepository(context);
                var routingKeyMatcher = new RoutingKeyMatcher();
                var eventListener     = new AuditLogEventListener(repository);
                var eventBusBuilder   = new EventBusBuilder().FromEnvironment();
                using var eventBus = eventBusBuilder.CreateEventBus(new ConnectionFactory
                {
                    HostName = eventBusBuilder.HostName,
                    Port     = eventBusBuilder.Port,
                    UserName = eventBusBuilder.UserName,
                    Password = eventBusBuilder.Password
                });
                var eventReplayer   = new EventReplayer(eventBus);
                var commandListener =
                    new AuditLogCommandListener(repository, eventReplayer, routingKeyMatcher, eventBus);
                eventBus.AddEventListener(eventListener, "#");
                eventBus.AddCommandListener(commandListener, "AuditLog");

                logger.LogTrace("Host started, audit logger ready to log");

                _stopEvent.WaitOne();
            }
            catch (Exception e)
            {
                logger.LogError($"Error occured while running the client with message: {e.Message}");
            }
        }