You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by mhi_inc <mi...@michaelhoffmaninc.com> on 2016/05/18 15:33:49 UTC

How Can I Get the Camel Content Enricher to Process an Exchange from a REST Call?

I'm building a sample implementation that routes orders to an order
management system. Inbound to the route is an exchange with two identifiers,
one for the customer ID and one for the catalog item ID. I then transform
the body the inbound exchange to my Order domain object. My goal is then to
call the content enricher pattern, once to aggregate data from the customer
and one to aggregate data from the catalog item.

My route is:

 @Override
   public void configure() {
      // Start by building an instance of RestConfigurationDefinition. Need
to
      // specify the component we are going to use for enabling REST
endpoints,
      // specifically CamelServlet in this case. Set the binding mode to
JSON.
      restConfiguration().
            // Leverage the CamelServlet component for the REST DSL
            component("servlet").
            // Bind using JSON
            bindingMode(RestBindingMode.json).
            // I like pretty things...
            dataFormatProperty("prettyPrint", "true").
            // This is the context path to be used for Swagger API
documentation
            apiContextPath("api-doc").
            // Properties for Swagger
            // Title of the API
      apiProperty("api.title", "Order Management API").
            // Version of the API
            apiProperty("api.version", "1.0.0").
            // CORS (resource sharing) enablement
            apiProperty("cors", "true").
            // Use localhost for calls
            apiProperty("host", "localhost:8083").
            // Set base path
            apiProperty("base.path",
"nvisia-order-router-camel-service/api");

      // Definition of the post order endpoint
      rest("/orderRouter").
            // This is a POST method call for routing an order using the
            // order form
      post().
            // Description of what the method does
            description("Routes a new order to the order management
service").
            // Define the type used for input
            type(OrderForm.class).
            // Define the type used for output, in this case the order
            outType(String.class).
            // Next, define where the message is routed to, first
transformation
           
to("bean:orderRouterService?method=transformOrderFormToOrder(${body})")
            .to("direct:enrichOrder");

      // Definition of the enrich order endpoint
      from("direct:enrichOrder").
            // Use the Content Enricher EIP to aggregate customer info in
the
            // order.
      enrich(
           
"http4://localhost:8081/nvisia-customer-camel-service/api/customer/${body.customerId}",
            new AggregationStrategy() {
               @Override
               public Exchange aggregate(Exchange oldExchange, Exchange
newExchange) {
                  Order originalBody = (Order)
oldExchange.getIn().getBody();
                  Customer resourceResponse = (Customer)
newExchange.getIn().getBody();
                  originalBody.setCustomer(resourceResponse);
                  if (oldExchange.getPattern().isOutCapable()) {
                     oldExchange.getOut().setBody(originalBody);
                  } else {
                     oldExchange.getIn().setBody(originalBody);
                  }
                  return oldExchange;
               }
            }).
            // Use the Content Enricher EIP to aggregate catalog info in the
            // order.
      enrich(
           
"http4://localhost:8080/nvisia-catalog-camel-service/api/customer/${body.catalogItemId}",
            new AggregationStrategy() {
               @Override
               public Exchange aggregate(Exchange oldExchange, Exchange
newExchange) {
                  Order originalBody = (Order)
oldExchange.getIn().getBody();
                  CatalogItem resourceResponse = (CatalogItem)
newExchange.getIn()
                        .getBody();
                  originalBody.setCatalogItem(resourceResponse);
                  if (oldExchange.getPattern().isOutCapable()) {
                     oldExchange.getOut().setBody(originalBody);
                  } else {
                     oldExchange.getIn().setBody(originalBody);
                  }
                  return oldExchange;
               }
            }).to("direct:sendOrder");

      // Definition of the send order endpoint
      from("direct:sendOrder").
            // Need to define the content type on the header
            setHeader(org.apache.camel.Exchange.CONTENT_TYPE,
                  constant("application/json"))
            .
            // Be safe and define this as a post
            setHeader(Exchange.HTTP_METHOD,
                 
constant(org.apache.camel.component.http4.HttpMethods.POST))
            .
            // Finally, send the order to be managed and get back the order
ID
           
to("http4://localhost:8082/nvisia-order-management-camel-service/api/order");

The exception I get is:

org.apache.camel.InvalidPayloadException: No body available of type:
java.io.InputStream but has value: OrderForm [customerId=1, catalogItemId=1]
of type: com.nvisia.examples.camel.orderrouter.OrderForm on: Message[].
Caused by: No type converter available to convert from type:
com.nvisia.examples.camel.orderrouter.OrderForm to the required type:
java.io.InputStream with value OrderForm [customerId=1, catalogItemId=1].
Exchange[ID-nvisia-mhoffman-50981-1463522552963-0-8]. Caused by:
[org.apache.camel.NoTypeConversionAvailableException - No type converter
available to convert from type:
com.nvisia.examples.camel.orderrouter.OrderForm to the required type:
java.io.InputStream with value OrderForm [customerId=1, catalogItemId=1]]
    at
org.apache.camel.impl.MessageSupport.getMandatoryBody(MessageSupport.java:107)
    at
org.apache.camel.component.http4.HttpProducer.createRequestEntity(HttpProducer.java:523)
    at
org.apache.camel.component.http4.HttpProducer.createMethod(HttpProducer.java:422)
    at
org.apache.camel.component.http4.HttpProducer.process(HttpProducer.java:110)
    at
org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)
    at org.apache.camel.processor.Enricher.process(Enricher.java:187)
    at
org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
    at
org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:468)
    at
