// internal/server/server.go
package server
import (
"context"
"fmt"
"net/http"
"time"
internallog "envoy-control-plane/internal/log"
"envoy-control-plane/internal/pkg/api"
)
// RunRESTServer starts the REST API server with graceful shutdown support.
func RunRESTServer(ctx context.Context, mux *http.ServeMux, restPort uint, webrootPath string, enableCertIssuance bool) {
log := internallog.LogFromContext(ctx)
corsHandler := api.CORS(mux)
restAddr := fmt.Sprintf(":%d", restPort)
log.Infof("starting REST API server on %s", restAddr)
if enableCertIssuance {
log.Infof("ACME challenge path configured: %s/ -> %s", api.ACME_CALLENGE_WEB_PATH, webrootPath)
}
srv := &http.Server{
Addr: restAddr,
Handler: corsHandler,
}
// Shutdown goroutine
go func() {
<-ctx.Done()
log.Infof("REST API server shutting down gracefully...")
shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := srv.Shutdown(shutdownCtx); err != nil {
log.Errorf("REST API server forced to shutdown: %v", err)
}
}()
// Start server (blocking)
err := srv.ListenAndServe()
if err != nil && err != http.ErrServerClosed {
log.Errorf("REST server error: %v", err)
}
}