You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by ra...@centrum.cz on 2013/10/01 11:25:52 UTC

Bean component/Bean Binding: Body as InputStream parametr (specified as ${body} in route)

Hello,
I am playing with "bean binding" on bean component. I know, that I can solve my requirements by another way. 
But anyway I think, that my "syntetic" example doesn't work how I expect (I tested it with Camel 2.11.2, 2.12.1).

I have a "streamBodyBindingBean" bean with this method:

public void bodyBinding(InputStream in) throws IOException {
  int byteCount = 0;
  int c;
  while((c = in.read()) != -1)
    byteCount++;
  System.out.println("ByteCount: " + byteCount);
}

And this route:

<route id="" trace="true">
  <from uri="direct://body-input-stream-binding-in"/>
  <to uri="bean://streamBodyBindingBean?method=bodyBinding(${body})"/>
  <!-- to uri="bean://isBodyBindingBean"/-->
  <to uri="mock://body-input-stream-binding-out"/>
</route>

Here is a way how I send exchange from test stuff:

ByteArrayInputStream in = new ByteArrayInputStream(
  "Small body, which I want to bind as InputStream".getBytes("UTF-8")
);
Exchange exchange = createExchangeWithBody(in);
exchange.getIn().setHeader("testHeader", "testHeader");
exchange.setPattern(ExchangePattern.InOnly);
template.send("direct://body-input-stream-binding-in", exchange);

In this case I got a sysout message: "ByteCount: 0".
When I used the commented variant in route, I got expected result: "ByteCount: 47",  => is it an ${body} evaluation problem?

I think that the reason is MethodInfo class, line 526 (with strange comment for me):

// the parameter value was not already valid, but since the simple language have evaluated the expression
// which may change the parameterValue, so we have to check it again to see if its now valid
exp = exchange.getContext().getTypeConverter().convertTo(String.class, parameterValue);
// String values from the simple language is always valid
if (!valid) {
  ...
}

The line after "strange" comment caused that my "InputStream" is transformed into String (what can be a problem in case of "big" InputStream).
The question is, why this line isn't in "if(!valid)" block? I am unable to decide, if it is a problem, which should be reported to JIRA or 
I only don't understand how bean binding should work or if I have only "stupid/incorrect" example.

This i a reason, why I ask first here.

Thank you for any feedback.
Radek Kraus.

Re: Bean component/Bean Binding: Body as InputStream parametr (specified as ${body} in route)

Posted by ra...@centrum.cz.
Thanks for answer..

But IMHO it isn't  "stream-caching" problem. I have stream-caching enabled by "camel-context" attribute:
<camel:camelContext id="camelContext" ...streamCache="true" .../>

In addition, when I change the route, where I used bean component twice:
<route id="" trace="true">
  <from uri="direct://body-input-stream-binding-in"/>
  <to uri="bean://streamBodyBindingBean?method=bodyBinding(${body})"/>
  <to uri="bean://isBodyBindingBean"/>
  <to uri="mock://body-input-stream-binding-out"/>
</route>

I got this result:

