예제 #1
0
        public static void ApplyMigrations(ServiceProvider serviceProvider)
        {
            var connectionStrings = serviceProvider.GetServices <SqlConnectionStringWrapper>();

            foreach (var connectionString in connectionStrings)
            {
                ExtendedConsole.Log($"Applying migrations for {connectionString.ContextType.Name}");
                using (var context = (DbContext)serviceProvider.GetRequiredService(connectionString.ContextType))
                {
                    var migrations = context.Database.GetPendingMigrations();
                    if (migrations.Any())
                    {
                        ExtendedConsole.Log($"Applying the following {migrations.Count()} migrations for {connectionString.ContextType.Name}:");
                        foreach (var migration in migrations)
                        {
                            ExtendedConsole.Log(migration);
                        }
                        context.Database.Migrate();
                        ExtendedConsole.Log($"Finished applying migrations for {connectionString.ContextType.Name}");
                    }
                    else
                    {
                        ExtendedConsole.Log($"No migrations found to apply for {connectionString.ContextType.Name}");
                    }
                }
            }
        }
        public override async Task OnExceptionAsync(ExceptionContext context)
        {
            ExtendedConsole.Log(context.Exception);
            await Logger.LogExceptionAsync(context.Exception, false);

            await base.OnExceptionAsync(context);
        }
예제 #3
0
        public static ServiceProvider Run(Assembly assembly, string busConnectionString, Func <IServiceCollection, IServiceCollection> addAdditionalServices = null, params Action <ServiceProvider>[] additionalActions)
        {
            var installerStopwatch = new Stopwatch();

            installerStopwatch.Start();

            addAdditionalServices = addAdditionalServices ?? (s => s);

            var bus = RabbitHutch.CreateBus(busConnectionString).WaitForConnection();

            ExtendedConsole.Log($"ServiceInstaller: Bus connected: {bus.IsConnected}.");

            var serviceProvider = addAdditionalServices(new ServiceCollection())
                                  .AddEventHandlers(assembly)
                                  .AddRequestHandlers(assembly)
                                  .AddPingRequestHandlers(assembly)
                                  .AddSingleton(bus)
                                  .BuildServiceProvider(true);

            ExtendedConsole.Log("ServiceInstaller: Services are registered.");

            Logger.SetServiceProvider(serviceProvider);
            ExtendedConsole.Log("ServiceInstaller: Logger initialized");

            var responder = new AutoResponder(bus, new AutoResponderRequestDispatcher(serviceProvider));

            responder.RespondAsync(assembly);
            ExtendedConsole.Log("ServiceInstaller: AutoResponders initialized.");

            var pingResponder = new PingResponder(bus, new AutoResponderRequestDispatcher(serviceProvider));

            pingResponder.RespondAsync(assembly);
            ExtendedConsole.Log("ServiceInstaller: PingResponder initialized.");

            var subscriber = new CustomAutoSubscriber(bus, new CustomAutoSubscriberMessageDispatcher(serviceProvider), assembly.FullName);

            subscriber.SubscribeAsync(assembly);
            ExtendedConsole.Log("ServiceInstaller: AutoSubscribers initialized.");

            if (additionalActions != null)
            {
                foreach (var additionalAction in additionalActions)
                {
                    var additionalActionStopwatch = new Stopwatch();
                    additionalActionStopwatch.Start();

                    ExtendedConsole.Log($"ServiceInstaller: Running {additionalAction.Method.Name}");
                    additionalAction(serviceProvider);
                    additionalActionStopwatch.Stop();

                    ExtendedConsole.Log($"ServiceInstaller: {additionalAction.Method.Name} finished running in {additionalActionStopwatch.ElapsedMilliseconds}ms.");
                }
            }

            installerStopwatch.Stop();
            ExtendedConsole.Log($"ServiceInstaller: Finished running in {installerStopwatch.ElapsedMilliseconds}ms.");

            return(serviceProvider);
        }
        public static IServiceCollection AddRabbitBus(this IServiceCollection serviceCollection, string connectionString)
        {
            var bus = RabbitHutch.CreateBus(connectionString).WaitForConnection();

            ExtendedConsole.Log($"Bus connected: {bus.IsConnected}.");

            return(serviceCollection.AddSingleton(bus));
        }
예제 #5
0
        public static IBus WaitForConnection(this IBus bus, int retryInMs = 2500)
        {
            while (!bus.IsConnected)
            {
                Thread.Sleep(retryInMs);
                ExtendedConsole.Log("IBus.WaitForConnection: Waiting for bus to come online..");
            }

            return(bus);
        }
예제 #6
0
        public Task <bool> TrySaveChangesAsync()
        {
            try
            {
                SaveChangesAsync();
            }
            catch (DbUpdateException ex)
            {
                ExtendedConsole.Log(ex);
                Logger.LogExceptionAsync(ex, true);
                return(Task.FromResult(false));
            }

            return(Task.FromResult(true));
        }
예제 #7
0
        private async Task CheckInterval(TimeInterval interval, DateTime now, Func <DateTime, Task> publishAction)
        {
            if (IntervalHasPassed(_lastCheck[interval], now))
            {
                ExtendedConsole.Log($"{interval.ToString()} has passed!");
                _lastCheck[interval].Last = now;
                _context.TimeEvents.Add(new TimeEvent
                {
                    Type    = interval,
                    Created = now
                });

                await _context.SaveChangesAsync();
                await publishAction(now);
            }
        }
        public async Task DispatchAsync <TMessage, TConsumer>(TMessage message)
            where TMessage : class
            where TConsumer : class, IConsumeAsync <TMessage>
        {
            ExtendedConsole.Log($"{message.GetType().Name} received");
            var consumer = _serviceProvider.GetRequiredService <TConsumer>();

            try
            {
                await consumer.ConsumeAsync(message);
            }
            catch (Exception ex)
            {
                ExtendedConsole.Log(ex);
                Logger.LogExceptionAsync(ex, false, consumer.GetType().Name);
            }
        }
