From 1e82794236e724e45f04c8e08589c728879cccd3 Mon Sep 17 00:00:00 2001 From: okumin Date: Mon, 4 May 2026 17:29:15 +0900 Subject: [PATCH 1/7] HIVE-29593: Server-side Metrics Reporting for Iceberg operations --- .../hive/metastore/conf/MetastoreConf.java | 4 ++ .../iceberg/rest/HMSCatalogAdapter.java | 27 ++++++++--- .../iceberg/rest/HMSCatalogFactory.java | 23 ++++++++- .../iceberg/rest/HMSCatalogServlet.java | 11 ++++- .../rest/metrics/IcebergMetricsReporter.java | 40 ++++++++++++++++ .../rest/metrics/LoggingMetricsReporter.java | 48 +++++++++++++++++++ .../rest/extension/RESTCatalogServer.java | 4 ++ 7 files changed, 147 insertions(+), 10 deletions(-) create mode 100644 standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/metrics/IcebergMetricsReporter.java create mode 100644 standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/metrics/LoggingMetricsReporter.java diff --git a/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/conf/MetastoreConf.java b/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/conf/MetastoreConf.java index 10015f74837c..ca3c7c3c8646 100644 --- a/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/conf/MetastoreConf.java +++ b/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/conf/MetastoreConf.java @@ -1935,6 +1935,10 @@ public enum ConfVars { "hive.metastore.iceberg.catalog.cache.expiry", -1, "HMS Iceberg Catalog cache expiry." ), + ICEBERG_CATALOG_METRICS_REPORTERS("metastore.iceberg.catalog.metrics.reporters", + "hive.metastore.iceberg.catalog.metrics.reporters", "org.apache.iceberg.rest.metrics.LoggingMetricsReporter", + "A comma separated list of custom Iceberg Metrics Reporting plugins." + ), HTTPSERVER_THREADPOOL_MIN("hive.metastore.httpserver.threadpool.min", "hive.metastore.httpserver.threadpool.min", 8, "HMS embedded HTTP server minimum number of threads." diff --git a/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogAdapter.java b/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogAdapter.java index 73d23ae5daf0..046f11a18266 100644 --- a/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogAdapter.java +++ b/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogAdapter.java @@ -20,6 +20,9 @@ package org.apache.iceberg.rest; import com.google.common.base.Preconditions; + +import java.io.IOException; +import java.time.Clock; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -52,6 +55,7 @@ import org.apache.iceberg.relocated.com.google.common.collect.ImmutableMap; import org.apache.iceberg.relocated.com.google.common.collect.Lists; import org.apache.iceberg.rest.HTTPRequest.HTTPMethod; +import org.apache.iceberg.rest.metrics.IcebergMetricsReporter; import org.apache.iceberg.rest.requests.CommitTransactionRequest; import org.apache.iceberg.rest.requests.CreateNamespaceRequest; import org.apache.iceberg.rest.requests.CreateTableRequest; @@ -99,17 +103,21 @@ public class HMSCatalogAdapter implements RESTClient { .put(CommitStateUnknownException.class, 500) .buildOrThrow(); + private final String catalogName; private final Catalog catalog; private final SupportsNamespaces asNamespaceCatalog; private final ViewCatalog asViewCatalog; + private final List metricsReporters; + private final Clock clock = Clock.systemUTC(); - - public HMSCatalogAdapter(Catalog catalog) { + public HMSCatalogAdapter(String catalogName, Catalog catalog, List metricsReporters) { Preconditions.checkArgument(catalog instanceof SupportsNamespaces); Preconditions.checkArgument(catalog instanceof ViewCatalog); + this.catalogName = catalogName; this.catalog = catalog; this.asNamespaceCatalog = (SupportsNamespaces) catalog; this.asViewCatalog = (ViewCatalog) catalog; + this.metricsReporters = metricsReporters; } enum Route { @@ -315,9 +323,11 @@ private RESTResponse renameTable(Object body) { return null; } - private RESTResponse reportMetrics(Object body) { - // nothing to do here other than checking that we're getting the correct request - castRequest(ReportMetricsRequest.class, body); + private RESTResponse reportMetrics(Map vars, Object body) { + final var ident = identFromPathVars(vars); + final var report = castRequest(ReportMetricsRequest.class, body).report(); + final var receivedAt = clock.instant(); + metricsReporters.forEach(reporter -> reporter.report(catalogName, ident, report, receivedAt)); return null; } @@ -456,7 +466,7 @@ private T handleRequest( return (T) renameTable(body); case REPORT_METRICS: - return (T) reportMetrics(body); + return (T) reportMetrics(vars, body); case COMMIT_TRANSACTION: return (T) commitTransaction(body); @@ -574,8 +584,11 @@ public T postForm( } @Override - public void close() { + public void close() throws IOException { // The caller is responsible for closing the underlying catalog backing this REST catalog. + for (IcebergMetricsReporter reporter : metricsReporters) { + reporter.close(); + } } private static class BadResponseType extends RuntimeException { diff --git a/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogFactory.java b/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogFactory.java index d21f239f3416..77ed09caba09 100644 --- a/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogFactory.java +++ b/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogFactory.java @@ -18,6 +18,8 @@ */ package org.apache.iceberg.rest; +import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; @@ -32,6 +34,8 @@ import org.apache.iceberg.CatalogProperties; import org.apache.iceberg.catalog.Catalog; import org.apache.iceberg.hive.HiveCatalog; +import org.apache.iceberg.rest.metrics.IcebergMetricsReporter; +import org.apache.iceberg.rest.metrics.LoggingMetricsReporter; /** * Catalog & servlet factory. @@ -112,7 +116,24 @@ private HttpServlet createServlet(Catalog catalog) { // Iceberg REST client uses "catalog" by default List scopes = Collections.singletonList("catalog"); ServletSecurity security = new ServletSecurity(AuthType.fromString(authType), configuration, req -> scopes); - return security.proxy(new HMSCatalogServlet(new HMSCatalogAdapter(catalog))); + String catalogName = MetastoreConf.getVar(configuration, ConfVars.CATALOG_DEFAULT); + List reporters = createReporters(); + return security.proxy(new HMSCatalogServlet(new HMSCatalogAdapter(catalogName, catalog, reporters))); + } + + private List createReporters() { + final var classes = configuration.getClasses( + ConfVars.ICEBERG_CATALOG_METRICS_REPORTERS.getVarname(), + LoggingMetricsReporter.class + ); + return Arrays.stream(classes).map(clazz -> { + try { + final var constructor = clazz.getDeclaredConstructor(Configuration.class); + return (IcebergMetricsReporter) constructor.newInstance(configuration); + } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { + throw new IllegalArgumentException("Failed to instantiate IcebergMetricsReporter: {}" + clazz.getName(), e); + } + }).toList(); } /** diff --git a/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogServlet.java b/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogServlet.java index 6140f40b2de5..5b144ba958f3 100644 --- a/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogServlet.java +++ b/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogServlet.java @@ -147,8 +147,15 @@ static ServletRequestContext from(HttpServletRequest request) throws IOException Route route = routeContext.first(); Object requestBody = null; if (route.requestClass() != null) { - requestBody = - RESTObjectMapper.mapper().readValue(request.getReader(), route.requestClass()); + try { + requestBody = RESTObjectMapper.mapper().readValue(request.getReader(), route.requestClass()); + } catch (Exception e) { + return new ServletRequestContext(ErrorResponse.builder() + .responseCode(400) + .withType(e.getClass().getSimpleName()) + .withMessage(e.getMessage()) + .build()); + } } Map queryParams = diff --git a/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/metrics/IcebergMetricsReporter.java b/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/metrics/IcebergMetricsReporter.java new file mode 100644 index 000000000000..d7f781e36233 --- /dev/null +++ b/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/metrics/IcebergMetricsReporter.java @@ -0,0 +1,40 @@ +/* + * 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.iceberg.rest.metrics; + +import org.apache.iceberg.catalog.TableIdentifier; +import org.apache.iceberg.metrics.MetricsReport; + +import java.io.Closeable; +import java.time.Instant; + +/** + * An event reporter for Iceberg metrics. + */ +public interface IcebergMetricsReporter extends Closeable { + /** + * Report an event. + * + * @param catalog the catalog name + * @param identifier the table identifier + * @param report the event + * @param receivedAt the timestamp when the Iceberg REST Catalog received the event + */ + void report(String catalog, TableIdentifier identifier, MetricsReport report, Instant receivedAt); +} diff --git a/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/metrics/LoggingMetricsReporter.java b/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/metrics/LoggingMetricsReporter.java new file mode 100644 index 000000000000..c8ce1fc2b48c --- /dev/null +++ b/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/metrics/LoggingMetricsReporter.java @@ -0,0 +1,48 @@ +/* + * 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.iceberg.rest.metrics; + +import org.apache.hadoop.conf.Configuration; +import org.apache.iceberg.catalog.TableIdentifier; +import org.apache.iceberg.metrics.MetricsReport; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.time.Instant; + +/** + * A metrics reporter that logs events. + */ +public class LoggingMetricsReporter implements IcebergMetricsReporter { + private static final Logger LOG = LoggerFactory.getLogger(LoggingMetricsReporter.class); + + public LoggingMetricsReporter(Configuration conf) { + } + + @Override + public void report(String catalog, TableIdentifier identifier, MetricsReport report, Instant receivedAt) { + LOG.info("Event reported at {}: catalog={}, table={}, report={}", receivedAt, catalog, identifier, report); + } + + @Override + public void close() { + LOG.info("Closing {}", getClass().getName()); + } +} diff --git a/standalone-metastore/metastore-rest-catalog/src/test/java/org/apache/iceberg/rest/extension/RESTCatalogServer.java b/standalone-metastore/metastore-rest-catalog/src/test/java/org/apache/iceberg/rest/extension/RESTCatalogServer.java index 836e18cb8e77..13e322bcd4b0 100644 --- a/standalone-metastore/metastore-rest-catalog/src/test/java/org/apache/iceberg/rest/extension/RESTCatalogServer.java +++ b/standalone-metastore/metastore-rest-catalog/src/test/java/org/apache/iceberg/rest/extension/RESTCatalogServer.java @@ -19,6 +19,7 @@ package org.apache.iceberg.rest.extension; +import java.nio.file.Files; import java.nio.file.Path; import java.util.UUID; import org.apache.hadoop.conf.Configuration; @@ -60,6 +61,9 @@ public void start(Configuration conf) throws Exception { String uniqueTestKey = String.format("RESTCatalogServer_%s", UUID.randomUUID()); warehouseDir = Path.of(MetaStoreTestUtils.getTestWarehouseDir(uniqueTestKey)); + Files.createDirectories(warehouseDir); + System.setProperty("derby.stream.error.file", + warehouseDir.resolve("derby.log").toAbsolutePath().toString()); String jdbcUrl = String.format("jdbc:derby:memory:%s;create=true", warehouseDir.resolve("metastore_db").toAbsolutePath()); MetastoreConf.setVar(conf, ConfVars.CONNECT_URL_KEY, jdbcUrl); From cba14c801ce74dadaa877e477b2dc5cfabdaa7ae Mon Sep 17 00:00:00 2001 From: okumin Date: Tue, 5 May 2026 11:39:07 +0900 Subject: [PATCH 2/7] Remove unused import --- .../org/apache/iceberg/rest/metrics/LoggingMetricsReporter.java | 1 - 1 file changed, 1 deletion(-) diff --git a/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/metrics/LoggingMetricsReporter.java b/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/metrics/LoggingMetricsReporter.java index c8ce1fc2b48c..afc37cd40665 100644 --- a/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/metrics/LoggingMetricsReporter.java +++ b/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/metrics/LoggingMetricsReporter.java @@ -24,7 +24,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; import java.time.Instant; /** From 49704bf4fc862348037d1d598bcb3a012fe75b07 Mon Sep 17 00:00:00 2001 From: okumin Date: Tue, 5 May 2026 18:12:53 +0900 Subject: [PATCH 3/7] Fix an error message --- .../main/java/org/apache/iceberg/rest/HMSCatalogFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogFactory.java b/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogFactory.java index 77ed09caba09..6beeb923bedf 100644 --- a/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogFactory.java +++ b/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogFactory.java @@ -131,7 +131,7 @@ private List createReporters() { final var constructor = clazz.getDeclaredConstructor(Configuration.class); return (IcebergMetricsReporter) constructor.newInstance(configuration); } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { - throw new IllegalArgumentException("Failed to instantiate IcebergMetricsReporter: {}" + clazz.getName(), e); + throw new IllegalArgumentException("Failed to instantiate IcebergMetricsReporter: " + clazz.getName(), e); } }).toList(); } From d896dfad835f8a718a4f5dbb6ceb7e7299b47b77 Mon Sep 17 00:00:00 2001 From: okumin Date: Tue, 5 May 2026 18:14:36 +0900 Subject: [PATCH 4/7] Add a type name for readability --- .../main/java/org/apache/iceberg/rest/HMSCatalogAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogAdapter.java b/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogAdapter.java index 046f11a18266..fa8b3a259ad1 100644 --- a/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogAdapter.java +++ b/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogAdapter.java @@ -324,7 +324,7 @@ private RESTResponse renameTable(Object body) { } private RESTResponse reportMetrics(Map vars, Object body) { - final var ident = identFromPathVars(vars); + final TableIdentifier ident = identFromPathVars(vars); final var report = castRequest(ReportMetricsRequest.class, body).report(); final var receivedAt = clock.instant(); metricsReporters.forEach(reporter -> reporter.report(catalogName, ident, report, receivedAt)); From 69c2efd90e4607a9d21dc1ebf6c4a0c811779d23 Mon Sep 17 00:00:00 2001 From: okumin Date: Tue, 5 May 2026 18:20:08 +0900 Subject: [PATCH 5/7] Invoke all IcebergMetricsReporter#close --- .../org/apache/iceberg/rest/HMSCatalogAdapter.java | 11 +++++++++-- .../org/apache/iceberg/rest/HMSCatalogServlet.java | 6 ++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogAdapter.java b/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogAdapter.java index fa8b3a259ad1..252bde85a5eb 100644 --- a/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogAdapter.java +++ b/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogAdapter.java @@ -76,12 +76,15 @@ import org.apache.iceberg.rest.responses.UpdateNamespacePropertiesResponse; import org.apache.iceberg.util.Pair; import org.apache.iceberg.util.PropertyUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Original @ RESTCatalogAdapter.java * Adaptor class to translate REST requests into {@link Catalog} API calls. */ public class HMSCatalogAdapter implements RESTClient { + private static final Logger LOG = LoggerFactory.getLogger(HMSCatalogAdapter.class); private static final Splitter SLASH = Splitter.on('/'); private static final Map, Integer> EXCEPTION_ERROR_CODES = @@ -584,10 +587,14 @@ public T postForm( } @Override - public void close() throws IOException { + public void close() { // The caller is responsible for closing the underlying catalog backing this REST catalog. for (IcebergMetricsReporter reporter : metricsReporters) { - reporter.close(); + try { + reporter.close(); + } catch (IOException e) { + LOG.error("Failed to close metrics reporter: {}", reporter, e); + } } } diff --git a/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogServlet.java b/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogServlet.java index 5b144ba958f3..e608ba5229a6 100644 --- a/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogServlet.java +++ b/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogServlet.java @@ -100,6 +100,12 @@ private Consumer handle(HttpServletResponse response) { }; } + @Override + public void destroy() { + super.destroy(); + restCatalogAdapter.close(); + } + public static class ServletRequestContext { private HTTPMethod method; private String path; From e7941bcb4c7ac845d3820c421ed971539bfb82bc Mon Sep 17 00:00:00 2001 From: okumin Date: Tue, 5 May 2026 19:28:15 +0900 Subject: [PATCH 6/7] Use MetastoreConf.getClasses --- .../hive/metastore/conf/MetastoreConf.java | 18 ++++++++++++++++++ .../apache/iceberg/rest/HMSCatalogFactory.java | 6 +----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/conf/MetastoreConf.java b/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/conf/MetastoreConf.java index ca3c7c3c8646..d4be4303016b 100644 --- a/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/conf/MetastoreConf.java +++ b/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/conf/MetastoreConf.java @@ -2520,6 +2520,24 @@ public static Class getClass(Configuration conf, ConfVars var, conf.getClass(var.varname, defaultValue, xface); } + /** + * Get class instances based on a configuration value + * @param conf configuration file to retrieve it from + * @param var variable to retrieve + * @return instances of the classes + */ + public static Class[] getClasses(Configuration conf, ConfVars var) { + assert var.defaultVal.getClass() == String.class; + Class defaultClass; + try { + defaultClass = Class.forName((String) var.defaultVal); + } catch (ClassNotFoundException e) { + throw new RuntimeException("The default class " + var.defaultVal + " does not exist"); + } + String val = conf.get(var.varname); + return val == null ? conf.getClasses(var.hiveName, defaultClass) : conf.getClasses(var.varname, defaultClass); + } + /** * Set the class name in the configuration file * @param conf configuration file to set it in diff --git a/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogFactory.java b/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogFactory.java index 6beeb923bedf..54e0ec20267c 100644 --- a/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogFactory.java +++ b/standalone-metastore/metastore-rest-catalog/src/main/java/org/apache/iceberg/rest/HMSCatalogFactory.java @@ -35,7 +35,6 @@ import org.apache.iceberg.catalog.Catalog; import org.apache.iceberg.hive.HiveCatalog; import org.apache.iceberg.rest.metrics.IcebergMetricsReporter; -import org.apache.iceberg.rest.metrics.LoggingMetricsReporter; /** * Catalog & servlet factory. @@ -122,10 +121,7 @@ private HttpServlet createServlet(Catalog catalog) { } private List createReporters() { - final var classes = configuration.getClasses( - ConfVars.ICEBERG_CATALOG_METRICS_REPORTERS.getVarname(), - LoggingMetricsReporter.class - ); + final var classes = MetastoreConf.getClasses(configuration, ConfVars.ICEBERG_CATALOG_METRICS_REPORTERS); return Arrays.stream(classes).map(clazz -> { try { final var constructor = clazz.getDeclaredConstructor(Configuration.class); From 60bbbc1b943b5ed925629cf6c7706724e919627a Mon Sep 17 00:00:00 2001 From: okumin Date: Tue, 5 May 2026 23:42:42 +0900 Subject: [PATCH 7/7] Address checkstyle issues --- .../hive/metastore/conf/MetastoreConf.java | 23 ++++++++++++------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/conf/MetastoreConf.java b/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/conf/MetastoreConf.java index d4be4303016b..8f8befd83480 100644 --- a/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/conf/MetastoreConf.java +++ b/standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/conf/MetastoreConf.java @@ -33,6 +33,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.google.common.base.Preconditions; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hive.common.ZooKeeperHiveHelper; import org.apache.hadoop.hive.metastore.utils.StringUtils; @@ -2521,21 +2522,27 @@ public static Class getClass(Configuration conf, ConfVars var, } /** - * Get class instances based on a configuration value + * Get class instances based on a configuration value. + * * @param conf configuration file to retrieve it from - * @param var variable to retrieve + * @param confVar variable to retrieve * @return instances of the classes */ - public static Class[] getClasses(Configuration conf, ConfVars var) { - assert var.defaultVal.getClass() == String.class; + public static Class[] getClasses(Configuration conf, ConfVars confVar) { + Preconditions.checkArgument(confVar.defaultVal.getClass() == String.class); Class defaultClass; try { - defaultClass = Class.forName((String) var.defaultVal); + defaultClass = Class.forName((String) confVar.defaultVal); } catch (ClassNotFoundException e) { - throw new RuntimeException("The default class " + var.defaultVal + " does not exist"); + throw new IllegalArgumentException( + String.format("Failed to load the the default value of %s: %s", confVar.defaultVal, confVar.varname), + e + ); } - String val = conf.get(var.varname); - return val == null ? conf.getClasses(var.hiveName, defaultClass) : conf.getClasses(var.varname, defaultClass); + String val = conf.get(confVar.varname); + return val == null + ? conf.getClasses(confVar.hiveName, defaultClass) + : conf.getClasses(confVar.varname, defaultClass); } /**