@axway/api-builder-runtime
Version:
API Builder Runtime
117 lines (102 loc) • 3.94 kB
JavaScript
const fs = require('fs');
const path = require('path');
const uuid = require('uuid');
const { promisify } = require('util');
const reporterClasses = require('./reporters');
class Billing {
/**
* @param {object} config - subscriptionUsageTracking configuration
* @param {boolean} [config.enabled=false] - Enables subscription usage tracking if true
* @param {string} [config.environment] - The ID for the Amplify platform environment
* that the service will be related to
* @param {string} [config.org] - The platform org GUID that the transactions will be related to
* @param {number} [config.reportInterval=3600] - The interval in seconds at which all
* transactions so far will be reported
* @param {string} [config.platformEnv=production] - The platform environment to report to.
* Must be production or staging
* @param {string} [config.platformURL] - The URL to the platform to report to, if it differs
* from production or staging.
* @param {string[]} [config.reporters=['platform']] - The list of reporters which
* will be used by the service (platform, console)
* @param {number} [config.timeout=10000] = The timeout in miliseconds for sending the report
* to the platform
* @param {object} options - options provided by API Builder
* @param {object} options.logger - the API Builder logger
* @param {string} options.dir - the directory of the service
* @param {string} options.runtimeVersion - the version of API Builder
* @param {string} [options.proxy] - the configured proxy
*/
async init(config, options) {
const { logger, dir, runtimeVersion, proxy } = options;
const {
environment,
org,
platformURL,
reportInterval = 3600,
timeout = 10000,
platformEnv = 'production',
reporters = [ 'platform' ]
} = config;
if (!Array.isArray(reporters) || !reporters.length) {
throw new Error('config.subscriptionUsageTracking.reporters should be an array with at least one reporter type');
}
if (typeof reportInterval !== 'number' || reportInterval < 60) {
throw new Error('config.subscriptionUsageTracking.reportInterval should be at least 60');
}
const session = uuid.v4();
this.logger = logger.getScoped(`[Subscription usage tracking: ${session}]`);
// read package.json
const readFile = promisify(fs.readFile);
const file = path.join(options.dir, 'package.json');
const pkg = JSON.parse(await readFile(file, 'utf8'));
// Ensure there aren't duplicate reporters
const uniqueReporters = [ ...new Set(reporters) ];
// Finally init the reporters
this.reporters = await Promise.all(uniqueReporters.map(async type => {
const Reporter = reporterClasses[type];
if (!Reporter) {
throw new Error(`config.subscriptionUsageTracking.reporters has unknown reporter: ${type}`);
}
const reporter = new Reporter();
await reporter.init({
logger: logger.getScoped(`[${type}-reporter: ${session}]`),
appVersion: pkg.version,
appName: pkg.name,
dir,
org,
timeout,
runtimeVersion,
platformEnv,
platformURL,
environment,
session,
proxy
});
this.logger.trace(`Registered ${type} transaction reporter`);
return reporter;
}));
this.interval = setInterval(() => Promise.all(
this.reporters.map(reporter => reporter.onInterval())
), reportInterval * 1000);
this.logger.info(`Reporting transactions every ${reportInterval}s`);
}
async countTransaction() {
return Promise.all(
this.reporters.map(reporter => reporter.countTransaction())
).catch(err => {
// Never needs to be awaited, so should never reject.
this.logger.error(err);
});
}
async stop() {
clearInterval(this.interval);
return Promise.all(
(this.reporters || []).map(async reporter => {
// flush transactions
await reporter.onInterval();
// no reporter implements stop right now, but if they did it would be here
})
);
}
}
module.exports = Billing;