I've recently upgraded from Camel 2.11.1 to 2.13.1, and it would appear that
I'm now losing attachments on exchanges when I use the Velocity endpoint
through a routing slip.

I've got a route which looks like this:

        from('direct:mail.velocity')
            .process( new Processor(){
                @Override
                void process(Exchange exchange) throws Exception {
                    log.info("1) mail attachments =
${exchange.in.attachments}")
                }
            })
            .routingSlip(header(MAIL_TEMPLATE_ROUTING_SLIP))
            .process( new Processor(){
                @Override
                void process(Exchange exchange) throws Exception {
                    log.info("2) mail attachments =
${exchange.in.attachments}")
                }
            })
            .to("direct:mail")

the routing slip header directs to a velocity endpoint (e.g.
"velocity://myTemplate) to create an email.  In this case, I can see in the
1st logger that we have an attachment, but in the second, we don't.

I believe this is because in the VelocityEndpoint.onExchange() method, in
the very last line, we have:

        out.setAttachments(exchange.getIn().getAttachments());

This means that both the in & out attachments have the same Map storing the
attachments (rather than each having their own map containing the same
items).

Then, as part of the RoutingSlip.doRoutingSlip(), we use
ExchangeHelper.copyResults(Exchange result, Exchange source) to copy the
result exchange.  As the source & results exchanges are not the same, this
calls:

        result.getIn().copyFrom(source.getIn())

which uses MessageSupport.copyFrom(), using the following code:

        
        if (hasAttachments()) {
            getAttachments().clear();
        }
        if (that.hasAttachments()) {
            getAttachments().putAll(that.getAttachments());
        }


Given that the two exchanges share the same map of attachments, when we call
getAttachments().clear() as the first step, we actually clear out both sets
of attachments - so there are no longer any attachments in the source
exchange to copy in the second step (I've verified this in a debugger).

I believe this could be fixed by changing VelocityEndpoint.onExchange() to
use something like:

        Map theAttachments = new LinkedHashMap();
        theAttachments.putAll( exchange.getIn().getAttachments() );
        out.setAttachments(theAttachments);

Or in MessageSupport.copyFrom(), check for the same attachments in the same
way you do for headers:

        boolean sameAttachmentsInstance = false;
        if (hasAttachments() && that.hasAttachments() && getAttachments() ==
that.getAttachments()) {
                sameAttachmentsInstance = true;
        }
        if (!sameAttachmentsInstance){
                if (hasAttachments()) {
                    getAttachments().clear();
                }
                if (that.hasAttachments()) {
                    getAttachments().putAll(that.getAttachments());
                }
        }

hopefully this make sense to you, but if you need any more details, please
let me know,

  Andrew Lawrenson.





--
View this message in context: 
http://camel.465427.n5.nabble.com/losing-exchange-attachments-with-camel-2-13-1-tp5752324.html
Sent from the Camel Development mailing list archive at Nabble.com.

Reply via email to