MCP-서버 리팩토링 후 P&ID 추출 테스트전 다른 기능 확인 후 커밋
This commit is contained in:
155
src/Web/Program.cs
Normal file
155
src/Web/Program.cs
Normal file
@@ -0,0 +1,155 @@
|
||||
using ExperionCrawler.Core.Application.Interfaces;
|
||||
using ExperionCrawler.Core.Application.Services;
|
||||
using ExperionCrawler.Infrastructure.Certificates;
|
||||
using ExperionCrawler.Infrastructure.Csv;
|
||||
using ExperionCrawler.Infrastructure.Database;
|
||||
using ExperionCrawler.Infrastructure.Mcp;
|
||||
using ExperionCrawler.Infrastructure.OpcUa;
|
||||
using ExperionCrawler.Web;
|
||||
using Microsoft.AspNetCore.Mvc.ApplicationParts;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// ── MVC / Swagger ─────────────────────────────────────────────────────────────
|
||||
var mvcBuilder = builder.Services.AddControllers()
|
||||
.AddJsonOptions(opt =>
|
||||
{
|
||||
// JSON 직렬화 시 대소문자 구분 없이 처리하도록 PascalCase 유지
|
||||
opt.JsonSerializerOptions.PropertyNamingPolicy = null;
|
||||
});
|
||||
|
||||
// ── P&ID 컨트롤러 조건부 활성화 (기본: 비활성화) ─────────────────────────────
|
||||
// PidControllers:Enabled = true 로 설정 시 P&ID 관련 컨트롤러 활성화
|
||||
bool pidEnabled = builder.Configuration.GetValue<bool>("PidControllers:Enabled");
|
||||
if (!pidEnabled)
|
||||
{
|
||||
var partManager = mvcBuilder.PartManager;
|
||||
var excludedNames = new[] { "PidController", "ExperionPidController", "PidGraphController" };
|
||||
var existingProvider = partManager.FeatureProviders
|
||||
.OfType<Microsoft.AspNetCore.Mvc.Controllers.ControllerFeatureProvider>()
|
||||
.FirstOrDefault();
|
||||
if (existingProvider != null)
|
||||
{
|
||||
partManager.FeatureProviders.Remove(existingProvider);
|
||||
partManager.FeatureProviders.Add(new ExcludedControllersFeatureProvider(existingProvider, excludedNames));
|
||||
}
|
||||
}
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen(c =>
|
||||
c.SwaggerDoc("v1", new() { Title = "ExperionCrawler API", Version = "v1" }));
|
||||
|
||||
// ── Infrastructure ────────────────────────────────────────────────────────────
|
||||
builder.Services.AddSingleton<IExperionCertificateService, ExperionCertificateService>();
|
||||
builder.Services.AddSingleton<IExperionStatusCodeService, ExperionStatusCodeService>();
|
||||
builder.Services.AddSingleton<IOpcUaConfigProvider, OpcUaConfigProvider>();
|
||||
builder.Services.AddScoped<IExperionOpcClient, ExperionOpcClient>();
|
||||
builder.Services.AddScoped<IExperionCsvService, ExperionCsvService>();
|
||||
builder.Services.AddScoped<AssetLoader>();
|
||||
|
||||
// PostgreSQL – Ubuntu 서버에서 별도 설치 없이 동작
|
||||
Directory.CreateDirectory("data");
|
||||
builder.Services.AddDbContext<ExperionDbContext>(opt =>
|
||||
opt.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection")));
|
||||
builder.Services.AddScoped<IExperionDbService, ExperionDbService>();
|
||||
|
||||
// ── Application Services ──────────────────────────────────────────────────────
|
||||
builder.Services.AddScoped<ExperionCrawlService>();
|
||||
|
||||
// ── KST 시간대 관리 서비스 ──────────────────────────────────────────────────
|
||||
builder.Services.AddSingleton<IClock, SystemClock>();
|
||||
builder.Services.AddSingleton<KstClock>();
|
||||
|
||||
// ── 한글 시간 범위 추출기 ──────────────────────────────────────────────────
|
||||
builder.Services.AddSingleton<KoreanTimeRangeExtractor>();
|
||||
|
||||
// ── Text-to-SQL Service ──────────────────────────────────────────────────────
|
||||
builder.Services.AddSingleton<SqlValidatorOptions>(_ => new SqlValidatorOptions
|
||||
{
|
||||
RequiredTables = ["history_table"],
|
||||
AllowedTables = ["history_table", "node_map_master"],
|
||||
MaxSubqueryDepth = 4
|
||||
});
|
||||
builder.Services.AddSingleton<SqlValidator>();
|
||||
builder.Services.AddScoped<ITextToSqlService, TextToSqlService>();
|
||||
|
||||
// ── Realtime & History BackgroundServices ─────────────────────────────────────
|
||||
builder.Services.AddSingleton<ExperionRealtimeService>();
|
||||
builder.Services.AddSingleton<IExperionRealtimeService>(
|
||||
sp => sp.GetRequiredService<ExperionRealtimeService>());
|
||||
builder.Services.AddHostedService(
|
||||
sp => sp.GetRequiredService<ExperionRealtimeService>());
|
||||
builder.Services.AddHostedService<ExperionHistoryService>();
|
||||
|
||||
// ── MCP Service ───────────────────────────────────────────────────────────────
|
||||
// Python MCP 서버 (localhost:5001)와 통신
|
||||
// McpClient: 저수준 HTTP 클라이언트 / McpService: IMcpService 구현 (McpClient 위임)
|
||||
builder.Services.AddSingleton<McpClient>();
|
||||
builder.Services.AddSingleton<IMcpService, McpService>();
|
||||
builder.Services.AddHostedService<McpServerHostedService>();
|
||||
|
||||
// ── OPC UA Server BackgroundService ──────────────────────────────────────────
|
||||
builder.Services.AddSingleton<ExperionOpcServerService>();
|
||||
builder.Services.AddSingleton<IExperionOpcServerService>(
|
||||
sp => sp.GetRequiredService<ExperionOpcServerService>());
|
||||
builder.Services.AddHostedService(
|
||||
sp => sp.GetRequiredService<ExperionOpcServerService>());
|
||||
|
||||
// ── FastTable Service ─────────────────────────────────────────────────────────
|
||||
// 중요: Singleton으로 하나만 생성 후 IExperionFastService와 IHostedService 양쪽에 같은 인스턴스 공유
|
||||
builder.Services.AddSingleton<ExperionFastService>();
|
||||
builder.Services.AddSingleton<IExperionFastService>(sp => sp.GetRequiredService<ExperionFastService>());
|
||||
builder.Services.AddHostedService(sp => sp.GetRequiredService<ExperionFastService>());
|
||||
|
||||
// ── P&ID Services ───────────────────────────────────────────────────────────────
|
||||
builder.Services.AddScoped<IPidExtractorService, PidExtractorService>();
|
||||
builder.Services.AddScoped<ITagMappingService, TagMappingService>();
|
||||
builder.Services.AddScoped<IPidGraphService, PidGraphService>();
|
||||
builder.Services.AddDbContextFactory<ExperionDbContext>();
|
||||
builder.Services.AddScoped<IStatusStore, DbStatusStore>();
|
||||
builder.Services.AddSingleton<IPidGraphEventBroadcaster, PidGraphEventBroadcaster>();
|
||||
|
||||
// ── FastTable Cleanup Service ─────────────────────────────────────────────────
|
||||
builder.Services.AddHostedService<ExperionFastCleanupService>();
|
||||
|
||||
// ── CORS ──────────────────────────────────────────────────────────────────────
|
||||
builder.Services.AddCors(opt =>
|
||||
opt.AddDefaultPolicy(p => p.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader()));
|
||||
|
||||
// ── 포트 설정 (Ubuntu 환경: 기본 5000) ───────────────────────────────────────
|
||||
builder.WebHost.UseUrls("http://0.0.0.0:5000");
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// ── DB 초기화 ─────────────────────────────────────────────────────────────────
|
||||
try
|
||||
{
|
||||
using (var scope = app.Services.CreateScope())
|
||||
{
|
||||
var db = scope.ServiceProvider.GetRequiredService<IExperionDbService>();
|
||||
await db.InitializeAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// DB 초기화 실패 시 앱 시작 계속 — 기능 사용 시 지연 초기화
|
||||
var logger = app.Services.GetRequiredService<ILogger<Program>>();
|
||||
logger.LogWarning(ex, "[DB] 초기화 실패 — DB 관련 기능 비활성화 (앱 시작 계속)");
|
||||
}
|
||||
|
||||
// ── Middleware ────────────────────────────────────────────────────────────────
|
||||
app.UseCors();
|
||||
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
}
|
||||
|
||||
app.UseDefaultFiles(); // index.html
|
||||
app.UseStaticFiles(); // wwwroot/
|
||||
app.MapControllers();
|
||||
app.MapFallbackToFile("index.html");
|
||||
|
||||
app.Run();
|
||||
Reference in New Issue
Block a user