Beispiel #1
0
        // Inject background service, for receiving message
        public void ConfigureServices(IServiceCollection services)
        {
            var loggerFactorySrv = services.BuildServiceProvider().GetService <ILoggerFactory>();

            ILogger _logger = loggerFactorySrv
                              .AddConsole()
                              .AddDebug()
                              .CreateLogger <Startup>();

            var _operationalUnit = new OperationalUnit(
                environment: Environemnt.EnvironmentName,
                assembly: AssemblyName);

            services.AddSingleton <IOperationalUnit>(srv => _operationalUnit);

            services.AddSingleton <LocalConfiguration, LocalConfiguration>(srv => SystemLocalConfiguration);
            services.AddSingleton <IMessagePublisher, RabbitMQPublisher>(srv =>
            {
                return(RabbitMQPublisher.Create(loggerFactorySrv, new RabbitMQConfiguration
                {
                    hostName = SystemLocalConfiguration.MessagesMiddleware,
                    exchange = SystemLocalConfiguration.MiddlewareExchange,
                    userName = SystemLocalConfiguration.MessagesMiddlewareUsername,
                    password = SystemLocalConfiguration.MessagesMiddlewarePassword,
                    routes = new string[] { SystemLocalConfiguration.MessagePublisherRoute }
                }));
            });

            ///
            /// Injecting message receiver background service
            ///

            services.AddDistributedRedisCache(redisOptions =>
            {
                redisOptions.Configuration = SystemLocalConfiguration.CacheServer;
                redisOptions.Configuration = SystemLocalConfiguration.CacheDBVehicles;
            });

            services.AddApiVersioning(options =>
            {
                options.DefaultApiVersion = new Microsoft.AspNetCore.Mvc.ApiVersion(1, 0);
                options.AssumeDefaultVersionWhenUnspecified = true;
                options.ReportApiVersions = true;
            });

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info {
                    Title = _operationalUnit.Assembly, Version = "v1"
                });
            });

            services.AddMvc(options =>
            {
                //TODO: add practical policy instead of empty policy for authentication / authorization .
                options.Filters.Add(new CustomAuthorizer(_logger, _operationalUnit));
                options.Filters.Add(new CustomeExceptoinHandler(_logger, _operationalUnit, Environemnt));
                options.Filters.Add(new CustomResponseResult(_logger, _operationalUnit));
            });
        }
