|
12 | 12 | import com.fasterxml.jackson.databind.ObjectMapper;
|
13 | 13 | import com.google.api.gax.paging.Page;
|
14 | 14 | import com.google.api.gax.rpc.FixedHeaderProvider;
|
| 15 | +import com.google.auth.oauth2.AccessToken; |
| 16 | +import com.google.auth.oauth2.GoogleCredentials; |
15 | 17 | import com.google.cloud.storage.Blob;
|
16 | 18 | import com.google.cloud.storage.BlobId;
|
17 | 19 | import com.google.cloud.storage.BlobInfo;
|
|
43 | 45 | import net.snowflake.client.core.ObjectMapperFactory;
|
44 | 46 | import net.snowflake.client.core.SFSession;
|
45 | 47 | import net.snowflake.client.core.SFSessionProperty;
|
| 48 | +import net.snowflake.client.core.SnowflakeJdbcInternalApi; |
46 | 49 | import net.snowflake.client.jdbc.ErrorCode;
|
47 | 50 | import net.snowflake.client.jdbc.FileBackedOutputStream;
|
48 | 51 | import net.snowflake.client.jdbc.MatDesc;
|
|
74 | 77 | * @author ppaulus
|
75 | 78 | */
|
76 | 79 | public class SnowflakeGCSClient implements SnowflakeStorageClient {
|
| 80 | + @SnowflakeJdbcInternalApi |
| 81 | + public static final String DISABLE_GCS_DEFAULT_CREDENTIALS_PROPERTY_NAME = |
| 82 | + "net.snowflake.jdbc.disableGcsDefaultCredentials"; |
| 83 | + |
77 | 84 | private static final String GCS_ENCRYPTIONDATAPROP = "encryptiondata";
|
78 | 85 | private static final String localFileSep = systemGetProperty("file.separator");
|
79 | 86 | private static final String GCS_METADATA_PREFIX = "x-goog-meta-";
|
@@ -1200,13 +1207,19 @@ private void setupGCSClient(
|
1200 | 1207 | try {
|
1201 | 1208 | String accessToken = (String) stage.getCredentials().get("GCS_ACCESS_TOKEN");
|
1202 | 1209 | if (accessToken != null) {
|
| 1210 | + // We are authenticated with an oauth access token. |
| 1211 | + StorageOptions.Builder builder = StorageOptions.newBuilder(); |
| 1212 | + if (areDisabledGcsDefaultCredentials(session)) { |
| 1213 | + logger.debug( |
| 1214 | + "Adding explicit credentials to avoid default credential lookup by the GCS client"); |
| 1215 | + builder.setCredentials(GoogleCredentials.create(new AccessToken(accessToken, null))); |
| 1216 | + } |
| 1217 | + |
1203 | 1218 | // Using GoogleCredential with access token will cause IllegalStateException when the token
|
1204 | 1219 | // is expired and trying to refresh, which cause error cannot be caught. Instead, set a
|
1205 | 1220 | // header so we can caught the error code.
|
1206 |
| - |
1207 |
| - // We are authenticated with an oauth access token. |
1208 | 1221 | this.gcsClient =
|
1209 |
| - StorageOptions.newBuilder() |
| 1222 | + builder |
1210 | 1223 | .setHeaderProvider(
|
1211 | 1224 | FixedHeaderProvider.create("Authorization", "Bearer " + accessToken))
|
1212 | 1225 | .build()
|
@@ -1234,6 +1247,12 @@ private void setupGCSClient(
|
1234 | 1247 | }
|
1235 | 1248 | }
|
1236 | 1249 |
|
| 1250 | + private static boolean areDisabledGcsDefaultCredentials(SFSession session) { |
| 1251 | + return session != null && session.getDisableGcsDefaultCredentials() |
| 1252 | + || SnowflakeUtil.convertSystemPropertyToBooleanValue( |
| 1253 | + DISABLE_GCS_DEFAULT_CREDENTIALS_PROPERTY_NAME, false); |
| 1254 | + } |
| 1255 | + |
1237 | 1256 | private static boolean isSuccessStatusCode(int code) {
|
1238 | 1257 | return code < 300 && code >= 200;
|
1239 | 1258 | }
|
|
0 commit comments