@zowe/zos-jobs-for-zowe-sdk
Version:
Zowe SDK to interact with jobs on z/OS
202 lines • 10.2 kB
JavaScript
;
/*
* This program and the accompanying materials are made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Copyright Contributors to the Zowe Project.
*
*/
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DownloadJobs = void 0;
const path = require("path");
const imperative_1 = require("@zowe/imperative");
const JobsConstants_1 = require("./JobsConstants");
const core_for_zowe_sdk_1 = require("@zowe/core-for-zowe-sdk");
const GetJobs_1 = require("./GetJobs");
const MonitorJobs_1 = require("./MonitorJobs");
/**
* Class to handle downloading of job information
* @export
* @class DownloadJobs
*/
class DownloadJobs {
/**
* Download spool content to a the default download directory
* @static
* @param {AbstractSession} session - z/OSMF connection info
* @param jobFile - spool file to download
* @returns {Promise<string>} - content downloaded
* @memberof DownloadJobs
*/
static downloadSpoolContent(session, jobFile) {
return __awaiter(this, void 0, void 0, function* () {
this.log.trace("Entered downloadSpoolContent for job file %s", JSON.stringify(jobFile));
return DownloadJobs.downloadSpoolContentCommon(session, { jobFile });
});
}
/**
* Download all job output (spool content) for a job to a the local directory
* @static
* @param {AbstractSession} session - z/OSMF connection info
* @param {IDownloadAllSpoolContentParms} parms - parameter object (see IDownloadAllSpoolContentParms for details)
* @returns {Promise<void>} - a promise which will resolve when the download is complete
* @memberof DownloadJobs
*/
static downloadAllSpoolContentCommon(session, parms) {
return __awaiter(this, void 0, void 0, function* () {
this.log.trace("Entering downloadAllSpoolContentCommon with parms %s", JSON.stringify(parms));
imperative_1.ImperativeExpect.keysToBeDefined(parms, ["jobid", "jobname"], "You must specify job ID and job name on your" +
" 'parms' object to the downloadAllSpoolContent API.");
this.log.debug("Downloading all spool content for job %s(%s)", parms.jobname, parms.jobid);
const jobFiles = yield GetJobs_1.GetJobs.getSpoolFiles(session, parms.jobname, parms.jobid);
// Maintain a mapping of step names and associated DD names to detect duplicate step names
const usedStepNames = {};
for (const file of jobFiles) {
let uniqueDDName = file.ddname;
if (usedStepNames[file.stepname] != null) {
let index = 1;
while (usedStepNames[file.stepname].indexOf(uniqueDDName) !== -1) {
uniqueDDName = `${file.ddname}(${index})`;
index++;
}
}
yield DownloadJobs.downloadSpoolContentCommon(session, Object.assign(Object.assign({}, parms), { jobFile: Object.assign(Object.assign({}, file), { ddname: uniqueDDName }) }));
usedStepNames[file.stepname] = [...usedStepNames[file.stepname] || [], uniqueDDName];
}
});
}
/**
* Download spool content to specified directory
* @static
* @param {AbstractSession} session - z/OSMF connection info
* @param {IDownloadSpoolContentParms} parms - parm object (see IDownloadSpoolContentParms interface for details)
* @returns {Promise<void>} - promise that resolves when the file is downloaded
* @memberof DownloadJobs
*/
static downloadSpoolContentCommon(session, parms) {
return __awaiter(this, void 0, void 0, function* () {
var _a;
this.log.trace("Entering downloadSpoolContentCommon with parms %s", JSON.stringify(parms));
imperative_1.ImperativeExpect.keysToBeDefined(parms, ["jobFile"], "You must specify a job file on your 'parms' parameter" +
" object to the downloadSpoolContentCommon API.");
//waiting for job to be active before continuing with job download
if (parms.waitForActive) {
yield MonitorJobs_1.MonitorJobs.waitForActiveStatus(session, parms.jobname, parms.jobid);
}
//waiting for job status to be output before continuing on with job download
if (parms.waitForOutput) {
yield MonitorJobs_1.MonitorJobs.waitForJobOutputStatus(session, {
jobname: parms.jobname,
jobid: parms.jobid
});
}
const job = parms.jobFile;
let debugMessage = `Downloading spool file ${job.ddname} for job ${job.jobname}(${job.jobid})`;
let file;
if (parms.stream == null) {
file = DownloadJobs.getSpoolDownloadFilePath(parms);
imperative_1.IO.createDirsSyncFromFilePath(file);
imperative_1.IO.createFileSync(file);
debugMessage += ` to ${file}`;
}
this.log.debug(debugMessage);
let parameters = imperative_1.EncodeUri.encUriPathForZos(session, JobsConstants_1.JobsConstants.RESOURCE + "/" + job.jobname + "/" + job.jobid +
JobsConstants_1.JobsConstants.RESOURCE_SPOOL_FILES + "/" + job.id + JobsConstants_1.JobsConstants.RESOURCE_SPOOL_CONTENT);
if (parms.binary) {
parameters += "?mode=binary";
}
else if (parms.record) {
parameters += "?mode=record";
}
if (!parms.binary && !parms.record && parms.encoding != null && String(parms.encoding).trim()) {
parameters += "?fileEncoding=" + parms.encoding;
}
const headers = [imperative_1.Headers.TEXT_PLAIN_UTF8];
// Handle record range
if (parms.recordRange) {
const recordRangeMatch = parms.recordRange.match(/^(\d+)-(\d+)$/); // Match multi-digit numbers
if (recordRangeMatch) {
const start = parseInt(recordRangeMatch[1], 10);
const end = parseInt(recordRangeMatch[2], 10);
if (start >= 0 && end > start) {
if (parms.recordRange) {
headers.push({ "X-IBM-Record-Range": `${start}-${end}` });
}
}
else {
throw new Error(`Invalid record range specified: ${parms.recordRange}. Ensure the format is x-y with x < y.`);
}
}
else {
throw new Error(`Invalid record range format: ${parms.recordRange}. Expected format is x-y.`);
}
}
const writeStream = (_a = parms.stream) !== null && _a !== void 0 ? _a : imperative_1.IO.createWriteStream(file);
const normalizeResponseNewLines = !(parms.binary || parms.record);
yield core_for_zowe_sdk_1.ZosmfRestClient.getStreamed(session, parameters, headers, writeStream, normalizeResponseNewLines);
});
}
/**
* Get the file where a specified spool file (IJobFile) would be downloaded to
* @static
* @param {IDownloadSpoolContentParms} parms - parm object (see IDownloadSpoolContentParms interface for details)
* @returns {string} the file path that the spool file would be downloaded to
* @memberof DownloadJobs
*/
static getSpoolDownloadFilePath(parms) {
var _a, _b;
this.log.trace("getSpoolDownloadFilePath called with jobFile %s, omitJobIDDirectory: %s, outDir: %s", JSON.stringify(parms.jobFile), parms.omitJobidDirectory + "", parms.outDir);
let directory = (_a = parms.outDir) !== null && _a !== void 0 ? _a : DownloadJobs.DEFAULT_JOBS_OUTPUT_DIR;
const parentDirectory = directory;
if (parms.omitJobidDirectory == null || parms.omitJobidDirectory === false) {
directory += path.posix.sep + parms.jobFile.jobid;
}
if (parms.jobFile.procstep != null) {
directory += path.posix.sep + parms.jobFile.procstep;
}
if (parms.jobFile.stepname != null) {
directory += path.posix.sep + parms.jobFile.stepname;
}
const extension = (_b = parms.extension) !== null && _b !== void 0 ? _b : DownloadJobs.DEFAULT_JOBS_OUTPUT_FILE_EXT;
const finalPath = directory + path.posix.sep + parms.jobFile.ddname + extension;
if (imperative_1.IO.containsBacktrack(finalPath) || !imperative_1.IO.isSubPath(parentDirectory, finalPath)) {
throw new imperative_1.ImperativeError({ msg: "The generated file path contains illegal characters." });
}
return finalPath;
}
/**
* Getter for Zowe logger
* @returns {Logger}
*/
static get log() {
return imperative_1.Logger.getAppLogger();
}
}
exports.DownloadJobs = DownloadJobs;
/**
* Default directory where output will be placed
* @static
* @type {string}
* @memberof DownloadJobs
*/
DownloadJobs.DEFAULT_JOBS_OUTPUT_DIR = "./output";
/**
* Default extension of downloaded folders
* @static
* @type {string}
* @memberof DownloadJobs
*/
DownloadJobs.DEFAULT_JOBS_OUTPUT_FILE_EXT = ".txt";
//# sourceMappingURL=DownloadJobs.js.map