Files
SNote/Server/Program.cs
T

116 lines
4.3 KiB
C#
Raw Normal View History

2026-06-01 05:09:20 +10:00
using System;
using System.IO;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using SNote.Server.Data;
using SNote.Server.Endpoints;
using SNote.Server.Security;
2026-05-28 02:54:17 +10:00
namespace SNote.Server;
public class Program
{
public static void Main(string[] args)
{
2026-06-01 05:09:20 +10:00
var builder = WebApplication.CreateBuilder(args);
2026-05-28 02:54:17 +10:00
2026-06-01 05:09:20 +10:00
// Add Configuration & DB Context (SQLite)
var dbPath = Path.Combine(AppContext.BaseDirectory, "snote_server.db");
builder.Services.AddDbContext<ServerDbContext>(options =>
options.UseSqlite($"Data Source={dbPath}"));
// Register custom security managers & HTTP utilities
builder.Services.AddSingleton<CertificateManager>();
builder.Services.AddSingleton<PeerCache>();
builder.Services.AddSingleton<HttpClient>();
2026-05-28 02:54:17 +10:00
2026-06-01 05:09:20 +10:00
// Register OpenAPI explorer
2026-05-28 02:54:17 +10:00
builder.Services.AddOpenApi();
var app = builder.Build();
2026-06-01 05:09:20 +10:00
// 1. Initialize SQLite Database Schema
using (var scope = app.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<ServerDbContext>();
db.Database.EnsureCreated();
}
// Configure Development Tools
2026-05-28 02:54:17 +10:00
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
}
2026-06-01 05:09:20 +10:00
// 2. Map Modular API Endpoint Classes
app.MapAuthEndpoints();
app.MapNodeEndpoints();
app.MapSyncEndpoints();
2026-05-28 02:54:17 +10:00
2026-06-01 05:09:20 +10:00
// Welcome / Healthcheck root
app.MapGet("/", () => Results.Ok(new
{
service = "SNote Server",
status = "Online",
time = DateTime.UtcNow
}));
2026-05-28 02:54:17 +10:00
2026-06-01 05:09:20 +10:00
// 3. Start Background Sync Runner
var hostApplicationLifetime = app.Services.GetRequiredService<IHostApplicationLifetime>();
var services = app.Services;
// Dynamic Bootstrapping check on startup
var config = app.Configuration;
var bootstrapUrl = config["BootstrapFromPeer"];
if (!string.IsNullOrEmpty(bootstrapUrl))
{
Task.Run(async () =>
{
// Wait briefly for server startup
await Task.Delay(2000);
using var scope = services.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<ServerDbContext>();
var certManager = scope.ServiceProvider.GetRequiredService<CertificateManager>();
var client = scope.ServiceProvider.GetRequiredService<HttpClient>();
await SyncEndpoints.BootstrapFromPeerServerAsync(bootstrapUrl, db, certManager, client);
});
}
2026-05-28 02:54:17 +10:00
2026-06-01 05:09:20 +10:00
// Dynamic Handshake: Connect to target destination server and register local address on startup
var destUrl = config["Sync:DestinationServerUrl"];
var localUrl = config["Sync:LocalServerUrl"];
if (!string.IsNullOrEmpty(destUrl) && !string.IsNullOrEmpty(localUrl))
{
Task.Run(async () =>
{
// Wait briefly for server startup
await Task.Delay(2000);
using var scope = services.CreateScope();
var certManager = scope.ServiceProvider.GetRequiredService<CertificateManager>();
var client = scope.ServiceProvider.GetRequiredService<HttpClient>();
await SyncEndpoints.RegisterPeerWithDestinationAsync(destUrl, localUrl, certManager, client);
});
}
2026-05-28 02:54:17 +10:00
2026-06-01 05:09:20 +10:00
// Heartbeat Loop: Periodic Downstream Heartbeat pinger pings downstream peers every 30 seconds
Task.Run(async () =>
{
var token = hostApplicationLifetime.ApplicationStopping;
using var scope = services.CreateScope();
var peerCache = scope.ServiceProvider.GetRequiredService<PeerCache>();
var certManager = scope.ServiceProvider.GetRequiredService<CertificateManager>();
var client = scope.ServiceProvider.GetRequiredService<HttpClient>();
await SyncEndpoints.StartHeartbeatPingerAsync(peerCache, certManager, client, token);
});
app.Run();
}
2026-05-28 02:54:17 +10:00
}