You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by Kevin Jackson <fo...@gmail.com> on 2010/03/11 09:21:50 UTC

Testing consuming mail with attachments

Hi,

I have a requirement to take an email, consume it extract the
attachment, then process the contents of the attachment.

I have the processing completed, but I cannot find an elegant method
of testing the mail attachment handling.  The documentation seems to
require that my processing is coupled to Camel, I would prefer to use
a simple bean rather than a Processor implementation.

The canonical example of handling mail attachments is similar to :

public void process(Exchange ex) throws Exception {
        Map<String, DataHandler> attachments = ex.getIn().getAttachments();
        if(attachments.size() > 0) {
            //loop here but really only expect a single attachment
            for(String name : attachments.keySet()) {
                DataHandler dh = attachments.get(name);

                String filename = dh.getName();
                byte[] data =
ex.getContext().getTypeConverter().convertTo(byte[].class,
dh.getInputStream());
                FileOutputStream fos = new
FileOutputStream(getAttachmentPath()+filename);
                fos.write(data);
                fos.flush();
                fos.close();
            }
        }
    }

Unfortunately this means that my mail processing is camel specific -
I'd rather be able to handle MimeMessage instead of Exchange and be
completely free of a camel dependency so that I can test the handling
of mail independently.  However other code for handling mail
attachments seems to be needlessly complex.  Right now i have a choice
between short relatively simple code that cannot be tested to my
satisfaction, or writing much more complex code that I can test
without tight coupling to the camel code.  Neither solution smells
right and neither is particularly nice.

Has anyone else come across this problem?

Thanks,
Kev

Re: Testing consuming mail with attachments

Posted by Claus Ibsen <cl...@gmail.com>.
Hi Keven

Thanks for the patch.

Lets get rid of the last @Attachments need as we can let Camel detect
the Map itself.

See in BeanInfo class in the method createParameterUnmarshalExpression.
Here you can return the AttachmentsExpression if the method is a Map
type and genericfied with the <Object, DataHolder>

Then Camel can assume its attachments since the Map is a <Object,
DataHolder> map.



On Sun, Mar 14, 2010 at 6:18 AM, Willem Jiang <wi...@gmail.com> wrote:
> Hi Kevin,
>
> I fixed the issue which is based on your patch, please feel free to check
> out the change[1]
>
> [1]http://svn.apache.org/viewvc?rev=922763&view=rev
>
> Willem
> Kevin Jackson wrote:
>>
>> Hi,
>>>
>>> Good ideas. Feel free to create a JIRA ticket.
>>> And a patch is also welcome. We love contributions.
>>
>> https://issues.apache.org/activemq/browse/CAMEL-2547
>>
>> Includes skeleton patch/tests for this functionality.
>>
>> Thanks,
>> Kev
>>
>
>



-- 
Claus Ibsen
Apache Camel Committer

Author of Camel in Action: http://www.manning.com/ibsen/
Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/
Twitter: http://twitter.com/davsclaus

Re: Testing consuming mail with attachments

Posted by Willem Jiang <wi...@gmail.com>.
Hi Kevin,

I fixed the issue which is based on your patch, please feel free to 
check out the change[1]

[1]http://svn.apache.org/viewvc?rev=922763&view=rev

Willem
Kevin Jackson wrote:
> Hi,
>> Good ideas. Feel free to create a JIRA ticket.
>> And a patch is also welcome. We love contributions.
> 
> https://issues.apache.org/activemq/browse/CAMEL-2547
> 
> Includes skeleton patch/tests for this functionality.
> 
> Thanks,
> Kev
> 


Re: Testing consuming mail with attachments

Posted by Kevin Jackson <fo...@gmail.com>.
Hi,
> Good ideas. Feel free to create a JIRA ticket.
> And a patch is also welcome. We love contributions.

https://issues.apache.org/activemq/browse/CAMEL-2547

Includes skeleton patch/tests for this functionality.

Thanks,
Kev

Re: Testing consuming mail with attachments

Posted by Claus Ibsen <cl...@gmail.com>.
Hi

