2020-03-29 16:03:07 +00:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"net/http"
|
|
|
|
|
|
|
|
"go.uber.org/zap"
|
|
|
|
|
|
|
|
"gitlab.com/slon/shad-go/distbuild/pkg/build"
|
|
|
|
)
|
|
|
|
|
|
|
|
func NewServiceHandler(l *zap.Logger, s Service) *ServiceHandler {
|
|
|
|
return &ServiceHandler{
|
|
|
|
l: l,
|
|
|
|
s: s,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type ServiceHandler struct {
|
|
|
|
l *zap.Logger
|
|
|
|
s Service
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *ServiceHandler) Register(mux *http.ServeMux) {
|
|
|
|
mux.HandleFunc("/build", s.build)
|
|
|
|
mux.HandleFunc("/signal", s.signal)
|
|
|
|
}
|
|
|
|
|
|
|
|
type statusWriter struct {
|
|
|
|
written bool
|
|
|
|
w http.ResponseWriter
|
|
|
|
enc *json.Encoder
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *statusWriter) Started(rsp *BuildStarted) error {
|
|
|
|
w.written = true
|
|
|
|
w.w.Header().Set("content-type", "application/json")
|
|
|
|
w.w.WriteHeader(http.StatusOK)
|
|
|
|
return w.enc.Encode(rsp)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *statusWriter) Updated(update *StatusUpdate) error {
|
|
|
|
return w.enc.Encode(update)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *ServiceHandler) doBuild(w http.ResponseWriter, r *http.Request) error {
|
|
|
|
reqJSON, err := ioutil.ReadAll(r.Body)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
var req BuildRequest
|
2020-03-29 17:35:39 +00:00
|
|
|
if err = json.Unmarshal(reqJSON, &req); err != nil {
|
2020-03-29 16:03:07 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
sw := &statusWriter{w: w, enc: json.NewEncoder(w)}
|
|
|
|
err = s.s.StartBuild(r.Context(), &req, sw)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
if sw.written {
|
|
|
|
_ = sw.Updated(&StatusUpdate{BuildFailed: &BuildFailed{Error: err.Error()}})
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *ServiceHandler) build(w http.ResponseWriter, r *http.Request) {
|
|
|
|
if err := s.doBuild(w, r); err != nil {
|
|
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
|
|
_, _ = fmt.Fprintf(w, "%v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *ServiceHandler) doSignal(w http.ResponseWriter, r *http.Request) error {
|
|
|
|
buildIDParam := r.URL.Query().Get("build_id")
|
|
|
|
if buildIDParam == "" {
|
|
|
|
return fmt.Errorf(`"build_id" parameter is missing`)
|
|
|
|
}
|
|
|
|
|
|
|
|
var buildID build.ID
|
|
|
|
if err := buildID.UnmarshalText([]byte(buildIDParam)); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
reqJSON, err := ioutil.ReadAll(r.Body)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
var req SignalRequest
|
2020-03-29 17:35:39 +00:00
|
|
|
if err = json.Unmarshal(reqJSON, &req); err != nil {
|
2020-03-29 16:03:07 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
rsp, err := s.s.SignalBuild(r.Context(), buildID, &req)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
rspJSON, err := json.Marshal(rsp)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
w.Header().Set("content-type", "application/json")
|
|
|
|
w.WriteHeader(http.StatusOK)
|
|
|
|
_, _ = w.Write(rspJSON)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *ServiceHandler) signal(w http.ResponseWriter, r *http.Request) {
|
|
|
|
if err := s.doSignal(w, r); err != nil {
|
|
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
|
|
_, _ = fmt.Fprintf(w, "%v", err)
|
|
|
|
}
|
|
|
|
}
|