Rename nodeType name in order to have file context menu in both mssql and SqlOpsStudio (#3862)

* Added data service context menu: file related operations. All new files are ported from SqlOpsStudio. Will remove these functionality from SqlOpsStudio.

* Used the existing constant hadoopKnoxEndpointName

* Rename nodeType name from hdfs to bdc. So we can have file context menu in both mssql and SqlOpsStudio. Need to add "Create External Table from CSV" support for bdc nodeType

* Rename bdc to mssqlcluster
This commit is contained in:
Yurong He
2019-01-31 13:34:59 -08:00
committed by GitHub
parent 90d8c37f91
commit ecac6201d0
20 changed files with 715 additions and 56 deletions

View File

@@ -13,7 +13,8 @@ const localize = nls.loadMessageBundle();
import * as constants from '../constants';
import * as LocalizedConstants from '../localizedConstants';
import * as utils from '../utils';
import { IFileSource, HdfsFileSource, IHdfsOptions, IRequestParams, FileSourceFactory } from './fileSources';
import { IFileSource, IHdfsOptions, IRequestParams, FileSourceFactory } from './fileSources';
import { IEndpoint } from './objectExplorerNodeProvider';
function appendIfExists(uri: string, propName: string, propValue: string): string {
if (propValue) {
@@ -110,7 +111,7 @@ export class Connection {
isCloud: false,
azureVersion: 0,
osVersion: '',
options: { isBigDataCluster: false, clusterEndpoints: []}
options: {}
};
return info;
}
@@ -188,15 +189,23 @@ export class Connection {
return this.connectionInfo.options[constants.groupIdName];
}
public isMatch(connectionInfo: sqlops.ConnectionInfo): boolean {
public async isMatch(connectionInfo: sqlops.ConnectionInfo): Promise<boolean> {
if (!connectionInfo) {
return false;
}
let otherConnection = new Connection(connectionInfo);
return otherConnection.groupId === this.groupId
&& otherConnection.host === this.host
&& otherConnection.knoxport === this.knoxport
&& otherConnection.user === this.user;
let profile = connectionInfo as sqlops.IConnectionProfile;
if (profile) {
let result: IEndpoint = await utils.getClusterEndpoint(profile.id, constants.hadoopKnoxEndpointName);
if (result === undefined || !result.ipAddress || !result.port) {
return false;
}
return connectionInfo.options.groupId === this.groupId
&& result.ipAddress === this.host
&& String(result.port).startsWith(this.knoxport)
&& String(result.port).endsWith(this.knoxport);
// TODO: enable the user check when the unified user is used
//&& connectionInfo.options.user === this.user;
}
}
public createHdfsFileSource(factory?: FileSourceFactory, additionalRequestParams?: IRequestParams): IFileSource {

View File

@@ -63,7 +63,7 @@ export async function getNode<T extends TreeNode>(context: ICommandViewContext |
export class UploadFilesCommand extends ProgressCommand {
constructor(prompter: IPrompter, appContext: AppContext) {
super('hdfs.uploadFiles', prompter, appContext);
super('mssqlCluster.uploadFiles', prompter, appContext);
}
protected async preExecute(context: ICommandViewContext | ICommandObjectExplorerContext, args: object = {}): Promise<any> {
@@ -131,7 +131,7 @@ export class UploadFilesCommand extends ProgressCommand {
export class MkDirCommand extends ProgressCommand {
constructor(prompter: IPrompter, appContext: AppContext) {
super('hdfs.mkdir', prompter, appContext);
super('mssqlCluster.mkdir', prompter, appContext);
}
protected async preExecute(context: ICommandViewContext | ICommandObjectExplorerContext, args: object = {}): Promise<any> {
@@ -177,7 +177,7 @@ export class MkDirCommand extends ProgressCommand {
export class DeleteFilesCommand extends Command {
constructor(private prompter: IPrompter, appContext: AppContext) {
super('hdfs.deleteFiles', appContext);
super('mssqlCluster.deleteFiles', appContext);
}
protected async preExecute(context: ICommandViewContext |ICommandObjectExplorerContext, args: object = {}): Promise<any> {
@@ -197,10 +197,10 @@ export class DeleteFilesCommand extends Command {
oeNodeToRefresh = await oeNodeToDelete.getParent();
}
switch (treeItem.contextValue) {
case constants.HdfsItems.Folder:
case constants.MssqlClusterItems.Folder:
await this.deleteFolder(<FolderNode>node);
break;
case constants.HdfsItems.File:
case constants.MssqlClusterItems.File:
await this.deleteFile(<FileNode>node);
break;
default:
@@ -248,7 +248,7 @@ export class DeleteFilesCommand extends Command {
export class SaveFileCommand extends ProgressCommand {
constructor(prompter: IPrompter, appContext: AppContext) {
super('hdfs.saveFile', prompter, appContext);
super('mssqlCluster.saveFile', prompter, appContext);
}
protected async preExecute(context: ICommandViewContext | ICommandObjectExplorerContext, args: object = {}): Promise<any> {
@@ -286,7 +286,7 @@ export class PreviewFileCommand extends ProgressCommand {
public static readonly DefaultMaxSize = 30 * 1024 * 1024;
constructor(prompter: IPrompter, appContext: AppContext) {
super('hdfs.previewFile', prompter, appContext);
super('mssqlCluster.previewFile', prompter, appContext);
}
protected async preExecute(context: ICommandViewContext | ICommandObjectExplorerContext, args: object = {}): Promise<any> {
@@ -338,7 +338,7 @@ export class CopyPathCommand extends Command {
public static readonly DefaultMaxSize = 30 * 1024 * 1024;
constructor(appContext: AppContext) {
super('hdfs.copyPath', appContext);
super('mssqlCluster.copyPath', appContext);
}
protected async preExecute(context: ICommandViewContext | ICommandObjectExplorerContext, args: object = {}): Promise<any> {

View File

@@ -108,7 +108,7 @@ export class FolderNode extends HdfsFileSourceNode {
protected _nodeType: string;
constructor(context: TreeDataContext, path: string, fileSource: IFileSource, nodeType?: string) {
super(context, path, fileSource);
this._nodeType = nodeType ? nodeType : Constants.HdfsItems.Folder;
this._nodeType = nodeType ? nodeType : Constants.MssqlClusterItems.Folder;
}
private ensureChildrenExist(): void {
@@ -209,7 +209,7 @@ export class FolderNode extends HdfsFileSourceNode {
export class ConnectionNode extends FolderNode {
constructor(context: TreeDataContext, private displayName: string, fileSource: IFileSource) {
super(context, '/', fileSource, Constants.HdfsItems.Connection);
super(context, '/', fileSource, Constants.MssqlClusterItems.Connection);
}
getDisplayName(): string {
@@ -247,7 +247,7 @@ export class FileNode extends HdfsFileSourceNode implements IFileNode {
dark: this.context.extensionContext.asAbsolutePath('resources/dark/file_inverse.svg'),
light: this.context.extensionContext.asAbsolutePath('resources/light/file.svg')
};
item.contextValue = Constants.HdfsItems.File;
item.contextValue = Constants.MssqlClusterItems.File;
return item;
}
@@ -261,7 +261,7 @@ export class FileNode extends HdfsFileSourceNode implements IFileNode {
metadata: undefined,
nodePath: this.generateNodePath(),
nodeStatus: undefined,
nodeType: Constants.HdfsItems.File,
nodeType: Constants.MssqlClusterItems.File,
nodeSubType: this.getSubType(),
iconType: 'FileGroupFile'
};
@@ -306,7 +306,7 @@ export class FileNode extends HdfsFileSourceNode implements IFileNode {
private getSubType(): string {
if (this.getDisplayName().toLowerCase().endsWith('.jar') || this.getDisplayName().toLowerCase().endsWith('.py')) {
return Constants.HdfsItemsSubType.Spark;
return Constants.MssqlClusterItemsSubType.Spark;
}
return undefined;
@@ -344,7 +344,7 @@ export class MessageNode extends TreeNode {
public getTreeItem(): vscode.TreeItem | Promise<vscode.TreeItem> {
let item = new vscode.TreeItem(this.message, vscode.TreeItemCollapsibleState.None);
item.contextValue = Constants.HdfsItems.Message;
item.contextValue = Constants.MssqlClusterItems.Message;
return item;
}
@@ -357,7 +357,7 @@ export class MessageNode extends TreeNode {
metadata: undefined,
nodePath: this.generateNodePath(),
nodeStatus: undefined,
nodeType: Constants.HdfsItems.Message,
nodeType: Constants.MssqlClusterItems.Message,
nodeSubType: undefined,
iconType: 'MessageType'
};

View File

@@ -21,7 +21,7 @@ import { AppContext } from '../appContext';
import * as constants from '../constants';
const outputChannel = vscode.window.createOutputChannel(constants.providerId);
interface IEndpoint {
export interface IEndpoint {
serviceName: string;
ipAddress: string;
port: number;
@@ -209,7 +209,7 @@ export class MssqlObjectExplorerNodeProvider extends ProviderBase implements sql
async findNodeForContext<T extends TreeNode>(explorerContext: sqlops.ObjectExplorerContext): Promise<T> {
let node: T = undefined;
let session = this.findSessionForConnection(explorerContext.connectionProfile);
let session = await this.findSessionForConnection(explorerContext.connectionProfile);
if (session) {
if (explorerContext.isConnectionNode) {
// Note: ideally fix so we verify T matches RootNode and go from there
@@ -222,9 +222,9 @@ export class MssqlObjectExplorerNodeProvider extends ProviderBase implements sql
return node;
}
private findSessionForConnection(connectionProfile: sqlops.IConnectionProfile): Session {
private async findSessionForConnection(connectionProfile: sqlops.IConnectionProfile): Promise<Session> {
for (let session of this.sessionMap.values()) {
if (session.connection && session.connection.isMatch(connectionProfile)) {
if (session.connection && await session.connection.isMatch(connectionProfile)) {
return session;
}
}