Skip to content
This repository has been archived by the owner on Jul 2, 2020. It is now read-only.

Commit

Permalink
feat: aggregation deploy
Browse files Browse the repository at this point in the history
  • Loading branch information
echosoar committed Dec 12, 2019
1 parent ecd4c61 commit d97d3a1
Show file tree
Hide file tree
Showing 17 changed files with 212 additions and 35 deletions.
6 changes: 3 additions & 3 deletions packages/serverless-fc-spec/src/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ export class FCSpecBuilder extends SpecBuilder {

for (const funName in functionsData) {
const funSpec: FCFunctionStructure = functionsData[funName];

const handler = funSpec.handler || 'index.handler';
const functionTemplate: FCFunctionSpec = {
Type: 'Aliyun::Serverless::Function',
Properties: {
Description: funSpec.description || '',
Initializer: funSpec.initializer || 'index.initializer',
Handler: funSpec.handler || 'index.handler',
Initializer: funSpec.initializer || handler.split('.').slice(0, -1).join('.') + '.initializer',
Handler: handler,
Runtime: funSpec.runtime || providerData.runtime || 'nodejs8',
CodeUri: funSpec.codeUri || '.',
Timeout: funSpec.timeout || providerData.timeout || 30,
Expand Down
21 changes: 20 additions & 1 deletion packages/serverless-midway-plugin/src/core/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { IServerless, IServerlessOptions } from '../interface/midwayServerless';
import { transform, saveYaml } from '@midwayjs/spec-builder';
import { join } from 'path';
const { Select } = require('enquirer');
const coverAttributes = ['layers'];
const coverAttributes = ['layers', 'aggregation'];
export class MidwayServerless {

serverless: IServerless;
Expand Down Expand Up @@ -42,10 +42,29 @@ export class MidwayServerless {
}
});

this.assignAggregationToFunctions();

ProviderManager.call(this);

this.serverless.pluginManager.commands.deploy.lifecycleEvents = [
'midway-deploy',
];
}

// 合并高密度部署
assignAggregationToFunctions() {
if (!this.serverless.service.aggregation || !this.serverless.service.functions) {
return;
}

for (const aggregationName in this.serverless.service.aggregation) {
this.serverless.service.functions[`aggregation_${aggregationName}`] = this.serverless.service.aggregation[aggregationName];
if (!this.serverless.service.functions[`aggregation_${aggregationName}`].events) {
this.serverless.service.functions[`aggregation_${aggregationName}`].events = [];
}
if (!this.serverless.service.functions[`aggregation_${aggregationName}`].events.length) {
this.serverless.service.functions[`aggregation_${aggregationName}`].events.push({ http: { method: 'get' }});
}
}
}
}
50 changes: 43 additions & 7 deletions packages/serverless-midway-plugin/src/core/providerBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,46 @@ export class ProviderBase {

async loadWrapper(WrapperContent: string) {
const files = {};
for (const func in this.serverless.service.functions) {
const handlerConf = this.serverless.service.functions[func];
const functions = this.serverless.service.functions || {};
for (const func in functions) {
const handlerConf = functions[func];
const [handlerFileName, name] = handlerConf.handler.split('.');
if (!files[handlerFileName]) {
files[handlerFileName] = {
handlers: [],
originLayers: []
};
}
files[handlerFileName].originLayers.push(handlerConf.layers);
files[handlerFileName].handlers.push({
name,
handler: handlerConf.handler
});
if (handlerConf.layers && handlerConf.layers.length) {
files[handlerFileName].originLayers.push(handlerConf.layers);
}
// 高密度部署
if (/^aggregation_/.test(func) && handlerConf.functions) {
files[handlerFileName].handlers.push({
name,
handlers: handlerConf.functions.map((functionName: string) => {
const func = functions[functionName];
if (!func || !func.events) {
return;
}
const httpEvent = func.events.find((event: any) => !!event.http);
if (!httpEvent || !httpEvent.http.path) {
return;
}
return {
path: httpEvent.http.path,
handler: func.handler
};
}).filter((func: any) => !!func)
});
} else {
files[handlerFileName].handlers.push({
name,
handler: handlerConf.handler
});
}
}

for (const file in files) {
const fileName = join(this.midwayBuildPath, `${file}.js`);
const layers = this.getLayers(this.serverless.service.layers, ...files[file].originLayers);
Expand Down Expand Up @@ -113,4 +138,15 @@ export class ProviderBase {
}
return this.serverless.pluginManager.invoke.call(this.serverless.pluginManager, [command], true);
}

getSpecJson() {
const service = this.serverless.service;
return {
service: service.service,
provider: service.provider,
functions: service.functions,
resources: service.resources,
package: service.package,
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface IServerless {
events: any;
initialize?: string;
layers?: Ilayer
functions?: string[]
}
},
provider: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class ProviderFc extends ProviderBase {

},
'package:midway-spec': async () => {
await generateFunctionsSpecFile(join(this.servicePath, 'serverless.yml'), join(this.midwayBuildPath, 'template.yml'));
await generateFunctionsSpecFile(this.getSpecJson(), join(this.midwayBuildPath, 'template.yml'));
},
'package:midway-wrapper': async () => {
this.loadWrapper(wrapperContent);
Expand Down
10 changes: 10 additions & 0 deletions packages/serverless-midway-plugin/src/provider/aliyun/wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ exports.<%=handlerData.name%> = asyncWrapper(async (...args) => {
if (!inited) {
await initializeMethod();
}
<% if (handlerData.handler) { %>
return runtime.asyncEvent(starter.handleInvokeWrapper('<%=handlerData.handler%>'))(...args);
<% } else { %>
return runtime.asyncEvent(async (ctx) => {
<% handlerData.handlers.forEach(function(multiHandler){ %> if (ctx && ctx.path === '<%=multiHandler.path%>') {
return starter.handleInvokeWrapper('<%=multiHandler.handler%>')(ctx);
} else <% }); %>{
return 'unhandler path';
}
})(...args);
<% } %>
});
<% }); %>`;
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class ProviderTencent extends ProviderBase {

this.hooks = {
'package:midway-spec': async () => {
await generateFunctionsSpecFile(join(this.servicePath, 'serverless.yml'), join(this.midwayBuildPath, 'serverless.yml'));
await generateFunctionsSpecFile(this.getSpecJson(), join(this.midwayBuildPath, 'serverless.yml'));
},
'package:midway-wrapper': async () => {
this.loadWrapper(wrapperContent);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('../../../../dist');
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"dependencies": {
"@midwayjs/runtime-engine": "*",
"@midwayjs/serverless-fc-starter": "*",
"@midwayjs/faas": "*"
}
}
34 changes: 34 additions & 0 deletions packages/serverless-midway-plugin/test/aggregation/serverless.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
service: serverless-midway-test

provider:
name: aliyun

functions:
index:
handler: index.handler
events:
- http:
path: '/'
method: get
hello:
handler: hello.handler
events:
- http:
path: '/hello'
method: get

plugins:
- test

aggregation:
index:
handler: aggregation.handler
functions:
- index
- hello

package:
include:
exclude:
excludeDevDependencies: false
artifact: my-artifact.zip
13 changes: 13 additions & 0 deletions packages/serverless-midway-plugin/test/aggregation/src/hello.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { FaaSContext, func, inject, provide } from '@midwayjs/faas';

@provide()
@func('hello.handler')
export class HelloService {

@inject()
ctx: FaaSContext; // context

async handler(event, obj = {}) {
return 'hello.handler';
}
}
13 changes: 13 additions & 0 deletions packages/serverless-midway-plugin/test/aggregation/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { FaaSContext, func, inject, provide } from '@midwayjs/faas';

@provide()
@func('index.handler')
export class HelloService {

@inject()
ctx: FaaSContext; // context

async handler(event, obj = {}) {
return 'index.handler';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import * as assert from 'assert';

describe('/test/deploy/test/deploy.test.ts', () => {
it('deploy result', async () => {
assert(true);
});
});
22 changes: 22 additions & 0 deletions packages/serverless-midway-plugin/test/aggregation/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"compileOnSave": true,
"compilerOptions": {
"target": "ES2018",
"module": "commonjs",
"moduleResolution": "node",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"inlineSourceMap":true,
"noImplicitThis": true,
"noUnusedLocals": true,
"stripInternal": true,
"pretty": true,
"declaration": true,
"outDir": "dist"
},
"exclude": [
"dist",
"node_modules",
"test"
]
}
8 changes: 4 additions & 4 deletions packages/serverless-scf-spec/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ export const generateTemplateFunctionsSpec = (filePath: string) => {
};

export const generateFunctionsSpecFile = (
filePath: string,
sourceFilePathOrJson: any,
targetFilePath = '.serverless/serverless.yml'
) => {
generate(filePath, targetFilePath, SCFServerlessSpecBuilder);
generate(sourceFilePathOrJson, targetFilePath, SCFServerlessSpecBuilder);
};

export const generateTemplateFunctionsSpecFile = (
filePath: string,
sourceFilePathOrJson: any,
targetFilePath = 'template.yml'
) => {
generate(filePath, targetFilePath, SCFTemplateSpecBuilder);
generate(sourceFilePathOrJson, targetFilePath, SCFTemplateSpecBuilder);
};
13 changes: 9 additions & 4 deletions packages/spec-builder/src/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class SpecBuilder implements Builder {
}

getProvider() {
return this.originData['provider'];
return this.originData['provider'] || {};
}

getFunctions() {
Expand All @@ -26,7 +26,7 @@ export class SpecBuilder implements Builder {
}

getPackage() {
return this.originData['package'];
return this.originData['package'] || {};
}

getPlugins() {
Expand All @@ -40,14 +40,18 @@ export class SpecBuilder implements Builder {
name: serviceData
};
} else {
return serviceData;
return serviceData || {};
}
}

getLayers() {
return this.originData['layers'];
}

getAggregation() {
return this.originData['aggregation'];
}

toJSON(): object {
return {
service: this.getService(),
Expand All @@ -56,7 +60,8 @@ export class SpecBuilder implements Builder {
layers: this.getLayers(),
resources: this.getResources(),
plugins: this.getPlugins(),
package: this.getPackage()
package: this.getPackage(),
aggregation: this.getAggregation()
};
}
}
37 changes: 23 additions & 14 deletions packages/spec-builder/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,37 @@ import { SpecBuilder } from './builder';
export * from './interface';
export * from './builder';

export const transform = (sourcefilePath: string, builderCls?) => {
if (fs.existsSync(sourcefilePath)) {
const content = fs.readFileSync(sourcefilePath, 'utf8');
const result = parse(sourcefilePath, content);
if (builderCls) {
return new builderCls(result).toJSON();
} else {
return new SpecBuilder(result).toJSON();
export const transform = (sourcefilePathOrJson: string, builderCls?) => {
let result: any = sourcefilePathOrJson;
if (typeof sourcefilePathOrJson === 'string') {
if (fs.existsSync(sourcefilePathOrJson)) {
const content = fs.readFileSync(sourcefilePathOrJson, 'utf8');
result = parse(sourcefilePathOrJson, content);
}
}
if (!result) {
return;
}
if (builderCls) {
return new builderCls(result).toJSON();
} else {
return new SpecBuilder(result).toJSON();
}
};

export { saveYaml } from './parse';

export const generate = (sourceFilePath: string, targetFilePath: string, builderCls?) => {
const transformResultJSON = transform(sourceFilePath, builderCls);
export const generate = (sourceFilePathOrJson: any, targetFilePath: string, builderCls?) => {
let baseDir = process.cwd();
if (!path.isAbsolute(sourceFilePath)) {
sourceFilePath = path.join(baseDir, sourceFilePath);
} else {
baseDir = path.dirname(sourceFilePath);
let transformResultJSON = {};
if (typeof sourceFilePathOrJson === 'string') {
if (!path.isAbsolute(sourceFilePathOrJson)) {
sourceFilePathOrJson = path.join(baseDir, sourceFilePathOrJson);
} else {
baseDir = path.dirname(sourceFilePathOrJson);
}
}
transformResultJSON = transform(sourceFilePathOrJson, builderCls);
if (!path.isAbsolute(targetFilePath)) {
targetFilePath = path.join(baseDir, targetFilePath);
}
Expand Down

0 comments on commit d97d3a1

Please sign in to comment.