go-judge/cmd/executorserver/rest_executor/cmd_handler.go

76 lines
1.7 KiB
Go

package restexecutor
import (
"net/http"
"github.com/criyle/go-judge/cmd/executorserver/model"
"github.com/criyle/go-judge/filestore"
"github.com/criyle/go-judge/worker"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
// Register registers executor the handler
//
// POST /run, GET /file, POST /file, GET /file/:fid, DELETE /file/:fid
type Register interface {
Register(*gin.Engine)
}
// New creates new REST API handler
func New(worker worker.Worker, fs filestore.FileStore, srcPrefix string, logger *zap.Logger) Register {
return &handle{
worker: worker,
fileHandle: fileHandle{fs: fs},
srcPrefix: srcPrefix,
logger: logger,
}
}
type handle struct {
worker worker.Worker
fileHandle
srcPrefix string
logger *zap.Logger
}
func (h *handle) Register(r *gin.Engine) {
// Run handle
r.POST("/run", h.handleRun)
// File handle
r.GET("/file", h.fileGet)
r.POST("/file", h.filePost)
r.GET("/file/:fid", h.fileIDGet)
r.DELETE("/file/:fid", h.fileIDDelete)
}
func (h *handle) handleRun(c *gin.Context) {
var req model.Request
if err := c.ShouldBindJSON(&req); err != nil {
c.Error(err)
c.AbortWithStatusJSON(http.StatusBadRequest, err.Error())
return
}
if len(req.Cmd) == 0 {
c.AbortWithStatusJSON(http.StatusBadRequest, "no cmd provided")
return
}
r, err := model.ConvertRequest(&req, h.srcPrefix)
if err != nil {
c.Error(err)
c.AbortWithStatusJSON(http.StatusBadRequest, err.Error())
return
}
h.logger.Sugar().Debugf("request: %+v", r)
rt := <-h.worker.Submit(c.Request.Context(), r)
h.logger.Sugar().Debugf("response: %+v", rt)
if rt.Error != nil {
c.Error(rt.Error)
c.AbortWithStatusJSON(http.StatusInternalServerError, rt.Error.Error())
return
}
c.JSON(http.StatusOK, model.ConvertResponse(rt).Results)
}