This is an automated email from the ASF dual-hosted git repository.

roryqi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git


The following commit(s) were added to refs/heads/main by this push:
     new 34556b6e6c [#9223] test(authz): Add GCP credential vending IT (#9222)
34556b6e6c is described below

commit 34556b6e6c197dc785d4611eb97199e15a473b2c
Author: Bharath Krishna <[email protected]>
AuthorDate: Sun Nov 23 22:22:37 2025 -0800

    [#9223] test(authz): Add GCP credential vending IT (#9222)
    
    ### What changes were proposed in this pull request?
    Add Google Cloud credential vending integration tests
    
    ### Why are the changes needed?
    Add IT for Google Cloud credential vending
    
    Fix: #9223
    
    ### Does this PR introduce _any_ user-facing change?
    No
    
    ### How was this patch tested?
    Integration tests
    ```
     gcloud auth login
     export GRAVITINO_TEST_CLOUD_IT=true && export 
GRAVITINO_GCS_BUCKET=<bucket> && export GRAVITINO_GCS_PATH_PREFIX=<path>&& 
./gradlew :iceberg:iceberg-rest-server:test --tests 
"*IcebergRESTGCSTokenAuthorizationIT" --info
    ```
---
 ... IcebergRESTCloudTokenAuthorizationBaseIT.java} | 168 +++++++---------
 .../test/IcebergRESTGCSTokenAuthorizationIT.java   | 119 +++++++++++
 .../test/IcebergRESTS3TokenAuthorizationIT.java    | 224 +--------------------
 3 files changed, 196 insertions(+), 315 deletions(-)

diff --git 
a/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/IcebergRESTS3TokenAuthorizationIT.java
 
b/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/IcebergRESTCloudTokenAuthorizationBaseIT.java
similarity index 69%
copy from 
iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/IcebergRESTS3TokenAuthorizationIT.java
copy to 
iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/IcebergRESTCloudTokenAuthorizationBaseIT.java
index 1f3edd453c..c49cf9e8df 100644
--- 
a/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/IcebergRESTS3TokenAuthorizationIT.java
+++ 
b/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/IcebergRESTCloudTokenAuthorizationBaseIT.java
@@ -20,7 +20,6 @@
 package org.apache.gravitino.iceberg.integration.test;
 
 import com.google.common.collect.ImmutableList;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -35,59 +34,24 @@ import org.apache.gravitino.authorization.Owner;
 import org.apache.gravitino.authorization.Privileges;
 import org.apache.gravitino.authorization.SecurableObject;
 import org.apache.gravitino.authorization.SecurableObjects;
-import org.apache.gravitino.catalog.lakehouse.iceberg.IcebergConstants;
-import org.apache.gravitino.credential.CredentialConstants;
-import org.apache.gravitino.credential.S3TokenCredential;
-import org.apache.gravitino.integration.test.util.BaseIT;
-import org.apache.gravitino.integration.test.util.DownloaderUtils;
 import org.apache.gravitino.integration.test.util.ITUtils;
-import org.apache.gravitino.storage.S3Properties;
 import org.apache.iceberg.exceptions.ForbiddenException;
 import org.apache.spark.SparkException;
 import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
-import org.junit.platform.commons.util.StringUtils;
 
+/**
+ * Abstract base class for Iceberg REST credential vending integration tests 
with cloud storage
+ * providers (S3, GCS, Azure, etc.).
+ *
+ * <p>This class contains all common test logic and helper methods for testing 
privilege-based
+ * credential vending. Subclasses implement cloud-specific configuration and 
setup.
+ */
 @SuppressWarnings("FormatStringAnnotation")
-@EnabledIfEnvironmentVariable(named = "GRAVITINO_TEST_CLOUD_IT", matches = 
"true")
-public class IcebergRESTS3TokenAuthorizationIT extends IcebergAuthorizationIT {
-
-  private static final String SCHEMA_NAME = "schema";
-  private String s3Warehouse;
-  private String accessKey;
-  private String secretKey;
-  private String region;
-  private String roleArn;
-  private String externalId;
-
-  @BeforeAll
-  public void startIntegrationTest() throws Exception {
-    this.s3Warehouse =
-        String.format(
-            "s3://%s/test1", 
System.getenv().getOrDefault("GRAVITINO_S3_BUCKET", "{BUCKET_NAME}"));
-    this.accessKey = System.getenv().getOrDefault("GRAVITINO_S3_ACCESS_KEY", 
"{ACCESS_KEY}");
-    this.secretKey = System.getenv().getOrDefault("GRAVITINO_S3_SECRET_KEY", 
"{SECRET_KEY}");
-    this.region = System.getenv().getOrDefault("GRAVITINO_S3_REGION", 
"ap-southeast-2");
-    this.roleArn = System.getenv().getOrDefault("GRAVITINO_S3_ROLE_ARN", 
"{ROLE_ARN}");
-    this.externalId = System.getenv().getOrDefault("GRAVITINO_S3_EXTERNAL_ID", 
"");
-
-    super.startIntegrationTest();
-
-    catalogClientWithAllPrivilege.asSchemas().createSchema(SCHEMA_NAME, 
"test", new HashMap<>());
+public abstract class IcebergRESTCloudTokenAuthorizationBaseIT extends 
IcebergAuthorizationIT {
 
-    if (ITUtils.isEmbedded()) {
-      return;
-    }
-    try {
-      downloadIcebergAwsBundleJar();
-    } catch (IOException e) {
-      throw new RuntimeException(e);
-    }
-    copyS3BundleJar();
-  }
+  protected static final String SCHEMA_NAME = "schema";
 
   @BeforeEach
   void revokePrivilege() {
@@ -105,20 +69,63 @@ public class IcebergRESTS3TokenAuthorizationIT extends 
IcebergAuthorizationIT {
   }
 
   @Override
-  public Map<String, String> getCustomProperties() {
-    HashMap<String, String> m = new HashMap<>();
-    m.putAll(getS3Config());
-    return m;
+  protected boolean supportsCredentialVending() {
+    return true;
   }
 
+  /**
+   * Returns the cloud-specific configuration properties. Subclasses implement 
this to provide
+   * cloud-specific settings like credentials, warehouse location, IO 
implementation, etc.
+   *
+   * @return Map of cloud storage configuration properties
+   */
   @Override
-  protected boolean supportsCredentialVending() {
-    return true;
+  public abstract Map<String, String> getCustomProperties();
+
+  /**
+   * Downloads cloud-specific bundle JARs (e.g., iceberg-aws-bundle, 
iceberg-gcp-bundle). Subclasses
+   * implement this to download the appropriate bundle for their cloud 
provider.
+   *
+   * @throws Exception if download fails
+   */
+  protected abstract void downloadCloudBundleJar() throws Exception;
+
+  /**
+   * Copies cloud-specific bundle JARs to the Iceberg REST server libs 
directory. Subclasses
+   * implement this to copy the appropriate bundle (e.g., "aws", "gcp", 
"azure").
+   */
+  protected abstract void copyCloudBundleJar();
+
+  /**
+   * Returns the cloud provider name for table naming (e.g., "s3", "gcs", 
"azure"). Used to generate
+   * unique table names like "test_owner_s3", "test_select_gcs".
+   *
+   * @return Cloud provider suffix for table names
+   */
+  protected abstract String getCloudProviderName();
+
+  /**
+   * Sets up cloud-specific bundle JARs by downloading and copying them. This 
method should be
+   * called from subclass {@code startIntegrationTest()} methods after calling 
{@code
+   * super.startIntegrationTest()}.
+   *
+   * <p>Skips setup if running in embedded mode.
+   */
+  protected void setupCloudBundles() {
+    if (ITUtils.isEmbedded()) {
+      return;
+    }
+    try {
+      downloadCloudBundleJar();
+    } catch (Exception e) {
+      throw new RuntimeException("Failed to download cloud bundle JAR", e);
+    }
+    copyCloudBundleJar();
   }
 
   @Test
-  void testIcebergOwnerS3Token() {
-    String tableName = "test_owner_s3";
+  void testIcebergOwnerCloudToken() {
+    String tableName = "test_owner_" + getCloudProviderName();
     grantCreateTableRole(SCHEMA_NAME);
     sql("CREATE TABLE %s(a int, b int) PARTITIONED BY (a)", tableName);
     sql("INSERT INTO %s VALUES (1,1),(2,2)", tableName);
@@ -139,8 +146,8 @@ public class IcebergRESTS3TokenAuthorizationIT extends 
IcebergAuthorizationIT {
   }
 
   @Test
-  void testIcebergSelectTableS3Token() {
-    String tableName = "test_select_s3";
+  void testIcebergSelectTableCloudToken() {
+    String tableName = "test_select_" + getCloudProviderName();
     createTable(SCHEMA_NAME, tableName);
 
     // No privileges
@@ -170,8 +177,8 @@ public class IcebergRESTS3TokenAuthorizationIT extends 
IcebergAuthorizationIT {
   }
 
   @Test
-  void testIcebergModifyTableS3Token() {
-    String tableName = "test_modify_s3";
+  void testIcebergModifyTableCloudToken() {
+    String tableName = "test_modify_" + getCloudProviderName();
     createTable(SCHEMA_NAME, tableName);
 
     // No privileges
@@ -182,7 +189,6 @@ public class IcebergRESTS3TokenAuthorizationIT extends 
IcebergAuthorizationIT {
         () -> sql("SELECT * FROM %s.%s.%s", SPARK_CATALOG_NAME, SCHEMA_NAME, 
tableName));
 
     grantModifyTableRole(tableName);
-
     sql("INSERT INTO %s VALUES (1,1),(2,2)", tableName);
     List<Object[]> rows = sql("SELECT * FROM %s", tableName);
     Assertions.assertEquals(2, rows.size());
@@ -200,7 +206,7 @@ public class IcebergRESTS3TokenAuthorizationIT extends 
IcebergAuthorizationIT {
     Assertions.assertEquals(2, rows.size());
   }
 
-  private void grantUseSchemaRole(String schema) {
+  protected void grantUseSchemaRole(String schema) {
     String roleName = "useSchema_" + UUID.randomUUID();
     List<SecurableObject> securableObjects = new ArrayList<>();
     SecurableObject catalogObject =
@@ -216,7 +222,7 @@ public class IcebergRESTS3TokenAuthorizationIT extends 
IcebergAuthorizationIT {
     
metalakeClientWithAllPrivilege.grantRolesToUser(ImmutableList.of(roleName), 
NORMAL_USER);
   }
 
-  private String grantCreateTableRole(String schema) {
+  protected String grantCreateTableRole(String schema) {
     String roleName = "createTable_" + UUID.randomUUID();
     List<SecurableObject> securableObjects = new ArrayList<>();
     SecurableObject catalogObject =
@@ -232,7 +238,7 @@ public class IcebergRESTS3TokenAuthorizationIT extends 
IcebergAuthorizationIT {
     return roleName;
   }
 
-  private String grantSelectTableRole(String tableName) {
+  protected String grantSelectTableRole(String tableName) {
     String roleName = "selectTable_" + UUID.randomUUID();
     List<SecurableObject> securableObjects = new ArrayList<>();
     SecurableObject catalogObject =
@@ -251,7 +257,7 @@ public class IcebergRESTS3TokenAuthorizationIT extends 
IcebergAuthorizationIT {
     return roleName;
   }
 
-  private String grantModifyTableRole(String tableName) {
+  protected String grantModifyTableRole(String tableName) {
     String roleName = "modifyTable_" + UUID.randomUUID();
     List<SecurableObject> securableObjects = new ArrayList<>();
     SecurableObject catalogObject =
@@ -270,7 +276,7 @@ public class IcebergRESTS3TokenAuthorizationIT extends 
IcebergAuthorizationIT {
     return roleName;
   }
 
-  private void clearTable() {
+  protected void clearTable() {
     Arrays.stream(
             
catalogClientWithAllPrivilege.asTableCatalog().listTables(Namespace.of(SCHEMA_NAME)))
         .forEach(
@@ -283,40 +289,4 @@ public class IcebergRESTS3TokenAuthorizationIT extends 
IcebergAuthorizationIT {
         
catalogClientWithAllPrivilege.asTableCatalog().listTables(Namespace.of(SCHEMA_NAME));
     Assertions.assertEquals(0, nameIdentifiers.length);
   }
-
-  private void downloadIcebergAwsBundleJar() throws IOException {
-    String icebergBundleJarUri =
-        String.format(
-            "https://repo1.maven.org/maven2/org/apache/iceberg/";
-                + "iceberg-aws-bundle/%s/iceberg-aws-bundle-%s.jar",
-            ITUtils.icebergVersion(), ITUtils.icebergVersion());
-    String gravitinoHome = System.getenv("GRAVITINO_HOME");
-    String targetDir = String.format("%s/iceberg-rest-server/libs/", 
gravitinoHome);
-    DownloaderUtils.downloadFile(icebergBundleJarUri, targetDir);
-  }
-
-  private void copyS3BundleJar() {
-    String gravitinoHome = System.getenv("GRAVITINO_HOME");
-    String targetDir = String.format("%s/iceberg-rest-server/libs/", 
gravitinoHome);
-    BaseIT.copyBundleJarsToDirectory("aws", targetDir);
-  }
-
-  private Map<String, String> getS3Config() {
-    Map configMap = new HashMap<String, String>();
-
-    configMap.put(
-        CredentialConstants.CREDENTIAL_PROVIDERS, 
S3TokenCredential.S3_TOKEN_CREDENTIAL_TYPE);
-    configMap.put(S3Properties.GRAVITINO_S3_REGION, region);
-    configMap.put(S3Properties.GRAVITINO_S3_ACCESS_KEY_ID, accessKey);
-    configMap.put(S3Properties.GRAVITINO_S3_SECRET_ACCESS_KEY, secretKey);
-    configMap.put(S3Properties.GRAVITINO_S3_ROLE_ARN, roleArn);
-    if (StringUtils.isNotBlank(externalId)) {
-      configMap.put(S3Properties.GRAVITINO_S3_EXTERNAL_ID, externalId);
-    }
-
-    configMap.put(IcebergConstants.IO_IMPL, 
"org.apache.iceberg.aws.s3.S3FileIO");
-    configMap.put(IcebergConstants.WAREHOUSE, s3Warehouse);
-
-    return configMap;
-  }
 }
diff --git 
a/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/IcebergRESTGCSTokenAuthorizationIT.java
 
b/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/IcebergRESTGCSTokenAuthorizationIT.java
new file mode 100644
index 0000000000..00b625b0d9
--- /dev/null
+++ 
b/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/IcebergRESTGCSTokenAuthorizationIT.java
@@ -0,0 +1,119 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.gravitino.iceberg.integration.test;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.gravitino.catalog.lakehouse.iceberg.IcebergConstants;
+import org.apache.gravitino.credential.CredentialConstants;
+import org.apache.gravitino.credential.GCSTokenCredential;
+import org.apache.gravitino.integration.test.util.BaseIT;
+import org.apache.gravitino.integration.test.util.DownloaderUtils;
+import org.apache.gravitino.integration.test.util.ITUtils;
+import org.apache.gravitino.storage.GCSProperties;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
+
+/**
+ * Integration tests for Iceberg REST credential vending with GCS (Google 
Cloud Storage).
+ *
+ * <p>Authentication: Supports both service account key file and Application 
Default Credentials
+ * (ADC).
+ *
+ * <p>Required environment variables:
+ *
+ * <ul>
+ *   <li>GRAVITINO_TEST_CLOUD_IT=true - enables cloud integration tests
+ *   <li>GRAVITINO_GCS_BUCKET - GCS bucket name (e.g., "my-bucket")
+ *   <li>GRAVITINO_GCS_PATH_PREFIX - path prefix within bucket (e.g., 
"test/gravitino")
+ *   <li>GRAVITINO_GCS_SERVICE_ACCOUNT_FILE (optional) - path to service 
account JSON key. If
+ *       omitted, uses ADC (requires: gcloud auth application-default login)
+ * </ul>
+ */
+@SuppressWarnings("FormatStringAnnotation")
+@EnabledIfEnvironmentVariable(named = "GRAVITINO_TEST_CLOUD_IT", matches = 
"true")
+public class IcebergRESTGCSTokenAuthorizationIT extends 
IcebergRESTCloudTokenAuthorizationBaseIT {
+
+  private String gcsWarehouse;
+  private String serviceAccountFile;
+
+  @BeforeAll
+  public void startIntegrationTest() throws Exception {
+    String bucket = System.getenv().getOrDefault("GRAVITINO_GCS_BUCKET", 
"{BUCKET_NAME}");
+    String pathPrefix = 
System.getenv().getOrDefault("GRAVITINO_GCS_PATH_PREFIX", "test1");
+    this.gcsWarehouse = String.format("gs://%s/%s", bucket, pathPrefix);
+    // Use null to trigger ADC (Application Default Credentials) if not 
explicitly provided
+    this.serviceAccountFile = 
System.getenv().get("GRAVITINO_GCS_SERVICE_ACCOUNT_FILE");
+
+    super.startIntegrationTest();
+
+    catalogClientWithAllPrivilege.asSchemas().createSchema(SCHEMA_NAME, 
"test", new HashMap<>());
+
+    setupCloudBundles();
+  }
+
+  @Override
+  public Map<String, String> getCustomProperties() {
+    HashMap<String, String> m = new HashMap<>();
+    m.putAll(getGCSConfig());
+    return m;
+  }
+
+  @Override
+  protected String getCloudProviderName() {
+    return "gcs";
+  }
+
+  @Override
+  protected void downloadCloudBundleJar() throws IOException {
+    String icebergBundleJarUri =
+        String.format(
+            "https://repo1.maven.org/maven2/org/apache/iceberg/";
+                + "iceberg-gcp-bundle/%s/iceberg-gcp-bundle-%s.jar",
+            ITUtils.icebergVersion(), ITUtils.icebergVersion());
+    String gravitinoHome = System.getenv("GRAVITINO_HOME");
+    String targetDir = String.format("%s/iceberg-rest-server/libs/", 
gravitinoHome);
+    DownloaderUtils.downloadFile(icebergBundleJarUri, targetDir);
+  }
+
+  @Override
+  protected void copyCloudBundleJar() {
+    String gravitinoHome = System.getenv("GRAVITINO_HOME");
+    String targetDir = String.format("%s/iceberg-rest-server/libs/", 
gravitinoHome);
+    BaseIT.copyBundleJarsToDirectory("gcp", targetDir);
+  }
+
+  private Map<String, String> getGCSConfig() {
+    Map<String, String> configMap = new HashMap<>();
+
+    configMap.put(
+        CredentialConstants.CREDENTIAL_PROVIDERS, 
GCSTokenCredential.GCS_TOKEN_CREDENTIAL_TYPE);
+    // Only set service account file if explicitly provided, otherwise use ADC
+    if (serviceAccountFile != null && !serviceAccountFile.isEmpty()) {
+      configMap.put(GCSProperties.GRAVITINO_GCS_SERVICE_ACCOUNT_FILE, 
serviceAccountFile);
+    }
+
+    configMap.put(IcebergConstants.IO_IMPL, 
"org.apache.iceberg.gcp.gcs.GCSFileIO");
+    configMap.put(IcebergConstants.WAREHOUSE, gcsWarehouse);
+
+    return configMap;
+  }
+}
diff --git 
a/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/IcebergRESTS3TokenAuthorizationIT.java
 
b/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/IcebergRESTS3TokenAuthorizationIT.java
index 1f3edd453c..ac5c85729b 100644
--- 
a/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/IcebergRESTS3TokenAuthorizationIT.java
+++ 
b/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/IcebergRESTS3TokenAuthorizationIT.java
@@ -19,22 +19,9 @@
 
 package org.apache.gravitino.iceberg.integration.test;
 
-import com.google.common.collect.ImmutableList;
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
-import java.util.UUID;
-import org.apache.gravitino.MetadataObject;
-import org.apache.gravitino.MetadataObjects;
-import org.apache.gravitino.NameIdentifier;
-import org.apache.gravitino.Namespace;
-import org.apache.gravitino.authorization.Owner;
-import org.apache.gravitino.authorization.Privileges;
-import org.apache.gravitino.authorization.SecurableObject;
-import org.apache.gravitino.authorization.SecurableObjects;
 import org.apache.gravitino.catalog.lakehouse.iceberg.IcebergConstants;
 import org.apache.gravitino.credential.CredentialConstants;
 import org.apache.gravitino.credential.S3TokenCredential;
@@ -42,20 +29,14 @@ import org.apache.gravitino.integration.test.util.BaseIT;
 import org.apache.gravitino.integration.test.util.DownloaderUtils;
 import org.apache.gravitino.integration.test.util.ITUtils;
 import org.apache.gravitino.storage.S3Properties;
-import org.apache.iceberg.exceptions.ForbiddenException;
-import org.apache.spark.SparkException;
-import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
 import org.junit.platform.commons.util.StringUtils;
 
 @SuppressWarnings("FormatStringAnnotation")
 @EnabledIfEnvironmentVariable(named = "GRAVITINO_TEST_CLOUD_IT", matches = 
"true")
-public class IcebergRESTS3TokenAuthorizationIT extends IcebergAuthorizationIT {
+public class IcebergRESTS3TokenAuthorizationIT extends 
IcebergRESTCloudTokenAuthorizationBaseIT {
 
-  private static final String SCHEMA_NAME = "schema";
   private String s3Warehouse;
   private String accessKey;
   private String secretKey;
@@ -78,30 +59,7 @@ public class IcebergRESTS3TokenAuthorizationIT extends 
IcebergAuthorizationIT {
 
     catalogClientWithAllPrivilege.asSchemas().createSchema(SCHEMA_NAME, 
"test", new HashMap<>());
 
-    if (ITUtils.isEmbedded()) {
-      return;
-    }
-    try {
-      downloadIcebergAwsBundleJar();
-    } catch (IOException e) {
-      throw new RuntimeException(e);
-    }
-    copyS3BundleJar();
-  }
-
-  @BeforeEach
-  void revokePrivilege() {
-    revokeUserRoles();
-    resetMetalakeAndCatalogOwner();
-    MetadataObject schemaObject =
-        MetadataObjects.of(
-            Arrays.asList(GRAVITINO_CATALOG_NAME, SCHEMA_NAME), 
MetadataObject.Type.SCHEMA);
-    metalakeClientWithAllPrivilege.setOwner(schemaObject, SUPER_USER, 
Owner.Type.USER);
-    clearTable();
-    // Grant user the privilege to use the catalog and schema
-    grantUseSchemaRole(SCHEMA_NAME);
-    sql("USE %s;", SPARK_CATALOG_NAME);
-    sql("USE %s;", SCHEMA_NAME);
+    setupCloudBundles();
   }
 
   @Override
@@ -112,179 +70,12 @@ public class IcebergRESTS3TokenAuthorizationIT extends 
IcebergAuthorizationIT {
   }
 
   @Override
-  protected boolean supportsCredentialVending() {
-    return true;
-  }
-
-  @Test
-  void testIcebergOwnerS3Token() {
-    String tableName = "test_owner_s3";
-    grantCreateTableRole(SCHEMA_NAME);
-    sql("CREATE TABLE %s(a int, b int) PARTITIONED BY (a)", tableName);
-    sql("INSERT INTO %s VALUES (1,1),(2,2)", tableName);
-    List<Object[]> rows = sql("SELECT * FROM %s", tableName);
-    Assertions.assertEquals(2, rows.size());
-
-    rows = sql("SELECT * FROM %s.%s.%s", SPARK_CATALOG_NAME, SCHEMA_NAME, 
tableName);
-    Assertions.assertEquals(2, rows.size());
-
-    rows = sql("SELECT * FROM %s.%s", SCHEMA_NAME, tableName);
-    Assertions.assertEquals(2, rows.size());
-
-    rows = sql("SELECT * FROM %s.%s.%s.partitions", SPARK_CATALOG_NAME, 
SCHEMA_NAME, tableName);
-    Assertions.assertEquals(2, rows.size());
-
-    rows = sql("SELECT *,_file FROM %s", tableName);
-    Assertions.assertEquals(2, rows.size());
-  }
-
-  @Test
-  void testIcebergSelectTableS3Token() {
-    String tableName = "test_select_s3";
-    createTable(SCHEMA_NAME, tableName);
-
-    // No privileges
-    Assertions.assertThrows(
-        ForbiddenException.class, () -> sql("INSERT INTO %s VALUES 
(1,1),(2,2)", tableName));
-    Assertions.assertThrows(
-        ForbiddenException.class,
-        () -> sql("SELECT * FROM %s.%s.%s", SPARK_CATALOG_NAME, SCHEMA_NAME, 
tableName));
-
-    grantSelectTableRole(tableName);
-    Assertions.assertThrows(
-        SparkException.class, () -> sql("INSERT INTO %s VALUES (1,1),(2,2)", 
tableName));
-    List<Object[]> rows = sql("SELECT * FROM %s", tableName);
-    Assertions.assertEquals(0, rows.size());
-
-    rows = sql("SELECT * FROM %s.%s.%s", SPARK_CATALOG_NAME, SCHEMA_NAME, 
tableName);
-    Assertions.assertEquals(0, rows.size());
-
-    rows = sql("SELECT * FROM %s.%s", SCHEMA_NAME, tableName);
-    Assertions.assertEquals(0, rows.size());
-
-    rows = sql("SELECT * FROM %s.%s.%s.partitions", SPARK_CATALOG_NAME, 
SCHEMA_NAME, tableName);
-    Assertions.assertEquals(0, rows.size());
-
-    rows = sql("SELECT *,_file FROM %s", tableName);
-    Assertions.assertEquals(0, rows.size());
-  }
-
-  @Test
-  void testIcebergModifyTableS3Token() {
-    String tableName = "test_modify_s3";
-    createTable(SCHEMA_NAME, tableName);
-
-    // No privileges
-    Assertions.assertThrows(
-        ForbiddenException.class, () -> sql("INSERT INTO %s VALUES 
(1,1),(2,2)", tableName));
-    Assertions.assertThrows(
-        ForbiddenException.class,
-        () -> sql("SELECT * FROM %s.%s.%s", SPARK_CATALOG_NAME, SCHEMA_NAME, 
tableName));
-
-    grantModifyTableRole(tableName);
-
-    sql("INSERT INTO %s VALUES (1,1),(2,2)", tableName);
-    List<Object[]> rows = sql("SELECT * FROM %s", tableName);
-    Assertions.assertEquals(2, rows.size());
-
-    rows = sql("SELECT * FROM %s.%s.%s", SPARK_CATALOG_NAME, SCHEMA_NAME, 
tableName);
-    Assertions.assertEquals(2, rows.size());
-
-    rows = sql("SELECT * FROM %s.%s", SCHEMA_NAME, tableName);
-    Assertions.assertEquals(2, rows.size());
-
-    rows = sql("SELECT * FROM %s.%s.%s.partitions", SPARK_CATALOG_NAME, 
SCHEMA_NAME, tableName);
-    Assertions.assertEquals(1, rows.size());
-
-    rows = sql("SELECT *,_file FROM %s", tableName);
-    Assertions.assertEquals(2, rows.size());
-  }
-
-  private void grantUseSchemaRole(String schema) {
-    String roleName = "useSchema_" + UUID.randomUUID();
-    List<SecurableObject> securableObjects = new ArrayList<>();
-    SecurableObject catalogObject =
-        SecurableObjects.ofCatalog(
-            GRAVITINO_CATALOG_NAME, 
ImmutableList.of(Privileges.UseCatalog.allow()));
-    securableObjects.add(catalogObject);
-    SecurableObject schemaObject =
-        SecurableObjects.ofSchema(
-            catalogObject, schema, 
ImmutableList.of(Privileges.UseSchema.allow()));
-    securableObjects.add(schemaObject);
-    metalakeClientWithAllPrivilege.createRole(roleName, new HashMap<>(), 
securableObjects);
-
-    
metalakeClientWithAllPrivilege.grantRolesToUser(ImmutableList.of(roleName), 
NORMAL_USER);
+  protected String getCloudProviderName() {
+    return "s3";
   }
 
-  private String grantCreateTableRole(String schema) {
-    String roleName = "createTable_" + UUID.randomUUID();
-    List<SecurableObject> securableObjects = new ArrayList<>();
-    SecurableObject catalogObject =
-        SecurableObjects.ofCatalog(
-            GRAVITINO_CATALOG_NAME, 
ImmutableList.of(Privileges.UseCatalog.allow()));
-    securableObjects.add(catalogObject);
-    SecurableObject schemaObject =
-        SecurableObjects.ofSchema(
-            catalogObject, schema, 
ImmutableList.of(Privileges.CreateTable.allow()));
-    securableObjects.add(schemaObject);
-    metalakeClientWithAllPrivilege.createRole(roleName, new HashMap<>(), 
securableObjects);
-    
metalakeClientWithAllPrivilege.grantRolesToUser(ImmutableList.of(roleName), 
NORMAL_USER);
-    return roleName;
-  }
-
-  private String grantSelectTableRole(String tableName) {
-    String roleName = "selectTable_" + UUID.randomUUID();
-    List<SecurableObject> securableObjects = new ArrayList<>();
-    SecurableObject catalogObject =
-        SecurableObjects.ofCatalog(
-            GRAVITINO_CATALOG_NAME, 
ImmutableList.of(Privileges.UseCatalog.allow()));
-    securableObjects.add(catalogObject);
-    SecurableObject schemaObject =
-        SecurableObjects.ofSchema(
-            catalogObject, SCHEMA_NAME, 
ImmutableList.of(Privileges.UseSchema.allow()));
-    SecurableObject tableObject =
-        SecurableObjects.ofTable(
-            schemaObject, tableName, 
ImmutableList.of(Privileges.SelectTable.allow()));
-    securableObjects.add(tableObject);
-    metalakeClientWithAllPrivilege.createRole(roleName, new HashMap<>(), 
securableObjects);
-    
metalakeClientWithAllPrivilege.grantRolesToUser(ImmutableList.of(roleName), 
NORMAL_USER);
-    return roleName;
-  }
-
-  private String grantModifyTableRole(String tableName) {
-    String roleName = "modifyTable_" + UUID.randomUUID();
-    List<SecurableObject> securableObjects = new ArrayList<>();
-    SecurableObject catalogObject =
-        SecurableObjects.ofCatalog(
-            GRAVITINO_CATALOG_NAME, 
ImmutableList.of(Privileges.UseCatalog.allow()));
-    securableObjects.add(catalogObject);
-    SecurableObject schemaObject =
-        SecurableObjects.ofSchema(
-            catalogObject, SCHEMA_NAME, 
ImmutableList.of(Privileges.UseSchema.allow()));
-    SecurableObject tableObject =
-        SecurableObjects.ofTable(
-            schemaObject, tableName, 
ImmutableList.of(Privileges.ModifyTable.allow()));
-    securableObjects.add(tableObject);
-    metalakeClientWithAllPrivilege.createRole(roleName, new HashMap<>(), 
securableObjects);
-    
metalakeClientWithAllPrivilege.grantRolesToUser(ImmutableList.of(roleName), 
NORMAL_USER);
-    return roleName;
-  }
-
-  private void clearTable() {
-    Arrays.stream(
-            
catalogClientWithAllPrivilege.asTableCatalog().listTables(Namespace.of(SCHEMA_NAME)))
-        .forEach(
-            table -> {
-              catalogClientWithAllPrivilege
-                  .asTableCatalog()
-                  .dropTable(NameIdentifier.of(SCHEMA_NAME, table.name()));
-            });
-    NameIdentifier[] nameIdentifiers =
-        
catalogClientWithAllPrivilege.asTableCatalog().listTables(Namespace.of(SCHEMA_NAME));
-    Assertions.assertEquals(0, nameIdentifiers.length);
-  }
-
-  private void downloadIcebergAwsBundleJar() throws IOException {
+  @Override
+  protected void downloadCloudBundleJar() throws IOException {
     String icebergBundleJarUri =
         String.format(
             "https://repo1.maven.org/maven2/org/apache/iceberg/";
@@ -295,7 +86,8 @@ public class IcebergRESTS3TokenAuthorizationIT extends 
IcebergAuthorizationIT {
     DownloaderUtils.downloadFile(icebergBundleJarUri, targetDir);
   }
 
-  private void copyS3BundleJar() {
+  @Override
+  protected void copyCloudBundleJar() {
     String gravitinoHome = System.getenv("GRAVITINO_HOME");
     String targetDir = String.format("%s/iceberg-rest-server/libs/", 
gravitinoHome);
     BaseIT.copyBundleJarsToDirectory("aws", targetDir);

Reply via email to