This is an automated email from the ASF dual-hosted git repository.
oscerd pushed a commit to branch camel-4.14.x
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/camel-4.14.x by this push:
new f33f72598160 CAMEL-24243: camel-aws2-athena - do not relaunch a
still-running query when waitTimeout expires
f33f72598160 is described below
commit f33f72598160cb7b2bef98f3f0013b088945a765
Author: Andrea Cosentino <[email protected]>
AuthorDate: Fri Jul 24 10:13:49 2026 +0200
CAMEL-24243: camel-aws2-athena - do not relaunch a still-running query when
waitTimeout expires
Backport to camel-4.14.x: when the waitTimeout expires and the Athena query
is still running, the helper no longer treats it as retryable. This prevents
orphaning the running query and double-billing.
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
---
components/camel-aws/camel-aws2-athena/pom.xml | 5 ++
.../component/aws2/athena/Athena2QueryHelper.java | 21 +++++++++
.../aws2/athena/Athena2QueryHelperTest.java | 55 ++++++++++++++++++++++
3 files changed, 81 insertions(+)
diff --git a/components/camel-aws/camel-aws2-athena/pom.xml
b/components/camel-aws/camel-aws2-athena/pom.xml
index 6d9fb8f9b961..7dd4317270fd 100644
--- a/components/camel-aws/camel-aws2-athena/pom.xml
+++ b/components/camel-aws/camel-aws2-athena/pom.xml
@@ -72,6 +72,11 @@
<version>${mockito-version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
<!-- test infra -->
<dependency>
diff --git
a/components/camel-aws/camel-aws2-athena/src/main/java/org/apache/camel/component/aws2/athena/Athena2QueryHelper.java
b/components/camel-aws/camel-aws2-athena/src/main/java/org/apache/camel/component/aws2/athena/Athena2QueryHelper.java
index 97fe349a05d0..467cd7673533 100644
---
a/components/camel-aws/camel-aws2-athena/src/main/java/org/apache/camel/component/aws2/athena/Athena2QueryHelper.java
+++
b/components/camel-aws/camel-aws2-athena/src/main/java/org/apache/camel/component/aws2/athena/Athena2QueryHelper.java
@@ -120,11 +120,32 @@ class Athena2QueryHelper {
return false;
}
+ if (isWaitTimeoutExceeded()) {
+ LOG.trace("AWS Athena start query execution exceeded the wait
timeout of {} while the query was still"
+ + " running, will not relaunch it",
+ this.waitTimeout);
+ return false;
+ }
+
// if this.isRetry, return true
return true;
}
+ /**
+ * Did the wait window elapse while the query was still running? Only a
completed-and-retryable query is meant to
+ * consume another attempt, so a query that is merely slow must not be
relaunched.
+ * <p>
+ * Called from {@link #shouldAttempt()} once success and failure have been
ruled out, so {@code isRetry} is the only
+ * completion state left to exclude here.
+ */
+ private boolean isWaitTimeoutExceeded() {
+ if (this.attempts == 0 || this.isRetry) {
+ return false;
+ }
+ return now() - this.startMs >= this.waitTimeout;
+ }
+
/**
* Should there be a wait for the query to complete?
*/
diff --git
a/components/camel-aws/camel-aws2-athena/src/test/java/org/apache/camel/component/aws2/athena/Athena2QueryHelperTest.java
b/components/camel-aws/camel-aws2-athena/src/test/java/org/apache/camel/component/aws2/athena/Athena2QueryHelperTest.java
index db81f368106c..76688f21a3dc 100644
---
a/components/camel-aws/camel-aws2-athena/src/test/java/org/apache/camel/component/aws2/athena/Athena2QueryHelperTest.java
+++
b/components/camel-aws/camel-aws2-athena/src/test/java/org/apache/camel/component/aws2/athena/Athena2QueryHelperTest.java
@@ -28,6 +28,7 @@ import
software.amazon.awssdk.services.athena.model.QueryExecution;
import software.amazon.awssdk.services.athena.model.QueryExecutionState;
import software.amazon.awssdk.services.athena.model.QueryExecutionStatus;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -155,6 +156,60 @@ public class Athena2QueryHelperTest {
assertFalse(helper.shouldAttempt());
}
+ @Test
+ void aStillRunningQueryIsNotRelaunchedWhenTheWaitTimeoutExpires() {
+ Athena2Configuration configuration = new Athena2Configuration();
+ configuration.setMaxAttempts(3);
+ configuration.setWaitTimeout(1);
+ configuration.setInitialDelay(1);
+ configuration.setDelay(1);
+ configuration.setRetry("always");
+
+ Athena2QueryHelper helper = new Athena2QueryHelper(
+ new DefaultExchange(new DefaultCamelContext()),
+ configuration);
+
+ assertThat(helper.shouldAttempt()).isTrue();
+ helper.markAttempt();
+
+ // the query is still running when the wait window elapses, so no
completion state gets set
+ helper.doWait();
+
helper.setStatusFrom(newGetQueryExecutionResponse(QueryExecutionState.RUNNING));
+
+ assertThat(helper.shouldWait()).isFalse();
+ assertThat(helper.isSuccess()).isFalse();
+ assertThat(helper.isFailure()).isFalse();
+ assertThat(helper.isRetry()).isFalse();
+
+ // attempts are reserved for retrying completed-and-retryable queries;
relaunching here would
+ // orphan the running query and bill the same SQL twice
+ assertThat(helper.shouldAttempt()).isFalse();
+ assertThat(helper.getAttempts()).isEqualTo(1);
+ }
+
+ @Test
+ void aRetryableFailureStillConsumesAnotherAttemptAfterTheWaitTimeout() {
+ Athena2Configuration configuration = new Athena2Configuration();
+ configuration.setMaxAttempts(3);
+ configuration.setWaitTimeout(1);
+ configuration.setInitialDelay(1);
+ configuration.setDelay(1);
+ configuration.setRetry("always");
+
+ Athena2QueryHelper helper = new Athena2QueryHelper(
+ new DefaultExchange(new DefaultCamelContext()),
+ configuration);
+
+ assertThat(helper.shouldAttempt()).isTrue();
+ helper.markAttempt();
+
+ helper.doWait();
+
helper.setStatusFrom(newGetQueryExecutionResponse(QueryExecutionState.FAILED,
"GENERIC_INTERNAL_ERROR"));
+
+ assertThat(helper.isRetry()).isTrue();
+ assertThat(helper.shouldAttempt()).isTrue();
+ }
+
@Test
public void isComplete() {
Athena2QueryHelper helper = defaultAthena2QueryHelper();