Skip to content

Commit

Permalink
Merge pull request #766 from zowe/add-like-param
Browse files Browse the repository at this point in the history
Implementation of new "like" parameter for data set creation
  • Loading branch information
zFernand0 authored Jul 30, 2020
2 parents 2a8805c + c4fa836 commit 071584c
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 27 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
8 changes: 8 additions & 0 deletions packages/zosfiles/src/api/constants/ZosFiles.messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
67 changes: 43 additions & 24 deletions packages/zosfiles/src/api/methods/create/Create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,27 +56,27 @@ 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;
break;
}

if (!validCmdType) {
throw new ImperativeError({msg: ZosFilesMessages.unsupportedDatasetType.message});
throw new ImperativeError({ msg: ZosFilesMessages.unsupportedDatasetType.message });
} else {
try {
// Handle the size option
Expand Down Expand Up @@ -134,6 +134,25 @@ export class Create {
}
}

public static async dataSetLike(session: AbstractSession, dataSetName: string, likeDataSetName: string): Promise<IZosFilesResponse> {
// 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
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;

Expand All @@ -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;
Expand All @@ -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;

Expand All @@ -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;

Expand All @@ -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;

Expand All @@ -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 });

}
}
Expand Down Expand Up @@ -376,17 +395,17 @@ export class Create {
ussPath: string,
type: string,
mode?: string)
: Promise<IZosFilesResponse> {
: Promise<IZosFilesResponse> {
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);

Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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
}
Expand Down

0 comments on commit 071584c

Please sign in to comment.