You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2024/09/04 19:32:07 UTC
(camel) 01/01: CAMEL-21176: DefaultExchangeHolder - Also store exchange variables together with exchange properties
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch holder
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 67e623ac7d5beab539670e5a6e2af8998e54462f
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Sep 4 21:31:38 2024 +0200
CAMEL-21176: DefaultExchangeHolder - Also store exchange variables together with exchange properties
---
.../camel/impl/DefaultExchangeHolderTest.java | 8 +-
.../camel/support/DefaultExchangeHolder.java | 121 ++++++++++++++-------
.../ROOT/pages/camel-4x-upgrade-guide-4_8.adoc | 3 +
3 files changed, 90 insertions(+), 42 deletions(-)
diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/DefaultExchangeHolderTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/DefaultExchangeHolderTest.java
index 409b421196f..824d6416959 100644
--- a/core/camel-core/src/test/java/org/apache/camel/impl/DefaultExchangeHolderTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/DefaultExchangeHolderTest.java
@@ -57,6 +57,8 @@ public class DefaultExchangeHolderTest extends ContextTestSupport {
assertEquals("Bye World", exchange.getOut().getBody());
assertEquals(123, exchange.getIn().getHeader("foo"));
assertNull(exchange.getProperty("bar"));
+ assertNull(exchange.getProperty("myVar"));
+ assertNull(exchange.getProperty("myOtherVar"));
}
@Test
@@ -71,6 +73,8 @@ public class DefaultExchangeHolderTest extends ContextTestSupport {
assertEquals("Hi Camel", exchange.getIn().getHeader("CamelFoo"));
assertEquals(444, exchange.getProperty("bar"));
assertEquals(555, exchange.getProperty("CamelBar"));
+ assertEquals(666, exchange.getVariable("myVar"));
+ assertEquals("cheese", exchange.getVariable("myOtherVar"));
assertEquals(id, exchange.getExchangeId());
}
@@ -184,8 +188,10 @@ public class DefaultExchangeHolderTest extends ContextTestSupport {
exchange.getIn().setHeader("CamelFoo", "Hi Camel");
exchange.setProperty("bar", 444);
exchange.setProperty("CamelBar", 555);
+ exchange.setVariable("myVar", 666);
+ exchange.setVariable("myOtherVar", "cheese");
exchange.getOut().setBody("Bye World");
- return DefaultExchangeHolder.marshal(exchange, includeProperties);
+ return DefaultExchangeHolder.marshal(exchange, includeProperties, false);
}
private static final class MyFoo {
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/DefaultExchangeHolder.java b/core/camel-support/src/main/java/org/apache/camel/support/DefaultExchangeHolder.java
index 80577d0c3e7..768c09c18b4 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/DefaultExchangeHolder.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/DefaultExchangeHolder.java
@@ -43,7 +43,6 @@ import org.slf4j.LoggerFactory;
* <li>exchangeId</li>
* <li>in body</li>
* <li>out body</li>
- * <li>fault body</li>
* <li>exception</li>
* </ul>
* <br/>
@@ -53,12 +52,12 @@ import org.slf4j.LoggerFactory;
* <ul>
* <li>in headers</li>
* <li>out headers</li>
- * <li>fault headers</li>
* </ul>
- * The body is serialized and stored as serialized bytes. The header and exchange properties only include primitive,
- * String, and Number types (and Exception types for exchange properties). Any other type is skipped. Any message body
- * object that is not serializable will be skipped and Camel will log this at <tt>WARN</tt> level. And any message
- * header values that is not a primitive value will be skipped and Camel will log this at <tt>DEBUG</tt> level.
+ * The body is serialized and stored as serialized bytes. The header and exchange properties, exchange variables are
+ * only include primitive, String, and Number types (and Exception types for exchange properties). Any other type is
+ * skipped. Any message body object that is not serializable will be skipped and Camel will log this at <tt>WARN</tt>
+ * level. And any message header values that is not a primitive value will be skipped and Camel will log this at
+ * <tt>DEBUG</tt> level.
*/
public class DefaultExchangeHolder implements Serializable {
@@ -71,11 +70,14 @@ public class DefaultExchangeHolder implements Serializable {
private Map<String, Object> inHeaders;
private Map<String, Object> outHeaders;
private Map<String, Object> properties;
+ private Map<String, Object> variables;
private Exception exception;
/**
* Creates a payload object with the information from the given exchange.
*
+ * Exchange properties and variables is included. Serialized values are skipped.
+ *
* @param exchange the exchange, must <b>not</b> be <tt>null</tt>
* @return the holder object with information copied form the exchange
*/
@@ -84,10 +86,10 @@ public class DefaultExchangeHolder implements Serializable {
}
/**
- * Creates a payload object with the information from the given exchange.
+ * Creates a payload object with the information from the given exchange. Serialized values are skipped.
*
* @param exchange the exchange, must <b>not</b> be <tt>null</tt>
- * @param includeProperties whether or not to include exchange properties
+ * @param includeProperties whether or not to include exchange properties and variables
* @return the holder object with information copied form the exchange
*/
public static DefaultExchangeHolder marshal(Exchange exchange, boolean includeProperties) {
@@ -97,27 +99,27 @@ public class DefaultExchangeHolder implements Serializable {
/**
* Creates a payload object with the information from the given exchange.
*
- * @param exchange the exchange, must <b>not</b> be <tt>null</tt>
- * @param includeProperties whether or not to include exchange properties
- * @param allowSerializedHeaders whether or not to include serialized headers
- * @return the holder object with information copied form the exchange
+ * @param exchange the exchange, must <b>not</b> be <tt>null</tt>
+ * @param includeProperties whether or not to include exchange properties and variables
+ * @param allowSerializedValues whether or not to include serialized values
+ * @return the holder object with information copied form the exchange
*/
- public static DefaultExchangeHolder marshal(Exchange exchange, boolean includeProperties, boolean allowSerializedHeaders) {
- return marshal(exchange, includeProperties, allowSerializedHeaders, true);
+ public static DefaultExchangeHolder marshal(Exchange exchange, boolean includeProperties, boolean allowSerializedValues) {
+ return marshal(exchange, includeProperties, allowSerializedValues, true);
}
/**
* Creates a payload object with the information from the given exchange.
*
- * @param exchange the exchange, must <b>not</b> be <tt>null</tt>
- * @param includeProperties whether or not to include exchange properties
- * @param allowSerializedHeaders whether or not to include serialized headers
- * @param preserveExchangeId whether to preserve exchange id
- * @return the holder object with information copied form the exchange
+ * @param exchange the exchange, must <b>not</b> be <tt>null</tt>
+ * @param includeProperties whether or not to include exchange properties and variables
+ * @param allowSerializedValues whether or not to include serialized headers
+ * @param preserveExchangeId whether to preserve exchange id
+ * @return the holder object with information copied form the exchange
*/
public static DefaultExchangeHolder marshal(
Exchange exchange, boolean includeProperties,
- boolean allowSerializedHeaders, boolean preserveExchangeId) {
+ boolean allowSerializedValues, boolean preserveExchangeId) {
ObjectHelper.notNull(exchange, "exchange");
// we do not support files
@@ -134,13 +136,14 @@ public class DefaultExchangeHolder implements Serializable {
payload.exchangeId = exchange.getExchangeId();
}
payload.inBody = checkSerializableBody("in body", exchange, exchange.getIn().getBody());
- payload.safeSetInHeaders(exchange, allowSerializedHeaders);
+ payload.safeSetInHeaders(exchange, allowSerializedValues);
if (exchange.hasOut()) {
payload.outBody = checkSerializableBody("out body", exchange, exchange.getOut().getBody());
- payload.safeSetOutHeaders(exchange, allowSerializedHeaders);
+ payload.safeSetOutHeaders(exchange, allowSerializedValues);
}
if (includeProperties) {
- payload.safeSetProperties(exchange, allowSerializedHeaders);
+ payload.safeSetProperties(exchange, allowSerializedValues);
+ payload.safeSetVariables(exchange, allowSerializedValues);
}
payload.exception = exchange.getException();
@@ -175,6 +178,11 @@ public class DefaultExchangeHolder implements Serializable {
exchange.setProperty(entry.getKey(), entry.getValue());
}
}
+ if (payload.variables != null) {
+ for (Map.Entry<String, Object> entry : payload.variables.entrySet()) {
+ exchange.setVariable(entry.getKey(), entry.getValue());
+ }
+ }
exchange.setException(payload.exception);
}
@@ -198,12 +206,33 @@ public class DefaultExchangeHolder implements Serializable {
payload.properties.put(key, property);
}
+ /**
+ * Adds a variable to the payload.
+ * <p/>
+ * This can be done in special situations where additional information must be added which was not provided from the
+ * source.
+ *
+ * @param payload the serialized payload
+ * @param key the variable key to add
+ * @param variable the variable value to add
+ */
+ public static void addVariable(DefaultExchangeHolder payload, String key, Serializable variable) {
+ if (key == null || variable == null) {
+ return;
+ }
+ if (payload.variables == null) {
+ payload.variables = new LinkedHashMap<>();
+ }
+ payload.variables.put(key, variable);
+ }
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder("DefaultExchangeHolder[exchangeId=").append(exchangeId);
sb.append("inBody=").append(inBody).append(", outBody=").append(outBody);
sb.append(", inHeaders=").append(inHeaders).append(", outHeaders=").append(outHeaders);
- sb.append(", properties=").append(properties).append(", exception=").append(exception);
+ sb.append(", properties=").append(properties).append(", variables=").append(variables);
+ sb.append(", exception=").append(exception);
return sb.append(']').toString();
}
@@ -219,10 +248,10 @@ public class DefaultExchangeHolder implements Serializable {
}
@Deprecated(since = "3.0.0")
- private Map<String, Object> safeSetOutHeaders(Exchange exchange, boolean allowSerializedHeaders) {
+ private Map<String, Object> safeSetOutHeaders(Exchange exchange, boolean allowSerializedValues) {
if (exchange.hasOut() && exchange.getOut().hasHeaders()) {
Map<String, Object> map
- = checkValidHeaderObjects("out headers", exchange, exchange.getOut().getHeaders(), allowSerializedHeaders);
+ = checkValidHeaderObjects("out headers", exchange, exchange.getOut().getHeaders(), allowSerializedValues);
if (map != null && !map.isEmpty()) {
outHeaders = new LinkedHashMap<>(map);
}
@@ -230,16 +259,25 @@ public class DefaultExchangeHolder implements Serializable {
return null;
}
- private Map<String, Object> safeSetProperties(Exchange exchange, boolean allowSerializedHeaders) {
+ private Map<String, Object> safeSetProperties(Exchange exchange, boolean allowSerializedValues) {
// also include the internal properties
Map<String, Object> map = checkValidExchangePropertyObjects("properties", exchange, exchange.getAllProperties(),
- allowSerializedHeaders);
+ allowSerializedValues);
if (map != null && !map.isEmpty()) {
properties = new LinkedHashMap<>(map);
}
return null;
}
+ private Map<String, Object> safeSetVariables(Exchange exchange, boolean allowSerializedValues) {
+ Map<String, Object> map = checkValidExchangePropertyObjects("variables", exchange, exchange.getVariables(),
+ allowSerializedValues);
+ if (map != null && !map.isEmpty()) {
+ variables = new LinkedHashMap<>(map);
+ }
+ return null;
+ }
+
private static Object checkSerializableBody(String type, Exchange exchange, Object object) {
if (object == null) {
return null;
@@ -287,7 +325,7 @@ public class DefaultExchangeHolder implements Serializable {
}
private static Map<String, Object> checkValidExchangePropertyObjects(
- String type, Exchange exchange, Map<String, Object> map, boolean allowSerializedHeaders) {
+ String type, Exchange exchange, Map<String, Object> map, boolean allowSerializedValues) {
if (map == null) {
return null;
}
@@ -300,7 +338,7 @@ public class DefaultExchangeHolder implements Serializable {
continue;
}
- Object value = getValidExchangePropertyValue(entry.getKey(), entry.getValue(), allowSerializedHeaders);
+ Object value = getValidExchangePropertyValue(entry.getKey(), entry.getValue(), allowSerializedValues);
if (value != null) {
Serializable converted
= exchange.getContext().getTypeConverter().convertTo(Serializable.class, exchange, value);
@@ -331,12 +369,12 @@ public class DefaultExchangeHolder implements Serializable {
*
* We make possible store serialized headers by the boolean field allowSerializedHeaders
*
- * @param headerName the header name
- * @param headerValue the header value
- * @param allowSerializedHeaders the header value
- * @return the value to use, <tt>null</tt> to ignore this header
+ * @param headerName the header name
+ * @param headerValue the header value
+ * @param allowSerializedValues whether to include serialized values
+ * @return the value to use, <tt>null</tt> to ignore this header
*/
- protected static Object getValidHeaderValue(String headerName, Object headerValue, boolean allowSerializedHeaders) {
+ protected static Object getValidHeaderValue(String headerName, Object headerValue, boolean allowSerializedValues) {
if (headerValue instanceof String) {
return headerValue;
} else if (headerValue instanceof BigInteger) {
@@ -353,7 +391,7 @@ public class DefaultExchangeHolder implements Serializable {
return headerValue;
} else if (headerValue instanceof Date) {
return headerValue;
- } else if (allowSerializedHeaders) {
+ } else if (allowSerializedValues) {
if (headerValue instanceof Serializable) {
return headerValue;
}
@@ -368,17 +406,18 @@ public class DefaultExchangeHolder implements Serializable {
* This default implementation will allow the same values as {@link #getValidHeaderValue(String, Object, boolean)}
* and in addition any value of type {@link Throwable}.
*
- * @param propertyName the property name
- * @param propertyValue the property value
- * @return the value to use, <tt>null</tt> to ignore this header
+ * @param propertyName the property name
+ * @param propertyValue the property value
+ * @param allowSerializedValues whether to include serialized values
+ * @return the value to use, <tt>null</tt> to ignore this header
*/
protected static Object getValidExchangePropertyValue(
- String propertyName, Object propertyValue, boolean allowSerializedHeaders) {
+ String propertyName, Object propertyValue, boolean allowSerializedValues) {
// for exchange properties we also allow exception to be transferred so people can store caught exception
if (propertyValue instanceof Throwable) {
return propertyValue;
}
- return getValidHeaderValue(propertyName, propertyValue, allowSerializedHeaders);
+ return getValidHeaderValue(propertyName, propertyValue, allowSerializedValues);
}
private static void logCannotSerializeObject(String type, String key, Object value) {
diff --git a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_8.adoc b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_8.adoc
index 48a4f932f16..1df7e49bce5 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_8.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_8.adoc
@@ -25,6 +25,9 @@ performing these copies has increased from 4096 bytes to 16384 bytes (the defaul
The tracer (`BacklogTracer`) has changed the `backlogSize` default value from `1000` to `100`, and `maxBodySize` from `128kb` to `32kb`.
This reduces the amount of data captured and stored and helps reduce the tracing overhead.
+The `org.apache.camel.support.DefaultExchangeHolder` will now include both exchange variables and properties,
+if the parameter `includeProperties` is set to true.
+
=== camel-jbang
The `camel trace` command has changed to show tracing status (by default). To dump traced messages use `camel trace --action=dump`.