I'm trying to generate a aggregate view of consecutive market data, which means we need to calculate the sum value every 2 message. say the data coming in as:
(V0,T0),(V1,T1),(V2,T2),(V3,T3)....
V
means value T
means timestamp when we receive the data.
We need to generate the sum for every 2 points say:
(R1=Sum(V0,V1),T1),(R2=Sum(V1,V2),T2),(R3=Sum(V2,V3),T3),....
Any suggestion how can we do this by using aggregator2
or we need to write a processor for this?
You are right, aggregator2 component is the good way to go. I would try something like that:
from("somewhere").split(body().tokenize("),")).streaming()
.aggregate(new ValueAggregationStrategy()).completionTimeout(1500)
.to("whatYouWant");
class ValueAggregationStrategy implements AggregationStrategy {
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
if (oldExchange == null) {
return newExchange;
}
String oldBody = oldExchange.getIn().getBody(String.class);
String newBody = newExchange.getIn().getBody(String.class);
oldExchange.getIn().setBody(extractValue(oldBody) + extractValue(newBody));
return oldExchange;
}
public int extractValue(String body) {
// Do the work "(V0,T0" -> "V0"
}
}
NB: It would be easier to parse if you could have a format like that: V0,T0;V1,T1...
For more information: here is an article wrote by Claus Ibsen on parsing large file with Camel
After reading the source code of Aggregator, it turns out that camel only aggregate one message to one group, we have to build a "aggregator" for this purpose. here is the code:
public abstract class GroupingGenerator<I> implements Processor {
private final EvictingQueue<I> queue;
private final int size;
public int getSize() {
return size;
}
public GroupingGenerator(int size) {
super();
this.size = size;
this.queue = EvictingQueue.create(size);
}
@SuppressWarnings("unchecked")
@Override
public void process(Exchange exchange) throws Exception {
queue.offer((I) exchange.getIn().getBody());
if (queue.size() != size) {
exchange.setProperty(Exchange.ROUTE_STOP, true);
return;
} else {
processGroup(queue, exchange);
}
}
protected abstract void processGroup(Collection<I> items, Exchange exchange);
}