Remove phoenix and notebook temporary down features and apply phoenix for whitelisted acounts

This commit is contained in:
kcheekuri 2021-11-10 10:52:41 -05:00
parent a9d38cdb3b
commit a7409553d4
18 changed files with 164 additions and 217 deletions

View File

@ -96,7 +96,6 @@ export class Flights {
public static readonly AutoscaleTest = "autoscaletest"; public static readonly AutoscaleTest = "autoscaletest";
public static readonly PartitionKeyTest = "partitionkeytest"; public static readonly PartitionKeyTest = "partitionkeytest";
public static readonly PKPartitionKeyTest = "pkpartitionkeytest"; public static readonly PKPartitionKeyTest = "pkpartitionkeytest";
public static readonly Phoenix = "phoenix";
public static readonly NotebooksDownBanner = "notebooksdownbanner"; public static readonly NotebooksDownBanner = "notebooksdownbanner";
} }

View File

@ -438,14 +438,16 @@ export interface ContainerInfo {
} }
export interface IProvisionData { export interface IProvisionData {
subscriptionId: string;
resourceGroup: string;
dbAccountName: string;
cosmosEndpoint: string; cosmosEndpoint: string;
} }
export interface IContainerData { export interface IAccountData {
subscriptionId: string;
resourceGroup: string;
dbAccountName: string; dbAccountName: string;
}
export interface IContainerData extends IAccountData {
forwardingId: string; forwardingId: string;
} }

View File

