package uk.bl.monitrix;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import play.*;
import play.mvc.*;
import play.mvc.Http.*;
import play.libs.Akka;
import play.libs.F.Promise;
import static play.mvc.Results.*;
import uk.bl.monitrix.database.DBConnector;
import uk.bl.monitrix.database.cassandra.CassandraDBConnector;
import uk.bl.monitrix.database.cassandra.ingest.CassandraDBIngestConnector;
import uk.bl.monitrix.heritrix.api.HeritrixAPI;
import uk.bl.monitrix.heritrix.ingest.IngestWatcher;
/**
* The Play! Global object.
* @author Rainer Simon <rainer.simon@ait.ac.at>
*/
public class Global extends GlobalSettings {
private static DBConnector db = null;
private static IngestWatcher ingestWatcher = null;
// TODO persist registered API endpoints in DB!
private static List<HeritrixAPI> crawlers = new ArrayList<HeritrixAPI>();
private void connectBackend() {
try {
db = new CassandraDBConnector();
ingestWatcher = new IngestWatcher(new CassandraDBIngestConnector(db), Akka.system());
ingestWatcher.startWatching();
Logger.info("Database connected");
} catch (Exception e) {
Logger.error("FATAL - could not connect to database " + e);
e.printStackTrace();
}
}
/**
* Returns the database read connector or <code>null</code> if the DB connection failed
* for whatever reason. (Check the logs.)
* @return the database read connector or <code>null</code>
*/
public static DBConnector getBackend() {
return db;
}
/**
* Returns the ingest watcher, which is in charge of conducting periodic log-to-database syncs.
* @return the ingest watcher
*/
public static IngestWatcher getIngestWatcher() {
return ingestWatcher;
}
/**
* Returns the configured Heritrix crawler APIs, in the form of a map {:endpointURL API}.
* @return the crawler APIs
*/
public static List<HeritrixAPI> getCrawlerAPIs() {
return crawlers;
}
@Override
public void onStop(Application app) {
ingestWatcher.stopWatching();
if (db != null) {
db.close();
Logger.info("Database disconnected");
}
}
/**
* Redirect all errors (i.e. RuntimeExceptions) to a custom error page.
*/
public Promise<SimpleResult> onError(RequestHeader request, Throwable t) {
t.printStackTrace();
while(t.getCause() != null)
t = t.getCause();
return Promise.<SimpleResult>pure(internalServerError(
views.html.error.generalServerError.render(t)
));
}
/**
* In case the DB is not connected, montrix redirects to a specific error
* page with extra DB connection instructions.
*/
@Override
@SuppressWarnings("rawtypes")
public Action onRequest(Request request, Method actionMethod) {
if (db == null) {
connectBackend();
if (db == null)
return new Action.Simple() {
@Override
public Promise<SimpleResult> call(Context arg0) throws Throwable {
return Promise.<SimpleResult>pure(ok(views.html.error.dbConnectError.render()));
}
};
}
return super.onRequest(request, actionMethod);
}
}