UNPKG

@zowe/cli

Version:

Zowe CLI is a command line interface (CLI) that provides a simple and streamlined way to interact with IBM z/OS.

297 lines 16.2 kB
"use strict"; /* * 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 }); const rest_1 = require("../../../rest"); const imperative_1 = require("@zowe/imperative"); const JobsConstants_1 = require("./JobsConstants"); const JobsMessages_1 = require("./JobsMessages"); const GetJobs_1 = require("./GetJobs"); const DownloadJobs_1 = require("./DownloadJobs"); const MonitorJobs_1 = require("./MonitorJobs"); /** * Class to handle submitting of z/OS batch jobs via z/OSMF * @export * @class SubmitJobs */ class SubmitJobs { /** * Submit a job that resides in a z/OS data set. * @static * @param {AbstractSession} session - z/OSMF connection info * @param {string} jobDataSet - job data set to be translated into parms object * @returns {Promise<IJob>} - Promise that resolves to an IJob document with details about the submitted job * @memberof SubmitJobs */ static submitJob(session, jobDataSet) { this.log.trace("submitJob called with data set %s", jobDataSet); return SubmitJobs.submitJobCommon(session, { jobDataSet }); } /** * Submit a job that resides in a z/OS data set. * @static * @param {AbstractSession} session - z/OSMF connection info * @param {ISubmitJobParms} parms - parm object (see for details) * @returns {Promise<IJob>} - Promise that resolves to an IJob document with details about the submitted job * @memberof SubmitJobs */ static submitJobCommon(session, parms) { return __awaiter(this, void 0, void 0, function* () { this.log.trace("submitJobCommon called with parms %s", JSON.stringify(parms)); imperative_1.ImperativeExpect.keysToBeDefined(parms, ["jobDataSet"], "You must provide a data set containing JCL to submit in parms.jobDataSet"); this.log.debug("Submitting a job located in the data set '%s'", parms.jobDataSet); const fullyQualifiedDataset = "//'" + parms.jobDataSet + "'"; const jobObj = { file: fullyQualifiedDataset }; return rest_1.ZosmfRestClient.putExpectJSON(session, JobsConstants_1.JobsConstants.RESOURCE, [imperative_1.Headers.APPLICATION_JSON], jobObj); }); } /** * Submit a string of JCL to run * @static * @param {AbstractSession} session - z/OSMF connection info * @param {string} jcl - string of JCL that you want to be submit * @param {string} internalReaderRecfm - record format of the jcl you want to submit. "F" (fixed) or "V" (variable) * @param {string} internalReaderLrecl - logical record length of the jcl you want to submit * @returns {Promise<IJob>} - Promise that resolves to an IJob document with details about the submitted job * @memberof SubmitJobs */ static submitJcl(session, jcl, internalReaderRecfm, internalReaderLrecl) { this.log.trace("submitJcl called with jcl of length %d. internalReaderRecfm %s internalReaderLrecl %s", jcl == null ? "no jcl!" : jcl.length, internalReaderRecfm, internalReaderLrecl); return SubmitJobs.submitJclCommon(session, { jcl, internalReaderRecfm, internalReaderLrecl }); } static submitJclString(session, jcl, parms) { return __awaiter(this, void 0, void 0, function* () { imperative_1.ImperativeExpect.toNotBeNullOrUndefined(jcl, JobsMessages_1.ZosJobsMessages.missingJcl.message); imperative_1.ImperativeExpect.toNotBeEqual(jcl, "", JobsMessages_1.ZosJobsMessages.missingJcl.message); const responseJobInfo = yield SubmitJobs.submitJclCommon(session, { jcl }); const response = this.checkSubmitOptions(session, parms, responseJobInfo); return response; }); } /** * Submit a JCL string to run * @static * @param {AbstractSession} session - z/OSMF connection info * @param {ISubmitJclParms} parms - parm object (see for details) * @returns {Promise<IJob>} - Promise that resolves to an IJob document with details about the submitted job * @memberof SubmitJobs */ static submitJclCommon(session, parms) { return __awaiter(this, void 0, void 0, function* () { this.log.trace("submitJclCommon called with parms %s", JSON.stringify(parms)); imperative_1.ImperativeExpect.keysToBeDefined(parms, ["jcl"], "You must provide a JCL string to submit. The 'jcl' field of the provided parameters was undefined. "); this.log.debug("Submitting JCL of length %d", parms.jcl.length); const headers = [imperative_1.Headers.TEXT_PLAIN_UTF8, rest_1.ZosmfHeaders.X_IBM_INTRDR_MODE_TEXT]; if (parms.internalReaderLrecl) { this.log.debug("Custom internal reader logical record length (internalReaderLrecl) '%s' specified ", parms.internalReaderLrecl); headers.push({ "X-IBM-Intrdr-Lrecl": parms.internalReaderLrecl }); } else { // default to 80 record length headers.push(rest_1.ZosmfHeaders.X_IBM_INTRDR_LRECL_80); } if (parms.internalReaderRecfm) { this.log.debug("Custom internal reader record format (internalReaderRecfm) '%s' specified ", parms.internalReaderRecfm); headers.push({ "X-IBM-Intrdr-Recfm": parms.internalReaderRecfm }); } else { // default to fixed format records headers.push(rest_1.ZosmfHeaders.X_IBM_INTRDR_RECFM_F); } return rest_1.ZosmfRestClient.putExpectJSON(session, JobsConstants_1.JobsConstants.RESOURCE, headers, parms.jcl); }); } /** * Submit a JCL string to run * @static * @param {AbstractSession} session - z/OSMF connection info * @param {string} jcl - string of JCL that you want to be submit * @param {string} internalReaderRecfm - record format of the jcl you want to submit. "F" (fixed) or "V" (variable). * @param {string} internalReaderLrecl - logical record length of the jcl you want to submit * @returns {Promise<IJob>} - Promise that resolves to an IJob document with details about the submitted job * @memberof SubmitJobs */ static submitJclNotify(session, jcl, internalReaderRecfm, internalReaderLrecl) { return __awaiter(this, void 0, void 0, function* () { this.log.trace("submitJclNotiy called with jcl of length %s, internalReaderRecfm %s, internalReaderLrecl %s", jcl == null ? "no jcl!" : jcl.length, internalReaderRecfm, internalReaderLrecl); return SubmitJobs.submitJclNotifyCommon(session, { jcl, internalReaderRecfm, internalReaderLrecl }); }); } /** * Submit a job from a string of JCL and be notified whenever it reaches the default status on a default polling interval. * @static * @param {AbstractSession} session - z/OSMF connection info * @param {ISubmitJclNotifyParm} parms - parm object (see for details) * @returns {Promise<IJob>} - Promise that resolves to an IJob document with details about the submitted job * @memberof SubmitJobs */ static submitJclNotifyCommon(session, parms) { return __awaiter(this, void 0, void 0, function* () { this.log.trace("submitJclNotifyCommon called with parms %s", JSON.stringify(parms)); const job = yield SubmitJobs.submitJclCommon(session, parms); return SubmitJobs.submitNotifyCommon(session, job, parms.status, parms.watchDelay); }); } /** * Submit a job and be notified whenever it reaches the default status on a default polling interval. * @static * @param {AbstractSession} session - z/OSMF connection info * @param {string} jobDataSet - job data set to be translated into parms object with assumed defaults * @returns {Promise<IJob>} - Promise that resolves to an IJob document with details about the submitted job * @memberof SubmitJobs */ static submitJobNotify(session, jobDataSet) { return __awaiter(this, void 0, void 0, function* () { this.log.trace("submitJobNotify called with data set %s", jobDataSet); return SubmitJobs.submitJobNotifyCommon(session, { jobDataSet }); }); } /** * Submit a job from a data set and be notified whenever it reaches a certain status. * If not status is specified, MonitorJobs.DEFAULT_STATUS is assumed. * The polling interval can also be optionally controlled via parms.watchDelay. * If not specified, the default polling is MonitorJobs.DEFAULT_WATCH_DELAY. * @static * @param {AbstractSession} session - z/OSMF connection info * @param {ISubmitJobNotifyParm} parms - parm object (see for details) * @returns {Promise<IJob>} - Promise that resolves to an IJob document with details about the submitted job * @memberof SubmitJobs */ static submitJobNotifyCommon(session, parms) { return __awaiter(this, void 0, void 0, function* () { this.log.trace("submitJobNotifyCommon called with parms %s", JSON.stringify(parms)); imperative_1.ImperativeExpect.keysToBeDefined(parms, ["jobDataSet"], "You must provide a data set containing JCL to submit in parms.jobDataSet."); const job = yield SubmitJobs.submitJobCommon(session, parms); return SubmitJobs.submitNotifyCommon(session, job, parms.status, parms.watchDelay); }); } /** * Common method to handle job submit options * @public * @static * @param {AbstractSession} session - z/OSMF connection info * @param {ISubmitParms } parms - Submit options * @param {IJob} responseJobInfo - job document for a previously submitted job * @returns {Promise<IJob | ISpoolFile[]>} - Promise that resolves to an IJob or ISpoolFile[] * @memberof SubmitJobs */ static checkSubmitOptions(session, parms, responseJobInfo) { return __awaiter(this, void 0, void 0, function* () { if (parms.waitForActive) { const activeJob = yield MonitorJobs_1.MonitorJobs.waitForStatusCommon(session, { jobid: responseJobInfo.jobid, jobname: responseJobInfo.jobname, status: "ACTIVE" }); return activeJob; } // if viewAppSpoolContent option passed, it waits till job status is output // then get content of each spool file and return array of ISpoolFiles object if (parms.viewAllSpoolContent || parms.waitForOutput) { if (parms.task != null) { parms.task.statusMessage = "Waiting for " + responseJobInfo.jobid + " to enter OUTPUT"; parms.task.percentComplete = imperative_1.TaskProgress.THIRTY_PERCENT; } const job = yield MonitorJobs_1.MonitorJobs.waitForJobOutputStatus(session, responseJobInfo); if (!parms.viewAllSpoolContent) { return job; } if (parms.task != null) { parms.task.statusMessage = "Retrieving spool content for " + job.jobid + (job.retcode == null ? "" : ", " + job.retcode); parms.task.percentComplete = imperative_1.TaskProgress.SEVENTY_PERCENT; } const spoolFiles = yield GetJobs_1.GetJobs.getSpoolFilesForJob(session, job); const arrOfSpoolFile = []; for (const file of spoolFiles) { const spoolContent = yield GetJobs_1.GetJobs.getSpoolContent(session, file); arrOfSpoolFile.push({ id: file.id, ddName: file.ddname, stepName: file.stepname, procName: file.procstep, data: spoolContent, }); } return arrOfSpoolFile; // if directory option passed, it waits till job status is output // then downloads content of all spool files and returns IJob object } else if (parms.directory) { // waits job status to be output if (parms.task != null) { parms.task.statusMessage = "Waiting for " + responseJobInfo.jobid + " to enter OUTPUT"; parms.task.percentComplete = imperative_1.TaskProgress.THIRTY_PERCENT; } const job = yield MonitorJobs_1.MonitorJobs.waitForJobOutputStatus(session, responseJobInfo); const downloadParms = { jobid: job.jobid, jobname: job.jobname, outDir: parms.directory }; if (parms.extension) { downloadParms.extension = imperative_1.IO.normalizeExtension(parms.extension); } if (parms.task != null) { parms.task.statusMessage = "Downloading spool content for " + job.jobid + (job.retcode == null ? "" : ", " + job.retcode); parms.task.percentComplete = imperative_1.TaskProgress.SEVENTY_PERCENT; } (yield DownloadJobs_1.DownloadJobs.downloadAllSpoolContentCommon(session, downloadParms)); return job; } return responseJobInfo; }); } /** * Common method to watch for a job to reach a certain status whether the job was * submitted through raw JCL statement or through a data set containing JCL. * @private * @static * @param {AbstractSession} session - z/OSMF connection info * @param {IJob} job - job document for a previously submitted job * @param {JOB_STATUS } status - status that we want this job to reach before notifying * @param {number} watchDelay - delay / interval to poll * @returns {Promise<IJob>} - Promise that resolves to an IJob document with details about the submitted job * @memberof SubmitJobs */ static submitNotifyCommon(session, job, status, watchDelay) { return __awaiter(this, void 0, void 0, function* () { this.log.trace("submitNotiyCommon called with job %s, status %s, watchDelay %s", JSON.stringify(job), status, watchDelay); imperative_1.ImperativeExpect.keysToBeDefined(job, ["jobname", "jobid"], "The job object you provide must contain both 'jobname' and 'jobid'."); this.log.debug("Waiting to be notified of job completion from Monitor Jobs API for job %s (%s)", job.jobname, job.jobid); return MonitorJobs_1.MonitorJobs.waitForStatusCommon(session, { jobname: job.jobname, jobid: job.jobid, status, watchDelay, }); }); } /** * Getter for brightside logger * @returns {Logger} */ static get log() { return imperative_1.Logger.getAppLogger(); } } exports.SubmitJobs = SubmitJobs; //# sourceMappingURL=SubmitJobs.js.map