UNPKG

mvom

Version:

Multivalue Object Mapper

220 lines (201 loc) 7.48 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _path = _interopRequireDefault(require("path")); var _axios = _interopRequireDefault(require("axios")); var _fsExtra = _interopRequireDefault(require("fs-extra")); var _errors = require("./errors"); // #region types // #endregion class DeploymentManager { /** File system path of the UniBasic source code */ static unibasicPath = _path.default.resolve(_path.default.join(__dirname, 'unibasic')); /** MVIS subroutine name */ /** Axios instance */ /** Database account name */ /** Log handler instance used for diagnostic logging */ /** MVIS Admin authorization header */ /** Main file source code name */ constructor(/** URL of the MVIS Admin */ mvisAdminUrl, /** Database account that will be administered will be used against */ account, /** MVIS Admin username */ username, /** MVIS Admin password */ password, /** Request timeout (ms) */ timeout, /** Log handler instance */ logHandler, options) { const { httpAgent, httpsAgent } = options; this.account = account; this.logHandler = logHandler; this.authorization = Buffer.from(`${username}:${password}`).toString('base64'); const url = new URL(mvisAdminUrl); url.pathname = url.pathname.replace(/\/?$/, `/api/`); const baseURL = url.toString(); this.axiosInstance = _axios.default.create({ baseURL, timeout, transitional: { clarifyTimeoutError: true }, ...(httpAgent && { httpAgent }), ...(httpsAgent && { httpsAgent }) }); const mainFileName = _fsExtra.default.readdirSync(DeploymentManager.unibasicPath).find(filename => /^mvom_main@[a-f0-9]{8}\.mvb$/.test(filename)); // e.g. mvom_main@abcdef12.mvb if (mainFileName == null) { throw new Error('DB Server source code repository is corrupted'); } this.mainFileName = mainFileName; const [subroutineName] = mainFileName.split('.'); this.subroutineName = subroutineName; } /** Create a deployment manager */ static createDeploymentManager(/** URL of the MVIS Admin */ mvisAdminUrl, /** Database account that will be administered will be used against */ account, /** MVIS Admin username */ username, /** MVIS Admin password */ password, /** Log Handler */ logHandler, options = {}) { const { timeout = 0, httpAgent, httpsAgent } = options; if (!Number.isInteger(timeout)) { throw new _errors.InvalidParameterError({ parameterName: 'timeout' }); } return new DeploymentManager(mvisAdminUrl, account, username, password, timeout, logHandler, { httpAgent, httpsAgent }); } /** Validate that the MVOM main subroutine is available */ async validateDeployment() { const headers = await this.authenticate(); const [isRestDefinitionValid, isCatalogValid] = await Promise.all([this.validateRestDefinition(headers), this.validateCatalog(headers)]); const isValid = isRestDefinitionValid && isCatalogValid; if (isValid) { this.logHandler.debug(`${this.subroutineName} is available for calling through MVIS`); } else { this.logHandler.warn(`${this.subroutineName} is unavailable for calling through MVIS`); } return isValid; } /** Deploy the MVOM main subroutine to MVIS */ async deploy(sourceDir, options = {}) { const { createDir = false } = options; const headers = await this.authenticate(); const [isRestDefinitionValid, isCatalogValid] = await Promise.all([this.validateRestDefinition(headers), this.validateCatalog(headers)]); if (!isRestDefinitionValid) { await this.createRestDefinition(headers, sourceDir, createDir); } if (!isCatalogValid) { await this.deploySubroutine(headers); } } /** Authenticate to MVIS admin and return headers needed for subsequent API calls */ async authenticate() { this.logHandler.debug('Authenticating to MVIS Admin'); const authResponse = await this.axiosInstance.get('user', { headers: { authorization: `Basic ${this.authorization}` } }); const cookies = authResponse.headers['set-cookie']; if (cookies == null) { throw new Error('Unable to authenticate with MVIS Admin. No session id and xsrf token cookies returned.'); } const xsrfTokenCookie = cookies.find(cookie => cookie.startsWith('XSRF-TOKEN=')); if (xsrfTokenCookie == null) { throw new Error('Unable to authenticate with MVIS Admin. No xsrf token returned.'); } // ex: XSRF-TOKEN=3c2a0741-f1a5-4d52-9145-b508e4fbc845; Path=/ const xsrfToken = xsrfTokenCookie.split('=')[1].split(';')[0]; this.logHandler.debug('Successfully authenticated to MVIS admin'); return { Cookie: cookies.join('; '), 'X-XSRF-TOKEN': xsrfToken }; } /** Validate the presence of the REST subroutine definition */ async validateRestDefinition(headers) { this.logHandler.debug('Fetching list of REST subroutines from MVIS Admin'); const { data: response } = await this.axiosInstance.get(`manager/rest/${this.account}/subroutines`, { headers }); return Object.values(response).some(subroutine => subroutine.name === this.subroutineName); } /** Validate that the MVOM subroutine is cataloged */ async validateCatalog(headers) { this.logHandler.debug('Fetching list of cataloged subroutines from MVIS Admin'); const { data: { ctlgprograms } } = await this.axiosInstance.get(`manager/rest/${this.account}/ctlgprograms`, { headers }); return ctlgprograms.includes(this.subroutineName); } /** Create MVIS REST Definition */ async createRestDefinition(headers, sourceDir, createDir) { const sourcePath = _path.default.join(DeploymentManager.unibasicPath, this.mainFileName); this.logHandler.debug(`Reading unibasic source from ${sourcePath}`); const source = await _fsExtra.default.readFile(sourcePath, 'utf8'); this.logHandler.debug(`Creating REST subroutine definition for ${this.subroutineName} in MVIS Admin`); await this.axiosInstance.post(`manager/rest/${this.account}/subroutine`, { name: this.subroutineName, parameter_count: 2, input: { name: '', parameters: [{ name: 'input', type: 'json', order: 1, dname: '' }] }, output: { name: '', parameters: [{ name: 'output', type: 'json', order: 2, dname: '' }] }, allowCompileAndCatalog: true, createSourceDir: createDir, sourceDir, catalogOptions: 'force', compileOptions: '-i -o -d', source }, { headers }); this.logHandler.debug(`${this.subroutineName} successfully created in MVIS Admin`); } /** Deploy subroutine to database server */ async deploySubroutine(headers) { this.logHandler.debug(`Compiling and cataloging ${this.subroutineName} on database server`); await this.axiosInstance.get(`manager/rest/${this.account}/loadsubroutine/${this.subroutineName}`, { headers }); this.logHandler.debug(`Compiled ${this.subroutineName} on database server`); } } var _default = exports.default = DeploymentManager;