]> git.somenet.org - pub/jan/sbc.git/blob - src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/AbstractXVSMConnector.java
Make cook and waiter look around for work to do if they are idle
[pub/jan/sbc.git] / src / main / java / at / ac / tuwien / sbc / valesriegler / xvsm / AbstractXVSMConnector.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.Date;
8 import java.util.List;
9
10 import org.mozartspaces.capi3.AnyCoordinator;
11 import org.mozartspaces.capi3.Coordinator;
12 import org.mozartspaces.capi3.CountNotMetException;
13 import org.mozartspaces.capi3.LindaCoordinator;
14 import org.mozartspaces.capi3.LindaCoordinator.LindaSelector;
15 import org.mozartspaces.core.Capi;
16 import org.mozartspaces.core.CapiUtil;
17 import org.mozartspaces.core.ContainerReference;
18 import org.mozartspaces.core.DefaultMzsCore;
19 import org.mozartspaces.core.Entry;
20 import org.mozartspaces.core.MzsConstants;
21 import org.mozartspaces.core.MzsCore;
22 import org.mozartspaces.core.MzsCoreException;
23 import org.mozartspaces.core.MzsTimeoutException;
24 import org.mozartspaces.core.TransactionReference;
25 import org.mozartspaces.notifications.NotificationManager;
26 import org.mozartspaces.notifications.Operation;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 import at.ac.tuwien.sbc.valesriegler.common.HasId;
31 import at.ac.tuwien.sbc.valesriegler.common.Util;
32 import at.ac.tuwien.sbc.valesriegler.types.GroupData;
33
34 public abstract class AbstractXVSMConnector {
35         public static Object lockObject = new Object();
36         public static long timeOflastOperation = new Date().getTime();
37         
38         private static final Logger log = LoggerFactory.getLogger(AbstractXVSMConnector.class);
39
40         protected ContainerReference tableAssignedContainer;
41         protected ContainerReference assignTableContainer;
42         protected ContainerReference takeOrderContainer;
43         protected ContainerReference orderTakenContainer;
44         protected ContainerReference preparePizzasContainer;
45         protected ContainerReference deliverPizzasContainer;
46         protected ContainerReference paymentRequestContainer;
47         protected ContainerReference freeTablesContainer;
48         protected ContainerReference pizzaInProgressContainer;
49         protected ContainerReference orderCompleteContainer;
50         protected ContainerReference isEatingContainer;
51         protected ContainerReference paymentDoneContainer;
52         protected Capi capi;
53         protected NotificationManager notificationMgr;
54
55         public AbstractXVSMConnector() {
56                 initSpaceCommunication();
57         }
58
59         public void initSpaceCommunication() {
60                 try {
61                         MzsCore core = DefaultMzsCore.newInstanceWithoutSpace();
62                         capi = new Capi(core);
63                         notificationMgr = new NotificationManager(core);
64                 } catch (Exception e) {
65                         log.error("Space connection could not be established! Have you started the Space Server?");
66                         handleSpaceErrorAndTerminate(e);
67                 }
68         }
69         
70         protected ContainerReference useContainer(String containerName) {
71                 try {
72                         return CapiUtil.lookupOrCreateContainer(containerName, URI.create(Util.SERVER_ADDR), createCoordinators(new AnyCoordinator(), new LindaCoordinator(false)), null, capi);
73                 } catch (MzsCoreException e) {
74                         handleSpaceErrorAndTerminate(e);
75                 }
76                 
77                 throw new RuntimeException("Could not Create container " + containerName);
78         }
79
80         protected List<Coordinator> createCoordinators(Coordinator... coordinator) {
81                 return Arrays.asList(coordinator);
82         }
83
84         protected void handleSpaceErrorAndTerminate(Exception e) {
85                 log.error(e.getMessage());
86                 e.printStackTrace();
87                 System.exit(1);
88         }
89         
90         protected void createNotification(SpaceListener listener,
91                         ContainerReference cref) {
92                 listener.startHandlingAbsenceOfNotifications();
93                 try {
94                         notificationMgr.createNotification(cref, listener, Operation.WRITE);
95                 } catch (Exception e) {
96                         handleSpaceErrorAndTerminate(e);
97                 }
98         }
99
100         protected <T extends Serializable> void sendItemsToContainer(
101                 List<T> items, ContainerReference cref, long timeout, TransactionReference tx) {
102                         
103                         try {
104                                 List<Entry> entries = new ArrayList<>();
105                                 for (Serializable item : items) {
106                                         entries.add(new Entry(item));
107                                 }
108                                 capi.write(entries, cref, timeout, tx);
109                         } catch (Exception e) {
110                                 log.info(e.getMessage());
111                                 e.printStackTrace();
112                         }
113                 }
114
115         @SuppressWarnings("unchecked")
116         protected <T extends Serializable> T takeMatchingEntity(
117                         T entity, ContainerReference ref, TransactionReference tx, long timeout, String errorMsg)
118                         throws MzsCoreException {
119                                 try {
120                                         LindaSelector sel = LindaCoordinator.newSelector(entity, 1);
121                                         
122                                         ArrayList<Serializable> entities = capi.take(ref,  sel, timeout, tx);
123                                         
124                                         return (T) CapiUtil.getSingleEntry(entities);
125                                 } catch (CountNotMetException e) {
126                                         capi.rollbackTransaction(tx);
127                                         
128                                         throw new EntityNotFoundByTemplate(errorMsg);
129                                 } catch(MzsTimeoutException e) {
130                                         capi.rollbackTransaction(tx);
131                                         
132                                         throw new EntityNotFoundByTemplate(errorMsg);
133                                 }
134                         }
135         
136         protected <T extends Serializable> List<T> takeMatchingEntities(
137                         T entity, ContainerReference ref, TransactionReference tx, long timeout, String errorMsg)
138                         throws MzsCoreException {
139                                 try {
140                                         LindaSelector sel = LindaCoordinator.newSelector(entity, MzsConstants.Selecting.COUNT_MAX);
141                                         
142                                         ArrayList<Serializable> entities = capi.take(ref,  sel, timeout, tx);
143                                         
144                                         return (List<T>) entities;
145                                 } catch (CountNotMetException e) {
146                                         capi.rollbackTransaction(tx);
147                                         
148                                         throw new EntityNotFoundByTemplate(errorMsg);
149                                 } catch(MzsTimeoutException e) {
150                                         capi.rollbackTransaction(tx);
151                                         
152                                         throw new EntityNotFoundByTemplate(errorMsg);
153                                 }
154                         }
155
156         protected <T extends Serializable> List<T> castEntries(List<? extends Serializable> entries) {
157                 List<T> newList = new ArrayList<T>();
158                 if(entries.size() == 0) return newList;
159                 
160                 Serializable firstEntry = entries.get(0);
161                 if (firstEntry instanceof Entry) {
162                         
163                         List<Entry> newEntries = (List<Entry>) entries;
164                         for (Entry entry : newEntries) {
165                                 newList.add((T) entry.getValue());
166                         }
167                         return newList;
168                 } else {
169                         return (List<T>) entries;
170                 }
171         }
172         
173         
174         protected <T extends HasId> T getSingleEntity(final List<T> entities) {
175                 if(entities.size() != 1) {
176                 throw new RuntimeException("Only one entity was expected!");
177         }
178        return entities.get(0);
179         }
180         
181         protected<T extends Serializable> GroupData getSingleGroup(final List<T> entities) {
182                 List<GroupData> groups = castEntries(entities);
183                 if(groups.size() != 1) {
184                 throw new RuntimeException("Only one group was expected!");
185         }
186        return groups.get(0);
187         }
188 }