package eu.play_project.dcep.distributedetalis; import static eu.play_project.dcep.constants.DcepConstants.LOG_DCEP; import static eu.play_project.dcep.constants.DcepConstants.LOG_DCEP_ENTRY; import static eu.play_project.dcep.constants.DcepConstants.LOG_DCEP_FAILED_ENTRY; import java.io.Serializable; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import org.apache.commons.collections.buffer.CircularFifoBuffer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.jtalis.core.event.EtalisEvent; import com.jtalis.core.event.JtalisInputEventProvider; import eu.play_project.dcep.distributedetalis.api.DistributedEtalisException; import eu.play_project.dcep.distributedetalis.measurement.MeasurementUnit; import eu.play_project.dcep.distributedetalis.utils.EventCloudHelpers; import fr.inria.eventcloud.api.CompoundEvent; /** * To communicate with ETALIS. Push events to and receive events from ETALIS. * * @author sobermeier */ public class JtalisInputProvider implements JtalisInputEventProvider, Serializable { private static final long serialVersionUID = 100L; BlockingQueue<EtalisEvent> events = null; // Contains events till ETALIS has consumed them. BlockingQueue<EtalisEvent> meausrementEvents = null; //Contains measurement events. They are preferred to the other events. boolean shutdownEtalis = false; // If true ETALIS will shutdown. private MeasurementUnit measurementUnit; private final PrologSemWebLib semWebLib; public static int eventConsumed = 0; private static Logger logger = LoggerFactory.getLogger(JtalisInputProvider.class); private final CircularFifoBuffer duplicatesCache = new CircularFifoBuffer(32); public JtalisInputProvider(PrologSemWebLib semWebLib) { super(); this.semWebLib = semWebLib; this.events = new LinkedBlockingQueue<EtalisEvent>(); } /** * Push events to Jtalis. */ public void notify(CompoundEvent event) { String eventType = EventCloudHelpers.getEventType(event); String eventId = event.getGraph().toString(); /* * Do some checking for duplicates (memorizing a few recently seen * events) */ synchronized (duplicatesCache) { if (!duplicatesCache.contains(eventId)) { // Do not remove this line, needed for logs. :stuehmer logger.info(LOG_DCEP_ENTRY + eventId); if (logger.isDebugEnabled()) { logger.debug(LOG_DCEP + "Simple Event:\n{}", event.toString()); } duplicatesCache.add(eventId); } else { logger.info(LOG_DCEP_FAILED_ENTRY + "Duplicate Event suppressed: " + eventId); return; } } try { //Thread.sleep(100); // Add RDF payload to Prolog: semWebLib.addEvent(event); // Trigger event in ETALIS: events.put(new EtalisEvent("'" + eventType + "'", eventId)); } catch (InterruptedException e) { logger.error(LOG_DCEP_FAILED_ENTRY + "Error adding event to Jtalis queue.", e); } catch (DistributedEtalisException e) { logger.error(LOG_DCEP_FAILED_ENTRY + "Error on new event. ", e); } } @Override public boolean hasMore() { if (shutdownEtalis) { return false; } else { return true; // Otherwise workerthread of jtalis shuts down. } } /** * Jtalis gets events from here. */ @Override public EtalisEvent getEvent() { // Return the oldest event (FIFO) blocking if there is none: try { EtalisEvent e = events.take(); incrementEventCounter(); return e; } catch (InterruptedException e) { e.printStackTrace(); } return null; } @Override public void setup() { } public static synchronized void incrementEventCounter(){ eventConsumed++; } public static synchronized void resetEventCounter(){ eventConsumed = 0; } public static synchronized int getEventCounter(){ return eventConsumed; } @Override public void shutdown() { shutdownEtalis = true; } public int getInputQueueSize(){ return events.size(); } }