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