diff --git a/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStoreClient.java b/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStoreClient.java index c7e1044589..205c867db1 100644 --- a/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStoreClient.java +++ b/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStoreClient.java @@ -3346,7 +3346,10 @@ public CompactionResponse compact2(String dbname, String tableName, String parti @Override public ShowCompactResponse showCompactions() throws TException { - return client.show_compact(new ShowCompactRequest()); + ShowCompactResponse response = client.show_compact(new ShowCompactRequest()); + response.setCompacts(FilterUtils.filterCompactionsIfEnabled(isClientFilterEnabled, + filterHook, getDefaultCatalog(conf), response.getCompacts())); + return response; } @Deprecated diff --git a/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/utils/FilterUtils.java b/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/utils/FilterUtils.java index d9da00dd21..d25ed801a0 100644 --- a/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/utils/FilterUtils.java +++ b/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/utils/FilterUtils.java @@ -17,8 +17,7 @@ */ package org.apache.hadoop.hive.metastore.utils; -import java.util.Collections; -import java.util.List; + import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.hadoop.hive.metastore.utils.MetaStoreUtils.CATALOG_DB_SEPARATOR; @@ -31,6 +30,13 @@ import org.apache.hadoop.hive.metastore.api.PartitionSpec; import org.apache.hadoop.hive.metastore.api.Table; import org.apache.hadoop.hive.metastore.api.TableMeta; +import org.apache.hadoop.hive.metastore.api.ShowCompactResponseElement; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * Utilities common to Filtering operations. @@ -371,4 +377,69 @@ public static void checkDbAndTableFilters(boolean isFilterEnabled, } } + /** + * Filter the list of compactions if filtering is enabled. Otherwise, return original list + * + * @param isFilterEnabled true: filtering is enabled; false: filtering is disabled. + * @param filterHook the object that does filtering + * @param compactions the list of compactions + * @return the list of compactions that user has access or original list if filtering is disabled; + * @throws MetaException + */ + public static List filterCompactionsIfEnabled( + boolean isFilterEnabled, + MetaStoreFilterHook filterHook, String catName, List compactions) + throws MetaException { + + if (isFilterEnabled) { + List result = new ArrayList<>(compactions.size()); + + // DBName -> List of TableNames map used for checking access rights for non partitioned tables + Map> nonPartTables = new HashMap<>(); + // DBName -> TableName -> List of PartitionNames map used for checking access rights for + // partitioned tables + Map>> partTables = new HashMap<>(); + for (ShowCompactResponseElement c : compactions) { + if (c.getPartitionname() == null) { + nonPartTables.computeIfAbsent(c.getDbname(), k -> new ArrayList<>()); + if (!nonPartTables.get(c.getDbname()).contains(c.getTablename())) { + nonPartTables.get(c.getDbname()).add(c.getTablename()); + } + } else { + partTables.computeIfAbsent(c.getDbname(), k -> new HashMap<>()); + partTables.get(c.getDbname()).computeIfAbsent(c.getTablename(), k -> new ArrayList<>()); + if (!partTables.get(c.getDbname()).get(c.getTablename()).contains(c.getPartitionname())) { + partTables.get(c.getDbname()).get(c.getTablename()).add(c.getPartitionname()); + } + } + } + // Checking non partitioned table access rights + for (Map.Entry> e : nonPartTables.entrySet()) { + nonPartTables.put(e.getKey(), filterHook.filterTableNames(catName, e.getKey(), e.getValue())); + } + // Checking partitioned table access rights + for (Map.Entry>> dbName : partTables.entrySet()) { + for (Map.Entry> tableName : dbName.getValue().entrySet()) { + dbName.getValue().put(tableName.getKey(), + filterHook.filterPartitionNames(catName, dbName.getKey(), tableName.getKey(), tableName.getValue())); + } + } + + // Add the compactions to the response only we have access right + for (ShowCompactResponseElement c : compactions) { + if (c.getPartitionname() == null) { + if (nonPartTables.get(c.getDbname()).contains(c.getTablename())) { + result.add(c); + } + } else { + if (partTables.get(c.getDbname()).get(c.getTablename()).contains(c.getPartitionname())) { + result.add(c); + } + } + } + return result; + } else { + return compactions; + } + } } diff --git a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java index b6de1460a5..6483a3839b 100644 --- a/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java +++ b/standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java @@ -8249,7 +8249,10 @@ public CompactionResponse compact2(CompactionRequest rqst) throws TException { @Override public ShowCompactResponse show_compact(ShowCompactRequest rqst) throws TException { - return getTxnHandler().showCompact(rqst); + ShowCompactResponse response = getTxnHandler().showCompact(rqst); + response.setCompacts(FilterUtils.filterCompactionsIfEnabled(isServerFilterEnabled, + filterHook, getDefaultCatalog(conf), response.getCompacts())); + return response; } @Override diff --git a/standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/TestFilterHooks.java b/standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/TestFilterHooks.java index 23faa7444a..ae8d7a06dd 100644 --- a/standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/TestFilterHooks.java +++ b/standalone-metastore/metastore-server/src/test/java/org/apache/hadoop/hive/metastore/TestFilterHooks.java @@ -19,23 +19,26 @@ package org.apache.hadoop.hive.metastore; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import org.apache.hadoop.hive.metastore.annotation.MetastoreUnitTest; +import org.apache.hadoop.hive.metastore.api.CompactionType; +import org.apache.hadoop.hive.metastore.api.Database; +import org.apache.hadoop.hive.metastore.api.MetaException; +import org.apache.hadoop.hive.metastore.api.NoSuchObjectException; +import org.apache.hadoop.hive.metastore.api.Partition; import org.apache.hadoop.hive.metastore.api.PartitionSpec; +import org.apache.hadoop.hive.metastore.api.Table; import org.apache.hadoop.hive.metastore.api.TableMeta; import org.apache.hadoop.hive.metastore.client.builder.DatabaseBuilder; import org.apache.hadoop.hive.metastore.client.builder.TableBuilder; import org.apache.hadoop.hive.metastore.conf.MetastoreConf; import org.apache.hadoop.hive.metastore.conf.MetastoreConf.ConfVars; +import org.apache.hadoop.hive.metastore.txn.TxnDbUtil; import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.hive.metastore.api.Database; -import org.apache.hadoop.hive.metastore.api.MetaException; -import org.apache.hadoop.hive.metastore.api.NoSuchObjectException; -import org.apache.hadoop.hive.metastore.api.Partition; -import org.apache.hadoop.hive.metastore.api.Table; import org.apache.hadoop.util.StringUtils; import org.junit.Test; @@ -235,6 +238,11 @@ protected void creatEnv(Configuration conf) throws Exception { .inTable(tab2) .addValue("value2") .addToTable(client, conf); + + TxnDbUtil.cleanDb(conf); + TxnDbUtil.prepDb(conf); + client.compact2(DBNAME1, TAB1, null, CompactionType.MAJOR, new HashMap<>()); + client.compact2(DBNAME1, TAB2, "name=value1", CompactionType.MINOR, new HashMap<>()); } /** @@ -261,6 +269,8 @@ public void testHMSServerWithoutFilter() throws Exception { assertNotNull(client.getPartition(DBNAME1, TAB2, "name=value1")); assertEquals(1, client.getPartitionsByNames(DBNAME1, TAB2, Lists.newArrayList("name=value1")).size()); + + assertEquals(2, client.showCompactions().getCompacts().size()); } /** @@ -279,11 +289,12 @@ public void testHMSServerWithFilter() throws Exception { testFilterForDb(true); testFilterForTables(true); testFilterForPartition(true); + testFilterForCompaction(); } /** * Disable filtering at HMS client - * By default, the HMS server side filtering is diabled, so we can see HMS client filtering behavior + * By default, the HMS server side filtering is disabled, so we can see HMS client filtering behavior * @throws Exception */ @Test @@ -305,6 +316,8 @@ public void testHMSClientWithoutFilter() throws Exception { assertNotNull(client.getPartition(DBNAME1, TAB2, "name=value1")); assertEquals(1, client.getPartitionsByNames(DBNAME1, TAB2, Lists.newArrayList("name=value1")).size()); + + assertEquals(2, client.showCompactions().getCompacts().size()); } /** @@ -322,6 +335,7 @@ public void testHMSClientWithFilter() throws Exception { testFilterForDb(false); testFilterForTables(false); testFilterForPartition(false); + testFilterForCompaction(); } protected void testFilterForDb(boolean filterAtServer) throws Exception { @@ -386,4 +400,8 @@ protected void testFilterForPartition(boolean filterAtServer) throws Exception { Lists.newArrayList("name=value1")).size()); } } + + protected void testFilterForCompaction() throws Exception { + assertEquals(0, client.showCompactions().getCompacts().size()); + } }