Compare commits

..

3 Commits

Author SHA1 Message Date
Senthamil Sindhu
d720be1250 Activate CassandraProxy in MPAC 2024-03-26 09:30:33 -07:00
Senthamil Sindhu
5042f28229 Merge branch 'master' of https://github.com/Azure/cosmos-explorer 2024-03-25 15:11:53 -07:00
Senthamil Sindhu
e1430fd06f Fix API endpoint for CassandraProxy query API 2024-03-18 10:25:17 -07:00
45 changed files with 210 additions and 470 deletions

3
.gitignore vendored
View File

@@ -16,5 +16,4 @@ Contracts/*
.env
failure.png
screenshots/*
GettingStarted-ignore*.ipynb
.vscode/
GettingStarted-ignore*.ipynb

View File

@@ -85,8 +85,6 @@ export const tokenProvider = async (requestInfo: Cosmos.RequestInfo) => {
return decodeURIComponent(result.PrimaryReadWriteToken);
};
// TODO
// Need to create separate plugins or change endpoint logic to return the correct write or read endpoint.
export const requestPlugin: Cosmos.Plugin<any> = async (requestContext, diagnosticNode, next) => {
requestContext.endpoint = new URL(configContext.PROXY_PATH, window.location.href).href;
requestContext.headers["x-ms-proxy-target"] = endpoint();
@@ -136,32 +134,9 @@ enum SDKSupportedCapabilities {
PartitionMerge = 1 << 0,
}
// Client Management
let _client: Cosmos.CosmosClient;
let _readClients: Map<string, Cosmos.CosmosClient> = new Map();
export enum ClientOperationType {
READ,
WRITE,
}
export function client(clientOperationType: ClientOperationType): Cosmos.CosmosClient {
switch (clientOperationType) {
case ClientOperationType.READ:
return readClients();
case ClientOperationType.WRITE:
return writeClient();
default:
throw new Error("Invalid operation type");
}
}
export function writeClient(): Cosmos.CosmosClient {
console.log(`Called primary client`);
const currentUserContextDocumentEndpoint = userContext?.databaseAccount?.properties?.documentEndpoint;
console.log(`Current selected endpoint in userContext: ${currentUserContextDocumentEndpoint}`);
export function client(): Cosmos.CosmosClient {
if (_client) return _client;
let _defaultHeaders: Cosmos.CosmosHeaders = {};
@@ -208,61 +183,3 @@ export function writeClient(): Cosmos.CosmosClient {
_client = new Cosmos.CosmosClient(options);
return _client;
}
export function readClients(): Cosmos.CosmosClient {
console.log(`Called read only client`);
const currentUserContextDocumentEndpoint = userContext?.databaseAccount?.properties?.documentEndpoint;
console.log(`Current selected read endpoint in userContext: ${currentUserContextDocumentEndpoint}`);
3;
const selectedEndpoint = endpoint() || "https://cosmos.azure.com";
if (_readClients.has(selectedEndpoint)) {
return _readClients.get(selectedEndpoint);
}
let _defaultHeaders: Cosmos.CosmosHeaders = {};
_defaultHeaders["x-ms-cosmos-sdk-supportedcapabilities"] =
SDKSupportedCapabilities.None | SDKSupportedCapabilities.PartitionMerge;
if (
userContext.authType === AuthType.ConnectionString ||
userContext.authType === AuthType.EncryptedToken ||
userContext.authType === AuthType.ResourceToken
) {
// Default to low priority. Needed for non-AAD-auth scenarios
// where we cannot use RP API, and thus, cannot detect whether priority
// based execution is enabled.
// The header will be ignored if priority based execution is disabled on the account.
_defaultHeaders["x-ms-cosmos-priority-level"] = PriorityLevel.Default;
}
const options: Cosmos.CosmosClientOptions = {
endpoint: selectedEndpoint, // CosmosClient gets upset if we pass a bad URL. This should never actually get called
key: userContext.masterKey,
tokenProvider,
userAgentSuffix: "Azure Portal",
defaultHeaders: _defaultHeaders,
connectionPolicy: {
retryOptions: {
maxRetryAttemptCount: LocalStorageUtility.getEntryNumber(StorageKey.RetryAttempts),
fixedRetryIntervalInMilliseconds: LocalStorageUtility.getEntryNumber(StorageKey.RetryInterval),
maxWaitTimeInSeconds: LocalStorageUtility.getEntryNumber(StorageKey.MaxWaitTimeInSeconds),
},
},
};
if (configContext.PROXY_PATH !== undefined) {
(options as any).plugins = [{ on: "request", plugin: requestPlugin }];
}
if (PriorityBasedExecutionUtils.isFeatureEnabled()) {
const plugins = (options as any).plugins || [];
plugins.push({ on: "request", plugin: PriorityBasedExecutionUtils.requestPlugin });
(options as any).plugins = plugins;
}
_readClients.set(selectedEndpoint, new Cosmos.CosmosClient(options));
return _readClients.get(selectedEndpoint);
}

View File

@@ -1,7 +1,7 @@
import { JSONObject, OperationResponse } from "@azure/cosmos";
import { CollectionBase } from "../../Contracts/ViewModels";
import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { ClientOperationType, client } from "../CosmosClient";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
export const bulkCreateDocument = async (
@@ -13,7 +13,7 @@ export const bulkCreateDocument = async (
);
try {
const response = await client(ClientOperationType.WRITE)
const response = await client()
.database(collection.databaseId)
.container(collection.id())
.items.bulk(

View File

@@ -6,14 +6,14 @@ import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstan
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import { userContext } from "../../UserContext";
import { getCollectionName } from "../../Utils/APITypeUtils";
import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { createUpdateCassandraTable } from "../../Utils/arm/generatedClients/cosmos/cassandraResources";
import { createUpdateGremlinGraph } from "../../Utils/arm/generatedClients/cosmos/gremlinResources";
import { createUpdateMongoDBCollection } from "../../Utils/arm/generatedClients/cosmos/mongoDBResources";
import { createUpdateSqlContainer } from "../../Utils/arm/generatedClients/cosmos/sqlResources";
import { createUpdateTable } from "../../Utils/arm/generatedClients/cosmos/tableResources";
import * as ARMTypes from "../../Utils/arm/generatedClients/cosmos/types";
import { ClientOperationType, client } from "../CosmosClient";
import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
import { createMongoCollectionWithProxy } from "../MongoProxyClient";
import { createDatabase } from "./createDatabase";
@@ -284,9 +284,7 @@ const createCollectionWithSDK = async (params: DataModels.CreateCollectionParams
}
}
const databaseResponse: DatabaseResponse = await client(ClientOperationType.WRITE).databases.createIfNotExists(
createDatabaseBody,
);
const databaseResponse: DatabaseResponse = await client().databases.createIfNotExists(createDatabaseBody);
const collectionResponse: ContainerResponse = await databaseResponse?.database.containers.create(
createCollectionBody,
collectionOptions,

View File

@@ -4,7 +4,6 @@ import * as DataModels from "../../Contracts/DataModels";
import { useDatabases } from "../../Explorer/useDatabases";
import { userContext } from "../../UserContext";
import { getDatabaseName } from "../../Utils/APITypeUtils";
import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { createUpdateCassandraKeyspace } from "../../Utils/arm/generatedClients/cosmos/cassandraResources";
import { createUpdateGremlinDatabase } from "../../Utils/arm/generatedClients/cosmos/gremlinResources";
import { createUpdateMongoDBDatabase } from "../../Utils/arm/generatedClients/cosmos/mongoDBResources";
@@ -16,7 +15,8 @@ import {
MongoDBDatabaseCreateUpdateParameters,
SqlDatabaseCreateUpdateParameters,
} from "../../Utils/arm/generatedClients/cosmos/types";
import { ClientOperationType, client } from "../CosmosClient";
import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
export async function createDatabase(params: DataModels.CreateDatabaseParams): Promise<DataModels.Database> {
@@ -153,7 +153,7 @@ async function createDatabaseWithSDK(params: DataModels.CreateDatabaseParams): P
}
}
const response: DatabaseResponse = await client(ClientOperationType.WRITE).databases.create(createBody);
const response: DatabaseResponse = await client().databases.create(createBody);
return response.resource;
}

View File

@@ -1,6 +1,6 @@
import { CollectionBase } from "../../Contracts/ViewModels";
import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { ClientOperationType, client } from "../CosmosClient";
import { client } from "../CosmosClient";
import { getEntityName } from "../DocumentUtility";
import { handleError } from "../ErrorHandlingUtils";
@@ -9,7 +9,7 @@ export const createDocument = async (collection: CollectionBase, newDocument: un
const clearMessage = logConsoleProgress(`Creating new ${entityName} for container ${collection.id()}`);
try {
const response = await client(ClientOperationType.WRITE)
const response = await client()
.database(collection.databaseId)
.container(collection.id())
.items.create(newDocument);

View File

@@ -1,7 +1,6 @@
import { Resource, StoredProcedureDefinition } from "@azure/cosmos";
import { AuthType } from "../../AuthType";
import { userContext } from "../../UserContext";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import {
createUpdateSqlStoredProcedure,
getSqlStoredProcedure,
@@ -10,7 +9,8 @@ import {
SqlStoredProcedureCreateUpdateParameters,
SqlStoredProcedureResource,
} from "../../Utils/arm/generatedClients/cosmos/types";
import { ClientOperationType, client } from "../CosmosClient";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
export async function createStoredProcedure(
@@ -63,7 +63,7 @@ export async function createStoredProcedure(
return rpResponse && (rpResponse.properties?.resource as StoredProcedureDefinition & Resource);
}
const response = await client(ClientOperationType.WRITE)
const response = await client()
.database(databaseId)
.container(collectionId)
.scripts.storedProcedures.create(storedProcedure);

View File

@@ -1,10 +1,10 @@
import { TriggerDefinition } from "@azure/cosmos";
import { AuthType } from "../../AuthType";
import { userContext } from "../../UserContext";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { createUpdateSqlTrigger, getSqlTrigger } from "../../Utils/arm/generatedClients/cosmos/sqlResources";
import { SqlTriggerCreateUpdateParameters, SqlTriggerResource } from "../../Utils/arm/generatedClients/cosmos/types";
import { ClientOperationType, client } from "../CosmosClient";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
export async function createTrigger(
@@ -55,7 +55,7 @@ export async function createTrigger(
return rpResponse && rpResponse.properties?.resource;
}
const response = await client(ClientOperationType.WRITE)
const response = await client()
.database(databaseId)
.container(collectionId)
.scripts.triggers.create(trigger as unknown as TriggerDefinition); // TODO: TypeScript does not like the SQL SDK trigger type

View File

@@ -1,7 +1,6 @@
import { Resource, UserDefinedFunctionDefinition } from "@azure/cosmos";
import { AuthType } from "../../AuthType";
import { userContext } from "../../UserContext";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import {
createUpdateSqlUserDefinedFunction,
getSqlUserDefinedFunction,
@@ -10,7 +9,8 @@ import {
SqlUserDefinedFunctionCreateUpdateParameters,
SqlUserDefinedFunctionResource,
} from "../../Utils/arm/generatedClients/cosmos/types";
import { ClientOperationType, client } from "../CosmosClient";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
export async function createUserDefinedFunction(
@@ -63,7 +63,7 @@ export async function createUserDefinedFunction(
return rpResponse && (rpResponse.properties?.resource as UserDefinedFunctionDefinition & Resource);
}
const response = await client(ClientOperationType.WRITE)
const response = await client()
.database(databaseId)
.container(collectionId)
.scripts.userDefinedFunctions.create(userDefinedFunction);

View File

@@ -6,7 +6,7 @@ import { deleteMongoDBCollection } from "../../Utils/arm/generatedClients/cosmos
import { deleteSqlContainer } from "../../Utils/arm/generatedClients/cosmos/sqlResources";
import { deleteTable } from "../../Utils/arm/generatedClients/cosmos/tableResources";
import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { client, ClientOperationType } from "../CosmosClient";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
export async function deleteCollection(databaseId: string, collectionId: string): Promise<void> {
@@ -15,7 +15,7 @@ export async function deleteCollection(databaseId: string, collectionId: string)
if (userContext.authType === AuthType.AAD && !userContext.features.enableSDKoperations) {
await deleteCollectionWithARM(databaseId, collectionId);
} else {
await client(ClientOperationType.WRITE).database(databaseId).container(collectionId).delete();
await client().database(databaseId).container(collectionId).delete();
}
logConsoleInfo(`Successfully deleted container ${collectionId}`);
} catch (error) {

View File

@@ -1,9 +1,9 @@
import { RequestOptions } from "@azure/cosmos";
import { CollectionBase } from "../../Contracts/ViewModels";
import ConflictId from "../../Explorer/Tree/ConflictId";
import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { ClientOperationType, client } from "../CosmosClient";
import { CollectionBase } from "../../Contracts/ViewModels";
import { RequestOptions } from "@azure/cosmos";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
import { logConsoleProgress, logConsoleInfo } from "../../Utils/NotificationConsoleUtils";
export const deleteConflict = async (collection: CollectionBase, conflictId: ConflictId): Promise<void> => {
const clearMessage = logConsoleProgress(`Deleting conflict ${conflictId.id()}`);
@@ -13,7 +13,7 @@ export const deleteConflict = async (collection: CollectionBase, conflictId: Con
partitionKey: getPartitionKeyHeaderForConflict(conflictId),
};
await client(ClientOperationType.WRITE)
await client()
.database(collection.databaseId)
.container(collection.id())
.conflict(conflictId.id())

View File

@@ -5,7 +5,7 @@ import { deleteGremlinDatabase } from "../../Utils/arm/generatedClients/cosmos/g
import { deleteMongoDBDatabase } from "../../Utils/arm/generatedClients/cosmos/mongoDBResources";
import { deleteSqlDatabase } from "../../Utils/arm/generatedClients/cosmos/sqlResources";
import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { client, ClientOperationType } from "../CosmosClient";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
export async function deleteDatabase(databaseId: string): Promise<void> {
@@ -15,7 +15,7 @@ export async function deleteDatabase(databaseId: string): Promise<void> {
if (userContext.authType === AuthType.AAD && !userContext.features.enableSDKoperations) {
await deleteDatabaseWithARM(databaseId);
} else {
await client(ClientOperationType.WRITE).database(databaseId).delete();
await client().database(databaseId).delete();
}
logConsoleInfo(`Successfully deleted database ${databaseId}`);
} catch (error) {

View File

@@ -1,7 +1,7 @@
import { CollectionBase } from "../../Contracts/ViewModels";
import DocumentId from "../../Explorer/Tree/DocumentId";
import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { ClientOperationType, client } from "../CosmosClient";
import { client } from "../CosmosClient";
import { getEntityName } from "../DocumentUtility";
import { handleError } from "../ErrorHandlingUtils";
import { getPartitionKeyValue } from "./getPartitionKeyValue";
@@ -11,7 +11,7 @@ export const deleteDocument = async (collection: CollectionBase, documentId: Doc
const clearMessage = logConsoleProgress(`Deleting ${entityName} ${documentId.id()}`);
try {
await client(ClientOperationType.WRITE)
await client()
.database(collection.databaseId)
.container(collection.id())
.item(documentId.id(), getPartitionKeyValue(documentId))

View File

@@ -2,7 +2,7 @@ import { AuthType } from "../../AuthType";
import { userContext } from "../../UserContext";
import { deleteSqlStoredProcedure } from "../../Utils/arm/generatedClients/cosmos/sqlResources";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { client, ClientOperationType } from "../CosmosClient";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
export async function deleteStoredProcedure(
@@ -26,11 +26,7 @@ export async function deleteStoredProcedure(
storedProcedureId,
);
} else {
await client(ClientOperationType.WRITE)
.database(databaseId)
.container(collectionId)
.scripts.storedProcedure(storedProcedureId)
.delete();
await client().database(databaseId).container(collectionId).scripts.storedProcedure(storedProcedureId).delete();
}
} catch (error) {
handleError(error, "DeleteStoredProcedure", `Error while deleting stored procedure ${storedProcedureId}`);

View File

@@ -2,7 +2,7 @@ import { AuthType } from "../../AuthType";
import { userContext } from "../../UserContext";
import { deleteSqlTrigger } from "../../Utils/arm/generatedClients/cosmos/sqlResources";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { client, ClientOperationType } from "../CosmosClient";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
export async function deleteTrigger(databaseId: string, collectionId: string, triggerId: string): Promise<void> {
@@ -22,11 +22,7 @@ export async function deleteTrigger(databaseId: string, collectionId: string, tr
triggerId,
);
} else {
await client(ClientOperationType.WRITE)
.database(databaseId)
.container(collectionId)
.scripts.trigger(triggerId)
.delete();
await client().database(databaseId).container(collectionId).scripts.trigger(triggerId).delete();
}
} catch (error) {
handleError(error, "DeleteTrigger", `Error while deleting trigger ${triggerId}`);

View File

@@ -2,7 +2,7 @@ import { AuthType } from "../../AuthType";
import { userContext } from "../../UserContext";
import { deleteSqlUserDefinedFunction } from "../../Utils/arm/generatedClients/cosmos/sqlResources";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { client, ClientOperationType } from "../CosmosClient";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
export async function deleteUserDefinedFunction(databaseId: string, collectionId: string, id: string): Promise<void> {
@@ -22,11 +22,7 @@ export async function deleteUserDefinedFunction(databaseId: string, collectionId
id,
);
} else {
await client(ClientOperationType.WRITE)
.database(databaseId)
.container(collectionId)
.scripts.userDefinedFunction(id)
.delete();
await client().database(databaseId).container(collectionId).scripts.userDefinedFunction(id).delete();
}
} catch (error) {
handleError(error, "DeleteUserDefinedFunction", `Error while deleting user defined function ${id}`);

View File

@@ -1,9 +1,9 @@
import { Collection } from "../../Contracts/ViewModels";
import StoredProcedure from "../../Explorer/Tree/StoredProcedure";
import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { ClientDefaults, HttpHeaders } from "../Constants";
import { ClientOperationType, client } from "../CosmosClient";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
import { logConsoleProgress, logConsoleInfo } from "../../Utils/NotificationConsoleUtils";
import StoredProcedure from "../../Explorer/Tree/StoredProcedure";
export interface ExecuteSprocResult {
result: StoredProcedure;
@@ -22,7 +22,7 @@ export const executeStoredProcedure = async (
}, ClientDefaults.requestTimeoutMs);
try {
const response = await client(ClientOperationType.WRITE)
const response = await client()
.database(collection.databaseId)
.container(collection.id())
.scripts.storedProcedure(storedProcedure.id())

View File

@@ -1,9 +1,9 @@
import { AuthType } from "../../AuthType";
import { userContext } from "../../UserContext";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import * as Constants from "../Constants";
import { ClientOperationType, client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
import { AuthType } from "../../AuthType";
import { userContext } from "../../UserContext";
export async function getIndexTransformationProgress(databaseId: string, collectionId: string): Promise<number> {
if (userContext.authType !== AuthType.AAD) {
@@ -12,10 +12,7 @@ export async function getIndexTransformationProgress(databaseId: string, collect
let indexTransformationPercentage: number;
const clearMessage = logConsoleProgress(`Reading container ${collectionId}`);
try {
const response = await client(ClientOperationType.READ)
.database(databaseId)
.container(collectionId)
.read({ populateQuotaInfo: true });
const response = await client().database(databaseId).container(collectionId).read({ populateQuotaInfo: true });
indexTransformationPercentage = parseInt(
response.headers[Constants.HttpHeaders.collectionIndexTransformationProgress] as string,

View File

@@ -1,5 +1,5 @@
import { ConflictDefinition, FeedOptions, QueryIterator, Resource } from "@azure/cosmos";
import { ClientOperationType, client } from "../CosmosClient";
import { client } from "../CosmosClient";
export const queryConflicts = (
databaseId: string,
@@ -7,5 +7,5 @@ export const queryConflicts = (
query: string,
options: FeedOptions,
): QueryIterator<ConflictDefinition & Resource> => {
return client(ClientOperationType.READ).database(databaseId).container(containerId).conflicts.query(query, options);
return client().database(databaseId).container(containerId).conflicts.query(query, options);
};

View File

@@ -1,7 +1,7 @@
import { FeedOptions, ItemDefinition, QueryIterator, Resource } from "@azure/cosmos";
import { LocalStorageUtility, StorageKey } from "../../Shared/StorageUtility";
import { Queries } from "../Constants";
import { ClientOperationType, client } from "../CosmosClient";
import { client } from "../CosmosClient";
export const queryDocuments = (
databaseId: string,
@@ -10,7 +10,7 @@ export const queryDocuments = (
options: FeedOptions,
): QueryIterator<ItemDefinition & Resource> => {
options = getCommonQueryOptions(options);
return client(ClientOperationType.READ).database(databaseId).container(containerId).items.query(query, options);
return client().database(databaseId).container(containerId).items.query(query, options);
};
export const getCommonQueryOptions = (options: FeedOptions): FeedOptions => {

View File

@@ -3,11 +3,11 @@ import { sampleDataClient } from "Common/SampleDataClient";
import { userContext } from "UserContext";
import * as DataModels from "../../Contracts/DataModels";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { ClientOperationType, client } from "../CosmosClient";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
export async function readCollection(databaseId: string, collectionId: string): Promise<DataModels.Collection> {
const cosmosClient = client(ClientOperationType.READ);
const cosmosClient = client();
return await readCollectionInternal(cosmosClient, databaseId, collectionId);
}

View File

@@ -10,7 +10,7 @@ import { listGremlinGraphs } from "../../Utils/arm/generatedClients/cosmos/greml
import { listMongoDBCollections } from "../../Utils/arm/generatedClients/cosmos/mongoDBResources";
import { listSqlContainers } from "../../Utils/arm/generatedClients/cosmos/sqlResources";
import { listTables } from "../../Utils/arm/generatedClients/cosmos/tableResources";
import { ClientOperationType, client } from "../CosmosClient";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
export async function readCollections(databaseId: string): Promise<DataModels.Collection[]> {
@@ -31,7 +31,7 @@ export async function readCollections(databaseId: string): Promise<DataModels.Co
const tokenCollectionId = resourceIdObj[3];
if (tokenDatabaseId === databaseId) {
promises.push(client(ClientOperationType.READ).database(databaseId).container(tokenCollectionId).read());
promises.push(client().database(databaseId).container(tokenCollectionId).read());
}
}
@@ -61,7 +61,7 @@ export async function readCollections(databaseId: string): Promise<DataModels.Co
return await readCollectionsWithARM(databaseId);
}
const sdkResponse = await client(ClientOperationType.READ).database(databaseId).containers.readAll().fetchAll();
const sdkResponse = await client().database(databaseId).containers.readAll().fetchAll();
return sdkResponse.resources as DataModels.Collection[];
} catch (error) {
handleError(error, "ReadCollections", `Error while querying containers for database ${databaseId}`);
@@ -77,7 +77,7 @@ export async function readCollectionsWithPagination(
): Promise<DataModels.CollectionsWithPagination> {
const clearMessage = logConsoleProgress(`Querying containers for database ${databaseId}`);
try {
const sdkResponse = await client(ClientOperationType.READ)
const sdkResponse = await client()
.database(databaseId)
.containers.query(
{ query: "SELECT * FROM c" },

View File

@@ -7,7 +7,7 @@ import { listCassandraKeyspaces } from "../../Utils/arm/generatedClients/cosmos/
import { listGremlinDatabases } from "../../Utils/arm/generatedClients/cosmos/gremlinResources";
import { listMongoDBDatabases } from "../../Utils/arm/generatedClients/cosmos/mongoDBResources";
import { listSqlDatabases } from "../../Utils/arm/generatedClients/cosmos/sqlResources";
import { ClientOperationType, client } from "../CosmosClient";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
export async function readDatabases(): Promise<DataModels.Database[]> {
@@ -56,7 +56,7 @@ export async function readDatabases(): Promise<DataModels.Database[]> {
) {
databases = await readDatabasesWithARM();
} else {
const sdkResponse = await client(ClientOperationType.READ).databases.readAll().fetchAll();
const sdkResponse = await client().databases.readAll().fetchAll();
databases = sdkResponse.resources as DataModels.Database[];
}
} catch (error) {

View File

@@ -3,7 +3,7 @@ import { CollectionBase } from "../../Contracts/ViewModels";
import DocumentId from "../../Explorer/Tree/DocumentId";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { HttpHeaders } from "../Constants";
import { ClientOperationType, client } from "../CosmosClient";
import { client } from "../CosmosClient";
import { getEntityName } from "../DocumentUtility";
import { handleError } from "../ErrorHandlingUtils";
import { getPartitionKeyValue } from "./getPartitionKeyValue";
@@ -19,7 +19,7 @@ export const readDocument = async (collection: CollectionBase, documentId: Docum
[HttpHeaders.partitionKey]: documentId.partitionKeyValue,
}
: {};
const response = await client(ClientOperationType.READ)
const response = await client()
.database(collection.databaseId)
.container(collection.id())
.item(documentId.id(), getPartitionKeyValue(documentId))

View File

@@ -1,7 +1,7 @@
import { RequestOptions } from "@azure/cosmos";
import { Offer } from "../../Contracts/DataModels";
import { HttpHeaders } from "../Constants";
import { ClientOperationType, client } from "../CosmosClient";
import { client } from "../CosmosClient";
import { parseSDKOfferResponse } from "../OfferUtility";
import { readOffers } from "./readOffers";
@@ -21,7 +21,7 @@ export const readOfferWithSDK = async (offerId: string, resourceId: string): Pro
[HttpHeaders.populateCollectionThroughputInfo]: true,
},
};
const response = await client(ClientOperationType.READ).offer(offerId).read(options);
const response = await client().offer(offerId).read(options);
return parseSDKOfferResponse(response);
};

View File

@@ -1,13 +1,13 @@
import { SDKOfferDefinition } from "../../Contracts/DataModels";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { ClientOperationType, client } from "../CosmosClient";
import { getErrorMessage, handleError } from "../ErrorHandlingUtils";
import { client } from "../CosmosClient";
import { handleError, getErrorMessage } from "../ErrorHandlingUtils";
export const readOffers = async (): Promise<SDKOfferDefinition[]> => {
const clearMessage = logConsoleProgress(`Querying offers`);
try {
const response = await client(ClientOperationType.READ).offers.readAll().fetchAll();
const response = await client().offers.readAll().fetchAll();
return response?.resources;
} catch (error) {
// This should be removed when we can correctly identify if an account is serverless when connected using connection string too.

View File

@@ -4,7 +4,7 @@ import { AuthType } from "../../AuthType";
import { userContext } from "../../UserContext";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { listSqlStoredProcedures } from "../../Utils/arm/generatedClients/cosmos/sqlResources";
import { ClientOperationType, client } from "../CosmosClient";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
export async function readStoredProcedures(
@@ -34,7 +34,7 @@ export async function readStoredProcedures(
throw new Error(cloudError?.error?.message);
}
const response = await client(ClientOperationType.READ)
const response = await client()
.database(databaseId)
.container(collectionId)
.scripts.storedProcedures.readAll()

View File

@@ -1,10 +1,10 @@
import { TriggerDefinition } from "@azure/cosmos";
import { AuthType } from "../../AuthType";
import { userContext } from "../../UserContext";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { listSqlTriggers } from "../../Utils/arm/generatedClients/cosmos/sqlResources";
import { SqlTriggerResource } from "../../Utils/arm/generatedClients/cosmos/types";
import { ClientOperationType, client } from "../CosmosClient";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
export async function readTriggers(
@@ -28,11 +28,7 @@ export async function readTriggers(
return rpResponse?.value?.map((trigger) => trigger.properties?.resource);
}
const response = await client(ClientOperationType.READ)
.database(databaseId)
.container(collectionId)
.scripts.triggers.readAll()
.fetchAll();
const response = await client().database(databaseId).container(collectionId).scripts.triggers.readAll().fetchAll();
return response?.resources;
} catch (error) {
handleError(error, "ReadTriggers", `Failed to query triggers for container ${collectionId}`);

View File

@@ -1,9 +1,9 @@
import { Resource, UserDefinedFunctionDefinition } from "@azure/cosmos";
import { AuthType } from "../../AuthType";
import { userContext } from "../../UserContext";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { listSqlUserDefinedFunctions } from "../../Utils/arm/generatedClients/cosmos/sqlResources";
import { ClientOperationType, client } from "../CosmosClient";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
export async function readUserDefinedFunctions(
@@ -24,7 +24,7 @@ export async function readUserDefinedFunctions(
return rpResponse?.value?.map((udf) => udf.properties?.resource as UserDefinedFunctionDefinition & Resource);
}
const response = await client(ClientOperationType.READ)
const response = await client()
.database(databaseId)
.container(collectionId)
.scripts.userDefinedFunctions.readAll()

View File

@@ -2,7 +2,6 @@ import { ContainerDefinition, RequestOptions } from "@azure/cosmos";
import { AuthType } from "../../AuthType";
import { Collection } from "../../Contracts/DataModels";
import { userContext } from "../../UserContext";
import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import {
createUpdateCassandraTable,
getCassandraTable,
@@ -20,7 +19,8 @@ import {
SqlContainerCreateUpdateParameters,
SqlContainerResource,
} from "../../Utils/arm/generatedClients/cosmos/types";
import { ClientOperationType, client } from "../CosmosClient";
import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
export async function updateCollection(
@@ -40,7 +40,7 @@ export async function updateCollection(
) {
collection = await updateCollectionWithARM(databaseId, collectionId, newCollection);
} else {
const sdkResponse = await client(ClientOperationType.WRITE)
const sdkResponse = await client()
.database(databaseId)
.container(collectionId)
.replace(newCollection as ContainerDefinition, options);

View File

@@ -3,7 +3,7 @@ import { HttpHeaders } from "Common/Constants";
import { CollectionBase } from "../../Contracts/ViewModels";
import DocumentId from "../../Explorer/Tree/DocumentId";
import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { ClientOperationType, client } from "../CosmosClient";
import { client } from "../CosmosClient";
import { getEntityName } from "../DocumentUtility";
import { handleError } from "../ErrorHandlingUtils";
import { getPartitionKeyValue } from "./getPartitionKeyValue";
@@ -23,7 +23,7 @@ export const updateDocument = async (
[HttpHeaders.partitionKey]: documentId.partitionKeyValue,
}
: {};
const response = await client(ClientOperationType.WRITE)
const response = await client()
.database(collection.databaseId)
.container(collection.id())
.item(documentId.id(), getPartitionKeyValue(documentId))

View File

@@ -2,7 +2,6 @@ import { OfferDefinition, RequestOptions } from "@azure/cosmos";
import { AuthType } from "../../AuthType";
import { Offer, SDKOfferDefinition, UpdateOfferParams } from "../../Contracts/DataModels";
import { userContext } from "../../UserContext";
import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import {
migrateCassandraKeyspaceToAutoscale,
migrateCassandraKeyspaceToManualThroughput,
@@ -41,8 +40,9 @@ import {
updateTableThroughput,
} from "../../Utils/arm/generatedClients/cosmos/tableResources";
import { ThroughputSettingsUpdateParameters } from "../../Utils/arm/generatedClients/cosmos/types";
import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { HttpHeaders } from "../Constants";
import { ClientOperationType, client } from "../CosmosClient";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
import { parseSDKOfferResponse } from "../OfferUtility";
import { readCollectionOffer } from "./readCollectionOffer";
@@ -401,7 +401,7 @@ const updateOfferWithSDK = async (params: UpdateOfferParams): Promise<Offer> =>
newOffer.content.offerAutopilotSettings = { maxThroughput: 0 };
}
const sdkResponse = await client(ClientOperationType.WRITE)
const sdkResponse = await client()
.offer(params.currentOffer.id)
// TODO Remove casting when SDK types are fixed (https://github.com/Azure/azure-sdk-for-js/issues/10660)
.replace(newOffer as unknown as OfferDefinition, options);

View File

@@ -1,7 +1,6 @@
import { Resource, StoredProcedureDefinition } from "@azure/cosmos";
import { AuthType } from "../../AuthType";
import { userContext } from "../../UserContext";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import {
createUpdateSqlStoredProcedure,
getSqlStoredProcedure,
@@ -10,7 +9,8 @@ import {
SqlStoredProcedureCreateUpdateParameters,
SqlStoredProcedureResource,
} from "../../Utils/arm/generatedClients/cosmos/types";
import { ClientOperationType, client } from "../CosmosClient";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
export async function updateStoredProcedure(
@@ -54,7 +54,7 @@ export async function updateStoredProcedure(
throw new Error(`Failed to update stored procedure: ${storedProcedure.id} does not exist.`);
}
const response = await client(ClientOperationType.WRITE)
const response = await client()
.database(databaseId)
.container(collectionId)
.scripts.storedProcedure(storedProcedure.id)

View File

@@ -1,10 +1,10 @@
import { TriggerDefinition } from "@azure/cosmos";
import { AuthType } from "../../AuthType";
import { userContext } from "../../UserContext";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { createUpdateSqlTrigger, getSqlTrigger } from "../../Utils/arm/generatedClients/cosmos/sqlResources";
import { SqlTriggerCreateUpdateParameters, SqlTriggerResource } from "../../Utils/arm/generatedClients/cosmos/types";
import { ClientOperationType, client } from "../CosmosClient";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
export async function updateTrigger(
@@ -47,7 +47,7 @@ export async function updateTrigger(
throw new Error(`Failed to update trigger: ${trigger.id} does not exist.`);
}
const response = await client(ClientOperationType.WRITE)
const response = await client()
.database(databaseId)
.container(collectionId)
.scripts.trigger(trigger.id)

View File

@@ -1,7 +1,6 @@
import { Resource, UserDefinedFunctionDefinition } from "@azure/cosmos";
import { AuthType } from "../../AuthType";
import { userContext } from "../../UserContext";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import {
createUpdateSqlUserDefinedFunction,
getSqlUserDefinedFunction,
@@ -10,7 +9,8 @@ import {
SqlUserDefinedFunctionCreateUpdateParameters,
SqlUserDefinedFunctionResource,
} from "../../Utils/arm/generatedClients/cosmos/types";
import { ClientOperationType, client } from "../CosmosClient";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils";
export async function updateUserDefinedFunction(
@@ -53,7 +53,7 @@ export async function updateUserDefinedFunction(
throw new Error(`Failed to update user defined function: ${userDefinedFunction.id} does not exist.`);
}
const response = await client(ClientOperationType.WRITE)
const response = await client()
.database(databaseId)
.container(collectionId)
.scripts.userDefinedFunction(userDefinedFunction.id)

View File

@@ -102,20 +102,20 @@ let configContext: Readonly<ConfigContext> = {
NEW_BACKEND_APIS: [BackendApi.GenerateToken],
MONGO_PROXY_ENDPOINT: MongoProxyEndpoints.Prod,
NEW_MONGO_APIS: [
// "resourcelist",
// "createDocument",
// "readDocument",
// "updateDocument",
// "deleteDocument",
// "createCollectionWithProxy",
"resourcelist",
"createDocument",
"readDocument",
"updateDocument",
"deleteDocument",
"createCollectionWithProxy",
],
MONGO_PROXY_OUTBOUND_IPS_ALLOWLISTED: false,
CASSANDRA_PROXY_ENDPOINT: CassandraProxyEndpoints.Prod,
NEW_CASSANDRA_APIS: [
// "postQuery",
// "createOrDelete",
// "getKeys",
// "getSchema",
"postQuery",
"createOrDelete",
"getKeys",
"getSchema",
],
CASSANDRA_PROXY_OUTBOUND_IPS_ALLOWLISTED: false,
isTerminalEnabled: false,
@@ -248,3 +248,4 @@ export async function initializeConfiguration(): Promise<ConfigContext> {
}
export { configContext };

View File

@@ -53,7 +53,6 @@ export type FabricMessageV2 =
id: string;
message: {
connectionId: string;
isVisible: boolean;
};
}
| {
@@ -73,7 +72,7 @@ export type FabricMessageV2 =
};
}
| {
type: "explorerVisible";
type: "setToolbarStatus";
message: {
visible: boolean;
};

View File

@@ -23,7 +23,7 @@ import * as Constants from "../../../Common/Constants";
import { Platform, configContext } from "../../../ConfigContext";
import * as ViewModels from "../../../Contracts/ViewModels";
import { JunoClient } from "../../../Juno/JunoClient";
import { updateUserContext, userContext } from "../../../UserContext";
import { userContext } from "../../../UserContext";
import { getCollectionName, getDatabaseName } from "../../../Utils/APITypeUtils";
import { isRunningOnNationalCloud } from "../../../Utils/CloudUtils";
import { useSidePanel } from "../../../hooks/useSidePanel";
@@ -168,14 +168,6 @@ export function createStaticCommandBarButtons(
}
}
// Attempting to add region selection button here.
addDivider();
const [selectedRegion, setSelectedRegion] = React.useState(
userContext.databaseAccount.properties.locations[0].locationName,
);
const newReadRegionSelectionBtn = createReadRegionSelectionGroup(container, selectedRegion, setSelectedRegion);
buttons.push(newReadRegionSelectionBtn);
return buttons;
}
@@ -248,7 +240,7 @@ export function createControlCommandBarButtons(container: Explorer): CommandButt
buttons.push(fullScreenButton);
}
if (configContext.platform === Platform.Portal) {
if (configContext.platform !== Platform.Emulator) {
const label = "Feedback";
const feedbackButtonOptions: CommandButtonComponentProps = {
iconSrc: FeedbackIcon,
@@ -609,103 +601,6 @@ function createManageGitHubAccountButton(container: Explorer): CommandButtonComp
};
}
// function createReadRegionSelectionGroup(container: Explorer): CommandButtonComponentProps {
// const label = "Select a Read Region";
// return {
// iconAlt: label,
// commandButtonLabel: label,
// hasPopup: false,
// disabled: false,
// ariaLabel: label,
// onCommandClick: async () => {
// console.log(
// `CURRENT DOCUMENT ENDPOINT: ${JSON.stringify(userContext.databaseAccount.properties.documentEndpoint)}`,
// );
// userContext.databaseAccount.properties.readLocations.forEach((readLocation) => {
// console.log(`CURRENT READ ENDPOINT(S): ${JSON.stringify(readLocation)}`);
// });
// const updatedDatabaseAccount = {
// ...userContext.databaseAccount,
// properties: {
// ...userContext.databaseAccount.properties,
// documentEndpoint: "https://test-craig-nosql-periodic-eastus.documents.azure.com:443/",
// },
// };
// updateUserContext({
// databaseAccount: updatedDatabaseAccount,
// });
// },
// };
// }
function createReadRegionSelectionGroup(
container: Explorer,
selectedRegion: string,
setSelectedRegion: (region: string) => void,
): CommandButtonComponentProps {
const children = userContext.databaseAccount.properties.readLocations.map((readLocation) => ({
commandButtonLabel: readLocation.locationName,
onCommandClick: async () => {
const updatedDatabaseAccount = {
...userContext.databaseAccount,
properties: {
...userContext.databaseAccount.properties,
documentEndpoint: readLocation.documentEndpoint,
},
};
updateUserContext({
databaseAccount: updatedDatabaseAccount,
});
setSelectedRegion(readLocation.locationName);
},
hasPopup: false,
ariaLabel: `Select ${readLocation.locationName}`,
}));
const label = selectedRegion || "Select a Read Region";
return {
iconAlt: label,
commandButtonLabel: label,
onCommandClick: () => {},
hasPopup: true,
ariaLabel: label,
isDropdown: true,
children,
dropdownWidth: 100,
};
}
// function createAccountRegionSelectionButton(container: Explorer): JSX.Element {
// const [selectedEndpoint, setSelectedEndpoint] = useState(userContext.databaseAccount.properties.documentEndpoint);
// const handleChange = (event: React.ChangeEvent<{ value: unknown }>) => {
// const endpoint = event.target.value as string;
// setSelectedEndpoint(endpoint);
// const updatedDatabaseAccount = {
// ...userContext.databaseAccount,
// properties: {
// ...userContext.databaseAccount.properties,
// documentEndpoint: endpoint,
// },
// };
// updateUserContext({
// databaseAccount: updatedDatabaseAccount,
// });
// };
// return (
// <Select
// value={selectedEndpoint}
// onChange={handleChange}
// displayEmpty
// >
// {userContext.databaseAccount.properties.readLocations.map((readLocation) => (
// <MenuItem value={readLocation}>{readLocation}</MenuItem>
// ))}
// </Select>
// );
// }
function createStaticCommandBarButtonsForResourceToken(
container: Explorer,
selectedNodeState: SelectedNodeState,

View File

@@ -1,5 +1,4 @@
// TODO convert this file to an action registry in order to have actions and their handlers be more tightly coupled.
import { useDatabases } from "Explorer/useDatabases";
import React from "react";
import { ActionContracts } from "../../Contracts/ExplorerContracts";
import * as ViewModels from "../../Contracts/ViewModels";
@@ -41,112 +40,97 @@ function openCollectionTab(
databases: ViewModels.Database[],
initialDatabaseIndex = 0,
) {
//if databases are not yet loaded, wait until loaded
if (!databases || databases.length === 0) {
const databaseActionHandler = (databases: ViewModels.Database[]) => {
databasesUnsubscription();
openCollectionTab(action, databases, 0);
return;
};
const databasesUnsubscription = useDatabases.subscribe(databaseActionHandler, (state) => state.databases);
} else {
for (let i = initialDatabaseIndex; i < databases.length; i++) {
const database: ViewModels.Database = databases[i];
if (!!action.databaseResourceId && database.id() !== action.databaseResourceId) {
continue;
}
//expand database first if not expanded to load the collections
if (!database.isDatabaseExpanded?.()) {
database.expandDatabase?.();
}
const collectionActionHandler = (collections: ViewModels.Collection[]) => {
if (!action.collectionResourceId && collections.length === 0) {
subscription.dispose();
openCollectionTab(action, databases, ++i);
return;
}
for (let j = 0; j < collections.length; j++) {
const collection: ViewModels.Collection = collections[j];
if (!!action.collectionResourceId && collection.id() !== action.collectionResourceId) {
continue;
}
// select the collection
collection.expandCollection();
if (
action.tabKind === ActionContracts.TabKind.SQLDocuments ||
action.tabKind === ActionContracts.TabKind[ActionContracts.TabKind.SQLDocuments]
) {
collection.onDocumentDBDocumentsClick();
break;
}
if (
action.tabKind === ActionContracts.TabKind.MongoDocuments ||
action.tabKind === ActionContracts.TabKind[ActionContracts.TabKind.MongoDocuments]
) {
collection.onMongoDBDocumentsClick();
break;
}
if (
action.tabKind === ActionContracts.TabKind.SchemaAnalyzer ||
action.tabKind === ActionContracts.TabKind[ActionContracts.TabKind.SchemaAnalyzer]
) {
collection.onSchemaAnalyzerClick();
break;
}
if (
action.tabKind === ActionContracts.TabKind.TableEntities ||
action.tabKind === ActionContracts.TabKind[ActionContracts.TabKind.TableEntities]
) {
collection.onTableEntitiesClick();
break;
}
if (
action.tabKind === ActionContracts.TabKind.Graph ||
action.tabKind === ActionContracts.TabKind[ActionContracts.TabKind.Graph]
) {
collection.onGraphDocumentsClick();
break;
}
if (
action.tabKind === ActionContracts.TabKind.SQLQuery ||
action.tabKind === ActionContracts.TabKind[ActionContracts.TabKind.SQLQuery]
) {
collection.onNewQueryClick(
collection,
undefined,
generateQueryText(action as ActionContracts.OpenQueryTab, collection.partitionKeyProperties),
);
break;
}
if (
action.tabKind === ActionContracts.TabKind.ScaleSettings ||
action.tabKind === ActionContracts.TabKind[ActionContracts.TabKind.ScaleSettings]
) {
collection.onSettingsClick();
break;
}
}
subscription.dispose();
};
const subscription = database.collections.subscribe((collections) => collectionActionHandler(collections));
if (database.collections && database.collections() && database.collections().length) {
collectionActionHandler(database.collections());
}
break;
for (let i = initialDatabaseIndex; i < databases.length; i++) {
const database: ViewModels.Database = databases[i];
if (!!action.databaseResourceId && database.id() !== action.databaseResourceId) {
continue;
}
const collectionActionHandler = (collections: ViewModels.Collection[]) => {
if (!action.collectionResourceId && collections.length === 0) {
subscription.dispose();
openCollectionTab(action, databases, ++i);
return;
}
for (let j = 0; j < collections.length; j++) {
const collection: ViewModels.Collection = collections[j];
if (!!action.collectionResourceId && collection.id() !== action.collectionResourceId) {
continue;
}
// select the collection
collection.expandCollection();
if (
action.tabKind === ActionContracts.TabKind.SQLDocuments ||
action.tabKind === ActionContracts.TabKind[ActionContracts.TabKind.SQLDocuments]
) {
collection.onDocumentDBDocumentsClick();
break;
}
if (
action.tabKind === ActionContracts.TabKind.MongoDocuments ||
action.tabKind === ActionContracts.TabKind[ActionContracts.TabKind.MongoDocuments]
) {
collection.onMongoDBDocumentsClick();
break;
}
if (
action.tabKind === ActionContracts.TabKind.SchemaAnalyzer ||
action.tabKind === ActionContracts.TabKind[ActionContracts.TabKind.SchemaAnalyzer]
) {
collection.onSchemaAnalyzerClick();
break;
}
if (
action.tabKind === ActionContracts.TabKind.TableEntities ||
action.tabKind === ActionContracts.TabKind[ActionContracts.TabKind.TableEntities]
) {
collection.onTableEntitiesClick();
break;
}
if (
action.tabKind === ActionContracts.TabKind.Graph ||
action.tabKind === ActionContracts.TabKind[ActionContracts.TabKind.Graph]
) {
collection.onGraphDocumentsClick();
break;
}
if (
action.tabKind === ActionContracts.TabKind.SQLQuery ||
action.tabKind === ActionContracts.TabKind[ActionContracts.TabKind.SQLQuery]
) {
collection.onNewQueryClick(
collection,
undefined,
generateQueryText(action as ActionContracts.OpenQueryTab, collection.partitionKeyProperties),
);
break;
}
if (
action.tabKind === ActionContracts.TabKind.ScaleSettings ||
action.tabKind === ActionContracts.TabKind[ActionContracts.TabKind.ScaleSettings]
) {
collection.onSettingsClick();
break;
}
}
subscription.dispose();
};
const subscription = database.collections.subscribe((collections) => collectionActionHandler(collections));
if (database.collections && database.collections() && database.collections().length) {
collectionActionHandler(database.collections());
}
break;
}
}

View File

@@ -19,7 +19,7 @@ import Explorer from "../Explorer";
import * as TableConstants from "./Constants";
import * as Entities from "./Entities";
import * as TableEntityProcessor from "./TableEntityProcessor";
import { CassandraProxyAPIs } from "../../Common/Constants";
import { CassandraProxyAPIs, CassandraProxyEndpoints } from "../../Common/Constants";
export interface CassandraTableKeys {
partitionKeys: CassandraTableKey[];
@@ -458,7 +458,7 @@ export class CassandraAPIDataClient extends TableDataClient {
}
public getTableKeys(collection: ViewModels.Collection): Q.Promise<CassandraTableKeys> {
if (!this.useCassandraProxyEndpoint("getTableKeys")) {
if (!this.useCassandraProxyEndpoint("getKeys")) {
return this.getTableKeys_ToBeDeprecated(collection);
}
@@ -732,6 +732,7 @@ export class CassandraAPIDataClient extends TableDataClient {
}
private useCassandraProxyEndpoint(api: string): boolean {
const activeCassandraProxyEndpoints: string[] = [CassandraProxyEndpoints.Development, CassandraProxyEndpoints.Mpac];
let canAccessCassandraProxy: boolean = userContext.databaseAccount.properties.publicNetworkAccess === "Enabled";
if (userContext.databaseAccount.properties.ipRules?.length > 0) {
canAccessCassandraProxy = canAccessCassandraProxy && configContext.CASSANDRA_PROXY_OUTBOUND_IPS_ALLOWLISTED;
@@ -740,9 +741,7 @@ export class CassandraAPIDataClient extends TableDataClient {
return (
canAccessCassandraProxy &&
configContext.NEW_CASSANDRA_APIS?.includes(api) &&
[Constants.CassandraProxyEndpoints.Development, Constants.CassandraProxyEndpoints.Mpac].includes(
configContext.CASSANDRA_PROXY_ENDPOINT,
)
activeCassandraProxyEndpoints.includes(configContext.CASSANDRA_PROXY_ENDPOINT)
);
}
}

View File

@@ -40,10 +40,11 @@ export default class TabsBase extends WaitsForTemplateViewModel {
this.database = options.database;
this.rid = options.rid || (this.collection && this.collection.rid) || "";
this.tabKind = options.tabKind;
this.tabTitle = ko.observable<string>(this.getTitle(options));
this.tabTitle = ko.observable<string>(options.title);
this.tabPath =
this.collection &&
ko.observable<string>(`${this.collection.databaseId}>${this.collection.id()}>${options.title}`);
ko.observable(options.tabPath ?? "") ||
(this.collection &&
ko.observable<string>(`${this.collection.databaseId}>${this.collection.id()}>${this.tabTitle()}`));
this.pendingNotification = ko.observable<DataModels.Notification>(undefined);
this.onLoadStartKey = options.onLoadStartKey;
this.closeTabButton = {
@@ -142,26 +143,6 @@ export default class TabsBase extends WaitsForTemplateViewModel {
return (this.collection && this.collection.container) || (this.database && this.database.container);
}
public getTitle(options: ViewModels.TabOptions): string {
const coll = this.collection?.id();
const db = this.database?.id();
if (coll) {
if (coll.length > 8) {
return coll.slice(0, 5) + "…" + options.title;
} else {
return coll + "." + options.title;
}
} else if (db) {
if (db.length > 8) {
return db.slice(0, 5) + "…" + options.title;
} else {
return db + "." + options.title;
}
} else {
return options.title;
}
}
/** Renders a Javascript object to be displayed inside Monaco Editor */
public renderObjectForEditor(value: any, replacer: any, space: string | number): string {
return JSON.stringify(value, replacer, space);

View File

@@ -308,7 +308,7 @@ export default class Collection implements ViewModels.Collection {
collectionName: this.id(),
dataExplorerArea: Constants.Areas.Tab,
tabTitle: "Items",
tabTitle: this.rawDataModel.id + " - Items",
});
this.documentIds([]);
@@ -316,7 +316,7 @@ export default class Collection implements ViewModels.Collection {
partitionKey: this.partitionKey,
documentIds: ko.observableArray<DocumentId>([]),
tabKind: ViewModels.CollectionTabKind.Documents,
title: "Items",
title: this.rawDataModel.id + " - Items",
collection: this,
node: this,
tabPath: `${this.databaseId}>${this.id()}>Documents`,

View File

@@ -51,7 +51,6 @@ interface FabricContext {
connectionId: string;
databaseConnectionInfo: FabricDatabaseConnectionInfo | undefined;
isReadOnly: boolean;
isVisible: boolean;
}
export type AdminFeedbackControlPolicy =

View File

@@ -2,6 +2,7 @@ import { createUri } from "Common/UrlUtility";
import { DATA_EXPLORER_RPC_VERSION } from "Contracts/DataExplorerMessagesContract";
import { FABRIC_RPC_VERSION, FabricMessageV2 } from "Contracts/FabricMessagesContract";
import Explorer from "Explorer/Explorer";
import { useCommandBar } from "Explorer/Menus/CommandBar/CommandBarComponentAdapter";
import { useSelectedNode } from "Explorer/useSelectedNode";
import { scheduleRefreshDatabaseResourceToken } from "Platform/Fabric/FabricUtil";
import { getNetworkSettingsWarningMessage } from "Utils/NetworkUtility";
@@ -89,7 +90,6 @@ async function configureFabric(): Promise<Explorer> {
// These are the versions of Fabric that Data Explorer supports.
const SUPPORTED_FABRIC_VERSIONS = [FABRIC_RPC_VERSION];
let firstContainerOpened = false;
let explorer: Explorer;
return new Promise<Explorer>((resolve) => {
window.addEventListener(
@@ -121,10 +121,7 @@ async function configureFabric(): Promise<Explorer> {
await scheduleRefreshDatabaseResourceToken(true);
resolve(explorer);
await explorer.refreshAllDatabases();
if (userContext.fabricContext.isVisible && !firstContainerOpened) {
firstContainerOpened = true;
openFirstContainer(explorer, userContext.fabricContext.databaseConnectionInfo.databaseId);
}
openFirstContainer(explorer, userContext.fabricContext.databaseConnectionInfo.databaseId);
break;
}
case "newContainer":
@@ -135,16 +132,8 @@ async function configureFabric(): Promise<Explorer> {
handleCachedDataMessage(data);
break;
}
case "explorerVisible": {
userContext.fabricContext.isVisible = data.message.visible;
if (
userContext.fabricContext.isVisible &&
!firstContainerOpened &&
userContext?.fabricContext?.databaseConnectionInfo?.databaseId !== undefined
) {
firstContainerOpened = true;
openFirstContainer(explorer, userContext.fabricContext.databaseConnectionInfo.databaseId);
}
case "setToolbarStatus": {
useCommandBar.getState().setIsHidden(data.message.visible === false);
break;
}
default:
@@ -338,13 +327,12 @@ function configureHostedWithResourceToken(config: ResourceToken): Explorer {
return explorer;
}
function createExplorerFabric(params: { connectionId: string; isVisible: boolean }): Explorer {
function createExplorerFabric(params: { connectionId: string }): Explorer {
updateUserContext({
fabricContext: {
connectionId: params.connectionId,
databaseConnectionInfo: undefined,
isReadOnly: true,
isVisible: params.isVisible ?? true,
},
authType: AuthType.ConnectionString,
databaseAccount: {

View File

@@ -302,7 +302,6 @@ module.exports = function (_env = {}, argv = {}) {
pathRewrite: { "^/proxy": "" },
router: (req) => {
let newTarget = req.headers["x-ms-proxy-target"];
console.log(`Proxy path used. New target is: ${newTarget}`);
return newTarget;
},
},