UNPKG

wistroni40-bnft

Version:

Benefit platform parameters publish job template

260 lines (246 loc) 6.59 kB
/** * 專案名稱: @wistroni40/bnft * 部門代號: ML8100 * 檔案說明: API服務器 * @CREATE Mon Feb 08 2021 下午2:56:08 * @author Steve Y Lin * @contact Steve_Y_Lin@wistron.com #1342 * ----------------------------------------------------------------------------- * @NOTE */ import * as bodyParser from 'body-parser'; import * as express from 'express'; import * as fs from 'fs'; import * as http from 'http'; import { BnftTemplate } from 'src/bnft'; import * as swaggerUi from 'swagger-ui-express'; import { Log4js } from './../logger'; import { SWAGGER_DOC } from './swagger'; /** * API服務器 */ export class Server { /** * 日誌 */ private readonly logger = new Log4js('api'); /** * API Server */ private readonly server = express(); /** * API */ private api?: http.Server; /** * 效益計算Job */ private benefit = new Map<string, BnftTemplate>(); /** * 單一實例 */ public static instance = new Server(); private constructor() { // 啟動API Server this.start(); } /** * 取得效益計算Job清單 * * @method private * @return 回傳效益計算Job清單 */ private getBenefitList(): BnftTemplate[] { return Array.from(this.benefit).map(benefit => benefit[1]); } /** * 取得效益Key名稱 * * @method private * @param req 請求 * @return 回傳效益Key名稱 */ private getBenefitKey(req: express.Request): string { const systemId = req.query.systemId; const typeId = req.query.typeId; return `${systemId}.${typeId}`; } /** * 重新上拋所有效益 * * @method private * @param req 請求 * @param res 回應 */ private async sendBenefit( req: express.Request, res: express.Response, ): Promise<void> { const timestamp = new Date(parseInt(req.query.timestamp as string, 10)); timestamp.setDate(timestamp.getDate() + 1); await Promise.all( this.getBenefitList().map(benefit => benefit.execute(timestamp).toPromise(), ), ); res.send(true); } /** * 重新上拋特定效益 * * @method private * @param req 請求 * @param res 回應 */ private async sendSpecificBenefit( req: express.Request, res: express.Response, ): Promise<void> { const key = this.getBenefitKey(req); const timestamp = new Date(parseInt(req.query.timestamp as string, 10)); timestamp.setDate(timestamp.getDate() + 1); const benefit = this.benefit.get(key); if (benefit) { await benefit.execute(timestamp).toPromise(); res.send(true); } else { res.send(null); } } /** * 重新上拋特定時間區間內的所有效益 * * @method private * @param req 請求 * @param res 會應 */ private async sendBenefitByTimeGroup( req: express.Request, res: express.Response, ): Promise<void> { if (Array.isArray(req.body) && req.body.length > 0) { await Promise.all( req.body.map(async date => { const timestamp = new Date(parseInt(date, 10)); timestamp.setDate(timestamp.getDate() + 1); await Promise.all( this.getBenefitList().map(benefit => benefit.execute(timestamp).toPromise(), ), ); }), ); res.send(true); } else { res.send('body format error'); } } /** * 重新上拋特定時間區間內的特定效益 * * @method private * @param req 請求 * @param res 會應 */ public async sendSpecificBenefitByTimeGroup( req: express.Request, res: express.Response, ): Promise<void> { if (Array.isArray(req.body) && req.body.length > 0) { const key = this.getBenefitKey(req); await Promise.all( req.body.map(async date => { const timestamp = new Date(parseInt(date, 10)); timestamp.setDate(timestamp.getDate() + 1); const benefit = await this.benefit.get(key); if (benefit) { await benefit.execute(timestamp).toPromise(); } }), ); res.send(true); } else { res.send('body format error'); } } /** * 重拋上拋失敗的效益 * * @method private * @param req 請求 * @param res 會應 */ private async sendBackupBenefit( req: express.Request, res: express.Response, ): Promise<void> { const files = fs.readdirSync('backup'); await Promise.all( files.map(file => { const benefit = fs.readFileSync(`backup/${file}`, { encoding: 'utf8' }); try { if (this.getBenefitList().length > 0) { this.getBenefitList()[0].send(JSON.parse(benefit)); fs.unlinkSync(`backup/${file}`); } } catch (error) { this.logger.warn('Send backup benefit failed'); this.logger.warn(benefit); } return JSON.parse(benefit); }), ); res.send(true); } /** * 啟動API Server * * @method public * @return 回傳物件本身 */ public start(): Server { const port = 3000; this.server.use(bodyParser.json()); this.server.post('/benefit/send', this.sendBenefit.bind(this)); this.server.post( '/specific/benefit/send', this.sendSpecificBenefit.bind(this), ); this.server.post( '/benefit/send/timestamps', this.sendBenefitByTimeGroup.bind(this), ); this.server.post( '/specific/benefit/send/timestamps', this.sendSpecificBenefitByTimeGroup.bind(this), ); this.server.post('/benefit/backup', this.sendBackupBenefit.bind(this)); this.server.use('/', swaggerUi.serve, swaggerUi.setup(SWAGGER_DOC)); this.logger.info(`Listen api port ${port}`); this.api = this.server.listen(port); return this; } /** * 終止API Server * * @method public * @return 回傳物件本身 */ public stop(): Server { if (this.api) { this.api.close(); this.logger.warn('api close'); } return this; } /** * 註冊效益計算Job * * @method public * @param benefit 效益計算Job */ public register(benefit: BnftTemplate): void { const key = `${benefit.config.systemId}.${benefit.config.typeId}`; this.benefit.set(key, benefit); } }