Refactor code to remove the need for a "hostname" configuration.

This commit is contained in:
Tim Donohue
2020-01-31 16:45:22 -06:00
parent d455d7df87
commit b116c55714
14 changed files with 187 additions and 36 deletions

View File

@@ -33,6 +33,7 @@ import org.apache.commons.lang3.StringUtils;
import org.dspace.core.ConfigurationManager;
import org.dspace.core.Context;
import org.dspace.core.LogManager;
import org.dspace.core.Utils;
import org.dspace.discovery.DiscoverQuery;
import org.dspace.discovery.SearchServiceException;
import org.dspace.discovery.SearchUtils;
@@ -581,7 +582,7 @@ public class LogAnalyser {
}
// now do the host name and url lookup
hostName = ConfigurationManager.getProperty("dspace.ui.hostname").trim();
hostName = Utils.getHostName(ConfigurationManager.getProperty("dspace.ui.url"));
name = ConfigurationManager.getProperty("dspace.name").trim();
url = ConfigurationManager.getProperty("dspace.ui.url").trim();
if ((url != null) && (!url.endsWith("/"))) {

View File

@@ -27,6 +27,7 @@ import org.dspace.checker.service.SimpleReporterService;
import org.dspace.core.ConfigurationManager;
import org.dspace.core.Context;
import org.dspace.core.Email;
import org.dspace.core.Utils;
/**
* <p>
@@ -62,7 +63,7 @@ public class DailyReportEmailer {
public void sendReport(File attachment, int numberOfBitstreams)
throws IOException, javax.mail.MessagingException {
if (numberOfBitstreams > 0) {
String hostname = ConfigurationManager.getProperty("dspace.ui.hostname");
String hostname = Utils.getHostName(ConfigurationManager.getProperty("dspace.ui.url"));
Email email = new Email();
email.setSubject(
"Checksum checker Report - " + numberOfBitstreams + " Bitstreams found with POSSIBLE issues on " +

View File

@@ -265,7 +265,8 @@ public class OREDisseminationCrosswalk
Element pmhMeta = new Element("entry",ATOM_NS);
pUri = new Element("id",ATOM_NS);
String oaiId = new String("oai:" + ConfigurationManager.getProperty("dspace.ui.hostname") + ":" + item.getHandle
String hostname = Utils.getHostName(ConfigurationManager.getProperty("dspace.ui.url"));
String oaiId = new String("oai:" + hostname + ":" + item.getHandle
());
pUri.addContent(oaiId + "#oai_dc");
pmhMeta.addContent(pUri);

View File

@@ -13,6 +13,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.net.URI;
import java.net.URISyntaxException;
import java.rmi.dgc.VMID;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -30,7 +32,10 @@ import java.util.regex.Pattern;
import com.coverity.security.Escape;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringSubstitutor;
import org.apache.logging.log4j.Logger;
import org.dspace.services.ConfigurationService;
import org.dspace.services.factory.DSpaceServicesFactory;
/**
* Utility functions for DSpace.
@@ -408,4 +413,38 @@ public final class Utils {
return schema + separator + element + separator + qualifier;
}
}
/**
* Retrieve the hostname from a given URI string
* @param uriString URI string
* @return hostname (without any www.) or null (if URI was invalid)
*/
public static String getHostName(String uriString) {
try {
URI uri = new URI(uriString);
String hostname = uri.getHost();
// remove the "www." from hostname, if it exists
if (hostname != null) {
return hostname.startsWith("www.") ? hostname.substring(4) : hostname;
}
return hostname;
} catch (URISyntaxException e) {
return null;
}
}
/**
* Replaces configuration placeholders within a String with the corresponding value
* from DSpace's Configuration Service.
* <P>
* For example, given a String like "My DSpace is installed at ${dspace.dir}", this
* method will replace "${dspace.dir}" with the configured value of that property.
* @param string source string
* @return string with any placeholders replaced with configured values.
*/
public static String interpolateConfigsInString(String string) {
ConfigurationService config = DSpaceServicesFactory.getInstance().getConfigurationService();
return StringSubstitutor.replace(string, config.getProperties());
}
}

View File

