From cf5609ef0cfaac4010dfe165bb8c92d0427bba98 Mon Sep 17 00:00:00 2001 From: "Craig Boger (from Dev Box)" Date: Wed, 12 Feb 2025 14:49:02 -0800 Subject: [PATCH] Use endpoint instead of region name to track selected region. Prevents having to do endpoint lookups. --- src/Common/Constants.ts | 4 -- src/Common/CosmosClient.ts | 17 +++++-- src/Common/dataAccess/updateDocument.ts | 5 ++ .../Panes/SettingsPane/SettingsPane.tsx | 49 +++++++++++-------- src/Shared/StorageUtility.ts | 2 +- src/hooks/useKnockoutExplorer.ts | 25 +++++----- 6 files changed, 62 insertions(+), 40 deletions(-) diff --git a/src/Common/Constants.ts b/src/Common/Constants.ts index 7350d3099..840849904 100644 --- a/src/Common/Constants.ts +++ b/src/Common/Constants.ts @@ -239,10 +239,6 @@ export class SavedQueries { public static readonly PartitionKeyProperty: string = "id"; } -export class RegionSelectionOptions { - public static readonly Global: string = "Global"; -} - export class DocumentsGridMetrics { public static DocumentsPerPage: number = 100; public static IndividualRowHeight: number = 34; diff --git a/src/Common/CosmosClient.ts b/src/Common/CosmosClient.ts index 338e83894..fed5fd924 100644 --- a/src/Common/CosmosClient.ts +++ b/src/Common/CosmosClient.ts @@ -110,13 +110,21 @@ export const requestPlugin: Cosmos.Plugin = async (requestContext, diagnost console.log(`REQUEST CONTEXT ENDPOINT: ${JSON.stringify(requestContext.endpoint)}`); requestContext.headers["x-ms-proxy-target"] = endpoint(); console.log(`REQUEST CONTEXT PROXY: ${JSON.stringify(requestContext.headers["x-ms-proxy-target"])}`); + // return await next(requestContext); + + // try { + // return await next(requestContext); + // } catch (error) { + // throw { + // code: error?.code || undefined, + // message: error.message, + // }; + // } + try { return await next(requestContext); } catch (error) { - throw { - code: error?.code || undefined, - message: error.message, - }; + console.log(error.code); } }; @@ -236,6 +244,7 @@ export function client(): Cosmos.CosmosClient { const options: Cosmos.CosmosClientOptions = { endpoint: endpoint() || "https://cosmos.azure.com", // CosmosClient gets upset if we pass a bad URL. This should never actually get called key: userContext.dataPlaneRbacEnabled ? "" : userContext.masterKey, + diagnosticLevel: Cosmos.CosmosDbDiagnosticLevel.debugUnsafe, tokenProvider, userAgentSuffix: "Azure Portal", defaultHeaders: _defaultHeaders, diff --git a/src/Common/dataAccess/updateDocument.ts b/src/Common/dataAccess/updateDocument.ts index dd97b46de..b3ce5bec5 100644 --- a/src/Common/dataAccess/updateDocument.ts +++ b/src/Common/dataAccess/updateDocument.ts @@ -29,9 +29,14 @@ export const updateDocument = async ( .item(documentId.id(), getPartitionKeyValue(documentId)) .replace(newDocument, options); + console.log(response.diagnostics); logConsoleInfo(`Successfully updated ${entityName} ${documentId.id()}`); return response?.resource; } catch (error) { + // If error has diagnostic information, log it. + if (error && error.diagnostics) { + console.error("Diagnostics:", error.diagnostics); + } handleError(error, "UpdateDocument", `Failed to update ${entityName} ${documentId.id()}`); throw error; } finally { diff --git a/src/Explorer/Panes/SettingsPane/SettingsPane.tsx b/src/Explorer/Panes/SettingsPane/SettingsPane.tsx index 332b4c21f..68837bbad 100644 --- a/src/Explorer/Panes/SettingsPane/SettingsPane.tsx +++ b/src/Explorer/Panes/SettingsPane/SettingsPane.tsx @@ -145,10 +145,10 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({ ? LocalStorageUtility.getEntryString(StorageKey.IsGraphAutoVizDisabled) : "false", ); - const [selectedRegion, setSelectedRegion] = useState( - LocalStorageUtility.hasItem(StorageKey.SelectedRegion) - ? LocalStorageUtility.getEntryString(StorageKey.SelectedRegion) - : Constants.RegionSelectionOptions.Global, + const [selectedRegionalEndpoint, setSelectedRegionalEndpoint] = useState( + LocalStorageUtility.hasItem(StorageKey.SelectedRegionalEndpoint) + ? LocalStorageUtility.getEntryString(StorageKey.SelectedRegionalEndpoint) + : "", ); const [retryAttempts, setRetryAttempts] = useState( LocalStorageUtility.hasItem(StorageKey.RetryAttempts) @@ -192,10 +192,10 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({ const uniqueAccountRegions = new Set(); const regionOptions: IDropdownOption[] = []; regionOptions.push({ - key: Constants.RegionSelectionOptions.Global, - text: `${Constants.RegionSelectionOptions.Global} (Default)`, + key: userContext?.databaseAccount?.properties?.documentEndpoint, + text: `Global (Default)`, data: { - endpoint: userContext?.databaseAccount?.properties?.documentEndpoint, + isGlobal: true, writeEnabled: true, }, }); @@ -203,10 +203,10 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({ if (!uniqueAccountRegions.has(loc.locationName)) { uniqueAccountRegions.add(loc.locationName); regionOptions.push({ - key: loc.locationName, + key: loc.documentEndpoint, text: `${loc.locationName} (Read/Write)`, data: { - endpoint: loc.documentEndpoint, + isGlobal: false, writeEnabled: true, }, }); @@ -216,10 +216,10 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({ if (!uniqueAccountRegions.has(loc.locationName)) { uniqueAccountRegions.add(loc.locationName); regionOptions.push({ - key: loc.locationName, + key: loc.documentEndpoint, text: `${loc.locationName} (Read)`, data: { - endpoint: loc.documentEndpoint, + isGlobal: false, writeEnabled: false, }, }); @@ -311,18 +311,23 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({ } } - const storedRegion = LocalStorageUtility.getEntryString(StorageKey.SelectedRegion); - const selectedRegionIsGlobal = selectedRegion === Constants.RegionSelectionOptions.Global; - if (selectedRegionIsGlobal && storedRegion) { - LocalStorageUtility.removeEntry(StorageKey.SelectedRegion); + const storedRegionalEndpoint = LocalStorageUtility.getEntryString(StorageKey.SelectedRegionalEndpoint); + const selectedRegionIsGlobal = + selectedRegionalEndpoint === userContext?.databaseAccount?.properties?.documentEndpoint; + if (selectedRegionIsGlobal && storedRegionalEndpoint) { + LocalStorageUtility.removeEntry(StorageKey.SelectedRegionalEndpoint); updateUserContext({ selectedRegionalEndpoint: undefined, refreshCosmosClient: true, }); - } else if (!selectedRegionIsGlobal && selectedRegion !== storedRegion) { - LocalStorageUtility.setEntryString(StorageKey.SelectedRegion, selectedRegion); + } else if ( + selectedRegionalEndpoint && + !selectedRegionIsGlobal && + selectedRegionalEndpoint !== storedRegionalEndpoint + ) { + LocalStorageUtility.setEntryString(StorageKey.SelectedRegionalEndpoint, selectedRegionalEndpoint); updateUserContext({ - selectedRegionalEndpoint: regionOptions.find((option) => option.key === selectedRegion)?.data?.endpoint, + selectedRegionalEndpoint: selectedRegionalEndpoint, refreshCosmosClient: true, }); } @@ -477,7 +482,7 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({ }; const handleOnSelectedRegionOptionChange = (ev: React.FormEvent, option: IDropdownOption): void => { - setSelectedRegion(option.key as string); + setSelectedRegionalEndpoint(option.key as string); }; const handleOnQueryRetryAttemptsSpinButtonChange = (ev: React.MouseEvent, newValue?: string): void => { @@ -649,7 +654,11 @@ export const SettingsPane: FunctionComponent<{ explorer: Explorer }> = ({ option.key === selectedRegion)?.text} + placeholder={ + selectedRegionalEndpoint + ? regionOptions.find((option) => option.key === selectedRegionalEndpoint)?.text + : regionOptions[0]?.text + } onChange={handleOnSelectedRegionOptionChange} options={regionOptions} styles={{ root: { marginBottom: "10px" } }} diff --git a/src/Shared/StorageUtility.ts b/src/Shared/StorageUtility.ts index 1a31f9588..8ebd54463 100644 --- a/src/Shared/StorageUtility.ts +++ b/src/Shared/StorageUtility.ts @@ -11,7 +11,7 @@ export enum StorageKey { RUThreshold, QueryTimeoutEnabled, QueryTimeout, - SelectedRegion, + SelectedRegionalEndpoint, RetryAttempts, RetryInterval, MaxWaitTimeInSeconds, diff --git a/src/hooks/useKnockoutExplorer.ts b/src/hooks/useKnockoutExplorer.ts index 56b99c201..0007e8949 100644 --- a/src/hooks/useKnockoutExplorer.ts +++ b/src/hooks/useKnockoutExplorer.ts @@ -298,7 +298,7 @@ async function configureHostedWithAAD(config: AAD): Promise { `Configuring Data Explorer for ${userContext.apiType} account ${account.name}`, "Explorer/configureHostedWithAAD", ); - if (userContext.apiType === "SQL") { + if (userContext.apiType === "SQL" && userContext.authType === AuthType.AAD) { checkAndUpdateSelectedRegionalEndpoint(); } if (!userContext.features.enableAadDataPlane) { @@ -555,7 +555,7 @@ async function configurePortal(): Promise { const { databaseAccount: account, subscriptionId, resourceGroup } = userContext; - if (userContext.apiType === "SQL") { + if (userContext.apiType === "SQL" && userContext.authType === AuthType.AAD) { checkAndUpdateSelectedRegionalEndpoint(); } @@ -678,16 +678,19 @@ function updateAADEndpoints(portalEnv: PortalEnv) { } function checkAndUpdateSelectedRegionalEndpoint() { - //TODO: Possibly refactor userContext to store selected regional endpoint instead of selected region. - if (LocalStorageUtility.hasItem(StorageKey.SelectedRegion)) { - const storedRegion = LocalStorageUtility.getEntryString(StorageKey.SelectedRegion); - const location = userContext.databaseAccount?.properties?.readLocations?.find( - (loc) => loc.locationName === storedRegion, + if (LocalStorageUtility.hasItem(StorageKey.SelectedRegionalEndpoint)) { + const storedRegionalEndpoint = LocalStorageUtility.getEntryString(StorageKey.SelectedRegionalEndpoint); + const validLocation = userContext.databaseAccount?.properties?.readLocations?.find( + (loc) => loc.documentEndpoint === storedRegionalEndpoint, ); - updateUserContext({ - selectedRegionalEndpoint: location?.documentEndpoint, - refreshCosmosClient: true, - }); + if (validLocation) { + updateUserContext({ + selectedRegionalEndpoint: storedRegionalEndpoint, + refreshCosmosClient: true, + }); + } else { + LocalStorageUtility.removeEntry(StorageKey.SelectedRegionalEndpoint); + } } }