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

gnodet pushed a commit to branch camel-4.18.x
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/camel-4.18.x by this push:
     new b5c3e555b39c [backport camel-4.18.x] CAMEL-26891: camel-whatsapp - log 
the response status at INFO and the response body at DEBUG (#29776)
b5c3e555b39c is described below

commit b5c3e555b39c2ffce112dead9fb8f326da4f2216
Author: Guillaume Nodet <[email protected]>
AuthorDate: Fri Nov 13 10:22:00 2026 +0100

    [backport camel-4.18.x] CAMEL-26891: camel-whatsapp - log the response 
status at INFO and the response body at DEBUG (#29776)
    
    * [backport camel-4.18.x] CAMEL-26891: camel-whatsapp - log the response 
status at INFO and the response body at DEBUG
    
    * CAMEL-26891: camel-whatsapp - use camel-test-junit5 in the backported test
    
    camel-4.18.x has no camel-test-junit6.
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
    
    ---------
    
    Signed-off-by: Claus Ibsen <[email protected]>
    Co-authored-by: Claus Ibsen <[email protected]>
    Co-authored-by: Claude Opus 5.5 <[email protected]>
---
 .../service/WhatsAppServiceRestAPIAdapter.java     |   3 +-
 .../whatsapp/WhatsAppProducerResponseLogTest.java  | 147 +++++++++++++++++++++
 2 files changed, 149 insertions(+), 1 deletion(-)

diff --git 
a/components/camel-whatsapp/src/main/java/org/apache/camel/component/whatsapp/service/WhatsAppServiceRestAPIAdapter.java
 
b/components/camel-whatsapp/src/main/java/org/apache/camel/component/whatsapp/service/WhatsAppServiceRestAPIAdapter.java
index 0b4c73abecd9..d678fdf10728 100644
--- 
a/components/camel-whatsapp/src/main/java/org/apache/camel/component/whatsapp/service/WhatsAppServiceRestAPIAdapter.java
+++ 
b/components/camel-whatsapp/src/main/java/org/apache/camel/component/whatsapp/service/WhatsAppServiceRestAPIAdapter.java
@@ -200,7 +200,8 @@ public class WhatsAppServiceRestAPIAdapter implements 
WhatsAppService {
             asyncResponse.thenAccept(response -> {
                 try {
                     int statusCode = response.statusCode();
-                    LOG.info("Response received with status {} and body {}", 
statusCode, response.body());
+                    LOG.info("Response received with status {}", statusCode);
+                    LOG.debug("Response body: {}", response.body());
                     final boolean success = statusCode >= 200 && statusCode < 
300;
                     if (success) {
                         final Object result = 
mapper.readValue(response.body(), resultClass);
diff --git 
a/components/camel-whatsapp/src/test/java/org/apache/camel/component/whatsapp/WhatsAppProducerResponseLogTest.java
 
b/components/camel-whatsapp/src/test/java/org/apache/camel/component/whatsapp/WhatsAppProducerResponseLogTest.java
new file mode 100644
index 000000000000..8831924810c1
--- /dev/null
+++ 
b/components/camel-whatsapp/src/test/java/org/apache/camel/component/whatsapp/WhatsAppProducerResponseLogTest.java
@@ -0,0 +1,147 @@
+/*
+ * 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.component.whatsapp;
+
+import java.net.InetSocketAddress;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.TimeUnit;
+
+import com.sun.net.httpserver.HttpServer;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.whatsapp.model.MessageResponse;
+import org.apache.camel.component.whatsapp.model.TextMessage;
+import org.apache.camel.component.whatsapp.model.TextMessageRequest;
+import 
org.apache.camel.component.whatsapp.service.WhatsAppServiceRestAPIAdapter;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.Logger;
+import org.apache.logging.log4j.core.appender.AbstractAppender;
+import org.apache.logging.log4j.core.config.Property;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * At INFO the producer logs only the status of the provider response, not its 
body. The body stays available at DEBUG
+ * for diagnostics and the parsed response still reaches the route.
+ */
+class WhatsAppProducerResponseLogTest extends CamelTestSupport {
+
+    // values that appear in the response body but must not be echoed into the 
INFO log
+    private static final String RECIPIENT = "15550009999";
+    private static final String MESSAGE_ID = "wamid.TESTONLYMARKER";
+
+    private HttpServer server;
+
+    @Override
+    protected void setupResources() throws Exception {
+        server = HttpServer.create(new InetSocketAddress("localhost", 0), 0);
+        server.createContext("/", exchange -> {
+            byte[] body = ("{\"messaging_product\":\"whatsapp\","
+                           + "\"contacts\":[{\"input\":\"" + RECIPIENT + 
"\",\"wa_id\":\"" + RECIPIENT + "\"}],"
+                           + "\"messages\":[{\"id\":\"" + MESSAGE_ID + "\"}]}")
+                    .getBytes(StandardCharsets.UTF_8);
+            exchange.getResponseHeaders().add("Content-Type", 
"application/json");
+            exchange.sendResponseHeaders(200, body.length);
+            exchange.getResponseBody().write(body);
+            exchange.close();
+        });
+        server.start();
+    }
+
+    @Override
+    protected void cleanupResources() {
+        server.stop(0);
+    }
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext context = super.createCamelContext();
+        WhatsAppComponent component = new WhatsAppComponent();
+        component.setAuthorizationToken("token");
+        context.addComponent("whatsapp", component);
+        return context;
+    }
+
+    @Test
+    void logsTheStatusButNotTheResponseBodyAtInfo() throws Exception {
+        Logger adapterLogger = (Logger) 
LogManager.getLogger(WhatsAppServiceRestAPIAdapter.class);
+        LogEventCaptor captor = new LogEventCaptor();
+        adapterLogger.addAppender(captor);
+
+        Exchange exchange;
+        try {
+            exchange = template.asyncSend("direct:server", e -> 
e.getIn().setBody(textMessage()))
+                    .get(30, TimeUnit.SECONDS);
+        } finally {
+            adapterLogger.removeAppender(captor);
+        }
+
+        // functionality preserved: the parsed response still reaches the route
+        assertThat(exchange.getException()).isNull();
+        
assertThat(exchange.getMessage().getBody()).isInstanceOf(MessageResponse.class);
+
+        List<String> infoMessages = captor.events.stream()
+                .filter(event -> event.getLevel() == Level.INFO)
+                .map(event -> event.getMessage().getFormattedMessage())
+                .toList();
+
+        // the status is still reported at INFO ...
+        assertThat(infoMessages).anyMatch(message -> message.contains("200"));
+        // ... but the response body (recipient and message identifiers) is not
+        assertThat(infoMessages).noneMatch(message -> 
message.contains(RECIPIENT));
+        assertThat(infoMessages).noneMatch(message -> 
message.contains(MESSAGE_ID));
+    }
+
+    private static TextMessageRequest textMessage() {
+        TextMessageRequest request = new TextMessageRequest();
+        request.setTo(RECIPIENT);
+        request.setText(new TextMessage());
+        request.getText().setBody("Hello");
+        return request;
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                
from("direct:server").to("whatsapp:123?baseUri=http://localhost:"; + 
server.getAddress().getPort());
+            }
+        };
+    }
+
+    private static final class LogEventCaptor extends AbstractAppender {
+        private final List<LogEvent> events = new CopyOnWriteArrayList<>();
+
+        LogEventCaptor() {
+            super("WhatsAppProducerResponseLogCaptor", null, null, false, 
Property.EMPTY_ARRAY);
+            start();
+        }
+
+        @Override
+        public void append(LogEvent event) {
+            events.add(event.toImmutable());
+        }
+    }
+}

Reply via email to