mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-03-06 18:07:11 +00:00
Update to V3 messaging
This commit is contained in:
parent
36c0bf7392
commit
8cfd951c31
@ -1,5 +1,6 @@
|
||||
import * as Cosmos from "@azure/cosmos";
|
||||
import { getAuthorizationTokenUsingResourceTokens } from "Common/getAuthorizationTokenUsingResourceTokens";
|
||||
import { CosmosDbArtifactType } from "Contracts/FabricMessagesContract";
|
||||
import { AuthorizationToken } from "Contracts/FabricMessageTypes";
|
||||
import { checkDatabaseResourceTokensValidity, isFabricMirrored } from "Platform/Fabric/FabricUtil";
|
||||
import { LocalStorageUtility, StorageKey } from "Shared/StorageUtility";
|
||||
@ -8,7 +9,7 @@ import { AuthType } from "../AuthType";
|
||||
import { BackendApi, PriorityLevel } from "../Common/Constants";
|
||||
import * as Logger from "../Common/Logger";
|
||||
import { Platform, configContext } from "../ConfigContext";
|
||||
import { updateUserContext, userContext } from "../UserContext";
|
||||
import { FabricArtifactInfo, updateUserContext, userContext } from "../UserContext";
|
||||
import { logConsoleError } from "../Utils/NotificationConsoleUtils";
|
||||
import * as PriorityBasedExecutionUtils from "../Utils/PriorityBasedExecutionUtils";
|
||||
import { EmulatorMasterKey, HttpHeaders } from "./Constants";
|
||||
@ -54,8 +55,13 @@ export const tokenProvider = async (requestInfo: Cosmos.RequestInfo) => {
|
||||
// User resource tokens
|
||||
// TODO userContext.fabricContext.databaseConnectionInfo can be undefined
|
||||
headers[HttpHeaders.msDate] = new Date().toUTCString();
|
||||
const resourceTokens = userContext.fabricContext.mirroredConnectionInfo.resourceTokens;
|
||||
checkDatabaseResourceTokensValidity(userContext.fabricContext.mirroredConnectionInfo.resourceTokensTimestamp);
|
||||
const resourceTokens = (
|
||||
userContext.fabricContext.artifactInfo as FabricArtifactInfo[CosmosDbArtifactType.MIRRORED_KEY]
|
||||
).resourceTokenInfo.resourceTokens;
|
||||
checkDatabaseResourceTokensValidity(
|
||||
(userContext.fabricContext.artifactInfo as FabricArtifactInfo[CosmosDbArtifactType.MIRRORED_KEY])
|
||||
.resourceTokenInfo.resourceTokensTimestamp,
|
||||
);
|
||||
return getAuthorizationTokenUsingResourceTokens(resourceTokens, requestInfo.path, requestInfo.resourceId);
|
||||
|
||||
case Cosmos.ResourceType.none:
|
||||
@ -66,7 +72,9 @@ export const tokenProvider = async (requestInfo: Cosmos.RequestInfo) => {
|
||||
// For now, these operations aren't used, so fetching the authorization token is commented out.
|
||||
// This provider must return a real token to pass validation by the client, so we return the cached resource token
|
||||
// (which is a valid token, but won't work for these operations).
|
||||
const resourceTokens2 = userContext.fabricContext.mirroredConnectionInfo.resourceTokens;
|
||||
const resourceTokens2 = (
|
||||
userContext.fabricContext.artifactInfo as FabricArtifactInfo[CosmosDbArtifactType.MIRRORED_KEY]
|
||||
).resourceTokenInfo.resourceTokens;
|
||||
return getAuthorizationTokenUsingResourceTokens(resourceTokens2, requestInfo.path, requestInfo.resourceId);
|
||||
|
||||
/* ************** TODO: Uncomment this code if we need to support these operations **************
|
||||
|
@ -1,9 +1,10 @@
|
||||
import { ContainerResponse } from "@azure/cosmos";
|
||||
import { Queries } from "Common/Constants";
|
||||
import { CosmosDbArtifactType } from "Contracts/FabricMessagesContract";
|
||||
import { isFabricMirrored } from "Platform/Fabric/FabricUtil";
|
||||
import { AuthType } from "../../AuthType";
|
||||
import * as DataModels from "../../Contracts/DataModels";
|
||||
import { userContext } from "../../UserContext";
|
||||
import { FabricArtifactInfo, userContext } from "../../UserContext";
|
||||
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
|
||||
import { listCassandraTables } from "../../Utils/arm/generatedClients/cosmos/cassandraResources";
|
||||
import { listGremlinGraphs } from "../../Utils/arm/generatedClients/cosmos/gremlinResources";
|
||||
@ -16,11 +17,13 @@ import { handleError } from "../ErrorHandlingUtils";
|
||||
export async function readCollections(databaseId: string): Promise<DataModels.Collection[]> {
|
||||
const clearMessage = logConsoleProgress(`Querying containers for database ${databaseId}`);
|
||||
|
||||
if (isFabricMirrored() && userContext.fabricContext?.mirroredConnectionInfo.databaseId === databaseId) {
|
||||
if (isFabricMirrored() && userContext.fabricContext?.databaseName === databaseId) {
|
||||
const collections: DataModels.Collection[] = [];
|
||||
const promises: Promise<ContainerResponse>[] = [];
|
||||
|
||||
for (const collectionResourceId in userContext.fabricContext.mirroredConnectionInfo.resourceTokens) {
|
||||
for (const collectionResourceId in (
|
||||
userContext.fabricContext.artifactInfo as FabricArtifactInfo[CosmosDbArtifactType.MIRRORED_KEY]
|
||||
).resourceTokenInfo.resourceTokens) {
|
||||
// Dictionary key looks like this: dbs/SampleDB/colls/Container
|
||||
const resourceIdObj = collectionResourceId.split("/");
|
||||
const tokenDatabaseId = resourceIdObj[1];
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { CosmosDbArtifactType } from "Contracts/FabricMessagesContract";
|
||||
import { isFabricMirrored, isFabricNative } from "Platform/Fabric/FabricUtil";
|
||||
import { AuthType } from "../../AuthType";
|
||||
import * as DataModels from "../../Contracts/DataModels";
|
||||
import { userContext } from "../../UserContext";
|
||||
import { FabricArtifactInfo, userContext } from "../../UserContext";
|
||||
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
|
||||
import { listCassandraKeyspaces } from "../../Utils/arm/generatedClients/cosmos/cassandraResources";
|
||||
import { listGremlinDatabases } from "../../Utils/arm/generatedClients/cosmos/gremlinResources";
|
||||
@ -14,8 +15,13 @@ export async function readDatabases(): Promise<DataModels.Database[]> {
|
||||
let databases: DataModels.Database[];
|
||||
const clearMessage = logConsoleProgress(`Querying databases`);
|
||||
|
||||
if (isFabricMirrored() && userContext.fabricContext?.mirroredConnectionInfo.resourceTokens) {
|
||||
const tokensData = userContext.fabricContext.mirroredConnectionInfo;
|
||||
if (
|
||||
isFabricMirrored() &&
|
||||
(userContext.fabricContext?.artifactInfo as FabricArtifactInfo[CosmosDbArtifactType.MIRRORED_KEY]).resourceTokenInfo
|
||||
.resourceTokens
|
||||
) {
|
||||
const tokensData = (userContext.fabricContext.artifactInfo as FabricArtifactInfo[CosmosDbArtifactType.MIRRORED_KEY])
|
||||
.resourceTokenInfo;
|
||||
|
||||
const databaseIdsSet = new Set<string>(); // databaseId
|
||||
|
||||
@ -46,8 +52,8 @@ export async function readDatabases(): Promise<DataModels.Database[]> {
|
||||
}));
|
||||
clearMessage();
|
||||
return databases;
|
||||
} else if (isFabricNative() && userContext.fabricContext?.nativeConnectionInfo.databaseName) {
|
||||
const databaseId = userContext.fabricContext.nativeConnectionInfo.databaseName;
|
||||
} else if (isFabricNative() && userContext.fabricContext?.databaseName) {
|
||||
const databaseId = userContext.fabricContext.databaseName;
|
||||
databases = [
|
||||
{
|
||||
_rid: "",
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { AuthorizationToken } from "./FabricMessageTypes";
|
||||
|
||||
// This is the version of these messages
|
||||
export const FABRIC_RPC_VERSION = "2";
|
||||
export const FABRIC_RPC_VERSION = "FabricMessageV3";
|
||||
|
||||
// Fabric to Data Explorer
|
||||
export type FabricMessageV2 =
|
||||
@ -16,11 +16,6 @@ export type FabricMessageV2 =
|
||||
message: {
|
||||
connectionId: string;
|
||||
isVisible: boolean;
|
||||
isReadOnly: boolean;
|
||||
artifactType: CosmosDbArtifactType;
|
||||
|
||||
// For Native artifacts
|
||||
nativeConnectionInfo?: FabricNativeDatabaseConnectionInfo;
|
||||
};
|
||||
}
|
||||
| {
|
||||
@ -36,7 +31,41 @@ export type FabricMessageV2 =
|
||||
message: {
|
||||
id: string;
|
||||
error: string | undefined;
|
||||
data: FabricMirroredDatabaseConnectionInfo | undefined;
|
||||
data: ResourceTokenInfo | undefined;
|
||||
};
|
||||
}
|
||||
| {
|
||||
type: "explorerVisible";
|
||||
message: {
|
||||
visible: boolean;
|
||||
};
|
||||
};
|
||||
|
||||
export type FabricMessageV3 =
|
||||
| {
|
||||
type: "newContainer";
|
||||
databaseName: string;
|
||||
}
|
||||
| {
|
||||
type: "initialize";
|
||||
version: string;
|
||||
id: string;
|
||||
message: InitializeMessageV3<CosmosDbArtifactType>;
|
||||
}
|
||||
| {
|
||||
type: "authorizationToken";
|
||||
message: {
|
||||
id: string;
|
||||
error: string | undefined;
|
||||
data: AuthorizationToken | undefined;
|
||||
};
|
||||
}
|
||||
| {
|
||||
type: "allResourceTokens_v2";
|
||||
message: {
|
||||
id: string;
|
||||
error: string | undefined;
|
||||
data: ResourceTokenInfo | undefined;
|
||||
};
|
||||
}
|
||||
| {
|
||||
@ -47,27 +76,38 @@ export type FabricMessageV2 =
|
||||
};
|
||||
|
||||
export enum CosmosDbArtifactType {
|
||||
MIRRORED = "MIRRORED",
|
||||
MIRRORED_KEY = "MIRRORED_KEY",
|
||||
MIRRORED_AAD = "MIRRORED_AAD",
|
||||
NATIVE = "NATIVE",
|
||||
}
|
||||
export interface ArtifactConnectionInfo {
|
||||
[CosmosDbArtifactType.MIRRORED_KEY]: { connectionId: string };
|
||||
[CosmosDbArtifactType.MIRRORED_AAD]: AccessTokenConnectionInfo;
|
||||
[CosmosDbArtifactType.NATIVE]: AccessTokenConnectionInfo;
|
||||
}
|
||||
|
||||
export interface FabricNativeDatabaseConnectionInfo {
|
||||
export interface AccessTokenConnectionInfo {
|
||||
accessToken: string;
|
||||
databaseName: string;
|
||||
accountEndpoint: string;
|
||||
}
|
||||
|
||||
export interface CosmosDBTokenResponse {
|
||||
token: string;
|
||||
date: string;
|
||||
export interface InitializeMessageV3<T extends CosmosDbArtifactType> {
|
||||
connectionId: string;
|
||||
isVisible: boolean;
|
||||
isReadOnly: boolean;
|
||||
artifactType: T;
|
||||
artifactConnectionInfo: ArtifactConnectionInfo[T];
|
||||
}
|
||||
|
||||
export interface CosmosDBConnectionInfoResponse {
|
||||
endpoint: string;
|
||||
databaseId: string;
|
||||
resourceTokens: Record<string, string>;
|
||||
resourceTokens: Record<string, string> | undefined;
|
||||
accessToken: string | undefined;
|
||||
isReadOnly: boolean;
|
||||
credentialType: "Key" | "OAuth2" | undefined;
|
||||
}
|
||||
|
||||
export interface FabricMirroredDatabaseConnectionInfo extends CosmosDBConnectionInfoResponse {
|
||||
export interface ResourceTokenInfo extends CosmosDBConnectionInfoResponse {
|
||||
resourceTokensTimestamp: number;
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ import { fromContentUri, toRawContentUri } from "../Utils/GitHubUtils";
|
||||
import * as NotificationConsoleUtils from "../Utils/NotificationConsoleUtils";
|
||||
import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../Utils/NotificationConsoleUtils";
|
||||
import { useSidePanel } from "../hooks/useSidePanel";
|
||||
import { useTabs } from "../hooks/useTabs";
|
||||
import { ReactTabKind, useTabs } from "../hooks/useTabs";
|
||||
import "./ComponentRegisterer";
|
||||
import { DialogProps, useDialog } from "./Controls/Dialog";
|
||||
import { GalleryTab as GalleryTabKind } from "./Controls/NotebookGallery/GalleryViewerComponent";
|
||||
@ -187,6 +187,10 @@ export default class Explorer {
|
||||
useNotebook.getState().setNotebookBasePath(userContext.features.notebookBasePath);
|
||||
}
|
||||
|
||||
if (isFabricMirrored()) {
|
||||
useTabs.getState().closeReactTab(ReactTabKind.Home);
|
||||
}
|
||||
|
||||
this.refreshExplorer();
|
||||
}
|
||||
|
||||
|
@ -133,9 +133,7 @@ const GlobalCommands: React.FC<GlobalCommandsProps> = ({ explorer }) => {
|
||||
label: `New ${getCollectionName()}`,
|
||||
icon: <Add16Regular />,
|
||||
onClick: () => {
|
||||
const databaseId = isFabricNative()
|
||||
? userContext.fabricContext?.nativeConnectionInfo?.databaseName
|
||||
: undefined;
|
||||
const databaseId = isFabricNative() ? userContext.fabricContext?.databaseName : undefined;
|
||||
explorer.onNewCollectionClicked({ databaseId });
|
||||
},
|
||||
keyboardAction: KeyboardAction.NEW_COLLECTION,
|
||||
|
@ -130,9 +130,7 @@ export const FabricHomeScreen: React.FC<SplashScreenProps> = (props: SplashScree
|
||||
description: "Create a destination container to store your data",
|
||||
icon: <DocumentAddRegular />,
|
||||
onClick: () => {
|
||||
const databaseId = isFabricNative()
|
||||
? userContext.fabricContext?.nativeConnectionInfo?.databaseName
|
||||
: undefined;
|
||||
const databaseId = isFabricNative() ? userContext.fabricContext?.databaseName : undefined;
|
||||
props.explorer.onNewCollectionClicked({ databaseId });
|
||||
},
|
||||
},
|
||||
|
@ -342,12 +342,15 @@ describe("Documents tab (noSql API)", () => {
|
||||
updateConfigContext({ platform: Platform.Fabric });
|
||||
updateUserContext({
|
||||
fabricContext: {
|
||||
connectionId: "test",
|
||||
mirroredConnectionInfo: undefined,
|
||||
nativeConnectionInfo: undefined,
|
||||
artifactType: CosmosDbArtifactType.MIRRORED,
|
||||
databaseName: "database",
|
||||
artifactInfo: {
|
||||
connectionId: "test",
|
||||
resourceTokenInfo: undefined,
|
||||
},
|
||||
artifactType: CosmosDbArtifactType.MIRRORED_KEY,
|
||||
isReadOnly: true,
|
||||
isVisible: true,
|
||||
fabricClientRpcVersion: "rpcVersion",
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -557,7 +557,9 @@ describe("createDatabaseTreeNodes", () => {
|
||||
() => {
|
||||
updateConfigContext({ platform: Platform.Fabric });
|
||||
updateUserContext({
|
||||
fabricContext: { artifactType: CosmosDbArtifactType.MIRRORED } as FabricContext,
|
||||
fabricContext: {
|
||||
artifactType: CosmosDbArtifactType.MIRRORED_KEY,
|
||||
} as FabricContext<CosmosDbArtifactType>,
|
||||
});
|
||||
},
|
||||
],
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { sendCachedDataMessage } from "Common/MessageHandler";
|
||||
import { configContext, Platform } from "ConfigContext";
|
||||
import { FabricMessageTypes } from "Contracts/FabricMessageTypes";
|
||||
import { CosmosDbArtifactType, FabricMirroredDatabaseConnectionInfo } from "Contracts/FabricMessagesContract";
|
||||
import { CosmosDbArtifactType, ResourceTokenInfo } from "Contracts/FabricMessagesContract";
|
||||
import { updateUserContext, userContext } from "UserContext";
|
||||
import { logConsoleError } from "Utils/NotificationConsoleUtils";
|
||||
|
||||
@ -19,21 +19,25 @@ const requestDatabaseResourceTokens = async (): Promise<void> => {
|
||||
|
||||
lastRequestTimestamp = Date.now();
|
||||
try {
|
||||
const fabricDatabaseConnectionInfo = await sendCachedDataMessage<FabricMirroredDatabaseConnectionInfo>(
|
||||
const resourceTokenInfo = await sendCachedDataMessage<ResourceTokenInfo>(
|
||||
FabricMessageTypes.GetAllResourceTokens,
|
||||
[],
|
||||
userContext.fabricContext.connectionId,
|
||||
userContext.fabricContext.artifactInfo.connectionId,
|
||||
);
|
||||
|
||||
if (!userContext.databaseAccount.properties.documentEndpoint) {
|
||||
userContext.databaseAccount.properties.documentEndpoint = fabricDatabaseConnectionInfo.endpoint;
|
||||
userContext.databaseAccount.properties.documentEndpoint = resourceTokenInfo.endpoint;
|
||||
}
|
||||
|
||||
updateUserContext({
|
||||
fabricContext: {
|
||||
...userContext.fabricContext,
|
||||
mirroredConnectionInfo: fabricDatabaseConnectionInfo,
|
||||
isReadOnly: true,
|
||||
databaseName: resourceTokenInfo.databaseId,
|
||||
artifactInfo: {
|
||||
...userContext.fabricContext.artifactInfo,
|
||||
resourceTokenInfo,
|
||||
},
|
||||
isReadOnly: resourceTokenInfo.isReadOnly ?? userContext.fabricContext.isReadOnly,
|
||||
},
|
||||
databaseAccount: { ...userContext.databaseAccount },
|
||||
});
|
||||
@ -75,7 +79,8 @@ export const checkDatabaseResourceTokensValidity = (tokenTimestamp: number): voi
|
||||
|
||||
export const isFabricMirrored = (): boolean =>
|
||||
configContext.platform === Platform.Fabric &&
|
||||
userContext.fabricContext?.artifactType === CosmosDbArtifactType.MIRRORED;
|
||||
(userContext.fabricContext?.artifactType === CosmosDbArtifactType.MIRRORED_KEY ||
|
||||
userContext.fabricContext?.artifactType === CosmosDbArtifactType.MIRRORED_AAD);
|
||||
|
||||
export const isFabricNative = (): boolean =>
|
||||
configContext.platform === Platform.Fabric && userContext.fabricContext?.artifactType === CosmosDbArtifactType.NATIVE;
|
||||
|
@ -1,8 +1,4 @@
|
||||
import {
|
||||
CosmosDbArtifactType,
|
||||
FabricMirroredDatabaseConnectionInfo,
|
||||
FabricNativeDatabaseConnectionInfo,
|
||||
} from "Contracts/FabricMessagesContract";
|
||||
import { CosmosDbArtifactType, ResourceTokenInfo } from "Contracts/FabricMessagesContract";
|
||||
import { ParsedResourceTokenConnectionString } from "Platform/Hosted/Helpers/ResourceTokenUtils";
|
||||
import { Action } from "Shared/Telemetry/TelemetryConstants";
|
||||
import { traceOpen } from "Shared/Telemetry/TelemetryProcessor";
|
||||
@ -51,13 +47,21 @@ export interface VCoreMongoConnectionParams {
|
||||
connectionString: string;
|
||||
}
|
||||
|
||||
export interface FabricContext {
|
||||
connectionId: string;
|
||||
export interface FabricArtifactInfo {
|
||||
[CosmosDbArtifactType.MIRRORED_KEY]: {
|
||||
connectionId: string;
|
||||
resourceTokenInfo: ResourceTokenInfo | undefined;
|
||||
};
|
||||
[CosmosDbArtifactType.MIRRORED_AAD]: undefined;
|
||||
[CosmosDbArtifactType.NATIVE]: undefined;
|
||||
}
|
||||
export interface FabricContext<T extends CosmosDbArtifactType> {
|
||||
fabricClientRpcVersion: string;
|
||||
isReadOnly: boolean;
|
||||
isVisible: boolean;
|
||||
databaseName: string;
|
||||
artifactType: CosmosDbArtifactType;
|
||||
mirroredConnectionInfo: FabricMirroredDatabaseConnectionInfo | undefined;
|
||||
nativeConnectionInfo: FabricNativeDatabaseConnectionInfo | undefined;
|
||||
artifactInfo: FabricArtifactInfo[T];
|
||||
}
|
||||
|
||||
export type AdminFeedbackControlPolicy =
|
||||
@ -76,7 +80,7 @@ export type AdminFeedbackPolicySettings = {
|
||||
};
|
||||
|
||||
export interface UserContext {
|
||||
readonly fabricContext?: FabricContext;
|
||||
readonly fabricContext?: FabricContext<CosmosDbArtifactType>;
|
||||
readonly authType?: AuthType;
|
||||
readonly masterKey?: string;
|
||||
readonly subscriptionId?: string;
|
||||
|
@ -3,11 +3,14 @@ import { createUri } from "Common/UrlUtility";
|
||||
import { DATA_EXPLORER_RPC_VERSION } from "Contracts/DataExplorerMessagesContract";
|
||||
import { FabricMessageTypes } from "Contracts/FabricMessageTypes";
|
||||
import {
|
||||
ArtifactConnectionInfo,
|
||||
CosmosDbArtifactType,
|
||||
FABRIC_RPC_VERSION,
|
||||
FabricMessageV2,
|
||||
FabricNativeDatabaseConnectionInfo,
|
||||
FabricMessageV3,
|
||||
InitializeMessageV3,
|
||||
} from "Contracts/FabricMessagesContract";
|
||||
import { useDialog } from "Explorer/Controls/Dialog";
|
||||
import Explorer from "Explorer/Explorer";
|
||||
import { useDataPlaneRbac } from "Explorer/Panes/SettingsPane/SettingsPane";
|
||||
import { useSelectedNode } from "Explorer/useSelectedNode";
|
||||
@ -49,7 +52,7 @@ import {
|
||||
} from "../Platform/Hosted/HostedUtils";
|
||||
import { extractFeatures } from "../Platform/Hosted/extractFeatures";
|
||||
import { DefaultExperienceUtility } from "../Shared/DefaultExperienceUtility";
|
||||
import { Node, PortalEnv, updateUserContext, userContext } from "../UserContext";
|
||||
import { FabricArtifactInfo, Node, PortalEnv, updateUserContext, userContext } from "../UserContext";
|
||||
import {
|
||||
acquireMsalTokenForAccount,
|
||||
acquireTokenWithMsal,
|
||||
@ -109,7 +112,7 @@ export function useKnockoutExplorer(platform: Platform): Explorer {
|
||||
|
||||
async function configureFabric(): Promise<Explorer> {
|
||||
// These are the versions of Fabric that Data Explorer supports.
|
||||
const SUPPORTED_FABRIC_VERSIONS = [FABRIC_RPC_VERSION];
|
||||
const SUPPORTED_FABRIC_VERSIONS = ["2", FABRIC_RPC_VERSION];
|
||||
|
||||
let firstContainerOpened = false;
|
||||
let explorer: Explorer;
|
||||
@ -125,7 +128,7 @@ async function configureFabric(): Promise<Explorer> {
|
||||
return;
|
||||
}
|
||||
|
||||
const data: FabricMessageV2 = event.data?.data;
|
||||
const data: FabricMessageV2 | FabricMessageV3 = event.data?.data;
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
@ -134,30 +137,51 @@ async function configureFabric(): Promise<Explorer> {
|
||||
case "initialize": {
|
||||
const fabricVersion = data.version;
|
||||
if (!SUPPORTED_FABRIC_VERSIONS.includes(fabricVersion)) {
|
||||
// TODO Surface error to user
|
||||
// TODO Surface error to user and log to telemetry
|
||||
useDialog
|
||||
.getState()
|
||||
.showOkModalDialog("Unsupported Fabric version", `Unsupported Fabric version: ${fabricVersion}`);
|
||||
Logger.logError(`Unsupported Fabric version: ${fabricVersion}`, "Explorer/configureFabric");
|
||||
console.error(`Unsupported Fabric version: ${fabricVersion}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Default values points to MIRRORED. This is for old fabric clients to explitly settings these values
|
||||
data.message.artifactType = data.message.artifactType ?? CosmosDbArtifactType.MIRRORED;
|
||||
data.message.isReadOnly = data.message.isReadOnly ?? true;
|
||||
if (fabricVersion === "2") {
|
||||
// ----------------- TODO: Remove this when FabricMessageV2 is deprecated -----------------
|
||||
const initializationMessage = data.message as {
|
||||
connectionId: string;
|
||||
isVisible: boolean;
|
||||
};
|
||||
|
||||
explorer = createExplorerFabric(data.message);
|
||||
|
||||
if (data.message.artifactType === CosmosDbArtifactType.MIRRORED) {
|
||||
// Do not show Home tab for Mirrored
|
||||
useTabs.getState().closeReactTab(ReactTabKind.Home);
|
||||
explorer = createExplorerFabricLegacy(initializationMessage, data.version);
|
||||
await scheduleRefreshDatabaseResourceToken(true);
|
||||
resolve(explorer);
|
||||
await explorer.refreshAllDatabases();
|
||||
if (userContext.fabricContext.isVisible) {
|
||||
firstContainerOpened = true;
|
||||
openFirstContainer(explorer, userContext.fabricContext.databaseName);
|
||||
}
|
||||
// -----------------------------------------------------------------------------------------
|
||||
} else if (fabricVersion === FABRIC_RPC_VERSION) {
|
||||
const initializationMessage = data.message as InitializeMessageV3<CosmosDbArtifactType>;
|
||||
explorer = createExplorerFabric(initializationMessage, data.version);
|
||||
|
||||
if (initializationMessage.artifactType === CosmosDbArtifactType.MIRRORED_KEY) {
|
||||
// Do not show Home tab for Mirrored
|
||||
useTabs.getState().closeReactTab(ReactTabKind.Home);
|
||||
await scheduleRefreshDatabaseResourceToken(true);
|
||||
}
|
||||
|
||||
resolve(explorer);
|
||||
await explorer.refreshAllDatabases();
|
||||
|
||||
const { databaseName } = userContext.fabricContext;
|
||||
if (userContext.fabricContext.isVisible && databaseName) {
|
||||
firstContainerOpened = true;
|
||||
openFirstContainer(explorer, databaseName);
|
||||
}
|
||||
}
|
||||
|
||||
resolve(explorer);
|
||||
await explorer.refreshAllDatabases();
|
||||
|
||||
if (userContext.fabricContext.isVisible && userContext.fabricContext.mirroredConnectionInfo?.databaseId) {
|
||||
firstContainerOpened = true;
|
||||
openFirstContainer(explorer, userContext.fabricContext.mirroredConnectionInfo.databaseId);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "newContainer":
|
||||
@ -170,13 +194,12 @@ async function configureFabric(): Promise<Explorer> {
|
||||
}
|
||||
case "explorerVisible": {
|
||||
userContext.fabricContext.isVisible = data.message.visible;
|
||||
if (
|
||||
userContext.fabricContext.isVisible &&
|
||||
!firstContainerOpened &&
|
||||
userContext?.fabricContext?.mirroredConnectionInfo?.databaseId !== undefined
|
||||
) {
|
||||
firstContainerOpened = true;
|
||||
openFirstContainer(explorer, userContext.fabricContext.mirroredConnectionInfo.databaseId);
|
||||
if (userContext.fabricContext.isVisible && !firstContainerOpened) {
|
||||
const { databaseName } = userContext.fabricContext;
|
||||
if (databaseName !== undefined) {
|
||||
firstContainerOpened = true;
|
||||
openFirstContainer(explorer, databaseName);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -431,25 +454,67 @@ function configureHostedWithResourceToken(config: ResourceToken): Explorer {
|
||||
return explorer;
|
||||
}
|
||||
|
||||
const createExplorerFabric = (params: {
|
||||
connectionId: string;
|
||||
isVisible: boolean;
|
||||
isReadOnly?: boolean;
|
||||
artifactType?: CosmosDbArtifactType;
|
||||
nativeConnectionInfo?: FabricNativeDatabaseConnectionInfo;
|
||||
}): Explorer => {
|
||||
/**
|
||||
* Initialization for FabricMessageV2
|
||||
* TODO: delete when FabricMessageV2 is deprecated
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
function createExplorerFabricLegacy(
|
||||
params: { connectionId: string; isVisible: boolean },
|
||||
fabricClientRpcVersion: string,
|
||||
): Explorer {
|
||||
const artifactInfo: FabricArtifactInfo[CosmosDbArtifactType.MIRRORED_KEY] = {
|
||||
connectionId: params.connectionId,
|
||||
resourceTokenInfo: undefined,
|
||||
};
|
||||
|
||||
updateUserContext({
|
||||
fabricContext: {
|
||||
connectionId: params.connectionId,
|
||||
mirroredConnectionInfo: undefined, // Set with resource token response
|
||||
isReadOnly: params.isReadOnly,
|
||||
fabricClientRpcVersion,
|
||||
isReadOnly: true,
|
||||
isVisible: params.isVisible ?? true,
|
||||
databaseName: undefined,
|
||||
artifactType: CosmosDbArtifactType.MIRRORED_KEY,
|
||||
artifactInfo,
|
||||
},
|
||||
authType: AuthType.ConnectionString,
|
||||
databaseAccount: {
|
||||
id: "",
|
||||
location: "",
|
||||
type: "",
|
||||
name: "Mounted",
|
||||
kind: AccountKind.Default,
|
||||
properties: {
|
||||
documentEndpoint: undefined,
|
||||
},
|
||||
},
|
||||
});
|
||||
const explorer = new Explorer();
|
||||
return explorer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialization for FabricMessageV3 and above
|
||||
* @param params
|
||||
* @returns
|
||||
*/
|
||||
const createExplorerFabric = (
|
||||
params: InitializeMessageV3<CosmosDbArtifactType>,
|
||||
fabricClientRpcVersion: string,
|
||||
): Explorer => {
|
||||
updateUserContext({
|
||||
fabricContext: {
|
||||
fabricClientRpcVersion,
|
||||
databaseName: undefined,
|
||||
isVisible: params.isVisible,
|
||||
isReadOnly: params.isReadOnly,
|
||||
artifactType: params.artifactType,
|
||||
nativeConnectionInfo: params.nativeConnectionInfo,
|
||||
artifactInfo: undefined,
|
||||
},
|
||||
});
|
||||
|
||||
if (params.artifactType === CosmosDbArtifactType.MIRRORED) {
|
||||
if (params.artifactType === CosmosDbArtifactType.MIRRORED_KEY) {
|
||||
updateUserContext({
|
||||
authType: AuthType.ConnectionString, // TODO: will need its own type and Mirroring could be using AAD
|
||||
databaseAccount: {
|
||||
@ -462,8 +527,17 @@ const createExplorerFabric = (params: {
|
||||
documentEndpoint: undefined,
|
||||
},
|
||||
},
|
||||
fabricContext: {
|
||||
...userContext.fabricContext,
|
||||
artifactInfo: {
|
||||
connectionId: (params.artifactConnectionInfo as ArtifactConnectionInfo[CosmosDbArtifactType.MIRRORED_KEY])
|
||||
.connectionId,
|
||||
resourceTokenInfo: undefined,
|
||||
},
|
||||
},
|
||||
});
|
||||
} else if (params.artifactType === CosmosDbArtifactType.NATIVE) {
|
||||
const nativeParams = params as InitializeMessageV3<CosmosDbArtifactType.NATIVE>;
|
||||
// Make it behave like Hosted/AAD/RBAC
|
||||
updateUserContext({
|
||||
databaseAccount: {
|
||||
@ -473,14 +547,20 @@ const createExplorerFabric = (params: {
|
||||
name: "Native", // TODO: not used?
|
||||
kind: AccountKind.Default,
|
||||
properties: {
|
||||
documentEndpoint: params.nativeConnectionInfo.accountEndpoint,
|
||||
documentEndpoint: nativeParams.artifactConnectionInfo.accountEndpoint,
|
||||
},
|
||||
},
|
||||
authType: AuthType.AAD,
|
||||
dataPlaneRbacEnabled: true,
|
||||
aadToken: params.nativeConnectionInfo.accessToken,
|
||||
aadToken: nativeParams.artifactConnectionInfo.accessToken,
|
||||
masterKey: undefined,
|
||||
fabricContext: {
|
||||
...userContext.fabricContext,
|
||||
databaseName: nativeParams.artifactConnectionInfo.databaseName,
|
||||
},
|
||||
});
|
||||
} else if (params.artifactType === CosmosDbArtifactType.MIRRORED_AAD) {
|
||||
throw new Error("Mirrored AAD is not supported");
|
||||
}
|
||||
|
||||
const explorer = new Explorer();
|
||||
|
Loading…
x
Reference in New Issue
Block a user