1 package at.ac.tuwien.sbc.valesriegler.xvsm;
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;
17 import java.io.Serializable;
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.Date;
22 import java.util.List;
23 import java.util.concurrent.atomic.AtomicLong;
25 public abstract class AbstractXVSMConnector {
26 public static Object lockObject = new Object();
27 public static AtomicLong timeOflastOperation = new AtomicLong(new Date().getTime());
29 private static final Logger log = LoggerFactory.getLogger(AbstractXVSMConnector.class);
31 protected ContainerReference tableAssignedContainer;
32 protected ContainerReference assignTableContainer;
33 protected ContainerReference takeOrderContainer;
34 protected ContainerReference orderTakenContainer;
35 protected ContainerReference deliveryOrderTakenContainer;
36 protected ContainerReference preparePizzasContainer;
37 protected ContainerReference prepareDeliveryPizzasContainer;
38 protected ContainerReference preparedPizzasContainer;
39 protected ContainerReference preparedDeliveryPizzasContainer;
40 protected ContainerReference paymentRequestContainer;
41 protected ContainerReference freeTablesContainer;
42 protected ContainerReference pizzaInProgressContainer;
43 protected ContainerReference orderDeliveredContainer;
44 protected ContainerReference paymentDoneContainer;
45 protected ContainerReference pizzeriaInfoContainer;
46 protected ContainerReference phoneCallsContainer;
47 protected ContainerReference groupAgentInfoContainer;
48 protected ContainerReference deliverDeliveryOrderContainer;
49 protected ContainerReference pizzeriaGroupContainer;
50 protected ContainerReference pizzeriaDeliveryContainer;
51 protected ContainerReference pizzeriaTableContainer;
52 protected ContainerReference deliveryInProgress;
53 protected ContainerReference deliveryDone;
54 protected ContainerReference billPaid;
57 protected NotificationManager notificationMgr;
60 public AbstractXVSMConnector(int port) {
62 initSpaceCommunication(port);
65 public void initSpaceCommunication(int port) {
67 // Configuration config = CommonsXmlConfiguration.load(0);
68 // config.setEmbeddedSpace(false);
69 MzsCore core = DefaultMzsCore.newInstanceWithoutSpace();
70 capi = new Capi(core);
71 notificationMgr = new NotificationManager(core);
72 } catch (Exception e) {
73 log.error("Space connection could not be established! Have you started the Space Server?");
74 Util.handleSpaceErrorAndTerminate(e);
78 protected ContainerReference useContainer(String containerName) {
79 return useContainerOfSpaceWithPort(containerName, port);
82 protected ContainerReference useContainerOfSpaceWithPort(String containerName, int spacePort) {
84 final String address = String.format(Util.SERVER_ADDR, spacePort);
85 return CapiUtil.lookupOrCreateContainer(containerName, URI.create(address), createCoordinators(new FifoCoordinator(), new LindaCoordinator(false)), null, capi);
86 } catch (MzsCoreException e) {
87 Util.handleSpaceErrorAndTerminate(e);
90 throw new RuntimeException("Could not lookup or create container " + containerName);
93 protected List<Coordinator> createCoordinators(Coordinator... coordinator) {
94 return Arrays.asList(coordinator);
97 protected <T extends Serializable> void sendItemsToContainer(
98 List<T> items, ContainerReference cref, long timeout, TransactionReference tx) {
101 List<Entry> entries = new ArrayList<>();
102 for (Serializable item : items) {
103 entries.add(new Entry(item));
105 capi.write(entries, cref, timeout, tx);
106 } catch (Exception e) {
107 log.info(e.getMessage());
112 @SuppressWarnings("unchecked")
114 * Searches for one entity matching the given template object by linda selection.
116 protected <T extends Serializable> T takeMatchingEntity(
117 T entity, ContainerReference ref, TransactionReference tx, long timeout, String errorMsg)
118 throws MzsCoreException {
120 LindaSelector sel = LindaCoordinator.newSelector(entity, 1);
122 ArrayList<Serializable> entities = capi.take(ref, sel, timeout, tx);
124 return (T) CapiUtil.getSingleEntry(entities);
125 } catch (CountNotMetException e) {
126 capi.rollbackTransaction(tx);
128 throw new EntityNotFoundByTemplate(errorMsg);
129 } catch (MzsTimeoutException e) {
130 capi.rollbackTransaction(tx);
132 throw new EntityNotFoundByTemplate(errorMsg);
136 protected <T extends Serializable> T takeMatchingEntityIfItExists(
137 T entity, ContainerReference ref, TransactionReference tx, long timeout)
138 throws MzsCoreException {
140 LindaSelector sel = LindaCoordinator.newSelector(entity, 1);
142 ArrayList<Serializable> entities = capi.take(ref, sel, timeout, tx);
144 return (T) CapiUtil.getSingleEntry(entities);
145 } catch (CountNotMetException e) {
146 } catch (MzsTimeoutException e) {
147 capi.rollbackTransaction(tx);
149 throw new EntityNotFoundByTemplate();
156 * Searches for all entities matching the given template object by linda selection and takes them.
158 protected <T extends Serializable> List<T> takeMatchingEntities(
159 T entity, ContainerReference ref, TransactionReference tx, long timeout, String errorMsg)
160 throws MzsCoreException {
162 LindaSelector sel = LindaCoordinator.newSelector(entity, MzsConstants.Selecting.COUNT_MAX);
164 ArrayList<Serializable> entities = capi.take(ref, sel, timeout, tx);
166 return (List<T>) entities;
167 } catch (CountNotMetException e) {
168 capi.rollbackTransaction(tx);
170 throw new EntityNotFoundByTemplate(errorMsg);
171 } catch (MzsTimeoutException e) {
172 capi.rollbackTransaction(tx);
174 throw new EntityNotFoundByTemplate(errorMsg);
179 * Searches for all entities matching the given template object by linda selection and reads them.
181 protected <T extends Serializable> List<T> readMatchingEntities(
182 T entity, ContainerReference ref, TransactionReference tx, long timeout, String errorMsg)
183 throws MzsCoreException {
185 LindaSelector sel = LindaCoordinator.newSelector(entity, MzsConstants.Selecting.COUNT_MAX);
187 ArrayList<Serializable> entities = capi.read(ref, sel, timeout, tx);
189 return (List<T>) entities;
190 } catch (CountNotMetException e) {
191 capi.rollbackTransaction(tx);
193 throw new EntityNotFoundByTemplate(errorMsg);
194 } catch (MzsTimeoutException e) {
195 capi.rollbackTransaction(tx);
197 throw new EntityNotFoundByTemplate(errorMsg);
200 protected <T extends Serializable> List<T> castEntries(List<? extends Serializable> entries) {
201 List<T> newList = new ArrayList<T>();
202 if (entries.size() == 0) return newList;
204 Serializable firstEntry = entries.get(0);
205 if (firstEntry instanceof Entry) {
207 List<Entry> newEntries = (List<Entry>) entries;
208 for (Entry entry : newEntries) {
209 newList.add((T) entry.getValue());
213 return (List<T>) entries;
218 protected <T extends HasId> T getSingleEntity(final List<T> entities) {
219 if (entities.size() != 1) {
220 throw new RuntimeException("Only one entity was expected!");
222 return entities.get(0);
225 protected <T extends Serializable> GroupData getSingleGroup(final List<T> entities) {
226 List<GroupData> groups = castEntries(entities);
227 if (groups.size() != 1) {
228 throw new RuntimeException("Only one group was expected!");
230 return groups.get(0);
233 protected TransactionReference getDefaultTransaction() throws MzsCoreException {
234 return capi.createTransaction(
235 Util.SPACE_TRANSACTION_TIMEOUT,
236 URI.create(String.format(Util.SERVER_ADDR, port)));
239 protected SpaceListenerImplBuilder getDefaultBuilder() {
240 return new SpaceListenerImplBuilder().setCapi(capi).setNotificationManager(notificationMgr);