You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by or...@apache.org on 2023/05/02 05:24:00 UTC
[camel] branch main updated: CAMEL-19058: rework the Message to avoid hitting the type-check scalability issue
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 <an...@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 <an...@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) {
+
+ }
}
}