diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a668751e8..c9b16ef5c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to the Zowe CLI package will be documented in this file. +## Recent Changes + +- Added new method "dataSetLike(session, dataSetName, options)" to `Create` class, for use when creating a dataset with parameters like another data set + ## `6.19.1` - Update Imperative version diff --git a/package-lock.json b/package-lock.json index 8ea41d8d15..798ec0cc8c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -730,9 +730,9 @@ } }, "@zowe/imperative": { - "version": "4.7.3", - "resolved": "https://zowe.jfrog.io/zowe/api/npm/npm-release/@zowe/imperative/-/@zowe/imperative-4.7.3.tgz", - "integrity": "sha1-S0JCpvJQXKwgSDKlnlEFUuFFDSw=", + "version": "4.7.4", + "resolved": "https://zowe.jfrog.io/zowe/api/npm/npm-release/@zowe/imperative/-/@zowe/imperative-4.7.4.tgz", + "integrity": "sha1-1zHwUuv1oxgOIJZVmbOAImGjjkA=", "requires": { "@types/lodash-deep": "2.0.0", "@types/yargs": "13.0.4", diff --git a/packages/zosfiles/__tests__/__system__/api/methods/create/Create.system.test.ts b/packages/zosfiles/__tests__/__system__/api/methods/create/Create.system.test.ts index 51a6fc1ca9..f5cf657508 100644 --- a/packages/zosfiles/__tests__/__system__/api/methods/create/Create.system.test.ts +++ b/packages/zosfiles/__tests__/__system__/api/methods/create/Create.system.test.ts @@ -106,6 +106,69 @@ describe("Create data set", () => { }, LONGER_TIMEOUT); }); +describe("Allocate Like", () => { + let dsnameLike: string; + const options: ICreateDataSetOptions = { + dsorg: "PO", + alcunit: "CYL", + primary: 20, + recfm: "FB", + blksize: 6160, + lrecl: 80, + showAttributes: true + } as any; + + beforeAll(async () => { + testEnvironment = await TestEnvironment.setUp({ + testName: "zos_create_dataset_like" + }); + defaultSystem = testEnvironment.systemTestProperties; + + REAL_SESSION = TestEnvironment.createZosmfSession(testEnvironment); + dsnameLike = `${dsname}.LIKE`; + + await Create.dataSet(REAL_SESSION, CreateDataSetTypeEnum.DATA_SET_CLASSIC, dsname, options); + }); + + afterAll(async () => { + await TestEnvironment.cleanUp(testEnvironment); + }); + + beforeEach(async () => { + try { + await Create.dataSet(REAL_SESSION, CreateDataSetTypeEnum.DATA_SET_CLASSIC, dsname, options); + } catch (error) { + Imperative.console.info("Error: " + inspect(error)); + } + }); + + afterEach(async () => { + try { + await Delete.dataSet(REAL_SESSION, dsname); + await Delete.dataSet(REAL_SESSION, dsnameLike); + } catch (error) { + Imperative.console.info("Error: " + inspect(error)); + } + }); + + it("should be able to allocate like from a sequential data set", async () => { + let error; + let response; + + try { + response = await Create.dataSetLike(REAL_SESSION, dsnameLike, dsname); + Imperative.console.info("Response: " + inspect(response)); + } catch (err) { + error = err; + Imperative.console.info("Error: " + inspect(error)); + } + + expect(error).toBeFalsy(); + expect(response).toBeTruthy(); + expect(response.commandResponse).toContain(ZosFilesMessages.dataSetCreatedSuccessfully.message); + }); +}); + describe("Create VSAM", () => { beforeAll(async () => { diff --git a/packages/zosfiles/__tests__/api/methods/create/Create.unit.test.ts b/packages/zosfiles/__tests__/api/methods/create/Create.unit.test.ts index 2b09cd9103..26be5a940d 100644 --- a/packages/zosfiles/__tests__/api/methods/create/Create.unit.test.ts +++ b/packages/zosfiles/__tests__/api/methods/create/Create.unit.test.ts @@ -139,6 +139,12 @@ describe("Create data set", () => { ); }); + it("should be able to allocate like from a sequential data set", async () => { + const response = await Create.dataSetLike(dummySession, "testing2", dataSetName); + + expect(response.commandResponse).toContain("created successfully"); + }); + it("should be able to create a sequential data set using the primary allocation and secondary allocation options", async () => { const custOptions = { dsorg: "PS", diff --git a/packages/zosfiles/src/api/constants/ZosFiles.messages.ts b/packages/zosfiles/src/api/constants/ZosFiles.messages.ts index 44f66a76d7..410f5b678c 100644 --- a/packages/zosfiles/src/api/constants/ZosFiles.messages.ts +++ b/packages/zosfiles/src/api/constants/ZosFiles.messages.ts @@ -47,6 +47,14 @@ export const ZosFilesMessages: { [key: string]: IMessageDefinition } = { message: "Specify the data set name." }, + /** + * Message indicating that the data set "like" name is required + * @type {IMessageDefinition} + */ + missingDatasetLikeName: { + message: "Specify the name of the data set to \"allocate like\" from." + }, + /** * Message indicating that the USS File name is required * @type {IMessageDefinition} diff --git a/packages/zosfiles/src/api/methods/create/Create.ts b/packages/zosfiles/src/api/methods/create/Create.ts index df1f2f9166..b4c0248d5c 100644 --- a/packages/zosfiles/src/api/methods/create/Create.ts +++ b/packages/zosfiles/src/api/methods/create/Create.ts @@ -56,19 +56,19 @@ export class Create { switch (cmdType) { case CreateDataSetTypeEnum.DATA_SET_PARTITIONED: - tempOptions = {...CreateDefaults.DATA_SET.PARTITIONED, ...tempOptions}; + tempOptions = { ...CreateDefaults.DATA_SET.PARTITIONED, ...tempOptions }; break; case CreateDataSetTypeEnum.DATA_SET_SEQUENTIAL: - tempOptions = {...CreateDefaults.DATA_SET.SEQUENTIAL, ...tempOptions}; + tempOptions = { ...CreateDefaults.DATA_SET.SEQUENTIAL, ...tempOptions }; break; case CreateDataSetTypeEnum.DATA_SET_BINARY: - tempOptions = {...CreateDefaults.DATA_SET.BINARY, ...tempOptions}; + tempOptions = { ...CreateDefaults.DATA_SET.BINARY, ...tempOptions }; break; case CreateDataSetTypeEnum.DATA_SET_C: - tempOptions = {...CreateDefaults.DATA_SET.C, ...tempOptions}; + tempOptions = { ...CreateDefaults.DATA_SET.C, ...tempOptions }; break; case CreateDataSetTypeEnum.DATA_SET_CLASSIC: - tempOptions = {...CreateDefaults.DATA_SET.CLASSIC, ...tempOptions}; + tempOptions = { ...CreateDefaults.DATA_SET.CLASSIC, ...tempOptions }; break; default: validCmdType = false; @@ -76,7 +76,7 @@ export class Create { } if (!validCmdType) { - throw new ImperativeError({msg: ZosFilesMessages.unsupportedDatasetType.message}); + throw new ImperativeError({ msg: ZosFilesMessages.unsupportedDatasetType.message }); } else { try { // Handle the size option @@ -134,6 +134,25 @@ export class Create { } } + public static async dataSetLike(session: AbstractSession, dataSetName: string, likeDataSetName: string): Promise { + // Required + ImperativeExpect.toNotBeNullOrUndefined(dataSetName, ZosFilesMessages.missingDatasetName.message); + ImperativeExpect.toNotBeNullOrUndefined(likeDataSetName, ZosFilesMessages.missingDatasetLikeName.message); + + try { + const endpoint: string = ZosFilesConstants.RESOURCE + ZosFilesConstants.RES_DS_FILES + "/" + dataSetName; + + const data = await ZosmfRestClient.postExpectString(session, endpoint, [], JSON.stringify({ like: likeDataSetName })); + + return { + success: true, + commandResponse: ZosFilesMessages.dataSetCreatedSuccessfully.message + }; + } catch (error) { + throw error; + } + } + /** * Validate supplied parameters * @static @@ -161,7 +180,7 @@ export class Create { case "TRK": break; default: - throw new ImperativeError({msg: ZosFilesMessages.invalidAlcunitOption.message + tempOptions.alcunit}); + throw new ImperativeError({ msg: ZosFilesMessages.invalidAlcunitOption.message + tempOptions.alcunit }); } break; @@ -186,11 +205,11 @@ export class Create { case "dirblk": // Validate non-zero if dsorg is PS if (tempOptions.dirblk !== 0 && tempOptions.dsorg === "PS") { - throw new ImperativeError({msg: ZosFilesMessages.invalidPSDsorgDirblkCombination.message}); + throw new ImperativeError({ msg: ZosFilesMessages.invalidPSDsorgDirblkCombination.message }); } // Validate non-zero if 'dsorg' is PO if (tempOptions.dirblk === 0 && tempOptions.dsorg === "PO") { - throw new ImperativeError({msg: ZosFilesMessages.invalidPODsorgDirblkCombination.message}); + throw new ImperativeError({ msg: ZosFilesMessages.invalidPODsorgDirblkCombination.message }); } break; @@ -199,8 +218,8 @@ export class Create { // Key to create a PDSE. const type: string = tempOptions.dsntype.toUpperCase(); const availableTypes = ["BASIC", "EXTPREF", "EXTREQ", "HFS", "LARGE", "PDS", "LIBRARY", "PIPE"]; - if (availableTypes.indexOf(type) === -1 ) { - throw new ImperativeError({msg: ZosFilesMessages.invalidDsntypeOption.message + tempOptions.dsntype}); + if (availableTypes.indexOf(type) === -1) { + throw new ImperativeError({ msg: ZosFilesMessages.invalidDsntypeOption.message + tempOptions.dsntype }); } break; @@ -212,7 +231,7 @@ export class Create { break; default: - throw new ImperativeError({msg: ZosFilesMessages.invalidDsorgOption.message + tempOptions.dsorg}); + throw new ImperativeError({ msg: ZosFilesMessages.invalidDsorgOption.message + tempOptions.dsorg }); } break; @@ -223,7 +242,7 @@ export class Create { // Validate maximum allocation quantity if (tempOptions.primary > ZosFilesConstants.MAX_ALLOC_QUANTITY) { - throw new ImperativeError({msg: ZosFilesMessages.maximumAllocationQuantityExceeded.message + " for 'primary'."}); + throw new ImperativeError({ msg: ZosFilesMessages.maximumAllocationQuantityExceeded.message + " for 'primary'." }); } break; @@ -235,7 +254,7 @@ export class Create { // Validate maximum allocation quantity if (tempOptions.secondary > ZosFilesConstants.MAX_ALLOC_QUANTITY) { - throw new ImperativeError({msg: ZosFilesMessages.maximumAllocationQuantityExceeded.message + " for 'secondary'."}); + throw new ImperativeError({ msg: ZosFilesMessages.maximumAllocationQuantityExceeded.message + " for 'secondary'." }); } break; @@ -255,7 +274,7 @@ export class Create { case "U": break; default: - throw new ImperativeError({msg: ZosFilesMessages.invalidRecfmOption.message + tempOptions.recfm}); + throw new ImperativeError({ msg: ZosFilesMessages.invalidRecfmOption.message + tempOptions.recfm }); } break; @@ -274,7 +293,7 @@ export class Create { break; default: - throw new ImperativeError({msg: ZosFilesMessages.invalidFilesCreateOption.message + option}); + throw new ImperativeError({ msg: ZosFilesMessages.invalidFilesCreateOption.message + option }); } } @@ -376,17 +395,17 @@ export class Create { ussPath: string, type: string, mode?: string) - : Promise { + : Promise { ImperativeExpect.toNotBeNullOrUndefined(type, ZosFilesMessages.missingRequestType.message); ImperativeExpect.toNotBeEqual(type, "", ZosFilesMessages.missingRequestType.message); ussPath = path.posix.normalize(ussPath); ussPath = ussPath.charAt(0) === "/" ? ussPath.substring(1) : ussPath; ussPath = encodeURIComponent(ussPath); const parameters: string = `${ZosFilesConstants.RESOURCE}${ZosFilesConstants.RES_USS_FILES}/${ussPath}`; - const headers: object[] = [ZosmfHeaders.X_CSRF_ZOSMF_HEADER, {"Content-Type": "application/json"}]; + const headers: object[] = [ZosmfHeaders.X_CSRF_ZOSMF_HEADER, { "Content-Type": "application/json" }]; let payload: object = { type }; - if(mode) { - payload = {...payload, ...{ mode }}; + if (mode) { + payload = { ...payload, ...{ mode } }; } const data = await ZosmfRestClient.postExpectString(session, parameters, headers, payload); @@ -419,7 +438,7 @@ export class Create { } const jsonContent = JSON.stringify(tempOptions); - const headers = [{"Content-Length": jsonContent.length}]; + const headers = [{ "Content-Length": jsonContent.length }]; const data = await ZosmfRestClient.postExpectString(session, endpoint, headers, jsonContent); @@ -460,7 +479,7 @@ export class Create { } // start with our default options, and override with any supplied options. - idcamsOptions = {...CreateDefaults.VSAM, ...idcamsOptions}; + idcamsOptions = { ...CreateDefaults.VSAM, ...idcamsOptions }; // when secondary is not specified, use 10% of primary if (isNullOrUndefined(idcamsOptions.secondary)) { @@ -580,7 +599,7 @@ export class Create { break; default: - throw new ImperativeError({msg: ZosFilesMessages.invalidFilesCreateOption.message + option}); + throw new ImperativeError({ msg: ZosFilesMessages.invalidFilesCreateOption.message + option }); } // end switch } @@ -650,7 +669,7 @@ export class Create { break; default: - throw new ImperativeError({msg: ZosFilesMessages.invalidFilesCreateOption.message + option}); + throw new ImperativeError({ msg: ZosFilesMessages.invalidFilesCreateOption.message + option }); } // end switch }