Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: throw error when router duplicate #1023

Merged
merged 2 commits into from
May 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 24 additions & 6 deletions packages/core/src/util/webRouterCollector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ export class WebRouterCollector {
} as FaaSMetadata.HTTPTriggerOptions;
}

this.routes.get(prefix).push(data);
this.checkDuplicateAndPush(prefix, data);
}
}
}
Expand Down Expand Up @@ -265,7 +265,7 @@ export class WebRouterCollector {
module,
webRouter['methodName']
) || [];
// 新 http/apigateway 函数
// 新 http/api gateway 函数
const data: RouterInfo = {
prefix,
routerName: '',
Expand All @@ -287,11 +287,11 @@ export class WebRouterCollector {
data.functionTriggerName = webRouter['type'];
data.functionTriggerMetadata = webRouter['metadata'];
}
this.routes.get(prefix).push(data);
this.checkDuplicateAndPush(prefix, data);
} else {
if (functionMeta) {
// 其他类型的函数
this.routes.get(prefix).push({
this.checkDuplicateAndPush(prefix, {
prefix,
routerName: '',
url: '',
Expand Down Expand Up @@ -342,11 +342,11 @@ export class WebRouterCollector {
};
}
// 老函数的 http
this.routes.get(prefix).push(data);
this.checkDuplicateAndPush(prefix, data);
} else {
if (functionMeta) {
// 非 http
this.routes.get(prefix).push({
this.checkDuplicateAndPush(prefix, {
prefix,
routerName: '',
url: '',
Expand Down Expand Up @@ -464,4 +464,22 @@ export class WebRouterCollector {
}
return routeArr;
}

private checkDuplicateAndPush(prefix, routerInfo: RouterInfo) {
const prefixList = this.routes.get(prefix);
const matched = prefixList.filter(item => {
return (
routerInfo.url &&
routerInfo.requestMethod &&
item.url === routerInfo.url &&
item.requestMethod === routerInfo.requestMethod
);
});
if (matched && matched.length) {
throw new Error(
`Duplicate router "${routerInfo.requestMethod} ${routerInfo.url}" at "${matched[0].handlerName}" and "${routerInfo.handlerName}"`
);
}
prefixList.push(routerInfo);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "ali-demo"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const customKey = 'hello';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// load when NODE_ENV=production
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Configuration } from '@midwayjs/decorator';
import { ILifeCycle } from '@midwayjs/core';
import { join } from 'path';

@Configuration({
importConfigs: [join(__dirname, './config/')],
})
export class ContainerLifeCycle implements ILifeCycle {
async onReady() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Inject, Provide, Query, ServerlessTrigger, ServerlessTriggerType, } from '@midwayjs/decorator';

@Provide()
export class HelloAliyunService {
@Inject()
ctx: any;

@ServerlessTrigger(ServerlessTriggerType.EVENT)
async handleEvent(event: any) {
return event;
}

@ServerlessTrigger(ServerlessTriggerType.API_GATEWAY, {
path: '/api_gateway_aliyun',
method: 'post',
})
@ServerlessTrigger(ServerlessTriggerType.API_GATEWAY, {
path: '/api_another',
method: 'post',
})
async handleAPIGatewayEvent(@Query() name) {
return `hello ${name}`;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {
Provide,
Inject,
ServerlessTrigger,
ServerlessTriggerType,
Body,
} from '@midwayjs/decorator';

@Provide()
export class HelloTencentService {
@Inject()
ctx: any;

@ServerlessTrigger(ServerlessTriggerType.API_GATEWAY, {
path: '/api_gateway_aliyun',
method: 'post',
})
async handleAPIGatewayEvent(@Body() name) {
return `hello ${name}`;
}
}
4 changes: 1 addition & 3 deletions packages/core/test/services/configService.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import assert = require('assert');
import { resolve, join } from 'path';
import { MidwayContainer } from '../../src';
import { MidwayConfigService } from '../../src/service/configService';
import { MidwayContainer, MidwayConfigService, MidwayInformationService } from '../../src';
import * as mm from 'mm';
import { MidwayInformationService } from '../../dist/service/informationService';

describe('/test/services/configService.test.ts', () => {
const informationService = new MidwayInformationService({
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { ServerlessTriggerCollector } from '../src';
import { ServerlessTriggerCollector } from '../../src';
import { join } from 'path';
import { clearAllModule } from '@midwayjs/decorator';
import { clearContainerCache } from '../src';
import { matchObjectPropertyInArray } from './util';
import { clearContainerCache } from '../../src';
import { matchObjectPropertyInArray } from '../util';

describe('/test/triggerCollector.test.ts', function () {
describe('/test/util/triggerCollector.test.ts', function () {

it('should test with function router', async () => {
clearAllModule();
clearContainerCache();
const collector = new ServerlessTriggerCollector(join(__dirname, './fixtures/base-app-func-router/src'));
const collector = new ServerlessTriggerCollector(join(__dirname, '../fixtures/base-app-func-router/src'));
const result = await collector.getFunctionList();
expect(matchObjectPropertyInArray(result, {
"controllerId": "apiController",
Expand Down Expand Up @@ -187,10 +187,8 @@ describe('/test/triggerCollector.test.ts', function () {
it('should test with serverless trigger', async () => {
clearAllModule();
clearContainerCache();
const collector = new ServerlessTriggerCollector(join(__dirname, './fixtures/app-with-serverless-trigger/src'));
const collector = new ServerlessTriggerCollector(join(__dirname, '../fixtures/app-with-serverless-trigger/src'));
const result = await collector.getFunctionList();
// console.log(result);
console.log('3');
expect(matchObjectPropertyInArray(result, {
functionName: 'helloAliyunService-handleTimerEvent',
functionTriggerName: 'timer',
Expand All @@ -203,4 +201,11 @@ describe('/test/triggerCollector.test.ts', function () {
})).toBeTruthy();
});

it('should test duplicate router', async () => {
clearAllModule();
clearContainerCache();
const collector = new ServerlessTriggerCollector(join(__dirname, '../fixtures/app-with-duplicate-router/src'));
await expect(collector.getFunctionList()).rejects.toThrow('Duplicate router')
});

});
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import * as assert from 'assert';
import { join } from 'path';
import { safeRequire, safelyGet, joinURLPath } from '../src/util';
import { PathFileUtil } from '../src/';
import { StaticConfigLoader } from '../src/util/staticConfig';
import { safeRequire, safelyGet, joinURLPath } from '../../src/util';
import { PathFileUtil } from '../../src';
import { StaticConfigLoader } from '../../src/util/staticConfig';

describe('/test/util.test.ts', () => {
describe('/test/util/util.test.ts', () => {

it('should test safeRequire', () => {
// assert(safeRequire('@ali/abc') === undefined);
// assert(safeRequire('url') === require('url'));
//
// assert.strictEqual(safeRequire(join(__dirname, './fixtures/dir/ok')), require('./fixtures/dir/ok'));
// assert.strictEqual(safeRequire(join(__dirname, './fixtures/foo')), undefined);
assert.strictEqual(safeRequire(join(__dirname, './fixtures/dir/nok.js')), undefined);
assert.strictEqual(safeRequire('./fixtures/dir/bbb/nok.js'), undefined);
// assert.strictEqual(safeRequire(join(__dirname, '../fixtures/dir/ok')), require('./fixtures/dir/ok'));
// assert.strictEqual(safeRequire(join(__dirname, '../fixtures/foo')), undefined);
assert.strictEqual(safeRequire(join(__dirname, '../fixtures/dir/nok.js')), undefined);
assert.strictEqual(safeRequire('../fixtures/dir/bbb/nok.js'), undefined);
});

it('should safeGet be ok', () => {
Expand All @@ -25,13 +25,13 @@ describe('/test/util.test.ts', () => {
});

it('should load static config from app', async () => {
let loader = new StaticConfigLoader(join(__dirname, '/fixtures/app-with-configuration-static-config-loader/base-app-decorator'), 'local');
let loader = new StaticConfigLoader(join(__dirname, '../fixtures/app-with-configuration-static-config-loader/base-app-decorator'), 'local');
let configText = await loader.getSerializeConfig();
expect(configText['helloworld']).toEqual(234);
expect(configText['ok']['text']).toEqual('ok3');
expect(configText['mock']['b']).toEqual('local');

loader = new StaticConfigLoader(join(__dirname, '/fixtures/app-with-configuration-static-config-loader/base-app-decorator'), 'production');
loader = new StaticConfigLoader(join(__dirname, '../fixtures/app-with-configuration-static-config-loader/base-app-decorator'), 'production');
configText = await loader.getSerializeConfig();
expect(configText['helloworld']).toEqual(123);
expect(configText['ok']['text']).toEqual('ok');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { WebRouterCollector } from '../src';
import { WebRouterCollector } from '../../src';
import { join } from 'path';
import { clearAllModule } from '@midwayjs/decorator';
import { clearContainerCache } from '../src';
import { matchObjectPropertyInArray } from './util';
import { clearContainerCache } from '../../src';
import { matchObjectPropertyInArray } from '../util';

describe('/test/webRouterCollector.test.ts', function () {
describe('/test/util/webRouterCollector.test.ts', function () {

it('should test generate router', async () => {
const collector = new WebRouterCollector(join(__dirname, './fixtures/base-app-controller'));
const collector = new WebRouterCollector(join(__dirname, '../fixtures/base-app-controller'));
const result = await collector.getRouterTable();
expect(result.size).toEqual(3);

Expand All @@ -16,15 +16,15 @@ describe('/test/webRouterCollector.test.ts', function () {
});

it('should test generate flatten router', async () => {
const collector = new WebRouterCollector(join(__dirname, './fixtures/base-app-controller'));
const collector = new WebRouterCollector(join(__dirname, '../fixtures/base-app-controller'));
const result = await collector.getFlattenRouterTable();
expect(result.length > 0).toBeTruthy();
});

it('should test with function router', async () => {
clearAllModule();
clearContainerCache();
const collector = new WebRouterCollector(join(__dirname, './fixtures/base-app-func-router'), { includeFunctionRouter: true});
const collector = new WebRouterCollector(join(__dirname, '../fixtures/base-app-func-router'), { includeFunctionRouter: true});
const result = await collector.getFlattenRouterTable();
expect(result.length).toEqual(6);
expect(matchObjectPropertyInArray(result, {
Expand Down Expand Up @@ -111,4 +111,5 @@ describe('/test/webRouterCollector.test.ts', function () {
expect(result2[1].url).toEqual('/:page/page');
expect(result2[2].url).toEqual('/:category/:slug');
});

});