@@ -5,75 +5,102 @@ import (
55 "github.com/android-sms-gateway/server/internal/sms-gateway/handlers/base"
66 "github.com/android-sms-gateway/server/internal/sms-gateway/modules/health"
77 "github.com/android-sms-gateway/server/internal/version"
8- "github.com/capcom6/ go-helpers/maps "
8+ "github.com/go-playground/validator/v10 "
99 "github.com/gofiber/fiber/v2"
10- "go.uber.org/fx "
10+ "github.com/samber/lo "
1111 "go.uber.org/zap"
1212)
1313
14- type healthHanlderParams struct {
15- fx.In
16-
17- HealthSvc * health.Service
18-
19- Logger * zap.Logger
20- }
21-
2214type healthHandler struct {
2315 base.Handler
2416
2517 healthSvc * health.Service
18+ }
2619
27- logger * zap.Logger
20+ func newHealthHandler (
21+ healthSvc * health.Service ,
22+ logger * zap.Logger ,
23+ validator * validator.Validate ,
24+ ) * healthHandler {
25+ return & healthHandler {
26+ Handler : base.Handler {
27+ Logger : logger ,
28+ Validator : validator ,
29+ },
30+ healthSvc : healthSvc ,
31+ }
2832}
2933
30- // @Summary Health check
31- // @Description Checks if service is healthy
34+ // @Summary Liveness probe
35+ // @Description Checks if service is running (liveness probe)
3236// @Tags System
3337// @Produce json
34- // @Success 200 {object} smsgateway.HealthResponse "Health check result"
35- // @Failure 500 {object} smsgateway.HealthResponse "Service is unhealthy"
36- // @Router /3rdparty/v1/health [get]
38+ // @Success 200 {object} smsgateway.HealthResponse "Service is alive"
39+ // @Failure 503 {object} smsgateway.HealthResponse "Service is not alive"
40+ // @Router /health/live [get]
41+ //
42+ // Liveness probe
43+ func (h * healthHandler ) getLiveness (c * fiber.Ctx ) error {
44+ return writeProbe (c , h .healthSvc .CheckLiveness (c .Context ()))
45+ }
46+
47+ // @Summary Readiness probe
48+ // @Description Checks if service is ready to serve traffic (readiness probe)
49+ // @Tags System
50+ // @Produce json
51+ // @Success 200 {object} smsgateway.HealthResponse "Service is ready"
52+ // @Failure 503 {object} smsgateway.HealthResponse "Service is not ready"
53+ // @Router /health/ready [get]
54+ // @Router /3rdparty/v1/health [get]
3755//
38- // Health check
39- func (h * healthHandler ) getHealth (c * fiber.Ctx ) error {
40- check , err := h .healthSvc .HealthCheck (c .Context ())
41- if err != nil {
42- return err
56+ // Readiness probe
57+ func (h * healthHandler ) getReadiness (c * fiber.Ctx ) error {
58+ return writeProbe (c , h .healthSvc .CheckReadiness (c .Context ()))
59+ }
60+
61+ // @Summary Startup probe
62+ // @Description Checks if service has completed initialization (startup probe)
63+ // @Tags System
64+ // @Produce json
65+ // @Success 200 {object} smsgateway.HealthResponse "Service has completed initialization"
66+ // @Failure 503 {object} smsgateway.HealthResponse "Service has not completed initialization"
67+ // @Router /health/startup [get]
68+ //
69+ // Startup probe
70+ func (h * healthHandler ) getStartup (c * fiber.Ctx ) error {
71+ return writeProbe (c , h .healthSvc .CheckStartup (c .Context ()))
72+ }
73+
74+ func writeProbe (c * fiber.Ctx , r health.CheckResult ) error {
75+ status := fiber .StatusOK
76+ if r .Status () == health .StatusFail {
77+ status = fiber .StatusServiceUnavailable
4378 }
79+ return c .Status (status ).JSON (makeResponse (r ))
80+ }
4481
45- res := smsgateway.HealthResponse {
46- Status : smsgateway .HealthStatus (check .Status ),
82+ func makeResponse (result health.CheckResult ) smsgateway.HealthResponse {
83+ return smsgateway.HealthResponse {
84+ Status : smsgateway .HealthStatus (result .Status ()),
4785 Version : version .AppVersion ,
4886 ReleaseID : version .AppReleaseID (),
49- Checks : maps .MapValues (
50- check .Checks ,
51- func (c health.CheckDetail ) smsgateway.HealthCheck {
87+ Checks : lo .MapValues (
88+ result .Checks ,
89+ func (value health.CheckDetail , key string ) smsgateway.HealthCheck {
5290 return smsgateway.HealthCheck {
53- Description : c .Description ,
54- ObservedUnit : c .ObservedUnit ,
55- ObservedValue : c .ObservedValue ,
56- Status : smsgateway .HealthStatus (c .Status ),
91+ Description : value .Description ,
92+ ObservedUnit : value .ObservedUnit ,
93+ ObservedValue : value .ObservedValue ,
94+ Status : smsgateway .HealthStatus (value .Status ),
5795 }
5896 },
5997 ),
6098 }
61-
62- if check .Status == health .StatusFail {
63- return c .Status (fiber .StatusInternalServerError ).JSON (res )
64- }
65-
66- return c .Status (fiber .StatusOK ).JSON (res )
6799}
68100
69101func (h * healthHandler ) Register (router fiber.Router ) {
70- router .Get ("/health" , h .getHealth )
71- }
72-
73- func newHealthHandler (params healthHanlderParams ) * healthHandler {
74- return & healthHandler {
75- Handler : base.Handler {Logger : params .Logger .Named ("HealthHandler" ), Validator : nil },
76- healthSvc : params .HealthSvc ,
77- logger : params .Logger ,
78- }
102+ router .Get ("/health" , h .getReadiness )
103+ router .Get ("/health/live" , h .getLiveness )
104+ router .Get ("/health/ready" , h .getReadiness )
105+ router .Get ("/health/startup" , h .getStartup )
79106}
0 commit comments