]> git.somenet.org - pub/jan/sbc.git/blob - src/main/java/at/ac/tuwien/sbc/valesriegler/xvsm/AbstractXVSMConnector.java
[XVSM] Crucial container communication changes
[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 at.ac.tuwien.sbc.valesriegler.common.HasId;
4 import at.ac.tuwien.sbc.valesriegler.common.Util;
5 import at.ac.tuwien.sbc.valesriegler.types.GroupData;
6 import at.ac.tuwien.sbc.valesriegler.xvsm.spacehelpers.SpaceListenerImplBuilder;
7 import org.mozartspaces.capi3.Coordinator;
8 import org.mozartspaces.capi3.CountNotMetException;
9 import org.mozartspaces.capi3.FifoCoordinator;
10 import org.mozartspaces.capi3.LindaCoordinator;
11 import org.mozartspaces.capi3.LindaCoordinator.LindaSelector;
12 import org.mozartspaces.core.*;
13 import org.mozartspaces.notifications.NotificationManager;
14 import org.slf4j.Logger;
15 import org.slf4j.LoggerFactory;
16
17 import java.io.Serializable;
18 import java.net.URI;
19 import java.util.*;
20 import java.util.concurrent.atomic.AtomicLong;
21
22 public abstract class AbstractXVSMConnector {
23     public static Object lockObject = new Object();
24     public static AtomicLong timeOflastOperation = new AtomicLong(new Date().getTime());
25
26     private static final Logger log = LoggerFactory.getLogger(AbstractXVSMConnector.class);
27
28     protected ContainerReference tableAssignedContainer;
29     protected ContainerReference assignTableContainer;
30     protected ContainerReference takeOrderContainer;
31     protected ContainerReference orderTakenContainer;
32     protected ContainerReference deliveryOrderTakenContainer;
33     protected ContainerReference preparePizzasContainer;
34     protected ContainerReference prepareDeliveryPizzasContainer;
35     protected ContainerReference preparedPizzasContainer;
36     protected ContainerReference preparedDeliveryPizzasContainer;
37     protected ContainerReference paymentRequestContainer;
38     protected ContainerReference freeTablesContainer;
39     protected ContainerReference pizzaInProgressContainer;
40     protected ContainerReference orderDeliveredContainer;
41     protected ContainerReference paymentDoneContainer;
42     protected ContainerReference pizzeriaInfoContainer;
43     protected ContainerReference phoneCallsContainer;
44     protected ContainerReference groupAgentInfoContainer;
45     protected ContainerReference deliverDeliveryOrderContainer;
46     protected ContainerReference pizzeriaGroupContainer;
47     protected ContainerReference pizzeriaDeliveryContainer;
48     protected ContainerReference pizzeriaTableContainer;
49
50     protected Capi capi;
51     protected NotificationManager notificationMgr;
52     protected int port;
53
54     private HashMap<String, ContainerReference> containers = new HashMap<String, ContainerReference>();
55
56     public AbstractXVSMConnector(int port) {
57         this.port = port;
58         initSpaceCommunication(port);
59     }
60
61     public void initSpaceCommunication(int port) {
62         try {
63 //            Configuration config = CommonsXmlConfiguration.load(0);
64 //            config.setEmbeddedSpace(false);
65             MzsCore core = DefaultMzsCore.newInstanceWithoutSpace();
66             capi = new Capi(core);
67             notificationMgr = new NotificationManager(core);
68         } catch (Exception e) {
69             log.error("Space connection could not be established! Have you started the Space Server?");
70             Util.handleSpaceErrorAndTerminate(e);
71         }
72     }
73
74     protected ContainerReference useContainer(String containerName) {
75         return useContainerOfSpaceWithPort(containerName, port);
76     }
77
78     protected ContainerReference useContainerOfSpaceWithPort(String containerName, int spacePort) {
79         String key = containerName + port;
80         ContainerReference container = containers.get(key);
81         if(container != null) return container;
82
83         try {
84             final String address = String.format(Util.SERVER_ADDR, spacePort);
85             container = CapiUtil.lookupOrCreateContainer(containerName, URI.create(address), createCoordinators(new FifoCoordinator(), new LindaCoordinator(false)), null, capi);
86             containers.put(key, container);
87             return container;
88         } catch (MzsCoreException e) {
89             Util.handleSpaceErrorAndTerminate(e);
90         }
91
92         throw new RuntimeException("Could not Create container " + containerName);
93     }
94
95     protected List<Coordinator> createCoordinators(Coordinator... coordinator) {
96         return Arrays.asList(coordinator);
97     }
98
99     protected <T extends Serializable> void sendItemsToContainer(
100             List<T> items, ContainerReference cref, long timeout, TransactionReference tx) {
101
102         try {
103             List<Entry> entries = new ArrayList<>();
104             for (Serializable item : items) {
105                 entries.add(new Entry(item));
106             }
107             capi.write(entries, cref, timeout, tx);
108         } catch (Exception e) {
109             log.info(e.getMessage());
110             e.printStackTrace();
111         }
112     }
113
114     @SuppressWarnings("unchecked")
115     /**
116      * Searches for one entity matching the given template object by linda selection.
117      */
118     protected <T extends Serializable> T takeMatchingEntity(
119             T entity, ContainerReference ref, TransactionReference tx, long timeout, String errorMsg)
120             throws MzsCoreException {
121         try {
122             LindaSelector sel = LindaCoordinator.newSelector(entity, 1);
123
124             ArrayList<Serializable> entities = capi.take(ref, sel, timeout, tx);
125
126             return (T) CapiUtil.getSingleEntry(entities);
127         } catch (CountNotMetException e) {
128             capi.rollbackTransaction(tx);
129
130             throw new EntityNotFoundByTemplate(errorMsg);
131         } catch (MzsTimeoutException e) {
132             capi.rollbackTransaction(tx);
133
134             throw new EntityNotFoundByTemplate(errorMsg);
135         }
136     }
137
138     protected <T extends Serializable> T takeMatchingEntityIfItExists(
139             T entity, ContainerReference ref, TransactionReference tx, long timeout)
140             throws MzsCoreException {
141         try {
142             LindaSelector sel = LindaCoordinator.newSelector(entity, 1);
143
144             ArrayList<Serializable> entities = capi.take(ref, sel, timeout, tx);
145
146             return (T) CapiUtil.getSingleEntry(entities);
147         } catch (CountNotMetException e) {
148         } catch (MzsTimeoutException e) {
149             capi.rollbackTransaction(tx);
150
151             throw new EntityNotFoundByTemplate();
152         }
153
154         return null;
155     }
156
157     /**
158      * Searches for all entities matching the given template object by linda selection and takes them.
159      */
160     protected <T extends Serializable> List<T> takeMatchingEntities(
161             T entity, ContainerReference ref, TransactionReference tx, long timeout, String errorMsg)
162             throws MzsCoreException {
163         try {
164             LindaSelector sel = LindaCoordinator.newSelector(entity, MzsConstants.Selecting.COUNT_MAX);
165
166             ArrayList<Serializable> entities = capi.take(ref, sel, timeout, tx);
167
168             return (List<T>) entities;
169         } catch (CountNotMetException e) {
170             capi.rollbackTransaction(tx);
171
172             throw new EntityNotFoundByTemplate(errorMsg);
173         } catch (MzsTimeoutException e) {
174             capi.rollbackTransaction(tx);
175
176             throw new EntityNotFoundByTemplate(errorMsg);
177         }
178     }
179
180     /**
181      * Searches for all entities matching the given template object by linda selection and reads them.
182      */
183     protected <T extends Serializable> List<T> readMatchingEntities(
184             T entity, ContainerReference ref, TransactionReference tx, long timeout, String errorMsg)
185             throws MzsCoreException {
186         try {
187             LindaSelector sel = LindaCoordinator.newSelector(entity, MzsConstants.Selecting.COUNT_MAX);
188
189             ArrayList<Serializable> entities = capi.read(ref, sel, timeout, tx);
190
191             return (List<T>) entities;
192         } catch (CountNotMetException e) {
193             capi.rollbackTransaction(tx);
194
195             throw new EntityNotFoundByTemplate(errorMsg);
196         } catch (MzsTimeoutException e) {
197             capi.rollbackTransaction(tx);
198
199             throw new EntityNotFoundByTemplate(errorMsg);
200         }
201     }
202     protected <T extends Serializable> List<T> castEntries(List<? extends Serializable> entries) {
203         List<T> newList = new ArrayList<T>();
204         if (entries.size() == 0) return newList;
205
206         Serializable firstEntry = entries.get(0);
207         if (firstEntry instanceof Entry) {
208
209             List<Entry> newEntries = (List<Entry>) entries;
210             for (Entry entry : newEntries) {
211                 newList.add((T) entry.getValue());
212             }
213             return newList;
214         } else {
215             return (List<T>) entries;
216         }
217     }
218
219
220     protected <T extends HasId> T getSingleEntity(final List<T> entities) {
221         if (entities.size() != 1) {
222             throw new RuntimeException("Only one entity was expected!");
223         }
224         return entities.get(0);
225     }
226
227     protected <T extends Serializable> GroupData getSingleGroup(final List<T> entities) {
228         List<GroupData> groups = castEntries(entities);
229         if (groups.size() != 1) {
230             throw new RuntimeException("Only one group was expected!");
231         }
232         return groups.get(0);
233     }
234
235     protected TransactionReference getDefaultTransaction() throws MzsCoreException {
236         return capi.createTransaction(
237                 Util.SPACE_TRANSACTION_TIMEOUT,
238                 URI.create(String.format(Util.SERVER_ADDR, port)));
239     }
240
241     protected SpaceListenerImplBuilder getDefaultBuilder() {
242         return new SpaceListenerImplBuilder().setCapi(capi).setNotificationManager(notificationMgr);
243     }
244 }