Beispiel #2
0
        // Inject background service, for receiving message
        public void ConfigureServices(IServiceCollection services)
        {
            var serviceProvider  = services.BuildServiceProvider();
            var loggerFactorySrv = serviceProvider.GetService <ILoggerFactory>();

            services.AddDbContextPool <TrackingDbContext>(options => options.UseSqlServer(
                                                              _systemLocalConfiguration.EventDbConnection,
                                                              //enable connection resilience
                                                              connectOptions =>
            {
                connectOptions.EnableRetryOnFailure();
                connectOptions.CommandTimeout(Identifiers.TimeoutInSec);
            })  //.UseLoggerFactory(loggerFactorySrv)// to log queries
                                                          );

            //add application insights information, could be used to monitor the performance, and more analytics when application moved to the cloud.
            loggerFactorySrv.AddApplicationInsights(services.BuildServiceProvider(), LogLevel.Information);

            ILogger _logger = loggerFactorySrv
                              .AddConsole()
                              .AddDebug()
                              .AddFile(Configuration.GetSection("Logging"))
                              .CreateLogger <Startup>();


            // set cache service for db index 1
            services.AddSingleton <ICacheProvider, CacheManager>(srv => new CacheManager(Logger, _systemLocalConfiguration.CacheServer));
            services.AddSingleton <MiddlewareConfiguration, MiddlewareConfiguration>(srv => _systemLocalConfiguration);
            services.AddScoped <IOperationalUnit, IOperationalUnit>(srv => new OperationalUnit(
                                                                        environment: Environemnt.EnvironmentName,
                                                                        assembly: AssemblyName));
            services.AddOptions();

            #region worker background services

            #region tracking vehicle query client

            services.AddScoped <IMessageRequest <TrackingFilterModel, IEnumerable <DomainModels.Business.TrackingDomain.Tracking> >,
                                RabbitMQRequestClient <TrackingFilterModel, IEnumerable <DomainModels.Business.TrackingDomain.Tracking> > >(
                srv =>
            {
                return(new RabbitMQRequestClient <TrackingFilterModel, IEnumerable <DomainModels.Business.TrackingDomain.Tracking> >
                           (loggerFactorySrv, new RabbitMQConfiguration
                {
                    exchange = "",
                    hostName = _systemLocalConfiguration.MessagesMiddleware,
                    userName = _systemLocalConfiguration.MessagesMiddlewareUsername,
                    password = _systemLocalConfiguration.MessagesMiddlewarePassword,
                    routes = new string[] { "rpc_queue_tracking_filter" },
                }));
            });

            #endregion


            #region tracking query worker
            // business logic
            services.AddSingleton <IHostedService, RabbitMQRequestWorker>(srv =>
            {
                var trackingSrv = new TrackingManager(loggerFactorySrv, srv.GetService <TrackingDbContext>());

                return(new RabbitMQRequestWorker
                           (serviceProvider, loggerFactorySrv, new RabbitMQConfiguration
                {
                    exchange = "",
                    hostName = _systemLocalConfiguration.MessagesMiddleware,
                    userName = _systemLocalConfiguration.MessagesMiddlewareUsername,
                    password = _systemLocalConfiguration.MessagesMiddlewarePassword,
                    routes = new string[] { "rpc_queue_tracking_filter" },
                }
                           , (trackingMessageRequest) =>
                {
                    try
                    {
                        //TODO: add business logic, result should be serializable
                        var trackingFilter = Utilities.JsonBinaryDeserialize <TrackingFilterModel>(trackingMessageRequest);
                        Logger.LogInformation($"[x] callback of RabbitMQ tracking worker=> a message");
                        var response = trackingSrv.Query(trackingFilter.Body, predicate: null)?.ToList();
                        if (response == null)
                        {
                            return new byte[0];
                        }
                        return Utilities.JsonBinarySerialize(response);
                    }
                    catch (Exception ex)
                    {
                        Logger.LogCritical(ex, "Object de-serialization exception.");
                        //to respond back to RPC client
                        return new byte[0];
                    }
                }));
            });
            #endregion

            //you may get a different cache db, by passing db index parameter.
            #region cache workers

            //1- cache vehicle status (key/value)
            services.AddSingleton <IHostedService, RabbitMQSubscriberWorker>(srv =>
            {
                var trackingSrv = new TrackingManager(loggerFactorySrv, srv.GetService <TrackingDbContext>());
                var cacheSrv    = new CacheManager(Logger, _systemLocalConfiguration.CacheServer);
                cacheSrv.Subscribe(Identifiers.onPing, (message) =>
                {
                    // onPing callback
                    // add status & time stamp to vehicle 'set'
                    var pingModel = Utilities.JsonBinaryDeserialize <PingModel>(message);
                    if (pingModel?.Body != null)
                    {
                        cacheSrv.SetHash(pingModel.Body.ChassisNumber, new Dictionary <string, string> {
                            { pingModel.Header.Timestamp.ToString(), Enum.GetName(typeof(StatusModel), pingModel.Body.Status) }
                        }, Identifiers.cache_db_idx1).Wait();
                    }
                });

                return(new RabbitMQSubscriberWorker
                           (serviceProvider, loggerFactorySrv, new RabbitMQConfiguration
                {
                    hostName = _systemLocalConfiguration.MessagesMiddleware,
                    exchange = _systemLocalConfiguration.MiddlewareExchange,
                    userName = _systemLocalConfiguration.MessagesMiddlewareUsername,
                    password = _systemLocalConfiguration.MessagesMiddlewarePassword,
                    routes = new string[] { _systemLocalConfiguration.MessageSubscriberRoute }
                }
                           , (pingMessageCallback) =>
                {
                    try
                    {
                        var message = pingMessageCallback();
                        if (message != null)
                        {
                            //get ping model

                            var pingModel = Utilities.JsonBinaryDeserialize <PingModel>(message);
                            if (pingModel != null)
                            {
                                //push vehicle ping on cache that expire after 1 minute, querying this cache db will have vehicles that ping within 1 minute
                                cacheSrv.Set(pingModel.Body.ChassisNumber, pingModel.Header.Timestamp.ToString(), Defaults.CacheTimeout, Identifiers.cache_db_idx2)
                                .Wait();
                                //get relevant vehicle
                                Vehicle vehicle = null;
                                Customer customer = null;
                                var vehicleBinary = cacheSrv.GetBinary(pingModel.Body.ChassisNumber)?.Result;
                                if (vehicleBinary != null)
                                {
                                    vehicle = Utilities.JsonBinaryDeserialize <Vehicle>(vehicleBinary);
                                    //get customer by vehicle
                                    var customerBinary = cacheSrv.GetBinary(vehicle.CustomerId.ToString())?.Result;
                                    if (customerBinary != null)
                                    {
                                        customer = Utilities.JsonBinaryDeserialize <Customer>(customerBinary);
                                    }
                                }
                                //build tracking object
                                var trackingObj = new DomainModels.Business.TrackingDomain.Tracking
                                {
                                    CorrelationId = pingModel.Header.CorrelationId,
                                    ChassisNumber = vehicle?.ChassisNumber ?? pingModel.Body.ChassisNumber,
                                    Model = vehicle?.Model,
                                    Owner = customer?.Name,
                                    OwnerRef = (customer?.Id)?.ToString(),
                                    Status = pingModel.Body.Status,
                                    Message = pingModel.Body.Message,
                                    Timestamp = pingModel.Header.Timestamp,
                                };
                                //push tracking object to repository
                                var trackingDbModel = new TrackingSQLDB.DbModels.Tracking(trackingObj);
                                trackingSrv.Add(trackingDbModel).Wait();
                                // publish on-ping cache event
                                cacheSrv.Publish(Identifiers.onPing, message);
                            }
                        }
                        Logger.LogInformation($"[x] Tracking service received a message from exchange: {_systemLocalConfiguration.MiddlewareExchange}, route :{_systemLocalConfiguration.MessageSubscriberRoute}");
                    }
                    catch (Exception ex)
                    {
                        Logger.LogCritical(ex, "Object de-serialization exception.");
                    }
                }));
            });


            #endregion


            #region internal functions

            #endregion


            #endregion

            ///
            /// Injecting message receiver background service
            ///

            services.AddDistributedRedisCache(redisOptions =>
            {
                redisOptions.Configuration = _systemLocalConfiguration.CacheServer;
                redisOptions.InstanceName  = _systemLocalConfiguration.VehiclesCacheDB;
            });

            services.AddApiVersioning(options =>
            {
                options.DefaultApiVersion = new Microsoft.AspNetCore.Mvc.ApiVersion(1, 0);
                options.AssumeDefaultVersionWhenUnspecified = true;
                options.ReportApiVersions = true;
            });

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info {
                    Title = AssemblyName, Version = "v1"
                });
            });


            services.AddMediatR();

            var _operationalUnit = new OperationalUnit(
                environment: Environemnt.EnvironmentName,
                assembly: AssemblyName);

            services.AddMvc(options =>
            {
                //TODO: add practical policy instead of empty policy for authentication / authorization .
                options.Filters.Add(new CustomAuthorizer(_logger, _operationalUnit));
                options.Filters.Add(new CustomeExceptoinHandler(_logger, _operationalUnit, Environemnt));
                options.Filters.Add(new CustomResponseResult(_logger, _operationalUnit));
            });
        }
        // Inject background service, for receiving message
        public void ConfigureServices(IServiceCollection services)
        {
            var serviceProvider  = services.BuildServiceProvider();
            var loggerFactorySrv = serviceProvider.GetService <ILoggerFactory>();

            services.AddDbContextPool <VehicleDbContext>(options => options.UseSqlServer(
                                                             _systemLocalConfiguration.EventDbConnection,
                                                             //enable connection resilience
                                                             connectOptions =>
            {
                connectOptions.EnableRetryOnFailure();
                connectOptions.CommandTimeout(Identifiers.TimeoutInSec);
            })   //.UseLoggerFactory(loggerFactorySrv)// to log queries
                                                         );
            //add application insights information, could be used to monitor the performance, and more analytics when application moved to the cloud.
            loggerFactorySrv.AddApplicationInsights(services.BuildServiceProvider(), LogLevel.Information);

            ILogger _logger = loggerFactorySrv
                              .AddConsole()
                              .AddDebug()
                              .AddFile(Configuration.GetSection("Logging"))
                              .CreateLogger <Startup>();

            // no need to inject the following service since, currently they are injected for the mediator.

            services.AddSingleton <MiddlewareConfiguration, MiddlewareConfiguration>(srv => _systemLocalConfiguration);
            services.AddScoped <IOperationalUnit, IOperationalUnit>(srv => new OperationalUnit(
                                                                        environment: Environemnt.EnvironmentName,
                                                                        assembly: AssemblyName));
            services.AddScoped <IMessageCommand, RabbitMQPublisher>(srv => new RabbitMQPublisher(loggerFactorySrv,
                                                                                                 new RabbitMQConfiguration
            {
                hostName = _systemLocalConfiguration.MessagesMiddleware,
                exchange = _systemLocalConfiguration.MiddlewareExchange,
                userName = _systemLocalConfiguration.MessagesMiddlewareUsername,
                password = _systemLocalConfiguration.MessagesMiddlewarePassword,
                routes   = new string[] { _systemLocalConfiguration.MessagePublisherRoute }
            }));
            services.AddOptions();

            #region worker

            #region vehicle worker

            services.AddSingleton <IHostedService, RabbitMQSubscriberWorker>(srv =>
            {
                //get Vehicle service
                var vehicleSrv = new VehicleManager(loggerFactorySrv, srv.GetService <VehicleDbContext>());
                var cacheSrv   = new CacheManager(Logger, _systemLocalConfiguration.CacheServer);
                return(new RabbitMQSubscriberWorker
                           (serviceProvider, loggerFactorySrv, new RabbitMQConfiguration
                {
                    hostName = _systemLocalConfiguration.MessagesMiddleware,
                    exchange = _systemLocalConfiguration.MiddlewareExchange,
                    userName = _systemLocalConfiguration.MessagesMiddlewareUsername,
                    password = _systemLocalConfiguration.MessagesMiddlewarePassword,
                    routes = _systemLocalConfiguration.MessageSubscriberRoute?.Split('-') ?? new string[0]
                }
                           , (messageCallback) =>
                {
                    try
                    {
                        var message = messageCallback();
                        if (message != null)
                        {
                            var domainModel = Utilities.JsonBinaryDeserialize <VehicleModel>(message);
                            var vehicle = new VehicleSQLDB.DbModels.Vehicle(domainModel.Body);
                            //get the correlated customer from the cache, to fill name field
                            var customerBinary = cacheSrv.GetBinary(vehicle.CustomerId.ToString())?.Result;
                            if (customerBinary != null)
                            {
                                var customer = Utilities.JsonBinaryDeserialize <Customer>(customerBinary);
                                vehicle.CustomerName = customer.Name;
                            }
                            vehicleSrv.Add(vehicle).Wait();
                            cacheSrv.SetBinary(vehicle.ChassisNumber, Utilities.JsonBinarySerialize(vehicle)).Wait();
                        }
                        Logger.LogInformation($"[x] Vehicle service receiving a message from exchange: {_systemLocalConfiguration.MiddlewareExchange}, route :{_systemLocalConfiguration.MessageSubscriberRoute}");
                    }
                    catch (System.Exception ex)
                    {
                        Logger.LogCritical(ex, "Object de-serialization exception.");
                    }
                }));
            });

            #endregion

            #region tracking vehicle query client

            services.AddScoped <IMessageRequest <VehicleFilterModel, IEnumerable <DomainModels.Business.VehicleDomain.Vehicle> >,
                                RabbitMQRequestClient <VehicleFilterModel, IEnumerable <DomainModels.Business.VehicleDomain.Vehicle> > >(
                srv =>
            {
                return(new RabbitMQRequestClient <VehicleFilterModel, IEnumerable <DomainModels.Business.VehicleDomain.Vehicle> >
                           (loggerFactorySrv, new RabbitMQConfiguration
                {
                    exchange = "",
                    hostName = _systemLocalConfiguration.MessagesMiddleware,
                    userName = _systemLocalConfiguration.MessagesMiddlewareUsername,
                    password = _systemLocalConfiguration.MessagesMiddlewarePassword,
                    routes = new string[] { "rpc_queue_vehicle_filter" },
                }));
            });

            #endregion

            #region vehicle query worker
            // business logic
            services.AddSingleton <IHostedService, RabbitMQRequestWorker>(srv =>
            {
                var customerSrv = new VehicleManager(loggerFactorySrv, srv.GetService <VehicleDbContext>());

                return(new RabbitMQRequestWorker
                           (serviceProvider, loggerFactorySrv, new RabbitMQConfiguration
                {
                    exchange = "",
                    hostName = _systemLocalConfiguration.MessagesMiddleware,
                    userName = _systemLocalConfiguration.MessagesMiddlewareUsername,
                    password = _systemLocalConfiguration.MessagesMiddlewarePassword,
                    routes = new string[] { "rpc_queue_vehicle_filter" },
                }
                           , (customerFilterMessageRequest) =>
                {
                    try
                    {
                        //TODO: add business logic, result should be serializable
                        var customerFilter = Utilities.JsonBinaryDeserialize <VehicleFilterModel>(customerFilterMessageRequest);
                        Logger.LogInformation($"[x] callback of RabbitMQ customer worker=> a message");
                        var response = customerSrv.Query((c) =>
                        {
                            return c.CustomerId == customerFilter.Body?.CustomerId;
                        })?.ToList();
                        if (response == null)
                        {
                            return new byte[0];
                        }
                        return Utilities.JsonBinarySerialize(response);
                    }
                    catch (Exception ex)
                    {
                        Logger.LogCritical(ex, "Object de-serialization exception.");
                        //to respond back to RPC client
                        return new byte[0];
                    }
                }));
            });
            #endregion

            #endregion

            ///
            /// Injecting message receiver background service
            ///

            services.AddDistributedRedisCache(redisOptions =>
            {
                redisOptions.Configuration = _systemLocalConfiguration.CacheServer;
                redisOptions.Configuration = _systemLocalConfiguration.VehiclesCacheDB;
            });

            services.AddApiVersioning(options =>
            {
                options.DefaultApiVersion = new Microsoft.AspNetCore.Mvc.ApiVersion(1, 0);
                options.AssumeDefaultVersionWhenUnspecified = true;
                options.ReportApiVersions = true;
            });

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info {
                    Title = AssemblyName, Version = "v1"
                });
            });

            services.AddMediatR();

            var _operationalUnit = new OperationalUnit(
                environment: Environemnt.EnvironmentName,
                assembly: AssemblyName);

            services.AddMvc(options =>
            {
                //TODO: add practical policy instead of empty policy for authentication / authorization .
                options.Filters.Add(new CustomAuthorizer(_logger, _operationalUnit));
                options.Filters.Add(new CustomeExceptoinHandler(_logger, _operationalUnit, Environemnt));
                options.Filters.Add(new CustomResponseResult(_logger, _operationalUnit));
            });
        }
        // Inject background service, for receiving message
        public void ConfigureServices(IServiceCollection services)
        {
            var serviceProvider  = services.BuildServiceProvider();
            var loggerFactorySrv = serviceProvider.GetService <ILoggerFactory>();

            //add application insights information, could be used to monitor the performance, and more analytics when application moved to the cloud.
            loggerFactorySrv.AddApplicationInsights(services.BuildServiceProvider(), LogLevel.Information);

            ILogger _logger = loggerFactorySrv
                              .AddConsole()
                              .AddDebug()
                              .AddFile(Configuration.GetSection("Logging"))
                              .CreateLogger <Startup>();

            // no need to inject the following service since, currently they are injected for the mediator.

            services.AddSingleton <MiddlewareConfiguration, MiddlewareConfiguration>(srv => _systemLocalConfiguration);
            services.AddScoped <IOperationalUnit, IOperationalUnit>(srv => new OperationalUnit(
                                                                        environment: Environemnt.EnvironmentName,
                                                                        assembly: AssemblyName));
            services.AddScoped <IMessageCommand, RabbitMQPublisher>(srv => new RabbitMQPublisher(loggerFactorySrv,
                                                                                                 new RabbitMQConfiguration
            {
                hostName = _systemLocalConfiguration.MessagesMiddleware,
                exchange = _systemLocalConfiguration.MiddlewareExchange,
                userName = _systemLocalConfiguration.MessagesMiddlewareUsername,
                password = _systemLocalConfiguration.MessagesMiddlewarePassword,
                routes   = new string[] { _systemLocalConfiguration.MessagePublisherRoute }
            }));
            services.AddOptions();

            #region worker


            #endregion

            ///
            /// Injecting message receiver background service
            ///

            services.AddDistributedRedisCache(redisOptions =>
            {
                redisOptions.Configuration = _systemLocalConfiguration.CacheServer;
                redisOptions.Configuration = _systemLocalConfiguration.VehiclesCacheDB;
            });

            services.AddApiVersioning(options =>
            {
                options.DefaultApiVersion = new Microsoft.AspNetCore.Mvc.ApiVersion(1, 0);
                options.AssumeDefaultVersionWhenUnspecified = true;
                options.ReportApiVersions = true;
            });

            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Info {
                    Title = AssemblyName, Version = "v1"
                });
            });

            services.AddMediatR();

            var _operationalUnit = new OperationalUnit(
                environment: Environemnt.EnvironmentName,
                assembly: AssemblyName);

            services.AddMvc(options =>
            {
                //TODO: add practical policy instead of empty policy for authentication / authorization .
                options.Filters.Add(new CustomAuthorizer(_logger, _operationalUnit));
                options.Filters.Add(new CustomeExceptoinHandler(_logger, _operationalUnit, Environemnt));
                options.Filters.Add(new CustomResponseResult(_logger, _operationalUnit));
            });
        }