mirror of
https://github.com/andwati/telecom-platform.git
synced 2026-11-11 14:35:13 +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()
|
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
|
// toRow maps domain -> row. Passthrough of CreatedAt/UpdatedAt lets GORM hooks
|
||||||
// populate them on first save.
|
// populate them on first save.
|
||||||
func toRow(p *Profile) *profileRow {
|
func toRow(p *Profile) *profileRow {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package repository
|
package repository
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrNotFound is returned when a profile lookup misses.
|
// ErrNotFound is returned when a profile lookup misses.
|
||||||
@@ -39,4 +39,5 @@ type ProfileRepository interface {
|
|||||||
List(ctx context.Context, f ListFilter) ([]*Profile, int, error)
|
List(ctx context.Context, f ListFilter) ([]*Profile, int, error)
|
||||||
UpdateState(ctx context.Context, iccid, state string) (*Profile, error)
|
UpdateState(ctx context.Context, iccid, state string) (*Profile, error)
|
||||||
Delete(ctx context.Context, iccid string) 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) {
|
func setupRoutes(router *gin.Engine, client *es2.ES2Client, repo repository.ProfileRepository) {
|
||||||
api := router.Group("/api/v1")
|
api := router.Group("/api/v1")
|
||||||
api.GET("/health", healthHandler)
|
api.GET("/health", healthHandler)
|
||||||
|
api.GET("/health/ready", readinessHandler(repo))
|
||||||
|
api.GET("/health/live", livenessHandler)
|
||||||
|
|
||||||
esim := api.Group("/esim")
|
esim := api.Group("/esim")
|
||||||
{
|
{
|
||||||
@@ -39,3 +41,38 @@ func healthHandler(c *gin.Context) {
|
|||||||
"timestamp": time.Now().UTC(),
|
"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