|
| 1 | +// <copyright file="Program.cs" company="MPCoreDeveloper"> |
| 2 | +// Copyright (c) 2026 MPCoreDeveloper and GitHub Copilot. All rights reserved. |
| 3 | +// Licensed under the MIT License. |
| 4 | +// </copyright> |
| 5 | + |
| 6 | +using Microsoft.AspNetCore.Server.Kestrel.Core; |
| 7 | +using Serilog; |
| 8 | +using SharpCoreDB.Server.Core; |
| 9 | + |
| 10 | +// Create and configure the host |
| 11 | +var builder = WebApplication.CreateBuilder(args); |
| 12 | + |
| 13 | +// Configure Serilog |
| 14 | +Log.Logger = new LoggerConfiguration() |
| 15 | + .ReadFrom.Configuration(builder.Configuration) |
| 16 | + .Enrich.FromLogContext() |
| 17 | + .WriteTo.Console() |
| 18 | + .WriteTo.File( |
| 19 | + "logs/sharpcoredb-server-.log", |
| 20 | + rollingInterval: RollingInterval.Day, |
| 21 | + retainedFileCountLimit: 30) |
| 22 | + .CreateLogger(); |
| 23 | + |
| 24 | +builder.Host.UseSerilog(); |
| 25 | + |
| 26 | +// Configure Kestrel for gRPC and HTTP |
| 27 | +builder.WebHost.ConfigureKestrel((context, options) => |
| 28 | +{ |
| 29 | + var config = context.Configuration.GetSection("Server").Get<ServerConfiguration>(); |
| 30 | + if (config is null) |
| 31 | + { |
| 32 | + throw new InvalidOperationException("Server configuration is missing"); |
| 33 | + } |
| 34 | + |
| 35 | + // gRPC endpoint |
| 36 | + if (config.EnableGrpc) |
| 37 | + { |
| 38 | + options.ListenAnyIP(config.GrpcPort, listenOptions => |
| 39 | + { |
| 40 | + listenOptions.Protocols = HttpProtocols.Http2; |
| 41 | + |
| 42 | + if (config.Security.TlsEnabled && config.Security.TlsCertificatePath is not null) |
| 43 | + { |
| 44 | + listenOptions.UseHttps(config.Security.TlsCertificatePath, config.Security.TlsPrivateKeyPath); |
| 45 | + } |
| 46 | + }); |
| 47 | + } |
| 48 | + |
| 49 | + // HTTP REST API endpoint |
| 50 | + if (config.EnableHttp) |
| 51 | + { |
| 52 | + options.ListenAnyIP(config.HttpPort, listenOptions => |
| 53 | + { |
| 54 | + listenOptions.Protocols = HttpProtocols.Http1AndHttp2; |
| 55 | + }); |
| 56 | + } |
| 57 | +}); |
| 58 | + |
| 59 | +// Add services |
| 60 | +builder.Services.AddGrpc(options => |
| 61 | +{ |
| 62 | + options.MaxReceiveMessageSize = 100 * 1024 * 1024; // 100MB |
| 63 | + options.MaxSendMessageSize = 100 * 1024 * 1024; |
| 64 | +}); |
| 65 | + |
| 66 | +builder.Services.AddGrpcReflection(); |
| 67 | + |
| 68 | +// Add server configuration |
| 69 | +builder.Services.Configure<ServerConfiguration>( |
| 70 | + builder.Configuration.GetSection("Server")); |
| 71 | + |
| 72 | +// Add core services |
| 73 | +builder.Services.AddSingleton<NetworkServer>(); |
| 74 | + |
| 75 | +// Add health checks |
| 76 | +builder.Services.AddHealthChecks(); |
| 77 | + |
| 78 | +var app = builder.Build(); |
| 79 | + |
| 80 | +// Map gRPC services |
| 81 | +// TODO: Add gRPC service implementations in Phase 1, Week 2 |
| 82 | +// app.MapGrpcService<DatabaseServiceImpl>(); |
| 83 | +// app.MapGrpcService<VectorSearchServiceImpl>(); |
| 84 | + |
| 85 | +// Enable gRPC reflection for development |
| 86 | +if (app.Environment.IsDevelopment()) |
| 87 | +{ |
| 88 | + app.MapGrpcReflectionService(); |
| 89 | +} |
| 90 | + |
| 91 | +// Map health check endpoint |
| 92 | +app.MapHealthChecks("/health"); |
| 93 | + |
| 94 | +// Map REST API endpoints (placeholder) |
| 95 | +app.MapGet("/", () => new |
| 96 | +{ |
| 97 | + name = "SharpCoreDB Server", |
| 98 | + version = "1.5.0", |
| 99 | + status = "running", |
| 100 | + observability = "Serilog + HealthChecks" |
| 101 | +}); |
| 102 | + |
| 103 | +// Start the server |
| 104 | +Log.Information("Starting SharpCoreDB Server v1.5.0"); |
| 105 | +Log.Information("gRPC endpoint: {GrpcEndpoint}", $"http://localhost:{builder.Configuration["Server:GrpcPort"] ?? "5001"}"); |
| 106 | +Log.Information("HTTP endpoint: {HttpEndpoint}", $"http://localhost:{builder.Configuration["Server:HttpPort"] ?? "8080"}"); |
| 107 | + |
| 108 | +try |
| 109 | +{ |
| 110 | + // Start the network server |
| 111 | + var networkServer = app.Services.GetRequiredService<NetworkServer>(); |
| 112 | + await networkServer.StartAsync(app.Lifetime.ApplicationStopping); |
| 113 | + |
| 114 | + // Run the web host |
| 115 | + await app.RunAsync(); |
| 116 | +} |
| 117 | +catch (Exception ex) |
| 118 | +{ |
| 119 | + Log.Fatal(ex, "SharpCoreDB Server terminated unexpectedly"); |
| 120 | +} |
| 121 | +finally |
| 122 | +{ |
| 123 | + Log.Information("SharpCoreDB Server shutdown complete"); |
| 124 | + await Log.CloseAndFlushAsync(); |
| 125 | +} |
0 commit comments