1 package at.ac.tuwien.sbc.valesriegler.xvsm;
4 import at.ac.tuwien.sbc.valesriegler.common.Bill;
5 import at.ac.tuwien.sbc.valesriegler.common.Util;
6 import at.ac.tuwien.sbc.valesriegler.types.*;
7 import at.ac.tuwien.sbc.valesriegler.xvsm.spacehelpers.SpaceAction;
8 import org.mozartspaces.capi3.EntryLockedException;
9 import org.mozartspaces.core.ContainerReference;
10 import org.mozartspaces.core.MzsConstants;
11 import org.mozartspaces.core.MzsCoreException;
12 import org.mozartspaces.core.TransactionReference;
13 import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory;
16 import java.io.Serializable;
18 import java.util.Arrays;
19 import java.util.List;
21 public class DriverXVSM extends AbstractXVSMConnector {
22 private static final Logger log = LoggerFactory.getLogger(DriverXVSM.class);
26 public DriverXVSM(int id, int port) {
31 preparedDeliveryPizzasContainer = useContainer(Util.DELIVER_DELIVERY_PIZZAS);
32 deliveryOrderTakenContainer = useContainer(Util.DELIVERY_ORDER_TAKEN);
33 deliverDeliveryOrderContainer = useContainer(Util.DELIVER_DELIVERY_ORDER);
34 pizzeriaDeliveryContainer = useContainer(Util.PIZZERIA_DELIVERY);
38 public void listenForPreparedDeliveryOrders() {
39 getDefaultBuilder("listenForPreparedDeliveryOrders").setCref(deliverDeliveryOrderContainer).setLookaround(true).setSpaceAction(new SpaceAction() {
42 public void onEntriesWritten(List<? extends Serializable> entries) throws Exception {
43 handleDeliveries(entries);
46 }).createSpaceListenerImpl();
49 private void handleDeliveries(List<? extends Serializable> entries) throws MzsCoreException {
50 final List<DeliveryGroupData> deliveries = castEntries(entries);
52 for (DeliveryGroupData delivery : deliveries) {
53 DeliveryGroupData template = new DeliveryGroupData(delivery.getId());
54 template.setDeliveryStatus(DeliveryStatus.ORDERED);
56 final TransactionReference tx = capi.createTransaction(
58 URI.create(String.format(Util.SERVER_ADDR, port)));
59 final String error = "Another driver wants to deliver this order!";
62 // Get lock for delivering this delivery order
63 takeMatchingEntity(template, deliverDeliveryOrderContainer, tx, MzsConstants.RequestTimeout.ZERO, error);
64 final DeliveryGroupData group = takeMatchingEntity(template, pizzeriaDeliveryContainer, tx, MzsConstants.RequestTimeout.DEFAULT, "Cannot get the delivery order!");
65 group.setDriverId(driverId);
66 group.setDeliveryStatus(DeliveryStatus.IN_PROGRESS);
68 final List<DeliveryGroupData> groups = Arrays.asList(group);
69 sendItemsToContainer(groups,
70 pizzeriaDeliveryContainer, MzsConstants.RequestTimeout.ZERO, null);
72 if (!Util.runSimulation) {
76 final String address = String.format(Util.SERVER_ADDR, Util.DELIVERY_CUSTOMERS_PORT);
77 ContainerReference cref = null;
78 boolean success = false;
80 cref = capi.lookupContainer(group.getAddress(), URI.create(address), MzsConstants.RequestTimeout.ZERO, null);
81 log.debug("Looked up container {} successfully!", address);
84 } catch (Exception ex) {
85 log.info("Could not find container {}", address);
88 group.setDeliveryStatus(DeliveryStatus.DELIVERED);
89 if (!Util.runSimulation) {
90 double sum = computeSum(group.getOrder());
91 sendItemsToContainer(Arrays.asList(new Bill(sum, group.getId())), cref, MzsConstants.RequestTimeout.ZERO, null);
94 group.setDeliveryStatus(DeliveryStatus.DELIVERY_FAILED);
96 sendItemsToContainer(groups, pizzeriaDeliveryContainer, MzsConstants.RequestTimeout.ZERO, tx);
97 capi.commitTransaction(tx);
100 } catch(EntryLockedException e) {
101 capi.rollbackTransaction(tx);
102 } catch(NullPointerException e) {
103 log.info("strange npe from space!");
104 } catch (Exception e) {
105 log.info("DRiverXVSM exception");
106 log.info(e.getMessage());
112 private double computeSum(Order order) {
113 final List<PizzaOrder> orderedPizzas = order.getOrderedPizzas();
115 for (PizzaOrder pizza : orderedPizzas) {
116 final PizzaType pizzaType = pizza.getPizzaType();
118 case CARDINALE: sum = sum + 6;
120 case MARGHERITA: sum = sum + 5;
122 case SALAMI: sum = sum + 5.5;
125 throw new RuntimeException("Unhandled Pizzatype: " + pizzaType);
131 public void listenForPreparedDeliveryPizzas() {
132 getDefaultBuilder("listenForPreparedDeliveryPizzas").setCref(preparedDeliveryPizzasContainer).setLookaround(true).setSpaceAction(new SpaceAction() {
135 public void onEntriesWritten(List<? extends Serializable> entries)
138 List<Pizza> pizzas = castEntries(entries);
140 for (Pizza pizza : pizzas) {
141 int orderId = pizza.getOrderId();
142 Order order = new Order();
143 order.setId(orderId);
145 TransactionReference tx = getDefaultTransaction();
148 DeliveryGroupData entity = new DeliveryGroupData();
149 entity.setDeliveryStatus(null);
150 entity.setOrder(order);
152 final DeliveryGroupData groupData = takeMatchingEntity(entity,
153 deliveryOrderTakenContainer, tx, MzsConstants.RequestTimeout.DEFAULT,
154 "Another driver just checks if the delivery order is complete");
155 int numberOfPizzas = groupData.getOrder().getNumberOfPizzas();
157 Pizza pizzaTemplate = new Pizza();
158 pizzaTemplate.setOrderId(orderId);
160 List<Pizza> pizzasOfOrder = takeMatchingEntities(
161 pizzaTemplate, preparedDeliveryPizzasContainer, tx,
162 MzsConstants.RequestTimeout.DEFAULT,
163 "Cannot take the pizzas from the preparedDeliveryPizzasContainer");
165 if (pizzasOfOrder.size() == numberOfPizzas) {
166 final List<DeliveryGroupData> groupsWithCompleteOrder = Arrays.asList(groupData);
167 sendItemsToContainer(groupsWithCompleteOrder,
168 deliverDeliveryOrderContainer, MzsConstants.RequestTimeout.DEFAULT,
171 capi.commitTransaction(tx);
173 log.info("Not yet all pizzas prepared! Order with id "
174 + orderId + " has " + numberOfPizzas
175 + " pizzas, but only " + pizzasOfOrder.size()
176 + " pizzas are ready by now!");
177 capi.rollbackTransaction(tx);
179 } catch (NullPointerException e) {
181 } catch (Exception e) {
182 capi.rollbackTransaction(tx);
186 }).createSpaceListenerImpl();