Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
8279e65
feat: add `parse` method and unit tests for `SettingsServiceBean.Key`…
poikilotherm Jul 15, 2025
0a95753
feat: add `listAllWithoutLocalizations` method to filter settings wit…
poikilotherm Jul 15, 2025
54c3f6e
feat: implement `listAllAsJson` for settings retrieval with localizat…
poikilotherm Jul 15, 2025
0ebe683
chore: add JaCoCo args placeholders to pom.xml
poikilotherm Jul 15, 2025
684c7d1
feat: replace tabular ingest size limits configuration using JSON #11639
poikilotherm Jul 15, 2025
b11b722
feat(db): migrate TabularIngestSizeLimit settings to JSON format with…
poikilotherm Jul 15, 2025
92adb8a
docs: improve TabularIngestSizeLimit documentation with JSON examples…
poikilotherm Jul 16, 2025
b17e52a
fix: handle unsupported JSON integers in tabular ingest size limits #…
poikilotherm Jul 16, 2025
4932396
refactor: simplify `listAllAsJson` method and update corresponding te…
poikilotherm Jul 16, 2025
d153cac
feat: add validation for settings names and language codes in Admin S…
poikilotherm Jul 16, 2025
3975db0
feat: support JSON objects in `listAllAsJson` settings output and upd…
poikilotherm Jul 17, 2025
865ed5c
refactor: centralize validation logic for settings names and language…
poikilotherm Jul 17, 2025
8fe9754
feat: add `validateKeys` method to validate settings keys and update …
poikilotherm Jul 17, 2025
515472d
feat: add `SettingsServiceBean.convertJsonToSettings()` method and un…
poikilotherm Jul 17, 2025
a106111
feat: add `putAllSettings` endpoint to Admin API for bulk settings up…
poikilotherm Jul 17, 2025
11c8f82
style: normalize spacing in `Setting` entity named queries #11639
poikilotherm Jul 18, 2025
71a403c
fix: add unique constraint to `Setting` entity for `name` and `lang` …
poikilotherm Jul 18, 2025
a9b1974
refactor: update `Setting` entity and queries to treat empty string a…
poikilotherm Jul 18, 2025
5ae758c
refactor: enforce non-null constraint, VARCHAR type, and limit length…
poikilotherm Jul 18, 2025
974d6c4
chore: update migration script comment for clarity #11639
poikilotherm Jul 18, 2025
c3f1ed7
chore: add migration script to update `Setting` table structure #11639
poikilotherm Jul 18, 2025
782542f
refactor: enhance `Setting` entity equality and constructor for clari…
poikilotherm Jul 18, 2025
aed9f36
refactor: rename `BuiltinUsers.KEY` setting to `:BuiltinUsersKey` for…
poikilotherm Jul 18, 2025
48db4b3
refactor: extract `convertToJsonKey` method in `SettingsServiceBean` …
poikilotherm Jul 18, 2025
a736052
feat: implement atomic bulk settings replacement with detailed operat…
poikilotherm Jul 18, 2025
c68ac57
refactor: change `List` to `Set` for `convertJsonToSettings` #11639
poikilotherm Jul 18, 2025
6f90535
fix: add null checks for `settings` in `setAllFromJson` and `validate…
poikilotherm Jul 18, 2025
1f8a280
feat: return operation details from `setAllFromJson` in `SettingsServ…
poikilotherm Jul 18, 2025
614fc71
fix: prevent accidental removal of all settings in `setAllFromJson` b…
poikilotherm Jul 18, 2025
580039b
fix: ensure transactional integrity in `replaceAllSettings` using sel…
poikilotherm Jul 21, 2025
bd85f72
fix,build: ensure proper late variable binding for JaCoCo configurati…
poikilotherm Jul 21, 2025
c91b4fc
style: correct typo in `internalError` key in `JsonResponseBuilder`
poikilotherm Jul 21, 2025
4b5b689
fix,style: update SQL and class definitions to standardize lowercase …
poikilotherm Jul 22, 2025
c7434a5
fix: update Flyway migration to replace constraints and indexes in `s…
poikilotherm Jul 22, 2025
ff45c80
fix: update `get` method in `Admin` API to handle third parameter for…
poikilotherm Jul 22, 2025
1189068
test: add nested test cases for settings API in `AdminIT` #11639
poikilotherm Jul 22, 2025
982e092
docs: add release note and API docs for #11639
poikilotherm Jul 23, 2025
1b06dfb
feat: add `UNCHANGED` state handling in `SettingsServiceBean` operati…
poikilotherm Jul 23, 2025
d500650
test: add unit tests for `replaceAllSettings` in `SettingsServiceBean…
poikilotherm Jul 23, 2025
4758f86
refactor: introduce `SettingsValidationException` for enhanced error …
poikilotherm Jul 24, 2025
e33b3f7
test: add validation test for invalid settings in `AdminIT` #11639
poikilotherm Jul 24, 2025
08a2861
fix: replace `@Transactional` with `@TransactionAttribute` in `Settin…
poikilotherm Jul 24, 2025
5a099ef
feat(ct): add database settings replacement script to configbaker ima…
poikilotherm Jul 24, 2025
558e8f9
refactor(ct): extract common utility functions in `apply-db-settings.…
poikilotherm Jul 25, 2025
8e220fb
feat(ct): support additional environment variable sources in `apply-d…
poikilotherm Jul 25, 2025
bde0384
feat,refactor(ct): move yq parsing and add envsubst #11639
poikilotherm Jul 25, 2025
2368d7e
fix(migrate): move `UPDATE` statement post constraint drops for NULL …
poikilotherm Aug 1, 2025
21ca0b8
fix(scripts): exclude hidden mounted files in `read-to-env.sh`
poikilotherm Aug 1, 2025
7f83292
chore(scripts): comment out config file print in `apply-db-settings.s…
poikilotherm Aug 1, 2025
37015d6
fix(settings): handle JSON string unescaping in `SettingsServiceBean`…
poikilotherm Aug 1, 2025
292855b
doc suggestions for settings API #11639
pdurbin Aug 1, 2025
b7e541d
doc tweaks #11639
pdurbin Aug 4, 2025
071f695
chore: move migrations to be part of v6.9 instead of v6.8 #11639
poikilotherm Sep 17, 2025
efd7bbf
create test methods for getting and setting all settings (and use the…
pdurbin Aug 5, 2025
95533c6
the "not found" message now ends in a period #11639
pdurbin Aug 7, 2025
30f4603
add to the enum many archive-related settings #11639
pdurbin Aug 7, 2025
4d72fcb
add basic test for :TabularIngestSizeLimit #11639
pdurbin Aug 8, 2025
159b189
more ingest size limit tests #11639
pdurbin Aug 8, 2025
839dd79
improve docs based on ingest size limit testing #11639
pdurbin Aug 8, 2025
2450ecd
add more settings to enum to pass validation #11639
pdurbin Aug 8, 2025
692be46
add TODOs for WorkflowsAdmin#IP_WHITELIST_KEY db setting #11639
pdurbin Aug 8, 2025
a43da29
style(settings): rename `WorkflowsAdmin#IP_WHITELIST_KEY` to `:Workfl…
poikilotherm Sep 15, 2025
2a97dd7
chore(settings): mark `SettingsServiceBean` methods using String for …
poikilotherm Sep 15, 2025
c667b18
doc(settings): clarify database changes require app reload for ORM
poikilotherm Sep 15, 2025
553894a
Merge branch 'develop' into 11639-db-opts-idempotency #11639
pdurbin Sep 26, 2025
525b788
Merge branch 'develop' into 11639-db-opts-idempotency
ofahimIQSS Oct 14, 2025
9930242
Merge branch 'develop' into 11639-db-opts-idempotency
ofahimIQSS Oct 16, 2025
cd5198a
Merge branch 'develop' into 11639-db-opts-idempotency #11639
pdurbin Oct 23, 2025
f994cdc
Merge branch 'develop' into 11639-db-opts-idempotency
ofahimIQSS Oct 24, 2025
ca00bf9
Merge branch 'develop' into 11639-db-opts-idempotency
ofahimIQSS Oct 24, 2025
c4d2f4a
chore(settings): add deprecation notices for String-based methods in …
poikilotherm Oct 30, 2025
3ce5875
style(settings): make `Op` enum public to resolve IDE warnings #11654
poikilotherm Oct 30, 2025
5eea9d5
feat(util): add `getJsonValue` method for robust JSON parsing #11654
poikilotherm Oct 31, 2025
9497acd
fix(settings): improve JSON handling in `SettingsServiceBean` and add…
poikilotherm Oct 31, 2025
b621459
Merge branch 'develop' into 11639-db-opts-idempotency
sekmiller Nov 12, 2025
efe575f
Merge branch 'develop' into 11639-db-opts-idempotency
sekmiller Nov 13, 2025
886a9cf
feat(db): add `SettingsCleanupCallback` to remove invalid settings af…
poikilotherm Nov 14, 2025
757f2e5
Merge branch 'develop' into 11639-db-opts-idempotency
sekmiller Nov 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions doc/release-notes/11639-db-opts-idempotency.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
## Database Settings Cleanup

With this release, we remove some legacy specialties around Database Settings and provide better Admin API endpoints for them.

Most important changes:

1. Setting `BuiltinUsers.KEY` was renamed to `:BuiltinUsersKey`, aligned with our general naming pattern for options.
2. Setting `WorkflowsAdmin#IP_WHITELIST_KEY` was renamed to `:WorkflowsAdminIpWhitelist`, aligned with our general naming pattern for options.
3. Setting `:TabularIngestSizeLimit` no longer uses suffixes for formats and becomes a JSON-based setting instead.
4. If set, all three settings will be migrated to their new form automatically for you (Flyway migration).
5. You can no longer (accidentally) create or use arbitrary setting names or languages.
All Admin API endpoints for settings now validate setting names and languages for existence and compliance.

As an administrator of a Dataverse instance, you can now make use of enhanced Bulk Operations on the Settings Admin API:

1. Retrieving all settings as JSON via `GET /api/admin/settings` supports localized options now, too.
2. You can replace all existing settings in an idempotent way sending JSON to `PUT /api/admin/settings`.
This will create, update and remove settings as necessary in one atomic operation.
The new endpoint is especially useful to admins using GitOps or other automations.
It allows control over all Database Settings from a single source without risking an undefined state.

Note: Despite the validation of setting names and languages, the content of any database setting is still not being validated when using the Settings Admin API!

### Updated Database Settings

The following database settings are were added to the official list within the code (to remain valid with the settings cleanup mentioned above):

- `:BagGeneratorThreads`
- `:BagItHandlerEnabled`
- `:BagItLocalPath`
- `:BagValidatorJobPoolSize`
- `:BagValidatorJobWaitInterval`
- `:BagValidatorMaxErrors`
- `:BuiltinUsersKey` - formerly `BuiltinUsers.KEY`
- `:CreateDataFilesMaxErrorsToDisplay`
- `:DRSArchiverConfig` - a Harvard-specific setting
- `:DuraCloudContext`
- `:DuraCloudHost`
- `:DuraCloudPort`
- `:FileCategories`
- `:GoogleCloudBucket`
- `:GoogleCloudProject`
- `:LDNAnnounceRequiredFields`
- `:LDNTarget`
- `:WorkflowsAdminIpWhitelist` - formerly `WorkflowsAdmin#IP_WHITELIST_KEY`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@poikilotherm do we need to note the changes to TabularIngestSizeLimit here?

3 changes: 3 additions & 0 deletions doc/sphinx-guides/source/api/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ This API changelog is experimental and we would love feedback on its usefulness.

v6.9
----

- The POST /api/admin/makeDataCount/{id}/updateCitationsForDataset processing is now asynchronous and the response no longer includes the number of citations. The response can be OK if the request is queued or 503 if the queue is full (default queue size is 1000).
- The way to set per-format size limits for tabular ingest has changed. JSON input is now used. See :ref:`:TabularIngestSizeLimit`.
- In the past, the settings API would accept any key and value. This is no longer the case because validation has been added. See :ref:`settings_put_single`, for example.

v6.8
----
Expand Down
192 changes: 175 additions & 17 deletions doc/sphinx-guides/source/api/native-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5843,13 +5843,13 @@ Builtin users are known as "Username/Email and Password" users in the :doc:`/use
Create a Builtin User
~~~~~~~~~~~~~~~~~~~~~

For security reasons, builtin users cannot be created via API unless the team who runs the Dataverse installation has populated a database setting called ``BuiltinUsers.KEY``, which is described under :ref:`securing-your-installation` and :ref:`database-settings` sections of Configuration in the Installation Guide. You will need to know the value of ``BuiltinUsers.KEY`` before you can proceed.
For security reasons, builtin users cannot be created via API unless the team who runs the Dataverse installation has populated a database setting called ``:BuiltinUsersKey``, which is described under :ref:`securing-your-installation` and :ref:`database-settings` sections of Configuration in the Installation Guide. You will need to know the value of ``:BuiltinUsersKey`` before you can proceed.

To create a builtin user via API, you must first construct a JSON document. You can download :download:`user-add.json <../_static/api/user-add.json>` or copy the text below as a starting point and edit as necessary.

.. literalinclude:: ../_static/api/user-add.json

Place this ``user-add.json`` file in your current directory and run the following curl command, substituting variables as necessary. Note that both the password of the new user and the value of ``BuiltinUsers.KEY`` are passed as query parameters::
Place this ``user-add.json`` file in your current directory and run the following curl command, substituting variables as necessary. Note that both the password of the new user and the value of ``:BuiltinUsersKey`` are passed as query parameters::

curl -d @user-add.json -H "Content-type:application/json" "$SERVER_URL/api/builtin-users?password=$NEWUSER_PASSWORD&key=$BUILTIN_USERS_KEY"

Expand Down Expand Up @@ -7133,35 +7133,193 @@ If the PID is not managed by Dataverse, this call will report if the PID is reco
Admin
-----

This is the administrative part of the API. For security reasons, it is absolutely essential that you block it before allowing public access to a Dataverse installation. Blocking can be done using settings. See the ``post-install-api-block.sh`` script in the ``scripts/api`` folder for details. See :ref:`blocking-api-endpoints` in Securing Your Installation section of the Configuration page of the Installation Guide.
This is the administrative part of the API.
For security reasons, it is absolutely essential that you block it before allowing public access to a Dataverse installation.
See :ref:`blocking-api-endpoints` in the Installation Guide for details.

.. note:: See :ref:`curl-examples-and-environment-variables` if you are unfamiliar with the use of export below.

.. _admin-api-db-settings:

Manage Database Settings
~~~~~~~~~~~~~~~~~~~~~~~~

These are the API endpoints for managing the :ref:`database-settings` listed in the Installation Guide.

.. _settings_get_all:

List All Database Settings
~~~~~~~~~~~~~~~~~~~~~~~~~~
^^^^^^^^^^^^^^^^^^^^^^^^^^

.. code-block:: bash

List all settings::
export SERVER_URL="http://localhost:8080"

curl "$SERVER_URL/api/admin/settings"

GET http://$SERVER/api/admin/settings
The fully expanded example above (without environment variables) looks like this:

Configure Database Setting
~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: bash

Sets setting ``name`` to the body of the request::
curl http://localhost:8080/api/admin/settings

PUT http://$SERVER/api/admin/settings/$name
.. _settings_get_single:

Get Single Database Setting
~~~~~~~~~~~~~~~~~~~~~~~~~~~
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Get the setting under ``name``::
.. code-block:: bash

GET http://$SERVER/api/admin/settings/$name
export SERVER_URL="http://localhost:8080"
export NAME=":UploadMethods"

curl "$SERVER_URL/api/admin/settings/$NAME"

Delete Database Setting
~~~~~~~~~~~~~~~~~~~~~~~
The fully expanded example above (without environment variables) looks like this:

.. code-block:: bash

curl http://localhost:8080/api/admin/settings/:UploadMethods

.. _settings_get_single_lang:

Get Single Database Setting With Language/Locale
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

A small number of settings, most notably :ref:`:ApplicationTermsOfUse`, can be saved in multiple languages.

Use two-character ISO 639-1 language codes.

.. code-block:: bash

export SERVER_URL="http://localhost:8080"
export NAME=":ApplicationTermsOfUse"
export LANG="en"

curl "$SERVER_URL/api/admin/settings/$NAME/lang/$LANG"

The fully expanded example above (without environment variables) looks like this:

.. code-block:: bash

curl http://localhost:8080/api/admin/settings/:ApplicationTermsOfUse/lang/en

.. _settings_put_single:

Configure Single Database Setting
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. code-block:: bash

export SERVER_URL="http://localhost:8080"
export NAME=":InstallationName"
export VALUE="LibreScholar"

curl -X PUT "$SERVER_URL/api/admin/settings/$NAME" -d "$VALUE"

The fully expanded example above (without environment variables) looks like this:

.. code-block:: bash

curl -X PUT http://localhost:8080/api/admin/settings/:InstallationName -d LibreScholar

Note: ``NAME`` values are validated for existence and compliance.

.. _settings_put_single_lang:

Configure Single Database Setting With Language/Locale
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

A small number of settings, most notably :ref:`:ApplicationTermsOfUse`, can be saved in multiple languages.

Use two-character ISO 639-1 language codes.

Delete the setting under ``name``::
.. code-block:: bash

export SERVER_URL="http://localhost:8080"
export NAME=":ApplicationTermsOfUse"
export LANG="fr"

curl -X PUT "$SERVER_URL/api/admin/settings/$NAME/lang/$LANG" --upload-file /tmp/apptou_fr.html

The fully expanded example above (without environment variables) looks like this:

.. code-block:: bash

curl -X PUT http://localhost:8080/api/admin/settings/:ApplicationTermsOfUse/lang/fr --upload-file /tmp/apptou_fr.html

Note: ``NAME`` and ``LANG`` values are validated for existence and compliance.

.. _settings_put_bulk:

Configure All Database Settings
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Using a JSON file, replace all settings in a single idempotent and atomic operation and delete any settings not present in that JSON file.

Use the JSON ``data`` object in output of ``GET /api/admin/settings`` (:ref:`settings_get_all`) for the JSON input structure for this endpoint.
To put this concretely, you can save just the ``data`` object for your existing settings to disk by filtering them through ``jq`` like this:

.. code-block:: bash

curl http://localhost:8080/api/admin/settings | jq '.data' > /tmp/all-settings.json

Then you can use this "all-settings.json" file as a starting point for your input file.
The :doc:`../installation/config` page of the Installation Guide has a :ref:`complete list of all the available settings <database-settings>`.
Note that settings in the JSON file are validated for existence and compliance.

.. code-block:: bash

export SERVER_URL="http://localhost:8080"

curl -X PUT -H "Content-type:application/json" "$SERVER_URL/api/admin/settings" --upload-file /tmp/all-settings.json

The fully expanded example above (without environment variables) looks like this:

.. code-block:: bash

curl -X PUT -H "Content-type:application/json" http://localhost:8080/api/admin/settings --upload-file /tmp/all-settings.json

.. _settings_delete_single:

Delete Single Database Setting
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. code-block:: bash

export SERVER_URL="http://localhost:8080"
export NAME=":InstallationName"

curl -X DELETE "$SERVER_URL/api/admin/settings/$NAME"

The fully expanded example above (without environment variables) looks like this:

.. code-block:: bash

curl -X DELETE http://localhost:8080/api/admin/settings/:InstallationName

.. _settings_delete_single_lang:

Delete Single Database Setting With Language/Locale
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

A small number of settings, most notably :ref:`:ApplicationTermsOfUse`, can be saved in multiple languages.

Use two-character ISO 639-1 language codes.

.. code-block:: bash

export SERVER_URL="http://localhost:8080"
export NAME=":ApplicationTermsOfUse"
export LANG="fr"

curl -X DELETE "$SERVER_URL/api/admin/settings/$NAME/lang/$LANG"

The fully expanded example above (without environment variables) looks like this:

.. code-block:: bash

DELETE http://$SERVER/api/admin/settings/$name
curl -X DELETE http://localhost:8080/api/admin/settings/:ApplicationTermsOfUse/lang/fr

.. _list-all-feature-flags:

Expand Down
2 changes: 1 addition & 1 deletion doc/sphinx-guides/source/developers/testing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ The Burrito Key

For reasons that have been lost to the mists of time, the Dataverse software really wants you to to have a burrito. Specifically, if you're trying to run REST Assured tests and see the error "Dataverse config issue: No API key defined for built in user management", you must run the following curl command (or make an equivalent change to your database):

``curl -X PUT -d 'burrito' http://localhost:8080/api/admin/settings/BuiltinUsers.KEY``
``curl -X PUT -d 'burrito' http://localhost:8080/api/admin/settings/:BuiltinUsersKey``

Without this "burrito" key in place, REST Assured will not be able to create users. We create users to create objects we want to test, such as collections, datasets, and files.

Expand Down
Loading
Loading