Modified CveDB and Settings so that they are no longer singletons; first step in thread safety updates

This commit is contained in:
Jeremy Long
2017-08-30 06:47:45 -04:00
parent c4b67a1db2
commit 74a2326e0e
113 changed files with 1809 additions and 1400 deletions

View File

@@ -62,9 +62,23 @@ public final class Downloader {
private static final String GET = "GET";
/**
* Private constructor for utility class.
* The configured settings.
*/
private Downloader() {
private final Settings settings;
/**
* The URL connection facctory.
*/
private final URLConnectionFactory connFactory;
/**
* Constructs a new downloader object.
*
* @param settings the configured settings
*/
public Downloader(Settings settings) {
this.settings = settings;
this.connFactory = new URLConnectionFactory(settings);
}
/**
@@ -75,7 +89,7 @@ public final class Downloader {
* @throws DownloadFailedException is thrown if there is an error
* downloading the file
*/
public static void fetchFile(URL url, File outputPath) throws DownloadFailedException {
public void fetchFile(URL url, File outputPath) throws DownloadFailedException {
fetchFile(url, outputPath, true);
}
@@ -89,7 +103,7 @@ public final class Downloader {
* @throws DownloadFailedException is thrown if there is an error
* downloading the file
*/
public static void fetchFile(URL url, File outputPath, boolean useProxy) throws DownloadFailedException {
public void fetchFile(URL url, File outputPath, boolean useProxy) throws DownloadFailedException {
if ("file".equalsIgnoreCase(url.getProtocol())) {
File file;
try {
@@ -113,7 +127,7 @@ public final class Downloader {
HttpURLConnection conn = null;
try {
LOGGER.debug("Attempting download of {}", url.toString());
conn = URLConnectionFactory.createHttpURLConnection(url, useProxy);
conn = connFactory.createHttpURLConnection(url, useProxy);
conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
conn.connect();
int status = conn.getResponseCode();
@@ -129,7 +143,7 @@ public final class Downloader {
conn = null;
}
LOGGER.debug("Download is being redirected from {} to {}", url.toString(), location);
conn = URLConnectionFactory.createHttpURLConnection(new URL(location), useProxy);
conn = connFactory.createHttpURLConnection(new URL(location), useProxy);
conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
conn.connect();
status = conn.getResponseCode();
@@ -217,7 +231,7 @@ public final class Downloader {
* @throws DownloadFailedException is thrown if an exception occurs making
* the HTTP request
*/
public static long getLastModified(URL url) throws DownloadFailedException {
public long getLastModified(URL url) throws DownloadFailedException {
return getLastModified(url, false);
}
@@ -233,7 +247,7 @@ public final class Downloader {
* @throws DownloadFailedException is thrown if an exception occurs making
* the HTTP request
*/
private static long getLastModified(URL url, boolean isRetry) throws DownloadFailedException {
private long getLastModified(URL url, boolean isRetry) throws DownloadFailedException {
long timestamp = 0;
//TODO add the FTP protocol?
if ("file".equalsIgnoreCase(url.getProtocol())) {
@@ -249,7 +263,7 @@ public final class Downloader {
final String httpMethod = determineHttpMethod();
HttpURLConnection conn = null;
try {
conn = URLConnectionFactory.createHttpURLConnection(url);
conn = connFactory.createHttpURLConnection(url);
conn.setRequestMethod(httpMethod);
conn.connect();
final int t = conn.getResponseCode();
@@ -269,8 +283,8 @@ public final class Downloader {
}
try {
//retry
if (!isRetry && Settings.getBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP)) {
Settings.setBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP, false);
if (!isRetry && settings.getBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP)) {
settings.setBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP, false);
return getLastModified(url, true);
}
} catch (InvalidSettingException ex1) {
@@ -300,7 +314,7 @@ public final class Downloader {
* @throws DownloadFailedException a wrapper exception that contains the
* original exception as the cause
*/
protected static synchronized void checkForCommonExceptionTypes(IOException ex) throws DownloadFailedException {
protected synchronized void checkForCommonExceptionTypes(IOException ex) throws DownloadFailedException {
Throwable cause = ex;
while (cause != null) {
if (cause instanceof java.net.UnknownHostException) {
@@ -328,7 +342,7 @@ public final class Downloader {
*
* @return the HTTP method to use
*/
private static String determineHttpMethod() {
private String determineHttpMethod() {
return isQuickQuery() ? HEAD : GET;
}
@@ -338,11 +352,11 @@ public final class Downloader {
*
* @return true if configured to use HEAD requests
*/
private static boolean isQuickQuery() {
private boolean isQuickQuery() {
boolean quickQuery;
try {
quickQuery = Settings.getBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP, true);
quickQuery = settings.getBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP, true);
} catch (InvalidSettingException e) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Invalid settings : {}", e.getMessage(), e);

View File

@@ -101,25 +101,6 @@ public final class FileUtils {
return tempDir;
}
/**
* Generates a new temporary file name that is guaranteed to be unique.
*
* @param prefix the prefix for the file name to generate
* @param extension the extension of the generated file name
* @return a temporary File
* @throws java.io.IOException thrown if the temporary folder could not be
* created
*/
public static File getTempFile(String prefix, String extension) throws IOException {
final File dir = Settings.getTempDirectory();
final String tempFileName = String.format("%s%s.%s", prefix, UUID.randomUUID().toString(), extension);
final File tempFile = new File(dir, tempFileName);
if (tempFile.exists()) {
return getTempFile(prefix, extension);
}
return tempFile;
}
/**
* Return the bit bucket for the OS. '/dev/null' for Unix and 'NUL' for
* Windows

View File

@@ -42,15 +42,21 @@ public class SSLSocketFactoryEx extends SSLSocketFactory {
* The protocols.
*/
private String[] protocols;
/**
* The configured settings.
*/
private final Settings settings;
/**
* Constructs a new SSLSocketFactory.
*
* @param settings reference to the configured settings
* @throws NoSuchAlgorithmException thrown when an algorithm is not
* supported
* @throws KeyManagementException thrown if initialization fails
*/
public SSLSocketFactoryEx() throws NoSuchAlgorithmException, KeyManagementException {
public SSLSocketFactoryEx(Settings settings) throws NoSuchAlgorithmException, KeyManagementException {
this.settings = settings;
initSSLSocketFactoryEx(null, null, null);
}
@@ -60,11 +66,13 @@ public class SSLSocketFactoryEx extends SSLSocketFactory {
* @param km the key manager
* @param tm the trust manager
* @param random secure random
* @param settings reference to the configured settings
* @throws NoSuchAlgorithmException thrown when an algorithm is not
* supported
* @throws KeyManagementException thrown if initialization fails
*/
public SSLSocketFactoryEx(KeyManager[] km, TrustManager[] tm, SecureRandom random) throws NoSuchAlgorithmException, KeyManagementException {
public SSLSocketFactoryEx(KeyManager[] km, TrustManager[] tm, SecureRandom random, Settings settings) throws NoSuchAlgorithmException, KeyManagementException {
this.settings = settings;
initSSLSocketFactoryEx(km, tm, random);
}
@@ -72,11 +80,13 @@ public class SSLSocketFactoryEx extends SSLSocketFactory {
* Constructs a new SSLSocketFactory.
*
* @param ctx the SSL context
* @param settings reference to the configured settings
* @throws NoSuchAlgorithmException thrown when an algorithm is not
* supported
* @throws KeyManagementException thrown if initialization fails
*/
public SSLSocketFactoryEx(SSLContext ctx) throws NoSuchAlgorithmException, KeyManagementException {
public SSLSocketFactoryEx(SSLContext ctx, Settings settings) throws NoSuchAlgorithmException, KeyManagementException {
this.settings = settings;
initSSLSocketFactoryEx(ctx);
}
@@ -254,7 +264,7 @@ public class SSLSocketFactoryEx extends SSLSocketFactory {
protected String[] getProtocolList() {
SSLSocket socket = null;
String[] availableProtocols = null;
final String[] preferredProtocols = Settings.getString(
final String[] preferredProtocols = settings.getString(
Settings.KEYS.DOWNLOADER_TLS_PROTOCOL_LIST,
"TLSv1,TLSv1.1,TLSv1.2,TLSv1.3")
.split(",");

View File

@@ -32,6 +32,7 @@ import java.net.URLDecoder;
import java.security.ProtectionDomain;
import java.util.Enumeration;
import java.util.Properties;
import java.util.UUID;
import org.apache.commons.lang3.StringUtils;
@@ -54,10 +55,6 @@ public final class Settings {
* Array separator.
*/
private static final String ARRAY_SEP = ",";
/**
* Thread local settings.
*/
private static final ThreadLocal<Settings> LOCAL_SETTINGS = new ThreadLocal<>();
/**
* The properties.
*/
@@ -67,7 +64,7 @@ public final class Settings {
* A reference to the temporary directory; used in case it needs to be
* deleted during cleanup.
*/
private static File tempDirectory = null;
private File tempDirectory = null;
//<editor-fold defaultstate="collapsed" desc="KEYS used to access settings">
/**
@@ -448,13 +445,25 @@ public final class Settings {
}
//</editor-fold>
public Settings() {
initialize(PROPERTIES_FILE);
}
/**
* Private constructor for the Settings class. This class loads the
* properties files.
* This class loads the settings from the given properties file.
*
* @param propertiesFilePath the path to the base properties file to load
*/
private Settings(String propertiesFilePath) {
public Settings(String propertiesFilePath) {
initialize(propertiesFilePath);
}
/**
* Initializes the settings object from the given file.
*
* @param propertiesFilePath the path to the settings property file
*/
private final void initialize(String propertiesFilePath) {
props = new Properties();
try (InputStream in = FileUtils.getResourceAsStream(propertiesFilePath)) {
props.load(in);
@@ -468,54 +477,11 @@ public final class Settings {
logProperties("Properties loaded", props);
}
/**
* <p>
* Initializes the thread local settings object. Note, to use the settings
* object you must call this method. However, you must also call
* Settings.cleanup() to properly release resources.</p>
*
* <p>
* <b>Note</b> - Only an end user interface such as the CLI, Maven Plugin,
* etc. should call initialize. When called `initialize` will over-write any
* configured settings (i.e. configured via the maven plugin) and the
* default values from dependency-check-core will be used. If you are
* running into issues with the settings not being initialized it is likely
* due to multi-threading and you should use the `Settings.setInstance`
* method instead. See the `TimestampRetriever` class within NvdCveUpdater
* as an example.</p>
*
*/
public static void initialize() {
LOCAL_SETTINGS.set(new Settings(PROPERTIES_FILE));
}
/**
* <p>
* Initializes the thread local settings object. Note, to use the settings
* object you must call this method. However, you must also call
* Settings.cleanup() to properly release resources.</p>
*
* <p>
* <b>Note</b> - Only an end user interface such as the CLI, Maven Plugin,
* etc. should call initialize. When called `initialize` will over-write any
* configured settings (i.e. configured via the maven plugin) and the
* default values from dependency-check-core will be used. If you are
* running into issues with the settings not being initialized it is likely
* due to multi-threading and you should use the `Settings.setInstance`
* method instead. See the `TimestampRetriever` class within NvdCveUpdater
* as an example.</p>
*
* @param propertiesFilePath the path to the base properties file to load
*/
public static void initialize(String propertiesFilePath) {
LOCAL_SETTINGS.set(new Settings(propertiesFilePath));
}
/**
* Cleans up resources to prevent memory leaks.
*
*/
public static void cleanup() {
public void cleanup() {
cleanup(true);
}
@@ -525,39 +491,11 @@ public final class Settings {
* @param deleteTemporary flag indicating whether any temporary directories
* generated should be removed
*/
public static synchronized void cleanup(boolean deleteTemporary) {
public synchronized void cleanup(boolean deleteTemporary) {
if (deleteTemporary && tempDirectory != null && tempDirectory.exists()) {
FileUtils.delete(tempDirectory);
tempDirectory = null;
}
try {
LOCAL_SETTINGS.remove();
} catch (Throwable ex) {
LOGGER.debug("Error cleaning up Settings", ex);
}
}
/**
* Gets the underlying instance of the Settings object.
*
* @return the Settings object
*/
public static Settings getInstance() {
return LOCAL_SETTINGS.get();
}
/**
* <p>
* Sets the instance of the Settings object to use in this thread.</p>
* <p>
* <b>Note</b> - if using this method to enable multi-threading one must
* call `Settings.cleanup(false)`. See the `TimestampRetriever` class within
* NvdCveUpdater as an example.</p>
*
* @param instance the instance of the settings object to use in this thread
*/
public static void setInstance(Settings instance) {
LOCAL_SETTINGS.set(instance);
}
/**
@@ -567,7 +505,7 @@ public final class Settings {
* @param header the header to print with the log message
* @param properties the properties to log
*/
private static void logProperties(String header, Properties properties) {
private void logProperties(String header, Properties properties) {
if (LOGGER.isDebugEnabled()) {
final StringWriter sw = new StringWriter();
try (PrintWriter pw = new PrintWriter(sw)) {
@@ -597,8 +535,8 @@ public final class Settings {
* @param key the key for the property
* @param value the value for the property
*/
public static void setString(String key, String value) {
LOCAL_SETTINGS.get().props.setProperty(key, value);
public void setString(String key, String value) {
props.setProperty(key, value);
LOGGER.debug("Setting: {}='{}'", key, value);
}
@@ -608,7 +546,7 @@ public final class Settings {
* @param key the key for the property
* @param value the value for the property
*/
public static void setStringIfNotNull(String key, String value) {
public void setStringIfNotNull(String key, String value) {
if (null != value) {
setString(key, value);
}
@@ -620,7 +558,7 @@ public final class Settings {
* @param key the key for the property
* @param value the value for the property
*/
public static void setStringIfNotEmpty(String key, String value) {
public void setStringIfNotEmpty(String key, String value) {
if (null != value && !value.isEmpty()) {
setString(key, value);
}
@@ -632,7 +570,7 @@ public final class Settings {
* @param key the key for the property
* @param value the value for the property
*/
public static void setArrayIfNotEmpty(String key, String[] value) {
public void setArrayIfNotEmpty(String key, String[] value) {
if (null != value && value.length > 0) {
setString(key, StringUtils.join(value, ARRAY_SEP));
}
@@ -644,7 +582,7 @@ public final class Settings {
* @param key the key for the property
* @param value the value for the property
*/
public static void setBoolean(String key, boolean value) {
public void setBoolean(String key, boolean value) {
setString(key, Boolean.toString(value));
}
@@ -654,7 +592,7 @@ public final class Settings {
* @param key the key for the property
* @param value the value for the property
*/
public static void setBooleanIfNotNull(String key, Boolean value) {
public void setBooleanIfNotNull(String key, Boolean value) {
if (null != value) {
setBoolean(key, value);
}
@@ -666,8 +604,8 @@ public final class Settings {
* @param key the key for the property
* @param value the value for the property
*/
public static void setInt(String key, int value) {
LOCAL_SETTINGS.get().props.setProperty(key, String.valueOf(value));
public void setInt(String key, int value) {
props.setProperty(key, String.valueOf(value));
LOGGER.debug("Setting: {}='{}'", key, value);
}
@@ -677,7 +615,7 @@ public final class Settings {
* @param key the key for the property
* @param value the value for the property
*/
public static void setIntIfNotNull(String key, Integer value) {
public void setIntIfNotNull(String key, Integer value) {
if (null != value) {
setInt(key, value);
}
@@ -695,7 +633,7 @@ public final class Settings {
* @throws IOException is thrown when there is an exception loading/merging
* the properties
*/
public static void mergeProperties(File filePath) throws FileNotFoundException, IOException {
public void mergeProperties(File filePath) throws FileNotFoundException, IOException {
try (FileInputStream fis = new FileInputStream(filePath)) {
mergeProperties(fis);
}
@@ -713,7 +651,7 @@ public final class Settings {
* @throws IOException is thrown when there is an exception loading/merging
* the properties
*/
public static void mergeProperties(String filePath) throws FileNotFoundException, IOException {
public void mergeProperties(String filePath) throws FileNotFoundException, IOException {
try (FileInputStream fis = new FileInputStream(filePath)) {
mergeProperties(fis);
}
@@ -729,9 +667,9 @@ public final class Settings {
* @throws IOException is thrown when there is an exception loading/merging
* the properties
*/
public static void mergeProperties(InputStream stream) throws IOException {
LOCAL_SETTINGS.get().props.load(stream);
logProperties("Properties updated via merge", LOCAL_SETTINGS.get().props);
public void mergeProperties(InputStream stream) throws IOException {
props.load(stream);
logProperties("Properties updated via merge", props);
}
/**
@@ -743,7 +681,7 @@ public final class Settings {
* @param key the key to lookup within the properties file
* @return the property from the properties file converted to a File object
*/
public static File getFile(String key) {
public File getFile(String key) {
final String file = getString(key);
if (file == null) {
return null;
@@ -765,7 +703,7 @@ public final class Settings {
* @param key the key to lookup within the properties file
* @return the property from the properties file converted to a File object
*/
protected static File getDataFile(String key) {
protected File getDataFile(String key) {
final String file = getString(key);
LOGGER.debug("Settings.getDataFile() - file: '{}'", file);
if (file == null) {
@@ -788,7 +726,7 @@ public final class Settings {
*
* @return a File object
*/
private static File getJarPath() {
private File getJarPath() {
String decodedPath = ".";
String jarPath = "";
final ProtectionDomain domain = Settings.class.getProtectionDomain();
@@ -819,8 +757,8 @@ public final class Settings {
* @param defaultValue the default value for the requested property
* @return the property from the properties file
*/
public static String getString(String key, String defaultValue) {
return System.getProperty(key, LOCAL_SETTINGS.get().props.getProperty(key, defaultValue));
public String getString(String key, String defaultValue) {
return System.getProperty(key, props.getProperty(key, defaultValue));
}
/**
@@ -830,9 +768,9 @@ public final class Settings {
* @throws java.io.IOException thrown if the temporary directory does not
* exist and cannot be created
*/
public static synchronized File getTempDirectory() throws IOException {
public synchronized File getTempDirectory() throws IOException {
if (tempDirectory == null) {
final File baseTemp = new File(Settings.getString(Settings.KEYS.TEMP_DIRECTORY, System.getProperty("java.io.tmpdir")));
final File baseTemp = new File(getString(Settings.KEYS.TEMP_DIRECTORY, System.getProperty("java.io.tmpdir")));
tempDirectory = FileUtils.createTempDirectory(baseTemp);
}
return tempDirectory;
@@ -847,19 +785,19 @@ public final class Settings {
* @param key the key to lookup within the properties file
* @return the property from the properties file
*/
public static String getString(String key) {
return System.getProperty(key, LOCAL_SETTINGS.get().props.getProperty(key));
public String getString(String key) {
return System.getProperty(key, props.getProperty(key));
}
/**
* Returns a list with the given key.
*
* If the propery is not set then {@code null} will be returned.
* If the property is not set then {@code null} will be returned.
*
* @param key the key to get from this {@link Settings} singleton.
* @param key the key to get from this {@link Settings}.
* @return the list or {@code null} if the key wasn't present.
*/
public static String[] getArray(final String key) {
public String[] getArray(final String key) {
final String string = getString(key);
if (string != null) {
return string.split(ARRAY_SEP);
@@ -873,8 +811,8 @@ public final class Settings {
*
* @param key the property key to remove
*/
public static void removeProperty(String key) {
LOCAL_SETTINGS.get().props.remove(key);
public void removeProperty(String key) {
props.remove(key);
}
/**
@@ -888,9 +826,9 @@ public final class Settings {
* @throws InvalidSettingException is thrown if there is an error retrieving
* the setting
*/
public static int getInt(String key) throws InvalidSettingException {
public int getInt(String key) throws InvalidSettingException {
try {
return Integer.parseInt(Settings.getString(key));
return Integer.parseInt(getString(key));
} catch (NumberFormatException ex) {
throw new InvalidSettingException("Could not convert property '" + key + "' to an int.", ex);
}
@@ -907,13 +845,13 @@ public final class Settings {
* @return the property from the properties file or the defaultValue if the
* property does not exist or cannot be converted to an integer
*/
public static int getInt(String key, int defaultValue) {
public int getInt(String key, int defaultValue) {
int value;
try {
value = Integer.parseInt(Settings.getString(key));
value = Integer.parseInt(getString(key));
} catch (NumberFormatException ex) {
if (!Settings.getString(key, "").isEmpty()) {
LOGGER.debug("Could not convert property '{}={}' to an int; using {} instead.", key, Settings.getString(key), defaultValue);
if (!getString(key, "").isEmpty()) {
LOGGER.debug("Could not convert property '{}={}' to an int; using {} instead.", key, getString(key), defaultValue);
}
value = defaultValue;
}
@@ -931,9 +869,9 @@ public final class Settings {
* @throws InvalidSettingException is thrown if there is an error retrieving
* the setting
*/
public static long getLong(String key) throws InvalidSettingException {
public long getLong(String key) throws InvalidSettingException {
try {
return Long.parseLong(Settings.getString(key));
return Long.parseLong(getString(key));
} catch (NumberFormatException ex) {
throw new InvalidSettingException("Could not convert property '" + key + "' to a long.", ex);
}
@@ -951,8 +889,8 @@ public final class Settings {
* @throws InvalidSettingException is thrown if there is an error retrieving
* the setting
*/
public static boolean getBoolean(String key) throws InvalidSettingException {
return Boolean.parseBoolean(Settings.getString(key));
public boolean getBoolean(String key) throws InvalidSettingException {
return Boolean.parseBoolean(getString(key));
}
/**
@@ -969,8 +907,8 @@ public final class Settings {
* @throws InvalidSettingException is thrown if there is an error retrieving
* the setting
*/
public static boolean getBoolean(String key, boolean defaultValue) throws InvalidSettingException {
return Boolean.parseBoolean(Settings.getString(key, Boolean.toString(defaultValue)));
public boolean getBoolean(String key, boolean defaultValue) throws InvalidSettingException {
return Boolean.parseBoolean(getString(key, Boolean.toString(defaultValue)));
}
/**
@@ -986,9 +924,9 @@ public final class Settings {
* @throws IOException thrown the data directory cannot be created
* @throws InvalidSettingException thrown if there is an invalid setting
*/
public static String getConnectionString(String connectionStringKey, String dbFileNameKey)
public String getConnectionString(String connectionStringKey, String dbFileNameKey)
throws IOException, InvalidSettingException {
final String connStr = Settings.getString(connectionStringKey);
final String connStr = getString(connectionStringKey);
if (connStr == null) {
final String msg = String.format("Invalid properties file; %s is missing.", connectionStringKey);
throw new InvalidSettingException(msg);
@@ -997,7 +935,7 @@ public final class Settings {
final File directory = getDataDirectory();
String fileName = null;
if (dbFileNameKey != null) {
fileName = Settings.getString(dbFileNameKey);
fileName = getString(dbFileNameKey);
}
if (fileName == null) {
final String msg = String.format("Invalid properties file to get a file based connection string; '%s' must be defined.",
@@ -1024,12 +962,32 @@ public final class Settings {
* @return the data directory to store data files
* @throws IOException is thrown if an IOException occurs of course...
*/
public static File getDataDirectory() throws IOException {
final File path = Settings.getDataFile(Settings.KEYS.DATA_DIRECTORY);
public File getDataDirectory() throws IOException {
final File path = getDataFile(Settings.KEYS.DATA_DIRECTORY);
if (path != null && (path.exists() || path.mkdirs())) {
return path;
}
throw new IOException(String.format("Unable to create the data directory '%s'",
(path == null) ? "unknown" : path.getAbsolutePath()));
}
/**
* Generates a new temporary file name that is guaranteed to be unique.
*
* @param prefix the prefix for the file name to generate
* @param extension the extension of the generated file name
* @return a temporary File
* @throws java.io.IOException thrown if the temporary folder could not be
* created
*/
public File getTempFile(String prefix, String extension) throws IOException {
final File dir = getTempDirectory();
final String tempFileName = String.format("%s%s.%s", prefix, UUID.randomUUID().toString(), extension);
final File tempFile = new File(dir, tempFileName);
if (tempFile.exists()) {
return getTempFile(prefix, extension);
}
return tempFile;
}
}

View File

@@ -48,11 +48,18 @@ public final class URLConnectionFactory {
* The logger.
*/
private static final Logger LOGGER = LoggerFactory.getLogger(URLConnectionFactory.class);
/**
* The configured settings.
*/
private final Settings settings;
/**
* Private constructor for this factory.
*
* @param settings reference to the configured settings
*/
private URLConnectionFactory() {
public URLConnectionFactory(Settings settings) {
this.settings = settings;
}
/**
@@ -65,17 +72,17 @@ public final class URLConnectionFactory {
* @throws URLConnectionFailureException thrown if there is an exception
*/
@SuppressFBWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE", justification = "Just being extra safe")
public static HttpURLConnection createHttpURLConnection(URL url) throws URLConnectionFailureException {
public HttpURLConnection createHttpURLConnection(URL url) throws URLConnectionFailureException {
HttpURLConnection conn = null;
final String proxyHost = Settings.getString(Settings.KEYS.PROXY_SERVER);
final String proxyHost = settings.getString(Settings.KEYS.PROXY_SERVER);
try {
if (proxyHost != null && !matchNonProxy(url)) {
final int proxyPort = Settings.getInt(Settings.KEYS.PROXY_PORT);
final int proxyPort = settings.getInt(Settings.KEYS.PROXY_PORT);
final SocketAddress address = new InetSocketAddress(proxyHost, proxyPort);
final String username = Settings.getString(Settings.KEYS.PROXY_USERNAME);
final String password = Settings.getString(Settings.KEYS.PROXY_PASSWORD);
final String username = settings.getString(Settings.KEYS.PROXY_USERNAME);
final String password = settings.getString(Settings.KEYS.PROXY_PASSWORD);
if (username != null && password != null) {
final Authenticator auth = new Authenticator() {
@@ -84,7 +91,7 @@ public final class URLConnectionFactory {
if (proxyHost.equals(getRequestingHost()) || getRequestorType().equals(Authenticator.RequestorType.PROXY)) {
LOGGER.debug("Using the configured proxy username and password");
try {
if (Settings.getBoolean(Settings.KEYS.PROXY_DISABLE_SCHEMAS, true)) {
if (settings.getBoolean(Settings.KEYS.PROXY_DISABLE_SCHEMAS, true)) {
System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
}
} catch (InvalidSettingException ex) {
@@ -103,8 +110,8 @@ public final class URLConnectionFactory {
} else {
conn = (HttpURLConnection) url.openConnection();
}
final int timeout = Settings.getInt(Settings.KEYS.CONNECTION_TIMEOUT, 10000);
conn.setConnectTimeout(timeout);
final int connectionTimeout = settings.getInt(Settings.KEYS.CONNECTION_TIMEOUT, 10000);
conn.setConnectTimeout(connectionTimeout);
conn.setInstanceFollowRedirects(true);
} catch (IOException ex) {
if (conn != null) {
@@ -126,11 +133,11 @@ public final class URLConnectionFactory {
* @param url the url to connect to
* @return matching result. true: match nonProxy
*/
private static boolean matchNonProxy(final URL url) {
private boolean matchNonProxy(final URL url) {
final String host = url.getHost();
// code partially from org.apache.maven.plugins.site.AbstractDeployMojo#getProxyInfo
final String nonProxyHosts = Settings.getString(Settings.KEYS.PROXY_NON_PROXY_HOSTS);
final String nonProxyHosts = settings.getString(Settings.KEYS.PROXY_NON_PROXY_HOSTS);
if (null != nonProxyHosts) {
final String[] nonProxies = nonProxyHosts.split("(,)|(;)|(\\|)");
for (final String nonProxyHost : nonProxies) {
@@ -172,14 +179,14 @@ public final class URLConnectionFactory {
* @return a newly constructed HttpURLConnection
* @throws URLConnectionFailureException thrown if there is an exception
*/
public static HttpURLConnection createHttpURLConnection(URL url, boolean proxy) throws URLConnectionFailureException {
public HttpURLConnection createHttpURLConnection(URL url, boolean proxy) throws URLConnectionFailureException {
if (proxy) {
return createHttpURLConnection(url);
}
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) url.openConnection();
final int timeout = Settings.getInt(Settings.KEYS.CONNECTION_TIMEOUT, 10000);
final int timeout = settings.getInt(Settings.KEYS.CONNECTION_TIMEOUT, 10000);
conn.setConnectTimeout(timeout);
conn.setInstanceFollowRedirects(true);
} catch (IOException ioe) {
@@ -197,11 +204,11 @@ public final class URLConnectionFactory {
* @param url the URL
* @param conn the connection
*/
private static void configureTLS(URL url, URLConnection conn) {
private void configureTLS(URL url, URLConnection conn) {
if ("https".equals(url.getProtocol())) {
try {
final HttpsURLConnection secCon = (HttpsURLConnection) conn;
final SSLSocketFactoryEx factory = new SSLSocketFactoryEx();
final SSLSocketFactoryEx factory = new SSLSocketFactoryEx(settings);
secCon.setSSLSocketFactory(factory);
} catch (NoSuchAlgorithmException ex) {
LOGGER.debug("Unsupported algorithm in SSLSocketFactoryEx", ex);

View File

@@ -15,8 +15,8 @@
*/
package org.owasp.dependencycheck.utils;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.After;
import org.junit.Before;
/**
*
@@ -24,13 +24,33 @@ import org.junit.BeforeClass;
*/
public class BaseTest {
@BeforeClass
public static void setUpClass() throws Exception {
Settings.initialize();
/**
* The configured settings.
*/
private Settings settings;
/**
* Initialize the {@link Settings}.
*/
@Before
public void setUp() {
settings = new Settings();
}
@AfterClass
public static void tearDownClass() throws Exception {
Settings.cleanup(true);
/**
* Clean the {@link Settings}.
*/
@After
public void tearDown() {
settings.cleanup(true);
}
/**
* Returns the settings for the test cases.
*
* @return
*/
protected Settings getSettings() {
return settings;
}
}

View File

@@ -40,16 +40,18 @@ public class DownloaderIT extends BaseTest {
// Settings.setString(Settings.KEYS.CONNECTION_TIMEOUT, "1000");
// Settings.setString(Settings.KEYS.PROXY_PORT, "8080");
// Settings.setString(Settings.KEYS.PROXY_SERVER, "127.0.0.1");
URL url = new URL(Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL));
URL url = new URL(getSettings().getString(Settings.KEYS.CVE_MODIFIED_20_URL));
File outputPath = new File("target/downloaded_cve.xml");
Downloader.fetchFile(url, outputPath);
Downloader downloader = new Downloader(getSettings());
downloader.fetchFile(url, outputPath);
assertTrue(outputPath.isFile());
}
@Test
public void testGetLastModified() throws Exception {
URL url = new URL(Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL));
long timestamp = Downloader.getLastModified(url);
URL url = new URL(getSettings().getString(Settings.KEYS.CVE_MODIFIED_20_URL));
Downloader downloader = new Downloader(getSettings());
long timestamp = downloader.getLastModified(url);
assertTrue("timestamp equal to zero?", timestamp > 0);
}
}

View File

@@ -25,11 +25,12 @@ import org.junit.Test;
*
* @author Jeremy Long
*/
public class DownloaderTest {
public class DownloaderTest extends BaseTest {
@Test
public void testGetLastModified_file() throws Exception {
long timestamp = Downloader.getLastModified(new File("target/test-classes/dependencycheck.properties").toURI().toURL());
Downloader instance = new Downloader(getSettings());
long timestamp = instance.getLastModified(new File("target/test-classes/dependencycheck.properties").toURI().toURL());
assertTrue("timestamp equal to zero?", timestamp > 0);
}
}

View File

@@ -50,7 +50,7 @@ public class FileUtilsTest extends BaseTest {
@Test
public void testDelete() throws Exception {
File file = File.createTempFile("tmp", "deleteme", Settings.getTempDirectory());
File file = File.createTempFile("tmp", "deleteme", getSettings().getTempDirectory());
if (!file.exists()) {
fail("Unable to create a temporary file.");
}

View File

@@ -26,9 +26,7 @@ import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
@@ -37,22 +35,6 @@ import org.junit.Test;
*/
public class SettingsTest extends BaseTest {
/**
* Initialize the {@link Settings} singleton.
*/
@Before
public void setUp() {
Settings.initialize();
}
/**
* Clean the {@link Settings} singleton.
*/
@After
public void tearDown() {
Settings.cleanup();
}
/**
* Test of getString method, of class Settings.
*/
@@ -60,7 +42,7 @@ public class SettingsTest extends BaseTest {
public void testGetString() {
String key = Settings.KEYS.CVE_MODIFIED_VALID_FOR_DAYS;
String expResult = "7";
String result = Settings.getString(key);
String result = getSettings().getString(key);
Assert.assertTrue(result.endsWith(expResult));
}
@@ -71,21 +53,23 @@ public class SettingsTest extends BaseTest {
public void testGetDataFile() throws IOException {
String key = Settings.KEYS.DATA_DIRECTORY;
String expResult = "data";
File result = Settings.getDataFile(key);
File result = getSettings().getDataFile(key);
Assert.assertTrue(result.getAbsolutePath().endsWith(expResult));
}
/**
* Test of mergeProperties method, of class Settings.
* @throws java.io.IOException thrown when the test fails
* @throws java.net.URISyntaxException thrown when the test fails
*/
@Test
public void testMergeProperties_String() throws IOException, URISyntaxException {
String key = Settings.KEYS.PROXY_PORT;
String expResult = Settings.getString(key);
String expResult = getSettings().getString(key);
File f = new File(this.getClass().getClassLoader().getResource("test.properties").toURI());
//InputStream in = this.getClass().getClassLoader().getResourceAsStream("test.properties");
Settings.mergeProperties(f.getAbsolutePath());
String result = Settings.getString(key);
getSettings().mergeProperties(f.getAbsolutePath());
String result = getSettings().getString(key);
Assert.assertTrue("setting didn't change?", (expResult == null && result != null) || !expResult.equals(result));
}
@@ -96,8 +80,8 @@ public class SettingsTest extends BaseTest {
public void testSetString() {
String key = "newProperty";
String value = "someValue";
Settings.setString(key, value);
String expResults = Settings.getString(key);
getSettings().setString(key, value);
String expResults = getSettings().getString(key);
Assert.assertEquals(expResults, value);
}
@@ -108,9 +92,9 @@ public class SettingsTest extends BaseTest {
public void testSetStringIfNotNull() {
String key = "nullableProperty";
String value = "someValue";
Settings.setString(key, value);
Settings.setStringIfNotNull(key, null); // NO-OP
String expResults = Settings.getString(key);
getSettings().setString(key, value);
getSettings().setStringIfNotNull(key, null); // NO-OP
String expResults = getSettings().getString(key);
Assert.assertEquals(expResults, value);
}
@@ -121,9 +105,9 @@ public class SettingsTest extends BaseTest {
public void testSetStringIfNotEmpty() {
String key = "optionalProperty";
String value = "someValue";
Settings.setString(key, value);
Settings.setStringIfNotEmpty(key, ""); // NO-OP
String expResults = Settings.getString(key);
getSettings().setString(key, value);
getSettings().setStringIfNotEmpty(key, ""); // NO-OP
String expResults = getSettings().getString(key);
Assert.assertEquals(expResults, value);
}
@@ -135,9 +119,9 @@ public class SettingsTest extends BaseTest {
String key = "key That Doesn't Exist";
String defaultValue = "blue bunny";
String expResult = "blue bunny";
String result = Settings.getString(key);
String result = getSettings().getString(key);
Assert.assertTrue(result == null);
result = Settings.getString(key, defaultValue);
result = getSettings().getString(key, defaultValue);
Assert.assertEquals(expResult, result);
}
@@ -147,7 +131,7 @@ public class SettingsTest extends BaseTest {
@Test
public void testGetString_String() {
String key = Settings.KEYS.CONNECTION_TIMEOUT;
String result = Settings.getString(key);
String result = getSettings().getString(key);
Assert.assertTrue(result == null);
}
@@ -158,8 +142,8 @@ public class SettingsTest extends BaseTest {
public void testGetInt() throws InvalidSettingException {
String key = "SomeNumber";
int expResult = 85;
Settings.setString(key, "85");
int result = Settings.getInt(key);
getSettings().setString(key, "85");
int result = getSettings().getInt(key);
Assert.assertEquals(expResult, result);
}
@@ -170,8 +154,8 @@ public class SettingsTest extends BaseTest {
public void testGetIntDefault() throws InvalidSettingException {
String key = "SomeKey";
int expResult = 85;
Settings.setString(key, "blue");
int result = Settings.getInt(key, expResult);
getSettings().setString(key, "blue");
int result = getSettings().getInt(key, expResult);
Assert.assertEquals(expResult, result);
}
@@ -182,8 +166,8 @@ public class SettingsTest extends BaseTest {
public void testGetLong() throws InvalidSettingException {
String key = "SomeNumber";
long expResult = 300L;
Settings.setString(key, "300");
long result = Settings.getLong(key);
getSettings().setString(key, "300");
long result = getSettings().getLong(key);
Assert.assertEquals(expResult, result);
}
@@ -193,14 +177,14 @@ public class SettingsTest extends BaseTest {
@Test
public void testGetBoolean() throws InvalidSettingException {
String key = "SomeBoolean";
Settings.setString(key, "false");
getSettings().setString(key, "false");
boolean expResult = false;
boolean result = Settings.getBoolean(key);
boolean result = getSettings().getBoolean(key);
Assert.assertEquals(expResult, result);
key = "something that does not exist";
expResult = true;
result = Settings.getBoolean(key, true);
result = getSettings().getBoolean(key, true);
Assert.assertEquals(expResult, result);
}
@@ -212,11 +196,11 @@ public class SettingsTest extends BaseTest {
String key = "SomeKey";
String value = "value";
String dfault = "default";
Settings.setString(key, value);
String ret = Settings.getString(key);
getSettings().setString(key, value);
String ret = getSettings().getString(key);
Assert.assertEquals(value, ret);
Settings.removeProperty(key);
ret = Settings.getString(key, dfault);
getSettings().removeProperty(key);
ret = getSettings().getString(key, dfault);
Assert.assertEquals(dfault, ret);
}
@@ -225,11 +209,11 @@ public class SettingsTest extends BaseTest {
*/
@Test
public void testGetConnectionString() throws Exception {
String value = Settings.getConnectionString(Settings.KEYS.DB_CONNECTION_STRING, Settings.KEYS.DB_FILE_NAME);
String value = getSettings().getConnectionString(Settings.KEYS.DB_CONNECTION_STRING, Settings.KEYS.DB_FILE_NAME);
Assert.assertNotNull(value);
String msg = null;
try {
value = Settings.getConnectionString("invalidKey", null);
value = getSettings().getConnectionString("invalidKey", null);
} catch (InvalidSettingException e) {
msg = e.getMessage();
}
@@ -241,7 +225,7 @@ public class SettingsTest extends BaseTest {
*/
@Test
public void testGetTempDirectory() throws Exception {
File tmp = Settings.getTempDirectory();
File tmp = getSettings().getTempDirectory();
Assert.assertTrue(tmp.exists());
}
@@ -253,10 +237,10 @@ public class SettingsTest extends BaseTest {
public void testGetArrayFromADelimitedString() {
// GIVEN a delimited string
final String delimitedString = "value1,value2";
Settings.setString("key", delimitedString);
getSettings().setString("key", delimitedString);
// WHEN getting the array
final String[] array = Settings.getArray("key");
final String[] array = getSettings().getArray("key");
// THEN the split array is returned
assertThat("Expected the array to be non-null", array, notNullValue());
@@ -272,7 +256,7 @@ public class SettingsTest extends BaseTest {
@Test
public void testGetArrayWhereThePropertyIsNotSet() {
// WHEN getting the array
final String[] array = Settings.getArray("key");
final String[] array = getSettings().getArray("key");
// THEN null is returned
assertThat("Expected the array to be null", array, nullValue());
@@ -288,10 +272,10 @@ public class SettingsTest extends BaseTest {
final String[] array = {};
// WHEN setting the array
Settings.setArrayIfNotEmpty("key", array);
getSettings().setArrayIfNotEmpty("key", array);
// THEN the property was not set
assertThat("Expected the property to not be set", Settings.getString("key"), nullValue());
assertThat("Expected the property to not be set", getSettings().getString("key"), nullValue());
}
/**
@@ -304,10 +288,10 @@ public class SettingsTest extends BaseTest {
final String[] array = null;
// WHEN setting the array
Settings.setArrayIfNotEmpty("key", array);
getSettings().setArrayIfNotEmpty("key", array);
// THEN the property was not set
assertThat("Expected the property to not be set", Settings.getString("key"), nullValue());
assertThat("Expected the property to not be set", getSettings().getString("key"), nullValue());
}
/**
@@ -320,10 +304,10 @@ public class SettingsTest extends BaseTest {
final String[] array = {"value1", "value2"};
// WHEN setting the array
Settings.setArrayIfNotEmpty("key", array);
getSettings().setArrayIfNotEmpty("key", array);
// THEN the property is set
assertThat("Expected the property to be set", Settings.getString("key"), is("value1,value2"));
assertThat("Expected the property to be set", getSettings().getString("key"), is("value1,value2"));
}
/**
@@ -336,9 +320,9 @@ public class SettingsTest extends BaseTest {
final String[] array = {"value1"};
// WHEN setting the array
Settings.setArrayIfNotEmpty("key", array);
getSettings().setArrayIfNotEmpty("key", array);
// THEN the property is set
assertThat("Expected the property to be set", Settings.getString("key"), is("value1"));
assertThat("Expected the property to be set", getSettings().getString("key"), is("value1"));
}
}