add server api get and update service control endpoints

This commit is contained in:
Fran Jurmanović
2025-07-29 20:50:44 +02:00
parent 44acb170a7
commit 647f4f7487
27 changed files with 424 additions and 2025 deletions

View File

@@ -1,149 +0,0 @@
package controller
import (
"acc-server-manager/local/middleware"
"acc-server-manager/local/service"
"acc-server-manager/local/utl/common"
"acc-server-manager/local/utl/error_handler"
"github.com/gofiber/fiber/v2"
"github.com/google/uuid"
)
type ApiController struct {
service *service.ApiService
errorHandler *error_handler.ControllerErrorHandler
}
// NewApiController
// Initializes ApiController.
//
// Args:
// *services.ApiService: API service
// *Fiber.RouterGroup: Fiber Router Group
// Returns:
// *ApiController: Controller for "api" interactions
func NewApiController(as *service.ApiService, routeGroups *common.RouteGroups, auth *middleware.AuthMiddleware) *ApiController {
ac := &ApiController{
service: as,
errorHandler: error_handler.NewControllerErrorHandler(),
}
apiGroup := routeGroups.Api
apiGroup.Use(auth.Authenticate)
apiGroup.Get("/", ac.getFirst)
apiGroup.Get("/:service", ac.getStatus)
apiGroup.Post("/start", ac.startServer)
apiGroup.Post("/stop", ac.stopServer)
apiGroup.Post("/restart", ac.restartServer)
return ac
}
// getFirst returns API
//
// @Summary Return API
// @Description Return API
// @Tags api
// @Success 200 {array} string
// @Router /v1/api [get]
func (ac *ApiController) getFirst(c *fiber.Ctx) error {
return c.SendStatus(fiber.StatusOK)
}
// getStatus returns service status
//
// @Summary Return service status
// @Description Returns service status
// @Param service path string true "required"
// @Tags api
// @Success 200 {array} string
// @Router /v1/api/{service} [get]
func (ac *ApiController) getStatus(c *fiber.Ctx) error {
service := c.Params("service")
if service == "" {
serverId := c.Params("service")
if _, err := uuid.Parse(serverId); err != nil {
return ac.errorHandler.HandleUUIDError(c, "server ID")
}
c.Locals("serverId", serverId)
} else {
c.Locals("service", service)
}
apiModel, err := ac.service.GetStatus(c)
if err != nil {
return ac.errorHandler.HandleServiceError(c, err)
}
return c.SendString(string(apiModel))
}
// startServer starts service
//
// @Summary Start service
// @Description Starts service
// @Param name body string true "required"
// @Tags api
// @Success 200 {array} string
// @Router /v1/api/start [post]
func (ac *ApiController) startServer(c *fiber.Ctx) error {
model := new(Service)
if err := c.BodyParser(model); err != nil {
return ac.errorHandler.HandleParsingError(c, err)
}
c.Locals("service", model.Name)
c.Locals("serverId", model.ServerId)
apiModel, err := ac.service.ApiStartServer(c)
if err != nil {
return ac.errorHandler.HandleServiceError(c, err)
}
return c.SendString(apiModel)
}
// stopServer stops service
//
// @Summary Stop service
// @Description Stops service
// @Param name body string true "required"
// @Tags api
// @Success 200 {array} string
// @Router /v1/api/stop [post]
func (ac *ApiController) stopServer(c *fiber.Ctx) error {
model := new(Service)
if err := c.BodyParser(model); err != nil {
return ac.errorHandler.HandleParsingError(c, err)
}
c.Locals("service", model.Name)
c.Locals("serverId", model.ServerId)
apiModel, err := ac.service.ApiStopServer(c)
if err != nil {
return ac.errorHandler.HandleServiceError(c, err)
}
return c.SendString(apiModel)
}
// restartServer returns API
//
// @Summary Restart service
// @Description Restarts service
// @Param name body string true "required"
// @Tags api
// @Success 200 {array} string
// @Router /v1/api/restart [post]
func (ac *ApiController) restartServer(c *fiber.Ctx) error {
model := new(Service)
if err := c.BodyParser(model); err != nil {
return ac.errorHandler.HandleParsingError(c, err)
}
c.Locals("service", model.Name)
c.Locals("serverId", model.ServerId)
apiModel, err := ac.service.ApiRestartServer(c)
if err != nil {
return ac.errorHandler.HandleServiceError(c, err)
}
return c.SendString(apiModel)
}
type Service struct {
Name string `json:"name" xml:"name" form:"name"`
ServerId string `json:"serverId" xml:"serverId" form:"serverId"`
}

