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

fanng 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 e27ff4e70 [#4393] improvement(docs): Refine authentication information 
about Iceberg rest catalog and Add IT for Kerberos Hive backend. (#4395)
e27ff4e70 is described below

commit e27ff4e70da1fffd27317cb928e1d93ba8661bd6
Author: Qi Yu <[email protected]>
AuthorDate: Thu Aug 15 09:29:43 2024 +0800

    [#4393] improvement(docs): Refine authentication information about Iceberg 
rest catalog and Add IT for Kerberos Hive backend. (#4395)
    
    ### What changes were proposed in this pull request?
    
    Add document about authentication for Iceberg rest catalog.
    
    ### Why are the changes needed?
    
    To make the information consistent.
    
    Fix: #4393
    
    ### Does this PR introduce _any_ user-facing change?
    
    N/A.
    
    ### How was this patch tested?
    
    N/A.
---
 docs/iceberg-rest-service.md                       |  47 +++---
 docs/lakehouse-iceberg-catalog.md                  |  45 +++---
 .../iceberg/common/ops/IcebergTableOps.java        |  18 +++
 .../iceberg/common/ops/IcebergTableOpsManager.java |   7 +-
 .../iceberg/common/utils/IcebergCatalogUtil.java   |   7 +-
 .../integration/test/IcebergRESTHiveCatalogIT.java |   2 +-
 .../test/IcebergRestKerberosHiveCatalogIT.java     | 160 +++++++++++++++++++++
 .../util/IcebergRESTServerManagerForDeploy.java    |  43 +++++-
 8 files changed, 284 insertions(+), 45 deletions(-)

diff --git a/docs/iceberg-rest-service.md b/docs/iceberg-rest-service.md
index 234104b87..70c5b6812 100644
--- a/docs/iceberg-rest-service.md
+++ b/docs/iceberg-rest-service.md
@@ -83,6 +83,21 @@ You can also specify filter parameters by setting 
configuration entries in the s
 
 Gravitino Iceberg REST server supports OAuth2 and HTTPS, please refer to 
[Security](./security.md) for more details.
 
+#### Backend authentication
+
+For JDBC backend, you can use the `gravitino.iceberg-rest.jdbc.user` and 
`gravitino.iceberg-rest.jdbc.password` to authenticate the JDBC connection. For 
Hive backend, you can use the `gravitino.iceberg-rest.authentication.type` to 
specify the authentication type, and use the 
`gravitino.iceberg-rest.authentication.kerberos.principal` and 
`gravitino.iceberg-rest.authentication.kerberos.keytab-uri` to authenticate the 
Kerberos connection.
+The detailed configuration items are as follows:
+
+| Configuration item                                                        | 
Description                                                                     
                                                                                
                                                                                
      | Default value | Required                                                
                           | Since Version |
+|---------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------|------------------------------------------------------------------------------------|---------------|
+| `gravitino.iceberg-rest.authentication.type`                              | 
The type of authentication for Iceberg rest catalog backend. This configuration 
only applicable for for Hive backend, and only supports `Kerberos`, `simple` 
currently. As for JDBC backend, only username/password authentication was 
supported now. | `simple`      | No                                             
                                    | 0.6.0         |
+| `gravitino.iceberg-rest.authentication.impersonation-enable`              | 
Whether to enable impersonation for the Iceberg catalog                         
                                                                                
                                                                                
      | `false`       | No                                                      
                           | 0.6.0         |
+| `gravitino.iceberg-rest.authentication.kerberos.principal`                | 
The principal of the Kerberos authentication                                    
                                                                                
                                                                                
      | (none)        | required if the value of 
`gravitino.iceberg-rest.authentication.type` is Kerberos. | 0.6.0         |
+| `gravitino.iceberg-rest.authentication.kerberos.keytab-uri`               | 
The URI of The keytab for the Kerberos authentication.                          
                                                                                
                                                                                
      | (none)        | required if the value of 
`gravitino.iceberg-rest.authentication.type` is Kerberos. | 0.6.0         |
+| `gravitino.iceberg-rest.authentication.kerberos.check-interval-sec`       | 
The check interval of Kerberos credential for Iceberg catalog.                  
                                                                                
                                                                                
      | 60            | No                                                      
                           | 0.6.0         |
+| `gravitino.iceberg-rest.authentication.kerberos.keytab-fetch-timeout-sec` | 
The fetch timeout of retrieving Kerberos keytab from 
`authentication.kerberos.keytab-uri`.                                           
                                                                                
                                 | 60            | No                           
                                                      | 0.6.0         |
+
+
 ### Storage
 
 Gravitino Iceberg REST server supports S3 and HDFS for storage.
@@ -121,25 +136,25 @@ The Gravitino Iceberg REST catalog service uses the 
memory catalog backend by de
 
 #### Hive backend configuration
 
-| Configuration item                            | Description                  
                                                                                
                                | Default value                                 
                                | Required | Since Version |
-|-----------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------|----------|---------------|
-| `gravitino.iceberg-rest.catalog-backend`      | The Catalog backend of the 
Gravitino Iceberg REST catalog service. Use the value **`hive`** for a Hive 
catalog.                              | `memory`                                
                                      | Yes      | 0.2.0         |
-| `gravitino.iceberg-rest.uri`                  | The Hive metadata address, 
such as `thrift://127.0.0.1:9083`.                                              
                                  | (none)                                      
                                  | Yes      | 0.2.0         |
-| `gravitino.iceberg-rest.warehouse`            | The warehouse directory of 
the Hive catalog, such as `/user/hive/warehouse-hive/`.                         
                                  | (none)                                      
                                  | Yes      | 0.2.0         |
-| `gravitino.iceberg-rest.catalog-backend-name` | The catalog backend name 
passed to underlying Iceberg catalog backend. Catalog name in JDBC backend is 
used to isolate namespace and tables. | `hive` for Hive backend, `jdbc` for 
JDBC backend, `memory` for memory backend | No       | 0.5.2         |
+| Configuration item                                                        | 
Description                                                                     
                                                             | Default value    
                                                              | Required | 
Since Version |
+|---------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------|----------|---------------|
+| `gravitino.iceberg-rest.catalog-backend`                                  | 
The Catalog backend of the Gravitino Iceberg REST catalog service. Use the 
value **`hive`** for a Hive catalog.                              | `memory`    
                                                                   | Yes      | 
0.2.0         |
+| `gravitino.iceberg-rest.uri`                                              | 
The Hive metadata address, such as `thrift://127.0.0.1:9083`.                   
                                                             | (none)           
                                                              | Yes      | 
0.2.0         |
+| `gravitino.iceberg-rest.warehouse`                                        | 
The warehouse directory of the Hive catalog, such as 
`/user/hive/warehouse-hive/`.                                                   
        | (none)                                                                
         | Yes      | 0.2.0         |
+| `gravitino.iceberg-rest.catalog-backend-name`                             | 
The catalog backend name passed to underlying Iceberg catalog backend. Catalog 
name in JDBC backend is used to isolate namespace and tables. | `hive` for Hive 
backend, `jdbc` for JDBC backend, `memory` for memory backend  | No       | 
0.5.2         |
 
 #### JDBC backend configuration
 
-| Configuration item                            | Description                  
                                                                                
                        | Default value           | Required | Since Version |
-|-----------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------|-------------------------|----------|---------------|
-| `gravitino.iceberg-rest.catalog-backend`      | The Catalog backend of the 
Gravitino Iceberg REST catalog service. Use the value **`jdbc`** for a JDBC 
catalog.                      | `memory`                | Yes      | 0.2.0      
   |
-| `gravitino.iceberg-rest.uri`                  | The JDBC connection address, 
such as `jdbc:postgresql://127.0.0.1:5432` for Postgres, or 
`jdbc:mysql://127.0.0.1:3306/` for mysql.   | (none)                  | Yes     
 | 0.2.0         |
-| `gravitino.iceberg-rest.warehouse `           | The warehouse directory of 
JDBC catalog. Set the HDFS prefix if using HDFS, such as 
`hdfs://127.0.0.1:9000/user/hive/warehouse-jdbc` | (none)                  | 
Yes      | 0.2.0         |
-| `gravitino.iceberg-rest.catalog-backend-name` | The catalog name passed to 
underlying Iceberg catalog backend. Catalog name in JDBC backend is used to 
isolate namespace and tables. | `jdbc` for JDBC backend | No       | 0.5.2      
   |
-| `gravitino.iceberg-rest.jdbc.user`            | The username of the JDBC 
connection.                                                                     
                            | (none)                  | Yes      | 0.2.0        
 |
-| `gravitino.iceberg-rest.jdbc.password`        | The password of the JDBC 
connection.                                                                     
                            | (none)                  | Yes      | 0.2.0        
 |
-| `gravitino.iceberg-rest.jdbc-initialize`      | Whether to initialize the 
meta tables when creating the JDBC catalog.                                     
                           | `true`                  | No       | 0.2.0         
|
-| `gravitino.iceberg-rest.jdbc-driver`          | `com.mysql.jdbc.Driver` or 
`com.mysql.cj.jdbc.Driver` for MySQL, `org.postgresql.Driver` for PostgreSQL.   
                          | (none)                  | Yes      | 0.3.0         |
+| Configuration item                                                        | 
Description                                                                     
                                                      | Default value           
 | Required | Since Version |
+|---------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------|--------------------------|----------|---------------|
+| `gravitino.iceberg-rest.catalog-backend`                                  | 
The Catalog backend of the Gravitino Iceberg REST catalog service. Use the 
value **`jdbc`** for a JDBC catalog.                       | `memory`           
      | Yes      | 0.2.0         |
+| `gravitino.iceberg-rest.uri`                                              | 
The JDBC connection address, such as `jdbc:postgresql://127.0.0.1:5432` for 
Postgres, or `jdbc:mysql://127.0.0.1:3306/` for mysql.    | (none)              
     | Yes      | 0.2.0         |
+| `gravitino.iceberg-rest.warehouse `                                       | 
The warehouse directory of JDBC catalog. Set the HDFS prefix if using HDFS, 
such as `hdfs://127.0.0.1:9000/user/hive/warehouse-jdbc`  | (none)              
     | Yes      | 0.2.0         |
+| `gravitino.iceberg-rest.catalog-backend-name`                             | 
The catalog name passed to underlying Iceberg catalog backend. Catalog name in 
JDBC backend is used to isolate namespace and tables.  | `jdbc` for JDBC 
backend  | No       | 0.5.2         |
+| `gravitino.iceberg-rest.jdbc.user`                                        | 
The username of the JDBC connection.                                            
                                                      | (none)                  
 | Yes      | 0.2.0         |
+| `gravitino.iceberg-rest.jdbc.password`                                    | 
The password of the JDBC connection.                                            
                                                      | (none)                  
 | Yes      | 0.2.0         |
+| `gravitino.iceberg-rest.jdbc-initialize`                                  | 
Whether to initialize the meta tables when creating the JDBC catalog.           
                                                      | `true`                  
 | No       | 0.2.0         |
+| `gravitino.iceberg-rest.jdbc-driver`                                      | 
`com.mysql.jdbc.Driver` or `com.mysql.cj.jdbc.Driver` for MySQL, 
`org.postgresql.Driver` for PostgreSQL.                              | (none)   
                | Yes      | 0.3.0         |
 
 If you have a JDBC Iceberg catalog prior, you must set `catalog-backend-name` 
to keep consistent with your Jdbc Iceberg catalog name to operate the prior 
namespace and tables.
 
diff --git a/docs/lakehouse-iceberg-catalog.md 
b/docs/lakehouse-iceberg-catalog.md
index 1b330d30f..f20487fa1 100644
--- a/docs/lakehouse-iceberg-catalog.md
+++ b/docs/lakehouse-iceberg-catalog.md
@@ -25,7 +25,7 @@ Builds with Apache Iceberg `1.5.2`. The Apache Iceberg table 
format version is `
 
 ### Catalog capabilities
 
-- Works as a catalog proxy, supporting `HiveCatalog`, `JdbcCatalog` and 
`RESTCatalog`.
+- Works as a catalog proxy, supporting `Hive`, `JDBC` and `REST` as catalog 
backend.
 - Supports DDL operations for Iceberg schemas and tables.
 - Doesn't support snapshot or table management operations.
 - Supports S3 and HDFS storage.
@@ -33,30 +33,24 @@ Builds with Apache Iceberg `1.5.2`. The Apache Iceberg 
table format version is `
 
 ### Catalog properties
 
-| Property name                                      | Description             
                                                                                
                                                                                
        | Default value          | Required                                     
               | Since Version |
-|----------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------|-------------------------------------------------------------|---------------|
-| `catalog-backend`                                  | Catalog backend of 
Gravitino Iceberg catalog. Supports `hive` or `jdbc` or `rest`.                 
                                                                                
             | (none)                 | Yes                                     
                    | 0.2.0         |
-| `uri`                                              | The URI configuration 
of the Iceberg catalog. `thrift://127.0.0.1:9083` or 
`jdbc:postgresql://127.0.0.1:5432/db_name` or 
`jdbc:mysql://127.0.0.1:3306/metastore_db` or `http://127.0.0.1:9001`. | (none) 
                | Yes                                                         | 
0.2.0         |
-| `warehouse`                                        | Warehouse directory of 
catalog. `file:///user/hive/warehouse-hive/` for local fs or 
`hdfs://namespace/hdfs/path` for HDFS.                                          
                            | (none)                 | Yes                      
                                   | 0.2.0         |
-| `catalog-backend-name`                             | The catalog name passed 
to underlying Iceberg catalog backend. Catalog name in JDBC backend is used to 
isolate namespace and tables.                                                   
         | Gravitino catalog name | No                                          
                | 0.5.2         |
-| `authentication.type`                              | The type of 
authentication for Iceberg catalog backend, currently Gravitino only supports 
`Kerberos`, `simple`.                                                           
                      | `simple`               | No                             
                             | 0.6.0         |
-| `authentication.impersonation-enable`              | Whether to enable 
impersonation for the Iceberg catalog                                           
                                                                                
              | `false`                | No                                     
                     | 0.6.0         |
-| `authentication.kerberos.principal`                | The principal of the 
Kerberos authentication                                                         
                                                                                
           | (none)                 | required if the value of 
`authentication.type` is Kerberos. | 0.6.0         |
-| `authentication.kerberos.keytab-uri`               | The URI of The keytab 
for the Kerberos authentication.                                                
                                                                                
          | (none)                 | required if the value of 
`authentication.type` is Kerberos. | 0.6.0         |
-| `authentication.kerberos.check-interval-sec`       | The check interval of 
Kerberos credential for Iceberg catalog.                                        
                                                                                
          | 60                     | No                                         
                 | 0.6.0         |
-| `authentication.kerberos.keytab-fetch-timeout-sec` | The fetch timeout of 
retrieving Kerberos keytab from `authentication.kerberos.keytab-uri`.           
                                                                                
           | 60                     | No                                        
                  | 0.6.0         |
+| Property name                                      | Description             
                                                                                
                                                                                
                                                         | Default value        
  | Required                                                    | Since Version 
|
+|----------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------|-------------------------------------------------------------|---------------|
+| `catalog-backend`                                  | Catalog backend of 
Gravitino Iceberg catalog. Supports `hive` or `jdbc` or `rest`.                 
                                                                                
                                                              | (none)          
       | Yes                                                         | 0.2.0    
     |
+| `uri`                                              | The URI configuration 
of the Iceberg catalog. `thrift://127.0.0.1:9083` or 
`jdbc:postgresql://127.0.0.1:5432/db_name` or 
`jdbc:mysql://127.0.0.1:3306/metastore_db` or `http://127.0.0.1:9001`.          
                                        | (none)                 | Yes          
                                               | 0.2.0         |
+| `warehouse`                                        | Warehouse directory of 
catalog. `file:///user/hive/warehouse-hive/` for local fs or 
`hdfs://namespace/hdfs/path` for HDFS.                                          
                                                                             | 
(none)                 | Yes                                                    
     | 0.2.0         |
+| `catalog-backend-name`                             | The catalog name passed 
to underlying Iceberg catalog backend. Catalog name in JDBC backend is used to 
isolate namespace and tables.                                                   
                                                          | Gravitino catalog 
name | No                                                          | 0.5.2      
   |
 
 
-Any properties not defined by Gravitino with `gravitino.bypass.` prefix will 
pass to Iceberg catalog properties and HDFS configuration. For example, if 
specify `gravitino.bypass.list-all-tables`, `list-all-tables` will pass to 
Iceberg catalog properties.
+Any property not defined by Gravitino with `gravitino.bypass.` prefix will 
pass to Iceberg catalog properties and HDFS configuration. For example, if 
specify `gravitino.bypass.list-all-tables`, `list-all-tables` will pass to 
Iceberg catalog properties.
 
-When you use the Gravitino with Trino. You can pass the Trino Iceberg 
connector configuration using prefix `trino.bypass.`. For example, using 
`trino.bypass.iceberg.table-statistics-enabled` to pass the 
`iceberg.table-statistics-enabled` to the Gravitino Iceberg catalog in Trino 
runtime.
+If you are using the Gravitino with Trino, you can pass the Trino Iceberg 
connector configuration using prefix `trino.bypass.`. For example, using 
`trino.bypass.iceberg.table-statistics-enabled` to pass the 
`iceberg.table-statistics-enabled` to the Gravitino Iceberg catalog in Trino 
runtime.
 
-When you use the Gravitino with Spark. You can pass the Spark Iceberg 
connector configuration using prefix `spark.bypass.`. For example, using 
`spark.bypass.io-impl` to pass the `io-impl` to the Spark Iceberg connector in 
Spark runtime.
+If you are using the Gravitino with Spark, you can pass the Spark Iceberg 
connector configuration using prefix `spark.bypass.`. For example, using 
`spark.bypass.io-impl` to pass the `io-impl` to the Spark Iceberg connector in 
Spark runtime.
 
 
-#### JDBC catalog
+#### JDBC backend
 
-If you are using JDBC catalog, you must provide `jdbc-user`, `jdbc-password` 
and `jdbc-driver` to catalog properties.
+If you are using JDBC backend, you must provide properties like `jdbc-user`, 
`jdbc-password` and `jdbc-driver`.
 
 | Property name     | Description                                              
                                               | Default value | Required | 
Since Version |
 
|-------------------|---------------------------------------------------------------------------------------------------------|---------------|----------|---------------|
@@ -68,7 +62,7 @@ If you are using JDBC catalog, you must provide `jdbc-user`, 
`jdbc-password` and
 If you have a JDBC Iceberg catalog prior, you must set `catalog-backend-name` 
to keep consistent with your Jdbc Iceberg catalog name to operate the prior 
namespace and tables.
 
 :::caution
-You must download the corresponding JDBC driver to the 
`catalogs/lakehouse-iceberg/libs` directory.
+You must download the corresponding JDBC driver and place it to the 
`catalogs/lakehouse-iceberg/libs` directory If you are using JDBC backend.
 :::
 
 #### S3
@@ -89,6 +83,19 @@ For other Iceberg s3 properties not managed by Gravitino 
like `s3.sse.type`, you
 Please set `gravitino.iceberg-rest.warehouse` to 
`s3://{bucket_name}/${prefix_name}` for JDBC catalog backend, 
`s3a://{bucket_name}/${prefix_name}` for Hive catalog backend.
 :::
 
+#### Catalog backend security
+
+Users can use the following properties to configure the security of the 
catalog backend if needed. For example, if you are using a Kerberos Hive 
catalog backend, you must set `authentication.type` to `Kerberos` and provide 
`authentication.kerberos.principal` and `authentication.kerberos.keytab-uri`.
+
+| Property name                                      | Description             
                                                                                
                                                                                
                                                         | Default value        
  | Required                                                    | Since Version 
|
+|----------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------|-------------------------------------------------------------|---------------|
+| `authentication.type`                              | The type of 
authentication for Iceberg catalog backend. This configuration only applicable 
for for Hive backend, and only supports `Kerberos`, `simple` currently. As for 
JDBC backend, only username/password authentication was supported now. | 
`simple`               | No                                                     
     | 0.6.0         |
+| `authentication.impersonation-enable`              | Whether to enable 
impersonation for the Iceberg catalog                                           
                                                                                
                                                               | `false`        
        | No                                                          | 0.6.0   
      |
+| `authentication.kerberos.principal`                | The principal of the 
Kerberos authentication                                                         
                                                                                
                                                            | (none)            
     | required if the value of `authentication.type` is Kerberos. | 0.6.0      
   |
+| `authentication.kerberos.keytab-uri`               | The URI of The keytab 
for the Kerberos authentication.                                                
                                                                                
                                                           | (none)             
    | required if the value of `authentication.type` is Kerberos. | 0.6.0       
  |
+| `authentication.kerberos.check-interval-sec`       | The check interval of 
Kerberos credential for Iceberg catalog.                                        
                                                                                
                                                           | 60                 
    | No                                                          | 0.6.0       
  |
+| `authentication.kerberos.keytab-fetch-timeout-sec` | The fetch timeout of 
retrieving Kerberos keytab from `authentication.kerberos.keytab-uri`.           
                                                                                
                                                            | 60                
     | No                                                          | 0.6.0      
   |
+
 ### Catalog operations
 
 Please refer to [Manage Relational Metadata Using 
Gravitino](./manage-relational-metadata-using-gravitino.md#catalog-operations) 
for more details.
diff --git 
a/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/ops/IcebergTableOps.java
 
b/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/ops/IcebergTableOps.java
index 56ca6e505..0720c0abb 100644
--- 
a/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/ops/IcebergTableOps.java
+++ 
b/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/ops/IcebergTableOps.java
@@ -36,6 +36,8 @@ import org.apache.gravitino.iceberg.common.IcebergConfig;
 import org.apache.gravitino.iceberg.common.utils.IcebergCatalogUtil;
 import org.apache.gravitino.utils.IsolatedClassLoader;
 import org.apache.gravitino.utils.MapUtils;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.iceberg.Transaction;
 import org.apache.iceberg.catalog.Catalog;
 import org.apache.iceberg.catalog.Namespace;
@@ -66,6 +68,7 @@ public class IcebergTableOps implements AutoCloseable {
   private final IcebergCatalogBackend catalogBackend;
   private String catalogUri = null;
   private Map<String, String> catalogConfigToClients;
+  private Map<String, String> catalogPropertiesMap;
   private static final Set<String> catalogPropertiesToClientKeys =
       ImmutableSet.of(
           IcebergConstants.IO_IMPL,
@@ -91,6 +94,8 @@ public class IcebergTableOps implements AutoCloseable {
         MapUtils.getFilteredMap(
             icebergConfig.getIcebergCatalogProperties(),
             key -> catalogPropertiesToClientKeys.contains(key));
+
+    this.catalogPropertiesMap = icebergConfig.getIcebergCatalogProperties();
   }
 
   public IcebergTableOps() {
@@ -139,6 +144,19 @@ public class IcebergTableOps implements AutoCloseable {
     return CatalogHandlers.registerTable(catalog, namespace, request);
   }
 
+  /**
+   * Reload hadoop configuration, this is useful when the hadoop configuration 
UserGroupInformation
+   * is shared by multiple threads. UserGroupInformation#authenticationMethod 
was first initialized
+   * in KerberosClient, however, when switching to iceberg-rest thead,
+   * UserGroupInformation#authenticationMethod will be reset to the default 
value; we need to
+   * reinitialize it again.
+   */
+  public void reloadHadoopConf() {
+    Configuration configuration = new Configuration();
+    this.catalogPropertiesMap.forEach(configuration::set);
+    UserGroupInformation.setConfiguration(configuration);
+  }
+
   public LoadTableResponse createTable(Namespace namespace, CreateTableRequest 
request) {
     request.validate();
     if (request.stageCreate()) {
diff --git 
a/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/ops/IcebergTableOpsManager.java
 
b/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/ops/IcebergTableOpsManager.java
index 7b6270be6..57792b89f 100644
--- 
a/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/ops/IcebergTableOpsManager.java
+++ 
b/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/ops/IcebergTableOpsManager.java
@@ -54,7 +54,12 @@ public class IcebergTableOpsManager implements AutoCloseable 
{
    */
   public IcebergTableOps getOps(String rawPrefix) {
     String catalogName = getCatalogName(rawPrefix);
-    return icebergTableOpsCache.get(catalogName, k -> 
provider.getIcebergTableOps(catalogName));
+    IcebergTableOps tableOps =
+        icebergTableOpsCache.get(catalogName, k -> 
provider.getIcebergTableOps(catalogName));
+    // Reload conf to reset UserGroupInformation or icebergTableOps will 
always use
+    // Simple auth.
+    tableOps.reloadHadoopConf();
+    return tableOps;
   }
 
   private String getCatalogName(String rawPrefix) {
diff --git 
a/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/utils/IcebergCatalogUtil.java
 
b/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/utils/IcebergCatalogUtil.java
index 8f171bea6..f6e8b4e36 100644
--- 
a/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/utils/IcebergCatalogUtil.java
+++ 
b/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/utils/IcebergCatalogUtil.java
@@ -99,8 +99,11 @@ public class IcebergCatalogUtil {
       Map<String, String> properties, Configuration conf) {
     try {
       KerberosClient kerberosClient = new KerberosClient(properties, conf);
-      File keytabFile =
-          
kerberosClient.saveKeyTabFileFromUri(Long.valueOf(properties.get("catalog_uuid")));
+
+      // For Iceberg rest server, we haven't set the catalog_uuid, so we set 
it to 0 as there is
+      // only one catalog in the rest server, so it's okay to set it to 0.
+      String catalogUUID = properties.getOrDefault("catalog_uuid", "0");
+      File keytabFile = 
kerberosClient.saveKeyTabFileFromUri(Long.valueOf(catalogUUID));
       kerberosClient.login(keytabFile.getAbsolutePath());
       return kerberosClient;
     } catch (IOException e) {
diff --git 
a/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/IcebergRESTHiveCatalogIT.java
 
b/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/IcebergRESTHiveCatalogIT.java
index 837b40961..2284a9a82 100644
--- 
a/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/IcebergRESTHiveCatalogIT.java
+++ 
b/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/IcebergRESTHiveCatalogIT.java
@@ -32,7 +32,7 @@ import org.junit.jupiter.api.TestInstance.Lifecycle;
 @Tag("gravitino-docker-test")
 @TestInstance(Lifecycle.PER_CLASS)
 public class IcebergRESTHiveCatalogIT extends IcebergRESTServiceIT {
-  private static final ContainerSuite containerSuite = 
ContainerSuite.getInstance();
+  protected static final ContainerSuite containerSuite = 
ContainerSuite.getInstance();
 
   public IcebergRESTHiveCatalogIT() {
     catalogType = IcebergCatalogBackend.HIVE;
diff --git 
a/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/IcebergRestKerberosHiveCatalogIT.java
 
b/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/IcebergRestKerberosHiveCatalogIT.java
new file mode 100644
index 000000000..e647c5959
--- /dev/null
+++ 
b/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/IcebergRestKerberosHiveCatalogIT.java
@@ -0,0 +1,160 @@
+/*
+ * 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.File;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import org.apache.commons.io.FileUtils;
+import org.apache.gravitino.iceberg.common.IcebergCatalogBackend;
+import org.apache.gravitino.iceberg.common.IcebergConfig;
+import org.apache.gravitino.integration.test.container.HiveContainer;
+import org.apache.gravitino.integration.test.util.GravitinoITUtils;
+import org.apache.gravitino.integration.test.util.ITUtils;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.TestInstance;
+import org.junit.jupiter.api.TestInstance.Lifecycle;
+import org.junit.jupiter.api.condition.EnabledIf;
+
+@Tag("gravitino-docker-test")
+@TestInstance(Lifecycle.PER_CLASS)
+@EnabledIf("isEmbedded")
+public class IcebergRestKerberosHiveCatalogIT extends IcebergRESTHiveCatalogIT 
{
+
+  private static final String HIVE_METASTORE_CLIENT_PRINCIPAL = 
"cli@HADOOPKRB";
+  private static final String HIVE_METASTORE_CLIENT_KEYTAB = "/client.keytab";
+
+  private static String tempDir;
+
+  public IcebergRestKerberosHiveCatalogIT() {
+    super();
+  }
+
+  void initEnv() {
+    containerSuite.startKerberosHiveContainer();
+    try {
+
+      // Init kerberos configurations;
+      File baseDir = new File(System.getProperty("java.io.tmpdir"));
+      File file = Files.createTempDirectory(baseDir.toPath(), "test").toFile();
+      file.deleteOnExit();
+      tempDir = file.getAbsolutePath();
+
+      HiveContainer kerberosHiveContainer = 
containerSuite.getKerberosHiveContainer();
+      kerberosHiveContainer
+          .getContainer()
+          .copyFileFromContainer("/etc/admin.keytab", tempDir + 
HIVE_METASTORE_CLIENT_KEYTAB);
+
+      String tmpKrb5Path = tempDir + "/krb5.conf_tmp";
+      String krb5Path = tempDir + "/krb5.conf";
+      
kerberosHiveContainer.getContainer().copyFileFromContainer("/etc/krb5.conf", 
tmpKrb5Path);
+
+      // Modify the krb5.conf and change the kdc and admin_server to the 
container IP
+      String ip = 
containerSuite.getKerberosHiveContainer().getContainerIpAddress();
+      String content = FileUtils.readFileToString(new File(tmpKrb5Path), 
StandardCharsets.UTF_8);
+      content = content.replace("kdc = localhost:88", "kdc = " + ip + ":88");
+      content = content.replace("admin_server = localhost", "admin_server = " 
+ ip + ":749");
+      FileUtils.write(new File(krb5Path), content, StandardCharsets.UTF_8);
+
+      LOG.info("Kerberos kdc config:\n{}, path: {}", content, krb5Path);
+      System.setProperty("java.security.krb5.conf", krb5Path);
+      System.setProperty("sun.security.krb5.debug", "true");
+      System.setProperty("java.security.krb5.realm", "HADOOPKRB");
+      System.setProperty("java.security.krb5.kdc", ip);
+
+      sun.security.krb5.Config.refresh();
+      resetDefaultRealm();
+
+      // Give cli@HADOOPKRB permission to access the hdfs
+      containerSuite
+          .getKerberosHiveContainer()
+          .executeInContainer("hadoop", "fs", "-chown", "-R", "cli", 
"/user/hive/");
+
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  void resetDefaultRealm() {
+    try {
+      String kerberosNameClass = 
"org.apache.hadoop.security.authentication.util.KerberosName";
+      Class<?> cl = Class.forName(kerberosNameClass);
+      cl.getMethod("resetDefaultRealm").invoke(null);
+    } catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  @Override
+  Map<String, String> getCatalogConfig() {
+    Map<String, String> configMap = new HashMap<>();
+
+    configMap.put("gravitino.iceberg-rest.authentication.type", "kerberos");
+    configMap.put(
+        "gravitino.iceberg-rest.authentication.kerberos.principal",
+        HIVE_METASTORE_CLIENT_PRINCIPAL);
+    configMap.put(
+        "gravitino.iceberg-rest.authentication.kerberos.keytab-uri",
+        tempDir + HIVE_METASTORE_CLIENT_KEYTAB);
+    configMap.put("gravitino.iceberg-rest.hive.metastore.sasl.enabled", 
"true");
+    configMap.put(
+        "gravitino.iceberg-rest.hive.metastore.kerberos.principal",
+        "hive/_HOST@HADOOPKRB"
+            .replace("_HOST", 
containerSuite.getKerberosHiveContainer().getHostName()));
+
+    configMap.put("gravitino.iceberg-rest.hadoop.security.authentication", 
"kerberos");
+
+    configMap.put(
+        "gravitino.iceberg-rest.dfs.namenode.kerberos.principal",
+        "hdfs/_HOST@HADOOPKRB"
+            .replace("_HOST", 
containerSuite.getKerberosHiveContainer().getHostName()));
+
+    configMap.put(
+        IcebergConfig.ICEBERG_CONFIG_PREFIX + 
IcebergConfig.CATALOG_BACKEND.getKey(),
+        IcebergCatalogBackend.HIVE.toString().toLowerCase());
+
+    configMap.put(
+        IcebergConfig.ICEBERG_CONFIG_PREFIX + 
IcebergConfig.CATALOG_URI.getKey(),
+        String.format(
+            "thrift://%s:%d",
+            containerSuite.getKerberosHiveContainer().getContainerIpAddress(),
+            HiveContainer.HIVE_METASTORE_PORT));
+
+    configMap.put(
+        IcebergConfig.ICEBERG_CONFIG_PREFIX + 
IcebergConfig.CATALOG_WAREHOUSE.getKey(),
+        GravitinoITUtils.genRandomName(
+            String.format(
+                "hdfs://%s:%d/user/hive/warehouse-hive",
+                
containerSuite.getKerberosHiveContainer().getContainerIpAddress(),
+                HiveContainer.HDFS_DEFAULTFS_PORT)));
+    return configMap;
+  }
+
+  private static boolean isEmbedded() {
+    String mode =
+        System.getProperty(ITUtils.TEST_MODE) == null
+            ? ITUtils.EMBEDDED_TEST_MODE
+            : System.getProperty(ITUtils.TEST_MODE);
+
+    return Objects.equals(mode, ITUtils.EMBEDDED_TEST_MODE);
+  }
+}
diff --git 
a/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/util/IcebergRESTServerManagerForDeploy.java
 
b/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/util/IcebergRESTServerManagerForDeploy.java
index dda2c593e..135713223 100644
--- 
a/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/util/IcebergRESTServerManagerForDeploy.java
+++ 
b/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/util/IcebergRESTServerManagerForDeploy.java
@@ -18,10 +18,14 @@
  */
 package org.apache.gravitino.iceberg.integration.test.util;
 
+import java.io.File;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Optional;
+import java.util.UUID;
 import java.util.concurrent.Future;
+import org.apache.commons.io.FileUtils;
 import org.apache.gravitino.integration.test.util.CommandExecutor;
 import org.apache.gravitino.integration.test.util.JdbcDriverDownloader;
 import org.apache.gravitino.integration.test.util.ProcessData;
@@ -51,12 +55,39 @@ public class IcebergRESTServerManagerForDeploy extends 
IcebergRESTServerManager
         SQLITE_DRIVER_DOWNLOAD_URL,
         Paths.get(icebergRESTServerHome.toString(), "iceberg-rest-server", 
"libs").toString());
 
-    String cmd = String.format("%s/bin/%s start", 
icebergRESTServerHome.toString(), SCRIPT_NAME);
-    CommandExecutor.executeCommandLocalHost(
-        cmd,
-        false,
-        ProcessData.TypesOfData.OUTPUT,
-        ImmutableMap.of("GRAVITINO_HOME", icebergRESTServerHome.toString()));
+    String gravitinoRestStartShell = icebergRESTServerHome.toString() + 
"/bin/" + SCRIPT_NAME;
+    String krb5Path = System.getProperty("java.security.krb5.conf");
+    if (krb5Path != null) {
+      LOG.info("java.security.krb5.conf: {}", krb5Path);
+      String modifiedGravitinoStartShell =
+          String.format(
+              "%s/bin/gravitino-iceberg-rest-server_%s.sh",
+              icebergRESTServerHome.toString(), UUID.randomUUID());
+      // Replace '/etc/krb5.conf' with the one in the test
+      try {
+        String content =
+            FileUtils.readFileToString(new File(gravitinoRestStartShell), 
StandardCharsets.UTF_8);
+        content =
+            content.replace(
+                "#JAVA_OPTS+=\" -Djava.security.krb5.conf=/etc/krb5.conf\"",
+                String.format("JAVA_OPTS+=\" -Djava.security.krb5.conf=%s\"", 
krb5Path));
+        File tmp = new File(modifiedGravitinoStartShell);
+        FileUtils.write(tmp, content, StandardCharsets.UTF_8);
+        tmp.setExecutable(true);
+        LOG.info("modifiedGravitinoStartShell content: \n{}", content);
+        CommandExecutor.executeCommandLocalHost(
+            modifiedGravitinoStartShell + " start", false, 
ProcessData.TypesOfData.OUTPUT);
+      } catch (Exception e) {
+        LOG.error("Can replace /etc/krb5.conf with real kerberos 
configuration", e);
+      }
+    } else {
+      String cmd = String.format("%s/bin/%s start", 
icebergRESTServerHome.toString(), SCRIPT_NAME);
+      CommandExecutor.executeCommandLocalHost(
+          cmd,
+          false,
+          ProcessData.TypesOfData.OUTPUT,
+          ImmutableMap.of("GRAVITINO_HOME", icebergRESTServerHome.toString()));
+    }
     return Optional.empty();
   }
 


Reply via email to