UNPKG

deep-package-manager

Version:
293 lines (240 loc) 6.13 kB
/** * Created by AlexanderC on 11/24/15. */ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.AbstractDriver = undefined; var _deepCore = require('deep-core'); var _deepCore2 = _interopRequireDefault(_deepCore); var _WaitFor = require('../../Helpers/WaitFor'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class AbstractDriver extends _deepCore2.default.OOP.Interface { /** * * @param {Object} awsService * @param {String} baseHash * @param {Boolean} debug */ constructor(awsService, baseHash, debug = false) { super(['_removeResource', 'service']); this._awsService = awsService; this._baseHash = baseHash; this._debug = debug; this._stack = []; this._retries = AbstractDriver.DEFAULT_RETRIES; } /** * @param {Number} retries */ set retries(retries) { this._retries = retries; } /** * @returns {Number} */ get retries() { return this._retries; } /** * @returns {String} */ get baseHash() { return this._baseHash; } /** * @param {Function} cb * @param {Object} rawResourcesObj * @returns {AbstractDriver} */ execute(cb, rawResourcesObj) { let resources = this._extractResources(rawResourcesObj); this._log(`Starting undeploy for ${this.service()}`); this._execute(error => { let removedResources = error ? null : this.extractResetStack; if (removedResources && removedResources.length > 0) { this._log(`There are ${removedResources.length} resources removed from ${this.service()}`); } else if (!error) { this._log(`No resources to remove for ${this.service()}`); } else { this._logError(`An error occurred when working with ${this.service()}: ${error}`); } cb(error, removedResources); }, resources); return this; } /** * @param {Function} cb * @param {Object} resources */ _execute(cb, resources) { let wait = new _WaitFor.WaitFor(); let resourcesRemaining = resources.length; let resourceIds = []; wait.push(() => { return resourcesRemaining <= 0; }); for (let i in resources) { if (!resources.hasOwnProperty(i)) { continue; } let resourceInfo = resources[i]; let resourceId = resourceInfo.id; let resourceData = resourceInfo.data; // manage duplicate resources if (resourceIds.indexOf(resourceId) !== -1) { resourcesRemaining--; continue; } resourceIds.push(resourceId); setTimeout(() => { this._removeResourceRetryable(resourceId, resourceData, error => { resourcesRemaining--; if (!error) { this._pushStack(resourceId); return; } this._logError(`Error while removing resource #${resourceId}: ${error}`); }); }, i * 200); } wait.ready(() => { cb(null); }); } /** * @param {String} resourceId * @param {Object|String} resourceData * @param {Function} cb * @param {Number|null} retries * @private */ _removeResourceRetryable(resourceId, resourceData, cb, retries = null) { retries = retries === null ? this._retries : retries; this._removeResource(resourceId, resourceData, error => { if (error) { if (retries <= 0) { cb(error); return; } let retriesDelay = parseInt(10000 / retries); this._logError(`Retrying undeploy on ${this.service()}:${resourceId} in ${retriesDelay} ms due to the error: ${error}`); setTimeout(() => { this._removeResourceRetryable(resourceId, resourceData, cb, retries - 1); }, retriesDelay); return; } cb(null); }); } /** * @param {String} resourceId * @private */ _pushStack(resourceId) { this._log(`Removing resource #${resourceId} from ${this.service()}`); this._stack.push(resourceId); } /** * @returns {Object} */ get extractResetStack() { let stack = this._stack; this._stack = []; return stack; } /** * @returns {Object} */ get awsService() { return this._awsService; } /** * @returns {Boolean} */ get debug() { return this._debug; } /** * @param {Boolean} state */ set debug(state) { this._debug = state; } /** * @param {Object} service * @param {String} credentials */ static injectServiceCredentials(service, credentials) { Object.defineProperty(service, AbstractDriver.CREDENTIALS_KEY, { value: credentials, enumerable: false, configurable: true, writable: false }); } /** * @returns {String} */ static get CREDENTIALS_KEY() { return '__deep_undeploy_cred__'; } /** * @returns {Object} * @private */ get _credentials() { if (this._awsService.hasOwnProperty(AbstractDriver.CREDENTIALS_KEY)) { return this._awsService[AbstractDriver.CREDENTIALS_KEY]; } return null; } /** * @param {Object} rawResourcesObj * @returns {Object[]} */ _extractResources(rawResourcesObj) { let service = this.service(); let resourcesVector = []; if (rawResourcesObj.hasOwnProperty(service)) { for (let resourceId in rawResourcesObj[service]) { if (!rawResourcesObj[service].hasOwnProperty(resourceId)) { continue; } let resourceData = rawResourcesObj[service][resourceId]; resourcesVector.push({ id: resourceId, data: resourceData }); } } return resourcesVector; } /** * @returns {Number} * @constructor */ static get DEFAULT_RETRIES() { return 3; } /** * @todo: abstract this? * * @param {*} args * @private */ _log(...args) { this._debug && console.log(...args); } /** * @todo: abstract this? * * @param {*} args * @private */ _logError(...args) { this._debug && console.error(...args); } } exports.AbstractDriver = AbstractDriver;