package main import ( "context" "log" "os" "time" "github.com/gin-gonic/gin" "github.com/mrhid6/keymanager/server/internal/api" "github.com/mrhid6/keymanager/server/internal/auth" "github.com/mrhid6/keymanager/server/internal/db" grpcserver "github.com/mrhid6/keymanager/server/internal/grpc" "github.com/mrhid6/keymanager/server/internal/services" ) func main() { mongoURI := getEnv("MONGO_URI", "mongodb://localhost:27017") dbName := getEnv("MONGO_DB", "keymanager") if err := db.Connect(mongoURI, dbName); err != nil { log.Fatalf("failed to connect to MongoDB: %v", err) } log.Println("connected to MongoDB") redisAddr := getEnv("REDIS_ADDR", "localhost:6379") if err := auth.InitRedis(redisAddr); err != nil { log.Fatalf("failed to connect to Redis: %v", err) } log.Println("connected to Redis") if err := auth.InitOIDC(context.Background()); err != nil { log.Fatalf("failed to initialise OIDC: %v", err) } // Background goroutine to mark offline servers go func() { ticker := time.NewTicker(2 * time.Minute) defer ticker.Stop() for range ticker.C { if err := services.MarkOfflineServers(5 * time.Minute); err != nil { log.Printf("mark offline error: %v", err) } } }() // Start gRPC server go func() { if err := grpcserver.StartGRPC(9090); err != nil { log.Fatalf("gRPC server error: %v", err) } }() // Start REST server r := gin.Default() r.Use(corsMiddleware()) api.RegisterRoutes(r) log.Println("REST server listening on :8080") if err := r.Run(":8080"); err != nil { log.Fatalf("REST server error: %v", err) } } func corsMiddleware() gin.HandlerFunc { return func(c *gin.Context) { c.Header("Access-Control-Allow-Origin", "*") c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS") c.Header("Access-Control-Allow-Headers", "Content-Type, Authorization") if c.Request.Method == "OPTIONS" { c.AbortWithStatus(204) return } c.Next() } } func getEnv(key, fallback string) string { if v := os.Getenv(key); v != "" { return v } return fallback }