From 4ddb3fe54bb3d4e42849da382203d8adcac88638 Mon Sep 17 00:00:00 2001 From: "Michael A. Neilson" Date: Fri, 7 Aug 2026 14:13:44 +0000 Subject: [PATCH 1/2] Some additional tracking. --- .../src/test/java/cwms/cda/api/rss/RssHandlerIT.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/cwms-data-api/src/test/java/cwms/cda/api/rss/RssHandlerIT.java b/cwms-data-api/src/test/java/cwms/cda/api/rss/RssHandlerIT.java index e4925d1e5..5aa255472 100644 --- a/cwms-data-api/src/test/java/cwms/cda/api/rss/RssHandlerIT.java +++ b/cwms-data-api/src/test/java/cwms/cda/api/rss/RssHandlerIT.java @@ -49,6 +49,8 @@ import java.math.BigInteger; import java.net.URI; import java.util.List; +import java.util.concurrent.TimeUnit; + import javax.servlet.http.HttpServletResponse; import org.jooq.Configuration; import org.jooq.impl.DSL; @@ -82,10 +84,12 @@ void setup() throws Exception { @Test void test_rss_feed_with_pagination() { // Page 1: verify core RSS elements + 5 items + next link exists + int pagesVisited = 0; ExtractableResponse page1 = given() .log().ifValidationFails(LogDetail.ALL, true) .accept(Formats.RSS) .header(AUTH_HEADER, user.toHeaderValue()) + .header("page", pagesVisited) .queryParam(PAGE_SIZE, 5) .when() .redirects().follow(true) @@ -96,7 +100,7 @@ void test_rss_feed_with_pagination() { .assertThat() .statusCode(is(HttpServletResponse.SC_OK)) .extract(); - + pagesVisited++; String xmlBody = page1.asString(); XmlPath xml = rssXml(xmlBody); @@ -114,7 +118,7 @@ void test_rss_feed_with_pagination() { assertNotNull(nextHref, "Expected an atom:link rel=\"next\" on the first page"); // Walk pages via nextLine - int pagesVisited = 1; + int maxPages = 500; while (nextHref != null && pagesVisited < maxPages) { String nextPath = toPathAndQuery(nextHref); @@ -123,6 +127,7 @@ void test_rss_feed_with_pagination() { .log().ifValidationFails(LogDetail.ALL, true) .accept(Formats.RSS) .header(AUTH_HEADER, user.toHeaderValue()) + .header("page", pagesVisited) .when() .redirects().follow(true) .redirects().max(3) @@ -144,7 +149,7 @@ void test_rss_feed_with_pagination() { String waitStr = nextPage.header("Retry-After"); int wait = waitStr != null && !waitStr.isEmpty() ? Integer.parseInt(waitStr) : 10; try { - Thread.sleep(wait*1000 + 500 /* extra half second just to avoid the best being brittle */); + TimeUnit.SECONDS.sleep(wait); // NOSONAR - have to wait, 429 response } catch (InterruptedException ex) { LOGGER.atFine().withCause(ex).log("Next query wait was interrupted."); } From da6e271cfeff08fb7e318fb659f0a710a402062c Mon Sep 17 00:00:00 2001 From: "Michael A. Neilson" Date: Fri, 7 Aug 2026 14:50:51 +0000 Subject: [PATCH 2/2] Allow 429 as a valid response and only wait if 429 was sent. --- .../java/cwms/cda/api/rss/RssHandlerIT.java | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/cwms-data-api/src/test/java/cwms/cda/api/rss/RssHandlerIT.java b/cwms-data-api/src/test/java/cwms/cda/api/rss/RssHandlerIT.java index 5aa255472..0b14cc3e9 100644 --- a/cwms-data-api/src/test/java/cwms/cda/api/rss/RssHandlerIT.java +++ b/cwms-data-api/src/test/java/cwms/cda/api/rss/RssHandlerIT.java @@ -29,6 +29,7 @@ import static cwms.cda.api.Controllers.PAGE_SIZE; import static cwms.cda.security.ApiKeyIdentityProvider.AUTH_HEADER; import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.either; import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -135,23 +136,25 @@ void test_rss_feed_with_pagination() { .then() .log().ifValidationFails(LogDetail.ALL, true) .assertThat() - .statusCode(is(HttpServletResponse.SC_OK)) + .statusCode(either(is(HttpServletResponse.SC_OK)).or(is(429))) .extract(); - - XmlPath nextXml = rssXml(nextPage.asString()); - - // Still a valid RSS document with items - assertNotNull(nextXml.getString("rss.channel.title")); - assertNotNull(nextXml.getList("rss.channel.item")); - - pagesVisited++; - nextHref = nextLinkHref(nextXml); + if (nextPage.statusCode() == HttpServletResponse.SC_OK) { + XmlPath nextXml = rssXml(nextPage.asString()); + // Still a valid RSS document with items + assertNotNull(nextXml.getString("rss.channel.title")); + assertNotNull(nextXml.getList("rss.channel.item")); + + pagesVisited++; + nextHref = nextLinkHref(nextXml); + } String waitStr = nextPage.header("Retry-After"); - int wait = waitStr != null && !waitStr.isEmpty() ? Integer.parseInt(waitStr) : 10; - try { - TimeUnit.SECONDS.sleep(wait); // NOSONAR - have to wait, 429 response - } catch (InterruptedException ex) { - LOGGER.atFine().withCause(ex).log("Next query wait was interrupted."); + if (waitStr != null) { + int wait = waitStr != null && !waitStr.isEmpty() ? Integer.parseInt(waitStr) : 10; + try { + TimeUnit.SECONDS.sleep(wait); // NOSONAR - have to wait, 429 response + } catch (InterruptedException ex) { + LOGGER.atFine().withCause(ex).log("Next query wait was interrupted."); + } } }