131 lines
3 KiB
Go
131 lines
3 KiB
Go
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))
|
|
}
|