]> git.somenet.org - pub/jan/sbc.git/blob - src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/WaiterXVSM.java
Space cooks prepare pizzas and Pizzeria GUI shows that
[pub/jan/sbc.git] / src / main / java / at / ac / tuwien / sbc / valesriegler / xvsm / WaiterXVSM.java
1 package at.ac.tuwien.sbc.valesriegler.xvsm;
2
3 import java.io.Serializable;
4 import java.net.URI;
5 import java.util.ArrayList;
6 import java.util.Arrays;
7 import java.util.Collections;
8 import java.util.List;
9
10 import org.mozartspaces.capi3.CountNotMetException;
11 import org.mozartspaces.core.MzsConstants.RequestTimeout;
12 import org.mozartspaces.core.MzsCoreException;
13 import org.mozartspaces.core.MzsTimeoutException;
14 import org.mozartspaces.core.TransactionException;
15 import org.mozartspaces.core.TransactionReference;
16 import org.mozartspaces.notifications.Notification;
17 import org.mozartspaces.notifications.NotificationListener;
18 import org.mozartspaces.notifications.Operation;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21
22 import at.ac.tuwien.sbc.valesriegler.common.Util;
23 import at.ac.tuwien.sbc.valesriegler.types.GroupData;
24 import at.ac.tuwien.sbc.valesriegler.types.GroupState;
25 import at.ac.tuwien.sbc.valesriegler.types.Order;
26 import at.ac.tuwien.sbc.valesriegler.types.OrderStatus;
27 import at.ac.tuwien.sbc.valesriegler.types.PizzaOrder;
28 import at.ac.tuwien.sbc.valesriegler.types.Table;
29
30 public class WaiterXVSM extends AbstractXVSMConnector {
31         private static final Logger log = LoggerFactory.getLogger(WaiterXVSM.class);
32         private final int waiterId;
33         
34         public WaiterXVSM(int waiterId) {
35                 super();
36                 
37                 this.waiterId = waiterId;
38                 
39                 useFreeTablesContainer();
40                 useAssignTableContainer();
41                 useTablesContainer();
42                 useTakeOrderContainer();
43                 useOrdersContainer();
44                 usePreparePizzasContainer();
45                 useGroupsContainer();
46         }
47         
48         public void listenForFreeTable() {
49                         
50                 NotificationListener freeTableListener = new NotificationListener() {
51             @Override
52             public void entryOperationFinished(final Notification notification, final Operation operation, final List<? extends Serializable> entries) {
53                
54                                 log.info("{} tables have become free", entries.size());
55                                 
56                                 List<Table> tables = castEntries(entries);
57                                 Collections.shuffle(tables);
58                                 
59                                 for (Table table : tables) {
60                                         try {
61                                                 TransactionReference tx = capi.createTransaction(3000, URI.create(Util.SERVER_ADDR));
62                                                 
63                                                 try {
64                                                         // Acquire a lock for the free table in the FreeTableContainer
65                                                         int id = table.getId();
66                                                         log.info("Try to find the table with id {}", id);
67                                                 
68                                                         Table tableTemplate = new Table(id);
69                                                         Table lockedFreeTable = takeEntityByTemplateFromContainer(tableTemplate, freeTablesContainer, tx, 1000, String.format("There was no free table found with id %d", id));
70                                                         
71                                                         log.info("Table with id {} was found", id);
72                                                         
73                                                         GroupData groupTemplate = new GroupData();
74                                                         GroupData lockedGroup = takeEntityByTemplateFromContainer(groupTemplate, assignTableContainer, tx, RequestTimeout.DEFAULT, "There is no group waiting for a table at the moment");
75                                         
76                                                         assignGroupToTable(lockedGroup, lockedFreeTable, tx);
77                                                         
78                                                 } catch (IllegalArgumentException e) {
79                                                         log.info("IllegalArgumentException");
80                                                         e.printStackTrace();
81                                                 } catch (EntityNotFoundByTemplate e) {
82                                                         log.info(e.getMessage());
83                                                 }  catch (Exception e) {
84                                                         log.error("AN INNER EXCEPTION");
85                                                         e.printStackTrace();
86                                                 }
87                                         } catch (TransactionException e) {
88                                                 log.info("An unimportant TransactionException has occurred");
89                                         } catch (Exception e) {
90                                                 log.error("OUTER EXCEPTION");
91                                         }
92                                         
93                                 }
94             }
95         };
96         try {
97                         notificationMgr.createNotification(freeTablesContainer, freeTableListener, Operation.WRITE);
98                         log.info("Created freeTablesContainer notification for a waiter");
99         } catch (Exception e) {
100                         handleSpaceErrorAndTerminate(e);
101                 }
102                         
103         }
104         
105         public void listenForNewGuests() {
106                 NotificationListener newGroupsListener = new NotificationListener() {
107             @Override
108             public void entryOperationFinished(final Notification notification, final Operation operation, final List<? extends Serializable> entries) {
109                
110                                 log.info("New guest groups have arrived");
111                                 
112                                 List<GroupData> groups = castEntries(entries);
113                                 Collections.shuffle(groups);
114                                 
115                                 for (GroupData group : groups) {
116                                         try {
117                                                 TransactionReference tx = capi.createTransaction(1500, URI.create(Util.SERVER_ADDR));
118                                                 
119                                                 try {
120                                                         // Acquire a lock for the group in the AssignTableContainer
121                                                         String groupNotFound = String.format("Group with id %d was already assigned a table by another waiter!", group.getId());
122                                                         
123                                                         GroupData lockedGroup = takeEntityByTemplateFromContainer(new GroupData(group.getId()), assignTableContainer, tx, 1000, groupNotFound);
124                                                         // Acquire a lock for one free table in the TablesContainer
125                                                         Table lockedFreeTable = takeEntityByTemplateFromContainer(new Table(null), freeTablesContainer, tx, RequestTimeout.DEFAULT, String.format("No free table for group with id %d could be found", group.getId()));
126                                                         
127                                                         assignGroupToTable(lockedGroup, lockedFreeTable, tx);
128                                                         
129                                                 } catch (IllegalArgumentException e) {
130                                                         log.info("IllegalArgumentException");
131                                                         e.printStackTrace();
132                                                 } catch (EntityNotFoundByTemplate e) {
133                                                         log.info(e.getMessage());
134                                                 }  catch (Exception e) {
135                                                         log.error("AN INNER EXCEPTION");
136                                                         e.printStackTrace();
137                                                 }
138                                         } catch (TransactionException e) {
139                                                 log.info("An unimportant TransactionException has occurred");
140                                         } catch (Exception e) {
141                                                 log.error("OUTER EXCEPTION");
142                                         }
143                                         
144                                 }
145             }
146         };
147         try {
148                         notificationMgr.createNotification(assignTableContainer, newGroupsListener, Operation.WRITE);
149                         log.info("Created assingTableContainer notification for a waiter");
150         } catch (Exception e) {
151                         handleSpaceErrorAndTerminate(e);
152                 }
153         }
154
155         public void listenForOrders() {
156                 NotificationListener ordersListener = new NotificationListener() {
157             @Override
158             public void entryOperationFinished(final Notification notification, final Operation operation, final List<? extends Serializable> entries) {
159                log.info("A new order has arrived!");
160                
161                List<GroupData> groups = castEntries(entries);
162                if(groups.size() != 1) throw new RuntimeException("Multiple orders in one notification?! That should not happen!");
163                
164                GroupData groupData = groups.get(0);
165                
166                try {
167                         TransactionReference tx = capi.createTransaction(1500, URI.create(Util.SERVER_ADDR));
168                         GroupData entity = new GroupData(groupData.getId());
169                         entity.setState(GroupState.ORDER_PENDING);
170                         takeEntityByTemplateFromContainer(entity, takeOrderContainer, tx, RequestTimeout.DEFAULT, String.format("The order for group %d was already taken by an other waiter!", groupData.getId()));
171                    
172                   
173                                         log.info("Will now write taken order from group {} to space", groupData.getId());
174                                         groupData.setOrderWaiter(waiterId);
175                                         groupData.setState(GroupState.ORDERED);
176                                         Order order = groupData.getOrder();
177                                         order.setStatus(OrderStatus.ORDERED);
178                                         
179                                         sendItemsToContainer(Arrays.asList(groupData), ordersContainer, RequestTimeout.ZERO, tx);                                       
180                                         sendItemsToContainer(Arrays.asList(groupData), groupsContainer, RequestTimeout.ZERO, tx);
181                                         sendItemsToContainer(order.getOrderedPizzas(), preparePizzasContainer, RequestTimeout.ZERO, tx);
182                                         capi.commitTransaction(tx);
183                         
184                    
185                                         log.info("Waiter has taken order from group {}", groupData.getId());
186                } catch (MzsCoreException e) {
187                    log.info("ERROR in listenForOrders");
188                    e.printStackTrace();
189                }
190             }
191                 };
192                 
193         try {
194                         notificationMgr.createNotification(takeOrderContainer, ordersListener, Operation.WRITE);
195                         log.info("Created takeOrderContainer notification for a waiter");
196                 } catch (Exception e) {
197                         handleSpaceErrorAndTerminate(e);
198                 }
199         }
200         
201         public void listenForPreparedPizzas() {
202                 
203         }
204
205         private void assignGroupToTable(GroupData lockedGroup,
206                         Table lockedFreeTable, TransactionReference tx)
207                         throws MzsCoreException {
208                 // The new group sits down at the table
209                 lockedFreeTable.setGroupId(lockedGroup.getId());
210
211                 
212                 // The new group now wants to order
213                 lockedGroup.setState(GroupState.ORDER_PENDING);
214                 lockedGroup.setTable(lockedFreeTable);
215                 lockedGroup.setTableWaiter(waiterId);
216                 
217                 sendItemsToContainer(Arrays.asList(lockedFreeTable), tablesContainer, RequestTimeout.ZERO, tx);
218                 sendItemsToContainer(Arrays.asList(lockedGroup), takeOrderContainer, RequestTimeout.ZERO, tx);
219                 sendItemsToContainer(Arrays.asList(lockedGroup), groupsContainer, RequestTimeout.ZERO, tx);
220                 
221                 try {
222                         capi.commitTransaction(tx);
223                         log.info("Assigned table to group with groupId {}", lockedGroup.getId());
224                 } catch (Exception e) {
225                         log.info("Assigning a table to group with groupId {} failed", lockedGroup.getId());
226                 }
227                 
228         }
229
230
231
232 }