Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apache-camel: Enabling bridgeEndpoint on the http endpoint

I created a simple route to get contact from a remote host. But, there seems to be a lot of confusion regarding the bridgeEndpoint option.

Initially, I added the route using the Java DSL as follows:

        from("direct:getContact")
                .marshal().json(JsonLibrary.Jackson)
                .setHeader("Content-Type", constant("application/json"))
                .setHeader("Accept", constant("application/json"))
                .setHeader(Exchange.HTTP_METHOD, constant("GET"))
                .recipientList(simple("http://<remoteHost>:8080/api/contact" +
                        "/${header.contactId}"))
                .unmarshal().json(JsonLibrary.Jackson);

This route is just a proxy for the get contact API of the remote host. I got the following error:

Invalid uri: /ib/contact/51702/contact/51702. If you are forwarding/bridging http endpoints, then enable the bridgeEndpoint option on the endpoint: Endpoint[http://<remoteHost>:8080/api/contact/51702]

/ib/* you see is the base url for the tomcat servlet. As suggested in the error, I added the bridgeEndpoint=true to the endpoint as shown below:

        from("direct:getContact")
                .marshal().json(JsonLibrary.Jackson)
                .setHeader("Content-Type", constant("application/json"))
                .setHeader("Accept", constant("application/json"))
                .setHeader(Exchange.HTTP_METHOD, constant("GET"))
                .recipientList(simple("http://<remoteHost>:8080/api/contact" +
                        "/${header.contactId}?bridgeEndpoint=true"))
                .unmarshal().json(JsonLibrary.Jackson);

Then, I get a different error:

org.apache.camel.component.http.HttpOperationFailedException: 
HTTP operation failed invoking 
http://<remoteHost>:8080/api/contact/51702/contact/51702 with statusCode: 404
at org.apache.camel.component.http.HttpProducer.populateHttpOperationFailedException(HttpProducer.java:233)
at org.apache.camel.component.http.HttpProducer.process(HttpProducer.java:158)
at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:448)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:190)
at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:652)
at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:580)
at org.apache.camel.processor.MulticastProcessor.process(MulticastProcessor.java:227)
at org.apache.camel.processor.RecipientList.sendToRecipientList(RecipientList.java:167)
at org.apache.camel.processor.RecipientList.process(RecipientList.java:120)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:118)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)

It is still appending "contact/51702" to the url of the remote host, which is giving 404. What am I missing here?

like image 917
ndsurendra Avatar asked Jun 02 '16 08:06

ndsurendra


2 Answers

From the FAQ

In camel there are a number of components that use the http protocol headers to do their business.

I believe your producer does it as well. So the following could solve your problem.

from("direct:getContact")
    .marshal().json(JsonLibrary.Jackson)
    .setHeader("Content-Type", constant("application/json"))
    .setHeader("Accept", constant("application/json"))
    .setHeader(Exchange.HTTP_METHOD, constant("GET"))
    .removeHeader(Exchange.HTTP_PATH)
    .recipientList(simple("http://<remoteHost>:8080/api/contact" +
        "/${header.contactId}?bridgeEndpoint=true"))
    .unmarshal().json(JsonLibrary.Jackson);

You could also remove contact/${header.contactId} from the endpoint. As it looks redundant. But this depends on what you want to achieve.

like image 198
SubOptimal Avatar answered Oct 13 '22 11:10

SubOptimal


Answer by @SubOptimal is almost correct, except it should be HTTP_URI header. From the doc:

If the bridgeEndpoint option is true, HttpProducer will ignore the Exchange.HTTP_URI header, and use the endpoint’s URI for request.

Therefore there are 2 solutions:

  1. add .removeHeader(Exchange.HTTP_URI) to the route definition
  2. add ?bridgeEndpoint=true query parameter

However this might not solve the problem if you have other headers that get in the way. Probably that was your case, that's why removing all Camel http headers helped.

Please be aware though that removing all headers might break your logic: for example HTTP_METHOD header is used to define the http method of the outgoing request. And it's up to you if you want to proxy the method too or not. You can find more in the same doc via the link above.

like image 34
Innokenty Avatar answered Oct 13 '22 11:10

Innokenty