Files
hpc/internal/handler/cluster.go
dailz e6162063ca feat: 添加 HTTP 处理层和结构化日志
- JobHandler: 提交/查询/取消/历史,5xx Error + 4xx Warn 日志

- ClusterHandler: 节点/分区/诊断,错误和未找到日志

- TemplateHandler: CRUD 操作,创建/更新/删除 Info + 未找到 Warn

- 不记录成功响应(由 middleware.RequestLogger 处理)

- 不记录请求体和模板内容(安全考虑)

- 完整 TDD 测试,使用 zaptest/observer 验证日志级别和字段

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-10 08:40:06 +08:00

95 lines
2.6 KiB
Go

package handler
import (
"gcy_hpc_server/internal/server"
"gcy_hpc_server/internal/service"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
// ClusterHandler handles HTTP requests for cluster operations (nodes, partitions, diag).
type ClusterHandler struct {
clusterSvc *service.ClusterService
logger *zap.Logger
}
// NewClusterHandler creates a new ClusterHandler with the given ClusterService.
func NewClusterHandler(clusterSvc *service.ClusterService, logger *zap.Logger) *ClusterHandler {
return &ClusterHandler{clusterSvc: clusterSvc, logger: logger}
}
// GetNodes handles GET /api/v1/nodes.
func (h *ClusterHandler) GetNodes(c *gin.Context) {
nodes, err := h.clusterSvc.GetNodes(c.Request.Context())
if err != nil {
h.logger.Error("handler error", zap.String("method", "GetNodes"), zap.Error(err))
server.InternalError(c, err.Error())
return
}
server.OK(c, nodes)
}
// GetNode handles GET /api/v1/nodes/:name.
func (h *ClusterHandler) GetNode(c *gin.Context) {
name := c.Param("name")
resp, err := h.clusterSvc.GetNode(c.Request.Context(), name)
if err != nil {
h.logger.Error("handler error", zap.String("method", "GetNode"), zap.Error(err))
server.InternalError(c, err.Error())
return
}
if resp == nil {
h.logger.Warn("not found", zap.String("method", "GetNode"), zap.String("name", name))
server.NotFound(c, "node not found")
return
}
server.OK(c, resp)
}
// GetPartitions handles GET /api/v1/partitions.
func (h *ClusterHandler) GetPartitions(c *gin.Context) {
partitions, err := h.clusterSvc.GetPartitions(c.Request.Context())
if err != nil {
h.logger.Error("handler error", zap.String("method", "GetPartitions"), zap.Error(err))
server.InternalError(c, err.Error())
return
}
server.OK(c, partitions)
}
// GetPartition handles GET /api/v1/partitions/:name.
func (h *ClusterHandler) GetPartition(c *gin.Context) {
name := c.Param("name")
resp, err := h.clusterSvc.GetPartition(c.Request.Context(), name)
if err != nil {
h.logger.Error("handler error", zap.String("method", "GetPartition"), zap.Error(err))
server.InternalError(c, err.Error())
return
}
if resp == nil {
h.logger.Warn("not found", zap.String("method", "GetPartition"), zap.String("name", name))
server.NotFound(c, "partition not found")
return
}
server.OK(c, resp)
}
// GetDiag handles GET /api/v1/diag.
func (h *ClusterHandler) GetDiag(c *gin.Context) {
resp, err := h.clusterSvc.GetDiag(c.Request.Context())
if err != nil {
h.logger.Error("handler error", zap.String("method", "GetDiag"), zap.Error(err))
server.InternalError(c, err.Error())
return
}
server.OK(c, resp)
}