[#9418] fix(iceberg): inject GCS FileIO token from gcs-service-account-file - #12962
Conversation
…account-file Iceberg's GCSFileIO ignores gcs-service-account-file; mint gcs.oauth2.token at catalog load so server-side FileIO works from catalog properties alone. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…load Co-authored-by: Cursor <cursoragent@cursor.com>
| */ | ||
| @VisibleForTesting | ||
| static void applyGcsServiceAccountCredentials(Map<String, String> properties) { | ||
| String serviceAccountFile = properties.get(GCSProperties.GRAVITINO_GCS_SERVICE_ACCOUNT_FILE); |
There was a problem hiding this comment.
How to refresh the GCP access token? I will recommend that we add a expire hook for the catalog cache.
You can recreate the catalog before the access token expiration.
There was a problem hiding this comment.
Good catch — addressed in the latest commit.
IRC catalog wrappers now keep the minted gcs.oauth2.token-expires-at on IcebergConfig, and IcebergCatalogWrapperManager uses a Caffeine Expiry that caps expire-after-access by token expiry minus a 5-minute buffer. When the entry is evicted, the next request recreates the catalog and remints the token.
There was a problem hiding this comment.
Follow-up: we dropped the catalog-cache expiry approach.
IRC catalogWrapperCache is back to plain expireAfterAccess. Token refresh now lives in a separate GcsAccessTokenCache + GravitinoGCSFileIO, which remints from gcs-service-account-file when the cached token is about to expire — independent of catalog-wrapper eviction.
There was a problem hiding this comment.
You can't. Because you can't handle ResolvingFileIO cases.ResolvingFile will use origin GCSFileIO.
…cache expiry Cap catalog-wrapper cache lifetime by gcs.oauth2.token-expires-at so hot catalogs recreate and remint OAuth2 tokens before they expire. Co-authored-by: Cursor <cursoragent@cursor.com>
…d FileIO Keep IRC catalog expire-after-access unchanged. Remint OAuth2 tokens in GcsAccessTokenCache and GravitinoGCSFileIO so credential lifetime is independent of catalog-wrapper eviction. Co-authored-by: Cursor <cursoragent@cursor.com>
…logUtil Co-authored-by: Cursor <cursoragent@cursor.com>
Rewrite GravitinoGCSFileIO to the Iceberg GCSFileIO class name via a string constant so iceberg-rest-server does not need iceberg-gcp at compile time. Co-authored-by: Cursor <cursoragent@cursor.com>
…tests Co-authored-by: Cursor <cursoragent@cursor.com>
Code Coverage Report
Files
|
Resolve IcebergConstants conflict by keeping both ADLS token-provider constants from main and GCS OAuth2 token constants from this branch. Co-authored-by: Cursor <cursoragent@cursor.com>
…expiry Mint gcs.oauth2.token from gcs-service-account-file and expire IRC catalog wrappers before token expiry, instead of a dedicated GravitinoGCSFileIO cache. Co-authored-by: Cursor <cursoragent@cursor.com>
roryqi
left a comment
There was a problem hiding this comment.
No better solution. If GCS FileIO API provides better solution, we should refactor the code.
…er close Caffeine may retire a missed cache entry asynchronously after close(), so asserting pool size immediately can flake with size 1. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
|
Do u test the refresh case? |
…account-file (apache#12962) Iceberg's `GCSFileIO` does not understand Gravitino's `gcs-service-account-file`. When that property is set, load the service account at catalog initialization and inject Iceberg `gcs.oauth2.token` / `gcs.oauth2.token-expires-at` so server-side FileIO can authenticate (same property-injection style as S3/OSS/ADLS key mapping). Also update GCS docs that previously required `GOOGLE_APPLICATION_CREDENTIALS` even when the catalog property was set. `gcs-service-account-file` reached the credential provider (vending worked) but not FileIO. Table create wrote metadata with Application Default Credentials and failed with 401 unless `GOOGLE_APPLICATION_CREDENTIALS` was set on the process. Fix: apache#9418 - Configuring `gcs-service-account-file` is sufficient for Iceberg GCS FileIO; `GOOGLE_APPLICATION_CREDENTIALS` is only a fallback when the property is unset. - No new public API or property keys. ``` ./gradlew :iceberg:iceberg-common:test --tests org.apache.gravitino.iceberg.common.utils.TestIcebergCatalogUtil -PskipITs ``` Made with [Cursor](https://cursor.com) --------- Co-authored-by: Cursor <cursoragent@cursor.com>
…account-file (apache#12962) Iceberg's `GCSFileIO` does not understand Gravitino's `gcs-service-account-file`. When that property is set, load the service account at catalog initialization and inject Iceberg `gcs.oauth2.token` / `gcs.oauth2.token-expires-at` so server-side FileIO can authenticate (same property-injection style as S3/OSS/ADLS key mapping). Also update GCS docs that previously required `GOOGLE_APPLICATION_CREDENTIALS` even when the catalog property was set. `gcs-service-account-file` reached the credential provider (vending worked) but not FileIO. Table create wrote metadata with Application Default Credentials and failed with 401 unless `GOOGLE_APPLICATION_CREDENTIALS` was set on the process. Fix: apache#9418 - Configuring `gcs-service-account-file` is sufficient for Iceberg GCS FileIO; `GOOGLE_APPLICATION_CREDENTIALS` is only a fallback when the property is unset. - No new public API or property keys. ``` ./gradlew :iceberg:iceberg-common:test --tests org.apache.gravitino.iceberg.common.utils.TestIcebergCatalogUtil -PskipITs ``` Made with [Cursor](https://cursor.com) --------- Co-authored-by: Cursor <cursoragent@cursor.com>
…account-file (apache#12962) Iceberg's `GCSFileIO` does not understand Gravitino's `gcs-service-account-file`. When that property is set, load the service account at catalog initialization and inject Iceberg `gcs.oauth2.token` / `gcs.oauth2.token-expires-at` so server-side FileIO can authenticate (same property-injection style as S3/OSS/ADLS key mapping). Also update GCS docs that previously required `GOOGLE_APPLICATION_CREDENTIALS` even when the catalog property was set. `gcs-service-account-file` reached the credential provider (vending worked) but not FileIO. Table create wrote metadata with Application Default Credentials and failed with 401 unless `GOOGLE_APPLICATION_CREDENTIALS` was set on the process. Fix: apache#9418 - Configuring `gcs-service-account-file` is sufficient for Iceberg GCS FileIO; `GOOGLE_APPLICATION_CREDENTIALS` is only a fallback when the property is unset. - No new public API or property keys. ``` ./gradlew :iceberg:iceberg-common:test --tests org.apache.gravitino.iceberg.common.utils.TestIcebergCatalogUtil -PskipITs ``` Made with [Cursor](https://cursor.com) --------- Co-authored-by: Cursor <cursoragent@cursor.com>
…t-file (#12962) Iceberg's `GCSFileIO` does not understand Gravitino's `gcs-service-account-file`. When that property is set, load the service account at catalog initialization and inject Iceberg `gcs.oauth2.token` / `gcs.oauth2.token-expires-at` so server-side FileIO can authenticate (same property-injection style as S3/OSS/ADLS key mapping). Also update GCS docs that previously required `GOOGLE_APPLICATION_CREDENTIALS` even when the catalog property was set. `gcs-service-account-file` reached the credential provider (vending worked) but not FileIO. Table create wrote metadata with Application Default Credentials and failed with 401 unless `GOOGLE_APPLICATION_CREDENTIALS` was set on the process. Fix: #9418 - Configuring `gcs-service-account-file` is sufficient for Iceberg GCS FileIO; `GOOGLE_APPLICATION_CREDENTIALS` is only a fallback when the property is unset. - No new public API or property keys. ``` ./gradlew :iceberg:iceberg-common:test --tests org.apache.gravitino.iceberg.common.utils.TestIcebergCatalogUtil -PskipITs ``` Made with [Cursor](https://cursor.com) --------- Co-authored-by: Cursor <cursoragent@cursor.com>


What changes were proposed in this pull request?
Iceberg's
GCSFileIOdoes not understand Gravitino'sgcs-service-account-file.When that property is set, load the service account at catalog initialization and
inject Iceberg
gcs.oauth2.token/gcs.oauth2.token-expires-atso server-sideFileIO can authenticate (same property-injection style as S3/OSS/ADLS key mapping).
Also update GCS docs that previously required
GOOGLE_APPLICATION_CREDENTIALSeven when the catalog property was set.
Why are the changes needed?
gcs-service-account-filereached the credential provider (vending worked) but notFileIO. Table create wrote metadata with Application Default Credentials and failed
with 401 unless
GOOGLE_APPLICATION_CREDENTIALSwas set on the process.Fix: #9418
Does this PR introduce any user-facing change?
gcs-service-account-fileis sufficient for Iceberg GCS FileIO;GOOGLE_APPLICATION_CREDENTIALSis only a fallback when the property is unset.How was this patch tested?
Made with Cursor