Reputation: 14782
import static java.lang.System.out;
import org.apache.camel.ExchangePattern;
import org.apache.camel.Message;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
class RequestReplyMessageSample {
class Replier {
String reply( final String /*Message*/ /*Exchange*/ request ) {
out.println( "\n[ERROR] Expected: 'Re'quest', Actual: " + request
+ " <-- Am I doing somethig wrong, is this a bug or a feature?\n" );
return String.format( "**** Replying to %s ****%n", request/*.getMessage()*/ /*.getBody( String.class )*/ );
}
} // Replier
private static final DefaultCamelContext cc = new DefaultCamelContext();
public static void main( final String... args ) throws Exception {
final Replier replier = new RequestReplyMessageSample().new Replier();
cc.setName( "Request Reply Sample" );
cc.addRoutes( new RouteBuilder() {
@Override
public void configure() {
from( "timer:start?repeatCount=1" )
.setExchangePattern( ExchangePattern.InOut )
.process().message( m -> m.setBody( "'Re'quest'" ) ) // EIP Request
.process().message( m -> print( "Request", m ) )
.log( "Requesting..." )
.log( "Replying..." )
// How to get Message (or Exchange) as argument in here?
.bean( replier, "reply(${body})" ) // EIP Requestor/Replier
.process().message( m -> print( "Reply", m ) ) // EIP Reply (in the body of the Message)
.setId( "Request/Reply" );
}
} );
cc.start();
Thread.sleep( 2000 );
cc.stop();
cc.close();
} // main()
static void print( final String endpoint, final Message m ) {
out.printf( "%s %s: %s%n", endpoint, m, m.getBody() );
} // print()
} // RequestReplyMessageSample
...
Request Message: 'Re'quest'
[ple) thread #1 - timer://start] Request/Reply INFO Requesting...
[ple) thread #1 - timer://start] Request/Reply INFO Replying...
[ERROR] Expected: 'Re'quest', Actual: Re'quest <-- Am I doing somethig wrong, is this a bug or a feature?
Reply Message: **** Replying to Re'quest ****
...
Upvotes: 0
Views: 677
Reputation: 7035
This is because the body is passed as explicit method parameter to the bean.
The single quotes are preserved in the following scenarios:
.setBody
) as constant.setBody
) as expressionOnly when the body is passed explicitly to a bean method, the quotes are interpreted as string literal boundaries.
.bean(new EchoBean(), "echoBody(${body})")
becomes in your case
.bean(new EchoBean(), "echoBody('Re'quest')")
You can try this test class (Camel 3, JUnit 5). It fails because the quotes are lost in the last bean call with explicit parameters.
package test.camel;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.test.junit5.CamelTestSupport;
import org.junit.jupiter.api.Test;
class QuoteTest extends CamelTestSupport {
public static final String MOCK_OUTPUT = "mock:output";
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
from( "direct:start" )
.log("Reveived body: ${body}")
.setBody(constant("'Re'quest'"))
.log("Body overwritten in route: ${body}")
.bean(new EchoBean())
.log("Body overwritten through bean: ${body}")
.process().message( m -> m.setBody( "'Re'quest'" ) )
.log("Body overwritten through processor: ${body}")
.bean(new EchoBean(), "echoBody(${body})")
.log("Body overwritten through bean with methodparameter: ${body}")
.to(MOCK_OUTPUT);
}
};
}
@Test
void routeTest_quoteHandling_processed() throws Exception {
getMockEndpoint(MOCK_OUTPUT).expectedBodiesReceived("'Re'quest'");
template.requestBody("direct:start", "'Re'quest'");
assertMockEndpointsSatisfied();
}
static class EchoBean {
public String echoBody(final String messageBody) {
System.out.println("Expected: 'Re'quest', Actual: " + messageBody);
return messageBody;
}
}
}
It produces the following output. As you can see, the quotes are preserved through all steps except the last bean call with explicit parameter passing
09:00:53.521 [main] INFO route1 - Reveived body: 'Re'quest'
09:00:53.521 [main] INFO route1 - Body overwritten in route: 'Re'quest'
Expected: 'Re'quest', Actual: 'Re'quest'
09:00:53.527 [main] INFO route1 - Body overwritten through bean: 'Re'quest'
09:00:53.527 [main] INFO route1 - Body overwritten through processor: 'Re'quest'
Expected: 'Re'quest', Actual: Re'quest <<-- only when the body is passed as method parameter, the quotes are lost
09:00:53.529 [main] INFO route1 - Body overwritten through bean with methodparameter: Re'quest
Upvotes: 1
Reputation: 777
It's a feature. In this case, the single quotes at the start/end of the expression are interpreted as a string literal start/end. You need to add another single quote to let the parser see it as character (i.e. m.setBody("''Re'quest''")
).
Upvotes: 2