NIHVIVO-3440 rework of db connection management for VitroJenaSDBModelMaker

This commit is contained in:
brianjlowe 2011-12-07 18:48:47 +00:00
parent 989f0d9f97
commit ae85e5c648
6 changed files with 471 additions and 486 deletions

View file

@ -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;
}
}

View file

@ -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) {

View file

@ -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<String> metaNameList = new ArrayList<String>();
ArrayList<String> storeNameList = new ArrayList<String>();
ArrayList<String> unionNameList = new ArrayList<String>();
Model metadataModel = getMetadataModel();
Iterator<RDFNode> metadataNameIt = metadataModel.listObjectsOfProperty(metadataModel.getProperty(HAS_NAMED_MODEL_URI));
Iterator<Node> storeNameIt = StoreUtils.storeGraphNames(getStore());
Node node = null;
RDFNode rdfNode = null;
// implement comparator to sort the lists
class sortList implements Comparator<String>{
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<String> metaItr = metaNameList.iterator();
Iterator<String> 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<String> listModels() {
Model metadataModel = getMetadataModel();
try {
return listModelNames(metadataModel);
} finally {
metadataModel.close();
}
}
private ExtendedIterator<String> listModelNames(Model metadataModel) {
Set<String> modelNameSet = new HashSet<String>();
Iterator<RDFNode> 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<Node> storeNameIt = StoreUtils.storeGraphNames(getStore());
while (storeNameIt.hasNext()){
Node node = storeNameIt.next();
modelNameSet.add(node.getURI());
}
List<String> modelNameList = new ArrayList<String>();
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());
}
}

View file

@ -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);

View file

@ -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");
}
}

View file

@ -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?