fermentord/internal/api/http.go

132 lines
3 KiB
Go
Raw Normal View History

2021-08-30 20:46:38 +00:00
package api
import (
"context"
"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
config *controllers.Config
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()
tx, err := a.db.Begin()
if err != nil {
http.Error(w, "Unhealthy", http.StatusServiceUnavailable)
return
}
var version string
err = tx.QueryRow("SELECT version()").Scan(&version)
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()
ctx := context.Background()
tx, err := a.db.Begin()
defer tx.Rollback()
if err != nil {
log.Panic().Err(err).Msg("Failed to start DB transaction.")
}
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
}
dbCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()
readings, err := dal.LoadTemperatureReadingsSince(dbCtx, tx, since)
if err != nil {
log.Panic().Err(err).Msg("Failed to load temperature readings from DB.")
}
tx.Commit()
data, err := json.MarshalIndent(readings, "", " ")
if err != nil {
log.Panic().Err(err).Msg("Failed to serialize temperature readings to JSON.")
}
fmt.Fprintf(w, string(data))
}
func (a *API) GetStateChanges(w http.ResponseWriter, r *http.Request) {
defer sentry.Recover()
ctx := context.Background()
tx, err := a.db.Begin()
if err != nil {
log.Panic().Err(err).Msg("Failed to start DB transaction.")
}
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
}
dbCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()
readings, err := dal.LoadChamberStateChangesSince(dbCtx, tx, since)
if err != nil {
log.Panic().Err(err).Msg("Failed to load temperature readings from DB.")
}
tx.Commit()
data, err := json.MarshalIndent(readings, "", " ")
if err != nil {
log.Panic().Err(err).Msg("Failed to serialize temperature readings to JSON.")
}
fmt.Fprintf(w, string(data))
}