sozsoft-platform/api/src/Sozsoft.Platform.HttpApi.Host/Program.cs
2026-08-09 11:52:28 +03:00

215 lines
8.7 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;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Sozsoft.Platform.Enums;
using Sozsoft.Platform.DbStartup;
using Sozsoft.Platform.DynamicServices;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;
using Serilog.Sinks.PostgreSQL;
using static Sozsoft.Settings.SettingsConsts;
using DevExpress.AspNetCore;
namespace Sozsoft.Platform;
public class Program
{
public async static Task<int> Main(string[] args)
{
ConfigurePostgreSqlCompatibility();
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? ""}.json", true)
.Build();
// ── Veritabanı varlık kontrolü ────────────────────────────────────────
// Serilog SQL sink kurulmadan ve ABP modülleri yüklenmeden önce yapılmalı.
// DB yoksa minimal setup uygulaması çalıştırılır.
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Warning()
.WriteTo.Console()
.CreateLogger();
if (!DatabaseReadinessChecker.Probe(configuration).IsReady)
{
var setupResult = await SetupAppRunner.RunAsync(args, configuration);
if (setupResult != 0)
return setupResult;
// Kurulum uygulaması durdu — DB gerçekten hazır mı, tekrar doğrula.
DatabaseReadinessChecker.Invalidate();
if (!DatabaseReadinessChecker.Probe(configuration).IsReady)
{
Log.Fatal("Kurulum modu sonlandı ancak veritabanı hâlâ hazır değil — uygulama başlatılmıyor.");
return 1;
}
Log.Warning("Migration tamamlandı — tam uygulama başlatılıyor.");
}
// ── Veritabanı mevcut — tam ABP başlatma ─────────────────────────────
var columnWriters = new Dictionary<string, ColumnWriterBase>
{
{ "Message", new RenderedMessageColumnWriter() },
{ "Message_Template", new MessageTemplateColumnWriter() },
{ "Level", new LevelColumnWriter() },
{ "Timestamp", new TimestampColumnWriter() },
{ "Exception", new ExceptionColumnWriter() },
{ "Properties", new LogEventSerializedColumnWriter() }
};
var loggerConfig = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.WriteTo.Console(); // Konsola da log yaz
switch (DefaultDatabaseProvider)
{
case DatabaseProvider.PostgreSql:
loggerConfig = loggerConfig.WriteTo.PostgreSQL(
connectionString: configuration.GetConnectionString(DefaultDatabaseProvider),
tableName: TableNameResolver.GetFullTableName(nameof(TableNameEnum.LogEntry)),
columnOptions: columnWriters,
needAutoCreateTable: false,
respectCase: true
);
break;
case DatabaseProvider.SqlServer:
var sinkOptions = new Serilog.Sinks.MSSqlServer.MSSqlServerSinkOptions
{
TableName = TableNameResolver.GetFullTableName(nameof(TableNameEnum.LogEntry)),
AutoCreateSqlTable = false
};
loggerConfig = loggerConfig.WriteTo.MSSqlServer(
connectionString: configuration.GetConnectionString(DefaultDatabaseProvider),
sinkOptions: sinkOptions,
columnOptions: new Serilog.Sinks.MSSqlServer.ColumnOptions()
);
break;
default:
throw new InvalidOperationException("Unsupported database provider for logging.");
}
Log.Logger = loggerConfig.CreateLogger();
try
{
Log.Information("Starting Sozsoft.Platform.HttpApi.Host.");
var builder = WebApplication.CreateBuilder(args);
builder.Host.AddAppSettingsSecretsJson()
.UseAutofac()
.UseSerilog();
await builder.AddApplicationAsync<PlatformHttpApiHostModule>();
var baseDomain = builder.Configuration["App:BaseDomain"]?.Trim();
var extraOrigins = (builder.Configuration["App:CorsOrigins"] ?? "")
.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
builder.Services.AddCors(options =>
{
options.AddPolicy("Dynamic", policy =>
{
policy
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials()
.SetIsOriginAllowed(origin =>
{
if (!Uri.TryCreate(origin, UriKind.Absolute, out var uri))
return false;
var scheme = uri.Scheme.ToLowerInvariant();
var host = uri.Host.ToLowerInvariant();
if (builder.Environment.IsProduction()) //IsProduction
{
if (scheme != "https") return false;
if (!string.IsNullOrWhiteSpace(baseDomain))
{
var bd = baseDomain.ToLowerInvariant();
if (host == bd || host.EndsWith("." + bd))
return true;
}
foreach (var o in extraOrigins)
{
if (Uri.TryCreate(o, UriKind.Absolute, out var eo)
&& eo.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase)
&& eo.Host.Equals(host, StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}
else //IsDevelopment
{
if (scheme == "https" && (host == "localhost" || host == "127.0.0.1" || host == "[::1]")
|| (scheme == "http" && (host == "localhost" || host == "127.0.0.1" || host == "[::1]"))
|| (!string.IsNullOrWhiteSpace(baseDomain) && (host == $"dev.{baseDomain.ToLowerInvariant()}")))
return true;
foreach (var o in extraOrigins)
{
if (Uri.TryCreate(o, UriKind.Absolute, out var eo)
&& eo.Host.Equals(host, StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}
});
});
});
var app = builder.Build();
app.UseDevExpressControls();
app.UseCors("Dynamic");
// Dynamic Assembly Registration Delegate Setup
DynamicServiceCompiler.NotifyAssemblyRegistration = DynamicAssemblyRegistrationService.RequestAssemblyRegistration;
DynamicServiceCompiler.NotifyAssemblyUnregistration = DynamicAssemblyRegistrationService.RequestAssemblyUnregistration;
await app.InitializeApplicationAsync();
await app.RunAsync();
return 0;
}
catch (Exception ex)
{
if (ex is HostAbortedException)
{
throw;
}
Log.Fatal(ex, "Host terminated unexpectedly!");
return 1;
}
finally
{
Log.CloseAndFlush();
}
}
private static void ConfigurePostgreSqlCompatibility()
{
if (DefaultDatabaseProvider == DatabaseProvider.PostgreSql)
{
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
}
}
}