From 43cd92c5f2040652608b2fb963941b57ca954f63 Mon Sep 17 00:00:00 2001 From: nithinkdb Date: Wed, 17 Aug 2022 11:10:47 -0700 Subject: [PATCH 01/14] Testing out changes Signed-off-by: nithinkdb --- .gitignore | 4 +-- lib/DBSQLClient.ts | 14 ++++++-- lib/connection/connections/XhrConnection.ts | 37 +++++++++++++++++++++ lib/connection/transports/XhrTransport.ts | 32 ++++++++++++++++++ 4 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 lib/connection/connections/XhrConnection.ts create mode 100644 lib/connection/transports/XhrTransport.ts diff --git a/.gitignore b/.gitignore index bec018fe..05133408 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,6 @@ node_modules .nyc_output coverage_e2e coverage_unit -*.code-workspace -dist *.DS_Store +dist +*.code-workspace diff --git a/lib/DBSQLClient.ts b/lib/DBSQLClient.ts index c60ebeb7..b3b55968 100644 --- a/lib/DBSQLClient.ts +++ b/lib/DBSQLClient.ts @@ -17,6 +17,9 @@ import StatusFactory from './factory/StatusFactory'; import HiveDriverError from './errors/HiveDriverError'; import { buildUserAgentString, definedOrError } from './utils'; import PlainHttpAuthentication from './connection/auth/PlainHttpAuthentication'; +import XhrConnection from './connection/connections/XhrConnection'; + +function isNodejs() { return typeof "process" !== "undefined" && process && process.versions && process.versions.node; } export default class DBSQLClient extends EventEmitter implements IDBSQLClient { private client: TCLIService.Client | null; @@ -33,11 +36,18 @@ export default class DBSQLClient extends EventEmitter implements IDBSQLClient { constructor() { super(); - this.connectionProvider = new HttpConnection(); - this.authProvider = new NoSaslAuthentication(); + if(isNodejs()) { + console.log("Bad"); + this.connectionProvider = new HttpConnection(); + } + else { + this.connectionProvider = new XhrConnection(); + console.log("Good"); + } this.statusFactory = new StatusFactory(); this.client = null; this.connection = null; + this.authProvider = new NoSaslAuthentication(); } private getConnectionOptions(options: IDBSQLConnectionOptions): IConnectionOptions { diff --git a/lib/connection/connections/XhrConnection.ts b/lib/connection/connections/XhrConnection.ts new file mode 100644 index 00000000..22457636 --- /dev/null +++ b/lib/connection/connections/XhrConnection.ts @@ -0,0 +1,37 @@ +import thrift from 'thrift'; +import https from 'https'; + +import IThriftConnection from '../contracts/IThriftConnection'; +import IConnectionProvider from '../contracts/IConnectionProvider'; +import IConnectionOptions, { Options } from '../contracts/IConnectionOptions'; +import IAuthentication from '../contracts/IAuthentication'; +import XhrTransport from '../transports/XhrTransport'; + +export default class XhrConnection implements IConnectionProvider, IThriftConnection { + private thrift = thrift; + private connection: any; + + connect(options: IConnectionOptions, authProvider: IAuthentication): Promise { + const xhrTransport = new XhrTransport({ + transport: thrift.TBufferedTransport, + protocol: thrift.TBinaryProtocol, + ...options.options, + }); + return authProvider.authenticate(xhrTransport).then(() => { + this.connection = this.thrift.createXHRConnection(options.host, options.port, xhrTransport.getOptions()); + return this; + }); + } + + isConnected(): boolean { + if (this.connection) { + return true; + } else { + return false; + } + } + + getConnection() { + return this.connection; + } +} \ No newline at end of file diff --git a/lib/connection/transports/XhrTransport.ts b/lib/connection/transports/XhrTransport.ts new file mode 100644 index 00000000..3aeecdbd --- /dev/null +++ b/lib/connection/transports/XhrTransport.ts @@ -0,0 +1,32 @@ +import ITransport from '../contracts/ITransport'; + +export default class XhrTransport implements ITransport { + private xhrOptions: object; + + constructor(httpOptions: object = {}) { + this.xhrOptions = httpOptions; + } + + getTransport(): any { + return this.xhrOptions; + } + + setOptions(option: string, value: any) { + this.xhrOptions = { + ...this.xhrOptions, + [option]: value, + }; + } + + getOptions(): object { + return this.xhrOptions; + } + + connect() {} + addListener() {} + removeListener() {} + write() {} + end() {} + emit() {} + } + \ No newline at end of file From 8559cc17e58b75a54d995fd30d23d26d88165a33 Mon Sep 17 00:00:00 2001 From: nithinkdb Date: Wed, 17 Aug 2022 11:54:31 -0700 Subject: [PATCH 02/14] Added check for node when building user string Signed-off-by: nithinkdb --- lib/DBSQLClient.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/DBSQLClient.ts b/lib/DBSQLClient.ts index b3b55968..e37b9688 100644 --- a/lib/DBSQLClient.ts +++ b/lib/DBSQLClient.ts @@ -37,12 +37,10 @@ export default class DBSQLClient extends EventEmitter implements IDBSQLClient { constructor() { super(); if(isNodejs()) { - console.log("Bad"); this.connectionProvider = new HttpConnection(); } else { this.connectionProvider = new XhrConnection(); - console.log("Good"); } this.statusFactory = new StatusFactory(); this.client = null; @@ -63,6 +61,7 @@ export default class DBSQLClient extends EventEmitter implements IDBSQLClient { } async connect(options: IDBSQLConnectionOptions): Promise { + let clientId = isNodejs() ? buildUserAgentString(options.clientId) : 'anonymous'; this.authProvider = new PlainHttpAuthentication({ username: 'token', password: options.token, From ae70278a1dd17e9fe6d6fdd9bf1678515dd207ce Mon Sep 17 00:00:00 2001 From: nithinkdb Date: Wed, 17 Aug 2022 12:34:34 -0700 Subject: [PATCH 03/14] Added default user agent string Signed-off-by: nithinkdb --- lib/DBSQLClient.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/DBSQLClient.ts b/lib/DBSQLClient.ts index e37b9688..d293997a 100644 --- a/lib/DBSQLClient.ts +++ b/lib/DBSQLClient.ts @@ -61,12 +61,12 @@ export default class DBSQLClient extends EventEmitter implements IDBSQLClient { } async connect(options: IDBSQLConnectionOptions): Promise { - let clientId = isNodejs() ? buildUserAgentString(options.clientId) : 'anonymous'; + let clientId = isNodejs() ? buildUserAgentString(options.clientId) : `NodejsDatabricksSqlConnector/0.1.8-beta.1 (${options.clientId})`; this.authProvider = new PlainHttpAuthentication({ username: 'token', password: options.token, headers: { - 'User-Agent': buildUserAgentString(options.clientId), + 'User-Agent': buildUserAgentString(clientId), }, }); From cc0378323c343628be177b4746565cb4d77ba139 Mon Sep 17 00:00:00 2001 From: nithinkdb Date: Wed, 17 Aug 2022 12:43:37 -0700 Subject: [PATCH 04/14] Removed pointless builduserstring and renamed for clarity Signed-off-by: nithinkdb --- lib/DBSQLClient.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/DBSQLClient.ts b/lib/DBSQLClient.ts index d293997a..ae2403ac 100644 --- a/lib/DBSQLClient.ts +++ b/lib/DBSQLClient.ts @@ -61,12 +61,12 @@ export default class DBSQLClient extends EventEmitter implements IDBSQLClient { } async connect(options: IDBSQLConnectionOptions): Promise { - let clientId = isNodejs() ? buildUserAgentString(options.clientId) : `NodejsDatabricksSqlConnector/0.1.8-beta.1 (${options.clientId})`; + let agentString = isNodejs() ? buildUserAgentString(options.clientId) : `NodejsDatabricksSqlConnector/0.1.8-beta.1 (${options.clientId})`; this.authProvider = new PlainHttpAuthentication({ username: 'token', password: options.token, headers: { - 'User-Agent': buildUserAgentString(clientId), + 'User-Agent': agentString, }, }); From 1d13c5bfc1f3414e491abb2063cf33a7f6e54dbd Mon Sep 17 00:00:00 2001 From: nithinkdb Date: Wed, 17 Aug 2022 12:48:55 -0700 Subject: [PATCH 05/14] Created Xhr client in browser mode Signed-off-by: nithinkdb --- lib/DBSQLClient.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/DBSQLClient.ts b/lib/DBSQLClient.ts index ae2403ac..4d407f72 100644 --- a/lib/DBSQLClient.ts +++ b/lib/DBSQLClient.ts @@ -72,8 +72,12 @@ export default class DBSQLClient extends EventEmitter implements IDBSQLClient { this.connection = await this.connectionProvider.connect(this.getConnectionOptions(options), this.authProvider); - this.client = this.thrift.createClient(TCLIService, this.connection.getConnection()); - + if(isNodejs()) { + this.client = this.thrift.createClient(TCLIService, this.connection.getConnection()); + } + else { + this.client = this.thrift.createXHRClient(TCLIService, this.connection.getConnection()); + } this.connection.getConnection().on('error', (error: Error) => { this.emit('error', error); }); From bdc6ae71e435b812f320bad5c57374b98661385a Mon Sep 17 00:00:00 2001 From: nithinkdb Date: Wed, 17 Aug 2022 16:33:13 -0700 Subject: [PATCH 06/14] Stopped attempting to change header Signed-off-by: nithinkdb --- lib/DBSQLClient.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/DBSQLClient.ts b/lib/DBSQLClient.ts index 4d407f72..632c8d34 100644 --- a/lib/DBSQLClient.ts +++ b/lib/DBSQLClient.ts @@ -61,14 +61,17 @@ export default class DBSQLClient extends EventEmitter implements IDBSQLClient { } async connect(options: IDBSQLConnectionOptions): Promise { - let agentString = isNodejs() ? buildUserAgentString(options.clientId) : `NodejsDatabricksSqlConnector/0.1.8-beta.1 (${options.clientId})`; - this.authProvider = new PlainHttpAuthentication({ + let opts = { username: 'token', password: options.token, - headers: { - 'User-Agent': agentString, - }, - }); + headers: {} + } + if(isNodejs()){ + opts.headers = { + 'User-Agent': buildUserAgentString(options.clientId) + } + } + this.authProvider = new PlainHttpAuthentication(opts); this.connection = await this.connectionProvider.connect(this.getConnectionOptions(options), this.authProvider); From c38756b5de73adccb38165cf54a02e1d37956ed4 Mon Sep 17 00:00:00 2001 From: nithinkdb Date: Fri, 19 Aug 2022 17:53:32 -0700 Subject: [PATCH 07/14] Changed xhr protocol to JSON Signed-off-by: nithinkdb --- lib/connection/connections/XhrConnection.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/connection/connections/XhrConnection.ts b/lib/connection/connections/XhrConnection.ts index 22457636..324c596b 100644 --- a/lib/connection/connections/XhrConnection.ts +++ b/lib/connection/connections/XhrConnection.ts @@ -14,7 +14,7 @@ export default class XhrConnection implements IConnectionProvider, IThriftConnec connect(options: IConnectionOptions, authProvider: IAuthentication): Promise { const xhrTransport = new XhrTransport({ transport: thrift.TBufferedTransport, - protocol: thrift.TBinaryProtocol, + protocol: thrift.TJSONProtocol, ...options.options, }); return authProvider.authenticate(xhrTransport).then(() => { From c36c233bf80172a487b26bbdb7399eda2e315f8f Mon Sep 17 00:00:00 2001 From: nithinkdb Date: Fri, 19 Aug 2022 18:12:16 -0700 Subject: [PATCH 08/14] Added header for JSON transport Signed-off-by: nithinkdb --- lib/connection/connections/XhrConnection.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/connection/connections/XhrConnection.ts b/lib/connection/connections/XhrConnection.ts index 324c596b..51547a0f 100644 --- a/lib/connection/connections/XhrConnection.ts +++ b/lib/connection/connections/XhrConnection.ts @@ -15,6 +15,9 @@ export default class XhrConnection implements IConnectionProvider, IThriftConnec const xhrTransport = new XhrTransport({ transport: thrift.TBufferedTransport, protocol: thrift.TJSONProtocol, + headers: { + 'Content-Type': 'application/vnd.apache.thrift.json', + }, ...options.options, }); return authProvider.authenticate(xhrTransport).then(() => { From 3e45c086f11127ec7239f2d0af3acb4967fa0939 Mon Sep 17 00:00:00 2001 From: nithinkdb Date: Fri, 19 Aug 2022 18:13:58 -0700 Subject: [PATCH 09/14] Reverted changes Signed-off-by: nithinkdb --- lib/connection/connections/XhrConnection.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/connection/connections/XhrConnection.ts b/lib/connection/connections/XhrConnection.ts index 51547a0f..22457636 100644 --- a/lib/connection/connections/XhrConnection.ts +++ b/lib/connection/connections/XhrConnection.ts @@ -14,10 +14,7 @@ export default class XhrConnection implements IConnectionProvider, IThriftConnec connect(options: IConnectionOptions, authProvider: IAuthentication): Promise { const xhrTransport = new XhrTransport({ transport: thrift.TBufferedTransport, - protocol: thrift.TJSONProtocol, - headers: { - 'Content-Type': 'application/vnd.apache.thrift.json', - }, + protocol: thrift.TBinaryProtocol, ...options.options, }); return authProvider.authenticate(xhrTransport).then(() => { From ef279c79daf884d32ddaae954ae57bea2ce3bd92 Mon Sep 17 00:00:00 2001 From: nithinkdb Date: Mon, 22 Aug 2022 11:18:19 -0700 Subject: [PATCH 10/14] Added MIME type for binary data Signed-off-by: nithinkdb --- lib/DBSQLClient.ts | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/lib/DBSQLClient.ts b/lib/DBSQLClient.ts index 632c8d34..c8d5de9d 100644 --- a/lib/DBSQLClient.ts +++ b/lib/DBSQLClient.ts @@ -61,14 +61,23 @@ export default class DBSQLClient extends EventEmitter implements IDBSQLClient { } async connect(options: IDBSQLConnectionOptions): Promise { - let opts = { - username: 'token', - password: options.token, - headers: {} - } + let opts; if(isNodejs()){ - opts.headers = { - 'User-Agent': buildUserAgentString(options.clientId) + opts = { + username: 'token', + password: options.token, + headers: { + 'User-Agent': buildUserAgentString(options.clientId) + } + } + } + else { + opts = { + username: 'token', + password: options.token, + headers: { + 'Content-Type': 'application/vnd.apache.thrift.binary' + } } } this.authProvider = new PlainHttpAuthentication(opts); From 79437b2da64ef9d5b4a29c247a206051e9f89996 Mon Sep 17 00:00:00 2001 From: nithinkdb Date: Mon, 22 Aug 2022 11:33:15 -0700 Subject: [PATCH 11/14] Added headers to createclient Signed-off-by: nithinkdb --- lib/DBSQLClient.ts | 5 +---- lib/connection/connections/XhrConnection.ts | 3 +++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/DBSQLClient.ts b/lib/DBSQLClient.ts index c8d5de9d..4890d000 100644 --- a/lib/DBSQLClient.ts +++ b/lib/DBSQLClient.ts @@ -74,10 +74,7 @@ export default class DBSQLClient extends EventEmitter implements IDBSQLClient { else { opts = { username: 'token', - password: options.token, - headers: { - 'Content-Type': 'application/vnd.apache.thrift.binary' - } + password: options.token } } this.authProvider = new PlainHttpAuthentication(opts); diff --git a/lib/connection/connections/XhrConnection.ts b/lib/connection/connections/XhrConnection.ts index 22457636..19143226 100644 --- a/lib/connection/connections/XhrConnection.ts +++ b/lib/connection/connections/XhrConnection.ts @@ -15,6 +15,9 @@ export default class XhrConnection implements IConnectionProvider, IThriftConnec const xhrTransport = new XhrTransport({ transport: thrift.TBufferedTransport, protocol: thrift.TBinaryProtocol, + headers: { + 'Content-Type': 'application/vnd.apache.thrift.binary' + }, ...options.options, }); return authProvider.authenticate(xhrTransport).then(() => { From 1b125d7adad922a2ed4fc80b2628312f80020c63 Mon Sep 17 00:00:00 2001 From: nithinkdb Date: Mon, 22 Aug 2022 16:13:37 -0700 Subject: [PATCH 12/14] Changed thrift dependency to test change Signed-off-by: nithinkdb --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e5251bdc..82d8acb1 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,6 @@ "dependencies": { "commander": "^9.3.0", "node-int64": "^0.4.0", - "thrift": "^0.16.0" + "thrift": "github:nithinkdb/thrift#xhr-binary" } } From 83507dac1d1c8455f8d079b221ddc79e92892d3f Mon Sep 17 00:00:00 2001 From: nithinkdb Date: Mon, 22 Aug 2022 17:02:45 -0700 Subject: [PATCH 13/14] Reverted Package.json Signed-off-by: nithinkdb --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 82d8acb1..e5251bdc 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,6 @@ "dependencies": { "commander": "^9.3.0", "node-int64": "^0.4.0", - "thrift": "github:nithinkdb/thrift#xhr-binary" + "thrift": "^0.16.0" } } From 379a073f94d679aab71b2b8998588df7f05b1336 Mon Sep 17 00:00:00 2001 From: nithinkdb Date: Mon, 22 Aug 2022 17:12:49 -0700 Subject: [PATCH 14/14] Ran linters Signed-off-by: nithinkdb --- lib/DBSQLClient.ts | 29 +++++----- lib/connection/connections/XhrConnection.ts | 57 ++++++++++---------- lib/connection/transports/XhrTransport.ts | 60 +++++++++++---------- 3 files changed, 74 insertions(+), 72 deletions(-) diff --git a/lib/DBSQLClient.ts b/lib/DBSQLClient.ts index 4890d000..2a32c821 100644 --- a/lib/DBSQLClient.ts +++ b/lib/DBSQLClient.ts @@ -19,7 +19,9 @@ import { buildUserAgentString, definedOrError } from './utils'; import PlainHttpAuthentication from './connection/auth/PlainHttpAuthentication'; import XhrConnection from './connection/connections/XhrConnection'; -function isNodejs() { return typeof "process" !== "undefined" && process && process.versions && process.versions.node; } +function isNodejs() { + return typeof 'process' !== 'undefined' && process && process.versions && process.versions.node; +} export default class DBSQLClient extends EventEmitter implements IDBSQLClient { private client: TCLIService.Client | null; @@ -36,10 +38,9 @@ export default class DBSQLClient extends EventEmitter implements IDBSQLClient { constructor() { super(); - if(isNodejs()) { + if (isNodejs()) { this.connectionProvider = new HttpConnection(); - } - else { + } else { this.connectionProvider = new XhrConnection(); } this.statusFactory = new StatusFactory(); @@ -62,29 +63,27 @@ export default class DBSQLClient extends EventEmitter implements IDBSQLClient { async connect(options: IDBSQLConnectionOptions): Promise { let opts; - if(isNodejs()){ + if (isNodejs()) { opts = { username: 'token', password: options.token, headers: { - 'User-Agent': buildUserAgentString(options.clientId) - } - } - } - else { + 'User-Agent': buildUserAgentString(options.clientId), + }, + }; + } else { opts = { username: 'token', - password: options.token - } + password: options.token, + }; } this.authProvider = new PlainHttpAuthentication(opts); this.connection = await this.connectionProvider.connect(this.getConnectionOptions(options), this.authProvider); - if(isNodejs()) { + if (isNodejs()) { this.client = this.thrift.createClient(TCLIService, this.connection.getConnection()); - } - else { + } else { this.client = this.thrift.createXHRClient(TCLIService, this.connection.getConnection()); } this.connection.getConnection().on('error', (error: Error) => { diff --git a/lib/connection/connections/XhrConnection.ts b/lib/connection/connections/XhrConnection.ts index 19143226..40fcf338 100644 --- a/lib/connection/connections/XhrConnection.ts +++ b/lib/connection/connections/XhrConnection.ts @@ -1,40 +1,39 @@ import thrift from 'thrift'; -import https from 'https'; import IThriftConnection from '../contracts/IThriftConnection'; import IConnectionProvider from '../contracts/IConnectionProvider'; -import IConnectionOptions, { Options } from '../contracts/IConnectionOptions'; +import IConnectionOptions from '../contracts/IConnectionOptions'; import IAuthentication from '../contracts/IAuthentication'; import XhrTransport from '../transports/XhrTransport'; export default class XhrConnection implements IConnectionProvider, IThriftConnection { - private thrift = thrift; - private connection: any; - - connect(options: IConnectionOptions, authProvider: IAuthentication): Promise { - const xhrTransport = new XhrTransport({ - transport: thrift.TBufferedTransport, - protocol: thrift.TBinaryProtocol, - headers: { - 'Content-Type': 'application/vnd.apache.thrift.binary' - }, - ...options.options, - }); - return authProvider.authenticate(xhrTransport).then(() => { - this.connection = this.thrift.createXHRConnection(options.host, options.port, xhrTransport.getOptions()); - return this; - }); - } + private thrift = thrift; + + private connection: any; - isConnected(): boolean { - if (this.connection) { - return true; - } else { - return false; - } - } + connect(options: IConnectionOptions, authProvider: IAuthentication): Promise { + const xhrTransport = new XhrTransport({ + transport: thrift.TBufferedTransport, + protocol: thrift.TBinaryProtocol, + headers: { + 'Content-Type': 'application/vnd.apache.thrift.binary', + }, + ...options.options, + }); + return authProvider.authenticate(xhrTransport).then(() => { + this.connection = this.thrift.createXHRConnection(options.host, options.port, xhrTransport.getOptions()); + return this; + }); + } - getConnection() { - return this.connection; + isConnected(): boolean { + if (this.connection) { + return true; } -} \ No newline at end of file + return false; + } + + getConnection() { + return this.connection; + } +} diff --git a/lib/connection/transports/XhrTransport.ts b/lib/connection/transports/XhrTransport.ts index 3aeecdbd..bd264171 100644 --- a/lib/connection/transports/XhrTransport.ts +++ b/lib/connection/transports/XhrTransport.ts @@ -1,32 +1,36 @@ import ITransport from '../contracts/ITransport'; export default class XhrTransport implements ITransport { - private xhrOptions: object; - - constructor(httpOptions: object = {}) { - this.xhrOptions = httpOptions; - } - - getTransport(): any { - return this.xhrOptions; - } - - setOptions(option: string, value: any) { - this.xhrOptions = { - ...this.xhrOptions, - [option]: value, - }; - } - - getOptions(): object { - return this.xhrOptions; - } - - connect() {} - addListener() {} - removeListener() {} - write() {} - end() {} - emit() {} + private xhrOptions: object; + + constructor(httpOptions: object = {}) { + this.xhrOptions = httpOptions; + } + + getTransport(): any { + return this.xhrOptions; + } + + setOptions(option: string, value: any) { + this.xhrOptions = { + ...this.xhrOptions, + [option]: value, + }; + } + + getOptions(): object { + return this.xhrOptions; } - \ No newline at end of file + + connect() {} + + addListener() {} + + removeListener() {} + + write() {} + + end() {} + + emit() {} +}