robot-control-manager/routers/api/v1/robot/robot.go

317 lines
8.0 KiB
Go

package robot
import (
"jannex/robot-control-manager/modules/cache"
"jannex/robot-control-manager/modules/database"
"jannex/robot-control-manager/modules/logger"
"jannex/robot-control-manager/modules/robot"
"jannex/robot-control-manager/modules/structs"
"jannex/robot-control-manager/modules/utils"
"time"
"git.ex.umbach.dev/Alex/roese-utils/rsutils"
"github.com/gofiber/fiber/v2"
"github.com/google/uuid"
)
func FirstRequest(c *fiber.Ctx) error {
// swagger:operation POST /robot robot robotFirstRequest
// ---
// summary: First request from robot.
// description: |
// This is the first request from the robot. It will be used to identify the robot.
// consumes:
// - application/json
// produces:
// - application/json
// parameters:
// - in: body
// name: body
// description: First request body.
// required: true
// schema:
// "$ref": "#/definitions/FirstRequestBody"
// responses:
// "200":
// description: Robot identified
// schema:
// "$ref": "#/definitions/StatusResponse"
// "400":
// description: Invalid request body
// "403":
// description: Permit join is enabled
var body structs.FirstRequestBody
if err := rsutils.BodyParserHelper(c, &body); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
var foundRobot structs.Robot
database.DB.First(&foundRobot, "id = ?", body.Id)
if !cache.IsPermitJoinEnabled() && foundRobot.Id == "" {
logger.AddSystemLog("Unauthorized robot tried to connect with id %v and type %v", body.Id, utils.GetRobotTypeString(body.Type))
return c.SendStatus(fiber.StatusForbidden)
}
if foundRobot.Id == "" {
now := time.Now()
newUnauthorizedRobot := structs.UnauthorizedRobot{
Id: body.Id,
Type: body.Type,
Address: c.IP(),
FirmwareVersion: body.FirmwareVersion,
ConnectedAt: now,
CreatedAt: now,
}
cache.AddUnauthorizedRobot(&newUnauthorizedRobot)
robot.BroadcastSSEMessage(structs.SSEMessage{
Cmd: utils.SSESentCmdAddUnauthorizedRobot,
Body: &newUnauthorizedRobot,
})
logger.AddSystemLog("Unauthorized robot connected with id %v and type %v", body.Id, utils.GetRobotTypeString(body.Type))
} else {
newRobot := structs.Robot{
Id: body.Id,
Type: body.Type,
Name: foundRobot.Name,
Status: utils.RobotStatusIdle,
Address: c.IP(),
CurrentJobId: "",
FirmwareVersion: body.FirmwareVersion,
ConnectedAt: time.Now(),
CreatedAt: foundRobot.CreatedAt,
}
cache.AddRobot(&newRobot)
database.DB.Model(&structs.Robot{}).
Where("id = ?", newRobot.Id).
Updates(structs.Robot{
Status: newRobot.Status,
Type: newRobot.Type,
Address: newRobot.Address,
FirmwareVersion: newRobot.FirmwareVersion,
})
robot.BroadcastSSEMessage(structs.SSEMessage{
Cmd: utils.SSESentCmdAddRobot,
Body: &newRobot,
})
logger.AddSystemLog("Robot connected with id %v and type %v", body.Id, utils.GetRobotTypeString(body.Type))
}
return c.JSON(structs.StatusResponse{Status: "ok"})
}
func AuthorizeRobot(c *fiber.Ctx) error {
// swagger:operation POST /robot/authorize/{robotId} robot robotAuthorize
// ---
// summary: Authorize robot.
// consumes:
// - application/json
// produces:
// - application/json
// parameters:
// - in: params
// name: robotId
// description: Robot id.
// required: true
// schema:
// type: string
// responses:
// "200":
// description: Robot authorized
// "400":
// description: Invalid robot id
// "422":
// description: Robot not found
var params structs.RobotIdParams
if err := rsutils.ParamsParserHelper(c, &params); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
if !cache.IsUnauthorizedRobotInList(params.RobotId) {
logger.AddSystemLog("Unauthorized robot with id %v not found", params.RobotId)
return c.SendStatus(fiber.StatusUnprocessableEntity)
}
unauthorizedRobot := cache.GetUnauthorizedRobotById(params.RobotId)
if unauthorizedRobot.Id == "" {
return c.SendStatus(fiber.StatusUnprocessableEntity)
}
newRobot := structs.Robot{
Id: params.RobotId,
Type: unauthorizedRobot.Type,
Name: uuid.New().String(),
Address: unauthorizedRobot.Address,
Status: utils.RobotStatusIdle,
FirmwareVersion: unauthorizedRobot.FirmwareVersion,
ConnectedAt: unauthorizedRobot.ConnectedAt,
CreatedAt: unauthorizedRobot.CreatedAt,
}
cache.AddRobot(&newRobot)
database.DB.Create(&newRobot)
cache.RemoveUnauthorizedRobotById(params.RobotId)
robot.BroadcastSSEMessage(structs.SSEMessage{
Cmd: utils.SSESentCmdAddRobot,
Body: &newRobot,
})
logger.AddSystemLog("Robot authorized with id %v and type %v", params.RobotId, utils.GetRobotTypeString(unauthorizedRobot.Type))
return c.SendStatus(fiber.StatusOK)
}
func DeleteRobot(c *fiber.Ctx) error {
// swagger:operation DELETE /robot/{robotId} robot robotDelete
// ---
// summary: Delete robot.
// consumes:
// - application/json
// produces:
// - application/json
// parameters:
// - in: path
// name: robotId
// description: Robot id.
// required: true
// schema:
// type: string
// responses:
// "200":
// description: Robot deleted
// "400":
// description: Invalid robot id
var params structs.RobotIdParams
if err := rsutils.ParamsParserHelper(c, &params); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
database.DB.Delete(&structs.Robot{}, "id = ?", params.RobotId)
cache.RemoveRobotById(params.RobotId)
robot.BroadcastSSEMessage(structs.SSEMessage{
Cmd: utils.SSESentCmdRemoveRobot,
Body: params.RobotId,
})
logger.AddSystemLog("Robot deleted with id %v", params.RobotId)
return c.SendStatus(fiber.StatusOK)
}
func DenyUnauthorizedRobot(c *fiber.Ctx) error {
// swagger:operation DELETE /robot/deny/{robotId} robot robotDenyUnauthorizedRobot
// ---
// summary: Deny unauthorized robot.
// consumes:
// - application/json
// produces:
// - application/json
// parameters:
// - in: path
// name: robotId
// description: Robot id.
// required: true
// schema:
// type: string
// responses:
// "200":
// description: Robot denied
// "400":
// description: Invalid robot id
var params structs.RobotIdParams
if err := rsutils.ParamsParserHelper(c, &params); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
cache.RemoveUnauthorizedRobotById(params.RobotId)
robot.BroadcastSSEMessage(structs.SSEMessage{
Cmd: utils.SSESentCmdRemoveUnauthorizedRobot,
Body: params.RobotId,
})
logger.AddSystemLog("Unauthorized robot denied with id %v", params.RobotId)
return c.SendStatus(fiber.StatusOK)
}
func UpdateRobot(c *fiber.Ctx) error {
// swagger:operation PATCH /robot robot robotUpdate
// ---
// summary: Update robot.
// consumes:
// - application/json
// produces:
// - application/json
// parameters:
// - in: body
// name: body
// description: Update robot body.
// required: true
// schema:
// "$ref": "#/definitions/Robot"
// responses:
// "200":
// description: Robot updated
// "400":
// description: Invalid request body
// "422":
// description: Robot not found
var body structs.UpdateRobotBody
if err := rsutils.BodyParserHelper(c, &body); err != nil {
return c.SendStatus(fiber.StatusBadRequest)
}
if !cache.IsRobotInList(body.RobotId) {
logger.AddSystemLog("Robot with id %v not found", body.RobotId)
return c.SendStatus(fiber.StatusUnprocessableEntity)
}
foundRobot := cache.GetRobotById(body.RobotId)
if foundRobot == nil || cache.IsRobotNameInList(body.Name) {
return c.SendStatus(fiber.StatusUnprocessableEntity)
}
foundRobot.Name = body.Name
database.DB.Model(&structs.Robot{}).
Where("id = ?", foundRobot.Id).
Update("name", foundRobot.Name)
robot.BroadcastSSEMessage(structs.SSEMessage{
Cmd: utils.SSESentCmdRobotUpdated,
Body: body,
})
logger.AddSystemLog("Robot with id %v name changed to %v", body.RobotId, body.Name)
return c.SendStatus(fiber.StatusOK)
}