diff --git a/docker/iceberg-rest-fixture/README.md b/docker/iceberg-rest-fixture/README.md index 3805cc2468cb..57c6ef181f8d 100644 --- a/docker/iceberg-rest-fixture/README.md +++ b/docker/iceberg-rest-fixture/README.md @@ -23,6 +23,38 @@ For converting different catalog implementations into a rest one. Adapter for wrapping the existing catalog backends over REST. +## Configuration + +All configuration is provided via environment variables. + +### Catalog name + +By default, the fixture serves a catalog named `rest_backend`. To match a +name expected by a specific engine (for example, a catalog created via Trino +or PyIceberg), set: + +```bash +docker run -e CATALOG_NAME=mycatalog -p 8181:8181 apache/iceberg-rest-fixture +``` + +### Backend catalog properties + +All other catalog properties can be set via `CATALOG_*` environment variables. +The `CATALOG_` prefix is stripped; single underscores become dots (`.`); +double underscores become dashes (`-`). Names are lowercased. + +| Env var | Catalog property | +|---|---| +| `CATALOG_WAREHOUSE` | `warehouse` | +| `CATALOG_URI` | `uri` | +| `CATALOG_CATALOG__IMPL` | `catalog-impl` | +| `CATALOG_IO__IMPL` | `io-impl` | +| `CATALOG_JDBC_USER` | `jdbc.user` | + +If `catalog-impl` and `uri` are unset, the fixture defaults to an in-memory +SQLite `JdbcCatalog`. + + ## Build the Docker Image When making changes to the local files and test them out, you can build the image locally: diff --git a/open-api/src/test/java/org/apache/iceberg/rest/TestRESTCatalogServer.java b/open-api/src/test/java/org/apache/iceberg/rest/TestRESTCatalogServer.java new file mode 100644 index 000000000000..f789fd9ab1da --- /dev/null +++ b/open-api/src/test/java/org/apache/iceberg/rest/TestRESTCatalogServer.java @@ -0,0 +1,68 @@ +/* + * 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; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Map; +import org.apache.iceberg.relocated.com.google.common.collect.Maps; +import org.junit.jupiter.api.Test; + +class TestRESTCatalogServer { + + @Test + void resolvesCatalogNameFromEnvWhenUnset() { + Map props = Maps.newHashMap(); + Map env = Map.of(RESTCatalogServer.CATALOG_NAME_ENV, "mycatalog"); + + RESTCatalogServer.resolveCatalogNameFromEnv(props, env); + + assertThat(props).containsEntry(RESTCatalogServer.CATALOG_NAME, "mycatalog"); + } + + @Test + void preservesExistingCatalogNameProperty() { + Map props = Maps.newHashMap(); + props.put(RESTCatalogServer.CATALOG_NAME, "explicit"); + Map env = Map.of(RESTCatalogServer.CATALOG_NAME_ENV, "from_env"); + + RESTCatalogServer.resolveCatalogNameFromEnv(props, env); + + assertThat(props).containsEntry(RESTCatalogServer.CATALOG_NAME, "explicit"); + } + + @Test + void ignoresMissingEnvVar() { + Map props = Maps.newHashMap(); + + RESTCatalogServer.resolveCatalogNameFromEnv(props, Map.of()); + + assertThat(props).doesNotContainKey(RESTCatalogServer.CATALOG_NAME); + } + + @Test + void ignoresEmptyEnvVar() { + Map props = Maps.newHashMap(); + Map env = Map.of(RESTCatalogServer.CATALOG_NAME_ENV, ""); + + RESTCatalogServer.resolveCatalogNameFromEnv(props, env); + + assertThat(props).doesNotContainKey(RESTCatalogServer.CATALOG_NAME); + } +} diff --git a/open-api/src/testFixtures/java/org/apache/iceberg/rest/RESTCatalogServer.java b/open-api/src/testFixtures/java/org/apache/iceberg/rest/RESTCatalogServer.java index 2e4541b50b33..5a0bdcf28807 100644 --- a/open-api/src/testFixtures/java/org/apache/iceberg/rest/RESTCatalogServer.java +++ b/open-api/src/testFixtures/java/org/apache/iceberg/rest/RESTCatalogServer.java @@ -26,6 +26,7 @@ import org.apache.iceberg.CatalogUtil; import org.apache.iceberg.catalog.Catalog; import org.apache.iceberg.jdbc.JdbcCatalog; +import org.apache.iceberg.relocated.com.google.common.annotations.VisibleForTesting; import org.apache.iceberg.relocated.com.google.common.collect.Maps; import org.apache.iceberg.util.PropertyUtil; import org.eclipse.jetty.compression.gzip.GzipCompression; @@ -46,6 +47,10 @@ public class RESTCatalogServer { public static final String CATALOG_NAME = "catalog.name"; static final String CATALOG_NAME_DEFAULT = "rest_backend"; + // The generic CATALOG_* → property scheme in RCKUtils.environmentCatalogConfig + // translates CATALOG_NAME to the property "name" (not "catalog.name"), so we + // resolve this convenience env var explicitly. + static final String CATALOG_NAME_ENV = "CATALOG_NAME"; private Server httpServer; private final Map config; @@ -98,6 +103,8 @@ private CatalogContext initializeBackendCatalog() throws IOException { LOG.info("No warehouse location set. Defaulting to temp location: {}", warehouseLocation); } + resolveCatalogNameFromEnv(catalogProperties, System.getenv()); + String catalogName = PropertyUtil.propertyAsString(catalogProperties, CATALOG_NAME, CATALOG_NAME_DEFAULT); @@ -107,6 +114,15 @@ private CatalogContext initializeBackendCatalog() throws IOException { catalogProperties); } + @VisibleForTesting + static void resolveCatalogNameFromEnv( + Map catalogProperties, Map env) { + String catalogNameFromEnv = env.get(CATALOG_NAME_ENV); + if (catalogNameFromEnv != null && !catalogNameFromEnv.isEmpty()) { + catalogProperties.putIfAbsent(CATALOG_NAME, catalogNameFromEnv); + } + } + public void start(boolean join) throws Exception { CatalogContext catalogContext = initializeBackendCatalog();