feat(api): display_state im Player-Status-Report persistieren
This commit is contained in:
parent
fbcda1e2b8
commit
f985a99ea1
2 changed files with 23 additions and 13 deletions
|
|
@ -2,12 +2,15 @@ package httpapi
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
storePackage "git.az-it.net/az/morz-infoboard/server/backend/internal/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
type screenStatusSummary struct {
|
type screenStatusSummary struct {
|
||||||
|
|
@ -47,6 +50,7 @@ type playerStatusRequest struct {
|
||||||
HeartbeatEverySeconds int `json:"heartbeat_every_seconds"`
|
HeartbeatEverySeconds int `json:"heartbeat_every_seconds"`
|
||||||
StartedAt string `json:"started_at"`
|
StartedAt string `json:"started_at"`
|
||||||
LastHeartbeatAt string `json:"last_heartbeat_at"`
|
LastHeartbeatAt string `json:"last_heartbeat_at"`
|
||||||
|
DisplayState string `json:"display_state,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// playerStatusMQTTConfig is the MQTT configuration returned to agents in the
|
// playerStatusMQTTConfig is the MQTT configuration returned to agents in the
|
||||||
|
|
@ -63,7 +67,7 @@ type playerStatusResponse struct {
|
||||||
MQTT *playerStatusMQTTConfig `json:"mqtt,omitempty"`
|
MQTT *playerStatusMQTTConfig `json:"mqtt,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func handlePlayerStatus(store playerStatusStore, mqttBroker, mqttUsername, mqttPassword string) http.HandlerFunc {
|
func handlePlayerStatus(store playerStatusStore, screenStore *storePackage.ScreenStore, mqttBroker, mqttUsername, mqttPassword string) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
var request playerStatusRequest
|
var request playerStatusRequest
|
||||||
if err := decodeJSON(r, &request); err != nil {
|
if err := decodeJSON(r, &request); err != nil {
|
||||||
|
|
@ -130,6 +134,12 @@ func handlePlayerStatus(store playerStatusStore, mqttBroker, mqttUsername, mqttP
|
||||||
LastHeartbeatAt: request.LastHeartbeatAt,
|
LastHeartbeatAt: request.LastHeartbeatAt,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if request.DisplayState != "" && screenStore != nil {
|
||||||
|
if err := screenStore.UpsertDisplayState(r.Context(), request.ScreenID, request.DisplayState); err != nil {
|
||||||
|
slog.Error("upsert display state", "screen_id", request.ScreenID, "err", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
resp := playerStatusResponse{Status: "accepted"}
|
resp := playerStatusResponse{Status: "accepted"}
|
||||||
if mqttBroker != "" {
|
if mqttBroker != "" {
|
||||||
resp.MQTT = &playerStatusMQTTConfig{
|
resp.MQTT = &playerStatusMQTTConfig{
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ func TestHandlePlayerStatusAccepted(t *testing.T) {
|
||||||
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewReader(body))
|
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewReader(body))
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
|
||||||
handlePlayerStatus(store, "", "", "")(w, req)
|
handlePlayerStatus(store, nil, "", "", "")(w, req)
|
||||||
|
|
||||||
if got, want := w.Code, http.StatusOK; got != want {
|
if got, want := w.Code, http.StatusOK; got != want {
|
||||||
t.Fatalf("status = %d, want %d", got, want)
|
t.Fatalf("status = %d, want %d", got, want)
|
||||||
|
|
@ -66,7 +66,7 @@ func TestHandlePlayerStatusRejectsInvalidJSON(t *testing.T) {
|
||||||
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewBufferString("{"))
|
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewBufferString("{"))
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
|
||||||
handlePlayerStatus(newInMemoryPlayerStatusStore(), "", "", "")(w, req)
|
handlePlayerStatus(newInMemoryPlayerStatusStore(), nil, "", "", "")(w, req)
|
||||||
|
|
||||||
if got, want := w.Code, http.StatusBadRequest; got != want {
|
if got, want := w.Code, http.StatusBadRequest; got != want {
|
||||||
t.Fatalf("status = %d, want %d", got, want)
|
t.Fatalf("status = %d, want %d", got, want)
|
||||||
|
|
@ -83,7 +83,7 @@ func TestHandlePlayerStatusRejectsMissingScreenID(t *testing.T) {
|
||||||
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewReader(body))
|
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewReader(body))
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
|
||||||
handlePlayerStatus(newInMemoryPlayerStatusStore(), "", "", "")(w, req)
|
handlePlayerStatus(newInMemoryPlayerStatusStore(), nil, "", "", "")(w, req)
|
||||||
|
|
||||||
if got, want := w.Code, http.StatusBadRequest; got != want {
|
if got, want := w.Code, http.StatusBadRequest; got != want {
|
||||||
t.Fatalf("status = %d, want %d", got, want)
|
t.Fatalf("status = %d, want %d", got, want)
|
||||||
|
|
@ -102,7 +102,7 @@ func TestHandlePlayerStatusStoresNormalizedScreenID(t *testing.T) {
|
||||||
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewReader(body))
|
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewReader(body))
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
|
||||||
handlePlayerStatus(store, "", "", "")(w, req)
|
handlePlayerStatus(store, nil, "", "", "")(w, req)
|
||||||
|
|
||||||
if got, want := w.Code, http.StatusOK; got != want {
|
if got, want := w.Code, http.StatusOK; got != want {
|
||||||
t.Fatalf("status = %d, want %d", got, want)
|
t.Fatalf("status = %d, want %d", got, want)
|
||||||
|
|
@ -122,7 +122,7 @@ func TestHandlePlayerStatusRejectsMissingTimestamp(t *testing.T) {
|
||||||
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewReader(body))
|
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewReader(body))
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
|
||||||
handlePlayerStatus(newInMemoryPlayerStatusStore(), "", "", "")(w, req)
|
handlePlayerStatus(newInMemoryPlayerStatusStore(), nil, "", "", "")(w, req)
|
||||||
|
|
||||||
if got, want := w.Code, http.StatusBadRequest; got != want {
|
if got, want := w.Code, http.StatusBadRequest; got != want {
|
||||||
t.Fatalf("status = %d, want %d", got, want)
|
t.Fatalf("status = %d, want %d", got, want)
|
||||||
|
|
@ -138,7 +138,7 @@ func TestHandlePlayerStatusRejectsMissingStatus(t *testing.T) {
|
||||||
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewReader(body))
|
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewReader(body))
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
|
||||||
handlePlayerStatus(newInMemoryPlayerStatusStore(), "", "", "")(w, req)
|
handlePlayerStatus(newInMemoryPlayerStatusStore(), nil, "", "", "")(w, req)
|
||||||
|
|
||||||
if got, want := w.Code, http.StatusBadRequest; got != want {
|
if got, want := w.Code, http.StatusBadRequest; got != want {
|
||||||
t.Fatalf("status = %d, want %d", got, want)
|
t.Fatalf("status = %d, want %d", got, want)
|
||||||
|
|
@ -155,7 +155,7 @@ func TestHandlePlayerStatusRejectsUnknownStatus(t *testing.T) {
|
||||||
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewReader(body))
|
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewReader(body))
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
|
||||||
handlePlayerStatus(newInMemoryPlayerStatusStore(), "", "", "")(w, req)
|
handlePlayerStatus(newInMemoryPlayerStatusStore(), nil, "", "", "")(w, req)
|
||||||
|
|
||||||
if got, want := w.Code, http.StatusBadRequest; got != want {
|
if got, want := w.Code, http.StatusBadRequest; got != want {
|
||||||
t.Fatalf("status = %d, want %d", got, want)
|
t.Fatalf("status = %d, want %d", got, want)
|
||||||
|
|
@ -173,7 +173,7 @@ func TestHandlePlayerStatusRejectsUnknownServerConnectivity(t *testing.T) {
|
||||||
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewReader(body))
|
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewReader(body))
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
|
||||||
handlePlayerStatus(newInMemoryPlayerStatusStore(), "", "", "")(w, req)
|
handlePlayerStatus(newInMemoryPlayerStatusStore(), nil, "", "", "")(w, req)
|
||||||
|
|
||||||
if got, want := w.Code, http.StatusBadRequest; got != want {
|
if got, want := w.Code, http.StatusBadRequest; got != want {
|
||||||
t.Fatalf("status = %d, want %d", got, want)
|
t.Fatalf("status = %d, want %d", got, want)
|
||||||
|
|
@ -191,7 +191,7 @@ func TestHandlePlayerStatusRejectsNonPositiveHeartbeatInterval(t *testing.T) {
|
||||||
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewReader(body))
|
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewReader(body))
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
|
||||||
handlePlayerStatus(newInMemoryPlayerStatusStore(), "", "", "")(w, req)
|
handlePlayerStatus(newInMemoryPlayerStatusStore(), nil, "", "", "")(w, req)
|
||||||
|
|
||||||
if got, want := w.Code, http.StatusBadRequest; got != want {
|
if got, want := w.Code, http.StatusBadRequest; got != want {
|
||||||
t.Fatalf("status = %d, want %d", got, want)
|
t.Fatalf("status = %d, want %d", got, want)
|
||||||
|
|
@ -208,7 +208,7 @@ func TestHandlePlayerStatusRejectsMalformedTimestamps(t *testing.T) {
|
||||||
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewReader(body))
|
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewReader(body))
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
|
||||||
handlePlayerStatus(newInMemoryPlayerStatusStore(), "", "", "")(w, req)
|
handlePlayerStatus(newInMemoryPlayerStatusStore(), nil, "", "", "")(w, req)
|
||||||
|
|
||||||
if got, want := w.Code, http.StatusBadRequest; got != want {
|
if got, want := w.Code, http.StatusBadRequest; got != want {
|
||||||
t.Fatalf("status = %d, want %d", got, want)
|
t.Fatalf("status = %d, want %d", got, want)
|
||||||
|
|
@ -226,7 +226,7 @@ func TestHandlePlayerStatusRejectsMalformedStartedAt(t *testing.T) {
|
||||||
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewReader(body))
|
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewReader(body))
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
|
||||||
handlePlayerStatus(newInMemoryPlayerStatusStore(), "", "", "")(w, req)
|
handlePlayerStatus(newInMemoryPlayerStatusStore(), nil, "", "", "")(w, req)
|
||||||
|
|
||||||
if got, want := w.Code, http.StatusBadRequest; got != want {
|
if got, want := w.Code, http.StatusBadRequest; got != want {
|
||||||
t.Fatalf("status = %d, want %d", got, want)
|
t.Fatalf("status = %d, want %d", got, want)
|
||||||
|
|
@ -244,7 +244,7 @@ func TestHandlePlayerStatusRejectsMalformedLastHeartbeatAt(t *testing.T) {
|
||||||
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewReader(body))
|
req := httptest.NewRequest(http.MethodPost, "/api/v1/player/status", bytes.NewReader(body))
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
|
|
||||||
handlePlayerStatus(newInMemoryPlayerStatusStore(), "", "", "")(w, req)
|
handlePlayerStatus(newInMemoryPlayerStatusStore(), nil, "", "", "")(w, req)
|
||||||
|
|
||||||
if got, want := w.Code, http.StatusBadRequest; got != want {
|
if got, want := w.Code, http.StatusBadRequest; got != want {
|
||||||
t.Fatalf("status = %d, want %d", got, want)
|
t.Fatalf("status = %d, want %d", got, want)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue