diff --git a/packages/faas-cli-command-core/test/fixtures/userLifecycle/test.txt b/packages/faas-cli-command-core/test/fixtures/userLifecycle/test.txt index 0b169cfd..96a370c8 100644 --- a/packages/faas-cli-command-core/test/fixtures/userLifecycle/test.txt +++ b/packages/faas-cli-command-core/test/fixtures/userLifecycle/test.txt @@ -1 +1 @@ -1589535981255 \ No newline at end of file +1592281077048 \ No newline at end of file diff --git a/packages/faas-cli-plugin-invoke/src/index.ts b/packages/faas-cli-plugin-invoke/src/index.ts index a6c3cec3..e646b308 100644 --- a/packages/faas-cli-plugin-invoke/src/index.ts +++ b/packages/faas-cli-plugin-invoke/src/index.ts @@ -32,13 +32,6 @@ enum LOCK_TYPE { COMPLETE, } -function getPlatformPath(p) { - if (type() === 'Windows_NT') { - return p.replace(/\\/g, '\\\\'); - } - return p; -} - export class FaaSInvokePlugin extends BasePlugin { baseDir: string; buildDir: string; @@ -388,15 +381,7 @@ export class FaaSInvokePlugin extends BasePlugin { const { name, fileName, userEntry } = this.checkUserEntry(); if (!userEntry) { const isTsMode = this.checkIsTsMode(); - let starterName; - const platform = this.getPlatform(); - this.core.debug('Platform entry', platform); - if (platform === 'aliyun') { - starterName = require.resolve('@midwayjs/serverless-fc-starter'); - } else if (platform === 'tencent') { - starterName = require.resolve('@midwayjs/serverless-scf-starter'); - } - + const starterName = this.getStarterName(); if (!starterName) { return; } @@ -407,10 +392,11 @@ export class FaaSInvokePlugin extends BasePlugin { layers: this.core.service.layers, functions: this.core.service.functions, }, + faasModName: process.env.MidwayModuleName, distDir: this.buildDir, - starter: getPlatformPath(starterName), + starter: this.getPlatformPath(starterName), loadDirectory: isTsMode - ? [getPlatformPath(resolve(this.defaultTmpFaaSOut, 'src'))] + ? [this.getPlatformPath(resolve(this.defaultTmpFaaSOut, 'src'))] : [], }); if (isTsMode) { @@ -432,12 +418,21 @@ export class FaaSInvokePlugin extends BasePlugin { this.core.debug('EntryInfo', this.entryInfo); } + getStarterName() { + const platform = this.getPlatform(); + this.core.debug('Platform entry', platform); + if (platform === 'aliyun') { + return require.resolve('@midwayjs/serverless-fc-starter'); + } else if (platform === 'tencent') { + return require.resolve('@midwayjs/serverless-scf-starter'); + } + } + async getInvoke() { let handler; let initHandler; let runtime; let invoke; - const platform = this.getPlatform(); if (this.entryInfo) { try { const handlerMod = require(this.entryInfo.fileName); @@ -462,13 +457,7 @@ export class FaaSInvokePlugin extends BasePlugin { if (runtime) { this.core.debug('Have Runtime'); invoke = async (...args) => { - let triggerMap; - if (platform === 'aliyun') { - triggerMap = FCTrigger; - } else if (platform === 'tencent') { - triggerMap = SCFTrigger; - } - const trigger = this.getTrigger(triggerMap, args); + const trigger = await this.getTriggerInfo(args); await runtime.start(); this.core.debug('Invoke', trigger); const result = await runtime.invoke(...trigger); @@ -482,6 +471,17 @@ export class FaaSInvokePlugin extends BasePlugin { this.invokeFun = invoke; } + async getTriggerInfo(args) { + const platform = this.getPlatform(); + let triggerMap; + if (platform === 'aliyun') { + triggerMap = FCTrigger; + } else if (platform === 'tencent') { + triggerMap = SCFTrigger; + } + return this.getTrigger(triggerMap, args); + } + async callInvoke() { const resultType = this.options.resultType; this.core.debug('ResultType', resultType); @@ -549,6 +549,7 @@ export class FaaSInvokePlugin extends BasePlugin { return 'tencent'; } } + return provider; } getFunctionInfo() { @@ -600,4 +601,11 @@ export class FaaSInvokePlugin extends BasePlugin { // eslint-disable-next-line node/no-deprecated-api return !!require.extensions['.ts']; } + + getPlatformPath(p) { + if (type() === 'Windows_NT') { + return p.replace(/\\/g, '\\\\'); + } + return p; + } } diff --git a/packages/faas-cli-plugin-package/src/index.ts b/packages/faas-cli-plugin-package/src/index.ts index f3b0090f..0594c08c 100644 --- a/packages/faas-cli-plugin-package/src/index.ts +++ b/packages/faas-cli-plugin-package/src/index.ts @@ -519,6 +519,12 @@ export class PackagePlugin extends BasePlugin { // } this.core.cli.log('Aggregation Deploy'); + + // use picomatch to match url + if (!this.core.service.globalDependencies) { + this.core.service.globalDependencies = {}; + } + this.core.service.globalDependencies['picomatch'] = '*'; const allAggregationPaths = []; let allFuncNames = Object.keys(this.core.service.functions); for (const aggregationName in this.core.service.aggregation) { diff --git a/packages/faas-cli-plugin-package/test/fixtures/aggregation/f.yml b/packages/faas-cli-plugin-package/test/fixtures/aggregation/f.yml index f67847e1..717263d7 100644 --- a/packages/faas-cli-plugin-package/test/fixtures/aggregation/f.yml +++ b/packages/faas-cli-plugin-package/test/fixtures/aggregation/f.yml @@ -22,6 +22,12 @@ functions: - http: method: get path: /api/3 + apiall: + handler: apiall.handler + events: + - http: + method: get + path: /api/* render: handler: render.handler events: @@ -55,7 +61,7 @@ functions: custom: customDomain: - domainName: 'aggregation.exanple.com' + domainName: 'fctest.iam.gy' aggregation: api: diff --git a/packages/faas-cli-plugin-package/test/fixtures/aggregation/src/index.ts b/packages/faas-cli-plugin-package/test/fixtures/aggregation/src/index.ts index a69b5ff1..1d5c6d96 100644 --- a/packages/faas-cli-plugin-package/test/fixtures/aggregation/src/index.ts +++ b/packages/faas-cli-plugin-package/test/fixtures/aggregation/src/index.ts @@ -1,13 +1,58 @@ import { FaaSContext, func, inject, provide } from '@midwayjs/faas'; @provide() -@func('index.handler') export class HelloService { @inject() ctx: FaaSContext; // context + @func('index.handler') async handler(event, obj = {}) { return 'hello world'; } + + @func('apiall.handler') + async apiall(event, obj = {}) { + return 'apiall:' + this.ctx.path; + } + + @func('api1.handler') + async api1(event, obj = {}) { + return 'api1:' + this.ctx.path;; + } + + @func('api2.handler') + async api2(event, obj = {}) { + return 'api2:' + this.ctx.path;; + } + + @func('api3.handler') + async api3(event, obj = {}) { + return 'api3:' + this.ctx.path;; + } + + @func('render.handler') + async render(event, obj = {}) { + return 'render:' + this.ctx.path;; + } + + @func('render1.handler') + async render1(event, obj = {}) { + return 'render1:' + this.ctx.path;; + } + + @func('render2.handler') + async render2(event, obj = {}) { + return 'render2:' + this.ctx.path;; + } + + @func('normal1.handler') + async normal1(event, obj = {}) { + return 'normal1:' + this.ctx.path;; + } + + @func('normal2.handler') + async normal2(event, obj = {}) { + return 'normal2:' + this.ctx.path;; + } } diff --git a/packages/serverless-spec-builder/src/wrapper.ts b/packages/serverless-spec-builder/src/wrapper.ts index de46cf45..96d10cd6 100644 --- a/packages/serverless-spec-builder/src/wrapper.ts +++ b/packages/serverless-spec-builder/src/wrapper.ts @@ -2,7 +2,7 @@ import { join } from 'path'; import { writeFileSync, existsSync } from 'fs'; import { render } from 'ejs'; import { getLayers } from './utils'; -export const wrapperContent = `const { FaaSStarter } = require('@midwayjs/faas'); +export const wrapperContent = `const { FaaSStarter } = require('<%=faasModName %>'); const { asyncWrapper, start } = require('<%=starter %>'); <% layerDeps.forEach(function(layer){ %>const <%=layer.name%> = require('<%=layer.path%>'); <% }); %> @@ -34,24 +34,23 @@ exports.<%=handlerData.name%> = asyncWrapper(async (...args) => { <% if (handlerData.handler) { %> return runtime.asyncEvent(starter.handleInvokeWrapper('<%=handlerData.handler%>'))(...args); <% } else { %> + const picomatch = require('picomatch'); const allHandlers = <%-JSON.stringify(handlerData.handlers)%>; return runtime.asyncEvent(async (ctx) => { let handler = null; let ctxPath = ctx && ctx.path || ''; if (ctxPath) { handler = allHandlers.find(handler => { - return ctxPath.indexOf(handler.path) === 0; + return picomatch.isMatch(ctxPath, handler.router) }); } - if (!handler) { - handler = allHandlers[allHandlers.length - 1]; - } - if (handler) { return starter.handleInvokeWrapper(handler.handler)(ctx); } - return 'unhandler path: ' + ctxPath + '; handlerInfo: ' + JSON.stringify(allHandlers); + ctx.status = 404; + ctx.set('Content-Type', 'text/html'); + return '

404 Page Not Found


Request path: ' + ctxPath + '
Powered by Midway
'; })(...args); <% } %> }); @@ -65,6 +64,7 @@ export function writeWrapper(options: { starter: string; cover?: boolean; loadDirectory?: string[]; + faasModName?: string; }) { const { service, @@ -72,6 +72,7 @@ export function writeWrapper(options: { starter, baseDir, cover, + faasModName, loadDirectory = [], } = options; const files = {}; @@ -114,6 +115,7 @@ export function writeWrapper(options: { const layers = getLayers(service.layers, ...files[file].originLayers); const content = render(wrapperContent, { starter, + faasModName: faasModName || '@midwayjs/faas', loadDirectory, handlers: files[file].handlers, ...layers, @@ -128,18 +130,17 @@ export function formetAggregationHandlers(handlers) { } return handlers .map(handler => { - const path = handler.path.replace(/\**$/, ''); return { handler: handler.handler, - path, - level: path.split('/').length - 1, + router: handler.path.replace(/\*/g, '**'), // picomatch use ** + pureRouter: handler.path.replace(/\**$/, ''), + level: handler.path.split('/').length - 1, }; }) .sort((handlerA, handlerB) => { - const levelDiff = handlerB.level - handlerA.level; - if (levelDiff === 0) { - return handlerB.path.length - handlerA.path.length; + if (handlerA.pureRouter === handlerB.pureRouter) { + return handlerA.router.length - handlerB.router.length; } - return levelDiff; + return handlerB.level - handlerA.level; }); } diff --git a/packages/serverless-spec-builder/test/fixtures/wrapper/aggre.js b/packages/serverless-spec-builder/test/fixtures/wrapper/aggre.js index bba6a5d6..0c80d67c 100644 --- a/packages/serverless-spec-builder/test/fixtures/wrapper/aggre.js +++ b/packages/serverless-spec-builder/test/fixtures/wrapper/aggre.js @@ -10,7 +10,7 @@ const initializeMethod = async (initializeContext = {}) => { runtime = await start({ layers: [] }); - starter = new FaaSStarter({ baseDir: __dirname, initializeContext }); + starter = new FaaSStarter({ baseDir: __dirname, initializeContext, applicationAdapter: runtime }); await starter.start(); inited = true; @@ -26,20 +26,17 @@ exports.handler = asyncWrapper(async (...args) => { await initializeMethod(); } - const allHandlers = [{"handler":"index.handler","path":"/api/test","level":2},{"handler":"render.handler","path":"/","level":1}]; + const picomatch = require('picomatch'); + const allHandlers = [{"handler":"index.handler","router":"/api/test","pureRouter":"/api/test","level":2},{"handler":"render.handler","router":"/*","pureRouter":"/","level":1}]; return runtime.asyncEvent(async (ctx) => { let handler = null; let ctxPath = ctx && ctx.path || ''; if (ctxPath) { handler = allHandlers.find(handler => { - return ctxPath.indexOf(handler.path) === 0; + return picomatch.isMatch(ctxPath, handler.router) }); } - if (!handler) { - handler = allHandlers[allHandlers.length - 1]; - } - if (handler) { return starter.handleInvokeWrapper(handler.handler)(ctx); } diff --git a/packages/serverless-spec-builder/test/fixtures/wrapper/index.js b/packages/serverless-spec-builder/test/fixtures/wrapper/index.js index 9642a4a8..a3fa8c0b 100644 --- a/packages/serverless-spec-builder/test/fixtures/wrapper/index.js +++ b/packages/serverless-spec-builder/test/fixtures/wrapper/index.js @@ -10,7 +10,7 @@ const initializeMethod = async (initializeContext = {}) => { runtime = await start({ layers: [] }); - starter = new FaaSStarter({ baseDir: __dirname, initializeContext }); + starter = new FaaSStarter({ baseDir: __dirname, initializeContext, applicationAdapter: runtime }); await starter.start(); inited = true; diff --git a/packages/serverless-spec-builder/test/fixtures/wrapper/render.js b/packages/serverless-spec-builder/test/fixtures/wrapper/render.js index cd8a9f77..86715b8f 100644 --- a/packages/serverless-spec-builder/test/fixtures/wrapper/render.js +++ b/packages/serverless-spec-builder/test/fixtures/wrapper/render.js @@ -10,7 +10,7 @@ const initializeMethod = async (initializeContext = {}) => { runtime = await start({ layers: [] }); - starter = new FaaSStarter({ baseDir: __dirname, initializeContext }); + starter = new FaaSStarter({ baseDir: __dirname, initializeContext, applicationAdapter: runtime }); await starter.start(); inited = true;