diff --git a/packages/zosmf/src/CheckStatus.ts b/packages/zosmf/src/CheckStatus.ts index b378c8ba2b..c46687ed74 100644 --- a/packages/zosmf/src/CheckStatus.ts +++ b/packages/zosmf/src/CheckStatus.ts @@ -36,6 +36,10 @@ export class CheckStatus { return ZosmfRestClient.getExpectJSON(session, infoEndpoint); } + public static async isZosVersionGreaterThan(session: AbstractSession, version: string): Promise { + return (await CheckStatus.getZosmfInfo(session)).zosmf_version >= version; + } + /** * Get Log * @returns {Logger} applicationLogger. diff --git a/packages/zosmf/src/constants/Zosmf.constants.ts b/packages/zosmf/src/constants/Zosmf.constants.ts index f8bce03178..5c3930ecfc 100644 --- a/packages/zosmf/src/constants/Zosmf.constants.ts +++ b/packages/zosmf/src/constants/Zosmf.constants.ts @@ -67,6 +67,15 @@ export const ZosmfConstants: { [key: string]: any } = { * @type {string} */ UNABLE_TO_VERIFY_LEAF_SIGNATURE: "UNABLE_TO_VERIFY_LEAF_SIGNATURE" + }, + + VERSIONS: { + V2R1: "24", + V2R2: "25", + V2R3: "26", + V2R4: "27", + V2R5: "28", + V3R1: "29", } }; diff --git a/packages/zostso/src/IssueTso.ts b/packages/zostso/src/IssueTso.ts index 77fd62b361..2f130f4d31 100644 --- a/packages/zostso/src/IssueTso.ts +++ b/packages/zostso/src/IssueTso.ts @@ -9,15 +9,19 @@ * */ -import { AbstractSession, ImperativeError } from "@zowe/imperative"; +import { AbstractSession, Headers, ImperativeError } from "@zowe/imperative"; import { IStartTsoParms } from "./doc/input/IStartTsoParms"; -import { noAccountNumber, noCommandInput } from "./TsoConstants"; +import { noAccountNumber, noCommandInput, TsoConstants } from "./TsoConstants"; import { SendTso } from "./SendTso"; import { StartTso } from "./StartTso"; import { IIssueResponse } from "./doc/IIssueResponse"; import { StopTso } from "./StopTso"; import { TsoValidator } from "./TsoValidator"; import { IIssueTsoParms } from "./doc/input/IIssueTsoParms"; +import { CheckStatus, ZosmfConstants } from "@zowe/zosmf-for-zowe-sdk"; +import { ZosmfRestClient } from "@zowe/core-for-zowe-sdk"; +import { IIssueTsoCmdResponse } from "./doc/IIssueTsoCmdResponse"; +import { IIssueTsoCmdParms } from "./doc/input/IIssueTsoCmdParms"; /** * Class to handle issue command to TSO @@ -25,7 +29,59 @@ import { IIssueTsoParms } from "./doc/input/IIssueTsoParms"; */ export class IssueTso { + public static async issueTsoCmd(session: AbstractSession, commandInfo: string | IIssueTsoCmdParms, addressSpaceOptions?: IStartTsoParms): + Promise { + + const command = typeof commandInfo === "string" ? commandInfo : commandInfo.command; + const version = typeof commandInfo === "string" ? "v1" : commandInfo.version ?? "v1"; + const isStateful = typeof commandInfo === "string" ? false : commandInfo.isStateful ?? false; + + if (addressSpaceOptions == null && await CheckStatus.isZosVersionGreaterThan(session, ZosmfConstants.VERSIONS.V2R4)) { + // use new api + const endpoint = TsoConstants.RESOURCE + "/" + version + "/" + TsoConstants.RES_START_TSO; + const response = await ZosmfRestClient.putExpectJSON(session, endpoint, [Headers.APPLICATION_JSON], { + "tsoCmd": command, + "cmdState": isStateful ? "stateful" : "stateless" + }); + + return response; + + } else if (addressSpaceOptions != null) { + // use old behavior + TsoValidator.validateSession(session); + TsoValidator.validateNotEmptyString(addressSpaceOptions.account, noAccountNumber.message); + TsoValidator.validateNotEmptyString(command, noCommandInput.message); + + const response: IIssueResponse = { + success: false, + startResponse: null, + startReady: false, + zosmfResponse: null, + commandResponse: null, + stopResponse: null + }; + response.startResponse = await StartTso.start(session, addressSpaceOptions.account, addressSpaceOptions || {}); + + if (!response.startResponse.success) { + throw new ImperativeError({ + msg: `TSO address space failed to start.`, + additionalDetails: response.startResponse.failureResponse?.message + }); + } + + const sendResponse = await SendTso.sendDataToTSOCollect(session, response.startResponse.servletKey, command); + response.success = sendResponse.success; + response.zosmfResponse = sendResponse.zosmfResponse; + response.commandResponse = sendResponse.commandResponse; + response.stopResponse = await StopTso.stop(session, response.startResponse.servletKey); + return response; + } else { + throw "ERROR"; + } + } + /** + * @deprecated Use issueTsoCmd instead * API method to start a TSO address space, issue a command, collect responses until prompt is reached, and terminate the address space. * @param {AbstractSession} session - z/OSMF connection info * @param {string} accountNumber - accounting info for Jobs @@ -34,50 +90,23 @@ export class IssueTso { * @returns {Promise} IssueTso response object, @see {IIssueResponse} * @memberof IssueTso */ - public static async issueTsoCommand(session: AbstractSession, accountNumber: string, command: string, startParams?: IStartTsoParms) { - - TsoValidator.validateSession(session); - TsoValidator.validateNotEmptyString(accountNumber, noAccountNumber.message); - TsoValidator.validateNotEmptyString(command, noCommandInput.message); - - const response: IIssueResponse = { - success: false, - startResponse: null, - startReady: false, - zosmfResponse: null, - commandResponse: null, - stopResponse: null - }; - response.startResponse = await StartTso.start(session, accountNumber, startParams || {}); + public static async issueTsoCommand(session: AbstractSession, accountNumber: string, command: string, startParams?: IStartTsoParms): Promise { + return await IssueTso.issueTsoCmd(session, command, { ...startParams, account: accountNumber }) as IIssueResponse; - if (!response.startResponse.success) { - throw new ImperativeError({ - msg: `TSO address space failed to start.`, - additionalDetails: response.startResponse.failureResponse?.message - }); - } - - const sendResponse = await SendTso.sendDataToTSOCollect(session, response.startResponse.servletKey, command); - response.success = sendResponse.success; - response.zosmfResponse = sendResponse.zosmfResponse; - response.commandResponse = sendResponse.commandResponse; - response.stopResponse = await StopTso.stop(session, response.startResponse.servletKey); - return response; } /** + * @deprecated use issueTsoCmd instead * API method to start a TSO address space with provided parameters, issue a command, * collect responses until prompt is reached, and terminate the address space. * @param {AbstractSession} session - z/OSMF connection info * @param {IIssueTsoParms} commandParms - object with required parameters, @see {IIssueTsoParms} * @returns {Promise} */ - public static async issueTsoCommandCommon(session: AbstractSession, commandParms: IIssueTsoParms) { - - TsoValidator.validateSession(session); - TsoValidator.validateIssueParams(commandParms); - TsoValidator.validateNotEmptyString(commandParms.command, noCommandInput.message); - return IssueTso.issueTsoCommand(session, commandParms.accountNumber, commandParms.command, commandParms.startParams); + public static async issueTsoCommandCommon(session: AbstractSession, commandParms: IIssueTsoParms): Promise { + return await IssueTso.issueTsoCmd(session, commandParms.command, { + ...commandParms.startParams, account: commandParms.accountNumber + }) as IIssueResponse; } } diff --git a/packages/zostso/src/doc/IIssueTsoCmdResponse.ts b/packages/zostso/src/doc/IIssueTsoCmdResponse.ts new file mode 100644 index 0000000000..2537831e02 --- /dev/null +++ b/packages/zostso/src/doc/IIssueTsoCmdResponse.ts @@ -0,0 +1,21 @@ +/* +* 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. +* +*/ + +export interface IIssueTsoCmdResponse { + + cmdResponse: {message: string}[]; + + tsoPromptReceived: "Y" | "N", + + servletKey?: string; + + keywordDetected?: "Y" | "N", +} diff --git a/packages/zostso/src/doc/input/IIssueTsoCmdParms.ts b/packages/zostso/src/doc/input/IIssueTsoCmdParms.ts new file mode 100644 index 0000000000..04cfbea2c8 --- /dev/null +++ b/packages/zostso/src/doc/input/IIssueTsoCmdParms.ts @@ -0,0 +1,19 @@ +/* +* 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. +* +*/ + +export interface IIssueTsoCmdParms { + + command: string; + + isStateful?: boolean; + + version?: string; +} diff --git a/packages/zostso/src/index.ts b/packages/zostso/src/index.ts index cd43f1a60a..a9592a8893 100644 --- a/packages/zostso/src/index.ts +++ b/packages/zostso/src/index.ts @@ -12,6 +12,7 @@ export * from "./constants/ZosTso.constants"; export * from "./constants/ZosTso.profile"; +export * from "./doc/input/IIssueTsoCmdParms"; export * from "./doc/input/IIssueTsoParms"; export * from "./doc/input/ISendTsoParms"; export * from "./doc/input/IStartTsoParms"; @@ -28,6 +29,7 @@ export * from "./doc/zosmf/IZosmfPingResponse"; export * from "./doc/zosmf/IZosmfTsoResponse"; export * from "./doc/ICollectedResponses"; +export * from "./doc/IIssueTsoCmdResponse"; export * from "./doc/IIssueResponse"; export * from "./doc/IPingResponse"; export * from "./doc/ISendResponse";