1
votes

I'm using the exchange headers to store any variables in the route. But, looks like these headers will be carried on to the other routes which are called from this route.

In the below sample, I'm calling a getContact route which will call a http endpoint. But, it will also send the headers, variable1 & variable2, it got from the initial route, direct:start.

    from("direct:start")
            .setHeader("variable1", constant("value1"))
            .setHeader("variable2", constant("value2"))
            .to("direct:getContact");

    from("direct:getContact")
            .setHeader("Content-Type", constant("application/json"))
            .setHeader("Accept", constant("application/json"))
            .setHeader(Exchange.HTTP_METHOD, constant("GET"))
            .to("http://<host>:<port>/contact/3")
            .unmarshal().json(JsonLibrary.Jackson);

Is there a way to avoid this? In contrast, a method call in java will hide all the existing variables by context switch.

3

3 Answers

1
votes

I've run into the problem before when sending a webservice call using http4. Tt's rather annoying that Camel seems to send send the entire exchange when you're using the http4/http endpoint. I got around this by using a content enricher. I placed the actual call using http4 in the enrich route and had an simple aggregation strategy combine the two messages afterwards.

Alternatively, you can make the call in a bean. This way you lose some of the benefits of camel but you have complete control over the call body.

1
votes

There is no direct way to avoid this. If you are setting the headers to a hard-coded value then you might be able to move the header to a URI property on your endpoint. If not then you only really have 2 other options. The first option is to remove all of the headers using a remove header call after your HTTP call so they don't go downstream. The second is to set all of the headers in the same route as the http call and have a different route call that endpoint with an enrich statement and in the aggregation back to the main route you can customize the returned exchange.

Here is an camel http reference page for all of the allowed headers to see if you can put it in the URI http://camel.apache.org/http4.html

Sample of a route removing headers

from("direct:start")
    .setHeader("variable1", constant("value1"))
    .setHeader("variable2", constant("value2"))
    .setHeader("Content-Type", constant("application/json"))
    .setHeader("Accept", constant("application/json"))
    .setHeader(Exchange.HTTP_METHOD, constant("GET"))
    .to("http://<host>:<port>/contact/3")
    .unmarshal().json(JsonLibrary.Jackson)
    .removeHeaders("variable*")
    .to("Anything I call now won't have the variable headers");

enrichment call

AggregationStrategy aggregationStrategy = new ExampleAggregationStrategy();

from("direct:start")
    .enrich("direct:getContact", aggregationStrategy)
    .to("You can have no additional headers here");

public class ExampleAggregationStrategy implements AggregationStrategy {
    public Exchange aggregate(Exchange original, Exchange resource) {
        Object originalBody = original.getIn().getBody();
        Object resourceResponse = resource.getIn().getBody();
        Object mergeResult = //TODO implement this however you want.  You can remove any headers here you like
        if (original.getPattern().isOutCapable()) {
            original.getOut().setBody(mergeResult);
        } else {
            original.getIn().setBody(mergeResult);
        }
        return original;
    }  
}

Actually 1 more option came to mind when going through the camel documentation I found an interesting property. Disclaimer I have never tried this property myself since I am still running camel 2.15 atm, but feel free to test it really quick it might just be what you need.

copyHeaders

default: true

Camel 2.16: If this option is true then IN exchange headers will be copied to OUT exchange headers according to copy strategy. Setting this to false, allows to only include the headers from the HTTP response (not propagating IN headers).

0
votes

Just use:

.removeHeaders("variable*")

to remove headers of any pattern.