Apache Camel Intercept - Capture Output.

白昼怎懂夜的黑 提交于 2019-12-11 21:24:30

问题


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?


回答1:


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.




回答2:


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.




回答3:


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



来源:https://stackoverflow.com/questions/23555899/apache-camel-intercept-capture-output

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!