This is an automated email from the ASF dual-hosted git repository.
collado 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 a303a1d70 Add Request Timeouts (#1431)
a303a1d70 is described below
commit a303a1d70df3733f59914bcff62d3fe1a0fc3edc
Author: Richard Liu <[email protected]>
AuthorDate: Thu Apr 24 17:33:38 2025 -0500
Add Request Timeouts (#1431)
* add timeout
* add iceberg exception mapping
* dont use quarkus bom, disable timeout
* nits
---
api/iceberg-service/build.gradle.kts | 2 ++
api/management-service/build.gradle.kts | 1 +
api/polaris-catalog-service/build.gradle.kts | 2 ++
gradle/libs.versions.toml | 1 +
quarkus/defaults/src/main/resources/application.properties | 4 ++++
quarkus/service/build.gradle.kts | 1 +
server-templates/api.mustache | 3 +++
service/common/build.gradle.kts | 2 ++
.../org/apache/polaris/service/exception/IcebergExceptionMapper.java | 2 ++
9 files changed, 18 insertions(+)
diff --git a/api/iceberg-service/build.gradle.kts
b/api/iceberg-service/build.gradle.kts
index 596864e7f..a940a1b5e 100644
--- a/api/iceberg-service/build.gradle.kts
+++ b/api/iceberg-service/build.gradle.kts
@@ -45,6 +45,8 @@ dependencies {
implementation("com.fasterxml.jackson.core:jackson-annotations")
implementation("com.fasterxml.jackson.core:jackson-core")
implementation("com.fasterxml.jackson.core:jackson-databind")
+
+ compileOnly(libs.microprofile.fault.tolerance.api)
}
openApiGenerate {
diff --git a/api/management-service/build.gradle.kts
b/api/management-service/build.gradle.kts
index 78a3b5a71..9c59b0303 100644
--- a/api/management-service/build.gradle.kts
+++ b/api/management-service/build.gradle.kts
@@ -33,6 +33,7 @@ dependencies {
compileOnly(libs.jakarta.annotation.api)
compileOnly(libs.jakarta.inject.api)
compileOnly(libs.jakarta.validation.api)
+ compileOnly(libs.microprofile.fault.tolerance.api)
compileOnly(libs.swagger.annotations)
implementation(libs.jakarta.servlet.api)
diff --git a/api/polaris-catalog-service/build.gradle.kts
b/api/polaris-catalog-service/build.gradle.kts
index 6cd15f88a..77b801b98 100644
--- a/api/polaris-catalog-service/build.gradle.kts
+++ b/api/polaris-catalog-service/build.gradle.kts
@@ -71,6 +71,8 @@ dependencies {
implementation("com.fasterxml.jackson.core:jackson-annotations")
implementation("com.fasterxml.jackson.core:jackson-core")
implementation("com.fasterxml.jackson.core:jackson-databind")
+
+ compileOnly(libs.microprofile.fault.tolerance.api)
}
openApiGenerate {
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 60ad6a680..25b2bc94f 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -73,6 +73,7 @@ javax-servlet-api = { module =
"javax.servlet:javax.servlet-api", version = "4.0
junit-bom = { module = "org.junit:junit-bom", version = "5.12.2" }
logback-classic = { module = "ch.qos.logback:logback-classic", version =
"1.5.18" }
micrometer-bom = { module = "io.micrometer:micrometer-bom", version = "1.14.6"
}
+microprofile-fault-tolerance-api = { module =
"org.eclipse.microprofile.fault-tolerance:microprofile-fault-tolerance-api",
version = "4.1.1" }
mockito-core = { module = "org.mockito:mockito-core", version = "5.17.0" }
mockito-junit-jupiter = { module = "org.mockito:mockito-junit-jupiter",
version = "5.17.0" }
opentelemetry-bom = { module = "io.opentelemetry:opentelemetry-bom", version =
"1.49.0" }
diff --git a/quarkus/defaults/src/main/resources/application.properties
b/quarkus/defaults/src/main/resources/application.properties
index 56b18ac3d..c7676b2ba 100644
--- a/quarkus/defaults/src/main/resources/application.properties
+++ b/quarkus/defaults/src/main/resources/application.properties
@@ -86,6 +86,10 @@ quarkus.otel.sdk.disabled=true
quarkus.test.integration-test-profile=it
+quarkus.fault-tolerance.global.timeout.enabled=false
+# quarkus.fault-tolerance.global.timeout.unit=minutes
+# quarkus.fault-tolerance.global.timeout.value=10
+
polaris.realm-context.type=default
polaris.realm-context.realms=POLARIS
polaris.realm-context.header-name=Polaris-Realm
diff --git a/quarkus/service/build.gradle.kts b/quarkus/service/build.gradle.kts
index 32d7ab421..eb729b020 100644
--- a/quarkus/service/build.gradle.kts
+++ b/quarkus/service/build.gradle.kts
@@ -55,6 +55,7 @@ dependencies {
implementation("io.quarkus:quarkus-opentelemetry")
implementation("io.quarkus:quarkus-security")
implementation("io.quarkus:quarkus-smallrye-context-propagation")
+ implementation("io.quarkus:quarkus-smallrye-fault-tolerance")
implementation(libs.jakarta.enterprise.cdi.api)
implementation(libs.jakarta.inject.api)
diff --git a/server-templates/api.mustache b/server-templates/api.mustache
index c5f8123d8..d572abee1 100644
--- a/server-templates/api.mustache
+++ b/server-templates/api.mustache
@@ -57,6 +57,8 @@ import {{javaxPackage}}.inject.Inject;
import org.apache.polaris.core.context.RealmContext;
+import org.eclipse.microprofile.faulttolerance.Timeout;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -108,6 +110,7 @@ public class {{classname}} {
@Produces({ {{#produces}}"{{{mediaType}}}"{{^-last}},
{{/-last}}{{/produces}} }){{/hasProduces}}{{#hasAuthMethods}}
{{#authMethods}}{{#isOAuth}}@RolesAllowed("**"){{/isOAuth}}{{/authMethods}}{{/hasAuthMethods}}
@Timed("{{metricsPrefix}}.{{baseName}}.{{nickname}}")
+ @Timeout
public Response {{nickname}}({{#isMultipart}}MultipartFormDataInput
input,{{/isMultipart}}{{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{^isMultipart}}{{>formParams}},{{/isMultipart}}{{#isMultipart}}{{^isFormParam}},{{/isFormParam}}{{/isMultipart}}{{/allParams}}@Context
@MeterTag(key="realm_id",expression="realmIdentifier") RealmContext
realmContext,@Context SecurityContext securityContext) {
{{! Don't log form or header params in case there are secrets, e.g., OAuth
tokens }}
LOGGER.atDebug().setMessage("Invoking {{baseName}} with params")
diff --git a/service/common/build.gradle.kts b/service/common/build.gradle.kts
index ca00893e0..d38838a85 100644
--- a/service/common/build.gradle.kts
+++ b/service/common/build.gradle.kts
@@ -90,6 +90,8 @@ dependencies {
implementation("com.azure:azure-storage-blob")
implementation("com.azure:azure-storage-file-datalake")
+ implementation(libs.microprofile.fault.tolerance.api)
+
testImplementation(platform(libs.junit.bom))
testImplementation("org.junit.jupiter:junit-jupiter")
testImplementation(libs.assertj.core)
diff --git
a/service/common/src/main/java/org/apache/polaris/service/exception/IcebergExceptionMapper.java
b/service/common/src/main/java/org/apache/polaris/service/exception/IcebergExceptionMapper.java
index 81bfbf21f..048da3f79 100644
---
a/service/common/src/main/java/org/apache/polaris/service/exception/IcebergExceptionMapper.java
+++
b/service/common/src/main/java/org/apache/polaris/service/exception/IcebergExceptionMapper.java
@@ -57,6 +57,7 @@ import
org.apache.iceberg.exceptions.UnprocessableEntityException;
import org.apache.iceberg.exceptions.ValidationException;
import org.apache.iceberg.rest.responses.ErrorResponse;
import org.apache.polaris.core.exceptions.FileIOUnknownHostException;
+import org.eclipse.microprofile.faulttolerance.exceptions.TimeoutException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.event.Level;
@@ -191,6 +192,7 @@ public class IcebergExceptionMapper implements
ExceptionMapper<RuntimeException>
case IllegalArgumentException e -> Status.BAD_REQUEST.getStatusCode();
case UnsupportedOperationException e ->
Status.NOT_ACCEPTABLE.getStatusCode();
case WebApplicationException e -> e.getResponse().getStatus();
+ case TimeoutException e -> Status.REQUEST_TIMEOUT.getStatusCode();
default -> Status.INTERNAL_SERVER_ERROR.getStatusCode();
};
}