Good ideas. Feel free to create a JIRA ticket.
And a patch is also welcome. We love contributions.



On Sat, Mar 13, 2010 at 10:31 AM, Kevin Jackson <fo...@gmail.com> wrote:
> Hi,
>
> This is a follow up to conclude how I tested consuming mail
> attachments in camel 2.1 + spring.  Posting here because others on the
> user list may find this useful going forward.
>
> With camel 2.1 it doesn't seem to be possible to completely decouple
> the processing of email messages with attachments from some link to
> camel.  My goal was to have a simple POJO with a single method which
> would accept an attachment and write it to disk.
>
> Using the Processor interface as suggested[1] in the docs would have
> meant that the bean was no longer a POJO.  I also wanted to avoid if
> possible being coupled to the camel datatypes (Exchange etc).
>
> Using bean parameter binding[2] I could specify which param should be
> treated as a Header or Body, but there (as yet) isn't an @Attachments.
>
> I settled on the following signature in my process method:
>
> public void process(Message msg) throws Exception
>
> Where the only coupling to camel is in the Message datatype
>
> With an @Attachments binding I could have decoupled a step further to
>
> public void process(@Attachments Map<String, DataHandler> msg) throws
> Exception (however the @Attachments would still be camel specific code
> - but I guess that's about the least coupled you can get).
>
> The alternative of course would be if the consumption of an email from
> a mailbox would produce a message of the type MimeMessage, not the
> camel specific Message (indeed MailMessage).
>
> So the flow is:
>
> camel-mail endpoint receives email -> converts to camel MailMessage ->
> my processor (which has to handle camel Message) -> disk
>
> I'm not sure whether or not my use-case points to a missing annotation
> for @Attachments, but I suggest at least for the sake of completeness
> that this annotation be added to camel trunk:
>
> package org.apache.camel;
>
> import java.lang.annotation.Documented;
>
> /**
>  * Marks a parameter as being an injection point of the attachments of
> an inbound {@link Message}
>  *
>  * @see Message#getAttachments()
>  */
> @Retention(RetentionPolicy.RUNTIME)
> @Documented
> @Target({ElementType.PARAMETER })
> public @interface Attachments {
> }
>
> Thanks for the help,
> Kev
>
> [1] http://camel.apache.org/mail.html
> [2] http://camel.apache.org/parameter-binding-annotations.html
>



-- 
Claus Ibsen
Apache Camel Committer

Author of Camel in Action: http://www.manning.com/ibsen/
Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/
Twitter: http://twitter.com/davsclaus

Re: Testing consuming mail with attachments

Posted by Kevin Jackson <fo...@gmail.com>.
Hi,

This is a follow up to conclude how I tested consuming mail
attachments in camel 2.1 + spring.  Posting here because others on the
user list may find this useful going forward.

With camel 2.1 it doesn't seem to be possible to completely decouple
the processing of email messages with attachments from some link to
camel.  My goal was to have a simple POJO with a single method which
would accept an attachment and write it to disk.

Using the Processor interface as suggested[1] in the docs would have
meant that the bean was no longer a POJO.  I also wanted to avoid if
possible being coupled to the camel datatypes (Exchange etc).

Using bean parameter binding[2] I could specify which param should be
treated as a Header or Body, but there (as yet) isn't an @Attachments.

I settled on the following signature in my process method:

public void process(Message msg) throws Exception

Where the only coupling to camel is in the Message datatype

With an @Attachments binding I could have decoupled a step further to

public void process(@Attachments Map<String, DataHandler> msg) throws
Exception (however the @Attachments would still be camel specific code
- but I guess that's about the least coupled you can get).

The alternative of course would be if the consumption of an email from
a mailbox would produce a message of the type MimeMessage, not the
camel specific Message (indeed MailMessage).

So the flow is:

camel-mail endpoint receives email -> converts to camel MailMessage ->
my processor (which has to handle camel Message) -> disk

I'm not sure whether or not my use-case points to a missing annotation
for @Attachments, but I suggest at least for the sake of completeness
that this annotation be added to camel trunk:

package org.apache.camel;

import java.lang.annotation.Documented;

/**
 * Marks a parameter as being an injection point of the attachments of
an inbound {@link Message}
 *
 * @see Message#getAttachments()
 */
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target({ElementType.PARAMETER })
public @interface Attachments {
}

Thanks for the help,
Kev

[1] http://camel.apache.org/mail.html
[2] http://camel.apache.org/parameter-binding-annotations.html

Re: Testing consuming mail with attachments

Posted by Kevin Jackson <fo...@gmail.com>.
Hi,

On Thu, Mar 11, 2010 at 9:22 AM, Claus Ibsen <cl...@gmail.com> wrote:
> Now you change subject to sending an mail using camel-mail, and by
> which you want to send it as a javax.mail.MimeMessage.
> Is this correct?

sorry, no I need to consume an email and the camel-mail test cases are
what I'm using as a starting point to understand how to do this.  I
apologize for not being clearer about this.

In testing the MimeMessage will be constructed programatically and
then I need some way of sending it to my processor (I guess using
direct:start and ProducerTemplate but again stand to be corrected)

In production the MimeMessage will be consumed via camel-mail from a
pop3 (I think) mailbox

I try to have a camel integration test using
resultEndpoint.expectedBodiesRecieved etc and a unit test which just
exercises the method.  This allows me to test the snippet of routing
associated with the change as well as the method

ie:

@Test
public void testMailIntegration() throws Exception {
  // camel stuff here
}

@Test
public void testMail() throws Exception {
  // pure pojo testing here
}

This may be why my previous email was a little confused.  I still
think that in both cases the body of the exchange should be a
MimeMessage as that is what should come out of the pop3 mailbox?  It's
how this is interacts with camel exchanges I don't quite get. Reading
MailMessage in camel-mail source I understand how a camel message can
contain attachments and then how this would fit with some of the
suggestions so far

>
> If so why dont you just try to see if it works.
>     template.send("smtp:xxx", myMimeMessage);
>
> I haven't checked the source code of camel-mail, but it could be very
> well that it can detect the MimeMessage type and use it as is.
>
>
>
> On Thu, Mar 11, 2010 at 10:16 AM, Kevin Jackson <fo...@gmail.com> wrote:
>> Hi,
>>
>>>> public void process(Exchange ex) throws Exception {
>>>>        Map<String, DataHandler> attachments = ex.getIn().getAttachments();
>>>>        if(attachments.size() > 0) {
>>>>            //loop here but really only expect a single attachment
>>>>            for(String name : attachments.keySet()) {
>>>>                DataHandler dh = attachments.get(name);
>>>>
>>>>                String filename = dh.getName();
>>>>                byte[] data =
>>>> ex.getContext().getTypeConverter().convertTo(byte[].class,
>>>> dh.getInputStream());
>>>>                FileOutputStream fos = new
>>>> FileOutputStream(getAttachmentPath()+filename);
>>>>                fos.write(data);
>>>>                fos.flush();
>>>>                fos.close();
>>>>            }
>>>>        }
>>>>    }
>>>>
>>> The bean parameter binding is what you would normally use to decouple
>>> a POJO from Camel Exchange.
>>> http://camel.apache.org/bean-binding.html
>>> http://camel.apache.org/parameter-binding-annotations.html
>>>
>>>
>>> But I can see it lacks a feature to binding attachements, so you can
>>> do something like
>>>
>>> public void foo(@Attachments Map<String, DataHandler> myAttachments) {
>>>  ..
>>> }
>>>
>>> But it could probably also be done without the @Attachments annotation
>>> as it can detect the types in the Map and see if its <String,
>>> DataHandler> and then map that automatic to the attachments of the
>>> Exchange. Anyone see a problem with this?
>>
>> I'm not sure I follow you here.
>>
>> I can use bean-binding annotations to mark a method in my pojo as a
>> @Handler method, does this negate the need to use the marker interface
>> Processor?
>>
>> The method signature suggests that the POJO would process Map<String
>> DataHandler>, this would mean that some pre-processing would be
>> required upstream to take the mime message and convert it into this
>> format?
>>
>> If this is the case, then my route would become something like :
>>
>> from("direct:start").bean(MailProc.class).to("mock:result"), where MailProc is :
>>
>> @Handler
>> public void proc(Map<String, DataHandler> attachments) throws Exception {
>>
>> }
>>
>> But when I kick this test off, I want to be using a programatically
>> created MimeMessage, so will that get converted from MimeMessage into
>> Map<String, DataHandler> attachments automatically due it being the
>> body of the Exchange?
>>
>> In the camel mail unit tests:
>>
>> @Test
>>    public void testSendAndRecieveMailWithAttachments() throws Exception {
>>        // START SNIPPET: e1
>>
>>        // create an exchange with a normal body and attachment to be
>> produced as email
>>        Endpoint endpoint =
>> context.getEndpoint("smtp://james@mymailserver.com?password=secret");
>>
>>        // create the exchange with the mail message that is multipart
>> with a file and a Hello World text/plain message.
>>        Exchange exchange = endpoint.createExchange();
>>        Message in = exchange.getIn();
>>        in.setBody("Hello World");
>>        in.addAttachment("logo.jpeg", new DataHandler(new
>> FileDataSource("src/test/data/logo.jpeg")));
>>
>>        // create a producer that can produce the exchange (= send the mail)
>>        Producer producer = endpoint.createProducer();
>>        // start the producer
>>        producer.start();
>>        // and let it go (processes the exchange by sending the email)
>>        producer.process(exchange);
>>
>>        // END SNIPPET: e1
>>
>>        // need some time for the mail to arrive on the inbox
>> (consumed and sent to the mock)
>>        Thread.sleep(2000);
>>
>>        MockEndpoint mock = getMockEndpoint("mock:result");
>>        mock.expectedMessageCount(1);
>>        Exchange out = mock.assertExchangeReceived(0);
>>        mock.assertIsSatisfied();
>>
>>        // plain text
>>        assertEquals("Hello World", out.getIn().getBody(String.class));
>>
>>        // attachment
>>        Map<String, DataHandler> attachments = out.getIn().getAttachments();
>>        assertNotNull("Should have attachments", attachments);
>>        assertEquals(1, attachments.size());
>>
>>        DataHandler handler = out.getIn().getAttachment("logo.jpeg");
>>        assertNotNull("The logo should be there", handler);
>>
>>        assertEquals("image/jpeg; name=logo.jpeg", handler.getContentType());
>>
>>        producer.stop();
>>    }
>>
>> This relies on Camel test classes and I would just like to be able to
>> create a new MimeMessage and use direct:start to
>> template.sendBody(attachmentEmail) rather than  rely on manually
>> creating Exchanges etc
>>
>> Sorry to bother you but this is an interesting investigation from my side
>> Kev
>>
>
>
>
> --
> Claus Ibsen
> Apache Camel Committer
>
> Author of Camel in Action: http://www.manning.com/ibsen/
> Open Source Integration: http://fusesource.com
> Blog: http://davsclaus.blogspot.com/
> Twitter: http://twitter.com/davsclaus
>

Re: Testing consuming mail with attachments

Posted by Claus Ibsen <cl...@gmail.com>.
Now you change subject to sending an mail using camel-mail, and by
which you want to send it as a javax.mail.MimeMessage.
Is this correct?

If so why dont you just try to see if it works.
     template.send("smtp:xxx", myMimeMessage);

I haven't checked the source code of camel-mail, but it could be very
well that it can detect the MimeMessage type and use it as is.



On Thu, Mar 11, 2010 at 10:16 AM, Kevin Jackson <fo...@gmail.com> wrote:
> Hi,
>
>>> public void process(Exchange ex) throws Exception {
>>>        Map<String, DataHandler> attachments = ex.getIn().getAttachments();
>>>        if(attachments.size() > 0) {
>>>            //loop here but really only expect a single attachment
>>>            for(String name : attachments.keySet()) {
>>>                DataHandler dh = attachments.get(name);
>>>
>>>                String filename = dh.getName();
>>>                byte[] data =
>>> ex.getContext().getTypeConverter().convertTo(byte[].class,
>>> dh.getInputStream());
>>>                FileOutputStream fos = new
>>> FileOutputStream(getAttachmentPath()+filename);
>>>                fos.write(data);
>>>                fos.flush();
>>>                fos.close();
>>>            }
>>>        }
>>>    }
>>>
>> The bean parameter binding is what you would normally use to decouple
>> a POJO from Camel Exchange.
>> http://camel.apache.org/bean-binding.html
>> http://camel.apache.org/parameter-binding-annotations.html
>>
>>
>> But I can see it lacks a feature to binding attachements, so you can
>> do something like
>>
>> public void foo(@Attachments Map<String, DataHandler> myAttachments) {
>>  ..
>> }
>>
>> But it could probably also be done without the @Attachments annotation
>> as it can detect the types in the Map and see if its <String,
>> DataHandler> and then map that automatic to the attachments of the
>> Exchange. Anyone see a problem with this?
>
> I'm not sure I follow you here.
>
> I can use bean-binding annotations to mark a method in my pojo as a
> @Handler method, does this negate the need to use the marker interface
> Processor?
>
> The method signature suggests that the POJO would process Map<String
> DataHandler>, this would mean that some pre-processing would be
> required upstream to take the mime message and convert it into this
> format?
>
> If this is the case, then my route would become something like :
>
> from("direct:start").bean(MailProc.class).to("mock:result"), where MailProc is :
>
> @Handler
> public void proc(Map<String, DataHandler> attachments) throws Exception {
>
> }
>
> But when I kick this test off, I want to be using a programatically
> created MimeMessage, so will that get converted from MimeMessage into
> Map<String, DataHandler> attachments automatically due it being the
> body of the Exchange?
>
> In the camel mail unit tests:
>
> @Test
>    public void testSendAndRecieveMailWithAttachments() throws Exception {
>        // START SNIPPET: e1
>
>        // create an exchange with a normal body and attachment to be
> produced as email
>        Endpoint endpoint =
> context.getEndpoint("smtp://james@mymailserver.com?password=secret");
>
>        // create the exchange with the mail message that is multipart
> with a file and a Hello World text/plain message.
>        Exchange exchange = endpoint.createExchange();
>        Message in = exchange.getIn();
>        in.setBody("Hello World");
>        in.addAttachment("logo.jpeg", new DataHandler(new
> FileDataSource("src/test/data/logo.jpeg")));
>
>        // create a producer that can produce the exchange (= send the mail)
>        Producer producer = endpoint.createProducer();
>        // start the producer
>        producer.start();
>        // and let it go (processes the exchange by sending the email)
>        producer.process(exchange);
>
>        // END SNIPPET: e1
>
>        // need some time for the mail to arrive on the inbox
> (consumed and sent to the mock)
>        Thread.sleep(2000);
>
>        MockEndpoint mock = getMockEndpoint("mock:result");
>        mock.expectedMessageCount(1);
>        Exchange out = mock.assertExchangeReceived(0);
>        mock.assertIsSatisfied();
>
>        // plain text
>        assertEquals("Hello World", out.getIn().getBody(String.class));
>
>        // attachment
>        Map<String, DataHandler> attachments = out.getIn().getAttachments();
>        assertNotNull("Should have attachments", attachments);
>        assertEquals(1, attachments.size());
>
>        DataHandler handler = out.getIn().getAttachment("logo.jpeg");
>        assertNotNull("The logo should be there", handler);
>
>        assertEquals("image/jpeg; name=logo.jpeg", handler.getContentType());
>
>        producer.stop();
>    }
>
> This relies on Camel test classes and I would just like to be able to
> create a new MimeMessage and use direct:start to
> template.sendBody(attachmentEmail) rather than  rely on manually
> creating Exchanges etc
>
> Sorry to bother you but this is an interesting investigation from my side
> Kev
>



-- 
Claus Ibsen
Apache Camel Committer

Author of Camel in Action: http://www.manning.com/ibsen/
Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/
Twitter: http://twitter.com/davsclaus

Re: Testing consuming mail with attachments

Posted by Kevin Jackson <fo...@gmail.com>.
Hi,

>> public void process(Exchange ex) throws Exception {
>>        Map<String, DataHandler> attachments = ex.getIn().getAttachments();
>>        if(attachments.size() > 0) {
>>            //loop here but really only expect a single attachment
>>            for(String name : attachments.keySet()) {
>>                DataHandler dh = attachments.get(name);
>>
>>                String filename = dh.getName();
>>                byte[] data =
>> ex.getContext().getTypeConverter().convertTo(byte[].class,
>> dh.getInputStream());
>>                FileOutputStream fos = new
>> FileOutputStream(getAttachmentPath()+filename);
>>                fos.write(data);
>>                fos.flush();
>>                fos.close();
>>            }
>>        }
>>    }
>>
> The bean parameter binding is what you would normally use to decouple
> a POJO from Camel Exchange.
> http://camel.apache.org/bean-binding.html
> http://camel.apache.org/parameter-binding-annotations.html
>
>
> But I can see it lacks a feature to binding attachements, so you can
> do something like
>
> public void foo(@Attachments Map<String, DataHandler> myAttachments) {
>  ..
> }
>
> But it could probably also be done without the @Attachments annotation
> as it can detect the types in the Map and see if its <String,
> DataHandler> and then map that automatic to the attachments of the
> Exchange. Anyone see a problem with this?

I'm not sure I follow you here.

I can use bean-binding annotations to mark a method in my pojo as a
@Handler method, does this negate the need to use the marker interface
Processor?

The method signature suggests that the POJO would process Map<String
DataHandler>, this would mean that some pre-processing would be
required upstream to take the mime message and convert it into this
format?

If this is the case, then my route would become something like :

from("direct:start").bean(MailProc.class).to("mock:result"), where MailProc is :

@Handler
public void proc(Map<String, DataHandler> attachments) throws Exception {

}

But when I kick this test off, I want to be using a programatically
created MimeMessage, so will that get converted from MimeMessage into
Map<String, DataHandler> attachments automatically due it being the
body of the Exchange?

In the camel mail unit tests:

@Test
    public void testSendAndRecieveMailWithAttachments() throws Exception {
        // START SNIPPET: e1

        // create an exchange with a normal body and attachment to be
produced as email
        Endpoint endpoint =
context.getEndpoint("smtp://james@mymailserver.com?password=secret");

        // create the exchange with the mail message that is multipart
with a file and a Hello World text/plain message.
        Exchange exchange = endpoint.createExchange();
        Message in = exchange.getIn();
        in.setBody("Hello World");
        in.addAttachment("logo.jpeg", new DataHandler(new
FileDataSource("src/test/data/logo.jpeg")));

        // create a producer that can produce the exchange (= send the mail)
        Producer producer = endpoint.createProducer();
        // start the producer
        producer.start();
        // and let it go (processes the exchange by sending the email)
        producer.process(exchange);

        // END SNIPPET: e1

        // need some time for the mail to arrive on the inbox
(consumed and sent to the mock)
        Thread.sleep(2000);

        MockEndpoint mock = getMockEndpoint("mock:result");
        mock.expectedMessageCount(1);
        Exchange out = mock.assertExchangeReceived(0);
        mock.assertIsSatisfied();

        // plain text
        assertEquals("Hello World", out.getIn().getBody(String.class));

        // attachment
        Map<String, DataHandler> attachments = out.getIn().getAttachments();
        assertNotNull("Should have attachments", attachments);
        assertEquals(1, attachments.size());

        DataHandler handler = out.getIn().getAttachment("logo.jpeg");
        assertNotNull("The logo should be there", handler);

        assertEquals("image/jpeg; name=logo.jpeg", handler.getContentType());

        producer.stop();
    }

This relies on Camel test classes and I would just like to be able to
create a new MimeMessage and use direct:start to
template.sendBody(attachmentEmail) rather than  rely on manually
creating Exchanges etc

Sorry to bother you but this is an interesting investigation from my side
Kev

Re: Question about enrich pattern.

Posted by Claus Ibsen <cl...@gmail.com>.
On Thu, Mar 11, 2010 at 10:11 AM, ext2 <xu...@tongtech.com> wrote:
>
> Hi:
>        The camle's enrich pattern could be used to enrich the original
> message by a producer's result message.
>        And does the pattern support to enrich the original message by  a
> "customed route result"?
>        For example, it maybe looks liked as :
>                <enrich aggregation="enrichAggregator>
>                        <pipeline>
>                                ... some processes ..
>                        </pipeline>
>                </enrich>
>
>
>

You can use direct endpoint
http://camel.apache.org/direct

To use another Camel route as the "customized route result".





-- 
Claus Ibsen
Apache Camel Committer

Author of Camel in Action: http://www.manning.com/ibsen/
Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/
Twitter: http://twitter.com/davsclaus

Question about enrich pattern.

Posted by ext2 <xu...@tongtech.com>.
Hi:
	The camle's enrich pattern could be used to enrich the original
message by a producer's result message.
	And does the pattern support to enrich the original message by  a
"customed route result"?
	For example, it maybe looks liked as :
		<enrich aggregation="enrichAggregator>
			<pipeline>
				... some processes ..
			</pipeline>
		</enrich>



Re: Testing consuming mail with attachments

Posted by Claus Ibsen <cl...@gmail.com>.
On Thu, Mar 11, 2010 at 9:21 AM, Kevin Jackson <fo...@gmail.com> wrote:
> Hi,
>
> I have a requirement to take an email, consume it extract the
> attachment, then process the contents of the attachment.
>
> I have the processing completed, but I cannot find an elegant method
> of testing the mail attachment handling.  The documentation seems to
> require that my processing is coupled to Camel, I would prefer to use
> a simple bean rather than a Processor implementation.
>
> The canonical example of handling mail attachments is similar to :
>
> public void process(Exchange ex) throws Exception {
>        Map<String, DataHandler> attachments = ex.getIn().getAttachments();
>        if(attachments.size() > 0) {
>            //loop here but really only expect a single attachment
>            for(String name : attachments.keySet()) {
>                DataHandler dh = attachments.get(name);
>
>                String filename = dh.getName();
>                byte[] data =
> ex.getContext().getTypeConverter().convertTo(byte[].class,
> dh.getInputStream());
>                FileOutputStream fos = new
> FileOutputStream(getAttachmentPath()+filename);
>                fos.write(data);
>                fos.flush();
>                fos.close();
>            }
>        }
>    }
>
> Unfortunately this means that my mail processing is camel specific -
> I'd rather be able to handle MimeMessage instead of Exchange and be
> completely free of a camel dependency so that I can test the handling
> of mail independently.  However other code for handling mail
> attachments seems to be needlessly complex.  Right now i have a choice
> between short relatively simple code that cannot be tested to my
> satisfaction, or writing much more complex code that I can test
> without tight coupling to the camel code.  Neither solution smells
> right and neither is particularly nice.
>
> Has anyone else come across this problem?
>
> Thanks,
> Kev
>

The bean parameter binding is what you would normally use to decouple
a POJO from Camel Exchange.
http://camel.apache.org/bean-binding.html
http://camel.apache.org/parameter-binding-annotations.html


But I can see it lacks a feature to binding attachements, so you can
do something like

public void foo(@Attachments Map<String, DataHandler> myAttachments) {
  ..
}

But it could probably also be done without the @Attachments annotation
as it can detect the types in the Map and see if its <String,
DataHandler> and then map that automatic to the attachments of the
Exchange. Anyone see a problem with this?




-- 
Claus Ibsen
Apache Camel Committer

Author of Camel in Action: http://www.manning.com/ibsen/
Open Source Integration: http://fusesource.com
Blog: http://davsclaus.blogspot.com/
Twitter: http://twitter.com/davsclaus