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