From 8f82f0c57dc5c980ca5c8ff6ca89677589e9296e Mon Sep 17 00:00:00 2001 From: Jonathan Jalouzot Date: Tue, 20 Mar 2018 15:37:37 +0100 Subject: [PATCH 1/4] feat: distinct entryPoint and function name --- package/lib/compileFunctions.js | 3 ++- package/lib/compileFunctions.test.js | 30 ++++++++++++++++++---------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/package/lib/compileFunctions.js b/package/lib/compileFunctions.js index de5034d..ddf5125 100644 --- a/package/lib/compileFunctions.js +++ b/package/lib/compileFunctions.js @@ -117,7 +117,8 @@ const getFunctionTemplate = (funcObject, region, sourceArchiveUrl) => { //eslint location: region, availableMemoryMb: 256, timeout: '60s', - function: funcObject.handler, + entryPoint: funcObject.handler, + function: funcObject.name, sourceArchiveUrl, }, }; diff --git a/package/lib/compileFunctions.test.js b/package/lib/compileFunctions.test.js index ce2ccb2..4b80362 100644 --- a/package/lib/compileFunctions.test.js +++ b/package/lib/compileFunctions.test.js @@ -113,7 +113,8 @@ describe('CompileFunctions', () => { name: 'my-service-dev-func1', properties: { location: 'us-central1', - function: 'func1', + entryPoint: 'func1', + function: 'my-service-dev-func1', availableMemoryMb: 1024, timeout: '60s', sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip', @@ -147,7 +148,8 @@ describe('CompileFunctions', () => { name: 'my-service-dev-func1', properties: { location: 'us-central1', - function: 'func1', + entryPoint: 'func1', + function: 'my-service-dev-func1', availableMemoryMb: 1024, timeout: '60s', sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip', @@ -181,7 +183,8 @@ describe('CompileFunctions', () => { name: 'my-service-dev-func1', properties: { location: 'us-central1', - function: 'func1', + entryPoint: 'func1', + function: 'my-service-dev-func1', availableMemoryMb: 256, timeout: '120s', sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip', @@ -215,7 +218,8 @@ describe('CompileFunctions', () => { name: 'my-service-dev-func1', properties: { location: 'us-central1', - function: 'func1', + entryPoint: 'func1', + function: 'my-service-dev-func1', availableMemoryMb: 256, timeout: '120s', sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip', @@ -251,7 +255,8 @@ describe('CompileFunctions', () => { name: 'my-service-dev-func1', properties: { location: 'us-central1', - function: 'func1', + entryPoint: 'func1', + function: 'my-service-dev-func1', availableMemoryMb: 256, timeout: '60s', sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip', @@ -289,7 +294,8 @@ describe('CompileFunctions', () => { name: 'my-service-dev-func1', properties: { location: 'us-central1', - function: 'func1', + entryPoint: 'func1', + function: 'my-service-dev-func1', availableMemoryMb: 256, timeout: '60s', sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip', @@ -331,7 +337,8 @@ describe('CompileFunctions', () => { name: 'my-service-dev-func1', properties: { location: 'us-central1', - function: 'func1', + entryPoint: 'func1', + function: 'my-service-dev-func1', availableMemoryMb: 256, timeout: '60s', sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip', @@ -367,7 +374,8 @@ describe('CompileFunctions', () => { name: 'my-service-dev-func1', properties: { location: 'us-central1', - function: 'func1', + entryPoint: 'func1', + function: 'my-service-dev-func1', availableMemoryMb: 256, timeout: '60s', sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip', @@ -418,7 +426,8 @@ describe('CompileFunctions', () => { name: 'my-service-dev-func1', properties: { location: 'us-central1', - function: 'func1', + entryPoint: 'func1', + function: 'my-service-dev-func1', availableMemoryMb: 256, timeout: '60s', sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip', @@ -435,7 +444,8 @@ describe('CompileFunctions', () => { name: 'my-service-dev-func2', properties: { location: 'us-central1', - function: 'func2', + entryPoint: 'func2', + function: 'my-service-dev-func2', availableMemoryMb: 256, timeout: '60s', sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip', From 2628daf0689bc13f9d759f74291df729ba59769d Mon Sep 17 00:00:00 2001 From: Jonathan Jalouzot Date: Tue, 20 Mar 2018 15:57:23 +0100 Subject: [PATCH 2/4] feat: change display info to use good name --- info/lib/displayServiceInfo.js | 2 +- info/lib/displayServiceInfo.test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/info/lib/displayServiceInfo.js b/info/lib/displayServiceInfo.js index f1cf35a..ebcfbe3 100644 --- a/info/lib/displayServiceInfo.js +++ b/info/lib/displayServiceInfo.js @@ -50,7 +50,7 @@ module.exports = { const region = this.options.region; const project = this.serverless.service.provider.project; const baseUrl = `https://${region}-${project}.cloudfunctions.net`; - const path = serviceFunc.handler; // NOTE this might change + const path = serviceFunc.name; // NOTE this might change funcResource = `${baseUrl}/${path}`; } diff --git a/info/lib/displayServiceInfo.test.js b/info/lib/displayServiceInfo.test.js index 984fa05..537529a 100644 --- a/info/lib/displayServiceInfo.test.js +++ b/info/lib/displayServiceInfo.test.js @@ -117,7 +117,7 @@ describe('DisplayServiceInfo', () => { functions: [ { name: 'func1', - resource: 'https://us-central1-my-project.cloudfunctions.net/handler', + resource: 'https://us-central1-my-project.cloudfunctions.net/my-service-dev-func1', }, { name: 'func2', From 747c8d1097a67a5529581cadce4c606a40153a36 Mon Sep 17 00:00:00 2001 From: Jonathan Jalouzot Date: Tue, 20 Mar 2018 15:57:48 +0100 Subject: [PATCH 3/4] feat: use function name in invoke --- invoke/lib/invokeFunction.js | 4 +++- invoke/lib/invokeFunction.test.js | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/invoke/lib/invokeFunction.js b/invoke/lib/invokeFunction.js index fcd7eff..3ae711c 100644 --- a/invoke/lib/invokeFunction.js +++ b/invoke/lib/invokeFunction.js @@ -14,14 +14,16 @@ module.exports = { invoke() { const project = this.serverless.service.provider.project; + const service = this.serverless.service.service; const region = this.options.region; + const stage = this.options.stage || 'dev'; let func = this.options.function; const data = this.options.data || ''; func = getGoogleCloudFunctionName(this.serverless.service.functions, func); const params = { - name: `projects/${project}/locations/${region}/functions/${func}`, + name: `projects/${project}/locations/${region}/functions/${service}-${stage}-${func}`, resource: { data, }, diff --git a/invoke/lib/invokeFunction.test.js b/invoke/lib/invokeFunction.test.js index dcbc1ca..381022c 100644 --- a/invoke/lib/invokeFunction.test.js +++ b/invoke/lib/invokeFunction.test.js @@ -78,7 +78,7 @@ describe('InvokeFunction', () => { 'functions', 'call', { - name: 'projects/my-project/locations/us-central1/functions/foo', + name: 'projects/my-project/locations/us-central1/functions/my-service-dev-foo', resource: { data: '', }, @@ -98,7 +98,7 @@ describe('InvokeFunction', () => { 'functions', 'call', { - name: 'projects/my-project/locations/us-central1/functions/foo', + name: 'projects/my-project/locations/us-central1/functions/my-service-dev-foo', resource: { data: googleInvoke.options.data, }, From 4ed3d6b7892e72c8447fbbc0bfab05ca975c9f8d Mon Sep 17 00:00:00 2001 From: Jonathan Jalouzot Date: Wed, 4 Apr 2018 16:58:32 +0200 Subject: [PATCH 4/4] feat: use option prependStage or prependService in function name --- info/lib/displayServiceInfo.js | 12 ++- info/lib/displayServiceInfo.test.js | 26 +++++- invoke/lib/invokeFunction.js | 26 ++++-- invoke/lib/invokeFunction.test.js | 74 +++++++++++++++- package/lib/compileFunctions.js | 22 +++-- package/lib/compileFunctions.test.js | 126 ++++++++++++++++++++++++--- 6 files changed, 261 insertions(+), 25 deletions(-) diff --git a/info/lib/displayServiceInfo.js b/info/lib/displayServiceInfo.js index ebcfbe3..3658776 100644 --- a/info/lib/displayServiceInfo.js +++ b/info/lib/displayServiceInfo.js @@ -45,12 +45,21 @@ module.exports = { const funcEventConfig = serviceFunc.events[0][eventType]; let funcResource = funcEventConfig.resource || null; + let funcName = serviceFunc.handler; + + if (serviceFunc.prependStage) { + funcName = `${this.options.stage}-${funcName}`; + } + + if (serviceFunc.prependService) { + funcName = `${this.serverless.service.service}-${funcName}`; + } if (eventType === 'http') { const region = this.options.region; const project = this.serverless.service.provider.project; const baseUrl = `https://${region}-${project}.cloudfunctions.net`; - const path = serviceFunc.name; // NOTE this might change + const path = funcName; // NOTE this might change funcResource = `${baseUrl}/${path}`; } @@ -99,5 +108,6 @@ const getFunctionNameInService = (funcName, service, stage) => { funcNameInService = funcNameInService.replace(service, ''); funcNameInService = funcNameInService.replace(stage, ''); funcNameInService = funcNameInService.slice(2, funcNameInService.length); + return funcNameInService; }; diff --git a/info/lib/displayServiceInfo.test.js b/info/lib/displayServiceInfo.test.js index 537529a..c02486c 100644 --- a/info/lib/displayServiceInfo.test.js +++ b/info/lib/displayServiceInfo.test.js @@ -34,6 +34,20 @@ describe('DisplayServiceInfo', () => { }, ], }, + func3: { + handler: 'handler', + prependStage: true, + events: [ + { http: 'foo3' }, + ], + }, + func4: { + handler: 'handler', + prependService: true, + events: [ + { http: 'foo4' }, + ], + }, }; serverless.service.provider = { project: 'my-project', @@ -105,6 +119,8 @@ describe('DisplayServiceInfo', () => { { type: 'resource.which.should.be.filterered', name: 'someResource' }, { type: 'cloudfunctions.v1beta2.function', name: 'my-service-dev-func1' }, { type: 'cloudfunctions.v1beta2.function', name: 'my-service-dev-func2' }, + { type: 'cloudfunctions.v1beta2.function', name: 'my-service-dev-func3' }, + { type: 'cloudfunctions.v1beta2.function', name: 'my-service-dev-func4' }, ], }; @@ -117,12 +133,20 @@ describe('DisplayServiceInfo', () => { functions: [ { name: 'func1', - resource: 'https://us-central1-my-project.cloudfunctions.net/my-service-dev-func1', + resource: 'https://us-central1-my-project.cloudfunctions.net/handler', }, { name: 'func2', resource: 'projects/*/topics/my-test-topic', }, + { + name: 'func3', + resource: 'https://us-central1-my-project.cloudfunctions.net/dev-handler', + }, + { + name: 'func4', + resource: 'https://us-central1-my-project.cloudfunctions.net/my-service-handler', + }, ], }, }; diff --git a/invoke/lib/invokeFunction.js b/invoke/lib/invokeFunction.js index 3ae711c..afa9b8a 100644 --- a/invoke/lib/invokeFunction.js +++ b/invoke/lib/invokeFunction.js @@ -14,16 +14,20 @@ module.exports = { invoke() { const project = this.serverless.service.provider.project; - const service = this.serverless.service.service; const region = this.options.region; - const stage = this.options.stage || 'dev'; + const stage = this.options.stage ? this.options.stage : 'dev'; let func = this.options.function; const data = this.options.data || ''; - func = getGoogleCloudFunctionName(this.serverless.service.functions, func); + func = getGoogleCloudFunctionName( + this.serverless.service.functions, + func, + stage, + this.serverless.service.service, + ); const params = { - name: `projects/${project}/locations/${region}/functions/${service}-${stage}-${func}`, + name: `projects/${project}/locations/${region}/functions/${func}`, resource: { data, }, @@ -57,7 +61,7 @@ module.exports = { }; // retrieve the functions name (Google uses our handler property as the function name) -const getGoogleCloudFunctionName = (serviceFunctions, func) => { +const getGoogleCloudFunctionName = (serviceFunctions, func, stage, service) => { if (!serviceFunctions[func]) { const errorMessage = [ `Function "${func}" not found. `, @@ -66,5 +70,15 @@ const getGoogleCloudFunctionName = (serviceFunctions, func) => { throw new Error(errorMessage); } - return serviceFunctions[func].handler; + let funcName = serviceFunctions[func].handler; + + if (serviceFunctions[func].prependStage) { + funcName = `${stage}-${funcName}`; + } + + if (serviceFunctions[func].prependService) { + funcName = `${service}-${funcName}`; + } + + return funcName; }; diff --git a/invoke/lib/invokeFunction.test.js b/invoke/lib/invokeFunction.test.js index 381022c..cf50f7d 100644 --- a/invoke/lib/invokeFunction.test.js +++ b/invoke/lib/invokeFunction.test.js @@ -24,6 +24,19 @@ describe('InvokeFunction', () => { func1: { handler: 'foo', }, + func2: { + handler: 'foo2', + prependService: true, + }, + func3: { + handler: 'foo3', + prependStage: true, + }, + func4: { + handler: 'foo4', + prependStage: true, + prependService: true, + }, }; serverless.setProvider('google', new GoogleProvider(serverless)); const options = { @@ -78,7 +91,64 @@ describe('InvokeFunction', () => { 'functions', 'call', { - name: 'projects/my-project/locations/us-central1/functions/my-service-dev-foo', + name: 'projects/my-project/locations/us-central1/functions/foo', + resource: { + data: '', + }, + })).toEqual(true); + }); + }); + + it('should invoke the provided function with prependService', () => { + googleInvoke.options.function = 'func2'; + + return googleInvoke.invoke().then(() => { + expect(requestStub.calledWithExactly( + 'cloudfunctions', + 'projects', + 'locations', + 'functions', + 'call', + { + name: 'projects/my-project/locations/us-central1/functions/my-service-foo2', + resource: { + data: '', + }, + })).toEqual(true); + }); + }); + + it('should invoke the provided function with prependStage', () => { + googleInvoke.options.function = 'func3'; + + return googleInvoke.invoke().then(() => { + expect(requestStub.calledWithExactly( + 'cloudfunctions', + 'projects', + 'locations', + 'functions', + 'call', + { + name: 'projects/my-project/locations/us-central1/functions/dev-foo3', + resource: { + data: '', + }, + })).toEqual(true); + }); + }); + + it('should invoke the provided function with all prepend', () => { + googleInvoke.options.function = 'func4'; + + return googleInvoke.invoke().then(() => { + expect(requestStub.calledWithExactly( + 'cloudfunctions', + 'projects', + 'locations', + 'functions', + 'call', + { + name: 'projects/my-project/locations/us-central1/functions/my-service-dev-foo4', resource: { data: '', }, @@ -98,7 +168,7 @@ describe('InvokeFunction', () => { 'functions', 'call', { - name: 'projects/my-project/locations/us-central1/functions/my-service-dev-foo', + name: 'projects/my-project/locations/us-central1/functions/foo', resource: { data: googleInvoke.options.data, }, diff --git a/package/lib/compileFunctions.js b/package/lib/compileFunctions.js index ddf5125..5e3c4aa 100644 --- a/package/lib/compileFunctions.js +++ b/package/lib/compileFunctions.js @@ -23,13 +23,15 @@ module.exports = { validateHandlerProperty(funcObject, functionName); validateEventsProperty(funcObject, functionName); - const funcTemplate = getFunctionTemplate( funcObject, this.options.region, + this.options.stage, + this.serverless.service.service, `gs://${ - this.serverless.service.provider.deploymentBucketName - }/${this.serverless.service.package.artifactFilePath}`); + this.serverless.service.provider.deploymentBucketName + }/${this.serverless.service.package.artifactFilePath}`, + ); funcTemplate.properties.availableMemoryMb = _.get(funcObject, 'memorySize') || _.get(this, 'serverless.service.provider.memorySize') @@ -109,7 +111,17 @@ const validateEventsProperty = (funcObject, functionName) => { } }; -const getFunctionTemplate = (funcObject, region, sourceArchiveUrl) => { //eslint-disable-line +const getFunctionTemplate = (funcObject, region, stage, service, sourceArchiveUrl) => { //eslint-disable-line + let funcName = funcObject.handler; + + if (funcObject.prependStage) { + funcName = `${stage}-${funcName}`; + } + + if (funcObject.prependService) { + funcName = `${service}-${funcName}`; + } + return { type: 'cloudfunctions.v1beta2.function', name: funcObject.name, @@ -118,7 +130,7 @@ const getFunctionTemplate = (funcObject, region, sourceArchiveUrl) => { //eslint availableMemoryMb: 256, timeout: '60s', entryPoint: funcObject.handler, - function: funcObject.name, + function: funcName, sourceArchiveUrl, }, }; diff --git a/package/lib/compileFunctions.test.js b/package/lib/compileFunctions.test.js index 4b80362..5963253 100644 --- a/package/lib/compileFunctions.test.js +++ b/package/lib/compileFunctions.test.js @@ -114,7 +114,7 @@ describe('CompileFunctions', () => { properties: { location: 'us-central1', entryPoint: 'func1', - function: 'my-service-dev-func1', + function: 'func1', availableMemoryMb: 1024, timeout: '60s', sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip', @@ -149,7 +149,7 @@ describe('CompileFunctions', () => { properties: { location: 'us-central1', entryPoint: 'func1', - function: 'my-service-dev-func1', + function: 'func1', availableMemoryMb: 1024, timeout: '60s', sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip', @@ -184,7 +184,7 @@ describe('CompileFunctions', () => { properties: { location: 'us-central1', entryPoint: 'func1', - function: 'my-service-dev-func1', + function: 'func1', availableMemoryMb: 256, timeout: '120s', sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip', @@ -219,7 +219,7 @@ describe('CompileFunctions', () => { properties: { location: 'us-central1', entryPoint: 'func1', - function: 'my-service-dev-func1', + function: 'func1', availableMemoryMb: 256, timeout: '120s', sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip', @@ -256,7 +256,7 @@ describe('CompileFunctions', () => { properties: { location: 'us-central1', entryPoint: 'func1', - function: 'my-service-dev-func1', + function: 'func1', availableMemoryMb: 256, timeout: '60s', sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip', @@ -295,7 +295,7 @@ describe('CompileFunctions', () => { properties: { location: 'us-central1', entryPoint: 'func1', - function: 'my-service-dev-func1', + function: 'func1', availableMemoryMb: 256, timeout: '60s', sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip', @@ -338,7 +338,7 @@ describe('CompileFunctions', () => { properties: { location: 'us-central1', entryPoint: 'func1', - function: 'my-service-dev-func1', + function: 'func1', availableMemoryMb: 256, timeout: '60s', sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip', @@ -375,7 +375,7 @@ describe('CompileFunctions', () => { properties: { location: 'us-central1', entryPoint: 'func1', - function: 'my-service-dev-func1', + function: 'func1', availableMemoryMb: 256, timeout: '60s', sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip', @@ -427,7 +427,7 @@ describe('CompileFunctions', () => { properties: { location: 'us-central1', entryPoint: 'func1', - function: 'my-service-dev-func1', + function: 'func1', availableMemoryMb: 256, timeout: '60s', sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip', @@ -445,7 +445,7 @@ describe('CompileFunctions', () => { properties: { location: 'us-central1', entryPoint: 'func2', - function: 'my-service-dev-func2', + function: 'func2', availableMemoryMb: 256, timeout: '60s', sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip', @@ -464,5 +464,111 @@ describe('CompileFunctions', () => { .toEqual(compiledResources); }); }); + + it('should set stage in function name with prependStage', () => { + googlePackage.serverless.service.functions = { + func1: { + handler: 'func1', + prependStage: true, + events: [ + { http: 'foo' }, + ], + }, + }; + + const compiledResources = [{ + type: 'cloudfunctions.v1beta2.function', + name: 'my-service-dev-func1', + properties: { + location: 'us-central1', + entryPoint: 'func1', + function: 'dev-func1', + availableMemoryMb: 256, + timeout: '60s', + sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip', + httpsTrigger: { + url: 'foo', + }, + labels: {}, + }, + }]; + + return googlePackage.compileFunctions().then(() => { + expect(consoleLogStub.calledOnce).toEqual(true); + expect(googlePackage.serverless.service.provider.compiledConfigurationTemplate.resources) + .toEqual(compiledResources); + }); + }); + + it('should set service in function name with prependService', () => { + googlePackage.serverless.service.functions = { + func1: { + handler: 'func1', + prependService: true, + events: [ + { http: 'foo' }, + ], + }, + }; + + const compiledResources = [{ + type: 'cloudfunctions.v1beta2.function', + name: 'my-service-dev-func1', + properties: { + location: 'us-central1', + entryPoint: 'func1', + function: 'my-service-func1', + availableMemoryMb: 256, + timeout: '60s', + sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip', + httpsTrigger: { + url: 'foo', + }, + labels: {}, + }, + }]; + + return googlePackage.compileFunctions().then(() => { + expect(consoleLogStub.calledOnce).toEqual(true); + expect(googlePackage.serverless.service.provider.compiledConfigurationTemplate.resources) + .toEqual(compiledResources); + }); + }); + + it('should set service and stage in function name with prependService and prependStage', () => { + googlePackage.serverless.service.functions = { + func1: { + handler: 'func1', + prependStage: true, + prependService: true, + events: [ + { http: 'foo' }, + ], + }, + }; + + const compiledResources = [{ + type: 'cloudfunctions.v1beta2.function', + name: 'my-service-dev-func1', + properties: { + location: 'us-central1', + entryPoint: 'func1', + function: 'my-service-dev-func1', + availableMemoryMb: 256, + timeout: '60s', + sourceArchiveUrl: 'gs://sls-my-service-dev-12345678/some-path/artifact.zip', + httpsTrigger: { + url: 'foo', + }, + labels: {}, + }, + }]; + + return googlePackage.compileFunctions().then(() => { + expect(consoleLogStub.calledOnce).toEqual(true); + expect(googlePackage.serverless.service.provider.compiledConfigurationTemplate.resources) + .toEqual(compiledResources); + }); + }); }); });