예제 #9
0
        public static Task <TResponse> RequestAsync <TResponse>(this IBus bus, IRequest <TResponse> request)
            where TResponse : class, IResponse, new()
        {
            var requestMethod = _typedRequestMethods.GetOrAdd(request.GetType(),
                                                              requestType => _genericRequestMethod.MakeGenericMethod(requestType, typeof(TResponse)));

            try
            {
                Logger.LogMessageAsync(request);
                return((Task <TResponse>)requestMethod.Invoke(bus, new object[] { request }));
            }
            catch (TimeoutException ex)
            {
                ExtendedConsole.Log($"Request {request.GetType().Name} failed. Exception: {ex}");
                Logger.LogExceptionAsync(ex, true);

                return(Task.FromResult(new TResponse().RequestFailed()));
            }
        }
예제 #10
0
        public static void ValidateMongoConnections(ServiceProvider serviceProvider)
        {
            var mongoConnectionStrings = serviceProvider.GetServices <MongoConnectionStringWrapper>();

            foreach (var connectionStringWrapper in mongoConnectionStrings)
            {
                while (true)
                {
                    var client = new MongoClient(connectionStringWrapper.ConnectionString);
                    if (client.Cluster.Description.State == ClusterState.Connected)
                    {
                        break;
                    }

                    Thread.Sleep(2500);
                    ExtendedConsole.Log($"Waiting for mongoserver for database {connectionStringWrapper.DatabaseName} to come online..");
                }

                ExtendedConsole.Log($"Mongoserver for database {connectionStringWrapper.DatabaseName} is online.");
            }
        }
예제 #11
0
        static void Main(string[] args)
        {
            ExtendedConsole.Log("LoggingService started..");

            SetupConfiguration();

            var serviceProvider = ServiceInstaller.Run(
                Assembly.GetExecutingAssembly(),
                _rabbitMqConnectionString,
                services => services
                .AddAutoMapper(Assembly.GetExecutingAssembly())
                .AddMongoDatabase(_mongoConnectionString, _mongoDatabase)
                .AddTransient <MessageHandler>()
                .AddTransient <ExceptionMessageHandler>()
                .AddTransient <WebRequestMessageHandler>(),
                DatabaseHelper.ValidateMongoConnections);

            var bus    = serviceProvider.GetRequiredService <IBus>();
            var logger = new MessageLogger(bus, serviceProvider, "MessageLoggerSubscription");

            logger.Start();

            bus.Receive <ExceptionMessage>(ServiceInstaller.ExceptionQueue, async message =>
            {
                var handler = serviceProvider.GetRequiredService <ExceptionMessageHandler>();
                await handler.HandleAsync(message);
            });

            bus.Receive <WebRequest>(ServiceInstaller.WebRequestsQueue, async message =>
            {
                var handler = serviceProvider.GetRequiredService <WebRequestMessageHandler>();
                await handler.HandleAsync(message);
            });

            Thread.Sleep(Timeout.Infinite);
        }
예제 #12
0
        public static void ValidateSqlConnections(ServiceProvider serviceProvider)
        {
            var connectionStrings = serviceProvider.GetServices <SqlConnectionStringWrapper>();

            foreach (var connectionStringWrapper in connectionStrings)
            {
                var factory             = SqlClientFactory.Instance;
                var connectionIsWorking = false;

                while (!connectionIsWorking)
                {
                    using (var connection = factory.CreateConnection())
                    {
                        connection.ConnectionString = connectionStringWrapper.ConnectionStringWithoutDatabase;
                        try
                        {
                            connection.Open();
                            if (connection.State == ConnectionState.Open)
                            {
                                connectionIsWorking = true;
                                connection.Close();
                            }
                        }
                        catch (SqlException e)
                        {
                            connectionIsWorking = false;
                            Thread.Sleep(2500);
                            ExtendedConsole.Log($"ConnectionValidator exception: {e}");
                            ExtendedConsole.Log($"Waiting for {connectionStringWrapper.ContextType.Name} to come online..");
                        }
                    }
                }

                ExtendedConsole.Log($"{connectionStringWrapper.ContextType.Name} is online.");
            }
        }
예제 #13
0
        public async Task <TResponse> DispatchAsync <TRequest, TResponse, THandler>(TRequest message)
            where TRequest : class, IRequest <TResponse>
            where THandler : IAsyncRequestHandler <TRequest, TResponse>
            where TResponse : class, IResponse, new()
        {
            ExtendedConsole.Log($"{message.GetType().Name} received");
            var handler = _serviceProvider.GetRequiredService <THandler>();

            try
            {
                var response = await handler.Handle(message);

                ExtendedConsole.Log($"{response.GetType().Name} returned");
                Logger.LogMessageAsync(response);
                return(response);
            }
            catch (Exception ex)
            {
                ExtendedConsole.Log(ex);
                Logger.LogExceptionAsync(ex, false, handler.GetType().Name);
            }

            return(new TResponse().RequestFailed());
        }
예제 #14
0
 public async Task HandleAsync(WebRequest message)
 {
     ExtendedConsole.Log($"{message.GetType().Name} received");
     await _logCollection.InsertOneAsync(new WebRequestEntry(message));
 }
예제 #15
0
 public async Task HandleAsync(ExceptionMessage message)
 {
     ExtendedConsole.Log($"{message.GetType().Name} received");
     await _logCollection.InsertOneAsync(new ExceptionEntry(message, DateTime.UtcNow));
 }