Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • scope: global and/or per route (route scope override all global scope)
  • multiple global scope
  • triggered either always, only if completed with success, or only if failed
  • onWhen predicate to only trigger in certain situations
  • Camel 2.14: mode: to define whether to run either before or after route consumer writes response back to callee (if its InOut)
  • Camel 2.14: whether to run async or sync (use a thread pool or not)

From Camel 2.14 onwards the onCompletion has been modified to support running the completion task in either synchronous or asynchronous mode (using a thread pool) and also whether to run before or after the route consumer is done. The reason is to give more flexibility. For example to specify to run synchronous and before the route consumer is done, which allows to modify the exchange before the consumer writes back any response to the callee. You can use this to for example add customer headers, or send to a log to log the response message, etc.

Info
titleChanges from Camel 2.14 onwards

The onCompletion has changed defaults and behavior from Camel 2.14 onwards. It now runs

  • Runs synchronously without any thread pool

In Camel 2.13 the defaults were

  • Runs asynchronous using a thread pool
Info
titleCamel 2.13 or older - On completion runs in separate thread

The onCompletion runs in a separate thread in parallel with the original route. It is therefore not intended to influence the outcome of the original route. The idea for on completion is to spin off a new thread to eg send logs to a central log database, send an email, send alterts to a monitoring system, store a copy of the result message etc.
Therefore if you want to do some work that influence the original route, then do not use onCompletion for that. Notice: if you use the UnitOfWork API as mentioned in the top of this page, then you can register a Synchronization callback on the Exchange which is executed in the original route. That way allows you to do some custom code when the route is completed; this is how custom components can enlist on completion services which they need, eg the File component does that for work that moves/deletes the original file etc.

...

Wiki Markup
{snippet:id=e1|lang=java|url=camel/trunk/camel-core/src/test/java/org/apache/camel/processor/OnCompletionWhenTest.java}

Using onCompletion with or without thread pool

Available as of Camel 2.14

OnCompletion will from Camel 2.14 onwards not use thread pool by default. To use thread pool then either set a executorService or set parallelProcessing to true.

For example in Java DSL do

Code Block
                onCompletion().parallelProcessing()
                    .to("mock:before")
                    .delay(1000)
                    .setBody(simple("OnComplete:${body}"));

And in XML DSL

Code Block
      <onCompletion parallelProcessing="true">
        <to uri="before"/>
        <delay><constant>1000</constant></delay>
        <setBody><simple>OnComplete:${body}</simple></setBody>
      </onCompletion>

You can also refer to a specific thread pool to be used, using the executorServiceRef option

Code Block
      <onCompletion executorServiceRef="myThreadPool">
        <to uri="before"/>
        <delay><constant>1000</constant></delay>
        <setBody><simple>OnComplete:${body}</simple></setBody>
      </onCompletion>

 

Using onCompletion to run before route consumer sends back response to callee

Available as of Camel 2.14

OnCompletion supports two modes

  • AfterConsumer - Default mode which runs after the consumer is done
  • BeforeConsumer - Runs before the consumer is done, and before the consumer writes back response to the callee

The AfterConsumer mode is the default mode which is the same behavior as in older Camel releases.

The new BeforeConsumer mode is used to run onCompletion before the consumer writes its response back to the callee (if in InOut mode). This allows the onCompletion to modify the Exchange, such as adding special headers, or to log the Exchange as a response logger etc.

For example to always add a "created by" header you use modeBeforeConsumer() as shown below:

Code Block
    .onCompletion().modeBeforeConsumer()
        .setHeader("createdBy", constant("Someone"))
    .end()

 

And in XML DSL you set the mode attribute to BeforeConsumer:

Code Block
      <onCompletion mode="BeforeConsumer">
        <setHeader headerName="createdBy">
          <constant>Someone</constant>
        </setHeader>
      </onCompletion>

 

See Also

  • Unit of Work