From b2457b99598fcb58ab6c2374ed7b8f5f0aea83f3 Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Thu, 22 Apr 2021 16:47:55 -0700 Subject: [PATCH 01/30] refactoring server --- server/helpers/index.js | 5 + server/helpers/moment-to-long.js | 5 + server/index.js | 39 +++--- .../tchannel-client/helpers/cli-transform.js | 28 ++++ .../tchannel-client/helpers/get-peers.js | 5 + .../tchannel-client/helpers/index.js | 13 ++ .../tchannel-client/helpers/lookup-async.js | 13 ++ .../tchannel-client/helpers/make-channel.js | 40 ++++++ .../tchannel-client/helpers/ui-transform.js | 50 +++++++ .../index.js} | 132 ++---------------- server/{routes.js => router.js} | 15 +- 11 files changed, 196 insertions(+), 149 deletions(-) create mode 100644 server/helpers/index.js create mode 100644 server/helpers/moment-to-long.js create mode 100644 server/middleware/tchannel-client/helpers/cli-transform.js create mode 100644 server/middleware/tchannel-client/helpers/get-peers.js create mode 100644 server/middleware/tchannel-client/helpers/index.js create mode 100644 server/middleware/tchannel-client/helpers/lookup-async.js create mode 100644 server/middleware/tchannel-client/helpers/make-channel.js create mode 100644 server/middleware/tchannel-client/helpers/ui-transform.js rename server/middleware/{tchannel-client.js => tchannel-client/index.js} (61%) rename server/{routes.js => router.js} (97%) diff --git a/server/helpers/index.js b/server/helpers/index.js new file mode 100644 index 000000000..19a183e1e --- /dev/null +++ b/server/helpers/index.js @@ -0,0 +1,5 @@ +const momentToLong = require('./moment-to-long'); + +module.exports = { + momentToLong, +}; diff --git a/server/helpers/moment-to-long.js b/server/helpers/moment-to-long.js new file mode 100644 index 000000000..c30f7ce4e --- /dev/null +++ b/server/helpers/moment-to-long.js @@ -0,0 +1,5 @@ +const Long = require('long'); + +const momentToLong = m => Long.fromValue(m.unix()).mul(1000000000); + +module.exports = momentToLong; diff --git a/server/index.js b/server/index.js index eb48d75fc..92a09a4cb 100644 --- a/server/index.js +++ b/server/index.js @@ -19,15 +19,22 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -const path = require('path'), - Koa = require('koa'), - bodyparser = require('koa-bodyparser'), - send = require('koa-send'), - staticRoot = path.join(__dirname, '../dist'), - app = new Koa(), - router = require('./routes'); +const path = require('path'); +const Koa = require('koa'); +const koaBodyparser = require('koa-bodyparser'); +const koaCompress = require('koa-compress'); +const koaSend = require('koa-send'); +const koaStatic = require('koa-static'); +const koaWebpack = require('koa-webpack'); +const webpack = require('webpack'); -app.webpackConfig = require('../webpack.config'); +const tchannelClient = require('./middleware/tchannel-client'); +const router = require('./router'); +const webpackConfig = require('../webpack.config'); + +const staticRoot = path.join(__dirname, '../dist'); +const app = new Koa(); +app.webpackConfig = webpackConfig; app.init = function(options) { options = options || {}; @@ -37,14 +44,10 @@ app.init = function(options) { ? options.useWebpack : process.env.NODE_ENV !== 'production'; - let koaWebpack; let compiler; if (useWebpack) { - const Webpack = require('webpack'); - - koaWebpack = require('koa-webpack'); - compiler = Webpack(app.webpackConfig); + compiler = webpack(app.webpackConfig); } app @@ -63,13 +66,13 @@ app.init = function(options) { ctx.body = { message: err.message }; } }) - .use(bodyparser()) + .use(koaBodyparser()) .use( - require('koa-compress')({ + koaCompress({ filter: contentType => !contentType.startsWith('text/event-stream'), }) ) - .use(require('./middleware/tchannel-client')) + .use(tchannelClient) .use( useWebpack ? koaWebpack({ @@ -77,7 +80,7 @@ app.init = function(options) { dev: { stats: { colors: true } }, hot: { port: process.env.TEST_RUN ? 8082 : 8081 }, }) - : require('koa-static')(staticRoot) + : koaStatic(staticRoot) ) .use(router.routes()) .use(router.allowedMethods()) @@ -97,7 +100,7 @@ app.init = function(options) { ctx.set('content-type', 'text/html'); ctx.body = compiler.outputFileSystem.readFileSync(filename); } else { - await send(ctx, 'index.html', { root: staticRoot }); + await koaSend(ctx, 'index.html', { root: staticRoot }); } } catch (err) { if (err.status !== 404) { diff --git a/server/middleware/tchannel-client/helpers/cli-transform.js b/server/middleware/tchannel-client/helpers/cli-transform.js new file mode 100644 index 000000000..8579a5d39 --- /dev/null +++ b/server/middleware/tchannel-client/helpers/cli-transform.js @@ -0,0 +1,28 @@ +const Long = require('long'); +const losslessJSON = require('lossless-json'); + +const cliTransform = item => { + if (!item || typeof item !== 'object') { + return item; + } + + Object.entries(item).forEach(([subkey, subvalue]) => { + if (subvalue && typeof subvalue.unsigned === 'boolean') { + item[subkey] = new losslessJSON.LosslessNumber( + Long.fromValue(subvalue).toString() + ); + } else if (Buffer.isBuffer(subvalue)) { + item[subkey] = subvalue.toString('base64'); + } else if (Array.isArray(subvalue)) { + subvalue.forEach(cliTransform); + } else if (subvalue && typeof subvalue === 'object') { + cliTransform(subvalue); + } else if (subvalue === null || subvalue === undefined) { + delete item[subkey]; + } + }); + + return item; +} + +module.exports = cliTransform; diff --git a/server/middleware/tchannel-client/helpers/get-peers.js b/server/middleware/tchannel-client/helpers/get-peers.js new file mode 100644 index 000000000..92cdccfb8 --- /dev/null +++ b/server/middleware/tchannel-client/helpers/get-peers.js @@ -0,0 +1,5 @@ +const getPeers = () => process.env.CADENCE_TCHANNEL_PEERS + ? process.env.CADENCE_TCHANNEL_PEERS.split(',') + : ['127.0.0.1:7933']; + +module.exports = getPeers; diff --git a/server/middleware/tchannel-client/helpers/index.js b/server/middleware/tchannel-client/helpers/index.js new file mode 100644 index 000000000..830a0bd75 --- /dev/null +++ b/server/middleware/tchannel-client/helpers/index.js @@ -0,0 +1,13 @@ +const cliTransform = require('./cli-transform'); +const getPeers = require('./get-peers'); +const lookupAsync = require('./lookup-async'); +const makeChannel = require('./make-channel'); +const uiTransform = require('./ui-transform'); + +module.exports = { + cliTransform, + getPeers, + lookupAsync, + makeChannel, + uiTransform, +}; diff --git a/server/middleware/tchannel-client/helpers/lookup-async.js b/server/middleware/tchannel-client/helpers/lookup-async.js new file mode 100644 index 000000000..cf5ad690e --- /dev/null +++ b/server/middleware/tchannel-client/helpers/lookup-async.js @@ -0,0 +1,13 @@ +const dns = require('dns'); + +const lookupAsync = host => new Promise((resolve, reject) => { + dns.lookup(host, { family: 4 }, (err, ip) => { + if (err) { + reject(err); + } else { + resolve(ip); + } + }); +}); + +module.exports = lookupAsync; diff --git a/server/middleware/tchannel-client/helpers/make-channel.js b/server/middleware/tchannel-client/helpers/make-channel.js new file mode 100644 index 000000000..945969cbd --- /dev/null +++ b/server/middleware/tchannel-client/helpers/make-channel.js @@ -0,0 +1,40 @@ +const isIPv4 = require('is-ipv4-node'); +const path = require('path'); +const TChannelAsThrift = require('tchannel/as/thrift'); + +const getPeers = require('./get-peers'); +const lookupAsync = require('./lookup-async'); + +const peers = getPeers(); + +const makeChannel = async (client) => { + const ipPeers = await Promise.all( + peers.map(peer => { + const [host, port] = peer.split(':'); + + if (!isIPv4(host)) { + return lookupAsync(host).then(ip => [ip, port].join(':')); + } else { + return peer; + } + }) + ); + + const cadenceChannel = client.makeSubChannel({ + serviceName: 'cadence-frontend', + peers: ipPeers, + requestDefaults: { + hasNoParent: true, + headers: { as: 'raw', cn: 'cadence-web' }, + }, + }); + + const tchannelAsThrift = TChannelAsThrift({ + channel: cadenceChannel, + entryPoint: path.join(__dirname, '../../../idl/cadence.thrift'), + }); + + return tchannelAsThrift; +}; + +module.exports = makeChannel; diff --git a/server/middleware/tchannel-client/helpers/ui-transform.js b/server/middleware/tchannel-client/helpers/ui-transform.js new file mode 100644 index 000000000..f9725d191 --- /dev/null +++ b/server/middleware/tchannel-client/helpers/ui-transform.js @@ -0,0 +1,50 @@ +const Long = require('long'); +const moment = require('moment'); + +const uiTransform = item => { + if (!item || typeof item !== 'object') { + return item; + } + + Object.entries(item).forEach(([subkey, subvalue]) => { + if (subvalue && typeof subvalue.unsigned === 'boolean') { + item[subkey] = Long.fromValue(subvalue).toNumber(); + const m = moment(item[subkey] / 1000000); + + if (m.isValid() && m.isAfter('2017-01-01')) { + item[subkey] = m.toISOString(); + } + } else if (Buffer.isBuffer(subvalue)) { + if (subkey === 'nextPageToken') { + item.nextPageToken = subvalue.toString('base64'); + + return; + } + + const stringval = subvalue.toString('utf8'); + + try { + // most of Cadence's uses of buffer is just line-delimited JSON. + item[subkey] = stringval + .split('\n') + .filter(x => x) + .map(JSON.parse); + + if (item[subkey].length === 1) { + item[subkey] = item[subkey][0]; + } + } catch (e) { + item[`${subkey}_base64`] = subvalue.toString('base64'); + item[subkey] = stringval; + } + } else if (Array.isArray(subvalue)) { + subvalue.forEach(uiTransform); + } else if (subvalue && typeof subvalue === 'object') { + uiTransform(subvalue); + } + }); + + return item; +} + +module.exports = uiTransform; diff --git a/server/middleware/tchannel-client.js b/server/middleware/tchannel-client/index.js similarity index 61% rename from server/middleware/tchannel-client.js rename to server/middleware/tchannel-client/index.js index 6b0a34835..f90d03ec0 100644 --- a/server/middleware/tchannel-client.js +++ b/server/middleware/tchannel-client/index.js @@ -21,130 +21,14 @@ 'use strict'; -const path = require('path'), - dns = require('dns'), - get = require('lodash.get'), - TChannelAsThrift = require('tchannel/as/thrift'), - TChannel = require('tchannel'), - Long = require('long'), - losslessJSON = require('lossless-json'), - moment = require('moment'), - isIPv4 = require('is-ipv4-node'); - -function uiTransform(item) { - if (!item || typeof item !== 'object') { - return item; - } - - Object.entries(item).forEach(([subkey, subvalue]) => { - if (subvalue && typeof subvalue.unsigned === 'boolean') { - item[subkey] = Long.fromValue(subvalue).toNumber(); - const m = moment(item[subkey] / 1000000); - - if (m.isValid() && m.isAfter('2017-01-01')) { - item[subkey] = m.toISOString(); - } - } else if (Buffer.isBuffer(subvalue)) { - if (subkey === 'nextPageToken') { - item.nextPageToken = subvalue.toString('base64'); - - return; - } - - const stringval = subvalue.toString('utf8'); - - try { - // most of Cadence's uses of buffer is just line-delimited JSON. - item[subkey] = stringval - .split('\n') - .filter(x => x) - .map(JSON.parse); - - if (item[subkey].length === 1) { - item[subkey] = item[subkey][0]; - } - } catch (e) { - item[`${subkey}_base64`] = subvalue.toString('base64'); - item[subkey] = stringval; - } - } else if (Array.isArray(subvalue)) { - subvalue.forEach(uiTransform); - } else if (subvalue && typeof subvalue === 'object') { - uiTransform(subvalue); - } - }); - - return item; -} - -function cliTransform(item) { - if (!item || typeof item !== 'object') { - return item; - } - - Object.entries(item).forEach(([subkey, subvalue]) => { - if (subvalue && typeof subvalue.unsigned === 'boolean') { - item[subkey] = new losslessJSON.LosslessNumber( - Long.fromValue(subvalue).toString() - ); - } else if (Buffer.isBuffer(subvalue)) { - item[subkey] = subvalue.toString('base64'); - } else if (Array.isArray(subvalue)) { - subvalue.forEach(cliTransform); - } else if (subvalue && typeof subvalue === 'object') { - cliTransform(subvalue); - } else if (subvalue === null || subvalue === undefined) { - delete item[subkey]; - } - }); - - return item; -} - -const lookupAsync = host => - new Promise(function(resolve, reject) { - dns.lookup(host, { family: 4 }, function(err, ip) { - if (err) { - reject(err); - } else { - resolve(ip); - } - }); - }); - -const peers = process.env.CADENCE_TCHANNEL_PEERS - ? process.env.CADENCE_TCHANNEL_PEERS.split(',') - : ['127.0.0.1:7933']; - -async function makeChannel(client) { - const ipPeers = await Promise.all( - peers.map(peer => { - const [host, port] = peer.split(':'); - - if (!isIPv4(host)) { - return lookupAsync(host).then(ip => [ip, port].join(':')); - } else { - return peer; - } - }) - ); - - const cadenceChannel = client.makeSubChannel({ - serviceName: 'cadence-frontend', - peers: ipPeers, - requestDefaults: { - hasNoParent: true, - headers: { as: 'raw', cn: 'cadence-web' }, - }, - }); - - const tchannelAsThrift = TChannelAsThrift({ - channel: cadenceChannel, - entryPoint: path.join(__dirname, '../idl/cadence.thrift'), - }); - - return tchannelAsThrift; -} +const get = require('lodash.get'); +const TChannel = require('tchannel'); + +const { + cliTransform, + makeChannel, + uiTransform, +} = require('./helpers'); module.exports = async function(ctx, next) { const client = TChannel(); diff --git a/server/routes.js b/server/router.js similarity index 97% rename from server/routes.js rename to server/router.js index 26ff42972..969ef4233 100644 --- a/server/routes.js +++ b/server/router.js @@ -19,13 +19,14 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -const Router = require('koa-router'), - router = new Router(), - moment = require('moment'), - Long = require('long'), - losslessJSON = require('lossless-json'), - featureFlags = require('./feature-flags.json'), - momentToLong = m => Long.fromValue(m.unix()).mul(1000000000); +const Router = require('koa-router'); +const losslessJSON = require('lossless-json'); +const moment = require('moment'); + +const featureFlags = require('./feature-flags.json'); +const { momentToLong } = require('./helpers'); + +const router = new Router(); router.get('/api/domains', async function(ctx) { ctx.body = await ctx.cadence.listDomains({ From aec6f41774cbeb65a2a0e3fde1c8f14915dcdf42 Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Thu, 22 Apr 2021 17:50:50 -0700 Subject: [PATCH 02/30] more refactoring --- .../middleware/tchannel-client/constants.js | 27 +++ .../tchannel-client/helpers/format-body.js | 5 + .../tchannel-client/helpers/format-method.js | 3 + .../helpers/format-request-name.js | 3 + .../tchannel-client/helpers/get-peers.js | 5 - .../tchannel-client/helpers/index.js | 18 +- .../tchannel-client/helpers/make-channel.js | 6 +- .../tchannel-client/helpers/make-request.js | 53 ++++ ...th-domain-paging-and-workflow-execution.js | 7 + .../helpers/with-domain-paging.js | 15 ++ .../with-verbose-workflow-execution.js | 20 ++ .../helpers/with-workflow-execution.js | 20 ++ server/middleware/tchannel-client/index.js | 228 +++++++----------- 13 files changed, 255 insertions(+), 155 deletions(-) create mode 100644 server/middleware/tchannel-client/constants.js create mode 100644 server/middleware/tchannel-client/helpers/format-body.js create mode 100644 server/middleware/tchannel-client/helpers/format-method.js create mode 100644 server/middleware/tchannel-client/helpers/format-request-name.js delete mode 100644 server/middleware/tchannel-client/helpers/get-peers.js create mode 100644 server/middleware/tchannel-client/helpers/make-request.js create mode 100644 server/middleware/tchannel-client/helpers/with-domain-paging-and-workflow-execution.js create mode 100644 server/middleware/tchannel-client/helpers/with-domain-paging.js create mode 100644 server/middleware/tchannel-client/helpers/with-verbose-workflow-execution.js create mode 100644 server/middleware/tchannel-client/helpers/with-workflow-execution.js diff --git a/server/middleware/tchannel-client/constants.js b/server/middleware/tchannel-client/constants.js new file mode 100644 index 000000000..db85730cc --- /dev/null +++ b/server/middleware/tchannel-client/constants.js @@ -0,0 +1,27 @@ +const PEERS = process.env.CADENCE_TCHANNEL_PEERS + ? process.env.CADENCE_TCHANNEL_PEERS.split(',') + : ['127.0.0.1:7933']; + +const REQUEST_RETRY_FLAGS = { onConnectionError: true }; + +const REQUEST_RETRY_LIMIT = Number(process.env.CADENCE_TCHANNEL_RETRY_LIMIT || 3); + +const REQUEST_TIMEOUT = 1000 * 60 * 5; + +const SERVICE_NAME = process.env.CADENCE_TCHANNEL_SERVICE || 'cadence-frontend'; + +const REQUEST_CONFIG = { + serviceName: SERVICE_NAME, + timeout: REQUEST_TIMEOUT, + retryFlags: REQUEST_RETRY_FLAGS, + retryLimit: REQUEST_RETRY_LIMIT, +}; + +module.exports = { + PEERS, + REQUEST_CONFIG, + REQUEST_RETRY_FLAGS, + REQUEST_RETRY_LIMIT, + REQUEST_TIMEOUT, + SERVICE_NAME, +}; diff --git a/server/middleware/tchannel-client/helpers/format-body.js b/server/middleware/tchannel-client/helpers/format-body.js new file mode 100644 index 000000000..1e30ded24 --- /dev/null +++ b/server/middleware/tchannel-client/helpers/format-body.js @@ -0,0 +1,5 @@ +const formatBody = ({ body, bodyTransform }) => typeof bodyTransform === 'function' + ? bodyTransform(body) + : body; + +module.exports = formatBody; diff --git a/server/middleware/tchannel-client/helpers/format-method.js b/server/middleware/tchannel-client/helpers/format-method.js new file mode 100644 index 000000000..15f1e7d35 --- /dev/null +++ b/server/middleware/tchannel-client/helpers/format-method.js @@ -0,0 +1,3 @@ +const formatMethod = method => `WorkflowService::${method}`; + +module.exports = formatMethod; diff --git a/server/middleware/tchannel-client/helpers/format-request-name.js b/server/middleware/tchannel-client/helpers/format-request-name.js new file mode 100644 index 000000000..672ef3d7c --- /dev/null +++ b/server/middleware/tchannel-client/helpers/format-request-name.js @@ -0,0 +1,3 @@ +const formatRequestName = requestName => `${requestName ? requestName + 'R' : 'r'}equest`; + +module.exports = formatRequestName; diff --git a/server/middleware/tchannel-client/helpers/get-peers.js b/server/middleware/tchannel-client/helpers/get-peers.js deleted file mode 100644 index 92cdccfb8..000000000 --- a/server/middleware/tchannel-client/helpers/get-peers.js +++ /dev/null @@ -1,5 +0,0 @@ -const getPeers = () => process.env.CADENCE_TCHANNEL_PEERS - ? process.env.CADENCE_TCHANNEL_PEERS.split(',') - : ['127.0.0.1:7933']; - -module.exports = getPeers; diff --git a/server/middleware/tchannel-client/helpers/index.js b/server/middleware/tchannel-client/helpers/index.js index 830a0bd75..2201243df 100644 --- a/server/middleware/tchannel-client/helpers/index.js +++ b/server/middleware/tchannel-client/helpers/index.js @@ -1,13 +1,27 @@ const cliTransform = require('./cli-transform'); -const getPeers = require('./get-peers'); +const formatBody = require('./format-body'); +const formatMethod = require('./format-method'); +const formatRequestName = require('./format-request-name'); const lookupAsync = require('./lookup-async'); const makeChannel = require('./make-channel'); +const makeRequest = require('./make-request'); const uiTransform = require('./ui-transform'); +const withDomainPagingAndWorkflowExecution = require('./with-domain-paging-and-workflow-execution'); +const withDomainPaging = require('./with-domain-paging'); +const withVerboseWorkflowExecution = require('./with-verbose-workflow-execution'); +const withWorkflowExecution = require('./with-workflow-execution'); module.exports = { cliTransform, - getPeers, + formatBody, + formatMethod, + formatRequestName, lookupAsync, makeChannel, + makeRequest, uiTransform, + withDomainPagingAndWorkflowExecution, + withDomainPaging, + withVerboseWorkflowExecution, + withWorkflowExecution, }; diff --git a/server/middleware/tchannel-client/helpers/make-channel.js b/server/middleware/tchannel-client/helpers/make-channel.js index 945969cbd..8263957ec 100644 --- a/server/middleware/tchannel-client/helpers/make-channel.js +++ b/server/middleware/tchannel-client/helpers/make-channel.js @@ -1,15 +1,13 @@ const isIPv4 = require('is-ipv4-node'); const path = require('path'); const TChannelAsThrift = require('tchannel/as/thrift'); - -const getPeers = require('./get-peers'); const lookupAsync = require('./lookup-async'); -const peers = getPeers(); +const { PEERS } = require('../constants'); const makeChannel = async (client) => { const ipPeers = await Promise.all( - peers.map(peer => { + PEERS.map(peer => { const [host, port] = peer.split(':'); if (!isIPv4(host)) { diff --git a/server/middleware/tchannel-client/helpers/make-request.js b/server/middleware/tchannel-client/helpers/make-request.js new file mode 100644 index 000000000..03e293926 --- /dev/null +++ b/server/middleware/tchannel-client/helpers/make-request.js @@ -0,0 +1,53 @@ +const formatBody = require('./format-body'); +const formatMethod = require('./format-method'); +const formatRequestName = require('./format-request-name'); +const uiTransform = require('./ui-transform'); +const { + REQUEST_CONFIG, +} = require('../constants'); + +const makeRequest = ({ + authTokenHeaders, + channel, + ctx, +}) => ({ + method, + requestName, + bodyTransform, + responseTransform, +}) => body => new Promise((resolve, reject) => { + try { + channel + .request(REQUEST_CONFIG) + .send( + formatMethod(method), + { + ...authTokenHeaders, + }, + { + [formatRequestName(requestName)]: formatBody({ body, bodyTransform }), + }, + (error, response) => { + try { + if (error) { + reject(error); + } else if (response.ok) { + resolve((responseTransform || uiTransform)(response.body)); + } else { + ctx.throw( + response.typeName === 'entityNotExistError' ? 404 : 400, + null, + response.body || response + ); + } + } catch (error) { + reject(error); + } + } + ); + } catch (error) { + reject(error); + } +}); + +module.exports = makeRequest; diff --git a/server/middleware/tchannel-client/helpers/with-domain-paging-and-workflow-execution.js b/server/middleware/tchannel-client/helpers/with-domain-paging-and-workflow-execution.js new file mode 100644 index 000000000..c77452079 --- /dev/null +++ b/server/middleware/tchannel-client/helpers/with-domain-paging-and-workflow-execution.js @@ -0,0 +1,7 @@ +const withDomainPaging = require('./with-domain-paging'); +const withWorkflowExecution = require('./with-workflow-execution'); + +const withDomainPagingAndWorkflowExecution = ctx => body => + Object.assign(withDomainPaging(ctx)(body), withWorkflowExecution(ctx)(body)); + +module.exports = withDomainPagingAndWorkflowExecution; diff --git a/server/middleware/tchannel-client/helpers/with-domain-paging.js b/server/middleware/tchannel-client/helpers/with-domain-paging.js new file mode 100644 index 000000000..78a75a876 --- /dev/null +++ b/server/middleware/tchannel-client/helpers/with-domain-paging.js @@ -0,0 +1,15 @@ +const get = require('lodash.get'); + +const withDomainPaging = ctx => body => { + const { domain } = get(ctx, 'params', {}); + + return Object.assign( + { + domain, + maximumPageSize: 100, + }, + body + ); +}; + +module.exports = withDomainPaging; diff --git a/server/middleware/tchannel-client/helpers/with-verbose-workflow-execution.js b/server/middleware/tchannel-client/helpers/with-verbose-workflow-execution.js new file mode 100644 index 000000000..07e464f8f --- /dev/null +++ b/server/middleware/tchannel-client/helpers/with-verbose-workflow-execution.js @@ -0,0 +1,20 @@ +const get = require('lodash.get'); + +const withVerboseWorkflowExecution = ctx => body => { + const { domain, runId, workflowId } = get(ctx, 'params', {}); + + const workflowExecution = (workflowId || runId) && { + workflowId, + runId, + }; + + return Object.assign( + { + domain, + workflowExecution, + }, + body + ); +}; + +module.exports = withVerboseWorkflowExecution; diff --git a/server/middleware/tchannel-client/helpers/with-workflow-execution.js b/server/middleware/tchannel-client/helpers/with-workflow-execution.js new file mode 100644 index 000000000..d91ab18b0 --- /dev/null +++ b/server/middleware/tchannel-client/helpers/with-workflow-execution.js @@ -0,0 +1,20 @@ +const get = require('lodash.get'); + +const withWorkflowExecution = ctx => body => { + const { domain, runId, workflowId } = get(ctx, 'params', {}); + + const execution = (workflowId || runId) && { + workflowId, + runId, + }; + + return Object.assign( + { + domain, + execution, + }, + body + ); +}; + +module.exports = withWorkflowExecution; diff --git a/server/middleware/tchannel-client/index.js b/server/middleware/tchannel-client/index.js index f90d03ec0..f6b253d13 100644 --- a/server/middleware/tchannel-client/index.js +++ b/server/middleware/tchannel-client/index.js @@ -21,161 +21,99 @@ 'use strict'; -const get = require('lodash.get'); const TChannel = require('tchannel'); const { cliTransform, makeChannel, - uiTransform, + makeRequest, + withDomainPaging, + withWorkflowExecution, + withVerboseWorkflowExecution, + withDomainPagingAndWorkflowExecution, } = require('./helpers'); -module.exports = async function(ctx, next) { - const client = TChannel(); - const channel = await makeChannel(client, ctx); +const tchannelClient = async function(ctx, next) { const { authTokenHeaders = {} } = ctx; - function req(method, reqName, bodyTransform, resTransform) { - return body => - new Promise(function(resolve, reject) { - try { - channel - .request({ - serviceName: - process.env.CADENCE_TCHANNEL_SERVICE || 'cadence-frontend', - timeout: 1000 * 60 * 5, - retryFlags: { onConnectionError: true }, - retryLimit: Number(process.env.CADENCE_TCHANNEL_RETRY_LIMIT || 3), - }) - .send( - `WorkflowService::${method}`, - { - ...authTokenHeaders, - }, - { - [`${reqName ? reqName + 'R' : 'r'}equest`]: - typeof bodyTransform === 'function' - ? bodyTransform(body) - : body, - }, - function(err, res) { - try { - if (err) { - reject(err); - } else if (res.ok) { - resolve((resTransform || uiTransform)(res.body)); - } else { - ctx.throw( - res.typeName === 'entityNotExistError' ? 404 : 400, - null, - res.body || res - ); - } - } catch (e) { - reject(e); - } - } - ); - } catch (e) { - reject(e); - } - }); - } - - const withDomainPaging = body => { - const { domain } = get(ctx, 'params', {}); - - return Object.assign( - { - domain, - maximumPageSize: 100, - }, - body - ); - }; - - const withWorkflowExecution = body => { - const { domain, runId, workflowId } = get(ctx, 'params', {}); - - const execution = (workflowId || runId) && { - workflowId, - runId, - }; - - return Object.assign( - { - domain, - execution, - }, - body - ); - }; - - const withVerboseWorkflowExecution = body => { - const { domain, runId, workflowId } = get(ctx, 'params', {}); - - const workflowExecution = (workflowId || runId) && { - workflowId, - runId, - }; - - return Object.assign( - { - domain, - workflowExecution, - }, - body - ); - }; - - const withDomainPagingAndWorkflowExecution = body => - Object.assign(withDomainPaging(body), withWorkflowExecution(body)); + const client = TChannel(); + const channel = await makeChannel(client); + const request = makeRequest({ + authTokenHeaders, + channel, + ctx, + }); ctx.cadence = { - archivedWorkflows: req( - 'ListArchivedWorkflowExecutions', - 'list', - withDomainPaging - ), - closedWorkflows: req( - 'ListClosedWorkflowExecutions', - 'list', - withDomainPaging - ), - describeDomain: req('DescribeDomain', 'describe'), - describeTaskList: req('DescribeTaskList'), - describeWorkflow: req( - 'DescribeWorkflowExecution', - 'describe', - withWorkflowExecution - ), - exportHistory: req( - 'GetWorkflowExecutionHistory', - 'get', - withDomainPagingAndWorkflowExecution, - cliTransform - ), - getHistory: req( - 'GetWorkflowExecutionHistory', - 'get', - withDomainPagingAndWorkflowExecution - ), - listDomains: req('ListDomains', 'list'), - listTaskListPartitions: req('ListTaskListPartitions'), - listWorkflows: req('ListWorkflowExecutions', 'list', withDomainPaging), - openWorkflows: req('ListOpenWorkflowExecutions', 'list', withDomainPaging), - queryWorkflow: req('QueryWorkflow', 'query', withWorkflowExecution), - signalWorkflow: req( - 'SignalWorkflowExecution', - 'signal', - withVerboseWorkflowExecution - ), - startWorkflow: req('StartWorkflowExecution', 'start'), - terminateWorkflow: req( - 'TerminateWorkflowExecution', - 'terminate', - withVerboseWorkflowExecution - ), + archivedWorkflows: request({ + method: 'ListArchivedWorkflowExecutions', + requestName: 'list', + bodyTransform: withDomainPaging(ctx), + }), + closedWorkflows: request({ + method: 'ListClosedWorkflowExecutions', + requestName: 'list', + bodyTransform: withDomainPaging(ctx), + }), + describeDomain: request({ + method: 'DescribeDomain', + requestName: 'describe', + }), + describeTaskList: request({ + method: 'DescribeTaskList', + }), + describeWorkflow: request({ + method: 'DescribeWorkflowExecution', + requestName: 'describe', + bodyTransform: withWorkflowExecution(ctx), + }), + exportHistory: request({ + method: 'GetWorkflowExecutionHistory', + requestName: 'get', + bodyTransform: withDomainPagingAndWorkflowExecution(ctx), + responseTransform: cliTransform, + }), + getHistory: request({ + method: 'GetWorkflowExecutionHistory', + requestName: 'get', + bodyTransform: withDomainPagingAndWorkflowExecution(ctx), + }), + listDomains: request({ + method: 'ListDomains', + requestName: 'list', + }), + listTaskListPartitions: request({ + method: 'ListTaskListPartitions', + }), + listWorkflows: request({ + method: 'ListWorkflowExecutions', + requestName: 'list', + bodyTransform: withDomainPaging(ctx), + }), + openWorkflows: request({ + method: 'ListOpenWorkflowExecutions', + requestName: 'list', + bodyTransform: withDomainPaging(ctx), + }), + queryWorkflow: request({ + method: 'QueryWorkflow', + requestName: 'query', + bodyTransform: withWorkflowExecution(ctx), + }), + signalWorkflow: request({ + method: 'SignalWorkflowExecution', + requestName: 'signal', + bodyTransform: withVerboseWorkflowExecution(ctx), + }), + startWorkflow: request({ + method: 'StartWorkflowExecution', + requestName: 'start', + }), + terminateWorkflow: request({ + method: 'TerminateWorkflowExecution', + requestName: 'terminate', + bodyTransform: withVerboseWorkflowExecution(ctx), + }), }; try { @@ -186,3 +124,5 @@ module.exports = async function(ctx, next) { throw e; } }; + +module.exports = tchannelClient; From 896cb5ab182f31b95b0696cedb0c08693418d2f4 Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Fri, 23 Apr 2021 10:05:49 -0700 Subject: [PATCH 03/30] fix lint --- server/helpers/index.js | 21 ++++++++ server/helpers/moment-to-long.js | 21 ++++++++ server/index.js | 3 +- .../middleware/tchannel-client/constants.js | 25 +++++++++- .../tchannel-client/helpers/cli-transform.js | 23 ++++++++- .../tchannel-client/helpers/format-body.js | 26 ++++++++-- .../tchannel-client/helpers/format-method.js | 21 ++++++++ .../helpers/format-request-name.js | 24 +++++++++- .../tchannel-client/helpers/index.js | 21 ++++++++ .../tchannel-client/helpers/lookup-async.js | 38 +++++++++++---- .../tchannel-client/helpers/make-channel.js | 28 +++++++++-- .../tchannel-client/helpers/make-request.js | 48 ++++++++++++------- .../tchannel-client/helpers/ui-transform.js | 23 ++++++++- ...th-domain-paging-and-workflow-execution.js | 21 ++++++++ .../helpers/with-domain-paging.js | 21 ++++++++ .../with-verbose-workflow-execution.js | 21 ++++++++ .../helpers/with-workflow-execution.js | 21 ++++++++ 17 files changed, 369 insertions(+), 37 deletions(-) diff --git a/server/helpers/index.js b/server/helpers/index.js index 19a183e1e..11957b0e5 100644 --- a/server/helpers/index.js +++ b/server/helpers/index.js @@ -1,3 +1,24 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const momentToLong = require('./moment-to-long'); module.exports = { diff --git a/server/helpers/moment-to-long.js b/server/helpers/moment-to-long.js index c30f7ce4e..fd5d0572d 100644 --- a/server/helpers/moment-to-long.js +++ b/server/helpers/moment-to-long.js @@ -1,3 +1,24 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const Long = require('long'); const momentToLong = m => Long.fromValue(m.unix()).mul(1000000000); diff --git a/server/index.js b/server/index.js index 92a09a4cb..7c8b0566b 100644 --- a/server/index.js +++ b/server/index.js @@ -28,12 +28,13 @@ const koaStatic = require('koa-static'); const koaWebpack = require('koa-webpack'); const webpack = require('webpack'); +const webpackConfig = require('../webpack.config'); const tchannelClient = require('./middleware/tchannel-client'); const router = require('./router'); -const webpackConfig = require('../webpack.config'); const staticRoot = path.join(__dirname, '../dist'); const app = new Koa(); + app.webpackConfig = webpackConfig; app.init = function(options) { diff --git a/server/middleware/tchannel-client/constants.js b/server/middleware/tchannel-client/constants.js index db85730cc..853a68057 100644 --- a/server/middleware/tchannel-client/constants.js +++ b/server/middleware/tchannel-client/constants.js @@ -1,10 +1,33 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const PEERS = process.env.CADENCE_TCHANNEL_PEERS ? process.env.CADENCE_TCHANNEL_PEERS.split(',') : ['127.0.0.1:7933']; const REQUEST_RETRY_FLAGS = { onConnectionError: true }; -const REQUEST_RETRY_LIMIT = Number(process.env.CADENCE_TCHANNEL_RETRY_LIMIT || 3); +const REQUEST_RETRY_LIMIT = Number( + process.env.CADENCE_TCHANNEL_RETRY_LIMIT || 3 +); const REQUEST_TIMEOUT = 1000 * 60 * 5; diff --git a/server/middleware/tchannel-client/helpers/cli-transform.js b/server/middleware/tchannel-client/helpers/cli-transform.js index 8579a5d39..b8fc7a6ef 100644 --- a/server/middleware/tchannel-client/helpers/cli-transform.js +++ b/server/middleware/tchannel-client/helpers/cli-transform.js @@ -1,3 +1,24 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const Long = require('long'); const losslessJSON = require('lossless-json'); @@ -23,6 +44,6 @@ const cliTransform = item => { }); return item; -} +}; module.exports = cliTransform; diff --git a/server/middleware/tchannel-client/helpers/format-body.js b/server/middleware/tchannel-client/helpers/format-body.js index 1e30ded24..7d698daa4 100644 --- a/server/middleware/tchannel-client/helpers/format-body.js +++ b/server/middleware/tchannel-client/helpers/format-body.js @@ -1,5 +1,25 @@ -const formatBody = ({ body, bodyTransform }) => typeof bodyTransform === 'function' - ? bodyTransform(body) - : body; +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +const formatBody = ({ body, bodyTransform }) => + typeof bodyTransform === 'function' ? bodyTransform(body) : body; module.exports = formatBody; diff --git a/server/middleware/tchannel-client/helpers/format-method.js b/server/middleware/tchannel-client/helpers/format-method.js index 15f1e7d35..dd6dd08a5 100644 --- a/server/middleware/tchannel-client/helpers/format-method.js +++ b/server/middleware/tchannel-client/helpers/format-method.js @@ -1,3 +1,24 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const formatMethod = method => `WorkflowService::${method}`; module.exports = formatMethod; diff --git a/server/middleware/tchannel-client/helpers/format-request-name.js b/server/middleware/tchannel-client/helpers/format-request-name.js index 672ef3d7c..65d9a3427 100644 --- a/server/middleware/tchannel-client/helpers/format-request-name.js +++ b/server/middleware/tchannel-client/helpers/format-request-name.js @@ -1,3 +1,25 @@ -const formatRequestName = requestName => `${requestName ? requestName + 'R' : 'r'}equest`; +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +const formatRequestName = requestName => + `${requestName ? requestName + 'R' : 'r'}equest`; module.exports = formatRequestName; diff --git a/server/middleware/tchannel-client/helpers/index.js b/server/middleware/tchannel-client/helpers/index.js index 2201243df..aff040afa 100644 --- a/server/middleware/tchannel-client/helpers/index.js +++ b/server/middleware/tchannel-client/helpers/index.js @@ -1,3 +1,24 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const cliTransform = require('./cli-transform'); const formatBody = require('./format-body'); const formatMethod = require('./format-method'); diff --git a/server/middleware/tchannel-client/helpers/lookup-async.js b/server/middleware/tchannel-client/helpers/lookup-async.js index cf5ad690e..e14443e79 100644 --- a/server/middleware/tchannel-client/helpers/lookup-async.js +++ b/server/middleware/tchannel-client/helpers/lookup-async.js @@ -1,13 +1,35 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const dns = require('dns'); -const lookupAsync = host => new Promise((resolve, reject) => { - dns.lookup(host, { family: 4 }, (err, ip) => { - if (err) { - reject(err); - } else { - resolve(ip); - } +const lookupAsync = host => + new Promise((resolve, reject) => { + dns.lookup(host, { family: 4 }, (err, ip) => { + if (err) { + reject(err); + } else { + resolve(ip); + } + }); }); -}); module.exports = lookupAsync; diff --git a/server/middleware/tchannel-client/helpers/make-channel.js b/server/middleware/tchannel-client/helpers/make-channel.js index 8263957ec..6fb31827e 100644 --- a/server/middleware/tchannel-client/helpers/make-channel.js +++ b/server/middleware/tchannel-client/helpers/make-channel.js @@ -1,11 +1,31 @@ -const isIPv4 = require('is-ipv4-node'); +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const path = require('path'); +const isIPv4 = require('is-ipv4-node'); const TChannelAsThrift = require('tchannel/as/thrift'); -const lookupAsync = require('./lookup-async'); - const { PEERS } = require('../constants'); +const lookupAsync = require('./lookup-async'); -const makeChannel = async (client) => { +const makeChannel = async client => { const ipPeers = await Promise.all( PEERS.map(peer => { const [host, port] = peer.split(':'); diff --git a/server/middleware/tchannel-client/helpers/make-request.js b/server/middleware/tchannel-client/helpers/make-request.js index 03e293926..5d464d271 100644 --- a/server/middleware/tchannel-client/helpers/make-request.js +++ b/server/middleware/tchannel-client/helpers/make-request.js @@ -1,25 +1,39 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +const { REQUEST_CONFIG } = require('../constants'); const formatBody = require('./format-body'); const formatMethod = require('./format-method'); const formatRequestName = require('./format-request-name'); const uiTransform = require('./ui-transform'); -const { - REQUEST_CONFIG, -} = require('../constants'); -const makeRequest = ({ - authTokenHeaders, - channel, - ctx, -}) => ({ +const makeRequest = ({ authTokenHeaders, channel, ctx }) => ({ method, requestName, bodyTransform, responseTransform, -}) => body => new Promise((resolve, reject) => { - try { - channel - .request(REQUEST_CONFIG) - .send( +}) => body => + new Promise((resolve, reject) => { + try { + channel.request(REQUEST_CONFIG).send( formatMethod(method), { ...authTokenHeaders, @@ -45,9 +59,9 @@ const makeRequest = ({ } } ); - } catch (error) { - reject(error); - } -}); + } catch (error) { + reject(error); + } + }); module.exports = makeRequest; diff --git a/server/middleware/tchannel-client/helpers/ui-transform.js b/server/middleware/tchannel-client/helpers/ui-transform.js index f9725d191..1d55764d4 100644 --- a/server/middleware/tchannel-client/helpers/ui-transform.js +++ b/server/middleware/tchannel-client/helpers/ui-transform.js @@ -1,3 +1,24 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const Long = require('long'); const moment = require('moment'); @@ -45,6 +66,6 @@ const uiTransform = item => { }); return item; -} +}; module.exports = uiTransform; diff --git a/server/middleware/tchannel-client/helpers/with-domain-paging-and-workflow-execution.js b/server/middleware/tchannel-client/helpers/with-domain-paging-and-workflow-execution.js index c77452079..09f598c85 100644 --- a/server/middleware/tchannel-client/helpers/with-domain-paging-and-workflow-execution.js +++ b/server/middleware/tchannel-client/helpers/with-domain-paging-and-workflow-execution.js @@ -1,3 +1,24 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const withDomainPaging = require('./with-domain-paging'); const withWorkflowExecution = require('./with-workflow-execution'); diff --git a/server/middleware/tchannel-client/helpers/with-domain-paging.js b/server/middleware/tchannel-client/helpers/with-domain-paging.js index 78a75a876..544ca817e 100644 --- a/server/middleware/tchannel-client/helpers/with-domain-paging.js +++ b/server/middleware/tchannel-client/helpers/with-domain-paging.js @@ -1,3 +1,24 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const get = require('lodash.get'); const withDomainPaging = ctx => body => { diff --git a/server/middleware/tchannel-client/helpers/with-verbose-workflow-execution.js b/server/middleware/tchannel-client/helpers/with-verbose-workflow-execution.js index 07e464f8f..68737337f 100644 --- a/server/middleware/tchannel-client/helpers/with-verbose-workflow-execution.js +++ b/server/middleware/tchannel-client/helpers/with-verbose-workflow-execution.js @@ -1,3 +1,24 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const get = require('lodash.get'); const withVerboseWorkflowExecution = ctx => body => { diff --git a/server/middleware/tchannel-client/helpers/with-workflow-execution.js b/server/middleware/tchannel-client/helpers/with-workflow-execution.js index d91ab18b0..2ec18bbbc 100644 --- a/server/middleware/tchannel-client/helpers/with-workflow-execution.js +++ b/server/middleware/tchannel-client/helpers/with-workflow-execution.js @@ -1,3 +1,24 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const get = require('lodash.get'); const withWorkflowExecution = ctx => body => { From 4e8de816b737df0e99fecdb25c18dc44c3dbe7b4 Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Fri, 23 Apr 2021 11:23:46 -0700 Subject: [PATCH 04/30] moved router into its own folder. moved helpers into router folder. split out more helpers in router into helpers. --- server/router/helpers/build-query-string.js | 16 ++++ server/{ => router}/helpers/index.js | 8 ++ server/router/helpers/list-workflows.js | 25 +++++++ server/router/helpers/map-history-response.js | 24 ++++++ server/{ => router}/helpers/moment-to-long.js | 0 server/router/helpers/replacer.js | 12 +++ server/{router.js => router/index.js} | 74 ++----------------- server/router/routes/domain-list-handler.js | 1 + server/router/routes/index.js | 0 9 files changed, 92 insertions(+), 68 deletions(-) create mode 100644 server/router/helpers/build-query-string.js rename server/{ => router}/helpers/index.js (81%) create mode 100644 server/router/helpers/list-workflows.js create mode 100644 server/router/helpers/map-history-response.js rename server/{ => router}/helpers/moment-to-long.js (100%) create mode 100644 server/router/helpers/replacer.js rename server/{router.js => router/index.js} (83%) create mode 100644 server/router/routes/domain-list-handler.js create mode 100644 server/router/routes/index.js diff --git a/server/router/helpers/build-query-string.js b/server/router/helpers/build-query-string.js new file mode 100644 index 000000000..2f80d1cc9 --- /dev/null +++ b/server/router/helpers/build-query-string.js @@ -0,0 +1,16 @@ +const buildQueryString = ( + startTime, + endTime, + { status, workflowId, workflowName } +) => + [ + `CloseTime >= "${startTime.toISOString()}"`, + `CloseTime <= "${endTime.toISOString()}"`, + status && `CloseStatus = "${status}"`, + workflowId && `WorkflowID = "${workflowId}"`, + workflowName && `WorkflowType = "${workflowName}"`, + ] + .filter(subQuery => !!subQuery) + .join(' and '); + +module.exports = buildQueryString; diff --git a/server/helpers/index.js b/server/router/helpers/index.js similarity index 81% rename from server/helpers/index.js rename to server/router/helpers/index.js index 11957b0e5..8e979dddb 100644 --- a/server/helpers/index.js +++ b/server/router/helpers/index.js @@ -19,8 +19,16 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +const buildQueryString = require('./build-query-string'); +const listWorkflows = require('./list-workflows'); +const mapHistoryResponse = require('./map-history-response'); const momentToLong = require('./moment-to-long'); +const replacer = require('./replacer'); module.exports = { + buildQueryString, + listWorkflows, + mapHistoryResponse, momentToLong, + replacer, }; diff --git a/server/router/helpers/list-workflows.js b/server/router/helpers/list-workflows.js new file mode 100644 index 000000000..a4b9c0544 --- /dev/null +++ b/server/router/helpers/list-workflows.js @@ -0,0 +1,25 @@ +const moment = require('moment'); +const momentToLong = require('./moment-to-long'); + +async function listWorkflows(state, ctx) { + const q = ctx.query || {}, + startTime = moment(q.startTime || NaN), + endTime = moment(q.endTime || NaN); + + ctx.assert(startTime.isValid() && endTime.isValid(), 400); + + ctx.body = await ctx.cadence[state + 'Workflows']({ + StartTimeFilter: { + earliestTime: momentToLong(startTime), + latestTime: momentToLong(endTime), + }, + typeFilter: q.workflowName ? { name: q.workflowName } : undefined, + executionFilter: q.workflowId ? { workflowId: q.workflowId } : undefined, + statusFilter: q.status || undefined, + nextPageToken: q.nextPageToken + ? Buffer.from(q.nextPageToken, 'base64') + : undefined, + }); +} + +module.exports = listWorkflows; diff --git a/server/router/helpers/map-history-response.js b/server/router/helpers/map-history-response.js new file mode 100644 index 000000000..1d34d7630 --- /dev/null +++ b/server/router/helpers/map-history-response.js @@ -0,0 +1,24 @@ +const replacer = require('./replacer'); + +const mapHistoryResponse = history => { + if (Array.isArray(history && history.events)) { + return history.events.map(e => { + const attr = e.eventType + ? e.eventType.charAt(0).toLowerCase() + + e.eventType.slice(1) + + 'EventAttributes' + : ''; + + const details = e[attr] && JSON.parse(JSON.stringify(e[attr]), replacer); + + return { + timestamp: e.timestamp, + eventType: e.eventType, + eventId: e.eventId, + details, + }; + }); + } +}; + +module.exports = mapHistoryResponse; diff --git a/server/helpers/moment-to-long.js b/server/router/helpers/moment-to-long.js similarity index 100% rename from server/helpers/moment-to-long.js rename to server/router/helpers/moment-to-long.js diff --git a/server/router/helpers/replacer.js b/server/router/helpers/replacer.js new file mode 100644 index 000000000..40bc41d94 --- /dev/null +++ b/server/router/helpers/replacer.js @@ -0,0 +1,12 @@ +const replacer = (key, value) => { + if (value && value.type && value.type === 'Buffer') { + return Buffer.from(value) + .toString() + .replace(/["]/g, '') + .trim(); + } + + return value; +}; + +module.exports = replacer; diff --git a/server/router.js b/server/router/index.js similarity index 83% rename from server/router.js rename to server/router/index.js index 969ef4233..a5dbd6d14 100644 --- a/server/router.js +++ b/server/router/index.js @@ -24,7 +24,11 @@ const losslessJSON = require('lossless-json'); const moment = require('moment'); const featureFlags = require('./feature-flags.json'); -const { momentToLong } = require('./helpers'); +const { + buildQueryString, + listWorkflows, + mapHistoryResponse, +} = require('./helpers'); const router = new Router(); @@ -41,26 +45,6 @@ router.get('/api/domains/:domain', async function(ctx) { ctx.body = await ctx.cadence.describeDomain({ name: ctx.params.domain }); }); -async function listWorkflows(state, ctx) { - const q = ctx.query || {}, - startTime = moment(q.startTime || NaN), - endTime = moment(q.endTime || NaN); - - ctx.assert(startTime.isValid() && endTime.isValid(), 400); - - ctx.body = await ctx.cadence[state + 'Workflows']({ - StartTimeFilter: { - earliestTime: momentToLong(startTime), - latestTime: momentToLong(endTime), - }, - typeFilter: q.workflowName ? { name: q.workflowName } : undefined, - executionFilter: q.workflowId ? { workflowId: q.workflowId } : undefined, - statusFilter: q.status || undefined, - nextPageToken: q.nextPageToken - ? Buffer.from(q.nextPageToken, 'base64') - : undefined, - }); -} /** * Override this route to perform authorization check @@ -89,26 +73,12 @@ router.get( '/api/domains/:domain/workflows/open', listWorkflows.bind(null, 'open') ); + router.get( '/api/domains/:domain/workflows/closed', listWorkflows.bind(null, 'closed') ); -const buildQueryString = ( - startTime, - endTime, - { status, workflowId, workflowName } -) => - [ - `CloseTime >= "${startTime.toISOString()}"`, - `CloseTime <= "${endTime.toISOString()}"`, - status && `CloseStatus = "${status}"`, - workflowId && `WorkflowID = "${workflowId}"`, - workflowName && `WorkflowType = "${workflowName}"`, - ] - .filter(subQuery => !!subQuery) - .join(' and '); - router.get('/api/domains/:domain/workflows/archived', async function(ctx) { const { nextPageToken, ...query } = ctx.query || {}; let queryString; @@ -142,38 +112,6 @@ router.get('/api/domains/:domain/workflows/list', async function(ctx) { }); }); -function replacer(key, value) { - if (value && value.type && value.type === 'Buffer') { - return Buffer.from(value) - .toString() - .replace(/["]/g, '') - .trim(); - } - - return value; -} - -const mapHistoryResponse = history => { - if (Array.isArray(history && history.events)) { - return history.events.map(e => { - const attr = e.eventType - ? e.eventType.charAt(0).toLowerCase() + - e.eventType.slice(1) + - 'EventAttributes' - : ''; - - const details = e[attr] && JSON.parse(JSON.stringify(e[attr]), replacer); - - return { - timestamp: e.timestamp, - eventType: e.eventType, - eventId: e.eventId, - details, - }; - }); - } -}; - router.get( '/api/domains/:domain/workflows/:workflowId/:runId/history', async function(ctx) { diff --git a/server/router/routes/domain-list-handler.js b/server/router/routes/domain-list-handler.js new file mode 100644 index 000000000..0ffdd02fc --- /dev/null +++ b/server/router/routes/domain-list-handler.js @@ -0,0 +1 @@ +// TODO \ No newline at end of file diff --git a/server/router/routes/index.js b/server/router/routes/index.js new file mode 100644 index 000000000..e69de29bb From 6952a2e192bea3c087cf85e93104a0b950781df5 Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Fri, 23 Apr 2021 11:36:46 -0700 Subject: [PATCH 05/30] fix conflicts --- server/router/index.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/server/router/index.js b/server/router/index.js index 314808f91..a5dbd6d14 100644 --- a/server/router/index.js +++ b/server/router/index.js @@ -24,15 +24,11 @@ const losslessJSON = require('lossless-json'); const moment = require('moment'); const featureFlags = require('./feature-flags.json'); -<<<<<<< HEAD:server/router/index.js const { buildQueryString, listWorkflows, mapHistoryResponse, } = require('./helpers'); -======= -const { momentToLong } = require('./helpers'); ->>>>>>> master:server/router.js const router = new Router(); From c17d10a9eb8e38dc2903f42597350495a7013627 Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Fri, 23 Apr 2021 13:09:01 -0700 Subject: [PATCH 06/30] moving code into separate files for route handlers --- server/router/index.js | 305 +++--------------- .../routes/domain-authorization-handler.js | 9 + server/router/routes/domain-handler.js | 5 + server/router/routes/domain-list-handler.js | 11 +- server/router/routes/feature-flag-handler.js | 18 ++ server/router/routes/health-handler.js | 3 + server/router/routes/index.js | 37 +++ server/router/routes/tasklist-handler.js | 20 ++ .../routes/tasklist-partition-list-handler.js | 10 + .../routes/tasklist-poller-list-handler.js | 36 +++ .../routes/workflow-archived-list-handler.js | 26 ++ .../router/routes/workflow-export-handler.js | 25 ++ server/router/routes/workflow-handler.js | 69 ++++ .../router/routes/workflow-history-handler.js | 16 + server/router/routes/workflow-list-handler.js | 12 + .../router/routes/workflow-query-handler.js | 20 ++ .../routes/workflow-query-type-handler.js | 9 + .../router/routes/workflow-signal-handler.js | 7 + .../routes/workflow-terminate-handler.js | 7 + 19 files changed, 376 insertions(+), 269 deletions(-) create mode 100644 server/router/routes/domain-authorization-handler.js create mode 100644 server/router/routes/domain-handler.js create mode 100644 server/router/routes/feature-flag-handler.js create mode 100644 server/router/routes/health-handler.js create mode 100644 server/router/routes/tasklist-handler.js create mode 100644 server/router/routes/tasklist-partition-list-handler.js create mode 100644 server/router/routes/tasklist-poller-list-handler.js create mode 100644 server/router/routes/workflow-archived-list-handler.js create mode 100644 server/router/routes/workflow-export-handler.js create mode 100644 server/router/routes/workflow-handler.js create mode 100644 server/router/routes/workflow-history-handler.js create mode 100644 server/router/routes/workflow-list-handler.js create mode 100644 server/router/routes/workflow-query-handler.js create mode 100644 server/router/routes/workflow-query-type-handler.js create mode 100644 server/router/routes/workflow-signal-handler.js create mode 100644 server/router/routes/workflow-terminate-handler.js diff --git a/server/router/index.js b/server/router/index.js index a5dbd6d14..d537b988c 100644 --- a/server/router/index.js +++ b/server/router/index.js @@ -20,31 +20,35 @@ // THE SOFTWARE. const Router = require('koa-router'); -const losslessJSON = require('lossless-json'); -const moment = require('moment'); -const featureFlags = require('./feature-flags.json'); const { - buildQueryString, + domainAuthorizationHandler, + domainHandler, + domainListHandler, + featureFlagHandler, + healthHandler, + tasklistHandler, + tasklistPartitionListHandler, + tasklistPollerListHandler, + workflowArchivedListHandler, + workflowExportHandler, + workflowHandler, + workflowHistoryHandler, + workflowListHandler, + workflowQueryHandler, + workflowQueryTypeHandler, + workflowSignalHandler, + workflowTerminateHandler, +} = require('./routes'); + +const { listWorkflows, - mapHistoryResponse, } = require('./helpers'); const router = new Router(); -router.get('/api/domains', async function(ctx) { - ctx.body = await ctx.cadence.listDomains({ - pageSize: 50, - nextPageToken: ctx.query.nextPageToken - ? Buffer.from(ctx.query.nextPageToken, 'base64') - : undefined, - }); -}); - -router.get('/api/domains/:domain', async function(ctx) { - ctx.body = await ctx.cadence.describeDomain({ name: ctx.params.domain }); -}); - +router.get('/api/domains', domainListHandler); +router.get('/api/domains/:domain', domainHandler); /** * Override this route to perform authorization check @@ -61,13 +65,7 @@ router.get('/api/domains/:domain', async function(ctx) { * }; * }) */ -router.get('/api/domains/:domain/authorization', async function(ctx, next) { - ctx.body = { - authorization: true, - }; - - next(); -}); +router.get('/api/domains/:domain/authorization', domainAuthorizationHandler); router.get( '/api/domains/:domain/workflows/open', @@ -79,282 +77,53 @@ router.get( listWorkflows.bind(null, 'closed') ); -router.get('/api/domains/:domain/workflows/archived', async function(ctx) { - const { nextPageToken, ...query } = ctx.query || {}; - let queryString; - - if (query.queryString) { - queryString = query.queryString; - } else { - const startTime = moment(query.startTime || NaN); - const endTime = moment(query.endTime || NaN); - - ctx.assert(startTime.isValid() && endTime.isValid(), 400); - queryString = buildQueryString(startTime, endTime, query); - } - - ctx.body = await ctx.cadence.archivedWorkflows({ - query: queryString, - nextPageToken: nextPageToken - ? Buffer.from(nextPageToken, 'base64') - : undefined, - }); -}); - -router.get('/api/domains/:domain/workflows/list', async function(ctx) { - const q = ctx.query || {}; +router.get('/api/domains/:domain/workflows/archived', workflowArchivedListHandler); - ctx.body = await ctx.cadence.listWorkflows({ - query: q.queryString || undefined, - nextPageToken: q.nextPageToken - ? Buffer.from(q.nextPageToken, 'base64') - : undefined, - }); -}); +router.get('/api/domains/:domain/workflows/list', workflowListHandler); router.get( '/api/domains/:domain/workflows/:workflowId/:runId/history', - async function(ctx) { - const q = ctx.query || {}; - - ctx.body = await ctx.cadence.getHistory({ - nextPageToken: q.nextPageToken - ? Buffer.from(q.nextPageToken, 'base64') - : undefined, - waitForNewEvent: 'waitForNewEvent' in q ? true : undefined, - }); - - ctx.body.history.events = mapHistoryResponse(ctx.body.history); - } + workflowHistoryHandler ); router.get( '/api/domains/:domain/workflows/:workflowId/:runId/export', - async function(ctx) { - let nextPageToken; - - do { - const page = await ctx.cadence.exportHistory({ nextPageToken }); - - if (!nextPageToken) { - ctx.status = 200; - } - - ctx.res.write( - (nextPageToken ? ',' : '[') + - page.history.events.map(losslessJSON.stringify).join(',') - ); - nextPageToken = - page.nextPageToken && Buffer.from(page.nextPageToken, 'base64'); - } while (nextPageToken); - - ctx.res.write(']'); - ctx.body = ''; - } + workflowExportHandler ); router.get( '/api/domains/:domain/workflows/:workflowId/:runId/query', - async function(ctx) { - // workaround implementation until https://github.com/uber/cadence/issues/382 is resolved - try { - await ctx.cadence.queryWorkflow({ - query: { - queryType: '__cadence_web_list', - }, - }); - - ctx.throw(500); - } catch (e) { - ctx.body = ((e.message || '').match( - /(KnownQueryTypes|knownTypes)=\[(.*)\]/ - ) || [null, null, ''])[2] - .split(/, | /) - .filter(q => q); - } - } + workflowQueryHandler ); router.post( '/api/domains/:domain/workflows/:workflowId/:runId/query/:queryType', - async function(ctx) { - ctx.body = await ctx.cadence.queryWorkflow({ - query: { - queryType: ctx.params.queryType, - }, - }); - } + workflowQueryTypeHandler ); router.post( '/api/domains/:domain/workflows/:workflowId/:runId/terminate', - async function(ctx) { - ctx.body = await ctx.cadence.terminateWorkflow({ - reason: ctx.request.body && ctx.request.body.reason, - }); - } + workflowTerminateHandler ); router.post( '/api/domains/:domain/workflows/:workflowId/:runId/signal/:signal', - async function(ctx) { - ctx.body = await ctx.cadence.signalWorkflow({ - signalName: ctx.params.signal, - }); - } + workflowSignalHandler ); -router.get('/api/domains/:domain/workflows/:workflowId/:runId', async function( - ctx -) { - try { - const describeResponse = await ctx.cadence.describeWorkflow(); - - if (describeResponse.workflowExecutionInfo) { - describeResponse.workflowExecutionInfo.closeEvent = null; - - if (describeResponse.workflowExecutionInfo.closeStatus) { - const closeEventResponse = await ctx.cadence.getHistory({ - HistoryEventFilterType: 'CLOSE_EVENT', - }); +router.get('/api/domains/:domain/workflows/:workflowId/:runId', workflowHandler); - describeResponse.workflowExecutionInfo.closeEvent = mapHistoryResponse( - closeEventResponse.history - )[0]; - } - } - - ctx.body = describeResponse; - } catch (error) { - if (error.name !== 'NotFoundError') { - throw error; - } - - const archivedHistoryResponse = await ctx.cadence.getHistory(); - const archivedHistoryEvents = mapHistoryResponse( - archivedHistoryResponse.history - ); - - if (!archivedHistoryEvents.length) { - throw error; - } - - const { runId, workflowId } = ctx.params; - - const { - timestamp: startTime, - details: { - taskList, - executionStartToCloseTimeoutSeconds, - taskStartToCloseTimeoutSeconds, - workflowType: type, - }, - } = archivedHistoryEvents[0]; - - ctx.body = { - executionConfiguration: { - taskList, - executionStartToCloseTimeoutSeconds, - taskStartToCloseTimeoutSeconds, - }, - workflowExecutionInfo: { - execution: { - runId, - workflowId, - }, - isArchived: true, - startTime, - type, - }, - pendingActivities: null, - pendingChildren: null, - }; - } -}); - -router.get('/api/domains/:domain/task-lists/:taskList/pollers', async function( - ctx -) { - const descTaskList = async taskListType => - ( - await ctx.cadence.describeTaskList({ - domain: ctx.params.domain, - taskList: { name: ctx.params.taskList }, - taskListType, - }) - ).pollers || []; - - const r = type => (o, poller) => { - const i = o[poller.identity] || {}; - - o[poller.identity] = { - lastAccessTime: - !i.lastAccessTime || i.lastAccessTime < poller.lastAccessTime - ? poller.lastAccessTime - : i.lastAccessTime, - taskListTypes: i.taskListTypes ? i.taskListTypes.concat([type]) : [type], - }; - - return o; - }; - - const activityL = await descTaskList('Activity'), - decisionL = await descTaskList('Decision'); - - ctx.body = activityL.reduce( - r('activity'), - decisionL.reduce(r('decision'), {}) - ); -}); +router.get('/api/domains/:domain/task-lists/:taskList/pollers', tasklistPollerListHandler); router.get( '/api/domains/:domain/task-lists/:taskList/partitions', - async function(ctx) { - const { domain, taskList } = ctx.params; - - ctx.body = await ctx.cadence.listTaskListPartitions({ - domain, - taskList: { name: taskList }, - }); - } + tasklistPartitionListHandler ); -router.get('/api/feature-flags/:key', (ctx, next) => { - const { - params: { key }, - } = ctx; - const featureFlag = featureFlags.find(featureFlag => featureFlag.key === key); - const value = (featureFlag && featureFlag.value) || false; - - ctx.body = { - key, - value, - }; - - next(); -}); - -router.get('/api/domains/:domain/task-lists/:taskListName', async function( - ctx -) { - const { domain, taskListName } = ctx.params; - const descTaskList = async taskListType => - await ctx.cadence.describeTaskList({ - domain, - taskList: { name: taskListName }, - taskListType, - }); - - const activityList = await descTaskList('Activity'); - const decisionList = await descTaskList('Decision'); - const activityPollerList = activityList.pollers || []; - const decisionPollerList = decisionList.pollers || []; - - const taskList = { pollers: [...activityPollerList, ...decisionPollerList] }; +router.get('/api/feature-flags/:key', featureFlagHandler); - ctx.body = taskList; -}); +router.get('/api/domains/:domain/task-lists/:taskListName', tasklistHandler); -router.get('/health', ctx => (ctx.body = 'OK')); +router.get('/health', healthHandler); module.exports = router; diff --git a/server/router/routes/domain-authorization-handler.js b/server/router/routes/domain-authorization-handler.js new file mode 100644 index 000000000..1f66092b8 --- /dev/null +++ b/server/router/routes/domain-authorization-handler.js @@ -0,0 +1,9 @@ +const domainAuthorizationHandler = async (ctx, next) => { + ctx.body = { + authorization: true, + }; + + next(); +}; + +module.exports = domainAuthorizationHandler; diff --git a/server/router/routes/domain-handler.js b/server/router/routes/domain-handler.js new file mode 100644 index 000000000..544487e76 --- /dev/null +++ b/server/router/routes/domain-handler.js @@ -0,0 +1,5 @@ +const domainHandler = async (ctx) => { + ctx.body = await ctx.cadence.describeDomain({ name: ctx.params.domain }); +}; + +module.exports = domainHandler; diff --git a/server/router/routes/domain-list-handler.js b/server/router/routes/domain-list-handler.js index 0ffdd02fc..c8c3e805f 100644 --- a/server/router/routes/domain-list-handler.js +++ b/server/router/routes/domain-list-handler.js @@ -1 +1,10 @@ -// TODO \ No newline at end of file +const domainListHandler = async (ctx) => { + ctx.body = await ctx.cadence.listDomains({ + pageSize: 50, + nextPageToken: ctx.query.nextPageToken + ? Buffer.from(ctx.query.nextPageToken, 'base64') + : undefined, + }); +}; + +module.exports = domainListHandler; diff --git a/server/router/routes/feature-flag-handler.js b/server/router/routes/feature-flag-handler.js new file mode 100644 index 000000000..4b8f95722 --- /dev/null +++ b/server/router/routes/feature-flag-handler.js @@ -0,0 +1,18 @@ +const featureFlags = require('./feature-flags.json'); + +const featureFlagHandler = (ctx, next) => { + const { + params: { key }, + } = ctx; + const featureFlag = featureFlags.find(featureFlag => featureFlag.key === key); + const value = (featureFlag && featureFlag.value) || false; + + ctx.body = { + key, + value, + }; + + next(); +}; + +module.exports = featureFlagHandler; diff --git a/server/router/routes/health-handler.js b/server/router/routes/health-handler.js new file mode 100644 index 000000000..2d3cd2984 --- /dev/null +++ b/server/router/routes/health-handler.js @@ -0,0 +1,3 @@ +const healthHandler = ctx => (ctx.body = 'OK'); + +module.exports = healthHandler; diff --git a/server/router/routes/index.js b/server/router/routes/index.js index e69de29bb..1e5977bea 100644 --- a/server/router/routes/index.js +++ b/server/router/routes/index.js @@ -0,0 +1,37 @@ +const domainAuthorizationHandler = require('./domain-authorization-handler'); +const domainHandler = require('./domain-handler'); +const domainListHandler = require('./domain-list-handler'); +const featureFlagHandler = require('./feature-flag-handler'); +const healthHandler = require('./health-handler'); +const tasklistHandler = require('./tasklist-handler'); +const tasklistPartitionListHandler = require('./tasklist-partition-list-handler'); +const tasklistPollerListHandler = require('./tasklist-poller-list-handler'); +const workflowArchivedListHandler = require('./workflow-archived-list-handler'); +const workflowExportHandler = require('./workflow-export-handler'); +const workflowHandler = require('./workflow-handler'); +const workflowHistoryHandler = require('./workflow-history-handler'); +const workflowListHandler = require('./workflow-list-handler'); +const workflowQueryHandler = require('./workflow-query-handler'); +const workflowQueryTypeHandler = require('./workflow-query-type-handler'); +const workflowSignalHandler = require('./workflow-signal-handler'); +const workflowTerminateHandler = require('./workflow-terminate-handler'); + +module.exports = { + domainAuthorizationHandler, + domainHandler, + domainListHandler, + featureFlagHandler, + healthHandler, + tasklistHandler, + tasklistPartitionListHandler, + tasklistPollerListHandler, + workflowArchivedListHandler, + workflowExportHandler, + workflowHandler, + workflowHistoryHandler, + workflowListHandler, + workflowQueryHandler, + workflowQueryTypeHandler, + workflowSignalHandler, + workflowTerminateHandler, +}; diff --git a/server/router/routes/tasklist-handler.js b/server/router/routes/tasklist-handler.js new file mode 100644 index 000000000..c6a44151b --- /dev/null +++ b/server/router/routes/tasklist-handler.js @@ -0,0 +1,20 @@ +const tasklistHandler = async (ctx) => { + const { domain, taskListName } = ctx.params; + const descTaskList = async taskListType => + await ctx.cadence.describeTaskList({ + domain, + taskList: { name: taskListName }, + taskListType, + }); + + const activityList = await descTaskList('Activity'); + const decisionList = await descTaskList('Decision'); + const activityPollerList = activityList.pollers || []; + const decisionPollerList = decisionList.pollers || []; + + const taskList = { pollers: [...activityPollerList, ...decisionPollerList] }; + + ctx.body = taskList; +}; + +module.exports = tasklistHandler; diff --git a/server/router/routes/tasklist-partition-list-handler.js b/server/router/routes/tasklist-partition-list-handler.js new file mode 100644 index 000000000..5166b8151 --- /dev/null +++ b/server/router/routes/tasklist-partition-list-handler.js @@ -0,0 +1,10 @@ +const tasklistPartitionListHandler = async (ctx) => { + const { domain, taskList } = ctx.params; + + ctx.body = await ctx.cadence.listTaskListPartitions({ + domain, + taskList: { name: taskList }, + }); +}; + +module.exports = tasklistPartitionListHandler; diff --git a/server/router/routes/tasklist-poller-list-handler.js b/server/router/routes/tasklist-poller-list-handler.js new file mode 100644 index 000000000..6c9865a6b --- /dev/null +++ b/server/router/routes/tasklist-poller-list-handler.js @@ -0,0 +1,36 @@ +const tasklistPollerListHandler = async function ( + ctx +) { + const descTaskList = async taskListType => + ( + await ctx.cadence.describeTaskList({ + domain: ctx.params.domain, + taskList: { name: ctx.params.taskList }, + taskListType, + }) + ).pollers || []; + + const r = type => (o, poller) => { + const i = o[poller.identity] || {}; + + o[poller.identity] = { + lastAccessTime: + !i.lastAccessTime || i.lastAccessTime < poller.lastAccessTime + ? poller.lastAccessTime + : i.lastAccessTime, + taskListTypes: i.taskListTypes ? i.taskListTypes.concat([type]) : [type], + }; + + return o; + }; + + const activityL = await descTaskList('Activity'), + decisionL = await descTaskList('Decision'); + + ctx.body = activityL.reduce( + r('activity'), + decisionL.reduce(r('decision'), {}) + ); +}; + +module.exports = tasklistPollerListHandler; diff --git a/server/router/routes/workflow-archived-list-handler.js b/server/router/routes/workflow-archived-list-handler.js new file mode 100644 index 000000000..86bb144fe --- /dev/null +++ b/server/router/routes/workflow-archived-list-handler.js @@ -0,0 +1,26 @@ +const moment = require('moment'); +const { buildQueryString } = require('../helpers'); + +const workflowArchivedListHandler = async (ctx) => { + const { nextPageToken, ...query } = ctx.query || {}; + let queryString; + + if (query.queryString) { + queryString = query.queryString; + } else { + const startTime = moment(query.startTime || NaN); + const endTime = moment(query.endTime || NaN); + + ctx.assert(startTime.isValid() && endTime.isValid(), 400); + queryString = buildQueryString(startTime, endTime, query); + } + + ctx.body = await ctx.cadence.archivedWorkflows({ + query: queryString, + nextPageToken: nextPageToken + ? Buffer.from(nextPageToken, 'base64') + : undefined, + }); +}; + +module.exports = workflowArchivedListHandler; diff --git a/server/router/routes/workflow-export-handler.js b/server/router/routes/workflow-export-handler.js new file mode 100644 index 000000000..d2e76857c --- /dev/null +++ b/server/router/routes/workflow-export-handler.js @@ -0,0 +1,25 @@ +const losslessJSON = require('lossless-json'); + +const workflowExportHandler = async (ctx) => { + let nextPageToken; + + do { + const page = await ctx.cadence.exportHistory({ nextPageToken }); + + if (!nextPageToken) { + ctx.status = 200; + } + + ctx.res.write( + (nextPageToken ? ',' : '[') + + page.history.events.map(losslessJSON.stringify).join(',') + ); + nextPageToken = + page.nextPageToken && Buffer.from(page.nextPageToken, 'base64'); + } while (nextPageToken); + + ctx.res.write(']'); + ctx.body = ''; +}; + +module.exports = workflowExportHandler; diff --git a/server/router/routes/workflow-handler.js b/server/router/routes/workflow-handler.js new file mode 100644 index 000000000..e5c782d71 --- /dev/null +++ b/server/router/routes/workflow-handler.js @@ -0,0 +1,69 @@ +const { mapHistoryResponse } = require('../helpers'); + +const workflowHandler = async (ctx) => { + try { + const describeResponse = await ctx.cadence.describeWorkflow(); + + if (describeResponse.workflowExecutionInfo) { + describeResponse.workflowExecutionInfo.closeEvent = null; + + if (describeResponse.workflowExecutionInfo.closeStatus) { + const closeEventResponse = await ctx.cadence.getHistory({ + HistoryEventFilterType: 'CLOSE_EVENT', + }); + + describeResponse.workflowExecutionInfo.closeEvent = mapHistoryResponse( + closeEventResponse.history + )[0]; + } + } + + ctx.body = describeResponse; + } catch (error) { + if (error.name !== 'NotFoundError') { + throw error; + } + + const archivedHistoryResponse = await ctx.cadence.getHistory(); + const archivedHistoryEvents = mapHistoryResponse( + archivedHistoryResponse.history + ); + + if (!archivedHistoryEvents.length) { + throw error; + } + + const { runId, workflowId } = ctx.params; + + const { + timestamp: startTime, + details: { + taskList, + executionStartToCloseTimeoutSeconds, + taskStartToCloseTimeoutSeconds, + workflowType: type, + }, + } = archivedHistoryEvents[0]; + + ctx.body = { + executionConfiguration: { + taskList, + executionStartToCloseTimeoutSeconds, + taskStartToCloseTimeoutSeconds, + }, + workflowExecutionInfo: { + execution: { + runId, + workflowId, + }, + isArchived: true, + startTime, + type, + }, + pendingActivities: null, + pendingChildren: null, + }; + } +}; + +module.exports = workflowHandler; diff --git a/server/router/routes/workflow-history-handler.js b/server/router/routes/workflow-history-handler.js new file mode 100644 index 000000000..4afc550ee --- /dev/null +++ b/server/router/routes/workflow-history-handler.js @@ -0,0 +1,16 @@ +const { mapHistoryResponse } = require('../helpers'); + +const workflowHistoryHandler = async (ctx) => { + const q = ctx.query || {}; + + ctx.body = await ctx.cadence.getHistory({ + nextPageToken: q.nextPageToken + ? Buffer.from(q.nextPageToken, 'base64') + : undefined, + waitForNewEvent: 'waitForNewEvent' in q ? true : undefined, + }); + + ctx.body.history.events = mapHistoryResponse(ctx.body.history); +}; + +module.exports = workflowHistoryHandler; diff --git a/server/router/routes/workflow-list-handler.js b/server/router/routes/workflow-list-handler.js new file mode 100644 index 000000000..2ef7485ba --- /dev/null +++ b/server/router/routes/workflow-list-handler.js @@ -0,0 +1,12 @@ +const workflowListHandler = async (ctx) => { + const q = ctx.query || {}; + + ctx.body = await ctx.cadence.listWorkflows({ + query: q.queryString || undefined, + nextPageToken: q.nextPageToken + ? Buffer.from(q.nextPageToken, 'base64') + : undefined, + }); +}; + +module.exports = workflowListHandler; diff --git a/server/router/routes/workflow-query-handler.js b/server/router/routes/workflow-query-handler.js new file mode 100644 index 000000000..ac6ee9719 --- /dev/null +++ b/server/router/routes/workflow-query-handler.js @@ -0,0 +1,20 @@ +const workflowQueryHandler = async (ctx) => { + // workaround implementation until https://github.com/uber/cadence/issues/382 is resolved + try { + await ctx.cadence.queryWorkflow({ + query: { + queryType: '__cadence_web_list', + }, + }); + + ctx.throw(500); + } catch (e) { + ctx.body = ((e.message || '').match( + /(KnownQueryTypes|knownTypes)=\[(.*)\]/ + ) || [null, null, ''])[2] + .split(/, | /) + .filter(q => q); + } +}; + +module.exports = workflowQueryHandler; diff --git a/server/router/routes/workflow-query-type-handler.js b/server/router/routes/workflow-query-type-handler.js new file mode 100644 index 000000000..c018f9626 --- /dev/null +++ b/server/router/routes/workflow-query-type-handler.js @@ -0,0 +1,9 @@ +const workflowQueryTypeHandler = async (ctx) => { + ctx.body = await ctx.cadence.queryWorkflow({ + query: { + queryType: ctx.params.queryType, + }, + }); +}; + +module.exports = workflowQueryTypeHandler; diff --git a/server/router/routes/workflow-signal-handler.js b/server/router/routes/workflow-signal-handler.js new file mode 100644 index 000000000..925c20e5e --- /dev/null +++ b/server/router/routes/workflow-signal-handler.js @@ -0,0 +1,7 @@ +const workflowSignalHandler = async (ctx) => { + ctx.body = await ctx.cadence.signalWorkflow({ + signalName: ctx.params.signal, + }); +}; + +module.exports = workflowSignalHandler; diff --git a/server/router/routes/workflow-terminate-handler.js b/server/router/routes/workflow-terminate-handler.js new file mode 100644 index 000000000..dcc680432 --- /dev/null +++ b/server/router/routes/workflow-terminate-handler.js @@ -0,0 +1,7 @@ +const workflowTerminateHandler = async (ctx) => { + ctx.body = await ctx.cadence.terminateWorkflow({ + reason: ctx.request.body && ctx.request.body.reason, + }); +}; + +module.exports = workflowTerminateHandler; From 366f3a595c14062a0218d02b4d193858f9835c9d Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Fri, 23 Apr 2021 13:10:51 -0700 Subject: [PATCH 07/30] fix lint --- server/router/helpers/build-query-string.js | 21 ++++++++++++++++ server/router/helpers/list-workflows.js | 21 ++++++++++++++++ server/router/helpers/map-history-response.js | 21 ++++++++++++++++ server/router/helpers/replacer.js | 21 ++++++++++++++++ server/router/index.js | 19 +++++++++----- .../routes/domain-authorization-handler.js | 21 ++++++++++++++++ server/router/routes/domain-handler.js | 23 ++++++++++++++++- server/router/routes/domain-list-handler.js | 23 ++++++++++++++++- server/router/routes/feature-flag-handler.js | 23 ++++++++++++++++- server/router/routes/health-handler.js | 21 ++++++++++++++++ server/router/routes/index.js | 21 ++++++++++++++++ server/router/routes/tasklist-handler.js | 23 ++++++++++++++++- .../routes/tasklist-partition-list-handler.js | 23 ++++++++++++++++- .../routes/tasklist-poller-list-handler.js | 25 ++++++++++++++++--- .../routes/workflow-archived-list-handler.js | 23 ++++++++++++++++- .../router/routes/workflow-export-handler.js | 25 +++++++++++++++++-- server/router/routes/workflow-handler.js | 23 ++++++++++++++++- .../router/routes/workflow-history-handler.js | 23 ++++++++++++++++- server/router/routes/workflow-list-handler.js | 23 ++++++++++++++++- .../router/routes/workflow-query-handler.js | 23 ++++++++++++++++- .../routes/workflow-query-type-handler.js | 23 ++++++++++++++++- .../router/routes/workflow-signal-handler.js | 23 ++++++++++++++++- .../routes/workflow-terminate-handler.js | 23 ++++++++++++++++- 23 files changed, 491 insertions(+), 24 deletions(-) diff --git a/server/router/helpers/build-query-string.js b/server/router/helpers/build-query-string.js index 2f80d1cc9..d115992ee 100644 --- a/server/router/helpers/build-query-string.js +++ b/server/router/helpers/build-query-string.js @@ -1,3 +1,24 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const buildQueryString = ( startTime, endTime, diff --git a/server/router/helpers/list-workflows.js b/server/router/helpers/list-workflows.js index a4b9c0544..c411b4986 100644 --- a/server/router/helpers/list-workflows.js +++ b/server/router/helpers/list-workflows.js @@ -1,3 +1,24 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const moment = require('moment'); const momentToLong = require('./moment-to-long'); diff --git a/server/router/helpers/map-history-response.js b/server/router/helpers/map-history-response.js index 1d34d7630..7894b3f44 100644 --- a/server/router/helpers/map-history-response.js +++ b/server/router/helpers/map-history-response.js @@ -1,3 +1,24 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const replacer = require('./replacer'); const mapHistoryResponse = history => { diff --git a/server/router/helpers/replacer.js b/server/router/helpers/replacer.js index 40bc41d94..d53228e98 100644 --- a/server/router/helpers/replacer.js +++ b/server/router/helpers/replacer.js @@ -1,3 +1,24 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const replacer = (key, value) => { if (value && value.type && value.type === 'Buffer') { return Buffer.from(value) diff --git a/server/router/index.js b/server/router/index.js index d537b988c..220472bac 100644 --- a/server/router/index.js +++ b/server/router/index.js @@ -41,9 +41,7 @@ const { workflowTerminateHandler, } = require('./routes'); -const { - listWorkflows, -} = require('./helpers'); +const { listWorkflows } = require('./helpers'); const router = new Router(); @@ -77,7 +75,10 @@ router.get( listWorkflows.bind(null, 'closed') ); -router.get('/api/domains/:domain/workflows/archived', workflowArchivedListHandler); +router.get( + '/api/domains/:domain/workflows/archived', + workflowArchivedListHandler +); router.get('/api/domains/:domain/workflows/list', workflowListHandler); @@ -111,9 +112,15 @@ router.post( workflowSignalHandler ); -router.get('/api/domains/:domain/workflows/:workflowId/:runId', workflowHandler); +router.get( + '/api/domains/:domain/workflows/:workflowId/:runId', + workflowHandler +); -router.get('/api/domains/:domain/task-lists/:taskList/pollers', tasklistPollerListHandler); +router.get( + '/api/domains/:domain/task-lists/:taskList/pollers', + tasklistPollerListHandler +); router.get( '/api/domains/:domain/task-lists/:taskList/partitions', diff --git a/server/router/routes/domain-authorization-handler.js b/server/router/routes/domain-authorization-handler.js index 1f66092b8..f1b4ae6b5 100644 --- a/server/router/routes/domain-authorization-handler.js +++ b/server/router/routes/domain-authorization-handler.js @@ -1,3 +1,24 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const domainAuthorizationHandler = async (ctx, next) => { ctx.body = { authorization: true, diff --git a/server/router/routes/domain-handler.js b/server/router/routes/domain-handler.js index 544487e76..b4733ae15 100644 --- a/server/router/routes/domain-handler.js +++ b/server/router/routes/domain-handler.js @@ -1,4 +1,25 @@ -const domainHandler = async (ctx) => { +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +const domainHandler = async ctx => { ctx.body = await ctx.cadence.describeDomain({ name: ctx.params.domain }); }; diff --git a/server/router/routes/domain-list-handler.js b/server/router/routes/domain-list-handler.js index c8c3e805f..cef4bbefa 100644 --- a/server/router/routes/domain-list-handler.js +++ b/server/router/routes/domain-list-handler.js @@ -1,4 +1,25 @@ -const domainListHandler = async (ctx) => { +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +const domainListHandler = async ctx => { ctx.body = await ctx.cadence.listDomains({ pageSize: 50, nextPageToken: ctx.query.nextPageToken diff --git a/server/router/routes/feature-flag-handler.js b/server/router/routes/feature-flag-handler.js index 4b8f95722..51e4f2d2a 100644 --- a/server/router/routes/feature-flag-handler.js +++ b/server/router/routes/feature-flag-handler.js @@ -1,4 +1,25 @@ -const featureFlags = require('./feature-flags.json'); +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +const featureFlags = require('../../feature-flags.json'); const featureFlagHandler = (ctx, next) => { const { diff --git a/server/router/routes/health-handler.js b/server/router/routes/health-handler.js index 2d3cd2984..d6b07ba83 100644 --- a/server/router/routes/health-handler.js +++ b/server/router/routes/health-handler.js @@ -1,3 +1,24 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const healthHandler = ctx => (ctx.body = 'OK'); module.exports = healthHandler; diff --git a/server/router/routes/index.js b/server/router/routes/index.js index 1e5977bea..04c5b1fec 100644 --- a/server/router/routes/index.js +++ b/server/router/routes/index.js @@ -1,3 +1,24 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const domainAuthorizationHandler = require('./domain-authorization-handler'); const domainHandler = require('./domain-handler'); const domainListHandler = require('./domain-list-handler'); diff --git a/server/router/routes/tasklist-handler.js b/server/router/routes/tasklist-handler.js index c6a44151b..20c9958cd 100644 --- a/server/router/routes/tasklist-handler.js +++ b/server/router/routes/tasklist-handler.js @@ -1,4 +1,25 @@ -const tasklistHandler = async (ctx) => { +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +const tasklistHandler = async ctx => { const { domain, taskListName } = ctx.params; const descTaskList = async taskListType => await ctx.cadence.describeTaskList({ diff --git a/server/router/routes/tasklist-partition-list-handler.js b/server/router/routes/tasklist-partition-list-handler.js index 5166b8151..b45b1a66e 100644 --- a/server/router/routes/tasklist-partition-list-handler.js +++ b/server/router/routes/tasklist-partition-list-handler.js @@ -1,4 +1,25 @@ -const tasklistPartitionListHandler = async (ctx) => { +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +const tasklistPartitionListHandler = async ctx => { const { domain, taskList } = ctx.params; ctx.body = await ctx.cadence.listTaskListPartitions({ diff --git a/server/router/routes/tasklist-poller-list-handler.js b/server/router/routes/tasklist-poller-list-handler.js index 6c9865a6b..4a37a093a 100644 --- a/server/router/routes/tasklist-poller-list-handler.js +++ b/server/router/routes/tasklist-poller-list-handler.js @@ -1,6 +1,25 @@ -const tasklistPollerListHandler = async function ( - ctx -) { +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +const tasklistPollerListHandler = async function(ctx) { const descTaskList = async taskListType => ( await ctx.cadence.describeTaskList({ diff --git a/server/router/routes/workflow-archived-list-handler.js b/server/router/routes/workflow-archived-list-handler.js index 86bb144fe..301d71af6 100644 --- a/server/router/routes/workflow-archived-list-handler.js +++ b/server/router/routes/workflow-archived-list-handler.js @@ -1,7 +1,28 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const moment = require('moment'); const { buildQueryString } = require('../helpers'); -const workflowArchivedListHandler = async (ctx) => { +const workflowArchivedListHandler = async ctx => { const { nextPageToken, ...query } = ctx.query || {}; let queryString; diff --git a/server/router/routes/workflow-export-handler.js b/server/router/routes/workflow-export-handler.js index d2e76857c..d755198ec 100644 --- a/server/router/routes/workflow-export-handler.js +++ b/server/router/routes/workflow-export-handler.js @@ -1,6 +1,27 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const losslessJSON = require('lossless-json'); -const workflowExportHandler = async (ctx) => { +const workflowExportHandler = async ctx => { let nextPageToken; do { @@ -12,7 +33,7 @@ const workflowExportHandler = async (ctx) => { ctx.res.write( (nextPageToken ? ',' : '[') + - page.history.events.map(losslessJSON.stringify).join(',') + page.history.events.map(losslessJSON.stringify).join(',') ); nextPageToken = page.nextPageToken && Buffer.from(page.nextPageToken, 'base64'); diff --git a/server/router/routes/workflow-handler.js b/server/router/routes/workflow-handler.js index e5c782d71..9139c3d8a 100644 --- a/server/router/routes/workflow-handler.js +++ b/server/router/routes/workflow-handler.js @@ -1,6 +1,27 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const { mapHistoryResponse } = require('../helpers'); -const workflowHandler = async (ctx) => { +const workflowHandler = async ctx => { try { const describeResponse = await ctx.cadence.describeWorkflow(); diff --git a/server/router/routes/workflow-history-handler.js b/server/router/routes/workflow-history-handler.js index 4afc550ee..d84b83d95 100644 --- a/server/router/routes/workflow-history-handler.js +++ b/server/router/routes/workflow-history-handler.js @@ -1,6 +1,27 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const { mapHistoryResponse } = require('../helpers'); -const workflowHistoryHandler = async (ctx) => { +const workflowHistoryHandler = async ctx => { const q = ctx.query || {}; ctx.body = await ctx.cadence.getHistory({ diff --git a/server/router/routes/workflow-list-handler.js b/server/router/routes/workflow-list-handler.js index 2ef7485ba..6b50389f0 100644 --- a/server/router/routes/workflow-list-handler.js +++ b/server/router/routes/workflow-list-handler.js @@ -1,4 +1,25 @@ -const workflowListHandler = async (ctx) => { +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +const workflowListHandler = async ctx => { const q = ctx.query || {}; ctx.body = await ctx.cadence.listWorkflows({ diff --git a/server/router/routes/workflow-query-handler.js b/server/router/routes/workflow-query-handler.js index ac6ee9719..9732e9217 100644 --- a/server/router/routes/workflow-query-handler.js +++ b/server/router/routes/workflow-query-handler.js @@ -1,4 +1,25 @@ -const workflowQueryHandler = async (ctx) => { +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +const workflowQueryHandler = async ctx => { // workaround implementation until https://github.com/uber/cadence/issues/382 is resolved try { await ctx.cadence.queryWorkflow({ diff --git a/server/router/routes/workflow-query-type-handler.js b/server/router/routes/workflow-query-type-handler.js index c018f9626..d7abdca23 100644 --- a/server/router/routes/workflow-query-type-handler.js +++ b/server/router/routes/workflow-query-type-handler.js @@ -1,4 +1,25 @@ -const workflowQueryTypeHandler = async (ctx) => { +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +const workflowQueryTypeHandler = async ctx => { ctx.body = await ctx.cadence.queryWorkflow({ query: { queryType: ctx.params.queryType, diff --git a/server/router/routes/workflow-signal-handler.js b/server/router/routes/workflow-signal-handler.js index 925c20e5e..af8fd6bcd 100644 --- a/server/router/routes/workflow-signal-handler.js +++ b/server/router/routes/workflow-signal-handler.js @@ -1,4 +1,25 @@ -const workflowSignalHandler = async (ctx) => { +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +const workflowSignalHandler = async ctx => { ctx.body = await ctx.cadence.signalWorkflow({ signalName: ctx.params.signal, }); diff --git a/server/router/routes/workflow-terminate-handler.js b/server/router/routes/workflow-terminate-handler.js index dcc680432..9f74ced44 100644 --- a/server/router/routes/workflow-terminate-handler.js +++ b/server/router/routes/workflow-terminate-handler.js @@ -1,4 +1,25 @@ -const workflowTerminateHandler = async (ctx) => { +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +const workflowTerminateHandler = async ctx => { ctx.body = await ctx.cadence.terminateWorkflow({ reason: ctx.request.body && ctx.request.body.reason, }); From dff085637ca0b20ac6016f83fb36f3a468a6ce58 Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Fri, 23 Apr 2021 15:01:44 -0700 Subject: [PATCH 08/30] adding cluster handler --- server/middleware/tchannel-client/index.js | 4 ++++ server/router/index.js | 4 ++++ server/router/routes/cluster-handler.js | 11 +++++++++++ server/router/routes/index.js | 2 ++ 4 files changed, 21 insertions(+) create mode 100644 server/router/routes/cluster-handler.js diff --git a/server/middleware/tchannel-client/index.js b/server/middleware/tchannel-client/index.js index f6b253d13..98ba712eb 100644 --- a/server/middleware/tchannel-client/index.js +++ b/server/middleware/tchannel-client/index.js @@ -55,6 +55,10 @@ const tchannelClient = async function(ctx, next) { requestName: 'list', bodyTransform: withDomainPaging(ctx), }), + describeCluster: request({ + method: 'DescribeCluster', + requestName: 'describe', + }), describeDomain: request({ method: 'DescribeDomain', requestName: 'describe', diff --git a/server/router/index.js b/server/router/index.js index 220472bac..73520e23d 100644 --- a/server/router/index.js +++ b/server/router/index.js @@ -22,6 +22,7 @@ const Router = require('koa-router'); const { + clusterHandler, domainAuthorizationHandler, domainHandler, domainListHandler, @@ -45,7 +46,10 @@ const { listWorkflows } = require('./helpers'); const router = new Router(); +router.get('/api/cluster', clusterHandler); + router.get('/api/domains', domainListHandler); + router.get('/api/domains/:domain', domainHandler); /** diff --git a/server/router/routes/cluster-handler.js b/server/router/routes/cluster-handler.js new file mode 100644 index 000000000..0ec8dbb28 --- /dev/null +++ b/server/router/routes/cluster-handler.js @@ -0,0 +1,11 @@ + + +const clusterHandler = async (ctx) => { + // TODO - Check cached response before calling API + // if cached, returned cache + // if not request and then save to cache. + + ctx.body = await ctx.cadence.describeCluster(); +}; + +module.exports = clusterHandler; diff --git a/server/router/routes/index.js b/server/router/routes/index.js index 04c5b1fec..525fcbc4a 100644 --- a/server/router/routes/index.js +++ b/server/router/routes/index.js @@ -19,6 +19,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +const clusterHandler = require('./cluster-handler'); const domainAuthorizationHandler = require('./domain-authorization-handler'); const domainHandler = require('./domain-handler'); const domainListHandler = require('./domain-list-handler'); @@ -38,6 +39,7 @@ const workflowSignalHandler = require('./workflow-signal-handler'); const workflowTerminateHandler = require('./workflow-terminate-handler'); module.exports = { + clusterHandler, domainAuthorizationHandler, domainHandler, domainListHandler, From 59dd93268f6a3c063fae323a78d4df8cbf956ed0 Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Fri, 23 Apr 2021 15:08:08 -0700 Subject: [PATCH 09/30] fix lint --- server/router/routes/cluster-handler.js | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/server/router/routes/cluster-handler.js b/server/router/routes/cluster-handler.js index 0ec8dbb28..160f60e12 100644 --- a/server/router/routes/cluster-handler.js +++ b/server/router/routes/cluster-handler.js @@ -1,6 +1,25 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. - -const clusterHandler = async (ctx) => { +const clusterHandler = async ctx => { // TODO - Check cached response before calling API // if cached, returned cache // if not request and then save to cache. From 5117b29da0779563a458731a7778fe39eb0338a0 Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Fri, 23 Apr 2021 15:56:15 -0700 Subject: [PATCH 10/30] piped through tchannel changes to support admin service requests. complete response now available from UI. need to cache response on server side and trim what is stored. --- client/routes/domain/workflow-list.vue | 7 +++++++ .../tchannel-client/helpers/format-method.js | 2 +- .../middleware/tchannel-client/helpers/index.js | 4 ++-- .../{make-channel.js => make-channels.js} | 16 ++++++++++++---- .../tchannel-client/helpers/make-request.js | 10 ++++++---- server/middleware/tchannel-client/index.js | 8 +++++--- 6 files changed, 33 insertions(+), 14 deletions(-) rename server/middleware/tchannel-client/helpers/{make-channel.js => make-channels.js} (84%) diff --git a/client/routes/domain/workflow-list.vue b/client/routes/domain/workflow-list.vue index f97910e7d..d54d77f9b 100644 --- a/client/routes/domain/workflow-list.vue +++ b/client/routes/domain/workflow-list.vue @@ -53,6 +53,7 @@ export default { }; }, async created() { + this.fetchCluster(); await this.fetchDomain(); this.fetchWorkflows(); }, @@ -255,6 +256,12 @@ export default { return { workflows, nextPageToken }; }, + async fetchCluster() { + const cluster = this.$http(`/api/cluster`); + + // TODO - hook up advanced button show/hide based on results returned. + // Should hide by default until response is returned. + }, fetchDomain() { const { domain } = this; diff --git a/server/middleware/tchannel-client/helpers/format-method.js b/server/middleware/tchannel-client/helpers/format-method.js index dd6dd08a5..cf72b044c 100644 --- a/server/middleware/tchannel-client/helpers/format-method.js +++ b/server/middleware/tchannel-client/helpers/format-method.js @@ -19,6 +19,6 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -const formatMethod = method => `WorkflowService::${method}`; +const formatMethod = ({ method, serviceName }) => `${serviceName}::${method}`; module.exports = formatMethod; diff --git a/server/middleware/tchannel-client/helpers/index.js b/server/middleware/tchannel-client/helpers/index.js index aff040afa..e77960706 100644 --- a/server/middleware/tchannel-client/helpers/index.js +++ b/server/middleware/tchannel-client/helpers/index.js @@ -24,7 +24,7 @@ const formatBody = require('./format-body'); const formatMethod = require('./format-method'); const formatRequestName = require('./format-request-name'); const lookupAsync = require('./lookup-async'); -const makeChannel = require('./make-channel'); +const makeChannels = require('./make-channels'); const makeRequest = require('./make-request'); const uiTransform = require('./ui-transform'); const withDomainPagingAndWorkflowExecution = require('./with-domain-paging-and-workflow-execution'); @@ -38,7 +38,7 @@ module.exports = { formatMethod, formatRequestName, lookupAsync, - makeChannel, + makeChannels, makeRequest, uiTransform, withDomainPagingAndWorkflowExecution, diff --git a/server/middleware/tchannel-client/helpers/make-channel.js b/server/middleware/tchannel-client/helpers/make-channels.js similarity index 84% rename from server/middleware/tchannel-client/helpers/make-channel.js rename to server/middleware/tchannel-client/helpers/make-channels.js index 6fb31827e..cab17d3c8 100644 --- a/server/middleware/tchannel-client/helpers/make-channel.js +++ b/server/middleware/tchannel-client/helpers/make-channels.js @@ -25,7 +25,7 @@ const TChannelAsThrift = require('tchannel/as/thrift'); const { PEERS } = require('../constants'); const lookupAsync = require('./lookup-async'); -const makeChannel = async client => { +const makeChannels = async client => { const ipPeers = await Promise.all( PEERS.map(peer => { const [host, port] = peer.split(':'); @@ -47,12 +47,20 @@ const makeChannel = async client => { }, }); - const tchannelAsThrift = TChannelAsThrift({ + const adminTChannelAsThrift = TChannelAsThrift({ + channel: cadenceChannel, + entryPoint: path.join(__dirname, '../../../idl/admin.thrift'), + }); + + const cadenceTChannelAsThrift = TChannelAsThrift({ channel: cadenceChannel, entryPoint: path.join(__dirname, '../../../idl/cadence.thrift'), }); - return tchannelAsThrift; + return { + admin: adminTChannelAsThrift, + cadence: cadenceTChannelAsThrift, + }; }; -module.exports = makeChannel; +module.exports = makeChannels; diff --git a/server/middleware/tchannel-client/helpers/make-request.js b/server/middleware/tchannel-client/helpers/make-request.js index 5d464d271..624b7601e 100644 --- a/server/middleware/tchannel-client/helpers/make-request.js +++ b/server/middleware/tchannel-client/helpers/make-request.js @@ -25,16 +25,18 @@ const formatMethod = require('./format-method'); const formatRequestName = require('./format-request-name'); const uiTransform = require('./ui-transform'); -const makeRequest = ({ authTokenHeaders, channel, ctx }) => ({ +const makeRequest = ({ authTokenHeaders, channels, ctx }) => ({ + bodyTransform, + channelName = 'cadence', method, requestName, - bodyTransform, responseTransform, + serviceName = 'WorkflowService', }) => body => new Promise((resolve, reject) => { try { - channel.request(REQUEST_CONFIG).send( - formatMethod(method), + channels[channelName].request(REQUEST_CONFIG).send( + formatMethod({ method, serviceName }), { ...authTokenHeaders, }, diff --git a/server/middleware/tchannel-client/index.js b/server/middleware/tchannel-client/index.js index 98ba712eb..0e34981a8 100644 --- a/server/middleware/tchannel-client/index.js +++ b/server/middleware/tchannel-client/index.js @@ -25,7 +25,7 @@ const TChannel = require('tchannel'); const { cliTransform, - makeChannel, + makeChannels, makeRequest, withDomainPaging, withWorkflowExecution, @@ -37,10 +37,10 @@ const tchannelClient = async function(ctx, next) { const { authTokenHeaders = {} } = ctx; const client = TChannel(); - const channel = await makeChannel(client); + const channels = await makeChannels(client); const request = makeRequest({ authTokenHeaders, - channel, + channels, ctx, }); @@ -56,8 +56,10 @@ const tchannelClient = async function(ctx, next) { bodyTransform: withDomainPaging(ctx), }), describeCluster: request({ + channelName: 'admin', method: 'DescribeCluster', requestName: 'describe', + serviceName: 'AdminService', }), describeDomain: request({ method: 'DescribeDomain', From 9a80a84a19062b61b338370066ba588504fc1f61 Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Fri, 23 Apr 2021 16:12:36 -0700 Subject: [PATCH 11/30] adding caching to cluster handler --- server/router/routes/cluster-handler.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/server/router/routes/cluster-handler.js b/server/router/routes/cluster-handler.js index 160f60e12..404870146 100644 --- a/server/router/routes/cluster-handler.js +++ b/server/router/routes/cluster-handler.js @@ -19,12 +19,21 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. +const ONE_HOUR_IN_MILLISECONDS = 60 * 60 * 1000; + +let cache = null; + const clusterHandler = async ctx => { - // TODO - Check cached response before calling API - // if cached, returned cache - // if not request and then save to cache. + if (cache) { + return (ctx.body = cache); + } + + const cluster = await ctx.cadence.describeCluster(); + cache = { ...cluster, membershipInfo: null }; + ctx.body = cache; - ctx.body = await ctx.cadence.describeCluster(); + // clear cache after 1 hour. It will fetch new value on next request to clusterHandler. + setTimeout(() => cache = null, ONE_HOUR_IN_MILLISECONDS); }; module.exports = clusterHandler; From 5447c1b3fc67af7dc1e81343216d0687cd2a22cf Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Fri, 23 Apr 2021 16:17:52 -0700 Subject: [PATCH 12/30] adding cluster cache ttl constant --- server/router/constants.js | 6 ++++++ server/router/routes/cluster-handler.js | 7 ++++--- 2 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 server/router/constants.js diff --git a/server/router/constants.js b/server/router/constants.js new file mode 100644 index 000000000..77ee0908d --- /dev/null +++ b/server/router/constants.js @@ -0,0 +1,6 @@ +const ONE_HOUR_IN_MILLISECONDS = 60 * 60 * 1000; +const CLUSTER_CACHE_TTL = ONE_HOUR_IN_MILLISECONDS; + +module.exports = { + CLUSTER_CACHE_TTL, +}; diff --git a/server/router/routes/cluster-handler.js b/server/router/routes/cluster-handler.js index 404870146..c48bcc071 100644 --- a/server/router/routes/cluster-handler.js +++ b/server/router/routes/cluster-handler.js @@ -19,7 +19,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -const ONE_HOUR_IN_MILLISECONDS = 60 * 60 * 1000; +const { CLUSTER_CACHE_TTL } = require('../constants'); let cache = null; @@ -32,8 +32,9 @@ const clusterHandler = async ctx => { cache = { ...cluster, membershipInfo: null }; ctx.body = cache; - // clear cache after 1 hour. It will fetch new value on next request to clusterHandler. - setTimeout(() => cache = null, ONE_HOUR_IN_MILLISECONDS); + // This timeout will clear cache after TTL period. + // It will fetch a new value on the next request to clusterHandler. + setTimeout(() => cache = null, CLUSTER_CACHE_TTL); }; module.exports = clusterHandler; From ccd8f49c01be102c5e2faa2977eb4b3cb3d97a30 Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Fri, 23 Apr 2021 16:19:47 -0700 Subject: [PATCH 13/30] revert frontend changes --- client/routes/domain/workflow-list.vue | 7 ------- 1 file changed, 7 deletions(-) diff --git a/client/routes/domain/workflow-list.vue b/client/routes/domain/workflow-list.vue index d54d77f9b..f97910e7d 100644 --- a/client/routes/domain/workflow-list.vue +++ b/client/routes/domain/workflow-list.vue @@ -53,7 +53,6 @@ export default { }; }, async created() { - this.fetchCluster(); await this.fetchDomain(); this.fetchWorkflows(); }, @@ -256,12 +255,6 @@ export default { return { workflows, nextPageToken }; }, - async fetchCluster() { - const cluster = this.$http(`/api/cluster`); - - // TODO - hook up advanced button show/hide based on results returned. - // Should hide by default until response is returned. - }, fetchDomain() { const { domain } = this; From 21eeb7e5be7e69e982805173ede3c9c890436c4a Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Fri, 23 Apr 2021 16:27:07 -0700 Subject: [PATCH 14/30] fix lint --- server/router/constants.js | 21 +++++++++++++++++++++ server/router/routes/cluster-handler.js | 3 ++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/server/router/constants.js b/server/router/constants.js index 77ee0908d..060b244da 100644 --- a/server/router/constants.js +++ b/server/router/constants.js @@ -1,3 +1,24 @@ +// Copyright (c) 2021 Uber Technologies Inc. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + const ONE_HOUR_IN_MILLISECONDS = 60 * 60 * 1000; const CLUSTER_CACHE_TTL = ONE_HOUR_IN_MILLISECONDS; diff --git a/server/router/routes/cluster-handler.js b/server/router/routes/cluster-handler.js index c48bcc071..e63f4c07c 100644 --- a/server/router/routes/cluster-handler.js +++ b/server/router/routes/cluster-handler.js @@ -29,12 +29,13 @@ const clusterHandler = async ctx => { } const cluster = await ctx.cadence.describeCluster(); + cache = { ...cluster, membershipInfo: null }; ctx.body = cache; // This timeout will clear cache after TTL period. // It will fetch a new value on the next request to clusterHandler. - setTimeout(() => cache = null, CLUSTER_CACHE_TTL); + setTimeout(() => (cache = null), CLUSTER_CACHE_TTL); }; module.exports = clusterHandler; From 1412c2f8ebbc0cd46dce0b467bc72549ca7823be Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Mon, 26 Apr 2021 11:46:18 -0700 Subject: [PATCH 15/30] artificial change to test integration tests. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index dd4df335e..3d6cefe31 100644 --- a/README.md +++ b/README.md @@ -71,3 +71,4 @@ The [webpack](https://webpack.js.org/) configuration is also exported as `webpac MIT License, please see [LICENSE](https://github.com/uber/cadence-web/blob/master/LICENSE) for details. [cadence]: https://github.com/uber/cadence + From 6536ad7c1286b935788eed8e638a80c23268e854 Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Tue, 27 Apr 2021 09:47:00 -0700 Subject: [PATCH 16/30] revert readme --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 3d6cefe31..dd4df335e 100644 --- a/README.md +++ b/README.md @@ -71,4 +71,3 @@ The [webpack](https://webpack.js.org/) configuration is also exported as `webpac MIT License, please see [LICENSE](https://github.com/uber/cadence-web/blob/master/LICENSE) for details. [cadence]: https://github.com/uber/cadence - From a7f0b27285430ca53a4c761dd2c933951f4c1e2c Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Tue, 27 Apr 2021 09:59:48 -0700 Subject: [PATCH 17/30] adding timeout --- client/test/workflow.test.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/client/test/workflow.test.js b/client/test/workflow.test.js index 95ea1bcdc..343e53cd4 100644 --- a/client/test/workflow.test.js +++ b/client/test/workflow.test.js @@ -343,6 +343,9 @@ describe('Workflow', () => { ); terminateEl.trigger('click'); + + this.timeout(1000); + const confirmTerminateEl = await summaryEl.waitUntilExists( '[data-modal="confirm-termination"]' ); From d2587f031a94a3171194f9defb4faf0ca3ab08fb Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Tue, 27 Apr 2021 10:06:09 -0700 Subject: [PATCH 18/30] add done for async test --- client/test/workflow.test.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/test/workflow.test.js b/client/test/workflow.test.js index 343e53cd4..105bf5cce 100644 --- a/client/test/workflow.test.js +++ b/client/test/workflow.test.js @@ -336,7 +336,7 @@ describe('Workflow', () => { }); describe('Actions', () => { - it('should offer the user to terminate a running workflow, prompting the user for a termination reason', async function test() { + it('should offer the user to terminate a running workflow, prompting the user for a termination reason', async function test(done) { const [summaryEl] = await summaryTest(this.test); const terminateEl = await summaryEl.waitUntilExists( 'aside.actions button' @@ -357,6 +357,8 @@ describe('Workflow', () => { .contain('button[name="button-terminate"]') .and.contain('button[name="button-cancel"]') .and.contain('input[placeholder="Reason"]'); + + done(); }); it('should terminate the workflow with the provided reason', async function test() { From 042ce1109ccf6e729461e327d8b9493f91eeaf2e Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Tue, 27 Apr 2021 10:11:56 -0700 Subject: [PATCH 19/30] reducing timeout to 500ms --- client/test/workflow.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/test/workflow.test.js b/client/test/workflow.test.js index 105bf5cce..cdb04a21e 100644 --- a/client/test/workflow.test.js +++ b/client/test/workflow.test.js @@ -344,7 +344,7 @@ describe('Workflow', () => { terminateEl.trigger('click'); - this.timeout(1000); + this.timeout(500); const confirmTerminateEl = await summaryEl.waitUntilExists( '[data-modal="confirm-termination"]' From c57c35e3393288ff52bfb2337698e6018a169465 Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Tue, 27 Apr 2021 10:14:33 -0700 Subject: [PATCH 20/30] fixed timeout as this is the timeout for the test before failing --- client/test/workflow.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/test/workflow.test.js b/client/test/workflow.test.js index cdb04a21e..23a12eba4 100644 --- a/client/test/workflow.test.js +++ b/client/test/workflow.test.js @@ -337,6 +337,8 @@ describe('Workflow', () => { describe('Actions', () => { it('should offer the user to terminate a running workflow, prompting the user for a termination reason', async function test(done) { + this.timeout(4000); + const [summaryEl] = await summaryTest(this.test); const terminateEl = await summaryEl.waitUntilExists( 'aside.actions button' @@ -344,8 +346,6 @@ describe('Workflow', () => { terminateEl.trigger('click'); - this.timeout(500); - const confirmTerminateEl = await summaryEl.waitUntilExists( '[data-modal="confirm-termination"]' ); From 73173aade2c5478e0f06f6d0c72dbded7e4aa86a Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Tue, 27 Apr 2021 10:19:57 -0700 Subject: [PATCH 21/30] increasing timeout time --- client/test/workflow.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/test/workflow.test.js b/client/test/workflow.test.js index 23a12eba4..506237e0c 100644 --- a/client/test/workflow.test.js +++ b/client/test/workflow.test.js @@ -337,7 +337,7 @@ describe('Workflow', () => { describe('Actions', () => { it('should offer the user to terminate a running workflow, prompting the user for a termination reason', async function test(done) { - this.timeout(4000); + this.timeout(10000); const [summaryEl] = await summaryTest(this.test); const terminateEl = await summaryEl.waitUntilExists( From 9e4321e6a810b3874dbcf4a1209456426430c27a Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Tue, 27 Apr 2021 10:25:24 -0700 Subject: [PATCH 22/30] removing done function as it does not work --- client/test/workflow.test.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/client/test/workflow.test.js b/client/test/workflow.test.js index 506237e0c..4dbd1437e 100644 --- a/client/test/workflow.test.js +++ b/client/test/workflow.test.js @@ -336,7 +336,7 @@ describe('Workflow', () => { }); describe('Actions', () => { - it('should offer the user to terminate a running workflow, prompting the user for a termination reason', async function test(done) { + it('should offer the user to terminate a running workflow, prompting the user for a termination reason', async function test() { this.timeout(10000); const [summaryEl] = await summaryTest(this.test); @@ -357,8 +357,6 @@ describe('Workflow', () => { .contain('button[name="button-terminate"]') .and.contain('button[name="button-cancel"]') .and.contain('input[placeholder="Reason"]'); - - done(); }); it('should terminate the workflow with the provided reason', async function test() { From 466d1ac01c9b76dd3c602953c06d28b92b4c6399 Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Tue, 27 Apr 2021 10:36:44 -0700 Subject: [PATCH 23/30] increase timeout to 20000ms --- client/test/workflow.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/test/workflow.test.js b/client/test/workflow.test.js index 4dbd1437e..1136c5fed 100644 --- a/client/test/workflow.test.js +++ b/client/test/workflow.test.js @@ -337,7 +337,7 @@ describe('Workflow', () => { describe('Actions', () => { it('should offer the user to terminate a running workflow, prompting the user for a termination reason', async function test() { - this.timeout(10000); + this.timeout(20000); const [summaryEl] = await summaryTest(this.test); const terminateEl = await summaryEl.waitUntilExists( From 7548afde76b9844ff473931aa9cc748a096c85a0 Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Tue, 27 Apr 2021 10:41:49 -0700 Subject: [PATCH 24/30] increasing timeout to 50K ms --- client/test/workflow.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/test/workflow.test.js b/client/test/workflow.test.js index 1136c5fed..6ab73f0ee 100644 --- a/client/test/workflow.test.js +++ b/client/test/workflow.test.js @@ -337,7 +337,7 @@ describe('Workflow', () => { describe('Actions', () => { it('should offer the user to terminate a running workflow, prompting the user for a termination reason', async function test() { - this.timeout(20000); + this.timeout(50000); const [summaryEl] = await summaryTest(this.test); const terminateEl = await summaryEl.waitUntilExists( From d9a1a9abe1ed367f7ccc08de7f4e866060f44e61 Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Tue, 27 Apr 2021 10:47:41 -0700 Subject: [PATCH 25/30] scrapping timeout and inserting delay to test --- client/test/workflow.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/test/workflow.test.js b/client/test/workflow.test.js index 6ab73f0ee..d43262ae9 100644 --- a/client/test/workflow.test.js +++ b/client/test/workflow.test.js @@ -337,8 +337,6 @@ describe('Workflow', () => { describe('Actions', () => { it('should offer the user to terminate a running workflow, prompting the user for a termination reason', async function test() { - this.timeout(50000); - const [summaryEl] = await summaryTest(this.test); const terminateEl = await summaryEl.waitUntilExists( 'aside.actions button' @@ -346,6 +344,8 @@ describe('Workflow', () => { terminateEl.trigger('click'); + await Promise.delay(1000); + const confirmTerminateEl = await summaryEl.waitUntilExists( '[data-modal="confirm-termination"]' ); From 61f28b54fad138a8e6b047494e0e2b1ea49e4eae Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Tue, 27 Apr 2021 10:53:16 -0700 Subject: [PATCH 26/30] tests now passing. trying to reduce timeout for faster runtime --- client/test/workflow.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/test/workflow.test.js b/client/test/workflow.test.js index d43262ae9..4eaf8a8cf 100644 --- a/client/test/workflow.test.js +++ b/client/test/workflow.test.js @@ -344,7 +344,7 @@ describe('Workflow', () => { terminateEl.trigger('click'); - await Promise.delay(1000); + await Promise.delay(100); const confirmTerminateEl = await summaryEl.waitUntilExists( '[data-modal="confirm-termination"]' From c6d59b9a5b217f552b37bf8717df9e4660c60c2b Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Tue, 27 Apr 2021 10:58:13 -0700 Subject: [PATCH 27/30] increasing delay to 200ms --- client/test/workflow.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/test/workflow.test.js b/client/test/workflow.test.js index 4eaf8a8cf..f48649e28 100644 --- a/client/test/workflow.test.js +++ b/client/test/workflow.test.js @@ -344,7 +344,7 @@ describe('Workflow', () => { terminateEl.trigger('click'); - await Promise.delay(100); + await Promise.delay(200); const confirmTerminateEl = await summaryEl.waitUntilExists( '[data-modal="confirm-termination"]' From ea4b4599a6ca9dd7cae38192467ebc30b3970130 Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Tue, 27 Apr 2021 11:04:44 -0700 Subject: [PATCH 28/30] increasing delay to 300ms --- client/test/workflow.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/test/workflow.test.js b/client/test/workflow.test.js index f48649e28..4fc8255b2 100644 --- a/client/test/workflow.test.js +++ b/client/test/workflow.test.js @@ -344,7 +344,7 @@ describe('Workflow', () => { terminateEl.trigger('click'); - await Promise.delay(200); + await Promise.delay(300); const confirmTerminateEl = await summaryEl.waitUntilExists( '[data-modal="confirm-termination"]' From b91ddf37eb3089e5885912435ddc31cfc203bdec Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Tue, 27 Apr 2021 11:10:57 -0700 Subject: [PATCH 29/30] increasing to 500ms --- client/test/workflow.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/test/workflow.test.js b/client/test/workflow.test.js index 4fc8255b2..f179aed91 100644 --- a/client/test/workflow.test.js +++ b/client/test/workflow.test.js @@ -344,7 +344,7 @@ describe('Workflow', () => { terminateEl.trigger('click'); - await Promise.delay(300); + await Promise.delay(500); const confirmTerminateEl = await summaryEl.waitUntilExists( '[data-modal="confirm-termination"]' From 153436dacff5c0d86529fa5bdb6c1fac75f11df8 Mon Sep 17 00:00:00 2001 From: Justin Muller Date: Tue, 27 Apr 2021 11:22:05 -0700 Subject: [PATCH 30/30] increasing delay to 1000ms --- client/test/workflow.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/test/workflow.test.js b/client/test/workflow.test.js index f179aed91..d43262ae9 100644 --- a/client/test/workflow.test.js +++ b/client/test/workflow.test.js @@ -344,7 +344,7 @@ describe('Workflow', () => { terminateEl.trigger('click'); - await Promise.delay(500); + await Promise.delay(1000); const confirmTerminateEl = await summaryEl.waitUntilExists( '[data-modal="confirm-termination"]'