Files
mirror-sync/cmd/server/api/api.go

117 lines
2.9 KiB
Go

package api
import (
"encoding/json"
"fmt"
"log/slog"
"mirror-sync/cmd/server/core/storage"
"mirror-sync/pkg/constants"
"mirror-sync/pkg/project"
"mirror-sync/pkg/remote/obj"
"net/http"
"runtime"
cronruntime "mirror-sync/cmd/server/core/runtime"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
)
type (
HTTPServer struct {
Server *http.Server
data *storage.Repository
scheduler *cronruntime.Scheduler
}
)
func NewServer(data *storage.Repository, scheduler *cronruntime.Scheduler, port int) *HTTPServer {
s := &HTTPServer{
data: data,
scheduler: scheduler,
}
router := chi.NewRouter()
router.NotFound(func(writer http.ResponseWriter, request *http.Request) {
notFound("id not found", writer, request)
})
router.MethodNotAllowed(func(writer http.ResponseWriter, request *http.Request) {
methodNotAllowed(writer, request)
})
router.Use(middleware.Logger)
router.Use(recoverMiddleware)
router.Use(middleware.GetHead)
router.Use(middleware.Compress(5, "application/gzip"))
router.Use(middleware.Heartbeat("/heartbeat"))
router.Route("/api", func(routerAPI chi.Router) {
routerAPI.Route("/v1", func(r chi.Router) {
// Get information about the server
r.Get("/version", s.Information)
r.Route("/projects", func(r chi.Router) {
r.Get("/all", s.ProjectsHandler)
r.Get("/{name}", func(w http.ResponseWriter, r *http.Request) {})
r.Post("/{name}", s.ProjectPostHandler)
r.Delete("/{name}", func(w http.ResponseWriter, r *http.Request) {})
})
})
})
s.Server = &http.Server{
Addr: fmt.Sprintf(":%d", port),
Handler: router,
}
return s
}
func (s *HTTPServer) Information(w http.ResponseWriter, r *http.Request) {
info := obj.SystemInformation{
Version: constants.Version,
APIVersion: constants.ApiVersion,
GoVersion: runtime.Version(),
OSName: runtime.GOOS,
OSArchitecture: runtime.GOARCH,
}
ok(info, w, r)
}
func (s *HTTPServer) ProjectPostHandler(w http.ResponseWriter, r *http.Request) {
name := chi.URLParam(r, "name")
if len(name) == 0 {
badRequest("project name cannot be empty", w, r)
return
}
var pr project.Project
d := json.NewDecoder(r.Body)
if err := d.Decode(&pr); err != nil {
slog.Error("failed to parse project description", "err", err)
internalServerError(err, w, r)
return
}
if err := s.data.Save(pr); err != nil {
slog.Error("failed to save project to the database", "err", err)
internalServerError(err, w, r)
return
}
s.scheduler.Remove(pr)
if err := s.scheduler.Add(pr); err != nil {
slog.Error("failed to run project", "err", err)
internalServerError(err, w, r)
return
}
w.WriteHeader(201)
}
func (s *HTTPServer) ProjectsHandler(w http.ResponseWriter, r *http.Request) {
prs, err := s.data.List()
if err != nil {
slog.Error("failed to fetch all the projects from the database", "err", err)
internalServerError(err, w, r)
return
}
ok(prs, w, r)
}