From c7d4ff9c362987b6aae6aac0fcef7bb0136177e0 Mon Sep 17 00:00:00 2001 From: amitjoshi438 <54068463+amitjoshi438@users.noreply.github.com> Date: Fri, 22 Nov 2024 14:09:09 +0530 Subject: [PATCH] Add environment list retrieval and refactor BAP endpoint logic (#1060) * Add environment list retrieval and refactor BAP endpoint logic * Add type annotation for environment list retrieval in Utils.ts * Update src/common/utilities/Utils.ts Co-authored-by: Priyanshu Agrawal * Refactor BAP environment list URL to use a variable for API version and update imports in Utils.ts --------- Co-authored-by: amitjoshi Co-authored-by: Priyanshu Agrawal --- src/common/services/BAPService.ts | 29 ++------- src/common/services/Constants.ts | 1 + src/common/services/TelemetryConstants.ts | 2 + src/common/utilities/Utils.ts | 74 +++++++++++++++++++++++ 4 files changed, 82 insertions(+), 24 deletions(-) diff --git a/src/common/services/BAPService.ts b/src/common/services/BAPService.ts index fb26251aa..bcfb51310 100644 --- a/src/common/services/BAPService.ts +++ b/src/common/services/BAPService.ts @@ -5,9 +5,10 @@ import { ITelemetry } from "../OneDSLoggerTelemetry/telemetry/ITelemetry"; import { bapServiceAuthentication, getCommonHeaders } from "./AuthenticationProvider"; -import { VSCODE_EXTENSION_GET_BAP_ENDPOINT_UNSUPPORTED_REGION, VSCODE_EXTENSION_GET_CROSS_GEO_DATA_MOVEMENT_ENABLED_FLAG_COMPLETED, VSCODE_EXTENSION_GET_CROSS_GEO_DATA_MOVEMENT_ENABLED_FLAG_FAILED } from "./TelemetryConstants"; +import { VSCODE_EXTENSION_GET_CROSS_GEO_DATA_MOVEMENT_ENABLED_FLAG_COMPLETED, VSCODE_EXTENSION_GET_CROSS_GEO_DATA_MOVEMENT_ENABLED_FLAG_FAILED } from "./TelemetryConstants"; import { ServiceEndpointCategory, BAP_API_VERSION, BAP_SERVICE_COPILOT_CROSS_GEO_FLAG_RELATIVE_URL, BAP_SERVICE_ENDPOINT } from "./Constants"; import { sendTelemetryEvent } from "../copilot/telemetry/copilotTelemetry"; +import { getBAPEndpoint } from "../utilities/Utils"; export class BAPService { public static async getCrossGeoCopilotDataMovementEnabledFlag(serviceEndpointStamp: ServiceEndpointCategory, telemetry: ITelemetry, environmentId: string): Promise { @@ -15,7 +16,7 @@ export class BAPService { try { const accessToken = await bapServiceAuthentication(telemetry, true); - const response = await fetch(await BAPService.getBAPEndpoint(serviceEndpointStamp, telemetry, environmentId), { + const response = await fetch(await BAPService.getBAPCopilotCrossGeoFlagEndpoint(serviceEndpointStamp, telemetry, environmentId), { method: 'GET', headers: getCommonHeaders(accessToken) }); @@ -33,29 +34,9 @@ export class BAPService { return false; } - static async getBAPEndpoint(serviceEndpointStamp: ServiceEndpointCategory, telemetry: ITelemetry, environmentId: string): Promise { + static async getBAPCopilotCrossGeoFlagEndpoint(serviceEndpointStamp: ServiceEndpointCategory, telemetry: ITelemetry, environmentId: string): Promise { - let bapEndpoint = ""; - - switch (serviceEndpointStamp) { - case ServiceEndpointCategory.TEST: - bapEndpoint = "https://test.api.bap.microsoft.com"; - break; - case ServiceEndpointCategory.PREPROD: - bapEndpoint = "https://preprod.api.bap.microsoft.com"; - break; - case ServiceEndpointCategory.PROD: - bapEndpoint = "https://api.bap.microsoft.com"; - break; - // All below endpoints are not supported yet - case ServiceEndpointCategory.DOD: - case ServiceEndpointCategory.GCC: - case ServiceEndpointCategory.HIGH: - case ServiceEndpointCategory.MOONCAKE: - default: - sendTelemetryEvent(telemetry, { eventName: VSCODE_EXTENSION_GET_BAP_ENDPOINT_UNSUPPORTED_REGION, data: serviceEndpointStamp }); - break; - } + const bapEndpoint = await getBAPEndpoint(serviceEndpointStamp, telemetry); return BAP_SERVICE_ENDPOINT.replace('{rootURL}', bapEndpoint) + BAP_SERVICE_COPILOT_CROSS_GEO_FLAG_RELATIVE_URL.replace('{environmentID}', environmentId).replace('{apiVersion}', BAP_API_VERSION); diff --git a/src/common/services/Constants.ts b/src/common/services/Constants.ts index d41c586b4..a77791abd 100644 --- a/src/common/services/Constants.ts +++ b/src/common/services/Constants.ts @@ -17,6 +17,7 @@ export const BAP_API_VERSION = '2021-04-01'; export const BAP_SERVICE_SCOPE_DEFAULT = "https://api.bap.microsoft.com/.default"; export const BAP_SERVICE_ENDPOINT = `{rootURL}/providers/Microsoft.BusinessAppPlatform/`; export const BAP_SERVICE_COPILOT_CROSS_GEO_FLAG_RELATIVE_URL = `scopes/admin/environments/{environmentID}?$expand=properties/copilotPolicies&api-version={apiVersion}`; +export const BAP_ENVIRONMENT_LIST_URL = `scopes/admin/environments?api-version={apiVersion}&select=name,properties.displayName,properties.linkedEnvironmentMetadata`; // PPAPI constants export const PPAPI_WEBSITES_API_VERSION = '2022-03-01-preview'; diff --git a/src/common/services/TelemetryConstants.ts b/src/common/services/TelemetryConstants.ts index 4d4d26404..18615c9b2 100644 --- a/src/common/services/TelemetryConstants.ts +++ b/src/common/services/TelemetryConstants.ts @@ -24,3 +24,5 @@ export const VSCODE_EXTENSION_GET_PPAPI_WEBSITES_ENDPOINT_UNSUPPORTED_REGION = " export const VSCODE_EXTENSION_DECODE_JWT_TOKEN_FAILED = "VSCodeExtensionDecodeJWTTokenFailed"; export const VSCODE_EXTENSION_PPAPI_GET_WEBSITE_BY_ID_COMPLETED = "VSCodeExtensionPPAPIGetWebsiteByIdCompleted"; export const VSCODE_EXTENSION_PPAPI_GET_WEBSITE_BY_ID_FAILED = "VSCodeExtensionPPAPIGetWebsiteByIdFailed"; +export const VSCODE_EXTENSION_GET_ENV_LIST_SUCCESS = "VSCodeExtensionGetEnvListSuccess"; +export const VSCODE_EXTENSION_GET_ENV_LIST_FAILED = "VSCodeExtensionGetEnvListFailed"; diff --git a/src/common/utilities/Utils.ts b/src/common/utilities/Utils.ts index 853f97433..0bbe584c9 100644 --- a/src/common/utilities/Utils.ts +++ b/src/common/utilities/Utils.ts @@ -14,6 +14,9 @@ import { getDisabledOrgList, getDisabledTenantList } from "../copilot/utils/copi import { CopilotNotAvailable, CopilotNotAvailableECSConfig } from "../copilot/telemetry/telemetryConstants"; import path from "path"; import { oneDSLoggerWrapper } from "../OneDSLoggerTelemetry/oneDSLoggerWrapper"; +import { bapServiceAuthentication } from "../services/AuthenticationProvider"; +import { BAP_API_VERSION, BAP_ENVIRONMENT_LIST_URL, BAP_SERVICE_ENDPOINT, ServiceEndpointCategory } from "../services/Constants"; +import { VSCODE_EXTENSION_GET_ENV_LIST_SUCCESS, VSCODE_EXTENSION_GET_ENV_LIST_FAILED, VSCODE_EXTENSION_GET_BAP_ENDPOINT_UNSUPPORTED_REGION } from "../services/TelemetryConstants"; export function getSelectedCode(editor: vscode.TextEditor): string { if (!editor) { @@ -320,3 +323,74 @@ export function getECSOrgLocationValue(clusterName: string, clusterNumber: strin return extractedSubstring; } + +//API call to get env list for an org +export async function getEnvList(telemetry: ITelemetry, endpointStamp: ServiceEndpointCategory): Promise<{ envId: string, envDisplayName: string }[]> { + const envInfo: { envId: string, envDisplayName: string }[] = []; + try { + const bapAuthToken = await bapServiceAuthentication(telemetry, true); + const bapEndpoint = getBAPEndpoint(endpointStamp, telemetry); + const envListEndpoint = `${bapEndpoint}${BAP_ENVIRONMENT_LIST_URL.replace('{apiVersion}', BAP_API_VERSION)}`; + + const envListResponse = await fetch(envListEndpoint, { + method: "GET", + headers: { + "Authorization": `Bearer ${bapAuthToken}` + } + }); + + if (envListResponse.ok) { + const envListJson = await envListResponse.json(); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + envListJson.value.forEach((env: any) => { + envInfo.push({ + envId: env.properties.linkedEnvironmentMetadata.instanceUrl, + envDisplayName: env.properties.displayName + }); + }); + sendTelemetryEvent(telemetry, { eventName: VSCODE_EXTENSION_GET_ENV_LIST_SUCCESS }); + oneDSLoggerWrapper.getLogger().traceInfo(VSCODE_EXTENSION_GET_ENV_LIST_SUCCESS); + } else { + sendTelemetryEvent(telemetry, { + eventName: VSCODE_EXTENSION_GET_ENV_LIST_FAILED, + errorMsg: envListResponse.statusText + }); + oneDSLoggerWrapper.getLogger().traceError(VSCODE_EXTENSION_GET_ENV_LIST_FAILED, VSCODE_EXTENSION_GET_ENV_LIST_FAILED, new Error(envListResponse.statusText)); + } + } catch (error) { + sendTelemetryEvent(telemetry, { + eventName: VSCODE_EXTENSION_GET_ENV_LIST_FAILED, + errorMsg: (error as Error).message + }); + oneDSLoggerWrapper.getLogger().traceError(VSCODE_EXTENSION_GET_ENV_LIST_FAILED, VSCODE_EXTENSION_GET_ENV_LIST_FAILED, error as Error); + } + return envInfo; +} + + +export function getBAPEndpoint(serviceEndpointStamp: ServiceEndpointCategory, telemetry: ITelemetry): string { + let bapEndpoint = ""; + + switch (serviceEndpointStamp) { + case ServiceEndpointCategory.TEST: + bapEndpoint = "https://test.api.bap.microsoft.com"; + break; + case ServiceEndpointCategory.PREPROD: + bapEndpoint = "https://preprod.api.bap.microsoft.com"; + break; + case ServiceEndpointCategory.PROD: + bapEndpoint = "https://api.bap.microsoft.com"; + break; + // All below endpoints are not supported yet + case ServiceEndpointCategory.DOD: + case ServiceEndpointCategory.GCC: + case ServiceEndpointCategory.HIGH: + case ServiceEndpointCategory.MOONCAKE: + default: + sendTelemetryEvent(telemetry, { eventName: VSCODE_EXTENSION_GET_BAP_ENDPOINT_UNSUPPORTED_REGION, data: serviceEndpointStamp }); + oneDSLoggerWrapper.getLogger().traceInfo(VSCODE_EXTENSION_GET_BAP_ENDPOINT_UNSUPPORTED_REGION, { data: serviceEndpointStamp }); + break; + } + + return BAP_SERVICE_ENDPOINT.replace('{rootURL}', bapEndpoint) +}