コード例 #1
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            var settings = Configuration.Get <AppSettings>();

            services.Configure((Action <AppSettings>)(setting =>
            {
                Configuration.Bind(setting);
            }));
            var healthChecksUI = services.AddHealthChecksUI(setup =>
            {
                setup.SetHeaderText("IoTSharp HealthChecks");
                //Maximum history entries by endpoint
                setup.MaximumHistoryEntriesPerEndpoint(50);
                setup.AddIoTSharpHealthCheckEndpoint();
            });

            var healthChecks = services.AddHealthChecks()
                               .AddDiskStorageHealthCheck(dso =>
            {
                System.IO.DriveInfo.GetDrives()
                .Where(d => d.DriveType != System.IO.DriveType.CDRom && d.DriveType != System.IO.DriveType.Ram)
                .Select(f => f.Name).Distinct().ToList()
                .ForEach(f => dso.AddDrive(f, 1024));
            }, name: "Disk Storage");

            switch (settings.DataBase)
            {
            case DataBaseType.MySql:
                services.ConfigureMySql(Configuration.GetConnectionString("IoTSharp"), settings.DbContextPoolSize, healthChecks, healthChecksUI);
                break;

            case DataBaseType.SqlServer:
                services.ConfigureSqlServer(Configuration.GetConnectionString("IoTSharp"), settings.DbContextPoolSize, healthChecks, healthChecksUI);
                break;

            case DataBaseType.Oracle:
                services.ConfigureOracle(Configuration.GetConnectionString("IoTSharp"), settings.DbContextPoolSize, healthChecks, healthChecksUI);
                break;

            case DataBaseType.Sqlite:
                services.ConfigureSqlite(Configuration.GetConnectionString("IoTSharp"), settings.DbContextPoolSize, healthChecks, healthChecksUI);
                break;

            case DataBaseType.PostgreSql:
            default:
                services.ConfigureNpgsql(Configuration.GetConnectionString("IoTSharp"), settings.DbContextPoolSize, healthChecks, healthChecksUI);
                break;
            }

            services.AddIdentity <IdentityUser, IdentityRole>()
            .AddRoles <IdentityRole>()
            .AddRoleManager <RoleManager <IdentityRole> >()
            .AddDefaultTokenProviders()
            .AddEntityFrameworkStores <ApplicationDbContext>();


            services.AddAuthentication(option =>
            {
                option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                option.DefaultChallengeScheme    = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer           = true,
                    ValidateAudience         = true,
                    ValidateLifetime         = false,
                    ValidateIssuerSigningKey = true,
                    ValidIssuer      = Configuration["JwtIssuer"],
                    ValidAudience    = Configuration["JwtAudience"],
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtKey"]))
                };
            });


            services.AddCors();
            services.AddLogging(loggingBuilder => loggingBuilder.AddConsole());
            services.AddOpenApiDocument(configure =>
            {
                Assembly assembly     = typeof(Startup).GetTypeInfo().Assembly;
                var description       = (AssemblyDescriptionAttribute)Attribute.GetCustomAttribute(assembly, typeof(AssemblyDescriptionAttribute));
                configure.Title       = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
                configure.Version     = typeof(Startup).GetTypeInfo().Assembly.GetName().Version.ToString();
                configure.Description = description?.Description;
                configure.AddJWTSecurity();
            });

            services.AddTransient <ApplicationDBInitializer>();
            services.AddIoTSharpMqttServer(settings.MqttBroker);
            services.AddMqttClient(settings.MqttClient);
            services.AddSingleton <RetainedMessageHandler>();
            services.AddSilkierQuartz(opt =>
            {
                //opt.Add("quartz.serializer.type", "json");
                //opt.Add("quartz.jobStore.type", "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz");
                //opt.Add("quartz.jobStore.driverDelegateType", "Quartz.Impl.AdoJobStore.StdAdoDelegate, Quartz");
                //opt.Add("quartz.jobStore.tablePrefix", "qrtz_");
                //opt.Add("quartz.jobStore.dataSource", "myDS");
                //opt.Add("quartz.dataSource.myDS.provider", "Npgsql");
                //opt.Add("quartz.dataSource.myDS.connectionString", Configuration.GetConnectionString("IoTSharp"));
                opt.Add("quartz.plugin.recentHistory.type", "Quartz.Plugins.RecentHistory.ExecutionHistoryPlugin, Quartz.Plugins.RecentHistory");
                opt.Add("quartz.plugin.recentHistory.storeType", "Quartz.Plugins.RecentHistory.Impl.InProcExecutionHistoryStore, Quartz.Plugins.RecentHistory");
            });
            services.AddControllers();

            services.AddMemoryCache();
            string _hc_Caching = $"{nameof(CachingUseIn)}-{Enum.GetName(settings.CachingUseIn)}";

            services.AddEasyCaching(options =>
            {
                switch (settings.CachingUseIn)
                {
                case CachingUseIn.Redis:
                    options.UseRedis(config =>
                    {
                        settings.CachingUseRedisHosts?.Split(';').ToList().ForEach(h =>
                        {
                            var hx = h.Split(':');
                            config.DBConfig.Endpoints.Add(new ServerEndPoint(hx[0], int.Parse(hx[1])));
                        });
                    }, "iotsharp");
                    healthChecks.AddRedis(settings.CachingUseRedisHosts, name: _hc_Caching);
                    break;

                case CachingUseIn.LiteDB:
                    options.UseLiteDB(cfg => cfg.DBConfig = new EasyCaching.LiteDB.LiteDBDBOptions()
                    {
                    }, name: "iotsharp");
                    break;

                case CachingUseIn.InMemory:
                default:
                    options.UseInMemory("iotsharp");
                    break;
                }
            });
            string _hc_telemetryStorage = $"{nameof(TelemetryStorage)}-{Enum.GetName(settings.TelemetryStorage)}";

            switch (settings.TelemetryStorage)
            {
            case TelemetryStorage.Sharding:
                services.AddEFCoreSharding(config =>
                {
                    switch (settings.DataBase)
                    {
                    case DataBaseType.MySql:
                        config.UseMySqlToSharding(Configuration.GetConnectionString("TelemetryStorage"), settings.Sharding.ExpandByDateMode);
                        break;

                    case DataBaseType.SqlServer:
                        config.UseSqlServerToSharding(Configuration.GetConnectionString("TelemetryStorage"), settings.Sharding.ExpandByDateMode);
                        break;

                    case DataBaseType.Oracle:
                        config.UseOracleToSharding(Configuration.GetConnectionString("TelemetryStorage"), settings.Sharding.ExpandByDateMode);
                        break;

                    case DataBaseType.Sqlite:
                        config.UseSQLiteToSharding(Configuration.GetConnectionString("TelemetryStorage"), settings.Sharding.ExpandByDateMode);
                        break;

                    case DataBaseType.PostgreSql:
                    default:
                        config.UseNpgsqlToSharding(Configuration.GetConnectionString("TelemetryStorage"), settings.Sharding.ExpandByDateMode);
                        break;
                    }
                    config.SetEntityAssemblies(new Assembly[] { typeof(TelemetryData).Assembly });
                });
                services.AddSingleton <IStorage, ShardingStorage>();
                break;

            case TelemetryStorage.Taos:
                services.AddSingleton <IStorage, TaosStorage>();
                services.AddObjectPool(() => new TaosConnection(settings.ConnectionStrings["TelemetryStorage"]));
                healthChecks.AddTDengine(Configuration.GetConnectionString("TelemetryStorage"), name: _hc_telemetryStorage);
                break;

            case TelemetryStorage.InfluxDB:
                //https://github.com/julian-fh/influxdb-setup
                services.AddSingleton <IStorage, InfluxDBStorage>();
                //"TelemetryStorage": "http://localhost:8086/?org=iotsharp&bucket=iotsharp-bucket&token=iotsharp-token"
                services.AddObjectPool(() => InfluxDBClientFactory.Create(Configuration.GetConnectionString("TelemetryStorage")));
                //healthChecks.AddInfluxDB(Configuration.GetConnectionString("TelemetryStorage"),name: _hc_telemetryStorage);
                break;

            case TelemetryStorage.PinusDB:
                services.AddSingleton <IStorage, PinusDBStorage>();
                services.AddObjectPool(() =>
                {
                    var cnt = new PinusConnection(settings.ConnectionStrings["TelemetryStorage"]);
                    cnt.Open();
                    return(cnt);
                });
                healthChecks.AddPinusDB(Configuration.GetConnectionString("TelemetryStorage"), name: _hc_telemetryStorage);
                break;

            case TelemetryStorage.TimescaleDB:
                services.AddSingleton <IStorage, TimescaleDBStorage>();
                break;

            case TelemetryStorage.SingleTable:
            default:
                services.AddSingleton <IStorage, EFStorage>();
                break;
            }

            services.AddTransient <IEventBusHandler, EventBusHandler>();
            if (settings.ZMQOption != null)
            {
                services.AddHostedZeroMQ(cfg => cfg = settings.ZMQOption);
            }
            services.AddCap(x =>
            {
                string _hc_EventBusStore     = $"{nameof(EventBusStore)}-{Enum.GetName(settings.EventBusStore)}";
                x.SucceedMessageExpiredAfter = settings.SucceedMessageExpiredAfter;
                x.ConsumerThreadCount        = settings.ConsumerThreadCount;
                switch (settings.EventBusStore)
                {
                case EventBusStore.PostgreSql:
                    x.UsePostgreSql(Configuration.GetConnectionString("EventBusStore"));
                    healthChecks.AddNpgSql(Configuration.GetConnectionString("EventBusStore"), name: _hc_EventBusStore);
                    break;

                case EventBusStore.MongoDB:
                    x.UseMongoDB(Configuration.GetConnectionString("EventBusStore"));      //注意,仅支持MongoDB 4.0+集群
                    healthChecks.AddMongoDb(Configuration.GetConnectionString("EventBusStore"), name: _hc_EventBusStore);
                    break;

                case EventBusStore.LiteDB:
                    x.UseLiteDBStorage(Configuration.GetConnectionString("EventBusStore"));
                    break;

                case EventBusStore.InMemory:
                default:
                    x.UseInMemoryStorage();
                    break;
                }
                string _hc_EventBusMQ = $"{nameof(EventBusMQ)}-{Enum.GetName(settings.EventBusMQ)}";
                switch (settings.EventBusMQ)
                {
                case EventBusMQ.RabbitMQ:
                    var url = new Uri(Configuration.GetConnectionString("EventBusMQ"));
                    x.UseRabbitMQ(cfg =>
                    {
                        cfg.ConnectionFactoryOptions = cf =>
                        {
                            cf.AutomaticRecoveryEnabled = true;
                            cf.Uri = new Uri(Configuration.GetConnectionString("EventBusMQ"));
                        };
                    });
                    //amqp://guest:guest@localhost:5672
                    healthChecks.AddRabbitMQ(connectionFactory =>
                    {
                        var factory = new ConnectionFactory()
                        {
                            Uri = new Uri(Configuration.GetConnectionString("EventBusMQ")),
                            AutomaticRecoveryEnabled = true
                        };
                        return(factory.CreateConnection());
                    }, _hc_EventBusMQ);
                    break;

                case EventBusMQ.Kafka:
                    x.UseKafka(Configuration.GetConnectionString("EventBusMQ"));
                    healthChecks.AddKafka(cfg =>
                    {
                        cfg.BootstrapServers = Configuration.GetConnectionString("EventBusMQ");
                    }, name: _hc_EventBusMQ);
                    break;

                case EventBusMQ.ZeroMQ:
                    x.UseZeroMQ(cfg =>
                    {
                        cfg.HostName = Configuration.GetConnectionString("EventBusMQ") ?? "127.0.0.1";
                        cfg.Pattern  = MaiKeBing.CAP.NetMQPattern.PushPull;
                    });
                    break;

                case EventBusMQ.InMemory:
                default:
                    x.UseInMemoryMessageQueue();
                    break;
                }
                x.UseDashboard();
                if (settings.Discovery != null)
                {
                    x.UseDiscovery(cfg => cfg = settings.Discovery);
                }
            });
        }
