243 lines
11 KiB
C#
243 lines
11 KiB
C#
using System.Net;
|
||
using BSI.Stack.Rabbit;
|
||
using DotNetCore.CAP;
|
||
using DotNetCore.CAP.Internal;
|
||
using Hangfire;
|
||
using Hangfire.Redis.StackExchange;
|
||
using Microsoft.Extensions.Configuration;
|
||
using RabbitMQ.Client;
|
||
using Savorboard.CAP.InMemoryMessageQueue;
|
||
using SJZY.Expand.ABP.Core.Localization;
|
||
using SJZY.Expand.ABP.Core.Logger;
|
||
using SJZY.Expand.ABP.Core.PublicMethords;
|
||
using SJZY.Expand.AliyunOSS;
|
||
using SJZY.InterfaceRelay.Application.Contracts;
|
||
using SJZY.Track.Application.CAP;
|
||
using SJZY.Track.Application.Contract;
|
||
using SJZY.Track.Application.Hangfire;
|
||
using SJZY.Track.Application.Kafka;
|
||
using SJZY.Track.Application.Localization;
|
||
using SJZY.Track.Application.Options;
|
||
using SJZY.Track.Application.Track2InterfaceRelay;
|
||
using SJZY.UserCenter.Contracts;
|
||
using SJZY.UserCenter.SharedModel;
|
||
using SJZY.UserCenter.SharedModel.Pub;
|
||
using Volo.Abp.AspNetCore.Mvc;
|
||
using Volo.Abp.AutoMapper;
|
||
using Volo.Abp.FluentValidation;
|
||
using Volo.Abp.Http.Client;
|
||
using Volo.Abp.Localization;
|
||
using Volo.Abp.Modularity;
|
||
using Volo.Abp.VirtualFileSystem;
|
||
|
||
namespace SJZY.Track.Application;
|
||
|
||
[DependsOn(
|
||
typeof(AbpAutoMapperModule),
|
||
typeof(AbpFluentValidationModule),
|
||
typeof(AbpLocalizationModule),
|
||
typeof(AbpVirtualFileSystemModule),
|
||
typeof(AbpHttpClientModule),
|
||
typeof(SjzyUserCenterHttpApiModule),
|
||
typeof(SJZYInterfaceRelayApplicationContractsModule),
|
||
typeof(SjzyTrackDomainModule),
|
||
typeof(SjzyTrackApplicationContractModule)
|
||
)]
|
||
public class SjzyTrackApplicationModule : AbpModule
|
||
{
|
||
public override void ConfigureServices(ServiceConfigurationContext context)
|
||
{
|
||
var configuration = context.Services.GetConfiguration();
|
||
Configure<AbpAutoMapperOptions>(options => { options.AddMaps<SjzyTrackApplicationModule>(true); });
|
||
|
||
Configure<AbpAspNetCoreMvcOptions>(options =>
|
||
{
|
||
options.ConventionalControllers.Create(typeof(SjzyTrackApplicationModule).Assembly); //创建动态api
|
||
});
|
||
|
||
//添加虚拟文件系统
|
||
Configure<AbpVirtualFileSystemOptions>(options => { options.FileSets.AddEmbedded<SjzyTrackApplicationModule>("SJZY.Track.Application"); });
|
||
|
||
//添加多语言
|
||
var languageConfig = configuration.GetSection("Language");
|
||
Configure<AbpLocalizationOptions>(options =>
|
||
{
|
||
options.Resources
|
||
.Add<TrackLocalizationResource>("zh")
|
||
.AddBaseTypes(typeof(SjzyBasicLocalization))
|
||
.AddRedisResource(languageConfig)
|
||
.AddVirtualJson("/Localization/Resources");
|
||
});
|
||
//授权拦截提示
|
||
context.Services.Configure<MvcOptions>(options => { options.Filters.Add(new ApiAsyncAuthorizationFilter()); });
|
||
|
||
//用户中心
|
||
context.Services.AddHttpClientProxies(typeof(SjzyUserCenterHttpApiModule).Assembly, "UserCenter", false);
|
||
|
||
// 接口通
|
||
context.Services.Configure<Track2InterfaceRelayOptions>(configuration.GetSection("Track2InterfaceRelay"));
|
||
context.Services.AddHttpClient("InterfaceForward")
|
||
.AddHttpMessageHandler<Track2InterfaceRelayHttpMessageHandler>();
|
||
context.Services.AddHttpClientProxies(typeof(SJZYInterfaceRelayApplicationContractsModule).Assembly,
|
||
"InterfaceForward", false
|
||
);
|
||
|
||
//CAP
|
||
context.Services.AddSingleton<ISubscribeExecutor, MySubscribeExecutor>();
|
||
context.Services.AddCapTableNameService();
|
||
if (!System.Diagnostics.Debugger.IsAttached)
|
||
{
|
||
context.Services.AddCap(options =>
|
||
{
|
||
options.UseMySql(configuration["ConnectionStrings:DefaultConnection"]!);
|
||
options.UseRabbitMQ(configure =>
|
||
{
|
||
configure.HostName = configuration["RabbitMQ:HostName"]!;
|
||
configure.UserName = configuration["RabbitMQ:UserName"]!;
|
||
configure.Password = configuration["RabbitMQ:Password"]!;
|
||
configure.Port = configuration.GetValue<int>("RabbitMQ:Port");
|
||
configure.BasicQosOptions =
|
||
new RabbitMQOptions.BasicQos(configuration.GetValue<ushort>("CAP:PrefetchCount"));
|
||
});
|
||
options.FailedRetryInterval = configuration.GetValue<int>("CAP:FailedRetryInterval");
|
||
options.FailedRetryCount = configuration.GetValue<int>("CAP:FailedRetryCount");
|
||
options.SucceedMessageExpiredAfter = configuration.GetValue<int>("CAP:SucceedMessageExpiredAfter");
|
||
options.FallbackWindowLookbackSeconds =
|
||
configuration.GetValue<int>("CAP:FallbackWindowLookbackSeconds");
|
||
|
||
options.UseDashboard(dashboardOptions =>
|
||
{
|
||
dashboardOptions.PathBase = System.Diagnostics.Debugger.IsAttached
|
||
? ""
|
||
: configuration["Swagger:JsonUrlPrefix"]!;
|
||
});
|
||
options.FailedThresholdCallback = faileCalback =>
|
||
{
|
||
try
|
||
{
|
||
LogHelper.Error($@"
|
||
|-CAP失败回调事件:
|
||
|-处理类型:{(faileCalback.MessageType == DotNetCore.CAP.Messages.MessageType.Subscribe ? "消费消息达到最大重试次数,需要开发人员介入" : "生产消息推送失败")}
|
||
|-头部信息:{faileCalback.Message.Headers.ToJson()}");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogHelper.Error("【严重】CAP失败回调事件发生未处理异常" + ex);
|
||
}
|
||
};
|
||
}).AddSubscribeFilter<CapFilter>();
|
||
}
|
||
else
|
||
{
|
||
//是本地调试环境,用内存存储和内存队列
|
||
context.Services.AddCap(capOptions =>
|
||
{
|
||
capOptions.UseInMemoryStorage();
|
||
capOptions.UseInMemoryMessageQueue();
|
||
capOptions.UseDashboard();
|
||
}).AddSubscribeFilter<CapFilter>();
|
||
Console.WriteLine("-- 当前为VS本地环境,用内存存储和内存队列");
|
||
}
|
||
|
||
context.Services.AddRabbitBoot(options =>
|
||
{
|
||
options.ConnectionString =
|
||
$"amqp://{configuration["RabbitMQ:UserName"]}:{configuration["RabbitMQ:Password"]}@{configuration["RabbitMQ:HostName"]}:{configuration["RabbitMQ:Port"]}";
|
||
options.PoolSize = configuration.GetValue<int>("RabbitMQ:PoolSize");
|
||
options.Declarations = new List<Action<IDeclaration>>()
|
||
{
|
||
o => o.ExchangeDeclare(GlobalConst.TrackChangeExchange, ExchangeType.Topic, true),
|
||
o => o.ExchangeDeclare(GlobalConst.TrackPushExchange, ExchangeType.Topic, true)
|
||
};
|
||
options.Consumes = new List<ConsumeOptions>
|
||
{
|
||
new()
|
||
{
|
||
Queue = GlobalConst.TrackRefreshSubscribe,
|
||
FetchCount = configuration.GetValue<ushort>("TrackApp:TrackRefreshFetchCount"),
|
||
FailedRequeue = false,
|
||
Declaration = o =>
|
||
{
|
||
o.ExchangeDeclare(GlobalConst.InterfaceRelayExchange, ExchangeType.Direct, true);
|
||
o.QueueDeclare(GlobalConst.TrackRefreshSubscribe, true);
|
||
o.QueueBind(GlobalConst.TrackRefreshSubscribe, GlobalConst.InterfaceRelayExchange,
|
||
GlobalConst.TrackRefreshSubscribe);
|
||
}
|
||
},
|
||
new()
|
||
{
|
||
Queue = GlobalConst.TrackPushCompletedSubscribe,
|
||
FetchCount = configuration.GetValue<ushort>("TrackApp:TrackRefreshFetchCount"),
|
||
FailedRequeue = false,
|
||
Declaration = o =>
|
||
{
|
||
o.ExchangeDeclare(GlobalConst.InterfaceRelayExchange, ExchangeType.Direct, true);
|
||
o.QueueDeclare(GlobalConst.TrackPushCompletedSubscribe, true);
|
||
o.QueueBind(GlobalConst.TrackPushCompletedSubscribe, GlobalConst.InterfaceRelayExchange,
|
||
GlobalConst.TrackPushCompletedSubscribe);
|
||
}
|
||
}
|
||
};
|
||
}, typeof(SjzyTrackApplicationModule).Assembly);
|
||
|
||
context.Services.Configure<TrackAppOptions>(configuration.GetSection("TrackApp"));
|
||
context.Services.Configure<InterfaceRelayParamsConfigOptions>(
|
||
configuration.GetSection("InterfaceRelayParamsConfig"));
|
||
|
||
//注册阿里云OSS服务
|
||
context.Services.AddAliOSS(option =>
|
||
{
|
||
option.AccessKeyId = configuration["OSS:AccessKeyId"];
|
||
option.AccessKeySecret = configuration["OSS:AccessKeySecret"];
|
||
option.Endpoint = configuration["OSS:Endpoint"];
|
||
option.BucketName = configuration["OSS:BucketName"];
|
||
option.ReturnHttpsUrl = true;
|
||
});
|
||
|
||
var connectionString = $"{configuration["Redis:Host"]}" +
|
||
$",password={configuration["Redis:Password"]}" +
|
||
$",defaultDatabase={configuration["Redis:Database"]}" +
|
||
$",abortConnect=false";
|
||
|
||
// 注册预警计算服务
|
||
//context.Services.AddWarningCalcServices(configuration);
|
||
|
||
// 注册预警任务后台服务
|
||
context.Services.AddHostedService<WarningTaskComponentBackgroundService>();
|
||
|
||
// 注册HangFire服务
|
||
context.Services.Configure<TrackWarningTaskOptions>(configuration.GetSection("WarningTask"));
|
||
context.Services.AddHangfire(o =>
|
||
{
|
||
var options = new RedisStorageOptions
|
||
{
|
||
Prefix = $"{GlobalConst.TrackHangfireKeyPrefix}:",
|
||
Db = int.Parse(configuration["Redis:Database"]!),
|
||
};
|
||
o.UseRedisStorage(connectionString, options)
|
||
.WithJobExpirationTimeout(TimeSpan.FromHours(1)); // 终止态任务只保留1小时
|
||
});
|
||
context.Services.AddHangfireServer(o =>
|
||
{
|
||
// 索引越小优先级越高
|
||
o.Queues = new[] { GlobalConst.WarningJobQueueLevel0, GlobalConst.WarningJobQueueLevel1, GlobalConst.WarningJobQueueLevel2, "default" };
|
||
o.ServerName = Dns.GetHostName();
|
||
o.ShutdownTimeout = TimeSpan.FromSeconds(10);
|
||
o.WorkerCount = 1;
|
||
});
|
||
}
|
||
|
||
public override void PreConfigureServices(ServiceConfigurationContext context)
|
||
{
|
||
PreConfigure<AbpHttpClientBuilderOptions>(options =>
|
||
{
|
||
options.ProxyClientActions.Add((_, _, httpClient) =>
|
||
{
|
||
//如果设置Token,前端需要传入Token 否则引发异常
|
||
httpClient.SetTokenHeader();
|
||
httpClient.Timeout = TimeSpan.FromMinutes(3);
|
||
});
|
||
});
|
||
}
|
||
}
|