Mount HDFS Dialog: basic support (#7580)

Implemented in this PR

- New base dialog for anything needing to work with the controller. This is important since going from SQL -> Controller we "should" have the right permissions but aren't guaranteed
- Support for Mount HDFS via a dialog. Includes basic polling for success/failure, but have to give up after 2.5min as mounting could take hours. By then it's assumed to be successful since server-side has 2min timeout built in.


Not implemented in this PR

- Script as Notebook button. This should convert the inputs to a set of cells in a notebook so users can run things themselves
- Updates based on PM / UX reviews. I think we'll need a round of feedback before completing this work.
This commit is contained in:
Kevin Cunnane
2019-10-11 11:06:40 -07:00
committed by GitHub
parent 9a3f72591e
commit 92e1f83046
9 changed files with 588 additions and 6 deletions

View File

@@ -6,6 +6,7 @@
'use strict';
import * as vscode from 'vscode';
import * as azdata from 'azdata';
import * as nls from 'vscode-nls';
import { ControllerTreeDataProvider } from './bigDataCluster/tree/controllerTreeDataProvider';
import { IconPathHelper } from './bigDataCluster/constants';
@@ -14,6 +15,8 @@ import { AddControllerDialogModel, AddControllerDialog } from './bigDataCluster/
import { ControllerNode } from './bigDataCluster/tree/controllerTreeNode';
import { BdcDashboard } from './bigDataCluster/dialog/bdcDashboard';
import { BdcDashboardModel } from './bigDataCluster/dialog/bdcDashboardModel';
import { MountHdfsDialogModel, MountHdfsProperties, MountHdfsDialog } from './bigDataCluster/dialog/mountHdfsDialog';
import { getControllerEndpoint } from './bigDataCluster/utils';
const localize = nls.loadMessageBundle();
@@ -21,6 +24,9 @@ const AddControllerCommand = 'bigDataClusters.command.addController';
const DeleteControllerCommand = 'bigDataClusters.command.deleteController';
const RefreshControllerCommand = 'bigDataClusters.command.refreshController';
const ManageControllerCommand = 'bigDataClusters.command.manageController';
const MountHdfsCommand = 'bigDataClusters.command.mount';
const endpointNotFoundError = localize('mount.error.endpointNotFound', "Controller endpoint information was not found");
let throttleTimers: { [key: string]: any } = {};
@@ -59,6 +65,52 @@ function registerCommands(context: vscode.ExtensionContext, treeDataProvider: Co
const dashboard: BdcDashboard = new BdcDashboard(title, new BdcDashboardModel(node.url, node.auth, node.username, node.password));
dashboard.showDashboard();
});
vscode.commands.registerCommand(MountHdfsCommand, e => mountHdfs(e).catch(error => {
vscode.window.showErrorMessage(error instanceof Error ? error.message : error);
}));
}
async function mountHdfs(explorerContext?: azdata.ObjectExplorerContext): Promise<void> {
let endpoint = await lookupController(explorerContext);
if (!endpoint) {
vscode.window.showErrorMessage(endpointNotFoundError);
return;
}
let profile = explorerContext.connectionProfile;
let mountProps: MountHdfsProperties = {
url: endpoint,
auth: profile.authenticationType === 'SqlLogin' ? 'basic' : 'integrated',
username: profile.userName,
password: profile.password,
hdfsPath: getHdsfPath(explorerContext.nodeInfo.nodePath)
};
let dialog = new MountHdfsDialog(new MountHdfsDialogModel(mountProps));
dialog.showDialog();
}
function getHdsfPath(nodePath: string): string {
const hdfsNodeLabel = '/HDFS';
let index = nodePath.indexOf(hdfsNodeLabel);
if (index >= 0) {
let subPath = nodePath.substring(index + hdfsNodeLabel.length);
return subPath.length > 0 ? subPath : '/';
}
// Use the root
return '/';
}
async function lookupController(explorerContext?: azdata.ObjectExplorerContext): Promise<string | undefined> {
if (!explorerContext) {
return undefined;
}
let serverInfo = await azdata.connection.getServerInfo(explorerContext.connectionProfile.id);
if (!serverInfo || !serverInfo.options) {
vscode.window.showErrorMessage(endpointNotFoundError);
return undefined;
}
return getControllerEndpoint(serverInfo);
}
function addBdcController(treeDataProvider: ControllerTreeDataProvider, node?: TreeNode): void {