feat: support domain name

This commit is contained in:
wss-git 2021-07-16 17:15:29 +08:00
parent 054d259f8f
commit 9c45edfdb5
5 changed files with 77 additions and 56 deletions

View File

@ -33,6 +33,7 @@
"@alicloud/fc2": "^2.2.2", "@alicloud/fc2": "^2.2.2",
"@serverless-devs/core": "^0.0.*", "@serverless-devs/core": "^0.0.*",
"fs-extra": "^10.0.0", "fs-extra": "^10.0.0",
"got": "^11.8.2",
"i18n": "^0.13.2", "i18n": "^0.13.2",
"lodash.get": "^4.4.2", "lodash.get": "^4.4.2",
"readline": "^1.3.0" "readline": "^1.3.0"

View File

@ -13,13 +13,11 @@ export default [
{ {
name: 'invocation-type', name: 'invocation-type',
description: 'Invocation type: optional value "async"|"sync", default value "sync" (default: "sync")', description: 'Invocation type: optional value "async"|"sync", default value "sync" (default: "sync")',
alias: 't',
type: String, type: String,
}, },
{ {
name: 'event', name: 'event',
description: 'Event data (strings) passed to the function during invocation (default: "").Http function format refers to [https://github.com/devsapp/fc-remote-invoke#特别说明]', description: 'Event data (strings) passed to the function during invocation (default: "").Http function format refers to [https://github.com/devsapp/fc-remote-invoke#特别说明]',
alias: 'e',
type: String, type: String,
}, },
{ {
@ -31,7 +29,6 @@ export default [
{ {
name: 'event-stdin', name: 'event-stdin',
description: 'Read from standard input, to support script pipeline.Http function format refers to [https://github.com/devsapp/fc-remote-invoke#特别说明]', description: 'Read from standard input, to support script pipeline.Http function format refers to [https://github.com/devsapp/fc-remote-invoke#特别说明]',
alias: 's',
type: Boolean, type: Boolean,
}, },
{ {
@ -49,6 +46,11 @@ export default [
description: 'Specify function name in cli mode', description: 'Specify function name in cli mode',
type: String, type: String,
}, },
{
name: 'domain-name',
description: 'Specify custom domain name in cli mode',
type: String,
},
], ],
}, },
{ {

View File

@ -15,21 +15,17 @@ export default class FcRemoteInvoke {
} }
async handlerInputs(inputs: InputProps): Promise<any> { async handlerInputs(inputs: InputProps): Promise<any> {
const credentials: ICredentials = await core.getCredential(inputs?.project?.access);
// 去除 args 的行首以及行尾的空格 // 去除 args 的行首以及行尾的空格
const args: string = (inputs?.args || '').replace(/(^\s*)|(\s*$)/g, ''); const args: string = (inputs?.args || '').replace(/(^\s*)|(\s*$)/g, '');
logger.debug(`input args: ${args}`); logger.debug(`input args: ${args}`);
const parsedArgs: {[key: string]: any} = core.commandParse({ args }, { const parsedArgs: {[key: string]: any} = core.commandParse({ args }, {
boolean: ['help', 'event-stdin'], boolean: ['help', 'event-stdin'],
string: ['invocation-type', 'event', 'event-file', 'region', 'service-name', 'function-name', 'qualifier'], string: ['invocation-type', 'event', 'event-file', 'region', 'domain-name','service-name', 'function-name', 'qualifier'],
alias: { alias: {
'help': 'h', 'help': 'h',
'event': 'e', 'event': 'e',
'invocation-type': 't',
'event-file': 'f', 'event-file': 'f',
'event-stdin': 's',
} }
}); });
@ -37,18 +33,17 @@ export default class FcRemoteInvoke {
logger.debug(`command parse: ${JSON.stringify(argsData)}`); logger.debug(`command parse: ${JSON.stringify(argsData)}`);
if (argsData.help) { if (argsData.help) {
return { return {
credentials, credentials: inputs.credentials,
isHelp: true, isHelp: true,
}; };
} }
// await StdoutFormatter.initStdout();
const { const {
e: event, e: event,
f: eventFile, f: eventFile,
s: eventStdin, 'event-file': eventStdin,
t: invocationType = 'sync', 'invocation-type': invocationType = 'sync',
'domain-name': domainName,
} = argsData; } = argsData;
const eventPayload = { event, eventFile, eventStdin }; const eventPayload = { event, eventFile, eventStdin };
// @ts-ignore: 判断三个值有几个真 // @ts-ignore: 判断三个值有几个真
@ -63,30 +58,27 @@ export default class FcRemoteInvoke {
if (!['sync', 'async'].includes(invocationType)) { if (!['sync', 'async'].includes(invocationType)) {
throw new Error('invocation-type enum value sync, async.'); throw new Error('invocation-type enum value sync, async.');
} }
if (!domainName && !inputs?.credentials) {
inputs.credentials = await core.getCredential(inputs?.project?.access);
}
logger.debug(`input props: ${JSON.stringify(inputs.props)}`); logger.debug(`input props: ${JSON.stringify(inputs.props)}`);
let props: IProperties = { const props: IProperties = {
region: argsData.region, region: argsData.region || inputs.props?.region,
serviceName: argsData['service-name'], serviceName: argsData['service-name'] || inputs.props?.serviceName,
functionName: argsData['function-name'], functionName: argsData['function-name'] || inputs.props?.functionName,
domainName: domainName || inputs.props?.domainName,
qualifier: argsData.qualifier || inputs.props?.qualifier,
}; };
logger.debug(`input args props: ${JSON.stringify(props)}`); logger.debug(`input args props: ${JSON.stringify(props)}`);
if (!isProperties(props)) {
props = inputs.props;
}
logger.debug(`props: ${JSON.stringify(props)}`);
if (!isProperties(props)) { if (!isProperties(props)) {
throw new Error('region/serviceName(service-name)/functionName(function-name) can not be empty.'); throw new Error('region/serviceName(service-name)/functionName(function-name) can not be empty.');
} }
props.qualifier = argsData.qualifier || inputs.props?.qualifier;
return { return {
props, props,
credentials, credentials: inputs.credentials,
eventPayload, eventPayload,
isHelp: false, isHelp: false,
invocationType: _.upperFirst(invocationType), invocationType: _.upperFirst(invocationType),
@ -113,7 +105,7 @@ export default class FcRemoteInvoke {
return; return;
} }
const remoteInvoke = new RemoteInvoke(props.region, credentials); const remoteInvoke = new RemoteInvoke(props.region, credentials, props.domainName);
await remoteInvoke.invoke(props, eventPayload, { invocationType }); await remoteInvoke.invoke(props, eventPayload, { invocationType });
} }
} }

View File

@ -26,9 +26,13 @@ export interface IProperties {
serviceName: string; serviceName: string;
functionName: string; functionName: string;
qualifier?: string; qualifier?: string;
domainName?: string;
} }
export function isProperties(args: any): args is IProperties { export function isProperties(args: any): args is IProperties {
return args && args.region && args.serviceName && args.functionName; if (!args) {
return false;
}
return args.domainName || (args.region && args.serviceName && args.functionName) ;
} }
export interface IEventPayload { export interface IEventPayload {

View File

@ -1,4 +1,5 @@
import _ from 'lodash'; import _ from 'lodash';
import got from 'got';
import Client from './client'; import Client from './client';
import { IProperties, IEventPayload } from '../interface/entity'; import { IProperties, IEventPayload } from '../interface/entity';
import Event from './event'; import Event from './event';
@ -8,9 +9,11 @@ export default class RemoteInvoke {
fcClient: any; fcClient: any;
accountId: string; accountId: string;
constructor(region: string, credentials) { constructor(region: string, credentials, domainName) {
this.accountId = credentials.AccountID; if (!domainName) {
this.fcClient = Client.buildFcClient(region, credentials); this.accountId = credentials.AccountID;
this.fcClient = Client.buildFcClient(region, credentials);
}
} }
async invoke (props: IProperties, eventPayload: IEventPayload, { invocationType }) { async invoke (props: IProperties, eventPayload: IEventPayload, { invocationType }) {
@ -21,8 +24,12 @@ export default class RemoteInvoke {
region, region,
serviceName, serviceName,
functionName, functionName,
domainName,
qualifier, qualifier,
} = props; } = props;
if (domainName) {
return this.requestDomain(domainName, event);
}
const httpTriggers = await this.getHttpTrigger(serviceName, functionName) const httpTriggers = await this.getHttpTrigger(serviceName, functionName)
const payload: any = { event, serviceName, functionName, qualifier }; const payload: any = { event, serviceName, functionName, qualifier };
@ -32,17 +39,27 @@ export default class RemoteInvoke {
await this.eventInvoke(payload); await this.eventInvoke(payload);
} else { } else {
payload.region = region; payload.region = region;
try { payload.event = this.getJsonEvent(event);
payload.event = event ? JSON.parse(event) : {};
} catch (ex) {
logger.debug(ex);
throw new Error('handler event error. Example: https://github.com/devsapp/fc-remote-invoke/blob/master/example/http.json');
}
await this.httpInvoke(payload); await this.httpInvoke(payload);
} }
} }
async requestDomain(url: string, event: string) {
const payload = this.getJsonEvent(event);
if (_.isEmpty(payload.headers)) {
payload.headers = {};
}
payload.headers['X-Fc-Log-Type'] = 'Tail';
const { body, headers } = await got(url, payload);
this.showLog(headers['x-fc-log-result']);
logger.log('\nFC Invoke Result:', 'green');
console.log(body);
logger.log('\n');
}
async getHttpTrigger(serviceName, functionName) { async getHttpTrigger(serviceName, functionName) {
const { data } = await this.fcClient.listTriggers(serviceName, functionName); const { data } = await this.fcClient.listTriggers(serviceName, functionName);
logger.debug(`get listTriggers: ${JSON.stringify(data)}`); logger.debug(`get listTriggers: ${JSON.stringify(data)}`);
@ -69,18 +86,10 @@ export default class RemoteInvoke {
'X-Fc-Invocation-Type': invocationType 'X-Fc-Invocation-Type': invocationType
}, qualifier); }, qualifier);
const log = rs.headers['x-fc-log-result']; this.showLog(rs.headers['x-fc-log-result']);
logger.log('\nFC Invoke Result:', 'green');
if (log) { console.log(rs.data);
logger.log('========= FC invoke Logs begin =========', 'yellow'); console.log('\n');
const decodedLog = Buffer.from(log, 'base64');
logger.log(decodedLog.toString());
logger.log('========= FC invoke Logs end =========', 'yellow');
logger.log('\nFC Invoke Result:', 'green');
console.log(rs.data);
console.log('\n');
}
} else { } else {
const { headers } = await this.fcClient.invokeFunction(serviceName, functionName, event, { const { headers } = await this.fcClient.invokeFunction(serviceName, functionName, event, {
'X-Fc-Invocation-Type': invocationType 'X-Fc-Invocation-Type': invocationType
@ -137,13 +146,8 @@ export default class RemoteInvoke {
logger.debug(`end invoke.`); logger.debug(`end invoke.`);
if (resp) { if (resp) {
const log = resp.headers['x-fc-log-result']; this.showLog(resp.headers['x-fc-log-result']);
if (log) {
logger.log('\n========= FC invoke Logs begin =========', 'yellow');
const decodedLog = Buffer.from(log, 'base64')
logger.log(decodedLog.toString())
logger.log('========= FC invoke Logs end =========', 'yellow');
}
logger.log('\nFC Invoke Result:', 'green'); logger.log('\nFC Invoke Result:', 'green');
console.log(resp.data); console.log(resp.data);
console.log('\n'); console.log('\n');
@ -184,4 +188,22 @@ export default class RemoteInvoke {
body: postBody body: postBody
} }
} }
private showLog(log) {
if (log) {
logger.log('========= FC invoke Logs begin =========', 'yellow');
const decodedLog = Buffer.from(log, 'base64');
logger.log(decodedLog.toString());
logger.log('========= FC invoke Logs end =========', 'yellow');
}
}
private getJsonEvent(event: string) {
try {
return event ? JSON.parse(event) : {};
} catch (ex) {
logger.debug(ex);
throw new Error('handler event error. Example: https://github.com/devsapp/fc-remote-invoke/blob/master/example/http.json');
}
}
} }