sedge
sedge

Reputation: 385

Apache Camel Intercept - Capture Output.

I am attempting to use Apache Camel Interceptor in the spring.xml file to capture incoming requests and outgoing responses, like this:

    <bean id="InterceptProcessor" class="CaptureProcessor"/>
<camel:camelContext id="camel">
    <camel:jmxAgent id="agent" disabled="true" />
    <camel:intercept>
        <camel:process ref="InterceptProcessor"></camel:process>
    </camel:intercept>
    <camel:route id="Resource.rConnect.rconnect" autoStartup="false">
        <camel:from
            uri="cxfjetty:${Resource.rConnect.rconnect.baseUrl}?urlTemplateRef=#URLTemplateRef.Resource.rConnect.rconnect&amp;
            convertAttachments=true" />
        <camel:to
            uri="sonicesb://Process/rConnect?bindingStrategy=#ExposeBindingStrategy.Resource.rConnect.rconnect&amp;headerFilterStrategy=#ExposeHeaderFilterStrategy.Resource.rConnect.rconnect&amp;esbConfig=#ExposeEsbConfig.Resource.rConnect.rconnect" />
    </camel:route>
    <camel:route autoStartup="false">
        <camel:from
            uri="directsonicesb:Resource.rConnect.rconnect?bindingStrategy=#InvokeBindingStrategy.Resource.rConnect.rconnect&amp;headerFilterStrategy=#InvokeHeaderFilterStrategy.Resource.rConnect.rconnect&amp;uriTemplate=#URITemplate.Resource.rConnect.rconnect" />
        <camel:to uri="sonicesb://Process/rConnect" />
    </camel:route>
</camel:camelContext>

Following this article.

But the "CaptureProcessor" is only called once on the input cycle.

How can I make it capture the Output as well?

Upvotes: 0

Views: 4221

Answers (3)

sedge
sedge

Reputation: 385

I found an approach that suited me better.

Using the intercept in my original question, then in the process class: Use a Synchronization and add the onCompletion processor.

import org.apache.camel.Exchange;
import org.apache.camel.Processor;
public class CaptureProcessor implements Processor, Synchronization    
{
    @Override
    public void process(Exchange exch) throws Exception
    {
         if (exch.hasOut())
         {
           // you won't get here
         } else
         {
            // ==== Add the onCompletion interceptor ====
            exch.addOnCompletion(this);
            // do in processing
                      ....
        }
    }

    @Override
    public void onComplete(Exchange exch)
    {
         if (exch.hasOut())
         {
                  // do the out procesing
                          ....
        } else
        {
             // you won't get here  
              }
    }

    @Override
    public void onFailure(Exchange exch)
    {
            // you get the idea by now
    }
}

And the inbound and outbound intercept are only called once each.

Upvotes: 2

sedge
sedge

Reputation: 385

Thanks Peter.

That did the trick.

Some interesting outcomes though

  • The intercept entry is still required to capture the incoming request.
  • Once I added the onCompletion entry to my Spring configuration, the Processor is invoked four times, three in and one out.

I tried moving the intercept and onCompletion entries into dofferent places but always got the same result. My solution was to add a specific Header on the first inbound call and bypass processing on the others if the header was already there.

Regards Steve

Upvotes: -1

Peter Keller
Peter Keller

Reputation: 7636

According to the Camel doc, this is not possible with intercept:

What happens is that the Exchange is intercepted before each processing step, that means that it will be intercepted before

Thus, it is not possible to intercept the processing after each step. However, there's an open Jira ticket for this requirement: CAMEL-6901

Alternatively, you may use onCompletion that is like an after completion callback which can be defined for each route or globally for the whole Camel context:

<onCompletion>
    <log message="${body}" />
</onCompletion>

See the Camel docs for more information about this possibility.

Upvotes: 4

Related Questions