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 285994f8606c CAMEL-23535: camel-api - batches 10-12: enhance
class-level Javadoc for data transformation, EIP storage, and error handling
SPIs (#23968)
285994f8606c is described below
commit 285994f8606c129ce7fa6971eb3a856766f2705e
Author: Adriano Machado <[email protected]>
AuthorDate: Sat Jun 13 01:23:45 2026 -0400
CAMEL-23535: camel-api - batches 10-12: enhance class-level Javadoc for
data transformation, EIP storage, and error handling SPIs (#23968)
* CAMEL-23535: camel-api - batch 10: enhance class-level Javadoc for data
transformation SPIs
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
* CAMEL-23535: camel-api - batch 11: enhance class-level Javadoc for
exchange processing and EIP storage SPIs
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
* CAMEL-23535: camel-api - batch 12: enhance class-level Javadoc for error
handling and debugging SPIs
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
* CAMEL-23535: camel-api - fix Validator.java Javadoc: replace incorrect
@DataTypeTransformer reference
Validators are registered via the DSL (ValidatorDefinition), not via
annotation-driven classpath scanning. The @DataTypeTransformer annotation
belongs to transformers only.
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
---------
Co-authored-by: Claude Sonnet 4.6 <[email protected]>
---
.../apache/camel/spi/AggregationRepository.java | 26 +++++++++++++++-------
.../java/org/apache/camel/spi/BacklogDebugger.java | 25 ++++++++++++++-------
.../java/org/apache/camel/spi/BacklogTracer.java | 15 ++++++++++++-
.../camel/spi/BacklogTracerEventMessage.java | 13 ++++++++++-
.../main/java/org/apache/camel/spi/Breakpoint.java | 23 ++++++++++++-------
.../org/apache/camel/spi/ClaimCheckRepository.java | 22 +++++++++++++-----
.../main/java/org/apache/camel/spi/DataFormat.java | 17 ++++++++++++--
.../org/apache/camel/spi/DataFormatFactory.java | 11 ++++++---
.../java/org/apache/camel/spi/DataFormatName.java | 11 +++++++--
.../main/java/org/apache/camel/spi/Debugger.java | 15 ++++++++++++-
.../java/org/apache/camel/spi/ErrorHandler.java | 12 +++++++++-
.../org/apache/camel/spi/ExceptionHandler.java | 14 +++++++++---
.../java/org/apache/camel/spi/ExchangeFactory.java | 23 +++++++++++--------
.../org/apache/camel/spi/ExchangeFormatter.java | 13 +++++++++--
.../org/apache/camel/spi/IdempotentRepository.java | 21 +++++++++++------
.../apache/camel/spi/MessageHistoryFactory.java | 14 +++++++++++-
.../apache/camel/spi/ProcessorExchangeFactory.java | 20 ++++++++++++-----
.../apache/camel/spi/StreamCachingStrategy.java | 21 ++++++++++++++---
.../java/org/apache/camel/spi/Transformer.java | 19 +++++++++++-----
.../java/org/apache/camel/spi/TransformerKey.java | 12 ++++++++--
.../org/apache/camel/spi/TransformerRegistry.java | 24 +++++++++++---------
.../main/java/org/apache/camel/spi/Validator.java | 20 ++++++++++++-----
.../org/apache/camel/spi/ValidatorRegistry.java | 24 +++++++++++---------
23 files changed, 311 insertions(+), 104 deletions(-)
diff --git
a/core/camel-api/src/main/java/org/apache/camel/spi/AggregationRepository.java
b/core/camel-api/src/main/java/org/apache/camel/spi/AggregationRepository.java
index fc337f2d8e29..ad05d22a062e 100644
---
a/core/camel-api/src/main/java/org/apache/camel/spi/AggregationRepository.java
+++
b/core/camel-api/src/main/java/org/apache/camel/spi/AggregationRepository.java
@@ -23,15 +23,25 @@ import org.apache.camel.Exchange;
import org.jspecify.annotations.Nullable;
/**
- * Repository for storing aggregated exchanges used by the Aggregator EIP.
+ * Persistent store for in-progress aggregated {@link Exchange} instances,
used by the
+ * <a href="https://camel.apache.org/manual/aggregator2.html">Aggregator
EIP</a>.
* <p/>
- * The aggregation lifecycle is: {@link #get(CamelContext, String)} to
retrieve the existing aggregate, then
- * {@link #add(CamelContext, String, Exchange)} to store the updated
aggregate, and finally
- * {@link #remove(CamelContext, String, Exchange)} when the aggregation is
complete.
- * {@link #confirm(CamelContext, String)} is called after the aggregated
exchange has been processed successfully.
- * <p/>
- * Implementations must be thread-safe as multiple threads may aggregate
concurrently for different correlation keys.
- *
+ * The Aggregator EIP correlates incoming exchanges by a key and accumulates
them until a completion condition is
+ * satisfied. This repository is the pluggable storage layer that holds the
partial aggregate between correlation
+ * events. The lifecycle for each aggregate is:
+ * <ol>
+ * <li>{@link #get(CamelContext, String)} — load the current partial aggregate
(or {@code null} if none exists
+ * yet).</li>
+ * <li>{@link #add(CamelContext, String, Exchange)} — store the updated
aggregate after applying the
+ * {@link org.apache.camel.AggregationStrategy}.</li>
+ * <li>{@link #remove(CamelContext, String, Exchange)} — delete the aggregate
once the completion condition fires.</li>
+ * <li>{@link #confirm(CamelContext, String)} — acknowledge successful
downstream processing of the completed aggregate
+ * (used by persistent stores to mark records as committed).</li>
+ * </ol>
+ * Implementations must be thread-safe: multiple threads can aggregate
concurrently for different correlation keys. The
+ * default in-memory implementation ({@code MemoryAggregationRepository}) is
suitable for non-persistent use cases;
+ * persistent implementations backed by JDBC, Hazelcast, Infinispan, or file
storage are available as separate Camel
+ * components.
*/
public interface AggregationRepository {
diff --git
a/core/camel-api/src/main/java/org/apache/camel/spi/BacklogDebugger.java
b/core/camel-api/src/main/java/org/apache/camel/spi/BacklogDebugger.java
index 19f4c7ca74a4..3fbb2260c56e 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/BacklogDebugger.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/BacklogDebugger.java
@@ -27,17 +27,26 @@ import org.apache.camel.util.StopWatch;
import org.jspecify.annotations.Nullable;
/**
- * A {@link org.apache.camel.spi.Debugger} that has easy debugging
functionality which can be used from JMX with
- * {@link org.apache.camel.api.management.mbean.ManagedBacklogDebuggerMBean}.
+ * High-level route debugger SPI that suspends {@link Exchange} processing at
named breakpoints and exposes the
+ * suspended state for inspection, as described in the
+ * <a href="https://camel.apache.org/manual/debugger.html">Debugger</a>
documentation.
* <p/>
- * This implementation allows setting breakpoints (with or without a
condition) and inspect the {@link Exchange} dumped
- * in XML in {@link BacklogTracerEventMessage} format. There is operations to
resume suspended breakpoints to continue
- * routing the {@link Exchange}. There is also step functionality, so you can
single step a given {@link Exchange}.
+ * The {@code BacklogDebugger} builds on the lower-level {@link Debugger} API
but adds breakpoint management with
+ * optional conditions, step-mode execution, and exchange inspection via
XML/JSON dumps in
+ * {@link BacklogTracerEventMessage} format. All operations are exposed over
JMX through
+ * {@link org.apache.camel.api.management.mbean.ManagedBacklogDebuggerMBean},
allowing IDE tooling (e.g.,
+ * camel-idea-plugin) to control a running Camel context remotely.
* <p/>
- * This implementation will only break the first {@link Exchange} that arrives
to a breakpoint. If Camel routes using
- * concurrency then sub-sequent {@link Exchange} will continue to be routed,
if their breakpoint already holds a
- * suspended {@link Exchange}.
+ * On reaching a breakpoint, only the <em>first</em> arriving {@link Exchange}
is suspended; concurrent exchanges on the
+ * same breakpoint continue to route past it. A suspended exchange blocks its
carrier thread until explicitly resumed
+ * via one of the {@code resume*} methods.
+ * <p/>
+ * When the environment variable {@value #SUSPEND_MODE_ENV_VAR_NAME} (or
system property
+ * {@value #SUSPEND_MODE_SYSTEM_PROP_NAME}) is set to {@code true}, the
debugger suspends <em>all</em> routes at startup
+ * and waits for a debugger client to attach before processing any messages.
*
+ * @see Debugger
+ * @see BacklogTracerEventMessage
* @since 4.2
*/
public interface BacklogDebugger extends StatefulService {
diff --git
a/core/camel-api/src/main/java/org/apache/camel/spi/BacklogTracer.java
b/core/camel-api/src/main/java/org/apache/camel/spi/BacklogTracer.java
index 5dd19f16c1cf..d56acdc2dde5 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/BacklogTracer.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/BacklogTracer.java
@@ -24,8 +24,21 @@ import org.apache.camel.NamedNode;
import org.jspecify.annotations.Nullable;
/**
- * Backlog tracer that captures the last N messages during routing in a
backlog.
+ * Passive message capture mechanism that records a rolling window of the last
N exchange snapshots as they pass through
+ * route nodes, as described in the <a
href="https://camel.apache.org/manual/backlog-tracer.html">Backlog Tracer</a>
+ * documentation.
+ * <p/>
+ * Unlike the {@link Debugger}/{@link BacklogDebugger} which can suspend and
step through exchanges, the
+ * {@code BacklogTracer} is non-blocking: it takes a snapshot of each exchange
at each route node and adds it to a
+ * bounded circular queue (the "backlog"). Snapshots are available via {@link
#dumpTracedMessagesAsXml(String, boolean)}
+ * or {@link #dumpTracedMessagesAsJSon(String, boolean)} for inspection or
test assertions. The maximum number of
+ * messages held in the backlog is configured by {@link #setBacklogSize(int)}.
+ * <p/>
+ * The tracer can be filtered to a subset of routes and nodes via {@link
#setTraceFilter(String)}, and can be put in
+ * standby mode (activated but not collecting) so it can be toggled at runtime
via JMX without restarting Camel.
*
+ * @see BacklogTracerEventMessage
+ * @see BacklogDebugger
* @since 4.0
*/
public interface BacklogTracer {
diff --git
a/core/camel-api/src/main/java/org/apache/camel/spi/BacklogTracerEventMessage.java
b/core/camel-api/src/main/java/org/apache/camel/spi/BacklogTracerEventMessage.java
index 95a1405d0982..791a6d4e976a 100644
---
a/core/camel-api/src/main/java/org/apache/camel/spi/BacklogTracerEventMessage.java
+++
b/core/camel-api/src/main/java/org/apache/camel/spi/BacklogTracerEventMessage.java
@@ -22,8 +22,19 @@ import org.apache.camel.Endpoint;
import org.jspecify.annotations.Nullable;
/**
- * Represents a traced message by the BacklogTracer.
+ * Snapshot of a single exchange event captured by the {@link BacklogTracer}
as a message transits a route node.
+ * <p/>
+ * Each instance represents a detached, point-in-time view of the exchange at
one route node: the exchange body and
+ * headers are serialized to XML/JSON at capture time so they can be read
after the exchange has moved on or has
+ * completed. The unique {@link #getUid()} counter and {@link #getTimestamp()}
allow events to be correlated and ordered
+ * across concurrent exchanges.
+ * <p/>
+ * For each route a message passes through, the tracer emits at least two
events: a "first" event when the exchange
+ * enters the route ({@link #isFirst()}) and a "last" event when it leaves
({@link #isLast()}). An exchange routed
+ * across multiple routes (e.g. via Direct or SEDA) produces separate
first/last pairs for each route.
*
+ * @see BacklogTracer
+ * @see BacklogEventMessage
* @since 4.0
*/
public interface BacklogTracerEventMessage extends BacklogEventMessage {
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/Breakpoint.java
b/core/camel-api/src/main/java/org/apache/camel/spi/Breakpoint.java
index e4a2b45628cd..074c5b0aa176 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/Breakpoint.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/Breakpoint.java
@@ -25,17 +25,24 @@ import org.apache.camel.spi.CamelEvent.ExchangeEvent;
import org.jspecify.annotations.Nullable;
/**
- * {@link org.apache.camel.spi.Breakpoint} are used by the {@link
org.apache.camel.spi.Debugger} API.
+ * Callback interface for a debugger breakpoint, registered with the {@link
Debugger} and invoked as
+ * {@link org.apache.camel.Exchange}s pass through route nodes.
* <p/>
- * This allows you to register {@link org.apache.camel.spi.Breakpoint}s to the
{@link org.apache.camel.spi.Debugger} and
- * have those breakpoints activated when their {@link
org.apache.camel.spi.Condition}s match.
+ * Breakpoints are registered via {@link Debugger#addBreakpoint(Breakpoint)}
(unconditional) or
+ * {@link Debugger#addBreakpoint(Breakpoint, Condition...)} (conditional).
When all provided {@link Condition}s are
+ * satisfied, the {@code Debugger} calls the appropriate {@code before*} /
{@code after*} callback on this interface.
+ * Multiple {@code before*} methods exist to differentiate the type of routing
event: entering a processor node,
+ * handling an exchange event, and so on.
* <p/>
- * If any exceptions is thrown from the callback methods then the {@link
org.apache.camel.spi.Debugger} will catch and
- * log those at <tt>WARN</tt> level and continue. This ensures Camel can
continue to route the message without having
- * breakpoints causing issues.
+ * Exceptions thrown from any callback method are caught by the {@code
Debugger} and logged at {@code WARN} level. This
+ * ensures that a buggy breakpoint does not abort routing of the exchange.
+ * <p/>
+ * A breakpoint can be in {@link State#Active} or {@link State#Suspended}
state. The {@link BacklogDebugger} uses the
+ * suspended state to pause exchange processing and wait for a resume signal
from a debugging client.
*
- * @see org.apache.camel.spi.Debugger
- * @see org.apache.camel.spi.Condition
+ * @see Debugger
+ * @see Condition
+ * @see BacklogDebugger
*/
public interface Breakpoint {
diff --git
a/core/camel-api/src/main/java/org/apache/camel/spi/ClaimCheckRepository.java
b/core/camel-api/src/main/java/org/apache/camel/spi/ClaimCheckRepository.java
index 5e41acf9e08a..029de9d148cf 100644
---
a/core/camel-api/src/main/java/org/apache/camel/spi/ClaimCheckRepository.java
+++
b/core/camel-api/src/main/java/org/apache/camel/spi/ClaimCheckRepository.java
@@ -21,14 +21,24 @@ import org.apache.camel.Service;
import org.jspecify.annotations.Nullable;
/**
- * Access to a repository of keys to implement the <a
href="https://camel.apache.org/claim-check.html">Claim Check</a>
- * pattern.
+ * Storage repository for the <a
href="https://camel.apache.org/manual/claim-check.html">Claim Check EIP</a>,
which
+ * temporarily parks a message payload so that a lighter message can travel
through an intermediate part of a route.
* <p/>
- * The <tt>add</tt> and <tt>contains</tt> methods is operating according to
the {@link java.util.Map} contract, and the
- * <tt>push</tt> and <tt>pop</tt> methods is operating according to the {@link
java.util.Stack} contract.
+ * The Claim Check pattern solves the problem of passing large payloads
through components that have size limits or
+ * performance concerns. The producing side stores the payload under a unique
key (the "claim check") using
+ * {@link #add(String, Exchange)} or {@link #push(Exchange)}, replacing the
message body with just the key. The
+ * consuming side later retrieves the payload with {@link #get(String)} or
{@link #pop()} and restores it to the
+ * exchange.
* <p/>
- * See important details about the Claim Check EIP implementation in Apache
Camel at
- * {@link org.apache.camel.processor.ClaimCheckProcessor}.
+ * The interface exposes two access styles:
+ * <ul>
+ * <li><b>keyed</b> ({@link #add}, {@link #contains}, {@link #get}, {@link
#getAndRemove}) — operates like a
+ * {@link java.util.Map}; the caller controls the key.</li>
+ * <li><b>stack</b> ({@link #push}, {@link #pop}) — operates like a {@link
java.util.Deque}; Camel manages the key
+ * internally, useful for nested claim checks.</li>
+ * </ul>
+ *
+ * @see org.apache.camel.processor.ClaimCheckProcessor
*/
public interface ClaimCheckRepository extends Service {
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/DataFormat.java
b/core/camel-api/src/main/java/org/apache/camel/spi/DataFormat.java
index 700a8eab2b43..013fa823fcc7 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/DataFormat.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/DataFormat.java
@@ -26,8 +26,21 @@ import org.apache.camel.Service;
import org.apache.camel.util.IOHelper;
/**
- * Represents a <a href="https://camel.apache.org/data-format.html">data
format</a> used to marshal objects to and from
- * streams such as Java Serialization or using JAXB2 to encode/decode objects
using XML or using SOAP encoding.
+ * Pluggable strategy for converting message bodies to and from a serialised
byte-stream format, as described in the
+ * <a href="https://camel.apache.org/manual/data-format.html">Data Format</a>
documentation.
+ * <p/>
+ * A {@code DataFormat} is the core abstraction behind the Camel {@code
.marshal()} and {@code .unmarshal()} DSL calls.
+ * Camel ships more than 50 data format implementations covering JSON
(Jackson, Gson, Fastjson), XML (JAXB, XStream),
+ * CSV, Avro, Protobuf, CBOR, and many others. Each data format is a {@link
org.apache.camel.Service}; Camel starts and
+ * stops it together with the route it is used in, making it safe to hold
state (thread-local codec contexts, etc.).
+ * <p/>
+ * Implementations must be thread-safe unless the enclosing route guarantees
single-threaded execution. The
+ * {@link #unmarshal(Exchange, Object)} default method converts the body to an
{@link java.io.InputStream} before
+ * delegating to {@link #unmarshal(Exchange, java.io.InputStream)}; override
it when a more direct conversion is
+ * possible (as {@code camel-jaxb} does for String payloads).
+ *
+ * @see DataFormatFactory
+ * @see DataFormatName
*/
public interface DataFormat extends Service {
diff --git
a/core/camel-api/src/main/java/org/apache/camel/spi/DataFormatFactory.java
b/core/camel-api/src/main/java/org/apache/camel/spi/DataFormatFactory.java
index e4dbc0ced9a5..aca852431ca6 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/DataFormatFactory.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/DataFormatFactory.java
@@ -17,10 +17,15 @@
package org.apache.camel.spi;
/**
- * A factory for creating {@link DataFormat} instances. The factory is used
when a data format needs custom
- * instantiation logic beyond the default resolution mechanism.
+ * Factory for creating fresh {@link DataFormat} instances on demand, used
when a data format requires per-use
+ * instantiation rather than sharing a single instance across the route.
* <p/>
- * Each call to {@link #newInstance()} should return a new data format
instance.
+ * Most data formats are stateless singletons resolved directly from the
registry or the META-INF service files. This
+ * factory is needed for formats that hold mutable per-invocation state (codec
contexts, stream writers, etc.) and must
+ * therefore not be reused concurrently. When Camel encounters a {@code
DataFormatFactory} in the registry, it calls
+ * {@link #newInstance()} for each {@code .marshal()} or {@code .unmarshal()}
call rather than reusing one instance.
+ *
+ * @see DataFormat
*/
@FunctionalInterface
public interface DataFormatFactory {
diff --git
a/core/camel-api/src/main/java/org/apache/camel/spi/DataFormatName.java
b/core/camel-api/src/main/java/org/apache/camel/spi/DataFormatName.java
index 87878b2df328..704862cc330a 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/DataFormatName.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/DataFormatName.java
@@ -17,8 +17,15 @@
package org.apache.camel.spi;
/**
- * The name of the {@link org.apache.camel.spi.DataFormat} which allows to
know which kind of data format the
- * implementation is.
+ * Marker interface that exposes the canonical name of a {@link DataFormat}
implementation, enabling runtime lookup and
+ * catalog introspection without depending on the concrete class.
+ * <p/>
+ * Camel uses the name returned by {@link #getDataFormatName()} to register
the format in the
+ * <a href="https://camel.apache.org/manual/data-format.html">data format</a>
catalog, to resolve formats by name in
+ * YAML/XML DSL declarations, and for display in the <a
href="https://camel.apache.org/manual/camel-jbang.html">Camel
+ * JBang</a> CLI. The name should match the {@code name} attribute declared in
the component's Maven descriptor.
+ *
+ * @see DataFormat
*/
public interface DataFormatName {
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/Debugger.java
b/core/camel-api/src/main/java/org/apache/camel/spi/Debugger.java
index a3658351fd83..e1f7c345bd75 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/Debugger.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/Debugger.java
@@ -26,7 +26,20 @@ import org.apache.camel.Service;
import org.apache.camel.spi.CamelEvent.ExchangeEvent;
/**
- * A debugger which allows tooling to attach breakpoints which is being
invoked when {@link Exchange}s is being routed.
+ * Low-level debugger SPI that fires {@link Breakpoint} callbacks as {@link
Exchange}s move through each route node, as
+ * described in the <a
href="https://camel.apache.org/manual/debugger.html">Debugger</a> documentation.
+ * <p/>
+ * The {@code Debugger} is integrated into Camel's {@link InternalProcessor}
pipeline; when enabled, the internal
+ * processor invokes the appropriate {@code before*} and {@code after*}
callbacks on each registered {@link Breakpoint}
+ * as exchanges enter and leave route nodes. Breakpoints can be conditioned
via {@link Condition} predicates (e.g.,
+ * match only a specific exchange ID or route ID).
+ * <p/>
+ * For a higher-level, JMX-accessible debugger with suspend/resume semantics,
see {@link BacklogDebugger}, which builds
+ * on top of this SPI. For passive message capture without execution control,
see {@link BacklogTracer}.
+ *
+ * @see Breakpoint
+ * @see Condition
+ * @see BacklogDebugger
*/
public interface Debugger extends Service, CamelContextAware {
diff --git
a/core/camel-api/src/main/java/org/apache/camel/spi/ErrorHandler.java
b/core/camel-api/src/main/java/org/apache/camel/spi/ErrorHandler.java
index 70d83aa5bdc9..189480932b93 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/ErrorHandler.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/ErrorHandler.java
@@ -19,8 +19,18 @@ package org.apache.camel.spi;
import org.apache.camel.Processor;
/**
- * An interface used to represent an error handler
+ * Marker interface identifying a {@link org.apache.camel.Processor} as an
error-handling wrapper, as described in the
+ * <a href="https://camel.apache.org/manual/error-handler.html">Error
Handler</a> documentation.
+ * <p/>
+ * Camel wraps each route's processing pipeline in an {@code ErrorHandler} at
startup. The handler intercepts exceptions
+ * thrown during message processing and applies the configured error-handling
strategy, such as retrying with back-off
+ * ({@code RedeliveryErrorHandler}), sending to a dead letter channel, or
simply logging and continuing.
+ * <p/>
+ * All built-in error handler implementations (NoErrorHandler,
DefaultErrorHandler, DeadLetterChannel,
+ * TransactionErrorHandler) implement this interface, making it possible for
Camel internals to detect whether a
+ * {@link org.apache.camel.Processor} is an error handler without needing to
know the concrete type.
*
+ * @see ExceptionHandler
* @since 3.7
*/
public interface ErrorHandler extends Processor {
diff --git
a/core/camel-api/src/main/java/org/apache/camel/spi/ExceptionHandler.java
b/core/camel-api/src/main/java/org/apache/camel/spi/ExceptionHandler.java
index 06245220ab4d..6d46e1ca7461 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/ExceptionHandler.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/ExceptionHandler.java
@@ -20,10 +20,18 @@ import org.apache.camel.Exchange;
import org.jspecify.annotations.Nullable;
/**
- * A Strategy pattern for handling exceptions; particularly in asynchronous
processes such as consumers.
+ * Strategy for handling exceptions that arise in asynchronous or background
processing where a normal exception
+ * propagation path does not exist, such as in a {@link
org.apache.camel.Consumer}'s polling thread.
* <p/>
- * Its important to <b>not</b> throw any exceptions when handling exceptions
as the handler is often invoked in a try ..
- * catch logic already
+ * Unlike the route-level {@link ErrorHandler}, which handles exceptions
thrown by processors inside a route,
+ * {@code ExceptionHandler} is used by infrastructure code (consumers,
schedulers, Quartz jobs, background threads) that
+ * cannot propagate exceptions through the normal routing chain. The default
implementation logs the exception and
+ * continues; custom implementations can re-route, alert, or escalate as
needed.
+ * <p/>
+ * Implementations must <b>not</b> throw exceptions from their {@code
handleException} methods, because the handler is
+ * typically called from within an existing catch block and a secondary
exception would mask the original failure.
+ *
+ * @see ErrorHandler
*/
public interface ExceptionHandler {
diff --git
a/core/camel-api/src/main/java/org/apache/camel/spi/ExchangeFactory.java
b/core/camel-api/src/main/java/org/apache/camel/spi/ExchangeFactory.java
index 594cd4b25108..dea988c9cdeb 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/ExchangeFactory.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/ExchangeFactory.java
@@ -23,17 +23,22 @@ import org.apache.camel.NonManagedService;
import org.jspecify.annotations.Nullable;
/**
- * Factory used by {@link Consumer} to create Camel {@link Exchange} holding
the incoming message received by the
- * consumer.
+ * Factory used by {@link Consumer} (and {@link
org.apache.camel.PollingConsumer}) to create the {@link Exchange} that
+ * carries an incoming message into Camel.
* <p/>
- * This factory is only for {@link Consumer}'s to give control on how {@link
Exchange} are created and comes into Camel.
- * Each Camel component that provides a {@link Consumer} should use this
{@link ExchangeFactory}. There may be other
- * parts in Camel that creates {@link Exchange} such as sub exchanges from
Splitter EIP, but they are not part of this
- * contract as we only want to control the created {@link Exchange} that comes
into Camel via {@link Consumer} or
- * {@link org.apache.camel.PollingConsumer}.
+ * This factory governs only the exchanges that enter Camel from the outside
world via a consumer. Sub-exchanges created
+ * internally (e.g., by the Splitter EIP) are outside this contract and use
{@link ProcessorExchangeFactory} instead.
* <p/>
- * The factory is pluggable which allows using different strategies. The
default factory will create a new
- * {@link Exchange} instance, and the pooled factory will pool and reuse
exchanges.
+ * The factory is pluggable to support two exchange-lifecycle strategies:
+ * <ul>
+ * <li><b>default</b> — allocates a fresh {@link Exchange} for every inbound
message; simple and GC-friendly for
+ * low-volume routes.</li>
+ * <li><b>pooled</b> — reuses {@link org.apache.camel.PooledExchange}
instances from an object pool; reduces
+ * garbage-collection pressure on high-throughput routes by recycling the
exchange and its internal state after each
+ * routing cycle completes.</li>
+ * </ul>
+ * Camel selects the strategy at startup based on the {@code exchangeFactory}
configuration option on the
+ * {@link org.apache.camel.CamelContext}.
*
* @see ProcessorExchangeFactory
* @see org.apache.camel.PooledExchange
diff --git
a/core/camel-api/src/main/java/org/apache/camel/spi/ExchangeFormatter.java
b/core/camel-api/src/main/java/org/apache/camel/spi/ExchangeFormatter.java
index a2bd7d850307..c3f5df0054f7 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/ExchangeFormatter.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/ExchangeFormatter.java
@@ -19,8 +19,17 @@ package org.apache.camel.spi;
import org.apache.camel.Exchange;
/**
- * A plugin used to turn an {@link Exchange} into a String representation
usually to be used for logging or tracing
- * purposes.
+ * Strategy for rendering an {@link Exchange} as a human-readable {@link
String}, used primarily for logging and tracing
+ * output.
+ * <p/>
+ * Camel's built-in logging processor, the {@link BacklogTracer}, and the log
component all delegate to an
+ * {@code ExchangeFormatter} to produce the text that appears in log lines.
The default implementation
+ * ({@code DefaultExchangeFormatter} in {@code camel-support}) provides
options to include/exclude headers, body
+ * content, and exchange properties, as well as to truncate large payloads.
Callers can register a custom
+ * {@code ExchangeFormatter} bean in the registry to override the default
rendering globally.
+ * <p/>
+ * Implementations must be thread-safe: a single instance is typically shared
across all threads that process exchanges
+ * on a route.
*/
public interface ExchangeFormatter {
diff --git
a/core/camel-api/src/main/java/org/apache/camel/spi/IdempotentRepository.java
b/core/camel-api/src/main/java/org/apache/camel/spi/IdempotentRepository.java
index 006e7485223f..2efa5af08c26 100644
---
a/core/camel-api/src/main/java/org/apache/camel/spi/IdempotentRepository.java
+++
b/core/camel-api/src/main/java/org/apache/camel/spi/IdempotentRepository.java
@@ -20,17 +20,24 @@ import org.apache.camel.Exchange;
import org.apache.camel.Service;
/**
- * Access to a repository of Message IDs to implement the
- * <a href="https://camel.apache.org/idempotent-consumer.html">Idempotent
Consumer</a> pattern.
+ * Persistent store of message identifiers that implements the
+ * <a
href="https://camel.apache.org/manual/idempotent-consumer.html">Idempotent
Consumer</a> pattern, ensuring each
+ * message is processed at most once.
* <p/>
- * The <tt>add</tt> and <tt>contains</tt> methods is operating according to
the {@link java.util.Set} contract.
+ * The {@code add} and {@code contains} methods follow the {@link
java.util.Set} contract: {@link #add(String)} returns
+ * {@code true} only when the key is new (first occurrence), and {@link
#contains(String)} tests membership without
+ * adding.
* <p/>
- * The repository supports eager (default) and non-eager mode.
+ * The repository supports two processing modes, controlled by the Idempotent
Consumer EIP configuration:
* <ul>
- * <li>eager: calls <tt>add</tt> and <tt>confirm</tt> if complete, or
<tt>remove</tt> if failed</li>
- * <li>non-eager: calls <tt>contains</tt> and <tt>add</tt> if complete, or
<tt>remove</tt> if failed</li>
+ * <li><b>eager (default)</b> — {@link #add(String)} is called on entry. On
success, {@link #confirm(String)} commits
+ * the key. On failure, {@link #remove(String)} rolls back so the message can
be redelivered.</li>
+ * <li><b>non-eager</b> — {@link #contains(String)} guards entry; {@link
#add(String)} is only called on success.
+ * {@link #remove(String)} is still called on failure.</li>
* </ul>
- * Notice the remove callback, can be configured to be disabled.
+ * The removal-on-failure callback can be disabled via the EIP option, which
is useful for at-most-once semantics even
+ * when the downstream processing fails. Persistent implementations backed by
a file, JDBC database, Redis, or Hazelcast
+ * are available as separate Camel components.
*/
public interface IdempotentRepository extends Service {
diff --git
a/core/camel-api/src/main/java/org/apache/camel/spi/MessageHistoryFactory.java
b/core/camel-api/src/main/java/org/apache/camel/spi/MessageHistoryFactory.java
index fe7ab740dc12..84c2d695ac87 100644
---
a/core/camel-api/src/main/java/org/apache/camel/spi/MessageHistoryFactory.java
+++
b/core/camel-api/src/main/java/org/apache/camel/spi/MessageHistoryFactory.java
@@ -24,7 +24,19 @@ import org.apache.camel.StaticService;
import org.jspecify.annotations.Nullable;
/**
- * A factory to create {@link MessageHistory} instances.
+ * Factory for creating {@link MessageHistory} entries, which together form
the audit trail of a single
+ * {@link org.apache.camel.Exchange} as it passes through each node of a route.
+ * <p/>
+ * When the message history feature is enabled on the {@link
org.apache.camel.CamelContext}, Camel's
+ * {@link InternalProcessor} calls
+ * {@link #newMessageHistory(String, org.apache.camel.NamedNode,
org.apache.camel.Exchange)} at every route-node
+ * boundary and attaches the resulting entry to the exchange's history list.
This history can later be rendered (e.g.,
+ * as part of an exception stack trace) to show exactly which EIP nodes the
message visited and in what order. The
+ * {@link #setCopyMessage(boolean)} option controls whether a snapshot of the
message body is captured at each step,
+ * which is useful for debugging but adds memory overhead.
+ *
+ * @see org.apache.camel.MessageHistory
+ * @see ExchangeFormatter
*/
public interface MessageHistoryFactory extends StaticService,
CamelContextAware {
diff --git
a/core/camel-api/src/main/java/org/apache/camel/spi/ProcessorExchangeFactory.java
b/core/camel-api/src/main/java/org/apache/camel/spi/ProcessorExchangeFactory.java
index 06cc1dd23988..93b11be3d6b3 100644
---
a/core/camel-api/src/main/java/org/apache/camel/spi/ProcessorExchangeFactory.java
+++
b/core/camel-api/src/main/java/org/apache/camel/spi/ProcessorExchangeFactory.java
@@ -23,13 +23,21 @@ import org.apache.camel.NonManagedService;
import org.apache.camel.Processor;
/**
- * Factory used by {@link org.apache.camel.Processor} (EIPs) when they create
copies of the processed {@link Exchange}.
+ * Factory used by {@link org.apache.camel.Processor} implementations (EIPs)
when they create copies of the current
+ * {@link Exchange} for sub-routing.
* <p/>
- * Some EIPs like WireTap, Multicast, Split etc creates copies of the
processed exchange which they use as sub
- * exchanges. This factory allows to use exchange pooling.
- *
- * The factory is pluggable which allows to use different strategies. The
default factory will create a new
- * {@link Exchange} instance, and the pooled factory will pool and reuse
exchanges.
+ * EIPs such as WireTap, Multicast, and Splitter each create one or more
derived exchanges (copies or correlated copies)
+ * to fan out processing. This factory gives those EIPs the same
exchange-pooling benefit as {@link ExchangeFactory}
+ * gives to consumers, without conflating the two lifecycle boundaries.
+ * <p/>
+ * Like {@link ExchangeFactory}, this factory is pluggable:
+ * <ul>
+ * <li><b>default</b> — creates a new {@link Exchange} copy per sub-routing
invocation.</li>
+ * <li><b>pooled</b> — reuses {@link org.apache.camel.PooledExchange}
instances, recycling them after the sub-exchange
+ * completes its portion of the route.</li>
+ * </ul>
+ * Each stateful EIP receives its own private {@code ProcessorExchangeFactory}
instance via
+ * {@link #newProcessorExchangeFactory(org.apache.camel.Processor)}.
*
* @see ExchangeFactory
* @see org.apache.camel.PooledExchange
diff --git
a/core/camel-api/src/main/java/org/apache/camel/spi/StreamCachingStrategy.java
b/core/camel-api/src/main/java/org/apache/camel/spi/StreamCachingStrategy.java
index 7ca380de8977..631d844425c4 100644
---
a/core/camel-api/src/main/java/org/apache/camel/spi/StreamCachingStrategy.java
+++
b/core/camel-api/src/main/java/org/apache/camel/spi/StreamCachingStrategy.java
@@ -26,10 +26,25 @@ import org.apache.camel.StreamCache;
import org.jspecify.annotations.Nullable;
/**
- * Strategy for stream caching, which allows message bodies based on streams
(such as {@link java.io.InputStream}) to be
- * re-read. The strategy controls whether caching uses memory or spools to
disk.
+ * Strategy that controls when and how stream-based message bodies (such as
{@link java.io.InputStream}) are buffered so
+ * they can be re-read, as described in the <a
href="https://camel.apache.org/manual/stream-caching.html">Stream
+ * Caching</a> documentation.
+ * <p/>
+ * Without stream caching, a stream body can only be consumed once; any EIP or
log statement that reads the body a
+ * second time will see an empty stream. When stream caching is enabled, Camel
wraps the body in a {@link StreamCache}
+ * that buffers data either in memory or in a temporary spool file on disk,
depending on thresholds configured on this
+ * strategy.
+ * <p/>
+ * The key thresholds are:
+ * <ul>
+ * <li>{@link #setSpoolThreshold(long)} — streams larger than this value are
spooled to disk rather than held in memory,
+ * preventing out-of-memory errors for large payloads.</li>
+ * <li>{@link #setBufferSize(int)} — the internal read-buffer size when
copying bytes to the spool file.</li>
+ * <li>{@link #setSpoolDirectory(java.io.File)} — the directory where spool
files are written.</li>
+ * </ul>
+ * Statistics about in-memory vs. on-disk cache usage are available via {@link
#getStatistics()}.
*
- * @see <a href="https://camel.apache.org/stream-caching.html">stream
caching</a>
+ * @see StreamCache
*/
public interface StreamCachingStrategy extends StaticService {
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/Transformer.java
b/core/camel-api/src/main/java/org/apache/camel/spi/Transformer.java
index e2406a3e0221..e40dd2780fda 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/Transformer.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/Transformer.java
@@ -26,12 +26,21 @@ import org.apache.camel.util.ObjectHelper;
import org.jspecify.annotations.Nullable;
/**
- * <a href="https://camel.apache.org/transformer.html">Transformer</a>
performs message transformation according to the
- * declared data type. {@link org.apache.camel.processor.ContractAdvice} looks
for a required Transformer and apply if
- * input/output type declared on a route is different from current message
type.
+ * Performs message body transformation between two {@link DataType}s as part
of Camel's
+ * <a href="https://camel.apache.org/manual/transformer.html">Transformer</a>
contract mechanism.
+ * <p/>
+ * When a route declares an {@code inputType} or {@code outputType}, Camel's
+ * {@link org.apache.camel.processor.ContractAdvice} inspects the current
message's {@link DataType} and looks up a
+ * matching {@code Transformer} in the {@link TransformerRegistry}. If the
current type differs from the declared type,
+ * the transformer's {@link #transform(org.apache.camel.Message, DataType,
DataType)} method is called automatically,
+ * without requiring the route developer to add an explicit conversion step.
+ * <p/>
+ * Transformers can be registered by annotating a subclass with {@link
DataTypeTransformer} (the annotation drives
+ * automatic registration) or manually via {@link
org.apache.camel.CamelContext#getTransformerRegistry()}.
*
- * @see {@link org.apache.camel.processor.ContractAdvice} {@link DataType}
- * {@link org.apache.camel.model.InputTypeDefinition} {@link
org.apache.camel.model.OutputTypeDefinition}
+ * @see DataTypeTransformer
+ * @see TransformerRegistry
+ * @see DataType
*/
public abstract class Transformer extends ServiceSupport implements
CamelContextAware {
diff --git
a/core/camel-api/src/main/java/org/apache/camel/spi/TransformerKey.java
b/core/camel-api/src/main/java/org/apache/camel/spi/TransformerKey.java
index 2ca7e899607e..4391e0d0ee1b 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/TransformerKey.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/TransformerKey.java
@@ -23,9 +23,17 @@ import org.apache.camel.util.StringHelper;
import org.jspecify.annotations.Nullable;
/**
- * Key used in {@link org.apache.camel.spi.TransformerRegistry} in
- * {@link org.apache.camel.impl.engine.AbstractCamelContext}, to ensure a
consistent lookup.
+ * Composite lookup key for the {@link TransformerRegistry}, encoding a
from-{@link DataType} / to-{@link DataType} pair
+ * as a single string value for efficient map-based lookup.
+ * <p/>
+ * The string form is {@code "fromType/toType"} when both ends are specified,
or just {@code "toType"} when the from
+ * side is {@link DataType#ANY} (scheme-only transformer that applies to any
input type). This normalization ensures
+ * that scheme-based transformers (e.g. all {@code json:*} conversions) can be
resolved with a single registry lookup
+ * without iterating all registered transformers.
*
+ * @see TransformerRegistry
+ * @see Transformer
+ * @see DataType
* @since 4.7
*/
public final class TransformerKey extends ValueHolder<String> {
diff --git
a/core/camel-api/src/main/java/org/apache/camel/spi/TransformerRegistry.java
b/core/camel-api/src/main/java/org/apache/camel/spi/TransformerRegistry.java
index 2821d5b59c54..747b38cc1dec 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/TransformerRegistry.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/TransformerRegistry.java
@@ -22,19 +22,23 @@ import org.apache.camel.StaticService;
import org.jspecify.annotations.Nullable;
/**
- * Registry to cache transformers in memory.
+ * Registry that stores and resolves {@link Transformer} instances for Camel's
+ * <a href="https://camel.apache.org/manual/transformer.html">data type
contract</a> mechanism.
* <p/>
- * The registry contains two caches:
+ * The registry maintains two separate caches to balance memory usage and
lookup performance:
* <ul>
- * <li>static - which keeps all the transformers in the cache for the entire
lifecycle</li>
- * <li>dynamic - which keeps the transformers in a {@link
org.apache.camel.support.LRUCache} and may evict transformers
- * which hasn't been requested recently</li>
+ * <li><b>static cache</b> — holds all transformers registered at route
startup; no eviction, no size limit. Contains
+ * every transformer bound to a {@link DataType} pair when the {@link
org.apache.camel.CamelContext} starts.</li>
+ * <li><b>dynamic cache</b> — holds transformers created or registered at
runtime (for example, from custom Java code or
+ * hot-deployed routes); backed by an LRU cache with a configurable size limit
(default 1000 entries) to prevent
+ * unbounded growth.</li>
* </ul>
- * The static cache stores all the transformers that are created as part of
setting up and starting routes. The static
- * cache has no upper limit.
- * <p/>
- * The dynamic cache stores the transformers that are created and used ad-hoc,
such as from custom Java code that
- * creates new transformers etc. The dynamic cache has an upper limit, that by
default is 1000 entries.
+ * Lookup is performed by {@link #resolveTransformer(TransformerKey)}, which
searches both caches using the from/to
+ * {@link DataType} pair encoded in the {@link TransformerKey}.
+ *
+ * @see Transformer
+ * @see TransformerKey
+ * @see DataType
*/
public interface TransformerRegistry extends Map<TransformerKey, Transformer>,
StaticService {
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/Validator.java
b/core/camel-api/src/main/java/org/apache/camel/spi/Validator.java
index 1bd7da3f1d88..d286fc46ba4a 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/Validator.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/Validator.java
@@ -26,12 +26,22 @@ import org.apache.camel.support.service.ServiceSupport;
import org.jspecify.annotations.Nullable;
/**
- * <a href="https://camel.apache.org/validator.html">Validator</a> performs
message content validation according to the
- * declared data type. {@link org.apache.camel.processor.ContractAdvice}
applies Validator if input/output type is
- * declared on a route with validation enabled.
+ * Validates message content against a declared {@link DataType}, as described
in the
+ * <a href="https://camel.apache.org/manual/transformer.html">Transformer and
Validator</a> documentation.
+ * <p/>
+ * When a route declares an {@code inputType} or {@code outputType} with
{@code validate = true},
+ * {@link org.apache.camel.processor.ContractAdvice} invokes the registered
{@code Validator} for that type before (or
+ * after) the route's main processing logic. If the message content does not
satisfy the validator's rules, the
+ * validator should throw a {@link org.apache.camel.ValidationException} to
signal the failure.
+ * <p/>
+ * Validators are registered in the {@link ValidatorRegistry} keyed by their
target {@link DataType}. Custom validators
+ * extend this abstract class and are registered via the DSL (e.g., {@code
inputType} / {@code outputType} with
+ * {@code validate = true}), which wires them through {@link
org.apache.camel.model.ValidatorDefinition} during route
+ * startup.
*
- * @see {@link org.apache.camel.processor.ContractAdvice} {@link
org.apache.camel.model.InputTypeDefinition}
- * {@link org.apache.camel.model.OutputTypeDefinition}
+ * @see ValidatorRegistry
+ * @see DataType
+ * @see org.apache.camel.model.ValidatorDefinition
*/
public abstract class Validator extends ServiceSupport implements
CamelContextAware {
diff --git
a/core/camel-api/src/main/java/org/apache/camel/spi/ValidatorRegistry.java
b/core/camel-api/src/main/java/org/apache/camel/spi/ValidatorRegistry.java
index 73cecf377ac3..500877b1a330 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/ValidatorRegistry.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/ValidatorRegistry.java
@@ -22,19 +22,23 @@ import org.apache.camel.StaticService;
import org.jspecify.annotations.Nullable;
/**
- * Registry to cache validators in memory.
+ * Registry that stores and resolves {@link Validator} instances for Camel's
+ * <a href="https://camel.apache.org/manual/transformer.html">data type
validation</a> mechanism.
* <p/>
- * The registry contains two caches:
+ * The registry maintains two separate caches mirroring the design of {@link
TransformerRegistry}:
* <ul>
- * <li>static - which keeps all the validators in the cache for the entire
lifecycle</li>
- * <li>dynamic - which keeps the validators in a {@link
org.apache.camel.support.LRUCache} and may evict validators
- * which hasn't been requested recently</li>
+ * <li><b>static cache</b> — holds all validators registered at route startup;
no eviction, no size limit. Contains
+ * every validator bound to a {@link DataType} when the {@link
org.apache.camel.CamelContext} starts.</li>
+ * <li><b>dynamic cache</b> — holds validators created or registered at
runtime (for example, from custom Java code or
+ * hot-deployed routes); backed by an LRU cache with a configurable size limit
(default 1000 entries) to prevent
+ * unbounded growth.</li>
* </ul>
- * The static cache stores all the validators that are created as part of
setting up and starting routes. The static
- * cache has no upper limit.
- * <p/>
- * The dynamic cache stores the validators that are created and used ad-hoc,
such as from custom Java code that creates
- * new validators etc. The dynamic cache has an upper limit, that by default
is 1000 entries.
+ * Lookup is performed by {@link #resolveValidator(ValidatorKey)}, which
searches both caches using the {@link DataType}
+ * encoded in the {@link ValidatorKey}.
+ *
+ * @see Validator
+ * @see ValidatorKey
+ * @see DataType
*/
public interface ValidatorRegistry extends Map<ValidatorKey, Validator>,
StaticService {