I also had this requirement (to perform synchronous, in-only processing on another route), and to achieve it I wrote a custom Processor that programmatically sends a copy of the Exchange. I think this results in a nicer DSL, in which the semantics at the point of use are clearer than by using enrich.
This static helper method creates the processor:
public static Processor synchronousWireTap(String uri) {
return exchange -> {
Exchange copy = exchange.copy();
exchange.getContext().createProducerTemplate().send(uri,copy);
//ProducerTemplate.send(String,Exchange) does not, unlike other send methods, rethrow an exception
//on the exchange. We want any unhandled exception to be rethrown, so we must do so here.
Throwable thrown = copy.getException(Throwable.class);
if (thrown != null) {
throw new CamelExecutionException(thrown.getMessage(), exchange, thrown);
}
};
}
And here's an example of use:
from("direct:foo")
.to("direct:doSomething") // 1 (POJO on the exchange body)
.process(synchronousWireTap("direct:storeInHazelcast")) // 2 (Does not destroy POJO because a copy of the exchange gets sent to this uri)
.to("direct:doSomethingElse") // 3 (POJO is still there)
Note that this custom processor is not quite a synchronous analogue of the standard wireTap(), which is fully in-only, in that this processor rethrows any unhandled exception that occurs on the target route - but the message itself is left untouched. This was my requirement, since what I wanted to do was perform some other processing synchronously on another route, and be notified if that failed, but otherwise not have the message on my main route be affected (sort of the equivalent of calling a void method in procedural code).