package uk.bl.monitrix.database.mongodb.model; import java.util.AbstractList; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import com.mongodb.BasicDBObject; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBCursor; import com.mongodb.DBObject; import uk.bl.monitrix.database.mongodb.MongoProperties; import uk.bl.monitrix.model.Alert; import uk.bl.monitrix.model.Alert.AlertType; import uk.bl.monitrix.model.AlertLog; /** * A MongoDB-backed implementation of {@link AlertLog}. * @author Rainer Simon <rainer.simon@ait.ac.at> */ public class MongoAlertLog implements AlertLog { protected DBCollection collection; public MongoAlertLog(DB db) { this.collection = db.getCollection(MongoProperties.COLLECTION_ALERT_LOG); // Collection is indexed by timestamp and host (will be skipped automatically if index exists) this.collection.ensureIndex(new BasicDBObject(MongoProperties.FIELD_ALERT_LOG_TIMESTAMP, 1)); this.collection.ensureIndex(new BasicDBObject(MongoProperties.FIELD_ALERT_LOG_OFFENDING_HOST, 1)); } @Override public long countAll() { return collection.count(); } @Override public Iterator<Alert> listAll() { return map(collection.find().sort(new BasicDBObject(MongoProperties.FIELD_ALERT_LOG_TIMESTAMP, -1))); } @Override public List<Alert> getMostRecent(int n) { DBCursor cursor = collection.find().sort(new BasicDBObject(MongoProperties.FIELD_ALERT_LOG_TIMESTAMP, -1)).limit(n); List<Alert> recent = new ArrayList<Alert>(); while(cursor.hasNext()) recent.add(new MongoAlert(cursor.next())); return recent; } @Override public List<String> getOffendingHosts() { @SuppressWarnings("rawtypes") final List offendingHosts = collection.distinct(MongoProperties.FIELD_ALERT_LOG_OFFENDING_HOST); return new AbstractList<String>() { @Override public String get(int index) { return offendingHosts.get(index).toString(); } @Override public int size() { return offendingHosts.size(); } }; } @Override public long countAlertsForHost(String hostname) { return collection.count(new BasicDBObject(MongoProperties.FIELD_ALERT_LOG_OFFENDING_HOST, hostname)); } @Override public long countAlertsForHost(String hostname, AlertType type) { DBObject query = new BasicDBObject(MongoProperties.FIELD_ALERT_LOG_OFFENDING_HOST, hostname) .append(MongoProperties.FIELD_ALERT_LOG_ALERT_TYPE, type.name()); return collection.count(query); } @Override public List<AlertType> getAlertTypesForHost(String hostname) { @SuppressWarnings("rawtypes") final List types = collection.distinct(MongoProperties.FIELD_ALERT_LOG_ALERT_TYPE, new BasicDBObject(MongoProperties.FIELD_ALERT_LOG_OFFENDING_HOST, hostname)); return new AbstractList<Alert.AlertType>() { @Override public AlertType get(int index) { return AlertType.valueOf(types.get(index).toString()); } @Override public int size() { return types.size(); } }; } @Override public Iterator<Alert> listAlertsForHost(String hostname) { return map(collection.find(new BasicDBObject(MongoProperties.FIELD_ALERT_LOG_OFFENDING_HOST, hostname)).sort(new BasicDBObject(MongoProperties.FIELD_ALERT_LOG_TIMESTAMP, -1))); } /** * Utility method that maps a database cursor to an Iterator of Alert domain objects. * @param cursor the DB cursor * @return the domain objects */ private static Iterator<Alert> map(final DBCursor cursor) { return new Iterator<Alert>() { @Override public boolean hasNext() { return cursor.hasNext(); } @Override public Alert next() { return new MongoAlert(cursor.next()); } @Override public void remove() { cursor.remove(); } }; } }