diff --git a/doc/release-notes/7457-introduce-mpconfig.md b/doc/release-notes/7457-introduce-mpconfig.md new file mode 100644 index 00000000000..2f90590fca5 --- /dev/null +++ b/doc/release-notes/7457-introduce-mpconfig.md @@ -0,0 +1,10 @@ +## Introducing MicroProfile Config API + +With this Dataverse release, we start to make use of the MicroProfile Config API. (As you might have noticed +for the database connection settings.) + +This will benefit both devs and sysadmins, but the codebase will have to be refactored to make use of it. +As this will take time, we will always provide a backward compatible way of using it. + +For more details, please see the development guide about "Consuming Configuration", which also +explains the benefits in more detail. \ No newline at end of file diff --git a/doc/sphinx-guides/source/developers/configuration.rst b/doc/sphinx-guides/source/developers/configuration.rst new file mode 100644 index 00000000000..d058a1e1705 --- /dev/null +++ b/doc/sphinx-guides/source/developers/configuration.rst @@ -0,0 +1,100 @@ +Consuming Configuration +======================= + +.. contents:: |toctitle| + :local: + +Dataverse uses different types of configuration: + +1. JVM system properties +2. Simple database value settings +3. Complex database stored data structures + +1 and 2 are usually simple text strings, boolean switches or digits. All of those can be found in :doc:`/installation/config`. + +Anything for 3 is configured via the API using either TSV or JSON structures. Examples are metadata blocks, +authentication providers, harvesters and others. + +Simple Configuration Options +---------------------------- + +Developers have accessed the simple properties via + +1. ``System.getProperty(...)`` for JVM system property settings +2. ``SettingsServiceBean.get(...)`` for database settings and +3. ``SystemConfig.xxx()`` for specially treated settings, maybe mixed from 1 and 2 and other sources. +4. ``SettingsWrapper``, reading from 2 and 3 for use in frontend pages based on JSF + +As of Dataverse 5.3, we start to streamline our efforts into using a more consistent approach, also bringing joy and +happiness to all the system administrators out there. This will be done by adopting the use of +`MicroProfile Config `_ over time. + +So far we streamlined configuration of these Dataverse parts: + +- ✅ Database Connection + +Complex Configuration Options +----------------------------- + +We should enable variable substitution in JSON configuration. Example: using substitution to retrieve values from +MicroProfile Config and insert into the authentication provider would allow much easier provisioning of secrets +into the providers. + +Why should I care about MicroProfile Config API? +------------------------------------------------ + +Developers benefit from: + +- A streamlined API to retrieve configuration, backward-compatible renaming strategies and easier testbed configurations. +- Config API is also pushing for validation of configuration, as it's typesafe and converters for non-standard types + can be added within our codebase. +- Defaults in code or bundled in ``META-INF/microprofile-config.properties`` allow for optional values without much hassle. + +System administrators benefit from: + +- Lots of database settings have been introduced in the past, but should be more easily configurable and not rely on a + database connection. +- Running Dataverse in containers gets much easier when configuration can be provisioned in a + streamlined fashion, mitigating the need for scripting glue and distinguishing between setting types. +- Classic installations have a profit, too: we can enable using a single config file, e.g. living in + ``/etc/dataverse/config.properties``. +- Features for monitoring resources and others are easier to use with this streamlined configuration, as we can + avoid people having to deal with ``asadmin`` commands and change a setting comfortably instead. + +Adopting MicroProfile Config API +--------------------------------- + +This technology is introduced on a step-by-step basis. There will not be a big shot, crashing upgrades for everyone. +Instead, we will provide backward compatibility by deprecating renamed or moved config options, while still +supporting the old way of setting them. + +- Introducing a new setting or moving and old one should result in a key ``dataverse..``. + That way we enable sys admins to recognize the meaning of an option and avoid name conflicts. + Starting with ``dataverse`` makes it perfectly clear that this is a setting meant for this application, which is + important when using environment variables, system properties or other MPCONFIG sources. +- Replace ``System.getProperty()`` calls with either injected configs or retrieve programmatically if more complex + handling is necessary. If you rename the property, you should provide an alias. See below. +- Database settings need to be refactored in multiple steps. First you need to change the code retrieving it to use + MicroProfile Config API instead (just like above). Then you should provide an alias to retain backward compatibility. + See below. + +Moving or Replacing a JVM Setting +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When moving an old key to a new (especially when doing so with a former JVM system property setting), you should +add an alias to ``src/main/resources/META-INF/microprofile-aliases.properties`` to enable backward compatibility. +The format is always like ``dataverse..newname...=old.property.name``. + +Details can be found in ``edu.harvard.iq.dataverse.settings.source.AliasConfigSource`` + +Aliasing Database Setting +^^^^^^^^^^^^^^^^^^^^^^^^^ + +When moving a database setting (``:ExampleSetting``), configure an alias +``dataverse.my.example.setting=dataverse.settings.fromdb.ExampleSetting`` in +``src/main/resources/META-INF/microprofile-aliases.properties``. This will enable backward compatibility. + +A database setting with an i18n attribute using *lang* will have available language codes appended to the name. +Example: ``dataverse.settings.fromdb.ExampleI18nSetting.en``, ``dataverse.settings.fromdb.ExampleI18nSetting.de`` + +More details in ``edu.harvard.iq.dataverse.settings.source.DbSettingConfigSource`` diff --git a/doc/sphinx-guides/source/developers/index.rst b/doc/sphinx-guides/source/developers/index.rst index 9c524571a39..184d8aff85a 100755 --- a/doc/sphinx-guides/source/developers/index.rst +++ b/doc/sphinx-guides/source/developers/index.rst @@ -22,6 +22,7 @@ Developer Guide dependencies debugging coding-style + configuration deployment containers making-releases diff --git a/doc/sphinx-guides/source/developers/intro.rst b/doc/sphinx-guides/source/developers/intro.rst index 2ce9c52bd37..e7ed6a12a37 100755 --- a/doc/sphinx-guides/source/developers/intro.rst +++ b/doc/sphinx-guides/source/developers/intro.rst @@ -28,6 +28,8 @@ Dataverse is a `Jakarta EE `_ applicat We make use of a variety of Jakarta EE technologies such as JPA, JAX-RS, JMS, and JSF. The front end is built using PrimeFaces and Bootstrap. +In addition, we start to adopt parts of Eclipse MicroProfile, namely `MicroProfile Config `_. + Roadmap ------- diff --git a/pom.xml b/pom.xml index 6d7378a7ac2..120c2d0ceff 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,8 @@ 4.13.1 5.7.0 ${junit.jupiter.version} - 1.13.0 + 1.15.0 + 0.4.1 2.28.2 5.2.4 1.20.1 @@ -280,6 +281,11 @@ 29.0-jre jar + + org.eclipse.microprofile.config + microprofile-config-api + provided + jakarta.platform jakarta.jakartaee-api @@ -637,6 +643,11 @@ junit-jupiter test + + org.testcontainers + postgresql + test + org.mockito mockito-core @@ -649,7 +660,12 @@ ${mockito.version} test - + + org.microbean + microbean-microprofile-config + ${microbean-mpconfig.version} + test +
- + @@ -814,22 +818,21 @@
- + -
- + @@ -1669,45 +1672,18 @@ } } - function testFilesSelected(popup) { + function testFilesSelected() { var count = PF('filesTable').getSelectedRowsCount(); if (count == 0) { - PF(popup).show(); + PF('selectFiles').show(); } else { return true; } } - - function testFilesSelectedForTags() { - return testFilesSelected("selectFilesForEditTags"); - } - - function testFilesSelectedForRestriction() { - return testFilesSelected("selectFilesForRestrict"); - } - - function testFilesSelectedForUnRestriction() { - return testFilesSelected("selectFilesForUnRestrict"); - } - - function testFilesSelectedForDelete() { - return testFilesSelected("selectFilesForDelete"); - } - - function testFilesSelectedForEditMetadata() { - return testFilesSelected("selectFilesForEditMetadata"); - } function updateTemplate() { $('button[id$="updateTemplate"]').trigger('click'); } - function checkNewlyRestricted() { - if ($('input[id$="showAccessPopup"]').val() === 'true') { - PF('accessPopup').show(); - } else { - $('button[id$="datasetSave"]').trigger('click'); - } - } function updateHiddenReason(textArea) { $('input[id$="hiddenReasonInput"]').val(textArea.value); } diff --git a/src/main/webapp/editFilesFragment.xhtml b/src/main/webapp/editFilesFragment.xhtml index be1f65418b5..833a6c2fd07 100644 --- a/src/main/webapp/editFilesFragment.xhtml +++ b/src/main/webapp/editFilesFragment.xhtml @@ -316,7 +316,6 @@ emptyMessage="#{datasetPage || EditDatafilesPage.showFileUploadFragment() ? bundle['file.noUploadedFiles.tip'] : bundle['file.noSelectedFiles.tip']}">
-
@@ -416,17 +415,25 @@
- -

#{bundle['dataset.noSelectedFilesForDelete']}

-
- -
-
- +

#{bundle['file.deleteFileDialog.tip']}

#{bundle['file.deleteFileDialog.failed.tip']}

@@ -594,6 +592,9 @@
+

+ #{bundle['dataset.access.description']} +

- +
@@ -613,16 +614,20 @@ data-toggle="tooltip" data-placement="auto top" data-original-title="#{bundle['file.dataFilesTab.terms.list.termsOfAccess.requestAccess.title']}">
- +
- - +
@@ -925,7 +930,17 @@
- + + + +

#{bundle['dataset.noSelectedFiles']}

+
+ +
+
diff --git a/src/main/webapp/editdatafiles.xhtml b/src/main/webapp/editdatafiles.xhtml index 81634bcb6d2..3c371c0150c 100644 --- a/src/main/webapp/editdatafiles.xhtml +++ b/src/main/webapp/editdatafiles.xhtml @@ -71,9 +71,11 @@
- +
@@ -81,53 +83,13 @@
-
- - -

#{bundle['dataset.noSelectedFilesForRestrict']}

-
- -
-
- -

#{bundle['dataset.noSelectedFilesForUnRestrict']}

-
- -
-
+ - - diff --git a/src/main/webapp/file-edit-button-fragment.xhtml b/src/main/webapp/file-edit-button-fragment.xhtml index 320283cfe69..6b47cac4057 100644 --- a/src/main/webapp/file-edit-button-fragment.xhtml +++ b/src/main/webapp/file-edit-button-fragment.xhtml @@ -18,7 +18,8 @@ This can be used for a single, specific file (passing "fileMetadata") or a group of selected files. - Parameters: + Parameters: + dataserVersion - the datasetversion object to associate with this view fileMetadata - for single file, the fileMetadata object of that file fileMetadataForAction - used by DatasetPage popups to identify single file (also clears for selected file) isDraftReplacementFile - for single file, if the file is a draft and already replacing a past file @@ -35,7 +36,7 @@
  • - @@ -46,19 +47,21 @@
  • - + update="@([id$=accessPopup])" + oncomplete="PF('accessPopup').show();bind_bsui_components();"> - + + +
  • @@ -90,7 +93,7 @@
  • @@ -113,7 +116,7 @@
  • diff --git a/src/main/webapp/file-edit-popup-fragment.xhtml b/src/main/webapp/file-edit-popup-fragment.xhtml index c14fbd00cd4..7fe8fb4c083 100644 --- a/src/main/webapp/file-edit-popup-fragment.xhtml +++ b/src/main/webapp/file-edit-popup-fragment.xhtml @@ -15,10 +15,10 @@ --> - +

    - #{bundle['file.restrictions.description']} + #{bundle['dataset.access.description']}

    @@ -28,7 +28,7 @@ data-toggle="tooltip" data-placement="auto right" data-original-title="#{bundle['file.dataFilesTab.terms.list.termsOfAccess.termsOfsAccess.title']}">
    - +
    @@ -39,16 +39,18 @@
    + value="#{bean.fileAccessRequest}" widgetVar="inputfar"/>
    - + +
    @@ -72,51 +74,15 @@ - - -

    #{bundle['dataset.noSelectedFilesForRestrict']}

    -
    - -
    -
    - -

    #{bundle['dataset.noSelectedFilesForUnRestrict']}

    -
    - -
    -
    - -

    #{bundle['dataset.noSelectedFilesForDelete']}

    -
    - -
    -
    - -

    #{bundle['dataset.noSelectedFilesForMetadataEdit']}

    -
    - -
    -
    - -

    #{bundle['dataset.noSelectedFilesForMetadataEdit']}

    + + +

    #{bundle['dataset.noSelectedFiles']}

    -
    -
    +
    \ No newline at end of file diff --git a/src/main/webapp/file.xhtml b/src/main/webapp/file.xhtml index 4e3b1dbd8e0..9c19273037c 100644 --- a/src/main/webapp/file.xhtml +++ b/src/main/webapp/file.xhtml @@ -225,6 +225,7 @@