fermentord/internal/api/http.go

136 lines
3 KiB
Go
Raw Normal View History

2021-08-30 20:46:38 +00:00
package api
import (
"context"
2021-11-16 05:19:24 +00:00
"database/sql"
2021-08-30 20:46:38 +00:00
"encoding/json"
"fmt"
"net/http"
"time"
"git.joco.dk/sng/fermentord/internal/controllers"
"git.joco.dk/sng/fermentord/internal/dal"
"github.com/getsentry/sentry-go"
"github.com/rs/zerolog/log"
)
type API struct {
db *dal.DAL
2021-11-16 05:19:24 +00:00
config *controllers.ControllerConfig
2021-08-30 20:46:38 +00:00
configChangeCallback func()
}
func NewAPI(db *dal.DAL) *API {
return &API{
db: db,
}
}
func (a *API) HealthCheck(w http.ResponseWriter, r *http.Request) {
defer sentry.Recover()
2021-11-16 05:19:24 +00:00
ctxb := context.Background()
2021-08-30 20:46:38 +00:00
2021-11-16 05:19:24 +00:00
ctx, cancel := context.WithTimeout(ctxb, 5*time.Second)
defer cancel()
err := a.db.InReadOnlyTransaction(ctx, func(tx *sql.Tx) error {
_, err := tx.Query("SELECT version()")
return err
})
2021-08-30 20:46:38 +00:00
if err != nil {
http.Error(w, "Unhealthy", http.StatusServiceUnavailable)
return
}
w.Write([]byte("Healthy"))
}
func (a *API) GetConfig(w http.ResponseWriter, r *http.Request) {
defer sentry.Recover()
resp, err := json.MarshalIndent(a.config, "", " ")
if err != nil {
log.Panic().Err(err).Msg("Error marshalling configuration.")
}
w.Write(resp)
}
func (a *API) GetTemperatures(w http.ResponseWriter, r *http.Request) {
defer sentry.Recover()
2021-11-16 05:19:24 +00:00
ctxb := context.Background()
2021-08-30 20:46:38 +00:00
keys, ok := r.URL.Query()["since"]
if !ok || len(keys[0]) < 1 {
http.Error(w, "Missing since parameter.", http.StatusBadRequest)
return
}
since, err := time.Parse(time.RFC3339, keys[0])
if err != nil {
http.Error(w, "Invalid format of since parameter. Expected RFC3339 formatted string.", http.StatusBadRequest)
return
}
2021-11-16 05:19:24 +00:00
ctx, cancel := context.WithTimeout(ctxb, 30*time.Second)
2021-08-30 20:46:38 +00:00
defer cancel()
2021-11-16 05:19:24 +00:00
var data []byte
err = a.db.InReadOnlyTransaction(ctx, func(tx *sql.Tx) error {
readings, err := dal.LoadTemperatureReadingsSince(ctx, tx, since)
if err != nil {
return err
}
data, err = json.MarshalIndent(readings, "", " ")
if err != nil {
return err
}
return nil
})
2021-08-30 20:46:38 +00:00
if err != nil {
log.Panic().Err(err).Msg("Failed to load temperature readings from DB.")
}
fmt.Fprintf(w, string(data))
}
func (a *API) GetStateChanges(w http.ResponseWriter, r *http.Request) {
defer sentry.Recover()
2021-11-16 05:19:24 +00:00
ctxb := context.Background()
2021-08-30 20:46:38 +00:00
keys, ok := r.URL.Query()["since"]
if !ok || len(keys[0]) < 1 {
http.Error(w, "Missing since parameter.", http.StatusBadRequest)
return
}
since, err := time.Parse(time.RFC3339, keys[0])
if err != nil {
http.Error(w, "Invalid format of since parameter. Expected RFC3339 formatted string.", http.StatusBadRequest)
return
}
2021-11-16 05:19:24 +00:00
ctx, cancel := context.WithTimeout(ctxb, 30*time.Second)
2021-08-30 20:46:38 +00:00
defer cancel()
2021-11-16 05:19:24 +00:00
var data []byte
err = a.db.InReadOnlyTransaction(ctx, func(tx *sql.Tx) error {
readings, err := dal.LoadChamberStateChangesSince(ctx, tx, since)
if err != nil {
return err
}
data, err = json.MarshalIndent(readings, "", " ")
if err != nil {
return err
}
return nil
})
2021-08-30 20:46:38 +00:00
if err != nil {
log.Panic().Err(err).Msg("Failed to serialize temperature readings to JSON.")
}
fmt.Fprintf(w, string(data))
}