From ae85e5c648d5a4049101fab4ac4313a22e4ca0e3 Mon Sep 17 00:00:00 2001 From: brianjlowe Date: Wed, 7 Dec 2011 18:48:47 +0000 Subject: [PATCH] NIHVIVO-3440 rework of db connection management for VitroJenaSDBModelMaker --- .../dao/jena/SDBGraphConnectionGenerator.java | 46 ++ .../webapp/dao/jena/SDBGraphGenerator.java | 32 +- .../dao/jena/VitroJenaSDBModelMaker.java | 597 ++++++++---------- .../servlet/setup/JenaDataSourceSetup.java | 7 +- .../setup/JenaDataSourceSetupBase.java | 263 ++++---- .../setup/JenaPersistentDataSourceSetup.java | 12 +- 6 files changed, 471 insertions(+), 486 deletions(-) create mode 100644 webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SDBGraphConnectionGenerator.java diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SDBGraphConnectionGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SDBGraphConnectionGenerator.java new file mode 100644 index 000000000..79adfe190 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SDBGraphConnectionGenerator.java @@ -0,0 +1,46 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.dao.jena; + +import java.sql.Connection; +import java.sql.SQLException; + +import org.apache.commons.dbcp.BasicDataSource; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class SDBGraphConnectionGenerator { + + private final static Log log = LogFactory.getLog( + SDBGraphConnectionGenerator.class); + + private BasicDataSource ds = null; + private Connection connection = null; + + public SDBGraphConnectionGenerator(BasicDataSource dataSource) { + this.ds = dataSource; + } + + public Connection generateConnection() throws SQLException { + if ( this.connection == null ) { + this.connection = ds.getConnection(); + } else if ( this.connection.isClosed() ) { + try { + this.connection.close(); + } catch (SQLException e) { + // The connection will throw an "Already closed" + // SQLException that we need to catch. We need to + // make this extra call to .close() in order to make + // sure that the connection is returned to the pool. + // This depends on the particular behavior of version + // 1.4 of the Apache Commons connection pool library. + // Earlier versions threw the exception right away, + // making this impossible. Future versions may do the + // same. + } + this.connection = ds.getConnection(); + } + return connection; + } + +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SDBGraphGenerator.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SDBGraphGenerator.java index 59f42fc92..9fe94ec17 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SDBGraphGenerator.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/SDBGraphGenerator.java @@ -17,14 +17,21 @@ public class SDBGraphGenerator implements SQLGraphGenerator { private static final Log log = LogFactory.getLog(SDBGraphGenerator.class.getName()); - private BasicDataSource ds; + private SDBGraphConnectionGenerator connGen; private Connection connection; private StoreDesc storeDesc; private String graphID; - + public SDBGraphGenerator(BasicDataSource dataSource, StoreDesc storeDesc, String graphID) { - this.ds = dataSource; + this.connGen = new SDBGraphConnectionGenerator(dataSource); + this.storeDesc = storeDesc; + this.graphID = graphID; + } + + public SDBGraphGenerator(SDBGraphConnectionGenerator connectionGenerator, + StoreDesc storeDesc, String graphID) { + this.connGen = connectionGenerator; this.storeDesc = storeDesc; this.graphID = graphID; } @@ -39,24 +46,7 @@ public class SDBGraphGenerator implements SQLGraphGenerator { public Graph generateGraph() { try { - if ( this.connection == null ) { - this.connection = ds.getConnection(); - } else if ( this.connection.isClosed() ) { - try { - this.connection.close(); - } catch (SQLException e) { - // The connection will throw an "Already closed" - // SQLException that we need to catch. We need to - // make this extra call to .close() in order to make - // sure that the connection is returned to the pool. - // This depends on the particular behavior of version - // 1.4 of the Apache Commons connection pool library. - // Earlier versions threw the exception right away, - // making this impossible. Future versions may do the - // same. - } - this.connection = ds.getConnection(); - } + this.connection = connGen.generateConnection(); Store store = SDBFactory.connectStore(connection, storeDesc); return SDBFactory.connectNamedGraph(store, graphID); } catch (SQLException e) { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VitroJenaSDBModelMaker.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VitroJenaSDBModelMaker.java index ec95d31b0..ffc84f15b 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VitroJenaSDBModelMaker.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/dao/jena/VitroJenaSDBModelMaker.java @@ -2,18 +2,18 @@ package edu.cornell.mannlib.vitro.webapp.dao.jena; -import java.sql.Connection; import java.sql.SQLException; +import java.text.Collator; import java.util.ArrayList; import java.util.Collections; -import java.util.Comparator; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; import java.util.Set; import org.apache.commons.dbcp.BasicDataSource; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import com.hp.hpl.jena.graph.Graph; import com.hp.hpl.jena.graph.GraphMaker; @@ -28,13 +28,10 @@ import com.hp.hpl.jena.rdf.model.Model; import com.hp.hpl.jena.rdf.model.ModelFactory; import com.hp.hpl.jena.rdf.model.ModelMaker; import com.hp.hpl.jena.rdf.model.ModelReader; -import com.hp.hpl.jena.rdf.model.Property; import com.hp.hpl.jena.rdf.model.RDFNode; import com.hp.hpl.jena.rdf.model.Resource; -import com.hp.hpl.jena.rdf.model.ResourceFactory; import com.hp.hpl.jena.rdf.model.Statement; import com.hp.hpl.jena.rdf.model.StmtIterator; -import com.hp.hpl.jena.sdb.SDB; import com.hp.hpl.jena.sdb.SDBFactory; import com.hp.hpl.jena.sdb.Store; import com.hp.hpl.jena.sdb.StoreDesc; @@ -42,74 +39,59 @@ import com.hp.hpl.jena.sdb.sql.SDBConnection; import com.hp.hpl.jena.sdb.util.StoreUtils; import com.hp.hpl.jena.util.iterator.ExtendedIterator; import com.hp.hpl.jena.util.iterator.WrappedIterator; -import com.hp.hpl.jena.vocabulary.OWL; -import com.hp.hpl.jena.vocabulary.RDF; import com.hp.hpl.jena.vocabulary.RDFS; -import com.ibm.icu.text.Collator; public class VitroJenaSDBModelMaker implements ModelMaker { - // TODO: need to rethink the inheritance/interfaces here - - private StoreDesc storeDesc = null; - private BasicDataSource bds = null; - private SDBConnection conn = null; - - public static final String METADATA_MODEL_URI = "http://vitro.mannlib.cornell.edu/ns/vitro/sdb/metadata"; - public static final String HAS_NAMED_MODEL_URI = "http://vitro.mannlib.cornell.edu/ns/vitro/sdb/hasNamedModel"; - - private Resource sdbResource; // a resource representing the SDB database - - public VitroJenaSDBModelMaker(StoreDesc storeDesc, BasicDataSource bds) throws SQLException { - - this.storeDesc = storeDesc; - this.bds = bds; - Store store = getStore(); - try { - - Model metadataModel = getMetadataModel(); - - if (metadataModel.size()==0) { - // set up the model name metadata to avoid expensive calls to listNames() - Resource sdbRes = metadataModel.createResource(); - this.sdbResource = sdbRes; - Iterator nameIt = SDBFactory.connectDataset(store).listNames(); - while (nameIt.hasNext()) { - String name = (String) nameIt.next(); - metadataModel.add(sdbResource,metadataModel.getProperty(HAS_NAMED_MODEL_URI),name); - } - } else { - StmtIterator stmtIt = metadataModel.listStatements((Resource)null, metadataModel.getProperty(HAS_NAMED_MODEL_URI),(RDFNode)null); - if (stmtIt.hasNext()) { - Statement stmt = stmtIt.nextStatement(); - sdbResource = stmt.getSubject(); - } - stmtIt.close(); - } - } finally { - store.close(); - } - } - - private static final int MAX_TRIES = 10; - - private Store getStore() { - Store store = null; - boolean goodStore = false; - int tries = 0; - while (!goodStore && tries < MAX_TRIES) { - tries++; - if (conn == null) { - try { - conn = new SDBConnection(bds.getConnection()); + private final static Log log = LogFactory.getLog(VitroJenaSDBModelMaker.class); + + private StoreDesc storeDesc = null; + private BasicDataSource bds = null; + private SDBConnection conn = null; + private SDBGraphConnectionGenerator connGen = null; + + public static final String METADATA_MODEL_URI = + "http://vitro.mannlib.cornell.edu/ns/vitro/sdb/metadata"; + + public static final String HAS_NAMED_MODEL_URI = + "http://vitro.mannlib.cornell.edu/ns/vitro/sdb/hasNamedModel"; + + private Resource sdbResource; // a resource representing the SDB database + + public VitroJenaSDBModelMaker(StoreDesc storeDesc, BasicDataSource bds) + throws SQLException { + + this.storeDesc = storeDesc; + this.bds = bds; + connGen = new SDBGraphConnectionGenerator(bds); + + Store store = getStore(); + try { + setUpMetadata(store); + } finally { + store.close(); + } + } + + private static final int MAX_TRIES = 10; + + private Store getStore() { + Store store = null; + boolean goodStore = false; + int tries = 0; + while (!goodStore && tries < MAX_TRIES) { + tries++; + if (conn == null) { + try { + conn = new SDBConnection(connGen.generateConnection()); } catch (SQLException sqle) { throw new RuntimeException( "Unable to get SQL connection", sqle); } - } - store = SDBFactory.connectStore(conn, storeDesc); - try { - if (!StoreUtils.isFormatted(store)) { + } + store = SDBFactory.connectStore(conn, storeDesc); + try { + if (!StoreUtils.isFormatted(store)) { // initialize the store try { store.getTableFormatter().create(); @@ -120,301 +102,244 @@ public class VitroJenaSDBModelMaker implements ModelMaker { "VitroJenaSDBModelMaker", e); } } - } catch (SQLException sqle) { + } catch (SQLException sqle) { conn.close(); conn = null; - } - if (conn != null) { + } + if (conn != null) { if (isWorking(store)) { goodStore = true; - } else { - conn.close(); + } else { + conn.close(); conn = null; - } + } } - } - if (store == null) { - throw new RuntimeException( - "Unable to connect to SDB store after " + - MAX_TRIES + " attempts"); - } - return store; - } - - Model getMetadataModel() { - return getModel(METADATA_MODEL_URI); - } - - private boolean isWorking(Store store) { - Dataset d = SDBFactory.connectDataset(store); - try { - String validationQuery = "ASK { <" + RDFS.Resource.getURI() + "> " + - " <" + RDFS.isDefinedBy.getURI() + "> " + - " <" + RDFS.Resource.getURI() + "> }"; - Query q = QueryFactory.create(validationQuery); - QueryExecution qe = QueryExecutionFactory.create(q, d); - try { - qe.execAsk(); - return true; - } catch (Exception e) { - e.printStackTrace(); - return false; - } finally { - qe.close(); - } - } finally { - d.close(); - } - } - - public void close() { - getStore().close(); - } + } + if (store == null) { + throw new RuntimeException( + "Unable to connect to SDB store after " + + MAX_TRIES + " attempts"); + } + return store; + } + + Model getMetadataModel() { + return getModel(METADATA_MODEL_URI); + } + + private void setUpMetadata(Store store) { + Model metadataModel = getMetadataModel(); + + if (metadataModel.size() == 0) { + // set up the model name metadata to avoid expensive calls to + // listNames() + Resource sdbRes = metadataModel.createResource(); + this.sdbResource = sdbRes; + Iterator nameIt = SDBFactory.connectDataset(store).listNames(); + while (nameIt.hasNext()) { + String name = (String) nameIt.next(); + metadataModel.add(sdbResource,metadataModel.getProperty( + HAS_NAMED_MODEL_URI),name); + } + } else { + StmtIterator stmtIt = metadataModel.listStatements( + (Resource) null, metadataModel.getProperty( + HAS_NAMED_MODEL_URI),(RDFNode) null); + if (stmtIt.hasNext()) { + Statement stmt = stmtIt.nextStatement(); + sdbResource = stmt.getSubject(); + } + stmtIt.close(); + } - public Model createModel(String modelName) { - Model model = getModel(modelName); - Model metadataModel = getMetadataModel(); - try { - metadataModel.add(sdbResource,metadataModel.getProperty(HAS_NAMED_MODEL_URI), modelName); - } finally { - metadataModel.close(); - } - return model; - } + } + + private boolean isWorking(Store store) { + Dataset d = SDBFactory.connectDataset(store); + try { + String validationQuery = "ASK { <" + RDFS.Resource.getURI() + "> " + + " <" + RDFS.isDefinedBy.getURI() + "> " + + " <" + RDFS.Resource.getURI() + "> }"; + Query q = QueryFactory.create(validationQuery); + QueryExecution qe = QueryExecutionFactory.create(q, d); + try { + qe.execAsk(); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } finally { + qe.close(); + } + } finally { + d.close(); + } + } + + public void close() { + getStore().close(); + } - public Model createModel(String arg0, boolean arg1) { - // TODO Figure out if we can offer a "create if not found" option using SDB - return createModel(arg0); - } + public Model createModel(String modelName) { + Model model = getModel(modelName); + Model metadataModel = getMetadataModel(); + try { + metadataModel.add( + sdbResource,metadataModel.getProperty( + HAS_NAMED_MODEL_URI), modelName); + } finally { + metadataModel.close(); + } + return model; + } - public GraphMaker getGraphMaker() { - throw new UnsupportedOperationException("GraphMaker not supported by "+this.getClass().getName()); - } + public Model createModel(String arg0, boolean arg1) { + // TODO Figure out if we can offer a "create if not found" option using SDB + return createModel(arg0); + } - public boolean hasModel(String arg0) { - Model metadataModel = getMetadataModel(); - try { - StmtIterator stmtIt = metadataModel.listStatements(sdbResource,metadataModel.getProperty(HAS_NAMED_MODEL_URI),arg0); - try { - return stmtIt.hasNext(); - } finally { - if (stmtIt != null) { - stmtIt.close(); - } - } - } finally { - metadataModel.close(); - } - } + public GraphMaker getGraphMaker() { + throw new UnsupportedOperationException( + "GraphMaker not supported by " + this.getClass().getName()); + } - public ExtendedIterator listModels() { - ArrayList metaNameList = new ArrayList(); - ArrayList storeNameList = new ArrayList(); - ArrayList unionNameList = new ArrayList(); - - Model metadataModel = getMetadataModel(); - - Iterator metadataNameIt = metadataModel.listObjectsOfProperty(metadataModel.getProperty(HAS_NAMED_MODEL_URI)); - Iterator storeNameIt = StoreUtils.storeGraphNames(getStore()); - Node node = null; - RDFNode rdfNode = null; - - // implement comparator to sort the lists - - class sortList implements Comparator{ - Collator collator = Collator.getInstance(); - int compareResult; - public int compare(String str1, String str2){ - compareResult = collator.compare(str1, str2); - if(compareResult > 0) - return 1; - else if(compareResult < 0) - return -1; - else - return 0; - } - } - - // put the names into the lists. - - while (metadataNameIt.hasNext()) { - rdfNode = metadataNameIt.next(); - if (rdfNode.isLiteral()) { - metaNameList.add( ((Literal)rdfNode).getLexicalForm()); - } - } - - - - while (storeNameIt.hasNext()){ - node = storeNameIt.next(); - storeNameList.add(node.getURI()); - } - - - // sort the lists - if(metaNameList.size()!=0) - Collections.sort(metaNameList, new sortList()); - if(storeNameList.size()!=0) - Collections.sort(storeNameList, new sortList()); - - - // code to merge the lists. - - Collator collator = Collator.getInstance(); - int check = 0; - - Iterator metaItr = metaNameList.iterator(); - Iterator storeItr = storeNameList.iterator(); - String metaString = null; - String storeString = null; - - do{ - - if(metaString != null && storeString !=null){ - check = collator.compare(metaString, storeString); - } - else if(metaString!=null && storeString == null){ - unionNameList.add(metaString); - if(metaItr.hasNext()) - metaString = metaItr.next(); - else - metaString = null; - continue; - } - else if(metaString==null && storeString!=null){ - unionNameList.add(storeString); - if(storeItr.hasNext()) - storeString = storeItr.next(); - else - storeString = null; - continue; - } - else{ - if(metaItr.hasNext()){ - metaString = metaItr.next(); - } - if(storeItr.hasNext()){ - storeString = storeItr.next(); - } - if(metaString!=null && storeString !=null) - check = collator.compare(metaString, storeString); - else - continue; - } - - if(check > 0){ - unionNameList.add(storeString); - if(storeItr.hasNext()) - storeString = storeItr.next(); - else - storeString = null; - } - else if(check < 0){ - unionNameList.add(metaString); - if(metaItr.hasNext()) - metaString = metaItr.next(); - else - metaString = null; - } - else{ - unionNameList.add(metaString); - if(metaItr.hasNext()) - metaString = metaItr.next(); - else - metaString = null; - - if(storeItr.hasNext()) - storeString = storeItr.next(); - else - storeString = null; - } - - - }while(metaString!=null || storeString!=null); - - if (metadataModel != null) { - metadataModel.close(); - } - - return WrappedIterator.create(unionNameList.iterator()); - } + public boolean hasModel(String arg0) { + Model metadataModel = getMetadataModel(); + try { + StmtIterator stmtIt = metadataModel.listStatements( + sdbResource, metadataModel.getProperty( + HAS_NAMED_MODEL_URI), arg0); + try { + return stmtIt.hasNext(); + } finally { + if (stmtIt != null) { + stmtIt.close(); + } + } + } finally { + metadataModel.close(); + } + } - public Model openModel(String arg0, boolean arg1) { - return SDBFactory.connectNamedModel(getStore(),arg0); - } + public ExtendedIterator listModels() { + Model metadataModel = getMetadataModel(); + try { + return listModelNames(metadataModel); + } finally { + metadataModel.close(); + } + } + + private ExtendedIterator listModelNames(Model metadataModel) { + Set modelNameSet = new HashSet(); + + Iterator metadataNameIt = metadataModel.listObjectsOfProperty( + metadataModel.getProperty(HAS_NAMED_MODEL_URI)); + while (metadataNameIt.hasNext()) { + RDFNode rdfNode = metadataNameIt.next(); + if (rdfNode.isLiteral()) { + modelNameSet.add(((Literal) rdfNode).getLexicalForm()); + } + } + + Iterator storeNameIt = StoreUtils.storeGraphNames(getStore()); + while (storeNameIt.hasNext()){ + Node node = storeNameIt.next(); + modelNameSet.add(node.getURI()); + } + + List modelNameList = new ArrayList(); + modelNameList.addAll(modelNameSet); + Collections.sort(modelNameList, Collator.getInstance()); + + return WrappedIterator.create(modelNameList.iterator()); + } - public void removeModel(String arg0) { - Model m = getModel(arg0); - m.removeAll(null,null,null); - Model metadataModel = getMetadataModel(); - try { - metadataModel.remove(sdbResource,metadataModel.getProperty(HAS_NAMED_MODEL_URI),metadataModel.createLiteral(arg0)); - } finally { - metadataModel.close(); - } - } + public Model openModel(String arg0, boolean arg1) { + return SDBFactory.connectNamedModel(getStore(),arg0); + } - public Model addDescription(Model arg0, Resource arg1) { - throw new UnsupportedOperationException("addDescription not supported by "+this.getClass().getName()); - } + public void removeModel(String arg0) { + Model m = getModel(arg0); + m.removeAll(null,null,null); + Model metadataModel = getMetadataModel(); + try { + metadataModel.remove(sdbResource, metadataModel.getProperty( + HAS_NAMED_MODEL_URI),metadataModel.createLiteral(arg0)); + } finally { + metadataModel.close(); + } + } - public Model createModelOver(String arg0) { - throw new UnsupportedOperationException("createModelOver not supported by "+this.getClass().getName()); - } + public Model addDescription(Model arg0, Resource arg1) { + throw new UnsupportedOperationException( + "addDescription not supported by " + this.getClass().getName()); + } - public Model getDescription() { - throw new UnsupportedOperationException("createModelOver not supported by "+this.getClass().getName()); - } + public Model createModelOver(String arg0) { + throw new UnsupportedOperationException( + "createModelOver not supported by " + this.getClass().getName()); + } - public Model getDescription(Resource arg0) { - throw new UnsupportedOperationException("getDescription not supported by "+this.getClass().getName()); - } + public Model getDescription() { + throw new UnsupportedOperationException( + "createModelOver not supported by " + this.getClass().getName()); + } - public Model openModel() { - return SDBFactory.connectDefaultModel(getStore()); - } + public Model getDescription(Resource arg0) { + throw new UnsupportedOperationException( + "getDescription not supported by "+this.getClass().getName()); + } - public Model createDefaultModel() { - return SDBFactory.connectDefaultModel(getStore()); - } + public Model openModel() { + return SDBFactory.connectDefaultModel(getStore()); + } - public Model createFreshModel() { - throw new UnsupportedOperationException("createFreshModel not supported by "+this.getClass().getName()); - } + public Model createDefaultModel() { + return SDBFactory.connectDefaultModel(getStore()); + } - /** - * @deprecated - */ - public Model createModel() { - return SDBFactory.connectDefaultModel(getStore()); - } + public Model createFreshModel() { + throw new UnsupportedOperationException( + "createFreshModel not supported by " + this.getClass().getName()); + } - /** - * @deprecated - */ - public Model getModel() { - return SDBFactory.connectDefaultModel(getStore()); - } + /** + * @deprecated + */ + public Model createModel() { + return SDBFactory.connectDefaultModel(getStore()); + } - public Model openModel(String arg0) { - return SDBFactory.connectDefaultModel(getStore()); - } + /** + * @deprecated + */ + public Model getModel() { + return SDBFactory.connectDefaultModel(getStore()); + } - public Model openModelIfPresent(String arg0) { - return (this.hasModel(arg0)) ? SDBFactory.connectNamedModel(getStore(),arg0) : null; - } + public Model openModel(String arg0) { + return SDBFactory.connectDefaultModel(getStore()); + } - public Model getModel(String modelName) { - SDBGraphGenerator graphGen = new SDBGraphGenerator( - bds, storeDesc, modelName); - Graph g = new RegeneratingGraph( - SDBFactory.connectNamedGraph(getStore(), modelName), graphGen); - return ModelFactory.createModelForGraph(g); - } + public Model openModelIfPresent(String arg0) { + return (this.hasModel(arg0)) + ? SDBFactory.connectNamedModel(getStore(),arg0) + : null; + } - public Model getModel(String arg0, ModelReader arg1) { - throw new UnsupportedOperationException("getModel(String,ModelReader) not supported by "+this.getClass().getName()); - } + public Model getModel(String modelName) { + SDBGraphGenerator graphGen = new SDBGraphGenerator( + connGen, storeDesc, modelName); + Graph g = new RegeneratingGraph( + SDBFactory.connectNamedGraph(getStore(), modelName), graphGen); + return ModelFactory.createModelForGraph(g); + } + + public Model getModel(String arg0, ModelReader arg1) { + throw new UnsupportedOperationException( + "getModel(String, ModelReader) not supported by " + + this.getClass().getName()); + } } 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 45079018f..1530d48fb 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 @@ -107,8 +107,11 @@ public class JenaDataSourceSetup extends JenaDataSourceSetupBase StoreDesc storeDesc = makeStoreDesc(ctx); setApplicationStoreDesc(storeDesc, ctx); - BasicDataSource bds = makeDataSourceFromConfigurationProperties(ctx); - this.setApplicationDataSource(bds, ctx); + BasicDataSource bds = getApplicationDataSource(ctx); + if (bds == null) { + bds = makeDataSourceFromConfigurationProperties(ctx); + setApplicationDataSource(bds, ctx); + } Store store = connectStore(bds, storeDesc); setApplicationStore(store, ctx); diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java index 4e0dd7807..a9f61f239 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaDataSourceSetupBase.java @@ -34,17 +34,24 @@ import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaModelMaker; import edu.cornell.mannlib.vitro.webapp.dao.jena.VitroJenaSDBModelMaker; public class JenaDataSourceSetupBase extends JenaBaseDaoCon { - private static final String VITRO_DEFAULT_NAMESPACE = "Vitro.defaultNamespace"; + private static final String VITRO_DEFAULT_NAMESPACE = "Vitro.defaultNamespace"; - private static final Log log = LogFactory.getLog( + private static final Log log = LogFactory.getLog( JenaDataSourceSetupBase.class); + protected final static String MAX_ACTIVE_PROPERTY = + "VitroConnection.DataSource.pool.maxActive"; + + protected final static String MAX_IDLE_PROPERTY = + "VitroConnection.DataSource.pool.maxIdle"; + protected final static int DEFAULT_MAXWAIT = 10000, // ms DEFAULT_MAXACTIVE = 40, + MINIMUM_MAXACTIVE = 20, DEFAULT_MAXIDLE = 10, - DEFAULT_TIMEBETWEENEVICTIONS = 3 * 1000, // ms + DEFAULT_TIMEBETWEENEVICTIONS = 180 * 1000, // ms DEFAULT_TESTSPEREVICTION = DEFAULT_MAXACTIVE, - DEFAULT_MINEVICTIONIDLETIME = 3 * 1000; // ms + DEFAULT_MINEVICTIONIDLETIME = 180 * 1000; // ms protected final static boolean DEFAULT_TESTONBORROW = true, DEFAULT_TESTONRETURN = true, DEFAULT_TESTWHILEIDLE = true; @@ -132,8 +139,8 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon { static final OntModelSpec MEM_ONT_MODEL_SPEC = OntModelSpec.OWL_MEM; private String getJdbcUrl(ServletContext ctx) { - String jdbcUrl = ConfigurationProperties.getBean(ctx).getProperty( - "VitroConnection.DataSource.url"); + String jdbcUrl = ConfigurationProperties.getBean(ctx).getProperty( + "VitroConnection.DataSource.url"); // Ensure that MySQL handles unicode properly, else all kinds of // horrible nastiness ensues. @@ -155,8 +162,8 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon { String jdbcUrl = getJdbcUrl(ctx); - String username = ConfigurationProperties.getBean(ctx).getProperty( - "VitroConnection.DataSource.username"); + String username = ConfigurationProperties.getBean(ctx).getProperty( + "VitroConnection.DataSource.username"); String password = ConfigurationProperties.getBean(ctx).getProperty( "VitroConnection.DataSource.password"); BasicDataSource ds = makeBasicDataSource( @@ -175,29 +182,29 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon { * a properties file. */ public final BasicDataSource makeDataSourceFromConfigurationProperties(ServletContext ctx){ - String dbDriverClassname = ConfigurationProperties.getBean(ctx) - .getProperty("VitroConnection.DataSource.driver", - getDbDriverClassName(ctx)); + String dbDriverClassname = ConfigurationProperties.getBean(ctx) + .getProperty("VitroConnection.DataSource.driver", + getDbDriverClassName(ctx)); String jdbcUrl = getJdbcUrl(ctx); - String username = ConfigurationProperties.getBean(ctx).getProperty( - "VitroConnection.DataSource.username"); - String password = ConfigurationProperties.getBean(ctx).getProperty( - "VitroConnection.DataSource.password"); + String username = ConfigurationProperties.getBean(ctx).getProperty( + "VitroConnection.DataSource.username"); + String password = ConfigurationProperties.getBean(ctx).getProperty( + "VitroConnection.DataSource.password"); return makeBasicDataSource( dbDriverClassname, jdbcUrl, username, password, ctx); } public void setApplicationDataSource(BasicDataSource bds, ServletContext ctx) { - ctx.setAttribute(getDataSourceAttributeName(), bds); + ctx.setAttribute(getDataSourceAttributeName(), bds); } public static BasicDataSource getApplicationDataSource(ServletContext ctx) { - return (BasicDataSource) ctx.getAttribute(getDataSourceAttributeName()); + return (BasicDataSource) ctx.getAttribute(getDataSourceAttributeName()); } private static String getDataSourceAttributeName() { - return JenaDataSourceSetupBase.class.getName() + ".dataSource"; + return JenaDataSourceSetupBase.class.getName() + ".dataSource"; } public static BasicDataSource makeBasicDataSource(String dbDriverClassname, @@ -213,21 +220,29 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon { ds.setUsername(username); ds.setPassword(password); int maxActiveInt = DEFAULT_MAXACTIVE; - String maxActiveStr = ConfigurationProperties.getBean(ctx).getProperty( - "VitroConnection.DataSource.pool.maxActive"); + String maxActiveStr = ConfigurationProperties.getBean(ctx).getProperty( + MAX_ACTIVE_PROPERTY); if (!StringUtils.isEmpty(maxActiveStr)) { try { - maxActiveInt = Integer.parseInt(maxActiveStr); + int maxActiveIntFromConfigProperties = Integer.parseInt(maxActiveStr); + if (maxActiveIntFromConfigProperties < MINIMUM_MAXACTIVE) { + log.warn("Specified value for " + MAX_ACTIVE_PROPERTY + + " is too low. Using minimum value of " + + MINIMUM_MAXACTIVE); + maxActiveInt = MINIMUM_MAXACTIVE; + } else { + maxActiveInt = maxActiveIntFromConfigProperties; + } } catch (NumberFormatException nfe) { log.error("Unable to parse connection pool maxActive setting " + maxActiveStr + " as an integer"); - } + } } int maxIdleInt = (maxActiveInt > DEFAULT_MAXACTIVE) ? maxActiveInt / 4 : DEFAULT_MAXIDLE; - String maxIdleStr = ConfigurationProperties.getBean(ctx).getProperty( - "VitroConnection.DataSource.pool.maxIdle"); + String maxIdleStr = ConfigurationProperties.getBean(ctx).getProperty( + MAX_IDLE_PROPERTY); if (!StringUtils.isEmpty(maxIdleStr)) { try { maxIdleInt = Integer.parseInt(maxIdleStr); @@ -245,6 +260,7 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon { ds.setMinEvictableIdleTimeMillis(DEFAULT_MINEVICTIONIDLETIME); ds.setNumTestsPerEvictionRun(maxActiveInt); ds.setTimeBetweenEvictionRunsMillis(DEFAULT_TIMEBETWEENEVICTIONS); + ds.setInitialSize(ds.getMaxActive() / 10); try { ds.getConnection().close(); @@ -256,19 +272,19 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon { } public enum TripleStoreType { - RDB, SDB + RDB, SDB } public static boolean isFirstStartup() { - return firstStartup; + return firstStartup; } protected Model makeDBModel(BasicDataSource ds, String jenaDbModelname, OntModelSpec jenaDbOntModelSpec, ServletContext ctx) { - return makeDBModel( - ds, jenaDbModelname, jenaDbOntModelSpec, TripleStoreType.RDB, ctx); + return makeDBModel( + ds, jenaDbModelname, jenaDbOntModelSpec, TripleStoreType.RDB, ctx); } protected Model makeDBModel(BasicDataSource ds, @@ -290,28 +306,28 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon { try { Graph g = null; switch (storeType) { - case RDB: - g = new RegeneratingGraph( - new RDBGraphGenerator( - ds, dbType, jenaDbModelName)); - break; - case SDB: - String layoutStr = ConfigurationProperties.getBean(ctx) - .getProperty( - "VitroConnection.DataSource.sdb.layout", - "layout2/hash"); - String dbtypeStr = ConfigurationProperties.getBean(ctx) - .getProperty("VitroConnection.DataSource.dbtype", - "MySQL"); - StoreDesc desc = new StoreDesc( - LayoutType.fetch(layoutStr), - DatabaseType.fetch(dbtypeStr) ); - g = new RegeneratingGraph( - new SDBGraphGenerator( - ds, desc, jenaDbModelName)); - break; - default: throw new RuntimeException ( - "Unsupported store type " + storeType); + case RDB: + g = new RegeneratingGraph( + new RDBGraphGenerator( + ds, dbType, jenaDbModelName)); + break; + case SDB: + String layoutStr = ConfigurationProperties.getBean(ctx) + .getProperty( + "VitroConnection.DataSource.sdb.layout", + "layout2/hash"); + String dbtypeStr = ConfigurationProperties.getBean(ctx) + .getProperty("VitroConnection.DataSource.dbtype", + "MySQL"); + StoreDesc desc = new StoreDesc( + LayoutType.fetch(layoutStr), + DatabaseType.fetch(dbtypeStr) ); + g = new RegeneratingGraph( + new SDBGraphGenerator( + ds, desc, jenaDbModelName)); + break; + default: throw new RuntimeException ( + "Unsupported store type " + storeType); } dbModel = ModelFactory.createModelForGraph(g); log.debug("Using database at "+ds.getUrl()); @@ -336,28 +352,28 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon { } public static void readOntologyFileFromPath(String p, Model model, ServletContext ctx) { - //Check that this is a file and not a directory - File f = new File(ctx.getRealPath(p)); - if(f.exists() && f.isFile()){ - String format = getRdfFormat(p); - log.info("Loading ontology file at " + p + - " as format " + format); - InputStream ontologyInputStream = ctx.getResourceAsStream(p); - try { - model.read(ontologyInputStream, null, format); - log.debug("...successful"); - } catch (Throwable t) { - log.error("Failed to load ontology file at '" + p + - "' as format " + format, t); - } - } else { - if(!f.exists()) { - log.debug("File for path " + p + " does not exist"); - } - else if(f.isDirectory()) { - log.debug("Path " + p + " corresponds to directory and not file so was not read in"); - } - } + //Check that this is a file and not a directory + File f = new File(ctx.getRealPath(p)); + if(f.exists() && f.isFile()){ + String format = getRdfFormat(p); + log.info("Loading ontology file at " + p + + " as format " + format); + InputStream ontologyInputStream = ctx.getResourceAsStream(p); + try { + model.read(ontologyInputStream, null, format); + log.debug("...successful"); + } catch (Throwable t) { + log.error("Failed to load ontology file at '" + p + + "' as format " + format, t); + } + } else { + if(!f.exists()) { + log.debug("File for path " + p + " does not exist"); + } + else if(f.isDirectory()) { + log.debug("Path " + p + " corresponds to directory and not file so was not read in"); + } + } } private static String getRdfFormat(String filename){ @@ -378,32 +394,33 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon { private static final String rdbModelMaker = "vitroJenaModelMaker"; protected void makeModelMakerFromConnectionProperties(TripleStoreType type, ServletContext ctx){ - String jdbcUrl = getJdbcUrl(ctx); + String jdbcUrl = getJdbcUrl(ctx); String dbtypeStr = ConfigurationProperties.getBean(ctx).getProperty("VitroConnection.DataSource.dbtype","MySQL"); - String username = ConfigurationProperties.getBean(ctx).getProperty( - "VitroConnection.DataSource.username"); - String password = ConfigurationProperties.getBean(ctx).getProperty( - "VitroConnection.DataSource.password"); - - if (TripleStoreType.RDB.equals(type)){ - vjmm = new VitroJenaModelMaker( - jdbcUrl, username, password, dbtypeStr, ctx); - } - - else if(TripleStoreType.SDB.equals(type)){ - StoreDesc storeDesc = new StoreDesc( - LayoutType.LayoutTripleNodesHash, DatabaseType.fetch(dbtypeStr)); - BasicDataSource bds = JenaDataSourceSetup.makeBasicDataSource( - getDbDriverClassName(ctx), jdbcUrl, username, password, ctx); - try { - vsmm = new VitroJenaSDBModelMaker(storeDesc, bds); - } catch (SQLException sqle) { - log.error("Unable to set up SDB ModelMaker", sqle); - } - } - - return; - + String username = ConfigurationProperties.getBean(ctx).getProperty( + "VitroConnection.DataSource.username"); + String password = ConfigurationProperties.getBean(ctx).getProperty( + "VitroConnection.DataSource.password"); + + if (TripleStoreType.RDB.equals(type)){ + vjmm = new VitroJenaModelMaker( + jdbcUrl, username, password, dbtypeStr, ctx); + } else if (TripleStoreType.SDB.equals(type)) { + StoreDesc storeDesc = new StoreDesc( + LayoutType.LayoutTripleNodesHash, DatabaseType.fetch(dbtypeStr)); + BasicDataSource bds = JenaDataSourceSetup.makeBasicDataSource( + getDbDriverClassName(ctx), jdbcUrl, username, password, ctx); + bds.setMaxActive(4); // for now, the SDB model makers should not use more + // than a small handful of connections + bds.setMaxIdle(2); + try { + vsmm = new VitroJenaSDBModelMaker(storeDesc, bds); + } catch (SQLException sqle) { + log.error("Unable to set up SDB ModelMaker", sqle); + } + } + + return; + } /** @@ -441,47 +458,47 @@ public class JenaDataSourceSetupBase extends JenaBaseDaoCon { public static void setVitroJenaModelMaker(VitroJenaModelMaker vjmm, ServletContext ctx){ - ctx.setAttribute(rdbModelMaker, vjmm); + ctx.setAttribute(rdbModelMaker, vjmm); } public static void setVitroJenaSDBModelMaker(VitroJenaSDBModelMaker vsmm, ServletContext ctx){ - ctx.setAttribute(sdbModelMaker, vsmm); + ctx.setAttribute(sdbModelMaker, vsmm); } - protected String getDefaultNamespace(ServletContext ctx) { - String dns = ConfigurationProperties.getBean(ctx).getProperty( - VITRO_DEFAULT_NAMESPACE); - if ((dns != null) && (!dns.isEmpty())) { - return dns; - } else { - throw new IllegalStateException("deploy.properties does not " - + "contain a value for '" + VITRO_DEFAULT_NAMESPACE + "'"); - } - } + protected String getDefaultNamespace(ServletContext ctx) { + String dns = ConfigurationProperties.getBean(ctx).getProperty( + VITRO_DEFAULT_NAMESPACE); + if ((dns != null) && (!dns.isEmpty())) { + return dns; + } else { + throw new IllegalStateException("deploy.properties does not " + + "contain a value for '" + VITRO_DEFAULT_NAMESPACE + "'"); + } + } protected VitroJenaModelMaker getVitroJenaModelMaker(){ - return vjmm; + return vjmm; } protected VitroJenaSDBModelMaker getVitroJenaSDBModelMaker(){ - return vsmm; + return vsmm; } - private static String getDbType(ServletContext ctx) { - return ConfigurationProperties.getBean(ctx).getProperty( // database type - "VitroConnection.DataSource.dbtype", "MySQL"); - } + private static String getDbType(ServletContext ctx) { + return ConfigurationProperties.getBean(ctx).getProperty( // database type + "VitroConnection.DataSource.dbtype", "MySQL"); + } - private static String getDbDriverClassName(ServletContext ctx) { - return ConfigurationProperties.getBean(ctx).getProperty( - "VitroConnection.DataSource.driver", "com.mysql.jdbc.Driver"); + private static String getDbDriverClassName(ServletContext ctx) { + return ConfigurationProperties.getBean(ctx).getProperty( + "VitroConnection.DataSource.driver", "com.mysql.jdbc.Driver"); - } + } - private static String getValidationQuery(ServletContext ctx) { - return ConfigurationProperties.getBean(ctx).getProperty( - "VitroConnection.DataSource.validationQuery", "SELECT 1"); - } + private static String getValidationQuery(ServletContext ctx) { + return ConfigurationProperties.getBean(ctx).getProperty( + "VitroConnection.DataSource.validationQuery", "SELECT 1"); + } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaPersistentDataSourceSetup.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaPersistentDataSourceSetup.java index b30b04921..ec135fe58 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaPersistentDataSourceSetup.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/servlet/setup/JenaPersistentDataSourceSetup.java @@ -9,6 +9,7 @@ import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; +import org.apache.commons.dbcp.BasicDataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.joda.time.DateTime; @@ -39,10 +40,13 @@ public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase // we do not want to fetch imports when we wrap Models in OntModels OntDocumentManager.getInstance().setProcessImports(false); + + BasicDataSource bds = makeDataSourceFromConfigurationProperties(ctx); + setApplicationDataSource(bds, ctx); // user accounts Model try { - Model userAccountsDbModel = makeDBModelFromConfigurationProperties( + Model userAccountsDbModel = makeDBModel(bds, JENA_USER_ACCOUNTS_MODEL, DB_ONT_MODEL_SPEC, ctx); if (userAccountsDbModel.size() == 0) { firstStartup = true; @@ -66,7 +70,7 @@ public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase // display, editing and navigation Model try { - Model displayDbModel = makeDBModelFromConfigurationProperties( + Model displayDbModel = makeDBModel(bds, JENA_DISPLAY_METADATA_MODEL, DB_ONT_MODEL_SPEC, ctx); if (displayDbModel.size() == 0) { readOntologyFilesInPathSet(APPPATH, ctx,displayDbModel); @@ -85,7 +89,7 @@ public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase //display tbox - currently reading in every time try { - Model displayTboxModel = makeDBModelFromConfigurationProperties( + Model displayTboxModel = makeDBModel(bds, JENA_DISPLAY_TBOX_MODEL, DB_ONT_MODEL_SPEC, ctx); //Reading in single file every time //TODO: Check if original needs to be cleared/removed every time? @@ -103,7 +107,7 @@ public class JenaPersistentDataSourceSetup extends JenaDataSourceSetupBase //Display Display model, currently empty, create if doesn't exist but no files to load try { - Model displayDisplayModel = makeDBModelFromConfigurationProperties( + Model displayDisplayModel = makeDBModel(bds, JENA_DISPLAY_DISPLAY_MODEL, DB_ONT_MODEL_SPEC, ctx); //Reading in single file every time //TODO: Check if original needs to be cleared/removed every time?