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 org.mozartspaces.capi3.Coordinator;
7 import org.mozartspaces.capi3.CountNotMetException;
8 import org.mozartspaces.capi3.FifoCoordinator;
9 import org.mozartspaces.capi3.LindaCoordinator;
10 import org.mozartspaces.capi3.LindaCoordinator.LindaSelector;
11 import org.mozartspaces.core.*;
12 import org.mozartspaces.core.config.CommonsXmlConfiguration;
13 import org.mozartspaces.core.config.Configuration;
14 import org.mozartspaces.notifications.NotificationManager;
15 import org.mozartspaces.notifications.Operation;
16 import org.slf4j.Logger;
17 import org.slf4j.LoggerFactory;
19 import java.io.Serializable;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.Date;
24 import java.util.List;
25 import java.util.concurrent.atomic.AtomicLong;
27 public abstract class AbstractXVSMConnector {
28 public static Object lockObject = new Object();
29 public static AtomicLong timeOflastOperation = new AtomicLong(new Date().getTime());
31 private static final Logger log = LoggerFactory.getLogger(AbstractXVSMConnector.class);
33 protected ContainerReference tableAssignedContainer;
34 protected ContainerReference assignTableContainer;
35 protected ContainerReference takeOrderContainer;
36 protected ContainerReference orderTakenContainer;
37 protected ContainerReference preparePizzasContainer;
38 protected ContainerReference deliverPizzasContainer;
39 protected ContainerReference paymentRequestContainer;
40 protected ContainerReference freeTablesContainer;
41 protected ContainerReference pizzaInProgressContainer;
42 protected ContainerReference orderCompleteContainer;
43 protected ContainerReference isEatingContainer;
44 protected ContainerReference paymentDoneContainer;
45 protected ContainerReference infoContainer;
47 protected NotificationManager notificationMgr;
51 public AbstractXVSMConnector(int port) {
53 initSpaceCommunication(port);
56 public void initSpaceCommunication(int port) {
58 // Configuration config = CommonsXmlConfiguration.load(0);
59 // config.setEmbeddedSpace(false);
60 MzsCore core = DefaultMzsCore.newInstanceWithoutSpace();
61 capi = new Capi(core);
62 notificationMgr = new NotificationManager(core);
63 } catch (Exception e) {
64 log.error("Space connection could not be established! Have you started the Space Server?");
65 handleSpaceErrorAndTerminate(e);
69 protected ContainerReference useContainer(String containerName) {
70 return useContainerOfSpaceWithPort(containerName, port);
73 protected ContainerReference useContainerOfSpaceWithPort(String containerName, int spacePort) {
75 final String address = String.format(Util.SERVER_ADDR, spacePort);
76 return CapiUtil.lookupOrCreateContainer(containerName, URI.create(address), createCoordinators(new FifoCoordinator(), new LindaCoordinator(false)), null, capi);
77 } catch (MzsCoreException e) {
78 handleSpaceErrorAndTerminate(e);
81 throw new RuntimeException("Could not Create container " + containerName);
84 protected List<Coordinator> createCoordinators(Coordinator... coordinator) {
85 return Arrays.asList(coordinator);
88 protected void handleSpaceErrorAndTerminate(Exception e) {
89 log.error(e.getMessage());
94 protected void createNotification(SpaceListener listener,
95 ContainerReference cref) {
96 listener.startHandlingAbsenceOfNotifications();
98 notificationMgr.createNotification(cref, listener, Operation.WRITE);
99 } catch (Exception e) {
100 handleSpaceErrorAndTerminate(e);
104 protected <T extends Serializable> void sendItemsToContainer(
105 List<T> items, ContainerReference cref, long timeout, TransactionReference tx) {
108 List<Entry> entries = new ArrayList<>();
109 for (Serializable item : items) {
110 entries.add(new Entry(item));
112 capi.write(entries, cref, timeout, tx);
113 } catch (Exception e) {
114 log.info(e.getMessage());
119 @SuppressWarnings("unchecked")
121 * Searches for one entity matching the given template object by linda selection.
123 protected <T extends Serializable> T takeMatchingEntity(
124 T entity, ContainerReference ref, TransactionReference tx, long timeout, String errorMsg)
125 throws MzsCoreException {
127 LindaSelector sel = LindaCoordinator.newSelector(entity, 1);
129 ArrayList<Serializable> entities = capi.take(ref, sel, timeout, tx);
131 return (T) CapiUtil.getSingleEntry(entities);
132 } catch (CountNotMetException e) {
133 capi.rollbackTransaction(tx);
135 throw new EntityNotFoundByTemplate(errorMsg);
136 } catch (MzsTimeoutException e) {
137 capi.rollbackTransaction(tx);
139 throw new EntityNotFoundByTemplate(errorMsg);
144 * Searches for all entities matching the given template object by linda selection.
146 protected <T extends Serializable> List<T> takeMatchingEntities(
147 T entity, ContainerReference ref, TransactionReference tx, long timeout, String errorMsg)
148 throws MzsCoreException {
150 LindaSelector sel = LindaCoordinator.newSelector(entity, MzsConstants.Selecting.COUNT_MAX);
152 ArrayList<Serializable> entities = capi.take(ref, sel, timeout, tx);
154 return (List<T>) entities;
155 } catch (CountNotMetException e) {
156 capi.rollbackTransaction(tx);
158 throw new EntityNotFoundByTemplate(errorMsg);
159 } catch (MzsTimeoutException e) {
160 capi.rollbackTransaction(tx);
162 throw new EntityNotFoundByTemplate(errorMsg);
166 protected <T extends Serializable> List<T> castEntries(List<? extends Serializable> entries) {
167 List<T> newList = new ArrayList<T>();
168 if (entries.size() == 0) return newList;
170 Serializable firstEntry = entries.get(0);
171 if (firstEntry instanceof Entry) {
173 List<Entry> newEntries = (List<Entry>) entries;
174 for (Entry entry : newEntries) {
175 newList.add((T) entry.getValue());
179 return (List<T>) entries;
184 protected <T extends HasId> T getSingleEntity(final List<T> entities) {
185 if (entities.size() != 1) {
186 throw new RuntimeException("Only one entity was expected!");
188 return entities.get(0);
191 protected <T extends Serializable> GroupData getSingleGroup(final List<T> entities) {
192 List<GroupData> groups = castEntries(entities);
193 if (groups.size() != 1) {
194 throw new RuntimeException("Only one group was expected!");
196 return groups.get(0);
199 protected TransactionReference getDefaultTransaction() throws MzsCoreException {
200 return capi.createTransaction(
201 Util.SPACE_TRANSACTION_TIMEOUT,
202 URI.create(String.format(Util.SERVER_ADDR, port)));