Skip to content

Commit

Permalink
add health endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
morphy2k committed Jan 23, 2021
1 parent 8fb9b58 commit 29482ef
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 2 deletions.
21 changes: 21 additions & 0 deletions controller/health.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package controller

import (
"net/http"

"github.com/tarkov-database/rest-api/model/api"
"github.com/tarkov-database/rest-api/view"

"github.com/julienschmidt/httprouter"
)

// HealthGET handles a GET request on the health endpoint
func HealthGET(w http.ResponseWriter, _ *http.Request, _ httprouter.Params) {
h, err := api.GetHealth()

if err != nil || !h.OK {
view.RenderJSON(h, http.StatusInternalServerError, w)
} else {
view.RenderJSON(h, http.StatusOK, w)
}
}
14 changes: 12 additions & 2 deletions core/database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (

"github.com/google/logger"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/readpref"
)

var db *mongo.Database
Expand Down Expand Up @@ -36,7 +35,7 @@ func Init() error {
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

if err := client.Ping(ctx, readpref.Primary()); err != nil {
if err := client.Ping(ctx, nil); err != nil {
return fmt.Errorf("connection error: %s", err)
}

Expand All @@ -63,6 +62,17 @@ func Shutdown() error {
return nil
}

// Ping sends a ping command to verify the DB connection
func Ping(ctx context.Context) error {
client := db.Client()

if err := client.Ping(ctx, nil); err != nil {
return fmt.Errorf("connection error: %s", err)
}

return nil
}

// GetDB returns a handle to the database
func GetDB() *mongo.Database {
return db
Expand Down
74 changes: 74 additions & 0 deletions model/api/health.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package api

import (
"context"
"time"

"github.com/tarkov-database/rest-api/core/database"
)

// Status represents the status code of a service
type Status int

const (
// OK status if all checks were successful
OK Status = iota

// Warning status if non-critical issues are discovered
Warning

// Failure status when critical problems are discovered
Failure
)

// Health represents the object of the health root endpoint
type Health struct {
OK bool `json:"ok"`
Service *Service `json:"service"`
}

// Service holds all services with their respective status
type Service struct {
Database Status `json:"database"`
}

// GetHealth performs a self-check and returns the result
func GetHealth() (*Health, error) {
var err error
var ok = true

svc := &Service{}

svc.Database, err = getDatabaseStatus()
if err != nil {
return nil, err
}

if svc.Database != OK {
ok = false
}

health := &Health{
OK: ok,
Service: svc,
}

return health, nil
}

func getDatabaseStatus() (Status, error) {
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

start := time.Now()

if err := database.Ping(ctx); err != nil {
return Failure, err
}

if time.Since(start).Seconds() > 3 {
return Warning, nil
}

return OK, nil
}
3 changes: 3 additions & 0 deletions route/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ func routes() *httprouter.Router {
r.GET(prefix, cntrl.IndexGET)
r.Handler("GET", "/", http.RedirectHandler(prefix, http.StatusMovedPermanently))

// Health
r.GET(prefix+"/health", cntrl.HealthGET)

// Item
r.GET(prefix+"/item", auth(jwt.ScopeItemRead, cntrl.ItemIndexGET))
r.GET(prefix+"/item/:kind", auth(jwt.ScopeItemRead, cntrl.ItemsGET))
Expand Down

0 comments on commit 29482ef

Please sign in to comment.