feat: add execution history queries and preserve bounded JSON payloads
This commit is contained in:
65
internal/transport/httpserver/history.go
Normal file
65
internal/transport/httpserver/history.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package httpserver
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"git.yuntuo.hk/k2safe/orbit/internal/fault"
|
||||
core "git.yuntuo.hk/k2safe/orbit/model"
|
||||
"git.yuntuo.hk/k2safe/orbit/platform/auth"
|
||||
"git.yuntuo.hk/k2safe/orbit/pulse/service"
|
||||
)
|
||||
|
||||
func historyQuery(r *http.Request, paged bool) (service.HistoryPageInput, error) {
|
||||
var in service.HistoryPageInput
|
||||
q, err := url.ParseQuery(r.URL.RawQuery)
|
||||
if err != nil {
|
||||
return in, fault.Invalid("invalid query encoding")
|
||||
}
|
||||
for key, values := range q {
|
||||
if !paged || len(values) != 1 || (key != "limit" && key != "cursor") {
|
||||
return in, fault.Invalid("invalid history query parameter")
|
||||
}
|
||||
}
|
||||
if q.Has("limit") {
|
||||
in.Limit, err = strconv.Atoi(q.Get("limit"))
|
||||
if err != nil || in.Limit < 1 {
|
||||
return in, fault.Invalid("invalid history limit")
|
||||
}
|
||||
}
|
||||
in.Cursor = q.Get("cursor")
|
||||
return in, nil
|
||||
}
|
||||
func registerHistory(mux *http.ServeMux, s *service.Service) {
|
||||
mux.HandleFunc("GET /v1/tasks/{task}/attempts", wrap(func(r *http.Request, t auth.Token) (any, int, error) {
|
||||
in, err := historyQuery(r, true)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out, err := s.ListTaskAttempts(r.Context(), t, core.ID(r.PathValue("task")), in)
|
||||
return out, 200, err
|
||||
}))
|
||||
mux.HandleFunc("GET /v1/tasks/{task}/attempts/{attempt}", wrap(func(r *http.Request, t auth.Token) (any, int, error) {
|
||||
if _, err := historyQuery(r, false); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out, err := s.GetTaskAttempt(r.Context(), t, core.ID(r.PathValue("task")), core.ID(r.PathValue("attempt")))
|
||||
return out, 200, err
|
||||
}))
|
||||
mux.HandleFunc("GET /v1/tasks/{task}/attempts/{attempt}/evidence", wrap(func(r *http.Request, t auth.Token) (any, int, error) {
|
||||
in, err := historyQuery(r, true)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out, err := s.ListAttemptEvidence(r.Context(), t, core.ID(r.PathValue("task")), core.ID(r.PathValue("attempt")), in)
|
||||
return out, 200, err
|
||||
}))
|
||||
mux.HandleFunc("GET /v1/tasks/{task}/attempts/{attempt}/evidence/{evidence}", wrap(func(r *http.Request, t auth.Token) (any, int, error) {
|
||||
if _, err := historyQuery(r, false); err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
out, err := s.GetAttemptEvidence(r.Context(), t, core.ID(r.PathValue("task")), core.ID(r.PathValue("attempt")), core.ID(r.PathValue("evidence")))
|
||||
return out, 200, err
|
||||
}))
|
||||
}
|
||||
@@ -32,6 +32,7 @@ func New(addr string, ready Checker, tasks ...*service.Service) *http.Server {
|
||||
})
|
||||
if len(tasks) > 0 && tasks[0] != nil {
|
||||
registerTasks(mux, tasks[0])
|
||||
registerHistory(mux, tasks[0])
|
||||
}
|
||||
return &http.Server{Addr: addr, Handler: mux, ReadHeaderTimeout: 5 * time.Second, ReadTimeout: 10 * time.Second, WriteTimeout: 15 * time.Second, IdleTimeout: 60 * time.Second, MaxHeaderBytes: 16 << 10}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
|
||||
"git.yuntuo.hk/k2safe/orbit/internal/fault"
|
||||
"git.yuntuo.hk/k2safe/orbit/internal/jsonvalue"
|
||||
"git.yuntuo.hk/k2safe/orbit/internal/jsonwire"
|
||||
core "git.yuntuo.hk/k2safe/orbit/model"
|
||||
"git.yuntuo.hk/k2safe/orbit/platform/auth"
|
||||
pulse "git.yuntuo.hk/k2safe/orbit/pulse/model"
|
||||
@@ -149,7 +150,7 @@ func wrap(next endpoint) http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
func writeJSON(w http.ResponseWriter, status int, body any) {
|
||||
raw, err := json.Marshal(body)
|
||||
raw, err := jsonwire.Marshal(body)
|
||||
if err != nil {
|
||||
status = 503
|
||||
raw = []byte(`{"error":{"code":"UNAVAILABLE","message":"operation unavailable"}}`)
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
|
||||
"git.yuntuo.hk/k2safe/orbit/internal/fault"
|
||||
"git.yuntuo.hk/k2safe/orbit/internal/jsonvalue"
|
||||
"git.yuntuo.hk/k2safe/orbit/internal/jsonwire"
|
||||
core "git.yuntuo.hk/k2safe/orbit/model"
|
||||
"git.yuntuo.hk/k2safe/orbit/platform/auth"
|
||||
"git.yuntuo.hk/k2safe/orbit/pulse/worker"
|
||||
@@ -154,7 +155,7 @@ func (h *WorkerHub) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
_ = writeWorkerFrame(ctx, conn, workerFrame{Version: "1", Type: "error", MessageID: requestID, ReplyTo: hello.MessageID, Error: publicWorkerError(err)})
|
||||
return
|
||||
}
|
||||
welcomeRaw, err := json.Marshal(welcome)
|
||||
welcomeRaw, err := jsonwire.Marshal(welcome)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -219,7 +220,7 @@ func (h *WorkerHub) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
raw, err := json.Marshal(frame)
|
||||
raw, err := jsonwire.Marshal(frame)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
@@ -320,7 +321,7 @@ func (h *WorkerHub) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
reply.Type = "error"
|
||||
reply.Error = publicWorkerError(commandErr)
|
||||
} else {
|
||||
reply.Body, commandErr = json.Marshal(body)
|
||||
reply.Body, commandErr = jsonwire.Marshal(body)
|
||||
if commandErr != nil {
|
||||
return
|
||||
}
|
||||
@@ -354,7 +355,7 @@ func (h *WorkerHub) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if assignment == nil {
|
||||
break
|
||||
}
|
||||
raw, err := json.Marshal(assignment)
|
||||
raw, err := jsonwire.Marshal(assignment)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -374,7 +375,7 @@ func publicWorkerError(err error) *fault.Error {
|
||||
return fault.Unavailable
|
||||
}
|
||||
func writeWorkerFrame(ctx context.Context, conn *websocket.Conn, frame workerFrame) error {
|
||||
raw, err := json.Marshal(frame)
|
||||
raw, err := jsonwire.Marshal(frame)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user