コード例 #2
0
ファイル: Startup.cs プロジェクト: IoTSharp/IoTSharp
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            var settings = Configuration.Get <AppSettings>();

            services.Configure((Action <AppSettings>)(setting =>
            {
                var option = setting.MqttBroker;
                Configuration.Bind(setting);
            }));
            var healthChecksUI = services.AddHealthChecksUI(setup =>
            {
                setup.SetHeaderText("IoTSharp HealthChecks");
                //Maximum history entries by endpoint
                setup.MaximumHistoryEntriesPerEndpoint(50);
                setup.AddIoTSharpHealthCheckEndpoint();
            });

            var healthChecks = services.AddHealthChecks()
                               .AddDiskStorageHealthCheck(dso =>
            {
                System.IO.DriveInfo.GetDrives()
                .Where(d => d.DriveType != System.IO.DriveType.CDRom && d.DriveType != System.IO.DriveType.Ram)
                .Select(f => f.Name).Distinct().ToList()
                .ForEach(f => dso.AddDrive(f, 1024));
            }, name: "Disk Storage");

            switch (settings.DataBase)
            {
            case DataBaseType.MySql:
                services.ConfigureMySql(Configuration.GetConnectionString("IoTSharp"), settings.DbContextPoolSize, healthChecks, healthChecksUI);
                break;

            case DataBaseType.SqlServer:
                services.ConfigureSqlServer(Configuration.GetConnectionString("IoTSharp"), settings.DbContextPoolSize, healthChecks, healthChecksUI);
                break;

            case DataBaseType.Oracle:
                services.ConfigureOracle(Configuration.GetConnectionString("IoTSharp"), settings.DbContextPoolSize, healthChecks, healthChecksUI);
                break;

            case DataBaseType.Sqlite:
                services.ConfigureSqlite(Configuration.GetConnectionString("IoTSharp"), settings.DbContextPoolSize, healthChecks, healthChecksUI);
                break;

            case DataBaseType.InMemory:
                services.ConfigureInMemory(settings.DbContextPoolSize, healthChecksUI);

                break;

            case DataBaseType.PostgreSql:
            default:
                services.ConfigureNpgsql(Configuration.GetConnectionString("IoTSharp"), settings.DbContextPoolSize, healthChecks, healthChecksUI);
                break;
            }

            services.AddIdentity <IdentityUser, IdentityRole>()
            .AddRoles <IdentityRole>()
            .AddRoleManager <RoleManager <IdentityRole> >()
            .AddDefaultTokenProviders()
            .AddEntityFrameworkStores <ApplicationDbContext>();



            var tokenValidationParams = new TokenValidationParameters
            {
                ValidateIssuer           = true,
                ValidateAudience         = true,
                ValidateLifetime         = true,
                RequireExpirationTime    = true,
                RequireSignedTokens      = true,
                ValidateIssuerSigningKey = true,
                ValidIssuer      = Configuration["JwtIssuer"],
                ValidAudience    = Configuration["JwtAudience"],
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtKey"])),
                //     ClockSkew=TimeSpan.Zero //JWT的缓冲时间默认5分钟,token实际过期时间为 appsettings.json 当中JwtExpireHours配置的时间(小时)加上这个时间。
            };

            services.AddSingleton(tokenValidationParams);

            services.AddAuthentication(option =>
            {
                option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                option.DefaultChallengeScheme    = JwtBearerDefaults.AuthenticationScheme;
                option.DefaultScheme             = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(options =>
            {
                options.SaveToken = true;
                options.TokenValidationParameters = tokenValidationParams;
            });

            services.AddCors();
            services.AddLogging(loggingBuilder =>
            {
                loggingBuilder.AddConsole();
                loggingBuilder.AddRinLogger();
            }
                                );
            services.AddRin();
            services.AddOpenApiDocument(configure =>
            {
                Assembly assembly     = typeof(Startup).GetTypeInfo().Assembly;
                var description       = (AssemblyDescriptionAttribute)Attribute.GetCustomAttribute(assembly, typeof(AssemblyDescriptionAttribute));
                configure.Title       = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
                configure.Version     = typeof(Startup).GetTypeInfo().Assembly.GetName().Version.ToString();
                configure.Description = description?.Description;
                configure.AddJWTSecurity();
            });

            services.AddTransient <ApplicationDBInitializer>();
            services.AddIoTSharpMqttServer(settings.MqttBroker);
            services.AddMqttClient(settings.MqttClient);
            services.AddSilkierQuartz(options =>
            {
                options.VirtualPathRoot       = "/quartz";
                options.UseLocalTime          = true;
                options.DefaultDateFormat     = "yyyy-MM-dd";
                options.DefaultTimeFormat     = "HH:mm:ss";
                options.CronExpressionOptions = new CronExpressionDescriptor.Options()
                {
                    DayOfWeekStartIndexZero = false //Quartz uses 1-7 as the range
                };
            }, authenticationOptions =>
            {
                authenticationOptions.AuthScheme              = CookieAuthenticationDefaults.AuthenticationScheme;
                authenticationOptions.SilkierQuartzClaim      = "Silkier";
                authenticationOptions.SilkierQuartzClaimValue = "Quartz";
                authenticationOptions.UserName          = settings.SilkierUsername;
                authenticationOptions.UserPassword      = settings.SilkierPassword;
                authenticationOptions.AccessRequirement = SilkierQuartzAuthenticationOptions.SimpleAccessRequirement.AllowAnonymous;//登录认证有问题
            }, stdSchedulerFactoryOption =>
            {
                //opt.Add("quartz.serializer.type", "json");
                //opt.Add("quartz.jobStore.type", "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz");
                //opt.Add("quartz.jobStore.driverDelegateType", "Quartz.Impl.AdoJobStore.StdAdoDelegate, Quartz");
                //opt.Add("quartz.jobStore.tablePrefix", "qrtz_");
                //opt.Add("quartz.jobStore.dataSource", "myDS");
                //opt.Add("quartz.dataSource.myDS.provider", "Npgsql");
                //opt.Add("quartz.dataSource.myDS.connectionString", Configuration.GetConnectionString("IoTSharp"));
                stdSchedulerFactoryOption.Add("quartz.plugin.recentHistory.type", "Quartz.Plugins.RecentHistory.ExecutionHistoryPlugin, Quartz.Plugins.RecentHistory");
                stdSchedulerFactoryOption.Add("quartz.plugin.recentHistory.storeType", "Quartz.Plugins.RecentHistory.Impl.InProcExecutionHistoryStore, Quartz.Plugins.RecentHistory");
            }
                                      );
            services.AddControllers();

            services.AddMemoryCache();
            string _hc_Caching = $"{nameof(CachingUseIn)}-{Enum.GetName(settings.CachingUseIn)}";

            services.AddEasyCaching(options =>
            {
                switch (settings.CachingUseIn)
                {
                case CachingUseIn.Redis:
                    options.UseRedis(config =>
                    {
                        settings.CachingUseRedisHosts?.Split(';').ToList().ForEach(h =>
                        {
                            var hx = h.Split(':');
                            config.DBConfig.Endpoints.Add(new ServerEndPoint(hx[0], int.Parse(hx[1])));
                        });
                    }, "iotsharp");
                    healthChecks.AddRedis(settings.CachingUseRedisHosts, name: _hc_Caching);
                    break;

                case CachingUseIn.LiteDB:
                    options.UseLiteDB(cfg => cfg.DBConfig = new EasyCaching.LiteDB.LiteDBDBOptions()
                    {
                    }, name: "iotsharp");
                    break;

                case CachingUseIn.InMemory:
                default:
                    options.UseInMemory("iotsharp");
                    break;
                }
            });
            string _hc_telemetryStorage = $"{nameof(TelemetryStorage)}-{Enum.GetName(settings.TelemetryStorage)}";

            switch (settings.TelemetryStorage)
            {
            case TelemetryStorage.Sharding:
                services.AddEFCoreSharding(config =>
                {
                    switch (settings.DataBase)
                    {
                    case DataBaseType.MySql:
                        config.UseMySqlToSharding(Configuration.GetConnectionString("TelemetryStorage"), settings.Sharding.ExpandByDateMode);
                        break;

                    case DataBaseType.SqlServer:
                        config.UseSqlServerToSharding(Configuration.GetConnectionString("TelemetryStorage"), settings.Sharding.ExpandByDateMode);
                        break;

                    case DataBaseType.Oracle:
                        config.UseOracleToSharding(Configuration.GetConnectionString("TelemetryStorage"), settings.Sharding.ExpandByDateMode);
                        break;

                    case DataBaseType.Sqlite:
                        config.UseSQLiteToSharding(Configuration.GetConnectionString("TelemetryStorage"), settings.Sharding.ExpandByDateMode);
                        break;

                    case DataBaseType.PostgreSql:
                    default:
                        config.UseNpgsqlToSharding(Configuration.GetConnectionString("TelemetryStorage"), settings.Sharding.ExpandByDateMode);
                        break;
                    }
                    config.SetEntityAssemblies(new Assembly[] { typeof(TelemetryData).Assembly });
                });
                services.AddSingleton <IStorage, ShardingStorage>();
                break;

            case TelemetryStorage.Taos:
                services.AddSingleton <IStorage, TaosStorage>();
                services.AddObjectPool(() => new TaosConnection(settings.ConnectionStrings["TelemetryStorage"]));
                healthChecks.AddTDengine(Configuration.GetConnectionString("TelemetryStorage"), name: _hc_telemetryStorage);
                break;

            case TelemetryStorage.InfluxDB:
                //https://github.com/julian-fh/influxdb-setup
                services.AddSingleton <IStorage, InfluxDBStorage>();
                //"TelemetryStorage": "http://localhost:8086/?org=iotsharp&bucket=iotsharp-bucket&token=iotsharp-token"
                services.AddObjectPool(() => InfluxDBClientFactory.Create(Configuration.GetConnectionString("TelemetryStorage")));
                //healthChecks.AddInfluxDB(Configuration.GetConnectionString("TelemetryStorage"),name: _hc_telemetryStorage);
                break;

            case TelemetryStorage.PinusDB:
                services.AddSingleton <IStorage, PinusDBStorage>();
                services.AddObjectPool(() =>
                {
                    var cnt = new PinusConnection(settings.ConnectionStrings["TelemetryStorage"]);
                    cnt.Open();
                    return(cnt);
                });
                healthChecks.AddPinusDB(Configuration.GetConnectionString("TelemetryStorage"), name: _hc_telemetryStorage);
                break;

            case TelemetryStorage.TimescaleDB:
                services.AddSingleton <IStorage, TimescaleDBStorage>();
                break;

            case TelemetryStorage.SingleTable:
            default:
                services.AddSingleton <IStorage, EFStorage>();
                break;
            }

            services.AddTransient <IEventBusHandler, EventBusHandler>();
            if (settings.ZMQOption != null)
            {
                services.AddHostedZeroMQ(cfg => cfg = settings.ZMQOption);
            }
            services.AddCap(x =>
            {
                string _hc_EventBusStore     = $"{nameof(EventBusStore)}-{Enum.GetName(settings.EventBusStore)}";
                x.SucceedMessageExpiredAfter = settings.SucceedMessageExpiredAfter;
                x.ConsumerThreadCount        = settings.ConsumerThreadCount;
                switch (settings.EventBusStore)
                {
                case EventBusStore.PostgreSql:
                    x.UsePostgreSql(Configuration.GetConnectionString("EventBusStore"));
                    healthChecks.AddNpgSql(Configuration.GetConnectionString("EventBusStore"), name: _hc_EventBusStore);
                    break;

                case EventBusStore.MongoDB:
                    x.UseMongoDB(Configuration.GetConnectionString("EventBusStore"));      //注意,仅支持MongoDB 4.0+集群
                    healthChecks.AddMongoDb(Configuration.GetConnectionString("EventBusStore"), name: _hc_EventBusStore);
                    break;

                case EventBusStore.LiteDB:
                    x.UseLiteDBStorage(Configuration.GetConnectionString("EventBusStore"));
                    break;

                case EventBusStore.InMemory:
                default:
                    x.UseInMemoryStorage();
                    break;
                }
                string _hc_EventBusMQ = $"{nameof(EventBusMQ)}-{Enum.GetName(settings.EventBusMQ)}";
                switch (settings.EventBusMQ)
                {
                case EventBusMQ.RabbitMQ:
                    var url = new Uri(Configuration.GetConnectionString("EventBusMQ"));
                    x.UseRabbitMQ(cfg =>
                    {
                        cfg.ConnectionFactoryOptions = cf =>
                        {
                            cf.AutomaticRecoveryEnabled = true;
                            cf.Uri = new Uri(Configuration.GetConnectionString("EventBusMQ"));
                        };
                    });
                    //amqp://guest:guest@localhost:5672
                    healthChecks.AddRabbitMQ(connectionFactory =>
                    {
                        var factory = new ConnectionFactory()
                        {
                            Uri = new Uri(Configuration.GetConnectionString("EventBusMQ")),
                            AutomaticRecoveryEnabled = true
                        };
                        return(factory.CreateConnection());
                    }, _hc_EventBusMQ);
                    break;

                case EventBusMQ.Kafka:
                    x.UseKafka(Configuration.GetConnectionString("EventBusMQ"));
                    healthChecks.AddKafka(cfg =>
                    {
                        cfg.BootstrapServers = Configuration.GetConnectionString("EventBusMQ");
                    }, name: _hc_EventBusMQ);
                    break;

                case EventBusMQ.ZeroMQ:
                    x.UseZeroMQ(cfg =>
                    {
                        cfg.HostName = Configuration.GetConnectionString("EventBusMQ") ?? "127.0.0.1";
                        cfg.Pattern  = MaiKeBing.CAP.NetMQPattern.PushPull;
                    });
                    break;

                case EventBusMQ.InMemory:
                default:
                    x.UseInMemoryMessageQueue();
                    break;
                }
                x.UseDashboard();
                if (settings.Discovery != null)
                {
                    x.UseDiscovery(cfg => cfg = settings.Discovery);
                }
            });

            services.Configure <BaiduTranslateProfile>(Configuration.GetSection("BaiduTranslateProfile"));
            services.AddControllers().AddNewtonsoftJson(options =>
            {
                options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            });
            services.AddRazorPages();

            // In production, the Angular files will be served from this directory
            services.AddSpaStaticFiles(configuration =>
            {
                configuration.RootPath = "ClientApp/dist";
            });
            services.AddScriptEngines(Configuration.GetSection("EngineSetting"));
            services.AddTransient <FlowRuleProcessor>();
            services.AddSingleton <TaskExecutorHelper>();
            services.AddTransient <PublishAttributeDataTask>();
            services.AddTransient <PublishTelemetryDataTask>();
        }