// Package handler provides HTTP handlers for various endpoints. package handler import ( "errors" "fmt" "net/http" "modelRT/constants" "modelRT/database" "modelRT/diagram" "modelRT/logger" "modelRT/network" "github.com/gin-gonic/gin" ) // MeasurementLinkHandler defines the measurement link process api func MeasurementLinkHandler(c *gin.Context) { var request network.MeasurementLinkRequest clientToken := c.GetString("client_token") if clientToken == "" { err := constants.ErrGetClientToken logger.Error(c, "failed to get client token from context", "error", err) c.JSON(http.StatusOK, network.FailureResponse{ Code: http.StatusBadRequest, Msg: err.Error(), }) return } if err := c.ShouldBindJSON(&request); err != nil { logger.Error(c, "failed to unmarshal measurement create request", "error", err) c.JSON(http.StatusOK, network.FailureResponse{ Code: http.StatusBadRequest, Msg: "Invalid request body format: " + err.Error(), }) return } var err error pgClient := database.GetPostgresDBClient() measurementID := request.MeasurementID action := request.Action measurementInfo, err := database.QueryMeasurementByID(c, pgClient, measurementID) if err != nil { logger.Error(c, "failed to query measurement info by measurement id from postgres", "meauserement_id", measurementID, "error", err) c.JSON(http.StatusOK, network.FailureResponse{ Code: http.StatusInternalServerError, Msg: "failed to query measurement info record: " + err.Error(), Payload: map[string]any{ "id": measurementID, "action": action, }, }) return } componentInfo, err := database.QueryComponentByUUID(c, pgClient, measurementInfo.ComponentUUID) if err != nil { logger.Error(c, "failed to query component info by component uuid from postgres", "component_uuid", measurementInfo.ComponentUUID, "error", err) c.JSON(http.StatusOK, network.FailureResponse{ Code: http.StatusInternalServerError, Msg: "failed to query component info record: " + err.Error(), Payload: map[string]any{ "id": measurementID, "action": action, }, }) return } allMeasSet := diagram.NewRedisSet(c, constants.RedisAllMeasTagSetKey, 0, false) compMeasLinkKey := fmt.Sprintf(constants.RedisSpecCompTagMeasSetKey, componentInfo.Tag) compMeasLinkSet := diagram.NewRedisSet(c, compMeasLinkKey, 0, false) switch action { case constants.SearchLinkAddAction: err1 := allMeasSet.SADD(measurementInfo.Tag) err2 := compMeasLinkSet.SADD(measurementInfo.Tag) err = processActionError(err1, err2, action) if err != nil { logger.Error(c, "add measurement link process operation failed", "measurement_id", measurementID, "action", action, "error", err) } case constants.SearchLinkDelAction: err1 := allMeasSet.SREM(measurementInfo.Tag) err2 := compMeasLinkSet.SREM(measurementInfo.Tag) err = processActionError(err1, err2, action) if err != nil { logger.Error(c, "del measurement link process operation failed", "measurement_id", measurementID, "action", action, "error", err) } default: err = constants.ErrUnsupportedLinkAction logger.Error(c, "unsupport measurement link process action", "measurement_id", measurementID, "action", action, "error", err) } if err != nil { c.JSON(http.StatusOK, network.FailureResponse{ Code: http.StatusBadRequest, Msg: err.Error(), Payload: map[string]any{ "measurement_id": request.MeasurementID, "action": request.Action, }, }) return } logger.Info(c, "process measurement link success", "measurement_id", measurementID, "action", request.Action) c.JSON(http.StatusOK, network.SuccessResponse{ Code: http.StatusOK, Msg: "measurement link process success", Payload: map[string]any{ "measurement_id": measurementID, "action": request.Action, }, }) } func processActionError(err1, err2 error, action string) error { var err error if err1 != nil && err2 != nil { err = errors.Join(err1, err2) err = fmt.Errorf("process measurement link failed, allMeasSet %s operation and compMeasLinkSet %s operation failed: %w", action, action, err) } else if err1 != nil { err = fmt.Errorf("process measurement link failed: allMeasSet %s operation failed: %w", action, err1) } else { err = fmt.Errorf("process measurement link failed: compMeasLinkSet %s operation: %w", action, err2) } return err }