Camel - Stream cache not caching / can't convert?

邮差的信 提交于 2019-12-04 10:02:01

Using stream cache allows you to read streams more than once in different processors but still only once in the same processor.

I tested with:

ModelCamelContext context = new DefaultCamelContext();
context.setStreamCaching(true); //!!
// ...

from("direct:start")
    .to("http://ip.jsontest.com/?callback=showMyIP")
    .process(new MyProcessor())
    .process(new MyProcessor());

And:

public class MyProcessor implements Processor {
    private static final Logger LOG = LoggerFactory.getLogger(HttpStreamCache.MyProcessor.class);
    @Override
    public void process(final Exchange exchange) throws Exception {
        LOG.info("***** Body Type: " + exchange.getIn().getBody().getClass().getCanonicalName());
        LOG.info("***** In msg1  : " + exchange.getIn().getBody(String.class));
        LOG.info("***** In msg2  : " + exchange.getIn().getBody(String.class));
    }
};

This prints:

INFO  ***** Body Type: org.apache.camel.converter.stream.InputStreamCache
INFO  ***** In msg1  : showMyIP({"ip": "00.000.000.00"});

INFO  ***** In msg2  : 
INFO  ***** Body Type: org.apache.camel.converter.stream.InputStreamCache
INFO  ***** In msg1  : showMyIP({"ip": "00.000.000.00"});

INFO  ***** In msg2  :  

I believe you problem is not the input stream is gone, but rather that it's reader position is at the last point of consumption, in this case, at the end of the stream.

you could use a stream "rewind" method that could bring your reader to the beginning of the stream - only if the stream supports it.

Here's a scala code that provides such a resetter:

object StreamResetter extends Processor {
  import org.apache.camel.util.MessageHelper
  import org.apache.camel.Exchange

  override def process(exchange: Exchange): Unit = MessageHelper.resetStreamCache(exchange.getIn)
}

than, on your route, just before the second log call, you can use

process(StreamResetter)

Regards.

If the content of your JSON input stream is not prohibitively large, you could convert your input stream into ByteArrayInputStream and that way you can read from it multiple times in any Processor. Hope that helps.

Working example for me:

from("direct:secondRoute")
     .to("callOtherService")
     .log("RESPONSE: ${body}")  
     .process(exchange -> {
        InputStream in = exchange.getIn().getBody(InputStream.class);
        in.reset();
     });

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