]> git.somenet.org - pub/jan/sbc.git/blob - src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/CookXVSM.java
[XVSM] Delivery in progress, Delivery done updates in UIs, Delivery logic
[pub/jan/sbc.git] / src / main / java / at / ac / tuwien / sbc / valesriegler / xvsm / CookXVSM.java
1 package at.ac.tuwien.sbc.valesriegler.xvsm;
2
3 import at.ac.tuwien.sbc.valesriegler.common.Util;
4 import at.ac.tuwien.sbc.valesriegler.types.*;
5 import at.ac.tuwien.sbc.valesriegler.xvsm.spacehelpers.SpaceAction;
6 import at.ac.tuwien.sbc.valesriegler.xvsm.spacehelpers.SpaceListener;
7 import org.mozartspaces.core.MzsConstants.RequestTimeout;
8 import org.mozartspaces.core.MzsCoreException;
9 import org.mozartspaces.core.TransactionReference;
10 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory;
12
13 import java.io.Serializable;
14 import java.net.URI;
15 import java.util.Arrays;
16 import java.util.Collections;
17 import java.util.List;
18
19 public class CookXVSM extends AbstractXVSMConnector {
20     private static final Logger log = LoggerFactory.getLogger(CookXVSM.class);
21
22     private int cookId;
23
24     public CookXVSM(int id, int port) {
25         super(port);
26
27         this.cookId = id;
28         orderTakenContainer = useContainer(Util.ORDER_TAKEN);
29         deliveryOrderTakenContainer = useContainer(Util.DELIVERY_ORDER_TAKEN);
30         preparedPizzasContainer = useContainer(Util.DELIVER_PIZZAS);
31         preparePizzasContainer = useContainer(Util.PREPARE_PIZZAS);
32         prepareDeliveryPizzasContainer = useContainer(Util.PREPARE_DELIVERY_PIZZAS);
33         pizzaInProgressContainer = useContainer(Util.PIZZAS_IN_PROGRESS);
34         preparedDeliveryPizzasContainer = useContainer(Util.DELIVER_DELIVERY_PIZZAS);
35         pizzeriaGroupContainer = useContainer(Util.PIZZERIA_GROUP);
36         pizzeriaDeliveryContainer = useContainer(Util.PIZZERIA_DELIVERY);
37     }
38
39     public void listenForPizzas() {
40         SpaceListener pizzasListener = getDefaultBuilder().setLookaround(true).setCref(preparePizzasContainer).setTimeout(15000).setSpaceAction(new SpaceAction() {
41
42             @Override
43             public void onEntriesWritten(List<? extends Serializable> entries)
44                     throws Exception {
45
46                 List<PizzaOrder> pizzas = castEntries(entries);
47
48                 if (inNotification.get()) Collections.shuffle(pizzas);
49
50                 for (PizzaOrder pizzaOrder : pizzas) {
51
52                     TransactionReference tx = capi.createTransaction(9000, URI.create(String.format(Util.SERVER_ADDR, port)));
53                     String pizzaAlreadyCooked = String.format("Pizza with id %d has already been cooked by another cook", pizzaOrder.getId());
54
55                     try {
56                         if (!mayPreparePizza(pizzaOrder, tx)) {
57                             capi.rollbackTransaction(tx);
58                             continue;
59                         }
60
61                         // Require the lock for preparing the pizza
62                         PizzaOrder order = takeMatchingEntity(new PizzaOrder(pizzaOrder.getId()), preparePizzasContainer, tx, RequestTimeout.ZERO, pizzaAlreadyCooked);
63
64
65                         // tell the space that you prepare the pizza -> without a transaction!!
66                         Pizza pizzaInProgress = Pizza.createPizzaFromPizzaOrder(order, cookId, true);
67                         pizzaInProgress.setStatus(PizzaOrderStatus.IN_PREPARATION);
68
69
70                         log.debug("I say that I now prepare a pizza for order {}", pizzaInProgress.getOrderId());
71                         sendItemsToContainer(Arrays.asList(pizzaInProgress), pizzaInProgressContainer, RequestTimeout.DEFAULT, null);
72
73                         PizzaOrder pizza = createPizza(order);
74
75                         sendItemsToContainer(Arrays.asList(pizza), preparedPizzasContainer, RequestTimeout.DEFAULT, tx);
76                         final GroupData group = new GroupData();
77                         final Order groupOrder = new Order();
78                         groupOrder.setId(pizza.getOrderId());
79                         group.setOrder(groupOrder);
80                         group.setState(GroupState.ORDERED);
81                         GroupData groupData = takeMatchingEntity(group, pizzeriaGroupContainer, tx, RequestTimeout.DEFAULT, "Cannot take the group from pizzeriaGroupContainer");
82                         final List<PizzaOrder> orderedPizzas = groupData.getOrder().getOrderedPizzas();
83                         for (PizzaOrder orderedPizza : orderedPizzas) {
84                             if (orderedPizza.getId() == pizza.getId()) {
85                                 orderedPizza.setStatus(PizzaOrderStatus.DONE);
86                                 orderedPizza.setCookId(pizza.getCookId());
87                             }
88                         }
89                         sendItemsToContainer(Arrays.asList(groupData), pizzeriaGroupContainer, RequestTimeout.DEFAULT, tx);
90                         capi.commitTransaction(tx);
91                         log.debug("I have completed preparing a pizza for order {}!", pizza.getOrderId());
92                     } catch (NullPointerException e) {
93                         // the strange nullpointer exception from the space
94                     } catch (Exception e) {
95                         log.info(e.getMessage());
96                     }
97
98                 }
99             }
100         }).createSpaceListenerImpl();
101
102     }
103
104     /**
105      * A cook may prepare a pizza if there is no current delivery order or if at least a pizza of the same order is
106      * in preparation!
107      */
108     private boolean mayPreparePizza(PizzaOrder pizzaOrder, TransactionReference tx) throws MzsCoreException {
109         List<PizzaOrder> deliveryPizzas = readMatchingEntities(new PizzaOrder(), prepareDeliveryPizzasContainer, tx, RequestTimeout.ZERO, "MAYPREPAREPIZZA: Cannot access prepareDeliveryPizzasContainer");
110         if (!deliveryPizzas.isEmpty()) {
111             final PizzaOrder template = new PizzaOrder();
112             template.setOrderId(pizzaOrder.getOrderId());
113             final List<PizzaOrder> pizzasOfOrderInProgress = readMatchingEntities(template, pizzaInProgressContainer, tx, RequestTimeout.ZERO, "MAYPREPAREPIZZA:: Cannot access pizzaInProgressContainer");
114             if (pizzasOfOrderInProgress.isEmpty()) return false;
115             final List<PizzaOrder> pizzasAlreadyDone = readMatchingEntities(template, preparedPizzasContainer, tx, RequestTimeout.ZERO, "MAYPREPAREPIZZA: Cannot access preparedPizzasContainer");
116             if(pizzasAlreadyDone.isEmpty()) return false;
117         }
118         return true;
119     }
120
121
122     public void listenForDeliveryPizzas() {
123         SpaceListener pizzasListener = getDefaultBuilder().setLookaround(true).setCref(prepareDeliveryPizzasContainer).setTimeout(15000).setSpaceAction(new SpaceAction() {
124
125             @Override
126             public void onEntriesWritten(List<? extends Serializable> entries)
127                     throws Exception {
128
129                 List<PizzaOrder> pizzas = castEntries(entries);
130
131                 if (inNotification.get()) Collections.shuffle(pizzas);
132
133                 for (PizzaOrder pizzaOrder : pizzas) {
134
135                     TransactionReference tx = capi.createTransaction(9000, URI.create(String.format(Util.SERVER_ADDR, port)));
136                     String pizzaAlreadyCooked = String.format("Pizza with id %d has already been cooked by another cook", pizzaOrder.getId());
137
138                     try {
139                         // Require the lock for preparing the pizza
140                         PizzaOrder order = takeMatchingEntity(new PizzaOrder(pizzaOrder.getId()), prepareDeliveryPizzasContainer, tx, RequestTimeout.ZERO, pizzaAlreadyCooked);
141
142                         // tell the space that you prepare the pizza -> without a transaction!!
143                         Pizza pizzaInProgress = Pizza.createPizzaFromPizzaOrder(order, cookId, true);
144                         pizzaInProgress.setStatus(PizzaOrderStatus.IN_PREPARATION);
145
146
147                         log.info("I say that I now prepare a pizza for order {}", pizzaInProgress.getOrderId());
148                         sendItemsToContainer(Arrays.asList(pizzaInProgress), pizzaInProgressContainer, RequestTimeout.DEFAULT, null);
149
150                         PizzaOrder pizza = createPizza(order);
151
152                         sendItemsToContainer(Arrays.asList(pizza), preparedDeliveryPizzasContainer, RequestTimeout.DEFAULT, tx);
153
154                         final DeliveryGroupData group = new DeliveryGroupData();
155                         final Order groupOrder = new Order();
156                         groupOrder.setId(pizza.getOrderId());
157                         group.setOrder(groupOrder);
158                         group.setDeliveryStatus(null);
159                         DeliveryGroupData groupData = takeMatchingEntity(group, pizzeriaDeliveryContainer, tx, RequestTimeout.DEFAULT, "Cannot take the delivery order from pizzeriaDeliveryContainer");
160                         final List<PizzaOrder> orderedPizzas = groupData.getOrder().getOrderedPizzas();
161                         for (PizzaOrder orderedPizza : orderedPizzas) {
162                             if (orderedPizza.getId() == pizza.getId()) {
163                                 orderedPizza.setStatus(PizzaOrderStatus.DONE);
164                                 orderedPizza.setCookId(pizza.getCookId());
165                             }
166                         }
167                         sendItemsToContainer(Arrays.asList(groupData), pizzeriaDeliveryContainer, RequestTimeout.DEFAULT, tx);
168
169                         capi.commitTransaction(tx);
170                         log.info("I have completed preparing a delivery pizza for order {}!", pizza.getOrderId());
171                     } catch (NullPointerException e) {
172                         // the strange nullpointer exception from the space
173                     } catch (Exception e) {
174                         log.info(e.getMessage());
175                     }
176
177                 }
178             }
179         }).createSpaceListenerImpl();
180
181     }
182
183     private PizzaOrder createPizza(PizzaOrder order) throws InterruptedException {
184         long duration = order.getPizzaType().duration;
185         Thread.sleep(duration * 1000);
186
187         PizzaOrder pizza = Pizza.createPizzaFromPizzaOrder(order, cookId, false);
188         pizza.setStatus(PizzaOrderStatus.DONE);
189         return pizza;
190     }
191
192 }