This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 019d995fc32 CAMEL-21176: DefaultExchangeHolder - Also store exchange
variables together with exchange properties (#15437)
019d995fc32 is described below
commit 019d995fc32f81181e5bf85018d873bb7508cb01
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Sep 5 06:35:17 2024 +0200
CAMEL-21176: DefaultExchangeHolder - Also store exchange variables together
with exchange properties (#15437)
---
.../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`.