mirror of
https://github.com/andwati/telecom-platform.git
synced 2026-10-18 11:02:54 +00:00
feat: Add liveness and readiness health check endpoints with database connectivity validation
- Add Ping method to PostgresProfileStore to check database connection status - Add Ping method to ProfileRepository interface - Add /api/v1/health/live endpoint for liveness checks (always returns alive if service is running) - Add /api/v1/health/ready endpoint for readiness checks with database connectivity validation - Add readinessHandler that returns SERVICE_UNAVAILABLE status when database ping fails
This commit is contained in:
@@ -144,6 +144,15 @@ func (s *PostgresProfileStore) Close() error {
|
||||
return sqlDB.Close()
|
||||
}
|
||||
|
||||
// Ping checks if the database connection is alive.
|
||||
func (s *PostgresProfileStore) Ping() error {
|
||||
sqlDB, err := s.db.DB()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return sqlDB.Ping()
|
||||
}
|
||||
|
||||
// toRow maps domain -> row. Passthrough of CreatedAt/UpdatedAt lets GORM hooks
|
||||
// populate them on first save.
|
||||
func toRow(p *Profile) *profileRow {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ErrNotFound is returned when a profile lookup misses.
|
||||
@@ -39,4 +39,5 @@ type ProfileRepository interface {
|
||||
List(ctx context.Context, f ListFilter) ([]*Profile, int, error)
|
||||
UpdateState(ctx context.Context, iccid, state string) (*Profile, error)
|
||||
Delete(ctx context.Context, iccid string) error
|
||||
Ping() error
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ import (
|
||||
func setupRoutes(router *gin.Engine, client *es2.ES2Client, repo repository.ProfileRepository) {
|
||||
api := router.Group("/api/v1")
|
||||
api.GET("/health", healthHandler)
|
||||
api.GET("/health/ready", readinessHandler(repo))
|
||||
api.GET("/health/live", livenessHandler)
|
||||
|
||||
esim := api.Group("/esim")
|
||||
{
|
||||
@@ -39,3 +41,38 @@ func healthHandler(c *gin.Context) {
|
||||
"timestamp": time.Now().UTC(),
|
||||
})
|
||||
}
|
||||
|
||||
// livenessHandler returns a simple liveness check (always healthy if service is running).
|
||||
func livenessHandler(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"status": "alive",
|
||||
"service": "carrier-connector",
|
||||
"timestamp": time.Now().UTC(),
|
||||
})
|
||||
}
|
||||
|
||||
// readinessHandler checks if the service is ready to accept requests (database connectivity).
|
||||
func readinessHandler(repo repository.ProfileRepository) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
// Check database connectivity
|
||||
if err := repo.Ping(); err != nil {
|
||||
c.JSON(http.StatusServiceUnavailable, gin.H{
|
||||
"status": "not ready",
|
||||
"service": "carrier-connector",
|
||||
"timestamp": time.Now().UTC(),
|
||||
"error": "database connection failed",
|
||||
"details": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"status": "ready",
|
||||
"service": "carrier-connector",
|
||||
"timestamp": time.Now().UTC(),
|
||||
"checks": gin.H{
|
||||
"database": "ok",
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user