serverless-leo
Advanced tools
Comparing version 1.2.0 to 1.3.0
@@ -0,0 +0,0 @@ module.exports = { |
@@ -0,0 +0,0 @@ /* eslint-disable no-template-curly-in-string */ |
@@ -0,0 +0,0 @@ 'use strict' |
@@ -0,0 +0,0 @@ 'use strict' |
@@ -0,0 +0,0 @@ 'use strict' |
@@ -0,0 +0,0 @@ 'use strict' |
@@ -0,0 +0,0 @@ const findUp = require('find-up') |
175
lib/leo.js
@@ -8,95 +8,94 @@ 'use strict' | ||
module.exports = { | ||
compileLeo () { | ||
const allFunctions = this.serverless.service.getAllFunctions() | ||
const stage = this.serverless.service.provider.stage | ||
const custom = this.serverless.service.custom[stage] ? this.serverless.service.custom[stage] : this.serverless.service.custom | ||
const cloudformation = this.serverless.service.provider.compiledCloudFormationTemplate | ||
const customInstall = { | ||
Type: 'Custom::Install', | ||
Properties: {} | ||
} | ||
compileLeo () { | ||
const allFunctions = this.serverless.service.getAllFunctions() | ||
const stage = this.serverless.service.provider.stage | ||
const custom = this.serverless.service.custom[stage] ? this.serverless.service.custom[stage] : this.serverless.service.custom | ||
const cloudformation = this.serverless.service.provider.compiledCloudFormationTemplate | ||
const customInstall = { | ||
Type: 'Custom::Install', | ||
Properties: {} | ||
} | ||
if (custom.leoRegister) { | ||
customInstall.Properties.ServiceToken = custom.leoRegister | ||
} else { | ||
customInstall.Properties.ServiceToken = { | ||
'Fn::ImportValue': { | ||
'Fn::Sub': `${custom.leoStack}-Register` | ||
} | ||
} | ||
} | ||
if (custom.leoRegister) { | ||
customInstall.Properties.ServiceToken = custom.leoRegister | ||
} else { | ||
customInstall.Properties.ServiceToken = { | ||
'Fn::ImportValue': { | ||
'Fn::Sub': `${custom.leoStack}-Register` | ||
} | ||
} | ||
} | ||
const registrations = [] | ||
const botIds = [] | ||
const registrations = [] | ||
const botIds = [] | ||
function addInstallProperty (logicalId, installProperty) { | ||
if (botIds.includes(installProperty.id)) { | ||
throw new Error(`Bot IDs must be unique. ${installProperty.id} has already been added to the cloudformation.`) | ||
} | ||
botIds.push(installProperty.id) | ||
if (registrations.length === 0) { | ||
registrations.push(cloneDeep(customInstall)) | ||
} | ||
let currentRegister = registrations[registrations.length - 1] | ||
if (Object.keys(currentRegister.Properties).length > 100) { | ||
currentRegister = cloneDeep(customInstall) | ||
registrations.push(currentRegister) | ||
} | ||
currentRegister.Properties[logicalId] = installProperty | ||
} | ||
function addInstallProperty (logicalId, installProperty) { | ||
if (botIds.includes(installProperty.id)) { | ||
throw new Error(`Bot IDs must be unique. ${installProperty.id} has already been added to the cloudformation.`) | ||
} | ||
botIds.push(installProperty.id) | ||
if (registrations.length === 0) { | ||
registrations.push(cloneDeep(customInstall)) | ||
} | ||
let currentRegister = registrations[registrations.length - 1] | ||
if (Object.keys(currentRegister.Properties).length > 100) { | ||
currentRegister = cloneDeep(customInstall) | ||
registrations.push(currentRegister) | ||
} | ||
currentRegister.Properties[logicalId] = installProperty | ||
} | ||
return BbPromise.each( | ||
allFunctions, | ||
ymlFunctionName => { | ||
const functionObj = this.serverless.service.getFunction(ymlFunctionName) | ||
const leoEvents = functionObj.events ? functionObj.events.filter(event => event.leo) : [] | ||
const logicalId = this.provider.naming.getLambdaLogicalId(ymlFunctionName) | ||
const botNumbers = times(functionObj.botCount || 1, Number) | ||
return BbPromise.each( | ||
allFunctions, | ||
ymlFunctionName => { | ||
const functionObj = this.serverless.service.getFunction(ymlFunctionName) | ||
const leoEvents = functionObj.events ? functionObj.events.filter(event => event.leo) : [] | ||
const logicalId = this.provider.naming.getLambdaLogicalId(ymlFunctionName) | ||
botNumbers.forEach(botNumber => { | ||
const botSuffix = botNumber > 0 ? '_' + botNumber : '' | ||
let botId = `${this.serverless.service.service}-${stage}-${ymlFunctionName}${botSuffix}` | ||
const installProperty = { | ||
type: 'cron', | ||
settings: { | ||
botNumber | ||
}, | ||
lambdaName: { | ||
Ref: logicalId | ||
}, | ||
name: functionObj.botName || botId.replace(`${this.serverless.service.service}-${stage}-`, '') | ||
} | ||
if (functionObj.leoCron) { | ||
installProperty.time = functionObj.leoCron | ||
} | ||
if (functionObj.leoCron && leoEvents.length === 0) { | ||
installProperty.id = botId | ||
addInstallProperty(botId, installProperty) | ||
} | ||
if (leoEvents.length > 0) { | ||
leoEvents.forEach(leoEvent => { | ||
const config = leoEvent.leo instanceof Object ? leoEvent.leo : false | ||
const sourceQueue = config ? config.queue : leoEvent.leo | ||
botId = `${this.serverless.service.service}-${stage}-${ymlFunctionName}_${sourceQueue}${botSuffix}` | ||
const installEventProperty = cloneDeep(installProperty) | ||
installEventProperty.id = botId | ||
if (config && config.name) { | ||
installEventProperty.name = config.name | ||
} else { | ||
installEventProperty.name = functionObj.botName || botId.replace(`${this.serverless.service.service}-${stage}-`, '') | ||
} | ||
installEventProperty.settings.source = sourceQueue | ||
addInstallProperty(botId, installEventProperty) | ||
}) | ||
} | ||
}) | ||
} | ||
).then(() => { | ||
registrations.forEach((leoRegister, index) => { | ||
cloudformation.Resources[`LeoRegister${index}`] = leoRegister | ||
}) | ||
}) | ||
} | ||
if (leoEvents.length > 0) { | ||
leoEvents.forEach(leoEvent => { | ||
const config = leoEvent.leo instanceof Object ? leoEvent.leo : false | ||
const sourceQueue = config ? config.queue : leoEvent.leo | ||
const botNumbers = times((config && config.botCount) || 1, Number) | ||
botNumbers.forEach(botNumber => { | ||
const botSuffix = botNumber > 0 ? '_' + botNumber : '' | ||
let botId = `${this.serverless.service.service}-${stage}-${ymlFunctionName}${botSuffix}` | ||
const installProperty = { | ||
id: botId, | ||
type: 'cron', | ||
settings: { | ||
botNumber | ||
}, | ||
lambdaName: { | ||
Ref: logicalId | ||
} | ||
} | ||
if (config && config.cron) { | ||
installProperty.time = config.cron | ||
} | ||
if (sourceQueue) { | ||
botId = `${this.serverless.service.service}-${stage}-${ymlFunctionName}_${sourceQueue}${botSuffix}` | ||
installProperty.id = botId | ||
installProperty.settings.source = sourceQueue | ||
} | ||
if (config && config.name) { | ||
installProperty.name = config.name + botSuffix | ||
} else { | ||
installProperty.name = functionObj.botName ? functionObj.botName + botSuffix : botId.replace(`${this.serverless.service.service}-${stage}-`, '') | ||
} | ||
if (config && config.codeOverrides) { | ||
installProperty.settings.codeOverrides = config.codeOverrides | ||
} | ||
if (sourceQueue || (config && (config.cron || config.register))) { | ||
addInstallProperty(botId, installProperty) | ||
} | ||
}) | ||
}) | ||
} | ||
}).then(() => { | ||
registrations.forEach((leoRegister, index) => { | ||
cloudformation.Resources[`LeoRegister${index}`] = leoRegister | ||
}) | ||
}) | ||
} | ||
} |
@@ -0,0 +0,0 @@ const fs = require('fs') |
@@ -0,0 +0,0 @@ 'use strict' |
{ | ||
"name": "serverless-leo", | ||
"version": "1.2.0", | ||
"version": "1.3.0", | ||
"description": "Serverless plugin for leo microservices", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -47,3 +47,5 @@ # serverless-leo | ||
handler: index.handler | ||
leoCron: 0 0 1 * * * # Trigger Lambda from a Leo Cron (down to minute) | ||
events: | ||
- leo | ||
cron: 0 0 1 * * * # Trigger Lambda from a Leo Cron (down to minute) | ||
``` | ||
@@ -70,2 +72,3 @@ | ||
You can specify multiple queues for a single lambda. Each will become a separate bot, visible in the bus ui (Botmon). | ||
#### Name bots | ||
@@ -87,3 +90,5 @@ You can define the queue as an object and give the bot a name. Otherwise the name of the bot will be the name of the lambda plus the queue. | ||
handler: index.handler | ||
leoCron: 0 0 1 * * * | ||
events: | ||
- leo: | ||
cron: 0 0 1 * * * | ||
``` | ||
@@ -93,11 +98,23 @@ The bot will be named the same as the lambda. | ||
### Variations | ||
Handle different versions of bot by adding "botCount". This will create the number of bots specified and pass in "botNumber" into the event when the bot is ran. | ||
Create multiple bots using the same lambda by adding "botCount". This will create the number of bots specified and pass in "botNumber" into the event when the bot is ran. | ||
``` | ||
world: | ||
handler: index.handler | ||
leoCron: 0 0 1 * * * | ||
botCount: 4 | ||
events: | ||
- leo: | ||
queue: helloWorldTestQueue | ||
botCount: 4 | ||
``` | ||
This allows you to partition the queue, or change the configuration of the bot based on the value of the variable at run time. | ||
### Manual bots | ||
Create bots without a trigger by adding "register: true". | ||
``` | ||
world: | ||
handler: index.handler | ||
events: | ||
- leo: | ||
register: true | ||
``` | ||
### LeoRegister configuration | ||
@@ -104,0 +121,0 @@ You can configure the plugin to use different stacks for different stages. |
@@ -39,6 +39,26 @@ 'use strict' | ||
}) | ||
it('adds LeoRegister to cloudformation if there is register is set to true', async () => { | ||
const sls = testServerless() | ||
const lambda = cloneDeep(helloNodeWorldLambda) | ||
lambda.events = [ | ||
{ | ||
leo: { | ||
register: true | ||
} | ||
} | ||
] | ||
sls.serverless.service.functions.helloNodeWorld = lambda | ||
await sls.compileLeo() | ||
expect(sls.serverless.service.provider.compiledCloudFormationTemplate.Resources).to.have.property('LeoRegister0') | ||
}) | ||
it('adds LeoRegister to cloudformation if there is a leoCron specified', async () => { | ||
const sls = testServerless() | ||
const lambda = cloneDeep(helloNodeWorldLambda) | ||
lambda.leoCron = '* * * * * *' | ||
lambda.events = [ | ||
{ | ||
leo: { | ||
cron: '* * * * * *' | ||
} | ||
} | ||
] | ||
sls.serverless.service.functions.helloNodeWorld = lambda | ||
@@ -52,9 +72,12 @@ await sls.compileLeo() | ||
lambda.events = [ | ||
{ | ||
'leo': 'test_hello' | ||
} | ||
{ | ||
'leo': { | ||
botCount: 5, | ||
name: 'test_hello', | ||
queue: 'something' | ||
} | ||
} | ||
] | ||
lambda.botCount = 5 | ||
sls.serverless.service.functions.helloNodeWorld = lambda | ||
await sls.compileLeo() | ||
await sls.compileLeo() | ||
expect(Object.keys(sls.serverless.service.provider.compiledCloudFormationTemplate.Resources['LeoRegister0'].Properties).length).to.equal(6) | ||
@@ -81,10 +104,15 @@ }) | ||
lambda.events = [ | ||
{ | ||
'leo': 'test_hello' | ||
}, | ||
{ | ||
'leo': 'test_hello2' | ||
} | ||
{ | ||
'leo': { | ||
queue: 'test_hello', | ||
botCount: 5 | ||
} | ||
}, | ||
{ | ||
'leo': { | ||
queue: 'test_hello2', | ||
botCount: 5 | ||
} | ||
} | ||
] | ||
lambda.botCount = 5 | ||
sls.serverless.service.functions.helloNodeWorld = lambda | ||
@@ -98,10 +126,15 @@ await sls.compileLeo() | ||
lambda.events = [ | ||
{ | ||
'leo': 'test_hello' | ||
}, | ||
{ | ||
'leo': 'test_hello2' | ||
} | ||
{ | ||
'leo': { | ||
queue: 'test_hello', | ||
botCount: 2 | ||
} | ||
}, | ||
{ | ||
'leo': { | ||
queue: 'test_hello2', | ||
botCount: 2 | ||
} | ||
} | ||
] | ||
lambda.botCount = 2 | ||
sls.serverless.service.functions.helloNodeWorld = lambda | ||
@@ -108,0 +141,0 @@ await sls.compileLeo() |
@@ -0,0 +0,0 @@ 'use strict' |
@@ -0,0 +0,0 @@ const fs = require('fs-extra') |
Sorry, the diff of this file is not supported yet
38776
852
128