From 304a1c7b1e7d7abb7f07f2c48fa013d10e6ba878 Mon Sep 17 00:00:00 2001 From: sjm222 Date: Thu, 3 Feb 2011 20:52:26 +0000 Subject: [PATCH] NIHVIVO-1843 KB Migration must happen in RDB mode --- .../ontology/update/KnowledgeBaseUpdater.java | 6 +- .../webapp/ontology/update/TBoxUpdater.java | 8 ++- .../servlet/setup/JenaDataSourceSetup.java | 27 ++++---- .../servlet/setup/JenaDataSourceSetupSDB.java | 65 +++++++++++++++++-- .../servlet/setup/UpdateKnowledgeBase.java | 54 +++++++-------- 5 files changed, 110 insertions(+), 50 deletions(-) diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java index 38020c8c8..594f05b8c 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/KnowledgeBaseUpdater.java @@ -299,14 +299,14 @@ public class KnowledgeBaseUpdater { return !qexec.execAsk(); } - + /** * loads a SPARQL ASK query from a text file * @param filePath * @return the query string or null if file not found */ - private String loadSparqlQuery(String filePath) throws IOException { - File file = new File(settings.getAskQueryFile()); + public static String loadSparqlQuery(String filePath) throws IOException { + File file = new File(filePath); if (!file.exists()) { return null; } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/TBoxUpdater.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/TBoxUpdater.java index e1f2e7689..91b93a6ee 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/TBoxUpdater.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/ontology/update/TBoxUpdater.java @@ -257,13 +257,15 @@ public class TBoxUpdater { siteModel.remove(actualRetractions); record.recordRetractions(actualRetractions); + long numAdded = actualAdditions.size(); + long numRemoved = actualRetractions.size(); + // log summary of changes - if (actualAdditions.size() > 0) { + if (numAdded > 0) { logger.log("Updated the default vitro annotation value for " + - actualAdditions.size() + " statements in the knowledge base"); + numAdded + " statements in the knowledge base"); } - long numRemoved = actualRetractions.size() - actualAdditions.size(); if (numRemoved > 0) { logger.log("Removed " + numRemoved + " outdated vitro annotation property setting" + ((numRemoved > 1) ? "s" : "") + " from the knowledge base"); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetup.java index 1112b5e24..0ea45c894 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetup.java @@ -29,6 +29,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaBaseDaoCon; import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaModelUtils; +import edu.cornell.mannlib.vitro.webapp.dao.jena.ModelContext; import edu.cornell.mannlib.vitro.webapp.dao.jena.SearchReindexingListener; import edu.cornell.mannlib.vitro.webapp.dao.jena.SimpleOntModelSelector; import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaModelMaker; @@ -44,6 +45,16 @@ public class JenaDataSourceSetup extends JenaDataSourceSetupBase implements java private static final Log log = LogFactory.getLog(JenaDataSourceSetup.class.getName()); public void contextInitialized(ServletContextEvent sce) { + + String tripleStoreTypeStr = + ConfigurationProperties.getProperty( + "VitroConnection.DataSource.tripleStoreType", "RDB"); + + if ("SDB".equals(tripleStoreTypeStr)) { + (new JenaDataSourceSetupSDB()).contextInitialized(sce); + return; + } + if (AbortStartup.isStartupAborted(sce.getServletContext())) { return; @@ -51,16 +62,6 @@ public class JenaDataSourceSetup extends JenaDataSourceSetupBase implements java try { - String tripleStoreTypeStr = - ConfigurationProperties.getProperty( - "VitroConnection.DataSource.tripleStoreType", "RDB"); - - //FIXME improve - if ("SDB".equals(tripleStoreTypeStr)) { - (new JenaDataSourceSetupSDB()).contextInitialized(sce); - return; - } - OntModel memModel = (OntModel) sce.getServletContext().getAttribute("jenaOntModel"); if (memModel == null) { memModel = ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC); @@ -96,19 +97,19 @@ public class JenaDataSourceSetup extends JenaDataSourceSetupBase implements java WebappDaoFactory baseWadf = new WebappDaoFactoryJena( baseOms, defaultNamespace, null, null); sce.getServletContext().setAttribute("assertionsWebappDaoFactory",baseWadf); - sce.getServletContext().setAttribute("baseOntModelSelector", baseOms); + ModelContext.setBaseOntModelSelector(baseOms, sce.getServletContext()); sce.getServletContext().setAttribute("inferenceOntModel", inferenceModel); WebappDaoFactory infWadf = new WebappDaoFactoryJena( inferenceOms, defaultNamespace, null, null); sce.getServletContext().setAttribute("deductionsWebappDaoFactory", infWadf); - sce.getServletContext().setAttribute("inferenceOntModelSelector", inferenceOms); + ModelContext.setInferenceOntModelSelector(inferenceOms, sce.getServletContext()); sce.getServletContext().setAttribute("jenaOntModel", unionModel); WebappDaoFactory wadf = new WebappDaoFactoryJena( unionOms, baseOms, inferenceOms, defaultNamespace, null, null); sce.getServletContext().setAttribute("webappDaoFactory",wadf); - sce.getServletContext().setAttribute("unionOntModelSelector", unionOms); + ModelContext.setUnionOntModelSelector(unionOms, sce.getServletContext()); ApplicationBean appBean = getApplicationBeanFromOntModel(memModel,wadf); if (appBean != null) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupSDB.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupSDB.java index 64553e0af..80ab54cd6 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupSDB.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupSDB.java @@ -2,6 +2,7 @@ package edu.cornell.mannlib.vitro.webapp.servlet.setup; +import java.io.IOException; import java.sql.SQLException; import java.util.ArrayList; import java.util.Iterator; @@ -51,6 +52,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelectorImpl; import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaModelMaker; import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaSDBModelMaker; import edu.cornell.mannlib.vitro.webapp.dao.jena.WebappDaoFactorySDB; +import edu.cornell.mannlib.vitro.webapp.ontology.update.KnowledgeBaseUpdater; import edu.cornell.mannlib.vitro.webapp.utils.NamespaceMapper; import edu.cornell.mannlib.vitro.webapp.utils.jena.InitialJenaModelUtils; import edu.cornell.mannlib.vitro.webapp.utils.jena.NamespaceMapperJena; @@ -73,6 +75,15 @@ public class JenaDataSourceSetupSDB extends JenaDataSourceSetupBase implements j // that it is not executed in a post-sdb-conversion environment. OntModel memModel = (OntModel) sce.getServletContext().getAttribute("jenaOntModel"); + if ( updateRequired(sce.getServletContext(), memModel)) { + log.error(getMigrationErrString()); + System.out.println(getMigrationErrString()); + // The rest of the application should not + // start if this condition is encountered + AbortStartup.abortStartup(sce.getServletContext()); + throw new MigrationRequiredError(getMigrationErrString()); + } + if (memModel == null) { memModel = ModelFactory.createOntologyModel(MEM_ONT_MODEL_SPEC); log.warn("WARNING: no database connected. Changes will disappear after context restart."); @@ -255,12 +266,12 @@ public class JenaDataSourceSetupSDB extends JenaDataSourceSetupBase implements j unionOms.setFullModel(masterUnion); sce.getServletContext().setAttribute("jenaOntModel", masterUnion); WebappDaoFactory wadf = new WebappDaoFactorySDB(unionOms, bds, storeDesc, defaultNamespace, null, null); - //WebappDaoFactory wadf = new WebappDaoFactorySDB(unionOms, dataset, defaultNamespace, null, null); sce.getServletContext().setAttribute("webappDaoFactory",wadf); + + ModelContext.setUnionOntModelSelector(unionOms, sce.getServletContext()); // assertions and inferences + ModelContext.setBaseOntModelSelector(baseOms, sce.getServletContext()); // assertions + ModelContext.setInferenceOntModelSelector(inferenceOms, sce.getServletContext()); // inferences - sce.getServletContext().setAttribute("unionOntModelSelector", unionOms); //assertions and inferences - sce.getServletContext().setAttribute("baseOntModelSelector", baseOms); //assertions - sce.getServletContext().setAttribute("inferenceOntModelSelector", inferenceOms); //inferences ApplicationBean appBean = getApplicationBeanFromOntModel(unionOms.getFullModel(),wadf); if (appBean != null) { sce.getServletContext().setAttribute("applicationBean", appBean); @@ -301,7 +312,9 @@ public class JenaDataSourceSetupSDB extends JenaDataSourceSetupBase implements j setVitroJenaSDBModelMaker(vsmm,sce); log.info("Model makers set up"); - + + } catch (MigrationRequiredError mre) { + throw new MigrationRequiredError(mre.getMessage()); } catch (Throwable t) { log.error("Throwable in " + this.getClass().getName(), t); // printing the error because Tomcat doesn't print context listener @@ -645,4 +658,46 @@ public class JenaDataSourceSetupSDB extends JenaDataSourceSetupBase implements j return (Store) ctx.getAttribute(STORE_ATTR); } + /** + * Executes a SPARQL ASK query to determine whether the knowledge base + * needs to be updated to conform to a new ontology version + */ + public boolean updateRequired(ServletContext ctx, OntModel m) throws IOException { + + String sparqlQueryStr = KnowledgeBaseUpdater.loadSparqlQuery(UpdateKnowledgeBase.getAskQueryPath(ctx)); + if (sparqlQueryStr == null) { + return false; + } + + Query query = QueryFactory.create(sparqlQueryStr); + QueryExecution qexec = QueryExecutionFactory.create(query, m); + + // if the ASK query DOES have a solution (i.e. the assertions exist + // showing that the update has already been performed), then the update + // is NOT required. + return !qexec.execAsk(); + + } + + private String getMigrationErrString() { + String errMessage = "\n*******************************************************************"; + errMessage += "\nA knowledge base migration is " + + "required and this must be done in" + + " RDB mode before converting to SDB. " + + "Please change deploy.properties to" + + " use RDB mode, redeploy, and restart. After " + + "the knowledge base migration has completed " + + "successfully, change deploy.properties to use " + + "SDB mode, redeploy, and restart.\n"; + errMessage += "*******************************************************************"; + + return errMessage; + } + + private class MigrationRequiredError extends Error { + public MigrationRequiredError(String string) { + super(string); + } + } + } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java index b95408454..ccdfc58e5 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/UpdateKnowledgeBase.java @@ -29,8 +29,8 @@ import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; import edu.cornell.mannlib.vitro.webapp.dao.jena.JenaBaseDao; import edu.cornell.mannlib.vitro.webapp.dao.jena.OntModelSelector; import edu.cornell.mannlib.vitro.webapp.dao.jena.SimpleOntModelSelector; -import edu.cornell.mannlib.vitro.webapp.ontology.update.UpdateSettings; import edu.cornell.mannlib.vitro.webapp.ontology.update.KnowledgeBaseUpdater; +import edu.cornell.mannlib.vitro.webapp.ontology.update.UpdateSettings; import edu.cornell.mannlib.vitro.webapp.search.lucene.LuceneSetup; /** @@ -43,25 +43,25 @@ public class UpdateKnowledgeBase implements ServletContextListener { private final static Log log = LogFactory.getLog(UpdateKnowledgeBase.class); - private final String DATA_DIR = "/WEB-INF/ontologies/update/"; - private final String LOG_DIR = "logs/"; - private final String CHANGED_DATA_DIR = "changedData/"; - private final String ASK_QUERY_FILE = DATA_DIR + "ask.sparql"; - private final String SUCCESS_ASSERTIONS_FILE = DATA_DIR + "success.n3"; - private final String SUCCESS_RDF_FORMAT = "N3"; - private final String DIFF_FILE = DATA_DIR + "diff.tab.txt"; - private final String LOG_FILE = DATA_DIR + LOG_DIR + "knowledgeBaseUpdate.log"; - private final String ERROR_LOG_FILE = DATA_DIR + LOG_DIR + "knowledgeBaseUpdate.error.log"; - private final String REMOVED_DATA_FILE = DATA_DIR + CHANGED_DATA_DIR + "removedData.n3"; - private final String ADDED_DATA_FILE = DATA_DIR + CHANGED_DATA_DIR + "addedData.n3"; - private final String SPARQL_CONSTRUCT_ADDITIONS_DIR = DATA_DIR + "sparqlConstructs/additions/"; - private final String SPARQL_CONSTRUCT_ADDITIONS_PASS2_DIR = DATA_DIR + "sparqlConstructs/additions-pass2/"; - private final String SPARQL_CONSTRUCT_DELETIONS_DIR = DATA_DIR + "sparqlConstructs/deletions/"; - private final String MISC_REPLACEMENTS_FILE = DATA_DIR + "miscReplacements.rdf"; - private final String OLD_TBOX_MODEL_DIR = DATA_DIR + "oldVersion/"; - private final String NEW_TBOX_MODEL_DIR = "/WEB-INF/submodels/"; - private final String OLD_TBOX_ANNOTATIONS_DIR = DATA_DIR + "oldAnnotations/"; - private final String NEW_TBOX_ANNOTATIONS_DIR = "/WEB-INF/ontologies/user"; + private static final String DATA_DIR = "/WEB-INF/ontologies/update/"; + private static final String LOG_DIR = "logs/"; + private static final String CHANGED_DATA_DIR = "changedData/"; + private static final String ASK_QUERY_FILE = DATA_DIR + "ask.sparql"; + private static final String SUCCESS_ASSERTIONS_FILE = DATA_DIR + "success.n3"; + private static final String SUCCESS_RDF_FORMAT = "N3"; + private static final String DIFF_FILE = DATA_DIR + "diff.tab.txt"; + private static final String LOG_FILE = DATA_DIR + LOG_DIR + "knowledgeBaseUpdate.log"; + private static final String ERROR_LOG_FILE = DATA_DIR + LOG_DIR + "knowledgeBaseUpdate.error.log"; + private static final String REMOVED_DATA_FILE = DATA_DIR + CHANGED_DATA_DIR + "removedData.n3"; + private static final String ADDED_DATA_FILE = DATA_DIR + CHANGED_DATA_DIR + "addedData.n3"; + private static final String SPARQL_CONSTRUCT_ADDITIONS_DIR = DATA_DIR + "sparqlConstructs/additions/"; + private static final String SPARQL_CONSTRUCT_ADDITIONS_PASS2_DIR = DATA_DIR + "sparqlConstructs/additions-pass2/"; + private static final String SPARQL_CONSTRUCT_DELETIONS_DIR = DATA_DIR + "sparqlConstructs/deletions/"; + private static final String MISC_REPLACEMENTS_FILE = DATA_DIR + "miscReplacements.rdf"; + private static final String OLD_TBOX_MODEL_DIR = DATA_DIR + "oldVersion/"; + private static final String NEW_TBOX_MODEL_DIR = "/WEB-INF/submodels/"; + private static final String OLD_TBOX_ANNOTATIONS_DIR = DATA_DIR + "oldAnnotations/"; + private static final String NEW_TBOX_ANNOTATIONS_DIR = "/WEB-INF/ontologies/user"; public void contextInitialized(ServletContextEvent sce) { @@ -72,13 +72,11 @@ public class UpdateKnowledgeBase implements ServletContextListener { try { ServletContext ctx = sce.getServletContext(); - - OntModelSelector oms = new SimpleOntModelSelector( - (OntModel) sce.getServletContext().getAttribute( - JenaBaseDao.ASSERTIONS_ONT_MODEL_ATTRIBUTE_NAME)); + + OntModelSelector oms = new SimpleOntModelSelector((OntModel) sce.getServletContext().getAttribute(JenaBaseDao.ASSERTIONS_ONT_MODEL_ATTRIBUTE_NAME)); UpdateSettings settings = new UpdateSettings(); - settings.setAskQueryFile(ctx.getRealPath(ASK_QUERY_FILE)); + settings.setAskQueryFile(getAskQueryPath(ctx)); settings.setDataDir(ctx.getRealPath(DATA_DIR)); settings.setSparqlConstructAdditionsDir(ctx.getRealPath(SPARQL_CONSTRUCT_ADDITIONS_DIR)); settings.setSparqlConstructAdditionsPass2Dir(ctx.getRealPath(SPARQL_CONSTRUCT_ADDITIONS_PASS2_DIR)); @@ -237,5 +235,9 @@ public class UpdateKnowledgeBase implements ServletContextListener { public void contextDestroyed(ServletContextEvent arg0) { // nothing to do } - + + public static String getAskQueryPath(ServletContext ctx) { + return ctx.getRealPath(ASK_QUERY_FILE); + + } }