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 7ebe6e5b80 [#11133] feat(iceberg): Enable table metadata cache by
default and increase default capacity (#11156)
7ebe6e5b80 is described below
commit 7ebe6e5b8059792cef679656fed6c30681dbbb1e
Author: MaSai <[email protected]>
AuthorDate: Mon May 25 11:49:49 2026 +0800
[#11133] feat(iceberg): Enable table metadata cache by default and increase
default capacity (#11156)
### What changes were proposed in this pull request?
1. Default `table-metadata-cache-impl` to
`org.apache.gravitino.iceberg.common.cache.LocalTableMetadataCache` in
`IcebergConfig`.
2. Raise default `table-metadata-cache-capacity` from **200** to
**1000** in `IcebergConfig`.
3. Update IRC and lakehouse-iceberg catalog docs to match the new
defaults.
4. Align `IcebergCatalogPropertiesMetadata` defaults with
`IcebergConfig`.
5. Add `TestIcebergConfig.testTableMetadataCacheDefaults` to assert the
new defaults.
`IcebergCatalogWrapper` already loads the configured cache
implementation when `table-metadata-cache-impl` is set; with the new
config default, deployments no longer silently fall back to
`TableMetadataCache.DUMMY` unless the property is explicitly cleared.
### Why are the changes needed?
Fixes #11133
`TABLE_METADATA_CACHE_IMPL` has no default today, so every deployment
that does not set the property uses `TableMetadataCache.DUMMY` in
`IcebergCatalogWrapper.loadTableMetadataCache` and reads `metadata.json`
from object storage on every `loadTable`. The default capacity of
**200** is also too small for typical enterprise working sets.
### Does this PR introduce _any_ user-facing change?
Yes.
1. `table-metadata-cache-impl` defaults to `LocalTableMetadataCache`
when not configured.
2. `table-metadata-cache-capacity` defaults to **1000** when not
configured.
### How was this patch tested?
- `./gradlew :iceberg:iceberg-common:spotlessApply
:catalogs:catalog-lakehouse-iceberg:spotlessApply`
- `./gradlew :iceberg:iceberg-common:test -PskipITs
-PskipDockerTests=true --tests
"org.apache.gravitino.iceberg.common.TestIcebergConfig"`
---
.../iceberg/IcebergCatalogPropertiesMetadata.java | 9 +-
.../TestIcebergCatalogPropertiesMetadata.java | 75 +++++++
docs/iceberg-rest-service.md | 10 +-
docs/lakehouse-iceberg-catalog.md | 10 +-
.../gravitino/iceberg/common/IcebergConfig.java | 9 +-
.../iceberg/common/ops/IcebergCatalogWrapper.java | 14 +-
.../iceberg/common/TestIcebergConfig.java | 16 ++
.../iceberg/integration/test/IcebergCacheIT.java | 230 +++++++++++++++++++++
8 files changed, 352 insertions(+), 21 deletions(-)
diff --git
a/catalogs/catalog-lakehouse-iceberg/src/main/java/org/apache/gravitino/catalog/lakehouse/iceberg/IcebergCatalogPropertiesMetadata.java
b/catalogs/catalog-lakehouse-iceberg/src/main/java/org/apache/gravitino/catalog/lakehouse/iceberg/IcebergCatalogPropertiesMetadata.java
index 7f4735dbf3..49680a512d 100644
---
a/catalogs/catalog-lakehouse-iceberg/src/main/java/org/apache/gravitino/catalog/lakehouse/iceberg/IcebergCatalogPropertiesMetadata.java
+++
b/catalogs/catalog-lakehouse-iceberg/src/main/java/org/apache/gravitino/catalog/lakehouse/iceberg/IcebergCatalogPropertiesMetadata.java
@@ -33,6 +33,7 @@ import
org.apache.gravitino.connector.BaseCatalogPropertiesMetadata;
import org.apache.gravitino.connector.PropertyEntry;
import org.apache.gravitino.iceberg.common.authentication.AuthenticationConfig;
import
org.apache.gravitino.iceberg.common.authentication.kerberos.KerberosConfig;
+import org.apache.gravitino.iceberg.common.cache.LocalTableMetadataCache;
import org.apache.gravitino.storage.AzureProperties;
import org.apache.gravitino.storage.OSSProperties;
import org.apache.gravitino.storage.S3Properties;
@@ -125,15 +126,17 @@ public class IcebergCatalogPropertiesMetadata extends
BaseCatalogPropertiesMetad
false /* hidden */),
stringOptionalPropertyEntry(
IcebergConstants.TABLE_METADATA_CACHE_IMPL,
- "Table metadata cache implementation",
+ "Table metadata cache implementation. Set to empty
string(\"\") if "
+ + "catalog-backend is rest catalog, or custom catalog
without the "
+ + "SupportsMetadataLocation interface.",
false /* immutable */,
- null /* defaultValue */,
+ LocalTableMetadataCache.class.getName() /* defaultValue */,
false /* hidden */),
integerOptionalPropertyEntry(
IcebergConstants.TABLE_METADATA_CACHE_CAPACITY,
"Table metadata cache capacity",
false /* immutable */,
- 200 /* defaultValue */,
+ 1000 /* defaultValue */,
false /* hidden */),
integerOptionalPropertyEntry(
IcebergConstants.TABLE_METADATA_CACHE_EXPIRE_MINUTES,
diff --git
a/catalogs/catalog-lakehouse-iceberg/src/test/java/org/apache/gravitino/catalog/lakehouse/iceberg/TestIcebergCatalogPropertiesMetadata.java
b/catalogs/catalog-lakehouse-iceberg/src/test/java/org/apache/gravitino/catalog/lakehouse/iceberg/TestIcebergCatalogPropertiesMetadata.java
new file mode 100644
index 0000000000..125323f283
--- /dev/null
+++
b/catalogs/catalog-lakehouse-iceberg/src/test/java/org/apache/gravitino/catalog/lakehouse/iceberg/TestIcebergCatalogPropertiesMetadata.java
@@ -0,0 +1,75 @@
+/*
+ * 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.catalog.lakehouse.iceberg;
+
+import com.google.common.collect.ImmutableMap;
+import java.util.Map;
+import org.apache.gravitino.iceberg.common.IcebergConfig;
+import org.apache.gravitino.iceberg.common.cache.LocalTableMetadataCache;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+public class TestIcebergCatalogPropertiesMetadata {
+
+ private IcebergCatalogPropertiesMetadata metadata;
+
+ @BeforeEach
+ void setUp() {
+ metadata = new IcebergCatalogPropertiesMetadata();
+ }
+
+ @Test
+ void testTableMetadataCacheImplDefaultValue() {
+ Assertions.assertEquals(
+ LocalTableMetadataCache.class.getName(),
+ metadata.getDefaultValue(IcebergConstants.TABLE_METADATA_CACHE_IMPL));
+ Assertions.assertEquals(
+ IcebergConfig.TABLE_METADATA_CACHE_IMPL.getDefaultValue(),
+ metadata.getDefaultValue(IcebergConstants.TABLE_METADATA_CACHE_IMPL));
+ }
+
+ @Test
+ void testTableMetadataCacheCapacityDefaultValue() {
+ Assertions.assertEquals(
+ 1000,
metadata.getDefaultValue(IcebergConstants.TABLE_METADATA_CACHE_CAPACITY));
+ Assertions.assertEquals(
+ IcebergConfig.TABLE_METADATA_CACHE_CAPACITY.getDefaultValue(),
+
metadata.getDefaultValue(IcebergConstants.TABLE_METADATA_CACHE_CAPACITY));
+ }
+
+ @Test
+ void testTableMetadataCacheDefaultsViaGetOrDefault() {
+ Map<String, String> catalogProperties =
+ ImmutableMap.of(
+ IcebergCatalogPropertiesMetadata.CATALOG_BACKEND,
+ "hive",
+ IcebergCatalogPropertiesMetadata.URI,
+ "thrift://127.0.0.1:9083",
+ IcebergCatalogPropertiesMetadata.WAREHOUSE,
+ "/tmp/warehouse");
+
+ Assertions.assertEquals(
+ IcebergConfig.TABLE_METADATA_CACHE_IMPL.getDefaultValue(),
+ metadata.getOrDefault(catalogProperties,
IcebergConstants.TABLE_METADATA_CACHE_IMPL));
+ Assertions.assertEquals(
+ IcebergConfig.TABLE_METADATA_CACHE_CAPACITY.getDefaultValue(),
+ metadata.getOrDefault(catalogProperties,
IcebergConstants.TABLE_METADATA_CACHE_CAPACITY));
+ }
+}
diff --git a/docs/iceberg-rest-service.md b/docs/iceberg-rest-service.md
index c89b927e71..9844bc7c69 100644
--- a/docs/iceberg-rest-service.md
+++ b/docs/iceberg-rest-service.md
@@ -563,11 +563,11 @@ You must download the corresponding JDBC driver to the
`iceberg-rest-server/libs
Gravitino features a pluggable cache system for updating or retrieving table
metadata in the cache. It validates the location of table metadata against the
catalog backend to ensure the correctness of cached data.
-| Configuration item | Description
| Default value | Required | Since Version |
-|--------------------------------------------------------------|---------------------------------------------|---------------|----------|---------------|
-| `gravitino.iceberg-rest.table-metadata-cache-impl` | The implement
of the cache. | (none) | No | 1.1.0 |
-| `gravitino.iceberg-rest.table-metadata-cache-capacity` | The capacity
of table metadata cache. | 200 | No | 1.1.0 |
-| `gravitino.iceberg-rest.table-metadata-cache-expire-minutes` | The expire
minutes of table metadata cache. | 60 | No | 1.1.0 |
+| Configuration item | Description
| Default value |
Required | Since Version |
+|--------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------|----------|---------------|
+| `gravitino.iceberg-rest.table-metadata-cache-impl` | The
implementation of the table metadata cache. Set to empty string("") if
`catalog-backend` is `rest` catalog, or `custom` catalog without the
`SupportsMetadataLocation` interface. |
`org.apache.gravitino.iceberg.common.cache.LocalTableMetadataCache` | No
| 1.1.0 |
+| `gravitino.iceberg-rest.table-metadata-cache-capacity` | The capacity
of the table metadata cache.
| 1000
| No | 1.1.0 |
+| `gravitino.iceberg-rest.table-metadata-cache-expire-minutes` | The
expiration time (in minutes) of the table metadata cache.
| 60
| No | 1.1.0 |
Gravitino provides the build-in
`org.apache.gravitino.iceberg.common.cache.LocalTableMetadataCache` to store
the cached data in the memory. You could also implement your custom table
metadata cache by implementing the
`org.apache.gravitino.iceberg.common.cache.TableMetadataCache` interface.
diff --git a/docs/lakehouse-iceberg-catalog.md
b/docs/lakehouse-iceberg-catalog.md
index 252fd7d34f..28c500f29d 100644
--- a/docs/lakehouse-iceberg-catalog.md
+++ b/docs/lakehouse-iceberg-catalog.md
@@ -218,11 +218,11 @@ Users can use the following properties to configure the
security of the catalog
Gravitino features a pluggable cache system for updating or retrieving table
metadata in the cache. It validates the location of table metadata against the
catalog backend to ensure the correctness of cached data.
-| Configuration item | Description
| Default value | Required | Since Version |
-|---------------------------------------|---------------------------------------------|---------------|----------|---------------|
-| `table-metadata-cache-impl` | The implement of the cache.
| (none) | No | 1.1.0 |
-| `table-metadata-cache-capacity` | The capacity of table metadata
cache. | 200 | No | 1.1.0 |
-| `table-metadata-cache-expire-minutes` | The expire minutes of table metadata
cache. | 60 | No | 1.1.0 |
+| Configuration item | Description
| Default
value | Required | Since
Version |
+|---------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------|----------|---------------|
+| `table-metadata-cache-impl` | The implementation of the table
metadata cache. Set to empty string("") if `catalog-backend` is `rest` catalog,
or `custom` catalog without the `SupportsMetadataLocation` interface. |
`org.apache.gravitino.iceberg.common.cache.LocalTableMetadataCache` | No
| 1.1.0 |
+| `table-metadata-cache-capacity` | The capacity of the table metadata
cache.
| 1000
| No | 1.1.0
|
+| `table-metadata-cache-expire-minutes` | The expiration time (in minutes) of
the table metadata cache.
| 60
| No | 1.1.0
|
Gravitino provides the build-in
`org.apache.gravitino.iceberg.common.cache.LocalTableMetadataCache` to store
the cached data in the memory. You could also implement your custom table
metadata cache by implementing the
`org.apache.gravitino.iceberg.common.cache.TableMetadataCache` interface.
diff --git
a/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/IcebergConfig.java
b/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/IcebergConfig.java
index 4da89e37ef..f5ee8dd512 100644
---
a/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/IcebergConfig.java
+++
b/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/IcebergConfig.java
@@ -33,6 +33,7 @@ import org.apache.gravitino.config.ConfigBuilder;
import org.apache.gravitino.config.ConfigConstants;
import org.apache.gravitino.config.ConfigEntry;
import org.apache.gravitino.credential.CredentialConstants;
+import org.apache.gravitino.iceberg.common.cache.LocalTableMetadataCache;
import org.apache.gravitino.storage.OSSProperties;
import org.apache.gravitino.storage.S3Properties;
@@ -273,17 +274,19 @@ public class IcebergConfig extends Config implements
OverwriteDefaultConfig {
public static final ConfigEntry<String> TABLE_METADATA_CACHE_IMPL =
new ConfigBuilder(IcebergConstants.TABLE_METADATA_CACHE_IMPL)
- .doc("Table metadata cache implementation")
+ .doc(
+ "Table metadata cache implementation. Set to empty string(\"\")
if catalog-backend "
+ + "is rest catalog, or custom catalog without the
SupportsMetadataLocation interface.")
.version(ConfigConstants.VERSION_1_1_0)
.stringConf()
- .create();
+ .createWithDefault(LocalTableMetadataCache.class.getName());
public static final ConfigEntry<Integer> TABLE_METADATA_CACHE_CAPACITY =
new ConfigBuilder(IcebergConstants.TABLE_METADATA_CACHE_CAPACITY)
.doc("Table metadata cache capacity")
.version(ConfigConstants.VERSION_1_1_0)
.intConf()
- .createWithDefault(200);
+ .createWithDefault(1000);
public static final ConfigEntry<Integer> TABLE_METADATA_CACHE_EXPIRE_MINUTES
=
new ConfigBuilder(IcebergConstants.TABLE_METADATA_CACHE_EXPIRE_MINUTES)
diff --git
a/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/ops/IcebergCatalogWrapper.java
b/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/ops/IcebergCatalogWrapper.java
index 97919418a6..0ab9f215f4 100644
---
a/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/ops/IcebergCatalogWrapper.java
+++
b/iceberg/iceberg-common/src/main/java/org/apache/gravitino/iceberg/common/ops/IcebergCatalogWrapper.java
@@ -457,11 +457,15 @@ public class IcebergCatalogWrapper implements
AutoCloseable {
return TableMetadataCache.DUMMY;
}
- Preconditions.checkArgument(
- catalog instanceof SupportsMetadataLocation,
- "You shouldn't enable Iceberg metadata cache for the catalog %s,"
- + " because the catalog impl does not support get metadata
location.",
- catalog.name());
+ if (!(catalog instanceof SupportsMetadataLocation)) {
+ LOG.warn(
+ "Catalog '{}' does not support the table metadata cache, because the
catalog impl does not "
+ + "support get metadata location. The cache is disabled. Set
'{}' to an empty string "
+ + "(\"\") in the configuration before the next restart.",
+ catalog.name(),
+ IcebergConfig.TABLE_METADATA_CACHE_IMPL.getKey());
+ return TableMetadataCache.DUMMY;
+ }
TableMetadataCache cache =
ClassUtils.loadAndGetInstance(impl,
Thread.currentThread().getContextClassLoader());
diff --git
a/iceberg/iceberg-common/src/test/java/org/apache/gravitino/iceberg/common/TestIcebergConfig.java
b/iceberg/iceberg-common/src/test/java/org/apache/gravitino/iceberg/common/TestIcebergConfig.java
index 86da78ed60..1bd47fcb16 100644
---
a/iceberg/iceberg-common/src/test/java/org/apache/gravitino/iceberg/common/TestIcebergConfig.java
+++
b/iceberg/iceberg-common/src/test/java/org/apache/gravitino/iceberg/common/TestIcebergConfig.java
@@ -21,6 +21,7 @@ package org.apache.gravitino.iceberg.common;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
+import org.apache.gravitino.iceberg.common.cache.LocalTableMetadataCache;
import org.apache.gravitino.server.web.JettyServerConfig;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -63,6 +64,21 @@ public class TestIcebergConfig {
Assertions.assertEquals(1001, jettyServerConfig.getHttpsPort());
}
+ @Test
+ public void testTableMetadataCacheDefaults() {
+ IcebergConfig icebergConfig = new IcebergConfig(ImmutableMap.of());
+ Assertions.assertEquals(
+ LocalTableMetadataCache.class.getName(),
+ icebergConfig.get(IcebergConfig.TABLE_METADATA_CACHE_IMPL));
+ Assertions.assertEquals(1000,
icebergConfig.get(IcebergConfig.TABLE_METADATA_CACHE_CAPACITY));
+ Assertions.assertEquals(
+ IcebergConfig.TABLE_METADATA_CACHE_IMPL.getDefaultValue(),
+ icebergConfig.get(IcebergConfig.TABLE_METADATA_CACHE_IMPL));
+ Assertions.assertEquals(
+ IcebergConfig.TABLE_METADATA_CACHE_CAPACITY.getDefaultValue(),
+ icebergConfig.get(IcebergConfig.TABLE_METADATA_CACHE_CAPACITY));
+ }
+
@Test
public void testDisableRestAuthzConfigKey() {
Map<String, String> propertiesWithNewKey =
diff --git
a/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/IcebergCacheIT.java
b/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/IcebergCacheIT.java
new file mode 100644
index 0000000000..cbd36562ed
--- /dev/null
+++
b/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/integration/test/IcebergCacheIT.java
@@ -0,0 +1,230 @@
+/*
+ * 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.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.gravitino.catalog.lakehouse.iceberg.IcebergCatalogBackend;
+import org.apache.gravitino.catalog.lakehouse.iceberg.IcebergConstants;
+import org.apache.gravitino.iceberg.common.IcebergConfig;
+import org.apache.gravitino.iceberg.common.cache.LocalTableMetadataCache;
+import org.apache.gravitino.iceberg.common.cache.SupportsMetadataLocation;
+import org.apache.gravitino.iceberg.common.cache.TableMetadataCache;
+import org.apache.gravitino.iceberg.common.ops.IcebergCatalogWrapper;
+import
org.apache.gravitino.iceberg.integration.test.util.IcebergRESTServerManager;
+import org.apache.gravitino.integration.test.container.ContainerSuite;
+import org.apache.gravitino.integration.test.container.HiveContainer;
+import org.apache.gravitino.integration.test.util.GravitinoITUtils;
+import org.apache.gravitino.server.web.JettyServerConfig;
+import org.apache.iceberg.Schema;
+import org.apache.iceberg.Table;
+import org.apache.iceberg.catalog.Catalog;
+import org.apache.iceberg.catalog.Namespace;
+import org.apache.iceberg.catalog.TableIdentifier;
+import org.apache.iceberg.memory.MemoryCatalogWithMetadataLocationSupport;
+import org.apache.iceberg.rest.requests.CreateNamespaceRequest;
+import org.apache.iceberg.rest.requests.CreateTableRequest;
+import org.apache.iceberg.rest.responses.LoadTableResponse;
+import org.apache.iceberg.types.Types;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+import org.junit.jupiter.api.TestInstance.Lifecycle;
+
+/** Docker IT for default table metadata cache in {@link
IcebergCatalogWrapper}. */
+@Tag("gravitino-docker-test")
+@TestInstance(Lifecycle.PER_CLASS)
+public class IcebergCacheIT {
+
+ private static final ContainerSuite CONTAINER_SUITE =
ContainerSuite.getInstance();
+
+ private static final Schema TABLE_SCHEMA =
+ new Schema(Types.NestedField.required(1, "id", Types.IntegerType.get()));
+
+ private IcebergRESTServerManager restServer;
+
+ @BeforeAll
+ void startDockerEnv() throws Exception {
+ CONTAINER_SUITE.startHiveContainer();
+ restServer = IcebergRESTServerManager.create();
+ Map<String, String> serverConfigs = new HashMap<>();
+ serverConfigs.put(
+ IcebergConfig.ICEBERG_CONFIG_PREFIX +
IcebergConfig.CATALOG_BACKEND.getKey(),
+ IcebergCatalogBackend.HIVE.toString().toLowerCase());
+ serverConfigs.put(
+ IcebergConfig.ICEBERG_CONFIG_PREFIX +
IcebergConfig.CATALOG_URI.getKey(),
+ hiveMetastoreUri());
+ serverConfigs.put(
+ IcebergConfig.ICEBERG_CONFIG_PREFIX +
IcebergConfig.CATALOG_WAREHOUSE.getKey(),
+ hdfsWarehouse("iceberg-rest-cache-it"));
+ restServer.registerCustomConfigs(serverConfigs);
+ restServer.startIcebergRESTServer();
+ }
+
+ @AfterAll
+ void stopDockerEnv() throws Exception {
+ if (restServer != null) {
+ restServer.stopIcebergRESTServer();
+ }
+ }
+
+ @Test
+ void testRestCacheDisabled() throws Exception {
+ int port = restPort();
+ Map<String, String> properties = new HashMap<>();
+ properties.put(
+ IcebergConstants.CATALOG_BACKEND,
IcebergCatalogBackend.REST.name().toLowerCase());
+ properties.put(IcebergConstants.URI,
String.format("http://127.0.0.1:%d/iceberg/", port));
+ properties.put(IcebergConstants.CATALOG_BACKEND_NAME, "rest_cache_it");
+
+ IcebergConfig icebergConfig = new IcebergConfig(properties);
+ Assertions.assertEquals(
+ LocalTableMetadataCache.class.getName(),
+ icebergConfig.get(IcebergConfig.TABLE_METADATA_CACHE_IMPL));
+
+ try (IcebergCatalogWrapper wrapper = new
IcebergCatalogWrapper(icebergConfig)) {
+ TableMetadataCache cache = metadataCache(wrapper);
+ Assertions.assertSame(TableMetadataCache.DUMMY, cache);
+ }
+ }
+
+ @Test
+ void testCustomNoSupportLocationOff() throws Exception {
+ Map<String, String> properties = new HashMap<>();
+ properties.put(
+ IcebergConstants.CATALOG_BACKEND,
IcebergCatalogBackend.CUSTOM.name().toLowerCase());
+ properties.put(
+ IcebergConstants.CATALOG_BACKEND_IMPL,
CustomNoSupportLocationCatalog.class.getName());
+ properties.put(IcebergConstants.CATALOG_BACKEND_NAME,
"custom_no_support_loc");
+ properties.put(IcebergConstants.URI, hiveMetastoreUri());
+ properties.put(IcebergConstants.WAREHOUSE,
hdfsWarehouse("custom-no-support-loc"));
+
+ IcebergConfig icebergConfig = new IcebergConfig(properties);
+ Assertions.assertEquals(
+ LocalTableMetadataCache.class.getName(),
+ icebergConfig.get(IcebergConfig.TABLE_METADATA_CACHE_IMPL));
+
+ try (IcebergCatalogWrapper wrapper = new
IcebergCatalogWrapper(icebergConfig)) {
+ TableMetadataCache cache = metadataCache(wrapper);
+ Assertions.assertSame(TableMetadataCache.DUMMY, cache);
+ }
+ }
+
+ @Test
+ void testCustomSupportLocationOn() throws Exception {
+ Map<String, String> properties = new HashMap<>();
+ properties.put(
+ IcebergConstants.CATALOG_BACKEND,
IcebergCatalogBackend.CUSTOM.name().toLowerCase());
+ properties.put(
+ IcebergConstants.CATALOG_BACKEND_IMPL,
CustomSupportLocationCatalog.class.getName());
+ properties.put(IcebergConstants.CATALOG_BACKEND_NAME,
"custom_support_loc");
+ properties.put(IcebergConstants.URI, hiveMetastoreUri());
+ properties.put(IcebergConstants.WAREHOUSE,
hdfsWarehouse("custom-support-loc"));
+
+ IcebergConfig icebergConfig = new IcebergConfig(properties);
+ Assertions.assertEquals(
+ LocalTableMetadataCache.class.getName(),
+ icebergConfig.get(IcebergConfig.TABLE_METADATA_CACHE_IMPL));
+ Assertions.assertEquals(1000,
icebergConfig.get(IcebergConfig.TABLE_METADATA_CACHE_CAPACITY));
+
+ Namespace namespace = Namespace.of("cache_ns");
+ TableIdentifier tableId = TableIdentifier.of(namespace, "cache_tbl");
+
+ try (IcebergCatalogWrapper wrapper = new
IcebergCatalogWrapper(icebergConfig)) {
+ TableMetadataCache cache = metadataCache(wrapper);
+ Assertions.assertInstanceOf(LocalTableMetadataCache.class, cache);
+
+
wrapper.createNamespace(CreateNamespaceRequest.builder().withNamespace(namespace).build());
+ LoadTableResponse createResponse =
+ wrapper.createTable(
+ namespace,
+ CreateTableRequest.builder()
+ .withName(tableId.name())
+ .withSchema(TABLE_SCHEMA)
+ .build());
+ Assertions.assertNotNull(createResponse);
+
+ Assertions.assertTrue(cache.getTableMetadata(tableId).isPresent());
+
+ LoadTableResponse loadResponse = wrapper.loadTable(tableId);
+ Assertions.assertNotNull(loadResponse);
+ Assertions.assertTrue(cache.getTableMetadata(tableId).isPresent());
+ }
+ }
+
+ private static String hiveMetastoreUri() {
+ return String.format(
+ "thrift://%s:%d",
+ CONTAINER_SUITE.getHiveContainer().getContainerIpAddress(),
+ HiveContainer.HIVE_METASTORE_PORT);
+ }
+
+ private static String hdfsWarehouse(String suffix) {
+ return GravitinoITUtils.genRandomName(
+ String.format(
+ "hdfs://%s:%d/user/hive/warehouse-%s",
+ CONTAINER_SUITE.getHiveContainer().getContainerIpAddress(),
+ HiveContainer.HDFS_DEFAULTFS_PORT,
+ suffix));
+ }
+
+ private int restPort() {
+ JettyServerConfig jettyServerConfig =
+ JettyServerConfig.fromConfig(
+ restServer.getServerConfig(), IcebergConfig.ICEBERG_CONFIG_PREFIX);
+ return jettyServerConfig.getHttpPort();
+ }
+
+ private static TableMetadataCache metadataCache(IcebergCatalogWrapper
wrapper) throws Exception {
+ Method method =
IcebergCatalogWrapper.class.getDeclaredMethod("getMetadataCache");
+ method.setAccessible(true);
+ return (TableMetadataCache) method.invoke(wrapper);
+ }
+
+ /** Custom catalog that does not support metadata location for cache IT. */
+ public static class CustomNoSupportLocationCatalog implements Catalog {
+
+ @Override
+ public List<TableIdentifier> listTables(Namespace namespace) {
+ return List.of();
+ }
+
+ @Override
+ public boolean dropTable(TableIdentifier identifier, boolean purge) {
+ return false;
+ }
+
+ @Override
+ public void renameTable(TableIdentifier from, TableIdentifier to) {}
+
+ @Override
+ public Table loadTable(TableIdentifier identifier) {
+ return null;
+ }
+ }
+
+ /** Custom catalog that supports metadata location for cache IT. */
+ public static class CustomSupportLocationCatalog extends
MemoryCatalogWithMetadataLocationSupport
+ implements SupportsMetadataLocation {}
+}