diff --git a/core/pom.xml b/core/pom.xml index 1f60410cb78..d095b8f12d8 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -232,6 +232,10 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved. org.apache.commons commons-text + + org.apache.commons + commons-dbcp2 + org.apache.lucene lucene-core diff --git a/core/src/main/java/org/owasp/dependencycheck/Engine.java b/core/src/main/java/org/owasp/dependencycheck/Engine.java index 5ace2fd1522..3315295264a 100644 --- a/core/src/main/java/org/owasp/dependencycheck/Engine.java +++ b/core/src/main/java/org/owasp/dependencycheck/Engine.java @@ -26,7 +26,7 @@ import org.owasp.dependencycheck.analyzer.Analyzer; import org.owasp.dependencycheck.analyzer.AnalyzerService; import org.owasp.dependencycheck.analyzer.FileTypeAnalyzer; -import org.owasp.dependencycheck.data.nvdcve.ConnectionFactory; +import org.owasp.dependencycheck.data.nvdcve.DatabaseManager; import org.owasp.dependencycheck.data.nvdcve.CveDB; import org.owasp.dependencycheck.data.nvdcve.DatabaseException; import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; @@ -686,7 +686,7 @@ private void initializeAndUpdateDatabase(@NotNull final List exceptio } } else { try { - if (ConnectionFactory.isH2Connection(settings) && !ConnectionFactory.h2DataFileExists(settings)) { + if (DatabaseManager.isH2Connection(settings) && !DatabaseManager.h2DataFileExists(settings)) { throw new ExceptionCollection(new NoDataException("Autoupdate is disabled and the database does not exist"), true); } else { openDatabase(true, true); @@ -709,7 +709,7 @@ private void initializeAndUpdateDatabase(@NotNull final List exceptio */ private void throwFatalDatabaseException(DatabaseException ex, final List exceptions) throws ExceptionCollection { final String msg; - if (ex.getMessage().contains("Unable to connect") && ConnectionFactory.isH2Connection(settings)) { + if (ex.getMessage().contains("Unable to connect") && DatabaseManager.isH2Connection(settings)) { msg = "Unable to connect to the database - if this error persists it may be " + "due to a corrupt database. Consider running `purge` to delete the existing database"; } else { @@ -856,7 +856,7 @@ public void doUpdates() throws UpdateException, DatabaseException { */ public void doUpdates(boolean remainOpen) throws UpdateException, DatabaseException { if (mode.isDatabaseRequired()) { - try (WriteLock dblock = new WriteLock(getSettings(), ConnectionFactory.isH2Connection(getSettings()))) { + try (WriteLock dblock = new WriteLock(getSettings(), DatabaseManager.isH2Connection(getSettings()))) { //lock is not needed as we already have the lock held openDatabase(false, false); LOGGER.info("Checking for updates"); @@ -962,11 +962,11 @@ public void openDatabase() throws DatabaseException { */ public void openDatabase(boolean readOnly, boolean lockRequired) throws DatabaseException { if (mode.isDatabaseRequired() && database == null) { - try (WriteLock dblock = new WriteLock(getSettings(), lockRequired && ConnectionFactory.isH2Connection(settings))) { + try (WriteLock dblock = new WriteLock(getSettings(), lockRequired && DatabaseManager.isH2Connection(settings))) { if (readOnly - && ConnectionFactory.isH2Connection(settings) + && DatabaseManager.isH2Connection(settings) && settings.getString(Settings.KEYS.DB_CONNECTION_STRING).contains("file:%s")) { - final File db = ConnectionFactory.getH2DataFile(settings); + final File db = DatabaseManager.getH2DataFile(settings); if (db.isFile()) { final File temp = settings.getTempDirectory(); final File tempDB = new File(temp, db.getName()); @@ -989,6 +989,7 @@ public void openDatabase(boolean readOnly, boolean lockRequired) throws Database } catch (WriteLockException ex) { throw new DatabaseException("Failed to obtain lock - unable to open database", ex); } + database.open(); } } diff --git a/core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java b/core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java index bafbffc39e8..c500cb17284 100644 --- a/core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java +++ b/core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java @@ -78,13 +78,10 @@ public final class CveDB implements AutoCloseable { private static final Logger LOGGER = LoggerFactory.getLogger(CveDB.class); /** - * The database connection factory. + * The database connection manager. */ - private final ConnectionFactory connectionFactory; - /** - * Database connection - */ - private Connection connection; + private final DatabaseManager databaseManager; + /** * The bundle of statements used when accessing the database. */ @@ -94,10 +91,6 @@ public final class CveDB implements AutoCloseable { * table. */ private DatabaseProperties databaseProperties; - /** - * The prepared statements. - */ - private final EnumMap preparedStatements = new EnumMap<>(PreparedStatementCveDb.class); /** * A reference to the vulnerable software builder. @@ -224,7 +217,15 @@ enum PreparedStatementCveDb { /** * Key for SQL Statement. */ - MERGE_CPE_ECOSYSTEM + MERGE_CPE_ECOSYSTEM, + /** + * Key for SQL Statement. + */ + DELETE_UNUSED_DICT_CPE, + /** + * Key for SQL Statement. + */ + ADD_DICT_CPE } /** @@ -239,88 +240,49 @@ public CveDB(Settings settings) throws DatabaseException { this.settings = settings; this.cpeStartsWithFilter = settings.getString(Settings.KEYS.CVE_CPE_STARTS_WITH_FILTER, "cpe:2.3:a:"); this.cveItemConverter = new CveItemOperator(cpeStartsWithFilter); - connectionFactory = new ConnectionFactory(settings); - open(); + databaseManager = new DatabaseManager(settings); + statementBundle = databaseManager.getDatabaseProductName() != null + ? ResourceBundle.getBundle("data/dbStatements", new Locale(databaseManager.getDatabaseProductName())) + : ResourceBundle.getBundle("data/dbStatements"); + isOracle = databaseManager.isOracle(); } /** - * Tries to determine the product name of the database. - * - * @param conn the database connection - * @return the product name of the database if successful, {@code null} else + * Opens the database connection pool.s */ - private String determineDatabaseProductName(Connection conn) { - try { - final String databaseProductName = conn.getMetaData().getDatabaseProductName().toLowerCase(); - LOGGER.debug("Database product: {}", databaseProductName); - return databaseProductName; - } catch (SQLException se) { - LOGGER.warn("Problem determining database product!", se); - return null; - } - } - - /** - * Opens the database connection. If the database does not exist, it will - * create a new one. - * - * @throws DatabaseException thrown if there is an error opening the - * database connection - */ - private synchronized void open() throws DatabaseException { - try { - if (!isOpen()) { - connection = connectionFactory.getConnection(); - final String databaseProductName = determineDatabaseProductName(this.connection); - isOracle = "oracle".equals(databaseProductName); - statementBundle = databaseProductName != null - ? ResourceBundle.getBundle("data/dbStatements", new Locale(databaseProductName)) - : ResourceBundle.getBundle("data/dbStatements"); - prepareStatements(); - databaseProperties = new DatabaseProperties(this); - } - } catch (DatabaseException e) { - releaseResources(); - throw e; - } + public void open() { + databaseManager.open(); + databaseProperties = new DatabaseProperties(this); } - /** * Closes the database connection. Close should be called on this object * when it is done being used. */ @Override - public synchronized void close() { + public void close() { if (isOpen()) { LOGGER.debug("Closing database"); clearCache(); LOGGER.debug("Cache cleared"); - closeStatements(); - LOGGER.debug("Statments closed"); try { - connection.close(); + databaseManager.close(); LOGGER.debug("Connection closed"); - } catch (SQLException ex) { - LOGGER.error("There was an error attempting to close the CveDB, see the log for more details."); - LOGGER.debug("", ex); } catch (Throwable ex) { LOGGER.error("There was an exception attempting to close the CveDB, see the log for more details."); LOGGER.debug("", ex); } releaseResources(); LOGGER.debug("Resources released"); - connectionFactory.cleanup(); + databaseManager.cleanup(); } } /** * Releases the resources used by CveDB. */ - private synchronized void releaseResources() { + private void releaseResources() { statementBundle = null; - preparedStatements.clear(); databaseProperties = null; - connection = null; } /** @@ -328,45 +290,30 @@ private synchronized void releaseResources() { * * @return whether the database connection is open or closed */ - protected synchronized boolean isOpen() { - return connection != null; - } - - /** - * Prepares all statements to be used. - * - * @throws DatabaseException thrown if there is an error preparing the - * statements - */ - private void prepareStatements() throws DatabaseException { - for (PreparedStatementCveDb key : values()) { - final PreparedStatement preparedStatement = prepareStatement(key); - if (preparedStatement != null) { - preparedStatements.put(key, preparedStatement); - } - } + public boolean isOpen() { + return databaseManager.isOpen(); } /** * Creates a prepared statement from the given key. The SQL is stored in a * properties file and the key is used to lookup the specific query. * + * @param connection the database connection * @param key the key to select the prepared statement from the properties * file * @return the prepared statement * @throws DatabaseException throw if there is an error generating the * prepared statement */ - private PreparedStatement prepareStatement(PreparedStatementCveDb key) throws DatabaseException { + private PreparedStatement getPreparedStatement(Connection connection, PreparedStatementCveDb key) throws DatabaseException { PreparedStatement preparedStatement = null; try { final String statementString = statementBundle.getString(key.name()); -// if (key == INSERT_CPE) { -// final String[] returnedColumns = {"id"}; -// preparedStatement = connection.prepareStatement(statementString, returnedColumns); -// } else { if (isOracle && key == UPDATE_VULNERABILITY) { preparedStatement = connection.prepareCall(statementString); +// } else if (key == INSERT_CPE) { +// final String[] returnedColumns = {"id"}; +// preparedStatement = connection.prepareStatement(statementString, returnedColumns); } else { preparedStatement = connection.prepareStatement(statementString); } @@ -375,7 +322,6 @@ private PreparedStatement prepareStatement(PreparedStatementCveDb key) throws Da // resultset at the client https://venkatsadasivam.com/2009/02/01/jdbc-performance-tuning-with-optimal-fetch-size/ preparedStatement.setFetchSize(10_000); } -// } } catch (SQLException ex) { throw new DatabaseException(ex); } catch (MissingResourceException ex) { @@ -386,43 +332,6 @@ private PreparedStatement prepareStatement(PreparedStatementCveDb key) throws Da return preparedStatement; } - /** - * Closes all prepared statements. - */ - private synchronized void closeStatements() { - preparedStatements.values().forEach((preparedStatement) -> DBUtils.closeStatement(preparedStatement)); - } - - /** - * Returns the specified prepared statement. - * - * @param key the prepared statement from {@link PreparedStatementCveDb} to - * return - * @return the prepared statement - * @throws SQLException thrown if a SQL Exception occurs - */ - private synchronized PreparedStatement getPreparedStatement(PreparedStatementCveDb key) throws SQLException { - if (!preparedStatements.containsKey(key)) { - return null; - } - final PreparedStatement preparedStatement = preparedStatements.get(key); - preparedStatement.clearParameters(); - return preparedStatement; - } - - /** - * Commits all completed transactions. - * - * @throws SQLException thrown if a SQL Exception occurs - */ - @SuppressWarnings("EmptyMethod") - public synchronized void commit() throws SQLException { - //temporarily remove this as autocommit is on. - //if (isOpen()) { - // connection.commit(); - //} - } - /** * Cleans up the object and ensures that "close" has been called. * @@ -441,7 +350,7 @@ protected void finalize() throws Throwable { * * @return the value of databaseProperties */ - public synchronized DatabaseProperties getDatabaseProperties() { + public DatabaseProperties getDatabaseProperties() { return databaseProperties; } @@ -450,7 +359,7 @@ public synchronized DatabaseProperties getDatabaseProperties() { * * @return the database properties */ - protected synchronized DatabaseProperties reloadProperties() { + protected DatabaseProperties reloadProperties() { databaseProperties = new DatabaseProperties(this); return databaseProperties; } @@ -465,11 +374,11 @@ protected synchronized DatabaseProperties reloadProperties() { * analyzed * @return a set of vulnerable software */ - public synchronized Set getCPEs(String vendor, String product) { + public Set getCPEs(String vendor, String product) { final Set cpe = new HashSet<>(); ResultSet rs = null; - try { - final PreparedStatement ps = getPreparedStatement(SELECT_CPE_ENTRIES); + try (Connection conn = databaseManager.getConnection(); + PreparedStatement ps = getPreparedStatement(conn, SELECT_CPE_ENTRIES)) { if (ps == null) { throw new SQLException("Database query does not exist in the resource bundle: " + SELECT_CPE_ENTRIES); } @@ -511,11 +420,11 @@ public synchronized Set getCPEs(String vendor, String product) { * @throws DatabaseException thrown when there is an error retrieving the * data from the DB */ - public synchronized Set> getVendorProductList() throws DatabaseException { + public Set> getVendorProductList() throws DatabaseException { final Set> data = new HashSet<>(); ResultSet rs = null; - try { - final PreparedStatement ps = getPreparedStatement(SELECT_VENDOR_PRODUCT_LIST); + try (Connection conn = databaseManager.getConnection(); + PreparedStatement ps = getPreparedStatement(conn, SELECT_VENDOR_PRODUCT_LIST)){ if (ps == null) { throw new SQLException("Database query does not exist in the resource bundle: " + SELECT_VENDOR_PRODUCT_LIST); } @@ -541,11 +450,11 @@ public synchronized Set> getVendorProductList() throws Data * @throws DatabaseException thrown when there is an error retrieving the * data from the DB */ - public synchronized Set> getVendorProductListForNode() throws DatabaseException { + public Set> getVendorProductListForNode() throws DatabaseException { final Set> data = new HashSet<>(); ResultSet rs = null; - try { - final PreparedStatement ps = getPreparedStatement(SELECT_VENDOR_PRODUCT_LIST_FOR_NODE); + try (Connection conn = databaseManager.getConnection(); + PreparedStatement ps = getPreparedStatement(conn, SELECT_VENDOR_PRODUCT_LIST_FOR_NODE)) { if (ps == null) { throw new SQLException("Database query does not exist in the resource bundle: " + SELECT_VENDOR_PRODUCT_LIST_FOR_NODE); } @@ -567,11 +476,11 @@ public synchronized Set> getVendorProductListForNode() thro * * @return the properties from the database */ - public synchronized Properties getProperties() { + public Properties getProperties() { final Properties prop = new Properties(); ResultSet rs = null; - try { - final PreparedStatement ps = getPreparedStatement(SELECT_PROPERTIES); + try (Connection conn = databaseManager.getConnection(); + PreparedStatement ps = getPreparedStatement(conn, SELECT_PROPERTIES)) { if (ps == null) { throw new SQLException("Database query does not exist in the resource bundle: " + SELECT_PROPERTIES); } @@ -594,30 +503,32 @@ public synchronized Properties getProperties() { * @param key the property key * @param value the property value */ - public synchronized void saveProperty(String key, String value) { + public void saveProperty(String key, String value) { clearCache(); - try { - final PreparedStatement mergeProperty = getPreparedStatement(MERGE_PROPERTY); + try (Connection conn = databaseManager.getConnection(); + PreparedStatement mergeProperty = getPreparedStatement(conn, MERGE_PROPERTY)) { if (mergeProperty != null) { mergeProperty.setString(1, key); mergeProperty.setString(2, value); mergeProperty.execute(); } else { // No Merge statement, so doing an Update/Insert... - final PreparedStatement updateProperty = getPreparedStatement(UPDATE_PROPERTY); - if (updateProperty == null) { - throw new SQLException("Database query does not exist in the resource bundle: " + UPDATE_PROPERTY); - } - updateProperty.setString(1, value); - updateProperty.setString(2, key); - if (updateProperty.executeUpdate() == 0) { - final PreparedStatement insertProperty = getPreparedStatement(INSERT_PROPERTY); - if (insertProperty == null) { - throw new SQLException("Database query does not exist in the resource bundle: " + INSERT_PROPERTY); + try (PreparedStatement updateProperty = getPreparedStatement(conn, UPDATE_PROPERTY)) { + if (updateProperty == null) { + throw new SQLException("Database query does not exist in the resource bundle: " + UPDATE_PROPERTY); + } + updateProperty.setString(1, value); + updateProperty.setString(2, key); + if (updateProperty.executeUpdate() == 0) { + try (PreparedStatement insertProperty = getPreparedStatement(conn, INSERT_PROPERTY)) { + if (insertProperty == null) { + throw new SQLException("Database query does not exist in the resource bundle: " + INSERT_PROPERTY); + } + insertProperty.setString(1, key); + insertProperty.setString(2, value); + insertProperty.executeUpdate(); + } } - insertProperty.setString(1, key); - insertProperty.setString(2, value); - insertProperty.executeUpdate(); } } } catch (SQLException ex) { @@ -635,7 +546,7 @@ public synchronized void saveProperty(String key, String value) { * It should be also called when DB is closed. *

*/ - private synchronized void clearCache() { + private void clearCache() { vulnerabilitiesForCpeCache.clear(); } @@ -646,7 +557,7 @@ private synchronized void clearCache() { * @return a list of Vulnerabilities * @throws DatabaseException thrown if there is an exception retrieving data */ - public synchronized List getVulnerabilities(Cpe cpe) throws DatabaseException { + public List getVulnerabilities(Cpe cpe) throws DatabaseException { final List cachedVulnerabilities = vulnerabilitiesForCpeCache.get(cpe.toCpe23FS()); if (cachedVulnerabilities != null) { LOGGER.debug("Cache hit for {}", cpe.toCpe23FS()); @@ -657,8 +568,8 @@ public synchronized List getVulnerabilities(Cpe cpe) throws Datab final List vulnerabilities = new ArrayList<>(); ResultSet rs = null; - try { - final PreparedStatement ps = getPreparedStatement(SELECT_CVE_FROM_SOFTWARE); + try (Connection conn = databaseManager.getConnection(); + PreparedStatement ps = getPreparedStatement(conn, SELECT_CVE_FROM_SOFTWARE)) { ps.setString(1, cpe.getVendor()); ps.setString(2, cpe.getProduct()); rs = ps.executeQuery(); @@ -727,15 +638,15 @@ public synchronized List getVulnerabilities(Cpe cpe) throws Datab * @return a vulnerability object * @throws DatabaseException if an exception occurs */ - public synchronized Vulnerability getVulnerability(String cve) throws DatabaseException { + public Vulnerability getVulnerability(String cve) throws DatabaseException { ResultSet rsV = null; ResultSet rsC = null; ResultSet rsR = null; ResultSet rsS = null; Vulnerability vuln = null; - try { - final PreparedStatement psV = getPreparedStatement(SELECT_VULNERABILITY); + try (Connection conn = databaseManager.getConnection(); + PreparedStatement psV = getPreparedStatement(conn, SELECT_VULNERABILITY)) { if (psV == null) { throw new SQLException("Database query does not exist in the resource bundle: " + SELECT_VULNERABILITY); } @@ -773,53 +684,54 @@ public synchronized Vulnerability getVulnerability(String cve) throws DatabaseEx getFloatValue(rsV, 20), rsV.getString(31)); vuln.setCvssV3(cvss); } - final PreparedStatement psCWE = getPreparedStatement(SELECT_VULNERABILITY_CWE); - if (psCWE == null) { - throw new SQLException("Database query does not exist in the resource bundle: " + SELECT_VULNERABILITY_CWE); - } - psCWE.setInt(1, cveId); - rsC = psCWE.executeQuery(); - while (rsC.next()) { - vuln.addCwe(rsC.getString(1)); - } - - final PreparedStatement psR = getPreparedStatement(SELECT_REFERENCES); - if (psR == null) { - throw new SQLException("Database query does not exist in the resource bundle: " + SELECT_REFERENCES); - } - psR.setInt(1, cveId); - rsR = psR.executeQuery(); - while (rsR.next()) { - vuln.addReference(rsR.getString(1), rsR.getString(2), rsR.getString(3)); + try (PreparedStatement psCWE = getPreparedStatement(conn, SELECT_VULNERABILITY_CWE)) { + if (psCWE == null) { + throw new SQLException("Database query does not exist in the resource bundle: " + SELECT_VULNERABILITY_CWE); + } + psCWE.setInt(1, cveId); + rsC = psCWE.executeQuery(); + while (rsC.next()) { + vuln.addCwe(rsC.getString(1)); + } } - - final PreparedStatement psS = getPreparedStatement(SELECT_SOFTWARE); - if (psS == null) { - throw new SQLException("Database query does not exist in the resource bundle: " + SELECT_SOFTWARE); + try (PreparedStatement psR = getPreparedStatement(conn, SELECT_REFERENCES)) { + if (psR == null) { + throw new SQLException("Database query does not exist in the resource bundle: " + SELECT_REFERENCES); + } + psR.setInt(1, cveId); + rsR = psR.executeQuery(); + while (rsR.next()) { + vuln.addReference(rsR.getString(1), rsR.getString(2), rsR.getString(3)); + } } - //1 part, 2 vendor, 3 product, 4 version, 5 update_version, 6 edition, 7 lang, - //8 sw_edition, 9 target_sw, 10 target_hw, 11 other, 12 versionEndExcluding, - //13 versionEndIncluding, 14 versionStartExcluding, 15 versionStartIncluding, 16 vulnerable - psS.setInt(1, cveId); - rsS = psS.executeQuery(); - while (rsS.next()) { - vulnerableSoftwareBuilder.part(rsS.getString(1)) - .vendor(rsS.getString(2)) - .product(rsS.getString(3)) - .version(rsS.getString(4)) - .update(rsS.getString(5)) - .edition(rsS.getString(6)) - .language(rsS.getString(7)) - .swEdition(rsS.getString(8)) - .targetSw(rsS.getString(9)) - .targetHw(rsS.getString(10)) - .other(rsS.getString(11)) - .versionEndExcluding(rsS.getString(12)) - .versionEndIncluding(rsS.getString(13)) - .versionStartExcluding(rsS.getString(14)) - .versionStartIncluding(rsS.getString(15)) - .vulnerable(rsS.getBoolean(16)); - vuln.addVulnerableSoftware(vulnerableSoftwareBuilder.build()); + try (PreparedStatement psS = getPreparedStatement(conn, SELECT_SOFTWARE)) { + if (psS == null) { + throw new SQLException("Database query does not exist in the resource bundle: " + SELECT_SOFTWARE); + } + //1 part, 2 vendor, 3 product, 4 version, 5 update_version, 6 edition, 7 lang, + //8 sw_edition, 9 target_sw, 10 target_hw, 11 other, 12 versionEndExcluding, + //13 versionEndIncluding, 14 versionStartExcluding, 15 versionStartIncluding, 16 vulnerable + psS.setInt(1, cveId); + rsS = psS.executeQuery(); + while (rsS.next()) { + vulnerableSoftwareBuilder.part(rsS.getString(1)) + .vendor(rsS.getString(2)) + .product(rsS.getString(3)) + .version(rsS.getString(4)) + .update(rsS.getString(5)) + .edition(rsS.getString(6)) + .language(rsS.getString(7)) + .swEdition(rsS.getString(8)) + .targetSw(rsS.getString(9)) + .targetHw(rsS.getString(10)) + .other(rsS.getString(11)) + .versionEndExcluding(rsS.getString(12)) + .versionEndIncluding(rsS.getString(13)) + .versionStartExcluding(rsS.getString(14)) + .versionStartIncluding(rsS.getString(15)) + .vulnerable(rsS.getBoolean(16)); + vuln.addVulnerableSoftware(vulnerableSoftwareBuilder.build()); + } } } } catch (SQLException ex) { @@ -858,7 +770,6 @@ public void updateVulnerability(DefCveItem cve, String baseEcosystem) { updateVulnerabilityInsertCwe(vulnerabilityId, cve); updateVulnerabilityInsertReferences(vulnerabilityId, cve); - //parse the CPEs outside of a synchronized method final List software = parseCpes(cve); updateVulnerabilityInsertSoftware(vulnerabilityId, cveId, software, baseEcosystem); } @@ -878,7 +789,8 @@ public void updateVulnerability(DefCveItem cve, String baseEcosystem) { private void loadCpeEcosystemCache() { final Map, String> map = new HashMap<>(); ResultSet rs = null; - try (PreparedStatement ps = prepareStatement(SELECT_CPE_ECOSYSTEM)) { + try (Connection conn = databaseManager.getConnection(); + PreparedStatement ps = getPreparedStatement(conn, SELECT_CPE_ECOSYSTEM)) { rs = ps.executeQuery(); while (rs.next()) { final Pair key = new Pair<>(rs.getString(1), rs.getString(2)); @@ -899,7 +811,8 @@ private void loadCpeEcosystemCache() { private void saveCpeEcosystemCache() { final Map, String> map = CpeEcosystemCache.getChanged(); if (map != null && !map.isEmpty()) { - try (PreparedStatement ps = prepareStatement(MERGE_CPE_ECOSYSTEM)) { + try (Connection conn = databaseManager.getConnection(); + PreparedStatement ps = getPreparedStatement(conn, MERGE_CPE_ECOSYSTEM)) { for (Map.Entry, String> entry : map.entrySet()) { ps.setString(1, entry.getKey().getLeft()); ps.setString(2, entry.getKey().getRight()); @@ -929,12 +842,13 @@ private void saveCpeEcosystemCache() { * @param description the description of the CVE entry * @return the vulnerability ID */ - private synchronized int updateOrInsertVulnerability(DefCveItem cve, String description) { + private int updateOrInsertVulnerability(DefCveItem cve, String description) { if (CpeEcosystemCache.isEmpty()) { loadCpeEcosystemCache(); } final int vulnerabilityId; - try (PreparedStatement callUpdate = prepareStatement(UPDATE_VULNERABILITY)) { + try (Connection conn = databaseManager.getConnection(); + PreparedStatement callUpdate = getPreparedStatement(conn, UPDATE_VULNERABILITY)) { if (callUpdate == null) { throw new SQLException("Database query does not exist in the resource bundle: " + UPDATE_VULNERABILITY); } @@ -1054,8 +968,9 @@ private synchronized int updateOrInsertVulnerability(DefCveItem cve, String desc * @param cve the CVE entry that contains the CWE entries to insert * @throws SQLException thrown if there is an error inserting the data */ - private synchronized void updateVulnerabilityInsertCwe(int vulnerabilityId, DefCveItem cve) throws SQLException { - try (PreparedStatement insertCWE = prepareStatement(INSERT_CWE)) { + private void updateVulnerabilityInsertCwe(int vulnerabilityId, DefCveItem cve) throws SQLException { + try (Connection conn = databaseManager.getConnection(); + PreparedStatement insertCWE = getPreparedStatement(conn, INSERT_CWE)) { if (insertCWE == null) { throw new SQLException("Database query does not exist in the resource bundle: " + INSERT_CWE); } @@ -1087,8 +1002,9 @@ private synchronized void updateVulnerabilityInsertCwe(int vulnerabilityId, DefC * @throws SQLException thrown if there is an error deleting the * vulnerability */ - private synchronized void deleteVulnerability(String cve) throws SQLException { - try (PreparedStatement deleteVulnerability = prepareStatement(DELETE_VULNERABILITY)) { + private void deleteVulnerability(String cve) throws SQLException { + try (Connection conn = databaseManager.getConnection(); + PreparedStatement deleteVulnerability = getPreparedStatement(conn, DELETE_VULNERABILITY)) { deleteVulnerability.setString(1, cve); deleteVulnerability.executeUpdate(); } @@ -1106,10 +1022,11 @@ private synchronized void deleteVulnerability(String cve) throws SQLException { * @throws DatabaseException thrown if there is an error inserting the data * @throws SQLException thrown if there is an error inserting the data */ - private synchronized void updateVulnerabilityInsertSoftware(int vulnerabilityId, String cveId, + private void updateVulnerabilityInsertSoftware(int vulnerabilityId, String cveId, List software, String baseEcosystem) throws DatabaseException, SQLException { - try (PreparedStatement insertSoftware = prepareStatement(INSERT_SOFTWARE)) { + try (Connection conn = databaseManager.getConnection(); + PreparedStatement insertSoftware = getPreparedStatement(conn, INSERT_SOFTWARE)) { if (insertSoftware == null) { throw new SQLException("Database query does not exist in the resource bundle: " + INSERT_SOFTWARE); } @@ -1165,8 +1082,9 @@ private synchronized void updateVulnerabilityInsertSoftware(int vulnerabilityId, * @param cve the CVE entry that contains the list of references * @throws SQLException thrown if there is an error inserting the data */ - private synchronized void updateVulnerabilityInsertReferences(int vulnerabilityId, DefCveItem cve) throws SQLException { - try (PreparedStatement insertReference = prepareStatement(INSERT_REFERENCE)) { + private void updateVulnerabilityInsertReferences(int vulnerabilityId, DefCveItem cve) throws SQLException { + try (Connection conn = databaseManager.getConnection(); + PreparedStatement insertReference = getPreparedStatement(conn, INSERT_REFERENCE)) { if (insertReference == null) { throw new SQLException("Database query does not exist in the resource bundle: " + INSERT_REFERENCE); } @@ -1321,10 +1239,10 @@ private void executeBatch(String vulnId, PreparedStatement statement) * * @return true if data exists; otherwise false */ - public synchronized boolean dataExists() { + public boolean dataExists() { ResultSet rs = null; - try { - final PreparedStatement cs = getPreparedStatement(COUNT_CPE); + try (Connection conn = databaseManager.getConnection(); + PreparedStatement cs = getPreparedStatement(conn, COUNT_CPE)) { if (cs == null) { LOGGER.error("Unable to validate if data exists in the database"); return false; @@ -1357,14 +1275,15 @@ public synchronized boolean dataExists() { * updates. This should be called after all updates have been completed to * ensure orphan entries are removed. */ - public synchronized void cleanupDatabase() { + public void cleanupDatabase() { LOGGER.info("Begin database maintenance"); final long start = System.currentTimeMillis(); saveCpeEcosystemCache(); clearCache(); - try (PreparedStatement psOrphans = getPreparedStatement(CLEANUP_ORPHANS); - PreparedStatement psEcosystem = getPreparedStatement(UPDATE_ECOSYSTEM); - PreparedStatement psEcosystem2 = getPreparedStatement(UPDATE_ECOSYSTEM2)) { + try (Connection conn = databaseManager.getConnection(); + PreparedStatement psOrphans = getPreparedStatement(conn, CLEANUP_ORPHANS); + PreparedStatement psEcosystem = getPreparedStatement(conn, UPDATE_ECOSYSTEM); + PreparedStatement psEcosystem2 = getPreparedStatement(conn, UPDATE_ECOSYSTEM2)) { if (psEcosystem != null) { final int count = psEcosystem.executeUpdate(); if (count > 0) { @@ -1397,15 +1316,18 @@ public synchronized void cleanupDatabase() { * If the database is using an H2 file based database calling * defrag() will de-fragment the database. */ - public synchronized void defrag() { - if (ConnectionFactory.isH2Connection(settings)) { + public void defrag() { + if (databaseManager.isH2Connection()) { final long start = System.currentTimeMillis(); - try (CallableStatement psCompaxt = connection.prepareCall("SHUTDOWN DEFRAG")) { - LOGGER.info("Begin database defrag"); - psCompaxt.execute(); - final long millis = System.currentTimeMillis() - start; - //final long seconds = TimeUnit.MILLISECONDS.toSeconds(millis); - LOGGER.info("End database defrag ({} ms)", millis); + try (Connection conn = databaseManager.getConnection(); + CallableStatement psCompaxt = conn.prepareCall("SHUTDOWN DEFRAG")) { + if (psCompaxt != null) { + LOGGER.info("Begin database defrag"); + psCompaxt.execute(); + final long millis = System.currentTimeMillis() - start; + //final long seconds = TimeUnit.MILLISECONDS.toSeconds(millis); + LOGGER.info("End database defrag ({} ms)", millis); + } } catch (SQLException ex) { LOGGER.error("An unexpected SQL Exception occurred compacting the database; please see the verbose log for more details."); LOGGER.debug("", ex); @@ -1501,16 +1423,13 @@ protected VulnerableSoftware getMatchingSoftware(Cpe cpe, Set */ - public synchronized void deleteUnusedCpe() { + public void deleteUnusedCpe() { clearCache(); - PreparedStatement ps = null; - try { - ps = connection.prepareStatement(statementBundle.getString("DELETE_UNUSED_DICT_CPE")); + try (Connection conn = databaseManager.getConnection(); + PreparedStatement ps = getPreparedStatement(conn, DELETE_UNUSED_DICT_CPE)) { ps.executeUpdate(); } catch (SQLException ex) { LOGGER.error("Unable to delete CPE dictionary entries", ex); - } finally { - DBUtils.closeStatement(ps); } } @@ -1525,19 +1444,16 @@ public synchronized void deleteUnusedCpe() { * @param vendor the CPE vendor * @param product the CPE product */ - public synchronized void addCpe(String cpe, String vendor, String product) { + public void addCpe(String cpe, String vendor, String product) { clearCache(); - PreparedStatement ps = null; - try { - ps = connection.prepareStatement(statementBundle.getString("ADD_DICT_CPE")); + try (Connection conn = databaseManager.getConnection(); + PreparedStatement ps = getPreparedStatement(conn, ADD_DICT_CPE)) { ps.setString(1, cpe); ps.setString(2, vendor); ps.setString(3, product); ps.executeUpdate(); } catch (SQLException ex) { LOGGER.error("Unable to add CPE dictionary entry", ex); - } finally { - DBUtils.closeStatement(ps); } } diff --git a/core/src/main/java/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.java b/core/src/main/java/org/owasp/dependencycheck/data/nvdcve/DatabaseManager.java similarity index 80% rename from core/src/main/java/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.java rename to core/src/main/java/org/owasp/dependencycheck/data/nvdcve/DatabaseManager.java index 4040b3d8903..75e772bcdab 100644 --- a/core/src/main/java/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.java +++ b/core/src/main/java/org/owasp/dependencycheck/data/nvdcve/DatabaseManager.java @@ -32,7 +32,9 @@ import java.sql.Statement; import javax.annotation.concurrent.ThreadSafe; import org.anarres.jdiagnostics.DefaultQuery; +import org.apache.commons.dbcp2.BasicDataSource; import org.apache.commons.io.IOUtils; +import org.h2.jdbcx.JdbcConnectionPool; import org.owasp.dependencycheck.utils.DBUtils; import org.owasp.dependencycheck.utils.DependencyVersion; import org.owasp.dependencycheck.utils.DependencyVersionUtil; @@ -50,12 +52,12 @@ * @author Jeremy Long */ @ThreadSafe -public final class ConnectionFactory { +public final class DatabaseManager { /** * The Logger. */ - private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionFactory.class); + private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseManager.class); /** * Resource location for SQL file used to create the database schema. */ @@ -93,14 +95,33 @@ public final class ConnectionFactory { * The configured settings. */ private final Settings settings; + /** + * Flag indicating if the database connection is for an H2 database. + */ + private boolean isH2; + /** + * Flag indicating if the database connection is for an Oracle database. + */ + private boolean isOracle; + /** + * The database product name. + */ + private String databaseProductName; + /** + * The database connection pool. + */ + private BasicDataSource connectionPool; /** * Private constructor for this factory class; no instance is ever needed. * * @param settings the configured settings + * @throws DatabaseException thrown if we are unable to connect to the + * database */ - public ConnectionFactory(Settings settings) { + public DatabaseManager(Settings settings) throws DatabaseException { this.settings = settings; + initialize(); } /** @@ -110,28 +131,26 @@ public ConnectionFactory(Settings settings) { * @throws DatabaseException thrown if we are unable to connect to the * database */ - public synchronized void initialize() throws DatabaseException { - //this only needs to be called once. - if (connectionString != null) { - return; - } + private void initialize() throws DatabaseException { final boolean autoUpdate = settings.getBoolean(Settings.KEYS.AUTO_UPDATE, true); Connection conn = null; try { //load the driver if necessary final String driverName = settings.getString(Settings.KEYS.DB_DRIVER_NAME, ""); - final String driverPath = settings.getString(Settings.KEYS.DB_DRIVER_PATH, ""); - LOGGER.debug("Loading driver '{}'", driverName); - try { - if (!driverPath.isEmpty()) { - LOGGER.debug("Loading driver from: {}", driverPath); - driver = DriverLoader.load(driverName, driverPath); - } else { - driver = DriverLoader.load(driverName); + if (!driverName.isEmpty()) { + final String driverPath = settings.getString(Settings.KEYS.DB_DRIVER_PATH, ""); + LOGGER.debug("Loading driver '{}'", driverName); + try { + if (!driverPath.isEmpty()) { + LOGGER.debug("Loading driver from: {}", driverPath); + driver = DriverLoader.load(driverName, driverPath); + } else { + driver = DriverLoader.load(driverName); + } + } catch (DriverLoadException ex) { + LOGGER.debug("Unable to load database driver", ex); + throw new DatabaseException("Unable to load database driver", ex); } - } catch (DriverLoadException ex) { - LOGGER.debug("Unable to load database driver", ex); - throw new DatabaseException("Unable to load database driver", ex); } userName = settings.getString(Settings.KEYS.DB_USER, "dcuser"); //yes, yes - hard-coded password - only if there isn't one in the properties file. @@ -144,9 +163,10 @@ public synchronized void initialize() throws DatabaseException { LOGGER.debug("Unable to retrieve the database connection string", ex); throw new DatabaseException("Unable to retrieve the database connection string", ex); } + isH2 = isH2Connection(connectionString); boolean shouldCreateSchema = false; try { - if (autoUpdate && connectionString.startsWith("jdbc:h2:file:")) { //H2 + if (autoUpdate && isH2) { shouldCreateSchema = !h2DataFileExists(); LOGGER.debug("Need to create DB Structure: {}", shouldCreateSchema); } @@ -181,6 +201,8 @@ public synchronized void initialize() throws DatabaseException { throw new DatabaseException("Unable to connect to the database", ex); } } + databaseProductName = determineDatabaseProductName(conn); + isOracle = "oracle".equals(databaseProductName); if (shouldCreateSchema) { try { createTables(conn); @@ -206,13 +228,30 @@ public synchronized void initialize() throws DatabaseException { } } + /** + * Tries to determine the product name of the database. + * + * @param conn the database connection + * @return the product name of the database if successful, {@code null} else + */ + private String determineDatabaseProductName(Connection conn) { + try { + final String databaseProductName = conn.getMetaData().getDatabaseProductName().toLowerCase(); + LOGGER.debug("Database product: {}", databaseProductName); + return databaseProductName; + } catch (SQLException se) { + LOGGER.warn("Problem determining database product!", se); + return null; + } + } + /** * Cleans up resources and unloads any registered database drivers. This * needs to be called to ensure the driver is unregistered prior to the * finalize method being called as during shutdown the class loader used to * load the driver may be unloaded prior to the driver being de-registered. */ - public synchronized void cleanup() { + public void cleanup() { if (driver != null) { DriverLoader.cleanup(driver); driver = null; @@ -222,26 +261,6 @@ public synchronized void cleanup() { password = null; } - /** - * Constructs a new database connection object per the database - * configuration. - * - * @return a database connection object - * @throws DatabaseException thrown if there is an exception loading the - * database connection - */ - public synchronized Connection getConnection() throws DatabaseException { - initialize(); - final Connection conn; - try { - conn = DriverManager.getConnection(connectionString, userName, password); - } catch (SQLException ex) { - LOGGER.debug("", ex); - throw new DatabaseException("Unable to connect to the database", ex); - } - return conn; - } - /** * Determines if the H2 database file exists. If it does not exist then the * data structure will need to be created. @@ -281,13 +300,31 @@ public static File getH2DataFile(Settings configuration) throws IOException { return new File(dir, fileName); } + /** + * Returns the database product name. + * + * @return the database product name + */ + public String getDatabaseProductName() { + return databaseProductName; + } + /** * Determines if the connection string is for an H2 database. * * @return true if the connection string is for an H2 database */ public boolean isH2Connection() { - return isH2Connection(settings); + return isH2; + } + + /** + * Determines if the connection string is for an Oracle database. + * + * @return true if the connection string is for an Oracle database + */ + public boolean isOracle() { + return isOracle; } /** @@ -306,7 +343,17 @@ public static boolean isH2Connection(Settings configuration) { LOGGER.debug("Unable to get connectionn string", ex); return false; } - return connStr.startsWith("jdbc:h2:file:"); + return isH2Connection(connStr); + } + + /** + * Determines if the connection string is for an H2 database. + * + * @param connectionString the connection string + * @return true if the connection string is for an H2 database + */ + public static boolean isH2Connection(String connectionString) { + return connectionString.startsWith("jdbc:h2:file:"); } /** @@ -462,4 +509,53 @@ private void ensureSchemaVersion(Connection conn) throws DatabaseException { DBUtils.closeStatement(ps); } } + + /** + * Opens the database connection pool + */ + public void open() { + connectionPool = new BasicDataSource(); + final String driverName = settings.getString(Settings.KEYS.DB_DRIVER_NAME, ""); + if (!driverName.isEmpty() && !"org.h2.Driver".equals(driverName)) { + connectionPool.setDriverClassName(driverName); + } + connectionPool.setUrl(connectionString); + connectionPool.setUsername(userName); + connectionPool.setPassword(password); + } + /** + * Closes the database connection pool. + */ + public void close() { + try { + connectionPool.close(); + } catch (SQLException ex) { + LOGGER.debug("Error closing the connection pool", ex); + } + connectionPool = null; + } + + /** + * Returns if the connection pool is open. + * @return if the connection pool is open + */ + public boolean isOpen() { + return connectionPool != null; + } + + /** + * Constructs a new database connection object per the database + * configuration. + * + * @return a database connection object + * @throws DatabaseException thrown if there is an exception obtaining the + * database connection + */ + public Connection getConnection() throws DatabaseException { + try { + return connectionPool.getConnection(); + } catch (SQLException ex) { + throw new DatabaseException("Error connecting to the database", ex); + } + } } diff --git a/core/src/main/java/org/owasp/dependencycheck/data/update/nvd/ProcessTask.java b/core/src/main/java/org/owasp/dependencycheck/data/update/nvd/ProcessTask.java index a56c7b96ea9..2a2c1df63b7 100644 --- a/core/src/main/java/org/owasp/dependencycheck/data/update/nvd/ProcessTask.java +++ b/core/src/main/java/org/owasp/dependencycheck/data/update/nvd/ProcessTask.java @@ -150,7 +150,6 @@ private void processFiles() throws UpdateException { final long startProcessing = System.currentTimeMillis(); try { importJSON(downloadTask.getFile()); - cveDB.commit(); properties.save(downloadTask.getNvdCveInfo()); } catch (ParserConfigurationException | SQLException | DatabaseException | ClassNotFoundException | IOException ex) { throw new UpdateException(ex); diff --git a/core/src/main/resources/dependencycheck.properties b/core/src/main/resources/dependencycheck.properties index 368ec7b80fc..e1d8082ccb7 100644 --- a/core/src/main/resources/dependencycheck.properties +++ b/core/src/main/resources/dependencycheck.properties @@ -44,8 +44,8 @@ data.password=DC-Pass1337! # to ensure any and all needed files can be added to the classpath to load the driver. # For non-JDBC4 drivers in the classpath only the driver_name needs to be set. # For MOST situations these properties likely do not need to be set. -data.driver_name=org.h2.Driver -data.driver_path= +#data.driver_name=org.h2.Driver +#data.driver_path= # the class name of the write lock shutdown hook data.writelock.shutdownhook=org.owasp.dependencycheck.utils.WriteLockCleanupHook diff --git a/core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java b/core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java index c488f909aa8..b5f896773a5 100644 --- a/core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java +++ b/core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java @@ -26,7 +26,7 @@ import java.util.zip.ZipInputStream; import org.apache.commons.compress.utils.IOUtils; import org.junit.Before; -import org.owasp.dependencycheck.data.nvdcve.ConnectionFactory; +import org.owasp.dependencycheck.data.nvdcve.DatabaseManager; import org.owasp.dependencycheck.utils.WriteLock; import org.owasp.dependencycheck.utils.Settings; import org.slf4j.Logger; @@ -54,7 +54,7 @@ public void setUp() throws Exception { } public void ensureDBExists() throws Exception { - try (WriteLock dblock = new WriteLock(getSettings(), ConnectionFactory.isH2Connection(getSettings()))) { + try (WriteLock dblock = new WriteLock(getSettings(), DatabaseManager.isH2Connection(getSettings()))) { File f = new File("./target/data/odc.mv.db"); if (f.exists() && f.isFile() && f.length() < 71680) { f.delete(); @@ -89,8 +89,7 @@ public void ensureDBExists() throws Exception { } } //update the schema - ConnectionFactory factory = new ConnectionFactory(getSettings()); - factory.initialize(); + DatabaseManager factory = new DatabaseManager(getSettings()); } } } diff --git a/core/src/test/java/org/owasp/dependencycheck/analyzer/HintAnalyzerTest.java b/core/src/test/java/org/owasp/dependencycheck/analyzer/HintAnalyzerTest.java index dc8e3a331f3..0e1ce35a1c4 100644 --- a/core/src/test/java/org/owasp/dependencycheck/analyzer/HintAnalyzerTest.java +++ b/core/src/test/java/org/owasp/dependencycheck/analyzer/HintAnalyzerTest.java @@ -74,7 +74,6 @@ public void testAnalyze() throws Exception { getSettings().setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, false); getSettings().setBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED, false); try (Engine engine = new Engine(getSettings())) { - engine.scan(guice); engine.scan(spring); engine.analyzeDependencies(); diff --git a/core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBIT.java b/core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBIT.java index 79bc0db780f..70a321a21c2 100644 --- a/core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBIT.java +++ b/core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBIT.java @@ -52,6 +52,7 @@ public class CveDBIT extends BaseDBTestCase { public void setUp() throws Exception { super.setUp(); instance = new CveDB(getSettings()); + instance.open(); } @After @@ -61,18 +62,6 @@ public void tearDown() throws Exception { super.tearDown(); } - /** - * Pretty useless tests of open, commit, and close methods, of class CveDB. - */ - @Test - public void testOpen() { - - try { - instance.commit(); - } catch (DatabaseException | SQLException ex) { - fail(ex.getMessage()); - } - } /** * Test of getCPEs method, of class CveDB. diff --git a/core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBMySqlIT.java b/core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBMySqlIT.java index 170bd78c90b..e9f6bb111ae 100644 --- a/core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBMySqlIT.java +++ b/core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBMySqlIT.java @@ -46,6 +46,7 @@ public class CveDBMySqlIT extends BaseTest { public void setUp() throws Exception { super.setUp(); instance = new CveDB(getSettings()); + instance.open(); } @After @@ -53,20 +54,7 @@ public void setUp() throws Exception { public void tearDown() throws Exception { instance.close(); super.tearDown(); - } - - /** - * Pretty useless tests of open, commit, and close methods, of class CveDB. - */ - @Test - public void testOpen() { - try { - instance.commit(); - } catch (SQLException | DatabaseException ex) { - System.out.println("Unable to connect to the My SQL database; verify that the db server is running and that the schema has been generated"); - fail(ex.getMessage()); - } - } + } /** * Test of getCPEs method, of class CveDB. diff --git a/core/src/test/java/org/owasp/dependencycheck/data/nvdcve/ConnectionFactoryTest.java b/core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DatabaseManagerTest.java similarity index 83% rename from core/src/test/java/org/owasp/dependencycheck/data/nvdcve/ConnectionFactoryTest.java rename to core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DatabaseManagerTest.java index a3da867703f..717375b48ac 100644 --- a/core/src/test/java/org/owasp/dependencycheck/data/nvdcve/ConnectionFactoryTest.java +++ b/core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DatabaseManagerTest.java @@ -26,20 +26,21 @@ * * @author jeremy long */ -public class ConnectionFactoryTest extends BaseDBTestCase { +public class DatabaseManagerTest extends BaseDBTestCase { /** - * Test of initialize method, of class ConnectionFactory. + * Test of initialize method, of class DatabaseManager. * * @throws org.owasp.dependencycheck.data.nvdcve.DatabaseException */ @Test public void testInitialize() throws DatabaseException, SQLException { - ConnectionFactory factory = new ConnectionFactory(getSettings()); - factory.initialize(); + DatabaseManager factory = new DatabaseManager(getSettings()); + factory.open(); try (Connection result = factory.getConnection()) { assertNotNull(result); } + factory.close(); factory.cleanup(); } } diff --git a/core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DatabasePropertiesIT.java b/core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DatabasePropertiesIT.java index a0dc8bb28a0..a191ccada43 100644 --- a/core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DatabasePropertiesIT.java +++ b/core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DatabasePropertiesIT.java @@ -40,6 +40,7 @@ public class DatabasePropertiesIT extends BaseDBTestCase { public void setUp() throws Exception { super.setUp(); cveDb = new CveDB(getSettings()); + cveDb.open(); } @After diff --git a/core/src/test/resources/dependencycheck.properties b/core/src/test/resources/dependencycheck.properties index 7abad65747f..169b00be171 100644 --- a/core/src/test/resources/dependencycheck.properties +++ b/core/src/test/resources/dependencycheck.properties @@ -40,8 +40,8 @@ data.password=DC-Pass1337! # to ensure any and all needed files can be added to the classpath to load the driver. # For non-JDBC4 drivers in the classpath only the driver_name needs to be set. # For MOST situations these properties likely do not need to be set. -data.driver_name=org.h2.Driver -data.driver_path= +#data.driver_name=org.h2.Driver +#data.driver_path= # the class name of the write lock shutdown hook data.writelock.shutdownhook=org.owasp.dependencycheck.utils.WriteLockCleanupHook diff --git a/pom.xml b/pom.xml index b18130b639d..b7b3fe825ae 100644 --- a/pom.xml +++ b/pom.xml @@ -902,6 +902,11 @@ Copyright (c) 2012 - Jeremy Long commons-validator 1.7
+ + org.apache.commons + commons-dbcp2 + 2.8.0 + com.github.package-url packageurl-java