deniskuzZ commented on code in PR #6789:
URL: https://github.com/apache/hive/pull/6789#discussion_r4400138483


##########
iceberg/iceberg-handler/src/main/java/org/apache/iceberg/mr/hive/HiveIcebergStorageHandler.java:
##########
@@ -279,8 +279,23 @@ public HiveAuthorizationProvider 
getAuthorizationProvider() {
 
   @Override
   public void configureInputJobCredentials(TableDesc tableDesc, Map<String, 
String> secrets) {
-    RestCatalogScanPlanningUtil.propagateCatalogSecretsToJob(tableDesc, 
secrets, conf);
-    IcebergVendedCredentialUtil.propagateVendedCredentialsToJob(tableDesc, 
secrets, conf);
+    Properties props = tableDesc.getProperties();
+    if (props == null) {
+      return;
+    }
+    if (!IcebergVendedCredentialUtil.requestsVendedCredentials(props, conf) &&
+        !RestCatalogScanPlanningUtil.isServerSideScanPlanningEnabled(conf)) {
+      return;
+    }
+    Table table;
+    try {
+      table = IcebergVendedCredentialUtil.getTableWithVendedCredentials(props, 
conf);
+    } catch (NoSuchTableException e) {
+      // Table may not exist yet for CTAS; there is nothing to plan or vend 
credentials for.
+      return;
+    }
+    RestCatalogScanPlanningUtil.propagateCatalogSecretsToJob(table, tableDesc, 
secrets, conf);

Review Comment:
   Could we simplify how credentials reach the job? Right now 
`configureInputJobCredentials` passes `table` + `tableDesc` into two helpers 
that each re-check null props, re-evaluate their own gate, and read 
`CATALOG_NAME` (one with the session-default fallback, one raw). Underneath, 
`propagateToJob` takes two out-param maps and callers pass `null` to select a 
half.
   
   Proposal:
   
   **1. Return both halves instead of writing into nullable maps**
   
   ```java
   /** Vended credentials split per HIVE-20651: plain job properties vs job 
secrets. */
   record VendedJobConf(Map<String, String> properties, Map<String, String> 
secrets) {
     static final VendedJobConf EMPTY = new VendedJobConf(Map.of(), Map.of());
   }
   
   static VendedJobConf toJobConf(Table table, String catalogName, 
Configuration conf) {
     List<StorageCredential> credentials =
         withConfigurationOverrides(catalogName, extractCredentials(table), 
conf);
     if (credentials.isEmpty()) {
       return VendedJobConf.EMPTY;
     }
     Map<String, String> properties = new LinkedHashMap<>();
     Map<String, String> secrets = new LinkedHashMap<>();
     secrets.put(
         InputFormatConfig.vendedCredentialsKey(table.name()),
         serializeToSingleLineBase64(Lists.newArrayList(credentials)));
     for (StorageCredential credential : credentials) {
       addCredentialEntries(catalogName, credential, properties, secrets, conf);
     }
     return new VendedJobConf(properties, secrets);
   }
   ```
   
   The `!= null` checks in `addCredentialEntries` / `addCredentialEntry` go 
away, and `propagateToJob` / `propagateVendedCredentialsToJob` can be dropped.
   
   **2. Let `configureInputJobCredentials` own the decisions**
   
   ```java
   @Override
   public void configureInputJobCredentials(TableDesc tableDesc, Map<String, 
String> secrets) {
     Properties props = tableDesc.getProperties();
     if (props == null) {
       return;
     }
     boolean vendedCredentials = 
IcebergVendedCredentialUtil.requestsVendedCredentials(props, conf);
     if (!vendedCredentials && 
!RestCatalogScanPlanningUtil.isServerSideScanPlanningEnabled(conf)) {
       return;
     }
     Table table;
     try {
       table = IcebergVendedCredentialUtil.getTableWithVendedCredentials(props, 
conf);
     } catch (NoSuchTableException e) {
       // Table may not exist yet for CTAS; there is nothing to plan or vend 
credentials for.
       return;
     }
     String catalogName = HiveTableUtil.resolveCatalogName(conf, 
props.getProperty(InputFormatConfig.CATALOG_NAME));
   
     if (RestCatalogScanPlanningUtil.shouldPlanServerSide(conf, table)) {
       RestCatalogScanPlanningUtil.propagateCatalogSecretsToJob(catalogName, 
secrets, conf);
     }
     if (vendedCredentials) {
       secrets.putAll(IcebergVendedCredentialUtil.toJobConf(table, catalogName, 
conf).secrets());
     }
   }
   ```
   
   with `propagateCatalogSecretsToJob` reduced to the copy itself:
   
   ```java
   public static void propagateCatalogSecretsToJob(
       String catalogName, Map<String, String> jobSecrets, Configuration 
sessionConf) {
     if (StringUtils.isEmpty(catalogName)) {
       return;
     }
     String catalogPrefix = IcebergCatalogProperties.CATALOG_CONFIG_PREFIX + 
catalogName + ".";
     sessionConf.forEach(entry -> {
       if (entry.getKey().startsWith(catalogPrefix)) {
         jobSecrets.put(entry.getKey(), entry.getValue());
       }
     });
   }
   ```
   
   **3. Other call sites**
   
   ```java
   // configureInputJobProperties
   if (isVendedCredentials) {
     IcebergVendedCredentialUtil.toJobConf(table, catalogName, configuration)
         .properties().forEach(map::putIfAbsent);
     table = IcebergVendedCredentialUtil.secretFreeCopy(table, configuration);
   }
   
   // refreshVendedCredentialsIfMissing
   VendedJobConf vended = toJobConf(table, catalogName, configuration);
   vended.properties().forEach(jobConf::set);
   mergeJobSecrets(tableDesc, vended.secrets());
   ```
   
   Here, `catalogName` should be resolved the same way in all three places 
(`HiveTableUtil.resolveCatalogName`). Today the secrets path falls back to the 
session default, the vended paths use the raw `CATALOG_NAME` (null for 
default-catalog tables, so `withConfigurationOverrides` skips session 
overrides), and `refreshVendedCredentialsIfMissing` returns early on null. Is 
that difference intended?
   
   Tests: 
`TestRestCatalogScanPlanningUtil.propagateCatalogSecretsToJobSkipsTableNotPlannedServerSide`
 would move to the storage handler (the gate now lives there), and the IT call 
at `TestHiveIcebergServerSideScanPlanningServerIT:404` needs the new signature.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to