org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:121)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)
    at
org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
    at
org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:62)
    at
org.apache.camel.processor.SendProcessor.process(SendProcessor.java:145)
    at
org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
    at
org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:468)
    at
org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:121)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)
    at
org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
    at
org.apache.camel.util.AsyncProcessorHelper.process(AsyncProcessorHelper.java:109)
    at
org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:87)
    at
org.apache.camel.http.common.CamelServlet.service(CamelServlet.java:143)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
    at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at
org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration$ApplicationContextHeaderFilter.doFilterInternal(EndpointWebMvcAutoConfiguration.java:261)
    at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at
org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:115)
    at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at
org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
    at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at
org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87)
    at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at
org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
    at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
    at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at
org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:103)
    at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at
org.springframework.boot.context.web.ErrorPageFilter.doFilter(ErrorPageFilter.java:120)
    at
org.springframework.boot.context.web.ErrorPageFilter.access$000(ErrorPageFilter.java:61)
    at
org.springframework.boot.context.web.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:95)
    at
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at
org.springframework.boot.context.web.ErrorPageFilter.doFilter(ErrorPageFilter.java:113)
    at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:217)
    at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
    at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
    at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
    at
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
    at
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673)
    at
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
    at
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
    at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.apache.camel.NoTypeConversionAvailableException: No type
converter available to convert from type:
com.nvisia.examples.camel.orderrouter.OrderForm to the required type:
java.io.InputStream with value OrderForm [customerId=1, catalogItemId=1]
    at
org.apache.camel.impl.converter.BaseTypeConverterRegistry.mandatoryConvertTo(BaseTypeConverterRegistry.java:198)
    at
org.apache.camel.impl.MessageSupport.getMandatoryBody(MessageSupport.java:105)
    ... 79 more

Note I am using the latest camel, 2.17.1. My question is, if I am getting an
exchange where the body is in JSON format, how do I make the two content
enricher calls to get my Order bean populated? As I don't need to send an
input stream to either content enricher call, I considered having a
processor before each exchange, but I think it will get challenging with the
second aggregation to maintain the information from the first aggregation.
If this is not a recommended way to use the content enricher, please let me
know. 



--
View this message in context: http://camel.465427.n5.nabble.com/How-Can-I-Get-the-Camel-Content-Enricher-to-Process-an-Exchange-from-a-REST-Call-tp5782759.html
Sent from the Camel - Users mailing list archive at Nabble.com.