BusinessHostModule.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. using Autofac.Core;
  2. using Business.Core.MongoDBHelper;
  3. using Business.Core.Utilities;
  4. using Business.EntityFrameworkCore;
  5. using Business.MultiTenancy;
  6. using Business.Quartz;
  7. using GZY.Quartz.MUI.EFContext;
  8. using GZY.Quartz.MUI.Extensions;
  9. using Microsoft.AspNetCore.Authentication.JwtBearer;
  10. using Microsoft.AspNetCore.Builder;
  11. using Microsoft.AspNetCore.Cors;
  12. using Microsoft.AspNetCore.DataProtection;
  13. using Microsoft.AspNetCore.Hosting;
  14. using Microsoft.EntityFrameworkCore;
  15. using Microsoft.Extensions.Configuration;
  16. using Microsoft.Extensions.DependencyInjection;
  17. using Microsoft.Extensions.Hosting;
  18. using Microsoft.Extensions.Logging;
  19. using Microsoft.OpenApi.Models;
  20. using NLog;
  21. using NLog.Extensions.Logging;
  22. using NLog.Web;
  23. using Quartz;
  24. using Serilog.Events;
  25. using StackExchange.Redis;
  26. using System;
  27. using System.Collections.Generic;
  28. using System.Data;
  29. using System.IO;
  30. using System.Linq;
  31. using Volo.Abp;
  32. using Volo.Abp.AspNetCore.ExceptionHandling;
  33. using Volo.Abp.AspNetCore.MultiTenancy;
  34. using Volo.Abp.AspNetCore.Mvc;
  35. using Volo.Abp.AspNetCore.Serilog;
  36. using Volo.Abp.Autofac;
  37. using Volo.Abp.Caching;
  38. using Volo.Abp.Data;
  39. using Volo.Abp.EntityFrameworkCore.MySQL;
  40. using Volo.Abp.Localization;
  41. using Volo.Abp.Modularity;
  42. using Volo.Abp.MultiTenancy;
  43. using Volo.Abp.Threading;
  44. using Volo.Abp.VirtualFileSystem;
  45. using Bussiness.MongoDB;
  46. namespace Business
  47. {
  48. [DependsOn(
  49. typeof(AbpAutofacModule),
  50. typeof(AbpEntityFrameworkCoreMySQLModule),
  51. typeof(BusinessHttpApiModule),
  52. typeof(BusinessApplicationModule),
  53. typeof(BusinessEntityFrameworkCoreModule),
  54. typeof(BussinessMongoDbModule),
  55. typeof(AbpAspNetCoreMultiTenancyModule),
  56. typeof(AbpAspNetCoreSerilogModule)
  57. )]
  58. public class BusinessHostModule : AbpModule
  59. {
  60. private const string DefaultCorsPolicyName = "Default";
  61. public override void ConfigureServices(ServiceConfigurationContext context)
  62. {
  63. var configuration = context.Services.GetConfiguration();
  64. var hostingEnvironment = context.Services.GetHostingEnvironment();
  65. //ConfigureConventionalControllers();
  66. ConfigureMultiTenancy();
  67. ConfigureAuthentication(context, configuration);
  68. ConfigureLocalization();
  69. ConfigureCache(configuration);
  70. ConfigureVirtualFileSystem(context, hostingEnvironment);
  71. //ConfigureRedis(context, configuration, hostingEnvironment);
  72. ConfigureCors(context, configuration);
  73. ConfigureSwaggerServices(context, configuration);
  74. ConfigureQuartz(context, configuration);
  75. //MongoDB依赖注入
  76. ConfigureMongoDB(configuration);
  77. if (hostingEnvironment.IsDevelopment())
  78. {
  79. Configure<AbpExceptionHandlingOptions>(options =>
  80. {
  81. options.SendExceptionsDetailsToClients = true;
  82. });
  83. }
  84. }
  85. private void ConfigureConventionalControllers()
  86. {
  87. Configure<AbpAspNetCoreMvcOptions>(options =>
  88. {
  89. options.ConventionalControllers.Create(typeof(BusinessApplicationModule).Assembly);
  90. });
  91. }
  92. private void ConfigureMultiTenancy()
  93. {
  94. Configure<AbpMultiTenancyOptions>(options =>
  95. {
  96. options.IsEnabled = true;
  97. });
  98. }
  99. private void ConfigureQuartz(ServiceConfigurationContext context, IConfiguration configuration)
  100. {
  101. //程序启动执行一次日志分表检查,可以自己初始化避免需要部署脚本
  102. LogHostedService logHostedService = new LogHostedService();
  103. logHostedService.LogInstall();
  104. context.Services.AddQuartz(q =>
  105. {
  106. q.UseMicrosoftDependencyInjectionScopedJobFactory();
  107. // Just use the name of your job that you created in the Jobs folder.
  108. var jobKey = new JobKey("SyncDataJob");
  109. q.AddJob<SyncMySQLDataJob>(opts => opts.WithIdentity(jobKey));
  110. q.AddTrigger(opts => opts
  111. .ForJob(jobKey)
  112. .WithIdentity("SyncDataJob-trigger")
  113. .WithCronSchedule("0 38 10 * * ?")
  114. .WithDescription("定时同步MySQL基础数据到MongoDB"));
  115. var NLogJobKey = new JobKey("NLogJob");
  116. q.AddJob<NLogJob>(opts => opts.WithIdentity(NLogJobKey));
  117. q.AddTrigger(opts => opts
  118. .ForJob(NLogJobKey)
  119. .WithIdentity("NLogJob-trigger")
  120. .WithCronSchedule("0 01 01 * * ?")
  121. .WithDescription("定时创建NLog日志按月分表"));
  122. //var ExtJobKey = new JobKey("ExtJob");
  123. //q.AddJob<ExtJob>(opts => opts.WithIdentity(ExtJobKey));
  124. //q.AddTrigger(opts => opts
  125. // .ForJob(ExtJobKey)
  126. // .WithIdentity("ExtJob-trigger")
  127. // .WithCronSchedule("0 01 01 * * ?")
  128. // .WithDescription("定时处理金蝶同步到Ext数据库的数据"));
  129. var WMSJobKey = new JobKey("WMSJob");
  130. q.AddJob<WMSJob>(opts => opts.WithIdentity(WMSJobKey));
  131. q.AddTrigger(opts => opts
  132. .ForJob(WMSJobKey)
  133. .WithIdentity("WMSJob-trigger")
  134. .WithCronSchedule("0 32 15 * * ?")
  135. .WithDescription("定时同步WMS物料订单等基础数据到MySQL"));
  136. //var ProductionScheduleJobKey = new JobKey("ProductionScheduleJob");
  137. //q.AddJob<ProductionScheduleJob>(opts => opts.WithIdentity(ProductionScheduleJobKey));
  138. //q.AddTrigger(opts => opts
  139. // .ForJob(ProductionScheduleJobKey)
  140. // .WithIdentity("ProductionScheduleJob-trigger")
  141. // .WithCronSchedule("0 01 01 * * ?")
  142. // .WithDescription("定时排产任务"));
  143. });
  144. context.Services.AddQuartzServer(options =>
  145. {
  146. // when shutting down we want jobs to complete gracefully
  147. options.WaitForJobsToComplete = true;
  148. });
  149. context.Services.AddQuartzUI();
  150. context.Services.AddQuartzClassJobs(); //添加本地调度任务访问
  151. context.Services.AddQuartzHostedService(options =>
  152. {
  153. // when shutting down we want jobs to complete gracefully
  154. options.WaitForJobsToComplete = true;
  155. });
  156. }
  157. /// <summary>
  158. /// MongoDB依赖注入
  159. /// </summary>
  160. /// <param name="context"></param>
  161. /// <param name="configuration"></param>
  162. private void ConfigureMongoDB(IConfiguration configuration)
  163. {
  164. Configure<Config>(options =>
  165. {
  166. options.connectstring = configuration.GetConnectionString("MongoDB");
  167. options.database = configuration.GetConnectionString("DBName");
  168. });
  169. }
  170. private void ConfigureCache(IConfiguration configuration)
  171. {
  172. Configure<AbpDistributedCacheOptions>(options =>
  173. {
  174. options.KeyPrefix = "dopbiz:";
  175. });
  176. }
  177. private void ConfigureVirtualFileSystem(ServiceConfigurationContext context, IWebHostEnvironment webHostEnvironment)
  178. {
  179. //var hostingEnvironment = context.Services.GetHostingEnvironment();
  180. if (webHostEnvironment.IsDevelopment())
  181. {
  182. Configure<AbpVirtualFileSystemOptions>(options =>
  183. {
  184. options.FileSets.ReplaceEmbeddedByPhysical<BusinessDomainModule>(Path.Combine(webHostEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}Business.Domain"));
  185. options.FileSets.ReplaceEmbeddedByPhysical<BusinessApplicationContractsModule>(Path.Combine(webHostEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}Business.Application.Contracts"));
  186. options.FileSets.ReplaceEmbeddedByPhysical<BusinessApplicationModule>(Path.Combine(webHostEnvironment.ContentRootPath, $"..{Path.DirectorySeparatorChar}Business.Application"));
  187. });
  188. }
  189. }
  190. private void ConfigureAuthentication(ServiceConfigurationContext context, IConfiguration configuration)
  191. {
  192. context.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
  193. .AddJwtBearer(options =>
  194. {
  195. options.Authority = configuration["AuthServer:Authority"];
  196. options.RequireHttpsMetadata = false;
  197. options.Audience = "BusinessService";
  198. });
  199. }
  200. private static void ConfigureSwaggerServices(ServiceConfigurationContext context, IConfiguration configuration)
  201. {
  202. if (configuration["UseSwagger"] == "true")
  203. {
  204. context.Services.AddSwaggerGen(options =>
  205. {
  206. options.SwaggerDoc("v1", new OpenApiInfo { Title = "Business Service API", Version = "v1" });
  207. options.DocInclusionPredicate((docName, description) => true);
  208. options.CustomSchemaIds(type => type.FullName);
  209. options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
  210. {
  211. Description = "请输入JWT令牌,例如:Bearer 12345abcdef",
  212. Name = "Authorization",
  213. In = ParameterLocation.Header,
  214. Type = SecuritySchemeType.ApiKey,
  215. Scheme = "Bearer"
  216. });
  217. options.AddSecurityRequirement(new OpenApiSecurityRequirement()
  218. {
  219. {
  220. new OpenApiSecurityScheme
  221. {
  222. Reference = new OpenApiReference
  223. {
  224. Type = ReferenceType.SecurityScheme,
  225. Id = "Bearer"
  226. },
  227. Scheme = "oauth2",
  228. Name = "Bearer",
  229. In = ParameterLocation.Header,
  230. },
  231. new List<string>()
  232. }
  233. });
  234. });
  235. }
  236. }
  237. private void ConfigureLocalization()
  238. {
  239. Configure<AbpLocalizationOptions>(options =>
  240. {
  241. options.Languages.Add(new LanguageInfo("cs", "cs", "Čeština"));
  242. options.Languages.Add(new LanguageInfo("en", "en", "English"));
  243. options.Languages.Add(new LanguageInfo("pt-BR", "pt-BR", "Português"));
  244. options.Languages.Add(new LanguageInfo("tr", "tr", "Türkçe"));
  245. options.Languages.Add(new LanguageInfo("zh-Hans", "zh-Hans", "简体中文"));
  246. options.Languages.Add(new LanguageInfo("zh-Hant", "zh-Hant", "繁體中文"));
  247. });
  248. }
  249. private void ConfigureRedis(
  250. ServiceConfigurationContext context,
  251. IConfiguration configuration,
  252. IWebHostEnvironment hostingEnvironment)
  253. {
  254. context.Services.AddStackExchangeRedisCache(options =>
  255. {
  256. options.Configuration = configuration["Redis:Configuration"];
  257. });
  258. if (!hostingEnvironment.IsDevelopment())
  259. {
  260. var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]);
  261. context.Services
  262. .AddDataProtection()
  263. .PersistKeysToStackExchangeRedis(redis, "DataProtection-Keys");
  264. }
  265. }
  266. private void ConfigureCors(ServiceConfigurationContext context, IConfiguration configuration)
  267. {
  268. context.Services.AddCors(options =>
  269. {
  270. options.AddPolicy(DefaultCorsPolicyName, builder =>
  271. {
  272. builder
  273. .WithOrigins(
  274. configuration["App:CorsOrigins"]
  275. .Split(",", StringSplitOptions.RemoveEmptyEntries)
  276. .Select(o => o.RemovePostFix("/"))
  277. .ToArray()
  278. )
  279. .WithAbpExposedHeaders()
  280. .SetIsOriginAllowedToAllowWildcardSubdomains()
  281. .AllowAnyHeader()
  282. .AllowAnyMethod()
  283. .AllowCredentials();
  284. });
  285. });
  286. }
  287. public override void OnApplicationInitialization(ApplicationInitializationContext context)
  288. {
  289. var app = context.GetApplicationBuilder();
  290. var configuration = context.GetConfiguration();
  291. app.UseCorrelationId();
  292. app.UseStaticFiles();
  293. app.UseRouting();
  294. app.UseCors(DefaultCorsPolicyName);
  295. app.UseAuthentication();
  296. app.UseAbpClaimsMap();
  297. if (MultiTenancyConsts.IsEnabled)
  298. {
  299. app.UseMultiTenancy();
  300. }
  301. app.UseAbpRequestLocalization();
  302. if (configuration["UseSwagger"] == "true")
  303. {
  304. app.UseSwagger();
  305. app.UseSwaggerUI(options =>
  306. {
  307. options.SwaggerEndpoint("/swagger/v1/swagger.json", "Business Service API");
  308. });
  309. }
  310. app.UseAuditing();
  311. app.UseAbpSerilogEnrichers();
  312. app.UseUnitOfWork();
  313. app.UseConfiguredEndpoints();
  314. app.UseQuartz();
  315. //AsyncHelper.RunSync(async () =>
  316. //{
  317. // using (var scope = context.ServiceProvider.CreateScope())
  318. // {
  319. // await scope.ServiceProvider
  320. // .GetRequiredService<IDataSeeder>()
  321. // .SeedAsync();
  322. // }
  323. //});
  324. }
  325. }
  326. }