From 4cc0aab909cabfdd81e3d8a3bbfe465f20ed01d7 Mon Sep 17 00:00:00 2001 From: Andrew Page Date: Fri, 3 Dec 2021 14:16:18 -0500 Subject: [PATCH 1/8] set custom client environment via config --- lib/core.js | 13 +++++++++++-- lib/errors.js | 1 + lib/global_config.js | 25 +++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/lib/core.js b/lib/core.js index 7c60eaebe..b7f21eed3 100644 --- a/lib/core.js +++ b/lib/core.js @@ -70,7 +70,7 @@ function Core(options) var validateCredentials = !config && (connectionOptions && !connectionOptions.sessionToken) var connectionConfig = - new ConnectionConfig(connectionOptions, validateCredentials, qaMode, clientInfo); + new ConnectionConfig(connectionOptions, validateCredentials, qaMode, Object.assign(clientInfo, GlobalConfig.getCustomClientEnvironment())); // if an http client was specified in the options passed to the module, use // it, otherwise create a new HttpClient @@ -171,7 +171,7 @@ function Core(options) { // check that the specified value is a valid tag Errors.checkArgumentValid(LoggerCore.isValidLogTag(logTag), - ErrorCodes.ERR_GLOGAL_CONFIGURE_INVALID_LOG_LEVEL); + ErrorCodes.ERR_GLOBAL_CONFIGURE_INVALID_LOG_LEVEL); Logger.getInstance().configure( { @@ -196,6 +196,15 @@ function Core(options) GlobalConfig.setOcspFailOpen(ocspFailOpen); } + + // Allow merging of additional fields into client environment. + let clientEnvironment = options.clientEnvironment; + if (Util.exists(clientEnvironment)) { + Errors.checkArgumentValid(Util.isObject(clientEnvironment), + ErrorCodes.ERR_GLOBAL_CONFIGURE_INVALID_CLIENT_ENVIRONMENT); + + GlobalConfig.setCustomClientEnvironment(clientEnvironment); + } } }; diff --git a/lib/errors.js b/lib/errors.js index 4da464094..9a80733e5 100644 --- a/lib/errors.js +++ b/lib/errors.js @@ -25,6 +25,7 @@ codes.ERR_LARGE_RESULT_SET_RESPONSE_FAILURE = 402002; codes.ERR_GLOBAL_CONFIGURE_INVALID_LOG_LEVEL = 403001; codes.ERR_GLOBAL_CONFIGURE_INVALID_INSECURE_CONNECT = 403002; codes.ERR_GLOBAL_CONFIGURE_INVALID_OCSP_MODE = 403003; +codes.ERR_GLOBAL_CONFIGURE_INVALID_CLIENT_ENVIRONMENT = 403004; // 404001 codes.ERR_CONN_CREATE_MISSING_OPTIONS = 404001; diff --git a/lib/global_config.js b/lib/global_config.js index 22b5b24c7..0d93d7367 100644 --- a/lib/global_config.js +++ b/lib/global_config.js @@ -145,3 +145,28 @@ const rest = { HTTPS_PROTOCOL: 'https' }; exports.rest = rest; + +let customClientEnvironment = {}; + +/** + * Updates the value of the 'customClientEnvironment' parameter. + * + * @param {boolean} value + */ +exports.setCustomClientEnvironment = function (value) +{ + // validate input + Errors.assertInternal(Util.isObject(value)); + + customClientEnvironment = value; +}; + +/** + * Returns the value of the 'customClientEnvironment' parameter. + * + * @returns {boolean} + */ +exports.getCustomClientEnvironment = function () +{ + return customClientEnvironment; +}; \ No newline at end of file From 94cbd8f4a3ef481e857d954d7e7840498190bae0 Mon Sep 17 00:00:00 2001 From: Andrew Page Date: Fri, 3 Dec 2021 15:30:52 -0500 Subject: [PATCH 2/8] update client application --- lib/authentication/authentication.js | 4 +++- lib/core.js | 11 +---------- lib/errors.js | 1 - lib/global_config.js | 25 ------------------------- 4 files changed, 4 insertions(+), 37 deletions(-) diff --git a/lib/authentication/authentication.js b/lib/authentication/authentication.js index 5975ff066..f1e684f5f 100644 --- a/lib/authentication/authentication.js +++ b/lib/authentication/authentication.js @@ -26,6 +26,7 @@ exports.authenticationTypes = authenticationTypes; * @param {String} username * @param {String} clientName * @param {String} clientVersion + * @param clientApplication * @param {Object} clientEnv * * @returns {JSON} @@ -54,7 +55,8 @@ exports.formAuthJSON = function formAuthJSON( { OS: clientEnv.OS, OS_VERSION: clientEnv.OS_VERSION, - OCSP_MODE: clientEnv.OCSP_MODE + OCSP_MODE: clientEnv.OCSP_MODE, + APPLICATION: clientApplication, } } }; diff --git a/lib/core.js b/lib/core.js index b7f21eed3..21dcde376 100644 --- a/lib/core.js +++ b/lib/core.js @@ -70,7 +70,7 @@ function Core(options) var validateCredentials = !config && (connectionOptions && !connectionOptions.sessionToken) var connectionConfig = - new ConnectionConfig(connectionOptions, validateCredentials, qaMode, Object.assign(clientInfo, GlobalConfig.getCustomClientEnvironment())); + new ConnectionConfig(connectionOptions, validateCredentials, qaMode, clientInfo); // if an http client was specified in the options passed to the module, use // it, otherwise create a new HttpClient @@ -196,15 +196,6 @@ function Core(options) GlobalConfig.setOcspFailOpen(ocspFailOpen); } - - // Allow merging of additional fields into client environment. - let clientEnvironment = options.clientEnvironment; - if (Util.exists(clientEnvironment)) { - Errors.checkArgumentValid(Util.isObject(clientEnvironment), - ErrorCodes.ERR_GLOBAL_CONFIGURE_INVALID_CLIENT_ENVIRONMENT); - - GlobalConfig.setCustomClientEnvironment(clientEnvironment); - } } }; diff --git a/lib/errors.js b/lib/errors.js index 9a80733e5..4da464094 100644 --- a/lib/errors.js +++ b/lib/errors.js @@ -25,7 +25,6 @@ codes.ERR_LARGE_RESULT_SET_RESPONSE_FAILURE = 402002; codes.ERR_GLOBAL_CONFIGURE_INVALID_LOG_LEVEL = 403001; codes.ERR_GLOBAL_CONFIGURE_INVALID_INSECURE_CONNECT = 403002; codes.ERR_GLOBAL_CONFIGURE_INVALID_OCSP_MODE = 403003; -codes.ERR_GLOBAL_CONFIGURE_INVALID_CLIENT_ENVIRONMENT = 403004; // 404001 codes.ERR_CONN_CREATE_MISSING_OPTIONS = 404001; diff --git a/lib/global_config.js b/lib/global_config.js index 0d93d7367..22b5b24c7 100644 --- a/lib/global_config.js +++ b/lib/global_config.js @@ -145,28 +145,3 @@ const rest = { HTTPS_PROTOCOL: 'https' }; exports.rest = rest; - -let customClientEnvironment = {}; - -/** - * Updates the value of the 'customClientEnvironment' parameter. - * - * @param {boolean} value - */ -exports.setCustomClientEnvironment = function (value) -{ - // validate input - Errors.assertInternal(Util.isObject(value)); - - customClientEnvironment = value; -}; - -/** - * Returns the value of the 'customClientEnvironment' parameter. - * - * @returns {boolean} - */ -exports.getCustomClientEnvironment = function () -{ - return customClientEnvironment; -}; \ No newline at end of file From f066fa9c68e5c0205ad81779c81a311037936fb3 Mon Sep 17 00:00:00 2001 From: Andrew Page Date: Fri, 3 Dec 2021 17:15:33 -0500 Subject: [PATCH 3/8] pass application to SF API --- lib/services/sf.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/services/sf.js b/lib/services/sf.js index d483613e7..60b2723bf 100644 --- a/lib/services/sf.js +++ b/lib/services/sf.js @@ -1082,17 +1082,17 @@ StateConnecting.prototype.continue = function () CLIENT_APP_NAME: this.connectionConfig.getClientApplication() }; - // if we have some information about the client environment, add it as well - var clientEnvironment = this.connectionConfig.getClientEnvironment(); - if (Util.isObject(clientEnvironment)) - { + // If we have some information about the client environment, add it as well + var clientEnvironment = this.connectionConfig.getClientEnvironment() || {}; + var clientApplication = this.connectionConfig.getClientApplication(); + if (Util.isString(clientApplication)) { + clientEnvironment["APPLICATION"] = clientApplication; + } + if (Object.keys(clientEnvironment).length > 0) { clientInfo.CLIENT_ENVIRONMENT = clientEnvironment; } - var sessionParameters = - { - SESSION_PARAMETERS: {} - }; + var sessionParameters = { SESSION_PARAMETERS: {} }; if (Util.exists(this.connectionConfig.getClientSessionKeepAlive())) { From db351980c2943e54edceb667e1792ce6a51ac04d Mon Sep 17 00:00:00 2001 From: Ernest Cheng Date: Tue, 1 Feb 2022 07:39:05 +0800 Subject: [PATCH 4/8] pass in describe only --- lib/connection/statement.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/lib/connection/statement.js b/lib/connection/statement.js index c1f6ee0a4..fee786b75 100644 --- a/lib/connection/statement.js +++ b/lib/connection/statement.js @@ -299,6 +299,13 @@ function createContextPreExec( ErrorCodes.ERR_CONN_EXEC_STMT_INVALID_INTERNAL); } + // if a describeOnly option is specified, make sure it's boolean + if (Util.exists(statementOptions.describeOnly)) + { + Errors.checkArgumentValid(Util.isBoolean(statementOptions.describeOnly), + ErrorCodes.ERR_CONN_EXEC_STMT_INVALID_OPTIONS); + } + // create a statement context var statementContext = createStatementContext(); @@ -325,6 +332,12 @@ function createContextPreExec( statementContext.internal = statementOptions.internal; } + // if the describeOnly flag is specified, add it to the statement context + if(Util.exists(statementOptions.describeOnly)) + { + statementContext.describeOnly = statementOptions.describeOnly; + } + // validate non-user-specified arguments Errors.assertInternal(Util.isObject(services)); Errors.assertInternal(Util.isObject(connectionConfig)); @@ -1121,6 +1134,12 @@ function sendRequestPreExec(statementContext, onResultAvailable) json.isInternal = statementContext.internal; } + // include statement parameters if a value was specified + if (Util.exists(statementContext.describeOnly)) + { + json.describeOnly = statementContext.describeOnly; + } + // use the snowflake service to issue the request sendSfRequest(statementContext, { From f6c594f8b2fb49bbf45cc03cb5a122651c03e129 Mon Sep 17 00:00:00 2001 From: Andrew Page Date: Mon, 17 Oct 2022 12:44:01 -0700 Subject: [PATCH 5/8] add clientApplication to arg list --- lib/authentication/authentication.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/authentication/authentication.js b/lib/authentication/authentication.js index 08c3dff8a..d2c24088b 100644 --- a/lib/authentication/authentication.js +++ b/lib/authentication/authentication.js @@ -37,6 +37,7 @@ exports.formAuthJSON = function formAuthJSON( username, clientName, clientVersion, + clientApplication, clientEnv ) { From c7ddc07783bbe07b2fd1634a99b72e496d07c49e Mon Sep 17 00:00:00 2001 From: Andrew Page Date: Mon, 17 Oct 2022 12:46:01 -0700 Subject: [PATCH 6/8] pass clientApplication in to formAuthJSON --- lib/authentication/authentication.js | 4 ++-- lib/connection/connection.js | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/authentication/authentication.js b/lib/authentication/authentication.js index d2c24088b..bc7ffbb4a 100644 --- a/lib/authentication/authentication.js +++ b/lib/authentication/authentication.js @@ -26,8 +26,8 @@ exports.authenticationTypes = authenticationTypes; * @param {String} username * @param {String} clientName * @param {String} clientVersion - * @param clientApplication * @param {Object} clientEnv + * @param {String} clientApplication * * @returns {JSON} */ @@ -37,8 +37,8 @@ exports.formAuthJSON = function formAuthJSON( username, clientName, clientVersion, + clientEnv, clientApplication, - clientEnv ) { var body = diff --git a/lib/connection/connection.js b/lib/connection/connection.js index 8f79fbfc1..cc7674ac3 100644 --- a/lib/connection/connection.js +++ b/lib/connection/connection.js @@ -209,7 +209,8 @@ function Connection(context) connectionConfig.username, connectionConfig.getClientName(), connectionConfig.getClientVersion(), - connectionConfig.getClientEnvironment()); + connectionConfig.getClientEnvironment(), + connectionConfig.getClientApplication()); // Update JSON body with the authentication values auth.updateBody(body); @@ -271,7 +272,8 @@ function Connection(context) connectionConfig.username, connectionConfig.getClientName(), connectionConfig.getClientVersion(), - connectionConfig.getClientEnvironment()); + connectionConfig.getClientEnvironment(), + connectionConfig.getClientApplication()); // Update JSON body with the authentication values auth.updateBody(body); From 00a5d5fe70e8ed22dbad5999bece96a520f7bf5c Mon Sep 17 00:00:00 2001 From: Daishan Peng Date: Tue, 13 Dec 2022 12:19:13 -0700 Subject: [PATCH 7/8] Retry response timeout error --- lib/services/large_result_set.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/large_result_set.js b/lib/services/large_result_set.js index 62732ae63..cf259b3f0 100644 --- a/lib/services/large_result_set.js +++ b/lib/services/large_result_set.js @@ -26,7 +26,7 @@ function LargeResultSetService(connectionConfig, httpClient) // Note: 403's are retried because of a bug in S3/Blob return Util.isRetryableHttpError( response, true // retry HTTP 403 - ) || err && (err.code === "ECONNRESET" || err.code === 'ETIMEDOUT'); + ) || err && (err.code === "ECONNRESET" || err.code === 'ETIMEDOUT' || err.name === 'ResponseTimeoutError'); } /** From 2b0e85f36ab8ec229dc3cf5ceda39ffed62d5b94 Mon Sep 17 00:00:00 2001 From: Daishan Peng Date: Tue, 13 Dec 2022 13:22:19 -0700 Subject: [PATCH 8/8] Retry on ConnectionTimeoutError --- lib/services/large_result_set.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/large_result_set.js b/lib/services/large_result_set.js index cf259b3f0..c726e26f1 100644 --- a/lib/services/large_result_set.js +++ b/lib/services/large_result_set.js @@ -26,7 +26,7 @@ function LargeResultSetService(connectionConfig, httpClient) // Note: 403's are retried because of a bug in S3/Blob return Util.isRetryableHttpError( response, true // retry HTTP 403 - ) || err && (err.code === "ECONNRESET" || err.code === 'ETIMEDOUT' || err.name === 'ResponseTimeoutError'); + ) || err && (err.code === "ECONNRESET" || err.code === 'ETIMEDOUT' || err.name === 'ResponseTimeoutError' || err.name === 'ConnectionTimeoutError'); } /**