package org.akka.essentials.java.future.example;
import static akka.pattern.Patterns.ask;
import static akka.pattern.Patterns.pipe;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;
import org.akka.essentials.java.future.example.messages.Address;
import org.akka.essentials.java.future.example.messages.Order;
import org.akka.essentials.java.future.example.messages.OrderHistory;
import scala.concurrent.Future;
import scala.concurrent.duration.Duration;
import akka.actor.ActorRef;
import akka.actor.Props;
import akka.actor.UntypedActor;
import akka.dispatch.Futures;
import akka.dispatch.Mapper;
import akka.util.Timeout;
public class ProcessOrderActor extends UntypedActor {
final Timeout t = new Timeout(Duration.create(5, TimeUnit.SECONDS));
ActorRef orderActor = getContext().actorOf(new Props(OrderActor.class));
ActorRef addressActor = getContext().actorOf(new Props(AddressActor.class));
ActorRef orderAggregateActor = getContext().actorOf(
new Props(OrderAggregateActor.class));
@Override
public void onReceive(Object message) throws Exception {
if (message instanceof Integer) {
Integer userId = (Integer) message;
final ArrayList<Future<Object>> futures = new ArrayList<Future<Object>>();
// make concurrent calls to actors
futures.add(ask(orderActor, userId, t));
futures.add(ask(addressActor, userId, t));
// set the sequence in which the reply are expected
final Future<Iterable<Object>> aggregate = Futures.sequence(
futures, getContext().system().dispatcher());
// once the replies comes back, we loop through the Iterable to
// get the replies in same order
// final Future<OrderHistory> aggResult =
final Future<OrderHistory> aggResult = aggregate.map(
new Mapper<Iterable<Object>, OrderHistory>() {
public OrderHistory apply(Iterable<Object> coll) {
final Iterator<Object> it = coll.iterator();
final Order order = (Order) it.next();
final Address address = (Address) it.next();
return new OrderHistory(order, address);
}
}, getContext().system().dispatcher());
// aggregated result is piped to another actor
pipe(aggResult, getContext().system().dispatcher()).to(
orderAggregateActor);
}
}
}