From ae666ca32a4de375f1684aed522f715feb7677ff Mon Sep 17 00:00:00 2001 From: Gregor Riegler Date: Thu, 9 May 2013 00:12:37 +0200 Subject: [PATCH] Show table and waiting group changes according to notifications in pizzeriaGUI and groupGUI --- README.md | 2 +- .../tuwien/sbc/valesriegler/group/Group.java | 16 +- .../sbc/valesriegler/group/GroupAgent.java | 20 +- .../group/gui/GroupOverviewModel.java | 5 +- .../valesriegler/pizzeria/PizzeriaAgent.java | 42 +-- .../gui/tablemodels/GroupsOverviewModel.java | 18 +- .../xvsm/AbstractXVSMConnector.java | 155 +++++++++ .../sbc/valesriegler/xvsm/GroupXVSM.java | 56 ++++ .../sbc/valesriegler/xvsm/PizzeriaXVSM.java | 83 +++++ .../xvsm/WaiterXVSMConnector.java | 184 ++++++++++ .../sbc/valesriegler/xvsm/XVSMConnector.java | 313 +----------------- .../sbc/valesriegler/xvsm/cook/Cook.java | 3 +- .../sbc/valesriegler/xvsm/waiter/Waiter.java | 11 +- 13 files changed, 539 insertions(+), 369 deletions(-) create mode 100644 src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/AbstractXVSMConnector.java create mode 100644 src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/GroupXVSM.java create mode 100644 src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/PizzeriaXVSM.java create mode 100644 src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/WaiterXVSMConnector.java diff --git a/README.md b/README.md index 5f077b4..c26b67b 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ Space Based Computing SS 2013 ================== ### How to start the Group GUI - mvn exec:java -Dexec.mainClass="at.ac.tuwien.sbc.valesriegler.group.GroupAgent" + mvn exec:java -Dexec.mainClass="at.ac.tuwien.sbc.valesriegler.group.GroupAgent" -Dmozartspaces.configurationFile="mozartspaces-client.xml" ### How to start the JMS Pizzeria GUI mvn exec:java -Dexec.mainClass="at.ac.tuwien.sbc.valesriegler.pizzeria.PizzeriaAgent" -Dexec.args="JMS" diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/group/Group.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/group/Group.java index 816b280..d078c82 100644 --- a/src/main/java/at/ac/tuwien/sbc/valesriegler/group/Group.java +++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/group/Group.java @@ -25,11 +25,8 @@ public class Group implements Runnable, HasId { private static final Logger log = LoggerFactory.getLogger(Group.class); private static int idNext = -1; // TODO: set to 0 after debugging! - final private GroupData groupData; + private GroupData groupData; - public GroupData getGroupData() { - return groupData; - } public Group() { groupData = new GroupData(++idNext); @@ -38,6 +35,8 @@ public class Group implements Runnable, HasId { public Group(Integer id) { groupData = new GroupData(id); } + + @Override public void run() { @@ -77,6 +76,15 @@ public class Group implements Runnable, HasId { e.printStackTrace(); } } + + + public void setGroupData(GroupData groupData) { + this.groupData = groupData; + } + + public GroupData getGroupData() { + return groupData; + } // lets go to the pizzaria. public void goGrabSomeFood() { diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/group/GroupAgent.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/group/GroupAgent.java index 08b4cfc..6ae4181 100644 --- a/src/main/java/at/ac/tuwien/sbc/valesriegler/group/GroupAgent.java +++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/group/GroupAgent.java @@ -11,11 +11,15 @@ import javax.swing.SwingUtilities; import org.mozartspaces.core.CapiUtil; import org.mozartspaces.core.Entry; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import at.ac.tuwien.sbc.valesriegler.common.Util; import at.ac.tuwien.sbc.valesriegler.group.gui.GroupOverviewModel; import at.ac.tuwien.sbc.valesriegler.group.jms.JMSGroupConnector; import at.ac.tuwien.sbc.valesriegler.types.GroupData; +import at.ac.tuwien.sbc.valesriegler.xvsm.AbstractXVSMConnector; +import at.ac.tuwien.sbc.valesriegler.xvsm.GroupXVSM; import at.ac.tuwien.sbc.valesriegler.xvsm.XVSMConnector; /** @@ -29,11 +33,12 @@ import at.ac.tuwien.sbc.valesriegler.xvsm.XVSMConnector; */ public class GroupAgent { - - public static GroupAgent groupAgent; + private static final Logger log = LoggerFactory.getLogger(GroupAgent.class); private GroupOverviewModel groupModel; private AbstractGroupConnector groupconn; - private XVSMConnector xvsm; + private GroupXVSM xvsm; + + public static GroupAgent groupAgent; public static void main(String[] args) { // TODO: use jms and xvsm manager here. @@ -49,10 +54,9 @@ public class GroupAgent { groupconn.init(); } else { - xvsm = new XVSMConnector(); - xvsm.initSpaceCommunication(); - xvsm.useGroupsContainer(); + xvsm = new GroupXVSM(); + xvsm.listenForGroupDataChanges(); } } @@ -75,7 +79,9 @@ public class GroupAgent { for (Group group : newGroups) { groupData.add(group.getGroupData()); } - xvsm.sendGroupsToSpace(groupData); + xvsm.sendNewGroupsToSpace(groupData); + + log.info("New Groups were sent to the space"); } } diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/group/gui/GroupOverviewModel.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/group/gui/GroupOverviewModel.java index 6933822..adf9167 100644 --- a/src/main/java/at/ac/tuwien/sbc/valesriegler/group/gui/GroupOverviewModel.java +++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/group/gui/GroupOverviewModel.java @@ -54,11 +54,11 @@ public class GroupOverviewModel extends TableModel { switch (wantedColumn) { case ID: int groupId = group.getGroupData().getId(); - log.info("This is the group id : {}", groupId); +// log.info("This is the group id : {}", groupId); return groupId; case SIZE: int groupSize = group.getGroupData().getSize(); - log.info("This is the size : {}", groupSize); +// log.info("This is the size : {}", groupSize); return groupSize; case PIZZAS: if (group.getGroupData().getOrder() == null) @@ -124,6 +124,7 @@ public class GroupOverviewModel extends TableModel { List groups = new ArrayList<>(); for (GroupData groupData : newItems) { Group group = items.get(groupData.getId()); + group.setGroupData(groupData); groups.add(group); } super.addItems(groups); diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/pizzeria/PizzeriaAgent.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/pizzeria/PizzeriaAgent.java index 76d73aa..f6be717 100644 --- a/src/main/java/at/ac/tuwien/sbc/valesriegler/pizzeria/PizzeriaAgent.java +++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/pizzeria/PizzeriaAgent.java @@ -22,7 +22,7 @@ import at.ac.tuwien.sbc.valesriegler.pizzeria.gui.tablemodels.TablesOverviewMode import at.ac.tuwien.sbc.valesriegler.pizzeria.gui.tablemodels.WaitersOfOrderModel; import at.ac.tuwien.sbc.valesriegler.types.GroupData; import at.ac.tuwien.sbc.valesriegler.types.Table; -import at.ac.tuwien.sbc.valesriegler.xvsm.XVSMConnector; +import at.ac.tuwien.sbc.valesriegler.xvsm.PizzeriaXVSM; /** * The Main class of the Pizzeria compoment. @@ -45,7 +45,7 @@ public class PizzeriaAgent { private WaitersOfOrderModel waitersModel; private PizzasOfOrderModel pizzasModel; - private XVSMConnector xvsm; + private PizzeriaXVSM xvsm; public static void main(String[] args) {// TODO: remove hardcoding of JMS. // if (args.length != 1) { @@ -78,40 +78,10 @@ public class PizzeriaAgent { } private void initXVSM() { - xvsm = new XVSMConnector(); - xvsm.initSpaceCommunication(); - xvsm.useTablesContainer(); - xvsm.useGroupsContainer(); - xvsm.useFreeTablesContainer(); - - NotificationListener tablesListener = new NotificationListener() { - @Override - public void entryOperationFinished(final Notification notification, final Operation operation, final List entries) { - log.info("Tables Change notified"); - - final List tables = new ArrayList<>(); - List entryList = (List) entries; - for (Entry entry : entryList) { - tables.add((Table) entry.getValue()); - } - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - PizzeriaAgent.getInstance().getTablesModel().addItems(tables); - } - }); - } - }; - - NotificationListener groupsListener = new NotificationListener() { - @Override - public void entryOperationFinished(final Notification notification, final Operation operation, final List entries) { - List groups = (List) entries; - PizzeriaAgent.getInstance().getGroupModel().addItems(groups); - } - }; -// xvsm.initTablesNotifications(tablesListener); - xvsm.initGroupNotifications(groupsListener); + xvsm = new PizzeriaXVSM(); + + xvsm.listenForTables(); + xvsm.listenForGroups(); } private void initGUI() { diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/pizzeria/gui/tablemodels/GroupsOverviewModel.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/pizzeria/gui/tablemodels/GroupsOverviewModel.java index 69ea92f..966cf22 100644 --- a/src/main/java/at/ac/tuwien/sbc/valesriegler/pizzeria/gui/tablemodels/GroupsOverviewModel.java +++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/pizzeria/gui/tablemodels/GroupsOverviewModel.java @@ -18,6 +18,22 @@ public class GroupsOverviewModel extends TableModel { protected String[] getColumns() { return COLUMNS; } + + @Override + public int getRowCount() { + List values = new ArrayList<>(items.values()); + Iterator it = values.iterator(); + while (it.hasNext()) { + GroupData groupData = it.next(); + // Show only the waiting groups! + // TODO what is the GroupState.NEW? + if(!(groupData.getState() == GroupState.NEW || groupData.getState() == GroupState.WAITING)) { + it.remove(); + } + } + + return values.size(); + } @Override public Object getValueAt(int rowIndex, int columnIndex) { @@ -26,7 +42,7 @@ public class GroupsOverviewModel extends TableModel { while (it.hasNext()) { GroupData groupData = it.next(); // Show only the waiting groups! - if(groupData.getState() != GroupState.WAITING) { + if(groupData.getState() != GroupState.NEW) { it.remove(); } } diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/AbstractXVSMConnector.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/AbstractXVSMConnector.java new file mode 100644 index 0000000..e317610 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/AbstractXVSMConnector.java @@ -0,0 +1,155 @@ +package at.ac.tuwien.sbc.valesriegler.xvsm; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.mozartspaces.capi3.AnyCoordinator; +import org.mozartspaces.capi3.Coordinator; +import org.mozartspaces.capi3.CountNotMetException; +import org.mozartspaces.capi3.LindaCoordinator; +import org.mozartspaces.capi3.LindaCoordinator.LindaSelector; +import org.mozartspaces.core.Capi; +import org.mozartspaces.core.CapiUtil; +import org.mozartspaces.core.ContainerReference; +import org.mozartspaces.core.DefaultMzsCore; +import org.mozartspaces.core.Entry; +import org.mozartspaces.core.MzsConstants.RequestTimeout; +import org.mozartspaces.core.MzsCore; +import org.mozartspaces.core.MzsCoreException; +import org.mozartspaces.core.TransactionReference; +import org.mozartspaces.notifications.NotificationManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.ac.tuwien.sbc.valesriegler.common.Util; +import at.ac.tuwien.sbc.valesriegler.types.GroupData; +import at.ac.tuwien.sbc.valesriegler.types.Table; + +public abstract class AbstractXVSMConnector { + private static final Logger log = LoggerFactory.getLogger(AbstractXVSMConnector.class); + + protected ContainerReference tablesContainer; + protected ContainerReference groupsContainer; + protected ContainerReference assignTableContainer; + protected ContainerReference takeOrderContainer; + private ContainerReference deliverPizzasContainer; + private ContainerReference paymentContainer; + protected ContainerReference freeTablesContainer; + protected Capi capi; + protected NotificationManager notificationMgr; + + public AbstractXVSMConnector() { + initSpaceCommunication(); + } + + public void initSpaceCommunication() { + try { + MzsCore core = DefaultMzsCore.newInstanceWithoutSpace(); + capi = new Capi(core); + notificationMgr = new NotificationManager(core); + } catch (Exception e) { + log.error("Space connection could not be established! Have you started the Space Server?"); + handleSpaceErrorAndTerminate(e); + } + } + + public void useTablesContainer() { + tablesContainer = useContainer(Util.TABLES_CONTAINER, createCoordinators(new AnyCoordinator(), new LindaCoordinator(false))) ; + } + + public void useTakeOrderContainer() { + takeOrderContainer = useContainer(Util.TAKE_ORDER, createCoordinators(new AnyCoordinator(), new LindaCoordinator(false))) ; + } + + public void useGroupsContainer() { + groupsContainer = useContainer(Util.GROUPS_CONTAINER, createCoordinators(new AnyCoordinator(), new LindaCoordinator(false))) ; + } + + public void useAssignTableContainer() { + assignTableContainer = useContainer(Util.ASSIGN_TABLE, createCoordinators(new AnyCoordinator(), new LindaCoordinator(false))) ; + } + + public void useFreeTablesContainer() { + freeTablesContainer = useContainer(Util.FREE_TABLES, createCoordinators(new AnyCoordinator(), new LindaCoordinator(false))); + } + + private ContainerReference useContainer(String containerName, List coordinators) { + try { + return Util.getOrCreateNamedContainer(Util.SERVER_ADDR, containerName, capi, coordinators); + } catch (MzsCoreException e) { + handleSpaceErrorAndTerminate(e); + } + + return null; + } + + private List createCoordinators(Coordinator... coordinator) { + return Arrays.asList(coordinator); + } + + protected void handleSpaceErrorAndTerminate(Exception e) { + log.error(e.getMessage()); + e.printStackTrace(); + System.exit(1); + } + + protected void sendItemsToContainer( + List items, ContainerReference cref) { + + try { + List entries = new ArrayList<>(); + for (Serializable item : items) { + entries.add(new Entry(item)); + } + capi.write(entries, cref); + } catch (Exception e) { + log.info(e.getMessage()); + e.printStackTrace(); + } + } + + @SuppressWarnings("unchecked") + protected T takeEntityByTemplateFromContainer( + T entity, ContainerReference ref, TransactionReference tx, long timeout, String errorMsg) + throws MzsCoreException { + try { + LindaSelector sel = LindaCoordinator.newSelector(entity, 1); + T singleEntity = null; + + ArrayList entities = capi.take(ref, sel, RequestTimeout.DEFAULT, tx); + + return (T) CapiUtil.getSingleEntry(entities); + } catch (CountNotMetException e) { + log.info(errorMsg); + capi.rollbackTransaction(tx); + + throw new EntityNotFoundByTemplate(errorMsg); + } + } + + protected List castEntries(List entries) { + List newList = new ArrayList(); + List newEntries = (List) entries; + for (Entry entry : newEntries) { + newList.add((T) entry.getValue()); + } + return newList; + } + + public void sendTablesToSpace(List
tables) { + sendItemsToContainer(tables, tablesContainer); + } + + public void sendFreeTablesToSpace(List
tables) { + sendItemsToContainer(tables, freeTablesContainer); + sendTablesToSpace(tables); + } + + public void sendNewGroupsToSpace(List newGroups) { + sendItemsToContainer(newGroups, groupsContainer); + sendItemsToContainer(newGroups, assignTableContainer); + } + +} \ No newline at end of file diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/GroupXVSM.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/GroupXVSM.java new file mode 100644 index 0000000..634619b --- /dev/null +++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/GroupXVSM.java @@ -0,0 +1,56 @@ +package at.ac.tuwien.sbc.valesriegler.xvsm; + +import java.io.Serializable; +import java.util.List; + +import javax.swing.SwingUtilities; + +import org.mozartspaces.core.MzsCoreException; +import org.mozartspaces.notifications.Notification; +import org.mozartspaces.notifications.NotificationListener; +import org.mozartspaces.notifications.Operation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.ac.tuwien.sbc.valesriegler.group.GroupAgent; +import at.ac.tuwien.sbc.valesriegler.types.GroupData; + +public class GroupXVSM extends AbstractXVSMConnector { + private static final Logger log = LoggerFactory.getLogger(GroupXVSM.class); + + public GroupXVSM() { + super(); + useGroupsContainer(); + useAssignTableContainer(); + } + + public void listenForGroupDataChanges() { + NotificationListener groupDataListener = new NotificationListener() { + @Override + public void entryOperationFinished(final Notification notification, final Operation operation, final List entries) { + + log.info("{} groups have changed", entries.size()); + + final List groups = castEntries(entries); + + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + GroupAgent.getInstance().getGroupModel().addGroupData(groups); + } + }); + } + }; + try { + notificationMgr.createNotification(groupsContainer, groupDataListener, Operation.WRITE); + log.info("Created groupsContainer notification for a waiter"); + } catch (MzsCoreException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } + +} diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/PizzeriaXVSM.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/PizzeriaXVSM.java new file mode 100644 index 0000000..4e48b4b --- /dev/null +++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/PizzeriaXVSM.java @@ -0,0 +1,83 @@ +package at.ac.tuwien.sbc.valesriegler.xvsm; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import javax.swing.SwingUtilities; + +import org.mozartspaces.core.Entry; +import org.mozartspaces.notifications.Notification; +import org.mozartspaces.notifications.NotificationListener; +import org.mozartspaces.notifications.Operation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.ac.tuwien.sbc.valesriegler.pizzeria.PizzeriaAgent; +import at.ac.tuwien.sbc.valesriegler.types.GroupData; +import at.ac.tuwien.sbc.valesriegler.types.Table; + +public class PizzeriaXVSM extends AbstractXVSMConnector { + private static final Logger log = LoggerFactory.getLogger(PizzeriaXVSM.class); + + public PizzeriaXVSM() { + super(); + useTablesContainer(); + useGroupsContainer(); + useFreeTablesContainer(); + } + + public void listenForTables() { + NotificationListener tablesListener = new NotificationListener() { + @Override + public void entryOperationFinished(final Notification notification, final Operation operation, final List entries) { + log.info("Tables Change notified"); + + final List
tables = castEntries(entries); + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + PizzeriaAgent.getInstance().getTablesModel().addItems(tables); + } + }); + } + }; + try { + notificationMgr.createNotification(tablesContainer, tablesListener, Operation.WRITE); + } catch (Exception e) { + handleSpaceErrorAndTerminate(e); + } + } + + public void listenForGroups() { + + NotificationListener groupsListener = new NotificationListener() { + @Override + public void entryOperationFinished(final Notification notification, final Operation operation, final List entries) { + final List groups = castEntries(entries); + + log.info("{} group changes!", groups.size()); + for (GroupData groupData : groups) { + log.info(groupData.toString()); + + } + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + PizzeriaAgent.getInstance().getGroupModel().addItems(groups); + } + }); + + } + }; + try { + notificationMgr.createNotification(groupsContainer, groupsListener, Operation.WRITE); + } catch (Exception e) { + handleSpaceErrorAndTerminate(e); + } + } + + +} diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/WaiterXVSMConnector.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/WaiterXVSMConnector.java new file mode 100644 index 0000000..8c91546 --- /dev/null +++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/WaiterXVSMConnector.java @@ -0,0 +1,184 @@ +package at.ac.tuwien.sbc.valesriegler.xvsm; + +import java.io.Serializable; +import java.net.URI; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.mozartspaces.capi3.CountNotMetException; +import org.mozartspaces.core.MzsCoreException; +import org.mozartspaces.core.TransactionReference; +import org.mozartspaces.core.MzsConstants.RequestTimeout; +import org.mozartspaces.notifications.Notification; +import org.mozartspaces.notifications.NotificationListener; +import org.mozartspaces.notifications.Operation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.ac.tuwien.sbc.valesriegler.common.Util; +import at.ac.tuwien.sbc.valesriegler.types.GroupData; +import at.ac.tuwien.sbc.valesriegler.types.GroupState; +import at.ac.tuwien.sbc.valesriegler.types.Table; + +public class WaiterXVSMConnector extends AbstractXVSMConnector { + private static final Logger log = LoggerFactory.getLogger(WaiterXVSMConnector.class); + + public WaiterXVSMConnector() { + super(); + useFreeTablesContainer(); + useAssignTableContainer(); + useTablesContainer(); + useTakeOrderContainer(); + useGroupsContainer(); + } + + public void listenForFreeTable() { + + NotificationListener freeTableListener = new NotificationListener() { + @Override + public void entryOperationFinished(final Notification notification, final Operation operation, final List entries) { + + log.info("{} tables have become free", entries.size()); + + List
tables = castEntries(entries); + Collections.shuffle(tables); + + for (Table table : tables) { + try { + TransactionReference tx = capi.createTransaction(RequestTimeout.INFINITE, URI.create(Util.SERVER_ADDR)); + + try { + // Acquire a lock for the free table in the FreeTableContainer + int id = table.getId(); + log.info("Try to find the table with id {}", id); + + Table lockedFreeTable = takeEntityByTemplateFromContainer(new Table(id), freeTablesContainer, tx, 1000, String.format("There was no free table found with id %d", id)); + + log.info("Table with id {} was found", id); + GroupData lockedGroup = takeEntityByTemplateFromContainer(new GroupData(), assignTableContainer, tx, 1000, "There is no group waiting for a table at the moment"); + + // The new group sits down at the table + lockedFreeTable.setGroupId(lockedGroup.getId()); + lockedGroup.setTable(lockedFreeTable); + + // The new group now wants to order + lockedGroup.setState(GroupState.ORDER_PENDING); + + sendItemsToContainer(Arrays.asList(lockedFreeTable), tablesContainer); + sendItemsToContainer(Arrays.asList(lockedGroup), groupsContainer); + sendItemsToContainer(Arrays.asList(lockedGroup), takeOrderContainer); + + log.info("Assigned Table to group with groupId {}", lockedGroup.getId()); + capi.commitTransaction(tx); + + } catch (IllegalArgumentException e) { + log.error("SHOULD NEVER HAPPEN!"); + System.exit(1); + } catch (CountNotMetException e) { + log.error("SHOULD NEVER HAPPEN!"); + System.exit(1); + log.info(e.getMessage()); + } catch (EntityNotFoundByTemplate e) { + // TODO check why another exception is thrown +// capi.rollbackTransaction(tx); + } catch (Exception e) { + log.error("SHOULD NEVER HAPPEN!"); + e.printStackTrace(); + log.info(e.getMessage()); + + capi.rollbackTransaction(tx); + } + } catch (Exception e) { + log.error("SHOULD NEVER HAPPEN!"); + + e.printStackTrace(); + } + + } + } + }; + try { + notificationMgr.createNotification(freeTablesContainer, freeTableListener, Operation.WRITE); + log.info("Created freeTablesContainer notification for a waiter"); + } catch (MzsCoreException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } + + + + public void listenForNewGuests() { + NotificationListener newGroupsListener = new NotificationListener() { + @Override + public void entryOperationFinished(final Notification notification, final Operation operation, final List entries) { + + log.info("New guest groups have arrived"); + + List groups = castEntries(entries); + Collections.shuffle(groups); + + for (GroupData group : groups) { + try { + TransactionReference tx = capi.createTransaction(1500, URI.create(Util.SERVER_ADDR)); + + try { + // Acquire a lock for the group in the AssignTableContainer + String groupNotFound = String.format("Group with id %d was already assigned a table by another waiter!", group.getId()); + GroupData lockedGroup = takeEntityByTemplateFromContainer(new GroupData(group.getId()), assignTableContainer, tx, 1000, groupNotFound); + // Acquire a lock for one free table in the TablesContainer + Table lockedFreeTable = takeEntityByTemplateFromContainer(new Table(), freeTablesContainer, tx, 1000, String.format("No free table for group with id %d could be found", group.getId())); + + // The new group sits down at the table + lockedFreeTable.setGroupId(lockedGroup.getId()); + lockedGroup.setTable(lockedFreeTable); + + // The new group now wants to order + lockedGroup.setState(GroupState.ORDER_PENDING); + + sendItemsToContainer(Arrays.asList(lockedFreeTable), tablesContainer); + sendItemsToContainer(Arrays.asList(lockedGroup), groupsContainer); + sendItemsToContainer(Arrays.asList(lockedGroup), takeOrderContainer); + + log.info("Assigned Table to group with groupId {}", lockedGroup.getId()); + capi.commitTransaction(tx); + + } catch (IllegalArgumentException e) { + log.error("SHOULD NEVER HAPPEN!"); + System.exit(1); + } catch (CountNotMetException e) { + log.error("SHOULD NEVER HAPPEN!"); + System.exit(1); + log.info(e.getMessage()); + } catch (EntityNotFoundByTemplate e) { +// capi.rollbackTransaction(tx); + } catch (Exception e) { + log.error("SHOULD NEVER HAPPEN!"); + e.printStackTrace(); + log.info(e.getMessage()); + + capi.rollbackTransaction(tx); + } + } catch (Exception e) { + log.error("SHOULD NEVER HAPPEN!"); + + e.printStackTrace(); + } + + } + } + }; + try { + notificationMgr.createNotification(assignTableContainer, newGroupsListener, Operation.WRITE); + log.info("Created assingTableContainer notification for a waiter"); + } catch (MzsCoreException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/XVSMConnector.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/XVSMConnector.java index df53848..2214022 100644 --- a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/XVSMConnector.java +++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/XVSMConnector.java @@ -8,25 +8,17 @@ import java.util.Collections; import java.util.List; import org.bouncycastle.crypto.RuntimeCryptoException; -import org.mozartspaces.capi3.AnyCoordinator; import org.mozartspaces.capi3.AnyCoordinator.AnySelector; -import org.mozartspaces.capi3.Coordinator; import org.mozartspaces.capi3.CountNotMetException; import org.mozartspaces.capi3.FifoCoordinator; import org.mozartspaces.capi3.LindaCoordinator; import org.mozartspaces.capi3.LindaCoordinator.LindaSelector; -import org.mozartspaces.core.Capi; -import org.mozartspaces.core.CapiUtil; -import org.mozartspaces.core.ContainerReference; -import org.mozartspaces.core.DefaultMzsCore; import org.mozartspaces.core.Entry; import org.mozartspaces.core.MzsConstants.RequestTimeout; -import org.mozartspaces.core.MzsCore; import org.mozartspaces.core.MzsCoreException; import org.mozartspaces.core.TransactionReference; import org.mozartspaces.notifications.Notification; import org.mozartspaces.notifications.NotificationListener; -import org.mozartspaces.notifications.NotificationManager; import org.mozartspaces.notifications.Operation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,80 +35,10 @@ import at.ac.tuwien.sbc.valesriegler.types.Table; * @author Gregor Riegler * */ -public class XVSMConnector { - private static final Logger log = LoggerFactory.getLogger(XVSMConnector.class); - - private ContainerReference tablesContainer; - private ContainerReference groupsContainer; - private ContainerReference assignTableContainer; - private ContainerReference takeOrderContainer; - private ContainerReference deliverPizzasContainer; - private ContainerReference paymentContainer; - private ContainerReference freeTablesContainer; -// private ContainerReference notificationContainer; - private Capi capi; - private NotificationManager notificationMgr; - - - - public void initSpaceCommunication() { - try { - MzsCore core = DefaultMzsCore.newInstanceWithoutSpace(); - capi = new Capi(core); - notificationMgr = new NotificationManager(core); - } catch (Exception e) { - log.error("Space connection could not be established! Have you started the Space Server?"); - handleSpaceErrorAndTerminate(e); - } - } - - public void useTablesContainer() { - tablesContainer = useContainer(Util.TABLES_CONTAINER, createCoordinators(new AnyCoordinator(), new LindaCoordinator(false))) ; - } - - public void useTakeOrderContainer() { - takeOrderContainer = useContainer(Util.TAKE_ORDER, createCoordinators(new AnyCoordinator(), new LindaCoordinator(false))) ; - } - - public void useGroupsContainer() { - groupsContainer = useContainer(Util.GROUPS_CONTAINER, createCoordinators(new AnyCoordinator(), new LindaCoordinator(false))) ; - } - - public void useAssignTableContainer() { - assignTableContainer = useContainer(Util.ASSIGN_TABLE, createCoordinators(new AnyCoordinator(), new LindaCoordinator(false))) ; - } - - public void useFreeTablesContainer() { - freeTablesContainer = useContainer(Util.FREE_TABLES, createCoordinators(new AnyCoordinator(), new LindaCoordinator(false))); - } - - - - private ContainerReference useContainer(String containerName, List coordinators) { - try { - return Util.getOrCreateNamedContainer(Util.SERVER_ADDR, containerName, capi, coordinators); - } catch (MzsCoreException e) { - handleSpaceErrorAndTerminate(e); - } - - return null; - } - - - public void sendTablesToSpace(List
tables) { - sendItemsToContainer(tables, tablesContainer); - } - - public void sendFreeTablesToSpace(List
tables) { - sendItemsToContainer(tables, freeTablesContainer); - sendTablesToSpace(tables); - } - - - public void sendGroupsToSpace(List newGroups) { - sendItemsToContainer(newGroups, groupsContainer); - } +public class XVSMConnector extends AbstractXVSMConnector { + static final Logger log = LoggerFactory.getLogger(XVSMConnector.class); + @Deprecated public void handleWaitingGroup(int id) { try { @@ -171,6 +93,7 @@ public class XVSMConnector { } } + @Deprecated public void handleOrderRequest(int id) { try { TransactionReference tx = capi.createTransaction(RequestTimeout.INFINITE, URI.create(Util.SERVER_ADDR)); @@ -222,235 +145,7 @@ public class XVSMConnector { handleSpaceErrorAndTerminate(e); } } - - public void handlePaymentRequest() { - } - - public void handlePizzaDistribution() { - } - - - private List createCoordinators(Coordinator... coordinator) { - return Arrays.asList(coordinator); - } - - private void handleSpaceErrorAndTerminate(Exception e) { - log.error(e.getMessage()); - e.printStackTrace(); - System.exit(1); - } - - - private void sendItemsToContainer(List items, ContainerReference cref) { - - try { - List entries = new ArrayList<>(); - for (Serializable item : items) { - entries.add(new Entry(item)); - } - capi.write(entries, cref); - } catch (Exception e) { - log.info(e.getMessage()); - e.printStackTrace(); - } - } - public void listenForFreeTable() { - - NotificationListener freeTableListener = new NotificationListener() { - @Override - public void entryOperationFinished(final Notification notification, final Operation operation, final List entries) { - - log.info("{} tables have become free", entries.size()); - - List
tables = castEntries(entries); - Collections.shuffle(tables); - - for (Table table : tables) { - try { - TransactionReference tx = capi.createTransaction(RequestTimeout.INFINITE, URI.create(Util.SERVER_ADDR)); - - try { - // Acquire a lock for the free table in the FreeTableContainer - int id = table.getId(); - log.info("Try to find the table with id {}", id); - - Table lockedFreeTable = takeEntityByTemplateFromContainer(new Table(id), freeTablesContainer, tx, 1000, String.format("There was no free table found with id %d", id)); - - log.info("Table with id {} was found", id); - GroupData lockedGroup = takeEntityByTemplateFromContainer(new GroupData(), assignTableContainer, tx, 1000, "There is no group waiting for a table at the moment"); - - // The new group sits down at the table - lockedFreeTable.setGroupId(lockedGroup.getId()); - lockedGroup.setTable(lockedFreeTable); - - // The new group now wants to order - lockedGroup.setState(GroupState.ORDER_PENDING); - - sendItemsToContainer(Arrays.asList(lockedFreeTable), tablesContainer); - sendItemsToContainer(Arrays.asList(lockedGroup), groupsContainer); - sendItemsToContainer(Arrays.asList(lockedGroup), takeOrderContainer); - - log.info("Assigned Table to group with groupId {}", lockedGroup.getId()); - capi.commitTransaction(tx); - - } catch (IllegalArgumentException e) { - log.error("SHOULD NEVER HAPPEN!"); - System.exit(1); - } catch (CountNotMetException e) { - log.error("SHOULD NEVER HAPPEN!"); - System.exit(1); - log.info(e.getMessage()); - } catch (EntityNotFoundByTemplate e) { - // TODO check why another exception is thrown -// capi.rollbackTransaction(tx); - } catch (Exception e) { - log.error("SHOULD NEVER HAPPEN!"); - e.printStackTrace(); - log.info(e.getMessage()); - - capi.rollbackTransaction(tx); - } - } catch (Exception e) { - log.error("SHOULD NEVER HAPPEN!"); - - e.printStackTrace(); - } - - } - } - }; - try { - notificationMgr.createNotification(freeTablesContainer, freeTableListener, Operation.WRITE); - log.info("Created freeTablesContainer notification for a waiter"); - } catch (MzsCoreException e) { - e.printStackTrace(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - } - - - public void listenForNewGuests() { - NotificationListener newGroupsListener = new NotificationListener() { - @Override - public void entryOperationFinished(final Notification notification, final Operation operation, final List entries) { - - log.info("New guest groups have arrived"); - - List groups = castEntries(entries); - Collections.shuffle(groups); - - for (GroupData group : groups) { - try { - TransactionReference tx = capi.createTransaction(1500, URI.create(Util.SERVER_ADDR)); - - try { - // Acquire a lock for the group in the AssignTableContainer - String groupNotFound = String.format("Group with id %d was already assigned a table by another waiter!", group.getId()); - GroupData lockedGroup = takeEntityByTemplateFromContainer(new GroupData(group.getId()), assignTableContainer, tx, 1000, groupNotFound); - // Acquire a lock for one free table in the TablesContainer - Table lockedFreeTable = takeEntityByTemplateFromContainer(new Table(), freeTablesContainer, tx, 1000, String.format("No free table for group with id %d could be found", group.getId())); - - // The new group sits down at the table - lockedFreeTable.setGroupId(lockedGroup.getId()); - lockedGroup.setTable(lockedFreeTable); - - // The new group now wants to order - lockedGroup.setState(GroupState.ORDER_PENDING); - - sendItemsToContainer(Arrays.asList(lockedFreeTable), tablesContainer); - sendItemsToContainer(Arrays.asList(lockedGroup), groupsContainer); - sendItemsToContainer(Arrays.asList(lockedGroup), takeOrderContainer); - - log.info("Assigned Table to group with groupId {}", lockedGroup.getId()); - capi.commitTransaction(tx); - - } catch (IllegalArgumentException e) { - log.error("SHOULD NEVER HAPPEN!"); - System.exit(1); - } catch (CountNotMetException e) { - log.error("SHOULD NEVER HAPPEN!"); - System.exit(1); - log.info(e.getMessage()); - } catch (EntityNotFoundByTemplate e) { -// capi.rollbackTransaction(tx); - } catch (Exception e) { - log.error("SHOULD NEVER HAPPEN!"); - e.printStackTrace(); - log.info(e.getMessage()); - - capi.rollbackTransaction(tx); - } - } catch (Exception e) { - log.error("SHOULD NEVER HAPPEN!"); - - e.printStackTrace(); - } - - } - } - }; - try { - notificationMgr.createNotification(assignTableContainer, newGroupsListener, Operation.WRITE); - log.info("Created assingTableContainer notification for a waiter"); - } catch (MzsCoreException e) { - e.printStackTrace(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - private GroupData getGroupWaitingForTable(GroupData group, - TransactionReference tx) throws MzsCoreException { - - - GroupData singleGroup = takeEntityByTemplateFromContainer(new GroupData(group.getId()), assignTableContainer, tx, 1000, String.format("Group with id %d was already assigned a table by another waiter!", group.getId())); - - - return singleGroup; - - } - - private Table getFreeTableForGroup(GroupData group, - TransactionReference tx) throws MzsCoreException { - - return takeEntityByTemplateFromContainer(new Table(), freeTablesContainer, tx, 1000, String.format("No free table for group with id %d could be found", group.getId())); - - - } - - @SuppressWarnings("unchecked") - private T takeEntityByTemplateFromContainer(T entity, ContainerReference ref, TransactionReference tx, long timeout, String errorMsg) throws MzsCoreException { - try { - LindaSelector sel = LindaCoordinator.newSelector(entity, 1); - T singleEntity = null; - - ArrayList entities = capi.take(ref, sel, RequestTimeout.DEFAULT, tx); - log.info("Returned {} entities", entities.size()); - - return (T) CapiUtil.getSingleEntry(entities); - } catch (CountNotMetException e) { - log.info(errorMsg); - capi.rollbackTransaction(tx); - - throw new EntityNotFoundByTemplate(errorMsg); - } - } - - - - private List castEntries(List entries) { - List newList = new ArrayList(); - List newEntries = (List) entries; - for (Entry entry : newEntries) { - newList.add((T) entry.getValue()); - } - return newList; - } - - - } diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/cook/Cook.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/cook/Cook.java index 59f7308..75e7264 100644 --- a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/cook/Cook.java +++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/cook/Cook.java @@ -3,6 +3,7 @@ package at.ac.tuwien.sbc.valesriegler.xvsm.cook; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import at.ac.tuwien.sbc.valesriegler.xvsm.AbstractXVSMConnector; import at.ac.tuwien.sbc.valesriegler.xvsm.XVSMConnector; public class Cook { @@ -10,7 +11,7 @@ public class Cook { private static final Logger log = LoggerFactory.getLogger(Cook.class); private int id; - private XVSMConnector xvsm; + private AbstractXVSMConnector xvsm; public static void main(String[] args) { if(args.length != 1) { diff --git a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/waiter/Waiter.java b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/waiter/Waiter.java index 8942ea7..36bedce 100644 --- a/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/waiter/Waiter.java +++ b/src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/waiter/Waiter.java @@ -16,6 +16,7 @@ import org.slf4j.LoggerFactory; import at.ac.tuwien.sbc.valesriegler.pizzeria.PizzeriaAgent; import at.ac.tuwien.sbc.valesriegler.types.GroupData; import at.ac.tuwien.sbc.valesriegler.types.Table; +import at.ac.tuwien.sbc.valesriegler.xvsm.WaiterXVSMConnector; import at.ac.tuwien.sbc.valesriegler.xvsm.XVSMConnector; /** @@ -29,7 +30,7 @@ public class Waiter implements Serializable { private static final Logger log = LoggerFactory.getLogger(Waiter.class); private int id; - private XVSMConnector xvsm; + private WaiterXVSMConnector xvsm; public static void main(String[] args) { if (args.length != 1) { @@ -49,13 +50,7 @@ public class Waiter implements Serializable { } private void start() { - xvsm = new XVSMConnector(); - xvsm.initSpaceCommunication(); - - xvsm.useFreeTablesContainer(); - xvsm.useAssignTableContainer(); - xvsm.useTablesContainer(); - xvsm.useTakeOrderContainer(); + xvsm = new WaiterXVSMConnector(); // when new guests arrive the waiter should try to assign a table to them xvsm.listenForNewGuests(); -- 2.43.0