Skip to content

Commit

Permalink
[apache#4508]feat(iceberg-rest-server): support load custom catalog a…
Browse files Browse the repository at this point in the history
…s backend in the Iceberg REST service (apache#4563)

### What changes were proposed in this pull request?

support load custom catalog as backend

### Why are the changes needed?

improvement: apache#4508

### Does this PR introduce _any_ user-facing change?

1. add a property key

### How was this patch tested?

1. add UT
2. manual test

---------

Co-authored-by: theoryxu <[email protected]>
  • Loading branch information
theoryxu and theoryxu authored Aug 19, 2024
1 parent 79fda5f commit 837b53b
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
public class IcebergConstants {
// Iceberg catalog properties constants
public static final String CATALOG_BACKEND = "catalog-backend";
public static final String CATALOG_BACKEND_IMPL = "catalog-backend-impl";

public static final String GRAVITINO_JDBC_USER = "jdbc-user";
public static final String ICEBERG_JDBC_USER = "jdbc.user";
Expand Down
8 changes: 8 additions & 0 deletions docs/iceberg-rest-service.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,14 @@ If you have a JDBC Iceberg catalog prior, you must set `catalog-backend-name` to
You must download the corresponding JDBC driver to the `iceberg-rest-server/libs` directory.
:::

#### Custom 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 **`custom`** for a Custom catalog. | `memory` | Yes | 0.2.0 |
| `gravitino.iceberg-rest.catalog-backend-impl` | The fully-qualified class name of a custom catalog implementation, only worked if `catalog-backend` is `custom`. | (none) | No | 0.7.0 |

If you want to use a custom Iceberg Catalog as `catalog-backend`, you can add a corresponding jar file to the classpath and load a custom Iceberg Catalog implementation by specifying the `catalog-backend-impl` property.

#### Multi catalog support

The Gravitino Iceberg REST server supports multiple catalogs and offers a configuration-based catalog management system.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ public enum IcebergCatalogBackend {
HIVE,
JDBC,
MEMORY,
REST
REST,
CUSTOM
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ public class IcebergConfig extends Config implements OverwriteDefaultConfig {
.stringConf()
.createWithDefault("memory");

public static final ConfigEntry<String> CATALOG_BACKEND_IMPL =
new ConfigBuilder(IcebergConstants.CATALOG_BACKEND_IMPL)
.doc(
"The fully-qualified class name of a custom catalog implementation, only worked if `catalog-backend` is `custom`")
.version(ConfigConstants.VERSION_0_7_0)
.stringConf()
.create();

public static final ConfigEntry<String> CATALOG_WAREHOUSE =
new ConfigBuilder(IcebergConstants.WAREHOUSE)
.doc("Warehouse directory of catalog")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hdfs.HdfsConfiguration;
import org.apache.iceberg.CatalogProperties;
import org.apache.iceberg.CatalogUtil;
import org.apache.iceberg.catalog.Catalog;
import org.apache.iceberg.hive.HiveCatalog;
import org.apache.iceberg.inmemory.InMemoryCatalog;
Expand Down Expand Up @@ -149,6 +150,16 @@ private static Catalog loadRestCatalog(IcebergConfig icebergConfig) {
return restCatalog;
}

private static Catalog loadCustomCatalog(IcebergConfig icebergConfig) {
String customCatalogName = icebergConfig.getCatalogBackendName("custom");
String className = icebergConfig.get(IcebergConfig.CATALOG_BACKEND_IMPL);
return CatalogUtil.loadCatalog(
className,
customCatalogName,
icebergConfig.getIcebergCatalogProperties(),
new HdfsConfiguration());
}

@VisibleForTesting
static Catalog loadCatalogBackend(String catalogType) {
return loadCatalogBackend(
Expand All @@ -168,6 +179,8 @@ public static Catalog loadCatalogBackend(
return loadJdbcCatalog(icebergConfig);
case REST:
return loadRestCatalog(icebergConfig);
case CUSTOM:
return loadCustomCatalog(icebergConfig);
default:
throw new RuntimeException(
catalogBackend
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* 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.common.utils;

import java.util.List;
import org.apache.iceberg.Table;
import org.apache.iceberg.catalog.Catalog;
import org.apache.iceberg.catalog.Namespace;
import org.apache.iceberg.catalog.TableIdentifier;

public class CustomCatalogForTest implements Catalog {
@Override
public List<TableIdentifier> listTables(Namespace namespace) {
return null;
}

@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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,38 @@ void testLoadCatalog() {
IcebergCatalogUtil.loadCatalogBackend("other");
});
}

@Test
void testValidLoadCustomCatalog() {
Catalog catalog;
Map<String, String> config = new HashMap<>();

config.put(
"catalog-backend-impl", "org.apache.gravitino.iceberg.common.utils.CustomCatalogForTest");
catalog =
IcebergCatalogUtil.loadCatalogBackend(
IcebergCatalogBackend.valueOf("CUSTOM"), new IcebergConfig(config));
Assertions.assertTrue(catalog instanceof CustomCatalogForTest);
}

@Test
void testInvalidLoadCustomCatalog() {
Assertions.assertThrowsExactly(
NullPointerException.class,
() ->
IcebergCatalogUtil.loadCatalogBackend(
IcebergCatalogBackend.valueOf("CUSTOM"), new IcebergConfig(new HashMap<>())));

Assertions.assertThrowsExactly(
IllegalArgumentException.class,
() ->
IcebergCatalogUtil.loadCatalogBackend(
IcebergCatalogBackend.valueOf("CUSTOM"),
new IcebergConfig(
new HashMap<String, String>() {
{
put("catalog-backend-impl", "org.apache.");
}
})));
}
}

0 comments on commit 837b53b

Please sign in to comment.