From 1a1727adab9a44325a32ed41303eb5b9a78e2559 Mon Sep 17 00:00:00 2001 From: douxu Date: Mon, 26 Jan 2026 16:29:50 +0800 Subject: [PATCH] optimize reponse code and business code of measurement sub api --- common/errcode/bussiness_error.go | 6 + constants/attribute_business_code.go | 17 --- constants/business_code.go | 31 +++++ handler/real_time_data_subscription.go | 155 +++++++++---------------- network/response.go | 2 +- 5 files changed, 94 insertions(+), 117 deletions(-) delete mode 100644 constants/attribute_business_code.go create mode 100644 constants/business_code.go diff --git a/common/errcode/bussiness_error.go b/common/errcode/bussiness_error.go index 04ff3f6..08fcfea 100644 --- a/common/errcode/bussiness_error.go +++ b/common/errcode/bussiness_error.go @@ -16,6 +16,12 @@ var ( // ErrFoundTargetFailed define variable to returned when the specific database table cannot be identified using the provided token info. ErrFoundTargetFailed = newError(40004, "found target table by token failed") + // ErrSubTargetRepeat define variable to indicates subscription target already exist in list + ErrSubTargetRepeat = newError(40005, "subscription target already exist in list") + // ErrSubTargetNotFound define variable to indicates can not find measurement by subscription target + ErrSubTargetNotFound = newError(40006, "found measuremnet by subscription target failed") + // ErrCancelSubTargetMissing define variable to indicates cancel a not exist subscription target + ErrCancelSubTargetMissing = newError(40007, "cancel a not exist subscription target") // ErrDBQueryFailed define variable to represents a generic failure during a PostgreSQL SELECT or SCAN operation. ErrDBQueryFailed = newError(50001, "query postgres database data failed") diff --git a/constants/attribute_business_code.go b/constants/attribute_business_code.go deleted file mode 100644 index 487b338..0000000 --- a/constants/attribute_business_code.go +++ /dev/null @@ -1,17 +0,0 @@ -// Package constants define constant variable -package constants - -const ( - // CodeSuccess define constant to indicates that the API was successfully processed - CodeSuccess = 20000 - // CodeInvalidParamFailed define constant to indicates request parameter parsing failed - CodeInvalidParamFailed = 40001 - // CodeDBQueryFailed define constant to indicates database query operation failed - CodeDBQueryFailed = 50001 - // CodeDBUpdateailed define constant to indicates database update operation failed - CodeDBUpdateailed = 50002 - // CodeRedisQueryFailed define constant to indicates redis query operation failed - CodeRedisQueryFailed = 60001 - // CodeRedisUpdateFailed define constant to indicates redis update operation failed - CodeRedisUpdateFailed = 60002 -) diff --git a/constants/business_code.go b/constants/business_code.go new file mode 100644 index 0000000..aa18e0e --- /dev/null +++ b/constants/business_code.go @@ -0,0 +1,31 @@ +// Package constants define constant variable +package constants + +const ( + // CodeSuccess define constant to indicates that the API was successfully processed + CodeSuccess = 20000 + // CodeInvalidParamFailed define constant to indicates request parameter parsing failed + CodeInvalidParamFailed = 40001 + // CodeFoundTargetFailed define variable to returned when the specific database table cannot be identified using the provided token info. + CodeFoundTargetFailed = 40004 + // CodeSubTargetRepeat define variable to indicates subscription target already exist in list + CodeSubTargetRepeat = 40005 + // CodeSubTargetNotFound define variable to indicates can not find measurement by subscription target + CodeSubTargetNotFound = 40006 + // CodeCancelSubTargetMissing define variable to indicates cancel a not exist subscription target + CodeCancelSubTargetMissing = 40007 + // CodeUpdateSubTargetMissing define variable to indicates update a not exist subscription target + CodeUpdateSubTargetMissing = 40008 + // CodeAppendSubTargetMissing define variable to indicates append a not exist subscription target + CodeAppendSubTargetMissing = 40009 + // CodeUnsupportSubOperation define variable to indicates append a not exist subscription target + CodeUnsupportSubOperation = 40010 + // CodeDBQueryFailed define constant to indicates database query operation failed + CodeDBQueryFailed = 50001 + // CodeDBUpdateailed define constant to indicates database update operation failed + CodeDBUpdateailed = 50002 + // CodeRedisQueryFailed define constant to indicates redis query operation failed + CodeRedisQueryFailed = 60001 + // CodeRedisUpdateFailed define constant to indicates redis update operation failed + CodeRedisUpdateFailed = 60002 +) diff --git a/handler/real_time_data_subscription.go b/handler/real_time_data_subscription.go index f0f435b..4f87f33 100644 --- a/handler/real_time_data_subscription.go +++ b/handler/real_time_data_subscription.go @@ -5,7 +5,6 @@ import ( "context" "fmt" "maps" - "net/http" "sync" "modelRT/constants" @@ -33,42 +32,42 @@ func init() { // @Accept json // @Produce json // @Param request body network.RealTimeSubRequest true "量测节点实时数据订阅" -// @Success 200 {object} network.SuccessResponse{payload=network.RealTimeSubPayload} "订阅实时数据结果列表" +// @Success 2000 {object} network.SuccessResponse{payload=network.RealTimeSubPayload} "订阅实时数据结果列表" // -// @Example 200 { -// "code": 200, -// "msg": "success", +// @Example 2000 { +// "code": 2000, +// "msg": "process completed", // "payload": { // "targets": [ // { // "id": "grid1.zone1.station1.ns1.tag1.bay.I11_C_rms", -// "code": "1001", +// "code": "20000", // "msg": "subscription success" // }, // { // "id": "grid1.zone1.station1.ns1.tag1.bay.I11_B_rms", -// "code": "1002", +// "code": "20000", // "msg": "subscription failed" // } // ] // } // } // -// @Failure 400 {object} network.FailureResponse{payload=network.RealTimeSubPayload} "订阅实时数据结果列表" +// @Failure 3000 {object} network.FailureResponse{payload=network.RealTimeSubPayload} "订阅实时数据结果列表" // -// @Example 400 { -// "code": 400, -// "msg": "failed to get recommend data from redis", +// @Example 3000 { +// "code": 3000, +// "msg": "process completed with partial failures", // "payload": { // "targets": [ // { // "id": "grid1.zone1.station1.ns1.tag1.bay.I11_A_rms", -// "code": "1002", +// "code": "40005", // "msg": "subscription failed" // }, // { // "id": "grid1.zone1.station1.ns1.tag1.bay.I11_B_rms", -// "code": "1002", +// "code": "50001", // "msg": "subscription failed" // } // ] @@ -83,10 +82,7 @@ func RealTimeSubHandler(c *gin.Context) { if err := c.ShouldBindJSON(&request); err != nil { logger.Error(c, "failed to unmarshal real time query request", "error", err) - c.JSON(http.StatusOK, network.FailureResponse{ - Code: http.StatusBadRequest, - Msg: err.Error(), - }) + renderRespFailure(c, constants.RespCodeInvalidParams, err.Error(), nil) return } @@ -95,10 +91,7 @@ func RealTimeSubHandler(c *gin.Context) { id, err := uuid.NewV4() if err != nil { logger.Error(c, "failed to generate client id", "error", err) - c.JSON(http.StatusOK, network.FailureResponse{ - Code: http.StatusBadRequest, - Msg: err.Error(), - }) + renderRespFailure(c, constants.RespCodeInvalidParams, err.Error(), nil) return } clientID = id.String() @@ -123,110 +116,74 @@ func RealTimeSubHandler(c *gin.Context) { results, err := globalSubState.CreateConfig(c, tx, clientID, request.Measurements) if err != nil { logger.Error(c, "create real time data subscription config failed", "error", err) - c.JSON(http.StatusOK, network.FailureResponse{ - Code: http.StatusBadRequest, - Msg: err.Error(), - Payload: network.RealTimeSubPayload{ - ClientID: clientID, - TargetResults: results, - }, + renderRespFailure(c, constants.RespCodeFailed, err.Error(), network.RealTimeSubPayload{ + ClientID: clientID, + TargetResults: results, }) return } - c.JSON(http.StatusOK, network.SuccessResponse{ - Code: http.StatusOK, - Msg: "success", - Payload: network.RealTimeSubPayload{ - ClientID: clientID, - TargetResults: results, - }, + renderRespSuccess(c, constants.RespCodeSuccess, "process completed", network.RealTimeSubPayload{ + ClientID: clientID, + TargetResults: results, }) return case constants.SubStopAction: results, err := globalSubState.RemoveTargets(c, clientID, request.Measurements) if err != nil { logger.Error(c, "remove target to real time data subscription config failed", "error", err) - c.JSON(http.StatusOK, network.FailureResponse{ - Code: http.StatusBadRequest, - Msg: err.Error(), - Payload: network.RealTimeSubPayload{ - ClientID: clientID, - TargetResults: results, - }, + renderRespFailure(c, constants.RespCodeFailed, err.Error(), network.RealTimeSubPayload{ + ClientID: clientID, + TargetResults: results, }) return } - c.JSON(http.StatusOK, network.SuccessResponse{ - Code: http.StatusOK, - Msg: "success", - Payload: network.RealTimeSubPayload{ - ClientID: clientID, - TargetResults: results, - }, + renderRespSuccess(c, constants.RespCodeSuccess, "success", network.RealTimeSubPayload{ + ClientID: clientID, + TargetResults: results, }) return case constants.SubAppendAction: results, err := globalSubState.AppendTargets(c, tx, clientID, request.Measurements) if err != nil { logger.Error(c, "append target to real time data subscription config failed", "error", err) - c.JSON(http.StatusOK, network.FailureResponse{ - Code: http.StatusBadRequest, - Msg: err.Error(), - Payload: network.RealTimeSubPayload{ - ClientID: clientID, - TargetResults: results, - }, + renderRespFailure(c, constants.RespCodeFailed, err.Error(), network.RealTimeSubPayload{ + ClientID: clientID, + TargetResults: results, }) return } - c.JSON(http.StatusOK, network.SuccessResponse{ - Code: http.StatusOK, - Msg: "success", - Payload: network.RealTimeSubPayload{ - ClientID: clientID, - TargetResults: results, - }, + renderRespSuccess(c, constants.RespCodeSuccess, "success", network.RealTimeSubPayload{ + ClientID: clientID, + TargetResults: results, }) return case constants.SubUpdateAction: results, err := globalSubState.UpdateTargets(c, tx, clientID, request.Measurements) if err != nil { logger.Error(c, "update target to real time data subscription config failed", "error", err) - c.JSON(http.StatusOK, network.FailureResponse{ - Code: http.StatusBadRequest, - Msg: err.Error(), - Payload: network.RealTimeSubPayload{ - ClientID: clientID, - TargetResults: results, - }, + renderRespFailure(c, constants.RespCodeFailed, err.Error(), network.RealTimeSubPayload{ + ClientID: clientID, + TargetResults: results, }) return } - c.JSON(http.StatusOK, network.SuccessResponse{ - Code: http.StatusOK, - Msg: "success", - Payload: network.RealTimeSubPayload{ - ClientID: clientID, - TargetResults: results, - }, + renderRespSuccess(c, constants.RespCodeSuccess, "success", network.RealTimeSubPayload{ + ClientID: clientID, + TargetResults: results, }) return default: err := fmt.Errorf("%w: request action is %s", constants.ErrUnsupportedSubAction, request.Action) logger.Error(c, "unsupported action of real time data subscription request", "error", err) requestTargetsCount := processRealTimeRequestCount(request.Measurements) - results := processRealTimeRequestTargets(request.Measurements, requestTargetsCount, err) - c.JSON(http.StatusOK, network.FailureResponse{ - Code: http.StatusBadRequest, - Msg: err.Error(), - Payload: network.RealTimeSubPayload{ - ClientID: clientID, - TargetResults: results, - }, + results := processRealTimeRequestTargets(request.Measurements, requestTargetsCount, constants.CodeUnsupportSubOperation, err) + renderRespFailure(c, constants.RespCodeInvalidParams, err.Error(), network.RealTimeSubPayload{ + ClientID: clientID, + TargetResults: results, }) return } @@ -283,12 +240,12 @@ func processAndValidateTargetsForStart(ctx context.Context, tx *gorm.DB, measure targetModel, err := database.ParseDataIdentifierToken(ctx, tx, target) if err != nil { logger.Error(ctx, "parse data indentity token failed", "error", err, "identity_token", target) - targetResult.Code = constants.SubFailedCode + targetResult.Code = constants.CodeFoundTargetFailed targetResult.Msg = fmt.Sprintf("%s: %s", constants.SubFailedMsg, err.Error()) targetProcessResults = append(targetProcessResults, targetResult) continue } - targetResult.Code = constants.SubSuccessCode + targetResult.Code = constants.CodeSuccess targetResult.Msg = constants.SubSuccessMsg targetProcessResults = append(targetProcessResults, targetResult) successfulTargets = append(successfulTargets, target) @@ -327,7 +284,7 @@ func processAndValidateTargetsForUpdate(ctx context.Context, tx *gorm.DB, config if _, exist := config.targetContext[target]; !exist { err := fmt.Errorf("target %s does not exists in subscription list", target) logger.Error(ctx, "update target does not exist in subscription list", "error", err, "target", target) - targetResult.Code = constants.UpdateSubFailedCode + targetResult.Code = constants.CodeUpdateSubTargetMissing targetResult.Msg = fmt.Sprintf("%s: %s", constants.UpdateSubFailedMsg, err.Error()) targetProcessResults = append(targetProcessResults, targetResult) continue @@ -336,13 +293,13 @@ func processAndValidateTargetsForUpdate(ctx context.Context, tx *gorm.DB, config targetModel, err := database.ParseDataIdentifierToken(ctx, tx, target) if err != nil { logger.Error(ctx, "parse data indentity token failed", "error", err, "identity_token", target) - targetResult.Code = constants.UpdateSubFailedCode + targetResult.Code = constants.CodeDBQueryFailed targetResult.Msg = fmt.Sprintf("%s: %s", constants.UpdateSubFailedMsg, err.Error()) targetProcessResults = append(targetProcessResults, targetResult) continue } - targetResult.Code = constants.UpdateSubSuccessCode + targetResult.Code = constants.CodeSuccess targetResult.Msg = constants.UpdateSubSuccessMsg targetProcessResults = append(targetProcessResults, targetResult) successfulTargets = append(successfulTargets, target) @@ -473,7 +430,7 @@ func (s *SharedSubState) AppendTargets(ctx context.Context, tx *gorm.DB, clientI if !exist { err := fmt.Errorf("clientID %s not found. use CreateConfig to start a new config", clientID) logger.Error(ctx, "clientID not found. use CreateConfig to start a new config", "error", err) - return processRealTimeRequestTargets(measurements, requestTargetsCount, err), err + return processRealTimeRequestTargets(measurements, requestTargetsCount, constants.CodeAppendSubTargetMissing, err), err } targetProcessResults, successfulTargets, newMeasMap, newMeasContextMap := processAndValidateTargetsForStart(ctx, tx, measurements, requestTargetsCount) @@ -507,7 +464,7 @@ func filterAndDeduplicateRepeatTargets(resultsSlice []network.TargetResult, idsS for index := range resultsSlice { if _, isTarget := set[resultsSlice[index].ID]; isTarget { - resultsSlice[index].Code = constants.SubRepeatCode + resultsSlice[index].Code = constants.CodeSubTargetRepeat resultsSlice[index].Msg = constants.SubRepeatMsg } } @@ -575,7 +532,7 @@ func (s *SharedSubState) RemoveTargets(ctx context.Context, clientID string, mea s.globalMutex.RUnlock() err := fmt.Errorf("clientID %s not found", clientID) logger.Error(ctx, "clientID not found in remove targets operation", "error", err) - return processRealTimeRequestTargets(measurements, requestTargetsCount, err), err + return processRealTimeRequestTargets(measurements, requestTargetsCount, constants.CodeCancelSubTargetMissing, err), err } s.globalMutex.RUnlock() @@ -595,7 +552,7 @@ func (s *SharedSubState) RemoveTargets(ctx context.Context, clientID string, mea for _, target := range measTargets { targetResult := network.TargetResult{ ID: target, - Code: constants.CancelSubFailedCode, + Code: constants.CodeCancelSubTargetMissing, Msg: constants.CancelSubFailedMsg, } targetProcessResults = append(targetProcessResults, targetResult) @@ -616,7 +573,7 @@ func (s *SharedSubState) RemoveTargets(ctx context.Context, clientID string, mea transportTargets.Targets = append(transportTargets.Targets, existingTarget) targetResult := network.TargetResult{ ID: existingTarget, - Code: constants.CancelSubSuccessCode, + Code: constants.CodeSuccess, Msg: constants.CancelSubSuccessMsg, } targetProcessResults = append(targetProcessResults, targetResult) @@ -639,7 +596,7 @@ func (s *SharedSubState) RemoveTargets(ctx context.Context, clientID string, mea for target := range targetsToRemoveMap { targetResult := network.TargetResult{ ID: target, - Code: constants.CancelSubFailedCode, + Code: constants.CodeCancelSubTargetMissing, Msg: fmt.Sprintf("%s: %s", constants.SubFailedMsg, err.Error()), } targetProcessResults = append(targetProcessResults, targetResult) @@ -673,7 +630,7 @@ func (s *SharedSubState) UpdateTargets(ctx context.Context, tx *gorm.DB, clientI s.globalMutex.RUnlock() err := fmt.Errorf("clientID %s not found", clientID) logger.Error(ctx, "clientID not found in remove targets operation", "error", err) - return processRealTimeRequestTargets(measurements, requestTargetsCount, err), err + return processRealTimeRequestTargets(measurements, requestTargetsCount, constants.CodeUpdateSubTargetMissing, err), err } targetProcessResults, successfulTargets, newMeasMap, newMeasContextMap := processAndValidateTargetsForUpdate(ctx, tx, config, measurements, requestTargetsCount) @@ -722,13 +679,13 @@ func processRealTimeRequestCount(measurements []network.RealTimeMeasurementItem) return totalTargetsCount } -func processRealTimeRequestTargets(measurements []network.RealTimeMeasurementItem, targetCount int, err error) []network.TargetResult { +func processRealTimeRequestTargets(measurements []network.RealTimeMeasurementItem, targetCount int, businessCode int, err error) []network.TargetResult { targetProcessResults := make([]network.TargetResult, 0, targetCount) for _, measurementItem := range measurements { for _, target := range measurementItem.Targets { var targetResult network.TargetResult targetResult.ID = target - targetResult.Code = constants.SubFailedCode + targetResult.Code = businessCode targetResult.Msg = fmt.Sprintf("%s: %s", constants.SubFailedMsg, err.Error()) targetProcessResults = append(targetProcessResults, targetResult) } diff --git a/network/response.go b/network/response.go index e8d775a..4bed98d 100644 --- a/network/response.go +++ b/network/response.go @@ -26,7 +26,7 @@ type MeasurementRecommendPayload struct { // TargetResult define struct of target item in real time data subscription response payload type TargetResult struct { ID string `json:"id" example:"grid1.zone1.station1.ns1.tag1.transformfeeder1_220.I_A_rms"` - Code string `json:"code" example:"1001"` + Code int `json:"code" example:"20000"` Msg string `json:"msg" example:"subscription success"` }