Setting REST response body in camel

风流意气都作罢 提交于 2019-12-13 02:04:35

问题


Here is the flow I'm trying to setup in Camel:

GET /product/foo --> MULTICAST [HTTP URI 1, HTTP URI 2, HTTP URI 3] --> AGGREGATE --> return aggregated value to HTTP response body

I've setup the route this way, BUT I get no data back in the response to the original GET.

How can I get the value returned by the aggregator ?

 @Override
    public void configure() throws Exception {

        restConfiguration()
                .host("localhost")
                .port("8081")
                .component("jetty");

        from("rest:get:product/foo")
                .multicast()
                .parallelProcessing()
                .aggregationStrategy(new ProductPriceAggregator())
                .to("direct:prodcutService1")
                .to("direct:prodcutService2")
                .to("direct:prodcutService3");

        from("direct:prodcutService1")
                .to("http4:localhost:9090/simple/product/foo?bridgeEndpoint=true")
                .to("direct:aggregate");

        from("direct:prodcutService2")
                .to("http4:localhost:9091/simple/product/foo?bridgeEndpoint=true")
                .to("direct:aggregate");

        from("direct:prodcutService3")
                .to("http4:localhost:9092/simple/product/foo?bridgeEndpoint=true")
                .to("direct:aggregate");

        from("direct:aggregate")
                .log("${body}").;
    }
}

Here is my aggregator :

public class ProductPriceAggregator implements AggregationStrategy {

    @Override
    public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
        System.out.println("FOO BAR");
        double oldPrice = oldExchange.getIn().getBody(Double.class);
        double newPrice = newExchange.getIn().getBody(Double.class);
        double finalPrice = oldPrice > newPrice ? newPrice : oldPrice;
        oldExchange.getIn().setBody(finalPrice);
        return oldExchange;
    }
}

回答1:


This will do it.

from("direct:aggregate").transform().body(); 

But there is a small mistake in your aggregation strategy. Have rewritten it here.

public class ProductPriceAggregator implements AggregationStrategy {

@Override
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) 
{

    if (oldExchange == null) {
       // the first time we aggregate we only have the new exchange,
       // so we just return it
       return newExchange;
    }

    System.out.println("FOO BAR");
    double oldPrice = oldExchange.getIn().getBody(Double.class);
    double newPrice = newExchange.getIn().getBody(Double.class);
    double finalPrice = oldPrice > newPrice ? newPrice : oldPrice;
    oldExchange.getIn().setBody(finalPrice);
    return oldExchange;
  }
}

For the first iteration oldExchange will be null so you need have a check and return newExchange.

EDIT:

For some strange reason(or may be it is designed like this) Camel is treating Double values completely different. To make it work, do the following changes.

 from("rest:get:product/foo")
                .setHeader("Accept", simple("application/json"))
                .multicast()
                .parallelProcessing()
                .......

This is because, by default it takes text/html as Accept type and double values are coming like html tags like <Double>2.345<Double>. So you need to specify type as application/json for better processing.

And in the Aggregator code you need to do like this.

double oldPrice = Double.valueOf(oldExchange.getIn().getBody(String.class));
double newPrice = Double.valueOf(newExchange.getIn().getBody(String.class));
double finalPrice = oldPrice > newPrice ? newPrice : oldPrice;
    oldExchange.getIn().setBody(Double.toString(finalPrice));


来源:https://stackoverflow.com/questions/48590193/setting-rest-response-body-in-camel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!