package org.nuxeo.mule.poll;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.codehaus.jackson.JsonNode;
import org.nuxeo.ecm.automation.client.OperationRequest;
import org.nuxeo.ecm.automation.client.Session;
import org.nuxeo.ecm.automation.client.model.PropertyMap;
public class EventPollingClient {
private static final Logger logger = Logger.getLogger(EventPollingClient.class);
private static final int MAX_ENTRIES = 100;
private static final int TIME_INTERVAL = 500;
private Session session;
private boolean subscribed = true;
private long pollingInterval = 5000;
protected List<Thread> runners = new ArrayList<Thread>();
public EventPollingClient(Session session, long pollingInterval) {
this.session = session;
if (pollingInterval>0) {
this.pollingInterval = pollingInterval;
}
}
protected void doSleepABit() throws Exception {
long nbLoop = pollingInterval/TIME_INTERVAL;
int i = 0;
while (i <= nbLoop && subscribed) {
Thread.sleep(TIME_INTERVAL);
i++;
}
}
public synchronized void subscribe(final ListenerConfig config) {
Runnable listener = new Runnable() {
protected long lastId = -1;
protected void markEventAsProcessed(JsonNode event) {
lastId = event.get("id").getValueAsLong();
logger.info("lastId " + lastId);
}
protected void processEvent(JsonNode event) throws Exception {
if (event==null) {
logger.info("skip null event");
return;
}
Map<String, Object> props = new HashMap<String, Object>();
Iterator<String> fieldNames = event.getFieldNames();
while(fieldNames.hasNext()) {
String name = fieldNames.next();
props.put(name, event.get(name).getValueAsText());
}
NuxeoSimpleEvent nxEvent = new NuxeoSimpleEvent(event);
if ("NuxeoAuthentication".equals(nxEvent.getCategory()) && session.getLogin().getUsername().equalsIgnoreCase(nxEvent.getPrincipalName())) {
logger.info("skip auth event generated by myself !");
markEventAsProcessed(event);
return;
} else {
logger.info("fire nxEvent " + nxEvent.toString());
config.getCallback().process(nxEvent, props);
markEventAsProcessed(event);
}
}
@Override
public void run() {
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, -5);
Date start = calendar.getTime();
Map<String, Object> ctx = new HashMap<String, Object>();
try {
OperationRequest queryRequest = session.newRequest(
"Audit.PageProvider", ctx);
queryRequest.set("providerName", "AUDIT_BROWSER");
queryRequest.set("pageSize", MAX_ENTRIES);
queryRequest.set("maxResults", MAX_ENTRIES);
queryRequest.set("currentPageIndex", 0);
PropertyMap namedParams = new PropertyMap();
namedParams.set("bas:startDate", start);
namedParams.set("bas:endDate", new Date());
queryRequest.set("namedQueryParams", namedParams);
int eventCount = 0;
while (subscribed && eventCount == 0) {
namedParams.set("bas:endDate", new Date());
queryRequest.set("namedQueryParams", namedParams);
Object result = queryRequest.execute();
JsonNode node = (JsonNode) result;
eventCount = node.get("currentPageSize").getValueAsInt();
logger.info("init event : nb results = " + eventCount);
JsonNode entries = node.get("entries");
for (int i = 0; i < eventCount; i++) {
JsonNode event = entries.get(i);
processEvent(event);
}
doSleepABit();
}
while (subscribed) {
ctx = new HashMap<String, Object>();
queryRequest = session.newRequest("Audit.PageProvider",
ctx);
queryRequest.set("providerName", "AUDIT_BROWSER");
queryRequest.set("pageSize", MAX_ENTRIES);
queryRequest.set("maxResults", MAX_ENTRIES);
queryRequest.set("currentPageIndex", 0);
namedParams = new PropertyMap();
namedParams.set("bas:logId", lastId);
queryRequest.set("namedQueryParams", namedParams);
Object result = queryRequest.execute();
JsonNode node = (JsonNode) result;
eventCount = node.get("currentPageSize").getValueAsInt();
JsonNode entries = node.get("entries");
for (int i = 0; i < eventCount; i++) {
JsonNode event = entries.get(i);
processEvent(event);
}
doSleepABit();
};
} catch (Exception e) {
logger.error("Error during event polling", e);
}
}
};
Thread runner =new Thread(listener, "Nuxeo event polling thread for endpont");
runner.start();
runners.add(runner);
}
public synchronized void unsubscribe() throws Exception {
// flag for stop
this.subscribed = false;
// wait for thread to automatically stop
Thread.sleep(2*TIME_INTERVAL);
// check
for (Thread runner : runners) {
if (runner.isAlive()) {
// force quit
runner.interrupt();
}
}
runners.clear();
}
}