This is an automated email from the ASF dual-hosted git repository.
adutra pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/polaris.git
The following commit(s) were added to refs/heads/main by this push:
new 2e373e51c Allow realm context resolution to execute blocking calls
(#1591)
2e373e51c is described below
commit 2e373e51ce5434c26635535b684ff210a53b1745
Author: Alexandre Dutra <[email protected]>
AuthorDate: Thu May 15 18:43:53 2025 +0200
Allow realm context resolution to execute blocking calls (#1591)
---
.../service/quarkus/config/QuarkusProducers.java | 2 +-
.../quarkus/context/RealmContextFilter.java | 67 ++++++++++++++++++++++
.../quarkus/logging/QuarkusLoggingMDCFilter.java | 2 +-
.../quarkus/metrics/RealmIdTagContributor.java | 38 +++++++++---
.../quarkus/tracing/QuarkusTracingFilter.java | 2 +-
.../service/quarkus/admin/RealmHeaderTest.java | 2 +-
.../test/PolarisIntegrationTestFixture.java | 7 ++-
.../context/DefaultRealmContextResolver.java | 16 ++++--
.../service/context/RealmContextFilter.java | 51 ----------------
.../service/context/RealmContextResolver.java | 33 +++++++++--
.../service/context/TestRealmContextResolver.java | 6 +-
.../context/UnresolvableRealmContextException.java | 34 -----------
.../service/exception/PolarisExceptionMapper.java | 3 -
.../context/DefaultRealmIdResolverTest.java | 49 +++++++++++-----
14 files changed, 183 insertions(+), 129 deletions(-)
diff --git
a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusProducers.java
b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusProducers.java
index 89bf2c6fb..40b79980d 100644
---
a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusProducers.java
+++
b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusProducers.java
@@ -60,7 +60,6 @@ import
org.apache.polaris.service.catalog.api.IcebergRestOAuth2ApiService;
import org.apache.polaris.service.catalog.io.FileIOFactory;
import org.apache.polaris.service.config.RealmEntityManagerFactory;
import org.apache.polaris.service.context.RealmContextConfiguration;
-import org.apache.polaris.service.context.RealmContextFilter;
import org.apache.polaris.service.context.RealmContextResolver;
import org.apache.polaris.service.events.PolarisEventListener;
import
org.apache.polaris.service.quarkus.auth.QuarkusAuthenticationConfiguration;
@@ -68,6 +67,7 @@ import
org.apache.polaris.service.quarkus.auth.QuarkusAuthenticationRealmConfigu
import
org.apache.polaris.service.quarkus.auth.external.tenant.OidcTenantResolver;
import
org.apache.polaris.service.quarkus.catalog.io.QuarkusFileIOConfiguration;
import
org.apache.polaris.service.quarkus.context.QuarkusRealmContextConfiguration;
+import org.apache.polaris.service.quarkus.context.RealmContextFilter;
import
org.apache.polaris.service.quarkus.events.QuarkusPolarisEventListenerConfiguration;
import
org.apache.polaris.service.quarkus.persistence.QuarkusPersistenceConfiguration;
import
org.apache.polaris.service.quarkus.ratelimiter.QuarkusRateLimiterFilterConfiguration;
diff --git
a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/context/RealmContextFilter.java
b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/context/RealmContextFilter.java
new file mode 100644
index 000000000..7ecce49b3
--- /dev/null
+++
b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/context/RealmContextFilter.java
@@ -0,0 +1,67 @@
+/*
+ * 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.polaris.service.quarkus.context;
+
+import io.smallrye.common.vertx.ContextLocals;
+import io.smallrye.mutiny.Uni;
+import jakarta.inject.Inject;
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import org.apache.iceberg.rest.responses.ErrorResponse;
+import org.apache.polaris.service.config.PolarisFilterPriorities;
+import org.apache.polaris.service.context.RealmContextResolver;
+import org.jboss.resteasy.reactive.server.ServerRequestFilter;
+
+public class RealmContextFilter {
+
+ public static final String REALM_CONTEXT_KEY = "realmContext";
+
+ @Inject RealmContextResolver realmContextResolver;
+
+ @ServerRequestFilter(preMatching = true, priority =
PolarisFilterPriorities.REALM_CONTEXT_FILTER)
+ public Uni<Response> resolveRealmContext(ContainerRequestContext rc) {
+ return Uni.createFrom()
+ .completionStage(
+ () ->
+ realmContextResolver.resolveRealmContext(
+ rc.getUriInfo().getRequestUri().toString(),
+ rc.getMethod(),
+ rc.getUriInfo().getPath(),
+ rc.getHeaders()::getFirst))
+ .onItem()
+ .invoke(realmContext -> rc.setProperty(REALM_CONTEXT_KEY,
realmContext))
+ .invoke(realmContext -> ContextLocals.put(REALM_CONTEXT_KEY,
realmContext))
+ .onItemOrFailure()
+ .transform((realmContext, error) -> error == null ? null :
errorResponse(error));
+ }
+
+ private static Response errorResponse(Throwable error) {
+ return Response.status(Response.Status.NOT_FOUND)
+ .type(MediaType.APPLICATION_JSON_TYPE)
+ .entity(
+ ErrorResponse.builder()
+ .responseCode(Response.Status.NOT_FOUND.getStatusCode())
+ .withMessage(
+ error.getMessage() != null ? error.getMessage() : "Missing
or invalid realm")
+ .withType("MissingOrInvalidRealm")
+ .build())
+ .build();
+ }
+}
diff --git
a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/logging/QuarkusLoggingMDCFilter.java
b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/logging/QuarkusLoggingMDCFilter.java
index 3062fabd3..cc4e7cd45 100644
---
a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/logging/QuarkusLoggingMDCFilter.java
+++
b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/logging/QuarkusLoggingMDCFilter.java
@@ -18,7 +18,7 @@
*/
package org.apache.polaris.service.quarkus.logging;
-import static
org.apache.polaris.service.context.RealmContextFilter.REALM_CONTEXT_KEY;
+import static
org.apache.polaris.service.quarkus.context.RealmContextFilter.REALM_CONTEXT_KEY;
import jakarta.annotation.Priority;
import jakarta.enterprise.context.ApplicationScoped;
diff --git
a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/metrics/RealmIdTagContributor.java
b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/metrics/RealmIdTagContributor.java
index 8388be9eb..7dd81f95b 100644
---
a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/metrics/RealmIdTagContributor.java
+++
b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/metrics/RealmIdTagContributor.java
@@ -30,24 +30,44 @@ import
org.apache.polaris.service.context.RealmContextResolver;
public class RealmIdTagContributor implements HttpServerMetricsTagsContributor
{
public static final String TAG_REALM = "realm_id";
+ public static final String TAG_REALM_RESOLUTION_FAILURE =
"realm_resolution_failure";
+
+ private static final Tags UNFINISHED_RESOLUTION_TAGS = Tags.of(TAG_REALM,
"???");
+ private static final Tags FAILED_RESOLUTION_TAGS = Tags.of(TAG_REALM, "!!!");
@Inject RealmContextResolver realmContextResolver;
@Override
public Tags contribute(Context context) {
- // FIXME request scope does not work here, so we have to resolve the realm
context manually
+ // FIXME retrieve the realm context from context.requestContextLocalData()
when this PR is in:
+ // https://github.com/quarkusio/quarkus/pull/47887
HttpServerRequest request = context.request();
try {
- RealmContext realmContext = resolveRealmContext(request);
- return Tags.of(TAG_REALM, realmContext.getRealmIdentifier());
- } catch (Exception ignored) {
- // ignore, the RealmContextFilter will handle the error
- return Tags.empty();
+ return realmContextResolver
+ .resolveRealmContext(
+ request.absoluteURI(),
+ request.method().name(),
+ request.path(),
+ request.headers()::get)
+ .thenApply(this::successfulResolutionTags)
+ .exceptionally(this::failedResolutionTags)
+ .toCompletableFuture()
+ // get the result of the CompletableFuture if it's already completed,
+ // otherwise return UNFINISHED_RESOLUTION_TAGS as this code is
executed on
+ // an event loop thread, and we don't want to block it.
+ .getNow(UNFINISHED_RESOLUTION_TAGS);
+ } catch (Exception e) {
+ return failedResolutionTags(e);
}
}
- private RealmContext resolveRealmContext(HttpServerRequest request) {
- return realmContextResolver.resolveRealmContext(
- request.absoluteURI(), request.method().name(), request.path(),
request.headers()::get);
+ private Tags successfulResolutionTags(RealmContext realmContext) {
+ return Tags.of(TAG_REALM, realmContext.getRealmIdentifier());
+ }
+
+ private Tags failedResolutionTags(Throwable error) {
+ return FAILED_RESOLUTION_TAGS.and(
+ TAG_REALM_RESOLUTION_FAILURE,
+ error.getMessage() == null ? error.getClass().getSimpleName() :
error.getMessage());
}
}
diff --git
a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/tracing/QuarkusTracingFilter.java
b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/tracing/QuarkusTracingFilter.java
index 6035cceb4..847905a6b 100644
---
a/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/tracing/QuarkusTracingFilter.java
+++
b/quarkus/service/src/main/java/org/apache/polaris/service/quarkus/tracing/QuarkusTracingFilter.java
@@ -26,8 +26,8 @@ import jakarta.ws.rs.container.ContainerRequestFilter;
import jakarta.ws.rs.container.PreMatching;
import jakarta.ws.rs.ext.Provider;
import org.apache.polaris.core.context.RealmContext;
-import org.apache.polaris.service.context.RealmContextFilter;
import org.apache.polaris.service.quarkus.config.QuarkusFilterPriorities;
+import org.apache.polaris.service.quarkus.context.RealmContextFilter;
import org.apache.polaris.service.quarkus.logging.QuarkusLoggingMDCFilter;
import org.eclipse.microprofile.config.inject.ConfigProperty;
diff --git
a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/RealmHeaderTest.java
b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/RealmHeaderTest.java
index f062f9263..eff5be116 100644
---
a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/RealmHeaderTest.java
+++
b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/RealmHeaderTest.java
@@ -90,7 +90,7 @@ public class RealmHeaderTest {
.extracting(ErrorResponse::code, ErrorResponse::type,
ErrorResponse::message)
.containsExactly(
Response.Status.NOT_FOUND.getStatusCode(),
- "UnresolvableRealmContextException",
+ "MissingOrInvalidRealm",
"Unknown realm: INVALID");
}
}
diff --git
a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/test/PolarisIntegrationTestFixture.java
b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/test/PolarisIntegrationTestFixture.java
index a550c98d1..259cfc648 100644
---
a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/test/PolarisIntegrationTestFixture.java
+++
b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/test/PolarisIntegrationTestFixture.java
@@ -104,8 +104,11 @@ public class PolarisIntegrationTestFixture {
}
RealmContext realmContext =
- helper.realmContextResolver.resolveRealmContext(
- baseUri.toString(), "GET", "/", Map.of(REALM_PROPERTY_KEY, realm));
+ helper
+ .realmContextResolver
+ .resolveRealmContext(baseUri.toString(), "GET", "/",
Map.of(REALM_PROPERTY_KEY, realm))
+ .toCompletableFuture()
+ .join();
BasePersistence metaStoreSession =
helper.metaStoreManagerFactory.getOrCreateSessionSupplier(realmContext).get();
diff --git
a/service/common/src/main/java/org/apache/polaris/service/context/DefaultRealmContextResolver.java
b/service/common/src/main/java/org/apache/polaris/service/context/DefaultRealmContextResolver.java
index 3318bd2f5..7d779ef85 100644
---
a/service/common/src/main/java/org/apache/polaris/service/context/DefaultRealmContextResolver.java
+++
b/service/common/src/main/java/org/apache/polaris/service/context/DefaultRealmContextResolver.java
@@ -21,6 +21,8 @@ package org.apache.polaris.service.context;
import io.smallrye.common.annotation.Identifier;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
import java.util.function.Function;
import org.apache.polaris.core.context.RealmContext;
@@ -36,21 +38,25 @@ public class DefaultRealmContextResolver implements
RealmContextResolver {
}
@Override
- public RealmContext resolveRealmContext(
+ public CompletionStage<RealmContext> resolveRealmContext(
String requestURL, String method, String path, Function<String, String>
headers) {
- String realm = resolveRealmIdentifier(headers);
- return () -> realm;
+ try {
+ String realm = resolveRealmIdentifier(headers);
+ return CompletableFuture.completedFuture(() -> realm);
+ } catch (Exception e) {
+ return CompletableFuture.failedFuture(e);
+ }
}
private String resolveRealmIdentifier(Function<String, String> headers) {
String realm = headers.apply(configuration.headerName());
if (realm != null) {
if (!configuration.realms().contains(realm)) {
- throw new UnresolvableRealmContextException("Unknown realm: " + realm);
+ throw new IllegalArgumentException("Unknown realm: " + realm);
}
} else {
if (configuration.requireHeader()) {
- throw new UnresolvableRealmContextException(
+ throw new IllegalArgumentException(
"Missing required realm header: " + configuration.headerName());
}
realm = configuration.defaultRealm();
diff --git
a/service/common/src/main/java/org/apache/polaris/service/context/RealmContextFilter.java
b/service/common/src/main/java/org/apache/polaris/service/context/RealmContextFilter.java
deleted file mode 100644
index 7939d05b1..000000000
---
a/service/common/src/main/java/org/apache/polaris/service/context/RealmContextFilter.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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.polaris.service.context;
-
-import jakarta.annotation.Priority;
-import jakarta.enterprise.context.ApplicationScoped;
-import jakarta.inject.Inject;
-import jakarta.ws.rs.container.ContainerRequestContext;
-import jakarta.ws.rs.container.ContainerRequestFilter;
-import jakarta.ws.rs.container.PreMatching;
-import jakarta.ws.rs.ext.Provider;
-import org.apache.polaris.core.context.RealmContext;
-import org.apache.polaris.service.config.PolarisFilterPriorities;
-
-@PreMatching
-@ApplicationScoped
-@Priority(PolarisFilterPriorities.REALM_CONTEXT_FILTER)
-@Provider
-public class RealmContextFilter implements ContainerRequestFilter {
-
- public static final String REALM_CONTEXT_KEY = "realmContext";
-
- @Inject RealmContextResolver realmContextResolver;
-
- @Override
- public void filter(ContainerRequestContext rc) {
- RealmContext realmContext =
- realmContextResolver.resolveRealmContext(
- rc.getUriInfo().getRequestUri().toString(),
- rc.getMethod(),
- rc.getUriInfo().getPath(),
- rc.getHeaders()::getFirst);
- rc.setProperty(REALM_CONTEXT_KEY, realmContext);
- }
-}
diff --git
a/service/common/src/main/java/org/apache/polaris/service/context/RealmContextResolver.java
b/service/common/src/main/java/org/apache/polaris/service/context/RealmContextResolver.java
index ae2b2dc6e..0aea6e9bd 100644
---
a/service/common/src/main/java/org/apache/polaris/service/context/RealmContextResolver.java
+++
b/service/common/src/main/java/org/apache/polaris/service/context/RealmContextResolver.java
@@ -19,22 +19,45 @@
package org.apache.polaris.service.context;
import java.util.Map;
+import java.util.concurrent.CompletionStage;
import java.util.function.Function;
import org.apache.commons.collections.map.CaseInsensitiveMap;
import org.apache.polaris.core.context.RealmContext;
+/**
+ * An interface for resolving the realm context for a given request.
+ *
+ * <p>General implementation guidance:
+ *
+ * <p>Methods in this class should not block the calling thread. If the realm
resolution process is
+ * blocking, it should be done in a separate thread.
+ *
+ * <p>In the case of an error during realm resolution, the {@link
CompletionStage} should complete
+ * exceptionally; methods should not throw exceptions directly.
+ *
+ * <p>The realm resolution takes place in the very early stages of the request
processing pipeline,
+ * and before any authentication or authorization checks are performed.
Implementations should be
+ * careful with the use of any blocking operations, as they may lead to
performance issues or
+ * deadlocks, especially in public environments.
+ */
public interface RealmContextResolver {
/**
- * Resolves the realm context for the given request.
+ * Resolves the realm context for the given request, and returns a {@link
CompletionStage} that
+ * completes with the resolved realm context.
*
- * @return the resolved realm context
- * @throws UnresolvableRealmContextException if the realm context cannot be
resolved
+ * @return a {@link CompletionStage} that completes with the resolved realm
context
*/
- RealmContext resolveRealmContext(
+ CompletionStage<RealmContext> resolveRealmContext(
String requestURL, String method, String path, Function<String, String>
headers);
- default RealmContext resolveRealmContext(
+ /**
+ * Resolves the realm context for the given request, and returns a {@link
CompletionStage} that
+ * completes with the resolved realm context.
+ *
+ * @return a {@link CompletionStage} that completes with the resolved realm
context
+ */
+ default CompletionStage<RealmContext> resolveRealmContext(
String requestURL, String method, String path, Map<String, String>
headers) {
CaseInsensitiveMap caseInsensitiveMap = new CaseInsensitiveMap(headers);
return resolveRealmContext(
diff --git
a/service/common/src/main/java/org/apache/polaris/service/context/TestRealmContextResolver.java
b/service/common/src/main/java/org/apache/polaris/service/context/TestRealmContextResolver.java
index 1fcff6496..79a914954 100644
---
a/service/common/src/main/java/org/apache/polaris/service/context/TestRealmContextResolver.java
+++
b/service/common/src/main/java/org/apache/polaris/service/context/TestRealmContextResolver.java
@@ -24,6 +24,8 @@ import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionStage;
import java.util.function.Function;
import org.apache.polaris.core.context.RealmContext;
import org.slf4j.Logger;
@@ -50,7 +52,7 @@ public class TestRealmContextResolver implements
RealmContextResolver {
}
@Override
- public RealmContext resolveRealmContext(
+ public CompletionStage<RealmContext> resolveRealmContext(
String requestURL, String method, String path, Function<String, String>
headers) {
// Since this default resolver is strictly for use in test/dev
environments, we'll consider
// it safe to log all contents. Any "real" resolver used in a prod
environment should make
@@ -72,7 +74,7 @@ public class TestRealmContextResolver implements
RealmContextResolver {
parsedProperties.put(REALM_PROPERTY_KEY, configuration.defaultRealm());
}
String realmId = parsedProperties.get(REALM_PROPERTY_KEY);
- return () -> realmId;
+ return CompletableFuture.completedFuture(() -> realmId);
}
/**
diff --git
a/service/common/src/main/java/org/apache/polaris/service/context/UnresolvableRealmContextException.java
b/service/common/src/main/java/org/apache/polaris/service/context/UnresolvableRealmContextException.java
deleted file mode 100644
index 4456fc602..000000000
---
a/service/common/src/main/java/org/apache/polaris/service/context/UnresolvableRealmContextException.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.polaris.service.context;
-
-import java.util.Map;
-import org.apache.polaris.core.exceptions.PolarisException;
-
-/**
- * Exception thrown when a realm context cannot be resolved.
- *
- * @see RealmContextResolver#resolveRealmContext(String, String, String, Map)
- */
-public class UnresolvableRealmContextException extends PolarisException {
-
- public UnresolvableRealmContextException(String message) {
- super(message);
- }
-}
diff --git
a/service/common/src/main/java/org/apache/polaris/service/exception/PolarisExceptionMapper.java
b/service/common/src/main/java/org/apache/polaris/service/exception/PolarisExceptionMapper.java
index 7eac23bd5..dfbd4f6c5 100644
---
a/service/common/src/main/java/org/apache/polaris/service/exception/PolarisExceptionMapper.java
+++
b/service/common/src/main/java/org/apache/polaris/service/exception/PolarisExceptionMapper.java
@@ -31,7 +31,6 @@ import
org.apache.polaris.core.policy.exceptions.PolicyAttachException;
import org.apache.polaris.core.policy.exceptions.PolicyInUseException;
import
org.apache.polaris.core.policy.exceptions.PolicyVersionMismatchException;
import org.apache.polaris.core.policy.validator.InvalidPolicyException;
-import org.apache.polaris.service.context.UnresolvableRealmContextException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.event.Level;
@@ -48,8 +47,6 @@ public class PolarisExceptionMapper implements
ExceptionMapper<PolarisException>
private Response.Status getStatus(PolarisException exception) {
if (exception instanceof AlreadyExistsException) {
return Response.Status.CONFLICT;
- } else if (exception instanceof UnresolvableRealmContextException) {
- return Response.Status.NOT_FOUND;
} else if (exception instanceof InvalidPolicyException) {
return Response.Status.BAD_REQUEST;
} else if (exception instanceof PolicyAttachException) {
diff --git
a/service/common/src/test/java/org/apache/polaris/service/context/DefaultRealmIdResolverTest.java
b/service/common/src/test/java/org/apache/polaris/service/context/DefaultRealmIdResolverTest.java
index 7b114cafb..e7d1ab70d 100644
---
a/service/common/src/test/java/org/apache/polaris/service/context/DefaultRealmIdResolverTest.java
+++
b/service/common/src/test/java/org/apache/polaris/service/context/DefaultRealmIdResolverTest.java
@@ -45,12 +45,16 @@ class DefaultRealmContextResolverTest {
void headerPresentSuccess() {
DefaultRealmContextResolver resolver = new
DefaultRealmContextResolver(config);
RealmContext RealmContext1 =
- resolver.resolveRealmContext(
- "requestURL", "method", "path", Map.of("Polaris-Header",
"realm1"));
+ resolver
+ .resolveRealmContext("requestURL", "method", "path",
Map.of("Polaris-Header", "realm1"))
+ .toCompletableFuture()
+ .join();
assertThat(RealmContext1.getRealmIdentifier()).isEqualTo("realm1");
RealmContext RealmContext2 =
- resolver.resolveRealmContext(
- "requestURL", "method", "path", Map.of("Polaris-Header",
"realm2"));
+ resolver
+ .resolveRealmContext("requestURL", "method", "path",
Map.of("Polaris-Header", "realm2"))
+ .toCompletableFuture()
+ .join();
assertThat(RealmContext2.getRealmIdentifier()).isEqualTo("realm2");
}
@@ -59,9 +63,13 @@ class DefaultRealmContextResolverTest {
DefaultRealmContextResolver resolver = new
DefaultRealmContextResolver(config);
assertThatThrownBy(
() ->
- resolver.resolveRealmContext(
- "requestURL", "method", "path", Map.of("Polaris-Header",
"realm3")))
- .isInstanceOf(UnresolvableRealmContextException.class)
+ resolver
+ .resolveRealmContext(
+ "requestURL", "method", "path",
Map.of("Polaris-Header", "realm3"))
+ .toCompletableFuture()
+ .join())
+ .rootCause()
+ .isInstanceOf(IllegalArgumentException.class)
.hasMessage("Unknown realm: realm3");
}
@@ -70,7 +78,10 @@ class DefaultRealmContextResolverTest {
when(config.requireHeader()).thenReturn(false);
DefaultRealmContextResolver resolver = new
DefaultRealmContextResolver(config);
RealmContext RealmContext1 =
- resolver.resolveRealmContext("requestURL", "method", "path", Map.of());
+ resolver
+ .resolveRealmContext("requestURL", "method", "path", Map.of())
+ .toCompletableFuture()
+ .join();
assertThat(RealmContext1.getRealmIdentifier()).isEqualTo("realm1");
}
@@ -78,8 +89,14 @@ class DefaultRealmContextResolverTest {
void headerNotPresentFailure() {
when(config.requireHeader()).thenReturn(true);
DefaultRealmContextResolver resolver = new
DefaultRealmContextResolver(config);
- assertThatThrownBy(() -> resolver.resolveRealmContext("requestURL",
"method", "path", Map.of()))
- .isInstanceOf(UnresolvableRealmContextException.class)
+ assertThatThrownBy(
+ () ->
+ resolver
+ .resolveRealmContext("requestURL", "method", "path",
Map.of())
+ .toCompletableFuture()
+ .join())
+ .rootCause()
+ .isInstanceOf(IllegalArgumentException.class)
.hasMessage("Missing required realm header: Polaris-Header");
}
@@ -87,12 +104,16 @@ class DefaultRealmContextResolverTest {
void headerCaseInsensitive() {
DefaultRealmContextResolver resolver = new
DefaultRealmContextResolver(config);
RealmContext RealmContext1 =
- resolver.resolveRealmContext(
- "requestURL", "method", "path", Map.of("POLARIS-HEADER",
"realm1"));
+ resolver
+ .resolveRealmContext("requestURL", "method", "path",
Map.of("POLARIS-HEADER", "realm1"))
+ .toCompletableFuture()
+ .join();
assertThat(RealmContext1.getRealmIdentifier()).isEqualTo("realm1");
RealmContext RealmContext2 =
- resolver.resolveRealmContext(
- "requestURL", "method", "path", Map.of("polaris-header",
"realm2"));
+ resolver
+ .resolveRealmContext("requestURL", "method", "path",
Map.of("polaris-header", "realm2"))
+ .toCompletableFuture()
+ .join();
assertThat(RealmContext2.getRealmIdentifier()).isEqualTo("realm2");
}
}