From 5de81462cc7b30ed58d9abb4de1a081298bbee14 Mon Sep 17 00:00:00 2001 From: EKhan Date: Mon, 10 Feb 2025 17:55:52 +0000 Subject: [PATCH 1/7] Added support for LTPA Signed-off-by: EKhan --- packages/vsce/CHANGELOG.md | 5 + .../trees/CICSSessionTree.unit.test.ts | 80 +++++----- .../trees/CICSSessionTreeLtpa.unit.test.ts | 90 +++++++++++ packages/vsce/src/extension.ts | 4 +- .../CICSCombinedLibraryTree.ts | 9 ++ .../CICSCombinedLocalFileTree.ts | 9 ++ .../CICSCombinedPipelineTree.ts | 9 ++ .../CICSCombinedProgramTree.ts | 9 ++ .../CICSCombinedTCPIPServiceTree.ts | 9 ++ .../CICSCombinedTrees/CICSCombinedTaskTree.ts | 9 ++ .../CICSCombinedTransactionTree.ts | 9 ++ .../CICSCombinedURIMapTree.ts | 9 ++ .../CICSCombinedWebServiceTree.ts | 9 ++ .../vsce/src/trees/CICSRegionsContainer.ts | 8 +- packages/vsce/src/trees/CICSSessionTree.ts | 11 +- packages/vsce/src/trees/CICSTree.ts | 149 ++++++++---------- packages/vsce/src/utils/profileManagement.ts | 10 +- packages/vsce/src/utils/profileUtils.ts | 34 ++++ 18 files changed, 343 insertions(+), 129 deletions(-) create mode 100644 packages/vsce/__tests__/__unit__/trees/CICSSessionTreeLtpa.unit.test.ts diff --git a/packages/vsce/CHANGELOG.md b/packages/vsce/CHANGELOG.md index b3f205b8..d16f39cc 100644 --- a/packages/vsce/CHANGELOG.md +++ b/packages/vsce/CHANGELOG.md @@ -2,7 +2,12 @@ All notable changes to the "cics-extension-for-zowe" extension will be documented in this file. +## Recent Changes + +- Enhancement: Use LTPA tokens to allow CMCI "sessions". [#217](https://github.com/zowe/cics-for-zowe-client/issues/217) + ## `3.3.3` + - BugFix: Duplicate CICSplex exist when connecting to a multi-CMAS system. [#227](https://github.com/zowe/cics-for-zowe-client/issues/227) - Enhancement: Show CMCI error response codes when failing to make requests. [#220](https://github.com/zowe/cics-for-zowe-client/issues/220) diff --git a/packages/vsce/__tests__/__unit__/trees/CICSSessionTree.unit.test.ts b/packages/vsce/__tests__/__unit__/trees/CICSSessionTree.unit.test.ts index f47c43d6..d013be24 100644 --- a/packages/vsce/__tests__/__unit__/trees/CICSSessionTree.unit.test.ts +++ b/packages/vsce/__tests__/__unit__/trees/CICSSessionTree.unit.test.ts @@ -11,67 +11,73 @@ const getIconFilePathFromNameMock = jest.fn(); +import { imperative } from "@zowe/zowe-explorer-api"; import { CICSPlexTree } from "../../../src/trees/CICSPlexTree"; import { CICSRegionTree } from "../../../src/trees/CICSRegionTree"; import { CICSSessionTree } from "../../../src/trees/CICSSessionTree"; import * as globalMocks from "../../__utils__/globalMocks"; + jest.mock("@zowe/zowe-explorer-api"); jest.mock("../../../src/utils/iconUtils", () => { return { getIconFilePathFromName: getIconFilePathFromNameMock }; }); -const cicsTreeMock = jest.fn(); +const cisutreeMock = jest.fn(); const treeResourceMock = globalMocks.getDummyTreeResources("cicsmanagedregion", "fileName*"); const profile = { profile: { user: "user", password: "pwd", hostname: "hostname", protocol: "https", type: "basic", rejectUnauthorized: false, port: 8080 }, }; describe("Test suite for CICSSessionTree", () => { let sut: CICSSessionTree; + let ses: imperative.Session; - beforeEach(() => { - getIconFilePathFromNameMock.mockReturnValue(treeResourceMock.iconPath); + describe("Validation", () => { - sut = new CICSSessionTree(profile); - sut.isUnauthorized = true; - expect(getIconFilePathFromNameMock).toHaveBeenCalledWith("profile-unverified"); - }); + beforeEach(() => { + getIconFilePathFromNameMock.mockReturnValue(treeResourceMock.iconPath); - afterEach(() => { - jest.resetAllMocks(); - }); + sut = new CICSSessionTree(profile); + sut.isUnauthorized = true; + expect(getIconFilePathFromNameMock).toHaveBeenCalledWith("profile-unverified"); + }); - describe("Test suite for addRegion", () => { - it("should push CICSRegionTree object into children", () => { - sut.addRegion(cicsTreeMock as any as CICSRegionTree); - expect(sut.getChildren().length).toBeGreaterThanOrEqual(1); + afterEach(() => { + jest.resetAllMocks(); }); - }); - describe("Test suite for addPlex", () => { - it("should push CICSPlexTree object into children", () => { - sut.addPlex(cicsTreeMock as any as CICSPlexTree); - expect(sut.getChildren().length).toBeGreaterThanOrEqual(1); + + describe("Test suite for addRegion", () => { + it("should push CICSRegionTree object into children", () => { + sut.addRegion(cisutreeMock as any as CICSRegionTree); + expect(sut.getChildren().length).toBeGreaterThanOrEqual(1); + }); }); - }); - describe("Test suite for getChildren", () => { - it("should return an array of childrens", () => { - expect(sut.getChildren().length).toBeGreaterThanOrEqual(0); + describe("Test suite for addPlex", () => { + it("should push CICSPlexTree object into children", () => { + sut.addPlex(cisutreeMock as any as CICSPlexTree); + expect(sut.getChildren().length).toBeGreaterThanOrEqual(1); + }); }); - }); - describe("Test suite for setUnauthorized", () => { - it("should set isUnauthorized to true", () => { - sut.setUnauthorized(); - expect(sut.isUnauthorized).toBeTruthy(); + describe("Test suite for getChildren", () => { + it("should return an array of childrens", () => { + expect(sut.getChildren().length).toBeGreaterThanOrEqual(0); + }); }); - }); - describe("Test suite for setAuthorized", () => { - it("should set isUnauthorized to false", () => { - sut.setAuthorized(); - expect(sut.isUnauthorized).toBeFalsy(); + describe("Test suite for setUnauthorized", () => { + it("should set isUnauthorized to true", () => { + sut.setUnauthorized(); + expect(sut.isUnauthorized).toBeTruthy(); + }); }); - }); - describe("Test suite for getIsUnauthorized", () => { - it("should return the object of isUnauthorized", () => { - expect(sut.getIsUnauthorized()).toBeTruthy(); + describe("Test suite for setAuthorized", () => { + it("should set isUnauthorized to false", () => { + sut.setAuthorized(); + expect(sut.isUnauthorized).toBeFalsy(); + }); + }); + describe("Test suite for getIsUnauthorized", () => { + it("should return the object of isUnauthorized", () => { + expect(sut.getIsUnauthorized()).toBeTruthy(); + }); }); }); }); diff --git a/packages/vsce/__tests__/__unit__/trees/CICSSessionTreeLtpa.unit.test.ts b/packages/vsce/__tests__/__unit__/trees/CICSSessionTreeLtpa.unit.test.ts new file mode 100644 index 00000000..9c1eacae --- /dev/null +++ b/packages/vsce/__tests__/__unit__/trees/CICSSessionTreeLtpa.unit.test.ts @@ -0,0 +1,90 @@ +/** + * 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. + * + */ + +const getIconFilePathFromNameMock = jest.fn(); + +import { imperative } from "@zowe/zowe-explorer-api"; +import { CICSSessionTree } from "../../../src/trees/CICSSessionTree"; + +jest.mock("../../../src/utils/iconUtils", () => { + return { getIconFilePathFromName: getIconFilePathFromNameMock }; +}); + +describe("Test suite for CICSSessionTree", () => { + let sut: CICSSessionTree; + let ses: imperative.Session; + + const cicsProfileMock = { + failNotFound: false, + message: "", + name: "A NAME", + profile: { + host: "a.b.c.d", + port: 12345, + rejectUnauthorized: false, + protocol: "http", + user: "A USER", + password: "A PASSWORD", + }, + type: "cics" + }; + + describe("cookies", () => { + + beforeEach(() => { + sut = new CICSSessionTree(cicsProfileMock); + }); + + afterEach(() => { + jest.resetAllMocks(); + }); + + it("Should not store invalid cookie", () => { + const cookie = { + Cookie: "blah=hello" + }; + + ses = sut.getSession(); + ses.storeCookie(cookie); + + expect(ses.ISession.tokenType).toEqual("LtpaToken2"); + expect(ses.ISession.tokenValue).toBeUndefined(); + }); + + it("Should store valid cookie", () => { + const cookies = { + Cookie: "LtpaToken2=testValue" + }; + + sut = new CICSSessionTree(cicsProfileMock); + ses = sut.getSession(); + + ses.storeCookie(cookies); + + expect(ses.ISession.tokenType).toEqual("LtpaToken2"); + expect(ses.ISession.tokenValue).toEqual("testValue"); + }); + + it("Should store valid cookie if more the one returned", () => { + const cookies = { + Cookie: "blah=hello;LtpaToken2=testValue" + }; + + sut = new CICSSessionTree(cicsProfileMock); + ses = sut.getSession(); + + ses.storeCookie(cookies); + + expect(ses.ISession.tokenType).toEqual("LtpaToken2"); + expect(ses.ISession.tokenValue).toEqual("testValue"); + }); + }); +}); diff --git a/packages/vsce/src/extension.ts b/packages/vsce/src/extension.ts index 1bc85d47..c55fa2ae 100644 --- a/packages/vsce/src/extension.ts +++ b/packages/vsce/src/extension.ts @@ -10,7 +10,6 @@ */ import { ExtensionContext, ProgressLocation, TreeItemCollapsibleState, window } from "vscode"; -import { CICSSessionTree } from "./trees/CICSSessionTree"; import { CICSTree } from "./trees/CICSTree"; import { plexExpansionHandler, regionContainerExpansionHandler, sessionExpansionHandler } from "./utils/expansionHandler"; import { ProfileManagement } from "./utils/profileManagement"; @@ -122,8 +121,7 @@ export async function activate(context: ExtensionContext) { try { plexExpansionHandler(node.element, treeDataProv); } catch (error) { - const newSessionTree = new CICSSessionTree(node.element.getParent().profile, getIconFilePathFromName("profile-disconnected")); - treeDataProv.loadedProfiles.splice(treeDataProv.getLoadedProfiles().indexOf(node.element.getParent()), 1, newSessionTree); + node.element.getParent().iconPath = getIconFilePathFromName("profile-disconnected"); treeDataProv._onDidChangeTreeData.fire(undefined); } }, diff --git a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedLibraryTree.ts b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedLibraryTree.ts index 25d71603..d7b8c277 100644 --- a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedLibraryTree.ts +++ b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedLibraryTree.ts @@ -60,6 +60,7 @@ export class CICSCombinedLibraryTree extends TreeItem { let count; const cacheTokenInfo = await ProfileManagement.generateCacheToken( this.parentPlex.getProfile(), + this.getSession(), this.parentPlex.getPlexName(), this.constant, criteria, @@ -72,6 +73,7 @@ export class CICSCombinedLibraryTree extends TreeItem { if (recordsCount <= this.incrementCount) { allLibraries = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, 1, @@ -80,6 +82,7 @@ export class CICSCombinedLibraryTree extends TreeItem { } else { allLibraries = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, 1, @@ -148,6 +151,7 @@ export class CICSCombinedLibraryTree extends TreeItem { } const cacheTokenInfo = await ProfileManagement.generateCacheToken( this.parentPlex.getProfile(), + this.getSession(), this.parentPlex.getPlexName(), this.constant, criteria, @@ -159,6 +163,7 @@ export class CICSCombinedLibraryTree extends TreeItem { const count = recordsCount; const allLibraries = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, this.currentCount + 1, @@ -203,4 +208,8 @@ export class CICSCombinedLibraryTree extends TreeItem { public getParent() { return this.parentPlex; } + + public getSession() { + return this.getParent().getParent().getSession(); + } } diff --git a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedLocalFileTree.ts b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedLocalFileTree.ts index a77ecfbd..3020eb47 100644 --- a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedLocalFileTree.ts +++ b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedLocalFileTree.ts @@ -60,6 +60,7 @@ export class CICSCombinedLocalFileTree extends TreeItem { try { const cacheTokenInfo = await ProfileManagement.generateCacheToken( this.parentPlex.getProfile(), + this.getSession(), this.parentPlex.getPlexName(), this.constant, criteria, @@ -72,6 +73,7 @@ export class CICSCombinedLocalFileTree extends TreeItem { if (recordsCount <= this.incrementCount) { allLocalFiles = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, 1, @@ -80,6 +82,7 @@ export class CICSCombinedLocalFileTree extends TreeItem { } else { allLocalFiles = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, 1, @@ -144,6 +147,7 @@ export class CICSCombinedLocalFileTree extends TreeItem { async () => { const cacheTokenInfo = await ProfileManagement.generateCacheToken( this.parentPlex.getProfile(), + this.getSession(), this.parentPlex.getPlexName(), this.constant, this.getParent().getGroupName(), @@ -154,6 +158,7 @@ export class CICSCombinedLocalFileTree extends TreeItem { const count = recordsCount; const allLocalFiles = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, this.currentCount + 1, @@ -198,4 +203,8 @@ export class CICSCombinedLocalFileTree extends TreeItem { public getParent() { return this.parentPlex; } + + public getSession() { + return this.getParent().getParent().getSession(); + } } diff --git a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedPipelineTree.ts b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedPipelineTree.ts index dd6405df..c724f6dc 100644 --- a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedPipelineTree.ts +++ b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedPipelineTree.ts @@ -60,6 +60,7 @@ export class CICSCombinedPipelineTree extends TreeItem { let count; const cacheTokenInfo = await ProfileManagement.generateCacheToken( this.parentPlex.getProfile(), + this.getSession(), this.parentPlex.getPlexName(), this.constant, criteria, @@ -72,6 +73,7 @@ export class CICSCombinedPipelineTree extends TreeItem { if (recordsCount <= this.incrementCount) { allPipelines = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, 1, @@ -80,6 +82,7 @@ export class CICSCombinedPipelineTree extends TreeItem { } else { allPipelines = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, 1, @@ -148,6 +151,7 @@ export class CICSCombinedPipelineTree extends TreeItem { } const cacheTokenInfo = await ProfileManagement.generateCacheToken( this.parentPlex.getProfile(), + this.getSession(), this.parentPlex.getPlexName(), this.constant, criteria, @@ -159,6 +163,7 @@ export class CICSCombinedPipelineTree extends TreeItem { const count = recordsCount; const allPipelines = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, this.currentCount + 1, @@ -203,4 +208,8 @@ export class CICSCombinedPipelineTree extends TreeItem { public getParent() { return this.parentPlex; } + + public getSession() { + return this.getParent().getParent().getSession(); + } } diff --git a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedProgramTree.ts b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedProgramTree.ts index c980e662..cb368bc5 100644 --- a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedProgramTree.ts +++ b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedProgramTree.ts @@ -63,6 +63,7 @@ export class CICSCombinedProgramTree extends TreeItem { let count; const cacheTokenInfo = await ProfileManagement.generateCacheToken( this.parentPlex.getProfile(), + this.getSession(), this.parentPlex.getPlexName(), this.constant, criteria, @@ -75,6 +76,7 @@ export class CICSCombinedProgramTree extends TreeItem { if (recordsCount <= this.incrementCount) { allPrograms = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, 1, @@ -83,6 +85,7 @@ export class CICSCombinedProgramTree extends TreeItem { } else { allPrograms = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, 1, @@ -160,6 +163,7 @@ export class CICSCombinedProgramTree extends TreeItem { } const cacheTokenInfo = await ProfileManagement.generateCacheToken( this.parentPlex.getProfile(), + this.getSession(), this.parentPlex.getPlexName(), this.constant, criteria, @@ -171,6 +175,7 @@ export class CICSCombinedProgramTree extends TreeItem { const count = recordsCount; const allPrograms = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, this.currentCount + 1, @@ -215,4 +220,8 @@ export class CICSCombinedProgramTree extends TreeItem { public getParent() { return this.parentPlex; } + + public getSession() { + return this.getParent().getParent().getSession(); + } } diff --git a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedTCPIPServiceTree.ts b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedTCPIPServiceTree.ts index 1d653089..f98e412a 100644 --- a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedTCPIPServiceTree.ts +++ b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedTCPIPServiceTree.ts @@ -60,6 +60,7 @@ export class CICSCombinedTCPIPServiceTree extends TreeItem { let count; const cacheTokenInfo = await ProfileManagement.generateCacheToken( this.parentPlex.getProfile(), + this.getSession(), this.parentPlex.getPlexName(), this.constant, criteria, @@ -72,6 +73,7 @@ export class CICSCombinedTCPIPServiceTree extends TreeItem { if (recordsCount <= this.incrementCount) { allTCPIPS = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, 1, @@ -80,6 +82,7 @@ export class CICSCombinedTCPIPServiceTree extends TreeItem { } else { allTCPIPS = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, 1, @@ -151,6 +154,7 @@ export class CICSCombinedTCPIPServiceTree extends TreeItem { } const cacheTokenInfo = await ProfileManagement.generateCacheToken( this.parentPlex.getProfile(), + this.getSession(), this.parentPlex.getPlexName(), this.constant, criteria, @@ -162,6 +166,7 @@ export class CICSCombinedTCPIPServiceTree extends TreeItem { const count = recordsCount; const allTCPIPS = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, this.currentCount + 1, @@ -206,4 +211,8 @@ export class CICSCombinedTCPIPServiceTree extends TreeItem { public getParent() { return this.parentPlex; } + + public getSession() { + return this.getParent().getParent().getSession(); + } } diff --git a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedTaskTree.ts b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedTaskTree.ts index ca7a638d..d9ebdb4b 100644 --- a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedTaskTree.ts +++ b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedTaskTree.ts @@ -60,6 +60,7 @@ export class CICSCombinedTaskTree extends TreeItem { let count; const cacheTokenInfo = await ProfileManagement.generateCacheToken( this.parentPlex.getProfile(), + this.getSession(), this.parentPlex.getPlexName(), this.constant, criteria, @@ -72,6 +73,7 @@ export class CICSCombinedTaskTree extends TreeItem { if (recordsCount <= this.incrementCount) { allTasks = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, 1, @@ -80,6 +82,7 @@ export class CICSCombinedTaskTree extends TreeItem { } else { allTasks = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, 1, @@ -149,6 +152,7 @@ export class CICSCombinedTaskTree extends TreeItem { async () => { const cacheTokenInfo = await ProfileManagement.generateCacheToken( this.parentPlex.getProfile(), + this.getSession(), this.parentPlex.getPlexName(), this.constant, this.getParent().getGroupName(), @@ -159,6 +163,7 @@ export class CICSCombinedTaskTree extends TreeItem { const count = recordsCount; const allTasks = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, this.currentCount + 1, @@ -200,4 +205,8 @@ export class CICSCombinedTaskTree extends TreeItem { // direct parent return this.parentPlex; } + + public getSession() { + return this.getParent().getParent().getSession(); + } } diff --git a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedTransactionTree.ts b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedTransactionTree.ts index 52b1ef7f..d1c1ad19 100644 --- a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedTransactionTree.ts +++ b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedTransactionTree.ts @@ -61,6 +61,7 @@ export class CICSCombinedTransactionsTree extends TreeItem { let count; const cacheTokenInfo = await ProfileManagement.generateCacheToken( this.parentPlex.getProfile(), + this.getSession(), this.parentPlex.getPlexName(), this.constant, criteria, @@ -73,6 +74,7 @@ export class CICSCombinedTransactionsTree extends TreeItem { if (recordsCount <= this.incrementCount) { allLocalTransactions = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, 1, @@ -81,6 +83,7 @@ export class CICSCombinedTransactionsTree extends TreeItem { } else { allLocalTransactions = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, 1, @@ -145,6 +148,7 @@ export class CICSCombinedTransactionsTree extends TreeItem { async () => { const cacheTokenInfo = await ProfileManagement.generateCacheToken( this.parentPlex.getProfile(), + this.getSession(), this.parentPlex.getPlexName(), this.constant, this.getParent().getGroupName(), @@ -155,6 +159,7 @@ export class CICSCombinedTransactionsTree extends TreeItem { const count = recordsCount; const allLocalTransactions = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, this.currentCount + 1, @@ -199,4 +204,8 @@ export class CICSCombinedTransactionsTree extends TreeItem { public getParent() { return this.parentPlex; } + + public getSession() { + return this.getParent().getParent().getSession(); + } } diff --git a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedURIMapTree.ts b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedURIMapTree.ts index f71143f6..1fe1f44c 100644 --- a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedURIMapTree.ts +++ b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedURIMapTree.ts @@ -60,6 +60,7 @@ export class CICSCombinedURIMapTree extends TreeItem { let count; const cacheTokenInfo = await ProfileManagement.generateCacheToken( this.parentPlex.getProfile(), + this.getSession(), this.parentPlex.getPlexName(), this.constant, criteria, @@ -72,6 +73,7 @@ export class CICSCombinedURIMapTree extends TreeItem { if (recordsCount <= this.incrementCount) { allURIMaps = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, 1, @@ -80,6 +82,7 @@ export class CICSCombinedURIMapTree extends TreeItem { } else { allURIMaps = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, 1, @@ -153,6 +156,7 @@ export class CICSCombinedURIMapTree extends TreeItem { } const cacheTokenInfo = await ProfileManagement.generateCacheToken( this.parentPlex.getProfile(), + this.getSession(), this.parentPlex.getPlexName(), this.constant, criteria, @@ -164,6 +168,7 @@ export class CICSCombinedURIMapTree extends TreeItem { const count = recordsCount; const allURIMaps = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, this.currentCount + 1, @@ -208,4 +213,8 @@ export class CICSCombinedURIMapTree extends TreeItem { public getParent() { return this.parentPlex; } + + public getSession() { + return this.getParent().getParent().getSession(); + } } diff --git a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedWebServiceTree.ts b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedWebServiceTree.ts index 431876e1..9d383968 100644 --- a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedWebServiceTree.ts +++ b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedWebServiceTree.ts @@ -60,6 +60,7 @@ export class CICSCombinedWebServiceTree extends TreeItem { let count; const cacheTokenInfo = await ProfileManagement.generateCacheToken( this.parentPlex.getProfile(), + this.getSession(), this.parentPlex.getPlexName(), this.constant, criteria, @@ -72,6 +73,7 @@ export class CICSCombinedWebServiceTree extends TreeItem { if (recordsCount <= this.incrementCount) { allWebServices = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, 1, @@ -80,6 +82,7 @@ export class CICSCombinedWebServiceTree extends TreeItem { } else { allWebServices = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, 1, @@ -149,6 +152,7 @@ export class CICSCombinedWebServiceTree extends TreeItem { } const cacheTokenInfo = await ProfileManagement.generateCacheToken( this.parentPlex.getProfile(), + this.getSession(), this.parentPlex.getPlexName(), this.constant, criteria, @@ -160,6 +164,7 @@ export class CICSCombinedWebServiceTree extends TreeItem { const count = recordsCount; const allWebServices = await ProfileManagement.getCachedResources( this.parentPlex.getProfile(), + this.getSession(), cacheTokenInfo.cacheToken, this.constant, this.currentCount + 1, @@ -204,4 +209,8 @@ export class CICSCombinedWebServiceTree extends TreeItem { public getParent() { return this.parentPlex; } + + public getSession() { + return this.getParent().getParent().getSession(); + } } diff --git a/packages/vsce/src/trees/CICSRegionsContainer.ts b/packages/vsce/src/trees/CICSRegionsContainer.ts index 4dd82fb0..bae8aa70 100644 --- a/packages/vsce/src/trees/CICSRegionsContainer.ts +++ b/packages/vsce/src/trees/CICSRegionsContainer.ts @@ -47,7 +47,7 @@ export class CICSRegionsContainer extends TreeItem { }, async (_, token) => { token.onCancellationRequested(() => {}); - const regionInfo = await ProfileManagement.getRegionInfoInPlex(this.parent); + const regionInfo = await ProfileManagement.getRegionInfoInPlex(this.parent, this.getSession()); this.addRegionsUtility(regionInfo); this.collapsibleState = TreeItemCollapsibleState.Expanded; this.iconPath = getFolderIcon(true); @@ -78,7 +78,7 @@ export class CICSRegionsContainer extends TreeItem { public async loadRegionsInPlex() { const parentPlex = this.getParent(); - const regionInfo = await ProfileManagement.getRegionInfoInPlex(parentPlex); + const regionInfo = await ProfileManagement.getRegionInfoInPlex(parentPlex, this.getSession()); if (regionInfo) { this.addRegionsUtility(regionInfo); // Keep container open after label change @@ -145,4 +145,8 @@ export class CICSRegionsContainer extends TreeItem { public clearChildren() { this.children = []; } + + public getSession() { + return this.getParent().getParent().getSession(); + } } diff --git a/packages/vsce/src/trees/CICSSessionTree.ts b/packages/vsce/src/trees/CICSSessionTree.ts index 05aa067b..aced9e75 100644 --- a/packages/vsce/src/trees/CICSSessionTree.ts +++ b/packages/vsce/src/trees/CICSSessionTree.ts @@ -14,6 +14,7 @@ import { CICSRegionTree } from "./CICSRegionTree"; import { CICSPlexTree } from "./CICSPlexTree"; import { imperative } from "@zowe/zowe-explorer-api"; import { getIconFilePathFromName } from "../utils/iconUtils"; +import { SessConstants } from "@zowe/imperative"; export class CICSSessionTree extends TreeItem { children: (CICSPlexTree | CICSRegionTree)[]; @@ -28,8 +29,11 @@ export class CICSSessionTree extends TreeItem { super(profile.name, TreeItemCollapsibleState.Collapsed); this.children = []; this.contextValue = `cicssession.${profile.name}`; + this.session = new imperative.Session({ - type: "basic", + type: SessConstants.AUTH_TYPE_TOKEN, + storeCookie: true, + tokenType: SessConstants.TOKEN_TYPE_LTPA, hostname: profile.profile!.host, port: Number(profile.profile!.port), user: profile.profile!.user || "", @@ -37,6 +41,7 @@ export class CICSSessionTree extends TreeItem { rejectUnauthorized: profile.profile!.rejectUnauthorized, protocol: profile.profile!.protocol, }); + this.profile = profile; this.isUnauthorized = undefined; } @@ -45,6 +50,10 @@ export class CICSSessionTree extends TreeItem { this.children.push(region); } + public clearChildren() { + this.children = []; + } + public addPlex(plex: CICSPlexTree) { this.children.push(plex); } diff --git a/packages/vsce/src/trees/CICSTree.ts b/packages/vsce/src/trees/CICSTree.ts index b7062256..a45243b3 100644 --- a/packages/vsce/src/trees/CICSTree.ts +++ b/packages/vsce/src/trees/CICSTree.ts @@ -30,7 +30,7 @@ import { import constants from "../utils/constants"; import { PersistentStorage } from "../utils/PersistentStorage"; import { InfoLoaded, ProfileManagement } from "../utils/profileManagement"; -import { missingSessionParameters, promptCredentials } from "../utils/profileUtils"; +import { updateProfile } from "../utils/profileUtils"; import { getIconFilePathFromName } from "../utils/iconUtils"; import { openConfigFile } from "../utils/workspaceUtils"; import { CICSPlexTree } from "./CICSPlexTree"; @@ -214,7 +214,7 @@ export class CICSTree implements TreeDataProvider { async loadProfile(profile?: imperative.IProfileLoaded, position?: number | undefined, sessionTree?: CICSSessionTree) { const persistentStorage = new PersistentStorage("zowe.cics.persistent"); await persistentStorage.addLoadedCICSProfile(profile.name); - let newSessionTree: CICSSessionTree; + window.withProgress( { title: "Load profile", @@ -230,98 +230,87 @@ export class CICSTree implements TreeDataProvider { try { const configInstance = await ProfileManagement.getConfigInstance(); if (configInstance.getTeamConfig().exists) { - let missingParamters = missingSessionParameters(profile.profile); - if (missingParamters.length) { - const userPass = ["user", "password"]; - if (missingParamters.includes(userPass[0]) || missingParamters.includes(userPass[1])) { - const updatedProfile = await promptCredentials(profile.name, true); - if (!updatedProfile) { - return; + // Initialise session tree + let plexInfo: InfoLoaded[]; + let retry = 0; + while (retry <= 1) { + try { + plexInfo = await ProfileManagement.getPlexInfo(profile, sessionTree.getSession()); + break; + } catch (error) { + if (error?.response?.status == constants.HTTP_ERROR_UNAUTHORIZED && retry === 0) { + retry = retry + 1; + const newProfile = await updateProfile(profile, sessionTree); + + if (!newProfile) { + return; + } + profile = newProfile; + } else { + throw error; } - profile = updatedProfile; - // Remove "user" and "password" from missing params array - missingParamters = missingParamters.filter((param) => userPass.indexOf(param) === -1); } - if (missingParamters.length) { - window.showInformationMessage( - `The following fields are missing from ${profile.name}: ${missingParamters.join(", ")}. Please update them in your config file.`, + } + + // For each InfoLoaded object - happens if there are multiple plexes + for (const item of plexInfo) { + // No plex + if (item.plexname === null) { + + const regionsObtained = await getResource(sessionTree.getSession(), { + name: "CICSRegion", + regionName: item.regions[0].applid, + }); + + // 200 OK received + sessionTree.setAuthorized(); + const newRegionTree = new CICSRegionTree( + item.regions[0].applid, + regionsObtained.response.records.cicsregion, + sessionTree, + undefined, + sessionTree, ); - return; - } - // If profile is expanded and it previously had 401 error code - } else if (sessionTree && sessionTree.getIsUnauthorized()) { - const updatedProfile = await promptCredentials(profile.name, true); - if (!updatedProfile) { - return; + sessionTree.clearChildren(); + sessionTree.addRegion(newRegionTree); + } else { + if (item.group) { + const newPlexTree = new CICSPlexTree(item.plexname, profile, sessionTree, profile.profile.regionName); + newPlexTree.setLabel(`${item.plexname} - ${profile.profile.regionName}`); + sessionTree.clearChildren(); + sessionTree.addPlex(newPlexTree); + } else { + //Plex + const newPlexTree = new CICSPlexTree(item.plexname, profile, sessionTree); + sessionTree.clearChildren(); + sessionTree.addPlex(newPlexTree); + } } - profile = updatedProfile; } - } - const plexInfo: InfoLoaded[] = await ProfileManagement.getPlexInfo(profile); - // Initialise session tree - newSessionTree = new CICSSessionTree(profile, getIconFilePathFromName("profile")); - // For each InfoLoaded object - happens if there are multiple plexes - for (const item of plexInfo) { - // No plex - if (item.plexname === null) { - const session = new imperative.Session({ - type: "basic", - hostname: profile.profile.host, - port: Number(profile.profile.port), - user: profile.profile.user, - password: profile.profile.password, - rejectUnauthorized: profile.profile.rejectUnauthorized, - protocol: profile.profile.protocol, - }); - const regionsObtained = await getResource(session, { - name: "CICSRegion", - regionName: item.regions[0].applid, - }); - // 200 OK received - newSessionTree.setAuthorized(); - const newRegionTree = new CICSRegionTree( - item.regions[0].applid, - regionsObtained.response.records.cicsregion, - newSessionTree, - undefined, - newSessionTree, - ); - newSessionTree.addRegion(newRegionTree); + // If method was called when expanding profile + if (sessionTree) { + this.loadedProfiles.splice(position, 1, sessionTree); + } + // If method was called when updating profile + else if (position || position === 0) { + this.loadedProfiles.splice(position, 0, sessionTree); } else { - if (item.group) { - const newPlexTree = new CICSPlexTree(item.plexname, profile, newSessionTree, profile.profile.regionName); - newPlexTree.setLabel(`${item.plexname} - ${profile.profile.regionName}`); - newSessionTree.addPlex(newPlexTree); - } else { - //Plex - const newPlexTree = new CICSPlexTree(item.plexname, profile, newSessionTree); - newSessionTree.addPlex(newPlexTree); - } + this.loadedProfiles.push(sessionTree); } + this._onDidChangeTreeData.fire(undefined); } - // If method was called when expanding profile - if (sessionTree) { - this.loadedProfiles.splice(position, 1, newSessionTree); - } - // If method was called when updating profile - else if (position || position === 0) { - this.loadedProfiles.splice(position, 0, newSessionTree); - } else { - this.loadedProfiles.push(newSessionTree); - } - this._onDidChangeTreeData.fire(undefined); } catch (error) { // Change session tree icon to disconnected upon error - newSessionTree = new CICSSessionTree(profile, getIconFilePathFromName("profile-disconnected")); + sessionTree = new CICSSessionTree(profile, getIconFilePathFromName("profile-disconnected")); // If method was called when expanding profile if (sessionTree) { - this.loadedProfiles.splice(position, 1, newSessionTree); + this.loadedProfiles.splice(position, 1, sessionTree); } // If method was called when updating profile else if (position || position === 0) { - this.loadedProfiles.splice(position, 0, newSessionTree); + this.loadedProfiles.splice(position, 0, sessionTree); } else { - this.loadedProfiles.push(newSessionTree); + this.loadedProfiles.push(sessionTree); } this._onDidChangeTreeData.fire(undefined); @@ -384,9 +373,9 @@ export class CICSTree implements TreeDataProvider { case constants.HTTP_ERROR_UNAUTHORIZED: window.showErrorMessage(`Error: Request failed with status code 401 for Profile '${profile.name}'`); // set the unauthorized flag to true for reprompting of credentials. - newSessionTree.setUnauthorized(); + sessionTree.setUnauthorized(); // Replace old profile tree with new disconnected profile tree item - this.loadedProfiles.splice(position, 1, newSessionTree); + this.loadedProfiles.splice(position, 1, sessionTree); break; case constants.HTTP_ERROR_NOT_FOUND: window.showErrorMessage(`Error: Request failed with status code 404 for Profile '${profile.name}' - Not Found`); diff --git a/packages/vsce/src/utils/profileManagement.ts b/packages/vsce/src/utils/profileManagement.ts index 2fe01a92..5190ca87 100644 --- a/packages/vsce/src/utils/profileManagement.ts +++ b/packages/vsce/src/utils/profileManagement.ts @@ -356,9 +356,7 @@ export class ProfileManagement { * @param profile * @returns Array of type InfoLoaded */ - public static async getPlexInfo(profile: imperative.IProfileLoaded): Promise { - - const session = this.getSessionFromProfile(profile.profile); + public static async getPlexInfo(profile: imperative.IProfileLoaded, session: Session): Promise { if (profile.profile.cicsPlex && profile.profile.regionName) { return this.regionPlexProvided(session, profile.profile); @@ -374,7 +372,7 @@ export class ProfileManagement { /** * Return all the regions in a given plex */ - public static async getRegionInfoInPlex(plex: CICSPlexTree): Promise { + public static async getRegionInfoInPlex(plex: CICSPlexTree, session: Session): Promise { try { const session = this.getSessionFromProfile(plex.getProfile().profile); const { resultsummary, records } = await this.runGetResource({ @@ -404,12 +402,12 @@ export class ProfileManagement { public static async generateCacheToken( profile: imperative.IProfileLoaded, + session: Session, plexName: string, resourceName: string, criteria?: string, group?: string ): Promise<{ cacheToken: string; recordCount: number; }> { - const session = this.getSessionFromProfile(profile.profile); try { const { response } = await getResource(session, { name: resourceName, @@ -436,11 +434,11 @@ export class ProfileManagement { public static async getCachedResources( profile: imperative.IProfileLoaded, + session: Session, cacheToken: string, resourceName: string, start = 1, increment = constants.RESOURCES_MAX) { - const session = this.getSessionFromProfile(profile.profile); const allItemsresponse = await getCache(session, { cacheToken, startIndex: start, diff --git a/packages/vsce/src/utils/profileUtils.ts b/packages/vsce/src/utils/profileUtils.ts index c0c767d5..b7cee3fe 100644 --- a/packages/vsce/src/utils/profileUtils.ts +++ b/packages/vsce/src/utils/profileUtils.ts @@ -12,6 +12,7 @@ import { ZoweVsCodeExtension, imperative } from "@zowe/zowe-explorer-api"; import { window } from "vscode"; import { ProfileManagement } from "./profileManagement"; +import { CICSSessionTree } from "../trees/CICSSessionTree"; export function missingSessionParameters(profileProfile: any): (string | undefined)[] { const params = ["host", "port", "user", "password", "rejectUnauthorized", "protocol"]; @@ -24,7 +25,40 @@ export function missingSessionParameters(profileProfile: any): (string | undefin return missing; } +export function missingUsernamePassword(missingParamters: any): boolean { + if (missingParamters.length > 0) { + const userPass = ["user", "password"]; + if (missingParamters.includes(userPass[0]) || missingParamters.includes(userPass[1])) { + return true; + } + } + + return false; +} + +export async function updateProfile(profile?: imperative.IProfileLoaded, sessionTree?: CICSSessionTree): Promise { + let missingParamters = missingSessionParameters(profile.profile); + if (missingUsernamePassword(missingParamters) || + // If profile is expanded and it previously had 401 error code + (sessionTree && sessionTree.getIsUnauthorized())) { + const updatedProfile = await promptCredentials(profile.name, true); + if (updatedProfile) { + profile = updatedProfile; + // Remove "user" and "password" from missing params array + missingParamters = missingParamters.filter((param) => ["user", "password"].indexOf(param) === -1); + } + + if (missingParamters.length) { + window.showInformationMessage( + `The following fields are missing from ${profile.name}: ${missingParamters.join(", ")}. Please update them in your config file.`, + ); + } else { + return profile; + } + } + return undefined; +} export async function promptCredentials(sessionName: string, rePrompt?: boolean): Promise { // const mProfileInfo = new ProfileInfo("zowe", { From f656ac1c24859cd1f39b8462cc54c1f08e17784c Mon Sep 17 00:00:00 2001 From: Andrew Twydell Date: Tue, 11 Feb 2025 12:33:11 +0000 Subject: [PATCH 2/7] loadProfile remove position arg & error handling Signed-off-by: Andrew Twydell --- packages/vsce/src/trees/CICSSessionTree.ts | 5 + packages/vsce/src/trees/CICSTree.ts | 129 ++------------------ packages/vsce/src/utils/expansionHandler.ts | 2 +- 3 files changed, 19 insertions(+), 117 deletions(-) diff --git a/packages/vsce/src/trees/CICSSessionTree.ts b/packages/vsce/src/trees/CICSSessionTree.ts index aced9e75..7daa682e 100644 --- a/packages/vsce/src/trees/CICSSessionTree.ts +++ b/packages/vsce/src/trees/CICSSessionTree.ts @@ -68,6 +68,7 @@ export class CICSSessionTree extends TreeItem { public setUnauthorized() { this.isUnauthorized = true; + this.iconPath = getIconFilePathFromName("profile-disconnected"); } public setAuthorized() { @@ -81,4 +82,8 @@ export class CICSSessionTree extends TreeItem { public getParent(): null { return null; } + + public setIsExpanded(isExpanded: boolean) { + this.collapsibleState = isExpanded ? TreeItemCollapsibleState.Expanded : TreeItemCollapsibleState.Collapsed; + } } diff --git a/packages/vsce/src/trees/CICSTree.ts b/packages/vsce/src/trees/CICSTree.ts index a45243b3..b6f34eec 100644 --- a/packages/vsce/src/trees/CICSTree.ts +++ b/packages/vsce/src/trees/CICSTree.ts @@ -10,7 +10,6 @@ */ import { FilterDescriptor } from "../utils/filterUtils"; -import { findSelectedNodes } from "../utils/commandUtils"; import { getResource } from "@zowe/cics-for-zowe-sdk"; import { Gui, imperative, FileManagement, ZoweVsCodeExtension } from "@zowe/zowe-explorer-api"; import { @@ -31,7 +30,6 @@ import constants from "../utils/constants"; import { PersistentStorage } from "../utils/PersistentStorage"; import { InfoLoaded, ProfileManagement } from "../utils/profileManagement"; import { updateProfile } from "../utils/profileUtils"; -import { getIconFilePathFromName } from "../utils/iconUtils"; import { openConfigFile } from "../utils/workspaceUtils"; import { CICSPlexTree } from "./CICSPlexTree"; import { CICSRegionTree } from "./CICSRegionTree"; @@ -211,7 +209,7 @@ export class CICSTree implements TreeDataProvider { * to replace position of current CICSSessionTree. * @param sessionTree current CICSSessionTree only passed in if expanding a profile */ - async loadProfile(profile?: imperative.IProfileLoaded, position?: number | undefined, sessionTree?: CICSSessionTree) { + async loadProfile(profile: imperative.IProfileLoaded, sessionTree: CICSSessionTree) { const persistentStorage = new PersistentStorage("zowe.cics.persistent"); await persistentStorage.addLoadedCICSProfile(profile.name); @@ -231,14 +229,20 @@ export class CICSTree implements TreeDataProvider { const configInstance = await ProfileManagement.getConfigInstance(); if (configInstance.getTeamConfig().exists) { // Initialise session tree - let plexInfo: InfoLoaded[]; + let plexInfo: InfoLoaded[]; let retry = 0; while (retry <= 1) { try { plexInfo = await ProfileManagement.getPlexInfo(profile, sessionTree.getSession()); break; } catch (error) { - if (error?.response?.status == constants.HTTP_ERROR_UNAUTHORIZED && retry === 0) { + if ( + retry === 0 && + ( + error?.mDetails?.errorCode === constants.HTTP_ERROR_UNAUTHORIZED || + error?.response?.status == constants.HTTP_ERROR_UNAUTHORIZED + ) + ) { retry = retry + 1; const newProfile = await updateProfile(profile, sessionTree); @@ -246,6 +250,7 @@ export class CICSTree implements TreeDataProvider { return; } profile = newProfile; + } else { throw error; } @@ -277,125 +282,20 @@ export class CICSTree implements TreeDataProvider { if (item.group) { const newPlexTree = new CICSPlexTree(item.plexname, profile, sessionTree, profile.profile.regionName); newPlexTree.setLabel(`${item.plexname} - ${profile.profile.regionName}`); - sessionTree.clearChildren(); sessionTree.addPlex(newPlexTree); } else { //Plex const newPlexTree = new CICSPlexTree(item.plexname, profile, sessionTree); - sessionTree.clearChildren(); sessionTree.addPlex(newPlexTree); } } } - // If method was called when expanding profile - if (sessionTree) { - this.loadedProfiles.splice(position, 1, sessionTree); - } - // If method was called when updating profile - else if (position || position === 0) { - this.loadedProfiles.splice(position, 0, sessionTree); - } else { - this.loadedProfiles.push(sessionTree); - } this._onDidChangeTreeData.fire(undefined); } } catch (error) { - // Change session tree icon to disconnected upon error - sessionTree = new CICSSessionTree(profile, getIconFilePathFromName("profile-disconnected")); - // If method was called when expanding profile - if (sessionTree) { - this.loadedProfiles.splice(position, 1, sessionTree); - } - // If method was called when updating profile - else if (position || position === 0) { - this.loadedProfiles.splice(position, 0, sessionTree); - } else { - this.loadedProfiles.push(sessionTree); - } + sessionTree.setUnauthorized(); + sessionTree.setIsExpanded(false); this._onDidChangeTreeData.fire(undefined); - - if (typeof error === "object") { - if ("code" in error) { - switch (error.code) { - case "ETIMEDOUT": - window.showErrorMessage(`Error: connect ETIMEDOUT ${profile.profile.host}:${profile.profile.port} (${profile.name})`); - break; - case "ENOTFOUND": - window.showErrorMessage(`Error: getaddrinfo ENOTFOUND ${profile.profile.host}:${profile.profile.port} (${profile.name})`); - break; - case "ECONNRESET": - window.showErrorMessage(`Error: socket hang up ${profile.profile.host}:${profile.profile.port} (${profile.name})`); - break; - case "EPROTO": - window.showErrorMessage(`Error: write EPROTO ${profile.profile.host}:${profile.profile.port} (${profile.name})`); - break; - case "DEPTH_ZERO_SELF_SIGNED_CERT": - case "SELF_SIGNED_CERT_IN_CHAIN": - case "ERR_TLS_CERT_ALTNAME_INVALID": - case "CERT_HAS_EXPIRED": - // If re-expanding a profile that has an expired certificate - if (sessionTree) { - const decision = await window.showInformationMessage( - `Warning: Your connection is not private (${error.code}) - ` + - `would you still like to proceed to ${profile.profile.host} (unsafe)?`, - ...["Yes", "No"], - ); - if (decision) { - if (decision === "Yes") { - const configInstance = await ProfileManagement.getConfigInstance(); - let updatedProfile; - if (configInstance.getTeamConfig().exists) { - const upd = { profileName: profile.name, profileType: "cics" }; - // const configInstance = await ProfileManagement.getConfigInstance(); - // flip rejectUnauthorized to false - await configInstance.updateProperty({ ...upd, property: "rejectUnauthorized", value: false }); - updatedProfile = await ProfileManagement.getProfilesCache().getLoadedProfConfig(profile.name); - } else { - await ProfileManagement.profilesCacheRefresh(); - updatedProfile = await ProfileManagement.getProfilesCache().loadNamedProfile(profile.name, "cics"); - } - await this.removeSession(sessionTree, updatedProfile, position); - } - } - } - break; - default: - window.showErrorMessage( - `Error: An error has occurred ${profile.profile.host}:${profile.profile.port} (${profile.name}) - ${JSON.stringify( - error, - Object.getOwnPropertyNames(error), - ).replace(/(\\n\t|\\n|\\t)/gm, " ")}`, - ); - } - } else if ("response" in error) { - if (error.response !== "undefined" && error.response.status) { - switch (error.response.status) { - case constants.HTTP_ERROR_UNAUTHORIZED: - window.showErrorMessage(`Error: Request failed with status code 401 for Profile '${profile.name}'`); - // set the unauthorized flag to true for reprompting of credentials. - sessionTree.setUnauthorized(); - // Replace old profile tree with new disconnected profile tree item - this.loadedProfiles.splice(position, 1, sessionTree); - break; - case constants.HTTP_ERROR_NOT_FOUND: - window.showErrorMessage(`Error: Request failed with status code 404 for Profile '${profile.name}' - Not Found`); - break; - case constants.HTTP_ERROR_SERVER_ERROR: - window.showErrorMessage(`Error: Request failed with status code 500 for Profile '${profile.name}'`); - break; - default: - window.showErrorMessage(`Error: Request failed with status code ${error.response.status} for Profile '${profile.name}'`); - } - } else { - window.showErrorMessage( - `Error: An error has occurred ${profile.profile.host}:${profile.profile.port} (${profile.name}) - ${JSON.stringify( - error, - Object.getOwnPropertyNames(error), - ).replace(/(\\n\t|\\n|\\t)/gm, " ")}`, - ); - } - } - } } }, ); @@ -432,13 +332,10 @@ export class CICSTree implements TreeDataProvider { this._onDidChangeTreeData.fire(undefined); } - async removeSession(session: CICSSessionTree, profile?: imperative.IProfileLoaded, position?: number) { + async removeSession(session: CICSSessionTree) { const persistentStorage = new PersistentStorage("zowe.cics.persistent"); await persistentStorage.removeLoadedCICSProfile(session.label.toString()); this.loadedProfiles = this.loadedProfiles.filter((p) => p.profile.name !== session.label?.toString()); - if (profile && position !== undefined) { - await this.loadProfile(profile, position); - } this._onDidChangeTreeData.fire(undefined); } diff --git a/packages/vsce/src/utils/expansionHandler.ts b/packages/vsce/src/utils/expansionHandler.ts index dd847209..83d28750 100644 --- a/packages/vsce/src/utils/expansionHandler.ts +++ b/packages/vsce/src/utils/expansionHandler.ts @@ -22,7 +22,7 @@ export async function sessionExpansionHandler(session: CICSSessionTree, tree: CI if (profile == null) { throw new Error("sessionExpansionHandler: Profile is not defined"); } - await tree.loadProfile(profile, tree.getLoadedProfiles().indexOf(session), session); + await tree.loadProfile(profile, session); } export function regionContainerExpansionHandler(regionContiner: CICSRegionsContainer, tree: CICSTree) { From 4b737cb8f38a4704e34ea6d3b29f2a0356ecdc92 Mon Sep 17 00:00:00 2001 From: EKhan Date: Tue, 11 Feb 2025 13:24:06 +0000 Subject: [PATCH 3/7] Update to fix some errors Signed-off-by: EKhan --- packages/vsce/src/trees/CICSSessionTree.ts | 2 +- packages/vsce/src/utils/profileManagement.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/vsce/src/trees/CICSSessionTree.ts b/packages/vsce/src/trees/CICSSessionTree.ts index 7daa682e..3150641c 100644 --- a/packages/vsce/src/trees/CICSSessionTree.ts +++ b/packages/vsce/src/trees/CICSSessionTree.ts @@ -24,7 +24,7 @@ export class CICSSessionTree extends TreeItem { constructor( profile: any, - public readonly iconPath = getIconFilePathFromName("profile-unverified"), + public iconPath = getIconFilePathFromName("profile-unverified"), ) { super(profile.name, TreeItemCollapsibleState.Collapsed); this.children = []; diff --git a/packages/vsce/src/utils/profileManagement.ts b/packages/vsce/src/utils/profileManagement.ts index 5190ca87..69b4c78b 100644 --- a/packages/vsce/src/utils/profileManagement.ts +++ b/packages/vsce/src/utils/profileManagement.ts @@ -374,7 +374,6 @@ export class ProfileManagement { */ public static async getRegionInfoInPlex(plex: CICSPlexTree, session: Session): Promise { try { - const session = this.getSessionFromProfile(plex.getProfile().profile); const { resultsummary, records } = await this.runGetResource({ session, resourceName: CicsCmciConstants.CICS_CMCI_MANAGED_REGION, From c1bfa61605cdec09aff6d24d6b04367462768baa Mon Sep 17 00:00:00 2001 From: EKhan Date: Tue, 11 Feb 2025 13:31:40 +0000 Subject: [PATCH 4/7] Update Signed-off-by: EKhan --- packages/vsce/src/trees/CICSSessionTree.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/vsce/src/trees/CICSSessionTree.ts b/packages/vsce/src/trees/CICSSessionTree.ts index 3150641c..93b9a18b 100644 --- a/packages/vsce/src/trees/CICSSessionTree.ts +++ b/packages/vsce/src/trees/CICSSessionTree.ts @@ -21,11 +21,9 @@ export class CICSSessionTree extends TreeItem { session: imperative.Session; profile: any; isUnauthorized: boolean | undefined; + iconPath = getIconFilePathFromName("profile-unverified"); - constructor( - profile: any, - public iconPath = getIconFilePathFromName("profile-unverified"), - ) { + constructor(profile: any) { super(profile.name, TreeItemCollapsibleState.Collapsed); this.children = []; this.contextValue = `cicssession.${profile.name}`; @@ -73,6 +71,7 @@ export class CICSSessionTree extends TreeItem { public setAuthorized() { this.isUnauthorized = false; + this.iconPath = getIconFilePathFromName("profile-unverified"); } public getIsUnauthorized() { From 8a4a9bf9d10393257e3fe8d38b25210c311f454a Mon Sep 17 00:00:00 2001 From: EKhan Date: Tue, 11 Feb 2025 13:55:01 +0000 Subject: [PATCH 5/7] Some cleanup Signed-off-by: EKhan --- .../src/trees/CICSCombinedTrees/CICSCombinedLibraryTree.ts | 2 +- .../trees/CICSCombinedTrees/CICSCombinedLocalFileTree.ts | 2 +- .../src/trees/CICSCombinedTrees/CICSCombinedPipelineTree.ts | 2 +- .../src/trees/CICSCombinedTrees/CICSCombinedProgramTree.ts | 2 +- .../trees/CICSCombinedTrees/CICSCombinedTCPIPServiceTree.ts | 2 +- .../src/trees/CICSCombinedTrees/CICSCombinedTaskTree.ts | 2 +- .../trees/CICSCombinedTrees/CICSCombinedTransactionTree.ts | 2 +- .../src/trees/CICSCombinedTrees/CICSCombinedURIMapTree.ts | 2 +- .../trees/CICSCombinedTrees/CICSCombinedWebServiceTree.ts | 2 +- packages/vsce/src/trees/CICSPlexTree.ts | 4 ++++ packages/vsce/src/trees/CICSRegionsContainer.ts | 6 +++--- packages/vsce/src/utils/profileManagement.ts | 3 ++- 12 files changed, 18 insertions(+), 13 deletions(-) diff --git a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedLibraryTree.ts b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedLibraryTree.ts index d7b8c277..a688e862 100644 --- a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedLibraryTree.ts +++ b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedLibraryTree.ts @@ -210,6 +210,6 @@ export class CICSCombinedLibraryTree extends TreeItem { } public getSession() { - return this.getParent().getParent().getSession(); + return this.getParent().getSession(); } } diff --git a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedLocalFileTree.ts b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedLocalFileTree.ts index 3020eb47..97908d07 100644 --- a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedLocalFileTree.ts +++ b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedLocalFileTree.ts @@ -205,6 +205,6 @@ export class CICSCombinedLocalFileTree extends TreeItem { } public getSession() { - return this.getParent().getParent().getSession(); + return this.getParent().getSession(); } } diff --git a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedPipelineTree.ts b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedPipelineTree.ts index c724f6dc..1ce8582b 100644 --- a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedPipelineTree.ts +++ b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedPipelineTree.ts @@ -210,6 +210,6 @@ export class CICSCombinedPipelineTree extends TreeItem { } public getSession() { - return this.getParent().getParent().getSession(); + return this.getParent().getSession(); } } diff --git a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedProgramTree.ts b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedProgramTree.ts index cb368bc5..182d8e2f 100644 --- a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedProgramTree.ts +++ b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedProgramTree.ts @@ -222,6 +222,6 @@ export class CICSCombinedProgramTree extends TreeItem { } public getSession() { - return this.getParent().getParent().getSession(); + return this.getParent().getSession(); } } diff --git a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedTCPIPServiceTree.ts b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedTCPIPServiceTree.ts index f98e412a..be59ab65 100644 --- a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedTCPIPServiceTree.ts +++ b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedTCPIPServiceTree.ts @@ -213,6 +213,6 @@ export class CICSCombinedTCPIPServiceTree extends TreeItem { } public getSession() { - return this.getParent().getParent().getSession(); + return this.getParent().getSession(); } } diff --git a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedTaskTree.ts b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedTaskTree.ts index d9ebdb4b..355a8600 100644 --- a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedTaskTree.ts +++ b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedTaskTree.ts @@ -207,6 +207,6 @@ export class CICSCombinedTaskTree extends TreeItem { } public getSession() { - return this.getParent().getParent().getSession(); + return this.getParent().getSession(); } } diff --git a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedTransactionTree.ts b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedTransactionTree.ts index d1c1ad19..2ff4ece1 100644 --- a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedTransactionTree.ts +++ b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedTransactionTree.ts @@ -206,6 +206,6 @@ export class CICSCombinedTransactionsTree extends TreeItem { } public getSession() { - return this.getParent().getParent().getSession(); + return this.getParent().getSession(); } } diff --git a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedURIMapTree.ts b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedURIMapTree.ts index 1fe1f44c..b25637f0 100644 --- a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedURIMapTree.ts +++ b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedURIMapTree.ts @@ -215,6 +215,6 @@ export class CICSCombinedURIMapTree extends TreeItem { } public getSession() { - return this.getParent().getParent().getSession(); + return this.getParent().getSession(); } } diff --git a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedWebServiceTree.ts b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedWebServiceTree.ts index 9d383968..2fc7e590 100644 --- a/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedWebServiceTree.ts +++ b/packages/vsce/src/trees/CICSCombinedTrees/CICSCombinedWebServiceTree.ts @@ -211,6 +211,6 @@ export class CICSCombinedWebServiceTree extends TreeItem { } public getSession() { - return this.getParent().getParent().getSession(); + return this.getParent().getSession(); } } diff --git a/packages/vsce/src/trees/CICSPlexTree.ts b/packages/vsce/src/trees/CICSPlexTree.ts index 33e28ff4..25436348 100644 --- a/packages/vsce/src/trees/CICSPlexTree.ts +++ b/packages/vsce/src/trees/CICSPlexTree.ts @@ -178,4 +178,8 @@ export class CICSPlexTree extends TreeItem { public getGroupName() { return this.groupName; } + + getSession() { + return this.parent.getSession(); + } } diff --git a/packages/vsce/src/trees/CICSRegionsContainer.ts b/packages/vsce/src/trees/CICSRegionsContainer.ts index bae8aa70..a88a135b 100644 --- a/packages/vsce/src/trees/CICSRegionsContainer.ts +++ b/packages/vsce/src/trees/CICSRegionsContainer.ts @@ -47,7 +47,7 @@ export class CICSRegionsContainer extends TreeItem { }, async (_, token) => { token.onCancellationRequested(() => {}); - const regionInfo = await ProfileManagement.getRegionInfoInPlex(this.parent, this.getSession()); + const regionInfo = await ProfileManagement.getRegionInfoInPlex(this.parent); this.addRegionsUtility(regionInfo); this.collapsibleState = TreeItemCollapsibleState.Expanded; this.iconPath = getFolderIcon(true); @@ -78,7 +78,7 @@ export class CICSRegionsContainer extends TreeItem { public async loadRegionsInPlex() { const parentPlex = this.getParent(); - const regionInfo = await ProfileManagement.getRegionInfoInPlex(parentPlex, this.getSession()); + const regionInfo = await ProfileManagement.getRegionInfoInPlex(parentPlex); if (regionInfo) { this.addRegionsUtility(regionInfo); // Keep container open after label change @@ -147,6 +147,6 @@ export class CICSRegionsContainer extends TreeItem { } public getSession() { - return this.getParent().getParent().getSession(); + return this.getParent().getSession(); } } diff --git a/packages/vsce/src/utils/profileManagement.ts b/packages/vsce/src/utils/profileManagement.ts index 69b4c78b..4b13e148 100644 --- a/packages/vsce/src/utils/profileManagement.ts +++ b/packages/vsce/src/utils/profileManagement.ts @@ -372,8 +372,9 @@ export class ProfileManagement { /** * Return all the regions in a given plex */ - public static async getRegionInfoInPlex(plex: CICSPlexTree, session: Session): Promise { + public static async getRegionInfoInPlex(plex: CICSPlexTree): Promise { try { + let session: Session = plex.getSession(); const { resultsummary, records } = await this.runGetResource({ session, resourceName: CicsCmciConstants.CICS_CMCI_MANAGED_REGION, From 901475bfdfc14b896f26055231c3ff900f5879b2 Mon Sep 17 00:00:00 2001 From: EKhan Date: Tue, 11 Feb 2025 14:17:30 +0000 Subject: [PATCH 6/7] Update to fix lint error Signed-off-by: EKhan --- packages/vsce/src/utils/profileManagement.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vsce/src/utils/profileManagement.ts b/packages/vsce/src/utils/profileManagement.ts index 4b13e148..156d65f0 100644 --- a/packages/vsce/src/utils/profileManagement.ts +++ b/packages/vsce/src/utils/profileManagement.ts @@ -374,7 +374,7 @@ export class ProfileManagement { */ public static async getRegionInfoInPlex(plex: CICSPlexTree): Promise { try { - let session: Session = plex.getSession(); + const session: Session = plex.getSession(); const { resultsummary, records } = await this.runGetResource({ session, resourceName: CicsCmciConstants.CICS_CMCI_MANAGED_REGION, From 22fb9a1791842a3274286123e7887609b10c5a0e Mon Sep 17 00:00:00 2001 From: EKhan Date: Thu, 13 Feb 2025 10:54:31 +0000 Subject: [PATCH 7/7] Some more cleanup Signed-off-by: EKhan --- packages/vsce/src/trees/CICSTree.ts | 11 +++-------- packages/vsce/src/utils/errorUtils.ts | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 packages/vsce/src/utils/errorUtils.ts diff --git a/packages/vsce/src/trees/CICSTree.ts b/packages/vsce/src/trees/CICSTree.ts index b6f34eec..31dba623 100644 --- a/packages/vsce/src/trees/CICSTree.ts +++ b/packages/vsce/src/trees/CICSTree.ts @@ -34,6 +34,7 @@ import { openConfigFile } from "../utils/workspaceUtils"; import { CICSPlexTree } from "./CICSPlexTree"; import { CICSRegionTree } from "./CICSRegionTree"; import { CICSSessionTree } from "./CICSSessionTree"; +import { getErrorCode } from "../utils/errorUtils"; export class CICSTree implements TreeDataProvider { loadedProfiles: CICSSessionTree[] = []; @@ -236,14 +237,8 @@ export class CICSTree implements TreeDataProvider { plexInfo = await ProfileManagement.getPlexInfo(profile, sessionTree.getSession()); break; } catch (error) { - if ( - retry === 0 && - ( - error?.mDetails?.errorCode === constants.HTTP_ERROR_UNAUTHORIZED || - error?.response?.status == constants.HTTP_ERROR_UNAUTHORIZED - ) - ) { - retry = retry + 1; + if (retry === 0 && getErrorCode(error) === constants.HTTP_ERROR_UNAUTHORIZED) { + retry++; const newProfile = await updateProfile(profile, sessionTree); if (!newProfile) { diff --git a/packages/vsce/src/utils/errorUtils.ts b/packages/vsce/src/utils/errorUtils.ts new file mode 100644 index 00000000..632880b7 --- /dev/null +++ b/packages/vsce/src/utils/errorUtils.ts @@ -0,0 +1,14 @@ +/** + * 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 function getErrorCode(error: any) { + return error.mDetails?.errorCode || error.response?.status; +}