1 package at.ac.tuwien.sbc.valesriegler.xvsm;
3 import java.io.Serializable;
5 import java.util.ArrayList;
6 import java.util.Arrays;
7 import java.util.Collections;
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;
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;
25 public class WaiterXVSMConnector extends AbstractXVSMConnector {
26 private static final Logger log = LoggerFactory.getLogger(WaiterXVSMConnector.class);
28 public WaiterXVSMConnector() {
30 useFreeTablesContainer();
31 useAssignTableContainer();
33 useTakeOrderContainer();
38 public void listenForFreeTable() {
40 NotificationListener freeTableListener = new NotificationListener() {
42 public void entryOperationFinished(final Notification notification, final Operation operation, final List<? extends Serializable> entries) {
44 log.info("{} tables have become free", entries.size());
46 List<Table> tables = castEntries(entries);
47 Collections.shuffle(tables);
49 for (Table table : tables) {
51 TransactionReference tx = capi.createTransaction(3000, URI.create(Util.SERVER_ADDR));
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);
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));
61 log.info("Table with id {} was found", id);
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");
66 assignGroupToTable(lockedGroup, lockedFreeTable, tx);
68 } catch (IllegalArgumentException e) {
69 log.error("SHOULD NEVER HAPPEN!");
71 } catch (CountNotMetException e) {
72 log.error("SHOULD NEVER HAPPEN!");
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!");
81 log.info(e.getMessage());
83 capi.rollbackTransaction(tx);
85 } catch (Exception e) {
86 log.error("SHOULD NEVER HAPPEN!");
95 notificationMgr.createNotification(freeTablesContainer, freeTableListener, Operation.WRITE);
96 log.info("Created freeTablesContainer notification for a waiter");
97 } catch (MzsCoreException e) {
99 } catch (InterruptedException e) {
107 public void listenForNewGuests() {
108 NotificationListener newGroupsListener = new NotificationListener() {
110 public void entryOperationFinished(final Notification notification, final Operation operation, final List<? extends Serializable> entries) {
112 log.info("New guest groups have arrived");
114 List<GroupData> groups = castEntries(entries);
115 Collections.shuffle(groups);
117 for (GroupData group : groups) {
119 TransactionReference tx = capi.createTransaction(1500, URI.create(Util.SERVER_ADDR));
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());
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()));
129 assignGroupToTable(lockedGroup, lockedFreeTable, tx);
131 } catch (IllegalArgumentException e) {
132 log.error("SHOULD NEVER HAPPEN!");
134 } catch (CountNotMetException e) {
135 log.error("SHOULD NEVER HAPPEN!");
137 log.info(e.getMessage());
138 } catch (EntityNotFoundByTemplate e) {
139 // capi.rollbackTransaction(tx);
140 } catch (Exception e) {
141 log.error("SHOULD NEVER HAPPEN!");
143 log.info(e.getMessage());
145 capi.rollbackTransaction(tx);
147 } catch (Exception e) {
148 log.error("SHOULD NEVER HAPPEN!");
157 notificationMgr.createNotification(assignTableContainer, newGroupsListener, Operation.WRITE);
158 log.info("Created assingTableContainer notification for a waiter");
159 } catch (MzsCoreException e) {
161 } catch (InterruptedException e) {
166 public void listenForOrders() {
167 NotificationListener ordersListener = new NotificationListener() {
169 public void entryOperationFinished(final Notification notification, final Operation operation, final List<? extends Serializable> entries) {
170 log.info("A new order has arrived!");
172 List<GroupData> groups = castEntries(entries);
173 if(groups.size() != 1) throw new RuntimeException("Multiple orders in one notification?! That should not happen!");
175 GroupData groupData = groups.get(0);
176 groupData.setState(GroupState.ORDERED);
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");
194 notificationMgr.createNotification(takeOrderContainer, ordersListener, Operation.WRITE);
195 log.info("Created takeOrderContainer notification for a waiter");
196 } catch (MzsCoreException e) {
198 } catch (InterruptedException e) {
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);
210 // The new group now wants to order
211 lockedGroup.setState(GroupState.ORDER_PENDING);
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);
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!");