2013-10-01 12:26:37.259 DEBUG {main} [SendProcessor] >>>> Endpoint[bean://isBodyBindingBean?method=bodyBinding%28%24%7Bbody%7D%29] Exchange[Message: [Body is instance of org.apache.camel.StreamCache]]
ByteCount: 0
2013-10-01 12:26:37.289 DEBUG {main} [SendProcessor] >>>> Endpoint[bean://isBodyBindingBean] Exchange[Message: [Body is instance of org.apache.camel.StreamCache]]
ByteCount: 47
2013-10-01 12:26:37.307 DEBUG {main} [SendProcessor] >>>> Endpoint[mock://body-input-stream-binding-out] Exchange[Message: [Body is instance of org.apache.camel.StreamCache]]

______________________________________________________________
> Od: Taariq Levack <ta...@gmail.com>
> Komu: <us...@camel.apache.org>
> Datum: 01.10.2013 11:43
> Předmět: Re: Bean component/Bean Binding: Body as InputStream parametr (specified as ${body} in route)
>
>Hi
>
>Looks like you're trying to read the stream twice, try again after enabling
>stream-caching[1]
>
>[1] http://camel.apache.org/stream-caching.html
>
>Taariq
>
>
>On Tue, Oct 1, 2013 at 11:25 AM, <ra...@centrum.cz> wrote:
>
>> Hello,
>> I am playing with "bean binding" on bean component. I know, that I can
>> solve my requirements by another way.
>> But anyway I think, that my "syntetic" example doesn't work how I expect
>> (I tested it with Camel 2.11.2, 2.12.1).
>>
>> I have a "streamBodyBindingBean" bean with this method:
>>
>> public void bodyBinding(InputStream in) throws IOException {
>>   int byteCount = 0;
>>   int c;
>>   while((c = in.read()) != -1)
>>     byteCount++;
>>   System.out.println("ByteCount: " + byteCount);
>> }
>>
>> And this route:
>>
>> <route id="" trace="true">
>>   <from uri="direct://body-input-stream-binding-in"/>
>>   <to uri="bean://streamBodyBindingBean?method=bodyBinding(${body})"/>
>>   <!-- to uri="bean://isBodyBindingBean"/-->
>>   <to uri="mock://body-input-stream-binding-out"/>
>> </route>
>>
>> Here is a way how I send exchange from test stuff:
>>
>> ByteArrayInputStream in = new ByteArrayInputStream(
>>   "Small body, which I want to bind as InputStream".getBytes("UTF-8")
>> );
>> Exchange exchange = createExchangeWithBody(in);
>> exchange.getIn().setHeader("testHeader", "testHeader");
>> exchange.setPattern(ExchangePattern.InOnly);
>> template.send("direct://body-input-stream-binding-in", exchange);
>>
>> In this case I got a sysout message: "ByteCount: 0".
>> When I used the commented variant in route, I got expected result:
>> "ByteCount: 47",  => is it an ${body} evaluation problem?
>>
>> I think that the reason is MethodInfo class, line 526 (with strange
>> comment for me):
>>
>> // the parameter value was not already valid, but since the simple
>> language have evaluated the expression
>> // which may change the parameterValue, so we have to check it again to
>> see if its now valid
>> exp = exchange.getContext().getTypeConverter().convertTo(String.class,
>> parameterValue);
>> // String values from the simple language is always valid
>> if (!valid) {
>>   ...
>> }
>>
>> The line after "strange" comment caused that my "InputStream" is
>> transformed into String (what can be a problem in case of "big"
>> InputStream).
>> The question is, why this line isn't in "if(!valid)" block? I am unable to
>> decide, if it is a problem, which should be reported to JIRA or
>> I only don't understand how bean binding should work or if I have only
>> "stupid/incorrect" example.
>>
>> This i a reason, why I ask first here.
>>
>> Thank you for any feedback.
>> Radek Kraus.
>>
>

Re: Bean component/Bean Binding: Body as InputStream parametr (specified as ${body} in route)

Posted by Taariq Levack <ta...@gmail.com>.
Hi

Looks like you're trying to read the stream twice, try again after enabling
stream-caching[1]

[1] http://camel.apache.org/stream-caching.html

Taariq


On Tue, Oct 1, 2013 at 11:25 AM, <ra...@centrum.cz> wrote:

> Hello,
> I am playing with "bean binding" on bean component. I know, that I can
> solve my requirements by another way.
> But anyway I think, that my "syntetic" example doesn't work how I expect
> (I tested it with Camel 2.11.2, 2.12.1).
>
> I have a "streamBodyBindingBean" bean with this method:
>
> public void bodyBinding(InputStream in) throws IOException {
>   int byteCount = 0;
>   int c;
>   while((c = in.read()) != -1)
>     byteCount++;
>   System.out.println("ByteCount: " + byteCount);
> }
>
> And this route:
>
> <route id="" trace="true">
>   <from uri="direct://body-input-stream-binding-in"/>
>   <to uri="bean://streamBodyBindingBean?method=bodyBinding(${body})"/>
>   <!-- to uri="bean://isBodyBindingBean"/-->
>   <to uri="mock://body-input-stream-binding-out"/>
> </route>
>
> Here is a way how I send exchange from test stuff:
>
> ByteArrayInputStream in = new ByteArrayInputStream(
>   "Small body, which I want to bind as InputStream".getBytes("UTF-8")
> );
> Exchange exchange = createExchangeWithBody(in);
> exchange.getIn().setHeader("testHeader", "testHeader");
> exchange.setPattern(ExchangePattern.InOnly);
> template.send("direct://body-input-stream-binding-in", exchange);
>
> In this case I got a sysout message: "ByteCount: 0".
> When I used the commented variant in route, I got expected result:
> "ByteCount: 47",  => is it an ${body} evaluation problem?
>
> I think that the reason is MethodInfo class, line 526 (with strange
> comment for me):
>
> // the parameter value was not already valid, but since the simple
> language have evaluated the expression
> // which may change the parameterValue, so we have to check it again to
> see if its now valid
> exp = exchange.getContext().getTypeConverter().convertTo(String.class,
> parameterValue);
> // String values from the simple language is always valid
> if (!valid) {
>   ...
> }
>
> The line after "strange" comment caused that my "InputStream" is
> transformed into String (what can be a problem in case of "big"
> InputStream).
> The question is, why this line isn't in "if(!valid)" block? I am unable to
> decide, if it is a problem, which should be reported to JIRA or
> I only don't understand how bean binding should work or if I have only
> "stupid/incorrect" example.
>
> This i a reason, why I ask first here.
>
> Thank you for any feedback.
> Radek Kraus.
>

Re: Bean component/Bean Binding: Body as InputStream parametr (specified as ${body} in route)

Posted by Radek Kraus <ra...@centrum.cz>.
The JIRA issue was create https://issues.apache.org/jira/browse/CAMEL-6810.
Thanks for help.



--
View this message in context: http://camel.465427.n5.nabble.com/Bean-component-Bean-Binding-Body-as-InputStream-parametr-specified-as-body-in-route-tp5740656p5740741.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Bean component/Bean Binding: Body as InputStream parametr (specified as ${body} in route)

Posted by Radek Kraus <ra...@centrum.cz>.
Yes, I know it. It is enough to use second variant (the commented one) of
bean component binding. I have already used it. 
I want only to know if using of simple language (${body}) is a problem,
which should be fixed. I will create the JIRA ticket, how Claus suggested.

Thanks all for help.



--
View this message in context: http://camel.465427.n5.nabble.com/Bean-component-Bean-Binding-Body-as-InputStream-parametr-specified-as-body-in-route-tp5740656p5740738.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Bean component/Bean Binding: Body as InputStream parametr (specified as ${body} in route)

Posted by Taariq Levack <ta...@gmail.com>.
If you're not aware and you need a workaround and this suits your scenario,
you'll get the body as the InputStream if you don't use Simple.
ie <camel:to uri="bean://streamBodyBindingBean?method=bodyBinding"/>

Taariq


On Tue, Oct 1, 2013 at 9:35 PM, Claus Ibsen <cl...@gmail.com> wrote:

> Hi
>
> Yeah sounds like a bug. Do you mind logging a JIRA ticket?
>
> On Tue, Oct 1, 2013 at 11:25 AM,  <ra...@centrum.cz> wrote:
> > Hello,
> > I am playing with "bean binding" on bean component. I know, that I can
> solve my requirements by another way.
> > But anyway I think, that my "syntetic" example doesn't work how I expect
> (I tested it with Camel 2.11.2, 2.12.1).
> >
> > I have a "streamBodyBindingBean" bean with this method:
> >
> > public void bodyBinding(InputStream in) throws IOException {
> >   int byteCount = 0;
> >   int c;
> >   while((c = in.read()) != -1)
> >     byteCount++;
> >   System.out.println("ByteCount: " + byteCount);
> > }
> >
> > And this route:
> >
> > <route id="" trace="true">
> >   <from uri="direct://body-input-stream-binding-in"/>
> >   <to uri="bean://streamBodyBindingBean?method=bodyBinding(${body})"/>
> >   <!-- to uri="bean://isBodyBindingBean"/-->
> >   <to uri="mock://body-input-stream-binding-out"/>
> > </route>
> >
> > Here is a way how I send exchange from test stuff:
> >
> > ByteArrayInputStream in = new ByteArrayInputStream(
> >   "Small body, which I want to bind as InputStream".getBytes("UTF-8")
> > );
> > Exchange exchange = createExchangeWithBody(in);
> > exchange.getIn().setHeader("testHeader", "testHeader");
> > exchange.setPattern(ExchangePattern.InOnly);
> > template.send("direct://body-input-stream-binding-in", exchange);
> >
> > In this case I got a sysout message: "ByteCount: 0".
> > When I used the commented variant in route, I got expected result:
> "ByteCount: 47",  => is it an ${body} evaluation problem?
> >
> > I think that the reason is MethodInfo class, line 526 (with strange
> comment for me):
> >
> > // the parameter value was not already valid, but since the simple
> language have evaluated the expression
> > // which may change the parameterValue, so we have to check it again to
> see if its now valid
> > exp = exchange.getContext().getTypeConverter().convertTo(String.class,
> parameterValue);
> > // String values from the simple language is always valid
> > if (!valid) {
> >   ...
> > }
> >
> > The line after "strange" comment caused that my "InputStream" is
> transformed into String (what can be a problem in case of "big"
> InputStream).
> > The question is, why this line isn't in "if(!valid)" block? I am unable
> to decide, if it is a problem, which should be reported to JIRA or
> > I only don't understand how bean binding should work or if I have only
> "stupid/incorrect" example.
> >
> > This i a reason, why I ask first here.
> >
> > Thank you for any feedback.
> > Radek Kraus.
>
>
>
> --
> Claus Ibsen
> -----------------
> Red Hat, Inc.
> Email: cibsen@redhat.com
> Twitter: davsclaus
> Blog: http://davsclaus.com
> Author of Camel in Action: http://www.manning.com/ibsen
>

Re: Bean component/Bean Binding: Body as InputStream parametr (specified as ${body} in route)

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

Yeah sounds like a bug. Do you mind logging a JIRA ticket?

On Tue, Oct 1, 2013 at 11:25 AM,  <ra...@centrum.cz> wrote:
> Hello,
> I am playing with "bean binding" on bean component. I know, that I can solve my requirements by another way.
> But anyway I think, that my "syntetic" example doesn't work how I expect (I tested it with Camel 2.11.2, 2.12.1).
>
> I have a "streamBodyBindingBean" bean with this method:
>
> public void bodyBinding(InputStream in) throws IOException {
>   int byteCount = 0;
>   int c;
>   while((c = in.read()) != -1)
>     byteCount++;
>   System.out.println("ByteCount: " + byteCount);
> }
>
> And this route:
>
> <route id="" trace="true">
>   <from uri="direct://body-input-stream-binding-in"/>
>   <to uri="bean://streamBodyBindingBean?method=bodyBinding(${body})"/>
>   <!-- to uri="bean://isBodyBindingBean"/-->
>   <to uri="mock://body-input-stream-binding-out"/>
> </route>
>
> Here is a way how I send exchange from test stuff:
>
> ByteArrayInputStream in = new ByteArrayInputStream(
>   "Small body, which I want to bind as InputStream".getBytes("UTF-8")
> );
> Exchange exchange = createExchangeWithBody(in);
> exchange.getIn().setHeader("testHeader", "testHeader");
> exchange.setPattern(ExchangePattern.InOnly);
> template.send("direct://body-input-stream-binding-in", exchange);
>
> In this case I got a sysout message: "ByteCount: 0".
> When I used the commented variant in route, I got expected result: "ByteCount: 47",  => is it an ${body} evaluation problem?
>
> I think that the reason is MethodInfo class, line 526 (with strange comment for me):
>
> // the parameter value was not already valid, but since the simple language have evaluated the expression
> // which may change the parameterValue, so we have to check it again to see if its now valid
> exp = exchange.getContext().getTypeConverter().convertTo(String.class, parameterValue);
> // String values from the simple language is always valid
> if (!valid) {
>   ...
> }
>
> The line after "strange" comment caused that my "InputStream" is transformed into String (what can be a problem in case of "big" InputStream).
> The question is, why this line isn't in "if(!valid)" block? I am unable to decide, if it is a problem, which should be reported to JIRA or
> I only don't understand how bean binding should work or if I have only "stupid/incorrect" example.
>
> This i a reason, why I ask first here.
>
> Thank you for any feedback.
> Radek Kraus.



-- 
Claus Ibsen
-----------------
Red Hat, Inc.
Email: cibsen@redhat.com
Twitter: davsclaus
Blog: http://davsclaus.com
Author of Camel in Action: http://www.manning.com/ibsen