diff --git a/package-lock.json b/package-lock.json index fde3d86ad..710e6249f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23516,9 +23516,9 @@ } }, "react": { - "version": "16.9.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.9.0.tgz", - "integrity": "sha512-+7LQnFBwkiw+BobzOF6N//BdoNw0ouwmSJTEm9cglOOmsg/TMiFHZLe2sEoN5M7LgJTj9oHH0gxklfnQe66S1w==", + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react/-/react-16.13.1.tgz", + "integrity": "sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -25755,6 +25755,23 @@ "resolved": "https://registry.npmjs.org/svgpath/-/svgpath-2.2.3.tgz", "integrity": "sha512-xA0glXYpJ9SYT4JeMp3c0psbqdZsG1c0ywGvdJUPY2FKEgwJV7NgkeYuuQiOxMp+XsK9nCqjm3KDw0LkM1YLXw==" }, + "swr": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/swr/-/swr-0.3.2.tgz", + "integrity": "sha512-Bs5Bihq1hQ66O5bdKaL47iZ2nlAaBsd8tTLRLkw9stZeuBEfH7zSuQI95S2TpchL0ybsMq3isWwuso2uPvCfHA==", + "dev": true, + "requires": { + "fast-deep-equal": "2.0.1" + }, + "dependencies": { + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + } + } + }, "symbol-observable": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", diff --git a/package.json b/package.json index fcb7d1134..d4eaac2ce 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "promise-polyfill": "8.1.0", "promise.prototype.finally": "3.1.0", "q": "1.5.1", - "react": "16.9.0", + "react": "16.13.1", "react-animate-height": "2.0.8", "react-dnd": "9.4.0", "react-dnd-html5-backend": "9.4.0", @@ -160,6 +160,7 @@ "rimraf": "3.0.0", "sinon": "3.2.1", "style-loader": "0.23.0", + "swr": "0.3.2", "terser-webpack-plugin": "3.0.5", "ts-loader": "6.2.2", "tslint": "5.11.0", diff --git a/src/Common/dataAccess/createCollection.ts b/src/Common/dataAccess/createCollection.ts index 204caba25..4b5ae01ea 100644 --- a/src/Common/dataAccess/createCollection.ts +++ b/src/Common/dataAccess/createCollection.ts @@ -6,23 +6,26 @@ import { ContainerRequest } from "@azure/cosmos/dist-esm/client/Container/Contai import { DatabaseRequest } from "@azure/cosmos/dist-esm/client/Database/DatabaseRequest"; import { DefaultAccountExperienceType } from "../../DefaultAccountExperienceType"; import { RequestOptions } from "@azure/cosmos/dist-esm"; -import * as ARMTypes from "../../Utils/arm/generatedClients/2020-04-01/types"; +import * as ARMTypes from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/types"; import { client } from "../CosmosClient"; import { createMongoCollectionWithProxy } from "../MongoProxyClient"; -import { createUpdateSqlContainer, getSqlContainer } from "../../Utils/arm/generatedClients/2020-04-01/sqlResources"; +import { + createUpdateSqlContainer, + getSqlContainer +} from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/sqlResources"; import { createUpdateCassandraTable, getCassandraTable -} from "../../Utils/arm/generatedClients/2020-04-01/cassandraResources"; +} from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/cassandraResources"; import { createUpdateMongoDBCollection, getMongoDBCollection -} from "../../Utils/arm/generatedClients/2020-04-01/mongoDBResources"; +} from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/mongoDBResources"; import { createUpdateGremlinGraph, getGremlinGraph -} from "../../Utils/arm/generatedClients/2020-04-01/gremlinResources"; -import { createUpdateTable, getTable } from "../../Utils/arm/generatedClients/2020-04-01/tableResources"; +} from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/gremlinResources"; +import { createUpdateTable, getTable } from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/tableResources"; import { logConsoleProgress, logConsoleError, logConsoleInfo } from "../../Utils/NotificationConsoleUtils"; import { logError } from "../Logger"; import { refreshCachedResources } from "../DataAccessUtilityBase"; diff --git a/src/Common/dataAccess/createDatabase.ts b/src/Common/dataAccess/createDatabase.ts index 785e69681..b4b168611 100644 --- a/src/Common/dataAccess/createDatabase.ts +++ b/src/Common/dataAccess/createDatabase.ts @@ -9,21 +9,24 @@ import { MongoDBDatabaseCreateUpdateParameters, SqlDatabaseCreateUpdateParameters, CreateUpdateOptions -} from "../../Utils/arm/generatedClients/2020-04-01/types"; +} from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/types"; import { client } from "../CosmosClient"; -import { createUpdateSqlDatabase, getSqlDatabase } from "../../Utils/arm/generatedClients/2020-04-01/sqlResources"; +import { + createUpdateSqlDatabase, + getSqlDatabase +} from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/sqlResources"; import { createUpdateCassandraKeyspace, getCassandraKeyspace -} from "../../Utils/arm/generatedClients/2020-04-01/cassandraResources"; +} from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/cassandraResources"; import { createUpdateMongoDBDatabase, getMongoDBDatabase -} from "../../Utils/arm/generatedClients/2020-04-01/mongoDBResources"; +} from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/mongoDBResources"; import { createUpdateGremlinDatabase, getGremlinDatabase -} from "../../Utils/arm/generatedClients/2020-04-01/gremlinResources"; +} from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/gremlinResources"; import { logConsoleProgress, logConsoleError, logConsoleInfo } from "../../Utils/NotificationConsoleUtils"; import { logError } from "../Logger"; import { refreshCachedOffers, refreshCachedResources } from "../DataAccessUtilityBase"; diff --git a/src/Common/dataAccess/deleteCollection.ts b/src/Common/dataAccess/deleteCollection.ts index 75d282fce..2dd4a083c 100644 --- a/src/Common/dataAccess/deleteCollection.ts +++ b/src/Common/dataAccess/deleteCollection.ts @@ -1,10 +1,10 @@ import { AuthType } from "../../AuthType"; import { DefaultAccountExperienceType } from "../../DefaultAccountExperienceType"; -import { deleteSqlContainer } from "../../Utils/arm/generatedClients/2020-04-01/sqlResources"; -import { deleteCassandraTable } from "../../Utils/arm/generatedClients/2020-04-01/cassandraResources"; -import { deleteMongoDBCollection } from "../../Utils/arm/generatedClients/2020-04-01/mongoDBResources"; -import { deleteGremlinGraph } from "../../Utils/arm/generatedClients/2020-04-01/gremlinResources"; -import { deleteTable } from "../../Utils/arm/generatedClients/2020-04-01/tableResources"; +import { deleteSqlContainer } from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/sqlResources"; +import { deleteCassandraTable } from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/cassandraResources"; +import { deleteMongoDBCollection } from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/mongoDBResources"; +import { deleteGremlinGraph } from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/gremlinResources"; +import { deleteTable } from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/tableResources"; import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils"; import { logError } from "../Logger"; import { sendNotificationForError } from "./sendNotificationForError"; diff --git a/src/Common/dataAccess/deleteDatabase.ts b/src/Common/dataAccess/deleteDatabase.ts index 4a2767d0f..b89614ca9 100644 --- a/src/Common/dataAccess/deleteDatabase.ts +++ b/src/Common/dataAccess/deleteDatabase.ts @@ -1,9 +1,9 @@ import { AuthType } from "../../AuthType"; import { DefaultAccountExperienceType } from "../../DefaultAccountExperienceType"; -import { deleteSqlDatabase } from "../../Utils/arm/generatedClients/2020-04-01/sqlResources"; -import { deleteCassandraKeyspace } from "../../Utils/arm/generatedClients/2020-04-01/cassandraResources"; -import { deleteMongoDBDatabase } from "../../Utils/arm/generatedClients/2020-04-01/mongoDBResources"; -import { deleteGremlinDatabase } from "../../Utils/arm/generatedClients/2020-04-01/gremlinResources"; +import { deleteSqlDatabase } from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/sqlResources"; +import { deleteCassandraKeyspace } from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/cassandraResources"; +import { deleteMongoDBDatabase } from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/mongoDBResources"; +import { deleteGremlinDatabase } from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/gremlinResources"; import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils"; import { userContext } from "../../UserContext"; import { client } from "../CosmosClient"; diff --git a/src/Common/dataAccess/readCollections.ts b/src/Common/dataAccess/readCollections.ts index 6ebca7b13..17d51514e 100644 --- a/src/Common/dataAccess/readCollections.ts +++ b/src/Common/dataAccess/readCollections.ts @@ -2,11 +2,11 @@ import * as DataModels from "../../Contracts/DataModels"; import { AuthType } from "../../AuthType"; import { DefaultAccountExperienceType } from "../../DefaultAccountExperienceType"; import { client } from "../CosmosClient"; -import { listSqlContainers } from "../../Utils/arm/generatedClients/2020-04-01/sqlResources"; -import { listCassandraTables } from "../../Utils/arm/generatedClients/2020-04-01/cassandraResources"; -import { listMongoDBCollections } from "../../Utils/arm/generatedClients/2020-04-01/mongoDBResources"; -import { listGremlinGraphs } from "../../Utils/arm/generatedClients/2020-04-01/gremlinResources"; -import { listTables } from "../../Utils/arm/generatedClients/2020-04-01/tableResources"; +import { listSqlContainers } from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/sqlResources"; +import { listCassandraTables } from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/cassandraResources"; +import { listMongoDBCollections } from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/mongoDBResources"; +import { listGremlinGraphs } from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/gremlinResources"; +import { listTables } from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/tableResources"; import { logConsoleProgress, logConsoleError } from "../../Utils/NotificationConsoleUtils"; import { logError } from "../Logger"; import { sendNotificationForError } from "./sendNotificationForError"; diff --git a/src/Common/dataAccess/readDatabases.ts b/src/Common/dataAccess/readDatabases.ts index b106a4e06..9aa8a978b 100644 --- a/src/Common/dataAccess/readDatabases.ts +++ b/src/Common/dataAccess/readDatabases.ts @@ -2,10 +2,10 @@ import * as DataModels from "../../Contracts/DataModels"; import { AuthType } from "../../AuthType"; import { DefaultAccountExperienceType } from "../../DefaultAccountExperienceType"; import { client } from "../CosmosClient"; -import { listSqlDatabases } from "../../Utils/arm/generatedClients/2020-04-01/sqlResources"; -import { listCassandraKeyspaces } from "../../Utils/arm/generatedClients/2020-04-01/cassandraResources"; -import { listMongoDBDatabases } from "../../Utils/arm/generatedClients/2020-04-01/mongoDBResources"; -import { listGremlinDatabases } from "../../Utils/arm/generatedClients/2020-04-01/gremlinResources"; +import { listSqlDatabases } from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/sqlResources"; +import { listCassandraKeyspaces } from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/cassandraResources"; +import { listMongoDBDatabases } from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/mongoDBResources"; +import { listGremlinDatabases } from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/gremlinResources"; import { logConsoleProgress, logConsoleError } from "../../Utils/NotificationConsoleUtils"; import { logError } from "../Logger"; import { sendNotificationForError } from "./sendNotificationForError"; diff --git a/src/Common/dataAccess/updateCollection.ts b/src/Common/dataAccess/updateCollection.ts index 794c10003..1d2715e94 100644 --- a/src/Common/dataAccess/updateCollection.ts +++ b/src/Common/dataAccess/updateCollection.ts @@ -6,23 +6,26 @@ import { ExtendedResourceProperties, SqlContainerCreateUpdateParameters, SqlContainerResource -} from "../../Utils/arm/generatedClients/2020-04-01/types"; +} from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/types"; import { RequestOptions } from "@azure/cosmos/dist-esm"; import { client } from "../CosmosClient"; -import { createUpdateSqlContainer, getSqlContainer } from "../../Utils/arm/generatedClients/2020-04-01/sqlResources"; +import { + createUpdateSqlContainer, + getSqlContainer +} from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/sqlResources"; import { createUpdateCassandraTable, getCassandraTable -} from "../../Utils/arm/generatedClients/2020-04-01/cassandraResources"; +} from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/cassandraResources"; import { createUpdateMongoDBCollection, getMongoDBCollection -} from "../../Utils/arm/generatedClients/2020-04-01/mongoDBResources"; +} from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/mongoDBResources"; import { createUpdateGremlinGraph, getGremlinGraph -} from "../../Utils/arm/generatedClients/2020-04-01/gremlinResources"; -import { createUpdateTable, getTable } from "../../Utils/arm/generatedClients/2020-04-01/tableResources"; +} from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/gremlinResources"; +import { createUpdateTable, getTable } from "../../Utils/arm/generatedClients/2020-04-01-cosmos-db/tableResources"; import { logConsoleError, logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils"; import { logError } from "../Logger"; import { refreshCachedResources } from "../DataAccessUtilityBase"; diff --git a/src/Contracts/DataModels.ts b/src/Contracts/DataModels.ts index 0a6d13970..f5d08e39f 100644 --- a/src/Contracts/DataModels.ts +++ b/src/Contracts/DataModels.ts @@ -709,11 +709,6 @@ export interface SparkPool extends ArmResource { properties: SparkPoolProperties; } -export interface MemoryUsageInfo { - freeKB: number; - totalKB: number; -} - export interface resourceTokenConnectionStringProperties { accountEndpoint: string; collectionId: string; diff --git a/src/Explorer/Explorer.ts b/src/Explorer/Explorer.ts index b1fe2b451..47a791b6b 100644 --- a/src/Explorer/Explorer.ts +++ b/src/Explorer/Explorer.ts @@ -243,7 +243,6 @@ export default class Explorer { public arcadiaWorkspaces: ko.ObservableArray; public hasStorageAnalyticsAfecFeature: ko.Observable; public isSynapseLinkUpdating: ko.Observable; - public memoryUsageInfo: ko.Observable; public notebookManager?: any; // This is dynamically loaded private _panes: ContextualPaneBase[] = []; @@ -374,7 +373,6 @@ export default class Explorer { ); } }); - this.memoryUsageInfo = ko.observable(); this.notificationsClient = options.notificationsClient; this.isEmulator = options.isEmulator; diff --git a/src/Explorer/Menus/CommandBar/CommandBarComponentAdapter.tsx b/src/Explorer/Menus/CommandBar/CommandBarComponentAdapter.tsx index 9ad9b482b..99de70ae4 100644 --- a/src/Explorer/Menus/CommandBar/CommandBarComponentAdapter.tsx +++ b/src/Explorer/Menus/CommandBar/CommandBarComponentAdapter.tsx @@ -82,9 +82,7 @@ export class CommandBarComponentAdapter implements ReactAdapter { uiFabricControlButtons.forEach((btn: ICommandBarItemProps) => (btn.iconOnly = true)); if (this.isNotebookTabActive()) { - uiFabricControlButtons.unshift( - CommandBarUtil.createMemoryTracker("memoryTracker", this.container.memoryUsageInfo) - ); + uiFabricControlButtons.unshift(CommandBarUtil.createMemoryTracker("memoryTracker")); } return ( diff --git a/src/Explorer/Menus/CommandBar/CommandBarUtil.tsx b/src/Explorer/Menus/CommandBar/CommandBarUtil.tsx index ca9ac1723..3d3d65f4f 100644 --- a/src/Explorer/Menus/CommandBar/CommandBarUtil.tsx +++ b/src/Explorer/Menus/CommandBar/CommandBarUtil.tsx @@ -1,16 +1,14 @@ -import _ from "underscore"; -import * as React from "react"; -import { Observable } from "knockout"; +import { ICommandBarItemProps } from "office-ui-fabric-react/lib/CommandBar"; +import { Dropdown, IDropdownOption, IDropdownStyles } from "office-ui-fabric-react/lib/Dropdown"; import { IconType } from "office-ui-fabric-react/lib/Icon"; import { IComponentAsProps } from "office-ui-fabric-react/lib/Utilities"; -import { StyleConstants } from "../../../Common/Constants"; -import { ICommandBarItemProps } from "office-ui-fabric-react/lib/CommandBar"; -import { Dropdown, IDropdownStyles, IDropdownOption } from "office-ui-fabric-react/lib/Dropdown"; -import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent"; +import * as React from "react"; +import _ from "underscore"; import ChevronDownIcon from "../../../../images/Chevron_down.svg"; +import { StyleConstants } from "../../../Common/Constants"; import { ArcadiaMenuPicker } from "../../Controls/Arcadia/ArcadiaMenuPicker"; +import { CommandButtonComponentProps } from "../../Controls/CommandButton/CommandButtonComponent"; import { MemoryTrackerComponent } from "./MemoryTrackerComponent"; -import { MemoryUsageInfo } from "../../../Contracts/DataModels"; /** * Utilities for CommandBar @@ -178,10 +176,10 @@ export class CommandBarUtil { }; } - public static createMemoryTracker(key: string, memoryUsageInfo: Observable): ICommandBarItemProps { + public static createMemoryTracker(key: string): ICommandBarItemProps { return { key, - onRender: () => + onRender: () => }; } } diff --git a/src/Explorer/Menus/CommandBar/MemoryTrackerComponent.tsx b/src/Explorer/Menus/CommandBar/MemoryTrackerComponent.tsx index 420b481ea..29687e5c7 100644 --- a/src/Explorer/Menus/CommandBar/MemoryTrackerComponent.tsx +++ b/src/Explorer/Menus/CommandBar/MemoryTrackerComponent.tsx @@ -1,50 +1,71 @@ -import * as React from "react"; -import { Observable, Subscription } from "knockout"; -import { MemoryUsageInfo } from "../../../Contracts/DataModels"; +import React, { FunctionComponent } from "react"; +import useSWR from "swr"; import { ProgressIndicator } from "office-ui-fabric-react/lib/ProgressIndicator"; import { Spinner, SpinnerSize } from "office-ui-fabric-react/lib/Spinner"; import { Stack } from "office-ui-fabric-react/lib/Stack"; +import { listConnectionInfo } from "../../../Utils/arm/generatedClients/2020-04-01-notebooks/notebookWorkspaces"; +import { NotebookWorkspaceConnectionInfoResult } from "../../../Utils/arm/generatedClients/2020-04-01-notebooks/types"; +import { userContext } from "../../../UserContext"; -interface MemoryTrackerProps { - memoryUsageInfo: Observable; +export interface MemoryUsageInfo { + total: number; + free: number; } -export class MemoryTrackerComponent extends React.Component { - private memoryUsageInfoSubscription: Subscription; +const kbInGB = 1048576; - public componentDidMount(): void { - this.memoryUsageInfoSubscription = this.props.memoryUsageInfo.subscribe(() => { - this.forceUpdate(); - }); - } - - public componentWillUnmount(): void { - this.memoryUsageInfoSubscription && this.memoryUsageInfoSubscription.dispose(); - } - - public render(): JSX.Element { - const memoryUsageInfo: MemoryUsageInfo = this.props.memoryUsageInfo(); - if (!memoryUsageInfo) { - return ( - - Memory - - - ); +const fetchMemoryInfo = async (_key: unknown, connectionInfo: NotebookWorkspaceConnectionInfoResult) => { + const response = await fetch(`${connectionInfo.notebookServerEndpoint}/api/metrics/memory`, { + method: "GET", + headers: { + Authorization: `Token ${connectionInfo.authToken}`, + "content-type": "application/json" } + }); + if (!response.ok) { + throw new Error(await response.text()); + } + const memoryUsageInfo = (await response.json()) as MemoryUsageInfo; + return { + totalKB: memoryUsageInfo.total, + freeKB: memoryUsageInfo.free + }; +}; - const totalGB = memoryUsageInfo.totalKB / 1048576; - const usedGB = totalGB - memoryUsageInfo.freeKB / 1048576; +export const MemoryTrackerComponent: FunctionComponent = () => { + const { data: connectionInfo } = useSWR( + [ + "notebooksConnectionInfo", + userContext.subscriptionId, + userContext.resourceGroup, + userContext.databaseAccount.name, + "default" + ], + (_key, subscriptionId, resourceGroup, accountName, workspace) => + listConnectionInfo(subscriptionId, resourceGroup, accountName, workspace) + ); + const { data } = useSWR(connectionInfo ? ["memoryUsage", connectionInfo] : null, fetchMemoryInfo, { + refreshInterval: 2000 + }); + if (!data) { return ( Memory - 0.8 ? "lowMemory" : ""} - description={usedGB.toFixed(1) + " of " + totalGB.toFixed(1) + " GB"} - percentComplete={usedGB / totalGB} - /> + ); } -} + const totalGB = data.totalKB / kbInGB; + const usedGB = totalGB - data.freeKB / kbInGB; + return ( + + Memory + 0.8 ? "lowMemory" : ""} + description={usedGB.toFixed(1) + " of " + totalGB.toFixed(1) + " GB"} + percentComplete={usedGB / totalGB} + /> + + ); +}; diff --git a/src/Explorer/Notebook/NotebookContainerClient.ts b/src/Explorer/Notebook/NotebookContainerClient.ts index 78cfa0fa3..9ba1dc158 100644 --- a/src/Explorer/Notebook/NotebookContainerClient.ts +++ b/src/Explorer/Notebook/NotebookContainerClient.ts @@ -2,89 +2,13 @@ * Notebook container related stuff */ import * as DataModels from "../../Contracts/DataModels"; -import * as Constants from "../../Common/Constants"; -import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent"; -import * as NotificationConsoleUtils from "../../Utils/NotificationConsoleUtils"; import * as Logger from "../../Common/Logger"; export class NotebookContainerClient { private reconnectingNotificationId: string; private isResettingWorkspace: boolean; - constructor( - private notebookServerInfo: ko.Observable, - private onConnectionLost: () => void, - private onMemoryUsageInfoUpdate: (update: DataModels.MemoryUsageInfo) => void - ) { - if (notebookServerInfo() && notebookServerInfo().notebookServerEndpoint) { - this.scheduleHeartbeat(Constants.Notebook.heartbeatDelayMs); - } else { - const subscription = notebookServerInfo.subscribe((newServerInfo: DataModels.NotebookWorkspaceConnectionInfo) => { - if (newServerInfo && newServerInfo.notebookServerEndpoint) { - this.scheduleHeartbeat(Constants.Notebook.heartbeatDelayMs); - } - subscription.dispose(); - }); - } - } - - /** - * Heartbeat: each ping schedules another ping - */ - private scheduleHeartbeat(delayMs: number): void { - setTimeout(() => { - this.getMemoryUsage() - .then(memoryUsageInfo => this.onMemoryUsageInfoUpdate(memoryUsageInfo)) - .finally(() => this.scheduleHeartbeat(Constants.Notebook.heartbeatDelayMs)); - }, delayMs); - } - - private async getMemoryUsage(): Promise { - if (!this.notebookServerInfo() || !this.notebookServerInfo().notebookServerEndpoint) { - const error = "No server endpoint detected"; - Logger.logError(error, "NotebookContainerClient/getMemoryUsage"); - return Promise.reject(error); - } - - if (this.isResettingWorkspace) { - return undefined; - } - - const { notebookServerEndpoint, authToken } = this.getNotebookServerConfig(); - try { - const response = await fetch(`${notebookServerEndpoint}/api/metrics/memory`, { - method: "GET", - headers: { - Authorization: authToken, - "content-type": "application/json" - } - }); - if (response.ok) { - if (this.reconnectingNotificationId) { - NotificationConsoleUtils.clearInProgressMessageWithId(this.reconnectingNotificationId); - this.reconnectingNotificationId = ""; - } - const memoryUsageInfo = await response.json(); - if (memoryUsageInfo) { - return { - totalKB: memoryUsageInfo.total, - freeKB: memoryUsageInfo.free - }; - } - } - return undefined; - } catch (error) { - Logger.logError(error, "NotebookContainerClient/getMemoryUsage"); - if (!this.reconnectingNotificationId) { - this.reconnectingNotificationId = NotificationConsoleUtils.logConsoleMessage( - ConsoleDataType.InProgress, - "Connection lost with Notebook server. Attempting to reconnect..." - ); - } - this.onConnectionLost(); - return undefined; - } - } + constructor(private notebookServerInfo: ko.Observable) {} public async resetWorkspace(): Promise { this.isResettingWorkspace = true; diff --git a/src/Explorer/Notebook/NotebookManager.ts b/src/Explorer/Notebook/NotebookManager.ts index 85b888d5a..f0db5b5eb 100644 --- a/src/Explorer/Notebook/NotebookManager.ts +++ b/src/Explorer/Notebook/NotebookManager.ts @@ -16,7 +16,6 @@ import { NotebookContentProvider } from "./NotebookComponent/NotebookContentProv import { GitHubContentProvider } from "../../GitHub/GitHubContentProvider"; import { contents } from "rx-jupyter"; import { NotebookContainerClient } from "./NotebookContainerClient"; -import { MemoryUsageInfo } from "../../Contracts/DataModels"; import { NotebookContentClient } from "./NotebookContentClient"; import { DialogProps } from "../Controls/DialogReactComponent/DialogComponent"; import { ResourceTreeAdapter } from "../Tree/ResourceTreeAdapter"; @@ -76,11 +75,7 @@ export default class NotebookManager { contents.JupyterContentProvider ); - this.notebookClient = new NotebookContainerClient( - this.params.container.notebookServerInfo, - () => this.params.container.initNotebooks(this.params.container.databaseAccount()), - (update: MemoryUsageInfo) => this.params.container.memoryUsageInfo(update) - ); + this.notebookClient = new NotebookContainerClient(this.params.container.notebookServerInfo); this.notebookContentClient = new NotebookContentClient( this.params.container.notebookServerInfo, diff --git a/src/Utils/arm/generatedClients/2020-04-01/cassandraResources.ts b/src/Utils/arm/generatedClients/2020-04-01-cosmos-db/cassandraResources.ts similarity index 100% rename from src/Utils/arm/generatedClients/2020-04-01/cassandraResources.ts rename to src/Utils/arm/generatedClients/2020-04-01-cosmos-db/cassandraResources.ts diff --git a/src/Utils/arm/generatedClients/2020-04-01/collection.ts b/src/Utils/arm/generatedClients/2020-04-01-cosmos-db/collection.ts similarity index 100% rename from src/Utils/arm/generatedClients/2020-04-01/collection.ts rename to src/Utils/arm/generatedClients/2020-04-01-cosmos-db/collection.ts diff --git a/src/Utils/arm/generatedClients/2020-04-01/collectionPartition.ts b/src/Utils/arm/generatedClients/2020-04-01-cosmos-db/collectionPartition.ts similarity index 100% rename from src/Utils/arm/generatedClients/2020-04-01/collectionPartition.ts rename to src/Utils/arm/generatedClients/2020-04-01-cosmos-db/collectionPartition.ts diff --git a/src/Utils/arm/generatedClients/2020-04-01/collectionPartitionRegion.ts b/src/Utils/arm/generatedClients/2020-04-01-cosmos-db/collectionPartitionRegion.ts similarity index 100% rename from src/Utils/arm/generatedClients/2020-04-01/collectionPartitionRegion.ts rename to src/Utils/arm/generatedClients/2020-04-01-cosmos-db/collectionPartitionRegion.ts diff --git a/src/Utils/arm/generatedClients/2020-04-01/collectionRegion.ts b/src/Utils/arm/generatedClients/2020-04-01-cosmos-db/collectionRegion.ts similarity index 100% rename from src/Utils/arm/generatedClients/2020-04-01/collectionRegion.ts rename to src/Utils/arm/generatedClients/2020-04-01-cosmos-db/collectionRegion.ts diff --git a/src/Utils/arm/generatedClients/2020-04-01/database.ts b/src/Utils/arm/generatedClients/2020-04-01-cosmos-db/database.ts similarity index 100% rename from src/Utils/arm/generatedClients/2020-04-01/database.ts rename to src/Utils/arm/generatedClients/2020-04-01-cosmos-db/database.ts diff --git a/src/Utils/arm/generatedClients/2020-04-01/databaseAccountRegion.ts b/src/Utils/arm/generatedClients/2020-04-01-cosmos-db/databaseAccountRegion.ts similarity index 100% rename from src/Utils/arm/generatedClients/2020-04-01/databaseAccountRegion.ts rename to src/Utils/arm/generatedClients/2020-04-01-cosmos-db/databaseAccountRegion.ts diff --git a/src/Utils/arm/generatedClients/2020-04-01/databaseAccounts.ts b/src/Utils/arm/generatedClients/2020-04-01-cosmos-db/databaseAccounts.ts similarity index 100% rename from src/Utils/arm/generatedClients/2020-04-01/databaseAccounts.ts rename to src/Utils/arm/generatedClients/2020-04-01-cosmos-db/databaseAccounts.ts diff --git a/src/Utils/arm/generatedClients/2020-04-01/gremlinResources.ts b/src/Utils/arm/generatedClients/2020-04-01-cosmos-db/gremlinResources.ts similarity index 100% rename from src/Utils/arm/generatedClients/2020-04-01/gremlinResources.ts rename to src/Utils/arm/generatedClients/2020-04-01-cosmos-db/gremlinResources.ts diff --git a/src/Utils/arm/generatedClients/2020-04-01/mongoDBResources.ts b/src/Utils/arm/generatedClients/2020-04-01-cosmos-db/mongoDBResources.ts similarity index 100% rename from src/Utils/arm/generatedClients/2020-04-01/mongoDBResources.ts rename to src/Utils/arm/generatedClients/2020-04-01-cosmos-db/mongoDBResources.ts diff --git a/src/Utils/arm/generatedClients/2020-04-01/operations.ts b/src/Utils/arm/generatedClients/2020-04-01-cosmos-db/operations.ts similarity index 100% rename from src/Utils/arm/generatedClients/2020-04-01/operations.ts rename to src/Utils/arm/generatedClients/2020-04-01-cosmos-db/operations.ts diff --git a/src/Utils/arm/generatedClients/2020-04-01/partitionKeyRangeId.ts b/src/Utils/arm/generatedClients/2020-04-01-cosmos-db/partitionKeyRangeId.ts similarity index 100% rename from src/Utils/arm/generatedClients/2020-04-01/partitionKeyRangeId.ts rename to src/Utils/arm/generatedClients/2020-04-01-cosmos-db/partitionKeyRangeId.ts diff --git a/src/Utils/arm/generatedClients/2020-04-01/partitionKeyRangeIdRegion.ts b/src/Utils/arm/generatedClients/2020-04-01-cosmos-db/partitionKeyRangeIdRegion.ts similarity index 100% rename from src/Utils/arm/generatedClients/2020-04-01/partitionKeyRangeIdRegion.ts rename to src/Utils/arm/generatedClients/2020-04-01-cosmos-db/partitionKeyRangeIdRegion.ts diff --git a/src/Utils/arm/generatedClients/2020-04-01/percentile.ts b/src/Utils/arm/generatedClients/2020-04-01-cosmos-db/percentile.ts similarity index 100% rename from src/Utils/arm/generatedClients/2020-04-01/percentile.ts rename to src/Utils/arm/generatedClients/2020-04-01-cosmos-db/percentile.ts diff --git a/src/Utils/arm/generatedClients/2020-04-01/percentileSourceTarget.ts b/src/Utils/arm/generatedClients/2020-04-01-cosmos-db/percentileSourceTarget.ts similarity index 100% rename from src/Utils/arm/generatedClients/2020-04-01/percentileSourceTarget.ts rename to src/Utils/arm/generatedClients/2020-04-01-cosmos-db/percentileSourceTarget.ts diff --git a/src/Utils/arm/generatedClients/2020-04-01/percentileTarget.ts b/src/Utils/arm/generatedClients/2020-04-01-cosmos-db/percentileTarget.ts similarity index 100% rename from src/Utils/arm/generatedClients/2020-04-01/percentileTarget.ts rename to src/Utils/arm/generatedClients/2020-04-01-cosmos-db/percentileTarget.ts diff --git a/src/Utils/arm/generatedClients/2020-04-01/sqlResources.ts b/src/Utils/arm/generatedClients/2020-04-01-cosmos-db/sqlResources.ts similarity index 100% rename from src/Utils/arm/generatedClients/2020-04-01/sqlResources.ts rename to src/Utils/arm/generatedClients/2020-04-01-cosmos-db/sqlResources.ts diff --git a/src/Utils/arm/generatedClients/2020-04-01/tableResources.ts b/src/Utils/arm/generatedClients/2020-04-01-cosmos-db/tableResources.ts similarity index 100% rename from src/Utils/arm/generatedClients/2020-04-01/tableResources.ts rename to src/Utils/arm/generatedClients/2020-04-01-cosmos-db/tableResources.ts diff --git a/src/Utils/arm/generatedClients/2020-04-01/types.ts b/src/Utils/arm/generatedClients/2020-04-01-cosmos-db/types.ts similarity index 100% rename from src/Utils/arm/generatedClients/2020-04-01/types.ts rename to src/Utils/arm/generatedClients/2020-04-01-cosmos-db/types.ts diff --git a/src/Utils/arm/generatedClients/2020-04-01-notebooks/notebookWorkspaces.ts b/src/Utils/arm/generatedClients/2020-04-01-notebooks/notebookWorkspaces.ts new file mode 100644 index 000000000..1ebf617e4 --- /dev/null +++ b/src/Utils/arm/generatedClients/2020-04-01-notebooks/notebookWorkspaces.ts @@ -0,0 +1,87 @@ +/* + AUTOGENERATED FILE + Do not manually edit + Run "npm run generateARMClients" to regenerate +*/ + +import { armRequest } from "../../request"; +import * as Types from "./types"; +import { configContext } from "../../../../ConfigContext"; +const apiVersion = "2020-04-01"; + +/* Gets the notebook workspace resources of an existing Cosmos DB account. */ +export async function listByDatabaseAccount( + subscriptionId: string, + resourceGroupName: string, + accountName: string +): Promise { + const path = `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}/providers/Microsoft.DocumentDB/databaseAccounts/${accountName}/notebookWorkspaces`; + return armRequest({ host: configContext.ARM_ENDPOINT, path, method: "GET", apiVersion }); +} + +/* Gets the notebook workspace for a Cosmos DB account. */ +export async function get( + subscriptionId: string, + resourceGroupName: string, + accountName: string, + notebookWorkspaceName: string +): Promise { + const path = `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}/providers/Microsoft.DocumentDB/databaseAccounts/${accountName}/notebookWorkspaces/${notebookWorkspaceName}`; + return armRequest({ host: configContext.ARM_ENDPOINT, path, method: "GET", apiVersion }); +} + +/* Creates the notebook workspace for a Cosmos DB account. */ +export async function createOrUpdate( + subscriptionId: string, + resourceGroupName: string, + accountName: string, + notebookWorkspaceName: string, + body: Types.NotebookWorkspaceCreateUpdateParameters +): Promise { + const path = `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}/providers/Microsoft.DocumentDB/databaseAccounts/${accountName}/notebookWorkspaces/${notebookWorkspaceName}`; + return armRequest({ host: configContext.ARM_ENDPOINT, path, method: "PUT", apiVersion, body }); +} + +/* Deletes the notebook workspace for a Cosmos DB account. */ +export async function destroy( + subscriptionId: string, + resourceGroupName: string, + accountName: string, + notebookWorkspaceName: string +): Promise { + const path = `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}/providers/Microsoft.DocumentDB/databaseAccounts/${accountName}/notebookWorkspaces/${notebookWorkspaceName}`; + return armRequest({ host: configContext.ARM_ENDPOINT, path, method: "DELETE", apiVersion }); +} + +/* Retrieves the connection info for the notebook workspace */ +export async function listConnectionInfo( + subscriptionId: string, + resourceGroupName: string, + accountName: string, + notebookWorkspaceName: string +): Promise { + const path = `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}/providers/Microsoft.DocumentDB/databaseAccounts/${accountName}/notebookWorkspaces/${notebookWorkspaceName}/listConnectionInfo`; + return armRequest({ host: configContext.ARM_ENDPOINT, path, method: "POST", apiVersion }); +} + +/* Regenerates the auth token for the notebook workspace */ +export async function regenerateAuthToken( + subscriptionId: string, + resourceGroupName: string, + accountName: string, + notebookWorkspaceName: string +): Promise { + const path = `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}/providers/Microsoft.DocumentDB/databaseAccounts/${accountName}/notebookWorkspaces/${notebookWorkspaceName}/regenerateAuthToken`; + return armRequest({ host: configContext.ARM_ENDPOINT, path, method: "POST", apiVersion }); +} + +/* Starts the notebook workspace */ +export async function start( + subscriptionId: string, + resourceGroupName: string, + accountName: string, + notebookWorkspaceName: string +): Promise { + const path = `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}/providers/Microsoft.DocumentDB/databaseAccounts/${accountName}/notebookWorkspaces/${notebookWorkspaceName}/start`; + return armRequest({ host: configContext.ARM_ENDPOINT, path, method: "POST", apiVersion }); +} diff --git a/src/Utils/arm/generatedClients/2020-04-01-notebooks/types.ts b/src/Utils/arm/generatedClients/2020-04-01-notebooks/types.ts new file mode 100644 index 000000000..3e4707bba --- /dev/null +++ b/src/Utils/arm/generatedClients/2020-04-01-notebooks/types.ts @@ -0,0 +1,36 @@ +/* + AUTOGENERATED FILE + Do not manually edit + Run "npm run generateARMClients" to regenerate +*/ + +/* Parameters to create a notebook workspace resource */ +export type NotebookWorkspaceCreateUpdateParameters = unknown; + +/* A list of notebook workspace resources */ +export interface NotebookWorkspaceListResult { + /* Array of notebook workspace resources */ + value?: NotebookWorkspace[]; +} + +/* A notebook workspace resource */ +export type NotebookWorkspace = unknown & { + /* Resource properties. */ + properties?: NotebookWorkspaceProperties; +}; + +/* Properties of a notebook workspace resource. */ +export interface NotebookWorkspaceProperties { + /* Specifies the endpoint of Notebook server. */ + readonly notebookServerEndpoint?: string; + /* Status of the notebook workspace. Possible values are: Creating, Online, Deleting, Failed, Updating. */ + readonly status?: string; +} + +/* The connection info for the given notebook workspace */ +export interface NotebookWorkspaceConnectionInfoResult { + /* Specifies auth token used for connecting to Notebook server (uses token-based auth). */ + readonly authToken?: string; + /* Specifies the endpoint of Notebook server. */ + readonly notebookServerEndpoint?: string; +} diff --git a/src/Utils/arm/request.ts b/src/Utils/arm/request.ts index 857841463..61601760d 100644 --- a/src/Utils/arm/request.ts +++ b/src/Utils/arm/request.ts @@ -6,7 +6,7 @@ Instead, generate ARM clients that consume this function with stricter typing. */ import promiseRetry, { AbortError } from "p-retry"; -import { ErrorResponse } from "./generatedClients/2020-04-01/types"; +import { ErrorResponse } from "./generatedClients/2020-04-01-cosmos-db/types"; import { userContext } from "../../UserContext"; interface ARMError extends Error { diff --git a/utils/armClientGenerator/generator.ts b/utils/armClientGenerator/generator.ts index b4bd7023f..fdbc46005 100644 --- a/utils/armClientGenerator/generator.ts +++ b/utils/armClientGenerator/generator.ts @@ -14,12 +14,14 @@ But it does work well enough to generate a fully typed tree-shakeable client for Results of this file should be checked into the repo. */ +const rpname = "cosmos-db"; // Can also use "notebooks" + // Array of strings to use for eventual output const outputTypes: string[] = [""]; const version = "2020-04-01"; -const schemaURL = `https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/stable/${version}/cosmos-db.json`; +const schemaURL = `https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification/cosmos-db/resource-manager/Microsoft.DocumentDB/stable/${version}/${rpname}.json`; -const outputDir = path.join(__dirname, `../../src/Utils/arm/generatedClients/${version}`); +const outputDir = path.join(__dirname, `../../src/Utils/arm/generatedClients/${version}-${rpname}`); mkdirp.sync(outputDir); // Buckets for grouping operations based on their name