200 lines
7.2 KiB
C#
200 lines
7.2 KiB
C#
using Fake.AspNetCore;
|
||
using Fake.AspNetCore.Auditing;
|
||
using Fake.AspNetCore.Mvc;
|
||
using Fake.AspNetCore.Mvc.Conventions;
|
||
using Fake.Autofac;
|
||
using Fake.Modularity;
|
||
using Fake.Security.Claims;
|
||
using FluentValidation.AspNetCore;
|
||
using Hangfire;
|
||
using Microsoft.AspNetCore.Authorization;
|
||
using Microsoft.AspNetCore.Mvc;
|
||
using Microsoft.AspNetCore.Mvc.Authorization;
|
||
using Microsoft.OpenApi.Models;
|
||
using OpenTelemetry.Resources;
|
||
using OpenTelemetry.Trace;
|
||
using TrackCenter.Application;
|
||
using TrackCenter.Application.Hangfire;
|
||
using TrackCenter.Domain.Extensions;
|
||
using TrackCenter.Repository;
|
||
using TrackCenter.Repository.Otel;
|
||
using TrackCenter.Repository.Otel.Options;
|
||
using TrackCenter.Application.Filters;
|
||
|
||
namespace TrackCenter.Api;
|
||
|
||
[DependsOn(typeof(FakeAutofacModule))]
|
||
[DependsOn(typeof(FakeAspNetCoreModule))]
|
||
[DependsOn(typeof(TrackCenterApplicationModule))]
|
||
[DependsOn(typeof(TrackCenterRepositoryModule))]
|
||
public class TrackCenterApiModule : FakeModule
|
||
{
|
||
private const string DefaultCorsPolicyName = "default";
|
||
|
||
public override void PreConfigureServices(ServiceConfigurationContext context)
|
||
{
|
||
FakeClaimTypes.UserId = "mapId";
|
||
}
|
||
|
||
public override void ConfigureServices(ServiceConfigurationContext context)
|
||
{
|
||
var services = context.Services;
|
||
var configuration = context.Services.GetConfiguration();
|
||
|
||
services.Configure<FakeAspNetCoreMvcOptions>(options =>
|
||
{
|
||
options.ApplicationServices2Controller<TrackCenterApplicationModule>();
|
||
});
|
||
|
||
// 配置签名验证选项
|
||
services.Configure<SignatureValidationOptions>(configuration.GetSection("SignatureValidation"));
|
||
|
||
// 全局授权配置:所有接口默认需要授权
|
||
services.AddMvc(options =>
|
||
{
|
||
var policy = new AuthorizationPolicyBuilder()
|
||
.RequireAuthenticatedUser()
|
||
.Build();
|
||
options.Filters.Add(new AuthorizeFilter(policy));
|
||
// 添加签名验证过滤器
|
||
options.Filters.Add<SignatureValidationFilter>();
|
||
}).AddNewtonsoftJson();
|
||
|
||
//Json格式化全局处理
|
||
context.Services.Configure<MvcNewtonsoftJsonOptions>(options =>
|
||
{
|
||
options.SerializerSettings.ContractResolver =
|
||
new Newtonsoft.Json.Serialization.
|
||
CamelCasePropertyNamesContractResolver(); // 首字母小写(驼峰样式)
|
||
options.SerializerSettings.Converters.Add(new DateTimeJsonConverter("yyyy-MM-dd HH:mm:ss"));
|
||
options.SerializerSettings.Converters.Add(new LongJsonConverter());
|
||
});
|
||
|
||
services.AddFakeSwaggerGen(options =>
|
||
{
|
||
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
|
||
{
|
||
Description = "JWT授权数据将在请求头中进行传输,在下方输入Bearer {token} 即可,注意两者之间有空格",
|
||
Name = "Authorization",
|
||
In = ParameterLocation.Header,
|
||
Type = SecuritySchemeType.ApiKey
|
||
});
|
||
options.AddSecurityRequirement(new OpenApiSecurityRequirement
|
||
{
|
||
{
|
||
new OpenApiSecurityScheme
|
||
{
|
||
Reference = new OpenApiReference()
|
||
{
|
||
Id = "Bearer",
|
||
Type = ReferenceType.SecurityScheme
|
||
}
|
||
},
|
||
[]
|
||
}
|
||
});
|
||
})
|
||
.AddFakeAspNetCoreAuditing();
|
||
|
||
services.AddFluentValidationAutoValidation().AddFluentValidationClientsideAdapters();
|
||
|
||
var otelOptions = new OTelOptions()
|
||
{
|
||
EnableAspNetCore = true,
|
||
EnableHttpClient = true,
|
||
EnableSql = true
|
||
};
|
||
configuration.GetSection("OTel").Bind(otelOptions);
|
||
ActivityHelper.InitActivitySource(otelOptions);
|
||
services.AddOpenTelemetry()
|
||
.ConfigureResource(resource => resource.AddService(otelOptions.ServiceName))
|
||
.WithTracing(tracing =>
|
||
{
|
||
switch (otelOptions.SamplerType)
|
||
{
|
||
case SamplerType.AlwaysOn:
|
||
tracing.SetSampler(new AlwaysOnSampler());
|
||
break;
|
||
case SamplerType.AlwaysOff:
|
||
tracing.SetSampler(new AlwaysOffSampler());
|
||
break;
|
||
case SamplerType.ParentBasedSampler:
|
||
{
|
||
Sampler childSampler = otelOptions.ChildBasedSampler switch
|
||
{
|
||
SamplerType.AlwaysOn => new AlwaysOnSampler(),
|
||
SamplerType.AlwaysOff => new AlwaysOffSampler(),
|
||
SamplerType.TraceIdRatio =>
|
||
new TraceIdRatioBasedSampler(otelOptions.SamplerProbability),
|
||
_ => new AlwaysOnSampler(),
|
||
};
|
||
tracing.SetSampler(new ParentBasedSampler(childSampler));
|
||
}
|
||
break;
|
||
case SamplerType.TraceIdRatio:
|
||
tracing.SetSampler(new TraceIdRatioBasedSampler(otelOptions.SamplerProbability));
|
||
break;
|
||
default:
|
||
tracing.SetSampler(new AlwaysOnSampler());
|
||
break;
|
||
}
|
||
|
||
tracing.AddSource(otelOptions.ServiceName);
|
||
});
|
||
|
||
services.AddCors(options =>
|
||
{
|
||
options.AddPolicy(DefaultCorsPolicyName, builder =>
|
||
{
|
||
builder.WithOrigins(configuration.GetSection("App:CorsOrigins").Get<string[]>() ?? [])
|
||
.AllowAnyHeader()
|
||
.AllowAnyMethod()
|
||
.AllowCredentials();
|
||
});
|
||
});
|
||
|
||
services.AddFakeJwtAuthentication();
|
||
|
||
// 添加授权服务
|
||
services.AddAuthorization();
|
||
}
|
||
|
||
public override void ConfigureApplication(ApplicationConfigureContext context)
|
||
{
|
||
var app = context.GetWebApplication();
|
||
app.Use(async (httpContext, next) =>
|
||
{
|
||
httpContext.Request.EnableBuffering();
|
||
await next.Invoke();
|
||
});
|
||
|
||
app.UseFakeExceptionHandling();
|
||
|
||
app.MapControllers();
|
||
// Configure the HTTP request pipeline.
|
||
app.UseFakeSwagger();
|
||
|
||
app.UseRouting();
|
||
|
||
app.UseCors(DefaultCorsPolicyName);
|
||
|
||
// todo: 缺乏配置
|
||
app.UseHangfireDashboard("/hangfire", new DashboardOptions
|
||
{
|
||
DisplayStorageConnectionString = false,
|
||
IgnoreAntiforgeryToken = true,
|
||
AppPath = "",
|
||
PrefixPath = "",
|
||
DashboardTitle = "轨迹预警任务",
|
||
Authorization = [new AnonymousHangfireAuthorizationFilter()]
|
||
});
|
||
|
||
LogHelper.Info("Application started", true);
|
||
}
|
||
|
||
public override void Shutdown(ApplicationShutdownContext context)
|
||
{
|
||
LogHelper.Info("Application stoped", true);
|
||
}
|
||
}
|