wip: work on http api
This commit is contained in:
parent
b5f5289b45
commit
34fca3d564
81
http.go
81
http.go
|
@ -31,13 +31,6 @@ func TelemRouter(log *slog.Logger, broker *Broker, db *db.TelemDb) http.Handler
|
||||||
r.Use(middleware.Logger) // TODO: integrate with slog instead of go default logger.
|
r.Use(middleware.Logger) // TODO: integrate with slog instead of go default logger.
|
||||||
r.Use(middleware.Recoverer)
|
r.Use(middleware.Recoverer)
|
||||||
|
|
||||||
r.Get("/schema", func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Set("Content-Type", "application/json")
|
|
||||||
// return the spicy json response.
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
w.Write([]byte(skylab.SkylabDefinitions))
|
|
||||||
})
|
|
||||||
|
|
||||||
// heartbeat request.
|
// heartbeat request.
|
||||||
r.Get("/ping", func(w http.ResponseWriter, r *http.Request) {
|
r.Get("/ping", func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Write([]byte("pong"))
|
w.Write([]byte("pong"))
|
||||||
|
@ -84,39 +77,7 @@ func apiV1(broker *Broker, db *db.TelemDb) chi.Router {
|
||||||
})
|
})
|
||||||
|
|
||||||
// this is to get a single field
|
// this is to get a single field
|
||||||
r.Get("/{name:[a-z_]+}/{field:[a-z_]+}", func(w http.ResponseWriter, r *http.Request) {
|
r.Get("/{name:[a-z_]+}/{field:[a-z_]+}")
|
||||||
var err error
|
|
||||||
|
|
||||||
// we need a start and end time. If none is provided,
|
|
||||||
// we use unix epoch as start, and now + 1 day as end.
|
|
||||||
start := time.Unix(0, 0)
|
|
||||||
startString := r.URL.Query().Get("start")
|
|
||||||
if startString != "" {
|
|
||||||
start, err = time.Parse(time.RFC3339, startString)
|
|
||||||
if err != nil {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end := time.Now().Add(1 * time.Hour)
|
|
||||||
endParam := r.URL.Query().Get("start")
|
|
||||||
if endParam != "" {
|
|
||||||
end, err = time.Parse(time.RFC3339, endParam)
|
|
||||||
if err != nil {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
name := chi.URLParam(r, "name")
|
|
||||||
field := chi.URLParam(r, "field")
|
|
||||||
// TODO: add limit/pagination ?
|
|
||||||
|
|
||||||
res, err := db.GetValues(r.Context(), name, field, start, end)
|
|
||||||
if err != nil {
|
|
||||||
// 500 server error:
|
|
||||||
fmt.Print(err)
|
|
||||||
}
|
|
||||||
b, err := json.Marshal(res)
|
|
||||||
w.Write(b)
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -190,6 +151,46 @@ func apiV1PacketSubscribe(broker *Broker, db *db.TelemDb) http.HandlerFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// apiV1GetValues is a function that creates a handler for
|
||||||
|
// getting the specific value from a packet.
|
||||||
|
// this is useful for OpenMCT or other viewer APIs
|
||||||
|
func apiV1GetValues(db *db.TelemDb) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
// we need a start and end time. If none is provided,
|
||||||
|
// we use unix epoch as start, and now + 1 day as end.
|
||||||
|
start := time.Unix(0, 0)
|
||||||
|
startString := r.URL.Query().Get("start")
|
||||||
|
if startString != "" {
|
||||||
|
start, err = time.Parse(time.RFC3339, startString)
|
||||||
|
if err != nil {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end := time.Now().Add(1 * time.Hour)
|
||||||
|
endParam := r.URL.Query().Get("start")
|
||||||
|
if endParam != "" {
|
||||||
|
end, err = time.Parse(time.RFC3339, endParam)
|
||||||
|
if err != nil {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
name := chi.URLParam(r, "name")
|
||||||
|
field := chi.URLParam(r, "field")
|
||||||
|
|
||||||
|
// TODO: add limit and pagination
|
||||||
|
|
||||||
|
res, err := db.GetValues(r.Context(), name, field, start, end)
|
||||||
|
if err != nil {
|
||||||
|
// 500 server error:
|
||||||
|
fmt.Print(err)
|
||||||
|
}
|
||||||
|
b, err := json.Marshal(res)
|
||||||
|
w.Write(b)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: rename. record is not a clear name. Runs? drives? segments?
|
// TODO: rename. record is not a clear name. Runs? drives? segments?
|
||||||
func apiV1GetRecords(db *db.TelemDb) http.HandlerFunc {
|
func apiV1GetRecords(db *db.TelemDb) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
|
@ -3,9 +3,66 @@ package db
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Modifier augments SQL strings.
|
||||||
|
type Modifier interface {
|
||||||
|
ModifyStatement(string) string
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type LimitOffsetModifier struct {
|
||||||
|
Limit int
|
||||||
|
Offset int
|
||||||
|
}
|
||||||
|
|
||||||
|
// BusEventFilter is a filter for bus events.
|
||||||
|
type BusEventFilter struct {
|
||||||
|
Names []string
|
||||||
|
TimerangeStart time.Time
|
||||||
|
TimerangeEnd time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bef *BusEventFilter) String() string {
|
||||||
|
var sb []string = make([]string, 0, 2)
|
||||||
|
if len(bef.Names) > 0 {
|
||||||
|
names := strings.Join(bef.Names, ",")
|
||||||
|
sb = append(sb, fmt.Sprintf("name IN (%s)", names))
|
||||||
|
}
|
||||||
|
if !bef.TimerangeStart.IsZero() && !bef.TimerangeEnd.IsZero() {
|
||||||
|
sb = append(sb, fmt.Sprintf(""))
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
type BusEventElement interface {
|
||||||
|
Element() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type NormalExtract struct {
|
||||||
|
Key string
|
||||||
|
}
|
||||||
|
|
||||||
|
type JSONExtract struct {
|
||||||
|
Key string
|
||||||
|
}
|
||||||
|
|
||||||
|
type BusEventQuery struct {
|
||||||
|
Elements []BusEventElement
|
||||||
|
Filter BusEventFilter
|
||||||
|
Limits LimitOffsetModifier
|
||||||
|
}
|
||||||
|
|
||||||
|
func (beq *BusEventQuery) String() string {
|
||||||
|
// select
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// now we can optionally add a limit.
|
||||||
|
|
||||||
// Datum is a single measurement - it is more granular than a packet.
|
// Datum is a single measurement - it is more granular than a packet.
|
||||||
// the classic example is bms_measurement.current
|
// the classic example is bms_measurement.current
|
||||||
type Datum struct {
|
type Datum struct {
|
||||||
|
@ -23,10 +80,10 @@ func (tdb *TelemDb) GetValues(ctx context.Context, packetName, field string, sta
|
||||||
SqlFrag := `
|
SqlFrag := `
|
||||||
SELECT
|
SELECT
|
||||||
ts as timestamp,
|
ts as timestamp,
|
||||||
json_extract(data, '$.current') as val
|
json_extract(data, '$.' || ?) as val
|
||||||
FROM bus_events WHERE name IS 'bms_measurement'
|
FROM bus_events WHERE name IS ?
|
||||||
`
|
`
|
||||||
rows, err := tdb.db.QueryxContext(ctx, SqlFrag)
|
rows, err := tdb.db.QueryxContext(ctx, SqlFrag, field, packetName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue