Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SNOW-1853185: Pom test #2098

Closed
wants to merge 50 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
a657244
SNOW-1853185: Base for OktaWiremockIT
sfc-gh-fpawlowski Feb 4, 2025
7cc2b33
SNOW-1853185: OktaWiremockIT with working endpoint
sfc-gh-fpawlowski Feb 5, 2025
23fd381
SNOW-1853185: OktaWiremockIT with working endpoint
sfc-gh-fpawlowski Feb 5, 2025
6ae4b1f
SNOW-1853185: OktaWiremockIT with port inclusion comments
sfc-gh-fpawlowski Feb 5, 2025
7f38b4a
Merge branch 'SNOW-1853185-jdbc-driver-v-3-16-native-okta-http-retry'…
sfc-gh-fpawlowski Feb 5, 2025
fcc5e08
Update SnowflakeDriverIT.java
sfc-gh-fpawlowski Feb 5, 2025
adf022c
Merge remote-tracking branch 'origin/SNOW-1853185-JDBC-Driver-v3.16-N…
sfc-gh-fpawlowski Feb 5, 2025
110faf0
SNOW-1853185: Reverted test commit
sfc-gh-fpawlowski Feb 5, 2025
0ab28ca
SNOW-1853185: Wiremock working test
sfc-gh-fpawlowski Feb 5, 2025
675a045
SNOW-1853185: Wiremock files structure organized
sfc-gh-fpawlowski Feb 5, 2025
f553892
SNOW-1853185: Wiremock files read from file
sfc-gh-fpawlowski Feb 5, 2025
ffabd53
SNOW-1853185: Rest request refactored
sfc-gh-fpawlowski Feb 6, 2025
4a54ab5
SNOW-1853185: Retry context manager added
sfc-gh-fpawlowski Feb 7, 2025
d393961
SNOW-1853185: Retry manager called
sfc-gh-fpawlowski Feb 9, 2025
4b60e61
Merge branch 'master' into SNOW-1853185-JDBC-Driver-v3.16-Native-Okta…
sfc-gh-fpawlowski Feb 9, 2025
c6daa3d
SNOW-1853185: Revert renaming isSocketTimeoutNoBackoff because of fai…
sfc-gh-fpawlowski Feb 9, 2025
5cb1272
SNOW-1853185: Added missing dependencies to tests
sfc-gh-fpawlowski Feb 9, 2025
c0c6389
SNOW-1853185: Javadoc fixes
sfc-gh-fpawlowski Feb 9, 2025
e9e964d
SNOW-1853185: Javadoc fixes
sfc-gh-fpawlowski Feb 9, 2025
d049d2c
SNOW-1853185: Formatting run
sfc-gh-fpawlowski Feb 9, 2025
73095ff
SNOW-1853185: Changed test to check time between calls to okta
sfc-gh-fpawlowski Feb 9, 2025
9327ce9
SNOW-1853185: Made tests check 429 is waited. Added deserialization
sfc-gh-fpawlowski Feb 10, 2025
d6dbcf5
SNOW-1853185: Code formatted
sfc-gh-fpawlowski Feb 10, 2025
0423238
SNOW-1853185: Code formatted
sfc-gh-fpawlowski Feb 10, 2025
fddcf10
SNOW-1853185: TODOs removed
sfc-gh-fpawlowski Feb 10, 2025
2bae032
SNOW-1853185: Replaced .* imports with specific
sfc-gh-fpawlowski Feb 10, 2025
d05b8c6
SNOW-1853185: Formatted
sfc-gh-fpawlowski Feb 10, 2025
1c66ff4
Merge branch 'master' into SNOW-1853185-JDBC-Driver-v3.16-Native-Okta…
sfc-gh-fpawlowski Feb 11, 2025
478a360
SNOW-1853185: Replaced custom Exception type with ThrowingCallable
sfc-gh-fpawlowski Feb 11, 2025
e3b8e2f
SNOW-1853185: Code cleanup - added docs, improved visibility and argu…
sfc-gh-fpawlowski Feb 11, 2025
780f97a
SNOW-1853185: Added javadocs and comments from PR
sfc-gh-fpawlowski Feb 11, 2025
678970f
SNOW-1853185: ThrowingFunction added and RetryManager migrated to use it
sfc-gh-fpawlowski Feb 12, 2025
0782b70
SNOW-1853185: Renamed RetryContextManager to RetryContext
sfc-gh-fpawlowski Feb 12, 2025
f4506b3
SNOW-1853185: visibility limited of retrycontext
sfc-gh-fpawlowski Feb 12, 2025
0d8df42
SNOW-1853185: Changed assertion types to hamcrest
sfc-gh-fpawlowski Feb 12, 2025
1e3c87b
SNOW-1853185: Implemented reading files using BufferedReader
sfc-gh-fpawlowski Feb 12, 2025
f3b3d19
SNOW-1853185: Test pom.xml - version moved to properties
sfc-gh-fpawlowski Feb 12, 2025
80f8ceb
SNOW-1853185: Code formatted
sfc-gh-fpawlowski Feb 12, 2025
1fa8914
SNOW-1853185: Code formatted
sfc-gh-fpawlowski Feb 12, 2025
88375a3
SNOW-1853185: Merged master
sfc-gh-fpawlowski Feb 17, 2025
0e730b2
SNOW-1853185: Unified federated auth flow methods to make them all ac…
sfc-gh-fpawlowski Feb 17, 2025
f8aeb21
SNOW-1853185: Pom test
sfc-gh-fpawlowski Feb 26, 2025
b46061a
Revert "SNOW-1853185: Pom test"
sfc-gh-fpawlowski Feb 27, 2025
90f14bd
merged master
sfc-gh-fpawlowski Feb 27, 2025
fd7ede3
Merge branch 'master' into fpawlowski/pom-xml-test-wiremock
sfc-gh-fpawlowski Feb 27, 2025
bc35ce9
SNOW-1853185: Added missing dependency
sfc-gh-fpawlowski Feb 27, 2025
1ef1bc5
SNOW-1853185: Changed httpclient dependency
sfc-gh-fpawlowski Mar 1, 2025
dc1f1fe
SNOW-1853185: charset in new version of utils
sfc-gh-fpawlowski Mar 1, 2025
509f1ac
SNOW-1853185: Disabled tests to check connection issues source
sfc-gh-fpawlowski Mar 2, 2025
ad6f2ab
SNOW-1853185: Disabled tests to check connection issues source
sfc-gh-fpawlowski Mar 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions TestOnly/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<surefire.version>3.5.1</surefire.version>
<mockito.version>3.5.6</mockito.version>
<netty.version>4.1.118.Final</netty.version>
<apache.httpclient.version>4.5.14</apache.httpclient.version>
<shadeBase>net.snowflake.client.jdbc.internal</shadeBase>
</properties>

Expand All @@ -31,6 +32,11 @@
<artifactId>netty-common</artifactId>
<version>${netty.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${apache.httpclient.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-buffer</artifactId>
Expand Down
101 changes: 95 additions & 6 deletions src/main/java/net/snowflake/client/core/HttpUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import javax.net.ssl.TrustManager;
import net.snowflake.client.jdbc.ErrorCode;
import net.snowflake.client.jdbc.RestRequest;
import net.snowflake.client.jdbc.RetryContext;
import net.snowflake.client.jdbc.SnowflakeDriver;
import net.snowflake.client.jdbc.SnowflakeSQLException;
import net.snowflake.client.jdbc.SnowflakeUtil;
Expand Down Expand Up @@ -618,7 +619,8 @@ static String executeRequestWithoutCookies(
true, // guid? (do we need this?)
false, // no retry on HTTP 403
getHttpClient(ocspAndProxyKey),
new ExecTimeTelemetryData());
new ExecTimeTelemetryData(),
null);
}

/**
Expand All @@ -642,6 +644,39 @@ public static String executeGeneralRequest(
int retryCount,
HttpClientSettingsKey ocspAndProxyAndGzipKey)
throws SnowflakeSQLException, IOException {
return executeGeneralRequest(
httpRequest,
retryTimeout,
authTimeout,
socketTimeout,
retryCount,
ocspAndProxyAndGzipKey,
null);
}

/**
* Executes an HTTP request for Snowflake.
*
* @param httpRequest HttpRequestBase
* @param retryTimeout retry timeout
* @param authTimeout authenticator specific timeout
* @param socketTimeout socket timeout (in ms)
* @param retryCount retry count for the request
* @param ocspAndProxyAndGzipKey OCSP mode and proxy settings for httpclient
* @param retryContext RetryContext used to customize retry handling functionality
* @return response
* @throws SnowflakeSQLException if Snowflake error occurs
* @throws IOException raises if a general IO error occurs
*/
public static String executeGeneralRequest(
HttpRequestBase httpRequest,
int retryTimeout,
int authTimeout,
int socketTimeout,
int retryCount,
HttpClientSettingsKey ocspAndProxyAndGzipKey,
RetryContext retryContext)
throws SnowflakeSQLException, IOException {
logger.debug("Executing general request");
return executeRequest(
httpRequest,
Expand All @@ -654,7 +689,8 @@ public static String executeGeneralRequest(
false, // no retry parameter
false, // no retry on HTTP 403
ocspAndProxyAndGzipKey,
new ExecTimeTelemetryData());
new ExecTimeTelemetryData(),
retryContext);
}

/**
Expand Down Expand Up @@ -692,7 +728,8 @@ public static String executeGeneralRequest(
true, // include request GUID
false, // no retry on HTTP 403
httpClient,
new ExecTimeTelemetryData());
new ExecTimeTelemetryData(),
null);
}

/**
Expand Down Expand Up @@ -726,6 +763,54 @@ public static String executeRequest(
HttpClientSettingsKey ocspAndProxyKey,
ExecTimeTelemetryData execTimeData)
throws SnowflakeSQLException, IOException {
return executeRequest(
httpRequest,
retryTimeout,
authTimeout,
socketTimeout,
maxRetries,
injectSocketTimeout,
canceling,
includeRetryParameters,
retryOnHTTP403,
ocspAndProxyKey,
execTimeData,
null);
}

/**
* Executes an HTTP request for Snowflake.
*
* @param httpRequest HttpRequestBase
* @param retryTimeout retry timeout
* @param authTimeout authenticator timeout
* @param socketTimeout socket timeout (in ms)
* @param maxRetries retry count for the request
* @param injectSocketTimeout injecting socket timeout
* @param canceling canceling?
* @param includeRetryParameters whether to include retry parameters in retried requests
* @param retryOnHTTP403 whether to retry on HTTP 403 or not
* @param ocspAndProxyKey OCSP mode and proxy settings for httpclient
* @param execTimeData query execution time telemetry data object
* @param retryContext RetryContext used to customize retry handling functionality
* @return response
* @throws SnowflakeSQLException if Snowflake error occurs
* @throws IOException raises if a general IO error occurs
*/
public static String executeRequest(
HttpRequestBase httpRequest,
int retryTimeout,
int authTimeout,
int socketTimeout,
int maxRetries,
int injectSocketTimeout,
AtomicBoolean canceling,
boolean includeRetryParameters,
boolean retryOnHTTP403,
HttpClientSettingsKey ocspAndProxyKey,
ExecTimeTelemetryData execTimeData,
RetryContext retryContext)
throws SnowflakeSQLException, IOException {
boolean ocspEnabled = !(ocspAndProxyKey.getOcspMode().equals(OCSPMode.DISABLE_OCSP_CHECKS));
logger.debug("Executing request with OCSP enabled: {}", ocspEnabled);
execTimeData.setOCSPStatus(ocspEnabled);
Expand All @@ -742,7 +827,8 @@ public static String executeRequest(
true, // include request GUID
retryOnHTTP403,
getHttpClient(ocspAndProxyKey),
execTimeData);
execTimeData,
retryContext);
}