@@ -92,7 +92,9 @@ public class S3BitStoreService implements BitStoreService {
// bucket name
if (StringUtils.isEmpty(bucketName)) {
bucketName = "dspace-asset-" + ConfigurationManager.getProperty("dspace.ui.hostname");
// get hostname of DSpace UI to use to name bucket
String hostname = Utils.getHostName(ConfigurationManager.getProperty("dspace.ui.url"));
bucketName = "dspace-asset-" + hostname;
log.warn("S3 BucketName is not configured, setting default: " + bucketName);
}
@@ -342,8 +344,10 @@ public class S3BitStoreService implements BitStoreService {
Region usEast1 = Region.getRegion(Regions.US_EAST_1);
store.s3Service.setRegion(usEast1);
// get hostname of DSpace UI to use to name bucket
String hostname = Utils.getHostName(ConfigurationManager.getProperty("dspace.ui.url"));
//Bucketname should be lowercase
store.bucketName = "dspace-asset-" + ConfigurationManager.getProperty("dspace.ui.hostname") + ".s3test";
store.bucketName = "dspace-asset-" + hostname + ".s3test";
store.s3Service.createBucket(store.bucketName);
/* Broken in DSpace 6 TODO Refactor
// time everything, todo, swtich to caliper

View File

@@ -0,0 +1,71 @@
/**
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://www.dspace.org/license/
*/
package org.dspace.core;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import org.dspace.AbstractUnitTest;
import org.dspace.services.ConfigurationService;
import org.dspace.services.factory.DSpaceServicesFactory;
import org.junit.Test;
/**
* Perform some basic unit tests for Utils Class
*
* @author tdonohue
*/
public class UtilsTest extends AbstractUnitTest {
/**
* Test of getHostName method, of class Utils
*/
@Test
public void testGetHostName() {
assertEquals("Test remove HTTP", "dspace.org",
Utils.getHostName("http://dspace.org"));
assertEquals("Test remove HTTPS", "dspace.org",
Utils.getHostName("https://dspace.org"));
assertEquals("Test remove trailing slash", "dspace.org",
Utils.getHostName("https://dspace.org/"));
assertEquals("Test remove www.", "dspace.org",
Utils.getHostName("https://www.dspace.org"));
assertEquals("Test keep other prefixes", "demo.dspace.org",
Utils.getHostName("https://demo.dspace.org"));
// This uses a bunch of reserved URI characters
assertNull("Test invalid URI returns null", Utils.getHostName("&+,?/@="));
}
/**
* Test of interpolateConfigsInString method, of class Utils
*/
@Test
public void testInterpolateConfigsInString() {
ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService();
// Add a new config to test with
String configName = "not.a.dspace.config.at.all";
String configValue = "demo.dspace.org";
configurationService.setProperty(configName, configValue);
// Create a string where the config is represented by ${variable}
String stringWithVariable = "The config " + configName + " has a value of ${" + configName + "}!";
String expectedValue = "The config " + configName + " has a value of " + configValue + "!";
assertEquals("Test config interpolation", expectedValue,
Utils.interpolateConfigsInString(stringWithVariable));
// remove the config we added
configurationService.setProperty(configName, null);
}
}

View File

@@ -7,22 +7,49 @@
*/
package org.dspace.xoai.services.impl.config;
import org.dspace.core.ConfigurationManager;
import org.dspace.core.Utils;
import org.dspace.services.factory.DSpaceServicesFactory;
import org.dspace.xoai.services.api.config.ConfigurationService;
public class DSpaceConfigurationService implements ConfigurationService {
private org.dspace.services.ConfigurationService configurationService =
DSpaceServicesFactory.getInstance().getConfigurationService();
/**
* Initialize the OAI Configuration Service
*/
public DSpaceConfigurationService() {
// Check the DSpace ConfigurationService for required OAI-PMH settings.
// If they do not exist, set sane defaults as needed.
// Per OAI Spec, "oai.identifier.prefix" should be the hostname / domain name of the site.
// This configuration is needed by the [dspace]/config/crosswalks/oai/description.xml template, so if
// unspecified we will dynamically set it to the hostname of the "dspace.ui.url" configuration.
if (!configurationService.hasProperty("oai.identifier.prefix")) {
configurationService.setProperty("oai.identifier.prefix",
Utils.getHostName(configurationService.getProperty("dspace.ui.url")));
}
}
@Override
public String getProperty(String key) {
return ConfigurationManager.getProperty(key);
return configurationService.getProperty(key);
}
@Override
public String getProperty(String module, String key) {
return ConfigurationManager.getProperty(module, key);
return configurationService.getProperty(module, key);
}
@Override
public boolean getBooleanProperty(String module, String key, boolean defaultValue) {
return ConfigurationManager.getBooleanProperty(module, key, defaultValue);
if (module == null) {
return configurationService.getBooleanProperty(key, defaultValue);
}
// Assume "module" properties are always prefixed with the module name
return configurationService.getBooleanProperty(module + "." + key, defaultValue);
}
}

View File

@@ -9,6 +9,7 @@ package org.dspace.xoai.services.impl.xoai;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
@@ -22,6 +23,7 @@ import org.apache.commons.io.FileUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dspace.core.Context;
import org.dspace.core.Utils;
import org.dspace.xoai.exceptions.InvalidMetadataFieldException;
import org.dspace.xoai.services.api.EarliestDateResolver;
import org.dspace.xoai.services.api.config.ConfigurationService;
@@ -132,13 +134,13 @@ public class DSpaceRepositoryConfiguration implements RepositoryConfiguration {
@Override
public List<String> getDescription() {
List<String> result = new ArrayList<String>();
String descriptionFile = configurationService.getProperty("oai", "description.file");
String descriptionFile = configurationService.getProperty("oai.description.file");
if (descriptionFile == null) {
// Try indexed
boolean stop = false;
List<String> descriptionFiles = new ArrayList<String>();
for (int i = 0; !stop; i++) {
String tmp = configurationService.getProperty("oai", "description.file." + i);
String tmp = configurationService.getProperty("oai.description.file." + i);
if (tmp == null) {
stop = true;
} else {
@@ -150,7 +152,10 @@ public class DSpaceRepositoryConfiguration implements RepositoryConfiguration {
try {
File f = new File(path);
if (f.exists()) {
result.add(FileUtils.readFileToString(f));
String fileAsString = FileUtils.readFileToString(f, StandardCharsets.UTF_8);
// replace any configuration placeholders (e.g. ${variable}) in string
fileAsString = Utils.interpolateConfigsInString(fileAsString);
result.add(fileAsString);
}
} catch (IOException e) {
log.debug(e.getMessage(), e);
@@ -161,7 +166,10 @@ public class DSpaceRepositoryConfiguration implements RepositoryConfiguration {
try {
File f = new File(descriptionFile);
if (f.exists()) {
result.add(FileUtils.readFileToString(f));
String fileAsString = FileUtils.readFileToString(f, StandardCharsets.UTF_8);
// replace any configuration placeholders (e.g. ${variable}) in string
fileAsString = Utils.interpolateConfigsInString(fileAsString);
result.add(fileAsString);
}
} catch (IOException e) {
log.debug(e.getMessage(), e);

View File

@@ -16,8 +16,11 @@ BINDIR=`dirname $0`
echo "Writing simple Handle server configuration"
# Read parameters from DSpace config
dshostname=`$BINDIR/dspace dsprop --property dspace.ui.hostname`
# Read server URL from DSpace config
dsurl=`$BINDIR/dspace dsprop --property dspace.server.url`
# Parse hostname from URL
dshostname=`echo $dsurl | awk -F/ '{ print $3; exit }'`
# Determine IP address from hostname
dshostip=`host $dshostname | awk '/has address/ { print $4; exit }'`
if [ "$dshostip" = "127.0.0.1" ]; then
# Just use default. SimpleSetup will fail when trying to bind to localhost addresses.

View File

@@ -1,6 +1,6 @@
<oai-identifier xmlns="http://www.openarchives.org/OAI/2.0/oai-identifier" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai-identifier http://www.openarchives.org/OAI/2.0/oai-identifier.xsd">
<scheme>oai</scheme>
<repositoryIdentifier>${dspace.ui.hostname}</repositoryIdentifier>
<repositoryIdentifier>${oai.identifier.prefix}</repositoryIdentifier>
<delimiter>:</delimiter>
<sampleIdentifier>oai:${dspace.ui.hostname}:${handle.prefix}/1234</sampleIdentifier>
<sampleIdentifier>oai:${oai.identifier.prefix}:${handle.prefix}/1234</sampleIdentifier>
</oai-identifier>

View File

@@ -26,11 +26,6 @@ dspace.dir = /dspace
# This is where REST API and all enabled server modules (OAI-PMH, SWORD, SWORDv2, RDF, etc) will respond
dspace.server.url = http://localhost:8080/server
# DSpace UI hostname. Should match dspace.ui.url. Do not include port number.
# This is used by some modules (e.g. OAI) as an identifier for your site.
# You also may chose to use this to populate other configurations below.
dspace.ui.hostname = localhost
# URL of DSpace frontend (Angular UI). Include port number etc
# This is used by the backend to provide links in emails, RSS feeds, Sitemaps, etc.
dspace.ui.url = http://localhost:3000
@@ -138,8 +133,9 @@ alert.recipient = ${mail.admin}
mail.charset = UTF-8
# A comma-separated list of hostnames that are allowed to refer browsers to email forms.
# Default behaviour is to accept referrals only from dspace.ui.hostname
mail.allowed.referrers = ${dspace.ui.hostname}
# Default behaviour is to accept referrals only from dspace.hostname
# TODO: Needs removal/replacement. No longer used in DSpace 7 codebase and dspace.hostname config no longer exists.
#mail.allowed.referrers = ${dspace.hostname}
# Pass extra settings to the Java mail library. Comma-separated, equals sign between
# the key and the value. For example:
@@ -1830,7 +1826,7 @@ webui.suggest.enable = false
# Force all authenticated connections to use SSL, only non-authenticated
# connections are allowed over plain http. If set to true, then you need to
# ensure that the 'dspace.ui.hostname' parameter is set to the correctly.
# ensure that the 'dspace.hostname' parameter is set to the correctly.
#xmlui.force.ssl = true
# Determine if new users should be allowed to register or edit their own metadata.

View File

@@ -34,11 +34,6 @@ dspace.dir=/dspace
# This is where REST API and all enabled server modules (OAI-PMH, SWORD, SWORDv2, RDF, etc) will respond
dspace.server.url = http://localhost:8080/server
# DSpace UI hostname. Should match dspace.ui.url. Do not include port number.
# This is used by some modules (e.g. OAI) as an identifier for your site.
# You also may chose to use this to populate other configurations below.
dspace.ui.hostname = localhost
# URL of DSpace frontend (Angular UI). Include port number etc
# This is used by the backend to provide links in emails, RSS feeds, Sitemaps, etc.
dspace.ui.url = http://localhost:3000

View File

@@ -8,7 +8,7 @@
# When "true", the OAI module is accessible on ${oai.path}
# When "false" or commented out, OAI is disabled/inaccessible.
# (Requires reboot of servlet container, e.g. Tomcat, to reload)
#oai.enabled = true
oai.enabled = true
# Path where OAI module is available
# Defaults to "oai", which means the OAI module would be available
@@ -25,9 +25,16 @@ oai.url = ${dspace.server.url}/${oai.path}
# Base solr index
oai.solr.url=${solr.server}/oai
# OAI persistent identifier prefix.
# Format - oai:PREFIX:HANDLE
oai.identifier.prefix = ${dspace.ui.hostname}
# OAI persistent identifier prefix
# This field is used for two purposes:
# 1. As your OAI-PMH <repositoryIdentifier>
# 2. As the prefix for all Identifiers in OAI-PMH (Format is "oai:${oai.identifier.prefix}:${handle.prefix}")
# The OAI-PMH spec requires this prefix to correspond to your site's hostname. Therefore, by default,
# DSpace will set this configuration to the hostname from your ${dspace.ui.url} configuration.
# However, you may override that default value by uncommenting this configuration.
# oai.identifier.prefix = YOUR_SITE_HOSTNAME
# Base url for bitstreams
oai.bitstream.baseUrl = ${dspace.ui.url}

View File

@@ -349,8 +349,6 @@ Common usage:
autoconfiguring itself (e.g. see DS-3104). -->
<include name="log4j*.properties"/>
<include name="log4j2*.xml"/>
<!-- Filter OAI-PMH description so it can include hostname and handle prefix -->
<include name="crosswalks/oai/description.xml"/>
<!-- Filter sample Tomcat context.xml -->
<include name="default.context.xml"/>
<!-- Filter RDF configs as these are TTL files -->