]> git.somenet.org - pub/jan/sbc.git/blob - src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/CookXVSM.java
GUI fix for Tables OutOfBoundsException
[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 org.mozartspaces.core.MzsConstants.RequestTimeout;
7 import org.mozartspaces.core.MzsCoreException;
8 import org.mozartspaces.core.TransactionReference;
9 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory;
11
12 import java.io.Serializable;
13 import java.net.URI;
14 import java.util.Arrays;
15 import java.util.Collections;
16 import java.util.List;
17
18 public class CookXVSM extends AbstractXVSMConnector {
19     private static final Logger log = LoggerFactory.getLogger(CookXVSM.class);
20
21     private int cookId;
22
23     public CookXVSM(int id, int port) {
24         super(port);
25
26         this.cookId = id;
27         orderTakenContainer = useContainer(Util.ORDER_TAKEN);
28         deliveryOrderTakenContainer = useContainer(Util.DELIVERY_ORDER_TAKEN);
29         preparedPizzasContainer = useContainer(Util.DELIVER_PIZZAS);
30         preparePizzasContainer = useContainer(Util.PREPARE_PIZZAS);
31         prepareDeliveryPizzasContainer = useContainer(Util.PREPARE_DELIVERY_PIZZAS);
32         pizzaInProgressContainer = useContainer(Util.PIZZAS_IN_PROGRESS);
33         preparedDeliveryPizzasContainer = useContainer(Util.DELIVER_DELIVERY_PIZZAS);
34         pizzeriaGroupContainer = useContainer(Util.PIZZERIA_GROUP);
35         pizzeriaDeliveryContainer = useContainer(Util.PIZZERIA_DELIVERY);
36     }
37
38     public void listenForPizzas() {
39        getDefaultBuilder("").setLookaround(true).setCref(preparePizzasContainer).setTimeout(15000).setSpaceAction(new SpaceAction() {
40
41             @Override
42             public void onEntriesWritten(List<? extends Serializable> entries)
43                     throws Exception {
44
45                 List<PizzaOrder> pizzas = castEntries(entries);
46
47                 if (inNotification.get()) Collections.shuffle(pizzas);
48
49                 for (PizzaOrder pizzaOrder : pizzas) {
50
51                     TransactionReference tx = capi.createTransaction(9000, URI.create(String.format(Util.SERVER_ADDR, port)));
52                     String pizzaAlreadyCooked = String.format("Normal pizza with id %d has already been cooked by another cook", pizzaOrder.getId());
53
54                     try {
55                         if (!mayPrepareCustomerPizza(pizzaOrder, tx)) {
56                             capi.rollbackTransaction(tx);
57                             continue;
58                         }
59
60                         // Require the lock for preparing the pizza
61                         PizzaOrder order = takeMatchingEntity(new PizzaOrder(pizzaOrder.getId()), preparePizzasContainer, tx, RequestTimeout.ZERO, pizzaAlreadyCooked);
62
63                         // tell the space that you prepare the pizza -> without a transaction!!
64                         Pizza pizzaInProgress = Pizza.createPizzaFromPizzaOrder(order, cookId, true);
65                         pizzaInProgress.setStatus(PizzaOrderStatus.IN_PREPARATION);
66
67                         notifyCustomerPizzaInProgress(order, pizzaInProgress);
68
69                         PizzaOrder pizza = createPizza(order);
70
71                         notifyCustomerPizzaDone(pizza, tx);
72                         capi.commitTransaction(tx);
73                         log.debug("I have completed preparing a pizza for order {}!", pizza.getOrderId());
74                     } catch (NullPointerException e) {
75                         // the strange nullpointer exception from the space
76                     } catch (EntityNotFoundByTemplate e) {
77                         log.info("entitynotfound: {}", e.getMessage());
78                     } catch (Exception e) {
79                         log.error("outer cook");
80                         log.error(e.getMessage());
81                     }
82
83                 }
84             }
85         }).createSpaceListenerImpl();
86
87     }
88
89     public void listenForDeliveryPizzas() {
90         getDefaultBuilder("").setLookaround(true).setCref(prepareDeliveryPizzasContainer).setTimeout(15000).setSpaceAction(new SpaceAction() {
91
92             @Override
93             public void onEntriesWritten(List<? extends Serializable> entries)
94                     throws Exception {
95
96                 List<PizzaOrder> pizzas = castEntries(entries);
97
98                 if (inNotification.get()) Collections.shuffle(pizzas);
99
100                 for (PizzaOrder pizzaOrder : pizzas) {
101
102                     TransactionReference tx = capi.createTransaction(12000, URI.create(String.format(Util.SERVER_ADDR, port)));
103                     String pizzaAlreadyCooked = String.format("Delivery Pizza with id %d has already been cooked by another cook", pizzaOrder.getId());
104
105                     try {
106                         if (!mayPrepareDeliveryPizza(tx)) {
107                             capi.rollbackTransaction(tx);
108                             continue;
109                         }
110
111                         // Require the lock for preparing the pizza
112                         PizzaOrder order = takeMatchingEntity(new PizzaOrder(pizzaOrder.getId()), prepareDeliveryPizzasContainer, tx, RequestTimeout.ZERO, pizzaAlreadyCooked);
113
114                         // tell the space that you prepare the pizza -> without a transaction!!
115                         Pizza pizzaInProgress = Pizza.createPizzaFromPizzaOrder(order, cookId, true);
116                         pizzaInProgress.setStatus(PizzaOrderStatus.IN_PREPARATION);
117
118                         notifyDeliveryPizzaInProgress(order, pizzaInProgress);
119
120                         log.debug("before creating!");
121
122                         PizzaOrder pizza = createPizza(order);
123
124                         log.debug("after creating!");
125
126                         sendItemsToContainer(Arrays.asList(pizza), preparedDeliveryPizzasContainer, RequestTimeout.DEFAULT, tx);
127
128                         log.debug("after prepareddeliverypizzascon");
129
130                         notifyDeliveryPizzaDone(pizza, tx);
131
132                         log.debug("after notifydone");
133
134                         capi.commitTransaction(tx);
135                         log.debug("I have completed preparing a delivery pizza for order {}!", pizza.getOrderId());
136                     } catch (NullPointerException e) {
137                         // the strange nullpointer exception from the space
138                     } catch (EntityNotFoundByTemplate e) {
139                         log.info("entitynotfound: {}", e.getMessage());
140
141                     } catch (Exception e) {
142                         log.error("outer cook");
143                         log.error(e.getMessage());
144                     }
145
146                 }
147             }
148         }).createSpaceListenerImpl();
149
150     }
151
152     /**
153      * A cook may prepare a pizza if there is no current delivery order or if at least a pizza of the same order is
154      * in preparation or has been done!
155      */
156     private boolean mayPrepareCustomerPizza(PizzaOrder pizzaOrder, TransactionReference tx) throws MzsCoreException {
157         List<PizzaOrder> deliveryPizzas = readMatchingEntities(new PizzaOrder(), prepareDeliveryPizzasContainer, tx, RequestTimeout.DEFAULT, "MAYPREPAREPIZZA: Cannot access prepareDeliveryPizzasContainer");
158         if (!deliveryPizzas.isEmpty()) {
159             final PizzaOrder template = new PizzaOrder();
160             template.setOrderId(pizzaOrder.getOrderId());
161             final List<PizzaOrder> pizzasAlreadyDone = readMatchingEntities(template, preparedPizzasContainer, tx, RequestTimeout.DEFAULT, "MAYPREPAREPIZZA: Cannot access preparedPizzasContainer");
162             if(! pizzasAlreadyDone.isEmpty()) return true;
163             final List<PizzaOrder> pizzasOfOrderInProgress = readMatchingEntities(template, pizzaInProgressContainer, tx, RequestTimeout.DEFAULT, "MAYPREPAREPIZZA:: Cannot access pizzaInProgressContainer");
164             if (! pizzasOfOrderInProgress.isEmpty()) return true;
165
166             return false;
167         }
168         else return true;
169     }
170
171
172     private boolean mayPrepareDeliveryPizza(TransactionReference tx) throws MzsCoreException {
173         final PizzaOrder template = new PizzaOrder();
174         template.setDeliveryPizza(false);
175         final List<PizzaOrder> preparedNonDeliveryPizzas  = readMatchingEntities(template, preparedPizzasContainer, tx, RequestTimeout.DEFAULT, "mayPrepareDeliveryPizza: cannot access preparedPizzasContainer");
176         if(! preparedNonDeliveryPizzas.isEmpty()) return false;
177         final List<PizzaOrder> nonDeliveryPizzasInProgress = readMatchingEntities(template, pizzaInProgressContainer, tx, RequestTimeout.DEFAULT, "mayPrepareDeliveryPizza: cannot access pizzaInProgressContainer");
178         if (! nonDeliveryPizzasInProgress.isEmpty()) return false;
179
180         return true;
181     }
182
183     private void notifyCustomerPizzaDone(PizzaOrder pizza, TransactionReference tx) throws MzsCoreException {
184         sendItemsToContainer(Arrays.asList(pizza), preparedPizzasContainer, RequestTimeout.DEFAULT, tx);
185         final GroupData group = new GroupData();
186         final Order groupOrder = new Order();
187         groupOrder.setId(pizza.getOrderId());
188         group.setOrder(groupOrder);
189         group.setState(GroupState.ORDERED);
190         GroupData groupData = takeMatchingEntity(group, pizzeriaGroupContainer, tx, RequestTimeout.INFINITE, "Cannot take the group from pizzeriaGroupContainer");
191         final List<PizzaOrder> orderedPizzas = groupData.getOrder().getOrderedPizzas();
192         for (PizzaOrder orderedPizza : orderedPizzas) {
193             if (orderedPizza.getId() == pizza.getId()) {
194                 orderedPizza.setStatus(PizzaOrderStatus.DONE);
195                 orderedPizza.setCookId(pizza.getCookId());
196             }
197         }
198         sendItemsToContainer(Arrays.asList(groupData), pizzeriaGroupContainer, RequestTimeout.DEFAULT, tx);
199     }
200
201     private void notifyDeliveryPizzaDone(PizzaOrder pizza, TransactionReference tx) throws MzsCoreException {
202         final DeliveryGroupData group = new DeliveryGroupData();
203         final Order groupOrder = new Order();
204         groupOrder.setId(pizza.getOrderId());
205         group.setOrder(groupOrder);
206         group.setDeliveryStatus(null);
207         DeliveryGroupData groupData = takeMatchingEntity(group, pizzeriaDeliveryContainer, tx, RequestTimeout.INFINITE, "Cannot take the delivery order from pizzeriaDeliveryContainer");
208         final List<PizzaOrder> orderedPizzas = groupData.getOrder().getOrderedPizzas();
209         for (PizzaOrder orderedPizza : orderedPizzas) {
210             if (orderedPizza.getId() == pizza.getId()) {
211                 orderedPizza.setStatus(PizzaOrderStatus.DONE);
212                 orderedPizza.setCookId(pizza.getCookId());
213             }
214         }
215         sendItemsToContainer(Arrays.asList(groupData), pizzeriaDeliveryContainer, RequestTimeout.DEFAULT, tx);
216     }
217
218     private void notifyDeliveryPizzaInProgress(PizzaOrder order, Pizza pizzaInProgress) throws MzsCoreException {
219         log.info("I say that I now prepare a delivery pizza for order {}", pizzaInProgress.getOrderId());
220         final DeliveryGroupData groupTemplate = new DeliveryGroupData();
221         final Order groupOrder = new Order();
222         groupOrder.setId(order.getOrderId());
223         groupTemplate.setOrder(groupOrder);
224         groupTemplate.setDeliveryStatus(null);
225         final TransactionReference inPreparationTx = getDefaultTransaction();
226         final DeliveryGroupData groupFromSpace = takeMatchingEntity(groupTemplate, pizzeriaDeliveryContainer, inPreparationTx, RequestTimeout.DEFAULT, "Cannot take the delivery order from pizzeriaDeliveryContainer");
227         final List<PizzaOrder> orderedPizzas = groupFromSpace.getOrder().getOrderedPizzas();
228         for (PizzaOrder orderedPizza : orderedPizzas) {
229             if (orderedPizza.getId() == pizzaInProgress.getId()) {
230                 orderedPizza.setStatus(PizzaOrderStatus.IN_PREPARATION);
231                 orderedPizza.setCookId(pizzaInProgress.getCookId());
232             }
233         }
234         sendItemsToContainer(Arrays.asList(groupFromSpace), pizzeriaDeliveryContainer, RequestTimeout.DEFAULT, inPreparationTx);
235         sendItemsToContainer(Arrays.asList(pizzaInProgress), pizzaInProgressContainer, RequestTimeout.DEFAULT, inPreparationTx);
236         log.debug("before inprogress comit!");
237         capi.commitTransaction(inPreparationTx);
238     }
239
240     private void notifyCustomerPizzaInProgress(PizzaOrder order, Pizza pizzaInProgress) {
241         try {
242             log.debug("I say that I now prepare a pizza for order {}", pizzaInProgress.getOrderId());
243             final GroupData groupTemplate = new GroupData();
244             final Order groupOrder = new Order();
245             groupOrder.setId(order.getOrderId());
246             groupTemplate.setOrder(groupOrder);
247             groupTemplate.setState(null);
248             final TransactionReference inPreparationTx = getDefaultTransaction();
249             final GroupData groupFromSpace = takeMatchingEntity(groupTemplate, pizzeriaGroupContainer, inPreparationTx, 100, "Cannot take the order from pizzeriaGroupContainer");
250             final List<PizzaOrder> orderedPizzas = groupFromSpace.getOrder().getOrderedPizzas();
251             for (PizzaOrder orderedPizza : orderedPizzas) {
252                 if (orderedPizza.getId() == pizzaInProgress.getId()) {
253                     orderedPizza.setStatus(PizzaOrderStatus.IN_PREPARATION);
254                     orderedPizza.setCookId(pizzaInProgress.getCookId());
255                 }
256             }
257             sendItemsToContainer(Arrays.asList(groupFromSpace), pizzeriaGroupContainer, RequestTimeout.ZERO, inPreparationTx);
258             sendItemsToContainer(Arrays.asList(pizzaInProgress), pizzaInProgressContainer, RequestTimeout.ZERO, inPreparationTx);
259             capi.commitTransaction(inPreparationTx);
260         } catch (Exception e) {
261             log.error("This error has occurred: {}", e.getMessage());
262             e.printStackTrace();
263         }
264     }
265
266     private PizzaOrder createPizza(PizzaOrder order) throws InterruptedException {
267         long duration = order.getPizzaType().duration;
268         if (! Util.runSimulation) {
269             Thread.sleep(duration * 1000);
270         }
271
272         PizzaOrder pizza = Pizza.createPizzaFromPizzaOrder(order, cookId, false);
273         pizza.setStatus(PizzaOrderStatus.DONE);
274         return pizza;
275     }
276
277 }