/**
Expand All @@ -764,6 +850,7 @@ public static String executeRequest(
* @param includeRequestGuid whether to include request_guid
* @param retryOnHTTP403 whether to retry on HTTP 403
* @param httpClient client object used to communicate with other machine
* @param retryContext RetryContext used to customize retry handling functionality
* @return response in String
* @throws SnowflakeSQLException if Snowflake error occurs
* @throws IOException raises if a general IO error occurs
Expand All @@ -781,7 +868,8 @@ private static String executeRequestInternal(
boolean includeRequestGuid,
boolean retryOnHTTP403,
CloseableHttpClient httpClient,
ExecTimeTelemetryData execTimeData)
ExecTimeTelemetryData execTimeData,
RetryContext retryContext)
throws SnowflakeSQLException, IOException {
// HttpRequest.toString() contains request URI. Scrub any credentials, if
// present, before logging
Expand Down Expand Up @@ -815,7 +903,8 @@ private static String executeRequestInternal(
includeRetryParameters,
includeRequestGuid,
retryOnHTTP403,
execTimeData);
execTimeData,
retryContext);
if (logger.isDebugEnabled() && stopwatch != null) {
stopwatch.stop();
}
Expand Down
45 changes: 33 additions & 12 deletions src/main/java/net/snowflake/client/core/SessionUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import net.snowflake.client.core.auth.oauth.OAuthAccessTokenProviderFactory;
import net.snowflake.client.core.auth.oauth.TokenResponseDTO;
import net.snowflake.client.jdbc.ErrorCode;
import net.snowflake.client.jdbc.RetryContext;
import net.snowflake.client.jdbc.SnowflakeDriver;
import net.snowflake.client.jdbc.SnowflakeReauthenticationRequest;
import net.snowflake.client.jdbc.SnowflakeSQLException;
Expand All @@ -48,6 +49,7 @@
import net.snowflake.client.log.SFLoggerFactory;
import net.snowflake.client.util.SecretDetector;
import net.snowflake.client.util.Stopwatch;
import net.snowflake.client.util.ThrowingCallable;
import net.snowflake.common.core.SqlState;
import org.apache.http.HttpHeaders;
import org.apache.http.client.config.RequestConfig;
Expand All @@ -74,6 +76,7 @@ public class SessionUtil {
// Request path
private static final String SF_PATH_LOGIN_REQUEST = "/session/v1/login-request";
private static final String SF_PATH_TOKEN_REQUEST = "/session/token-request";
private static final String SF_PATH_OKTA_REQUEST_SUFFIX = "/api/v1/authn";
public static final String SF_PATH_AUTHENTICATOR_REQUEST = "/session/authenticator-request";
public static final String SF_PATH_CONSOLE_LOGIN_REQUEST = "/console/login";

Expand Down Expand Up @@ -1340,16 +1343,33 @@ static void closeSession(SFLoginInput loginInput) throws SFException, SnowflakeS
*
* @param loginInput Login Info for the request
* @param ssoUrl URL to use for SSO
* @param oneTimeToken The token used for SSO
* @param oneTimeTokenSupplier The function returning token used for SSO
* @return The response in HTML form
* @throws SnowflakeSQLException Will be thrown if the destination URL in the SAML assertion does
* not match
*/
private static String federatedFlowStep4(
SFLoginInput loginInput, String ssoUrl, String oneTimeToken) throws SnowflakeSQLException {
SFLoginInput loginInput,
String ssoUrl,
ThrowingCallable<String, SnowflakeSQLException> oneTimeTokenSupplier)
throws SnowflakeSQLException {
String oneTimeToken = oneTimeTokenSupplier.call();
String responseHtml = "";

try {
RetryContext retryWithNewOTTManager =
new RetryContext(RetryContext.RetryHook.ALWAYS_BEFORE_RETRY);
retryWithNewOTTManager.registerRetryCallback(
(HttpRequestBase retrieveSamlRequest) -> {
try {
String newOneTimeToken = oneTimeTokenSupplier.call();
prepareFederatedFlowStep4Request(retrieveSamlRequest, ssoUrl, newOneTimeToken);
} catch (Exception e) {
throw new RuntimeException(e);
}

return null;
});

HttpGet httpGet = new HttpGet();
prepareFederatedFlowStep4Request(httpGet, ssoUrl, oneTimeToken);
Expand Down Expand Up @@ -1481,7 +1501,8 @@ private static JsonNode federatedFlowStep1(SFLoginInput loginInput) throws Snowf
JsonNode dataNode = null;
try {
StringEntity requestInput = prepareFederatedFlowStep1RequestInput(loginInput);
HttpPost postRequest = prepareFederatedFlowStep1PostRequest(loginInput, requestInput);
HttpPost postRequest = new HttpPost();
prepareFederatedFlowStep1PostRequest(postRequest, loginInput, requestInput);

final String gsResponse =
HttpUtil.executeGeneralRequest(
Expand Down Expand Up @@ -1559,8 +1580,10 @@ private static String getSamlResponseUsingOkta(SFLoginInput loginInput)
String tokenUrl = dataNode.path("tokenUrl").asText();
String ssoUrl = dataNode.path("ssoUrl").asText();
federatedFlowStep2(loginInput, tokenUrl, ssoUrl);
final String oneTimeToken = federatedFlowStep3(loginInput, tokenUrl);
return federatedFlowStep4(loginInput, ssoUrl, oneTimeToken);
ThrowingCallable<String, SnowflakeSQLException> oneTimeTokenSupplier =
() -> federatedFlowStep3(loginInput, tokenUrl);

return federatedFlowStep4(loginInput, ssoUrl, oneTimeTokenSupplier);
} catch (SnowflakeSQLException ex) {
// This error gets thrown if the okta request encountered a retry-able error that
// requires getting a new one-time token.
Expand Down Expand Up @@ -1889,7 +1912,8 @@ public static boolean isNewRetryStrategyRequest(HttpRequestBase request) {
if (requestPath != null) {
return requestPath.equals(SF_PATH_LOGIN_REQUEST)
|| requestPath.equals(SF_PATH_AUTHENTICATOR_REQUEST)
|| requestPath.equals(SF_PATH_TOKEN_REQUEST);
|| requestPath.equals(SF_PATH_TOKEN_REQUEST)
|| requestPath.contains(SF_PATH_OKTA_REQUEST_SUFFIX);
}
return false;
}
Expand All @@ -1899,25 +1923,22 @@ public static boolean isNewRetryStrategyRequest(HttpRequestBase request) {
*
* @param loginInput The login information for the request.
* @param inputData The JSON input data to include in the request.
* @return An {@link HttpPost} object ready to execute the federated flow request.
* @throws URISyntaxException If the constructed URI is invalid.
*/
private static HttpPost prepareFederatedFlowStep1PostRequest(
SFLoginInput loginInput, StringEntity inputData) throws URISyntaxException {
private static void prepareFederatedFlowStep1PostRequest(
HttpPost postRequest, SFLoginInput loginInput, StringEntity inputData) throws URISyntaxException {
URIBuilder fedUriBuilder = new URIBuilder(loginInput.getServerUrl());
// TODO: if loginInput.serverUrl contains port or additional segments - it will be ignored and
// overwritten here - to be fixed in SNOW-1922872
fedUriBuilder.setPath(SF_PATH_AUTHENTICATOR_REQUEST);
URI fedUrlUri = fedUriBuilder.build();
postRequest.setURI(fedUrlUri);

HttpPost postRequest = new HttpPost(fedUrlUri);
postRequest.setEntity(inputData);
postRequest.addHeader("accept", "application/json");

postRequest.addHeader(SF_HEADER_CLIENT_APP_ID, loginInput.getAppId());
postRequest.addHeader(SF_HEADER_CLIENT_APP_VERSION, loginInput.getAppVersion());

return postRequest;
}

/**
Expand Down
Loading
Loading