diff --git a/server/router/index.js b/server/router/index.js index f09ce7873..2bdb362ab 100644 --- a/server/router/index.js +++ b/server/router/index.js @@ -41,12 +41,13 @@ const { workflowSignalHandler, workflowTerminateHandler, } = require('./routes'); +const { clusterService } = require('./services'); const { listWorkflows } = require('./helpers'); const router = new Router(); -router.get('/api/cluster', clusterHandler.getCluster); +router.get('/api/cluster', clusterHandler(clusterService)); router.get('/api/domains', domainListHandler); diff --git a/server/router/routes/cluster-handler.js b/server/router/routes/cluster-handler.js index 2932a66a8..c0d236d25 100644 --- a/server/router/routes/cluster-handler.js +++ b/server/router/routes/cluster-handler.js @@ -19,39 +19,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -const { CLUSTER_CACHE_TTL } = require('../constants'); - -let cache = null; -let cacheExpiryDateTime = null; - -const clearCache = () => { - cache = null; - cacheExpiryDateTime = null; -}; - -const setCache = data => { - cache = data; - cacheExpiryDateTime = Date.now() + CLUSTER_CACHE_TTL; -}; - -const getCluster = async ctx => { - if (cacheExpiryDateTime && Date.now() < cacheExpiryDateTime) { - return (ctx.body = cache); - } - - const cluster = await ctx.cadence.describeCluster(); - - const data = { ...cluster, membershipInfo: null }; - - setCache(data); - - ctx.body = data; -}; - -const clusterHandler = { - clearCache, - getCluster, - setCache, -}; +const clusterHandler = clusterService => async ctx => + (ctx.body = await clusterService.getCluster(ctx)); module.exports = clusterHandler; diff --git a/server/router/services/cluster-service.js b/server/router/services/cluster-service.js new file mode 100644 index 000000000..3f6985ee2 --- /dev/null +++ b/server/router/services/cluster-service.js @@ -0,0 +1,57 @@ +// 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 { CLUSTER_CACHE_TTL } = require('../constants'); + +let cache = null; +let cacheExpiryDateTime = null; + +const clearCache = () => { + cache = null; + cacheExpiryDateTime = null; +}; + +const setCache = data => { + cache = data; + cacheExpiryDateTime = Date.now() + CLUSTER_CACHE_TTL; +}; + +const getCluster = async ctx => { + if (cacheExpiryDateTime && Date.now() < cacheExpiryDateTime) { + return cache; + } + + const cluster = await ctx.cadence.describeCluster(); + + const data = { ...cluster, membershipInfo: null }; + + setCache(data); + + return data; +}; + +const clusterService = { + clearCache, + getCluster, + setCache, +}; + +module.exports = clusterService; diff --git a/server/router/routes/cluster-handler.spec.js b/server/router/services/cluster-service.spec.js similarity index 82% rename from server/router/routes/cluster-handler.spec.js rename to server/router/services/cluster-service.spec.js index 7a8bd9bc6..959e37f28 100644 --- a/server/router/routes/cluster-handler.spec.js +++ b/server/router/services/cluster-service.spec.js @@ -19,12 +19,12 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -import clusterHandler from './cluster-handler'; +import clusterService from './cluster-service'; -describe('cluster handler', () => { +describe('clusterService', () => { describe('getCluster', () => { beforeEach(() => { - clusterHandler.clearCache(); + clusterService.clearCache(); }); describe('cache = null', () => { @@ -36,15 +36,14 @@ describe('cluster handler', () => { }; const ctx = { - body: null, cadence: { describeCluster: jest.fn().mockImplementation(() => cluster), }, }; - await clusterHandler.getCluster(ctx); + const data = await clusterService.getCluster(ctx); - expect(ctx.body).toEqual(cluster); + expect(data).toEqual(cluster); }); }); @@ -57,15 +56,14 @@ describe('cluster handler', () => { }; const ctx = { - body: null, cadence: { describeCluster: jest.fn().mockImplementation(() => clusterCache), }, }; - await clusterHandler.getCluster(ctx); + const data = await clusterService.getCluster(ctx); - expect(ctx.body).toEqual(clusterCache); + expect(data).toEqual(clusterCache); const clusterUpdated = { persistenceInfo: {}, @@ -73,12 +71,11 @@ describe('cluster handler', () => { version: 2, }; - ctx.body = null; ctx.cadence.describeCluster.mockImplementation(() => clusterUpdated); - await clusterHandler.getCluster(ctx); + const updatedData = await clusterService.getCluster(ctx); - expect(ctx.body).toEqual(clusterCache); + expect(updatedData).toEqual(clusterCache); }); describe('and time passes over CLUSTER_CACHE_TTL', () => { @@ -90,7 +87,6 @@ describe('cluster handler', () => { }; const ctx = { - body: null, cadence: { describeCluster: jest.fn().mockImplementation(() => clusterCache), }, @@ -103,9 +99,9 @@ describe('cluster handler', () => { new Date(Date.UTC(2020, 2, 10)).getTime() ); - await clusterHandler.getCluster(ctx); + const data = await clusterService.getCluster(ctx); - expect(ctx.body).toEqual(clusterCache); + expect(data).toEqual(clusterCache); const clusterUpdated = { persistenceInfo: {}, @@ -113,7 +109,6 @@ describe('cluster handler', () => { version: 2, }; - ctx.body = null; ctx.cadence.describeCluster.mockImplementation(() => clusterUpdated); // set current time to an hour into the future @@ -123,9 +118,9 @@ describe('cluster handler', () => { new Date(Date.UTC(2020, 2, 10, 2)).getTime() ); - await clusterHandler.getCluster(ctx); + const updatedData = await clusterService.getCluster(ctx); - expect(ctx.body).toEqual(clusterUpdated); + expect(updatedData).toEqual(clusterUpdated); }); }); }); diff --git a/server/router/services/index.js b/server/router/services/index.js new file mode 100644 index 000000000..8dc705ff7 --- /dev/null +++ b/server/router/services/index.js @@ -0,0 +1,26 @@ +// 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 clusterService = require('./cluster-service'); + +module.exports = { + clusterService, +};