github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/ctl/master/query_validation.go (about) 1 // Copyright 2022 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package master 15 16 import ( 17 "context" 18 "os" 19 "strings" 20 21 "github.com/pingcap/errors" 22 "github.com/pingcap/tiflow/dm/ctl/common" 23 "github.com/pingcap/tiflow/dm/pb" 24 "github.com/spf13/cobra" 25 ) 26 27 const ( 28 ValidationAllErr = "all" 29 ValidationIgnoredErr = "ignored" 30 ValidationUnprocessedErr = "unprocessed" 31 ValidationResolvedErr = "resolved" 32 ) 33 34 var mapStr2ErrState = map[string]pb.ValidateErrorState{ 35 ValidationAllErr: pb.ValidateErrorState_InvalidErr, 36 ValidationIgnoredErr: pb.ValidateErrorState_IgnoredErr, 37 ValidationUnprocessedErr: pb.ValidateErrorState_NewErr, 38 ValidationResolvedErr: pb.ValidateErrorState_ResolvedErr, 39 } 40 41 func NewQueryValidationErrorCmd() *cobra.Command { 42 cmd := &cobra.Command{ 43 Use: "show-error [--error error-state] <task-name>", 44 Short: "show validation error row change", 45 RunE: queryValidationError, 46 } 47 cmd.Flags().String("error", ValidationUnprocessedErr, "filtering type of error: all, ignored, or unprocessed") 48 return cmd 49 } 50 51 func queryValidationError(cmd *cobra.Command, _ []string) (err error) { 52 var ( 53 errState string 54 taskName string 55 pbErrState pb.ValidateErrorState 56 ok bool 57 ) 58 if len(cmd.Flags().Args()) != 1 { 59 return errors.New("task name should be specified") 60 } 61 taskName = cmd.Flags().Arg(0) 62 errState, err = cmd.Flags().GetString("error") 63 if err != nil { 64 return err 65 } 66 if pbErrState, ok = mapStr2ErrState[errState]; !ok || errState == ValidationResolvedErr { 67 // todo: support querying resolved error? 68 cmd.SetOut(os.Stdout) 69 common.PrintCmdUsage(cmd) 70 return errors.Errorf("error flag should be either `%s`, `%s`, or `%s`", ValidationAllErr, ValidationIgnoredErr, ValidationUnprocessedErr) 71 } 72 ctx, cancel := context.WithCancel(context.Background()) 73 defer cancel() 74 resp := &pb.GetValidationErrorResponse{} 75 err = common.SendRequest( 76 ctx, 77 "GetValidationError", 78 &pb.GetValidationErrorRequest{ 79 ErrState: pbErrState, // using InvalidValidateError to represent `all`` 80 TaskName: taskName, 81 }, 82 &resp, 83 ) 84 if err != nil { 85 return err 86 } 87 common.PrettyPrintResponse(resp) 88 return nil 89 } 90 91 func NewQueryValidationStatusCmd() *cobra.Command { 92 cmd := &cobra.Command{ 93 Use: "status [--table-stage stage] <task-name>", 94 Short: "query validation status of a task", 95 RunE: queryValidationStatus, 96 } 97 cmd.Flags().String("table-stage", "", "filter validation tables by stage: running/stopped") 98 return cmd 99 } 100 101 func queryValidationStatus(cmd *cobra.Command, _ []string) error { 102 var ( 103 stage string 104 taskName string 105 err error 106 ) 107 108 if len(cmd.Flags().Args()) != 1 { 109 cmd.SetOut(os.Stdout) 110 common.PrintCmdUsage(cmd) 111 return errors.New("task name should be specified") 112 } 113 taskName = cmd.Flags().Arg(0) 114 stage, err = cmd.Flags().GetString("table-stage") 115 if err != nil { 116 return err 117 } 118 if stage != "" && stage != strings.ToLower(pb.Stage_Running.String()) && stage != strings.ToLower(pb.Stage_Stopped.String()) { 119 cmd.SetOut(os.Stdout) 120 common.PrintCmdUsage(cmd) 121 return errors.Errorf( 122 "stage should be either `%s` or `%s`", 123 strings.ToLower(pb.Stage_Running.String()), 124 strings.ToLower(pb.Stage_Stopped.String()), 125 ) 126 } 127 var pbStage pb.Stage 128 switch stage { 129 case "": 130 // use invalid stage to represent `all` stages 131 pbStage = pb.Stage_InvalidStage 132 case strings.ToLower(pb.Stage_Running.String()): 133 pbStage = pb.Stage_Running 134 case strings.ToLower(pb.Stage_Stopped.String()): 135 pbStage = pb.Stage_Stopped 136 } 137 ctx, cancel := context.WithCancel(context.Background()) 138 defer cancel() 139 140 resp := &pb.GetValidationStatusResponse{} 141 err = common.SendRequest( 142 ctx, 143 "GetValidationStatus", 144 &pb.GetValidationStatusRequest{ 145 TaskName: taskName, 146 FilterStatus: pbStage, 147 }, 148 &resp, 149 ) 150 if err != nil { 151 return err 152 } 153 common.PrettyPrintResponse(resp) 154 return nil 155 }