mvom
Version:
Multivalue Object Mapper
220 lines (201 loc) • 7.48 kB
JavaScript
;
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;