View File

@@ -31,10 +31,28 @@ func NewServerController(ss *service.ServerService, routeGroups *common.RouteGro
serverRoutes.Post("/", auth.HasPermission(model.ServerCreate), ac.CreateServer)
serverRoutes.Put("/:id", auth.HasPermission(model.ServerUpdate), ac.UpdateServer)
serverRoutes.Delete("/:id", auth.HasPermission(model.ServerDelete), ac.DeleteServer)
apiServerRoutes := routeGroups.Api.Group("/server")
apiServerRoutes.Get("/", auth.HasPermission(model.ServerView), ac.GetAllApi)
return ac
}
// GetAll returns Servers
func (ac *ServerController) GetAllApi(c *fiber.Ctx) error {
var filter model.ServerFilter
if err := common.ParseQueryFilter(c, &filter); err != nil {
return ac.errorHandler.HandleValidationError(c, err, "query_filter")
}
ServerModel, err := ac.service.GetAll(c, &filter)
if err != nil {
return ac.errorHandler.HandleServiceError(c, err)
}
var apiServers []model.ServerAPI
for _, server := range *ServerModel {
apiServers = append(apiServers, *server.ToServerAPI())
}
return c.JSON(apiServers)
}
func (ac *ServerController) GetAll(c *fiber.Ctx) error {
var filter model.ServerFilter
if err := common.ParseQueryFilter(c, &filter); err != nil {

View File

@@ -0,0 +1,148 @@
package controller
import (
"acc-server-manager/local/middleware"
"acc-server-manager/local/service"
"acc-server-manager/local/utl/common"
"acc-server-manager/local/utl/error_handler"
"github.com/gofiber/fiber/v2"
)
type ServiceControlController struct {
service *service.ServiceControlService
errorHandler *error_handler.ControllerErrorHandler
}
// NewServiceControlController
// Initializes ServiceControlController.
//
// Args:
// *services.ServiceControlService: Service control service
// *Fiber.RouterGroup: Fiber Router Group
// Returns:
// *ServiceControlController: Controller for service control interactions
func NewServiceControlController(as *service.ServiceControlService, routeGroups *common.RouteGroups, auth *middleware.AuthMiddleware) *ServiceControlController {
ac := &ServiceControlController{
service: as,
errorHandler: error_handler.NewControllerErrorHandler(),
}
serviceRoutes := routeGroups.Server.Group("/service")
serviceRoutes.Get("/:service", ac.getStatus)
serviceRoutes.Post("/start", ac.startServer)
serviceRoutes.Post("/stop", ac.stopServer)
serviceRoutes.Post("/restart", ac.restartServer)
return ac
}
// getStatus returns service status
//
// @Summary Get service status
// @Description Get the current status of a Windows service
// @Tags Service Control
// @Accept json
// @Produce json
// @Param service path string true "Service name"
// @Success 200 {object} object{status=string,state=string} "Service status information"
// @Failure 400 {object} error_handler.ErrorResponse "Invalid service name"
// @Failure 401 {object} error_handler.ErrorResponse "Unauthorized"
// @Failure 404 {object} error_handler.ErrorResponse "Service not found"
// @Failure 500 {object} error_handler.ErrorResponse "Internal server error"
// @Security BearerAuth
// @Router /v1/service-control/{service} [get]
func (ac *ServiceControlController) getStatus(c *fiber.Ctx) error {
id := c.Params("id")
c.Locals("serverId", id)
apiModel, err := ac.service.GetStatus(c)
if err != nil {
return ac.errorHandler.HandleServiceError(c, err)
}
return c.SendString(string(apiModel))
}
// startServer starts service
//
// @Summary Start a Windows service
// @Description Start a stopped Windows service for an ACC server
// @Tags Service Control
// @Accept json
// @Produce json
// @Param service body object{name=string} true "Service name to start"
// @Success 200 {object} object{message=string} "Service started successfully"
// @Failure 400 {object} error_handler.ErrorResponse "Invalid request body"
// @Failure 401 {object} error_handler.ErrorResponse "Unauthorized"
// @Failure 403 {object} error_handler.ErrorResponse "Insufficient permissions"
// @Failure 404 {object} error_handler.ErrorResponse "Service not found"
// @Failure 409 {object} error_handler.ErrorResponse "Service already running"
// @Failure 500 {object} error_handler.ErrorResponse "Internal server error"
// @Security BearerAuth
// @Router /v1/service-control/start [post]
func (ac *ServiceControlController) startServer(c *fiber.Ctx) error {
id := c.Params("id")
c.Locals("serverId", id)
apiModel, err := ac.service.ServiceControlStartServer(c)
if err != nil {
return ac.errorHandler.HandleServiceError(c, err)
}
return c.SendString(apiModel)
}
// stopServer stops service
//
// @Summary Stop a Windows service
// @Description Stop a running Windows service for an ACC server
// @Tags Service Control
// @Accept json
// @Produce json
// @Param service body object{name=string} true "Service name to stop"
// @Success 200 {object} object{message=string} "Service stopped successfully"
// @Failure 400 {object} error_handler.ErrorResponse "Invalid request body"
// @Failure 401 {object} error_handler.ErrorResponse "Unauthorized"
// @Failure 403 {object} error_handler.ErrorResponse "Insufficient permissions"
// @Failure 404 {object} error_handler.ErrorResponse "Service not found"
// @Failure 409 {object} error_handler.ErrorResponse "Service already stopped"
// @Failure 500 {object} error_handler.ErrorResponse "Internal server error"
// @Security BearerAuth
// @Router /v1/service-control/stop [post]
func (ac *ServiceControlController) stopServer(c *fiber.Ctx) error {
id := c.Params("id")
c.Locals("serverId", id)
apiModel, err := ac.service.ServiceControlStopServer(c)
if err != nil {
return ac.errorHandler.HandleServiceError(c, err)
}
return c.SendString(apiModel)
}
// restartServer restarts service
//
// @Summary Restart a Windows service
// @Description Stop and start a Windows service for an ACC server
// @Tags Service Control
// @Accept json
// @Produce json
// @Param service body object{name=string} true "Service name to restart"
// @Success 200 {object} object{message=string} "Service restarted successfully"
// @Failure 400 {object} error_handler.ErrorResponse "Invalid request body"
// @Failure 401 {object} error_handler.ErrorResponse "Unauthorized"
// @Failure 403 {object} error_handler.ErrorResponse "Insufficient permissions"
// @Failure 404 {object} error_handler.ErrorResponse "Service not found"
// @Failure 500 {object} error_handler.ErrorResponse "Internal server error"
// @Security BearerAuth
// @Router /v1/service-control/restart [post]
func (ac *ServiceControlController) restartServer(c *fiber.Ctx) error {
id := c.Params("id")
c.Locals("serverId", id)
apiModel, err := ac.service.ServiceControlRestartServer(c)
if err != nil {
return ac.errorHandler.HandleServiceError(c, err)
}
return c.SendString(apiModel)
}
type Service struct {
Name string `json:"name" xml:"name" form:"name"`
ServerId string `json:"serverId" xml:"serverId" form:"serverId"`
}

View File

@@ -0,0 +1,38 @@
package controller
import (
"acc-server-manager/local/utl/common"
"github.com/gofiber/fiber/v2"
)
type SystemController struct {
}
// NewSystemController
// Initializes SystemController.
//
// Args:
// *services.SystemService: Service control service
// *Fiber.RouterGroup: Fiber Router Group
// Returns:
// *SystemController: Controller for service control interactions
func NewSystemController(routeGroups *common.RouteGroups) *SystemController {
ac := &SystemController{}
apiGroup := routeGroups.System
apiGroup.Get("/health", ac.getFirst)
return ac
}
// getFirst returns service control status
//
// @Summary Return service control status
// @Description Return service control status
// @Tags service-control
// @Success 200 {array} string
// @Router /v1/service-control [get]
func (ac *SystemController) getFirst(c *fiber.Ctx) error {
return c.SendStatus(fiber.StatusOK)
}