From f56b46fcefc3011bd6ff96ece7fca7534a4fe68d Mon Sep 17 00:00:00 2001 From: Ehco Date: Thu, 10 Feb 2022 11:29:35 +0800 Subject: [PATCH] openapi(dm): add error_msg in task status (#4421) ref pingcap/tiflow#3583 --- dm/dm/master/openapi.go | 21 ++- dm/dm/master/openapi_test.go | 104 ++++++++----- dm/openapi/gen.server.go | 172 ++++++++++----------- dm/openapi/gen.types.go | 3 + dm/openapi/spec/dm.yaml | 3 + dm/tests/openapi/client/openapi_task_check | 13 ++ dm/tests/openapi/run.sh | 75 ++++----- 7 files changed, 217 insertions(+), 174 deletions(-) diff --git a/dm/dm/master/openapi.go b/dm/dm/master/openapi.go index ada0dee4700..0581bda261d 100644 --- a/dm/dm/master/openapi.go +++ b/dm/dm/master/openapi.go @@ -936,6 +936,16 @@ func getOpenAPISubtaskStatusByTaskName(taskName string, return nil, terror.ErrOpenAPICommonError.New("worker's query-status response is nil") } sourceStatus := workerStatus.SourceStatus + openapiSubTaskStatus := openapi.SubTaskStatus{ + Name: taskName, + SourceName: sourceStatus.GetSource(), + WorkerName: sourceStatus.GetWorker(), + } + if !workerStatus.Result { + openapiSubTaskStatus.ErrorMsg = &workerStatus.Msg + subTaskStatusList = append(subTaskStatusList, openapiSubTaskStatus) + continue + } // find right task name var subTaskStatus *pb.SubTaskStatus for _, cfg := range workerStatus.SubTaskStatus { @@ -947,14 +957,9 @@ func getOpenAPISubtaskStatusByTaskName(taskName string, // not find continue } - openapiSubTaskStatus := openapi.SubTaskStatus{ - Name: taskName, - SourceName: sourceStatus.GetSource(), - WorkerName: sourceStatus.GetWorker(), - Stage: subTaskStatus.GetStage().String(), - Unit: subTaskStatus.GetUnit().String(), - UnresolvedDdlLockId: &subTaskStatus.UnresolvedDDLLockID, - } + openapiSubTaskStatus.Stage = subTaskStatus.GetStage().String() + openapiSubTaskStatus.Unit = subTaskStatus.GetUnit().String() + openapiSubTaskStatus.UnresolvedDdlLockId = &subTaskStatus.UnresolvedDDLLockID // add load status if loadS := subTaskStatus.GetLoad(); loadS != nil { openapiSubTaskStatus.LoadStatus = &openapi.LoadStatus{ diff --git a/dm/dm/master/openapi_test.go b/dm/dm/master/openapi_test.go index 3be3e748246..9638136fa99 100644 --- a/dm/dm/master/openapi_test.go +++ b/dm/dm/master/openapi_test.go @@ -536,7 +536,7 @@ func (t *openAPISuite) TestTaskAPI(c *check.C) { // get task status mockWorkerClient := pbmock.NewMockWorkerClient(ctrl) - mockTaskQueryStatus(mockWorkerClient, task.Name, source1.SourceName, workerName1) + mockTaskQueryStatus(mockWorkerClient, task.Name, source1.SourceName, workerName1, false) s.scheduler.SetWorkerClientForTest(workerName1, newMockRPCClient(mockWorkerClient)) taskStatusURL := fmt.Sprintf("%s/%s/status", taskURL, task.Name) result = testutil.NewRequest().Get(taskStatusURL).GoWithHTTPHandler(t.testT, s.openapiHandles) @@ -576,6 +576,21 @@ func (t *openAPISuite) TestTaskAPI(c *check.C) { c.Assert(status.WorkerName, check.Equals, workerName1) c.Assert(status.Name, check.Equals, task.Name) + // test some error happened on worker + mockWorkerClient = pbmock.NewMockWorkerClient(ctrl) + mockTaskQueryStatus(mockWorkerClient, task.Name, source1.SourceName, workerName1, true) + s.scheduler.SetWorkerClientForTest(workerName1, newMockRPCClient(mockWorkerClient)) + result = testutil.NewRequest().Get(taskURL+"?with_status=true").GoWithHTTPHandler(t.testT, s.openapiHandles) + c.Assert(result.Code(), check.Equals, http.StatusOK) + c.Assert(result.UnmarshalBodyToObject(&resultListTask), check.IsNil) + c.Assert(resultListTask.Data, check.HasLen, 1) + c.Assert(resultListTask.Total, check.Equals, 1) + c.Assert(resultListTask.Data[0].StatusList, check.NotNil) + statusList = *resultListTask.Data[0].StatusList + c.Assert(statusList, check.HasLen, 1) + status = statusList[0] + c.Assert(status.ErrorMsg, check.NotNil) + // stop task result = testutil.NewRequest().Delete(fmt.Sprintf("%s/%s", taskURL, task.Name)).GoWithHTTPHandler(t.testT, s.openapiHandles) c.Assert(result.Code(), check.Equals, http.StatusNoContent) @@ -840,49 +855,62 @@ func mockRelayQueryStatus( } func mockTaskQueryStatus( - mockWorkerClient *pbmock.MockWorkerClient, taskName, sourceName, workerName string) { - queryResp := &pb.QueryStatusResponse{ - Result: true, - SourceStatus: &pb.SourceStatus{ - Worker: workerName, - Source: sourceName, - }, - SubTaskStatus: []*pb.SubTaskStatus{ - { - Stage: pb.Stage_Running, - Name: taskName, - Status: &pb.SubTaskStatus_Sync{ - Sync: &pb.SyncStatus{ - TotalEvents: 0, - TotalTps: 0, - RecentTps: 0, - MasterBinlog: "", - MasterBinlogGtid: "", - SyncerBinlog: "", - SyncerBinlogGtid: "", - BlockingDDLs: nil, - UnresolvedGroups: nil, - Synced: false, - BinlogType: "", - SecondsBehindMaster: 0, + mockWorkerClient *pbmock.MockWorkerClient, taskName, sourceName, workerName string, needError bool) { + var queryResp *pb.QueryStatusResponse + if needError { + queryResp = &pb.QueryStatusResponse{ + Result: false, + Msg: "some error happened", + SourceStatus: &pb.SourceStatus{ + Worker: workerName, + Source: sourceName, + }, + } + } else { + queryResp = &pb.QueryStatusResponse{ + Result: true, + SourceStatus: &pb.SourceStatus{ + Worker: workerName, + Source: sourceName, + }, + SubTaskStatus: []*pb.SubTaskStatus{ + { + Stage: pb.Stage_Running, + Name: taskName, + Status: &pb.SubTaskStatus_Sync{ + Sync: &pb.SyncStatus{ + TotalEvents: 0, + TotalTps: 0, + RecentTps: 0, + MasterBinlog: "", + MasterBinlogGtid: "", + SyncerBinlog: "", + SyncerBinlogGtid: "", + BlockingDDLs: nil, + UnresolvedGroups: nil, + Synced: false, + BinlogType: "", + SecondsBehindMaster: 0, + }, }, }, - }, - { - Stage: pb.Stage_Running, - Name: taskName, - Status: &pb.SubTaskStatus_Dump{ - Dump: &pb.DumpStatus{ - CompletedTables: 0.0, - EstimateTotalRows: 10.0, - FinishedBytes: 0.0, - FinishedRows: 5.0, - TotalTables: 1, + { + Stage: pb.Stage_Running, + Name: taskName, + Status: &pb.SubTaskStatus_Dump{ + Dump: &pb.DumpStatus{ + CompletedTables: 0.0, + EstimateTotalRows: 10.0, + FinishedBytes: 0.0, + FinishedRows: 5.0, + TotalTables: 1, + }, }, }, }, - }, + } } + mockWorkerClient.EXPECT().QueryStatus( gomock.Any(), gomock.Any(), diff --git a/dm/openapi/gen.server.go b/dm/openapi/gen.server.go index 2ec86b20155..aa4dcc064d5 100644 --- a/dm/openapi/gen.server.go +++ b/dm/openapi/gen.server.go @@ -983,92 +983,92 @@ func RegisterHandlersWithOptions(router *gin.Engine, si ServerInterface, options // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", - "1pEAAA==", + "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", + "cJ+7WyeSAAA=", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/dm/openapi/gen.types.go b/dm/openapi/gen.types.go index ca478469ac9..8596087165d 100644 --- a/dm/openapi/gen.types.go +++ b/dm/openapi/gen.types.go @@ -312,6 +312,9 @@ type SubTaskStatus struct { // status of dump unit DumpStatus *DumpStatus `json:"dump_status,omitempty"` + // error message when something wrong + ErrorMsg *string `json:"error_msg,omitempty"` + // status of load unit LoadStatus *LoadStatus `json:"load_status,omitempty"` diff --git a/dm/openapi/spec/dm.yaml b/dm/openapi/spec/dm.yaml index 7db4ce256f2..e1b2187cb44 100644 --- a/dm/openapi/spec/dm.yaml +++ b/dm/openapi/spec/dm.yaml @@ -1301,6 +1301,9 @@ components: dump_status: nullable: true $ref: "#/components/schemas/DumpStatus" + error_msg: + type: string + description: "error message when something wrong" required: - "name" - "source_name" diff --git a/dm/tests/openapi/client/openapi_task_check b/dm/tests/openapi/client/openapi_task_check index 77e70d41264..8b7ab8c4262 100755 --- a/dm/tests/openapi/client/openapi_task_check +++ b/dm/tests/openapi/client/openapi_task_check @@ -184,6 +184,18 @@ def get_task_status_success(task_name, total): assert data["total"] == int(total) +def get_task_status_success_but_worker_meet_error(task_name, total): + url = API_ENDPOINT + "/" + task_name + "/status" + resp = requests.get(url=url) + data = resp.json() + assert resp.status_code == 200 + print("get_task_status_success_but_worker_meet_error resp=", data) + assert data["total"] == int(total) + for status in data["data"]: + assert status["name"] == task_name + assert status["error_msg"] is not None + + def get_task_list(task_count): url = API_ENDPOINT resp = requests.get(url=url) @@ -457,6 +469,7 @@ if __name__ == "__main__": "get_task_status_failed": get_task_status_failed, "get_illegal_char_task_status_failed": get_illegal_char_task_status_failed, "get_task_status_success": get_task_status_success, + "get_task_status_success_but_worker_meet_error": get_task_status_success_but_worker_meet_error, "operate_schema_and_table_success": operate_schema_and_table_success, "create_task_template_success": create_task_template_success, "create_task_template_failed": create_task_template_failed, diff --git a/dm/tests/openapi/run.sh b/dm/tests/openapi/run.sh index b2103cfe4a7..0286527b3bc 100644 --- a/dm/tests/openapi/run.sh +++ b/dm/tests/openapi/run.sh @@ -385,32 +385,33 @@ function test_task_templates() { function test_noshard_task_dump_status() { echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>START TEST OPENAPI: NO SHARD TASK DUMP STATUS" + + export GO_FAILPOINTS="github.com/pingcap/tiflow/dm/dumpling/dumpUnitProcessForever=return()" + kill_dm_worker + check_port_offline $WORKER1_PORT 20 + check_port_offline $WORKER2_PORT 20 + + # run dm-worker1 + run_dm_worker $WORK_DIR/worker1 $WORKER1_PORT $cur/conf/dm-worker1.toml + check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER1_PORT + # run dm-worker2 + run_dm_worker $WORK_DIR/worker2 $WORKER2_PORT $cur/conf/dm-worker2.toml + check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER2_PORT + prepare_database - task_name="test-no-shard" + task_name="test-no-shard-dump-status" target_table_name="" # empty means no route - # create source succesfully openapi_source_check "create_source1_success" openapi_source_check "list_source_success" 1 - - # get source status success openapi_source_check "get_source_status_success" "mysql-01" - - # create source succesfully openapi_source_check "create_source2_success" - # get source list success openapi_source_check "list_source_success" 2 - - # get source status success openapi_source_check "get_source_status_success" "mysql-02" - - # start task success: not vaild task create request openapi_task_check "start_task_failed" - # start no shard task success openapi_task_check "start_noshard_task_success" $task_name $target_table_name - run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ "query-status $task_name" \ "\"unit\": \"Dump\"" 2 @@ -418,8 +419,24 @@ function test_noshard_task_dump_status() { # check noshard task dump status success openapi_task_check "check_noshard_task_dump_status_success" "$task_name" 0 - # delete source success and clean data for other test + kill_dm_worker + check_port_offline $WORKER1_PORT 20 + check_port_offline $WORKER2_PORT 20 + + openapi_task_check "get_task_status_success_but_worker_meet_error" "$task_name" 2 clean_cluster_sources_and_tasks + + export GO_FAILPOINTS="" + kill_dm_worker + check_port_offline $WORKER1_PORT 20 + check_port_offline $WORKER2_PORT 20 + + # run dm-worker1 + run_dm_worker $WORK_DIR/worker1 $WORKER1_PORT $cur/conf/dm-worker1.toml + check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER1_PORT + # run dm-worker2 + run_dm_worker $WORK_DIR/worker2 $WORKER2_PORT $cur/conf/dm-worker2.toml + check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER2_PORT echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>TEST OPENAPI: NO SHARD TASK DUMP STATUS SUCCESS" } @@ -457,40 +474,14 @@ function run() { run_dm_worker $WORK_DIR/worker2 $WORKER2_PORT $cur/conf/dm-worker2.toml check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER2_PORT - test_source test_relay + test_source test_shard_task test_multi_tasks - - export GO_FAILPOINTS="github.com/pingcap/tiflow/dm/dumpling/dumpUnitProcessForever=return()" - kill_dm_worker - check_port_offline $WORKER1_PORT 20 - check_port_offline $WORKER2_PORT 20 - - # run dm-worker1 - run_dm_worker $WORK_DIR/worker1 $WORKER1_PORT $cur/conf/dm-worker1.toml - check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER1_PORT - # run dm-worker2 - run_dm_worker $WORK_DIR/worker2 $WORKER2_PORT $cur/conf/dm-worker2.toml - check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER2_PORT - - test_noshard_task_dump_status - - export GO_FAILPOINTS="" - kill_dm_worker - check_port_offline $WORKER1_PORT 20 - check_port_offline $WORKER2_PORT 20 - - # run dm-worker1 - run_dm_worker $WORK_DIR/worker1 $WORKER1_PORT $cur/conf/dm-worker1.toml - check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER1_PORT - # run dm-worker2 - run_dm_worker $WORK_DIR/worker2 $WORKER2_PORT $cur/conf/dm-worker2.toml - check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER2_PORT - test_noshard_task test_task_templates + test_noshard_task_dump_status # NOTE: this test case MUST running at last, because it will offline some members of cluster test_cluster