VIVO-869 ABoxRecomputer should pause the SearchIndexer during a rebuild.

This commit is contained in:
Jim Blake 2015-01-22 15:49:08 -05:00
parent ccb2063aa4
commit de5b80bf75
6 changed files with 137 additions and 11 deletions

View file

@ -38,6 +38,7 @@ import com.hp.hpl.jena.vocabulary.RDFS;
import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary;
import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceGraph; import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceGraph;
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames;
import edu.cornell.mannlib.vitro.webapp.modules.searchIndexer.SearchIndexer;
import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet; import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
@ -46,6 +47,8 @@ import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.RDFServiceUtils;
public class ABoxRecomputer { public class ABoxRecomputer {
private static final Log log = LogFactory.getLog(ABoxRecomputer.class); private static final Log log = LogFactory.getLog(ABoxRecomputer.class);
private final SearchIndexer searchIndexer;
private OntModel tboxModel; // asserted and inferred TBox axioms private OntModel tboxModel; // asserted and inferred TBox axioms
private OntModel aboxModel; private OntModel aboxModel;
@ -67,11 +70,13 @@ public class ABoxRecomputer {
public ABoxRecomputer(OntModel tboxModel, public ABoxRecomputer(OntModel tboxModel,
OntModel aboxModel, OntModel aboxModel,
RDFService rdfService, RDFService rdfService,
SimpleReasoner simpleReasoner) { SimpleReasoner simpleReasoner,
SearchIndexer searchIndexer) {
this.tboxModel = tboxModel; this.tboxModel = tboxModel;
this.aboxModel = aboxModel; this.aboxModel = aboxModel;
this.rdfService = rdfService; this.rdfService = rdfService;
this.simpleReasoner = simpleReasoner; this.simpleReasoner = simpleReasoner;
this.searchIndexer = searchIndexer;
recomputing = false; recomputing = false;
stopRequested = false; stopRequested = false;
handleSameAs = simpleReasoner.getSameAsEnabled(); handleSameAs = simpleReasoner.getSameAsEnabled();
@ -97,8 +102,14 @@ public class ABoxRecomputer {
} }
} }
try { try {
if (searchIndexer != null) {
searchIndexer.pause();
}
recomputeABox(); recomputeABox();
} finally { } finally {
if (searchIndexer != null) {
searchIndexer.unpause();
}
synchronized (lock1) { synchronized (lock1) {
recomputing = false; recomputing = false;
} }

View file

@ -43,6 +43,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.DifferenceGraph;
import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceGraph; import edu.cornell.mannlib.vitro.webapp.dao.jena.RDFServiceGraph;
import edu.cornell.mannlib.vitro.webapp.dao.jena.event.BulkUpdateEvent; import edu.cornell.mannlib.vitro.webapp.dao.jena.event.BulkUpdateEvent;
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames;
import edu.cornell.mannlib.vitro.webapp.modules.searchIndexer.SearchIndexer;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException;
import edu.cornell.mannlib.vitro.webapp.rdfservice.adapters.VitroModelFactory; import edu.cornell.mannlib.vitro.webapp.rdfservice.adapters.VitroModelFactory;
@ -60,6 +61,8 @@ public class SimpleReasoner extends StatementListener {
private static final Log log = LogFactory.getLog(SimpleReasoner.class); private static final Log log = LogFactory.getLog(SimpleReasoner.class);
private final SearchIndexer searchIndexer;
private OntModel tboxModel; // asserted and inferred TBox axioms private OntModel tboxModel; // asserted and inferred TBox axioms
private OntModel aboxModel; // ABox assertions private OntModel aboxModel; // ABox assertions
private Model inferenceModel; // ABox inferences private Model inferenceModel; // ABox inferences
@ -95,12 +98,17 @@ public class SimpleReasoner extends StatementListener {
* whole ABox inference model is rebuilt * whole ABox inference model is rebuilt
* @param inferenceScratchpadModel - output. This the model is temporarily used when * @param inferenceScratchpadModel - output. This the model is temporarily used when
* the whole ABox inference model is rebuilt * the whole ABox inference model is rebuilt
* @param searchIndexer - output. If not null, the indexer will be paused before the
* ABox inference model is rebuilt and unpaused when the rebuild is complete.
*/ */
public SimpleReasoner(OntModel tboxModel, public SimpleReasoner(OntModel tboxModel,
RDFService rdfService, RDFService rdfService,
Model inferenceModel, Model inferenceModel,
Model inferenceRebuildModel, Model inferenceRebuildModel,
Model scratchpadModel) { Model scratchpadModel,
SearchIndexer searchIndexer) {
this.searchIndexer = searchIndexer;
this.tboxModel = tboxModel; this.tboxModel = tboxModel;
@ -117,7 +125,7 @@ public class SimpleReasoner extends StatementListener {
this.batchMode = 0; this.batchMode = 0;
aBoxDeltaModeler1 = new CumulativeDeltaModeler(); aBoxDeltaModeler1 = new CumulativeDeltaModeler();
aBoxDeltaModeler2 = new CumulativeDeltaModeler(); aBoxDeltaModeler2 = new CumulativeDeltaModeler();
recomputer = new ABoxRecomputer(tboxModel, aboxModel, rdfService, this); recomputer = new ABoxRecomputer(tboxModel, aboxModel, rdfService, this, searchIndexer);
stopRequested = false; stopRequested = false;
if (rdfService == null) { if (rdfService == null) {
@ -140,6 +148,7 @@ public class SimpleReasoner extends StatementListener {
* ABox statements are maintained (added or retracted). * ABox statements are maintained (added or retracted).
*/ */
public SimpleReasoner(OntModel tboxModel, OntModel aboxModel, Model inferenceModel) { public SimpleReasoner(OntModel tboxModel, OntModel aboxModel, Model inferenceModel) {
this.searchIndexer = null;
this.tboxModel = tboxModel; this.tboxModel = tboxModel;
this.aboxModel = aboxModel; this.aboxModel = aboxModel;
this.inferenceModel = inferenceModel; this.inferenceModel = inferenceModel;
@ -155,7 +164,7 @@ public class SimpleReasoner extends StatementListener {
ds.addNamedModel(ModelNames.TBOX_ASSERTIONS, tboxModel); ds.addNamedModel(ModelNames.TBOX_ASSERTIONS, tboxModel);
ds.setDefaultModel(ModelFactory.createUnion(fullModel, tboxModel)); ds.setDefaultModel(ModelFactory.createUnion(fullModel, tboxModel));
recomputer = new ABoxRecomputer(tboxModel, aboxModel, new RDFServiceModel(ds), this); recomputer = new ABoxRecomputer(tboxModel, aboxModel, new RDFServiceModel(ds), this, searchIndexer);
} }
public void setPluginList(List<ReasonerPlugin> pluginList) { public void setPluginList(List<ReasonerPlugin> pluginList) {

View file

@ -23,8 +23,10 @@ import com.hp.hpl.jena.query.Dataset;
import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.RDFNode; import com.hp.hpl.jena.rdf.model.RDFNode;
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess;
import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames;
import edu.cornell.mannlib.vitro.webapp.modules.searchIndexer.SearchIndexer;
import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService;
import edu.cornell.mannlib.vitro.webapp.reasoner.ReasonerPlugin; import edu.cornell.mannlib.vitro.webapp.reasoner.ReasonerPlugin;
import edu.cornell.mannlib.vitro.webapp.reasoner.SimpleReasoner; import edu.cornell.mannlib.vitro.webapp.reasoner.SimpleReasoner;
@ -45,6 +47,7 @@ public class SimpleReasonerSetup implements ServletContextListener {
@Override @Override
public void contextInitialized(ServletContextEvent sce) { public void contextInitialized(ServletContextEvent sce) {
ServletContext ctx = sce.getServletContext(); ServletContext ctx = sce.getServletContext();
SearchIndexer searchIndexer = ApplicationUtils.instance().getSearchIndexer();
try { try {
OntModel tboxAssertionsModel = ModelAccess.on(ctx).getOntModel(ModelNames.TBOX_ASSERTIONS); OntModel tboxAssertionsModel = ModelAccess.on(ctx).getOntModel(ModelNames.TBOX_ASSERTIONS);
@ -70,7 +73,7 @@ public class SimpleReasonerSetup implements ServletContextListener {
// the simple reasoner will register itself as a listener to the ABox assertions // the simple reasoner will register itself as a listener to the ABox assertions
SimpleReasoner simpleReasoner = new SimpleReasoner( SimpleReasoner simpleReasoner = new SimpleReasoner(
tboxUnionModel, rdfService, inferenceModel, rebuildModel, scratchModel); tboxUnionModel, rdfService, inferenceModel, rebuildModel, scratchModel, searchIndexer);
sce.getServletContext().setAttribute(SimpleReasoner.class.getName(),simpleReasoner); sce.getServletContext().setAttribute(SimpleReasoner.class.getName(),simpleReasoner);
StartupStatus ss = StartupStatus.getBean(ctx); StartupStatus ss = StartupStatus.getBean(ctx);

View file

@ -7,6 +7,10 @@ import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import stubs.edu.cornell.mannlib.vitro.webapp.modules.ApplicationStub;
import stubs.edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngineStub;
import stubs.javax.servlet.ServletContextStub;
import com.hp.hpl.jena.ontology.OntModel; import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec; import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.ontology.OntProperty; import com.hp.hpl.jena.ontology.OntProperty;
@ -29,6 +33,10 @@ public class SimpleReasonerInversePropertyTest extends SimpleReasonerTBoxHelper
setLoggerLevel(SimpleReasonerTBoxListener.class, Level.OFF); setLoggerLevel(SimpleReasonerTBoxListener.class, Level.OFF);
setLoggerLevel(ABoxRecomputer.class, Level.OFF); setLoggerLevel(ABoxRecomputer.class, Level.OFF);
} }
@Before public void setup() {
ApplicationStub.setup(new ServletContextStub(), new SearchEngineStub());
}
@Test @Test
public void addABoxAssertion1Test(){ public void addABoxAssertion1Test(){

View file

@ -6,6 +6,7 @@ import java.lang.reflect.Field;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import stubs.edu.cornell.mannlib.vitro.webapp.modules.searchIndexer.SearchIndexerStub;
import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils; import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils;
import edu.cornell.mannlib.vitro.webapp.application.VitroHomeDirectory; import edu.cornell.mannlib.vitro.webapp.application.VitroHomeDirectory;
import edu.cornell.mannlib.vitro.webapp.modules.Application; import edu.cornell.mannlib.vitro.webapp.modules.Application;
@ -42,10 +43,14 @@ public class ApplicationStub implements Application {
private final ServletContext ctx; private final ServletContext ctx;
private final SearchEngine searchEngine; private final SearchEngine searchEngine;
private final SearchIndexer searchIndexer;
public ApplicationStub(ServletContext ctx, SearchEngine searchEngine) { public ApplicationStub(ServletContext ctx, SearchEngine searchEngine) {
this.ctx = ctx; this.ctx = ctx;
this.searchEngine = searchEngine; this.searchEngine = searchEngine;
this.searchIndexer = new SearchIndexerStub();
this.searchIndexer.unpause();
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
@ -62,6 +67,11 @@ public class ApplicationStub implements Application {
return searchEngine; return searchEngine;
} }
@Override
public SearchIndexer getSearchIndexer() {
return searchIndexer;
}
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// Un-implemented methods // Un-implemented methods
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
@ -109,10 +119,4 @@ public class ApplicationStub implements Application {
"ApplicationStub.getTBoxReasonerModule() not implemented."); "ApplicationStub.getTBoxReasonerModule() not implemented.");
} }
@Override
public SearchIndexer getSearchIndexer() {
throw new RuntimeException(
"Application.getSearchIndexer() not implemented.");
}
} }

View file

@ -0,0 +1,91 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package stubs.edu.cornell.mannlib.vitro.webapp.modules.searchIndexer;
import java.util.Collection;
import java.util.List;
import com.hp.hpl.jena.rdf.model.Statement;
import edu.cornell.mannlib.vitro.webapp.modules.Application;
import edu.cornell.mannlib.vitro.webapp.modules.ComponentStartupStatus;
import edu.cornell.mannlib.vitro.webapp.modules.searchIndexer.SearchIndexer;
import edu.cornell.mannlib.vitro.webapp.modules.searchIndexer.SearchIndexerStatus;
/**
* TODO
*/
public class SearchIndexerStub implements SearchIndexer {
// ----------------------------------------------------------------------
// Stub infrastructure
// ----------------------------------------------------------------------
private boolean paused = true;
// ----------------------------------------------------------------------
// Stub methods
// ----------------------------------------------------------------------
@Override
public void pause() {
paused = true;
}
@Override
public void unpause() {
paused = false;
}
// ----------------------------------------------------------------------
// Un-implemented methods
// ----------------------------------------------------------------------
@Override
public void startup(Application application, ComponentStartupStatus ss) {
throw new RuntimeException(
"SearchIndexerStub.startup() not implemented.");
}
@Override
public void scheduleUpdatesForStatements(List<Statement> changes) {
throw new RuntimeException(
"SearchIndexerStub.scheduleUpdatesForStatements() not implemented.");
}
@Override
public void scheduleUpdatesForUris(Collection<String> uris) {
throw new RuntimeException(
"SearchIndexerStub.scheduleUpdatesForUris() not implemented.");
}
@Override
public void rebuildIndex() {
throw new RuntimeException(
"SearchIndexerStub.rebuildIndex() not implemented.");
}
@Override
public SearchIndexerStatus getStatus() {
throw new RuntimeException(
"SearchIndexerStub.getStatus() not implemented.");
}
@Override
public void addListener(Listener listener) {
throw new RuntimeException(
"SearchIndexerStub.addListener() not implemented.");
}
@Override
public void removeListener(Listener listener) {
throw new RuntimeException(
"SearchIndexerStub.removeListener() not implemented.");
}
@Override
public void shutdown(Application app) {
throw new RuntimeException(
"SearchIndexerStub.shutdown() not implemented.");
}
}