// ABOUTME: Entry point for the metrics receiver service. // ABOUTME: HTTP service using Fuego framework with automatic OpenAPI 3.0 generation. package main import ( "flag" "fmt" "log/slog" "os" "time" "github.com/getkin/kin-openapi/openapi3" "github.com/go-fuego/fuego" "edp.buildth.ing/DevFW-CICD/forgejo-runner-sizer/internal/receiver" ) const ( defaultAddr = ":8080" defaultDBPath = "metrics.db" ) func main() { addr := flag.String("addr", defaultAddr, "HTTP listen address") dbPath := flag.String("db", defaultDBPath, "SQLite database path") readToken := flag.String("read-token", os.Getenv("RECEIVER_READ_TOKEN"), "Pre-shared token for read endpoints (or set RECEIVER_READ_TOKEN)") hmacKey := flag.String("hmac-key", os.Getenv("RECEIVER_HMAC_KEY"), "Secret key for push token generation/validation (or set RECEIVER_HMAC_KEY)") tokenTTL := flag.Duration("token-ttl", 2*time.Hour, "Time-to-live for push tokens (default 2h)") flag.Parse() logger := slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{ Level: slog.LevelInfo, })) store, err := receiver.NewStore(*dbPath) if err != nil { logger.Error("failed to open database", slog.String("error", err.Error())) os.Exit(1) } defer func() { _ = store.Close() }() handler := receiver.NewHandler(store, logger, *readToken, *hmacKey, *tokenTTL) // Create Fuego server with OpenAPI configuration s := fuego.NewServer( fuego.WithAddr(*addr), fuego.WithEngineOptions( fuego.WithOpenAPIConfig(fuego.OpenAPIConfig{ PrettyFormatJSON: true, JSONFilePath: "docs/openapi.json", SwaggerURL: "/swagger", Info: &openapi3.Info{ Title: "Forgejo Runner Resource Collector API", Version: "1.0.0", Description: "HTTP service that receives and stores CI/CD resource metrics from collectors, providing query and sizing recommendation APIs.", Contact: &openapi3.Contact{ Name: "API Support", URL: "https://edp.buildth.ing/DevFW-CICD/forgejo-runner-sizer", }, License: &openapi3.License{ Name: "Apache 2.0", URL: "http://www.apache.org/licenses/LICENSE-2.0.html", }, }, }), ), ) // Register routes handler.RegisterRoutes(s) logger.Info("starting metrics receiver", slog.String("addr", *addr), slog.String("db", *dbPath), slog.String("swagger", fmt.Sprintf("http://localhost%s/swagger", *addr)), ) // Run server (handles graceful shutdown) if err := s.Run(); err != nil { fmt.Fprintf(os.Stderr, "error: %v\n", err) os.Exit(1) } }