This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch camel-4.10.x
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/camel-4.10.x by this push:
new df12381957f CAMEL-21755: Adjust attachments API on Message to avoid
issue during routing (#17243)
df12381957f is described below
commit df12381957fa00d0f80a2c3c19d0e5431a08665b
Author: Claus Ibsen <[email protected]>
AuthorDate: Mon Feb 24 12:05:29 2025 +0000
CAMEL-21755: Adjust attachments API on Message to avoid issue during
routing (#17243)
* CAMEL-21755: Adjust attachments API on Message to avoid issue during
routing
* CAMEL-21755: Adjust attachments API on Message to avoid issue during
routing
---
.../camel/attachment/AttachmentConverter.java | 2 -
.../attachment/AttachmentExpressionBuilder.java | 115 ++++++++++-----------
.../org/apache/camel/attachment/AttachmentMap.java | 31 ------
.../apache/camel/attachment/AttachmentMessage.java | 21 ++--
.../camel/attachment/CSimpleAttachmentHelper.java | 44 ++++----
.../camel/attachment/DefaultAttachmentMessage.java | 114 +++++++++-----------
.../component/jetty12/AttachmentHttpBinding.java | 7 +-
.../apache/camel/component/mail/MailConsumer.java | 8 --
.../component/mail/SplitAttachmentsExpression.java | 2 +-
.../component/mail/MailAttachmentNamesTest.java | 5 +-
.../component/servlet/AttachmentHttpBinding.java | 3 +-
.../undertow/DefaultUndertowHttpBinding.java | 3 +-
.../java/org/apache/camel/ExchangeExtension.java | 5 -
.../src/main/java/org/apache/camel/Message.java | 10 ++
.../apache/camel/trait/message/MessageTrait.java | 9 +-
.../org/apache/camel/support/AbstractExchange.java | 12 ++-
.../org/apache/camel/support/DefaultMessage.java | 2 +
.../org/apache/camel/support/ExchangeHelper.java | 16 +--
.../camel/support/ExtendedExchangeExtension.java | 5 -
.../org/apache/camel/support/MessageSupport.java | 19 +++-
.../apache/camel/support/MessageHelperTest.java | 15 +--
21 files changed, 196 insertions(+), 252 deletions(-)
diff --git
a/components/camel-attachments/src/main/java/org/apache/camel/attachment/AttachmentConverter.java
b/components/camel-attachments/src/main/java/org/apache/camel/attachment/AttachmentConverter.java
index 9fcf132a725..bfe3b0e81d4 100644
---
a/components/camel-attachments/src/main/java/org/apache/camel/attachment/AttachmentConverter.java
+++
b/components/camel-attachments/src/main/java/org/apache/camel/attachment/AttachmentConverter.java
@@ -37,8 +37,6 @@ public final class AttachmentConverter {
answer = am;
} else {
answer = new DefaultAttachmentMessage(message);
- // need to wrap exchange message as attachment capable
- message.getExchange().setMessage(answer);
}
return answer;
}
diff --git
a/components/camel-attachments/src/main/java/org/apache/camel/attachment/AttachmentExpressionBuilder.java
b/components/camel-attachments/src/main/java/org/apache/camel/attachment/AttachmentExpressionBuilder.java
index d86f06e6664..fbdda092088 100644
---
a/components/camel-attachments/src/main/java/org/apache/camel/attachment/AttachmentExpressionBuilder.java
+++
b/components/camel-attachments/src/main/java/org/apache/camel/attachment/AttachmentExpressionBuilder.java
@@ -30,14 +30,21 @@ import static
org.apache.camel.support.builder.ExpressionBuilder.simpleExpressio
public class AttachmentExpressionBuilder {
+ private static AttachmentMessage toAttachmentMessage(Exchange exchange) {
+ AttachmentMessage answer;
+ if (exchange.getMessage() instanceof AttachmentMessage am) {
+ answer = am;
+ } else {
+ answer = new DefaultAttachmentMessage(exchange.getMessage());
+ }
+ return answer;
+ }
+
public static Expression attachments() {
return new ExpressionAdapter() {
@Override
public Object evaluate(Exchange exchange) {
- if (exchange.getMessage() instanceof AttachmentMessage am) {
- return am.getAttachments();
- }
- return null;
+ return toAttachmentMessage(exchange).getAttachments();
}
};
}
@@ -46,10 +53,7 @@ public class AttachmentExpressionBuilder {
return new ExpressionAdapter() {
@Override
public Object evaluate(Exchange exchange) {
- if (exchange.getMessage() instanceof AttachmentMessage am) {
- return am.getAttachments().size();
- }
- return 0;
+ return toAttachmentMessage(exchange).getAttachments().size();
}
};
}
@@ -60,20 +64,18 @@ public class AttachmentExpressionBuilder {
@Override
public Object evaluate(Exchange exchange) {
- Object answer = null;
- if (exchange.getMessage() instanceof AttachmentMessage am) {
- var dh = am.getAttachment(key);
+ Object answer;
+ var dh = toAttachmentMessage(exchange).getAttachment(key);
+ try {
+ answer = dh.getContent();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ if (answer != null && clazz != null) {
try {
- answer = dh.getContent();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- if (answer != null && clazz != null) {
- try {
- answer =
exchange.getContext().getTypeConverter().mandatoryConvertTo(clazz, answer);
- } catch (NoTypeConversionAvailableException e) {
- throw
CamelExecutionException.wrapCamelExecutionException(exchange, e);
- }
+ answer =
exchange.getContext().getTypeConverter().mandatoryConvertTo(clazz, answer);
+ } catch (NoTypeConversionAvailableException e) {
+ throw
CamelExecutionException.wrapCamelExecutionException(exchange, e);
}
}
return answer;
@@ -99,16 +101,14 @@ public class AttachmentExpressionBuilder {
@Override
public Object evaluate(Exchange exchange) {
Object answer = null;
- if (exchange.getMessage() instanceof AttachmentMessage am) {
- var ao = am.getAttachmentObject(key);
- if (ao != null) {
- answer = ao.getHeader(name);
- if (answer != null && clazz != null) {
- try {
- answer =
exchange.getContext().getTypeConverter().mandatoryConvertTo(clazz, answer);
- } catch (NoTypeConversionAvailableException e) {
- throw
CamelExecutionException.wrapCamelExecutionException(exchange, e);
- }
+ var ao =
toAttachmentMessage(exchange).getAttachmentObject(key);
+ if (ao != null) {
+ answer = ao.getHeader(name);
+ if (answer != null && clazz != null) {
+ try {
+ answer =
exchange.getContext().getTypeConverter().mandatoryConvertTo(clazz, answer);
+ } catch (NoTypeConversionAvailableException e) {
+ throw
CamelExecutionException.wrapCamelExecutionException(exchange, e);
}
}
}
@@ -132,11 +132,9 @@ public class AttachmentExpressionBuilder {
return new ExpressionAdapter() {
@Override
public Object evaluate(Exchange exchange) {
- if (exchange.getMessage() instanceof AttachmentMessage am) {
- var dh = am.getAttachment(key);
- if (dh != null) {
- return dh.getContentType();
- }
+ var dh = toAttachmentMessage(exchange).getAttachment(key);
+ if (dh != null) {
+ return dh.getContentType();
}
return null;
}
@@ -164,15 +162,12 @@ public class AttachmentExpressionBuilder {
return new ExpressionAdapter() {
@Override
public Object evaluate(Exchange exchange) {
- if (exchange.getMessage() instanceof AttachmentMessage am) {
- String key = attachmentName.evaluate(exchange,
String.class);
- Object answer = am.getAttachment(key);
- if (mandatory && answer == null) {
- throw
RuntimeCamelException.wrapRuntimeCamelException(new
NoSuchAttachmentException(exchange, key));
- }
- return answer;
+ String key = attachmentName.evaluate(exchange, String.class);
+ Object answer =
toAttachmentMessage(exchange).getAttachment(key);
+ if (mandatory && answer == null) {
+ throw RuntimeCamelException.wrapRuntimeCamelException(new
NoSuchAttachmentException(exchange, key));
}
- return null;
+ return answer;
}
@Override
@@ -198,27 +193,25 @@ public class AttachmentExpressionBuilder {
return new SimpleExpressionBuilder.KeyedOgnlExpressionAdapter(
ognl, "attachmentOgnl(" + ognl + ")",
(exchange, exp) -> {
- if (exchange.getMessage() instanceof AttachmentMessage am)
{
- String text = exp.evaluate(exchange, String.class);
- var dh = am.getAttachment(text);
- if (dh == null && ObjectHelper.isNumber(text)) {
- try {
- // fallback to lookup by numeric index
- int idx = Integer.parseInt(text);
- if (idx < am.getAttachments().size()) {
- var it =
am.getAttachments().values().iterator();
- for (int i = 0; i < idx; i++) {
- it.next();
- }
- dh = it.next();
+ String text = exp.evaluate(exchange, String.class);
+ var am = toAttachmentMessage(exchange);
+ var dh = am.getAttachment(text);
+ if (dh == null && ObjectHelper.isNumber(text)) {
+ try {
+ // fallback to lookup by numeric index
+ int idx = Integer.parseInt(text);
+ if (idx < am.getAttachments().size()) {
+ var it =
am.getAttachments().values().iterator();
+ for (int i = 0; i < idx; i++) {
+ it.next();
}
- } catch (NumberFormatException e) {
- // ignore
+ dh = it.next();
}
+ } catch (NumberFormatException e) {
+ // ignore
}
- return dh;
}
- return null;
+ return dh;
});
}
diff --git
a/components/camel-attachments/src/main/java/org/apache/camel/attachment/AttachmentMap.java
b/components/camel-attachments/src/main/java/org/apache/camel/attachment/AttachmentMap.java
deleted file mode 100644
index bf4eb24c2cc..00000000000
---
a/components/camel-attachments/src/main/java/org/apache/camel/attachment/AttachmentMap.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.attachment;
-
-import java.util.LinkedHashMap;
-
-import org.apache.camel.SafeCopyProperty;
-
-public final class AttachmentMap extends LinkedHashMap<String, Attachment>
implements SafeCopyProperty {
-
- @Override
- public SafeCopyProperty safeCopy() {
- AttachmentMap clone = new AttachmentMap();
- clone.putAll(this);
- return clone;
- }
-}
diff --git
a/components/camel-attachments/src/main/java/org/apache/camel/attachment/AttachmentMessage.java
b/components/camel-attachments/src/main/java/org/apache/camel/attachment/AttachmentMessage.java
index 44240d265e7..4a910993ddf 100644
---
a/components/camel-attachments/src/main/java/org/apache/camel/attachment/AttachmentMessage.java
+++
b/components/camel-attachments/src/main/java/org/apache/camel/attachment/AttachmentMessage.java
@@ -28,12 +28,6 @@ import org.apache.camel.Message;
*/
public interface AttachmentMessage extends Message {
- /**
- * The {@link AttachmentMessage} will wrap the previous {@link Message}
and this method gives access to the previous
- * message instance.
- */
- Message getDelegateMessage();
-
/**
* Returns the attachment specified by the id
*
@@ -81,16 +75,20 @@ public interface AttachmentMessage extends Message {
void addAttachmentObject(String id, Attachment content);
/**
- * Returns all attachments of the message
+ * Returns all attachments of the message.
+ * <p/>
+ * To add or remove attachments then use the APIs from this message, as
the returned map is a read-only instance.
*
- * @return the attachments in a map or <tt>null</tt>
+ * @return the attachments in a read-only map
*/
Map<String, DataHandler> getAttachments();
/**
* Returns all attachments of the message
+ * <p/>
+ * To add or remove attachments then use the APIs from this message, as
the returned map is a read-only instance.
*
- * @return the attachments in a map or <tt>null</tt>
+ * @return the attachments in a read-only map
*/
Map<String, Attachment> getAttachmentObjects();
@@ -115,4 +113,9 @@ public interface AttachmentMessage extends Message {
*/
boolean hasAttachments();
+ /**
+ * Clears all the attachments.
+ */
+ void clearAttachments();
+
}
diff --git
a/components/camel-attachments/src/main/java/org/apache/camel/attachment/CSimpleAttachmentHelper.java
b/components/camel-attachments/src/main/java/org/apache/camel/attachment/CSimpleAttachmentHelper.java
index 1252657eadd..b6caaefb121 100644
---
a/components/camel-attachments/src/main/java/org/apache/camel/attachment/CSimpleAttachmentHelper.java
+++
b/components/camel-attachments/src/main/java/org/apache/camel/attachment/CSimpleAttachmentHelper.java
@@ -24,31 +24,33 @@ import org.apache.camel.Exchange;
public class CSimpleAttachmentHelper {
- public static Map<String, DataHandler> attachments(Exchange exchange) {
+ private static AttachmentMessage toAttachmentMessage(Exchange exchange) {
+ AttachmentMessage answer;
if (exchange.getMessage() instanceof AttachmentMessage am) {
- return am.getAttachments();
+ answer = am;
+ } else {
+ answer = new DefaultAttachmentMessage(exchange.getMessage());
}
- return null;
+ return answer;
+ }
+
+ public static Map<String, DataHandler> attachments(Exchange exchange) {
+ return toAttachmentMessage(exchange).getAttachments();
}
public static int attachmentsSize(Exchange exchange) {
- if (exchange.getMessage() instanceof AttachmentMessage am) {
- return am.getAttachments().size();
- }
- return 0;
+ return toAttachmentMessage(exchange).getAttachments().size();
}
public static Object attachmentContent(Exchange exchange, String key)
throws Exception {
- if (exchange.getMessage() instanceof AttachmentMessage am) {
- var dh = am.getAttachments().get(key);
- if (dh != null) {
- return dh.getContent();
- }
+ var dh = toAttachmentMessage(exchange).getAttachments().get(key);
+ if (dh != null) {
+ return dh.getContent();
}
return null;
}
- public static Object attachmentContentAsText(Exchange exchange, String
key) throws Exception {
+ public static String attachmentContentAsText(Exchange exchange, String
key) throws Exception {
Object data = attachmentContent(exchange, key);
if (data != null) {
return
exchange.getContext().getTypeConverter().convertTo(String.class, exchange,
data);
@@ -65,21 +67,17 @@ public class CSimpleAttachmentHelper {
}
public static String attachmentContentType(Exchange exchange, String key) {
- if (exchange.getMessage() instanceof AttachmentMessage am) {
- var dh = am.getAttachments().get(key);
- if (dh != null) {
- return dh.getContentType();
- }
+ var dh = toAttachmentMessage(exchange).getAttachments().get(key);
+ if (dh != null) {
+ return dh.getContentType();
}
return null;
}
public static String attachmentHeader(Exchange exchange, String key,
String name) {
- if (exchange.getMessage() instanceof AttachmentMessage am) {
- var ao = am.getAttachmentObjects().get(key);
- if (ao != null) {
- return ao.getHeader(name);
- }
+ var ao = toAttachmentMessage(exchange).getAttachmentObjects().get(key);
+ if (ao != null) {
+ return ao.getHeader(name);
}
return null;
}
diff --git
a/components/camel-attachments/src/main/java/org/apache/camel/attachment/DefaultAttachmentMessage.java
b/components/camel-attachments/src/main/java/org/apache/camel/attachment/DefaultAttachmentMessage.java
index 10e53c88b78..fb31dfb2837 100644
---
a/components/camel-attachments/src/main/java/org/apache/camel/attachment/DefaultAttachmentMessage.java
+++
b/components/camel-attachments/src/main/java/org/apache/camel/attachment/DefaultAttachmentMessage.java
@@ -16,6 +16,7 @@
*/
package org.apache.camel.attachment;
+import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
@@ -30,23 +31,24 @@ import org.apache.camel.trait.message.MessageTrait;
public final class DefaultAttachmentMessage implements AttachmentMessage {
- /*
- * Attachments are stores as a property on the {@link Exchange} which
ensures they are propagated
- * during routing and we dont have to pollute the generic {@link Message}
with attachment APIs
- */
- private static final String ATTACHMENT_OBJECTS = "CamelAttachmentObjects";
-
private final Message delegate;
- private final Exchange exchange;
public DefaultAttachmentMessage(Message delegate) {
this.delegate = delegate;
- this.exchange = delegate.getExchange();
+ }
+
+ private Map<String, Object> getAttachmentsMap() {
+ var m = (Map<String, Object>)
delegate.getPayloadForTrait(MessageTrait.ATTACHMENTS);
+ if (m == null) {
+ m = new LinkedHashMap<>();
+ delegate.setPayloadForTrait(MessageTrait.ATTACHMENTS, m);
+ }
+ return m;
}
@Override
- public Message getDelegateMessage() {
- return delegate;
+ public Message newInstance() {
+ return new DefaultAttachmentMessage(delegate);
}
@Override
@@ -176,7 +178,7 @@ public final class DefaultAttachmentMessage implements
AttachmentMessage {
@Override
public Message copy() {
- return delegate.copy();
+ return new DefaultAttachmentMessage(delegate.copy());
}
@Override
@@ -190,106 +192,77 @@ public final class DefaultAttachmentMessage implements
AttachmentMessage {
}
@Override
- @SuppressWarnings("unchecked")
public DataHandler getAttachment(String id) {
- AttachmentMap map =
exchange.getExchangeExtension().getSafeCopyProperty(ATTACHMENT_OBJECTS,
AttachmentMap.class);
- if (map != null) {
- Attachment att = map.get(id);
- if (att != null) {
- return att.getDataHandler();
- }
+ Attachment att = (Attachment) getAttachmentsMap().get(id);
+ if (att != null) {
+ return att.getDataHandler();
}
return null;
}
@Override
- @SuppressWarnings("unchecked")
public Attachment getAttachmentObject(String id) {
- AttachmentMap map =
exchange.getExchangeExtension().getSafeCopyProperty(ATTACHMENT_OBJECTS,
AttachmentMap.class);
- if (map != null) {
- return map.get(id);
- }
- return null;
+ return (Attachment) getAttachmentsMap().get(id);
}
@Override
- @SuppressWarnings("unchecked")
public Set<String> getAttachmentNames() {
- AttachmentMap map =
exchange.getExchangeExtension().getSafeCopyProperty(ATTACHMENT_OBJECTS,
AttachmentMap.class);
- if (map != null) {
- return map.keySet();
- }
- return null;
+ return getAttachmentsMap().keySet();
}
@Override
- @SuppressWarnings("unchecked")
public void removeAttachment(String id) {
- AttachmentMap map =
exchange.getExchangeExtension().getSafeCopyProperty(ATTACHMENT_OBJECTS,
AttachmentMap.class);
- if (map != null) {
- map.remove(id);
- }
+ getAttachmentsMap().remove(id);
}
@Override
- @SuppressWarnings("unchecked")
public void addAttachment(String id, DataHandler content) {
- AttachmentMap map =
exchange.getExchangeExtension().getSafeCopyProperty(ATTACHMENT_OBJECTS,
AttachmentMap.class);
- if (map == null) {
- map = new AttachmentMap();
-
exchange.getExchangeExtension().setSafeCopyProperty(ATTACHMENT_OBJECTS, map);
- }
- map.put(id, new DefaultAttachment(content));
+ getAttachmentsMap().put(id, new DefaultAttachment(content));
}
@Override
- @SuppressWarnings("unchecked")
public void addAttachmentObject(String id, Attachment content) {
- AttachmentMap map =
exchange.getExchangeExtension().getSafeCopyProperty(ATTACHMENT_OBJECTS,
AttachmentMap.class);
- if (map == null) {
- map = new AttachmentMap();
-
exchange.getExchangeExtension().setSafeCopyProperty(ATTACHMENT_OBJECTS, map);
- }
- map.put(id, content);
+ getAttachmentsMap().put(id, content);
}
@Override
- @SuppressWarnings("unchecked")
public Map<String, DataHandler> getAttachments() {
- Map<String, Attachment> map =
exchange.getExchangeExtension().getSafeCopyProperty(ATTACHMENT_OBJECTS,
Map.class);
- if (map != null) {
- Map<String, DataHandler> answer = new LinkedHashMap<>();
- map.forEach((id, att) -> answer.put(id, att.getDataHandler()));
- return answer;
- }
- return null;
+ Map<String, DataHandler> answer = new LinkedHashMap<>();
+ getAttachmentsMap().forEach((id, att) -> {
+ Attachment a = (Attachment) att;
+ answer.put(id, a.getDataHandler());
+ });
+ return Collections.unmodifiableMap(answer);
}
@Override
- @SuppressWarnings("unchecked")
public Map<String, Attachment> getAttachmentObjects() {
- return
exchange.getExchangeExtension().getSafeCopyProperty(ATTACHMENT_OBJECTS,
Map.class);
+ Map<String, Attachment> answer = new LinkedHashMap<>();
+ getAttachmentsMap().forEach((id, att) -> {
+ Attachment a = (Attachment) att;
+ answer.put(id, a);
+ });
+ return Collections.unmodifiableMap(answer);
}
@Override
public void setAttachments(Map<String, DataHandler> attachments) {
- AttachmentMap map = new AttachmentMap();
- attachments.forEach((id, dh) -> map.put(id, new
DefaultAttachment(dh)));
-
exchange.getExchangeExtension().setSafeCopyProperty(ATTACHMENT_OBJECTS, map);
+ attachments.forEach((id, dh) -> getAttachmentsMap().put(id, new
DefaultAttachment(dh)));
}
@Override
public void setAttachmentObjects(Map<String, Attachment> attachments) {
- AttachmentMap map = new AttachmentMap();
- map.putAll(attachments);
-
exchange.getExchangeExtension().setSafeCopyProperty(ATTACHMENT_OBJECTS, map);
+ getAttachmentsMap().putAll(attachments);
}
@Override
- @SuppressWarnings("unchecked")
public boolean hasAttachments() {
- AttachmentMap map =
exchange.getExchangeExtension().getSafeCopyProperty(ATTACHMENT_OBJECTS,
AttachmentMap.class);
- return map != null && !map.isEmpty();
+ return delegate.hasTrait(MessageTrait.ATTACHMENTS);
+ }
+
+ @Override
+ public void clearAttachments() {
+ delegate.removeTrait(MessageTrait.ATTACHMENTS);
}
@Override
@@ -306,4 +279,9 @@ public final class DefaultAttachmentMessage implements
AttachmentMessage {
public void setPayloadForTrait(MessageTrait trait, Object object) {
delegate.setPayloadForTrait(trait, object);
}
+
+ @Override
+ public void removeTrait(MessageTrait trait) {
+ delegate.removeTrait(trait);
+ }
}
diff --git
a/components/camel-jetty/src/main/java/org/apache/camel/component/jetty12/AttachmentHttpBinding.java
b/components/camel-jetty/src/main/java/org/apache/camel/component/jetty12/AttachmentHttpBinding.java
index 294d72f33d0..1cc465b6b50 100644
---
a/components/camel-jetty/src/main/java/org/apache/camel/component/jetty12/AttachmentHttpBinding.java
+++
b/components/camel-jetty/src/main/java/org/apache/camel/component/jetty12/AttachmentHttpBinding.java
@@ -33,6 +33,7 @@ import org.apache.camel.RuntimeCamelException;
import org.apache.camel.attachment.Attachment;
import org.apache.camel.attachment.AttachmentMessage;
import org.apache.camel.attachment.DefaultAttachment;
+import org.apache.camel.attachment.DefaultAttachmentMessage;
import org.apache.camel.component.jetty.MultiPartFilter;
import org.apache.camel.http.common.DefaultHttpBinding;
import org.apache.camel.http.common.HttpHelper;
@@ -65,7 +66,7 @@ final class AttachmentHttpBinding extends DefaultHttpBinding {
attachment.addHeader(headerName, headerValue);
}
}
- AttachmentMessage am =
message.getExchange().getMessage(AttachmentMessage.class);
+ AttachmentMessage am = new
DefaultAttachmentMessage(message);
am.addAttachmentObject(part.getName(), attachment);
String name = part.getSubmittedFileName();
Object value = am.getAttachment(name);
@@ -101,12 +102,12 @@ final class AttachmentHttpBinding extends
DefaultHttpBinding {
// }
// attachment is optional
- AttachmentMessage am =
message.getExchange().getMessage(AttachmentMessage.class);
+ AttachmentMessage am = new DefaultAttachmentMessage(message);
Enumeration<?> names = request.getParameterNames();
while (names.hasMoreElements()) {
String name = (String) names.nextElement();
- if (am != null && am.getAttachment(name) != null) {
+ if (am.getAttachment(name) != null) {
DataHandler dh = am.getAttachment(name);
Object value = dh;
if (dh.getContentType() == null ||
dh.getContentType().startsWith("text/plain")) {
diff --git
a/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailConsumer.java
b/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailConsumer.java
index d770c7daf2c..82c0887bb4e 100644
---
a/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailConsumer.java
+++
b/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailConsumer.java
@@ -235,10 +235,6 @@ public class MailConsumer extends
ScheduledBatchPollingConsumer {
// must use the original message in case we need to work around a
charset issue when extracting mail content
var msg = exchange.getIn();
- if (msg instanceof AttachmentMessage am) {
- // unwrap from attachment message
- msg = am.getDelegateMessage();
- }
final Message mail = ((MailMessage) msg).getOriginalMessage();
// add on completion to handle after work when the exchange is done
@@ -456,10 +452,6 @@ public class MailConsumer extends
ScheduledBatchPollingConsumer {
protected void processExchange(Exchange exchange) throws Exception {
if (LOG.isDebugEnabled()) {
var msg = exchange.getIn();
- if (msg instanceof AttachmentMessage am) {
- // unwrap from attachment message
- msg = am.getDelegateMessage();
- }
if (msg instanceof MailMessage mm) {
LOG.debug("Processing message: {}",
MailUtils.dumpMessage(mm.getMessage()));
}
diff --git
a/components/camel-mail/src/main/java/org/apache/camel/component/mail/SplitAttachmentsExpression.java
b/components/camel-mail/src/main/java/org/apache/camel/component/mail/SplitAttachmentsExpression.java
index d12ab09c643..3ec673dbd94 100644
---
a/components/camel-mail/src/main/java/org/apache/camel/component/mail/SplitAttachmentsExpression.java
+++
b/components/camel-mail/src/main/java/org/apache/camel/component/mail/SplitAttachmentsExpression.java
@@ -72,7 +72,7 @@ public class SplitAttachmentsExpression extends
ExpressionAdapter {
}
// clear attachments on original message after we have split them
- inMessage.getAttachmentObjects().clear();
+ inMessage.clearAttachments();
return answer;
} catch (Exception e) {
diff --git
a/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailAttachmentNamesTest.java
b/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailAttachmentNamesTest.java
index b2c740b4499..28daf0c5858 100644
---
a/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailAttachmentNamesTest.java
+++
b/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailAttachmentNamesTest.java
@@ -42,7 +42,6 @@ import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class MailAttachmentNamesTest extends CamelTestSupport {
@@ -170,7 +169,7 @@ public class MailAttachmentNamesTest extends
CamelTestSupport {
resultDefaultEndpoint.assertIsSatisfied();
Exchange exchange =
resultDefaultEndpoint.getReceivedExchanges().get(0);
assertNotNull(exchange.getIn(AttachmentMessage.class));
-
assertNull(exchange.getIn(AttachmentMessage.class).getAttachmentObjects());
+ assertEquals(0,
exchange.getIn(AttachmentMessage.class).getAttachmentObjects().size());
}
/**
@@ -185,7 +184,7 @@ public class MailAttachmentNamesTest extends
CamelTestSupport {
resultDefaultEndpoint.assertIsSatisfied();
Exchange exchange =
resultDefaultEndpoint.getReceivedExchanges().get(0);
assertNotNull(exchange.getIn(AttachmentMessage.class));
-
assertNull(exchange.getIn(AttachmentMessage.class).getAttachmentObjects());
+ assertEquals(0,
exchange.getIn(AttachmentMessage.class).getAttachmentObjects().size());
}
@Test
diff --git
a/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/AttachmentHttpBinding.java
b/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/AttachmentHttpBinding.java
index 1b360d5c0ec..0495a2cb9ab 100644
---
a/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/AttachmentHttpBinding.java
+++
b/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/AttachmentHttpBinding.java
@@ -31,6 +31,7 @@ import org.apache.camel.RuntimeCamelException;
import org.apache.camel.attachment.Attachment;
import org.apache.camel.attachment.AttachmentMessage;
import org.apache.camel.attachment.DefaultAttachment;
+import org.apache.camel.attachment.DefaultAttachmentMessage;
import org.apache.camel.http.common.DefaultHttpBinding;
import org.apache.camel.util.FileUtil;
import org.slf4j.Logger;
@@ -75,7 +76,7 @@ public final class AttachmentHttpBinding extends
DefaultHttpBinding {
attachment.addHeader(headerName, headerValue);
}
}
- AttachmentMessage am =
message.getExchange().getMessage(AttachmentMessage.class);
+ AttachmentMessage am = new
DefaultAttachmentMessage(message);
am.addAttachmentObject(part.getName(), attachment);
} else {
LOG.debug(
diff --git
a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/DefaultUndertowHttpBinding.java
b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/DefaultUndertowHttpBinding.java
index 114a9e95be6..a669de857ba 100644
---
a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/DefaultUndertowHttpBinding.java
+++
b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/DefaultUndertowHttpBinding.java
@@ -47,6 +47,7 @@ import org.apache.camel.Message;
import org.apache.camel.TypeConverter;
import org.apache.camel.attachment.AttachmentMessage;
import org.apache.camel.attachment.DefaultAttachment;
+import org.apache.camel.attachment.DefaultAttachmentMessage;
import org.apache.camel.spi.HeaderFilterStrategy;
import org.apache.camel.support.DefaultMessage;
import org.apache.camel.support.ExceptionHelper;
@@ -136,7 +137,7 @@ public class DefaultUndertowHttpBinding implements
UndertowHttpBinding {
formData.get(key).forEach(value -> {
if (value.isFile()) {
DefaultAttachment attachment = new
DefaultAttachment(new FilePartDataSource(value));
- AttachmentMessage am =
result.getExchange().getMessage(AttachmentMessage.class);
+ AttachmentMessage am = new
DefaultAttachmentMessage(result);
am.addAttachmentObject(key, attachment);
body.put(key, attachment.getDataHandler());
} else if (headerFilterStrategy != null
diff --git
a/core/camel-api/src/main/java/org/apache/camel/ExchangeExtension.java
b/core/camel-api/src/main/java/org/apache/camel/ExchangeExtension.java
index 9d13bcd16b1..ded6208da5b 100644
--- a/core/camel-api/src/main/java/org/apache/camel/ExchangeExtension.java
+++ b/core/camel-api/src/main/java/org/apache/camel/ExchangeExtension.java
@@ -38,11 +38,6 @@ public interface ExchangeExtension {
*/
<T> T getInOrNull(Class<T> type);
- /**
- * Prepares the exchange by setting IN as OUT
- */
- void prepareInToOut();
-
/**
* Sets the endpoint which originated this message exchange. This method
should typically only be called by
* {@link Endpoint} implementations
diff --git a/core/camel-api/src/main/java/org/apache/camel/Message.java
b/core/camel-api/src/main/java/org/apache/camel/Message.java
index a056aeb2dcb..9bdd1bb1e75 100644
--- a/core/camel-api/src/main/java/org/apache/camel/Message.java
+++ b/core/camel-api/src/main/java/org/apache/camel/Message.java
@@ -33,6 +33,11 @@ import org.apache.camel.trait.message.MessageTrait;
*/
public interface Message {
+ /**
+ * Returns a new instance of this type.
+ */
+ Message newInstance();
+
/**
* Clears the message from user data, so the message can be reused.
* <p/>
@@ -355,4 +360,9 @@ public interface Message {
*/
void setPayloadForTrait(MessageTrait trait, Object object);
+ /**
+ * Removes the trait
+ */
+ void removeTrait(MessageTrait trait);
+
}
diff --git
a/core/camel-api/src/main/java/org/apache/camel/trait/message/MessageTrait.java
b/core/camel-api/src/main/java/org/apache/camel/trait/message/MessageTrait.java
index 604c7fb1f1c..3b7067eaae2 100644
---
a/core/camel-api/src/main/java/org/apache/camel/trait/message/MessageTrait.java
+++
b/core/camel-api/src/main/java/org/apache/camel/trait/message/MessageTrait.java
@@ -22,13 +22,20 @@ package org.apache.camel.trait.message;
* type, etc). This is specifically for internal usage of Camel and not a
public API.
*/
public enum MessageTrait {
+
/**
* The redelivery trait for the message. See {@link
RedeliveryTraitPayload}.
*/
REDELIVERY,
+
/**
* Whether the message can store a data type. This carries the payload
associated with the API specified in
* {@link org.apache.camel.spi.DataTypeAware}.
*/
- DATA_AWARE
+ DATA_AWARE,
+
+ /**
+ * Trait for storing attachments on the message.
+ */
+ ATTACHMENTS
}
diff --git
a/core/camel-support/src/main/java/org/apache/camel/support/AbstractExchange.java
b/core/camel-support/src/main/java/org/apache/camel/support/AbstractExchange.java
index 98d1cabd2cb..46d948f1b1e 100644
---
a/core/camel-support/src/main/java/org/apache/camel/support/AbstractExchange.java
+++
b/core/camel-support/src/main/java/org/apache/camel/support/AbstractExchange.java
@@ -25,6 +25,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
import org.apache.camel.CamelExecutionException;
import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
@@ -515,10 +516,13 @@ abstract class AbstractExchange implements Exchange {
}
private Message newOutMessage() {
- if (in instanceof MessageSupport messageSupport) {
- return messageSupport.newInstance();
+ if (in != null) {
+ Message answer = in.newInstance();
+ CamelContextAware.trySetCamelContext(answer, getContext());
+ return answer;
+ } else {
+ return new DefaultMessage(getContext());
}
- return new DefaultMessage(getContext());
}
@SuppressWarnings("deprecated")
@@ -655,10 +659,8 @@ abstract class AbstractExchange implements Exchange {
public boolean isExternalRedelivered() {
if (externalRedelivered ==
RedeliveryTraitPayload.UNDEFINED_REDELIVERY) {
Message message = getIn();
-
externalRedelivered = (RedeliveryTraitPayload)
message.getPayloadForTrait(MessageTrait.REDELIVERY);
}
-
return externalRedelivered == RedeliveryTraitPayload.IS_REDELIVERY;
}
diff --git
a/core/camel-support/src/main/java/org/apache/camel/support/DefaultMessage.java
b/core/camel-support/src/main/java/org/apache/camel/support/DefaultMessage.java
index fdec471fc0f..728486f44dd 100644
---
a/core/camel-support/src/main/java/org/apache/camel/support/DefaultMessage.java
+++
b/core/camel-support/src/main/java/org/apache/camel/support/DefaultMessage.java
@@ -24,6 +24,7 @@ import java.util.function.Supplier;
import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.spi.HeadersMapFactory;
+import org.apache.camel.trait.message.MessageTrait;
/**
* The default implementation of {@link org.apache.camel.Message}
@@ -55,6 +56,7 @@ public class DefaultMessage extends MessageSupport {
if (headers != null) {
headers.clear();
}
+ removeTrait(MessageTrait.ATTACHMENTS);
}
@Override
diff --git
a/core/camel-support/src/main/java/org/apache/camel/support/ExchangeHelper.java
b/core/camel-support/src/main/java/org/apache/camel/support/ExchangeHelper.java
index 054b2d904b5..1d09ab4315c 100644
---
a/core/camel-support/src/main/java/org/apache/camel/support/ExchangeHelper.java
+++
b/core/camel-support/src/main/java/org/apache/camel/support/ExchangeHelper.java
@@ -398,13 +398,8 @@ public final class ExchangeHelper {
// we just need to ensure MEP is as expected (eg copy result to OUT if
out capable)
// and the result is not failed
if (result.getPattern().isOutCapable() && !result.hasOut() &&
!result.isFailed()) {
- // prepare IN as OUT as we expect a OUT response
- if (result == source) {
- // optimized
- result.getExchangeExtension().prepareInToOut();
- } else {
- result.getOut().copyFrom(source.getIn());
- }
+ // copy IN to OUT as we expect a OUT response
+ result.getOut().copyFrom(source.getIn());
}
}
@@ -415,12 +410,7 @@ public final class ExchangeHelper {
// so lets assume the last IN is the OUT
if (!preserverPattern && result.getPattern().isOutCapable()) {
// only set OUT if its OUT capable
- if (result == source) {
- // optimized
- result.getExchangeExtension().prepareInToOut();
- } else {
- result.getOut().copyFrom(source.getIn());
- }
+ result.getOut().copyFrom(source.getIn());
} else {
// if not replace IN instead to keep the MEP
result.getIn().copyFrom(source.getIn());
diff --git
a/core/camel-support/src/main/java/org/apache/camel/support/ExtendedExchangeExtension.java
b/core/camel-support/src/main/java/org/apache/camel/support/ExtendedExchangeExtension.java
index 8b383af7163..bb41cac492f 100644
---
a/core/camel-support/src/main/java/org/apache/camel/support/ExtendedExchangeExtension.java
+++
b/core/camel-support/src/main/java/org/apache/camel/support/ExtendedExchangeExtension.java
@@ -271,11 +271,6 @@ public class ExtendedExchangeExtension implements
ExchangeExtension {
return this.exchange.getInOrNull(type);
}
- @Override
- public void prepareInToOut() {
- this.exchange.out = this.exchange.in;
- }
-
@Override
public AsyncCallback getDefaultConsumerCallback() {
return this.defaultConsumerCallback;
diff --git
a/core/camel-support/src/main/java/org/apache/camel/support/MessageSupport.java
b/core/camel-support/src/main/java/org/apache/camel/support/MessageSupport.java
index f1813d0b32b..cb241291c1d 100644
---
a/core/camel-support/src/main/java/org/apache/camel/support/MessageSupport.java
+++
b/core/camel-support/src/main/java/org/apache/camel/support/MessageSupport.java
@@ -17,6 +17,8 @@
package org.apache.camel.support;
import java.util.EnumMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
import org.apache.camel.CamelContext;
import org.apache.camel.CamelContextAware;
@@ -198,6 +200,7 @@ public abstract class MessageSupport implements Message,
CamelContextAware, Data
}
@Override
+ @SuppressWarnings("raw")
public void copyFromWithNewBody(Message that, Object newBody) {
if (that == this) {
// it's the same instance, so do not need to copy
@@ -226,6 +229,12 @@ public abstract class MessageSupport implements Message,
CamelContextAware, Data
getHeaders().putAll(that.getHeaders());
}
}
+
+ // copy attachments
+ Map<String, Object> attachments = (Map<String, Object>)
that.getPayloadForTrait(MessageTrait.ATTACHMENTS);
+ if (attachments != null) {
+ setPayloadForTrait(MessageTrait.ATTACHMENTS, new
LinkedHashMap<>(attachments));
+ }
}
private boolean sameHeaders(Message that) {
@@ -252,11 +261,6 @@ public abstract class MessageSupport implements Message,
CamelContextAware, Data
this.typeConverter = camelContext.getTypeConverter();
}
- /**
- * Returns a new instance
- */
- public abstract Message newInstance();
-
/**
* A factory method to allow a provider to lazily create the message body
for inbound messages from other sources
*
@@ -319,4 +323,9 @@ public abstract class MessageSupport implements Message,
CamelContextAware, Data
public void setPayloadForTrait(MessageTrait trait, Object object) {
traits.put(trait, object);
}
+
+ @Override
+ public void removeTrait(MessageTrait trait) {
+ traits.remove(trait);
+ }
}
diff --git
a/core/camel-support/src/test/java/org/apache/camel/support/MessageHelperTest.java
b/core/camel-support/src/test/java/org/apache/camel/support/MessageHelperTest.java
index 6ba63e877b9..55d9a099154 100644
---
a/core/camel-support/src/test/java/org/apache/camel/support/MessageHelperTest.java
+++
b/core/camel-support/src/test/java/org/apache/camel/support/MessageHelperTest.java
@@ -92,8 +92,12 @@ class MessageHelperTest {
}
@Override
- public void reset() {
+ public Message newInstance() {
+ return null;
+ }
+ @Override
+ public void reset() {
}
@Override
@@ -108,7 +112,6 @@ class MessageHelperTest {
@Override
public void setMessageId(String messageId) {
-
}
@Override
@@ -153,7 +156,6 @@ class MessageHelperTest {
@Override
public void setHeader(String name, Object value) {
-
}
@Override
@@ -178,7 +180,6 @@ class MessageHelperTest {
@Override
public void setHeaders(Map<String, Object> headers) {
-
}
@Override
@@ -213,7 +214,6 @@ class MessageHelperTest {
@Override
public <T> void setBody(Object body, Class<T> type) {
-
}
@Override
@@ -223,12 +223,10 @@ class MessageHelperTest {
@Override
public void copyFrom(Message message) {
-
}
@Override
public void copyFromWithNewBody(Message message, Object newBody) {
-
}
@Override
@@ -243,7 +241,10 @@ class MessageHelperTest {
@Override
public void setPayloadForTrait(MessageTrait trait, Object object) {
+ }
+ @Override
+ public void removeTrait(MessageTrait trait) {
}
}
}