This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch backport/29843-to-camel-4-18-x
in repository https://gitbox.apache.org/repos/asf/camel.git

commit d5eef20a067169b465cd0c1634e624813e119e5c
Author: Vignesh Nayak Manel <[email protected]>
AuthorDate: Fri Oct 30 03:00:50 2026 +0530

    CAMEL-26130: camel-oaipmh - the CamelOaimphOnlyFirst and 
CamelOaimphIgnoreSSLWarnings headers apply to their exchange only (#28690)
    
    The producer wrote both headers onto the shared endpoint, so one exchange 
with
    CamelOaimphOnlyFirst=true made every later exchange return only the first 
page,
    and one with CamelOaimphIgnoreSSLWarnings=true made every later exchange 
accept
    a self-signed certificate. The headers are now read for the exchange only.
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
    (cherry picked from commit 00f66540c4ce9e24b483c2fc622fab13756db4db)
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../camel/oaipmh/component/OAIPMHProducer.java     |  18 ++--
 .../OAIPMHProducerHeadersPerExchangeTest.java      | 112 +++++++++++++++++++++
 2 files changed, 124 insertions(+), 6 deletions(-)

diff --git 
a/components/camel-oaipmh/src/main/java/org/apache/camel/oaipmh/component/OAIPMHProducer.java
 
b/components/camel-oaipmh/src/main/java/org/apache/camel/oaipmh/component/OAIPMHProducer.java
index a7fdf84cd88f..7ba958f02be3 100644
--- 
a/components/camel-oaipmh/src/main/java/org/apache/camel/oaipmh/component/OAIPMHProducer.java
+++ 
b/components/camel-oaipmh/src/main/java/org/apache/camel/oaipmh/component/OAIPMHProducer.java
@@ -50,13 +50,16 @@ public class OAIPMHProducer extends DefaultProducer {
                 endpoint.getFrom(),
                 endpoint.getSet(),
                 endpoint.getIdentifier());
-        overrideHarvesterConfigs(exchange.getIn(), harvester);
-        if (endpoint.isIgnoreSSLWarnings()) {
+        Message msg = exchange.getIn();
+        overrideHarvesterConfigs(msg, harvester);
+        // the headers apply to this exchange only, the endpoint is shared by 
all exchanges
+        boolean onlyFirst = getBooleanHeader(msg, OAIPMHConstants.ONLY_FIRST, 
endpoint.isOnlyFirst());
+        if (getBooleanHeader(msg, OAIPMHConstants.IGNORE_SSL_WARNINGS, 
endpoint.isIgnoreSSLWarnings())) {
             harvester.getHttpClient().setIgnoreSSLWarnings(true);
         }
-        List<String> synHarvest = harvester.synHarvest(endpoint.isOnlyFirst());
+        List<String> synHarvest = harvester.synHarvest(onlyFirst);
         exchange.getMessage().setBody(synHarvest);
-        if (endpoint.isOnlyFirst() && harvester.getResumptionToken() != null) {
+        if (onlyFirst && harvester.getResumptionToken() != null) {
             exchange.getMessage().setHeader(OAIPMHConstants.RESUMPTION_TOKEN, 
harvester.getResumptionToken());
         } else {
             
exchange.getMessage().removeHeader(OAIPMHConstants.RESUMPTION_TOKEN);
@@ -73,8 +76,11 @@ public class OAIPMHProducer extends DefaultProducer {
         checkAndSetConfigs(msg, OAIPMHConstants.SET, harvester::setSet, 
String.class);
         checkAndSetConfigs(msg, OAIPMHConstants.IDENTIFIER, 
harvester::setIdentifier, String.class);
         checkAndSetConfigs(msg, OAIPMHConstants.RESUMPTION_TOKEN, 
harvester::setResumptionToken, String.class);
-        checkAndSetConfigs(msg, OAIPMHConstants.ONLY_FIRST, 
endpoint::setOnlyFirst, Boolean.class);
-        checkAndSetConfigs(msg, OAIPMHConstants.IGNORE_SSL_WARNINGS, 
endpoint::setIgnoreSSLWarnings, Boolean.class);
+    }
+
+    private static boolean getBooleanHeader(Message message, String key, 
boolean defaultValue) {
+        Boolean header = message.getHeader(key, Boolean.class);
+        return header != null ? header : defaultValue;
     }
 
     private <T> void checkAndSetConfigs(final Message message, final String 
key, final Consumer<T> fn, final Class<T> type) {
diff --git 
a/components/camel-oaipmh/src/test/java/org/apache/camel/oaipmh/OAIPMHProducerHeadersPerExchangeTest.java
 
b/components/camel-oaipmh/src/test/java/org/apache/camel/oaipmh/OAIPMHProducerHeadersPerExchangeTest.java
new file mode 100644
index 000000000000..7b607557b644
--- /dev/null
+++ 
b/components/camel-oaipmh/src/test/java/org/apache/camel/oaipmh/OAIPMHProducerHeadersPerExchangeTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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.camel.oaipmh;
+
+import java.util.List;
+
+import javax.net.ssl.SSLException;
+
+import org.apache.camel.CamelExecutionException;
+import org.apache.camel.oaipmh.component.OAIPMHEndpoint;
+import org.apache.camel.oaipmh.component.model.OAIPMHConstants;
+import org.apache.camel.oaipmh.utils.MockOaipmhServer;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * The CamelOaimphOnlyFirst and CamelOaimphIgnoreSSLWarnings headers apply to 
the exchange that has them, not to the
+ * later exchanges sent to the same (shared) endpoint.
+ */
+class OAIPMHProducerHeadersPerExchangeTest extends CamelTestSupport {
+
+    private static MockOaipmhServer mockOaipmhServer;
+
+    @BeforeAll
+    static void startServer() {
+        mockOaipmhServer = MockOaipmhServer.create();
+        mockOaipmhServer.start();
+    }
+
+    @AfterAll
+    static void stopServer() {
+        mockOaipmhServer.stop();
+    }
+
+    @Test
+    void onlyFirstHeaderAppliesToItsExchangeOnly() {
+        String uri = "oaipmh://localhost:" + mockOaipmhServer.getHttpPort() + 
"/oai/request?from=2020-06-01T00:00:00Z";
+
+        List<?> allPages = template.requestBody(uri, null, List.class);
+        List<?> firstPage = template.requestBodyAndHeader(uri, null, 
OAIPMHConstants.ONLY_FIRST, true, List.class);
+        List<?> nextAllPages = template.requestBody(uri, null, List.class);
+
+        assertTrue(allPages.size() > 1, "all the pages: " + allPages.size());
+        assertEquals(1, firstPage.size());
+        assertEquals(allPages.size(), nextAllPages.size(), "an exchange 
without the header harvests all the pages");
+        assertFalse(context.getEndpoint(uri, 
OAIPMHEndpoint.class).isOnlyFirst());
+    }
+
+    @Test
+    void onlyFirstHeaderFalseOverridesTheEndpointOption() {
+        String uri = "oaipmh://localhost:" + mockOaipmhServer.getHttpPort()
+                     + "/oai/request?from=2020-06-01T00:00:00Z&onlyFirst=true";
+
+        List<?> allPages = template.requestBodyAndHeader(uri, null, 
OAIPMHConstants.ONLY_FIRST, false, List.class);
+        List<?> firstPage = template.requestBody(uri, null, List.class);
+
+        assertTrue(allPages.size() > 1, "a header of false harvests all the 
pages: " + allPages.size());
+        assertEquals(1, firstPage.size(), "an exchange without the header uses 
the endpoint option");
+        assertTrue(context.getEndpoint(uri, 
OAIPMHEndpoint.class).isOnlyFirst());
+    }
+
+    @Test
+    void ignoreSSLWarningsHeaderFalseOverridesTheEndpointOption() {
+        String uri = "oaipmh://localhost:" + mockOaipmhServer.getHttpsPort()
+                     + 
"/oai/request?ssl=true&verb=Identify&ignoreSSLWarnings=true";
+
+        CamelExecutionException e = assertThrows(CamelExecutionException.class,
+                () -> template.requestBodyAndHeader(uri, null, 
OAIPMHConstants.IGNORE_SSL_WARNINGS, false, List.class),
+                "a header of false rejects the self-signed certificate");
+        assertInstanceOf(SSLException.class, e.getCause(), "cause: " + 
e.getCause());
+
+        List<?> identify = template.requestBody(uri, null, List.class);
+        assertEquals(1, identify.size(), "an exchange without the header uses 
the endpoint option");
+        assertTrue(context.getEndpoint(uri, 
OAIPMHEndpoint.class).isIgnoreSSLWarnings());
+    }
+
+    @Test
+    void ignoreSSLWarningsHeaderAppliesToItsExchangeOnly() {
+        String uri = "oaipmh://localhost:" + mockOaipmhServer.getHttpsPort() + 
"/oai/request?ssl=true&verb=Identify";
+
+        List<?> identify = template.requestBodyAndHeader(uri, null, 
OAIPMHConstants.IGNORE_SSL_WARNINGS, true, List.class);
+        assertEquals(1, identify.size());
+
+        CamelExecutionException e = assertThrows(CamelExecutionException.class,
+                () -> template.requestBody(uri, null, List.class),
+                "the self-signed certificate is rejected for an exchange 
without the header");
+        assertInstanceOf(SSLException.class, e.getCause(), "cause: " + 
e.getCause());
+        assertFalse(context.getEndpoint(uri, 
OAIPMHEndpoint.class).isIgnoreSSLWarnings());
+    }
+}

Reply via email to