단일 server.go에 집중되어 있던 HTTP 라우팅 로직을 실행/작업/런너 핸들러 파일로 분리해 책임 경계를 더 선명하게 하며, milestone 기록 파일의 보관 위치도 정리한다.
92 lines
2.7 KiB
Go
92 lines
2.7 KiB
Go
package httpserver
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/toki/oto/services/core/internal/cicdstate"
|
|
otopb "github.com/toki/oto/services/core/oto"
|
|
)
|
|
|
|
func handleCreateJob(store *cicdstate.Store) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
var req struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
RunRequest *otopb.RunRequest `json:"run_request"`
|
|
}
|
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
|
writeResponse(w, http.StatusBadRequest, map[string]string{"error": "invalid request body"})
|
|
return
|
|
}
|
|
if req.ID == "" || req.Name == "" {
|
|
writeResponse(w, http.StatusBadRequest, map[string]string{"error": "id and name are required"})
|
|
return
|
|
}
|
|
job, err := store.CreateJob(req.ID, req.Name, runRequestFromJSON(req.RunRequest))
|
|
if err != nil {
|
|
writeResponse(w, http.StatusConflict, map[string]string{"error": err.Error()})
|
|
return
|
|
}
|
|
writeResponse(w, http.StatusCreated, jobToJSON(job))
|
|
}
|
|
}
|
|
|
|
func handleGetJob(store *cicdstate.Store) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
jobID := r.PathValue("id")
|
|
if jobID == "" {
|
|
parts := strings.Split(r.URL.Path, "/")
|
|
if len(parts) >= 5 {
|
|
jobID = parts[4]
|
|
}
|
|
}
|
|
if jobID == "" {
|
|
writeResponse(w, http.StatusBadRequest, map[string]string{"error": "missing job id"})
|
|
return
|
|
}
|
|
job, err := store.GetJob(jobID)
|
|
if err != nil {
|
|
if errors.Is(err, fmt.Errorf("job not found: %s", jobID)) || err.Error() == "job not found: "+jobID {
|
|
writeResponse(w, http.StatusNotFound, map[string]string{"error": "job not found"})
|
|
return
|
|
}
|
|
writeResponse(w, http.StatusInternalServerError, map[string]string{"error": "internal error"})
|
|
return
|
|
}
|
|
writeResponse(w, http.StatusOK, jobToJSON(job))
|
|
}
|
|
}
|
|
|
|
func handleCreateExecution(store *cicdstate.Store) http.HandlerFunc {
|
|
return func(w http.ResponseWriter, r *http.Request) {
|
|
jobID := r.PathValue("id")
|
|
if jobID == "" {
|
|
parts := strings.Split(r.URL.Path, "/")
|
|
if len(parts) >= 5 {
|
|
jobID = parts[4]
|
|
}
|
|
}
|
|
if jobID == "" {
|
|
writeResponse(w, http.StatusBadRequest, map[string]string{"error": "missing job id"})
|
|
return
|
|
}
|
|
var req struct {
|
|
ID string `json:"id"`
|
|
}
|
|
_ = json.NewDecoder(r.Body).Decode(&req)
|
|
if req.ID == "" {
|
|
writeResponse(w, http.StatusBadRequest, map[string]string{"error": "execution id is required"})
|
|
return
|
|
}
|
|
exec, err := store.CreateExecution(jobID, req.ID)
|
|
if err != nil {
|
|
writeResponse(w, http.StatusBadRequest, map[string]string{"error": err.Error()})
|
|
return
|
|
}
|
|
writeResponse(w, http.StatusCreated, execToJSON(exec))
|
|
}
|
|
}
|