From 6c9f217fa3366c4645b75a4e5aee81d74a357eda Mon Sep 17 00:00:00 2001 From: zoubingwu Date: Mon, 16 May 2022 17:20:40 +0800 Subject: [PATCH 1/9] feat: show warning when create/update task --- dm/ui/src/components/CreateOrUpdateTask/index.tsx | 8 ++++++-- dm/ui/src/models/task.ts | 10 ++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/dm/ui/src/components/CreateOrUpdateTask/index.tsx b/dm/ui/src/components/CreateOrUpdateTask/index.tsx index 80ada564222..02dbeca2122 100644 --- a/dm/ui/src/components/CreateOrUpdateTask/index.tsx +++ b/dm/ui/src/components/CreateOrUpdateTask/index.tsx @@ -106,11 +106,15 @@ const CreateTaskConfig: React.FC<{ const key = 'createTask-' + Date.now() message.loading({ content: t('requesting'), key }) try { - await handler({ task: payload as Task }).unwrap() + const data = await handler({ task: payload as Task }).unwrap() if (startAfterSaved) { await startTask({ taskName: payload.name }).unwrap() } - message.success({ content: t('request success'), key }) + if (data.check_result) { + message.success({ content: data.check_result, key }) + } else { + message.success({ content: t('request success'), key }) + } navigate('/migration/task') } catch (e) { message.destroy(key) diff --git a/dm/ui/src/models/task.ts b/dm/ui/src/models/task.ts index e4672cce84a..45610398d45 100644 --- a/dm/ui/src/models/task.ts +++ b/dm/ui/src/models/task.ts @@ -2,7 +2,10 @@ import { api, ListResponse } from './api' const injectedRtkApi = api.injectEndpoints({ endpoints: build => ({ - dmapiCreateTask: build.mutation({ + dmapiCreateTask: build.mutation< + { task: Task; check_result: string }, + { task: Task } + >({ query: queryArg => ({ url: `/tasks`, method: 'POST', @@ -50,7 +53,10 @@ const injectedRtkApi = api.injectEndpoints({ }), } ), - dmapiUpdateTask: build.mutation({ + dmapiUpdateTask: build.mutation< + { task: Task; check_result: string }, + { task: Task } + >({ query: queryArg => ({ url: `/tasks/${queryArg.task.name}`, method: 'PUT', From 9d4bfd328a89378eebd8c82675a5894fef45b51c Mon Sep 17 00:00:00 2001 From: zoubingwu Date: Tue, 17 May 2022 16:36:44 +0800 Subject: [PATCH 2/9] ui(dm): spec v3 updates --- dm/ui/locales/en.json | 9 +- dm/ui/locales/zh.json | 10 +- dm/ui/package.json | 2 +- dm/ui/public/mockServiceWorker.js | 4 +- dm/ui/src/mock.ts | 3329 +++++++++++++--------- dm/ui/src/models/task.ts | 6 +- dm/ui/src/pages/migration/task/index.tsx | 187 +- dm/ui/vite.config.js | 2 +- dm/ui/yarn.lock | 8 +- 9 files changed, 2080 insertions(+), 1477 deletions(-) diff --git a/dm/ui/locales/en.json b/dm/ui/locales/en.json index d718833d9d0..77e1453972f 100644 --- a/dm/ui/locales/en.json +++ b/dm/ui/locales/en.json @@ -14,7 +14,6 @@ "confirm": "Confirm", "confirm to delete source": "Confirm to delete source", "confirm to delete task?": "Confirm to delete task?", - "confirm to start task?": "Confirm to start task?", "confirm to stop task?": "Confirm to stop task?", "consistency requirement": "Consistency", "create task": "Create Task", @@ -114,6 +113,8 @@ "request success": "Request success", "requesting": "Requesting", "runtime config": "Runtime Config", + "safe mode time duration": "Safe-Mode Duration", + "safe mode time duration tooltip": "How long safe mode lasts after the task is started. This time is binlog time and not physical time. For a detailed description of Safe Mode and this configuration, please refer to the documentation", "save": "Save", "save and run": "Save and start", "search placeholder": "Search...", @@ -132,6 +133,12 @@ "source schema": "Source Database", "source table": "Source Table", "start": "Start", + "start task with params": "Start with params", + "start task with params desc": "Tasks will continue to sync based on the checkpoint at the last end. If it is started for the first time, it will start at the specified location or time according to the configuration file.", + "start task without params": "Start", + "start task without params desc": "The task will start according to the specified parameters, be sure to read the document about those parameters", + "start time on copy": "Start time", + "start time on copy tooltip": "Synchronize all upstreams from the specified point in time, the saved location information (checkpoint) will be ignored", "status": "Status", "stop": "Stop", "stop_task list": "Stop", diff --git a/dm/ui/locales/zh.json b/dm/ui/locales/zh.json index 37bb64da3d4..44ae1fea327 100644 --- a/dm/ui/locales/zh.json +++ b/dm/ui/locales/zh.json @@ -14,7 +14,7 @@ "confirm": "确认", "confirm to delete source": "确认删除上游", "confirm to delete task?": "确认删除任务?", - "confirm to start task?": "确认开始任务?", + "confirm to start task?": "confirm to start task?", "confirm to stop task?": "确认停止任务?", "consistency requirement": "一致性要求", "create task": "创建任务", @@ -114,6 +114,8 @@ "request success": "请求成功", "requesting": "请求中", "runtime config": "运行配置", + "safe mode time duration": "Safe-Mode 持续时间", + "safe mode time duration tooltip": "定义任务启动后 safe mode 持续时长。此时间为 binlog 时间非物理时间。关于 safe mode 及此配置的详细说明,请参阅在线文档", "save": "保存", "save and run": "保存并运行", "search placeholder": "搜索", @@ -132,6 +134,12 @@ "source schema": "上游库", "source table": "上游表", "start": "开始", + "start task with params": "条件启动", + "start task with params desc": "任务将根据指定条件启动,请务必阅读参数说明", + "start task without params": "直接启动", + "start task without params desc": "任务将根据上次结束时的 checkpoint 继续同步。若第一次启动则根据配置文件指定位置或时间启动", + "start time on copy": "复制起始时间", + "start time on copy tooltip": "从指定时间点同步所有上游,已保存的同步位置信息(checkpoint)将被忽略", "status": "状态", "stop": "停用", "stop_task list": "停止", diff --git a/dm/ui/package.json b/dm/ui/package.json index fbb541df892..4ad17399f7f 100644 --- a/dm/ui/package.json +++ b/dm/ui/package.json @@ -51,7 +51,7 @@ "less": "^4.1.2", "lint-staged": "^12.1.2", "msw": "^0.36.3", - "msw-auto-mock": "^0.5.2", + "msw-auto-mock": "^0.6.0", "prettier": "^2.5.1", "rollup-plugin-visualizer": "^5.5.2", "typescript": "4.5.4", diff --git a/dm/ui/public/mockServiceWorker.js b/dm/ui/public/mockServiceWorker.js index b3997b7ef94..47f3de8bb24 100644 --- a/dm/ui/public/mockServiceWorker.js +++ b/dm/ui/public/mockServiceWorker.js @@ -16,7 +16,7 @@ self.addEventListener('install', function () { return self.skipWaiting() }) -self.addEventListener('activate', async function () { +self.addEventListener('activate', async function (event) { return self.clients.claim() }) @@ -332,7 +332,7 @@ function respondWithMock(clientMessage) { function uuidv4() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { const r = (Math.random() * 16) | 0 - const v = c === 'x' ? r : (r & 0x3) | 0x8 + const v = c == 'x' ? r : (r & 0x3) | 0x8 return v.toString(16) }) } diff --git a/dm/ui/src/mock.ts b/dm/ui/src/mock.ts index 6dd258566e7..5214cbb5ae8 100644 --- a/dm/ui/src/mock.ts +++ b/dm/ui/src/mock.ts @@ -1,537 +1,543 @@ /** - * This file is AUTO GENERATED by msw-auto-mock, you can also commit/edit it as you prefer. + * This file is AUTO GENERATED by [msw-auto-mock](https://github.com/zoubingwu/msw-auto-mock) + * Feel free to commit/edit it as you need. */ /* eslint-disable */ +/* tslint:disable */ import { setupWorker, rest } from 'msw' import faker from '@faker-js/faker' faker.seed(1) +const baseURL = '' const MAX_ARRAY_LENGTH = 20 +const gen = (function* () { + let i = 0 + while (true) { + if (i === Number.MAX_SAFE_INTEGER - 1) { + i = 0 + } + yield i++ + } +})() + export const handlers = [ - rest.get('/api/v1/cluster/info', (req, res, ctx) => { - const resultArray = [ - [ - ctx.status(200), - ctx.json({ - cluster_id: faker.datatype.number(), - }), - ], - ] - return res(...faker.random.arrayElement(resultArray)) + rest.get(`${baseURL}/api/v1/docs`, (req, res, ctx) => { + const resultArray = [[ctx.status(200), ctx.json(null)]] + + return res(...resultArray[gen.next().value % resultArray.length]) }), - rest.get('/api/v1/cluster/masters', (req, res, ctx) => { + rest.get(`${baseURL}/api/v1/dm.json`, (req, res, ctx) => { + const resultArray = [[ctx.status(200), ctx.json(null)]] + + return res(...resultArray[gen.next().value % resultArray.length]) + }), + rest.post(`${baseURL}/api/v1/sources`, (req, res, ctx) => { const resultArray = [ [ - ctx.status(200), + ctx.status(201), ctx.json({ - data: [ + source_name: 'mysql-01' + '_' + faker.datatype.uuid(), + host: '127.0.0.1', + port: 3306, + user: 'root', + password: '123456', + enable_gtid: faker.datatype.boolean(), + enable: faker.datatype.boolean(), + flavor: 'mysql', + task_name_list: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => ({ - addr: faker.lorem.slug(), - alive: faker.datatype.boolean(), - leader: faker.datatype.boolean(), - name: faker.lorem.slug(), - })), - total: faker.datatype.number(), - }), - ], - [ - ctx.status(400), - ctx.json({ - error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), - }), - ], - ] - return res(...faker.random.arrayElement(resultArray)) - }), - rest.delete('/api/v1/cluster/masters/:masterName', (req, res, ctx) => { - const resultArray = [ - [ctx.status(204), ctx.json(null)], - [ - ctx.status(400), - ctx.json({ - error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), - }), - ], - ] - return res(...faker.random.arrayElement(resultArray)) - }), - rest.get('/api/v1/cluster/workers', (req, res, ctx) => { - const resultArray = [ - [ - ctx.status(200), - ctx.json({ - data: [ + ].map(_ => 'task1'), + security: { + ssl_ca_content: faker.lorem.slug(1), + ssl_cert_content: faker.lorem.slug(1), + ssl_key_content: faker.lorem.slug(1), + cert_allowed_cn: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + }, + purge: { + interval: faker.datatype.number(), + expires: faker.datatype.number(), + remain_space: faker.datatype.number(), + }, + status_list: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ - addr: faker.lorem.slug(), - bound_source_name: faker.lorem.slug(), - bound_stage: faker.lorem.slug(), - name: faker.lorem.slug(), + source_name: 'mysql-replica-01', + worker_name: 'worker-1', + relay_status: { + master_binlog: '(mysql-bin.000001, 1979)', + master_binlog_gtid: 'e9a1fc22-ec08-11e9-b2ac-0242ac110003:1-7849', + relay_dir: './sub_dir', + relay_binlog_gtid: 'e9a1fc22-ec08-11e9-b2ac-0242ac110003:1-7849', + relay_catch_up_master: faker.datatype.boolean(), + stage: 'Running', + }, + error_msg: faker.lorem.slug(1), })), - total: faker.datatype.number(), - }), - ], - [ - ctx.status(400), - ctx.json({ - error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), + relay_config: { + enable_relay: faker.datatype.boolean(), + relay_binlog_name: 'mysql-bin.000002', + relay_binlog_gtid: 'e9a1fc22-ec08-11e9-b2ac-0242ac110003:1-7849', + relay_dir: faker.lorem.slug(1), + }, }), ], - ] - return res(...faker.random.arrayElement(resultArray)) - }), - rest.delete('/api/v1/cluster/workers/:workerName', (req, res, ctx) => { - const resultArray = [ - [ctx.status(204), ctx.json(null)], [ ctx.status(400), ctx.json({ + error_msg: faker.lorem.slug(1), error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), }), ], ] - return res(...faker.random.arrayElement(resultArray)) - }), - rest.get('/api/v1/dm.json', (req, res, ctx) => { - const resultArray = [[ctx.status(200), ctx.json(null)]] - return res(...faker.random.arrayElement(resultArray)) - }), - rest.get('/api/v1/docs', (req, res, ctx) => { - const resultArray = [[ctx.status(200), ctx.json(null)]] - return res(...faker.random.arrayElement(resultArray)) + + return res(...resultArray[gen.next().value % resultArray.length]) }), - rest.get('/api/v1/sources', (req, res, ctx) => { + rest.get(`${baseURL}/api/v1/sources`, (req, res, ctx) => { const resultArray = [ [ ctx.status(200), ctx.json({ + total: faker.datatype.number(), data: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ + source_name: 'mysql-01', + host: '127.0.0.1', + port: 3306, + user: 'root', + password: '123456', enable_gtid: faker.datatype.boolean(), - host: faker.lorem.slug(), - password: faker.lorem.slug(), - port: faker.datatype.number(), - purge: { - expires: faker.datatype.number(), - interval: faker.datatype.number(), - remain_space: faker.datatype.number(), - }, - relay_config: { - enable_relay: faker.datatype.boolean(), - relay_binlog_gtid: faker.lorem.slug(), - relay_binlog_name: faker.lorem.slug(), - relay_dir: faker.lorem.slug(), - }, + enable: faker.datatype.boolean(), + flavor: 'mysql', + task_name_list: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => 'task1'), security: { + ssl_ca_content: faker.lorem.slug(1), + ssl_cert_content: faker.lorem.slug(1), + ssl_key_content: faker.lorem.slug(1), cert_allowed_cn: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - ssl_ca_content: faker.lorem.slug(), - ssl_cert_content: faker.lorem.slug(), - ssl_key_content: faker.lorem.slug(), + ].map(_ => faker.lorem.slug(1)), + }, + purge: { + interval: faker.datatype.number(), + expires: faker.datatype.number(), + remain_space: faker.datatype.number(), }, - source_name: faker.lorem.slug(), status_list: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ - error_msg: faker.lorem.slug(), + source_name: 'mysql-replica-01', + worker_name: 'worker-1', relay_status: { - master_binlog: faker.lorem.slug(), - master_binlog_gtid: faker.lorem.slug(), - relay_binlog_gtid: faker.lorem.slug(), + master_binlog: '(mysql-bin.000001, 1979)', + master_binlog_gtid: + 'e9a1fc22-ec08-11e9-b2ac-0242ac110003:1-7849', + relay_dir: './sub_dir', + relay_binlog_gtid: + 'e9a1fc22-ec08-11e9-b2ac-0242ac110003:1-7849', relay_catch_up_master: faker.datatype.boolean(), - relay_dir: faker.lorem.slug(), - stage: faker.lorem.slug(), + stage: 'Running', }, - source_name: faker.lorem.slug(), - worker_name: faker.lorem.slug(), + error_msg: faker.lorem.slug(1), })), - user: faker.lorem.slug(), + relay_config: { + enable_relay: faker.datatype.boolean(), + relay_binlog_name: 'mysql-bin.000002', + relay_binlog_gtid: 'e9a1fc22-ec08-11e9-b2ac-0242ac110003:1-7849', + relay_dir: faker.lorem.slug(1), + }, })), - total: faker.datatype.number(), }), ], ] - return res(...faker.random.arrayElement(resultArray)) + + return res(...resultArray[gen.next().value % resultArray.length]) }), - rest.post('/api/v1/sources', (req, res, ctx) => { + rest.get(`${baseURL}/api/v1/sources/:sourceName`, (req, res, ctx) => { const resultArray = [ [ - ctx.status(201), + ctx.status(200), ctx.json({ + source_name: 'mysql-01', + host: '127.0.0.1', + port: 3306, + user: 'root', + password: '123456', enable_gtid: faker.datatype.boolean(), - host: faker.lorem.slug(), - password: faker.lorem.slug(), - port: faker.datatype.number(), - purge: { - expires: faker.datatype.number(), - interval: faker.datatype.number(), - remain_space: faker.datatype.number(), - }, - relay_config: { - enable_relay: faker.datatype.boolean(), - relay_binlog_gtid: faker.lorem.slug(), - relay_binlog_name: faker.lorem.slug(), - relay_dir: faker.lorem.slug(), - }, + enable: faker.datatype.boolean(), + flavor: 'mysql', + task_name_list: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => 'task1'), security: { + ssl_ca_content: faker.lorem.slug(1), + ssl_cert_content: faker.lorem.slug(1), + ssl_key_content: faker.lorem.slug(1), cert_allowed_cn: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - ssl_ca_content: faker.lorem.slug(), - ssl_cert_content: faker.lorem.slug(), - ssl_key_content: faker.lorem.slug(), + ].map(_ => faker.lorem.slug(1)), + }, + purge: { + interval: faker.datatype.number(), + expires: faker.datatype.number(), + remain_space: faker.datatype.number(), }, - source_name: faker.lorem.slug(), status_list: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ - error_msg: faker.lorem.slug(), + source_name: 'mysql-replica-01', + worker_name: 'worker-1', relay_status: { - master_binlog: faker.lorem.slug(), - master_binlog_gtid: faker.lorem.slug(), - relay_binlog_gtid: faker.lorem.slug(), + master_binlog: '(mysql-bin.000001, 1979)', + master_binlog_gtid: 'e9a1fc22-ec08-11e9-b2ac-0242ac110003:1-7849', + relay_dir: './sub_dir', + relay_binlog_gtid: 'e9a1fc22-ec08-11e9-b2ac-0242ac110003:1-7849', relay_catch_up_master: faker.datatype.boolean(), - relay_dir: faker.lorem.slug(), - stage: faker.lorem.slug(), + stage: 'Running', }, - source_name: faker.lorem.slug(), - worker_name: faker.lorem.slug(), + error_msg: faker.lorem.slug(1), })), - user: faker.lorem.slug(), - }), - ], - [ - ctx.status(400), - ctx.json({ - error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), + relay_config: { + enable_relay: faker.datatype.boolean(), + relay_binlog_name: 'mysql-bin.000002', + relay_binlog_gtid: 'e9a1fc22-ec08-11e9-b2ac-0242ac110003:1-7849', + relay_dir: faker.lorem.slug(1), + }, }), ], + [ctx.status(404), ctx.json(null)], ] - return res(...faker.random.arrayElement(resultArray)) + + return res(...resultArray[gen.next().value % resultArray.length]) }), - rest.delete('/api/v1/sources/:sourceName', (req, res, ctx) => { + rest.delete(`${baseURL}/api/v1/sources/:sourceName`, (req, res, ctx) => { const resultArray = [ [ctx.status(204), ctx.json(null)], [ ctx.status(400), ctx.json({ + error_msg: faker.lorem.slug(1), error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), }), ], ] - return res(...faker.random.arrayElement(resultArray)) + + return res(...resultArray[gen.next().value % resultArray.length]) }), - rest.get('/api/v1/sources/:sourceName', (req, res, ctx) => { + rest.put(`${baseURL}/api/v1/sources/:sourceName`, (req, res, ctx) => { const resultArray = [ [ ctx.status(200), ctx.json({ + source_name: 'mysql-01', + host: '127.0.0.1', + port: 3306, + user: 'root', + password: '123456', enable_gtid: faker.datatype.boolean(), - host: faker.lorem.slug(), - password: faker.lorem.slug(), - port: faker.datatype.number(), - purge: { - expires: faker.datatype.number(), - interval: faker.datatype.number(), - remain_space: faker.datatype.number(), - }, - relay_config: { - enable_relay: faker.datatype.boolean(), - relay_binlog_gtid: faker.lorem.slug(), - relay_binlog_name: faker.lorem.slug(), - relay_dir: faker.lorem.slug(), - }, + enable: faker.datatype.boolean(), + flavor: 'mysql', + task_name_list: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => 'task1'), security: { + ssl_ca_content: faker.lorem.slug(1), + ssl_cert_content: faker.lorem.slug(1), + ssl_key_content: faker.lorem.slug(1), cert_allowed_cn: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - ssl_ca_content: faker.lorem.slug(), - ssl_cert_content: faker.lorem.slug(), - ssl_key_content: faker.lorem.slug(), + ].map(_ => faker.lorem.slug(1)), }, - source_name: faker.lorem.slug(), - status_list: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => ({ - error_msg: faker.lorem.slug(), - relay_status: { - master_binlog: faker.lorem.slug(), - master_binlog_gtid: faker.lorem.slug(), - relay_binlog_gtid: faker.lorem.slug(), - relay_catch_up_master: faker.datatype.boolean(), - relay_dir: faker.lorem.slug(), - stage: faker.lorem.slug(), - }, - source_name: faker.lorem.slug(), - worker_name: faker.lorem.slug(), - })), - user: faker.lorem.slug(), - }), - ], - [ctx.status(404), ctx.json(null)], - ] - return res(...faker.random.arrayElement(resultArray)) - }), - rest.put('/api/v1/sources/:sourceName', (req, res, ctx) => { - const resultArray = [ - [ - ctx.status(200), - ctx.json({ - enable_gtid: faker.datatype.boolean(), - host: faker.lorem.slug(), - password: faker.lorem.slug(), - port: faker.datatype.number(), purge: { - expires: faker.datatype.number(), interval: faker.datatype.number(), + expires: faker.datatype.number(), remain_space: faker.datatype.number(), }, - relay_config: { - enable_relay: faker.datatype.boolean(), - relay_binlog_gtid: faker.lorem.slug(), - relay_binlog_name: faker.lorem.slug(), - relay_dir: faker.lorem.slug(), - }, - security: { - cert_allowed_cn: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()), - ssl_ca_content: faker.lorem.slug(), - ssl_cert_content: faker.lorem.slug(), - ssl_key_content: faker.lorem.slug(), - }, - source_name: faker.lorem.slug(), status_list: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ - error_msg: faker.lorem.slug(), + source_name: 'mysql-replica-01', + worker_name: 'worker-1', relay_status: { - master_binlog: faker.lorem.slug(), - master_binlog_gtid: faker.lorem.slug(), - relay_binlog_gtid: faker.lorem.slug(), + master_binlog: '(mysql-bin.000001, 1979)', + master_binlog_gtid: 'e9a1fc22-ec08-11e9-b2ac-0242ac110003:1-7849', + relay_dir: './sub_dir', + relay_binlog_gtid: 'e9a1fc22-ec08-11e9-b2ac-0242ac110003:1-7849', relay_catch_up_master: faker.datatype.boolean(), - relay_dir: faker.lorem.slug(), - stage: faker.lorem.slug(), + stage: 'Running', }, - source_name: faker.lorem.slug(), - worker_name: faker.lorem.slug(), + error_msg: faker.lorem.slug(1), })), - user: faker.lorem.slug(), - }), - ], - [ - ctx.status(400), - ctx.json({ - error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), - }), - ], - ] - return res(...faker.random.arrayElement(resultArray)) - }), - rest.post('/api/v1/sources/:sourceName/disable', (req, res, ctx) => { - const resultArray = [ - [ctx.status(200), ctx.json(null)], - [ - ctx.status(400), - ctx.json({ - error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), + relay_config: { + enable_relay: faker.datatype.boolean(), + relay_binlog_name: 'mysql-bin.000002', + relay_binlog_gtid: 'e9a1fc22-ec08-11e9-b2ac-0242ac110003:1-7849', + relay_dir: faker.lorem.slug(1), + }, }), ], - ] - return res(...faker.random.arrayElement(resultArray)) - }), - rest.post('/api/v1/sources/:sourceName/enable', (req, res, ctx) => { - const resultArray = [ - [ctx.status(200), ctx.json(null)], [ ctx.status(400), ctx.json({ + error_msg: faker.lorem.slug(1), error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), }), ], ] - return res(...faker.random.arrayElement(resultArray)) + + return res(...resultArray[gen.next().value % resultArray.length]) }), - rest.post('/api/v1/sources/:sourceName/relay/disable', (req, res, ctx) => { + rest.get(`${baseURL}/api/v1/sources/:sourceName/status`, (req, res, ctx) => { const resultArray = [ - [ctx.status(200), ctx.json(null)], [ - ctx.status(400), + ctx.status(200), ctx.json({ - error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), + total: faker.datatype.number(), + data: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + source_name: 'mysql-replica-01', + worker_name: 'worker-1', + relay_status: { + master_binlog: '(mysql-bin.000001, 1979)', + master_binlog_gtid: 'e9a1fc22-ec08-11e9-b2ac-0242ac110003:1-7849', + relay_dir: './sub_dir', + relay_binlog_gtid: 'e9a1fc22-ec08-11e9-b2ac-0242ac110003:1-7849', + relay_catch_up_master: faker.datatype.boolean(), + stage: 'Running', + }, + error_msg: faker.lorem.slug(1), + })), }), ], - ] - return res(...faker.random.arrayElement(resultArray)) - }), - rest.post('/api/v1/sources/:sourceName/relay/enable', (req, res, ctx) => { - const resultArray = [ - [ctx.status(200), ctx.json(null)], [ ctx.status(400), ctx.json({ + error_msg: faker.lorem.slug(1), error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), }), ], ] - return res(...faker.random.arrayElement(resultArray)) + + return res(...resultArray[gen.next().value % resultArray.length]) }), - rest.post('/api/v1/sources/:sourceName/relay/purge', (req, res, ctx) => { + rest.post(`${baseURL}/api/v1/sources/:sourceName/enable`, (req, res, ctx) => { const resultArray = [ [ctx.status(200), ctx.json(null)], [ ctx.status(400), ctx.json({ + error_msg: faker.lorem.slug(1), error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), - }), - ], - ] - return res(...faker.random.arrayElement(resultArray)) - }), - rest.get('/api/v1/sources/:sourceName/schemas', (req, res, ctx) => { - const resultArray = [ - [ - ctx.status(200), - ctx.json( - [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()) - ), - ], - [ - ctx.status(400), - ctx.json({ - error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), }), ], ] - return res(...faker.random.arrayElement(resultArray)) + + return res(...resultArray[gen.next().value % resultArray.length]) }), - rest.get( - '/api/v1/sources/:sourceName/schemas/:schemaName', + rest.post( + `${baseURL}/api/v1/sources/:sourceName/disable`, (req, res, ctx) => { const resultArray = [ - [ - ctx.status(200), - ctx.json( - [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()) - ), - ], + [ctx.status(200), ctx.json(null)], [ ctx.status(400), ctx.json({ + error_msg: faker.lorem.slug(1), error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), }), ], ] - return res(...faker.random.arrayElement(resultArray)) + + return res(...resultArray[gen.next().value % resultArray.length]) } ), - rest.get('/api/v1/sources/:sourceName/status', (req, res, ctx) => { - const resultArray = [ - [ - ctx.status(200), - ctx.json({ - data: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => ({ - error_msg: faker.lorem.slug(), - relay_status: { - master_binlog: faker.lorem.slug(), - master_binlog_gtid: faker.lorem.slug(), - relay_binlog_gtid: faker.lorem.slug(), - relay_catch_up_master: faker.datatype.boolean(), - relay_dir: faker.lorem.slug(), - stage: faker.lorem.slug(), - }, - source_name: faker.lorem.slug(), - worker_name: faker.lorem.slug(), - })), - total: faker.datatype.number(), - }), - ], + rest.post( + `${baseURL}/api/v1/sources/:sourceName/transfer`, + (req, res, ctx) => { + const resultArray = [ + [ctx.status(200), ctx.json(null)], + [ + ctx.status(400), + ctx.json({ + error_msg: faker.lorem.slug(1), + error_code: faker.datatype.number(), + }), + ], + ] + + return res(...resultArray[gen.next().value % resultArray.length]) + } + ), + rest.post( + `${baseURL}/api/v1/sources/:sourceName/relay/enable`, + (req, res, ctx) => { + const resultArray = [ + [ctx.status(200), ctx.json(null)], + [ + ctx.status(400), + ctx.json({ + error_msg: faker.lorem.slug(1), + error_code: faker.datatype.number(), + }), + ], + ] + + return res(...resultArray[gen.next().value % resultArray.length]) + } + ), + rest.post( + `${baseURL}/api/v1/sources/:sourceName/relay/disable`, + (req, res, ctx) => { + const resultArray = [ + [ctx.status(200), ctx.json(null)], + [ + ctx.status(400), + ctx.json({ + error_msg: faker.lorem.slug(1), + error_code: faker.datatype.number(), + }), + ], + ] + + return res(...resultArray[gen.next().value % resultArray.length]) + } + ), + rest.post( + `${baseURL}/api/v1/sources/:sourceName/relay/purge`, + (req, res, ctx) => { + const resultArray = [ + [ctx.status(200), ctx.json(null)], + [ + ctx.status(400), + ctx.json({ + error_msg: faker.lorem.slug(1), + error_code: faker.datatype.number(), + }), + ], + ] + + return res(...resultArray[gen.next().value % resultArray.length]) + } + ), + rest.get(`${baseURL}/api/v1/sources/:sourceName/schemas`, (req, res, ctx) => { + const resultArray = [ [ - ctx.status(400), - ctx.json({ - error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), - }), + ctx.status(200), + ctx.json( + [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => 'db1') + ), ], - ] - return res(...faker.random.arrayElement(resultArray)) - }), - rest.post('/api/v1/sources/:sourceName/transfer', (req, res, ctx) => { - const resultArray = [ - [ctx.status(200), ctx.json(null)], [ ctx.status(400), ctx.json({ + error_msg: faker.lorem.slug(1), error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), }), ], ] - return res(...faker.random.arrayElement(resultArray)) + + return res(...resultArray[gen.next().value % resultArray.length]) }), - rest.get('/api/v1/tasks', (req, res, ctx) => { + rest.get( + `${baseURL}/api/v1/sources/:sourceName/schemas/:schemaName`, + (req, res, ctx) => { + const resultArray = [ + [ + ctx.status(200), + ctx.json( + [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => 'table1') + ), + ], + [ + ctx.status(400), + ctx.json({ + error_msg: faker.lorem.slug(1), + error_code: faker.datatype.number(), + }), + ], + ] + + return res(...resultArray[gen.next().value % resultArray.length]) + } + ), + rest.post(`${baseURL}/api/v1/tasks`, (req, res, ctx) => { const resultArray = [ [ - ctx.status(200), + ctx.status(201), ctx.json({ - data: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => ({ + task: { + name: 'task-1', + task_mode: 'all', + shard_mode: faker.random.arrayElement([ + 'pessimistic', + 'optimistic', + ]), + meta_schema: 'dm-meta', + enhance_online_schema_change: true, + on_duplicate: faker.random.arrayElement([ + 'replace', + 'error', + 'ignore', + ]), + target_config: { + host: '127.0.0.1', + port: 3306, + user: 'root', + password: '123456', + security: { + ssl_ca_content: faker.lorem.slug(1), + ssl_cert_content: faker.lorem.slug(1), + ssl_key_content: faker.lorem.slug(1), + cert_allowed_cn: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + }, + }, binlog_filter_rule: [...new Array(5).keys()] .map(_ => ({ [faker.lorem.word()]: { @@ -539,43 +545,56 @@ export const handlers = [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), + ].map(_ => 'all dml'), ignore_sql: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), + ].map(_ => '^Drop'), }, })) .reduce((acc, next) => Object.assign(acc, next), {}), - enhance_online_schema_change: faker.datatype.boolean(), - meta_schema: faker.lorem.slug(), - name: faker.lorem.slug(), - on_duplicate: faker.random.arrayElement(['overwrite', 'error']), - shard_mode: faker.random.arrayElement([ - 'pessimistic', - 'optimistic', - ]), + table_migrate_rule: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + source: { + source_name: 'source-name', + schema: 'db-*', + table: 'tb-*', + }, + target: { + schema: 'db1', + table: 'tb1', + }, + binlog_filter_rule: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => 'rule-1'), + })), source_config: { full_migrate_conf: { - consistency: faker.lorem.slug(), - data_dir: faker.lorem.slug(), export_threads: faker.datatype.number(), import_threads: faker.datatype.number(), + data_dir: './exported_data', + consistency: 'auto', }, incr_migrate_conf: { - repl_batch: faker.datatype.number(), repl_threads: faker.datatype.number(), + repl_batch: faker.datatype.number(), }, source_conf: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ - binlog_gtid: faker.lorem.slug(), - binlog_name: faker.lorem.slug(), - binlog_pos: faker.datatype.number(), - source_name: faker.lorem.slug(), + source_name: 'mysql-replica-01', + binlog_name: 'binlog.000001', + binlog_pos: 4, + binlog_gtid: + '03fc0263-28c7-11e7-a653-6c0b84d59f30:1-7041423,05474d3c-28c7-11e7-8352-203db246dd3d:1-170', })), }, status_list: [ @@ -583,305 +602,132 @@ export const handlers = [ faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ - dump_status: { - completed_tables: faker.datatype.number(), - estimate_total_rows: faker.datatype.number(), - finished_bytes: faker.datatype.number(), - finished_rows: faker.datatype.number(), - total_tables: faker.datatype.number(), - }, - error_msg: faker.lorem.slug(), - load_status: { - finished_bytes: faker.datatype.number(), - meta_binlog: faker.lorem.slug(), - meta_binlog_gtid: faker.lorem.slug(), - progress: faker.lorem.slug(), - total_bytes: faker.datatype.number(), - }, - name: faker.lorem.slug(), - source_name: faker.lorem.slug(), + name: faker.name.findName(), + source_name: faker.name.findName(), + worker_name: faker.name.findName(), stage: faker.random.arrayElement([ 'Stopped', 'Running', 'Finished', ]), + unit: 'sync', + unresolved_ddl_lock_id: faker.lorem.slug(1), + load_status: { + finished_bytes: faker.datatype.number(), + total_bytes: faker.datatype.number(), + progress: faker.lorem.slug(1), + meta_binlog: faker.lorem.slug(1), + meta_binlog_gtid: faker.lorem.slug(1), + }, sync_status: { - binlog_type: faker.lorem.slug(), + total_events: faker.datatype.number(), + total_tps: faker.datatype.number(), + recent_tps: faker.datatype.number(), + master_binlog: faker.lorem.slug(1), + master_binlog_gtid: faker.lorem.slug(1), + syncer_binlog: faker.lorem.slug(1), + syncer_binlog_gtid: faker.lorem.slug(1), blocking_ddls: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - master_binlog: faker.lorem.slug(), - master_binlog_gtid: faker.lorem.slug(), - recent_tps: faker.datatype.number(), - seconds_behind_master: faker.datatype.number(), - synced: faker.datatype.boolean(), - syncer_binlog: faker.lorem.slug(), - syncer_binlog_gtid: faker.lorem.slug(), - total_events: faker.datatype.number(), - total_tps: faker.datatype.number(), + ].map(_ => faker.lorem.slug(1)), unresolved_groups: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ + target: faker.lorem.slug(1), ddl_list: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - first_location: faker.lorem.slug(), + ].map(_ => faker.lorem.slug(1)), + first_location: faker.lorem.slug(1), synced: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - target: faker.lorem.slug(), + ].map(_ => faker.lorem.slug(1)), unsynced: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), + ].map(_ => faker.lorem.slug(1)), })), + synced: faker.datatype.boolean(), + binlog_type: faker.lorem.slug(1), + seconds_behind_master: faker.datatype.number(), + }, + dump_status: { + total_tables: faker.datatype.number(), + completed_tables: faker.datatype.number(), + finished_bytes: faker.datatype.number(), + finished_rows: faker.datatype.number(), + estimate_total_rows: faker.datatype.number(), }, - unit: faker.lorem.slug(), - unresolved_ddl_lock_id: faker.lorem.slug(), - worker_name: faker.lorem.slug(), + error_msg: faker.lorem.slug(1), })), - table_migrate_rule: [ + ignore_checking_items: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => ({ - binlog_filter_rule: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()), - source: { - schema: faker.lorem.slug(), - source_name: faker.lorem.slug(), - table: faker.lorem.slug(), - }, - target: { - schema: faker.lorem.slug(), - table: faker.lorem.slug(), - }, - })), - target_config: { - host: faker.lorem.slug(), - password: faker.lorem.slug(), - port: faker.datatype.number(), - security: { - cert_allowed_cn: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()), - ssl_ca_content: faker.lorem.slug(), - ssl_cert_content: faker.lorem.slug(), - ssl_key_content: faker.lorem.slug(), - }, - user: faker.lorem.slug(), - }, - task_mode: faker.random.arrayElement([ - 'full', - 'incremental', - 'all', - ]), - })), - total: faker.datatype.number(), - }), - ], - [ - ctx.status(400), - ctx.json({ - error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), + ].map(_ => 'version'), + }, + check_result: 'pre-check is passed. ', }), ], - ] - return res(...faker.random.arrayElement(resultArray)) - }), - rest.post('/api/v1/tasks', (req, res, ctx) => { - const resultArray = [ - // [ - // ctx.status(201), - // ctx.json({ - // binlog_filter_rule: [...new Array(5).keys()] - // .map(_ => ({ - // [faker.lorem.word()]: { - // ignore_event: [ - // ...new Array( - // faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - // ).keys(), - // ].map(_ => faker.lorem.slug()), - // ignore_sql: [ - // ...new Array( - // faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - // ).keys(), - // ].map(_ => faker.lorem.slug()), - // }, - // })) - // .reduce((acc, next) => Object.assign(acc, next), {}), - // enhance_online_schema_change: faker.datatype.boolean(), - // meta_schema: faker.lorem.slug(), - // name: faker.lorem.slug(), - // on_duplicate: faker.random.arrayElement(['overwrite', 'error']), - // shard_mode: faker.random.arrayElement(['pessimistic', 'optimistic']), - // source_config: { - // full_migrate_conf: { - // consistency: faker.lorem.slug(), - // data_dir: faker.lorem.slug(), - // export_threads: faker.datatype.number(), - // import_threads: faker.datatype.number(), - // }, - // incr_migrate_conf: { - // repl_batch: faker.datatype.number(), - // repl_threads: faker.datatype.number(), - // }, - // source_conf: [ - // ...new Array( - // faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - // ).keys(), - // ].map(_ => ({ - // binlog_gtid: faker.lorem.slug(), - // binlog_name: faker.lorem.slug(), - // binlog_pos: faker.datatype.number(), - // source_name: faker.lorem.slug(), - // })), - // }, - // status_list: [ - // ...new Array( - // faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - // ).keys(), - // ].map(_ => ({ - // dump_status: { - // completed_tables: faker.datatype.number(), - // estimate_total_rows: faker.datatype.number(), - // finished_bytes: faker.datatype.number(), - // finished_rows: faker.datatype.number(), - // total_tables: faker.datatype.number(), - // }, - // error_msg: faker.lorem.slug(), - // load_status: { - // finished_bytes: faker.datatype.number(), - // meta_binlog: faker.lorem.slug(), - // meta_binlog_gtid: faker.lorem.slug(), - // progress: faker.lorem.slug(), - // total_bytes: faker.datatype.number(), - // }, - // name: faker.lorem.slug(), - // source_name: faker.lorem.slug(), - // stage: faker.random.arrayElement([ - // 'Stopped', - // 'Running', - // 'Finished', - // ]), - // sync_status: { - // binlog_type: faker.lorem.slug(), - // blocking_ddls: [ - // ...new Array( - // faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - // ).keys(), - // ].map(_ => faker.lorem.slug()), - // master_binlog: faker.lorem.slug(), - // master_binlog_gtid: faker.lorem.slug(), - // recent_tps: faker.datatype.number(), - // seconds_behind_master: faker.datatype.number(), - // synced: faker.datatype.boolean(), - // syncer_binlog: faker.lorem.slug(), - // syncer_binlog_gtid: faker.lorem.slug(), - // total_events: faker.datatype.number(), - // total_tps: faker.datatype.number(), - // unresolved_groups: [ - // ...new Array( - // faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - // ).keys(), - // ].map(_ => ({ - // ddl_list: [ - // ...new Array( - // faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - // ).keys(), - // ].map(_ => faker.lorem.slug()), - // first_location: faker.lorem.slug(), - // synced: [ - // ...new Array( - // faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - // ).keys(), - // ].map(_ => faker.lorem.slug()), - // target: faker.lorem.slug(), - // unsynced: [ - // ...new Array( - // faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - // ).keys(), - // ].map(_ => faker.lorem.slug()), - // })), - // }, - // unit: faker.lorem.slug(), - // unresolved_ddl_lock_id: faker.lorem.slug(), - // worker_name: faker.lorem.slug(), - // })), - // table_migrate_rule: [ - // ...new Array( - // faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - // ).keys(), - // ].map(_ => ({ - // binlog_filter_rule: [ - // ...new Array( - // faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - // ).keys(), - // ].map(_ => faker.lorem.slug()), - // source: { - // schema: faker.lorem.slug(), - // source_name: faker.lorem.slug(), - // table: faker.lorem.slug(), - // }, - // target: { - // schema: faker.lorem.slug(), - // table: faker.lorem.slug(), - // }, - // })), - // target_config: { - // host: faker.lorem.slug(), - // password: faker.lorem.slug(), - // port: faker.datatype.number(), - // security: { - // cert_allowed_cn: [ - // ...new Array( - // faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - // ).keys(), - // ].map(_ => faker.lorem.slug()), - // ssl_ca_content: faker.lorem.slug(), - // ssl_cert_content: faker.lorem.slug(), - // ssl_key_content: faker.lorem.slug(), - // }, - // user: faker.lorem.slug(), - // }, - // task_mode: faker.random.arrayElement(['full', 'incremental', 'all']), - // }), - // ], [ ctx.status(400), ctx.json({ + error_msg: faker.lorem.slug(1), error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), }), ], ] - return res(...faker.random.arrayElement(resultArray)) + + return res(...resultArray[gen.next().value % resultArray.length]) }), - rest.get('/api/v1/tasks/templates', (req, res, ctx) => { + rest.get(`${baseURL}/api/v1/tasks`, (req, res, ctx) => { const resultArray = [ [ ctx.status(200), ctx.json({ + total: faker.datatype.number(), data: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ + name: 'task-1' + '_' + faker.lorem.slug(), + task_mode: 'all', + shard_mode: faker.random.arrayElement([ + 'pessimistic', + 'optimistic', + ]), + meta_schema: 'dm-meta', + enhance_online_schema_change: true, + on_duplicate: faker.random.arrayElement([ + 'replace', + 'error', + 'ignore', + ]), + target_config: { + host: '127.0.0.1', + port: 3306, + user: 'root', + password: '123456', + security: { + ssl_ca_content: faker.lorem.slug(1), + ssl_cert_content: faker.lorem.slug(1), + ssl_key_content: faker.lorem.slug(1), + cert_allowed_cn: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + }, + }, binlog_filter_rule: [...new Array(5).keys()] .map(_ => ({ [faker.lorem.word()]: { @@ -889,43 +735,56 @@ export const handlers = [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), + ].map(_ => 'all dml'), ignore_sql: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), + ].map(_ => '^Drop'), }, })) .reduce((acc, next) => Object.assign(acc, next), {}), - enhance_online_schema_change: faker.datatype.boolean(), - meta_schema: faker.lorem.slug(), - name: faker.lorem.slug(), - on_duplicate: faker.random.arrayElement(['overwrite', 'error']), - shard_mode: faker.random.arrayElement([ - 'pessimistic', - 'optimistic', - ]), + table_migrate_rule: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + source: { + source_name: 'source-name', + schema: 'db-*', + table: 'tb-*', + }, + target: { + schema: 'db1', + table: 'tb1', + }, + binlog_filter_rule: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => 'rule-1'), + })), source_config: { full_migrate_conf: { - consistency: faker.lorem.slug(), - data_dir: faker.lorem.slug(), export_threads: faker.datatype.number(), import_threads: faker.datatype.number(), + data_dir: './exported_data', + consistency: 'auto', }, incr_migrate_conf: { - repl_batch: faker.datatype.number(), repl_threads: faker.datatype.number(), + repl_batch: faker.datatype.number(), }, source_conf: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ - binlog_gtid: faker.lorem.slug(), - binlog_name: faker.lorem.slug(), - binlog_pos: faker.datatype.number(), - source_name: faker.lorem.slug(), + source_name: 'mysql-replica-01', + binlog_name: 'binlog.000001', + binlog_pos: 4, + binlog_gtid: + '03fc0263-28c7-11e7-a653-6c0b84d59f30:1-7041423,05474d3c-28c7-11e7-8352-203db246dd3d:1-170', })), }, status_list: [ @@ -933,132 +792,122 @@ export const handlers = [ faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ - dump_status: { - completed_tables: faker.datatype.number(), - estimate_total_rows: faker.datatype.number(), - finished_bytes: faker.datatype.number(), - finished_rows: faker.datatype.number(), - total_tables: faker.datatype.number(), - }, - error_msg: faker.lorem.slug(), - load_status: { - finished_bytes: faker.datatype.number(), - meta_binlog: faker.lorem.slug(), - meta_binlog_gtid: faker.lorem.slug(), - progress: faker.lorem.slug(), - total_bytes: faker.datatype.number(), - }, - name: faker.lorem.slug(), - source_name: faker.lorem.slug(), + name: faker.name.findName(), + source_name: faker.name.findName(), + worker_name: faker.name.findName(), stage: faker.random.arrayElement([ 'Stopped', 'Running', 'Finished', ]), - sync_status: { - binlog_type: faker.lorem.slug(), - blocking_ddls: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()), - master_binlog: faker.lorem.slug(), - master_binlog_gtid: faker.lorem.slug(), - recent_tps: faker.datatype.number(), - seconds_behind_master: faker.datatype.number(), - synced: faker.datatype.boolean(), - syncer_binlog: faker.lorem.slug(), - syncer_binlog_gtid: faker.lorem.slug(), + unit: 'sync', + unresolved_ddl_lock_id: faker.lorem.slug(1), + load_status: { + finished_bytes: faker.datatype.number(), + total_bytes: faker.datatype.number(), + progress: faker.lorem.slug(1), + meta_binlog: faker.lorem.slug(1), + meta_binlog_gtid: faker.lorem.slug(1), + }, + sync_status: { total_events: faker.datatype.number(), total_tps: faker.datatype.number(), + recent_tps: faker.datatype.number(), + master_binlog: faker.lorem.slug(1), + master_binlog_gtid: faker.lorem.slug(1), + syncer_binlog: faker.lorem.slug(1), + syncer_binlog_gtid: faker.lorem.slug(1), + blocking_ddls: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), unresolved_groups: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ + target: faker.lorem.slug(1), ddl_list: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - first_location: faker.lorem.slug(), + ].map(_ => faker.lorem.slug(1)), + first_location: faker.lorem.slug(1), synced: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - target: faker.lorem.slug(), + ].map(_ => faker.lorem.slug(1)), unsynced: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), + ].map(_ => faker.lorem.slug(1)), })), + synced: faker.datatype.boolean(), + binlog_type: faker.lorem.slug(1), + seconds_behind_master: faker.datatype.number(), + }, + dump_status: { + total_tables: faker.datatype.number(), + completed_tables: faker.datatype.number(), + finished_bytes: faker.datatype.number(), + finished_rows: faker.datatype.number(), + estimate_total_rows: faker.datatype.number(), }, - unit: faker.lorem.slug(), - unresolved_ddl_lock_id: faker.lorem.slug(), - worker_name: faker.lorem.slug(), + error_msg: faker.lorem.slug(1), })), - table_migrate_rule: [ + ignore_checking_items: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => ({ - binlog_filter_rule: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()), - source: { - schema: faker.lorem.slug(), - source_name: faker.lorem.slug(), - table: faker.lorem.slug(), - }, - target: { - schema: faker.lorem.slug(), - table: faker.lorem.slug(), - }, - })), - target_config: { - host: faker.lorem.slug(), - password: faker.lorem.slug(), - port: faker.datatype.number(), - security: { - cert_allowed_cn: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()), - ssl_ca_content: faker.lorem.slug(), - ssl_cert_content: faker.lorem.slug(), - ssl_key_content: faker.lorem.slug(), - }, - user: faker.lorem.slug(), - }, - task_mode: faker.random.arrayElement([ - 'full', - 'incremental', - 'all', - ]), + ].map(_ => 'version'), })), - total: faker.datatype.number(), }), ], [ ctx.status(400), ctx.json({ + error_msg: faker.lorem.slug(1), error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), }), ], ] - return res(...faker.random.arrayElement(resultArray)) + + return res(...resultArray[gen.next().value % resultArray.length]) }), - rest.post('/api/v1/tasks/templates', (req, res, ctx) => { + rest.get(`${baseURL}/api/v1/tasks/:taskName`, (req, res, ctx) => { const resultArray = [ [ - ctx.status(201), + ctx.status(200), ctx.json({ + name: 'task-1', + task_mode: 'all', + shard_mode: faker.random.arrayElement(['pessimistic', 'optimistic']), + meta_schema: 'dm-meta', + enhance_online_schema_change: true, + on_duplicate: faker.random.arrayElement([ + 'replace', + 'error', + 'ignore', + ]), + target_config: { + host: '127.0.0.1', + port: 3306, + user: 'root', + password: '123456', + security: { + ssl_ca_content: faker.lorem.slug(1), + ssl_cert_content: faker.lorem.slug(1), + ssl_key_content: faker.lorem.slug(1), + cert_allowed_cn: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + }, + }, binlog_filter_rule: [...new Array(5).keys()] .map(_ => ({ [faker.lorem.word()]: { @@ -1066,40 +915,56 @@ export const handlers = [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), + ].map(_ => 'all dml'), ignore_sql: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), + ].map(_ => '^Drop'), }, })) .reduce((acc, next) => Object.assign(acc, next), {}), - enhance_online_schema_change: faker.datatype.boolean(), - meta_schema: faker.lorem.slug(), - name: faker.lorem.slug(), - on_duplicate: faker.random.arrayElement(['overwrite', 'error']), - shard_mode: faker.random.arrayElement(['pessimistic', 'optimistic']), + table_migrate_rule: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + source: { + source_name: 'source-name', + schema: 'db-*', + table: 'tb-*', + }, + target: { + schema: 'db1', + table: 'tb1', + }, + binlog_filter_rule: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => 'rule-1'), + })), source_config: { full_migrate_conf: { - consistency: faker.lorem.slug(), - data_dir: faker.lorem.slug(), export_threads: faker.datatype.number(), import_threads: faker.datatype.number(), + data_dir: './exported_data', + consistency: 'auto', }, incr_migrate_conf: { - repl_batch: faker.datatype.number(), repl_threads: faker.datatype.number(), + repl_batch: faker.datatype.number(), }, source_conf: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ - binlog_gtid: faker.lorem.slug(), - binlog_name: faker.lorem.slug(), - binlog_pos: faker.datatype.number(), - source_name: faker.lorem.slug(), + source_name: 'mysql-replica-01', + binlog_name: 'binlog.000001', + binlog_pos: 4, + binlog_gtid: + '03fc0263-28c7-11e7-a653-6c0b84d59f30:1-7041423,05474d3c-28c7-11e7-8352-203db246dd3d:1-170', })), }, status_list: [ @@ -1107,337 +972,760 @@ export const handlers = [ faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ - dump_status: { - completed_tables: faker.datatype.number(), - estimate_total_rows: faker.datatype.number(), - finished_bytes: faker.datatype.number(), - finished_rows: faker.datatype.number(), - total_tables: faker.datatype.number(), - }, - error_msg: faker.lorem.slug(), - load_status: { - finished_bytes: faker.datatype.number(), - meta_binlog: faker.lorem.slug(), - meta_binlog_gtid: faker.lorem.slug(), - progress: faker.lorem.slug(), - total_bytes: faker.datatype.number(), - }, - name: faker.lorem.slug(), - source_name: faker.lorem.slug(), + name: faker.name.findName(), + source_name: faker.name.findName(), + worker_name: faker.name.findName(), stage: faker.random.arrayElement([ 'Stopped', 'Running', 'Finished', ]), + unit: 'sync', + unresolved_ddl_lock_id: faker.lorem.slug(1), + load_status: { + finished_bytes: faker.datatype.number(), + total_bytes: faker.datatype.number(), + progress: faker.lorem.slug(1), + meta_binlog: faker.lorem.slug(1), + meta_binlog_gtid: faker.lorem.slug(1), + }, sync_status: { - binlog_type: faker.lorem.slug(), + total_events: faker.datatype.number(), + total_tps: faker.datatype.number(), + recent_tps: faker.datatype.number(), + master_binlog: faker.lorem.slug(1), + master_binlog_gtid: faker.lorem.slug(1), + syncer_binlog: faker.lorem.slug(1), + syncer_binlog_gtid: faker.lorem.slug(1), blocking_ddls: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - master_binlog: faker.lorem.slug(), - master_binlog_gtid: faker.lorem.slug(), - recent_tps: faker.datatype.number(), - seconds_behind_master: faker.datatype.number(), - synced: faker.datatype.boolean(), - syncer_binlog: faker.lorem.slug(), - syncer_binlog_gtid: faker.lorem.slug(), - total_events: faker.datatype.number(), - total_tps: faker.datatype.number(), + ].map(_ => faker.lorem.slug(1)), unresolved_groups: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ + target: faker.lorem.slug(1), ddl_list: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - first_location: faker.lorem.slug(), + ].map(_ => faker.lorem.slug(1)), + first_location: faker.lorem.slug(1), synced: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - target: faker.lorem.slug(), + ].map(_ => faker.lorem.slug(1)), unsynced: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), + ].map(_ => faker.lorem.slug(1)), })), + synced: faker.datatype.boolean(), + binlog_type: faker.lorem.slug(1), + seconds_behind_master: faker.datatype.number(), }, - unit: faker.lorem.slug(), - unresolved_ddl_lock_id: faker.lorem.slug(), - worker_name: faker.lorem.slug(), - })), - table_migrate_rule: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => ({ - binlog_filter_rule: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()), - source: { - schema: faker.lorem.slug(), - source_name: faker.lorem.slug(), - table: faker.lorem.slug(), - }, - target: { - schema: faker.lorem.slug(), - table: faker.lorem.slug(), - }, - })), - target_config: { - host: faker.lorem.slug(), - password: faker.lorem.slug(), - port: faker.datatype.number(), - security: { - cert_allowed_cn: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()), - ssl_ca_content: faker.lorem.slug(), - ssl_cert_content: faker.lorem.slug(), - ssl_key_content: faker.lorem.slug(), + dump_status: { + total_tables: faker.datatype.number(), + completed_tables: faker.datatype.number(), + finished_bytes: faker.datatype.number(), + finished_rows: faker.datatype.number(), + estimate_total_rows: faker.datatype.number(), }, - user: faker.lorem.slug(), - }, - task_mode: faker.random.arrayElement(['full', 'incremental', 'all']), - }), - ], - [ - ctx.status(400), - ctx.json({ - error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), - }), - ], - ] - return res(...faker.random.arrayElement(resultArray)) - }), - rest.post('/api/v1/tasks/templates/import', (req, res, ctx) => { - const resultArray = [ - [ - ctx.status(202), - ctx.json({ - failed_task_list: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => ({ - error_msg: faker.lorem.slug(), - task_name: faker.lorem.slug(), + error_msg: faker.lorem.slug(1), })), - success_task_list: [ + ignore_checking_items: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - }), - ], - [ - ctx.status(400), - ctx.json({ - error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), + ].map(_ => 'version'), }), ], + [ctx.status(404), ctx.json(null)], ] - return res(...faker.random.arrayElement(resultArray)) + + return res(...resultArray[gen.next().value % resultArray.length]) }), - rest.delete('/api/v1/tasks/templates/:taskName', (req, res, ctx) => { + rest.delete(`${baseURL}/api/v1/tasks/:taskName`, (req, res, ctx) => { const resultArray = [ [ctx.status(204), ctx.json(null)], [ ctx.status(400), ctx.json({ + error_msg: faker.lorem.slug(1), error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), }), ], ] - return res(...faker.random.arrayElement(resultArray)) + + return res(...resultArray[gen.next().value % resultArray.length]) }), - rest.get('/api/v1/tasks/templates/:taskName', (req, res, ctx) => { + rest.put(`${baseURL}/api/v1/tasks/:taskName`, (req, res, ctx) => { const resultArray = [ [ ctx.status(200), ctx.json({ - binlog_filter_rule: [...new Array(5).keys()] - .map(_ => ({ - [faker.lorem.word()]: { - ignore_event: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()), - ignore_sql: [ + task: { + name: 'task-1', + task_mode: 'all', + shard_mode: faker.random.arrayElement([ + 'pessimistic', + 'optimistic', + ]), + meta_schema: 'dm-meta', + enhance_online_schema_change: true, + on_duplicate: faker.random.arrayElement([ + 'replace', + 'error', + 'ignore', + ]), + target_config: { + host: '127.0.0.1', + port: 3306, + user: 'root', + password: '123456', + security: { + ssl_ca_content: faker.lorem.slug(1), + ssl_cert_content: faker.lorem.slug(1), + ssl_key_content: faker.lorem.slug(1), + cert_allowed_cn: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), + ].map(_ => faker.lorem.slug(1)), }, - })) - .reduce((acc, next) => Object.assign(acc, next), {}), - enhance_online_schema_change: faker.datatype.boolean(), - meta_schema: faker.lorem.slug(), - name: faker.lorem.slug(), - on_duplicate: faker.random.arrayElement(['overwrite', 'error']), - shard_mode: faker.random.arrayElement(['pessimistic', 'optimistic']), - source_config: { - full_migrate_conf: { - consistency: faker.lorem.slug(), - data_dir: faker.lorem.slug(), - export_threads: faker.datatype.number(), - import_threads: faker.datatype.number(), - }, - incr_migrate_conf: { - repl_batch: faker.datatype.number(), - repl_threads: faker.datatype.number(), }, - source_conf: [ + binlog_filter_rule: [...new Array(5).keys()] + .map(_ => ({ + [faker.lorem.word()]: { + ignore_event: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => 'all dml'), + ignore_sql: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => '^Drop'), + }, + })) + .reduce((acc, next) => Object.assign(acc, next), {}), + table_migrate_rule: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ - binlog_gtid: faker.lorem.slug(), - binlog_name: faker.lorem.slug(), - binlog_pos: faker.datatype.number(), - source_name: faker.lorem.slug(), - })), - }, - status_list: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => ({ - dump_status: { - completed_tables: faker.datatype.number(), - estimate_total_rows: faker.datatype.number(), - finished_bytes: faker.datatype.number(), - finished_rows: faker.datatype.number(), - total_tables: faker.datatype.number(), - }, - error_msg: faker.lorem.slug(), - load_status: { - finished_bytes: faker.datatype.number(), - meta_binlog: faker.lorem.slug(), - meta_binlog_gtid: faker.lorem.slug(), - progress: faker.lorem.slug(), - total_bytes: faker.datatype.number(), - }, - name: faker.lorem.slug(), - source_name: faker.lorem.slug(), - stage: faker.random.arrayElement([ - 'Stopped', - 'Running', - 'Finished', - ]), - sync_status: { - binlog_type: faker.lorem.slug(), - blocking_ddls: [ + source: { + source_name: 'source-name', + schema: 'db-*', + table: 'tb-*', + }, + target: { + schema: 'db1', + table: 'tb1', + }, + binlog_filter_rule: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - master_binlog: faker.lorem.slug(), - master_binlog_gtid: faker.lorem.slug(), - recent_tps: faker.datatype.number(), - seconds_behind_master: faker.datatype.number(), - synced: faker.datatype.boolean(), - syncer_binlog: faker.lorem.slug(), - syncer_binlog_gtid: faker.lorem.slug(), - total_events: faker.datatype.number(), - total_tps: faker.datatype.number(), - unresolved_groups: [ + ].map(_ => 'rule-1'), + })), + source_config: { + full_migrate_conf: { + export_threads: faker.datatype.number(), + import_threads: faker.datatype.number(), + data_dir: './exported_data', + consistency: 'auto', + }, + incr_migrate_conf: { + repl_threads: faker.datatype.number(), + repl_batch: faker.datatype.number(), + }, + source_conf: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ - ddl_list: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()), - first_location: faker.lorem.slug(), - synced: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()), - target: faker.lorem.slug(), - unsynced: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()), + source_name: 'mysql-replica-01', + binlog_name: 'binlog.000001', + binlog_pos: 4, + binlog_gtid: + '03fc0263-28c7-11e7-a653-6c0b84d59f30:1-7041423,05474d3c-28c7-11e7-8352-203db246dd3d:1-170', })), }, - unit: faker.lorem.slug(), - unresolved_ddl_lock_id: faker.lorem.slug(), - worker_name: faker.lorem.slug(), - })), - table_migrate_rule: [ + status_list: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + name: faker.name.findName(), + source_name: faker.name.findName(), + worker_name: faker.name.findName(), + stage: faker.random.arrayElement([ + 'Stopped', + 'Running', + 'Finished', + ]), + unit: 'sync', + unresolved_ddl_lock_id: faker.lorem.slug(1), + load_status: { + finished_bytes: faker.datatype.number(), + total_bytes: faker.datatype.number(), + progress: faker.lorem.slug(1), + meta_binlog: faker.lorem.slug(1), + meta_binlog_gtid: faker.lorem.slug(1), + }, + sync_status: { + total_events: faker.datatype.number(), + total_tps: faker.datatype.number(), + recent_tps: faker.datatype.number(), + master_binlog: faker.lorem.slug(1), + master_binlog_gtid: faker.lorem.slug(1), + syncer_binlog: faker.lorem.slug(1), + syncer_binlog_gtid: faker.lorem.slug(1), + blocking_ddls: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + unresolved_groups: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + target: faker.lorem.slug(1), + ddl_list: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + first_location: faker.lorem.slug(1), + synced: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + unsynced: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + })), + synced: faker.datatype.boolean(), + binlog_type: faker.lorem.slug(1), + seconds_behind_master: faker.datatype.number(), + }, + dump_status: { + total_tables: faker.datatype.number(), + completed_tables: faker.datatype.number(), + finished_bytes: faker.datatype.number(), + finished_rows: faker.datatype.number(), + estimate_total_rows: faker.datatype.number(), + }, + error_msg: faker.lorem.slug(1), + })), + ignore_checking_items: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => 'version'), + }, + check_result: 'pre-check is passed. ', + }), + ], + [ + ctx.status(400), + ctx.json({ + error_msg: faker.lorem.slug(1), + error_code: faker.datatype.number(), + }), + ], + ] + + return res(...resultArray[gen.next().value % resultArray.length]) + }), + rest.get(`${baseURL}/api/v1/tasks/:taskName/status`, (req, res, ctx) => { + const resultArray = [ + [ + ctx.status(200), + ctx.json({ + total: faker.datatype.number(), + data: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ - binlog_filter_rule: [ + name: faker.name.findName(), + source_name: faker.name.findName(), + worker_name: faker.name.findName(), + stage: faker.random.arrayElement([ + 'Stopped', + 'Running', + 'Finished', + ]), + unit: 'sync', + unresolved_ddl_lock_id: faker.lorem.slug(1), + load_status: { + finished_bytes: faker.datatype.number(), + total_bytes: faker.datatype.number(), + progress: faker.lorem.slug(1), + meta_binlog: faker.lorem.slug(1), + meta_binlog_gtid: faker.lorem.slug(1), + }, + sync_status: { + total_events: faker.datatype.number(), + total_tps: faker.datatype.number(), + recent_tps: faker.datatype.number(), + master_binlog: faker.lorem.slug(1), + master_binlog_gtid: faker.lorem.slug(1), + syncer_binlog: faker.lorem.slug(1), + syncer_binlog_gtid: faker.lorem.slug(1), + blocking_ddls: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + unresolved_groups: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + target: faker.lorem.slug(1), + ddl_list: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + first_location: faker.lorem.slug(1), + synced: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + unsynced: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + })), + synced: faker.datatype.boolean(), + binlog_type: faker.lorem.slug(1), + seconds_behind_master: faker.datatype.number(), + }, + dump_status: { + total_tables: faker.datatype.number(), + completed_tables: faker.datatype.number(), + finished_bytes: faker.datatype.number(), + finished_rows: faker.datatype.number(), + estimate_total_rows: faker.datatype.number(), + }, + error_msg: faker.lorem.slug(1), + })), + }), + ], + [ + ctx.status(400), + ctx.json({ + error_msg: faker.lorem.slug(1), + error_code: faker.datatype.number(), + }), + ], + ] + + return res(...resultArray[gen.next().value % resultArray.length]) + }), + rest.post(`${baseURL}/api/v1/tasks/:taskName/start`, (req, res, ctx) => { + const resultArray = [ + [ctx.status(200), ctx.json(null)], + // [ + // ctx.status(400), + // ctx.json({ + // error_msg: faker.lorem.slug(1), + // error_code: faker.datatype.number(), + // }), + // ], + ] + + return res(...resultArray[gen.next().value % resultArray.length]) + }), + rest.post(`${baseURL}/api/v1/tasks/:taskName/stop`, (req, res, ctx) => { + const resultArray = [ + [ctx.status(200), ctx.json(null)], + [ + ctx.status(400), + ctx.json({ + error_msg: faker.lorem.slug(1), + error_code: faker.datatype.number(), + }), + ], + ] + + return res(...resultArray[gen.next().value % resultArray.length]) + }), + rest.get( + `${baseURL}/api/v1/tasks/:taskName/sources/:sourceName/migrate_targets`, + (req, res, ctx) => { + const resultArray = [ + [ + ctx.status(200), + ctx.json({ + total: faker.datatype.number(), + data: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - source: { - schema: faker.lorem.slug(), - source_name: faker.lorem.slug(), - table: faker.lorem.slug(), - }, - target: { - schema: faker.lorem.slug(), - table: faker.lorem.slug(), + ].map(_ => ({ + source_schema: 'db1', + source_table: 'tb1', + target_schema: 'db1', + target_table: 'tb1', + })), + }), + ], + [ + ctx.status(400), + ctx.json({ + error_msg: faker.lorem.slug(1), + error_code: faker.datatype.number(), + }), + ], + ] + + return res(...resultArray[gen.next().value % resultArray.length]) + } + ), + rest.get( + `${baseURL}/api/v1/tasks/:taskName/sources/:sourceName/schemas`, + (req, res, ctx) => { + const resultArray = [ + [ + ctx.status(200), + ctx.json( + [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => 'db1') + ), + ], + [ + ctx.status(400), + ctx.json({ + error_msg: faker.lorem.slug(1), + error_code: faker.datatype.number(), + }), + ], + ] + + return res(...resultArray[gen.next().value % resultArray.length]) + } + ), + rest.get( + `${baseURL}/api/v1/tasks/:taskName/sources/:sourceName/schemas/:schemaName`, + (req, res, ctx) => { + const resultArray = [ + [ + ctx.status(200), + ctx.json( + [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => 'table1') + ), + ], + [ + ctx.status(400), + ctx.json({ + error_msg: faker.lorem.slug(1), + error_code: faker.datatype.number(), + }), + ], + ] + + return res(...resultArray[gen.next().value % resultArray.length]) + } + ), + rest.get( + `${baseURL}/api/v1/tasks/:taskName/sources/:sourceName/schemas/:schemaName/:tableName`, + (req, res, ctx) => { + const resultArray = [ + [ + ctx.status(200), + ctx.json({ + schema_name: 'db1', + table_name: 'table1', + schema_create_sql: + 'CREATE TABLE `t1` (`id` int(11) NOT NULL AUTO_INCREMENT,PRIMARY KEY (`id`) /*T![clustered_index] CLUSTERED */) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin', + }), + ], + [ + ctx.status(400), + ctx.json({ + error_msg: faker.lorem.slug(1), + error_code: faker.datatype.number(), + }), + ], + ] + + return res(...resultArray[gen.next().value % resultArray.length]) + } + ), + rest.put( + `${baseURL}/api/v1/tasks/:taskName/sources/:sourceName/schemas/:schemaName/:tableName`, + (req, res, ctx) => { + const resultArray = [ + [ctx.status(200), ctx.json(null)], + [ + ctx.status(400), + ctx.json({ + error_msg: faker.lorem.slug(1), + error_code: faker.datatype.number(), + }), + ], + ] + + return res(...resultArray[gen.next().value % resultArray.length]) + } + ), + rest.delete( + `${baseURL}/api/v1/tasks/:taskName/sources/:sourceName/schemas/:schemaName/:tableName`, + (req, res, ctx) => { + const resultArray = [ + [ctx.status(204), ctx.json(null)], + [ + ctx.status(400), + ctx.json({ + error_msg: faker.lorem.slug(1), + error_code: faker.datatype.number(), + }), + ], + ] + + return res(...resultArray[gen.next().value % resultArray.length]) + } + ), + rest.post(`${baseURL}/api/v1/tasks/converters`, (req, res, ctx) => { + const resultArray = [ + [ + ctx.status(201), + ctx.json({ + task: { + name: 'task-1', + task_mode: 'all', + shard_mode: faker.random.arrayElement([ + 'pessimistic', + 'optimistic', + ]), + meta_schema: 'dm-meta', + enhance_online_schema_change: true, + on_duplicate: faker.random.arrayElement([ + 'replace', + 'error', + 'ignore', + ]), + target_config: { + host: '127.0.0.1', + port: 3306, + user: 'root', + password: '123456', + security: { + ssl_ca_content: faker.lorem.slug(1), + ssl_cert_content: faker.lorem.slug(1), + ssl_key_content: faker.lorem.slug(1), + cert_allowed_cn: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + }, }, - })), - target_config: { - host: faker.lorem.slug(), - password: faker.lorem.slug(), - port: faker.datatype.number(), - security: { - cert_allowed_cn: [ + binlog_filter_rule: [...new Array(5).keys()] + .map(_ => ({ + [faker.lorem.word()]: { + ignore_event: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => 'all dml'), + ignore_sql: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => '^Drop'), + }, + })) + .reduce((acc, next) => Object.assign(acc, next), {}), + table_migrate_rule: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + source: { + source_name: 'source-name', + schema: 'db-*', + table: 'tb-*', + }, + target: { + schema: 'db1', + table: 'tb1', + }, + binlog_filter_rule: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - ssl_ca_content: faker.lorem.slug(), - ssl_cert_content: faker.lorem.slug(), - ssl_key_content: faker.lorem.slug(), + ].map(_ => 'rule-1'), + })), + source_config: { + full_migrate_conf: { + export_threads: faker.datatype.number(), + import_threads: faker.datatype.number(), + data_dir: './exported_data', + consistency: 'auto', + }, + incr_migrate_conf: { + repl_threads: faker.datatype.number(), + repl_batch: faker.datatype.number(), + }, + source_conf: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + source_name: 'mysql-replica-01', + binlog_name: 'binlog.000001', + binlog_pos: 4, + binlog_gtid: + '03fc0263-28c7-11e7-a653-6c0b84d59f30:1-7041423,05474d3c-28c7-11e7-8352-203db246dd3d:1-170', + })), }, - user: faker.lorem.slug(), + status_list: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + name: faker.name.findName(), + source_name: faker.name.findName(), + worker_name: faker.name.findName(), + stage: faker.random.arrayElement([ + 'Stopped', + 'Running', + 'Finished', + ]), + unit: 'sync', + unresolved_ddl_lock_id: faker.lorem.slug(1), + load_status: { + finished_bytes: faker.datatype.number(), + total_bytes: faker.datatype.number(), + progress: faker.lorem.slug(1), + meta_binlog: faker.lorem.slug(1), + meta_binlog_gtid: faker.lorem.slug(1), + }, + sync_status: { + total_events: faker.datatype.number(), + total_tps: faker.datatype.number(), + recent_tps: faker.datatype.number(), + master_binlog: faker.lorem.slug(1), + master_binlog_gtid: faker.lorem.slug(1), + syncer_binlog: faker.lorem.slug(1), + syncer_binlog_gtid: faker.lorem.slug(1), + blocking_ddls: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + unresolved_groups: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + target: faker.lorem.slug(1), + ddl_list: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + first_location: faker.lorem.slug(1), + synced: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + unsynced: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + })), + synced: faker.datatype.boolean(), + binlog_type: faker.lorem.slug(1), + seconds_behind_master: faker.datatype.number(), + }, + dump_status: { + total_tables: faker.datatype.number(), + completed_tables: faker.datatype.number(), + finished_bytes: faker.datatype.number(), + finished_rows: faker.datatype.number(), + estimate_total_rows: faker.datatype.number(), + }, + error_msg: faker.lorem.slug(1), + })), + ignore_checking_items: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => 'version'), }, - task_mode: faker.random.arrayElement(['full', 'incremental', 'all']), + task_config_file: faker.lorem.slug(1), }), ], [ ctx.status(400), ctx.json({ + error_msg: faker.lorem.slug(1), error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), }), ], ] - return res(...faker.random.arrayElement(resultArray)) + + return res(...resultArray[gen.next().value % resultArray.length]) }), - rest.put('/api/v1/tasks/templates/:taskName', (req, res, ctx) => { + rest.post(`${baseURL}/api/v1/tasks/templates`, (req, res, ctx) => { const resultArray = [ [ - ctx.status(200), + ctx.status(201), ctx.json({ + name: 'task-1', + task_mode: 'all', + shard_mode: faker.random.arrayElement(['pessimistic', 'optimistic']), + meta_schema: 'dm-meta', + enhance_online_schema_change: true, + on_duplicate: faker.random.arrayElement([ + 'replace', + 'error', + 'ignore', + ]), + target_config: { + host: '127.0.0.1', + port: 3306, + user: 'root', + password: '123456', + security: { + ssl_ca_content: faker.lorem.slug(1), + ssl_cert_content: faker.lorem.slug(1), + ssl_key_content: faker.lorem.slug(1), + cert_allowed_cn: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + }, + }, binlog_filter_rule: [...new Array(5).keys()] .map(_ => ({ [faker.lorem.word()]: { @@ -1445,40 +1733,56 @@ export const handlers = [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), + ].map(_ => 'all dml'), ignore_sql: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), + ].map(_ => '^Drop'), }, })) .reduce((acc, next) => Object.assign(acc, next), {}), - enhance_online_schema_change: faker.datatype.boolean(), - meta_schema: faker.lorem.slug(), - name: faker.lorem.slug(), - on_duplicate: faker.random.arrayElement(['overwrite', 'error']), - shard_mode: faker.random.arrayElement(['pessimistic', 'optimistic']), + table_migrate_rule: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + source: { + source_name: 'source-name', + schema: 'db-*', + table: 'tb-*', + }, + target: { + schema: 'db1', + table: 'tb1', + }, + binlog_filter_rule: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => 'rule-1'), + })), source_config: { full_migrate_conf: { - consistency: faker.lorem.slug(), - data_dir: faker.lorem.slug(), export_threads: faker.datatype.number(), import_threads: faker.datatype.number(), + data_dir: './exported_data', + consistency: 'auto', }, incr_migrate_conf: { - repl_batch: faker.datatype.number(), repl_threads: faker.datatype.number(), + repl_batch: faker.datatype.number(), }, source_conf: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ - binlog_gtid: faker.lorem.slug(), - binlog_name: faker.lorem.slug(), - binlog_pos: faker.datatype.number(), - source_name: faker.lorem.slug(), + source_name: 'mysql-replica-01', + binlog_name: 'binlog.000001', + binlog_pos: 4, + binlog_gtid: + '03fc0263-28c7-11e7-a653-6c0b84d59f30:1-7041423,05474d3c-28c7-11e7-8352-203db246dd3d:1-170', })), }, status_list: [ @@ -1486,139 +1790,341 @@ export const handlers = [ faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ - dump_status: { - completed_tables: faker.datatype.number(), - estimate_total_rows: faker.datatype.number(), - finished_bytes: faker.datatype.number(), - finished_rows: faker.datatype.number(), - total_tables: faker.datatype.number(), - }, - error_msg: faker.lorem.slug(), - load_status: { - finished_bytes: faker.datatype.number(), - meta_binlog: faker.lorem.slug(), - meta_binlog_gtid: faker.lorem.slug(), - progress: faker.lorem.slug(), - total_bytes: faker.datatype.number(), - }, - name: faker.lorem.slug(), - source_name: faker.lorem.slug(), + name: faker.name.findName(), + source_name: faker.name.findName(), + worker_name: faker.name.findName(), stage: faker.random.arrayElement([ 'Stopped', 'Running', 'Finished', ]), + unit: 'sync', + unresolved_ddl_lock_id: faker.lorem.slug(1), + load_status: { + finished_bytes: faker.datatype.number(), + total_bytes: faker.datatype.number(), + progress: faker.lorem.slug(1), + meta_binlog: faker.lorem.slug(1), + meta_binlog_gtid: faker.lorem.slug(1), + }, sync_status: { - binlog_type: faker.lorem.slug(), + total_events: faker.datatype.number(), + total_tps: faker.datatype.number(), + recent_tps: faker.datatype.number(), + master_binlog: faker.lorem.slug(1), + master_binlog_gtid: faker.lorem.slug(1), + syncer_binlog: faker.lorem.slug(1), + syncer_binlog_gtid: faker.lorem.slug(1), blocking_ddls: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - master_binlog: faker.lorem.slug(), - master_binlog_gtid: faker.lorem.slug(), - recent_tps: faker.datatype.number(), - seconds_behind_master: faker.datatype.number(), - synced: faker.datatype.boolean(), - syncer_binlog: faker.lorem.slug(), - syncer_binlog_gtid: faker.lorem.slug(), - total_events: faker.datatype.number(), - total_tps: faker.datatype.number(), - unresolved_groups: [ + ].map(_ => faker.lorem.slug(1)), + unresolved_groups: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + target: faker.lorem.slug(1), + ddl_list: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + first_location: faker.lorem.slug(1), + synced: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + unsynced: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + })), + synced: faker.datatype.boolean(), + binlog_type: faker.lorem.slug(1), + seconds_behind_master: faker.datatype.number(), + }, + dump_status: { + total_tables: faker.datatype.number(), + completed_tables: faker.datatype.number(), + finished_bytes: faker.datatype.number(), + finished_rows: faker.datatype.number(), + estimate_total_rows: faker.datatype.number(), + }, + error_msg: faker.lorem.slug(1), + })), + ignore_checking_items: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => 'version'), + }), + ], + [ + ctx.status(400), + ctx.json({ + error_msg: faker.lorem.slug(1), + error_code: faker.datatype.number(), + }), + ], + ] + + return res(...resultArray[gen.next().value % resultArray.length]) + }), + rest.get(`${baseURL}/api/v1/tasks/templates`, (req, res, ctx) => { + const resultArray = [ + [ + ctx.status(200), + ctx.json({ + total: faker.datatype.number(), + data: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + name: 'task-1', + task_mode: 'all', + shard_mode: faker.random.arrayElement([ + 'pessimistic', + 'optimistic', + ]), + meta_schema: 'dm-meta', + enhance_online_schema_change: true, + on_duplicate: faker.random.arrayElement([ + 'replace', + 'error', + 'ignore', + ]), + target_config: { + host: '127.0.0.1', + port: 3306, + user: 'root', + password: '123456', + security: { + ssl_ca_content: faker.lorem.slug(1), + ssl_cert_content: faker.lorem.slug(1), + ssl_key_content: faker.lorem.slug(1), + cert_allowed_cn: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + }, + }, + binlog_filter_rule: [...new Array(5).keys()] + .map(_ => ({ + [faker.lorem.word()]: { + ignore_event: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => 'all dml'), + ignore_sql: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => '^Drop'), + }, + })) + .reduce((acc, next) => Object.assign(acc, next), {}), + table_migrate_rule: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + source: { + source_name: 'source-name', + schema: 'db-*', + table: 'tb-*', + }, + target: { + schema: 'db1', + table: 'tb1', + }, + binlog_filter_rule: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => 'rule-1'), + })), + source_config: { + full_migrate_conf: { + export_threads: faker.datatype.number(), + import_threads: faker.datatype.number(), + data_dir: './exported_data', + consistency: 'auto', + }, + incr_migrate_conf: { + repl_threads: faker.datatype.number(), + repl_batch: faker.datatype.number(), + }, + source_conf: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ - ddl_list: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()), - first_location: faker.lorem.slug(), - synced: [ + source_name: 'mysql-replica-01', + binlog_name: 'binlog.000001', + binlog_pos: 4, + binlog_gtid: + '03fc0263-28c7-11e7-a653-6c0b84d59f30:1-7041423,05474d3c-28c7-11e7-8352-203db246dd3d:1-170', + })), + }, + status_list: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + name: faker.name.findName(), + source_name: faker.name.findName(), + worker_name: faker.name.findName(), + stage: faker.random.arrayElement([ + 'Stopped', + 'Running', + 'Finished', + ]), + unit: 'sync', + unresolved_ddl_lock_id: faker.lorem.slug(1), + load_status: { + finished_bytes: faker.datatype.number(), + total_bytes: faker.datatype.number(), + progress: faker.lorem.slug(1), + meta_binlog: faker.lorem.slug(1), + meta_binlog_gtid: faker.lorem.slug(1), + }, + sync_status: { + total_events: faker.datatype.number(), + total_tps: faker.datatype.number(), + recent_tps: faker.datatype.number(), + master_binlog: faker.lorem.slug(1), + master_binlog_gtid: faker.lorem.slug(1), + syncer_binlog: faker.lorem.slug(1), + syncer_binlog_gtid: faker.lorem.slug(1), + blocking_ddls: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - target: faker.lorem.slug(), - unsynced: [ + ].map(_ => faker.lorem.slug(1)), + unresolved_groups: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - })), - }, - unit: faker.lorem.slug(), - unresolved_ddl_lock_id: faker.lorem.slug(), - worker_name: faker.lorem.slug(), - })), - table_migrate_rule: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => ({ - binlog_filter_rule: [ + ].map(_ => ({ + target: faker.lorem.slug(1), + ddl_list: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + first_location: faker.lorem.slug(1), + synced: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + unsynced: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + })), + synced: faker.datatype.boolean(), + binlog_type: faker.lorem.slug(1), + seconds_behind_master: faker.datatype.number(), + }, + dump_status: { + total_tables: faker.datatype.number(), + completed_tables: faker.datatype.number(), + finished_bytes: faker.datatype.number(), + finished_rows: faker.datatype.number(), + estimate_total_rows: faker.datatype.number(), + }, + error_msg: faker.lorem.slug(1), + })), + ignore_checking_items: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - source: { - schema: faker.lorem.slug(), - source_name: faker.lorem.slug(), - table: faker.lorem.slug(), - }, - target: { - schema: faker.lorem.slug(), - table: faker.lorem.slug(), - }, + ].map(_ => 'version'), })), - target_config: { - host: faker.lorem.slug(), - password: faker.lorem.slug(), - port: faker.datatype.number(), - security: { - cert_allowed_cn: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()), - ssl_ca_content: faker.lorem.slug(), - ssl_cert_content: faker.lorem.slug(), - ssl_key_content: faker.lorem.slug(), - }, - user: faker.lorem.slug(), - }, - task_mode: faker.random.arrayElement(['full', 'incremental', 'all']), }), ], [ ctx.status(400), ctx.json({ + error_msg: faker.lorem.slug(1), error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), }), ], ] - return res(...faker.random.arrayElement(resultArray)) + + return res(...resultArray[gen.next().value % resultArray.length]) }), - rest.delete('/api/v1/tasks/:taskName', (req, res, ctx) => { + rest.post(`${baseURL}/api/v1/tasks/templates/import`, (req, res, ctx) => { const resultArray = [ - [ctx.status(204), ctx.json(null)], + [ + ctx.status(202), + ctx.json({ + success_task_list: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + failed_task_list: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + task_name: faker.name.findName(), + error_msg: faker.lorem.slug(1), + })), + }), + ], [ ctx.status(400), ctx.json({ + error_msg: faker.lorem.slug(1), error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), }), ], ] - return res(...faker.random.arrayElement(resultArray)) + + return res(...resultArray[gen.next().value % resultArray.length]) }), - rest.get('/api/v1/tasks/:taskName', (req, res, ctx) => { + rest.get(`${baseURL}/api/v1/tasks/templates/:taskName`, (req, res, ctx) => { const resultArray = [ [ ctx.status(200), ctx.json({ + name: 'task-1', + task_mode: 'all', + shard_mode: faker.random.arrayElement(['pessimistic', 'optimistic']), + meta_schema: 'dm-meta', + enhance_online_schema_change: true, + on_duplicate: faker.random.arrayElement([ + 'replace', + 'error', + 'ignore', + ]), + target_config: { + host: '127.0.0.1', + port: 3306, + user: 'root', + password: '123456', + security: { + ssl_ca_content: faker.lorem.slug(1), + ssl_cert_content: faker.lorem.slug(1), + ssl_key_content: faker.lorem.slug(1), + cert_allowed_cn: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + }, + }, binlog_filter_rule: [...new Array(5).keys()] .map(_ => ({ [faker.lorem.word()]: { @@ -1626,40 +2132,56 @@ export const handlers = [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), + ].map(_ => 'all dml'), ignore_sql: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), + ].map(_ => '^Drop'), }, })) .reduce((acc, next) => Object.assign(acc, next), {}), - enhance_online_schema_change: faker.datatype.boolean(), - meta_schema: faker.lorem.slug(), - name: faker.lorem.slug(), - on_duplicate: faker.random.arrayElement(['overwrite', 'error']), - shard_mode: faker.random.arrayElement(['pessimistic', 'optimistic']), + table_migrate_rule: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + source: { + source_name: 'source-name', + schema: 'db-*', + table: 'tb-*', + }, + target: { + schema: 'db1', + table: 'tb1', + }, + binlog_filter_rule: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => 'rule-1'), + })), source_config: { full_migrate_conf: { - consistency: faker.lorem.slug(), - data_dir: faker.lorem.slug(), export_threads: faker.datatype.number(), import_threads: faker.datatype.number(), + data_dir: './exported_data', + consistency: 'auto', }, incr_migrate_conf: { - repl_batch: faker.datatype.number(), repl_threads: faker.datatype.number(), + repl_batch: faker.datatype.number(), }, source_conf: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ - binlog_gtid: faker.lorem.slug(), - binlog_name: faker.lorem.slug(), - binlog_pos: faker.datatype.number(), - source_name: faker.lorem.slug(), + source_name: 'mysql-replica-01', + binlog_name: 'binlog.000001', + binlog_pos: 4, + binlog_gtid: + '03fc0263-28c7-11e7-a653-6c0b84d59f30:1-7041423,05474d3c-28c7-11e7-8352-203db246dd3d:1-170', })), }, status_list: [ @@ -1667,120 +2189,121 @@ export const handlers = [ faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ - dump_status: { - completed_tables: faker.datatype.number(), - estimate_total_rows: faker.datatype.number(), - finished_bytes: faker.datatype.number(), - finished_rows: faker.datatype.number(), - total_tables: faker.datatype.number(), - }, - error_msg: faker.lorem.slug(), - load_status: { - finished_bytes: faker.datatype.number(), - meta_binlog: faker.lorem.slug(), - meta_binlog_gtid: faker.lorem.slug(), - progress: faker.lorem.slug(), - total_bytes: faker.datatype.number(), - }, - name: faker.lorem.slug(), - source_name: faker.lorem.slug(), + name: faker.name.findName(), + source_name: faker.name.findName(), + worker_name: faker.name.findName(), stage: faker.random.arrayElement([ 'Stopped', 'Running', 'Finished', ]), + unit: 'sync', + unresolved_ddl_lock_id: faker.lorem.slug(1), + load_status: { + finished_bytes: faker.datatype.number(), + total_bytes: faker.datatype.number(), + progress: faker.lorem.slug(1), + meta_binlog: faker.lorem.slug(1), + meta_binlog_gtid: faker.lorem.slug(1), + }, sync_status: { - binlog_type: faker.lorem.slug(), + total_events: faker.datatype.number(), + total_tps: faker.datatype.number(), + recent_tps: faker.datatype.number(), + master_binlog: faker.lorem.slug(1), + master_binlog_gtid: faker.lorem.slug(1), + syncer_binlog: faker.lorem.slug(1), + syncer_binlog_gtid: faker.lorem.slug(1), blocking_ddls: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - master_binlog: faker.lorem.slug(), - master_binlog_gtid: faker.lorem.slug(), - recent_tps: faker.datatype.number(), - seconds_behind_master: faker.datatype.number(), - synced: faker.datatype.boolean(), - syncer_binlog: faker.lorem.slug(), - syncer_binlog_gtid: faker.lorem.slug(), - total_events: faker.datatype.number(), - total_tps: faker.datatype.number(), + ].map(_ => faker.lorem.slug(1)), unresolved_groups: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ + target: faker.lorem.slug(1), ddl_list: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - first_location: faker.lorem.slug(), + ].map(_ => faker.lorem.slug(1)), + first_location: faker.lorem.slug(1), synced: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - target: faker.lorem.slug(), + ].map(_ => faker.lorem.slug(1)), unsynced: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), + ].map(_ => faker.lorem.slug(1)), })), + synced: faker.datatype.boolean(), + binlog_type: faker.lorem.slug(1), + seconds_behind_master: faker.datatype.number(), + }, + dump_status: { + total_tables: faker.datatype.number(), + completed_tables: faker.datatype.number(), + finished_bytes: faker.datatype.number(), + finished_rows: faker.datatype.number(), + estimate_total_rows: faker.datatype.number(), }, - unit: faker.lorem.slug(), - unresolved_ddl_lock_id: faker.lorem.slug(), - worker_name: faker.lorem.slug(), + error_msg: faker.lorem.slug(1), })), - table_migrate_rule: [ + ignore_checking_items: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => ({ - binlog_filter_rule: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()), - source: { - schema: faker.lorem.slug(), - source_name: faker.lorem.slug(), - table: faker.lorem.slug(), - }, - target: { - schema: faker.lorem.slug(), - table: faker.lorem.slug(), - }, - })), - target_config: { - host: faker.lorem.slug(), - password: faker.lorem.slug(), - port: faker.datatype.number(), - security: { - cert_allowed_cn: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()), - ssl_ca_content: faker.lorem.slug(), - ssl_cert_content: faker.lorem.slug(), - ssl_key_content: faker.lorem.slug(), - }, - user: faker.lorem.slug(), - }, - task_mode: faker.random.arrayElement(['full', 'incremental', 'all']), + ].map(_ => 'version'), + }), + ], + [ + ctx.status(400), + ctx.json({ + error_msg: faker.lorem.slug(1), + error_code: faker.datatype.number(), }), ], - [ctx.status(404), ctx.json(null)], ] - return res(...faker.random.arrayElement(resultArray)) + + return res(...resultArray[gen.next().value % resultArray.length]) }), - rest.put('/api/v1/tasks/:taskName', (req, res, ctx) => { + rest.put(`${baseURL}/api/v1/tasks/templates/:taskName`, (req, res, ctx) => { const resultArray = [ [ ctx.status(200), ctx.json({ + name: 'task-1', + task_mode: 'all', + shard_mode: faker.random.arrayElement(['pessimistic', 'optimistic']), + meta_schema: 'dm-meta', + enhance_online_schema_change: true, + on_duplicate: faker.random.arrayElement([ + 'replace', + 'error', + 'ignore', + ]), + target_config: { + host: '127.0.0.1', + port: 3306, + user: 'root', + password: '123456', + security: { + ssl_ca_content: faker.lorem.slug(1), + ssl_cert_content: faker.lorem.slug(1), + ssl_key_content: faker.lorem.slug(1), + cert_allowed_cn: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => faker.lorem.slug(1)), + }, + }, binlog_filter_rule: [...new Array(5).keys()] .map(_ => ({ [faker.lorem.word()]: { @@ -1788,382 +2311,344 @@ export const handlers = [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), + ].map(_ => 'all dml'), ignore_sql: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), + ].map(_ => '^Drop'), }, })) .reduce((acc, next) => Object.assign(acc, next), {}), - enhance_online_schema_change: faker.datatype.boolean(), - meta_schema: faker.lorem.slug(), - name: faker.lorem.slug(), - on_duplicate: faker.random.arrayElement(['overwrite', 'error']), - shard_mode: faker.random.arrayElement(['pessimistic', 'optimistic']), + table_migrate_rule: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + source: { + source_name: 'source-name', + schema: 'db-*', + table: 'tb-*', + }, + target: { + schema: 'db1', + table: 'tb1', + }, + binlog_filter_rule: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => 'rule-1'), + })), source_config: { full_migrate_conf: { - consistency: faker.lorem.slug(), - data_dir: faker.lorem.slug(), export_threads: faker.datatype.number(), import_threads: faker.datatype.number(), + data_dir: './exported_data', + consistency: 'auto', }, incr_migrate_conf: { - repl_batch: faker.datatype.number(), repl_threads: faker.datatype.number(), + repl_batch: faker.datatype.number(), }, source_conf: [ ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => ({ - binlog_gtid: faker.lorem.slug(), - binlog_name: faker.lorem.slug(), - binlog_pos: faker.datatype.number(), - source_name: faker.lorem.slug(), - })), - }, - status_list: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => ({ - dump_status: { - completed_tables: faker.datatype.number(), - estimate_total_rows: faker.datatype.number(), - finished_bytes: faker.datatype.number(), - finished_rows: faker.datatype.number(), - total_tables: faker.datatype.number(), - }, - error_msg: faker.lorem.slug(), - load_status: { - finished_bytes: faker.datatype.number(), - meta_binlog: faker.lorem.slug(), - meta_binlog_gtid: faker.lorem.slug(), - progress: faker.lorem.slug(), - total_bytes: faker.datatype.number(), - }, - name: faker.lorem.slug(), - source_name: faker.lorem.slug(), + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + source_name: 'mysql-replica-01', + binlog_name: 'binlog.000001', + binlog_pos: 4, + binlog_gtid: + '03fc0263-28c7-11e7-a653-6c0b84d59f30:1-7041423,05474d3c-28c7-11e7-8352-203db246dd3d:1-170', + })), + }, + status_list: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + name: faker.name.findName(), + source_name: faker.name.findName(), + worker_name: faker.name.findName(), stage: faker.random.arrayElement([ 'Stopped', 'Running', 'Finished', ]), + unit: 'sync', + unresolved_ddl_lock_id: faker.lorem.slug(1), + load_status: { + finished_bytes: faker.datatype.number(), + total_bytes: faker.datatype.number(), + progress: faker.lorem.slug(1), + meta_binlog: faker.lorem.slug(1), + meta_binlog_gtid: faker.lorem.slug(1), + }, sync_status: { - binlog_type: faker.lorem.slug(), + total_events: faker.datatype.number(), + total_tps: faker.datatype.number(), + recent_tps: faker.datatype.number(), + master_binlog: faker.lorem.slug(1), + master_binlog_gtid: faker.lorem.slug(1), + syncer_binlog: faker.lorem.slug(1), + syncer_binlog_gtid: faker.lorem.slug(1), blocking_ddls: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - master_binlog: faker.lorem.slug(), - master_binlog_gtid: faker.lorem.slug(), - recent_tps: faker.datatype.number(), - seconds_behind_master: faker.datatype.number(), - synced: faker.datatype.boolean(), - syncer_binlog: faker.lorem.slug(), - syncer_binlog_gtid: faker.lorem.slug(), - total_events: faker.datatype.number(), - total_tps: faker.datatype.number(), + ].map(_ => faker.lorem.slug(1)), unresolved_groups: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ + target: faker.lorem.slug(1), ddl_list: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - first_location: faker.lorem.slug(), + ].map(_ => faker.lorem.slug(1)), + first_location: faker.lorem.slug(1), synced: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), - target: faker.lorem.slug(), + ].map(_ => faker.lorem.slug(1)), unsynced: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()), + ].map(_ => faker.lorem.slug(1)), })), + synced: faker.datatype.boolean(), + binlog_type: faker.lorem.slug(1), + seconds_behind_master: faker.datatype.number(), }, - unit: faker.lorem.slug(), - unresolved_ddl_lock_id: faker.lorem.slug(), - worker_name: faker.lorem.slug(), + dump_status: { + total_tables: faker.datatype.number(), + completed_tables: faker.datatype.number(), + finished_bytes: faker.datatype.number(), + finished_rows: faker.datatype.number(), + estimate_total_rows: faker.datatype.number(), + }, + error_msg: faker.lorem.slug(1), })), - table_migrate_rule: [ + ignore_checking_items: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => ({ - binlog_filter_rule: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()), - source: { - schema: faker.lorem.slug(), - source_name: faker.lorem.slug(), - table: faker.lorem.slug(), - }, - target: { - schema: faker.lorem.slug(), - table: faker.lorem.slug(), - }, - })), - target_config: { - host: faker.lorem.slug(), - password: faker.lorem.slug(), - port: faker.datatype.number(), - security: { - cert_allowed_cn: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()), - ssl_ca_content: faker.lorem.slug(), - ssl_cert_content: faker.lorem.slug(), - ssl_key_content: faker.lorem.slug(), - }, - user: faker.lorem.slug(), - }, - task_mode: faker.random.arrayElement(['full', 'incremental', 'all']), + ].map(_ => 'version'), }), ], [ ctx.status(400), ctx.json({ + error_msg: faker.lorem.slug(1), error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), }), ], ] - return res(...faker.random.arrayElement(resultArray)) + + return res(...resultArray[gen.next().value % resultArray.length]) }), - rest.get( - '/api/v1/tasks/:taskName/sources/:sourceName/schemas', + rest.delete( + `${baseURL}/api/v1/tasks/templates/:taskName`, (req, res, ctx) => { const resultArray = [ - [ - ctx.status(200), - ctx.json( - [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()) - ), - ], + [ctx.status(204), ctx.json(null)], [ ctx.status(400), ctx.json({ + error_msg: faker.lorem.slug(1), error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), }), ], ] - return res(...faker.random.arrayElement(resultArray)) + + return res(...resultArray[gen.next().value % resultArray.length]) } ), - rest.get( - '/api/v1/tasks/:taskName/sources/:sourceName/schemas/:schemaName', - (req, res, ctx) => { - const resultArray = [ - [ - ctx.status(200), - ctx.json( - [ + rest.get(`${baseURL}/api/v1/cluster/info`, (req, res, ctx) => { + const resultArray = [ + [ + ctx.status(200), + ctx.json({ + cluster_id: faker.datatype.number(), + topology: { + master_topology_list: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), - ].map(_ => faker.lorem.slug()) - ), - ], - [ - ctx.status(400), - ctx.json({ - error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), - }), - ], - ] - return res(...faker.random.arrayElement(resultArray)) - } - ), - rest.delete( - '/api/v1/tasks/:taskName/sources/:sourceName/schemas/:schemaName/:tableName', - (req, res, ctx) => { - const resultArray = [ - [ctx.status(204), ctx.json(null)], - [ - ctx.status(400), - ctx.json({ - error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), - }), - ], - ] - return res(...faker.random.arrayElement(resultArray)) - } - ), - rest.get( - '/api/v1/tasks/:taskName/sources/:sourceName/schemas/:schemaName/:tableName', - (req, res, ctx) => { - const resultArray = [ - [ - ctx.status(200), - ctx.json({ - schema_create_sql: faker.lorem.slug(), - schema_name: faker.lorem.slug(), - table_name: faker.lorem.slug(), - }), - ], - [ - ctx.status(400), - ctx.json({ - error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), - }), - ], - ] - return res(...faker.random.arrayElement(resultArray)) - } - ), - rest.put( - '/api/v1/tasks/:taskName/sources/:sourceName/schemas/:schemaName/:tableName', - (req, res, ctx) => { - const resultArray = [ - [ctx.status(200), ctx.json(null)], - [ - ctx.status(400), - ctx.json({ - error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), - }), - ], - ] - return res(...faker.random.arrayElement(resultArray)) - } - ), - rest.post('/api/v1/tasks/:taskName/start', (req, res, ctx) => { + ].map(_ => ({ + name: 'master', + host: '127.0.0.1', + port: 8261, + })), + worker_topology_list: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + name: 'worker1', + host: '127.0.0.1', + port: 8261, + })), + grafana_topology: { + host: '127.0.0.1', + port: 3000, + }, + prometheus_topology: { + host: '127.0.0.1', + port: 9090, + }, + alert_manager_topology: { + host: '127.0.0.1', + port: 9093, + }, + }, + }), + ], + ] + + return res(...resultArray[gen.next().value % resultArray.length]) + }), + rest.put(`${baseURL}/api/v1/cluster/info`, (req, res, ctx) => { const resultArray = [ - [ctx.status(200), ctx.json(null)], [ - ctx.status(400), + ctx.status(200), ctx.json({ - error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), + cluster_id: faker.datatype.number(), + topology: { + master_topology_list: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + name: 'master', + host: '127.0.0.1', + port: 8261, + })), + worker_topology_list: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + name: 'worker1', + host: '127.0.0.1', + port: 8261, + })), + grafana_topology: { + host: '127.0.0.1', + port: 3000, + }, + prometheus_topology: { + host: '127.0.0.1', + port: 9090, + }, + alert_manager_topology: { + host: '127.0.0.1', + port: 9093, + }, + }, }), ], ] - return res(...faker.random.arrayElement(resultArray)) + + return res(...resultArray[gen.next().value % resultArray.length]) }), - rest.get('/api/v1/tasks/:taskName/status', (req, res, ctx) => { + rest.get(`${baseURL}/api/v1/cluster/masters`, (req, res, ctx) => { const resultArray = [ [ ctx.status(200), ctx.json({ + total: faker.datatype.number(), data: [ ...new Array( faker.datatype.number({ max: MAX_ARRAY_LENGTH }) ).keys(), ].map(_ => ({ - dump_status: { - completed_tables: faker.datatype.number(), - estimate_total_rows: faker.datatype.number(), - finished_bytes: faker.datatype.number(), - finished_rows: faker.datatype.number(), - total_tables: faker.datatype.number(), - }, - error_msg: faker.lorem.slug(), - load_status: { - finished_bytes: faker.datatype.number(), - meta_binlog: faker.lorem.slug(), - meta_binlog_gtid: faker.lorem.slug(), - progress: faker.lorem.slug(), - total_bytes: faker.datatype.number(), - }, - name: faker.lorem.slug(), - source_name: faker.lorem.slug(), - stage: faker.random.arrayElement([ - 'Stopped', - 'Running', - 'Finished', - ]), - sync_status: { - binlog_type: faker.lorem.slug(), - blocking_ddls: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()), - master_binlog: faker.lorem.slug(), - master_binlog_gtid: faker.lorem.slug(), - recent_tps: faker.datatype.number(), - seconds_behind_master: faker.datatype.number(), - synced: faker.datatype.boolean(), - syncer_binlog: faker.lorem.slug(), - syncer_binlog_gtid: faker.lorem.slug(), - total_events: faker.datatype.number(), - total_tps: faker.datatype.number(), - unresolved_groups: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => ({ - ddl_list: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()), - first_location: faker.lorem.slug(), - synced: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()), - target: faker.lorem.slug(), - unsynced: [ - ...new Array( - faker.datatype.number({ max: MAX_ARRAY_LENGTH }) - ).keys(), - ].map(_ => faker.lorem.slug()), - })), - }, - unit: faker.lorem.slug(), - unresolved_ddl_lock_id: faker.lorem.slug(), - worker_name: faker.lorem.slug(), + name: 'master1', + alive: true, + leader: true, + addr: '127.0.0.1:8261', })), - total: faker.datatype.number(), }), ], [ ctx.status(400), ctx.json({ + error_msg: faker.lorem.slug(1), error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), }), ], ] - return res(...faker.random.arrayElement(resultArray)) + + return res(...resultArray[gen.next().value % resultArray.length]) }), - rest.post('/api/v1/tasks/:taskName/stop', (req, res, ctx) => { + rest.delete( + `${baseURL}/api/v1/cluster/masters/:masterName`, + (req, res, ctx) => { + const resultArray = [ + [ctx.status(204), ctx.json(null)], + [ + ctx.status(400), + ctx.json({ + error_msg: faker.lorem.slug(1), + error_code: faker.datatype.number(), + }), + ], + ] + + return res(...resultArray[gen.next().value % resultArray.length]) + } + ), + rest.get(`${baseURL}/api/v1/cluster/workers`, (req, res, ctx) => { const resultArray = [ - [ctx.status(200), ctx.json(null)], + [ + ctx.status(200), + ctx.json({ + total: faker.datatype.number(), + data: [ + ...new Array( + faker.datatype.number({ max: MAX_ARRAY_LENGTH }) + ).keys(), + ].map(_ => ({ + name: 'worker1', + addr: '127.0.0.1:8261', + bound_stage: 'bound', + bound_source_name: 'mysql-01', + })), + }), + ], [ ctx.status(400), ctx.json({ + error_msg: faker.lorem.slug(1), error_code: faker.datatype.number(), - error_msg: faker.lorem.slug(), }), ], ] - return res(...faker.random.arrayElement(resultArray)) + + return res(...resultArray[gen.next().value % resultArray.length]) }), + rest.delete( + `${baseURL}/api/v1/cluster/workers/:workerName`, + (req, res, ctx) => { + const resultArray = [ + [ctx.status(204), ctx.json(null)], + [ + ctx.status(400), + ctx.json({ + error_msg: faker.lorem.slug(1), + error_code: faker.datatype.number(), + }), + ], + ] + + return res(...resultArray[gen.next().value % resultArray.length]) + } + ), ] // This configures a Service Worker with the given request handlers. diff --git a/dm/ui/src/models/task.ts b/dm/ui/src/models/task.ts index 45610398d45..3c93ce406de 100644 --- a/dm/ui/src/models/task.ts +++ b/dm/ui/src/models/task.ts @@ -172,8 +172,12 @@ export type DmapiStartTaskApiArg = { taskName: string startTaskRequest?: { remove_meta?: boolean - safe_mode_time_duration?: any + safe_mode_time_duration?: string source_name_list?: string[] + + /** + * RFC3339 format date string + */ start_time?: string } } diff --git a/dm/ui/src/pages/migration/task/index.tsx b/dm/ui/src/pages/migration/task/index.tsx index d7a849a00c0..86cee4d5b12 100644 --- a/dm/ui/src/pages/migration/task/index.tsx +++ b/dm/ui/src/pages/migration/task/index.tsx @@ -25,6 +25,8 @@ import { Tabs, Radio, Select, + Form, + DatePicker, } from '~/uikit' import { SearchOutlined, @@ -52,6 +54,7 @@ import { TaskUnit, SubTaskStatus, useDmapiConverterTaskMutation, + DmapiStartTaskApiArg, } from '~/models/task' import i18n from '~/i18n' import { useFuseSearch } from '~/utils/search' @@ -61,11 +64,16 @@ import TaskUnitTag from '~/components/SimpleTaskPanel/TaskUnitTag' SyntaxHighlighter.registerLanguage('yaml', yaml) -enum CreateTaskMethod { +enum OpenTaskMethod { ByGuide, ByConfigFile, } +enum StartTaskMethod { + Direct, + WithParams, +} + const SourceTable: React.FC<{ data: Source[] }> = ({ data }) => { @@ -218,11 +226,15 @@ const TaskList: React.FC = () => { const [sourceDrawerVisible, setSourceDrawerVisible] = useState(false) const [currentTaskName, setCurrentTaskName] = useState() const [selectedSources, setSelectedSources] = useState([]) - const [isModalVisible, setIsModalVisible] = useState(false) - const [method, setMethod] = useState(CreateTaskMethod.ByGuide) + const [isCreateTaskModalVisible, setIsCreateTaskModalVisible] = + useState(false) + const [isStartTaskModalVisible, setIsStartTaskModalVisible] = useState(false) + const [openTaskMethod, setOpenTaskMethod] = useState(OpenTaskMethod.ByGuide) + const [startTaskMethod, setStartTaskMethod] = useState(StartTaskMethod.Direct) const [currentTaskConfigFile, setCurrentTaskConfigFile] = useState('') const selectedTask = useAppSelector(state => state.globals.preloadedTask) const navigate = useNavigate() + const [form] = Form.useForm() const { data, isFetching, refetch } = useDmapiGetTaskListQuery({ withStatus: true, @@ -266,22 +278,25 @@ const TaskList: React.FC = () => { }, } - const handleRequest = useCallback( + const handleRequest = (handler: (...args: any[]) => void, key: string) => { + message.loading({ content: t('requesting'), key }) + Promise.all(selectedSources.map(name => handler({ taskName: name }))).then( + res => { + if (res.some((r: any) => r?.error)) { + message.destroy(key) + } else { + message.success({ content: t('request success'), key }) + } + } + ) + } + const handleRequestWithConfirmModal = useCallback( ({ key, handler, title }) => { Modal.confirm({ title, icon: , onOk() { - message.loading({ content: t('requesting'), key }) - Promise.all( - selectedSources.map(name => handler({ taskName: name })) - ).then(res => { - if (res.some(r => r?.error)) { - message.destroy(key) - } else { - message.success({ content: t('request success'), key }) - } - }) + handleRequest(handler, key) }, }) }, @@ -292,32 +307,56 @@ const TaskList: React.FC = () => { if (!selectedSources.length) { return } - handleRequest({ + handleRequestWithConfirmModal({ title: t('confirm to stop task?'), key: 'stopTask-' + Date.now(), handler: stopTask, }) - }, [selectedSources, handleRequest]) + }, [selectedSources, handleRequestWithConfirmModal]) const handleStartTask = useCallback(() => { if (!selectedSources.length) { return } - handleRequest({ - title: t('confirm to start task?'), - key: 'startTask-' + Date.now(), - handler: startTask, - }) - }, [selectedSources, handleRequest]) + setIsStartTaskModalVisible(true) + }, [selectedSources]) const handleDeleteTask = useCallback(() => { if (!selectedSources.length) { return } - handleRequest({ + handleRequestWithConfirmModal({ title: t('confirm to delete task?'), key: 'deleteTask-' + Date.now(), handler: deleteTask, }) - }, [selectedSources, handleRequest]) + }, [selectedSources, handleRequestWithConfirmModal]) + const handleConfirmOpenTask = () => { + if (openTaskMethod === OpenTaskMethod.ByGuide) { + selectedTask + ? navigate('/migration/task/edit') + : navigate('/migration/task/create') + } else if (openTaskMethod === OpenTaskMethod.ByConfigFile) { + selectedTask + ? navigate('/migration/task/edit#configFile') + : navigate('/migration/task/create#configFile') + } + setIsCreateTaskModalVisible(false) + } + const handleConfirmStartTask = () => { + const extraPayload: Partial = {} + + if (startTaskMethod === StartTaskMethod.WithParams) { + const formValues = form.getFieldsValue() + extraPayload.startTaskRequest = { + start_time: formValues.start_time.toISOString(), + safe_mode_time_duration: formValues.safe_mode_time_duration, + } + } + + handleRequest((payload: any) => { + const p = { ...payload, ...extraPayload } + startTask(p) + }, 'startTask-' + Date.now()) + } const dataSource = data?.data @@ -426,7 +465,7 @@ const TaskList: React.FC = () => { type="link" onClick={() => { dispatch(actions.setPreloadedTask(data)) - setIsModalVisible(true) + setIsCreateTaskModalVisible(true) }} > {t('edit')} @@ -459,6 +498,12 @@ const TaskList: React.FC = () => { refetchCurrentTaskStatus() }, [data]) + useEffect(() => { + if (!isCreateTaskModalVisible) { + form.resetFields() + } + }, [isStartTaskModalVisible]) + return (
@@ -515,7 +560,7 @@ const TaskList: React.FC = () => {