track/src/SJZY.Track.Application/SjzyTrackApplicationModule.cs
2025-05-13 14:30:03 +08:00

243 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
});
});
}
}