问题
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