You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by owain <ow...@integration.technology> on 2017/05/25 12:24:47 UTC

Restoring body from header holding MyPojo works differently in test (with mock) than production

Camel 2.19.0

I have a route that saves the Pojo in the exchange body to a header, does an
enrich to another route and then restores the original body from the header.  

    from("direct:validate")
      .routeId("i4ip-ValidateOrder")
          .setBody().method(MyPojo.class, "validate(${headers})")
          .choice().id("valid-order")
              .when().simple("${body.getStatus()} == \"200\"")
                  .setHeader("myapp_mypojo").body()
                  .enrich("direct:assignReference").id("assignReference")
                  .setHeader("myapp_reference").body()
                  .setBody().simple("${header.myapp_mypojo}")
                  .log(LoggingLevel.INFO, "Body class: ${body.class}")
                  .transform().method(MyPojo.class,
"returnUpdatedReference(${body},${header.myapp_reference})").id("setReferenceInBody")
          .end()
         
.setHeader(Exchange.HTTP_RESPONSE_CODE).simple("${body.getStatus()}")
          .marshal().json(JsonLibrary.Jackson, true)

When testing I mock out the enrich just returning a string as follows:

    camelContext.getRouteDefinition(ROUTE_ID).adviceWith(camelContext, new
AdviceWithRouteBuilder() {
      @Override
      public void configure() throws Exception {
        replaceFromWith("direct:in");
        weaveById("assignReference").replace().inOut(MOCK_ENRICH);
        weaveAddLast().to(MOCK_OUT);
      }
    });

    MockEndpoint mockOut = camelContext.getEndpoint(MOCK_OUT,
MockEndpoint.class);
    MockEndpoint mockEnrich = camelContext.getEndpoint(MOCK_ENRICH,
MockEndpoint.class);

    mockEnrich.returnReplyBody(ConstantLanguage.constant(REFERENCE));

All works fine in this test as the body is restored correctly from the
header as can be seen this log message.

i4ip-ValidateOrder                       : Body class: class mydomain.MyPojo

However, when I run the Spring Boot application "properly" the class of the
body changes to:

i4ip-ValidateOrder                       : Body class: class
java.lang.String

which causes problems later in the route with a ParameterBindingException
when the transform().method(....) is invoked.

I am not sure where to look to find out what is causing this.

Thanks for your help.




--
View this message in context: http://camel.465427.n5.nabble.com/Restoring-body-from-header-holding-MyPojo-works-differently-in-test-with-mock-than-production-tp5800667.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Restoring body from header holding MyPojo works differently in test (with mock) than production

Posted by owain <ow...@integration.technology>.
Thanks Claus.

So the general rule appears to be  that do not rely on the class of headers
as the components may manipulate them.  So it looks as though MockEndpoint
leaves them alone whereas the enrich route changes the type from pojo to
string.

Quoting from the book:  

"Properties—Similar to message headers, but they last for the duration of
the entire exchange. Properties are used to contain global-level
information, whereas message headers are specific to a particular message.
Camel itself will add various properties to the exchange during routing.
You, as a developer, can store and retrieve properties at any point during
the lifetime of an exchange."

So a simple change to the route to this works a treat.

                  .setProperty("savemybody").body()
                  .inOut("direct:doSomething")
                  .setProperty("returnedBody").body()
                  .setBody().simple("${property.savemybody}")

O.




--
View this message in context: http://camel.465427.n5.nabble.com/Restoring-body-from-header-holding-MyPojo-works-differently-in-test-with-mock-than-production-tp5800667p5801330.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: Restoring body from header holding MyPojo works differently in test (with mock) than production

Posted by Claus Ibsen <cl...@gmail.com>.
Store the body in an exchange property instead of header.

See Camel in Action chapter 1 book for more details and background.

On Thu, May 25, 2017 at 2:24 PM, owain <ow...@integration.technology> wrote:
> Camel 2.19.0
>
> I have a route that saves the Pojo in the exchange body to a header, does an
> enrich to another route and then restores the original body from the header.
>
>     from("direct:validate")
>       .routeId("i4ip-ValidateOrder")
>           .setBody().method(MyPojo.class, "validate(${headers})")
>           .choice().id("valid-order")
>               .when().simple("${body.getStatus()} == \"200\"")
>                   .setHeader("myapp_mypojo").body()
>                   .enrich("direct:assignReference").id("assignReference")
>                   .setHeader("myapp_reference").body()
>                   .setBody().simple("${header.myapp_mypojo}")
>                   .log(LoggingLevel.INFO, "Body class: ${body.class}")
>                   .transform().method(MyPojo.class,
> "returnUpdatedReference(${body},${header.myapp_reference})").id("setReferenceInBody")
>           .end()
>
> .setHeader(Exchange.HTTP_RESPONSE_CODE).simple("${body.getStatus()}")
>           .marshal().json(JsonLibrary.Jackson, true)
>
> When testing I mock out the enrich just returning a string as follows:
>
>     camelContext.getRouteDefinition(ROUTE_ID).adviceWith(camelContext, new
> AdviceWithRouteBuilder() {
>       @Override
>       public void configure() throws Exception {
>         replaceFromWith("direct:in");
>         weaveById("assignReference").replace().inOut(MOCK_ENRICH);
>         weaveAddLast().to(MOCK_OUT);
>       }
>     });
>
>     MockEndpoint mockOut = camelContext.getEndpoint(MOCK_OUT,
> MockEndpoint.class);
>     MockEndpoint mockEnrich = camelContext.getEndpoint(MOCK_ENRICH,
> MockEndpoint.class);
>
>     mockEnrich.returnReplyBody(ConstantLanguage.constant(REFERENCE));
>
> All works fine in this test as the body is restored correctly from the
> header as can be seen this log message.
>
> i4ip-ValidateOrder                       : Body class: class mydomain.MyPojo
>
> However, when I run the Spring Boot application "properly" the class of the
> body changes to:
>
> i4ip-ValidateOrder                       : Body class: class
> java.lang.String
>
> which causes problems later in the route with a ParameterBindingException
> when the transform().method(....) is invoked.
>
> I am not sure where to look to find out what is causing this.
>
> Thanks for your help.
>
>
>
>
> --
> View this message in context: http://camel.465427.n5.nabble.com/Restoring-body-from-header-holding-MyPojo-works-differently-in-test-with-mock-than-production-tp5800667.html
> Sent from the Camel - Users mailing list archive at Nabble.com.



-- 
Claus Ibsen
-----------------
http://davsclaus.com @davsclaus
Camel in Action 2: https://www.manning.com/ibsen2