Found a workaround by accessing the type converter registry as follows:

Object body = originalMessage.getBody();
TypeConverterRegistry reg = getContext().getTypeConverterRegistry();
TypeConverter converter = reg.lookup(String.class,body.getClass());
if (converter != null) {
  String str = converter.convertTo(String.class,body);
  System.out.println("Converted: " + str);
}
else {
  System.out.println("No converter found");
}

This seems to work although I still thinks the original message handling is
a bit "fishy".

/Bengt


2014-03-12 21:00 GMT+01:00 Bengt Rodehav <[email protected]>:

> BTW, while debugging I noticed another difference between the current
> message (retrieved by the getIn() method) and the original message. When
> comparing the message headers, the original message lacks the header
> "breadcrumbId". This probably isn't related but it seems strange that it is
> omitted.
>
> Note that the value of "breadcrumbId" seems to be the same as the
> messageId which in turn is the same for the current message and the
> original message.
>
> /Bengt
>
>
> 2014-03-12 20:49 GMT+01:00 Bengt Rodehav <[email protected]>:
>
> I've now done some debugging to see what actually happens. It turns out
>> that both the variable "message" and the variable "originalMessage" are of
>> type GenericFileMessage. It turns out that the "message" has an exchange
>> set to its "exchange" property while the "originalMessage" does not (i e
>> originalMessage.getExchange() returns null).
>>
>> This makes all the difference when looking at the base class
>> "MessageSupport". The type conversion ends up in the method
>> MessageSupport.getBody() method and it looks like this:
>>
>>     protected <T> T getBody(Class<T> type, Object body) {
>>         // eager same instance type test to avoid the overhead of
>> invoking the type converter
>>         // if already same type
>>         if (type.isInstance(body)) {
>>             return type.cast(body);
>>         }
>>
>>         Exchange e = getExchange();
>>         if (e != null) {
>>             TypeConverter converter = e.getContext().getTypeConverter();
>>
>>             // lets first try converting the body itself first
>>             // as for some types like InputStream v Reader its more
>> efficient to do the transformation
>>             // from the body itself as its got efficient implementations
>> of them, before trying the message
>>             T answer = converter.convertTo(type, e, body);
>>             if (answer != null) {
>>                 return answer;
>>             }
>>
>>             // fallback and try the message itself (e.g. used in
>> camel-http)
>>             answer = converter.tryConvertTo(type, e, this);
>>             if (answer != null) {
>>                 return answer;
>>             }
>>         }
>>
>>         // not possible to convert
>>         return null;
>>     }
>>
>> Thus, since now exchange is attached to the message this method always
>> returns null.
>>
>> If I change my code snippet to:
>>
>> ...
>> Message originalMessage =
>> theExchange.getUnitOfWork().getOriginalInMessage();
>> GenericFileMessage gfm =
>> (GenericFileMessage)originalMessage;gfm.setExchange(theExchange);
>> ...
>>
>> Then everything works. However, this is not a possible workaround for me.
>> I need this code to be generic and I can only access the Message interface.
>>
>> I'm not sure if it's by design that the originalMessage is not attached
>> to an exchange or not. I guess it could be. But then how can I, in a
>> generic way, convert the body to a string?
>>
>> /Bengt
>>
>>
>>
>> 2014-03-12 19:06 GMT+01:00 Bengt Rodehav <[email protected]>:
>>
>> I did the following:
>>>
>>> - Downloaded the zip file for Camel 2.12.3 (binary distribution)
>>>
>>> - Added two java files to the example project "camel-example-ftp". The
>>> files are called MyFileClient.java and MyFileClientRouteBuilder.java. Their
>>> contents is embedded at the end of this mail.
>>>
>>> - I started MyFileClient and dropped a file in the "target/in" directory.
>>>
>>> - I get the exact same result as I described in my earlier post. I
>>> cannot access the body contents of the original message.
>>>
>>> Is this as designed or is it a bug (or have I misunderstood)?
>>>
>>> /Bengt
>>>
>>> *MyFileClient.java*
>>> package org.apache.camel.example.ftp;
>>>
>>> import org.apache.camel.main.Main;
>>>
>>> public final class MyFileClient {
>>>
>>> private MyFileClient() {
>>>  }
>>>
>>> public static void main(String[] args) throws Exception {
>>> Main main = new Main();
>>>  main.addRouteBuilder(new MyFileClientRouteBuilder());
>>> main.enableHangupSupport();
>>> main.run();
>>>  }
>>> }
>>>
>>>
>>> *MyFileClientRouteBuilder.java*
>>> package org.apache.camel.example.ftp;
>>>
>>> import org.apache.camel.Exchange;
>>> import org.apache.camel.Message;
>>> import org.apache.camel.Processor;
>>> import org.apache.camel.builder.RouteBuilder;
>>>
>>> public class MyFileClientRouteBuilder extends RouteBuilder {
>>>
>>> @Override
>>> public void configure() throws Exception {
>>> // lets shutdown faster in case of in-flight messages stack up
>>>  getContext().getShutdownStrategy().setTimeout(10);
>>>
>>> from("file:target/in").streamCaching().process(new Processor() {
>>>    public void process(Exchange theExchange) {
>>>   Message originalMessage =
>>> theExchange.getUnitOfWork().getOriginalInMessage();
>>>   System.out.println("Original message: " + originalMessage);
>>>   System.out.println("Original body: " + originalMessage.getBody());
>>>   System.out.println("Original body as string: " +
>>> originalMessage.getBody(String.class));
>>>
>>>   Message message = theExchange.getIn();
>>>   System.out.println("Message: " + message);
>>>   System.out.println("Body: " + message.getBody());
>>>   System.out.println("Body as string: " +
>>> message.getBody(String.class));
>>>   }
>>> });
>>>  }
>>> }
>>>
>>>
>>>
>>> 2014-03-12 16:51 GMT+01:00 Bengt Rodehav <[email protected]>:
>>>
>>> Thanks for your reply Claus.
>>>>
>>>> I changed my code to:
>>>>
>>>> from("file:in").streamcaching().process(new Processor() {
>>>>   public void process(Exchange theExchange) {
>>>>   Message originalMessage =
>>>> theExchange.getUnitOfWork().getOriginalInMessage();
>>>>   System.out.println(originalMessage); // 1
>>>>   System.out.println("Body: " + originalMessage.getBody()); // 2
>>>>   System.out.println("Body as string: " +
>>>> originalMessage.getBody(String.class)); // 3
>>>>   }
>>>> });
>>>>
>>>> Unfortunately this makes no difference - I get the same result.
>>>>
>>>> Also, if I skip Step #2 above I still get "Body as string: null"  at
>>>> step #3 so I don't think I'm reeading the body twice.
>>>>
>>>> /Bengt
>>>>
>>>>
>>>>
>>>> 2014-03-12 16:34 GMT+01:00 Claus Ibsen <[email protected]>:
>>>>
>>>> Hi
>>>>>
>>>>> No its streams playing tricks on you
>>>>> http://camel.apache.org/why-is-my-message-body-empty.html
>>>>>
>>>>> So you get the body 2 times (at #2 and #3) and the 2nd time its empty.
>>>>>
>>>>> On Wed, Mar 12, 2014 at 4:29 PM, Bengt Rodehav <[email protected]>
>>>>> wrote:
>>>>> > I'm using Camel 2.12.1.
>>>>> >
>>>>> > For error handling purposes I need access to the original message
>>>>> but I'm
>>>>> > having problems with that.
>>>>> >
>>>>> > In my error handler I do this:
>>>>> >
>>>>> >   Message originalMessage =
>>>>> > theExchange.getUnitOfWork().getOriginalInMessage();
>>>>> >   System.out.println(originalMessage); // 1
>>>>> >   System.out.println("Body: " + originalMessage.getBody()); // 2
>>>>> >   System.out.println("Body as string: " +
>>>>> > originalMessage.getBody(String.class)); // 3
>>>>> >
>>>>> > The output at "1" is:
>>>>> >
>>>>> > TradeSet.xml
>>>>> >
>>>>> > The output at "2" is:
>>>>> >
>>>>> > Body:
>>>>> >
>>>>> GenericFile[C:\dev\karaf\connect-sts\head\apache-karaf2.3.4\bin\..\..\..\common\data\interfaces\ts2so\TradeSet.xml]
>>>>> >
>>>>> > The output at "3" is:
>>>>> >
>>>>> > Body as string: null
>>>>> >
>>>>> > I can reproduce this problem with a simple route that just uses the
>>>>> file
>>>>> > component. Something like this:
>>>>> >
>>>>> > from("file:in").process(new Processor() {
>>>>> >   public void process(Exchange theExchange) {
>>>>> >   Message originalMessage =
>>>>> > theExchange.getUnitOfWork().getOriginalInMessage();
>>>>> >   System.out.println(originalMessage); // 1
>>>>> >   System.out.println("Body: " + originalMessage.getBody()); // 2
>>>>> >   System.out.println("Body as string: " +
>>>>> > originalMessage.getBody(String.class)); // 3
>>>>> >   }
>>>>> > });
>>>>> >
>>>>> >
>>>>> > Thus it seems like I can access the original message but I can't get
>>>>> the
>>>>> > actual body content - at least not as a string. In my case the file
>>>>> > contains an xml document that I need to get hold of. Is this a known
>>>>> bug or
>>>>> > have I misunderstood the purpose with the getOriginalMessage()
>>>>> method?
>>>>> >
>>>>> > /Bengt
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Claus Ibsen
>>>>> -----------------
>>>>> Red Hat, Inc.
>>>>> Email: [email protected]
>>>>> Twitter: davsclaus
>>>>> Blog: http://davsclaus.com
>>>>> Author of Camel in Action: http://www.manning.com/ibsen
>>>>> Make your Camel applications look hawt, try: http://hawt.io
>>>>>
>>>>
>>>>
>>>
>>
>

Reply via email to