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

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 3ede9b0ab221 CAMEL-26167: camel-cm-sms - the from of an SMSMessage is 
the sender, and a validation failure names the invalid fields (#28766)
3ede9b0ab221 is described below

commit 3ede9b0ab2215908abc3d1260f670a178d5607cb
Author: Vignesh Nayak Manel <[email protected]>
AuthorDate: Sun Nov 1 19:02:55 2026 +0530

    CAMEL-26167: camel-cm-sms - the from of an SMSMessage is the sender, and a 
validation failure names the invalid fields (#28766)
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 .../org/apache/camel/component/cm/CMProducer.java  | 14 +++++++--
 .../org/apache/camel/component/cm/test/CMTest.java | 34 ++++++++++++++++++++++
 .../ROOT/pages/camel-4x-upgrade-guide-4_24.adoc    |  9 ++++++
 3 files changed, 54 insertions(+), 3 deletions(-)

diff --git 
a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMProducer.java
 
b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMProducer.java
index 53ba01ed62a0..3690949440fc 100644
--- 
a/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMProducer.java
+++ 
b/components/camel-cm-sms/src/main/java/org/apache/camel/component/cm/CMProducer.java
@@ -17,12 +17,14 @@
 package org.apache.camel.component.cm;
 
 import java.util.Set;
+import java.util.StringJoiner;
 
 import jakarta.validation.ConstraintViolation;
 import jakarta.validation.Validator;
 
 import org.apache.camel.Exchange;
 import org.apache.camel.InvalidPayloadRuntimeException;
+import org.apache.camel.ValidationException;
 import org.apache.camel.component.cm.client.SMSMessage;
 import org.apache.camel.component.cm.exceptions.HostUnavailableException;
 import org.apache.camel.support.DefaultProducer;
@@ -67,12 +69,15 @@ public class CMProducer extends DefaultProducer {
         LOG.trace("Validating SMSMessage instance provided: {}", smsMessage);
         final Set<ConstraintViolation<SMSMessage>> constraintViolations = 
getValidator().validate(smsMessage);
         if (!constraintViolations.isEmpty()) {
-            final StringBuilder msg = new StringBuilder();
+            final StringJoiner msg = new StringJoiner("; ", "Invalid 
SMSMessage: ", "");
             for (final ConstraintViolation<SMSMessage> cv : 
constraintViolations) {
-                msg.append(String.format("- Invalid value for %s: %s", 
cv.getPropertyPath().toString(), cv.getMessage()));
+                msg.add(String.format("invalid value for %s: %s", 
cv.getPropertyPath().toString(), cv.getMessage()));
             }
             LOG.debug("SMS message: {}", msg);
-            throw new InvalidPayloadRuntimeException(exchange, 
SMSMessage.class);
+            // the violations are in the message of the exception, so the user 
can see which field is invalid.
+            // The cause is a checked exception, so a Camel proxy still throws 
the InvalidPayloadRuntimeException.
+            throw new InvalidPayloadRuntimeException(
+                    exchange, SMSMessage.class, new 
ValidationException(exchange, msg.toString()));
         }
         LOG.trace("SMSMessage instance is valid: {}", smsMessage);
 
@@ -87,6 +92,9 @@ public class CMProducer extends DefaultProducer {
             String df = getConfiguration().getDefaultFrom();
             cmMessage.setSender(df);
             LOG.debug("Dynamic sender is set to default dynamic sender: {}", 
df);
+        } else {
+            cmMessage.setSender(smsMessage.getFrom());
+            LOG.debug("Dynamic sender is set to the sender of the SMSMessage: 
{}", smsMessage.getFrom());
         }
 
         // Remember, this can be null.
diff --git 
a/components/camel-cm-sms/src/test/java/org/apache/camel/component/cm/test/CMTest.java
 
b/components/camel-cm-sms/src/test/java/org/apache/camel/component/cm/test/CMTest.java
index 3bca0c65b4b2..046d939ea152 100644
--- 
a/components/camel-cm-sms/src/test/java/org/apache/camel/component/cm/test/CMTest.java
+++ 
b/components/camel-cm-sms/src/test/java/org/apache/camel/component/cm/test/CMTest.java
@@ -18,6 +18,8 @@ package org.apache.camel.component.cm.test;
 
 import java.math.BigInteger;
 import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.List;
 
 import com.google.i18n.phonenumbers.PhoneNumberUtil;
 import com.google.i18n.phonenumbers.PhoneNumberUtil.PhoneNumberFormat;
@@ -27,7 +29,9 @@ import org.apache.camel.InvalidPayloadRuntimeException;
 import org.apache.camel.Produce;
 import org.apache.camel.ResolveEndpointFailedException;
 import org.apache.camel.Service;
+import org.apache.camel.ValidationException;
 import org.apache.camel.component.cm.CMEndpoint;
+import org.apache.camel.component.cm.CMMessage;
 import org.apache.camel.component.cm.CMProducer;
 import org.apache.camel.component.cm.client.SMSMessage;
 import org.apache.camel.component.cm.exceptions.HostUnavailableException;
@@ -57,7 +61,10 @@ import org.junit.jupiter.api.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
 import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 @CamelSpringTest
 public class CMTest extends CamelTestConfiguration {
@@ -295,6 +302,33 @@ public class CMTest extends CamelTestConfiguration {
                 () -> cmProxy.send(smsMessage));
     }
 
+    @Test
+    public void testInvalidPayloadNamesTheInvalidField() {
+        // a sender longer than 11 characters
+        final SMSMessage smsMessage
+                = new SMSMessage(generateIdAsString(), 
generateGSM0338Message(), validNumber, "SenderTooLong");
+        InvalidPayloadRuntimeException e = 
assertThrows(InvalidPayloadRuntimeException.class,
+                () -> cmProxy.send(smsMessage));
+        assertTrue(e.getMessage().contains("Invalid SMSMessage: invalid value 
for from"), e.getMessage());
+        assertInstanceOf(ValidationException.class, e.getCause());
+    }
+
+    @Test
+    public void testTheSenderOfTheMessageIsUsed() throws Exception {
+        CMEndpoint endpoint = (CMEndpoint) context.getEndpoint(getUri());
+        CMProducer producer = endpoint.createProducer();
+        List<CMMessage> sent = new ArrayList<>();
+        producer.setSender(sent::add);
+
+        send(producer, new SMSMessage(generateIdAsString(), 
generateGSM0338Message(), validNumber, "MySender"));
+        send(producer, new SMSMessage(generateIdAsString(), 
generateGSM0338Message(), validNumber, null));
+
+        assertEquals(2, sent.size());
+        assertEquals("MySender", sent.get(0).getSender());
+        assertEquals(endpoint.getConfiguration().getDefaultFrom(), 
sent.get(1).getSender(),
+                "a message without a sender uses defaultFrom");
+    }
+
     /*
      * CMMessages
      */
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
index 20a743212e8f..674fffc04fb1 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
@@ -565,6 +565,15 @@ message sent to that endpoint returned only the first 
page, and after one messag
 `CamelOaimphIgnoreSSLWarnings=true` every later message accepted a self-signed 
certificate. A message without the
 header uses the `onlyFirst` and `ignoreSSLWarnings` options of the endpoint.
 
+=== camel-cm-sms - the from of an SMSMessage is the sender of the SMS
+
+An `SMSMessage` with a `from` is now sent with that sender. Before, the sender 
was set only when `from` was empty (to
+`defaultFrom`), so a message with its own `from` was sent with an empty 
sender. A message without a `from` is still sent
+with `defaultFrom`.
+
+When the validation of an `SMSMessage` fails, the 
`InvalidPayloadRuntimeException` now names the invalid fields in its
+message, and its cause is an `org.apache.camel.ValidationException`.
+
 === camel-aws - the HTTP client is no longer looked up on the classpath
 
 The camel-aws components now set the HTTP client of the AWS SDK clients they 
create for their endpoints: the Apache 5

Reply via email to