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();

Reply via email to