@ -83,7 +83,7 @@ export const createCollectionContextMenuButton = (
items.push({ items.push({
iconSrc: HostedTerminalIcon, iconSrc: HostedTerminalIcon,
isDisabled: useNotebook.getState().isShellEnabled && userContext.features.notebooksTemporarilyDown, isDisabled: useNotebook.getState().isShellEnabled && useNotebook.getState().isPhoenix === false,
onClick: () => { onClick: () => {
const selectedCollection: ViewModels.Collection = useSelectedNode.getState().findSelectedCollection(); const selectedCollection: ViewModels.Collection = useSelectedNode.getState().findSelectedCollection();
if (useNotebook.getState().isShellEnabled) { if (useNotebook.getState().isShellEnabled) {

View File

@ -14,7 +14,14 @@ import { getErrorMessage, getErrorStack, handleError } from "../Common/ErrorHand
import * as Logger from "../Common/Logger"; import * as Logger from "../Common/Logger";
import { QueriesClient } from "../Common/QueriesClient"; import { QueriesClient } from "../Common/QueriesClient";
import * as DataModels from "../Contracts/DataModels"; import * as DataModels from "../Contracts/DataModels";
import { ContainerConnectionInfo, IPhoenixConnectionInfoResult, IResponse } from "../Contracts/DataModels"; import {
ContainerConnectionInfo,
IAccountData,
IContainerData,
IPhoenixConnectionInfoResult,
IProvisionData,
IResponse,
} from "../Contracts/DataModels";
import * as ViewModels from "../Contracts/ViewModels"; import * as ViewModels from "../Contracts/ViewModels";
import { GitHubOAuthService } from "../GitHub/GitHubOAuthService"; import { GitHubOAuthService } from "../GitHub/GitHubOAuthService";
import { useSidePanel } from "../hooks/useSidePanel"; import { useSidePanel } from "../hooks/useSidePanel";
@ -30,7 +37,6 @@ import { update } from "../Utils/arm/generatedClients/cosmos/databaseAccounts";
import { import {
get as getWorkspace, get as getWorkspace,
listByDatabaseAccount, listByDatabaseAccount,
listConnectionInfo,
start, start,
} from "../Utils/arm/generatedClients/cosmosNotebooks/notebookWorkspaces"; } from "../Utils/arm/generatedClients/cosmosNotebooks/notebookWorkspaces";
import { stringToBlob } from "../Utils/BlobUtils"; import { stringToBlob } from "../Utils/BlobUtils";
@ -347,29 +353,11 @@ export default class Explorer {
if (!databaseAccount) { if (!databaseAccount) {
throw new Error("No database account specified"); throw new Error("No database account specified");
} }
if (this._isInitializingNotebooks) { if (this._isInitializingNotebooks) {
return; return;
} }
this._isInitializingNotebooks = true; this._isInitializingNotebooks = true;
if (userContext.features.phoenix === false) {
await this.ensureNotebookWorkspaceRunning();
const connectionInfo = await listConnectionInfo(
userContext.subscriptionId,
userContext.resourceGroup,
databaseAccount.name,
"default"
);
useNotebook.getState().setNotebookServerInfo({
notebookServerEndpoint: userContext.features.notebookServerUrl || connectionInfo.notebookServerEndpoint,
authToken: userContext.features.notebookServerToken || connectionInfo.authToken,
forwardingId: undefined,
});
}
this.refreshNotebookList(); this.refreshNotebookList();
this._isInitializingNotebooks = false; this._isInitializingNotebooks = false;
} }
@ -381,11 +369,13 @@ export default class Explorer {
(notebookServerInfo === undefined || (notebookServerInfo === undefined ||
(notebookServerInfo && notebookServerInfo.notebookServerEndpoint === undefined)) (notebookServerInfo && notebookServerInfo.notebookServerEndpoint === undefined))
) { ) {
const provisionData = { const provisionData: IProvisionData = {
cosmosEndpoint: userContext.databaseAccount.properties.documentEndpoint,
};
const accountData: IAccountData = {
subscriptionId: userContext.subscriptionId, subscriptionId: userContext.subscriptionId,
resourceGroup: userContext.resourceGroup, resourceGroup: userContext.resourceGroup,
dbAccountName: userContext.databaseAccount.name, dbAccountName: userContext.databaseAccount.name,
cosmosEndpoint: userContext.databaseAccount.properties.documentEndpoint,
}; };
const connectionStatus: ContainerConnectionInfo = { const connectionStatus: ContainerConnectionInfo = {
status: ConnectionStatusType.Connecting, status: ConnectionStatusType.Connecting,
@ -393,7 +383,7 @@ export default class Explorer {
useNotebook.getState().setConnectionInfo(connectionStatus); useNotebook.getState().setConnectionInfo(connectionStatus);
try { try {
useNotebook.getState().setIsAllocating(true); useNotebook.getState().setIsAllocating(true);
const connectionInfo = await this.phoenixClient.allocateContainer(provisionData); const connectionInfo = await this.phoenixClient.allocateContainer(provisionData, accountData);
await this.setNotebookInfo(connectionInfo, connectionStatus); await this.setNotebookInfo(connectionInfo, connectionStatus);
} catch (error) { } catch (error) {
connectionStatus.status = ConnectionStatusType.Failed; connectionStatus.status = ConnectionStatusType.Failed;
@ -412,9 +402,11 @@ export default class Explorer {
connectionStatus: DataModels.ContainerConnectionInfo connectionStatus: DataModels.ContainerConnectionInfo
) { ) {
if (connectionInfo.status === HttpStatusCodes.OK && connectionInfo.data && connectionInfo.data.notebookServerUrl) { if (connectionInfo.status === HttpStatusCodes.OK && connectionInfo.data && connectionInfo.data.notebookServerUrl) {
const containerData = { const containerData: IContainerData = {
forwardingId: connectionInfo.data.forwardingId, subscriptionId: userContext.subscriptionId,
resourceGroup: userContext.resourceGroup,
dbAccountName: userContext.databaseAccount.name, dbAccountName: userContext.databaseAccount.name,
forwardingId: connectionInfo.data.forwardingId,
}; };
await this.phoenixClient.initiateContainerHeartBeat(containerData); await this.phoenixClient.initiateContainerHeartBeat(containerData);
@ -443,14 +435,10 @@ export default class Explorer {
); );
return; return;
} }
const dialogContent = NotebookUtil.isPhoenixEnabled()
? "Notebooks saved in the temporary workspace will be deleted. Do you want to proceed?"
: "This lets you keep your notebook files and the workspace will be restored to default. Proceed anyway?";
const resetConfirmationDialogProps: DialogProps = { const resetConfirmationDialogProps: DialogProps = {
isModal: true, isModal: true,
title: "Reset Workspace", title: "Reset Workspace",
subText: dialogContent, subText: "Notebooks saved in the temporary workspace will be deleted. Do you want to proceed?",
primaryButtonText: "OK", primaryButtonText: "OK",
secondaryButtonText: "Cancel", secondaryButtonText: "Cancel",
onPrimaryButtonClick: this._resetNotebookWorkspace, onPrimaryButtonClick: this._resetNotebookWorkspace,
@ -517,17 +505,14 @@ export default class Explorer {
logConsoleError(error); logConsoleError(error);
return; return;
} }
if (NotebookUtil.isPhoenixEnabled()) {
useTabs.getState().closeAllNotebookTabs(true); useTabs.getState().closeAllNotebookTabs(true);
connectionStatus = { connectionStatus = {
status: ConnectionStatusType.Connecting, status: ConnectionStatusType.Connecting,
}; };
useNotebook.getState().setConnectionInfo(connectionStatus); useNotebook.getState().setConnectionInfo(connectionStatus);
}
const connectionInfo = await this.notebookManager?.notebookClient.resetWorkspace(); const connectionInfo = await this.notebookManager?.notebookClient.resetWorkspace();
if (connectionInfo && connectionInfo.status && connectionInfo.status === HttpStatusCodes.OK) { if (connectionInfo && connectionInfo.status && connectionInfo.status === HttpStatusCodes.OK) {
if (NotebookUtil.isPhoenixEnabled() && connectionInfo.data && connectionInfo.data.notebookServerUrl) { if (connectionInfo.data && connectionInfo.data.notebookServerUrl) {
await this.setNotebookInfo(connectionInfo, connectionStatus); await this.setNotebookInfo(connectionInfo, connectionStatus);
useNotebook.getState().setIsRefreshed(!useNotebook.getState().isRefreshed); useNotebook.getState().setIsRefreshed(!useNotebook.getState().isRefreshed);
} }
@ -536,27 +521,23 @@ export default class Explorer {
} else { } else {
logConsoleError(`Failed to reset notebook workspace`); logConsoleError(`Failed to reset notebook workspace`);
TelemetryProcessor.traceFailure(Action.ResetNotebookWorkspace); TelemetryProcessor.traceFailure(Action.ResetNotebookWorkspace);
if (NotebookUtil.isPhoenixEnabled()) {
connectionStatus = { connectionStatus = {
status: ConnectionStatusType.Reconnect, status: ConnectionStatusType.Reconnect,
}; };
useNotebook.getState().resetContainerConnection(connectionStatus); useNotebook.getState().resetContainerConnection(connectionStatus);
useNotebook.getState().setIsRefreshed(!useNotebook.getState().isRefreshed); useNotebook.getState().setIsRefreshed(!useNotebook.getState().isRefreshed);
} }
}
} catch (error) { } catch (error) {
logConsoleError(`Failed to reset notebook workspace: ${error}`); logConsoleError(`Failed to reset notebook workspace: ${error}`);
TelemetryProcessor.traceFailure(Action.ResetNotebookWorkspace, { TelemetryProcessor.traceFailure(Action.ResetNotebookWorkspace, {
error: getErrorMessage(error), error: getErrorMessage(error),
errorStack: getErrorStack(error), errorStack: getErrorStack(error),
}); });
if (NotebookUtil.isPhoenixEnabled()) {
connectionStatus = { connectionStatus = {
status: ConnectionStatusType.Failed, status: ConnectionStatusType.Failed,
}; };
useNotebook.getState().setConnectionInfo(connectionStatus); useNotebook.getState().setConnectionInfo(connectionStatus);
useNotebook.getState().setIsRefreshed(!useNotebook.getState().isRefreshed); useNotebook.getState().setIsRefreshed(!useNotebook.getState().isRefreshed);
}
throw error; throw error;
} finally { } finally {
clearInProgressMessage(); clearInProgressMessage();
@ -748,7 +729,7 @@ export default class Explorer {
if (!notebookContentItem || !notebookContentItem.path) { if (!notebookContentItem || !notebookContentItem.path) {
throw new Error(`Invalid notebookContentItem: ${notebookContentItem}`); throw new Error(`Invalid notebookContentItem: ${notebookContentItem}`);
} }
if (notebookContentItem.type === NotebookContentItemType.Notebook && NotebookUtil.isPhoenixEnabled()) { if (notebookContentItem.type === NotebookContentItemType.Notebook && useNotebook.getState().isPhoenix) {
await this.allocateContainer(); await this.allocateContainer();
} }
@ -972,7 +953,7 @@ export default class Explorer {
handleError(error, "Explorer/onNewNotebookClicked"); handleError(error, "Explorer/onNewNotebookClicked");
throw new Error(error); throw new Error(error);
} }
const isPhoenixEnabled = NotebookUtil.isPhoenixEnabled(); const isPhoenixEnabled = useNotebook.getState().isPhoenix;
if (isPhoenixEnabled) { if (isPhoenixEnabled) {
if (isGithubTree) { if (isGithubTree) {
async () => { async () => {
@ -1064,7 +1045,7 @@ export default class Explorer {
} }
public async openNotebookTerminal(kind: ViewModels.TerminalKind): Promise<void> { public async openNotebookTerminal(kind: ViewModels.TerminalKind): Promise<void> {
if (NotebookUtil.isPhoenixEnabled()) { if (useNotebook.getState().isPhoenix) {
await this.allocateContainer(); await this.allocateContainer();
const notebookServerInfo = useNotebook.getState().notebookServerInfo; const notebookServerInfo = useNotebook.getState().notebookServerInfo;
if (notebookServerInfo && notebookServerInfo.notebookServerEndpoint !== undefined) { if (notebookServerInfo && notebookServerInfo.notebookServerEndpoint !== undefined) {
@ -1204,7 +1185,7 @@ export default class Explorer {
} }
public async handleOpenFileAction(path: string): Promise<void> { public async handleOpenFileAction(path: string): Promise<void> {
if (userContext.features.phoenix) { if (useNotebook.getState().isPhoenix) {
await this.allocateContainer(); await this.allocateContainer();
} else if (!(await this._containsDefaultNotebookWorkspace(userContext.databaseAccount))) { } else if (!(await this._containsDefaultNotebookWorkspace(userContext.databaseAccount))) {
this._openSetupNotebooksPaneForQuickstart(); this._openSetupNotebooksPaneForQuickstart();
@ -1238,7 +1219,7 @@ export default class Explorer {
} }
public openUploadFilePanel(parent?: NotebookContentItem): void { public openUploadFilePanel(parent?: NotebookContentItem): void {
if (NotebookUtil.isPhoenixEnabled()) { if (useNotebook.getState().isPhoenix) {
useDialog.getState().showOkCancelModalDialog( useDialog.getState().showOkCancelModalDialog(
Notebook.newNotebookUploadModalTitle, Notebook.newNotebookUploadModalTitle,
undefined, undefined,
@ -1252,9 +1233,6 @@ export default class Explorer {
undefined, undefined,
this.getNewNoteWarningText() this.getNewNoteWarningText()
); );
} else {
parent = parent || this.resourceTree.myNotebooksContentRoot;
this.uploadFilePanel(parent);
} }
} }
@ -1268,7 +1246,7 @@ export default class Explorer {
} }
public getDownloadModalConent(fileName: string): JSX.Element { public getDownloadModalConent(fileName: string): JSX.Element {
if (NotebookUtil.isPhoenixEnabled()) { if (useNotebook.getState().isPhoenix) {
return ( return (
<> <>
<p>{Notebook.galleryNotebookDownloadContent1}</p> <p>{Notebook.galleryNotebookDownloadContent1}</p>
@ -1292,16 +1270,15 @@ export default class Explorer {
await useNotebook.getState().refreshNotebooksEnabledStateForAccount(); await useNotebook.getState().refreshNotebooksEnabledStateForAccount();
// TODO: remove reference to isNotebookEnabled and isNotebooksEnabledForAccount // TODO: remove reference to isNotebookEnabled and isNotebooksEnabledForAccount
const isNotebookEnabled = userContext.features.notebooksDownBanner || userContext.features.phoenix; const isNotebookEnabled = userContext.features.notebooksDownBanner || useNotebook.getState().isPhoenix;
useNotebook.getState().setIsNotebookEnabled(isNotebookEnabled); useNotebook.getState().setIsNotebookEnabled(isNotebookEnabled);
useNotebook.getState().setIsShellEnabled(userContext.features.phoenix && isPublicInternetAccessAllowed()); useNotebook.getState().setIsShellEnabled(useNotebook.getState().isPhoenix && isPublicInternetAccessAllowed());
TelemetryProcessor.trace(Action.NotebookEnabled, ActionModifiers.Mark, { TelemetryProcessor.trace(Action.NotebookEnabled, ActionModifiers.Mark, {
isNotebookEnabled, isNotebookEnabled,
dataExplorerArea: Constants.Areas.Notebook, dataExplorerArea: Constants.Areas.Notebook,
}); });
if (useNotebook.getState().isPhoenix) {
if (!userContext.features.notebooksTemporarilyDown) {
if (isNotebookEnabled) { if (isNotebookEnabled) {
await this.initNotebooks(userContext.databaseAccount); await this.initNotebooks(userContext.databaseAccount);
} else if (this.notebookToImport) { } else if (this.notebookToImport) {

View File

@ -4,15 +4,12 @@
* and update any knockout observables passed from the parent. * and update any knockout observables passed from the parent.
*/ */
import { CommandBar as FluentCommandBar, ICommandBarItemProps } from "@fluentui/react"; import { CommandBar as FluentCommandBar, ICommandBarItemProps } from "@fluentui/react";
import { useNotebook } from "Explorer/Notebook/useNotebook";
import * as React from "react"; import * as React from "react";
import create, { UseStore } from "zustand"; import create, { UseStore } from "zustand";
import { StyleConstants } from "../../../Common/Constants"; import { StyleConstants } from "../../../Common/Constants";
import * as ViewModels from "../../../Contracts/ViewModels";
import { useTabs } from "../../../hooks/useTabs";
import { userContext } from "../../../UserContext";
import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent"; import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent";
import Explorer from "../../Explorer"; import Explorer from "../../Explorer";
import { NotebookUtil } from "../../Notebook/NotebookUtil";
import { useSelectedNode } from "../../useSelectedNode"; import { useSelectedNode } from "../../useSelectedNode";
import * as CommandBarComponentButtonFactory from "./CommandBarComponentButtonFactory"; import * as CommandBarComponentButtonFactory from "./CommandBarComponentButtonFactory";
import * as CommandBarUtil from "./CommandBarUtil"; import * as CommandBarUtil from "./CommandBarUtil";
@ -56,18 +53,10 @@ export const CommandBar: React.FC<Props> = ({ container }: Props) => {
const uiFabricControlButtons = CommandBarUtil.convertButton(controlButtons, backgroundColor); const uiFabricControlButtons = CommandBarUtil.convertButton(controlButtons, backgroundColor);
uiFabricControlButtons.forEach((btn: ICommandBarItemProps) => (btn.iconOnly = true)); uiFabricControlButtons.forEach((btn: ICommandBarItemProps) => (btn.iconOnly = true));
if (NotebookUtil.isPhoenixEnabled()) { if (useNotebook.getState().isPhoenix) {
uiFabricControlButtons.unshift(CommandBarUtil.createConnectionStatus(container, "connectionStatus")); uiFabricControlButtons.unshift(CommandBarUtil.createConnectionStatus(container, "connectionStatus"));
} }
if (
userContext.features.phoenix === false &&
userContext.features.notebooksTemporarilyDown === false &&
useTabs.getState().activeTab?.tabKind === ViewModels.CollectionTabKind.NotebookV2
) {
uiFabricControlButtons.unshift(CommandBarUtil.createMemoryTracker("memoryTracker"));
}
return ( return (
<div className="commandBarContainer"> <div className="commandBarContainer">
<FluentCommandBar <FluentCommandBar

View File

@ -194,29 +194,26 @@ describe("CommandBarComponentButtonFactory tests", () => {
it("Notebooks is enabled and is unavailable - button should be shown and enabled", () => { it("Notebooks is enabled and is unavailable - button should be shown and enabled", () => {
useNotebook.getState().setIsNotebookEnabled(true); useNotebook.getState().setIsNotebookEnabled(true);
useNotebook.getState().setIsPhoenix(true);
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState); const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const openMongoShellBtn = buttons.find((button) => button.commandButtonLabel === openMongoShellBtnLabel); const openMongoShellBtn = buttons.find((button) => button.commandButtonLabel === openMongoShellBtnLabel);
expect(openMongoShellBtn).toBeDefined(); expect(openMongoShellBtn).toBeDefined();
//TODO: modify once notebooks are available expect(openMongoShellBtn.disabled).toBe(false);
expect(openMongoShellBtn.disabled).toBe(true); expect(openMongoShellBtn.tooltipText).toBe("");
//expect(openMongoShellBtn.disabled).toBe(false);
//expect(openMongoShellBtn.tooltipText).toBe("");
}); });
it("Notebooks is enabled and is available - button should be shown and enabled", () => { it("Notebooks is enabled and is available - button should be shown and enabled", () => {
useNotebook.getState().setIsNotebookEnabled(true); useNotebook.getState().setIsNotebookEnabled(true);
useNotebook.getState().setIsPhoenix(true);
useNotebook.getState().setIsNotebooksEnabledForAccount(true); useNotebook.getState().setIsNotebooksEnabledForAccount(true);
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState); const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const openMongoShellBtn = buttons.find((button) => button.commandButtonLabel === openMongoShellBtnLabel); const openMongoShellBtn = buttons.find((button) => button.commandButtonLabel === openMongoShellBtnLabel);
expect(openMongoShellBtn).toBeDefined(); expect(openMongoShellBtn).toBeDefined();
expect(openMongoShellBtn.disabled).toBe(false);
//TODO: modify once notebooks are available expect(openMongoShellBtn.tooltipText).toBe("");
expect(openMongoShellBtn.disabled).toBe(true);
//expect(openMongoShellBtn.disabled).toBe(false);
//expect(openMongoShellBtn.tooltipText).toBe("");
}); });
it("Notebooks is enabled and is available, terminal is unavailable due to ipRules - button should be hidden", () => { it("Notebooks is enabled and is available, terminal is unavailable due to ipRules - button should be hidden", () => {
@ -299,30 +296,27 @@ describe("CommandBarComponentButtonFactory tests", () => {
it("Notebooks is enabled and is unavailable - button should be shown and enabled", () => { it("Notebooks is enabled and is unavailable - button should be shown and enabled", () => {
useNotebook.getState().setIsNotebookEnabled(true); useNotebook.getState().setIsNotebookEnabled(true);
useNotebook.getState().setIsPhoenix(true);
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState); const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const openCassandraShellBtn = buttons.find((button) => button.commandButtonLabel === openCassandraShellBtnLabel); const openCassandraShellBtn = buttons.find((button) => button.commandButtonLabel === openCassandraShellBtnLabel);
expect(openCassandraShellBtn).toBeDefined(); expect(openCassandraShellBtn).toBeDefined();
//TODO: modify once notebooks are available expect(openCassandraShellBtn.disabled).toBe(false);
expect(openCassandraShellBtn.disabled).toBe(true); expect(openCassandraShellBtn.tooltipText).toBe("");
//expect(openCassandraShellBtn.disabled).toBe(false);
//expect(openCassandraShellBtn.tooltipText).toBe("");
}); });
it("Notebooks is enabled and is available - button should be shown and enabled", () => { it("Notebooks is enabled and is available - button should be shown and enabled", () => {
useNotebook.getState().setIsNotebookEnabled(true); useNotebook.getState().setIsNotebookEnabled(true);
useNotebook.getState().setIsPhoenix(true);
useNotebook.getState().setIsNotebooksEnabledForAccount(true); useNotebook.getState().setIsNotebooksEnabledForAccount(true);
const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState); const buttons = CommandBarComponentButtonFactory.createStaticCommandBarButtons(mockExplorer, selectedNodeState);
const openCassandraShellBtn = buttons.find((button) => button.commandButtonLabel === openCassandraShellBtnLabel); const openCassandraShellBtn = buttons.find((button) => button.commandButtonLabel === openCassandraShellBtnLabel);
expect(openCassandraShellBtn).toBeDefined(); expect(openCassandraShellBtn).toBeDefined();
expect(openCassandraShellBtn.disabled).toBe(false);
//TODO: modify once notebooks are available expect(openCassandraShellBtn.tooltipText).toBe("");
expect(openCassandraShellBtn.disabled).toBe(true);
//expect(openCassandraShellBtn.disabled).toBe(false);
//expect(openCassandraShellBtn.tooltipText).toBe("");
}); });
}); });

View File

@ -10,7 +10,6 @@ import CosmosTerminalIcon from "../../../../images/Cosmos-Terminal.svg";
import FeedbackIcon from "../../../../images/Feedback-Command.svg"; import FeedbackIcon from "../../../../images/Feedback-Command.svg";
import GitHubIcon from "../../../../images/github.svg"; import GitHubIcon from "../../../../images/github.svg";
import HostedTerminalIcon from "../../../../images/Hosted-Terminal.svg"; import HostedTerminalIcon from "../../../../images/Hosted-Terminal.svg";
import EnableNotebooksIcon from "../../../../images/notebook/Notebook-enable.svg";
import NewNotebookIcon from "../../../../images/notebook/Notebook-new.svg"; import NewNotebookIcon from "../../../../images/notebook/Notebook-new.svg";
import ResetWorkspaceIcon from "../../../../images/notebook/Notebook-reset-workspace.svg"; import ResetWorkspaceIcon from "../../../../images/notebook/Notebook-reset-workspace.svg";
import OpenInTabIcon from "../../../../images/open-in-tab.svg"; import OpenInTabIcon from "../../../../images/open-in-tab.svg";
@ -98,7 +97,7 @@ export function createStaticCommandBarButtons(
} }
notebookButtons.forEach((btn) => { notebookButtons.forEach((btn) => {
if (userContext.features.notebooksTemporarilyDown) { if (useNotebook.getState().isPhoenix === false && userContext.features.notebooksDownBanner) {
if (btn.commandButtonLabel.indexOf("Cassandra") !== -1) { if (btn.commandButtonLabel.indexOf("Cassandra") !== -1) {
applyNotebooksTemporarilyDownStyle(btn, Constants.Notebook.cassandraShellTemporarilyDownMsg); applyNotebooksTemporarilyDownStyle(btn, Constants.Notebook.cassandraShellTemporarilyDownMsg);
} else if (btn.commandButtonLabel.indexOf("Mongo") !== -1) { } else if (btn.commandButtonLabel.indexOf("Mongo") !== -1) {
@ -109,11 +108,6 @@ export function createStaticCommandBarButtons(
} }
buttons.push(btn); buttons.push(btn);
}); });
} else {
if (!isRunningOnNationalCloud() && !userContext.features.notebooksTemporarilyDown) {
buttons.push(createDivider());
buttons.push(createEnableNotebooksButton(container));
}
} }
if (!selectedNodeState.isDatabaseNodeOrNoneSelected()) { if (!selectedNodeState.isDatabaseNodeOrNoneSelected()) {
@ -168,7 +162,7 @@ export function createContextCommandBarButtons(
onCommandClick: () => { onCommandClick: () => {
const selectedCollection: ViewModels.Collection = selectedNodeState.findSelectedCollection(); const selectedCollection: ViewModels.Collection = selectedNodeState.findSelectedCollection();
if (useNotebook.getState().isShellEnabled) { if (useNotebook.getState().isShellEnabled) {
if (!userContext.features.notebooksTemporarilyDown) { if (useNotebook.getState().isPhoenix) {
container.openNotebookTerminal(ViewModels.TerminalKind.Mongo); container.openNotebookTerminal(ViewModels.TerminalKind.Mongo);
} }
} else { } else {
@ -179,12 +173,12 @@ export function createContextCommandBarButtons(
ariaLabel: label, ariaLabel: label,
hasPopup: true, hasPopup: true,
tooltipText: tooltipText:
useNotebook.getState().isShellEnabled && userContext.features.notebooksTemporarilyDown useNotebook.getState().isShellEnabled && useNotebook.getState().isPhoenix === false
? Constants.Notebook.mongoShellTemporarilyDownMsg ? Constants.Notebook.mongoShellTemporarilyDownMsg
: undefined, : undefined,
disabled: disabled:
(selectedNodeState.isDatabaseNodeOrNoneSelected() && userContext.apiType === "Mongo") || (selectedNodeState.isDatabaseNodeOrNoneSelected() && userContext.apiType === "Mongo") ||
(useNotebook.getState().isShellEnabled && userContext.features.notebooksTemporarilyDown), (useNotebook.getState().isShellEnabled && useNotebook.getState().isPhoenix === false),
}; };
buttons.push(newMongoShellBtn); buttons.push(newMongoShellBtn);
} }
@ -476,33 +470,6 @@ function createOpenQueryFromDiskButton(): CommandButtonComponentProps {
}; };
} }
function createEnableNotebooksButton(container: Explorer): CommandButtonComponentProps {
if (configContext.platform === Platform.Emulator) {
return undefined;
}
const label = "Enable Notebooks (Preview)";
const tooltip =
"Notebooks are not yet available in your account's region. View supported regions here: https://aka.ms/cosmos-enable-notebooks.";
const description =
"Looks like you have not yet created a notebooks workspace for this account. To proceed and start using notebooks, we'll need to create a default notebooks workspace in this account.";
return {
iconSrc: EnableNotebooksIcon,
iconAlt: label,
onCommandClick: () =>
useSidePanel
.getState()
.openSidePanel(
label,
<SetupNoteBooksPanel explorer={container} panelTitle={label} panelDescription={description} />
),
commandButtonLabel: label,
hasPopup: false,
disabled: !useNotebook.getState().isNotebooksEnabledForAccount,
ariaLabel: label,
tooltipText: useNotebook.getState().isNotebooksEnabledForAccount ? "" : tooltip,
};
}
function createOpenTerminalButton(container: Explorer): CommandButtonComponentProps { function createOpenTerminalButton(container: Explorer): CommandButtonComponentProps {
const label = "Open Terminal"; const label = "Open Terminal";
return { return {

View File

@ -10,6 +10,7 @@ import * as Logger from "../../Common/Logger";
import * as DataModels from "../../Contracts/DataModels"; import * as DataModels from "../../Contracts/DataModels";
import { import {
ContainerConnectionInfo, ContainerConnectionInfo,
IAccountData,
IPhoenixConnectionInfoResult, IPhoenixConnectionInfoResult,
IProvisionData, IProvisionData,
IResponse, IResponse,
@ -18,7 +19,6 @@ import { userContext } from "../../UserContext";
import { createOrUpdate, destroy } from "../../Utils/arm/generatedClients/cosmosNotebooks/notebookWorkspaces"; import { createOrUpdate, destroy } from "../../Utils/arm/generatedClients/cosmosNotebooks/notebookWorkspaces";
import { getAuthorizationHeader } from "../../Utils/AuthorizationUtils"; import { getAuthorizationHeader } from "../../Utils/AuthorizationUtils";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils"; import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { NotebookUtil } from "./NotebookUtil";
import { useNotebook } from "./useNotebook"; import { useNotebook } from "./useNotebook";
export class NotebookContainerClient { export class NotebookContainerClient {
@ -63,7 +63,7 @@ export class NotebookContainerClient {
this.scheduleHeartbeat(Constants.Notebook.heartbeatDelayMs); this.scheduleHeartbeat(Constants.Notebook.heartbeatDelayMs);
} }
} catch (exception) { } catch (exception) {
if (NotebookUtil.isPhoenixEnabled()) { if (useNotebook.getState().isPhoenix) {
const connectionStatus: ContainerConnectionInfo = { const connectionStatus: ContainerConnectionInfo = {
status: ConnectionStatusType.Failed, status: ConnectionStatusType.Failed,
}; };
@ -131,14 +131,14 @@ export class NotebookContainerClient {
} else if (response.status === HttpStatusCodes.NotFound) { } else if (response.status === HttpStatusCodes.NotFound) {
throw new AbortError(response.statusText); throw new AbortError(response.statusText);
} }
throw new Error(); throw new Error(response.statusText);
} else { } else {
return undefined; return undefined;
} }
} }
private checkStatus(): boolean { private checkStatus(): boolean {
if (NotebookUtil.isPhoenixEnabled()) { if (useNotebook.getState().isPhoenix) {
if (useNotebook.getState().containerStatus?.status === Constants.ContainerStatusType.Disconnected) { if (useNotebook.getState().containerStatus?.status === Constants.ContainerStatusType.Disconnected) {
const connectionStatus: ContainerConnectionInfo = { const connectionStatus: ContainerConnectionInfo = {
status: ConnectionStatusType.Reconnect, status: ConnectionStatusType.Reconnect,
@ -173,21 +173,20 @@ export class NotebookContainerClient {
} }
try { try {
if (NotebookUtil.isPhoenixEnabled()) { if (useNotebook.getState().isPhoenix) {
const provisionData: IProvisionData = { const provisionData: IProvisionData = {
cosmosEndpoint: userContext.databaseAccount.properties.documentEndpoint,
};
const accountData: IAccountData = {
subscriptionId: userContext.subscriptionId, subscriptionId: userContext.subscriptionId,
resourceGroup: userContext.resourceGroup, resourceGroup: userContext.resourceGroup,
dbAccountName: userContext.databaseAccount.name, dbAccountName: userContext.databaseAccount.name,
cosmosEndpoint: userContext.databaseAccount.properties.documentEndpoint,
}; };
return await this.phoenixClient.resetContainer(provisionData); return await this.phoenixClient.resetContainer(provisionData, accountData);
} }
return null; return null;
} catch (error) { } catch (error) {
Logger.logError(getErrorMessage(error), "NotebookContainerClient/resetWorkspace"); Logger.logError(getErrorMessage(error), "NotebookContainerClient/resetWorkspace");
if (!NotebookUtil.isPhoenixEnabled()) {
await this.recreateNotebookWorkspaceAsync();
}
throw error; throw error;
} }
} }

View File

@ -1,9 +1,9 @@
import { ImmutableCodeCell, ImmutableNotebook } from "@nteract/commutable"; import { ImmutableCodeCell, ImmutableNotebook } from "@nteract/commutable";
import { AppState, selectors } from "@nteract/core"; import { AppState, selectors } from "@nteract/core";
import domtoimage from "dom-to-image"; import domtoimage from "dom-to-image";
import { useNotebook } from "Explorer/Notebook/useNotebook";
import Html2Canvas from "html2canvas"; import Html2Canvas from "html2canvas";
import path from "path"; import path from "path";
import { userContext } from "../../UserContext";
import * as GitHubUtils from "../../Utils/GitHubUtils"; import * as GitHubUtils from "../../Utils/GitHubUtils";
import * as StringUtils from "../../Utils/StringUtils"; import * as StringUtils from "../../Utils/StringUtils";
import { SnapshotFragment } from "./NotebookComponent/types"; import { SnapshotFragment } from "./NotebookComponent/types";
@ -331,14 +331,10 @@ export class NotebookUtil {
} }
public static getNotebookBtnTitle(fileName: string): string { public static getNotebookBtnTitle(fileName: string): string {
if (this.isPhoenixEnabled()) { if (useNotebook.getState().isPhoenix) {
return `Download to ${fileName}`; return `Download to ${fileName}`;
} else { } else {
return `Download to my notebooks`; return `Download to my notebooks`;
} }
} }
public static isPhoenixEnabled(): boolean {
return userContext.features.notebooksTemporarilyDown === false && userContext.features.phoenix === true;
}
} }

View File

@ -1,4 +1,5 @@
import { cloneDeep } from "lodash"; import { cloneDeep } from "lodash";
import { PhoenixClient } from "Phoenix/PhoenixClient";
import create, { UseStore } from "zustand"; import create, { UseStore } from "zustand";
import { AuthType } from "../../AuthType"; import { AuthType } from "../../AuthType";
import * as Constants from "../../Common/Constants"; import * as Constants from "../../Common/Constants";
@ -7,7 +8,7 @@ import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
import * as Logger from "../../Common/Logger"; import * as Logger from "../../Common/Logger";
import { configContext } from "../../ConfigContext"; import { configContext } from "../../ConfigContext";
import * as DataModels from "../../Contracts/DataModels"; import * as DataModels from "../../Contracts/DataModels";
import { ContainerConnectionInfo, ContainerInfo } from "../../Contracts/DataModels"; import { ContainerConnectionInfo, ContainerInfo, IAccountData } from "../../Contracts/DataModels";
import { useTabs } from "../../hooks/useTabs"; import { useTabs } from "../../hooks/useTabs";
import { IPinnedRepo } from "../../Juno/JunoClient"; import { IPinnedRepo } from "../../Juno/JunoClient";
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants"; import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
@ -17,7 +18,6 @@ import { getAuthorizationHeader } from "../../Utils/AuthorizationUtils";
import * as GitHubUtils from "../../Utils/GitHubUtils"; import * as GitHubUtils from "../../Utils/GitHubUtils";
import { NotebookContentItem, NotebookContentItemType } from "./NotebookContentItem"; import { NotebookContentItem, NotebookContentItemType } from "./NotebookContentItem";
import NotebookManager from "./NotebookManager"; import NotebookManager from "./NotebookManager";
import { NotebookUtil } from "./NotebookUtil";
interface NotebookState { interface NotebookState {
isNotebookEnabled: boolean; isNotebookEnabled: boolean;
@ -37,6 +37,7 @@ interface NotebookState {
isAllocating: boolean; isAllocating: boolean;
isRefreshed: boolean; isRefreshed: boolean;
containerStatus: ContainerInfo; containerStatus: ContainerInfo;
isPhoenix: boolean;
setIsNotebookEnabled: (isNotebookEnabled: boolean) => void; setIsNotebookEnabled: (isNotebookEnabled: boolean) => void;
setIsNotebooksEnabledForAccount: (isNotebooksEnabledForAccount: boolean) => void; setIsNotebooksEnabledForAccount: (isNotebooksEnabledForAccount: boolean) => void;
setNotebookServerInfo: (notebookServerInfo: DataModels.NotebookWorkspaceConnectionInfo) => void; setNotebookServerInfo: (notebookServerInfo: DataModels.NotebookWorkspaceConnectionInfo) => void;
@ -58,6 +59,8 @@ interface NotebookState {
resetContainerConnection: (connectionStatus: ContainerConnectionInfo) => void; resetContainerConnection: (connectionStatus: ContainerConnectionInfo) => void;
setIsRefreshed: (isAllocating: boolean) => void; setIsRefreshed: (isAllocating: boolean) => void;
setContainerStatus: (containerStatus: ContainerInfo) => void; setContainerStatus: (containerStatus: ContainerInfo) => void;
getPhoenixStatus: () => Promise<void>;
setIsPhoenix: (isPhoenix: boolean) => void;
} }
export const useNotebook: UseStore<NotebookState> = create((set, get) => ({ export const useNotebook: UseStore<NotebookState> = create((set, get) => ({
@ -92,6 +95,7 @@ export const useNotebook: UseStore<NotebookState> = create((set, get) => ({
durationLeftInMinutes: undefined, durationLeftInMinutes: undefined,
notebookServerInfo: undefined, notebookServerInfo: undefined,
}, },
isPhoenix: undefined,
setIsNotebookEnabled: (isNotebookEnabled: boolean) => set({ isNotebookEnabled }), setIsNotebookEnabled: (isNotebookEnabled: boolean) => set({ isNotebookEnabled }),
setIsNotebooksEnabledForAccount: (isNotebooksEnabledForAccount: boolean) => set({ isNotebooksEnabledForAccount }), setIsNotebooksEnabledForAccount: (isNotebooksEnabledForAccount: boolean) => set({ isNotebooksEnabledForAccount }),
setNotebookServerInfo: (notebookServerInfo: DataModels.NotebookWorkspaceConnectionInfo) => setNotebookServerInfo: (notebookServerInfo: DataModels.NotebookWorkspaceConnectionInfo) =>
@ -104,6 +108,7 @@ export const useNotebook: UseStore<NotebookState> = create((set, get) => ({
setNotebookBasePath: (notebookBasePath: string) => set({ notebookBasePath }), setNotebookBasePath: (notebookBasePath: string) => set({ notebookBasePath }),
setNotebookFolderName: (notebookFolderName: string) => set({ notebookFolderName }), setNotebookFolderName: (notebookFolderName: string) => set({ notebookFolderName }),
refreshNotebooksEnabledStateForAccount: async (): Promise<void> => { refreshNotebooksEnabledStateForAccount: async (): Promise<void> => {
await get().getPhoenixStatus();
const { databaseAccount, authType } = userContext; const { databaseAccount, authType } = userContext;
if ( if (
authType === AuthType.EncryptedToken || authType === AuthType.EncryptedToken ||
@ -196,7 +201,7 @@ export const useNotebook: UseStore<NotebookState> = create((set, get) => ({
isGithubTree ? set({ gitHubNotebooksContentRoot: root }) : set({ myNotebooksContentRoot: root }); isGithubTree ? set({ gitHubNotebooksContentRoot: root }) : set({ myNotebooksContentRoot: root });
}, },
initializeNotebooksTree: async (notebookManager: NotebookManager): Promise<void> => { initializeNotebooksTree: async (notebookManager: NotebookManager): Promise<void> => {
const notebookFolderName = NotebookUtil.isPhoenixEnabled() === true ? "Temporary Notebooks" : "My Notebooks"; const notebookFolderName = "Temporary Notebooks";
set({ notebookFolderName }); set({ notebookFolderName });
const myNotebooksContentRoot = { const myNotebooksContentRoot = {
name: get().notebookFolderName, name: get().notebookFolderName,
@ -292,4 +297,17 @@ export const useNotebook: UseStore<NotebookState> = create((set, get) => ({
}, },
setIsRefreshed: (isRefreshed: boolean) => set({ isRefreshed }), setIsRefreshed: (isRefreshed: boolean) => set({ isRefreshed }),
setContainerStatus: (containerStatus: ContainerInfo) => set({ containerStatus }), setContainerStatus: (containerStatus: ContainerInfo) => set({ containerStatus }),
getPhoenixStatus: async () => {
if (get().isPhoenix === undefined) {
const phoenixClient = new PhoenixClient();
const accountData: IAccountData = {
subscriptionId: userContext.subscriptionId,
resourceGroup: userContext.resourceGroup,
dbAccountName: userContext.databaseAccount.name,
};
const isPhoenix = await phoenixClient.IsDbAcountWhitelisted(accountData);
set({ isPhoenix });
}
},
setIsPhoenix: (isPhoenix: boolean) => set({ isPhoenix }),
})); }));

View File

@ -5,7 +5,6 @@ import { getErrorMessage, handleError } from "../../../Common/ErrorHandlingUtils
import { GitHubOAuthService } from "../../../GitHub/GitHubOAuthService"; import { GitHubOAuthService } from "../../../GitHub/GitHubOAuthService";
import { useSidePanel } from "../../../hooks/useSidePanel"; import { useSidePanel } from "../../../hooks/useSidePanel";
import { IPinnedRepo, JunoClient } from "../../../Juno/JunoClient"; import { IPinnedRepo, JunoClient } from "../../../Juno/JunoClient";
import { userContext } from "../../../UserContext";
import * as GitHubUtils from "../../../Utils/GitHubUtils"; import * as GitHubUtils from "../../../Utils/GitHubUtils";
import * as NotificationConsoleUtils from "../../../Utils/NotificationConsoleUtils"; import * as NotificationConsoleUtils from "../../../Utils/NotificationConsoleUtils";
import Explorer from "../../Explorer"; import Explorer from "../../Explorer";
@ -76,7 +75,7 @@ export const CopyNotebookPane: FunctionComponent<CopyNotebookPanelProps> = ({
selectedLocation.owner, selectedLocation.owner,
selectedLocation.repo selectedLocation.repo
)} - ${selectedLocation.branch}`; )} - ${selectedLocation.branch}`;
} else if (selectedLocation.type === "MyNotebooks" && userContext.features.phoenix) { } else if (selectedLocation.type === "MyNotebooks") {
destination = useNotebook.getState().notebookFolderName; destination = useNotebook.getState().notebookFolderName;
} }

View File

@ -84,10 +84,7 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
const mainItems = this.createMainItems(); const mainItems = this.createMainItems();
const commonTaskItems = this.createCommonTaskItems(); const commonTaskItems = this.createCommonTaskItems();
let recentItems = this.createRecentItems(); let recentItems = this.createRecentItems();
if (userContext.features.notebooksTemporarilyDown) {
recentItems = recentItems.filter((item) => item.description !== "Notebook"); recentItems = recentItems.filter((item) => item.description !== "Notebook");
}
const tipsItems = this.createTipsItems(); const tipsItems = this.createTipsItems();
const onClearRecent = this.clearMostRecent; const onClearRecent = this.clearMostRecent;
@ -223,7 +220,7 @@ export class SplashScreen extends React.Component<SplashScreenProps> {
}); });
} }
if (useNotebook.getState().isNotebookEnabled && !userContext.features.notebooksTemporarilyDown) { if (useNotebook.getState().isPhoenix) {
heroes.push({ heroes.push({
iconSrc: NewNotebookIcon, iconSrc: NewNotebookIcon,
title: "New Notebook", title: "New Notebook",

View File

@ -1,5 +1,5 @@
import { Resource, StoredProcedureDefinition, TriggerDefinition, UserDefinedFunctionDefinition } from "@azure/cosmos"; import { Resource, StoredProcedureDefinition, TriggerDefinition, UserDefinedFunctionDefinition } from "@azure/cosmos";
import { NotebookUtil } from "Explorer/Notebook/NotebookUtil"; import { useNotebook } from "Explorer/Notebook/useNotebook";
import * as ko from "knockout"; import * as ko from "knockout";
import * as _ from "underscore"; import * as _ from "underscore";
import * as Constants from "../../Common/Constants"; import * as Constants from "../../Common/Constants";
@ -529,7 +529,7 @@ export default class Collection implements ViewModels.Collection {
}; };
public onSchemaAnalyzerClick = async () => { public onSchemaAnalyzerClick = async () => {
if (NotebookUtil.isPhoenixEnabled()) { if (useNotebook.getState().isPhoenix) {
await this.container.allocateContainer(); await this.container.allocateContainer();
} }
useSelectedNode.getState().setSelectedNode(this); useSelectedNode.getState().setSelectedNode(this);

View File

@ -121,18 +121,17 @@ export const ResourceTree: React.FC<ResourceTreeProps> = ({ container }: Resourc
children: [], children: [],
}; };
if (userContext.features.notebooksTemporarilyDown) { if (useNotebook.getState().isPhoenix === false && userContext.features.notebooksDownBanner) {
notebooksTree.children.push(buildNotebooksTemporarilyDownTree()); notebooksTree.children.push(buildNotebooksTemporarilyDownTree());
} else { } else if (useNotebook.getState().isPhoenix) {
if (galleryContentRoot) { if (galleryContentRoot) {
notebooksTree.children.push(buildGalleryNotebooksTree()); notebooksTree.children.push(buildGalleryNotebooksTree());
} }
if ( if (
myNotebooksContentRoot && myNotebooksContentRoot &&
((NotebookUtil.isPhoenixEnabled() && useNotebook.getState().isPhoenix &&
useNotebook.getState().connectionInfo.status === ConnectionStatusType.Connected) || useNotebook.getState().connectionInfo.status === ConnectionStatusType.Connected
userContext.features.phoenix === false)
) { ) {
notebooksTree.children.push(buildMyNotebooksTree()); notebooksTree.children.push(buildMyNotebooksTree());
} }
@ -166,15 +165,7 @@ export const ResourceTree: React.FC<ResourceTreeProps> = ({ container }: Resourc
const myNotebooksTree: TreeNode = buildNotebookDirectoryNode( const myNotebooksTree: TreeNode = buildNotebookDirectoryNode(
myNotebooksContentRoot, myNotebooksContentRoot,
(item: NotebookContentItem) => { (item: NotebookContentItem) => {
container.openNotebook(item).then((hasOpened) => { container.openNotebook(item);
if (
hasOpened &&
userContext.features.notebooksTemporarilyDown === false &&
userContext.features.phoenix === false
) {
mostRecentActivity.notebookWasItemOpened(userContext.databaseAccount?.id, item);
}
});
} }
); );
@ -189,15 +180,7 @@ export const ResourceTree: React.FC<ResourceTreeProps> = ({ container }: Resourc
const gitHubNotebooksTree: TreeNode = buildNotebookDirectoryNode( const gitHubNotebooksTree: TreeNode = buildNotebookDirectoryNode(
gitHubNotebooksContentRoot, gitHubNotebooksContentRoot,
(item: NotebookContentItem) => { (item: NotebookContentItem) => {
container.openNotebook(item).then((hasOpened) => { container.openNotebook(item);
if (
hasOpened &&
userContext.features.notebooksTemporarilyDown === false &&
userContext.features.phoenix === false
) {
mostRecentActivity.notebookWasItemOpened(userContext.databaseAccount?.id, item);
}
});
}, },
true true
); );
@ -528,7 +511,7 @@ export const ResourceTree: React.FC<ResourceTreeProps> = ({ container }: Resourc
isNotebookEnabled && isNotebookEnabled &&
userContext.apiType === "Mongo" && userContext.apiType === "Mongo" &&
isPublicInternetAccessAllowed() && isPublicInternetAccessAllowed() &&
!userContext.features.notebooksTemporarilyDown useNotebook.getState().isPhoenix
) { ) {
children.push({ children.push({
label: "Schema (Preview)", label: "Schema (Preview)",

View File

@ -5,6 +5,7 @@ import * as Logger from "../Common/Logger";
import { configContext } from "../ConfigContext"; import { configContext } from "../ConfigContext";
import { import {
ContainerInfo, ContainerInfo,
IAccountData,
IContainerData, IContainerData,
IPhoenixConnectionInfoResult, IPhoenixConnectionInfoResult,
IProvisionData, IProvisionData,
@ -22,24 +23,36 @@ export class PhoenixClient {
minTimeout: Notebook.retryAttemptDelayMs, minTimeout: Notebook.retryAttemptDelayMs,
}; };
public async allocateContainer(provisionData: IProvisionData): Promise<IResponse<IPhoenixConnectionInfoResult>> { public async allocateContainer(
return this.executeContainerAssignmentOperation(provisionData, "allocate"); provisionData: IProvisionData,
accountData: IAccountData
): Promise<IResponse<IPhoenixConnectionInfoResult>> {
return this.executeContainerAssignmentOperation(provisionData, accountData, "allocate");
} }
public async resetContainer(provisionData: IProvisionData): Promise<IResponse<IPhoenixConnectionInfoResult>> { public async resetContainer(
return this.executeContainerAssignmentOperation(provisionData, "reset"); provisionData: IProvisionData,
accountData: IAccountData
): Promise<IResponse<IPhoenixConnectionInfoResult>> {
return this.executeContainerAssignmentOperation(provisionData, accountData, "reset");
} }
private async executeContainerAssignmentOperation( private async executeContainerAssignmentOperation(
provisionData: IProvisionData, provisionData: IProvisionData,
accountData: IAccountData,
operation: string operation: string
): Promise<IResponse<IPhoenixConnectionInfoResult>> { ): Promise<IResponse<IPhoenixConnectionInfoResult>> {
try { try {
const response = await fetch(`${this.getPhoenixContainerPoolingEndPoint()}/${operation}`, { const response = await fetch(
method: "POST", `${this.getPhoenixContainerPoolingEndPoint()}/subscriptions/${accountData.subscriptionId}/resourceGroups/${
accountData.resourceGroup
}/providers/Microsoft.DocumentDB/databaseAccounts/${accountData.dbAccountName}/containerconnections`,
{
method: operation === "allocate" ? "POST" : "PATCH",
headers: PhoenixClient.getHeaders(), headers: PhoenixClient.getHeaders(),
body: JSON.stringify(provisionData), body: JSON.stringify(provisionData),
}); }
);
let data: IPhoenixConnectionInfoResult; let data: IPhoenixConnectionInfoResult;
if (response.status === HttpStatusCodes.OK) { if (response.status === HttpStatusCodes.OK) {
@ -55,7 +68,7 @@ export class PhoenixClient {
} }
} }
public async initiateContainerHeartBeat(containerData: { forwardingId: string; dbAccountName: string }) { public async initiateContainerHeartBeat(containerData: IContainerData) {
if (this.containerHealthHandler) { if (this.containerHealthHandler) {
clearTimeout(this.containerHealthHandler); clearTimeout(this.containerHealthHandler);
} }
@ -72,7 +85,11 @@ export class PhoenixClient {
try { try {
const runContainerStatusAsync = async () => { const runContainerStatusAsync = async () => {
const response = await window.fetch( const response = await window.fetch(
`${this.getPhoenixContainerPoolingEndPoint()}/${containerData.dbAccountName}/${containerData.forwardingId}`, `${this.getPhoenixContainerPoolingEndPoint()}/subscriptions/${containerData.subscriptionId}/resourceGroups/${
containerData.resourceGroup
}/providers/Microsoft.DocumentDB/databaseAccounts/${containerData.dbAccountName}/${
containerData.forwardingId
}`,
{ {
method: "GET", method: "GET",
headers: PhoenixClient.getHeaders(), headers: PhoenixClient.getHeaders(),
@ -101,7 +118,7 @@ export class PhoenixClient {
} }
} }
private async getContainerHealth(delayMs: number, containerData: { forwardingId: string; dbAccountName: string }) { private async getContainerHealth(delayMs: number, containerData: IContainerData) {
try { try {
const containerInfo = await this.getContainerStatusAsync(containerData); const containerInfo = await this.getContainerStatusAsync(containerData);
useNotebook.getState().setContainerStatus(containerInfo); useNotebook.getState().setContainerStatus(containerInfo);
@ -117,6 +134,24 @@ export class PhoenixClient {
} }
} }
public async IsDbAcountWhitelisted(accountData: IAccountData) {
try {
const response = await window.fetch(
`${this.getPhoenixContainerPoolingEndPoint()}/subscriptions/${accountData.subscriptionId}/resourceGroups/${
accountData.resourceGroup
}/providers/Microsoft.DocumentDB/databaseAccounts/${accountData.dbAccountName}`,
{
method: "GET",
headers: PhoenixClient.getHeaders(),
}
);
return response.status === HttpStatusCodes.OK;
} catch (error) {
Logger.logError(getErrorMessage(error), "PhoenixClient/IsDbAcountWhitelisted");
return false;
}
}
public static getPhoenixEndpoint(): string { public static getPhoenixEndpoint(): string {
const phoenixEndpoint = const phoenixEndpoint =
userContext.features.phoenixEndpoint ?? userContext.features.junoEndpoint ?? configContext.JUNO_ENDPOINT; userContext.features.phoenixEndpoint ?? userContext.features.junoEndpoint ?? configContext.JUNO_ENDPOINT;

View File

@ -11,7 +11,6 @@ export type Features = {
autoscaleDefault: boolean; autoscaleDefault: boolean;
partitionKeyDefault: boolean; partitionKeyDefault: boolean;
partitionKeyDefault2: boolean; partitionKeyDefault2: boolean;
phoenix: boolean;
notebooksDownBanner: boolean; notebooksDownBanner: boolean;
readonly enableSDKoperations: boolean; readonly enableSDKoperations: boolean;
readonly enableSpark: boolean; readonly enableSpark: boolean;
@ -33,7 +32,6 @@ export type Features = {
readonly ttl90Days: boolean; readonly ttl90Days: boolean;
readonly mongoProxyEndpoint?: string; readonly mongoProxyEndpoint?: string;
readonly mongoProxyAPIs?: string; readonly mongoProxyAPIs?: string;
readonly notebooksTemporarilyDown: boolean;
readonly enableThroughputCap: boolean; readonly enableThroughputCap: boolean;
}; };
@ -84,8 +82,6 @@ export function extractFeatures(given = new URLSearchParams(window.location.sear
autoscaleDefault: "true" === get("autoscaledefault"), autoscaleDefault: "true" === get("autoscaledefault"),
partitionKeyDefault: "true" === get("partitionkeytest"), partitionKeyDefault: "true" === get("partitionkeytest"),
partitionKeyDefault2: "true" === get("pkpartitionkeytest"), partitionKeyDefault2: "true" === get("pkpartitionkeytest"),
notebooksTemporarilyDown: "true" === get("notebookstemporarilydown", "true"),
phoenix: "true" === get("phoenix"),
notebooksDownBanner: "true" === get("notebooksDownBanner"), notebooksDownBanner: "true" === get("notebooksDownBanner"),
enableThroughputCap: "true" === get("enablethroughputcap"), enableThroughputCap: "true" === get("enablethroughputcap"),
}; };

View File

@ -10,7 +10,6 @@ import {
SortBy, SortBy,
} from "../Explorer/Controls/NotebookGallery/GalleryViewerComponent"; } from "../Explorer/Controls/NotebookGallery/GalleryViewerComponent";
import Explorer from "../Explorer/Explorer"; import Explorer from "../Explorer/Explorer";
import { NotebookUtil } from "../Explorer/Notebook/NotebookUtil";
import { useNotebook } from "../Explorer/Notebook/useNotebook"; import { useNotebook } from "../Explorer/Notebook/useNotebook";
import { IGalleryItem, JunoClient } from "../Juno/JunoClient"; import { IGalleryItem, JunoClient } from "../Juno/JunoClient";
import { Action, ActionModifiers } from "../Shared/Telemetry/TelemetryConstants"; import { Action, ActionModifiers } from "../Shared/Telemetry/TelemetryConstants";
@ -229,7 +228,7 @@ export function downloadItem(
undefined, undefined,
"Download", "Download",
async () => { async () => {
if (NotebookUtil.isPhoenixEnabled()) { if (useNotebook.getState().isPhoenix) {
await container.allocateContainer(); await container.allocateContainer();
} }
const notebookServerInfo = useNotebook.getState().notebookServerInfo; const notebookServerInfo = useNotebook.getState().notebookServerInfo;

View File

@ -339,9 +339,6 @@ function updateContextsFromPortalMessage(inputs: DataExplorerInputsFrame) {
if (inputs.flights.indexOf(Flights.PKPartitionKeyTest) !== -1) { if (inputs.flights.indexOf(Flights.PKPartitionKeyTest) !== -1) {
userContext.features.partitionKeyDefault2 = true; userContext.features.partitionKeyDefault2 = true;
} }
if (inputs.flights.indexOf(Flights.Phoenix) !== -1) {
userContext.features.phoenix = true;
}
if (inputs.flights.indexOf(Flights.NotebooksDownBanner) !== -1) { if (inputs.flights.indexOf(Flights.NotebooksDownBanner) !== -1) {
userContext.features.notebooksDownBanner = true; userContext.features.notebooksDownBanner = true;
} }