diff --git a/src/config/transports.js b/src/config/transports.js index c31c5817..8a274fc4 100644 --- a/src/config/transports.js +++ b/src/config/transports.js @@ -1,11 +1,16 @@ const _ = require('lodash'); +const path = require('path'); +const moment = require('moment'); const TransportStream = require('winston-transport'); +const { generateUuid } = require('../helper/agent'); const api = require('../core/api'); class S3FileTransport extends TransportStream { constructor(options = {}, afterLog) { super(options); + this.jobInfo = options.jobInfo; + this.apiKey = options.apiKey; this.filePath = options.filePath; this.signedUrl = options.signedUrl; this.parentLogger = options.logger; @@ -17,7 +22,34 @@ class S3FileTransport extends TransportStream { this.uploadToS3Throttled = _.throttle(this.uploadToS3, this.wait, { trailing: false }); } - uploadToS3() { + async uploadToS3() { + const parsedUrl = new URL(this.signedUrl); + const params = new URLSearchParams(parsedUrl.search); + + const amzDate = params.get('X-Amz-Date'); + const amzExpires = params.get('X-Amz-Expires'); + + const dateFormart = 'YYYYMMDDTHHmmss[Z]'; + const dateExpires = moment.utc(amzDate, dateFormart).toDate(); + dateExpires.setSeconds(dateExpires.getSeconds(), amzExpires * 1000); + + const now = new Date(); + if (dateExpires < now) { + const requestGetUploadInfo = async () => { + const response = await api.getUploadInfo(this.jobInfo.projectId, this.apiKey); + if (!response || !response.body) { + return null; + } + const { body } = response; + const { uploadUrl } = body; + this.signedUrl = uploadUrl; + const batch = generateUuid(); + const fileName = path.basename(this.filePath); + return api.saveJobLog(this.jobInfo, batch, fileName, this.apiKey); + }; + await requestGetUploadInfo(); + } + return api .uploadFile(this.signedUrl, this.filePath) .then(() => this.afterLog && this.afterLog()) diff --git a/src/service/agent.js b/src/service/agent.js index 06fb80cf..7eb77844 100644 --- a/src/service/agent.js +++ b/src/service/agent.js @@ -156,6 +156,8 @@ async function executeJob(jobInfo, keepFiles) { jLogger.add( new S3FileTransport( { + jobInfo, + apiKey, filePath: logFilePath, signedUrl: jobInfo.uploadUrl, logger,