This is an automated email from the ASF dual-hosted git repository. orpiske 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 d0888629fcb CAMEL-19058: rework the Message to avoid hitting the type-check scalability issue d0888629fcb is described below commit d0888629fcbcffb8839c6019aa2346b04cb40cb2 Author: Otavio Rodolfo Piske <angusyo...@gmail.com> AuthorDate: Fri Feb 10 09:44:05 2023 +0100 CAMEL-19058: rework the Message to avoid hitting the type-check scalability issue This introduces a trait that works similarly to the internal properties one in the Exchange so that we carry certain details about the message without relying on type specifications. Among other things this: - avoids unnecessarily recreating the DefaultMessage multiple times - moved the data type aware checks out of the hot path - reworks the isTransactedRedelivered to avoid costlier checks for specific message types Signed-off-by: Otavio R. Piske <angusyo...@gmail.com> --- .../camel/attachment/DefaultAttachmentMessage.java | 16 +++++++- .../org/apache/camel/component/jms/JmsMessage.java | 13 ++----- .../camel/component/jms/JmsMessageHelper.java | 24 ++++++++++++ .../apache/camel/component/sjms/SjmsMessage.java | 15 +++----- .../camel/component/sjms/jms/JmsMessageHelper.java | 24 ++++++++++++ .../src/main/java/org/apache/camel/Message.java | 25 ++++++++++++ .../apache/camel/trait/message/MessageTrait.java | 34 +++++++++++++++++ .../trait/message/RedeliveryTraitPayload.java | 38 +++++++++++++++++++ .../org/apache/camel/support/AbstractExchange.java | 23 +++++------ .../org/apache/camel/support/DefaultMessage.java | 15 -------- .../camel/support/DefaultPooledExchange.java | 1 - .../org/apache/camel/support/MessageHelper.java | 15 ++++---- .../org/apache/camel/support/MessageSupport.java | 44 ++++++++++++++++------ .../apache/camel/support/MessageHelperTest.java | 16 ++++++++ 14 files changed, 234 insertions(+), 69 deletions(-) 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 665b3d0bacb..71ab662adb0 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 @@ -26,9 +26,9 @@ import jakarta.activation.DataHandler; import org.apache.camel.Exchange; import org.apache.camel.InvalidPayloadException; import org.apache.camel.Message; +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 @@ -286,4 +286,18 @@ public final class DefaultAttachmentMessage implements AttachmentMessage { return map != null && !map.isEmpty(); } + @Override + public boolean hasTrait(MessageTrait trait) { + return delegate.hasTrait(trait); + } + + @Override + public Object getPayloadForTrait(MessageTrait trait) { + return delegate.getPayloadForTrait(trait); + } + + @Override + public void setPayloadForTrait(MessageTrait trait, Object object) { + delegate.setPayloadForTrait(trait, object); + } } diff --git a/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsMessage.java b/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsMessage.java index 86adc7ff5b8..add5a3b28e1 100644 --- a/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsMessage.java +++ b/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsMessage.java @@ -30,6 +30,7 @@ import org.apache.camel.Exchange; import org.apache.camel.RuntimeExchangeException; import org.apache.camel.support.DefaultMessage; import org.apache.camel.support.ExchangeHelper; +import org.apache.camel.trait.message.MessageTrait; import org.apache.camel.util.ObjectHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,6 +42,7 @@ import static org.apache.camel.support.MessageHelper.copyBody; */ public class JmsMessage extends DefaultMessage { private static final Logger LOG = LoggerFactory.getLogger(JmsMessage.class); + private Message jmsMessage; private Session jmsSession; private JmsBinding binding; @@ -148,6 +150,7 @@ public class JmsMessage extends DefaultMessage { } } this.jmsMessage = jmsMessage; + setPayloadForTrait(MessageTrait.REDELIVERY, JmsMessageHelper.evalRedeliveryMessageTrait(jmsMessage)); } /** @@ -269,15 +272,6 @@ public class JmsMessage extends DefaultMessage { } } - @Override - protected Boolean isTransactedRedelivered() { - if (jmsMessage != null) { - return JmsMessageHelper.getJMSRedelivered(jmsMessage); - } else { - return null; - } - } - private String getDestinationAsString(Destination destination) throws JMSException { String result = null; if (destination == null) { @@ -293,5 +287,4 @@ public class JmsMessage extends DefaultMessage { private String getSanitizedString(Object value) { return value != null ? value.toString().replaceAll("[^a-zA-Z0-9\\.\\_\\-]", "_") : ""; } - } diff --git a/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsMessageHelper.java b/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsMessageHelper.java index e18b19cb5d1..3f10d4767dd 100644 --- a/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsMessageHelper.java +++ b/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsMessageHelper.java @@ -28,6 +28,8 @@ import jakarta.jms.Message; import org.apache.camel.Exchange; import org.apache.camel.support.ExchangeHelper; +import org.apache.camel.trait.message.MessageTrait; +import org.apache.camel.trait.message.RedeliveryTraitPayload; import org.apache.camel.util.ObjectHelper; import static org.apache.camel.component.jms.JmsConfiguration.QUEUE_PREFIX; @@ -349,6 +351,28 @@ public final class JmsMessageHelper { return null; } + /** + * For a given message, evaluates what is the redelivery state for it and gives the appropriate {@link MessageTrait} + * for that redelivery state + * + * @param message the message to evalute + * @return The appropriate MessageTrait for the redelivery state (one of MessageTrait.UNDEFINED_REDELIVERY, + * MessageTrait.IS_REDELIVERY or MessageTrait.NON_REDELIVERY). + */ + public static RedeliveryTraitPayload evalRedeliveryMessageTrait(Message message) { + final Boolean redelivered = JmsMessageHelper.getJMSRedelivered(message); + + if (redelivered == null) { + return RedeliveryTraitPayload.UNDEFINED_REDELIVERY; + } + + if (Boolean.TRUE.equals(redelivered)) { + return RedeliveryTraitPayload.IS_REDELIVERY; + } + + return RedeliveryTraitPayload.NON_REDELIVERY; + } + /** * Gets the JMSMessageID from the message. * diff --git a/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsMessage.java b/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsMessage.java index a99ac0d0574..69c2b815345 100644 --- a/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsMessage.java +++ b/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsMessage.java @@ -32,6 +32,7 @@ import org.apache.camel.component.sjms.jms.JmsBinding; import org.apache.camel.component.sjms.jms.JmsMessageHelper; import org.apache.camel.support.DefaultMessage; import org.apache.camel.support.ExchangeHelper; +import org.apache.camel.trait.message.MessageTrait; import org.apache.camel.util.ObjectHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,6 +44,7 @@ import static org.apache.camel.support.MessageHelper.copyBody; */ public class SjmsMessage extends DefaultMessage { private static final Logger LOG = LoggerFactory.getLogger(SjmsMessage.class); + private Message jmsMessage; private Session jmsSession; private JmsBinding binding; @@ -52,6 +54,8 @@ public class SjmsMessage extends DefaultMessage { setJmsMessage(jmsMessage); setJmsSession(jmsSession); setBinding(binding); + + setPayloadForTrait(MessageTrait.REDELIVERY, JmsMessageHelper.evalRedeliveryMessageTrait(jmsMessage)); } public void init(Exchange exchange, Message jmsMessage, Session jmsSession, JmsBinding binding) { @@ -61,6 +65,8 @@ public class SjmsMessage extends DefaultMessage { setBinding(binding); // need to populate initial headers when we use pooled exchanges populateInitialHeaders(getHeaders()); + + setPayloadForTrait(MessageTrait.REDELIVERY, JmsMessageHelper.evalRedeliveryMessageTrait(jmsMessage)); } @Override @@ -287,15 +293,6 @@ public class SjmsMessage extends DefaultMessage { } } - @Override - protected Boolean isTransactedRedelivered() { - if (jmsMessage != null) { - return JmsMessageHelper.getJMSRedelivered(jmsMessage); - } else { - return null; - } - } - private String getDestinationAsString(Destination destination) throws JMSException { String result = null; if (destination == null) { diff --git a/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/jms/JmsMessageHelper.java b/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/jms/JmsMessageHelper.java index 43e8a741dbb..342a6e3d9d2 100644 --- a/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/jms/JmsMessageHelper.java +++ b/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/jms/JmsMessageHelper.java @@ -27,6 +27,8 @@ import jakarta.jms.Message; import org.apache.camel.Exchange; import org.apache.camel.support.ExchangeHelper; +import org.apache.camel.trait.message.MessageTrait; +import org.apache.camel.trait.message.RedeliveryTraitPayload; import org.apache.camel.util.ObjectHelper; import static org.apache.camel.util.StringHelper.removeStartingCharacters; @@ -328,6 +330,28 @@ public final class JmsMessageHelper { return null; } + /** + * For a given message, evaluates what is the redelivery state for it and gives the appropriate {@link MessageTrait} + * for that redelivery state + * + * @param message the message to evalute + * @return The appropriate MessageTrait for the redelivery state (one of MessageTrait.UNDEFINED_REDELIVERY, + * MessageTrait.IS_REDELIVERY or MessageTrait.NON_REDELIVERY). + */ + public static RedeliveryTraitPayload evalRedeliveryMessageTrait(Message message) { + final Boolean redelivered = JmsMessageHelper.getJMSRedelivered(message); + + if (redelivered == null) { + return RedeliveryTraitPayload.UNDEFINED_REDELIVERY; + } + + if (Boolean.TRUE.equals(redelivered)) { + return RedeliveryTraitPayload.IS_REDELIVERY; + } + + return RedeliveryTraitPayload.NON_REDELIVERY; + } + /** * Gets the JMSMessageID from the message. * 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 36e1a1538ef..b4d4da50eb9 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 @@ -20,6 +20,7 @@ import java.util.Map; import java.util.function.Supplier; import org.apache.camel.spi.HeadersMapFactory; +import org.apache.camel.trait.message.MessageTrait; /** * Implements the <a href="http://camel.apache.org/message.html">Message</a> pattern and represents an inbound or @@ -319,4 +320,28 @@ public interface Message { */ void copyFromWithNewBody(Message message, Object newBody); + /** + * Checks whether the message has a given {@link MessageTrait} + * + * @param trait the {@link MessageTrait} to check + * @return true if the message instance has the trait or false otherwise + */ + boolean hasTrait(MessageTrait trait); + + /** + * Gets the payload for the {@link MessageTrait} + * + * @param trait the {@link MessageTrait} to obtain the payload + * @return The trait payload or null if not available + */ + Object getPayloadForTrait(MessageTrait trait); + + /** + * Sets the payload for the {@link MessageTrait} + * + * @param trait the {@link MessageTrait} to set the payload + * @param object the payload + */ + void setPayloadForTrait(MessageTrait trait, Object object); + } 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 new file mode 100644 index 00000000000..8d25bba5a0b --- /dev/null +++ b/core/camel-api/src/main/java/org/apache/camel/trait/message/MessageTrait.java @@ -0,0 +1,34 @@ +/* + * 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.trait.message; + +/** + * Message traits are runtime traits that can be associated with a message (for instance, the redelivery state, a data + * 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; +} diff --git a/core/camel-api/src/main/java/org/apache/camel/trait/message/RedeliveryTraitPayload.java b/core/camel-api/src/main/java/org/apache/camel/trait/message/RedeliveryTraitPayload.java new file mode 100644 index 00000000000..71865b22acf --- /dev/null +++ b/core/camel-api/src/main/java/org/apache/camel/trait/message/RedeliveryTraitPayload.java @@ -0,0 +1,38 @@ +/* + * 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.trait.message; + +/** + * Some messages can carry redelivery details which might affect routing (i.e; JMS messages). This trait allows + * implementations to assign a payload that determines the redelivery state for the message. + */ +public enum RedeliveryTraitPayload { + /** + * The default redelivery payload, as most messages don't support redeliveries + **/ + UNDEFINED_REDELIVERY, + /** + * When a message supports redelivery, this indicates that this message is in a non-redelivery state + */ + NON_REDELIVERY, + + /** + * When a message supports redelivery, this indicates that this message is in a redelivery state + */ + IS_REDELIVERY, +} 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 26162146be4..2533c79bc6d 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 @@ -35,6 +35,8 @@ import org.apache.camel.MessageHistory; import org.apache.camel.SafeCopyProperty; import org.apache.camel.spi.HeadersMapFactory; import org.apache.camel.spi.UnitOfWork; +import org.apache.camel.trait.message.MessageTrait; +import org.apache.camel.trait.message.RedeliveryTraitPayload; import org.apache.camel.util.ObjectHelper; import static org.apache.camel.support.MessageHelper.copyBody; @@ -64,12 +66,12 @@ class AbstractExchange implements Exchange { protected Exception exception; protected String exchangeId; protected ExchangePattern pattern; - protected Boolean externalRedelivered; protected boolean routeStop; protected boolean rollbackOnly; protected boolean rollbackOnlyLast; protected Map<String, SafeCopyProperty> safeCopyProperties; private final ExtendedExchangeExtension privateExtension; + private RedeliveryTraitPayload externalRedelivered = RedeliveryTraitPayload.UNDEFINED_REDELIVERY; public AbstractExchange(CamelContext context) { this(context, ExchangePattern.InOnly); @@ -635,20 +637,13 @@ class AbstractExchange implements Exchange { @Override public boolean isExternalRedelivered() { - if (externalRedelivered == null) { - // lets avoid adding methods to the Message API, so we use the - // DefaultMessage to allow component specific messages to extend - // and implement the isExternalRedelivered method. - Message msg = getIn(); - if (msg instanceof DefaultMessage) { - externalRedelivered = ((DefaultMessage) msg).isTransactedRedelivered(); - } - // not from a transactional resource so mark it as false by default - if (externalRedelivered == null) { - externalRedelivered = false; - } + if (externalRedelivered == RedeliveryTraitPayload.UNDEFINED_REDELIVERY) { + Message message = getIn(); + + externalRedelivered = (RedeliveryTraitPayload) message.getPayloadForTrait(MessageTrait.REDELIVERY); } - return externalRedelivered; + + return externalRedelivered == RedeliveryTraitPayload.IS_REDELIVERY; } @Override 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 1716ba0dc52..2336629c1df 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 @@ -340,25 +340,10 @@ public class DefaultMessage extends MessageSupport { // do nothing by default } - /** - * A strategy for component specific messages to determine whether the message is redelivered or not. - * <p/> - * <b>Important: </b> It is not always possible to determine if the transacted is a redelivery or not, and therefore - * <tt>null</tt> is returned. Such an example would be a JDBC message. However JMS brokers provides details if a - * transacted message is redelivered. - * - * @return <tt>true</tt> if redelivered, <tt>false</tt> if not, <tt>null</tt> if not able to determine - */ - protected Boolean isTransactedRedelivered() { - // return null by default - return null; - } - /** * Returns true if the headers have been mutated in some way */ protected boolean hasPopulatedHeaders() { return headers != null; } - } diff --git a/core/camel-support/src/main/java/org/apache/camel/support/DefaultPooledExchange.java b/core/camel-support/src/main/java/org/apache/camel/support/DefaultPooledExchange.java index 958b6b92179..33e65434f07 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/DefaultPooledExchange.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/DefaultPooledExchange.java @@ -103,7 +103,6 @@ public final class DefaultPooledExchange extends AbstractExchange implements Poo // reset pattern to original this.pattern = originalPattern; // do not reset endpoint/fromRouteId as it would be the same consumer/endpoint again - this.externalRedelivered = null; this.routeStop = false; this.rollbackOnly = false; this.rollbackOnlyLast = false; diff --git a/core/camel-support/src/main/java/org/apache/camel/support/MessageHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/MessageHelper.java index 62a10bf16ad..b45106f8eb6 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/MessageHelper.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/MessageHelper.java @@ -38,6 +38,7 @@ import org.apache.camel.WrappedFile; import org.apache.camel.spi.DataTypeAware; import org.apache.camel.spi.ExchangeFormatter; import org.apache.camel.spi.HeaderFilterStrategy; +import org.apache.camel.trait.message.MessageTrait; import org.apache.camel.util.ObjectHelper; import org.apache.camel.util.StopWatch; import org.apache.camel.util.StringHelper; @@ -620,14 +621,14 @@ public final class MessageHelper { */ public static void copyBody(Message source, Message target) { // Preserve the DataType if both messages are DataTypeAware - if (source instanceof DataTypeAware && target instanceof DataTypeAware) { - final DataTypeAware dataTypeAwareSource = (DataTypeAware) source; - if (dataTypeAwareSource.hasDataType()) { - final DataTypeAware dataTypeAwareTarget = (DataTypeAware) target; - dataTypeAwareTarget.setBody(source.getBody(), dataTypeAwareSource.getDataType()); - return; - } + if (source.hasTrait(MessageTrait.DATA_AWARE)) { + target.setBody(source.getBody()); + target.setPayloadForTrait(MessageTrait.DATA_AWARE, + source.getPayloadForTrait(MessageTrait.DATA_AWARE)); + + return; } + target.setBody(source.getBody()); } 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 87f30bac445..78cf5a979c8 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 @@ -16,6 +16,8 @@ */ package org.apache.camel.support; +import java.util.Arrays; + import org.apache.camel.CamelContext; import org.apache.camel.CamelContextAware; import org.apache.camel.Exchange; @@ -24,6 +26,7 @@ import org.apache.camel.Message; import org.apache.camel.TypeConverter; import org.apache.camel.spi.DataType; import org.apache.camel.spi.DataTypeAware; +import org.apache.camel.trait.message.MessageTrait; /** * A base class for implementation inheritance providing the core {@link Message} body handling features but letting the @@ -33,19 +36,22 @@ import org.apache.camel.spi.DataTypeAware; * from {@link DefaultMessage} */ public abstract class MessageSupport implements Message, CamelContextAware, DataTypeAware { + private static final int NUM_TRAITS = MessageTrait.values().length; + CamelContext camelContext; TypeConverter typeConverter; private Exchange exchange; private Object body; private String messageId; private long messageTimestamp; - private DataType dataType; + + private final Object[] traits = new Object[NUM_TRAITS]; @Override public void reset() { body = null; messageId = null; - dataType = null; + Arrays.fill(traits, null); } @Override @@ -133,7 +139,7 @@ public abstract class MessageSupport implements Message, CamelContextAware, Data this.body = body; // set data type if in use if (body != null && camelContext != null && camelContext.isUseDataType()) { - this.dataType = new DataType(body.getClass()); + setPayloadForTrait(MessageTrait.DATA_AWARE, new DataType(body.getClass())); } } @@ -152,22 +158,23 @@ public abstract class MessageSupport implements Message, CamelContextAware, Data @Override public void setBody(Object body, DataType type) { this.body = body; - this.dataType = type; + setPayloadForTrait(MessageTrait.DATA_AWARE, type); } @Override public DataType getDataType() { - return this.dataType; + Object payload = getPayloadForTrait(MessageTrait.DATA_AWARE); + return (DataType) payload; } @Override public void setDataType(DataType type) { - this.dataType = type; + setPayloadForTrait(MessageTrait.DATA_AWARE, type); } @Override public boolean hasDataType() { - return dataType != null; + return hasTrait(MessageTrait.DATA_AWARE); } @Override @@ -187,11 +194,8 @@ public abstract class MessageSupport implements Message, CamelContextAware, Data copyFromWithNewBody(that, that.getBody()); // Preserve the DataType - if (that instanceof DataTypeAware) { - final DataTypeAware dataTypeAware = (DataTypeAware) that; - if (dataTypeAware.hasDataType()) { - setDataType(dataTypeAware.getDataType()); - } + if (that.hasTrait(MessageTrait.DATA_AWARE)) { + setPayloadForTrait(MessageTrait.DATA_AWARE, that.getPayloadForTrait(MessageTrait.DATA_AWARE)); } } @@ -306,4 +310,20 @@ public abstract class MessageSupport implements Message, CamelContextAware, Data } } + @Override + public boolean hasTrait(MessageTrait trait) { + Object payload = traits[trait.ordinal()]; + + return payload != null; + } + + @Override + public Object getPayloadForTrait(MessageTrait trait) { + return traits[trait.ordinal()]; + } + + @Override + public void setPayloadForTrait(MessageTrait trait, Object object) { + traits[trait.ordinal()] = object; + } } 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 d19dd43eb5e..661f778dd7f 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 @@ -24,6 +24,7 @@ import org.apache.camel.Exchange; import org.apache.camel.InvalidPayloadException; import org.apache.camel.Message; import org.apache.camel.spi.DataType; +import org.apache.camel.trait.message.MessageTrait; import org.junit.jupiter.api.Test; import static org.apache.camel.support.MessageHelper.copyBody; @@ -231,5 +232,20 @@ class MessageHelperTest { public void copyFromWithNewBody(Message message, Object newBody) { } + + @Override + public boolean hasTrait(MessageTrait trait) { + return false; + } + + @Override + public Object getPayloadForTrait(MessageTrait trait) { + return null; + } + + @Override + public void setPayloadForTrait(MessageTrait trait, Object object) { + + } } }