1 package at.ac.tuwien.sbc.valesriegler.xvsm;
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;
12 import java.io.Serializable;
14 import java.util.Arrays;
15 import java.util.Collections;
16 import java.util.List;
18 public class CookXVSM extends AbstractXVSMConnector {
19 private static final Logger log = LoggerFactory.getLogger(CookXVSM.class);
23 public CookXVSM(int id, int port) {
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);
38 public void listenForPizzas() {
39 getDefaultBuilder().setLookaround(true).enableCountAll().setCref(preparePizzasContainer).setTimeout(15000).setSpaceAction(new SpaceAction() {
42 public void onEntriesWritten(List<? extends Serializable> entries)
45 List<PizzaOrder> pizzas = castEntries(entries);
47 if (inNotification.get()) Collections.shuffle(pizzas);
49 for (PizzaOrder pizzaOrder : pizzas) {
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());
55 if (!mayPrepareCustomerPizza(pizzaOrder, tx)) {
56 capi.rollbackTransaction(tx);
60 // Require the lock for preparing the pizza
61 PizzaOrder order = takeMatchingEntity(new PizzaOrder(pizzaOrder.getId()), preparePizzasContainer, tx, RequestTimeout.DEFAULT, pizzaAlreadyCooked);
64 // tell the space that you prepare the pizza -> without a transaction!!
65 Pizza pizzaInProgress = Pizza.createPizzaFromPizzaOrder(order, cookId, true);
66 pizzaInProgress.setStatus(PizzaOrderStatus.IN_PREPARATION);
68 notifyCustomerPizzaInProgress(order, pizzaInProgress);
70 PizzaOrder pizza = createPizza(order);
72 notifyCustomerPizzaDone(pizza, tx);
73 capi.commitTransaction(tx);
74 // log.debug("I have completed preparing a pizza for order {}!", pizza.getOrderId());
75 } catch (NullPointerException e) {
76 // the strange nullpointer exception from the space
77 } catch (EntityNotFoundByTemplate e) {
78 // log.info("entitynotfound: {}", e.getMessage());
79 } catch (Exception e) {
80 // log.info("outer cook");
81 // log.info(e.getMessage());
82 // e.printStackTrace();
87 }).createSpaceListenerImpl();
91 public void listenForDeliveryPizzas() {
92 getDefaultBuilder().setLookaround(true).setCref(prepareDeliveryPizzasContainer).setTimeout(15000).setSpaceAction(new SpaceAction() {
95 public void onEntriesWritten(List<? extends Serializable> entries)
98 List<PizzaOrder> pizzas = castEntries(entries);
100 if (inNotification.get()) Collections.shuffle(pizzas);
102 for (PizzaOrder pizzaOrder : pizzas) {
104 TransactionReference tx = capi.createTransaction(12000, URI.create(String.format(Util.SERVER_ADDR, port)));
105 String pizzaAlreadyCooked = String.format("Delivery Pizza with id %d has already been cooked by another cook", pizzaOrder.getId());
108 if (!mayPrepareDeliveryPizza(pizzaOrder, tx)) {
109 capi.rollbackTransaction(tx);
113 // Require the lock for preparing the pizza
114 PizzaOrder order = takeMatchingEntity(new PizzaOrder(pizzaOrder.getId()), prepareDeliveryPizzasContainer, tx, RequestTimeout.DEFAULT, pizzaAlreadyCooked);
116 // tell the space that you prepare the pizza -> without a transaction!!
117 Pizza pizzaInProgress = Pizza.createPizzaFromPizzaOrder(order, cookId, true);
118 pizzaInProgress.setStatus(PizzaOrderStatus.IN_PREPARATION);
120 if (! Util.runSimulation) {
121 notifyDeliveryPizzaInProgress(order, pizzaInProgress);
124 // log.info("before creating!");
126 PizzaOrder pizza = createPizza(order);
128 // log.info("after creating!");
130 sendItemsToContainer(Arrays.asList(pizza), preparedDeliveryPizzasContainer, RequestTimeout.DEFAULT, tx);
132 // log.info("after prepareddeliverypizzascon");
134 notifyDeliveryPizzaDone(pizza, tx);
136 // log.info("after notifydone");
138 capi.commitTransaction(tx);
139 log.info("I have completed preparing a delivery pizza for order {}!", pizza.getOrderId());
140 } catch (NullPointerException e) {
141 // the strange nullpointer exception from the space
142 } catch (EntityNotFoundByTemplate e) {
143 // log.info("entitynotfound: {}", e.getMessage());
145 } catch (Exception e) {
146 // log.info("outer cook");
147 // log.info(e.getMessage());
148 // e.printStackTrace();
153 }).createSpaceListenerImpl();
158 * A cook may prepare a pizza if there is no current delivery order or if at least a pizza of the same order is
159 * in preparation or has been done!
161 private boolean mayPrepareCustomerPizza(PizzaOrder pizzaOrder, TransactionReference tx) throws MzsCoreException {
162 List<PizzaOrder> deliveryPizzas = readMatchingEntities(new PizzaOrder(), prepareDeliveryPizzasContainer, tx, RequestTimeout.INFINITE, "MAYPREPAREPIZZA: Cannot access prepareDeliveryPizzasContainer");
163 if (!deliveryPizzas.isEmpty()) {
164 final PizzaOrder template = new PizzaOrder();
165 template.setOrderId(pizzaOrder.getOrderId());
166 final List<PizzaOrder> pizzasAlreadyDone = readMatchingEntities(template, preparedPizzasContainer, tx, RequestTimeout.INFINITE, "MAYPREPAREPIZZA: Cannot access preparedPizzasContainer");
167 if(! pizzasAlreadyDone.isEmpty()) return true;
168 final List<PizzaOrder> pizzasOfOrderInProgress = readMatchingEntities(template, pizzaInProgressContainer, tx, RequestTimeout.INFINITE, "MAYPREPAREPIZZA:: Cannot access pizzaInProgressContainer");
169 if (! pizzasOfOrderInProgress.isEmpty()) return true;
177 private boolean mayPrepareDeliveryPizza(PizzaOrder pizzaOrder, TransactionReference tx) throws MzsCoreException {
178 // TODO: return false if a cook has already started cooking pizzas of an open order
182 private void notifyCustomerPizzaDone(PizzaOrder pizza, TransactionReference tx) throws MzsCoreException {
183 sendItemsToContainer(Arrays.asList(pizza), preparedPizzasContainer, RequestTimeout.DEFAULT, tx);
184 final GroupData group = new GroupData();
185 final Order groupOrder = new Order();
186 groupOrder.setId(pizza.getOrderId());
187 group.setOrder(groupOrder);
188 group.setState(GroupState.ORDERED);
189 GroupData groupData = takeMatchingEntity(group, pizzeriaGroupContainer, tx, RequestTimeout.INFINITE, "Cannot take the group from pizzeriaGroupContainer");
190 final List<PizzaOrder> orderedPizzas = groupData.getOrder().getOrderedPizzas();
191 for (PizzaOrder orderedPizza : orderedPizzas) {
192 if (orderedPizza.getId() == pizza.getId()) {
193 orderedPizza.setStatus(PizzaOrderStatus.DONE);
194 orderedPizza.setCookId(pizza.getCookId());
197 sendItemsToContainer(Arrays.asList(groupData), pizzeriaGroupContainer, RequestTimeout.DEFAULT, tx);
200 private void notifyDeliveryPizzaDone(PizzaOrder pizza, TransactionReference tx) throws MzsCoreException {
201 final DeliveryGroupData group = new DeliveryGroupData();
202 final Order groupOrder = new Order();
203 groupOrder.setId(pizza.getOrderId());
204 group.setOrder(groupOrder);
205 group.setDeliveryStatus(null);
206 DeliveryGroupData groupData = takeMatchingEntity(group, pizzeriaDeliveryContainer, tx, RequestTimeout.INFINITE, "Cannot take the delivery order from pizzeriaDeliveryContainer");
207 final List<PizzaOrder> orderedPizzas = groupData.getOrder().getOrderedPizzas();
208 for (PizzaOrder orderedPizza : orderedPizzas) {
209 if (orderedPizza.getId() == pizza.getId()) {
210 orderedPizza.setStatus(PizzaOrderStatus.DONE);
211 orderedPizza.setCookId(pizza.getCookId());
214 sendItemsToContainer(Arrays.asList(groupData), pizzeriaDeliveryContainer, RequestTimeout.DEFAULT, tx);
217 private void notifyDeliveryPizzaInProgress(PizzaOrder order, Pizza pizzaInProgress) throws MzsCoreException {
218 log.info("I say that I now prepare a delivery pizza for order {}", pizzaInProgress.getOrderId());
219 final DeliveryGroupData groupTemplate = new DeliveryGroupData();
220 final Order groupOrder = new Order();
221 groupOrder.setId(order.getOrderId());
222 groupTemplate.setOrder(groupOrder);
223 groupTemplate.setDeliveryStatus(null);
224 final TransactionReference inPreparationTx = getDefaultTransaction();
225 final DeliveryGroupData groupFromSpace = takeMatchingEntity(groupTemplate, pizzeriaDeliveryContainer, inPreparationTx, RequestTimeout.INFINITE, "Cannot take the delivery order from pizzeriaDeliveryContainer");
226 final List<PizzaOrder> orderedPizzas = groupFromSpace.getOrder().getOrderedPizzas();
227 for (PizzaOrder orderedPizza : orderedPizzas) {
228 if (orderedPizza.getId() == pizzaInProgress.getId()) {
229 orderedPizza.setStatus(PizzaOrderStatus.IN_PREPARATION);
230 orderedPizza.setCookId(pizzaInProgress.getCookId());
233 sendItemsToContainer(Arrays.asList(groupFromSpace), pizzeriaDeliveryContainer, RequestTimeout.DEFAULT, inPreparationTx);
234 sendItemsToContainer(Arrays.asList(pizzaInProgress), pizzaInProgressContainer, RequestTimeout.DEFAULT, inPreparationTx);
235 // log.info("before inprogress comit!");
236 capi.commitTransaction(inPreparationTx);
239 private void notifyCustomerPizzaInProgress(PizzaOrder order, Pizza pizzaInProgress) {
241 log.info("I say that I now prepare a pizza for order {}", pizzaInProgress.getOrderId());
242 final GroupData groupTemplate = new GroupData();
243 final Order groupOrder = new Order();
244 groupOrder.setId(order.getOrderId());
245 groupTemplate.setOrder(groupOrder);
246 groupTemplate.setState(null);
247 final TransactionReference inPreparationTx = getDefaultTransaction();
248 final GroupData groupFromSpace = takeMatchingEntity(groupTemplate, pizzeriaGroupContainer, inPreparationTx, RequestTimeout.INFINITE, "Cannot take the order from pizzeriaGroupContainer");
249 final List<PizzaOrder> orderedPizzas = groupFromSpace.getOrder().getOrderedPizzas();
250 for (PizzaOrder orderedPizza : orderedPizzas) {
251 if (orderedPizza.getId() == pizzaInProgress.getId()) {
252 orderedPizza.setStatus(PizzaOrderStatus.IN_PREPARATION);
253 orderedPizza.setCookId(pizzaInProgress.getCookId());
256 sendItemsToContainer(Arrays.asList(groupFromSpace), pizzeriaGroupContainer, RequestTimeout.DEFAULT, inPreparationTx);
257 sendItemsToContainer(Arrays.asList(pizzaInProgress), pizzaInProgressContainer, RequestTimeout.DEFAULT, inPreparationTx);
258 capi.commitTransaction(inPreparationTx);
259 } catch (Exception e) {
260 // log.error("This error has occurred: {}", e.getMessage());
261 // e.printStackTrace();
265 private PizzaOrder createPizza(PizzaOrder order) throws InterruptedException {
266 long duration = order.getPizzaType().duration;
267 if (! Util.runSimulation) {
268 Thread.sleep(duration * 1000);
271 PizzaOrder pizza = Pizza.createPizzaFromPizzaOrder(order, cookId, false);
272 pizza.setStatus(PizzaOrderStatus.DONE);