resources/META-INF/microprofile-config.properties
is used. (It's possible to use profiles.)
+ *
+ * @return Solr endpoint as string "hostname:port"
+ */
public String getSolrHostColonPort() {
- String SolrHost;
- if ( System.getenv("SOLR_SERVICE_HOST") != null && System.getenv("SOLR_SERVICE_HOST") != ""){
- SolrHost = System.getenv("SOLR_SERVICE_HOST");
- }
- else SolrHost = saneDefaultForSolrHostColonPort;
- String solrHostColonPort = settingsService.getValueForKey(SettingsServiceBean.Key.SolrHostColonPort, SolrHost);
- return solrHostColonPort;
+ // Get from MPCONFIG. Might be configured by a sysadmin or simply return the default shipped with
+ // resources/META-INF/microprofile-config.properties.
+ // NOTE: containers should use system property mp.config.profile=ct to use sane container usage default
+ String host = JvmSettings.SOLR_HOST.lookup();
+ String port = JvmSettings.SOLR_PORT.lookup();
+
+ // DB setting takes precedence over all. If not present, will return default from above.
+ return Optional.ofNullable(settingsService.getValueForKey(SettingsServiceBean.Key.SolrHostColonPort))
+ .orElse(host + ":" + port);
}
public boolean isProvCollectionEnabled() {
@@ -340,32 +234,58 @@ public static int getMinutesUntilPasswordResetTokenExpires() {
}
/**
- * The "official", designated URL of the site;
- * can be defined as a complete URL; or derived from the
- * "official" hostname. If none of these options is set,
- * defaults to the InetAddress.getLocalHOst() and https;
- * These are legacy JVM options. Will be eventualy replaced
- * by the Settings Service configuration.
+ * Lookup (or construct) the designated URL of this instance from configuration.
+ *
+ * Can be defined as a complete URL via dataverse.siteUrl
; or derived from the hostname
+ * dataverse.fqdn
and HTTPS. If none of these options is set, defaults to the
+ * {@link InetAddress#getLocalHost} and HTTPS.
+ *
+ * NOTE: This method does not provide any validation.
+ * TODO: The behaviour of this method is subject to a later change, see
+ * https://github.com/IQSS/dataverse/issues/6636
+ *
+ * @return The designated URL of this instance as per configuration.
*/
public String getDataverseSiteUrl() {
return getDataverseSiteUrlStatic();
}
+ /**
+ * Lookup (or construct) the designated URL of this instance from configuration.
+ *
+ * Can be defined as a complete URL via dataverse.siteUrl
; or derived from the hostname
+ * dataverse.fqdn
and HTTPS. If none of these options is set, defaults to the
+ * {@link InetAddress#getLocalHost} and HTTPS.
+ *
+ * NOTE: This method does not provide any validation.
+ * TODO: The behaviour of this method is subject to a later change, see
+ * https://github.com/IQSS/dataverse/issues/6636
+ *
+ * @return The designated URL of this instance as per configuration.
+ */
public static String getDataverseSiteUrlStatic() {
- String hostUrl = System.getProperty(SITE_URL);
- if (hostUrl != null && !"".equals(hostUrl)) {
- return hostUrl;
+ // If dataverse.siteUrl has been configured, simply return it
+ OptionalThe key and value of the JVM setting to be set must be specified via + * {@link #key()} and {@link #value()}. After the annotated method has been + * executed, the initial default value is restored.
+ * + *{@code SetJvmSetting} can be used on the method and on the class level. + * It is repeatable and inherited from higher-level containers. If a class is + * annotated, the configured property will be set before every test inside that + * class. Any method level configurations will override the class level + * configurations.
+ * + * Parallel execution of tests using this extension is prohibited by using + * resource locking provided by JUnit5 - system properties are a global state, + * these tests NEED to be done serial. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.METHOD, ElementType.TYPE }) +@Inherited +@Repeatable(JvmSetting.JvmSettings.class) +@ExtendWith(JvmSettingExtension.class) +@ResourceLock(value = Resources.SYSTEM_PROPERTIES, mode = ResourceAccessMode.READ_WRITE) +public @interface JvmSetting { + + /** + * The key of the system property to be set. + */ + edu.harvard.iq.dataverse.settings.JvmSettings key(); + + /** + * The value of the system property to be set. + */ + String value(); + + /** + * Containing annotation of repeatable {@code @SetSystemProperty}. + */ + @Retention(RetentionPolicy.RUNTIME) + @Target({ ElementType.METHOD, ElementType.TYPE }) + @Inherited + @ExtendWith(JvmSettingExtension.class) + @interface JvmSettings { + JvmSetting[] value(); + } +} diff --git a/src/test/java/edu/harvard/iq/dataverse/util/testing/JvmSettingExtension.java b/src/test/java/edu/harvard/iq/dataverse/util/testing/JvmSettingExtension.java new file mode 100644 index 00000000000..de18df0f575 --- /dev/null +++ b/src/test/java/edu/harvard/iq/dataverse/util/testing/JvmSettingExtension.java @@ -0,0 +1,49 @@ +package edu.harvard.iq.dataverse.util.testing; + +import org.junit.jupiter.api.extension.AfterTestExecutionCallback; +import org.junit.jupiter.api.extension.BeforeTestExecutionCallback; +import org.junit.jupiter.api.extension.ExtensionContext; + +public class JvmSettingExtension implements BeforeTestExecutionCallback, AfterTestExecutionCallback { + + private ExtensionContext.Store getStore(ExtensionContext context) { + return context.getStore(ExtensionContext.Namespace.create(getClass(), context.getRequiredTestClass(), context.getRequiredTestMethod())); + } + + @Override + public void beforeTestExecution(ExtensionContext extensionContext) throws Exception { + extensionContext.getTestMethod().ifPresent(method -> { + JvmSetting[] settings = method.getAnnotationsByType(JvmSetting.class); + for (JvmSetting setting : settings) { + // get the setting ... + String oldSetting = System.getProperty(setting.key().getScopedKey()); + + // if present - store in context to restore later + if (oldSetting != null) { + getStore(extensionContext).put(setting.key().getScopedKey(), oldSetting); + } + + // set to new value + System.setProperty(setting.key().getScopedKey(), setting.value()); + } + }); + } + + @Override + public void afterTestExecution(ExtensionContext extensionContext) throws Exception { + extensionContext.getTestMethod().ifPresent(method -> { + JvmSetting[] settings = method.getAnnotationsByType(JvmSetting.class); + for (JvmSetting setting : settings) { + // get a stored setting from context + String oldSetting = getStore(extensionContext).remove(setting.key().getScopedKey(), String.class); + // if present before, restore + if (oldSetting != null) { + System.setProperty(setting.key().getScopedKey(), oldSetting); + // if NOT present before, delete + } else { + System.clearProperty(setting.key().getScopedKey()); + } + } + }); + } +} diff --git a/src/test/resources/META-INF/microprofile-config.properties b/src/test/resources/META-INF/microprofile-config.properties new file mode 100644 index 00000000000..21f70b53896 --- /dev/null +++ b/src/test/resources/META-INF/microprofile-config.properties @@ -0,0 +1,11 @@ +# DEFAULTS FOR TESTS +# Unlike src/main/resources/META-INF/microprofile-config.properties, this file will not be included in +# a packaged WAR. It can be used to provide sane defaults for things like unit tests on classes requiring +# some sort of configuration. + +# PersistentIdentifierServiceBeanTest loads all the providers, which makes the EZID provider reach out +# to the service - switching to example.org to not trigger a DDoS via test executions at their place. +dataverse.pid.ezid.api-url=http://example.org +# Also requires the username and the password to be present when used in production, use a default for unit testing. +dataverse.pid.ezid.username=Dataverse Unit Test +dataverse.pid.ezid.password=supersecret \ No newline at end of file