diff --git a/dm/dm/config/task_converters.go b/dm/dm/config/task_converters.go index 32fa16f8070..7d0eb289be7 100644 --- a/dm/dm/config/task_converters.go +++ b/dm/dm/config/task_converters.go @@ -112,7 +112,7 @@ func TaskConfigToSubTaskConfigs(c *TaskConfig, sources map[string]DBConfig) ([]* // OpenAPITaskToSubTaskConfigs generates sub task configs by openapi.Task. func OpenAPITaskToSubTaskConfigs(task *openapi.Task, toDBCfg *DBConfig, sourceCfgMap map[string]*SourceConfig) ( - []SubTaskConfig, error) { + []*SubTaskConfig, error) { // source name -> migrate rule list tableMigrateRuleMap := make(map[string][]openapi.TaskTableMigrateRule) for _, rule := range task.TableMigrateRule { @@ -137,7 +137,7 @@ func OpenAPITaskToSubTaskConfigs(task *openapi.Task, toDBCfg *DBConfig, sourceCf } } // start to generate sub task configs - subTaskCfgList := make([]SubTaskConfig, len(task.SourceConfig.SourceConf)) + subTaskCfgList := make([]*SubTaskConfig, len(task.SourceConfig.SourceConf)) for i, sourceCfg := range task.SourceConfig.SourceConf { // precheck source config _, exist := sourceCfgMap[sourceCfg.SourceName] @@ -246,7 +246,7 @@ func OpenAPITaskToSubTaskConfigs(task *openapi.Task, toDBCfg *DBConfig, sourceCf if err := subTaskCfg.Adjust(true); err != nil { return nil, terror.Annotatef(err, "source name %s", sourceCfg.SourceName) } - subTaskCfgList[i] = *subTaskCfg + subTaskCfgList[i] = subTaskCfg } return subTaskCfgList, nil } diff --git a/dm/dm/config/task_converters_test.go b/dm/dm/config/task_converters_test.go index 1b6eac3527d..d8d402e0ff6 100644 --- a/dm/dm/config/task_converters_test.go +++ b/dm/dm/config/task_converters_test.go @@ -274,7 +274,7 @@ func testNoShardSubTaskConfigsToOpenAPITask(c *check.C) { // prepare sub task config subTaskConfigMap := make(map[string]map[string]SubTaskConfig) subTaskConfigMap[task.Name] = make(map[string]SubTaskConfig) - subTaskConfigMap[task.Name][source1Name] = subTaskConfigList[0] + subTaskConfigMap[task.Name][source1Name] = *subTaskConfigList[0] taskList := SubTaskConfigsToOpenAPITask(subTaskConfigMap) c.Assert(taskList, check.HasLen, 1) @@ -309,8 +309,8 @@ func testShardAndFilterSubTaskConfigsToOpenAPITask(c *check.C) { // prepare sub task config subTaskConfigMap := make(map[string]map[string]SubTaskConfig) subTaskConfigMap[task.Name] = make(map[string]SubTaskConfig) - subTaskConfigMap[task.Name][source1Name] = subTaskConfigList[0] - subTaskConfigMap[task.Name][source2Name] = subTaskConfigList[1] + subTaskConfigMap[task.Name][source1Name] = *subTaskConfigList[0] + subTaskConfigMap[task.Name][source2Name] = *subTaskConfigList[1] taskList := SubTaskConfigsToOpenAPITask(subTaskConfigMap) c.Assert(taskList, check.HasLen, 1) diff --git a/dm/dm/ctl/master/config.go b/dm/dm/ctl/master/config.go index 341cf3cca8f..122b9ea2c1c 100644 --- a/dm/dm/ctl/master/config.go +++ b/dm/dm/ctl/master/config.go @@ -52,11 +52,31 @@ func NewConfigCmd() *cobra.Command { newConfigWorkerCmd(), newExportCfgsCmd(), newImportCfgsCmd(), + newConfigTaskTemplateCmd(), ) cmd.PersistentFlags().StringP("path", "p", "", "specify the file path to export/import`") return cmd } +func newConfigTaskTemplateCmd() *cobra.Command { + cmd := &cobra.Command{ + Use: "task-template [task-name]", + Short: "show task template which is created by WebUI with task config format", + RunE: func(cmd *cobra.Command, args []string) error { + if len(args) == 0 || len(args) > 1 { + return cmd.Help() + } + name := args[0] + output, err := cmd.Flags().GetString("path") + if err != nil { + return err + } + return sendGetConfigRequest(pb.CfgType_TaskTemplateType, name, output) + }, + } + return cmd +} + func newConfigTaskCmd() *cobra.Command { cmd := &cobra.Command{ Use: "task [task-name]", diff --git a/dm/dm/master/openapi.go b/dm/dm/master/openapi.go index 9cb786dd881..41ce4e81165 100644 --- a/dm/dm/master/openapi.go +++ b/dm/dm/master/openapi.go @@ -441,11 +441,7 @@ func (s *Server) DMAPIStartTask(c *gin.Context) { return } // check subtask config - subTaskConfigPList := make([]*config.SubTaskConfig, len(subTaskConfigList)) - for i := range subTaskConfigList { - subTaskConfigPList[i] = &subTaskConfigList[i] - } - msg, err := checker.CheckSyncConfigFunc(newCtx, subTaskConfigPList, + msg, err := checker.CheckSyncConfigFunc(newCtx, subTaskConfigList, common.DefaultErrorCnt, common.DefaultWarnCnt) if err != nil { _ = c.Error(terror.WithClass(err, terror.ClassDMMaster)) @@ -456,13 +452,13 @@ func (s *Server) DMAPIStartTask(c *gin.Context) { log.L().Warn("openapi pre-check warning before start task", zap.String("warning", msg)) } // specify only start task on partial sources - var needStartSubTaskList []config.SubTaskConfig + var needStartSubTaskList []*config.SubTaskConfig if req.SourceNameList != nil { // source name -> sub task config subTaskCfgM := make(map[string]*config.SubTaskConfig, len(subTaskConfigList)) for idx := range subTaskConfigList { cfg := subTaskConfigList[idx] - subTaskCfgM[cfg.SourceID] = &cfg + subTaskCfgM[cfg.SourceID] = cfg } for _, sourceName := range *req.SourceNameList { subTaskCfg, ok := subTaskCfgM[sourceName] @@ -470,7 +466,7 @@ func (s *Server) DMAPIStartTask(c *gin.Context) { _ = c.Error(terror.ErrOpenAPITaskSourceNotFound.Generatef("source name %s", sourceName)) return } - needStartSubTaskList = append(needStartSubTaskList, *subTaskCfg) + needStartSubTaskList = append(needStartSubTaskList, subTaskCfg) } } else { needStartSubTaskList = subTaskConfigList @@ -495,7 +491,7 @@ func (s *Server) DMAPIStartTask(c *gin.Context) { return } } - err = s.scheduler.AddSubTasks(latched, needStartSubTaskList...) + err = s.scheduler.AddSubTasks(latched, subtaskCfgPointersToInstances(needStartSubTaskList...)...) if err != nil { _ = c.Error(err) return @@ -788,7 +784,7 @@ func (s *Server) DMAPIOperateTableStructure(c *gin.Context, taskName string, sou } } -// DMAPIImportTaskTemplate create task_config_template url is: (POST /api/v1/task/templates/import). +// DMAPIImportTaskTemplate create task_config_template url is: (POST /api/v1/tasks/templates/import). func (s *Server) DMAPIImportTaskTemplate(c *gin.Context) { var req openapi.TaskTemplateRequest if err := c.Bind(&req); err != nil { @@ -818,7 +814,7 @@ func (s *Server) DMAPIImportTaskTemplate(c *gin.Context) { c.IndentedJSON(http.StatusAccepted, resp) } -// DMAPICreateTaskTemplate create task_config_template url is: (POST /api/task/templates). +// DMAPICreateTaskTemplate create task_config_template url is: (POST /api/tasks/templates). func (s *Server) DMAPICreateTaskTemplate(c *gin.Context) { task := &openapi.Task{} if err := c.Bind(task); err != nil { @@ -843,7 +839,7 @@ func (s *Server) DMAPICreateTaskTemplate(c *gin.Context) { c.IndentedJSON(http.StatusCreated, task) } -// DMAPIGetTaskTemplateList get task_config_template list url is: (GET /api/v1/task/templates). +// DMAPIGetTaskTemplateList get task_config_template list url is: (GET /api/v1/tasks/templates). func (s *Server) DMAPIGetTaskTemplateList(c *gin.Context) { TaskConfigList, err := ha.GetAllOpenAPITaskTemplate(s.etcdClient) if err != nil { @@ -858,7 +854,7 @@ func (s *Server) DMAPIGetTaskTemplateList(c *gin.Context) { c.IndentedJSON(http.StatusOK, resp) } -// DMAPIDeleteTaskTemplate delete task_config_template url is: (DELETE /api/v1/task/templates/{task-name}). +// DMAPIDeleteTaskTemplate delete task_config_template url is: (DELETE /api/v1/tasks/templates/{task-name}). func (s *Server) DMAPIDeleteTaskTemplate(c *gin.Context, taskName string) { if err := ha.DeleteOpenAPITaskTemplate(s.etcdClient, taskName); err != nil { _ = c.Error(err) @@ -867,7 +863,7 @@ func (s *Server) DMAPIDeleteTaskTemplate(c *gin.Context, taskName string) { c.Status(http.StatusNoContent) } -// DMAPIGetTaskTemplate get task_config_template url is: (GET /api/v1/task/templates/{task-name}). +// DMAPIGetTaskTemplate get task_config_template url is: (GET /api/v1/tasks/templates/{task-name}). func (s *Server) DMAPIGetTaskTemplate(c *gin.Context, taskName string) { task, err := ha.GetOpenAPITaskTemplate(s.etcdClient, taskName) if err != nil { @@ -881,7 +877,7 @@ func (s *Server) DMAPIGetTaskTemplate(c *gin.Context, taskName string) { c.IndentedJSON(http.StatusOK, task) } -// DMAPUpdateTaskTemplate update task_config_template url is: (PUT /api/v1/task/templates/{task-name}). +// DMAPUpdateTaskTemplate update task_config_template url is: (PUT /api/v1/tasks/templates/{task-name}). func (s *Server) DMAPUpdateTaskTemplate(c *gin.Context, taskName string) { task := &openapi.Task{} if err := c.Bind(task); err != nil { diff --git a/dm/dm/master/openapi_test.go b/dm/dm/master/openapi_test.go index c4c0191a02c..a57f8b35521 100644 --- a/dm/dm/master/openapi_test.go +++ b/dm/dm/master/openapi_test.go @@ -497,7 +497,7 @@ func (t *openAPISuite) TestTaskAPI(c *check.C) { c.Assert(resultTaskList.Data[0].Name, check.Equals, task.Name) // test batch import task config - taskBatchImportURL := "/api/v1/task/templates/import" + taskBatchImportURL := "/api/v1/tasks/templates/import" req := openapi.TaskTemplateRequest{Overwrite: false} result = testutil.NewRequest().Post(taskBatchImportURL).WithJsonBody(req).GoWithHTTPHandler(t.testT, s.openapiHandles) c.Assert(result.Code(), check.Equals, http.StatusAccepted) @@ -707,7 +707,7 @@ func (t *openAPISuite) TestTaskTemplatesAPI(c *check.C) { c.Assert(result.Code(), check.Equals, http.StatusCreated) // create task config template - url := "/api/v1/task/templates" + url := "/api/v1/tasks/templates" task, err := fixtures.GenNoShardOpenAPITaskForTest() c.Assert(err, check.IsNil) diff --git a/dm/dm/master/server.go b/dm/dm/master/server.go index 4a039f8b874..b9de171296b 100644 --- a/dm/dm/master/server.go +++ b/dm/dm/master/server.go @@ -51,6 +51,7 @@ import ( "github.com/pingcap/tiflow/dm/pkg/cputil" "github.com/pingcap/tiflow/dm/pkg/election" "github.com/pingcap/tiflow/dm/pkg/etcdutil" + "github.com/pingcap/tiflow/dm/pkg/ha" "github.com/pingcap/tiflow/dm/pkg/log" "github.com/pingcap/tiflow/dm/pkg/terror" "github.com/pingcap/tiflow/dm/pkg/utils" @@ -2158,29 +2159,68 @@ func (s *Server) GetCfg(ctx context.Context, req *pb.GetCfgRequest) (*pb.GetCfgR if shouldRet { return resp2, err2 } - // For the get-config command, you want to filter out fields that are not easily readable by humans, - // such as SSLXXBytes field in `Security` struct + + formartAndSortTaskString := func(subCfgList []*config.SubTaskConfig) string { + sort.Slice(subCfgList, func(i, j int) bool { + return subCfgList[i].SourceID < subCfgList[j].SourceID + }) + // For the get-config command, we want to filter out fields that are not easily readable by humans, + // such as SSLXXBytes field in `Security` struct + taskCfg := config.SubTaskConfigsToTaskConfig(subCfgList...) + taskCfg.TargetDB.Password = "******" + if taskCfg.TargetDB.Security != nil { + taskCfg.TargetDB.Security.ClearSSLBytesData() + } + return taskCfg.String() + } switch req.Type { + case pb.CfgType_TaskTemplateType: + task, err := ha.GetOpenAPITaskTemplate(s.etcdClient, req.Name) + if err != nil { + resp2.Msg = err.Error() + // nolint:nilerr + return resp2, nil + } + if task == nil { + resp2.Msg = "task not found" + // nolint:nilerr + return resp2, nil + } + toDBCfg := config.GetTargetDBCfgFromOpenAPITask(task) + if adjustDBErr := adjustTargetDB(ctx, toDBCfg); adjustDBErr != nil { + if adjustDBErr != nil { + resp2.Msg = adjustDBErr.Error() + // nolint:nilerr + return resp2, nil + } + } + sourceCfgMap := make(map[string]*config.SourceConfig) + for _, cfg := range task.SourceConfig.SourceConf { + if sourceCfg := s.scheduler.GetSourceCfgByID(cfg.SourceName); sourceCfg != nil { + sourceCfgMap[cfg.SourceName] = sourceCfg + } else { + resp2.Msg = fmt.Sprintf("the source: %s of task not found", cfg.SourceName) + return resp2, nil + } + } + subTaskConfigList, err := config.OpenAPITaskToSubTaskConfigs(task, toDBCfg, sourceCfgMap) + if err != nil { + resp2.Msg = err.Error() + // nolint:nilerr + return resp2, nil + } + cfg = formartAndSortTaskString(subTaskConfigList) case pb.CfgType_TaskType: subCfgMap := s.scheduler.GetSubTaskCfgsByTask(req.Name) if len(subCfgMap) == 0 { resp2.Msg = "task not found" return resp2, nil } - subCfgList := make([]*config.SubTaskConfig, 0, len(subCfgMap)) + subTaskConfigList := make([]*config.SubTaskConfig, 0, len(subCfgMap)) for _, subCfg := range subCfgMap { - subCfgList = append(subCfgList, subCfg) - } - sort.Slice(subCfgList, func(i, j int) bool { - return subCfgList[i].SourceID < subCfgList[j].SourceID - }) - - taskCfg := config.SubTaskConfigsToTaskConfig(subCfgList...) - taskCfg.TargetDB.Password = "******" - if taskCfg.TargetDB.Security != nil { - taskCfg.TargetDB.Security.ClearSSLBytesData() + subTaskConfigList = append(subTaskConfigList, subCfg) } - cfg = taskCfg.String() + cfg = formartAndSortTaskString(subTaskConfigList) case pb.CfgType_MasterType: if req.Name == s.cfg.Name { cfg, err2 = s.cfg.Toml() diff --git a/dm/dm/master/server_test.go b/dm/dm/master/server_test.go index 75cd4b345ce..f6e7fe9f370 100644 --- a/dm/dm/master/server_test.go +++ b/dm/dm/master/server_test.go @@ -53,6 +53,7 @@ import ( "github.com/pingcap/tiflow/dm/dm/master/workerrpc" "github.com/pingcap/tiflow/dm/dm/pb" "github.com/pingcap/tiflow/dm/dm/pbmock" + "github.com/pingcap/tiflow/dm/openapi/fixtures" "github.com/pingcap/tiflow/dm/pkg/conn" "github.com/pingcap/tiflow/dm/pkg/cputil" "github.com/pingcap/tiflow/dm/pkg/etcdutil" @@ -2031,9 +2032,10 @@ func (t *testMaster) TestGetCfg(c *check.C) { c.Assert(resp1.Result, check.IsTrue) c.Assert(strings.Contains(resp1.Cfg, "name: test"), check.IsTrue) - // wrong task name + // not exist task name + taskName2 := "wrong" req2 := &pb.GetCfgRequest{ - Name: "haha", + Name: taskName2, Type: pb.CfgType_TaskType, } resp2, err := server.GetCfg(context.Background(), req2) @@ -2041,6 +2043,18 @@ func (t *testMaster) TestGetCfg(c *check.C) { c.Assert(resp2.Result, check.IsFalse) c.Assert(resp2.Msg, check.Equals, "task not found") + // generate a template named `wrong`, test get this task template + openapiTask, err := fixtures.GenNoShardOpenAPITaskForTest() + c.Assert(err, check.IsNil) + openapiTask.Name = taskName2 + c.Assert(ha.PutOpenAPITaskTemplate(t.etcdTestCli, openapiTask, true), check.IsNil) + c.Assert(failpoint.Enable("github.com/pingcap/tiflow/dm/dm/master/MockSkipAdjustTargetDB", `return(true)`), check.IsNil) + resp2, err = server.GetCfg(context.Background(), &pb.GetCfgRequest{Name: taskName2, Type: pb.CfgType_TaskTemplateType}) + c.Assert(failpoint.Disable("github.com/pingcap/tiflow/dm/dm/master/MockSkipAdjustTargetDB"), check.IsNil) + c.Assert(err, check.IsNil) + c.Assert(resp2.Result, check.IsTrue) + c.Assert(strings.Contains(resp2.Cfg, fmt.Sprintf("name: %s", taskName2)), check.IsTrue) + // test restart master server.scheduler.Close() c.Assert(server.scheduler.Start(ctx, t.etcdTestCli), check.IsNil) diff --git a/dm/dm/pb/dmmaster.pb.go b/dm/dm/pb/dmmaster.pb.go index 5a57d8ab04e..3ace56ccdef 100644 --- a/dm/dm/pb/dmmaster.pb.go +++ b/dm/dm/pb/dmmaster.pb.go @@ -92,11 +92,12 @@ func (LeaderOp) EnumDescriptor() ([]byte, []int) { type CfgType int32 const ( - CfgType_InvalidType CfgType = 0 - CfgType_TaskType CfgType = 1 - CfgType_MasterType CfgType = 2 - CfgType_WorkerType CfgType = 3 - CfgType_SourceType CfgType = 4 + CfgType_InvalidType CfgType = 0 + CfgType_TaskType CfgType = 1 + CfgType_MasterType CfgType = 2 + CfgType_WorkerType CfgType = 3 + CfgType_SourceType CfgType = 4 + CfgType_TaskTemplateType CfgType = 5 ) var CfgType_name = map[int32]string{ @@ -105,14 +106,16 @@ var CfgType_name = map[int32]string{ 2: "MasterType", 3: "WorkerType", 4: "SourceType", + 5: "TaskTemplateType", } var CfgType_value = map[string]int32{ - "InvalidType": 0, - "TaskType": 1, - "MasterType": 2, - "WorkerType": 3, - "SourceType": 4, + "InvalidType": 0, + "TaskType": 1, + "MasterType": 2, + "WorkerType": 3, + "SourceType": 4, + "TaskTemplateType": 5, } func (x CfgType) String() string { @@ -3187,136 +3190,137 @@ func init() { func init() { proto.RegisterFile("dmmaster.proto", fileDescriptor_f9bef11f2a341f03) } var fileDescriptor_f9bef11f2a341f03 = []byte{ - // 2064 bytes of a gzipped FileDescriptorProto + // 2074 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x59, 0x5f, 0x6f, 0xe3, 0xc6, - 0x11, 0x17, 0x25, 0x9f, 0x2c, 0x8f, 0x6c, 0x45, 0x5e, 0xcb, 0x32, 0x8f, 0xe7, 0xd3, 0x39, 0xdb, - 0x24, 0x30, 0x8c, 0xe2, 0x8c, 0x73, 0xfb, 0x14, 0x20, 0x05, 0x72, 0xd2, 0xe5, 0x62, 0xd4, 0x57, - 0xa7, 0xb4, 0x2f, 0x4d, 0x50, 0xa0, 0x08, 0x25, 0xad, 0x64, 0xc1, 0x14, 0xc9, 0x23, 0x29, 0xbb, - 0xc6, 0x21, 0x2f, 0xfd, 0x00, 0xfd, 0x83, 0x02, 0xcd, 0x63, 0x1f, 0xfa, 0x4d, 0xfa, 0xd4, 0xc7, - 0x00, 0x7d, 0xe9, 0x63, 0x71, 0xd7, 0x0f, 0x52, 0xec, 0xec, 0x2e, 0xb9, 0xa4, 0x28, 0xb7, 0x3a, - 0x20, 0x7e, 0xe3, 0xcc, 0xac, 0x66, 0x7e, 0xf3, 0x67, 0x67, 0x67, 0x57, 0xd0, 0x18, 0x4e, 0xa7, - 0x4e, 0x14, 0xb3, 0xf0, 0x71, 0x10, 0xfa, 0xb1, 0x4f, 0xca, 0x41, 0xdf, 0x6a, 0x0c, 0xa7, 0xd7, - 0x7e, 0x78, 0xa9, 0x78, 0xd6, 0xee, 0xd8, 0xf7, 0xc7, 0x2e, 0x3b, 0x74, 0x82, 0xc9, 0xa1, 0xe3, - 0x79, 0x7e, 0xec, 0xc4, 0x13, 0xdf, 0x8b, 0x84, 0x94, 0x7e, 0x03, 0xcd, 0xb3, 0xd8, 0x09, 0xe3, - 0x73, 0x27, 0xba, 0xb4, 0xd9, 0xab, 0x19, 0x8b, 0x62, 0x42, 0x60, 0x25, 0x76, 0xa2, 0x4b, 0xd3, - 0xd8, 0x33, 0xf6, 0xd7, 0x6c, 0xfc, 0x26, 0x26, 0xac, 0x46, 0xfe, 0x2c, 0x1c, 0xb0, 0xc8, 0x2c, - 0xef, 0x55, 0xf6, 0xd7, 0x6c, 0x45, 0x92, 0x0e, 0x40, 0xc8, 0xa6, 0xfe, 0x15, 0x7b, 0xc1, 0x62, - 0xc7, 0xac, 0xec, 0x19, 0xfb, 0x35, 0x5b, 0xe3, 0xd0, 0x57, 0xb0, 0xa9, 0x59, 0x88, 0x02, 0xdf, - 0x8b, 0x18, 0x69, 0x43, 0x35, 0x64, 0xd1, 0xcc, 0x8d, 0xd1, 0x48, 0xcd, 0x96, 0x14, 0x69, 0x42, - 0x65, 0x1a, 0x8d, 0xcd, 0x32, 0x5a, 0xe6, 0x9f, 0xe4, 0x28, 0x35, 0x5c, 0xd9, 0xab, 0xec, 0xd7, - 0x8f, 0xcc, 0xc7, 0x41, 0xff, 0x71, 0xd7, 0x9f, 0x4e, 0x7d, 0xef, 0x57, 0xe8, 0xa7, 0x52, 0x9a, - 0x40, 0xa2, 0xbf, 0x01, 0x72, 0x1a, 0xb0, 0xd0, 0x89, 0x99, 0xee, 0x96, 0x05, 0x65, 0x3f, 0x40, - 0x7b, 0x8d, 0x23, 0xe0, 0x4a, 0xb8, 0xf0, 0x34, 0xb0, 0xcb, 0x7e, 0xc0, 0x5d, 0xf6, 0x9c, 0x29, - 0x93, 0x86, 0xf1, 0x5b, 0x77, 0xb9, 0x92, 0x71, 0x99, 0xfe, 0xc1, 0x80, 0xad, 0x8c, 0x01, 0xe9, - 0xd5, 0x6d, 0x16, 0x52, 0x8f, 0xcb, 0x45, 0x1e, 0x57, 0x0a, 0x3d, 0x5e, 0xf9, 0x7f, 0x3d, 0xfe, - 0x14, 0x36, 0x5f, 0x06, 0xc3, 0x9c, 0xc3, 0x4b, 0xe5, 0x91, 0x86, 0x40, 0x74, 0x15, 0x77, 0x92, - 0xa8, 0xcf, 0xa0, 0xfd, 0xcb, 0x19, 0x0b, 0x6f, 0xce, 0x62, 0x27, 0x9e, 0x45, 0x27, 0x93, 0x28, - 0xd6, 0xb0, 0x63, 0x42, 0x8c, 0xe2, 0x84, 0xe4, 0xb0, 0x5f, 0xc1, 0xce, 0x9c, 0x9e, 0xa5, 0x1d, - 0x78, 0x92, 0x77, 0x60, 0x87, 0x3b, 0xa0, 0xe9, 0x9d, 0xc7, 0xdf, 0x85, 0xad, 0xb3, 0x0b, 0xff, - 0xba, 0xd7, 0x3b, 0x39, 0xf1, 0x07, 0x97, 0xd1, 0xbb, 0x05, 0xfe, 0xaf, 0x06, 0xac, 0x4a, 0x0d, - 0xa4, 0x01, 0xe5, 0xe3, 0x9e, 0xfc, 0x5d, 0xf9, 0xb8, 0x97, 0x68, 0x2a, 0x6b, 0x9a, 0x08, 0xac, - 0x4c, 0xfd, 0x21, 0x93, 0x25, 0x83, 0xdf, 0xa4, 0x05, 0xf7, 0xfc, 0x6b, 0x8f, 0x85, 0xe6, 0x0a, - 0x32, 0x05, 0xc1, 0x57, 0xf6, 0x7a, 0x27, 0x91, 0x79, 0x0f, 0x0d, 0xe2, 0x37, 0x8f, 0x47, 0x74, - 0xe3, 0x0d, 0xd8, 0xd0, 0xac, 0x22, 0x57, 0x52, 0xc4, 0x82, 0xda, 0xcc, 0x93, 0x92, 0x55, 0x94, - 0x24, 0x34, 0x1d, 0x40, 0x2b, 0xeb, 0xe6, 0xd2, 0xb1, 0x7d, 0x1f, 0xee, 0xb9, 0xfc, 0xa7, 0x32, - 0xb2, 0x75, 0x1e, 0x59, 0xa9, 0xce, 0x16, 0x12, 0xea, 0x42, 0xeb, 0xa5, 0xc7, 0x3f, 0x15, 0x5f, - 0x06, 0x33, 0x1f, 0x12, 0x0a, 0xeb, 0x21, 0x0b, 0x5c, 0x67, 0xc0, 0x4e, 0xd1, 0x63, 0x61, 0x25, - 0xc3, 0x23, 0x7b, 0x50, 0x1f, 0xf9, 0xe1, 0x80, 0xd9, 0xd8, 0x86, 0x64, 0x53, 0xd2, 0x59, 0xf4, - 0x53, 0xd8, 0xce, 0x59, 0x5b, 0xd6, 0x27, 0x6a, 0xc3, 0x7d, 0xd9, 0x04, 0x54, 0x79, 0xbb, 0xce, - 0x8d, 0x42, 0xfd, 0x40, 0x6b, 0x05, 0xe8, 0x2d, 0x4a, 0x65, 0x2f, 0x58, 0x5c, 0x0b, 0xdf, 0x19, - 0x60, 0x15, 0x29, 0x95, 0xe0, 0x6e, 0xd5, 0xfa, 0xc3, 0x76, 0x98, 0xef, 0x0c, 0xd8, 0xf9, 0x62, - 0x16, 0x8e, 0x8b, 0x9c, 0xd5, 0xfc, 0x31, 0xb2, 0x87, 0x83, 0x05, 0xb5, 0x89, 0xe7, 0x0c, 0xe2, - 0xc9, 0x15, 0x93, 0xa8, 0x12, 0x1a, 0x6b, 0x7b, 0x32, 0x15, 0xd9, 0xa9, 0xd8, 0xf8, 0xcd, 0xd7, - 0x8f, 0x26, 0x2e, 0xc3, 0xad, 0x2f, 0x4a, 0x39, 0xa1, 0xb1, 0x72, 0x67, 0xfd, 0xde, 0x24, 0x34, - 0xef, 0xa1, 0x44, 0x52, 0xf4, 0xb7, 0x60, 0xce, 0x03, 0xbb, 0x93, 0xf6, 0xf5, 0x15, 0x34, 0xbb, - 0x17, 0x6c, 0x70, 0xf9, 0xbf, 0x9a, 0x6e, 0x1b, 0xaa, 0x2c, 0x0c, 0xbb, 0x9e, 0xc8, 0x4c, 0xc5, - 0x96, 0x14, 0x8f, 0xdb, 0xb5, 0x13, 0x7a, 0x5c, 0x20, 0x82, 0xa0, 0x48, 0xfa, 0x09, 0x6c, 0x6a, - 0x9a, 0x97, 0x2e, 0xcd, 0x0b, 0x68, 0xc9, 0x2a, 0x3a, 0x43, 0xa8, 0x0a, 0xdc, 0xae, 0x56, 0x3f, - 0xeb, 0xdc, 0x3f, 0x21, 0x4e, 0x0b, 0x68, 0xe0, 0x7b, 0xa3, 0xc9, 0x58, 0x56, 0xa5, 0xa4, 0x78, - 0x52, 0x84, 0xc7, 0xc7, 0x3d, 0x79, 0x12, 0x26, 0x34, 0x9d, 0xc1, 0x76, 0xce, 0xd2, 0x9d, 0x44, - 0xfe, 0x19, 0x6c, 0xdb, 0x6c, 0x3c, 0xe1, 0xa3, 0x8f, 0x5a, 0x72, 0xeb, 0xb9, 0xe1, 0x0c, 0x87, - 0x21, 0x8b, 0x22, 0x69, 0x56, 0x91, 0xf4, 0x29, 0xb4, 0xf3, 0x6a, 0x96, 0x8e, 0xf5, 0xcf, 0xa0, - 0x75, 0x3a, 0x1a, 0xb9, 0x13, 0x8f, 0xbd, 0x60, 0xd3, 0x7e, 0x06, 0x49, 0x7c, 0x13, 0x24, 0x48, - 0xf8, 0x77, 0xd1, 0x98, 0xc1, 0x3b, 0x51, 0xee, 0xf7, 0x4b, 0x43, 0xf8, 0x69, 0x92, 0xee, 0x13, - 0xe6, 0x0c, 0x53, 0x08, 0x73, 0xe9, 0x16, 0x62, 0x91, 0x6e, 0x34, 0x9c, 0xfd, 0xd5, 0xd2, 0x86, - 0x7f, 0x6f, 0x00, 0xbc, 0xc0, 0x01, 0xf4, 0xd8, 0x1b, 0xf9, 0x85, 0xc1, 0xb7, 0xa0, 0x36, 0x45, - 0xbf, 0x8e, 0x7b, 0xf8, 0xcb, 0x15, 0x3b, 0xa1, 0xf9, 0xa9, 0xe5, 0xb8, 0x93, 0xa4, 0x41, 0x0b, - 0x82, 0xff, 0x22, 0x60, 0x2c, 0x7c, 0x69, 0x9f, 0x88, 0xf6, 0xb4, 0x66, 0x27, 0x34, 0x1f, 0x36, - 0x07, 0xee, 0x84, 0x79, 0x31, 0x4a, 0xc5, 0xb9, 0xa6, 0x71, 0x68, 0x1f, 0x40, 0x24, 0x72, 0x21, - 0x1e, 0x02, 0x2b, 0x3c, 0xfb, 0x2a, 0x05, 0xfc, 0x9b, 0xe3, 0x88, 0x62, 0x67, 0xac, 0x8e, 0x54, - 0x41, 0x60, 0xbf, 0xc1, 0x72, 0x93, 0x9d, 0x48, 0x52, 0xf4, 0x04, 0x9a, 0x7c, 0xc2, 0x10, 0x41, - 0x13, 0x39, 0x53, 0xa1, 0x31, 0xd2, 0xaa, 0x2e, 0x9a, 0x28, 0x95, 0xed, 0x4a, 0x6a, 0x9b, 0xfe, - 0x42, 0x68, 0x13, 0x51, 0x5c, 0xa8, 0x6d, 0x1f, 0x56, 0xc5, 0xa0, 0x2f, 0x4e, 0x8c, 0xfa, 0x51, - 0x83, 0xa7, 0x33, 0x0d, 0xbd, 0xad, 0xc4, 0x4a, 0x9f, 0x88, 0xc2, 0x6d, 0xfa, 0xc4, 0x25, 0x21, - 0xa3, 0x2f, 0x0d, 0x9d, 0xad, 0xc4, 0xf4, 0x6f, 0x06, 0xac, 0x0a, 0x35, 0x11, 0x79, 0x0c, 0x55, - 0x17, 0xbd, 0x46, 0x55, 0xf5, 0xa3, 0x16, 0xd6, 0x54, 0x2e, 0x16, 0x9f, 0x97, 0x6c, 0xb9, 0x8a, - 0xaf, 0x17, 0xb0, 0x30, 0x0a, 0xda, 0x7a, 0xdd, 0x5b, 0xbe, 0x5e, 0xac, 0xe2, 0xeb, 0x85, 0x59, - 0x8c, 0x90, 0xb6, 0x5e, 0xf7, 0x86, 0xaf, 0x17, 0xab, 0x9e, 0xd6, 0xa0, 0x2a, 0x6a, 0x89, 0x5f, - 0x32, 0x50, 0x6f, 0x66, 0x07, 0xb6, 0x33, 0x70, 0x6b, 0x09, 0xac, 0x76, 0x06, 0x56, 0x2d, 0x31, - 0xdf, 0xce, 0x98, 0xaf, 0x29, 0x33, 0xbc, 0x3c, 0x78, 0xfa, 0x54, 0x35, 0x0a, 0x82, 0x32, 0x20, - 0xba, 0xc9, 0xa5, 0xdb, 0xde, 0x87, 0xb0, 0x2a, 0xc0, 0x67, 0x86, 0x22, 0x19, 0x6a, 0x5b, 0xc9, - 0xe8, 0x5f, 0xca, 0x69, 0x2f, 0x1f, 0x5c, 0xb0, 0xa9, 0xb3, 0xb8, 0x97, 0xa3, 0x38, 0xbd, 0xd0, - 0xcc, 0x0d, 0x8e, 0x0b, 0x2f, 0x34, 0x7c, 0xcb, 0x0d, 0x9d, 0xd8, 0xe9, 0x3b, 0x51, 0x72, 0xec, - 0x2a, 0x9a, 0x7b, 0x1f, 0x3b, 0x7d, 0x97, 0xc9, 0x53, 0x57, 0x10, 0xb8, 0x39, 0xd0, 0x9e, 0x59, - 0x95, 0x9b, 0x03, 0x29, 0xbe, 0x7a, 0xe4, 0xce, 0xa2, 0x0b, 0x73, 0x55, 0x6c, 0x69, 0x24, 0x38, - 0x1a, 0x3e, 0x4a, 0x9a, 0x35, 0x64, 0xe2, 0x37, 0xdf, 0xca, 0xa3, 0xd0, 0x9f, 0x8a, 0x63, 0xc3, - 0x5c, 0x13, 0xf7, 0xc6, 0x94, 0xa3, 0xe4, 0xe7, 0x4e, 0x38, 0x66, 0xb1, 0x09, 0xa9, 0x5c, 0x70, - 0xf4, 0x93, 0x47, 0xc6, 0xe5, 0x4e, 0x4e, 0x9e, 0x03, 0x68, 0x3d, 0x67, 0xf1, 0xd9, 0xac, 0xcf, - 0x8f, 0xe6, 0xee, 0x68, 0x7c, 0xcb, 0xc1, 0x43, 0x5f, 0xc2, 0x76, 0x6e, 0xed, 0xd2, 0x10, 0x09, - 0xac, 0x0c, 0x46, 0x63, 0x95, 0x30, 0xfc, 0xa6, 0x3d, 0xd8, 0x78, 0xce, 0x62, 0xcd, 0xf6, 0x23, - 0xed, 0xa8, 0x91, 0x83, 0x61, 0x77, 0x34, 0x3e, 0xbf, 0x09, 0xd8, 0x2d, 0xe7, 0xce, 0x09, 0x34, - 0x94, 0x96, 0xa5, 0x51, 0x35, 0xa1, 0x32, 0x18, 0x25, 0x23, 0xe5, 0x60, 0x34, 0xa6, 0xdb, 0xb0, - 0xf5, 0x9c, 0xc9, 0x7d, 0x9d, 0x22, 0xa3, 0xfb, 0x18, 0x2d, 0x8d, 0x2d, 0x4d, 0x49, 0x05, 0x46, - 0xaa, 0xe0, 0x4f, 0x06, 0x90, 0xcf, 0x1d, 0x6f, 0xe8, 0xb2, 0x67, 0x61, 0xe8, 0x87, 0x0b, 0xe7, - 0x68, 0x94, 0xbe, 0x53, 0x91, 0xef, 0xc2, 0x5a, 0x7f, 0xe2, 0xb9, 0xfe, 0xf8, 0x0b, 0x3f, 0x92, - 0x55, 0x9e, 0x32, 0xb0, 0x44, 0x5f, 0xb9, 0xc9, 0x5d, 0x89, 0x7f, 0xd3, 0x08, 0xb6, 0x32, 0x90, - 0xee, 0xa4, 0xc0, 0x9e, 0xc3, 0xf6, 0x79, 0xe8, 0x78, 0xd1, 0x88, 0x85, 0xd9, 0xe1, 0x2d, 0x3d, - 0x8f, 0x0c, 0xfd, 0x3c, 0xd2, 0xda, 0x96, 0xb0, 0x2c, 0x29, 0x3e, 0xdc, 0xe4, 0x15, 0x2d, 0x7d, - 0xc0, 0x0f, 0x93, 0x87, 0x8e, 0xcc, 0xc0, 0xff, 0x50, 0xcb, 0xca, 0x86, 0x76, 0x0f, 0xf9, 0xf2, - 0x48, 0x0d, 0x92, 0x12, 0x69, 0x79, 0x01, 0x52, 0x91, 0x1a, 0x85, 0x34, 0x4e, 0x5a, 0xdc, 0x1d, - 0x4e, 0xef, 0x07, 0x7d, 0xa8, 0xa9, 0xf1, 0x97, 0x6c, 0xc1, 0x7b, 0xc7, 0xde, 0x95, 0xe3, 0x4e, - 0x86, 0x8a, 0xd5, 0x2c, 0x91, 0xf7, 0xa0, 0x8e, 0x2f, 0x57, 0x82, 0xd5, 0x34, 0x48, 0x13, 0xd6, - 0xc5, 0x13, 0x89, 0xe4, 0x94, 0x49, 0x03, 0xe0, 0x2c, 0xf6, 0x03, 0x49, 0x57, 0x90, 0xbe, 0xf0, - 0xaf, 0x25, 0xbd, 0x72, 0xf0, 0x73, 0xa8, 0xa9, 0x99, 0x4b, 0xb3, 0xa1, 0x58, 0xcd, 0x12, 0xd9, - 0x84, 0x8d, 0x67, 0x57, 0x93, 0x41, 0x9c, 0xb0, 0x0c, 0xb2, 0x03, 0x5b, 0x5d, 0xc7, 0x1b, 0x30, - 0x37, 0x2b, 0x28, 0x1f, 0x7c, 0x05, 0xab, 0x72, 0x5b, 0x73, 0x68, 0x52, 0x17, 0x27, 0x9b, 0x25, - 0xb2, 0x0e, 0x35, 0xde, 0x64, 0x90, 0x32, 0x38, 0x0c, 0xb1, 0xe7, 0x90, 0x46, 0x98, 0x22, 0x0a, - 0x48, 0x0b, 0x98, 0x08, 0x11, 0xe9, 0x95, 0x83, 0x1e, 0xac, 0x25, 0x19, 0x24, 0x2d, 0x68, 0x4a, - 0xdd, 0x09, 0xaf, 0x59, 0xe2, 0xbe, 0x63, 0x30, 0x90, 0xf7, 0xe5, 0x51, 0xd3, 0x10, 0xe1, 0xf1, - 0x03, 0xc5, 0x28, 0x1f, 0xfd, 0xbd, 0x01, 0x55, 0x61, 0x96, 0x7c, 0x0d, 0x6b, 0xc9, 0xa3, 0x1f, - 0xc1, 0x63, 0x3c, 0xff, 0xca, 0x68, 0x6d, 0xe7, 0xb8, 0x22, 0x3d, 0xf4, 0xd1, 0xef, 0xfe, 0xf9, - 0x9f, 0x3f, 0x97, 0xef, 0xd3, 0xd6, 0xa1, 0x13, 0x4c, 0xa2, 0xc3, 0xab, 0x27, 0x8e, 0x1b, 0x5c, - 0x38, 0x4f, 0x0e, 0xf9, 0xe6, 0x8e, 0x3e, 0x36, 0x0e, 0xc8, 0x08, 0xea, 0xda, 0xdb, 0x1b, 0x69, - 0x73, 0x35, 0xf3, 0xaf, 0x7d, 0xd6, 0xce, 0x1c, 0x5f, 0x1a, 0xf8, 0x08, 0x0d, 0xec, 0x59, 0x0f, - 0x8a, 0x0c, 0x1c, 0xbe, 0xe6, 0xbd, 0xf1, 0x5b, 0x6e, 0xe7, 0x13, 0x80, 0xf4, 0x3d, 0x8c, 0x20, - 0xda, 0xb9, 0x27, 0x36, 0xab, 0x9d, 0x67, 0x4b, 0x23, 0x25, 0xe2, 0x42, 0x5d, 0x7b, 0x3a, 0x22, - 0x56, 0xee, 0x2d, 0x49, 0x7b, 0xeb, 0xb2, 0x1e, 0x14, 0xca, 0xa4, 0xa6, 0x0f, 0x10, 0x6e, 0x87, - 0xec, 0xe6, 0xe0, 0x46, 0xb8, 0x54, 0xe2, 0x25, 0x5d, 0x58, 0xd7, 0x5f, 0x68, 0x08, 0x7a, 0x5f, - 0xf0, 0x34, 0x65, 0x99, 0xf3, 0x82, 0x04, 0xf2, 0x67, 0xb0, 0x91, 0x79, 0x13, 0x21, 0xb8, 0xb8, - 0xe8, 0x51, 0xc6, 0xba, 0x5f, 0x20, 0x49, 0xf4, 0x7c, 0x0d, 0xed, 0xf9, 0x37, 0x0c, 0x8c, 0xe2, - 0x43, 0x2d, 0x29, 0xf3, 0xef, 0x08, 0x56, 0x67, 0x91, 0x38, 0x51, 0x7d, 0x0a, 0xcd, 0xfc, 0x5d, - 0x9f, 0x60, 0xf8, 0x16, 0x3c, 0x4d, 0x58, 0xbb, 0xc5, 0xc2, 0x44, 0xe1, 0xc7, 0xb0, 0x96, 0x5c, - 0xb4, 0x45, 0xa1, 0xe6, 0x6f, 0xf4, 0xa2, 0x50, 0xe7, 0x6e, 0xe3, 0xb4, 0x44, 0xc6, 0xb0, 0x91, - 0xb9, 0xfb, 0x8a, 0x78, 0x15, 0x5d, 0xbc, 0x45, 0xbc, 0x0a, 0x2f, 0xca, 0xf4, 0x7d, 0x4c, 0xf0, - 0x03, 0xab, 0x9d, 0x4f, 0xb0, 0x68, 0x53, 0xbc, 0x14, 0x8f, 0xa1, 0x91, 0xbd, 0xa6, 0x92, 0xfb, - 0xa2, 0xe9, 0x16, 0xdc, 0x80, 0x2d, 0xab, 0x48, 0x94, 0x60, 0x0e, 0x61, 0x23, 0x73, 0xdb, 0x94, - 0x98, 0x0b, 0x2e, 0xb0, 0x12, 0x73, 0xd1, 0xd5, 0x94, 0xfe, 0x18, 0x31, 0x7f, 0x74, 0xf0, 0x41, - 0x0e, 0xb3, 0x1c, 0x5a, 0x0f, 0x5f, 0xf3, 0xa9, 0xe3, 0x5b, 0x55, 0x9c, 0x97, 0x49, 0x9c, 0x44, - 0x33, 0xcb, 0xc4, 0x29, 0x73, 0x63, 0xcd, 0xc4, 0x29, 0x7b, 0x2b, 0xa5, 0x1f, 0xa2, 0xcd, 0x47, - 0x96, 0x95, 0xb3, 0x29, 0x86, 0xfa, 0xc3, 0xd7, 0x7e, 0x80, 0xdb, 0xf6, 0xd7, 0x00, 0xe9, 0x58, - 0x2e, 0xb6, 0xed, 0xdc, 0xcd, 0x40, 0x6c, 0xdb, 0xf9, 0xe9, 0x9d, 0x76, 0xd0, 0x86, 0x49, 0xda, - 0xc5, 0x7e, 0x91, 0x51, 0x9a, 0x71, 0x31, 0xee, 0x66, 0x32, 0xae, 0x8f, 0xe7, 0xd9, 0x8c, 0x67, - 0x06, 0x54, 0xba, 0x87, 0x56, 0x2c, 0x6b, 0x3b, 0x9f, 0x71, 0x5c, 0xc6, 0x9d, 0x70, 0x71, 0xc2, - 0x4b, 0x07, 0x47, 0x61, 0xa7, 0x68, 0xee, 0x14, 0x76, 0x0a, 0xa7, 0x4c, 0xd5, 0xe9, 0x48, 0x27, - 0x6f, 0x67, 0xd6, 0xd7, 0x9b, 0x1d, 0x39, 0x87, 0xaa, 0x98, 0x04, 0xc9, 0xa6, 0x54, 0xa6, 0xe9, - 0x27, 0x3a, 0x4b, 0x2a, 0xfe, 0x11, 0x2a, 0x7e, 0x48, 0x6e, 0x6b, 0xa1, 0xe4, 0x1b, 0xa8, 0x6b, - 0xc3, 0x93, 0xe8, 0xd3, 0xf3, 0x03, 0x9e, 0xe8, 0xd3, 0x05, 0x53, 0xd6, 0xc2, 0x28, 0x31, 0xbe, - 0x0a, 0xb7, 0x45, 0x17, 0xd6, 0xf5, 0xe1, 0x52, 0x34, 0xbd, 0x82, 0x29, 0xd4, 0x32, 0xe7, 0x05, - 0xc9, 0x86, 0x38, 0x86, 0x46, 0x76, 0x4a, 0x12, 0x7b, 0xab, 0x70, 0x04, 0x13, 0x7b, 0xab, 0x78, - 0xa8, 0xa2, 0x25, 0x8e, 0x47, 0x1f, 0x63, 0x88, 0x7e, 0x04, 0x65, 0x9a, 0x92, 0x39, 0x2f, 0x50, - 0x4a, 0x9e, 0x9a, 0xff, 0x78, 0xd3, 0x31, 0xbe, 0x7f, 0xd3, 0x31, 0xfe, 0xfd, 0xa6, 0x63, 0xfc, - 0xf1, 0x6d, 0xa7, 0xf4, 0xfd, 0xdb, 0x4e, 0xe9, 0x5f, 0x6f, 0x3b, 0xa5, 0x7e, 0x15, 0xff, 0xb1, - 0xfb, 0xc9, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xc4, 0xaa, 0x26, 0x5e, 0xf5, 0x1b, 0x00, 0x00, + 0x11, 0x17, 0x25, 0x5b, 0x96, 0x47, 0xb6, 0x22, 0xaf, 0x65, 0x99, 0xc7, 0xf3, 0xe9, 0x1c, 0x36, + 0x09, 0x0c, 0xa3, 0x38, 0xe3, 0xdc, 0x3e, 0x05, 0x48, 0x81, 0x9c, 0x74, 0xb9, 0x18, 0xf5, 0xd5, + 0x29, 0xed, 0x4b, 0x1b, 0x14, 0x28, 0x42, 0x49, 0x2b, 0x59, 0x30, 0x45, 0xf2, 0x48, 0xca, 0xae, + 0x71, 0xc8, 0x4b, 0x3f, 0x40, 0xff, 0xa0, 0x40, 0xf3, 0xd8, 0x87, 0x7e, 0x93, 0x3e, 0xf5, 0x31, + 0x40, 0x5f, 0xfa, 0x58, 0xdc, 0xf5, 0x83, 0x14, 0x3b, 0xb3, 0x24, 0x97, 0x14, 0xe5, 0x56, 0x01, + 0xea, 0x37, 0xce, 0xcc, 0x6a, 0xe6, 0x37, 0x7f, 0x76, 0x76, 0x76, 0x05, 0x8d, 0xe1, 0x74, 0x6a, + 0x87, 0x11, 0x0f, 0x9e, 0xf8, 0x81, 0x17, 0x79, 0xac, 0xec, 0xf7, 0x8d, 0xc6, 0x70, 0x7a, 0xe3, + 0x05, 0x57, 0x31, 0xcf, 0xd8, 0x1b, 0x7b, 0xde, 0xd8, 0xe1, 0x47, 0xb6, 0x3f, 0x39, 0xb2, 0x5d, + 0xd7, 0x8b, 0xec, 0x68, 0xe2, 0xb9, 0x21, 0x49, 0xcd, 0xaf, 0xa1, 0x79, 0x1e, 0xd9, 0x41, 0x74, + 0x61, 0x87, 0x57, 0x16, 0x7f, 0x3d, 0xe3, 0x61, 0xc4, 0x18, 0xac, 0x44, 0x76, 0x78, 0xa5, 0x6b, + 0xfb, 0xda, 0xc1, 0xba, 0x85, 0xdf, 0x4c, 0x87, 0xb5, 0xd0, 0x9b, 0x05, 0x03, 0x1e, 0xea, 0xe5, + 0xfd, 0xca, 0xc1, 0xba, 0x15, 0x93, 0xac, 0x03, 0x10, 0xf0, 0xa9, 0x77, 0xcd, 0x5f, 0xf2, 0xc8, + 0xd6, 0x2b, 0xfb, 0xda, 0x41, 0xcd, 0x52, 0x38, 0xe6, 0x6b, 0xd8, 0x52, 0x2c, 0x84, 0xbe, 0xe7, + 0x86, 0x9c, 0xb5, 0xa1, 0x1a, 0xf0, 0x70, 0xe6, 0x44, 0x68, 0xa4, 0x66, 0x49, 0x8a, 0x35, 0xa1, + 0x32, 0x0d, 0xc7, 0x7a, 0x19, 0x2d, 0x8b, 0x4f, 0x76, 0x9c, 0x1a, 0xae, 0xec, 0x57, 0x0e, 0xea, + 0xc7, 0xfa, 0x13, 0xbf, 0xff, 0xa4, 0xeb, 0x4d, 0xa7, 0x9e, 0xfb, 0x0b, 0xf4, 0x33, 0x56, 0x9a, + 0x40, 0x32, 0x7f, 0x0d, 0xec, 0xcc, 0xe7, 0x81, 0x1d, 0x71, 0xd5, 0x2d, 0x03, 0xca, 0x9e, 0x8f, + 0xf6, 0x1a, 0xc7, 0x20, 0x94, 0x08, 0xe1, 0x99, 0x6f, 0x95, 0x3d, 0x5f, 0xb8, 0xec, 0xda, 0x53, + 0x2e, 0x0d, 0xe3, 0xb7, 0xea, 0x72, 0x25, 0xe3, 0xb2, 0xf9, 0x7b, 0x0d, 0xb6, 0x33, 0x06, 0xa4, + 0x57, 0x77, 0x59, 0x48, 0x3d, 0x2e, 0x17, 0x79, 0x5c, 0x29, 0xf4, 0x78, 0xe5, 0x7f, 0xf5, 0xf8, + 0x53, 0xd8, 0x7a, 0xe5, 0x0f, 0x73, 0x0e, 0x2f, 0x95, 0x47, 0x33, 0x00, 0xa6, 0xaa, 0xb8, 0x97, + 0x44, 0x7d, 0x06, 0xed, 0x9f, 0xcf, 0x78, 0x70, 0x7b, 0x1e, 0xd9, 0xd1, 0x2c, 0x3c, 0x9d, 0x84, + 0x91, 0x82, 0x1d, 0x13, 0xa2, 0x15, 0x27, 0x24, 0x87, 0xfd, 0x1a, 0x76, 0xe7, 0xf4, 0x2c, 0xed, + 0xc0, 0xd3, 0xbc, 0x03, 0xbb, 0xc2, 0x01, 0x45, 0xef, 0x3c, 0xfe, 0x2e, 0x6c, 0x9f, 0x5f, 0x7a, + 0x37, 0xbd, 0xde, 0xe9, 0xa9, 0x37, 0xb8, 0x0a, 0xbf, 0x5f, 0xe0, 0xff, 0xa2, 0xc1, 0x9a, 0xd4, + 0xc0, 0x1a, 0x50, 0x3e, 0xe9, 0xc9, 0xdf, 0x95, 0x4f, 0x7a, 0x89, 0xa6, 0xb2, 0xa2, 0x89, 0xc1, + 0xca, 0xd4, 0x1b, 0x72, 0x59, 0x32, 0xf8, 0xcd, 0x5a, 0xb0, 0xea, 0xdd, 0xb8, 0x3c, 0xd0, 0x57, + 0x90, 0x49, 0x84, 0x58, 0xd9, 0xeb, 0x9d, 0x86, 0xfa, 0x2a, 0x1a, 0xc4, 0x6f, 0x11, 0x8f, 0xf0, + 0xd6, 0x1d, 0xf0, 0xa1, 0x5e, 0x45, 0xae, 0xa4, 0x98, 0x01, 0xb5, 0x99, 0x2b, 0x25, 0x6b, 0x28, + 0x49, 0x68, 0x73, 0x00, 0xad, 0xac, 0x9b, 0x4b, 0xc7, 0xf6, 0x7d, 0x58, 0x75, 0xc4, 0x4f, 0x65, + 0x64, 0xeb, 0x22, 0xb2, 0x52, 0x9d, 0x45, 0x12, 0xd3, 0x81, 0xd6, 0x2b, 0x57, 0x7c, 0xc6, 0x7c, + 0x19, 0xcc, 0x7c, 0x48, 0x4c, 0xd8, 0x08, 0xb8, 0xef, 0xd8, 0x03, 0x7e, 0x86, 0x1e, 0x93, 0x95, + 0x0c, 0x8f, 0xed, 0x43, 0x7d, 0xe4, 0x05, 0x03, 0x6e, 0x61, 0x1b, 0x92, 0x4d, 0x49, 0x65, 0x99, + 0x9f, 0xc2, 0x4e, 0xce, 0xda, 0xb2, 0x3e, 0x99, 0x16, 0x3c, 0x90, 0x4d, 0x20, 0x2e, 0x6f, 0xc7, + 0xbe, 0x8d, 0x51, 0x3f, 0x54, 0x5a, 0x01, 0x7a, 0x8b, 0x52, 0xd9, 0x0b, 0x16, 0xd7, 0xc2, 0xb7, + 0x1a, 0x18, 0x45, 0x4a, 0x25, 0xb8, 0x3b, 0xb5, 0xfe, 0x7f, 0x3b, 0xcc, 0xb7, 0x1a, 0xec, 0x7e, + 0x31, 0x0b, 0xc6, 0x45, 0xce, 0x2a, 0xfe, 0x68, 0xd9, 0xc3, 0xc1, 0x80, 0xda, 0xc4, 0xb5, 0x07, + 0xd1, 0xe4, 0x9a, 0x4b, 0x54, 0x09, 0x8d, 0xb5, 0x3d, 0x99, 0x52, 0x76, 0x2a, 0x16, 0x7e, 0x8b, + 0xf5, 0xa3, 0x89, 0xc3, 0x71, 0xeb, 0x53, 0x29, 0x27, 0x34, 0x56, 0xee, 0xac, 0xdf, 0x9b, 0x04, + 0xfa, 0x2a, 0x4a, 0x24, 0x65, 0xfe, 0x06, 0xf4, 0x79, 0x60, 0xf7, 0xd2, 0xbe, 0x7e, 0x09, 0xcd, + 0xee, 0x25, 0x1f, 0x5c, 0xfd, 0xb7, 0xa6, 0xdb, 0x86, 0x2a, 0x0f, 0x82, 0xae, 0x4b, 0x99, 0xa9, + 0x58, 0x92, 0x12, 0x71, 0xbb, 0xb1, 0x03, 0x57, 0x08, 0x28, 0x08, 0x31, 0x69, 0x7e, 0x02, 0x5b, + 0x8a, 0xe6, 0xa5, 0x4b, 0xf3, 0x12, 0x5a, 0xb2, 0x8a, 0xce, 0x11, 0x6a, 0x0c, 0x6e, 0x4f, 0xa9, + 0x9f, 0x0d, 0xe1, 0x1f, 0x89, 0xd3, 0x02, 0x1a, 0x78, 0xee, 0x68, 0x32, 0x96, 0x55, 0x29, 0x29, + 0x91, 0x14, 0xf2, 0xf8, 0xa4, 0x27, 0x4f, 0xc2, 0x84, 0x36, 0x67, 0xb0, 0x93, 0xb3, 0x74, 0x2f, + 0x91, 0x7f, 0x0e, 0x3b, 0x16, 0x1f, 0x4f, 0xc4, 0xe8, 0x13, 0x2f, 0xb9, 0xf3, 0xdc, 0xb0, 0x87, + 0xc3, 0x80, 0x87, 0xa1, 0x34, 0x1b, 0x93, 0xe6, 0x33, 0x68, 0xe7, 0xd5, 0x2c, 0x1d, 0xeb, 0x9f, + 0x40, 0xeb, 0x6c, 0x34, 0x72, 0x26, 0x2e, 0x7f, 0xc9, 0xa7, 0xfd, 0x0c, 0x92, 0xe8, 0xd6, 0x4f, + 0x90, 0x88, 0xef, 0xa2, 0x31, 0x43, 0x74, 0xa2, 0xdc, 0xef, 0x97, 0x86, 0xf0, 0xe3, 0x24, 0xdd, + 0xa7, 0xdc, 0x1e, 0xa6, 0x10, 0xe6, 0xd2, 0x4d, 0x62, 0x4a, 0x37, 0x1a, 0xce, 0xfe, 0x6a, 0x69, + 0xc3, 0xbf, 0xd3, 0x00, 0x5e, 0xe2, 0x00, 0x7a, 0xe2, 0x8e, 0xbc, 0xc2, 0xe0, 0x1b, 0x50, 0x9b, + 0xa2, 0x5f, 0x27, 0x3d, 0xfc, 0xe5, 0x8a, 0x95, 0xd0, 0xe2, 0xd4, 0xb2, 0x9d, 0x49, 0xd2, 0xa0, + 0x89, 0x10, 0xbf, 0xf0, 0x39, 0x0f, 0x5e, 0x59, 0xa7, 0xd4, 0x9e, 0xd6, 0xad, 0x84, 0x16, 0xc3, + 0xe6, 0xc0, 0x99, 0x70, 0x37, 0x42, 0x29, 0x9d, 0x6b, 0x0a, 0xc7, 0xec, 0x03, 0x50, 0x22, 0x17, + 0xe2, 0x61, 0xb0, 0x22, 0xb2, 0x1f, 0xa7, 0x40, 0x7c, 0x0b, 0x1c, 0x61, 0x64, 0x8f, 0xe3, 0x23, + 0x95, 0x08, 0xec, 0x37, 0x58, 0x6e, 0xb2, 0x13, 0x49, 0xca, 0x3c, 0x85, 0xa6, 0x98, 0x30, 0x28, + 0x68, 0x94, 0xb3, 0x38, 0x34, 0x5a, 0x5a, 0xd5, 0x45, 0x13, 0x65, 0x6c, 0xbb, 0x92, 0xda, 0x36, + 0x7f, 0x46, 0xda, 0x28, 0x8a, 0x0b, 0xb5, 0x1d, 0xc0, 0x1a, 0x0d, 0xfa, 0x74, 0x62, 0xd4, 0x8f, + 0x1b, 0x22, 0x9d, 0x69, 0xe8, 0xad, 0x58, 0x1c, 0xeb, 0xa3, 0x28, 0xdc, 0xa5, 0x8f, 0x2e, 0x09, + 0x19, 0x7d, 0x69, 0xe8, 0xac, 0x58, 0x6c, 0xfe, 0x55, 0x83, 0x35, 0x52, 0x13, 0xb2, 0x27, 0x50, + 0x75, 0xd0, 0x6b, 0x54, 0x55, 0x3f, 0x6e, 0x61, 0x4d, 0xe5, 0x62, 0xf1, 0x79, 0xc9, 0x92, 0xab, + 0xc4, 0x7a, 0x82, 0x85, 0x51, 0x50, 0xd6, 0xab, 0xde, 0x8a, 0xf5, 0xb4, 0x4a, 0xac, 0x27, 0xb3, + 0x18, 0x21, 0x65, 0xbd, 0xea, 0x8d, 0x58, 0x4f, 0xab, 0x9e, 0xd5, 0xa0, 0x4a, 0xb5, 0x24, 0x2e, + 0x19, 0xa8, 0x37, 0xb3, 0x03, 0xdb, 0x19, 0xb8, 0xb5, 0x04, 0x56, 0x3b, 0x03, 0xab, 0x96, 0x98, + 0x6f, 0x67, 0xcc, 0xd7, 0x62, 0x33, 0xa2, 0x3c, 0x44, 0xfa, 0xe2, 0x6a, 0x24, 0xc2, 0xe4, 0xc0, + 0x54, 0x93, 0x4b, 0xb7, 0xbd, 0x0f, 0x61, 0x8d, 0xc0, 0x67, 0x86, 0x22, 0x19, 0x6a, 0x2b, 0x96, + 0x99, 0x7f, 0x2e, 0xa7, 0xbd, 0x7c, 0x70, 0xc9, 0xa7, 0xf6, 0xe2, 0x5e, 0x8e, 0xe2, 0xf4, 0x42, + 0x33, 0x37, 0x38, 0x2e, 0xbc, 0xd0, 0x88, 0x2d, 0x37, 0xb4, 0x23, 0xbb, 0x6f, 0x87, 0xc9, 0xb1, + 0x1b, 0xd3, 0xc2, 0xfb, 0xc8, 0xee, 0x3b, 0x5c, 0x9e, 0xba, 0x44, 0xe0, 0xe6, 0x40, 0x7b, 0x7a, + 0x55, 0x6e, 0x0e, 0xa4, 0xc4, 0xea, 0x91, 0x33, 0x0b, 0x2f, 0xf5, 0x35, 0xda, 0xd2, 0x48, 0x08, + 0x34, 0x62, 0x94, 0xd4, 0x6b, 0xc8, 0xc4, 0x6f, 0xb1, 0x95, 0x47, 0x81, 0x37, 0xa5, 0x63, 0x43, + 0x5f, 0xa7, 0x7b, 0x63, 0xca, 0x89, 0xe5, 0x17, 0x76, 0x30, 0xe6, 0x91, 0x0e, 0xa9, 0x9c, 0x38, + 0xea, 0xc9, 0x23, 0xe3, 0x72, 0x2f, 0x27, 0xcf, 0x21, 0xb4, 0x5e, 0xf0, 0xe8, 0x7c, 0xd6, 0x17, + 0x47, 0x73, 0x77, 0x34, 0xbe, 0xe3, 0xe0, 0x31, 0x5f, 0xc1, 0x4e, 0x6e, 0xed, 0xd2, 0x10, 0x19, + 0xac, 0x0c, 0x46, 0xe3, 0x38, 0x61, 0xf8, 0x6d, 0xf6, 0x60, 0xf3, 0x05, 0x8f, 0x14, 0xdb, 0x8f, + 0x95, 0xa3, 0x46, 0x0e, 0x86, 0xdd, 0xd1, 0xf8, 0xe2, 0xd6, 0xe7, 0x77, 0x9c, 0x3b, 0xa7, 0xd0, + 0x88, 0xb5, 0x2c, 0x8d, 0xaa, 0x09, 0x95, 0xc1, 0x28, 0x19, 0x29, 0x07, 0xa3, 0xb1, 0xb9, 0x03, + 0xdb, 0x2f, 0xb8, 0xdc, 0xd7, 0x29, 0x32, 0xf3, 0x00, 0xa3, 0xa5, 0xb0, 0xa5, 0x29, 0xa9, 0x40, + 0x4b, 0x15, 0xfc, 0x51, 0x03, 0xf6, 0xb9, 0xed, 0x0e, 0x1d, 0xfe, 0x3c, 0x08, 0xbc, 0x60, 0xe1, + 0x1c, 0x8d, 0xd2, 0xef, 0x55, 0xe4, 0x7b, 0xb0, 0xde, 0x9f, 0xb8, 0x8e, 0x37, 0xfe, 0xc2, 0x0b, + 0x65, 0x95, 0xa7, 0x0c, 0x2c, 0xd1, 0xd7, 0x4e, 0x72, 0x57, 0x12, 0xdf, 0x66, 0x08, 0xdb, 0x19, + 0x48, 0xf7, 0x52, 0x60, 0x2f, 0x60, 0xe7, 0x22, 0xb0, 0xdd, 0x70, 0xc4, 0x83, 0xec, 0xf0, 0x96, + 0x9e, 0x47, 0x9a, 0x7a, 0x1e, 0x29, 0x6d, 0x8b, 0x2c, 0x4b, 0x4a, 0x0c, 0x37, 0x79, 0x45, 0x4b, + 0x1f, 0xf0, 0xc3, 0xe4, 0xa1, 0x23, 0x33, 0xf0, 0x3f, 0x52, 0xb2, 0xb2, 0xa9, 0xdc, 0x43, 0xbe, + 0x3c, 0x8e, 0x07, 0x49, 0x89, 0xb4, 0xbc, 0x00, 0x29, 0xa5, 0x26, 0x46, 0x1a, 0x25, 0x2d, 0xee, + 0x1e, 0xa7, 0xf7, 0xc3, 0x3e, 0xd4, 0xe2, 0xf1, 0x97, 0x6d, 0xc3, 0x7b, 0x27, 0xee, 0xb5, 0xed, + 0x4c, 0x86, 0x31, 0xab, 0x59, 0x62, 0xef, 0x41, 0x1d, 0x5f, 0xae, 0x88, 0xd5, 0xd4, 0x58, 0x13, + 0x36, 0xe8, 0x89, 0x44, 0x72, 0xca, 0xac, 0x01, 0x70, 0x1e, 0x79, 0xbe, 0xa4, 0x2b, 0x48, 0x5f, + 0x7a, 0x37, 0x92, 0x5e, 0x39, 0xfc, 0x29, 0xd4, 0xe2, 0x99, 0x4b, 0xb1, 0x11, 0xb3, 0x9a, 0x25, + 0xb6, 0x05, 0x9b, 0xcf, 0xaf, 0x27, 0x83, 0x28, 0x61, 0x69, 0x6c, 0x17, 0xb6, 0xbb, 0xb6, 0x3b, + 0xe0, 0x4e, 0x56, 0x50, 0x3e, 0x74, 0x61, 0x4d, 0x6e, 0x6b, 0x01, 0x4d, 0xea, 0x12, 0x64, 0xb3, + 0xc4, 0x36, 0xa0, 0x26, 0x9a, 0x0c, 0x52, 0x9a, 0x80, 0x41, 0x7b, 0x0e, 0x69, 0x84, 0x49, 0x51, + 0x40, 0x9a, 0x60, 0x22, 0x44, 0xa4, 0x57, 0x58, 0x0b, 0x9a, 0xf8, 0x6b, 0x3e, 0xf5, 0x1d, 0x3b, + 0x22, 0xee, 0xea, 0x61, 0x0f, 0xd6, 0x93, 0xbc, 0x8a, 0x25, 0xd2, 0x62, 0xc2, 0x6b, 0x96, 0x44, + 0x44, 0x30, 0x44, 0xc8, 0xfb, 0xf2, 0xb8, 0xa9, 0x51, 0xd0, 0x3c, 0x3f, 0x66, 0x94, 0x8f, 0xff, + 0xd6, 0x80, 0x2a, 0x81, 0x61, 0x5f, 0xc1, 0x7a, 0xf2, 0x14, 0xc8, 0xf0, 0x70, 0xcf, 0xbf, 0x3d, + 0x1a, 0x3b, 0x39, 0x2e, 0x25, 0xcd, 0x7c, 0xfc, 0xdb, 0x7f, 0xfc, 0xfb, 0x4f, 0xe5, 0x07, 0x66, + 0xeb, 0xc8, 0xf6, 0x27, 0xe1, 0xd1, 0xf5, 0x53, 0xdb, 0xf1, 0x2f, 0xed, 0xa7, 0x47, 0x62, 0xcb, + 0x87, 0x1f, 0x6b, 0x87, 0x6c, 0x04, 0x75, 0xe5, 0x45, 0x8e, 0xb5, 0x85, 0x9a, 0xf9, 0x37, 0x40, + 0x63, 0x77, 0x8e, 0x2f, 0x0d, 0x7c, 0x84, 0x06, 0xf6, 0x8d, 0x87, 0x45, 0x06, 0x8e, 0xde, 0x88, + 0x8e, 0xf9, 0x8d, 0xb0, 0xf3, 0x09, 0x40, 0xfa, 0x4a, 0xc6, 0x10, 0xed, 0xdc, 0xc3, 0x9b, 0xd1, + 0xce, 0xb3, 0xa5, 0x91, 0x12, 0x73, 0xa0, 0xae, 0x3c, 0x28, 0x31, 0x23, 0xf7, 0xc2, 0xa4, 0xbc, + 0x80, 0x19, 0x0f, 0x0b, 0x65, 0x52, 0xd3, 0x07, 0x08, 0xb7, 0xc3, 0xf6, 0x72, 0x70, 0x43, 0x5c, + 0x2a, 0xf1, 0xb2, 0x2e, 0x6c, 0xa8, 0xef, 0x36, 0x0c, 0xbd, 0x2f, 0x78, 0xb0, 0x32, 0xf4, 0x79, + 0x41, 0x02, 0xf9, 0x33, 0xd8, 0xcc, 0xbc, 0x94, 0x30, 0x5c, 0x5c, 0xf4, 0x54, 0x63, 0x3c, 0x28, + 0x90, 0x24, 0x7a, 0xbe, 0x82, 0xf6, 0xfc, 0xcb, 0x06, 0x46, 0xf1, 0x91, 0x92, 0x94, 0xf9, 0xd7, + 0x05, 0xa3, 0xb3, 0x48, 0x9c, 0xa8, 0x3e, 0x83, 0x66, 0xfe, 0x05, 0x80, 0x61, 0xf8, 0x16, 0x3c, + 0x58, 0x18, 0x7b, 0xc5, 0xc2, 0x44, 0xe1, 0xc7, 0xb0, 0x9e, 0x5c, 0xbf, 0xa9, 0x50, 0xf3, 0xf7, + 0x7c, 0x2a, 0xd4, 0xb9, 0x3b, 0xba, 0x59, 0x62, 0x63, 0xd8, 0xcc, 0xdc, 0x88, 0x29, 0x5e, 0x45, + 0xd7, 0x71, 0x8a, 0x57, 0xe1, 0xf5, 0xd9, 0x7c, 0x1f, 0x13, 0xfc, 0xd0, 0x68, 0xe7, 0x13, 0x4c, + 0xcd, 0x4b, 0x94, 0xe2, 0x09, 0x34, 0xb2, 0x97, 0x57, 0xf6, 0x80, 0x5a, 0x71, 0xc1, 0xbd, 0xd8, + 0x30, 0x8a, 0x44, 0x09, 0xe6, 0x00, 0x36, 0x33, 0x77, 0x50, 0x89, 0xb9, 0xe0, 0x5a, 0x2b, 0x31, + 0x17, 0x5d, 0x58, 0xcd, 0x1f, 0x22, 0xe6, 0x8f, 0x0e, 0x3f, 0xc8, 0x61, 0x96, 0xa3, 0xec, 0xd1, + 0x1b, 0x31, 0x8b, 0x7c, 0x13, 0x17, 0xe7, 0x55, 0x12, 0x27, 0x6a, 0x71, 0x99, 0x38, 0x65, 0xee, + 0xb1, 0x99, 0x38, 0x65, 0xef, 0xaa, 0xe6, 0x87, 0x68, 0xf3, 0xb1, 0x61, 0xe4, 0x6c, 0xd2, 0xa8, + 0x7f, 0xf4, 0xc6, 0xf3, 0x71, 0xdb, 0xfe, 0x0a, 0x20, 0x1d, 0xd6, 0x69, 0xdb, 0xce, 0xdd, 0x17, + 0x68, 0xdb, 0xce, 0xcf, 0xf4, 0x66, 0x07, 0x6d, 0xe8, 0xac, 0x5d, 0xec, 0x17, 0x1b, 0xa5, 0x19, + 0xa7, 0x21, 0x38, 0x93, 0x71, 0x75, 0x68, 0xcf, 0x66, 0x3c, 0x33, 0xb6, 0x9a, 0xfb, 0x68, 0xc5, + 0x30, 0x76, 0xf2, 0x19, 0xc7, 0x65, 0xc2, 0x09, 0x07, 0xe7, 0xbe, 0x74, 0x9c, 0x24, 0x3b, 0x45, + 0xd3, 0x28, 0xd9, 0x29, 0x9c, 0x3d, 0xe3, 0x4e, 0xc7, 0x3a, 0x79, 0x3b, 0xb3, 0xbe, 0xda, 0xec, + 0xd8, 0x05, 0x54, 0x69, 0x3e, 0x64, 0x5b, 0x52, 0x99, 0xa2, 0x9f, 0xa9, 0x2c, 0xa9, 0xf8, 0x07, + 0xa8, 0xf8, 0x11, 0xbb, 0xab, 0x85, 0xb2, 0xaf, 0xa1, 0xae, 0x8c, 0x54, 0xd4, 0xa7, 0xe7, 0xc7, + 0x3e, 0xea, 0xd3, 0x05, 0xb3, 0xd7, 0xc2, 0x28, 0x71, 0xb1, 0x0a, 0xb7, 0x45, 0x17, 0x36, 0xd4, + 0x91, 0x93, 0x9a, 0x5e, 0xc1, 0x6c, 0x6a, 0xe8, 0xf3, 0x82, 0x64, 0x43, 0x9c, 0x40, 0x23, 0x3b, + 0x3b, 0xd1, 0xde, 0x2a, 0x1c, 0xcc, 0x68, 0x6f, 0x15, 0x8f, 0x5a, 0x66, 0x49, 0xe0, 0x51, 0x87, + 0x1b, 0xa6, 0x1e, 0x41, 0x99, 0xa6, 0xa4, 0xcf, 0x0b, 0x62, 0x25, 0xcf, 0xf4, 0xbf, 0xbf, 0xed, + 0x68, 0xdf, 0xbd, 0xed, 0x68, 0xff, 0x7a, 0xdb, 0xd1, 0xfe, 0xf0, 0xae, 0x53, 0xfa, 0xee, 0x5d, + 0xa7, 0xf4, 0xcf, 0x77, 0x9d, 0x52, 0xbf, 0x8a, 0xff, 0xe3, 0xfd, 0xe8, 0x3f, 0x01, 0x00, 0x00, + 0xff, 0xff, 0xa2, 0xd2, 0xac, 0xe5, 0x0b, 0x1c, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/dm/dm/proto/dmmaster.proto b/dm/dm/proto/dmmaster.proto index 2c973c7dfe8..a4504375923 100644 --- a/dm/dm/proto/dmmaster.proto +++ b/dm/dm/proto/dmmaster.proto @@ -401,6 +401,7 @@ enum CfgType { MasterType = 2; WorkerType = 3; SourceType = 4; + TaskTemplateType = 5; } message GetCfgRequest { diff --git a/dm/openapi/gen.client.go b/dm/openapi/gen.client.go index 29b03843994..3f1a57a84c5 100644 --- a/dm/openapi/gen.client.go +++ b/dm/openapi/gen.client.go @@ -149,6 +149,14 @@ type ClientInterface interface { DMAPITransferSource(ctx context.Context, sourceName string, body DMAPITransferSourceJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + // DMAPIGetTaskList request + DMAPIGetTaskList(ctx context.Context, params *DMAPIGetTaskListParams, reqEditors ...RequestEditorFn) (*http.Response, error) + + // DMAPIStartTask request with any body + DMAPIStartTaskWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) + + DMAPIStartTask(ctx context.Context, body DMAPIStartTaskJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) + // DMAPIGetTaskTemplateList request DMAPIGetTaskTemplateList(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -171,14 +179,6 @@ type ClientInterface interface { // DMAPUpdateTaskTemplate request DMAPUpdateTaskTemplate(ctx context.Context, taskName string, reqEditors ...RequestEditorFn) (*http.Response, error) - // DMAPIGetTaskList request - DMAPIGetTaskList(ctx context.Context, params *DMAPIGetTaskListParams, reqEditors ...RequestEditorFn) (*http.Response, error) - - // DMAPIStartTask request with any body - DMAPIStartTaskWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) - - DMAPIStartTask(ctx context.Context, body DMAPIStartTaskJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) - // DMAPIDeleteTask request DMAPIDeleteTask(ctx context.Context, taskName string, params *DMAPIDeleteTaskParams, reqEditors ...RequestEditorFn) (*http.Response, error) @@ -465,8 +465,8 @@ func (c *Client) DMAPITransferSource(ctx context.Context, sourceName string, bod return c.Client.Do(req) } -func (c *Client) DMAPIGetTaskTemplateList(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewDMAPIGetTaskTemplateListRequest(c.Server) +func (c *Client) DMAPIGetTaskList(ctx context.Context, params *DMAPIGetTaskListParams, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDMAPIGetTaskListRequest(c.Server, params) if err != nil { return nil, err } @@ -477,8 +477,8 @@ func (c *Client) DMAPIGetTaskTemplateList(ctx context.Context, reqEditors ...Req return c.Client.Do(req) } -func (c *Client) DMAPICreateTaskTemplateWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewDMAPICreateTaskTemplateRequestWithBody(c.Server, contentType, body) +func (c *Client) DMAPIStartTaskWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDMAPIStartTaskRequestWithBody(c.Server, contentType, body) if err != nil { return nil, err } @@ -489,8 +489,8 @@ func (c *Client) DMAPICreateTaskTemplateWithBody(ctx context.Context, contentTyp return c.Client.Do(req) } -func (c *Client) DMAPICreateTaskTemplate(ctx context.Context, body DMAPICreateTaskTemplateJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewDMAPICreateTaskTemplateRequest(c.Server, body) +func (c *Client) DMAPIStartTask(ctx context.Context, body DMAPIStartTaskJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDMAPIStartTaskRequest(c.Server, body) if err != nil { return nil, err } @@ -501,8 +501,8 @@ func (c *Client) DMAPICreateTaskTemplate(ctx context.Context, body DMAPICreateTa return c.Client.Do(req) } -func (c *Client) DMAPIImportTaskTemplateWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewDMAPIImportTaskTemplateRequestWithBody(c.Server, contentType, body) +func (c *Client) DMAPIGetTaskTemplateList(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDMAPIGetTaskTemplateListRequest(c.Server) if err != nil { return nil, err } @@ -513,8 +513,8 @@ func (c *Client) DMAPIImportTaskTemplateWithBody(ctx context.Context, contentTyp return c.Client.Do(req) } -func (c *Client) DMAPIImportTaskTemplate(ctx context.Context, body DMAPIImportTaskTemplateJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewDMAPIImportTaskTemplateRequest(c.Server, body) +func (c *Client) DMAPICreateTaskTemplateWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDMAPICreateTaskTemplateRequestWithBody(c.Server, contentType, body) if err != nil { return nil, err } @@ -525,8 +525,8 @@ func (c *Client) DMAPIImportTaskTemplate(ctx context.Context, body DMAPIImportTa return c.Client.Do(req) } -func (c *Client) DMAPIDeleteTaskTemplate(ctx context.Context, taskName string, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewDMAPIDeleteTaskTemplateRequest(c.Server, taskName) +func (c *Client) DMAPICreateTaskTemplate(ctx context.Context, body DMAPICreateTaskTemplateJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDMAPICreateTaskTemplateRequest(c.Server, body) if err != nil { return nil, err } @@ -537,8 +537,8 @@ func (c *Client) DMAPIDeleteTaskTemplate(ctx context.Context, taskName string, r return c.Client.Do(req) } -func (c *Client) DMAPIGetTaskTemplate(ctx context.Context, taskName string, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewDMAPIGetTaskTemplateRequest(c.Server, taskName) +func (c *Client) DMAPIImportTaskTemplateWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDMAPIImportTaskTemplateRequestWithBody(c.Server, contentType, body) if err != nil { return nil, err } @@ -549,8 +549,8 @@ func (c *Client) DMAPIGetTaskTemplate(ctx context.Context, taskName string, reqE return c.Client.Do(req) } -func (c *Client) DMAPUpdateTaskTemplate(ctx context.Context, taskName string, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewDMAPUpdateTaskTemplateRequest(c.Server, taskName) +func (c *Client) DMAPIImportTaskTemplate(ctx context.Context, body DMAPIImportTaskTemplateJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDMAPIImportTaskTemplateRequest(c.Server, body) if err != nil { return nil, err } @@ -561,8 +561,8 @@ func (c *Client) DMAPUpdateTaskTemplate(ctx context.Context, taskName string, re return c.Client.Do(req) } -func (c *Client) DMAPIGetTaskList(ctx context.Context, params *DMAPIGetTaskListParams, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewDMAPIGetTaskListRequest(c.Server, params) +func (c *Client) DMAPIDeleteTaskTemplate(ctx context.Context, taskName string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDMAPIDeleteTaskTemplateRequest(c.Server, taskName) if err != nil { return nil, err } @@ -573,8 +573,8 @@ func (c *Client) DMAPIGetTaskList(ctx context.Context, params *DMAPIGetTaskListP return c.Client.Do(req) } -func (c *Client) DMAPIStartTaskWithBody(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewDMAPIStartTaskRequestWithBody(c.Server, contentType, body) +func (c *Client) DMAPIGetTaskTemplate(ctx context.Context, taskName string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDMAPIGetTaskTemplateRequest(c.Server, taskName) if err != nil { return nil, err } @@ -585,8 +585,8 @@ func (c *Client) DMAPIStartTaskWithBody(ctx context.Context, contentType string, return c.Client.Do(req) } -func (c *Client) DMAPIStartTask(ctx context.Context, body DMAPIStartTaskJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { - req, err := NewDMAPIStartTaskRequest(c.Server, body) +func (c *Client) DMAPUpdateTaskTemplate(ctx context.Context, taskName string, reqEditors ...RequestEditorFn) (*http.Response, error) { + req, err := NewDMAPUpdateTaskTemplateRequest(c.Server, taskName) if err != nil { return nil, err } @@ -1372,8 +1372,8 @@ func NewDMAPITransferSourceRequestWithBody(server string, sourceName string, con return req, nil } -// NewDMAPIGetTaskTemplateListRequest generates requests for DMAPIGetTaskTemplateList -func NewDMAPIGetTaskTemplateListRequest(server string) (*http.Request, error) { +// NewDMAPIGetTaskListRequest generates requests for DMAPIGetTaskList +func NewDMAPIGetTaskListRequest(server string, params *DMAPIGetTaskListParams) (*http.Request, error) { var err error serverURL, err := url.Parse(server) @@ -1381,7 +1381,7 @@ func NewDMAPIGetTaskTemplateListRequest(server string) (*http.Request, error) { return nil, err } - operationPath := fmt.Sprintf("/api/v1/task/templates") + operationPath := fmt.Sprintf("/api/v1/tasks") if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -1391,6 +1391,24 @@ func NewDMAPIGetTaskTemplateListRequest(server string) (*http.Request, error) { return nil, err } + queryValues := queryURL.Query() + + if params.WithStatus != nil { + if queryFrag, err := runtime.StyleParamWithLocation("form", true, "with_status", runtime.ParamLocationQuery, *params.WithStatus); err != nil { + return nil, err + } else if parsed, err := url.ParseQuery(queryFrag); err != nil { + return nil, err + } else { + for k, v := range parsed { + for _, v2 := range v { + queryValues.Add(k, v2) + } + } + } + } + + queryURL.RawQuery = queryValues.Encode() + req, err := http.NewRequest("GET", queryURL.String(), nil) if err != nil { return nil, err @@ -1399,19 +1417,19 @@ func NewDMAPIGetTaskTemplateListRequest(server string) (*http.Request, error) { return req, nil } -// NewDMAPICreateTaskTemplateRequest calls the generic DMAPICreateTaskTemplate builder with application/json body -func NewDMAPICreateTaskTemplateRequest(server string, body DMAPICreateTaskTemplateJSONRequestBody) (*http.Request, error) { +// NewDMAPIStartTaskRequest calls the generic DMAPIStartTask builder with application/json body +func NewDMAPIStartTaskRequest(server string, body DMAPIStartTaskJSONRequestBody) (*http.Request, error) { var bodyReader io.Reader buf, err := json.Marshal(body) if err != nil { return nil, err } bodyReader = bytes.NewReader(buf) - return NewDMAPICreateTaskTemplateRequestWithBody(server, "application/json", bodyReader) + return NewDMAPIStartTaskRequestWithBody(server, "application/json", bodyReader) } -// NewDMAPICreateTaskTemplateRequestWithBody generates requests for DMAPICreateTaskTemplate with any type of body -func NewDMAPICreateTaskTemplateRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { +// NewDMAPIStartTaskRequestWithBody generates requests for DMAPIStartTask with any type of body +func NewDMAPIStartTaskRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { var err error serverURL, err := url.Parse(server) @@ -1419,7 +1437,7 @@ func NewDMAPICreateTaskTemplateRequestWithBody(server string, contentType string return nil, err } - operationPath := fmt.Sprintf("/api/v1/task/templates") + operationPath := fmt.Sprintf("/api/v1/tasks") if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -1439,19 +1457,8 @@ func NewDMAPICreateTaskTemplateRequestWithBody(server string, contentType string return req, nil } -// NewDMAPIImportTaskTemplateRequest calls the generic DMAPIImportTaskTemplate builder with application/json body -func NewDMAPIImportTaskTemplateRequest(server string, body DMAPIImportTaskTemplateJSONRequestBody) (*http.Request, error) { - var bodyReader io.Reader - buf, err := json.Marshal(body) - if err != nil { - return nil, err - } - bodyReader = bytes.NewReader(buf) - return NewDMAPIImportTaskTemplateRequestWithBody(server, "application/json", bodyReader) -} - -// NewDMAPIImportTaskTemplateRequestWithBody generates requests for DMAPIImportTaskTemplate with any type of body -func NewDMAPIImportTaskTemplateRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { +// NewDMAPIGetTaskTemplateListRequest generates requests for DMAPIGetTaskTemplateList +func NewDMAPIGetTaskTemplateListRequest(server string) (*http.Request, error) { var err error serverURL, err := url.Parse(server) @@ -1459,7 +1466,7 @@ func NewDMAPIImportTaskTemplateRequestWithBody(server string, contentType string return nil, err } - operationPath := fmt.Sprintf("/api/v1/task/templates/import") + operationPath := fmt.Sprintf("/api/v1/tasks/templates") if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -1469,33 +1476,35 @@ func NewDMAPIImportTaskTemplateRequestWithBody(server string, contentType string return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest("GET", queryURL.String(), nil) if err != nil { return nil, err } - req.Header.Add("Content-Type", contentType) - return req, nil } -// NewDMAPIDeleteTaskTemplateRequest generates requests for DMAPIDeleteTaskTemplate -func NewDMAPIDeleteTaskTemplateRequest(server string, taskName string) (*http.Request, error) { - var err error - - var pathParam0 string - - pathParam0, err = runtime.StyleParamWithLocation("simple", false, "task-name", runtime.ParamLocationPath, taskName) +// NewDMAPICreateTaskTemplateRequest calls the generic DMAPICreateTaskTemplate builder with application/json body +func NewDMAPICreateTaskTemplateRequest(server string, body DMAPICreateTaskTemplateJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) if err != nil { return nil, err } + bodyReader = bytes.NewReader(buf) + return NewDMAPICreateTaskTemplateRequestWithBody(server, "application/json", bodyReader) +} + +// NewDMAPICreateTaskTemplateRequestWithBody generates requests for DMAPICreateTaskTemplate with any type of body +func NewDMAPICreateTaskTemplateRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { + var err error serverURL, err := url.Parse(server) if err != nil { return nil, err } - operationPath := fmt.Sprintf("/api/v1/task/templates/%s", pathParam0) + operationPath := fmt.Sprintf("/api/v1/tasks/templates") if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -1505,31 +1514,37 @@ func NewDMAPIDeleteTaskTemplateRequest(server string, taskName string) (*http.Re return nil, err } - req, err := http.NewRequest("DELETE", queryURL.String(), nil) + req, err := http.NewRequest("POST", queryURL.String(), body) if err != nil { return nil, err } + req.Header.Add("Content-Type", contentType) + return req, nil } -// NewDMAPIGetTaskTemplateRequest generates requests for DMAPIGetTaskTemplate -func NewDMAPIGetTaskTemplateRequest(server string, taskName string) (*http.Request, error) { - var err error - - var pathParam0 string - - pathParam0, err = runtime.StyleParamWithLocation("simple", false, "task-name", runtime.ParamLocationPath, taskName) +// NewDMAPIImportTaskTemplateRequest calls the generic DMAPIImportTaskTemplate builder with application/json body +func NewDMAPIImportTaskTemplateRequest(server string, body DMAPIImportTaskTemplateJSONRequestBody) (*http.Request, error) { + var bodyReader io.Reader + buf, err := json.Marshal(body) if err != nil { return nil, err } + bodyReader = bytes.NewReader(buf) + return NewDMAPIImportTaskTemplateRequestWithBody(server, "application/json", bodyReader) +} + +// NewDMAPIImportTaskTemplateRequestWithBody generates requests for DMAPIImportTaskTemplate with any type of body +func NewDMAPIImportTaskTemplateRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { + var err error serverURL, err := url.Parse(server) if err != nil { return nil, err } - operationPath := fmt.Sprintf("/api/v1/task/templates/%s", pathParam0) + operationPath := fmt.Sprintf("/api/v1/tasks/templates/import") if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -1539,16 +1554,18 @@ func NewDMAPIGetTaskTemplateRequest(server string, taskName string) (*http.Reque return nil, err } - req, err := http.NewRequest("GET", queryURL.String(), nil) + req, err := http.NewRequest("POST", queryURL.String(), body) if err != nil { return nil, err } + req.Header.Add("Content-Type", contentType) + return req, nil } -// NewDMAPUpdateTaskTemplateRequest generates requests for DMAPUpdateTaskTemplate -func NewDMAPUpdateTaskTemplateRequest(server string, taskName string) (*http.Request, error) { +// NewDMAPIDeleteTaskTemplateRequest generates requests for DMAPIDeleteTaskTemplate +func NewDMAPIDeleteTaskTemplateRequest(server string, taskName string) (*http.Request, error) { var err error var pathParam0 string @@ -1563,7 +1580,7 @@ func NewDMAPUpdateTaskTemplateRequest(server string, taskName string) (*http.Req return nil, err } - operationPath := fmt.Sprintf("/api/v1/task/templates/%s", pathParam0) + operationPath := fmt.Sprintf("/api/v1/tasks/templates/%s", pathParam0) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -1573,7 +1590,7 @@ func NewDMAPUpdateTaskTemplateRequest(server string, taskName string) (*http.Req return nil, err } - req, err := http.NewRequest("PUT", queryURL.String(), nil) + req, err := http.NewRequest("DELETE", queryURL.String(), nil) if err != nil { return nil, err } @@ -1581,16 +1598,23 @@ func NewDMAPUpdateTaskTemplateRequest(server string, taskName string) (*http.Req return req, nil } -// NewDMAPIGetTaskListRequest generates requests for DMAPIGetTaskList -func NewDMAPIGetTaskListRequest(server string, params *DMAPIGetTaskListParams) (*http.Request, error) { +// NewDMAPIGetTaskTemplateRequest generates requests for DMAPIGetTaskTemplate +func NewDMAPIGetTaskTemplateRequest(server string, taskName string) (*http.Request, error) { var err error + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "task-name", runtime.ParamLocationPath, taskName) + if err != nil { + return nil, err + } + serverURL, err := url.Parse(server) if err != nil { return nil, err } - operationPath := fmt.Sprintf("/api/v1/tasks") + operationPath := fmt.Sprintf("/api/v1/tasks/templates/%s", pathParam0) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -1600,24 +1624,6 @@ func NewDMAPIGetTaskListRequest(server string, params *DMAPIGetTaskListParams) ( return nil, err } - queryValues := queryURL.Query() - - if params.WithStatus != nil { - if queryFrag, err := runtime.StyleParamWithLocation("form", true, "with_status", runtime.ParamLocationQuery, *params.WithStatus); err != nil { - return nil, err - } else if parsed, err := url.ParseQuery(queryFrag); err != nil { - return nil, err - } else { - for k, v := range parsed { - for _, v2 := range v { - queryValues.Add(k, v2) - } - } - } - } - - queryURL.RawQuery = queryValues.Encode() - req, err := http.NewRequest("GET", queryURL.String(), nil) if err != nil { return nil, err @@ -1626,27 +1632,23 @@ func NewDMAPIGetTaskListRequest(server string, params *DMAPIGetTaskListParams) ( return req, nil } -// NewDMAPIStartTaskRequest calls the generic DMAPIStartTask builder with application/json body -func NewDMAPIStartTaskRequest(server string, body DMAPIStartTaskJSONRequestBody) (*http.Request, error) { - var bodyReader io.Reader - buf, err := json.Marshal(body) +// NewDMAPUpdateTaskTemplateRequest generates requests for DMAPUpdateTaskTemplate +func NewDMAPUpdateTaskTemplateRequest(server string, taskName string) (*http.Request, error) { + var err error + + var pathParam0 string + + pathParam0, err = runtime.StyleParamWithLocation("simple", false, "task-name", runtime.ParamLocationPath, taskName) if err != nil { return nil, err } - bodyReader = bytes.NewReader(buf) - return NewDMAPIStartTaskRequestWithBody(server, "application/json", bodyReader) -} - -// NewDMAPIStartTaskRequestWithBody generates requests for DMAPIStartTask with any type of body -func NewDMAPIStartTaskRequestWithBody(server string, contentType string, body io.Reader) (*http.Request, error) { - var err error serverURL, err := url.Parse(server) if err != nil { return nil, err } - operationPath := fmt.Sprintf("/api/v1/tasks") + operationPath := fmt.Sprintf("/api/v1/tasks/templates/%s", pathParam0) if operationPath[0] == '/' { operationPath = "." + operationPath } @@ -1656,13 +1658,11 @@ func NewDMAPIStartTaskRequestWithBody(server string, contentType string, body io return nil, err } - req, err := http.NewRequest("POST", queryURL.String(), body) + req, err := http.NewRequest("PUT", queryURL.String(), nil) if err != nil { return nil, err } - req.Header.Add("Content-Type", contentType) - return req, nil } @@ -2233,6 +2233,14 @@ type ClientWithResponsesInterface interface { DMAPITransferSourceWithResponse(ctx context.Context, sourceName string, body DMAPITransferSourceJSONRequestBody, reqEditors ...RequestEditorFn) (*DMAPITransferSourceResponse, error) + // DMAPIGetTaskList request + DMAPIGetTaskListWithResponse(ctx context.Context, params *DMAPIGetTaskListParams, reqEditors ...RequestEditorFn) (*DMAPIGetTaskListResponse, error) + + // DMAPIStartTask request with any body + DMAPIStartTaskWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*DMAPIStartTaskResponse, error) + + DMAPIStartTaskWithResponse(ctx context.Context, body DMAPIStartTaskJSONRequestBody, reqEditors ...RequestEditorFn) (*DMAPIStartTaskResponse, error) + // DMAPIGetTaskTemplateList request DMAPIGetTaskTemplateListWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*DMAPIGetTaskTemplateListResponse, error) @@ -2255,14 +2263,6 @@ type ClientWithResponsesInterface interface { // DMAPUpdateTaskTemplate request DMAPUpdateTaskTemplateWithResponse(ctx context.Context, taskName string, reqEditors ...RequestEditorFn) (*DMAPUpdateTaskTemplateResponse, error) - // DMAPIGetTaskList request - DMAPIGetTaskListWithResponse(ctx context.Context, params *DMAPIGetTaskListParams, reqEditors ...RequestEditorFn) (*DMAPIGetTaskListResponse, error) - - // DMAPIStartTask request with any body - DMAPIStartTaskWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*DMAPIStartTaskResponse, error) - - DMAPIStartTaskWithResponse(ctx context.Context, body DMAPIStartTaskJSONRequestBody, reqEditors ...RequestEditorFn) (*DMAPIStartTaskResponse, error) - // DMAPIDeleteTask request DMAPIDeleteTaskWithResponse(ctx context.Context, taskName string, params *DMAPIDeleteTaskParams, reqEditors ...RequestEditorFn) (*DMAPIDeleteTaskResponse, error) @@ -2676,7 +2676,7 @@ func (r DMAPITransferSourceResponse) StatusCode() int { return 0 } -type DMAPIGetTaskTemplateListResponse struct { +type DMAPIGetTaskListResponse struct { Body []byte HTTPResponse *http.Response JSON200 *GetTaskListResponse @@ -2684,7 +2684,7 @@ type DMAPIGetTaskTemplateListResponse struct { } // Status returns HTTPResponse.Status -func (r DMAPIGetTaskTemplateListResponse) Status() string { +func (r DMAPIGetTaskListResponse) Status() string { if r.HTTPResponse != nil { return r.HTTPResponse.Status } @@ -2692,14 +2692,14 @@ func (r DMAPIGetTaskTemplateListResponse) Status() string { } // StatusCode returns HTTPResponse.StatusCode -func (r DMAPIGetTaskTemplateListResponse) StatusCode() int { +func (r DMAPIGetTaskListResponse) StatusCode() int { if r.HTTPResponse != nil { return r.HTTPResponse.StatusCode } return 0 } -type DMAPICreateTaskTemplateResponse struct { +type DMAPIStartTaskResponse struct { Body []byte HTTPResponse *http.Response JSON201 *Task @@ -2707,7 +2707,7 @@ type DMAPICreateTaskTemplateResponse struct { } // Status returns HTTPResponse.Status -func (r DMAPICreateTaskTemplateResponse) Status() string { +func (r DMAPIStartTaskResponse) Status() string { if r.HTTPResponse != nil { return r.HTTPResponse.Status } @@ -2715,22 +2715,22 @@ func (r DMAPICreateTaskTemplateResponse) Status() string { } // StatusCode returns HTTPResponse.StatusCode -func (r DMAPICreateTaskTemplateResponse) StatusCode() int { +func (r DMAPIStartTaskResponse) StatusCode() int { if r.HTTPResponse != nil { return r.HTTPResponse.StatusCode } return 0 } -type DMAPIImportTaskTemplateResponse struct { +type DMAPIGetTaskTemplateListResponse struct { Body []byte HTTPResponse *http.Response - JSON202 *TaskTemplateResponse + JSON200 *GetTaskListResponse JSON400 *ErrorWithMessage } // Status returns HTTPResponse.Status -func (r DMAPIImportTaskTemplateResponse) Status() string { +func (r DMAPIGetTaskTemplateListResponse) Status() string { if r.HTTPResponse != nil { return r.HTTPResponse.Status } @@ -2738,21 +2738,22 @@ func (r DMAPIImportTaskTemplateResponse) Status() string { } // StatusCode returns HTTPResponse.StatusCode -func (r DMAPIImportTaskTemplateResponse) StatusCode() int { +func (r DMAPIGetTaskTemplateListResponse) StatusCode() int { if r.HTTPResponse != nil { return r.HTTPResponse.StatusCode } return 0 } -type DMAPIDeleteTaskTemplateResponse struct { +type DMAPICreateTaskTemplateResponse struct { Body []byte HTTPResponse *http.Response + JSON201 *Task JSON400 *ErrorWithMessage } // Status returns HTTPResponse.Status -func (r DMAPIDeleteTaskTemplateResponse) Status() string { +func (r DMAPICreateTaskTemplateResponse) Status() string { if r.HTTPResponse != nil { return r.HTTPResponse.Status } @@ -2760,22 +2761,22 @@ func (r DMAPIDeleteTaskTemplateResponse) Status() string { } // StatusCode returns HTTPResponse.StatusCode -func (r DMAPIDeleteTaskTemplateResponse) StatusCode() int { +func (r DMAPICreateTaskTemplateResponse) StatusCode() int { if r.HTTPResponse != nil { return r.HTTPResponse.StatusCode } return 0 } -type DMAPIGetTaskTemplateResponse struct { +type DMAPIImportTaskTemplateResponse struct { Body []byte HTTPResponse *http.Response - JSON200 *Task + JSON202 *TaskTemplateResponse JSON400 *ErrorWithMessage } // Status returns HTTPResponse.Status -func (r DMAPIGetTaskTemplateResponse) Status() string { +func (r DMAPIImportTaskTemplateResponse) Status() string { if r.HTTPResponse != nil { return r.HTTPResponse.Status } @@ -2783,22 +2784,21 @@ func (r DMAPIGetTaskTemplateResponse) Status() string { } // StatusCode returns HTTPResponse.StatusCode -func (r DMAPIGetTaskTemplateResponse) StatusCode() int { +func (r DMAPIImportTaskTemplateResponse) StatusCode() int { if r.HTTPResponse != nil { return r.HTTPResponse.StatusCode } return 0 } -type DMAPUpdateTaskTemplateResponse struct { +type DMAPIDeleteTaskTemplateResponse struct { Body []byte HTTPResponse *http.Response - JSON200 *Task JSON400 *ErrorWithMessage } // Status returns HTTPResponse.Status -func (r DMAPUpdateTaskTemplateResponse) Status() string { +func (r DMAPIDeleteTaskTemplateResponse) Status() string { if r.HTTPResponse != nil { return r.HTTPResponse.Status } @@ -2806,22 +2806,22 @@ func (r DMAPUpdateTaskTemplateResponse) Status() string { } // StatusCode returns HTTPResponse.StatusCode -func (r DMAPUpdateTaskTemplateResponse) StatusCode() int { +func (r DMAPIDeleteTaskTemplateResponse) StatusCode() int { if r.HTTPResponse != nil { return r.HTTPResponse.StatusCode } return 0 } -type DMAPIGetTaskListResponse struct { +type DMAPIGetTaskTemplateResponse struct { Body []byte HTTPResponse *http.Response - JSON200 *GetTaskListResponse + JSON200 *Task JSON400 *ErrorWithMessage } // Status returns HTTPResponse.Status -func (r DMAPIGetTaskListResponse) Status() string { +func (r DMAPIGetTaskTemplateResponse) Status() string { if r.HTTPResponse != nil { return r.HTTPResponse.Status } @@ -2829,22 +2829,22 @@ func (r DMAPIGetTaskListResponse) Status() string { } // StatusCode returns HTTPResponse.StatusCode -func (r DMAPIGetTaskListResponse) StatusCode() int { +func (r DMAPIGetTaskTemplateResponse) StatusCode() int { if r.HTTPResponse != nil { return r.HTTPResponse.StatusCode } return 0 } -type DMAPIStartTaskResponse struct { +type DMAPUpdateTaskTemplateResponse struct { Body []byte HTTPResponse *http.Response - JSON201 *Task + JSON200 *Task JSON400 *ErrorWithMessage } // Status returns HTTPResponse.Status -func (r DMAPIStartTaskResponse) Status() string { +func (r DMAPUpdateTaskTemplateResponse) Status() string { if r.HTTPResponse != nil { return r.HTTPResponse.Status } @@ -2852,7 +2852,7 @@ func (r DMAPIStartTaskResponse) Status() string { } // StatusCode returns HTTPResponse.StatusCode -func (r DMAPIStartTaskResponse) StatusCode() int { +func (r DMAPUpdateTaskTemplateResponse) StatusCode() int { if r.HTTPResponse != nil { return r.HTTPResponse.StatusCode } @@ -3246,6 +3246,32 @@ func (c *ClientWithResponses) DMAPITransferSourceWithResponse(ctx context.Contex return ParseDMAPITransferSourceResponse(rsp) } +// DMAPIGetTaskListWithResponse request returning *DMAPIGetTaskListResponse +func (c *ClientWithResponses) DMAPIGetTaskListWithResponse(ctx context.Context, params *DMAPIGetTaskListParams, reqEditors ...RequestEditorFn) (*DMAPIGetTaskListResponse, error) { + rsp, err := c.DMAPIGetTaskList(ctx, params, reqEditors...) + if err != nil { + return nil, err + } + return ParseDMAPIGetTaskListResponse(rsp) +} + +// DMAPIStartTaskWithBodyWithResponse request with arbitrary body returning *DMAPIStartTaskResponse +func (c *ClientWithResponses) DMAPIStartTaskWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*DMAPIStartTaskResponse, error) { + rsp, err := c.DMAPIStartTaskWithBody(ctx, contentType, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseDMAPIStartTaskResponse(rsp) +} + +func (c *ClientWithResponses) DMAPIStartTaskWithResponse(ctx context.Context, body DMAPIStartTaskJSONRequestBody, reqEditors ...RequestEditorFn) (*DMAPIStartTaskResponse, error) { + rsp, err := c.DMAPIStartTask(ctx, body, reqEditors...) + if err != nil { + return nil, err + } + return ParseDMAPIStartTaskResponse(rsp) +} + // DMAPIGetTaskTemplateListWithResponse request returning *DMAPIGetTaskTemplateListResponse func (c *ClientWithResponses) DMAPIGetTaskTemplateListWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*DMAPIGetTaskTemplateListResponse, error) { rsp, err := c.DMAPIGetTaskTemplateList(ctx, reqEditors...) @@ -3316,32 +3342,6 @@ func (c *ClientWithResponses) DMAPUpdateTaskTemplateWithResponse(ctx context.Con return ParseDMAPUpdateTaskTemplateResponse(rsp) } -// DMAPIGetTaskListWithResponse request returning *DMAPIGetTaskListResponse -func (c *ClientWithResponses) DMAPIGetTaskListWithResponse(ctx context.Context, params *DMAPIGetTaskListParams, reqEditors ...RequestEditorFn) (*DMAPIGetTaskListResponse, error) { - rsp, err := c.DMAPIGetTaskList(ctx, params, reqEditors...) - if err != nil { - return nil, err - } - return ParseDMAPIGetTaskListResponse(rsp) -} - -// DMAPIStartTaskWithBodyWithResponse request with arbitrary body returning *DMAPIStartTaskResponse -func (c *ClientWithResponses) DMAPIStartTaskWithBodyWithResponse(ctx context.Context, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*DMAPIStartTaskResponse, error) { - rsp, err := c.DMAPIStartTaskWithBody(ctx, contentType, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseDMAPIStartTaskResponse(rsp) -} - -func (c *ClientWithResponses) DMAPIStartTaskWithResponse(ctx context.Context, body DMAPIStartTaskJSONRequestBody, reqEditors ...RequestEditorFn) (*DMAPIStartTaskResponse, error) { - rsp, err := c.DMAPIStartTask(ctx, body, reqEditors...) - if err != nil { - return nil, err - } - return ParseDMAPIStartTaskResponse(rsp) -} - // DMAPIDeleteTaskWithResponse request returning *DMAPIDeleteTaskResponse func (c *ClientWithResponses) DMAPIDeleteTaskWithResponse(ctx context.Context, taskName string, params *DMAPIDeleteTaskParams, reqEditors ...RequestEditorFn) (*DMAPIDeleteTaskResponse, error) { rsp, err := c.DMAPIDeleteTask(ctx, taskName, params, reqEditors...) @@ -3910,15 +3910,15 @@ func ParseDMAPITransferSourceResponse(rsp *http.Response) (*DMAPITransferSourceR return response, nil } -// ParseDMAPIGetTaskTemplateListResponse parses an HTTP response from a DMAPIGetTaskTemplateListWithResponse call -func ParseDMAPIGetTaskTemplateListResponse(rsp *http.Response) (*DMAPIGetTaskTemplateListResponse, error) { +// ParseDMAPIGetTaskListResponse parses an HTTP response from a DMAPIGetTaskListWithResponse call +func ParseDMAPIGetTaskListResponse(rsp *http.Response) (*DMAPIGetTaskListResponse, error) { bodyBytes, err := ioutil.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &DMAPIGetTaskTemplateListResponse{ + response := &DMAPIGetTaskListResponse{ Body: bodyBytes, HTTPResponse: rsp, } @@ -3943,15 +3943,15 @@ func ParseDMAPIGetTaskTemplateListResponse(rsp *http.Response) (*DMAPIGetTaskTem return response, nil } -// ParseDMAPICreateTaskTemplateResponse parses an HTTP response from a DMAPICreateTaskTemplateWithResponse call -func ParseDMAPICreateTaskTemplateResponse(rsp *http.Response) (*DMAPICreateTaskTemplateResponse, error) { +// ParseDMAPIStartTaskResponse parses an HTTP response from a DMAPIStartTaskWithResponse call +func ParseDMAPIStartTaskResponse(rsp *http.Response) (*DMAPIStartTaskResponse, error) { bodyBytes, err := ioutil.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &DMAPICreateTaskTemplateResponse{ + response := &DMAPIStartTaskResponse{ Body: bodyBytes, HTTPResponse: rsp, } @@ -3976,26 +3976,26 @@ func ParseDMAPICreateTaskTemplateResponse(rsp *http.Response) (*DMAPICreateTaskT return response, nil } -// ParseDMAPIImportTaskTemplateResponse parses an HTTP response from a DMAPIImportTaskTemplateWithResponse call -func ParseDMAPIImportTaskTemplateResponse(rsp *http.Response) (*DMAPIImportTaskTemplateResponse, error) { +// ParseDMAPIGetTaskTemplateListResponse parses an HTTP response from a DMAPIGetTaskTemplateListWithResponse call +func ParseDMAPIGetTaskTemplateListResponse(rsp *http.Response) (*DMAPIGetTaskTemplateListResponse, error) { bodyBytes, err := ioutil.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &DMAPIImportTaskTemplateResponse{ + response := &DMAPIGetTaskTemplateListResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 202: - var dest TaskTemplateResponse + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: + var dest GetTaskListResponse if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON202 = &dest + response.JSON200 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: var dest ErrorWithMessage @@ -4009,51 +4009,59 @@ func ParseDMAPIImportTaskTemplateResponse(rsp *http.Response) (*DMAPIImportTaskT return response, nil } -// ParseDMAPIDeleteTaskTemplateResponse parses an HTTP response from a DMAPIDeleteTaskTemplateWithResponse call -func ParseDMAPIDeleteTaskTemplateResponse(rsp *http.Response) (*DMAPIDeleteTaskTemplateResponse, error) { +// ParseDMAPICreateTaskTemplateResponse parses an HTTP response from a DMAPICreateTaskTemplateWithResponse call +func ParseDMAPICreateTaskTemplateResponse(rsp *http.Response) (*DMAPICreateTaskTemplateResponse, error) { bodyBytes, err := ioutil.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &DMAPIDeleteTaskTemplateResponse{ + response := &DMAPICreateTaskTemplateResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + var dest Task + if err := json.Unmarshal(bodyBytes, &dest); err != nil { + return nil, err + } + response.JSON201 = &dest + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: var dest ErrorWithMessage if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } response.JSON400 = &dest + } return response, nil } -// ParseDMAPIGetTaskTemplateResponse parses an HTTP response from a DMAPIGetTaskTemplateWithResponse call -func ParseDMAPIGetTaskTemplateResponse(rsp *http.Response) (*DMAPIGetTaskTemplateResponse, error) { +// ParseDMAPIImportTaskTemplateResponse parses an HTTP response from a DMAPIImportTaskTemplateWithResponse call +func ParseDMAPIImportTaskTemplateResponse(rsp *http.Response) (*DMAPIImportTaskTemplateResponse, error) { bodyBytes, err := ioutil.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &DMAPIGetTaskTemplateResponse{ + response := &DMAPIImportTaskTemplateResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest Task + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 202: + var dest TaskTemplateResponse if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON200 = &dest + response.JSON202 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: var dest ErrorWithMessage @@ -4067,55 +4075,47 @@ func ParseDMAPIGetTaskTemplateResponse(rsp *http.Response) (*DMAPIGetTaskTemplat return response, nil } -// ParseDMAPUpdateTaskTemplateResponse parses an HTTP response from a DMAPUpdateTaskTemplateWithResponse call -func ParseDMAPUpdateTaskTemplateResponse(rsp *http.Response) (*DMAPUpdateTaskTemplateResponse, error) { +// ParseDMAPIDeleteTaskTemplateResponse parses an HTTP response from a DMAPIDeleteTaskTemplateWithResponse call +func ParseDMAPIDeleteTaskTemplateResponse(rsp *http.Response) (*DMAPIDeleteTaskTemplateResponse, error) { bodyBytes, err := ioutil.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &DMAPUpdateTaskTemplateResponse{ + response := &DMAPIDeleteTaskTemplateResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest Task - if err := json.Unmarshal(bodyBytes, &dest); err != nil { - return nil, err - } - response.JSON200 = &dest - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: var dest ErrorWithMessage if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } response.JSON400 = &dest - } return response, nil } -// ParseDMAPIGetTaskListResponse parses an HTTP response from a DMAPIGetTaskListWithResponse call -func ParseDMAPIGetTaskListResponse(rsp *http.Response) (*DMAPIGetTaskListResponse, error) { +// ParseDMAPIGetTaskTemplateResponse parses an HTTP response from a DMAPIGetTaskTemplateWithResponse call +func ParseDMAPIGetTaskTemplateResponse(rsp *http.Response) (*DMAPIGetTaskTemplateResponse, error) { bodyBytes, err := ioutil.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &DMAPIGetTaskListResponse{ + response := &DMAPIGetTaskTemplateResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: - var dest GetTaskListResponse + var dest Task if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } @@ -4133,26 +4133,26 @@ func ParseDMAPIGetTaskListResponse(rsp *http.Response) (*DMAPIGetTaskListRespons return response, nil } -// ParseDMAPIStartTaskResponse parses an HTTP response from a DMAPIStartTaskWithResponse call -func ParseDMAPIStartTaskResponse(rsp *http.Response) (*DMAPIStartTaskResponse, error) { +// ParseDMAPUpdateTaskTemplateResponse parses an HTTP response from a DMAPUpdateTaskTemplateWithResponse call +func ParseDMAPUpdateTaskTemplateResponse(rsp *http.Response) (*DMAPUpdateTaskTemplateResponse, error) { bodyBytes, err := ioutil.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } - response := &DMAPIStartTaskResponse{ + response := &DMAPUpdateTaskTemplateResponse{ Body: bodyBytes, HTTPResponse: rsp, } switch { - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 201: + case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: var dest Task if err := json.Unmarshal(bodyBytes, &dest); err != nil { return nil, err } - response.JSON201 = &dest + response.JSON200 = &dest case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 400: var dest ErrorWithMessage diff --git a/dm/openapi/gen.server.go b/dm/openapi/gen.server.go index 479a3137478..434f551728e 100644 --- a/dm/openapi/gen.server.go +++ b/dm/openapi/gen.server.go @@ -71,30 +71,30 @@ type ServerInterface interface { // transfer source to a free worker // (POST /api/v1/sources/{source-name}/transfer) DMAPITransferSource(c *gin.Context, sourceName string) + // get task list + // (GET /api/v1/tasks) + DMAPIGetTaskList(c *gin.Context, params DMAPIGetTaskListParams) + // create and start task + // (POST /api/v1/tasks) + DMAPIStartTask(c *gin.Context) // get task template list - // (GET /api/v1/task/templates) + // (GET /api/v1/tasks/templates) DMAPIGetTaskTemplateList(c *gin.Context) // create task template - // (POST /api/v1/task/templates) + // (POST /api/v1/tasks/templates) DMAPICreateTaskTemplate(c *gin.Context) // import task template - // (POST /api/v1/task/templates/import) + // (POST /api/v1/tasks/templates/import) DMAPIImportTaskTemplate(c *gin.Context) // delete task template template - // (DELETE /api/v1/task/templates/{task-name}) + // (DELETE /api/v1/tasks/templates/{task-name}) DMAPIDeleteTaskTemplate(c *gin.Context, taskName string) // get task template template - // (GET /api/v1/task/templates/{task-name}) + // (GET /api/v1/tasks/templates/{task-name}) DMAPIGetTaskTemplate(c *gin.Context, taskName string) // update task template template - // (PUT /api/v1/task/templates/{task-name}) + // (PUT /api/v1/tasks/templates/{task-name}) DMAPUpdateTaskTemplate(c *gin.Context, taskName string) - // get task list - // (GET /api/v1/tasks) - DMAPIGetTaskList(c *gin.Context, params DMAPIGetTaskListParams) - // create and start task - // (POST /api/v1/tasks) - DMAPIStartTask(c *gin.Context) // delete and stop task // (DELETE /api/v1/tasks/{task-name}) DMAPIDeleteTask(c *gin.Context, taskName string, params DMAPIDeleteTaskParams) @@ -443,6 +443,39 @@ func (siw *ServerInterfaceWrapper) DMAPITransferSource(c *gin.Context) { siw.Handler.DMAPITransferSource(c, sourceName) } +// DMAPIGetTaskList operation middleware +func (siw *ServerInterfaceWrapper) DMAPIGetTaskList(c *gin.Context) { + var err error + + // Parameter object where we will unmarshal all parameters from the context + var params DMAPIGetTaskListParams + + // ------------- Optional query parameter "with_status" ------------- + if paramValue := c.Query("with_status"); paramValue != "" { + } + + err = runtime.BindQueryParameter("form", true, false, "with_status", c.Request.URL.Query(), ¶ms.WithStatus) + if err != nil { + c.JSON(http.StatusBadRequest, gin.H{"msg": fmt.Sprintf("Invalid format for parameter with_status: %s", err)}) + return + } + + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + } + + siw.Handler.DMAPIGetTaskList(c, params) +} + +// DMAPIStartTask operation middleware +func (siw *ServerInterfaceWrapper) DMAPIStartTask(c *gin.Context) { + for _, middleware := range siw.HandlerMiddlewares { + middleware(c) + } + + siw.Handler.DMAPIStartTask(c) +} + // DMAPIGetTaskTemplateList operation middleware func (siw *ServerInterfaceWrapper) DMAPIGetTaskTemplateList(c *gin.Context) { for _, middleware := range siw.HandlerMiddlewares { @@ -530,39 +563,6 @@ func (siw *ServerInterfaceWrapper) DMAPUpdateTaskTemplate(c *gin.Context) { siw.Handler.DMAPUpdateTaskTemplate(c, taskName) } -// DMAPIGetTaskList operation middleware -func (siw *ServerInterfaceWrapper) DMAPIGetTaskList(c *gin.Context) { - var err error - - // Parameter object where we will unmarshal all parameters from the context - var params DMAPIGetTaskListParams - - // ------------- Optional query parameter "with_status" ------------- - if paramValue := c.Query("with_status"); paramValue != "" { - } - - err = runtime.BindQueryParameter("form", true, false, "with_status", c.Request.URL.Query(), ¶ms.WithStatus) - if err != nil { - c.JSON(http.StatusBadRequest, gin.H{"msg": fmt.Sprintf("Invalid format for parameter with_status: %s", err)}) - return - } - - for _, middleware := range siw.HandlerMiddlewares { - middleware(c) - } - - siw.Handler.DMAPIGetTaskList(c, params) -} - -// DMAPIStartTask operation middleware -func (siw *ServerInterfaceWrapper) DMAPIStartTask(c *gin.Context) { - for _, middleware := range siw.HandlerMiddlewares { - middleware(c) - } - - siw.Handler.DMAPIStartTask(c) -} - // DMAPIDeleteTask operation middleware func (siw *ServerInterfaceWrapper) DMAPIDeleteTask(c *gin.Context) { var err error @@ -929,21 +929,21 @@ func RegisterHandlersWithOptions(router *gin.Engine, si ServerInterface, options router.POST(options.BaseURL+"/api/v1/sources/:source-name/transfer", wrapper.DMAPITransferSource) - router.GET(options.BaseURL+"/api/v1/task/templates", wrapper.DMAPIGetTaskTemplateList) + router.GET(options.BaseURL+"/api/v1/tasks", wrapper.DMAPIGetTaskList) - router.POST(options.BaseURL+"/api/v1/task/templates", wrapper.DMAPICreateTaskTemplate) + router.POST(options.BaseURL+"/api/v1/tasks", wrapper.DMAPIStartTask) - router.POST(options.BaseURL+"/api/v1/task/templates/import", wrapper.DMAPIImportTaskTemplate) + router.GET(options.BaseURL+"/api/v1/tasks/templates", wrapper.DMAPIGetTaskTemplateList) - router.DELETE(options.BaseURL+"/api/v1/task/templates/:task-name", wrapper.DMAPIDeleteTaskTemplate) + router.POST(options.BaseURL+"/api/v1/tasks/templates", wrapper.DMAPICreateTaskTemplate) - router.GET(options.BaseURL+"/api/v1/task/templates/:task-name", wrapper.DMAPIGetTaskTemplate) + router.POST(options.BaseURL+"/api/v1/tasks/templates/import", wrapper.DMAPIImportTaskTemplate) - router.PUT(options.BaseURL+"/api/v1/task/templates/:task-name", wrapper.DMAPUpdateTaskTemplate) + router.DELETE(options.BaseURL+"/api/v1/tasks/templates/:task-name", wrapper.DMAPIDeleteTaskTemplate) - router.GET(options.BaseURL+"/api/v1/tasks", wrapper.DMAPIGetTaskList) + router.GET(options.BaseURL+"/api/v1/tasks/templates/:task-name", wrapper.DMAPIGetTaskTemplate) - router.POST(options.BaseURL+"/api/v1/tasks", wrapper.DMAPIStartTask) + router.PUT(options.BaseURL+"/api/v1/tasks/templates/:task-name", wrapper.DMAPUpdateTaskTemplate) router.DELETE(options.BaseURL+"/api/v1/tasks/:task-name", wrapper.DMAPIDeleteTask) @@ -968,6 +968,7 @@ func RegisterHandlersWithOptions(router *gin.Engine, si ServerInterface, options // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ + "H4sIAAAAAAAC/+w9WXPjNpp/BcvdhyQlWZLtvrw1D9220+Nd291lK5WdSvWqIRKSMCYBGgDtaLr836dw", "kARJgKR8dKzEeUgcEceH775AfgtCmqSUICJ4cPAt4OEKJVD9eRhnXCB2BuW/5Q8poyliAiP1GEaR+jVC", "PGQ4FZiS4ED9ijgHdAHECoEwYwwRARK1CCA0QsEgQL/DJI1RcBBMdt/sjHfGO5ODt7uvJ8EgEOtU/s4F", @@ -1042,16 +1043,17 @@ var swaggerSpec = []string{ "cmtqPCW9rZfp9nAE9W3tPu7gExDXf+vrSf3C2g31LQmB84ttusDl80H7ssfom/6jdGF6MIuqCz8/Xhm0", "FAE925dn77m9s0b4pFxa7cDeLibVNdL786iATPSyWOUNwm0xWE8Q9jVuUd5VKx0S2LttNJamX/4pjWVx", "X6mPrSzuFD8fRmttwPouyZXay0G3RFHZr6K33+f/GCxF0566y9xC/SurrtpF3D+L5oowf2rVJRgkfGG+", - "w+DnsqkZtjXppyditWZnwp+F13JGKJwvCqB+3aKur3Rwl4D8apS38nSbQrtZ5ztULhtvzHZgRSUlY/PF", - "h+djYSq9UjVfWH9Qok/FwMb3E9UNzAcw/riqgQ+AZ1ozqFC2SVSvbI30/ZIOhX2iBn0nstc7Bjfngt0n", - "gmd73Elza+jeXPFN3VrZpJRUY46NLLp9MddhygtYehpy342b7WxMMBUWf5trXX33NpXbQ6bxX06tN611", - "G8nTzENy/Vb1F6JvB9EzRa3edK+p735+ct8uGwXE1vbYbLmLfg/PXGVcp/rlJE/hmTU/yffinff2zqH+", - "HKPxyLol+Z7+13PV7YM+L+B0KJfGtxbtfR/0xs6tdgU1N5nOp82YSbfZ9Gmwec789OUpexXt8ubd9nbv", - "3IM3dB9Ir36cF+7YVu4wzT73YI8HtvYUTT0f1pJ73pPofun/52C0XpqN/ijPuLXj6MFcvGEHUtF79MLS", - "Lz1RWytLzsaoRxYlOW8eow0jGvsLkC8y9cxkauB/CYkP5TkH9Ma558uuW5/Hr0get1h802T+i4S8SMgf", - "0GXX8gnrrTWArWLoLbCcFJ8sfhHFjTf/qwji4ycjOj+U/WdpJCu/6r2BvLZ7rf3aq613Vf+VsuobZcC+", - "g5XZ0k5uxa0599S5U73Wjd3k3FR9Q9OaZjsRTSAm6v1MgUSyWcD7KcH2V0JFNHzge6BG1xkOr4b6Cowu", - "aQ3N5nc1tgpcytZ86Oa7AGnAK54O1fZ3FfFzAJm/4KMYl/9w9+Xu3wEAAP//+FWMYRuQAAA=", + "w+DnsqkZtjXppyditWZnwp+F13JGKJwvCqB+3aKur3Rwl87bdVnA/M3VfYoGKkm4tSWDxju6HXRQJ4zN", + "Nyaej00roCoprr9c0V6aUA7kVN+1fArRa35h5I8sUZjPfWxLgQLqr8swUbzYuErZuiSP8q68fjKd9919", + "hyaELResou3xHhJWSsC07Jl8ClHzMfeLdLmlq0LZTYRrpO+KdThfJ2rQd6J7vft3czbYfSJ4tic0NDcA", + "788W39QVtE3qwjXu2Mg9t2/ZO/zyApaeXrnv+tx2dhmZcqm/Z72uwHsby+0h0/gvp9ib9rqN5GnmIbn+", + "RMIL0beD6JmiVm+6N/T3/bT2c+WIQZ93cDoC8sbnFu19H/TSzq02IDoCM81PmzGT7rTp02PznPnpy1O2", + "K9oVzrvtbeC5B2/oVpBeLTkv3LGt3GH6fe7BHg/s7in6ej6sJfe8J9H9KgDPwWi99Bv9UU50a9PRg7l4", + "wyakov3ohaVf2qK2VpacvVGPLEpy3jxGG0Y09kcgX2TqmcnUwP8eEh/Kcw7ojXPPx123PvtXkTxusfim", + "KcAXCXmRkD+g0a7lK9ZbawBbxdCblj0pvlr8Ioobb/5XEcTHT0Z0fiv7z9JLVn7YewN5bfda+3VYW6+r", + "/itl1TfKgH0HK7OlzdyKW3PuqXOnerMbu8m5qfqSpjXNdiKaQEzUK5oCiWSzgPdrgu1vhYpo+MBXQY2u", + "MxxeDfUtGN2oMjSb39XYKnApW/Otm+8CpAGveDpU299VxM8BZP6Oj2Jc/sPdl7t/BwAA//8QGZ0BHpAA", + "AA==", } // 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 e36f0b12a47..6913035c0bf 100644 --- a/dm/openapi/gen.types.go +++ b/dm/openapi/gen.types.go @@ -550,12 +550,6 @@ type DMAPIStopRelayJSONBody StopRelayRequest // DMAPITransferSourceJSONBody defines parameters for DMAPITransferSource. type DMAPITransferSourceJSONBody WorkerNameRequest -// DMAPICreateTaskTemplateJSONBody defines parameters for DMAPICreateTaskTemplate. -type DMAPICreateTaskTemplateJSONBody Task - -// DMAPIImportTaskTemplateJSONBody defines parameters for DMAPIImportTaskTemplate. -type DMAPIImportTaskTemplateJSONBody TaskTemplateRequest - // DMAPIGetTaskListParams defines parameters for DMAPIGetTaskList. type DMAPIGetTaskListParams struct { // get task with status @@ -565,6 +559,12 @@ type DMAPIGetTaskListParams struct { // DMAPIStartTaskJSONBody defines parameters for DMAPIStartTask. type DMAPIStartTaskJSONBody CreateTaskRequest +// DMAPICreateTaskTemplateJSONBody defines parameters for DMAPICreateTaskTemplate. +type DMAPICreateTaskTemplateJSONBody Task + +// DMAPIImportTaskTemplateJSONBody defines parameters for DMAPIImportTaskTemplate. +type DMAPIImportTaskTemplateJSONBody TaskTemplateRequest + // DMAPIDeleteTaskParams defines parameters for DMAPIDeleteTask. type DMAPIDeleteTaskParams struct { // source name list @@ -598,15 +598,15 @@ type DMAPIStopRelayJSONRequestBody DMAPIStopRelayJSONBody // DMAPITransferSourceJSONRequestBody defines body for DMAPITransferSource for application/json ContentType. type DMAPITransferSourceJSONRequestBody DMAPITransferSourceJSONBody +// DMAPIStartTaskJSONRequestBody defines body for DMAPIStartTask for application/json ContentType. +type DMAPIStartTaskJSONRequestBody DMAPIStartTaskJSONBody + // DMAPICreateTaskTemplateJSONRequestBody defines body for DMAPICreateTaskTemplate for application/json ContentType. type DMAPICreateTaskTemplateJSONRequestBody DMAPICreateTaskTemplateJSONBody // DMAPIImportTaskTemplateJSONRequestBody defines body for DMAPIImportTaskTemplate for application/json ContentType. type DMAPIImportTaskTemplateJSONRequestBody DMAPIImportTaskTemplateJSONBody -// DMAPIStartTaskJSONRequestBody defines body for DMAPIStartTask for application/json ContentType. -type DMAPIStartTaskJSONRequestBody DMAPIStartTaskJSONBody - // DMAPIPauseTaskJSONRequestBody defines body for DMAPIPauseTask for application/json ContentType. type DMAPIPauseTaskJSONRequestBody DMAPIPauseTaskJSONBody diff --git a/dm/openapi/spec/dm.yaml b/dm/openapi/spec/dm.yaml index bf61b9a0a4d..b1bfa185e96 100644 --- a/dm/openapi/spec/dm.yaml +++ b/dm/openapi/spec/dm.yaml @@ -731,7 +731,7 @@ paths: "application/json": schema: $ref: "#/components/schemas/ErrorWithMessage" - /api/v1/task/templates: + /api/v1/tasks/templates: post: tags: - task @@ -774,7 +774,7 @@ paths: "application/json": schema: $ref: "#/components/schemas/ErrorWithMessage" - /api/v1/task/templates/import: + /api/v1/tasks/templates/import: post: tags: - task @@ -799,7 +799,7 @@ paths: "application/json": schema: $ref: "#/components/schemas/ErrorWithMessage" - /api/v1/task/templates/{task-name}: + /api/v1/tasks/templates/{task-name}: get: tags: - task diff --git a/dm/tests/openapi/client/openapi_task_check b/dm/tests/openapi/client/openapi_task_check index a912159bb11..77e70d41264 100755 --- a/dm/tests/openapi/client/openapi_task_check +++ b/dm/tests/openapi/client/openapi_task_check @@ -295,6 +295,145 @@ def stop_task_success(task_name): print("stop_task_success") +def create_task_template_success(task_name, target_table_name=""): + url = API_ENDPOINT + "/templates" + task = { + "name": task_name, + "task_mode": "all", + "shard_mode": "pessimistic", + "meta_schema": "dm-meta", + "enhance_online_schema_change": True, + "on_duplicate": "error", + "target_config": { + "host": "127.0.0.1", + "port": 4000, + "user": "root", + "password": "", + }, + "table_migrate_rule": [ + { + "source": { + "source_name": SOURCE1_NAME, + "schema": "openapi", + "table": "*", + }, + "target": {"schema": "openapi", "table": target_table_name}, + }, + { + "source": { + "source_name": SOURCE2_NAME, + "schema": "openapi", + "table": "*", + }, + "target": {"schema": "openapi", "table": target_table_name}, + }, + ], + "source_config": { + "source_conf": [ + {"source_name": SOURCE1_NAME}, + {"source_name": SOURCE2_NAME}, + ], + }, + } + resp = requests.post(url=url, json=task) + print("create_task_template_success resp=", resp.json()) + assert resp.status_code == 201 + + +def create_task_template_failed(): + url = API_ENDPOINT + "/templates" + task = { + "name": "test", + "task_mode": "all", + "shard_mode": "pessimistic_xxd", # pessimistic_xxd is not a valid shard mode + "meta_schema": "dm-meta", + "enhance_online_schema_change": True, + "on_duplicate": "error", + "target_config": { + "host": "127.0.0.1", + "port": 4000, + "user": "root", + "password": "", + }, + "table_migrate_rule": [ + { + "source": { + "source_name": SOURCE1_NAME, + "schema": "openapi", + "table": "*", + }, + "target": {"schema": "openapi", "table": "t"}, + }, + { + "source": { + "source_name": SOURCE2_NAME, + "schema": "openapi", + "table": "*", + }, + "target": {"schema": "openapi", "table": "t"}, + }, + ], + "source_config": { + "source_conf": [ + {"source_name": SOURCE1_NAME}, + {"source_name": SOURCE2_NAME}, + ], + }, + } + resp = requests.post(url=url, json=task) + print("create_task_template_failed resp=", resp.json()) + assert resp.status_code == 400 + + +def list_task_template(count): + url = API_ENDPOINT + "/templates" + resp = requests.get(url=url) + data = resp.json() + assert resp.status_code == 200 + print("list_task_template resp=", data) + assert data["total"] == int(count) + + +def import_task_template(success_count, failed_count): + url = API_ENDPOINT + "/templates/import" + resp = requests.post(url=url) + data = resp.json() + print("import_task_template resp=", data) + assert resp.status_code == 202 + assert len(data["success_task_list"]) == int(success_count) + assert len(data["failed_task_list"]) == int(failed_count) + + +def get_task_template(name): + url = API_ENDPOINT + "/templates/" + name + resp = requests.get(url=url) + data = resp.json() + assert resp.status_code == 200 + print("get_task_template resp=", data) + assert data["name"] == name + + +def update_task_template_success(name, task_mode): + url = API_ENDPOINT + "/templates/" + name + + # get task template first + task = requests.get(url=url).json() + task["task_mode"] = task_mode + resp = requests.put(url=url, json=task) + print("update_task_template_success resp=", resp.json()) + assert resp.status_code == 200 + + # update task template success + assert requests.get(url=url).json()["task_mode"] == task_mode + + +def delete_task_template(name): + url = API_ENDPOINT + "/templates/" + name + resp = requests.delete(url=url) + assert resp.status_code == 204 + print("delete_task_template") + + def check_noshard_task_dump_status_success(task_name, total): url = API_ENDPOINT + "/" + task_name + "/status" resp = requests.get(url=url) @@ -319,6 +458,13 @@ if __name__ == "__main__": "get_illegal_char_task_status_failed": get_illegal_char_task_status_failed, "get_task_status_success": get_task_status_success, "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, + "list_task_template": list_task_template, + "import_task_template": import_task_template, + "get_task_template": get_task_template, + "update_task_template_success": update_task_template_success, + "delete_task_template": delete_task_template, "check_noshard_task_dump_status_success": check_noshard_task_dump_status_success, } diff --git a/dm/tests/openapi/run.sh b/dm/tests/openapi/run.sh index f1372175ce1..b2103cfe4a7 100644 --- a/dm/tests/openapi/run.sh +++ b/dm/tests/openapi/run.sh @@ -32,10 +32,18 @@ function init_shard_data() { run_sql_source2 "INSERT INTO openapi.t(i,j) VALUES (3, 4);" } +function clean_cluster_sources_and_tasks() { + openapi_source_check "delete_source_with_force_success" "mysql-01" + openapi_source_check "delete_source_with_force_success" "mysql-02" + openapi_source_check "list_source_success" 0 + openapi_task_check "get_task_list" 0 + run_sql_tidb "DROP DATABASE if exists openapi;" +} + function test_source() { echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>START TEST OPENAPI: SOURCE" prepare_database - # create source succesfully + # create source successfully openapi_source_check "create_source1_success" # recreate source will failed @@ -75,7 +83,7 @@ function test_source() { function test_relay() { echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>START TEST OPENAPI: RELAY" prepare_database - # create source succesfully + # create source successfully openapi_source_check "create_source1_success" # we need make sure that source is bounded by worker1 because we will start relay on worker1 @@ -159,20 +167,20 @@ function test_shard_task() { task_name="test-shard" - # create source succesfully + # create source successfully 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 + # create source successfully 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 + # start task success: not valid task create request openapi_task_check "start_task_failed" # start shard task success @@ -217,10 +225,7 @@ function test_shard_task() { openapi_task_check "get_task_list" 0 # delete source success - openapi_source_check "delete_source_success" "mysql-01" - openapi_source_check "delete_source_success" "mysql-02" - openapi_source_check "list_source_success" 0 - run_sql_tidb "DROP DATABASE if exists openapi;" + clean_cluster_sources_and_tasks echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>TEST OPENAPI: SHARD TASK SUCCESS" } @@ -232,14 +237,14 @@ function test_noshard_task() { task_name="test-no-shard" target_table_name="" # empty means no route - # create source succesfully + # create source successfully 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 + # create source successfully openapi_source_check "create_source2_success" # get source list success openapi_source_check "list_source_success" 2 @@ -247,7 +252,7 @@ function test_noshard_task() { # get source status success openapi_source_check "get_source_status_success" "mysql-02" - # start task success: not vaild task create request + # start task success: not valid task create request openapi_task_check "start_task_failed" # start no shard task success @@ -278,7 +283,7 @@ function test_noshard_task() { # pause task first for operate schema openapi_task_check "pause_task_success" "$task_name" "mysql-02" - # opreate schema + # operate schema openapi_task_check "operate_schema_and_table_success" "$task_name" "mysql-02" "openapi" "t2" # resume task @@ -329,33 +334,53 @@ function test_multi_tasks() { openapi_task_check "get_task_list_with_status" 2 $task2 2 # delete source success and clean data for other test - openapi_source_check "delete_source_with_force_success" "mysql-01" - openapi_source_check "delete_source_with_force_success" "mysql-02" - openapi_source_check "list_source_success" 0 - run_sql_tidb "DROP DATABASE if exists openapi;" - openapi_task_check "get_task_list" 0 + clean_cluster_sources_and_tasks echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>TEST OPENAPI: MULTI TASK SUCCESS" } -function test_cluster() { - # list master and worker node - openapi_cluster_check "list_master_success" 2 +function test_task_templates() { + echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>START TEST OPENAPI: TASK TEMPLATES" + prepare_database - openapi_cluster_check "list_worker_success" 2 + taskname="test-1" - # delete master node - openapi_cluster_check "delete_master_with_retry_success" "master2" - openapi_cluster_check "list_master_success" 1 + # create and check source + openapi_source_check "create_source1_success" + openapi_source_check "create_source2_success" + openapi_source_check "list_source_success" 2 - # delete worker node fialed because of worker is still online - openapi_cluster_check "delete_worker_failed" "worker1" - kill_dm_worker - check_port_offline $WORKER1_PORT 20 - check_port_offline $WORKER2_PORT 20 + # crud task template + openapi_task_check "create_task_template_failed" + openapi_task_check "create_task_template_success" $taskname + openapi_task_check "list_task_template" 1 + openapi_task_check "get_task_template" $taskname + openapi_task_check "update_task_template_success" $taskname "full" + openapi_task_check "delete_task_template" $taskname + openapi_task_check "list_task_template" 0 - openapi_cluster_check "delete_worker_with_retry_success" "worker1" - openapi_cluster_check "list_worker_success" 1 + # import from tasks and get from dmctl + init_noshard_data + openapi_task_check "start_noshard_task_success" $taskname + run_dm_ctl_with_retry $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "query-status $taskname" \ + "\"stage\": \"Running\"" 2 + openapi_task_check "import_task_template" 1 0 + openapi_task_check "list_task_template" 1 + + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "config task $taskname --path $WORK_DIR/get_task_from_task.yaml" \ + "\"result\": true" 1 + + run_dm_ctl $WORK_DIR "127.0.0.1:$MASTER_PORT" \ + "config task-template $taskname --path $WORK_DIR/get_task_from_task_template.yaml" \ + "\"result\": true" 1 + + diff $WORK_DIR/get_task_from_task.yaml $WORK_DIR/get_task_from_task_template.yaml || exit 1 + + # delete source success and clean data for other test + clean_cluster_sources_and_tasks + echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>TEST OPENAPI: TASK TEMPLATES" } function test_noshard_task_dump_status() { @@ -394,14 +419,30 @@ function test_noshard_task_dump_status() { openapi_task_check "check_noshard_task_dump_status_success" "$task_name" 0 # delete source success and clean data for other test - openapi_source_check "delete_source_with_force_success" "mysql-01" - openapi_source_check "delete_source_with_force_success" "mysql-02" - openapi_source_check "list_source_success" 0 - run_sql_tidb "DROP DATABASE if exists openapi;" - openapi_task_check "get_task_list" 0 + clean_cluster_sources_and_tasks echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>TEST OPENAPI: NO SHARD TASK DUMP STATUS SUCCESS" } +function test_cluster() { + # list master and worker node + openapi_cluster_check "list_master_success" 2 + + openapi_cluster_check "list_worker_success" 2 + + # delete master node + openapi_cluster_check "delete_master_with_retry_success" "master2" + openapi_cluster_check "list_master_success" 1 + + # delete worker node failed because of worker is still online + openapi_cluster_check "delete_worker_failed" "worker1" + kill_dm_worker + check_port_offline $WORKER1_PORT 20 + check_port_offline $WORKER2_PORT 20 + + openapi_cluster_check "delete_worker_with_retry_success" "worker1" + openapi_cluster_check "list_worker_success" 1 +} + function run() { # run dm-master1 run_dm_master $WORK_DIR/master1 $MASTER_PORT1 $cur/conf/dm-master1.toml @@ -449,7 +490,10 @@ function run() { check_rpc_alive $cur/../bin/check_worker_online 127.0.0.1:$WORKER2_PORT test_noshard_task - test_cluster # note that this test case should running at last, becasue it will offline some memebrs of cluster + test_task_templates + + # NOTE: this test case MUST running at last, because it will offline some members of cluster + test_cluster } cleanup_data openapi diff --git a/tools/check/go.sum b/tools/check/go.sum index 5701b086237..ea23d874225 100644 --- a/tools/check/go.sum +++ b/tools/check/go.sum @@ -279,7 +279,9 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -425,6 +427,7 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.10.1/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= @@ -1371,6 +1374,7 @@ google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c h1:wtujag7C+4D6KMoulW9YauvK2lgdvCMS260jsqqBXr0= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=