From 99a2a4e3ed894d20c1a6136d7ee8abae475983db Mon Sep 17 00:00:00 2001 From: Pierre Lasou Date: Thu, 4 Jul 2024 13:24:38 -0400 Subject: [PATCH 001/226] Update Docker-compose README.md Change to Docker command syntax V2: docker-compose changed to docker compose (cherry picked from commit d87911db0d9419b3b5607bad2bb7393dd7593cd4) --- dspace/src/main/docker-compose/README.md | 52 ++++++++++++------------ 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/dspace/src/main/docker-compose/README.md b/dspace/src/main/docker-compose/README.md index 19d22750420b..2f4c444714b5 100644 --- a/dspace/src/main/docker-compose/README.md +++ b/dspace/src/main/docker-compose/README.md @@ -54,29 +54,29 @@ Documentation for all Dockerfiles used by these compose scripts can be found in ## To refresh / pull DSpace images from Dockerhub ``` -docker-compose -f docker-compose.yml -f docker-compose-cli.yml pull +docker compose -f docker-compose.yml -f docker-compose-cli.yml pull ``` ## To build DSpace images using code in your branch ``` -docker-compose -f docker-compose.yml -f docker-compose-cli.yml build +docker compose -f docker-compose.yml -f docker-compose-cli.yml build ``` OPTIONALLY, you can build DSpace images using a different JDK_VERSION like this: ``` -docker-compose -f docker-compose.yml -f docker-compose-cli.yml build --build-arg JDK_VERSION=17 +docker compose -f docker-compose.yml -f docker-compose-cli.yml build --build-arg JDK_VERSION=17 ``` Default is Java 11, but other LTS releases (e.g. 17) are also supported. ## Run DSpace 8 REST from your current branch ``` -docker-compose -p d8 up -d +docker compose -p d8 up -d ``` ## Run DSpace 8 REST and Angular from your branch ``` -docker-compose -p d8 -f docker-compose.yml -f dspace/src/main/docker-compose/docker-compose-angular.yml up -d +docker compose -p d8 -f docker-compose.yml -f dspace/src/main/docker-compose/docker-compose-angular.yml up -d ``` NOTE: This starts the UI in development mode. It will take a few minutes to see the UI as the Angular code needs to be compiled. @@ -94,7 +94,7 @@ That container provides a [Cantaloupe image server](https://cantaloupe-project.g which can be used when IIIF support is enabled in DSpace (`iiif.enabled=true`). ``` -docker-compose -p d8 -f docker-compose.yml -f dspace/src/main/docker-compose/docker-compose-iiif.yml up -d +docker compose -p d8 -f docker-compose.yml -f dspace/src/main/docker-compose/docker-compose-iiif.yml up -d ``` ## Run DSpace 8 REST and Shibboleth SP (in Apache) from your branch @@ -132,17 +132,17 @@ The remainder of these instructions assume you are using ngrok (though other pro 3. Build the Shibboleth container (if you haven't built or pulled it before): ``` cd [dspace-src] - docker-compose -p d8 -f docker-compose.yml -f dspace/src/main/docker-compose/docker-compose-shibboleth.yml build + docker compose -p d8 -f docker-compose.yml -f dspace/src/main/docker-compose/docker-compose-shibboleth.yml build ``` 4. Start all containers, passing your public hostname as the `DSPACE_HOSTNAME` environment variable: ``` - DSPACE_HOSTNAME=[subdomain].ngrok.io docker-compose -p d8 -f docker-compose.yml -f dspace/src/main/docker-compose/docker-compose-shibboleth.yml up -d + DSPACE_HOSTNAME=[subdomain].ngrok.io docker compose -p d8 -f docker-compose.yml -f dspace/src/main/docker-compose/docker-compose-shibboleth.yml up -d ``` NOTE: For Windows you MUST either set the environment variable separately, or use the 'env' command provided with Git/Cygwin (you may already have this command if you are running Git for Windows). See https://superuser.com/a/1079563 ``` - env DSPACE_HOSTNAME=[subdomain].ngrok.io docker-compose -p d8 -f docker-compose.yml -f dspace/src/main/docker-compose/docker-compose-shibboleth.yml up -d + env DSPACE_HOSTNAME=[subdomain].ngrok.io docker compose -p d8 -f docker-compose.yml -f dspace/src/main/docker-compose/docker-compose-shibboleth.yml up -d ``` 5. Finally, for https://samltest.id/, you need to upload your Shibboleth Metadata for the site to "trust" you. @@ -170,7 +170,7 @@ The remainder of these instructions assume you are using ngrok (though other pro ``` * Spin up the `dspace-angular` container alongside the others, e.g. ``` - DSPACE_HOSTNAME=[subdomain].ngrok.io docker-compose -p d8 -f docker-compose.yml -f dspace/src/main/docker-compose/docker-compose-angular.yml -f dspace/src/main/docker-compose/docker-compose-shibboleth.yml up -d + DSPACE_HOSTNAME=[subdomain].ngrok.io docker compose -p d8 -f docker-compose.yml -f dspace/src/main/docker-compose/docker-compose-angular.yml -f dspace/src/main/docker-compose/docker-compose-shibboleth.yml up -d ``` ## Sample Test Data @@ -185,12 +185,12 @@ Prerequisites Create an admin account. By default, the dspace-cli container runs the dspace command. ``` -docker-compose -p d8 -f docker-compose-cli.yml run --rm dspace-cli create-administrator -e test@test.edu -f admin -l user -p admin -c en +docker compose -p d8 -f docker-compose-cli.yml run --rm dspace-cli create-administrator -e test@test.edu -f admin -l user -p admin -c en ``` Download a Zip file of AIP content and ingest test data ``` -docker-compose -p d8 -f docker-compose-cli.yml -f dspace/src/main/docker-compose/cli.ingest.yml run --rm dspace-cli +docker compose -p d8 -f docker-compose-cli.yml -f dspace/src/main/docker-compose/cli.ingest.yml run --rm dspace-cli ``` ### Ingest Entities Test Data @@ -204,12 +204,12 @@ Prerequisites Start DSpace REST with a postgres database dump downloaded from the internet. ``` -docker-compose -p d8 -f docker-compose.yml -f dspace/src/main/docker-compose/db.entities.yml up -d +docker compose -p d8 -f docker-compose.yml -f dspace/src/main/docker-compose/db.entities.yml up -d ``` Download an assetstore from a tar file on the internet. ``` -docker-compose -p d8 -f docker-compose-cli.yml -f dspace/src/main/docker-compose/cli.assetstore.yml run dspace-cli +docker compose -p d8 -f docker-compose-cli.yml -f dspace/src/main/docker-compose/cli.assetstore.yml run dspace-cli ``` ## Modify DSpace Configuration in Docker @@ -217,26 +217,26 @@ While your Docker containers are running, you may directly modify any configurat `[dspace-src]/dspace/config/`. Those config changes will be synced to the container. (This works because our `docker-compose.yml` mounts the `[src]/dspace/config` directory from the host into the running Docker instance.) -Many DSpace configuration settings will reload automatically (after a few seconds). However, configurations which are cached by DSpace (or by Spring Boot) may require you to quickly reboot the Docker containers by running `docker-compose -p d7 down` followed by `docker-compose -p d7 up -d`. +Many DSpace configuration settings will reload automatically (after a few seconds). However, configurations which are cached by DSpace (or by Spring Boot) may require you to quickly reboot the Docker containers by running `docker compose -p d7 down` followed by `docker compose -p d7 up -d`. ## Running DSpace CLI scripts in Docker While the Docker containers are running, you can use the DSpace CLI image to run any DSpace commandline script (i.e. any command that normally can be run by `[dspace]/bin/dspace`). The general format is: ``` -docker-compose -p d8 -f docker-compose-cli.yml run --rm dspace-cli [command] [parameters] +docker compose -p d8 -f docker-compose-cli.yml run --rm dspace-cli [command] [parameters] ``` So, for example, to reindex all content in Discovery, normally you'd run `./dspace index-discovery -b` from commandline. Using our DSpace CLI image, that command becomes: ``` -docker-compose -p d8 -f docker-compose-cli.yml run --rm dspace-cli index-discovery -b +docker compose -p d8 -f docker-compose-cli.yml run --rm dspace-cli index-discovery -b ``` Similarly, you can see the value of any DSpace configuration (in local.cfg or dspace.cfg) by running: ``` # Output the value of `dspace.ui.url` from running Docker instance -docker-compose -p d8 -f docker-compose-cli.yml run --rm dspace-cli dsprop -p dspace.ui.url +docker compose -p d8 -f docker-compose-cli.yml run --rm dspace-cli dsprop -p dspace.ui.url ``` NOTE: It is also possible to run CLI scripts directly on the "dspace" container (where the backend runs) @@ -245,7 +245,7 @@ This can be useful if you want to pass environment variables which override DSpa # Run the "./dspace database clean" command from the "dspace" container # Before doing so, it sets "db.cleanDisabled=false". # WARNING: This will delete all your data. It's just an example of how to do so. -docker-compose -p d8 exec -e "db__P__cleanDisabled=false" dspace /dspace/bin/dspace database clean +docker compose -p d8 exec -e "db__P__cleanDisabled=false" dspace /dspace/bin/dspace database clean ``` ## Upgrading PostgreSQL in Docker @@ -263,7 +263,7 @@ Here's how to fix those issues by migrating your old Postgres data to the new ve 1. First, you must start up the older PostgreSQL image (to dump your existing data to a `*.sql` file) ``` # This command assumes you are using the process described above to start all your containers - docker-compose -p d8 up -d + docker compose -p d8 up -d ``` * If you've already accidentally updated to the new PostgreSQL image, you have a few options: * Pull down an older version of the image from Dockerhub (using a tag) @@ -272,7 +272,7 @@ Here's how to fix those issues by migrating your old Postgres data to the new ve # This command will rebuild using PostgreSQL v11 & tag it locally as "latest" docker build --build-arg POSTGRES_VERSION=11 -t dspace/dspace-postgres-pgcrypto:latest ./dspace/src/main/docker/dspace-postgres-pgcrypto/ # Then restart container with that image - docker-compose -p d8 up -d + docker compose -p d8 up -d ``` 2. Dump your entire "dspace" database out of the old "dspacedb" container to a local file named `pgdump.sql` ``` @@ -295,7 +295,7 @@ Here's how to fix those issues by migrating your old Postgres data to the new ve 3. Now, stop all existing containers. This shuts down the old version of PostgreSQL ``` # This command assumes you are using the process described above to start/stop all your containers - docker-compose -p d8 down + docker compose -p d8 down ``` 4. Delete the `pgdata` volume. WARNING: This deletes all your old PostgreSQL data. Make sure you have that `pgdump.sql` file FIRST! ``` @@ -304,19 +304,19 @@ Here's how to fix those issues by migrating your old Postgres data to the new ve ``` 5. Now, pull down the latest PostgreSQL image with the NEW version of PostgreSQL. ``` - docker-compose -f docker-compose.yml -f docker-compose-cli.yml pull + docker compose -f docker-compose.yml -f docker-compose-cli.yml pull ``` 6. Start everything up using our `db.restore.yml` script. This script will recreate the database using the local `./pgdump.sql` file. IMPORTANT: If you renamed that "pgdump.sql" file or stored it elsewhere, then you MUST change the name/directory in the `db.restore.yml` script. ``` # Restore database from "./pgdump.sql" (this path is hardcoded in db.restore.yml) - docker-compose -p d8 -f docker-compose.yml -f dspace/src/main/docker-compose/db.restore.yml up -d + docker compose -p d8 -f docker-compose.yml -f dspace/src/main/docker-compose/db.restore.yml up -d ``` 7. Finally, reindex all database contents into Solr (just to be sure Solr indexes are current). ``` # Run "./dspace index-discovery -b" using our CLI image - docker-compose -p d8 -f docker-compose-cli.yml run --rm dspace-cli index-discovery -b + docker compose -p d8 -f docker-compose-cli.yml run --rm dspace-cli index-discovery -b ``` At this point in time, all your old database data should be migrated to the new Postgres -and running at http://localhost:8080/server/ \ No newline at end of file +and running at http://localhost:8080/server/ From c0b2323f7e5446b8cad6fcd191aab372767b5194 Mon Sep 17 00:00:00 2001 From: Pierre Lasou Date: Thu, 4 Jul 2024 13:29:53 -0400 Subject: [PATCH 002/226] Update Docker README.md Change docker-compose command by docker compose (cherry picked from commit 567f86aff23df43c86b2a3f73eae2baa24f7017e) --- dspace/src/main/docker/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dspace/src/main/docker/README.md b/dspace/src/main/docker/README.md index 5dd4e0ca2ea2..c737afd336af 100644 --- a/dspace/src/main/docker/README.md +++ b/dspace/src/main/docker/README.md @@ -145,15 +145,15 @@ can be pulled / built following the [docker compose resources](../docker-compose documentation. Or, to just build and/or run Solr: ```bash -docker-compose build dspacesolr -docker-compose -p d8 up -d dspacesolr +docker compose build dspacesolr +docker compose -p d8 up -d dspacesolr ``` If you're making iterative changes to the DSpace Solr configsets you'll need to rebuild / restart the `dspacesolr` container for the changes to be deployed. From DSpace root: ```bash -docker-compose -p d8 up --detach --build dspacesolr +docker compose -p d8 up --detach --build dspacesolr ``` ## ./test/ folder From a0fc515da7c73017cbc5113ac3cd0dee5a7e18ab Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 3 Jul 2024 14:17:05 -0500 Subject: [PATCH 003/226] Update redeployment of demo.dspace.org to use dspace-8_x branch. --- .github/workflows/reusable-docker-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reusable-docker-build.yml b/.github/workflows/reusable-docker-build.yml index 019dab51eddb..7a8de661fa68 100644 --- a/.github/workflows/reusable-docker-build.yml +++ b/.github/workflows/reusable-docker-build.yml @@ -69,7 +69,7 @@ env: REDEPLOY_SANDBOX_URL: ${{ secrets.REDEPLOY_SANDBOX_URL }} REDEPLOY_DEMO_URL: ${{ secrets.REDEPLOY_DEMO_URL }} # Current DSpace branches (and architecture) which are deployed to demo.dspace.org & sandbox.dspace.org respectively - DEPLOY_DEMO_BRANCH: 'dspace-7_x' + DEPLOY_DEMO_BRANCH: 'dspace-8_x' DEPLOY_SANDBOX_BRANCH: 'main' DEPLOY_ARCH: 'linux/amd64' From 7720a6ffbdf27862b1aeb58c9e25e4e69d331c9d Mon Sep 17 00:00:00 2001 From: nwoodward Date: Mon, 8 Jul 2024 12:26:42 -0500 Subject: [PATCH 004/226] updated creative commons licenses version from 3.0 to 4.0 (cherry picked from commit c3fec3fade575e17e36022de8360523ab8aec02e) --- .../impl/CCLicenseAddPatchOperation.java | 2 +- .../org/dspace/app/rest/ror-record.json | 4 +- .../org/dspace/app/rest/ror-records.json | 80 +++++++++---------- 3 files changed, 43 insertions(+), 43 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/CCLicenseAddPatchOperation.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/CCLicenseAddPatchOperation.java index 0aab935298ae..dace7c99ed94 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/CCLicenseAddPatchOperation.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/CCLicenseAddPatchOperation.java @@ -25,7 +25,7 @@ * Example: * curl -X PATCH http://${dspace.server.url}/api/submission/workspaceitems/31599 -H "Content-Type: * application/json" -d '[{ "op": "add", "path": "/sections/cclicense/uri", - * "value":"https://creativecommons.org/licenses/by-nc-sa/3.0/us/"}]' + * "value":"https://creativecommons.org/licenses/by-nc-sa/4.0/us/"}]' * */ public class CCLicenseAddPatchOperation extends AddPatchOperation { diff --git a/dspace-server-webapp/src/test/resources/org/dspace/app/rest/ror-record.json b/dspace-server-webapp/src/test/resources/org/dspace/app/rest/ror-record.json index 2ed43a01535a..4d0cd97fd5b6 100644 --- a/dspace-server-webapp/src/test/resources/org/dspace/app/rest/ror-record.json +++ b/dspace-server-webapp/src/test/resources/org/dspace/app/rest/ror-record.json @@ -39,8 +39,8 @@ "code": "US.TX.423" }, "license": { - "attribution": "Data from geonames.org under a CC-BY 3.0 license", - "license": "https://creativecommons.org/licenses/by/3.0/" + "attribution": "Data from geonames.org under a CC-BY 4.0 license", + "license": "https://creativecommons.org/licenses/by/4.0/" }, "nuts_level1": { "name": null, diff --git a/dspace-server-webapp/src/test/resources/org/dspace/app/rest/ror-records.json b/dspace-server-webapp/src/test/resources/org/dspace/app/rest/ror-records.json index d36f7ba74e5c..5f93bb7d07a0 100644 --- a/dspace-server-webapp/src/test/resources/org/dspace/app/rest/ror-records.json +++ b/dspace-server-webapp/src/test/resources/org/dspace/app/rest/ror-records.json @@ -53,8 +53,8 @@ "code": "US.TX.029" }, "license": { - "attribution": "Data from geonames.org under a CC-BY 3.0 license", - "license": "https://creativecommons.org/licenses/by/3.0/" + "attribution": "Data from geonames.org under a CC-BY 4.0 license", + "license": "https://creativecommons.org/licenses/by/4.0/" }, "nuts_level1": { "name": null, @@ -166,8 +166,8 @@ "code": "US.TX.423" }, "license": { - "attribution": "Data from geonames.org under a CC-BY 3.0 license", - "license": "https://creativecommons.org/licenses/by/3.0/" + "attribution": "Data from geonames.org under a CC-BY 4.0 license", + "license": "https://creativecommons.org/licenses/by/4.0/" }, "nuts_level1": { "name": null, @@ -298,8 +298,8 @@ "code": "US.TX.113" }, "license": { - "attribution": "Data from geonames.org under a CC-BY 3.0 license", - "license": "https://creativecommons.org/licenses/by/3.0/" + "attribution": "Data from geonames.org under a CC-BY 4.0 license", + "license": "https://creativecommons.org/licenses/by/4.0/" }, "nuts_level1": { "name": null, @@ -417,8 +417,8 @@ "code": "US.TX.439" }, "license": { - "attribution": "Data from geonames.org under a CC-BY 3.0 license", - "license": "https://creativecommons.org/licenses/by/3.0/" + "attribution": "Data from geonames.org under a CC-BY 4.0 license", + "license": "https://creativecommons.org/licenses/by/4.0/" }, "nuts_level1": { "name": null, @@ -532,8 +532,8 @@ "code": "US.TX.135" }, "license": { - "attribution": "Data from geonames.org under a CC-BY 3.0 license", - "license": "https://creativecommons.org/licenses/by/3.0/" + "attribution": "Data from geonames.org under a CC-BY 4.0 license", + "license": "https://creativecommons.org/licenses/by/4.0/" }, "nuts_level1": { "name": null, @@ -638,8 +638,8 @@ "code": "JP.39.1850156" }, "license": { - "attribution": "Data from geonames.org under a CC-BY 3.0 license", - "license": "https://creativecommons.org/licenses/by/3.0/" + "attribution": "Data from geonames.org under a CC-BY 4.0 license", + "license": "https://creativecommons.org/licenses/by/4.0/" }, "nuts_level1": { "name": null, @@ -750,8 +750,8 @@ "code": null }, "license": { - "attribution": "Data from geonames.org under a CC-BY 3.0 license", - "license": "https://creativecommons.org/licenses/by/3.0/" + "attribution": "Data from geonames.org under a CC-BY 4.0 license", + "license": "https://creativecommons.org/licenses/by/4.0/" }, "nuts_level1": { "name": null, @@ -855,8 +855,8 @@ "code": "US.OK.143" }, "license": { - "attribution": "Data from geonames.org under a CC-BY 3.0 license", - "license": "https://creativecommons.org/licenses/by/3.0/" + "attribution": "Data from geonames.org under a CC-BY 4.0 license", + "license": "https://creativecommons.org/licenses/by/4.0/" }, "nuts_level1": { "name": null, @@ -986,8 +986,8 @@ "code": "AU.07.24600" }, "license": { - "attribution": "Data from geonames.org under a CC-BY 3.0 license", - "license": "https://creativecommons.org/licenses/by/3.0/" + "attribution": "Data from geonames.org under a CC-BY 4.0 license", + "license": "https://creativecommons.org/licenses/by/4.0/" }, "nuts_level1": { "name": null, @@ -1086,8 +1086,8 @@ "code": null }, "license": { - "attribution": "Data from geonames.org under a CC-BY 3.0 license", - "license": "https://creativecommons.org/licenses/by/3.0/" + "attribution": "Data from geonames.org under a CC-BY 4.0 license", + "license": "https://creativecommons.org/licenses/by/4.0/" }, "nuts_level1": { "name": null, @@ -1198,8 +1198,8 @@ "code": "US.AL.119" }, "license": { - "attribution": "Data from geonames.org under a CC-BY 3.0 license", - "license": "https://creativecommons.org/licenses/by/3.0/" + "attribution": "Data from geonames.org under a CC-BY 4.0 license", + "license": "https://creativecommons.org/licenses/by/4.0/" }, "nuts_level1": { "name": null, @@ -1304,8 +1304,8 @@ "code": "US.FL.033" }, "license": { - "attribution": "Data from geonames.org under a CC-BY 3.0 license", - "license": "https://creativecommons.org/licenses/by/3.0/" + "attribution": "Data from geonames.org under a CC-BY 4.0 license", + "license": "https://creativecommons.org/licenses/by/4.0/" }, "nuts_level1": { "name": null, @@ -1416,8 +1416,8 @@ "code": "US.GA.045" }, "license": { - "attribution": "Data from geonames.org under a CC-BY 3.0 license", - "license": "https://creativecommons.org/licenses/by/3.0/" + "attribution": "Data from geonames.org under a CC-BY 4.0 license", + "license": "https://creativecommons.org/licenses/by/4.0/" }, "nuts_level1": { "name": null, @@ -1524,8 +1524,8 @@ "code": "US.OR.051" }, "license": { - "attribution": "Data from geonames.org under a CC-BY 3.0 license", - "license": "https://creativecommons.org/licenses/by/3.0/" + "attribution": "Data from geonames.org under a CC-BY 4.0 license", + "license": "https://creativecommons.org/licenses/by/4.0/" }, "nuts_level1": { "name": null, @@ -1626,8 +1626,8 @@ "code": "GB.ENG.F2" }, "license": { - "attribution": "Data from geonames.org under a CC-BY 3.0 license", - "license": "https://creativecommons.org/licenses/by/3.0/" + "attribution": "Data from geonames.org under a CC-BY 4.0 license", + "license": "https://creativecommons.org/licenses/by/4.0/" }, "nuts_level1": { "name": "SOUTH EAST (ENGLAND)", @@ -1752,8 +1752,8 @@ "code": null }, "license": { - "attribution": "Data from geonames.org under a CC-BY 3.0 license", - "license": "https://creativecommons.org/licenses/by/3.0/" + "attribution": "Data from geonames.org under a CC-BY 4.0 license", + "license": "https://creativecommons.org/licenses/by/4.0/" }, "nuts_level1": { "name": null, @@ -1869,8 +1869,8 @@ "code": null }, "license": { - "attribution": "Data from geonames.org under a CC-BY 3.0 license", - "license": "https://creativecommons.org/licenses/by/3.0/" + "attribution": "Data from geonames.org under a CC-BY 4.0 license", + "license": "https://creativecommons.org/licenses/by/4.0/" }, "nuts_level1": { "name": null, @@ -1984,8 +1984,8 @@ "code": "US.WI.035" }, "license": { - "attribution": "Data from geonames.org under a CC-BY 3.0 license", - "license": "https://creativecommons.org/licenses/by/3.0/" + "attribution": "Data from geonames.org under a CC-BY 4.0 license", + "license": "https://creativecommons.org/licenses/by/4.0/" }, "nuts_level1": { "name": null, @@ -2099,8 +2099,8 @@ "code": "US.WI.009" }, "license": { - "attribution": "Data from geonames.org under a CC-BY 3.0 license", - "license": "https://creativecommons.org/licenses/by/3.0/" + "attribution": "Data from geonames.org under a CC-BY 4.0 license", + "license": "https://creativecommons.org/licenses/by/4.0/" }, "nuts_level1": { "name": null, @@ -2208,8 +2208,8 @@ "code": "US.WI.063" }, "license": { - "attribution": "Data from geonames.org under a CC-BY 3.0 license", - "license": "https://creativecommons.org/licenses/by/3.0/" + "attribution": "Data from geonames.org under a CC-BY 4.0 license", + "license": "https://creativecommons.org/licenses/by/4.0/" }, "nuts_level1": { "name": null, From 7d3f268055f88f8d3a04f1f673bcd0e850071a1d Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 10 Jul 2024 12:24:25 -0500 Subject: [PATCH 005/226] Remove unused services & unnecessary cache cleanup. This can result in random failures if these services are not yet loaded by another test. (cherry picked from commit 3b5adf21ceecc84494a4e6eec85fe62a1e73c49d) --- .../controller/LinksetRestControllerIT.java | 33 ------------------- 1 file changed, 33 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/signposting/controller/LinksetRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/signposting/controller/LinksetRestControllerIT.java index b363e4885ed5..c5873dd53f42 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/signposting/controller/LinksetRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/signposting/controller/LinksetRestControllerIT.java @@ -41,15 +41,12 @@ import org.dspace.content.RelationshipType; import org.dspace.content.WorkspaceItem; import org.dspace.content.authority.Choices; -import org.dspace.content.authority.service.ChoiceAuthorityService; -import org.dspace.content.authority.service.MetadataAuthorityService; import org.dspace.content.service.BitstreamService; import org.dspace.content.service.ItemService; import org.dspace.content.service.RelationshipTypeService; import org.dspace.core.Constants; import org.dspace.eperson.Group; import org.dspace.services.ConfigurationService; -import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.util.SimpleMapConverter; import org.hamcrest.Matchers; import org.junit.Before; @@ -68,12 +65,6 @@ public class LinksetRestControllerIT extends AbstractControllerIntegrationTest { @Autowired private ConfigurationService configurationService; - @Autowired - private MetadataAuthorityService metadataAuthorityService; - - @Autowired - private ChoiceAuthorityService choiceAuthorityService; - @Autowired private ItemService itemService; @@ -736,10 +727,6 @@ public void findTypedLinkForBitstream() throws Exception { .andExpect(jsonPath("$[?(@.href == '" + uiUrl + "/signposting/linksets/" + item.getID() + "/json" + "' && @.rel == 'linkset' " + "&& @.type == 'application/linkset+json')]").exists()); - - DSpaceServicesFactory.getInstance().getConfigurationService().reloadConfig(); - metadataAuthorityService.clearCache(); - choiceAuthorityService.clearCache(); } @Test @@ -781,10 +768,6 @@ public void findTypedLinkForBitstreamWithType() throws Exception { "&& @.type == 'application/linkset+json')]").exists()) .andExpect(jsonPath("$[?(@.href == 'https://schema.org/ScholarlyArticle' " + "&& @.rel == 'type')]").exists()); - - DSpaceServicesFactory.getInstance().getConfigurationService().reloadConfig(); - metadataAuthorityService.clearCache(); - choiceAuthorityService.clearCache(); } @Test @@ -814,10 +797,6 @@ public void findTypedLinkForRestrictedBitstream() throws Exception { getClient().perform(get("/signposting/links/" + bitstream.getID())) .andExpect(status().isUnauthorized()); - - DSpaceServicesFactory.getInstance().getConfigurationService().reloadConfig(); - metadataAuthorityService.clearCache(); - choiceAuthorityService.clearCache(); } @Test @@ -845,10 +824,6 @@ public void findTypedLinkForBitstreamUnderEmbargo() throws Exception { getClient().perform(get("/signposting/links/" + bitstream.getID())) .andExpect(status().isUnauthorized()); - - DSpaceServicesFactory.getInstance().getConfigurationService().reloadConfig(); - metadataAuthorityService.clearCache(); - choiceAuthorityService.clearCache(); } @Test @@ -875,10 +850,6 @@ public void findTypedLinkForBitstreamOfWorkspaceItem() throws Exception { getClient().perform(get("/signposting/links/" + bitstream.getID())) .andExpect(status().isUnauthorized()); - - DSpaceServicesFactory.getInstance().getConfigurationService().reloadConfig(); - metadataAuthorityService.clearCache(); - choiceAuthorityService.clearCache(); } @Test @@ -891,10 +862,6 @@ public void findTypedLinkForUnDiscoverableItem() throws Exception { getClient().perform(get("/signposting/links/" + item.getID())) .andExpect(status().isUnauthorized()); - - DSpaceServicesFactory.getInstance().getConfigurationService().reloadConfig(); - metadataAuthorityService.clearCache(); - choiceAuthorityService.clearCache(); } @Test From 755e3f10fb56daca821a0f86f90bbc270d7a3fb0 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 10 Jul 2024 14:21:59 -0500 Subject: [PATCH 006/226] Fix random pagination failures in ManageGroupsFeatureIT by using the "feature" param to filter for the feature we are looking for. If this feature appeared on page 2, then the tests would fail. (cherry picked from commit 5cf5b494c3b6d3902482b5004a3e406cf625602c) --- .../authorization/ManageGroupsFeatureIT.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/ManageGroupsFeatureIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/ManageGroupsFeatureIT.java index a6d4108fbb1f..7a412ad425b3 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/ManageGroupsFeatureIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/authorization/ManageGroupsFeatureIT.java @@ -176,7 +176,7 @@ public void testSubGroupOfAdminGroup() throws Exception { // Verify an ePerson in a subgroup of the site administrators has this feature getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" - + "http://localhost/api/core/sites/" + siteService.findSite(context).getID())) + + "http://localhost/api/core/sites/" + siteService.findSite(context).getID() + "&feature=canManageGroups")) .andExpect(status().isOk()) .andExpect( jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='canManageGroups')]") @@ -285,7 +285,7 @@ public void testSubSubGroupOfAdminGroup() throws Exception { // Verify an ePerson in a sub-subgroup of the site administrators has this feature getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" - + "http://localhost/api/core/sites/" + siteService.findSite(context).getID())) + + "http://localhost/api/core/sites/" + siteService.findSite(context).getID() + "&feature=canManageGroups")) .andExpect(status().isOk()) .andExpect( jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='canManageGroups')]") @@ -502,7 +502,7 @@ public void testSubGroupOfAdminGroupNoCommunityGroupPermission() throws Exceptio // Verify an ePerson in a subgroup of the site administrators has this feature getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" - + "http://localhost/api/core/sites/" + siteService.findSite(context).getID())) + + "http://localhost/api/core/sites/" + siteService.findSite(context).getID() + "&feature=canManageGroups")) .andExpect(status().isOk()) .andExpect( jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='canManageGroups')]") @@ -636,7 +636,7 @@ public void testSubSubGroupOfAdminGroupNoCommunityGroupPermission() throws Excep // Verify an ePerson in a sub-subgroup of the site administrators has this feature getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" - + "http://localhost/api/core/sites/" + siteService.findSite(context).getID())) + + "http://localhost/api/core/sites/" + siteService.findSite(context).getID() + "&feature=canManageGroups")) .andExpect(status().isOk()) .andExpect( jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='canManageGroups')]") @@ -897,7 +897,7 @@ public void testSubGroupOfAdminGroupNoCollectionGroupPermission() throws Excepti // Verify an ePerson in a subgroup of the site administrators has this feature getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" - + "http://localhost/api/core/sites/" + siteService.findSite(context).getID())) + + "http://localhost/api/core/sites/" + siteService.findSite(context).getID() + "&feature=canManageGroups")) .andExpect(status().isOk()) .andExpect( jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='canManageGroups')]") @@ -1051,7 +1051,7 @@ public void testSubSubGroupOfAdminGroupNoCollectionGroupPermission() throws Exce // Verify an ePerson in a sub-subgroup of the site administrators has this feature getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" - + "http://localhost/api/core/sites/" + siteService.findSite(context).getID())) + + "http://localhost/api/core/sites/" + siteService.findSite(context).getID() + "&feature=canManageGroups")) .andExpect(status().isOk()) .andExpect( jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='canManageGroups')]") @@ -1352,7 +1352,7 @@ public void testSubGroupOfAdminGroupNoComColGroupPermission() throws Exception { // Verify an ePerson in a subgroup of the site administrators has this feature getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" - + "http://localhost/api/core/sites/" + siteService.findSite(context).getID())) + + "http://localhost/api/core/sites/" + siteService.findSite(context).getID() + "&feature=canManageGroups")) .andExpect(status().isOk()) .andExpect( jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='canManageGroups')]") @@ -1526,7 +1526,7 @@ public void testSubSubGroupOfAdminGroupNoComColGroupPermission() throws Exceptio // Verify an ePerson in a sub-subgroup of the site administrators has this feature getClient(token).perform(get("/api/authz/authorizations/search/object?embed=feature&uri=" - + "http://localhost/api/core/sites/" + siteService.findSite(context).getID())) + + "http://localhost/api/core/sites/" + siteService.findSite(context).getID() + "&feature=canManageGroups")) .andExpect(status().isOk()) .andExpect( jsonPath("$._embedded.authorizations[?(@._embedded.feature.id=='canManageGroups')]") From 22f40943563c404bbf43e8a857ab30c8c4268e88 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Wed, 17 Jul 2024 15:33:38 +0200 Subject: [PATCH 007/226] fix FromAsCasing warning (cherry picked from commit 51635d5ff1449c4956f7ad1750a8053de201949b) --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 964b76a2565d..75817980379c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,7 +9,7 @@ ARG JDK_VERSION=17 ARG DSPACE_VERSION=latest # Step 1 - Run Maven Build -FROM dspace/dspace-dependencies:${DSPACE_VERSION} as build +FROM dspace/dspace-dependencies:${DSPACE_VERSION} AS build ARG TARGET_DIR=dspace-installer WORKDIR /app # The dspace-installer directory will be written to /install @@ -31,7 +31,7 @@ RUN mvn --no-transfer-progress package ${MAVEN_FLAGS} && \ RUN rm -rf /install/webapps/server/ # Step 2 - Run Ant Deploy -FROM eclipse-temurin:${JDK_VERSION} as ant_build +FROM eclipse-temurin:${JDK_VERSION} AS ant_build ARG TARGET_DIR=dspace-installer # COPY the /install directory from 'build' container to /dspace-src in this container COPY --from=build /install /dspace-src From 6512513c4f3102bdd3b5b52826c1938f14da7d11 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Wed, 17 Jul 2024 15:34:52 +0200 Subject: [PATCH 008/226] fix FromAsCasing warning (cherry picked from commit f40e0aaf4eb13fdef1070bd35867fae08a2dfd61) --- Dockerfile.cli | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile.cli b/Dockerfile.cli index 7dd35c9651d9..5254d1eb4d69 100644 --- a/Dockerfile.cli +++ b/Dockerfile.cli @@ -9,7 +9,7 @@ ARG JDK_VERSION=17 ARG DSPACE_VERSION=latest # Step 1 - Run Maven Build -FROM dspace/dspace-dependencies:${DSPACE_VERSION} as build +FROM dspace/dspace-dependencies:${DSPACE_VERSION} AS build ARG TARGET_DIR=dspace-installer WORKDIR /app # The dspace-installer directory will be written to /install @@ -25,7 +25,7 @@ RUN mvn --no-transfer-progress package && \ mvn clean # Step 2 - Run Ant Deploy -FROM eclipse-temurin:${JDK_VERSION} as ant_build +FROM eclipse-temurin:${JDK_VERSION} AS ant_build ARG TARGET_DIR=dspace-installer # COPY the /install directory from 'build' container to /dspace-src in this container COPY --from=build /install /dspace-src From 4d014778823ef5c835f7a66df0c9d1a8c688d073 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Wed, 17 Jul 2024 15:35:21 +0200 Subject: [PATCH 009/226] fix FromAsCasing warning (cherry picked from commit ac43ec48edc408d3a08ea47bb0c9572bf23e39d4) --- Dockerfile.test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile.test b/Dockerfile.test index cdfd5e83af5f..f3acef00e825 100644 --- a/Dockerfile.test +++ b/Dockerfile.test @@ -11,7 +11,7 @@ ARG JDK_VERSION=17 ARG DSPACE_VERSION=latest # Step 1 - Run Maven Build -FROM dspace/dspace-dependencies:${DSPACE_VERSION} as build +FROM dspace/dspace-dependencies:${DSPACE_VERSION} AS build ARG TARGET_DIR=dspace-installer WORKDIR /app # The dspace-installer directory will be written to /install @@ -30,7 +30,7 @@ RUN mvn --no-transfer-progress package && \ RUN rm -rf /install/webapps/server/ # Step 2 - Run Ant Deploy -FROM eclipse-temurin:${JDK_VERSION} as ant_build +FROM eclipse-temurin:${JDK_VERSION} AS ant_build ARG TARGET_DIR=dspace-installer # COPY the /install directory from 'build' container to /dspace-src in this container COPY --from=build /install /dspace-src From ff280bef24ce7cca88dcbb0d426b35763a5bd680 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Wed, 17 Jul 2024 15:35:54 +0200 Subject: [PATCH 010/226] fix FromAsCasing warning (cherry picked from commit bed23969199549444d65b43f21315a33f9dd4cab) --- Dockerfile.dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile.dependencies b/Dockerfile.dependencies index 2ca4d3040e98..f3bf1f833205 100644 --- a/Dockerfile.dependencies +++ b/Dockerfile.dependencies @@ -7,7 +7,7 @@ ARG JDK_VERSION=17 # Step 1 - Run Maven Build -FROM maven:3-eclipse-temurin-${JDK_VERSION} as build +FROM maven:3-eclipse-temurin-${JDK_VERSION} AS build ARG TARGET_DIR=dspace-installer WORKDIR /app # Create the 'dspace' user account & home directory From f41113e198f49091ceeaa09c2d9369771b6f15bf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 22 Jul 2024 14:34:41 +0000 Subject: [PATCH 011/226] Bump dnsjava:dnsjava from 2.1.9 to 3.6.0 in /dspace-api Bumps [dnsjava:dnsjava](https://github.com/dnsjava/dnsjava) from 2.1.9 to 3.6.0. - [Release notes](https://github.com/dnsjava/dnsjava/releases) - [Changelog](https://github.com/dnsjava/dnsjava/blob/master/Changelog) - [Commits](https://github.com/dnsjava/dnsjava/compare/v2.1.9...v3.6.0) --- updated-dependencies: - dependency-name: dnsjava:dnsjava dependency-type: direct:production ... Signed-off-by: dependabot[bot] (cherry picked from commit 1775c88919cacf063788e4a6a0b67cdf1ef23fec) --- dspace-api/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index d2d2d123c350..dfb3f030ac0e 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -623,7 +623,7 @@ dnsjava dnsjava - 2.1.9 + 3.6.0 From 0d3f80e5d7ee150c4d840f344eade206334a5f6c Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Tue, 23 Jul 2024 12:17:07 +0200 Subject: [PATCH 012/226] Update spider list URLs to satisfy cloudflare redirects Update spider list URLs to satisfy cloudflare redirects Update spider list URLs to satisfy cloudflare redirects (cherry picked from commit d22ea117ca6970fd52b296ac18d3f71878c1a857) --- dspace/config/modules/solr-statistics.cfg | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dspace/config/modules/solr-statistics.cfg b/dspace/config/modules/solr-statistics.cfg index 28273809de70..57c061dac75d 100644 --- a/dspace/config/modules/solr-statistics.cfg +++ b/dspace/config/modules/solr-statistics.cfg @@ -28,10 +28,10 @@ solr-statistics.configset = statistics solr-statistics.autoCommit = true # URLs to download IP addresses of search engine spiders from -solr-statistics.spiderips.urls = http://iplists.com/google.txt, \ - http://iplists.com/inktomi.txt, \ - http://iplists.com/lycos.txt, \ - http://iplists.com/infoseek.txt, \ - http://iplists.com/altavista.txt, \ - http://iplists.com/excite.txt, \ - http://iplists.com/misc.txt +solr-statistics.spiderips.urls = https://www.iplists.com/google.txt, \ + https://www.iplists.com/inktomi.txt, \ + https://www.iplists.com/lycos.txt, \ + https://www.iplists.com/infoseek.txt, \ + https://www.iplists.com/altavista.txt, \ + https://www.iplists.com/excite.txt, \ + https://www.iplists.com/misc.txt From be2434bce12c2a059488716983b9fc9dec8da15e Mon Sep 17 00:00:00 2001 From: Vincenzo Mecca Date: Wed, 24 Jul 2024 19:07:44 +0200 Subject: [PATCH 013/226] [CST-14905] Orcid revoke token feature --- .../org/dspace/orcid/client/OrcidClient.java | 8 + .../dspace/orcid/client/OrcidClientImpl.java | 37 +++ .../orcid/client/OrcidConfiguration.java | 9 + .../impl/OrcidSynchronizationServiceImpl.java | 39 +++- .../ResearcherProfileRestRepositoryIT.java | 216 ++++++++++++++++-- dspace/config/modules/orcid.cfg | 1 + dspace/config/spring/api/orcid-services.xml | 1 + 7 files changed, 284 insertions(+), 27 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/orcid/client/OrcidClient.java b/dspace-api/src/main/java/org/dspace/orcid/client/OrcidClient.java index 99d1920aa53a..d21f61a922f5 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/client/OrcidClient.java +++ b/dspace-api/src/main/java/org/dspace/orcid/client/OrcidClient.java @@ -10,6 +10,7 @@ import java.util.List; import java.util.Optional; +import org.dspace.orcid.OrcidToken; import org.dspace.orcid.exception.OrcidClientException; import org.dspace.orcid.model.OrcidTokenResponseDTO; import org.orcid.jaxb.model.v3.release.record.Person; @@ -161,4 +162,11 @@ public interface OrcidClient { */ OrcidResponse deleteByPutCode(String accessToken, String orcid, String putCode, String path); + /** + * Revokes the given {@param accessToken} with a POST method. + * @param orcidToken the access token to revoke + * @throws OrcidClientException if some error occurs during the search + */ + void revokeToken(OrcidToken orcidToken); + } diff --git a/dspace-api/src/main/java/org/dspace/orcid/client/OrcidClientImpl.java b/dspace-api/src/main/java/org/dspace/orcid/client/OrcidClientImpl.java index 8356167692e3..6c2a1512980c 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/client/OrcidClientImpl.java +++ b/dspace-api/src/main/java/org/dspace/orcid/client/OrcidClientImpl.java @@ -42,6 +42,7 @@ import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.message.BasicNameValuePair; +import org.dspace.orcid.OrcidToken; import org.dspace.orcid.exception.OrcidClientException; import org.dspace.orcid.model.OrcidEntityType; import org.dspace.orcid.model.OrcidProfileSectionType; @@ -178,6 +179,16 @@ public OrcidResponse deleteByPutCode(String accessToken, String orcid, String pu return execute(buildDeleteUriRequest(accessToken, "/" + orcid + path + "/" + putCode), true); } + @Override + public void revokeToken(OrcidToken orcidToken) { + List params = new ArrayList<>(); + params.add(new BasicNameValuePair("client_id", orcidConfiguration.getClientId())); + params.add(new BasicNameValuePair("client_secret", orcidConfiguration.getClientSecret())); + params.add(new BasicNameValuePair("token", orcidToken.getAccessToken())); + + executeSuccessful(buildPostForRevokeToken(new UrlEncodedFormEntity(params, Charset.defaultCharset()))); + } + @Override public OrcidTokenResponseDTO getReadPublicAccessToken() { return getClientCredentialsAccessToken("/read-public"); @@ -220,6 +231,14 @@ private HttpUriRequest buildPostUriRequest(String accessToken, String relativePa .build(); } + private HttpUriRequest buildPostForRevokeToken(HttpEntity entity) { + return post(orcidConfiguration.getRevokeUrl()) + .addHeader("Accept", "application/json") + .addHeader("Content-Type", "application/x-www-form-urlencoded") + .setEntity(entity) + .build(); + } + private HttpUriRequest buildPutUriRequest(String accessToken, String relativePath, Object object) { return put(orcidConfiguration.getApiUrl() + relativePath.trim()) .addHeader("Content-Type", "application/vnd.orcid+xml") @@ -234,6 +253,24 @@ private HttpUriRequest buildDeleteUriRequest(String accessToken, String relative .build(); } + private void executeSuccessful(HttpUriRequest httpUriRequest) { + try { + HttpClient client = HttpClientBuilder.create().build(); + HttpResponse response = client.execute(httpUriRequest); + + if (isNotSuccessfull(response)) { + throw new OrcidClientException( + getStatusCode(response), + "Operation " + httpUriRequest.getMethod() + " for the resource " + httpUriRequest.getURI() + + " was not successful: " + new String(response.getEntity().getContent().readAllBytes(), + StandardCharsets.UTF_8) + ); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + private T executeAndParseJson(HttpUriRequest httpUriRequest, Class clazz) { HttpClient client = HttpClientBuilder.create().build(); diff --git a/dspace-api/src/main/java/org/dspace/orcid/client/OrcidConfiguration.java b/dspace-api/src/main/java/org/dspace/orcid/client/OrcidConfiguration.java index 550b0215c435..dfa90fcae03a 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/client/OrcidConfiguration.java +++ b/dspace-api/src/main/java/org/dspace/orcid/client/OrcidConfiguration.java @@ -35,6 +35,8 @@ public final class OrcidConfiguration { private String scopes; + private String revokeUrl; + public String getApiUrl() { return apiUrl; } @@ -111,4 +113,11 @@ public boolean isApiConfigured() { return !StringUtils.isAnyBlank(clientId, clientSecret); } + public String getRevokeUrl() { + return revokeUrl; + } + + public void setRevokeUrl(String revokeUrl) { + this.revokeUrl = revokeUrl; + } } diff --git a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java index 59e4dea64145..f976864d07f9 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidSynchronizationServiceImpl.java @@ -37,6 +37,7 @@ import org.dspace.eperson.EPerson; import org.dspace.eperson.service.EPersonService; import org.dspace.orcid.OrcidToken; +import org.dspace.orcid.client.OrcidClient; import org.dspace.orcid.model.OrcidEntityType; import org.dspace.orcid.model.OrcidTokenResponseDTO; import org.dspace.orcid.service.OrcidSynchronizationService; @@ -47,6 +48,8 @@ import org.dspace.profile.OrcidSynchronizationMode; import org.dspace.profile.service.ResearcherProfileService; import org.dspace.services.ConfigurationService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; /** @@ -57,6 +60,7 @@ */ public class OrcidSynchronizationServiceImpl implements OrcidSynchronizationService { + private static final Logger log = LoggerFactory.getLogger(OrcidSynchronizationServiceImpl.class); @Autowired private ItemService itemService; @@ -75,6 +79,9 @@ public class OrcidSynchronizationServiceImpl implements OrcidSynchronizationServ @Autowired private ResearcherProfileService researcherProfileService; + @Autowired + private OrcidClient orcidClient; + @Override public void linkProfile(Context context, Item profile, OrcidTokenResponseDTO token) throws SQLException { @@ -114,20 +121,33 @@ public void linkProfile(Context context, Item profile, OrcidTokenResponseDTO tok @Override public void unlinkProfile(Context context, Item profile) throws SQLException { - itemService.clearMetadata(context, profile, "person", "identifier", "orcid", Item.ANY); - itemService.clearMetadata(context, profile, "dspace", "orcid", "scope", Item.ANY); - itemService.clearMetadata(context, profile, "dspace", "orcid", "authenticated", Item.ANY); + clearOrcidProfileMetadata(context, profile); - if (!configurationService.getBooleanProperty("orcid.disconnection.remain-sync", false)) { - clearSynchronizationSettings(context, profile); - } + clearSynchronizationSettings(context, profile); - orcidTokenService.deleteByProfileItem(context, profile); + clearOrcidToken(context, profile); updateItem(context, profile); } + private void clearOrcidToken(Context context, Item profile) { + OrcidToken profileToken = orcidTokenService.findByProfileItem(context, profile); + if (profileToken == null) { + log.warn("Cannot find any token related to the user profile: {}", profile.getID()); + return; + } + + orcidTokenService.deleteByProfileItem(context, profile); + orcidClient.revokeToken(profileToken); + } + + private void clearOrcidProfileMetadata(Context context, Item profile) throws SQLException { + itemService.clearMetadata(context, profile, "person", "identifier", "orcid", Item.ANY); + itemService.clearMetadata(context, profile, "dspace", "orcid", "scope", Item.ANY); + itemService.clearMetadata(context, profile, "dspace", "orcid", "authenticated", Item.ANY); + } + @Override public boolean setEntityPreference(Context context, Item profile, OrcidEntityType type, OrcidEntitySyncPreference value) throws SQLException { @@ -273,6 +293,11 @@ private boolean updatePreferenceForSynchronizingWithOrcid(Context context, Item private void clearSynchronizationSettings(Context context, Item profile) throws SQLException { + + if (configurationService.getBooleanProperty("orcid.disconnection.remain-sync", false)) { + return; + } + itemService.clearMetadata(context, profile, "dspace", "orcid", "sync-mode", Item.ANY); itemService.clearMetadata(context, profile, "dspace", "orcid", "sync-profile", Item.ANY); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ResearcherProfileRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ResearcherProfileRestRepositoryIT.java index b3c70f8128d4..493b3bf94628 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ResearcherProfileRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ResearcherProfileRestRepositoryIT.java @@ -31,7 +31,10 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; @@ -45,6 +48,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import java.io.UnsupportedEncodingException; +import java.lang.reflect.Field; import java.sql.SQLException; import java.util.List; import java.util.UUID; @@ -80,11 +84,13 @@ import org.dspace.orcid.exception.OrcidClientException; import org.dspace.orcid.model.OrcidTokenResponseDTO; import org.dspace.orcid.service.OrcidQueueService; +import org.dspace.orcid.service.OrcidSynchronizationService; import org.dspace.orcid.service.OrcidTokenService; import org.dspace.services.ConfigurationService; import org.dspace.util.UUIDUtils; import org.junit.After; import org.junit.Test; +import org.mockito.Mock; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MvcResult; @@ -115,7 +121,11 @@ public class ResearcherProfileRestRepositoryIT extends AbstractControllerIntegra @Autowired private OrcidClient orcidClient; - private OrcidClient orcidClientMock = mock(OrcidClient.class); + @Mock + private OrcidClient orcidClientMock; + + @Autowired + private OrcidSynchronizationService orcidSynchronizationService; private EPerson user; @@ -159,16 +169,36 @@ public void setUp() throws Exception { context.restoreAuthSystemState(); - researcherProfileAddOrcidOperation.setOrcidClient(orcidClientMock); - + useInstanceForBean(orcidSynchronizationService, orcidClientMock); + useInstanceForBean(researcherProfileAddOrcidOperation, orcidClientMock); } @After public void after() { orcidTokenService.deleteAll(context); - researcherProfileAddOrcidOperation.setOrcidClient(orcidClient); + useInstanceForBean(orcidSynchronizationService, orcidClient); + useInstanceForBean(researcherProfileAddOrcidOperation, orcidClient); } + private void useInstanceForBean(B bean, I instance) { + Field[] fields = bean.getClass().getDeclaredFields(); + + for (Field field : fields) { + if (field.getType().isAssignableFrom(instance.getClass())) { + boolean accessible = field.isAccessible(); + try { + field.setAccessible(true); + field.set(bean, instance); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } finally { + field.setAccessible(accessible); + } + } + } + } + + /** * Verify that the findById endpoint returns the own profile. * @@ -609,30 +639,38 @@ public void testDeleteWithProfileLinkedWithOrcid() throws Exception { .withOrcidAuthenticated("authenticated") .build(); + context.restoreAuthSystemState(); + String id = user.getID().toString(); String authToken = getAuthToken(user.getEmail(), password); + OrcidToken orcidToken = orcidTokenService.findByProfileItem(context, profileItem); - context.restoreAuthSystemState(); - - getClient(authToken).perform(get("/api/eperson/profiles/{id}", id)) + getClient(authToken) + .perform(get("/api/eperson/profiles/{id}", id)) .andExpect(status().isOk()); assertThat(profileItem.getMetadata(), hasItem(with("person.identifier.orcid", "0000-1111-2222-3333"))); assertThat(profileItem.getMetadata(), hasItem(with("dspace.orcid.authenticated", "authenticated"))); - assertThat(getOrcidAccessToken(profileItem), notNullValue()); + assertThat(orcidToken.getAccessToken(), notNullValue()); getClient(authToken).perform(get("/api/eperson/profiles/{id}/item", id)) .andExpect(status().isOk()) .andExpect(jsonPath("$", hasJsonPath("$.metadata", matchMetadataNotEmpty("dspace.object.owner")))); + getClient(authToken).perform(delete("/api/eperson/profiles/{id}", id)) .andExpect(status().isNoContent()); + verify(orcidClientMock, times(1)).revokeToken(matchesToken(orcidToken)); + verifyNoMoreInteractions(orcidClientMock); + profileItem = context.reloadEntity(profileItem); + orcidToken = orcidTokenService.findByProfileItem(context, profileItem); + assertThat(profileItem.getMetadata(), not(hasItem(with("person.identifier.orcid", "0000-1111-2222-3333")))); assertThat(profileItem.getMetadata(), not(hasItem(with("dspace.orcid.authenticated", "authenticated")))); - assertThat(getOrcidAccessToken(profileItem), nullValue()); + assertThat(orcidToken, nullValue()); } @@ -1851,7 +1889,60 @@ public void testOwnerPatchToDisconnectProfileFromOrcidWithOnlyOwnerConfiguration .withNameInMetadata("Test", "User") .build(); - OrcidTokenBuilder.create(context, ePerson, "3de2e370-8aa9-4bbe-8d7e-f5b1577bdad4").build(); + OrcidToken orcidToken = + OrcidTokenBuilder.create(context, ePerson, "3de2e370-8aa9-4bbe-8d7e-f5b1577bdad4").build(); + + Item profile = createProfile(ePerson); + + context.restoreAuthSystemState(); + + assertThat(getMetadataValues(profile, "person.identifier.orcid"), not(empty())); + assertThat(getMetadataValues(profile, "dspace.orcid.scope"), not(empty())); + assertThat(getMetadataValues(profile, "dspace.orcid.authenticated"), not(empty())); + assertThat(getOrcidAccessToken(profile), is("3de2e370-8aa9-4bbe-8d7e-f5b1577bdad4")); + + getClient(getAuthToken(ePerson.getEmail(), password)) + .perform(patch("/api/eperson/profiles/{id}", ePerson.getID().toString()) + .content(getPatchContent(asList(new RemoveOperation("/orcid")))) + .contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.id", is(ePerson.getID().toString()))) + .andExpect(jsonPath("$.visible", is(false))) + .andExpect(jsonPath("$.type", is("profile"))) + .andExpect(jsonPath("$.orcid").doesNotExist()) + .andExpect(jsonPath("$.orcidSynchronization").doesNotExist()); + + verify(orcidClientMock, times(1)) + .revokeToken(matchesToken(orcidToken)); + verifyNoMoreInteractions(orcidClientMock); + + profile = context.reloadEntity(profile); + + assertThat(getMetadataValues(profile, "person.identifier.orcid"), empty()); + assertThat(getMetadataValues(profile, "dspace.orcid.scope"), empty()); + assertThat(getMetadataValues(profile, "dspace.orcid.authenticated"), empty()); + assertThat(getOrcidAccessToken(profile), nullValue()); + } + + @Test + public void testPatchToDisconnectProfileFromOrcidRevokesOrcidToken() throws Exception { + + configurationService.setProperty("orcid.disconnection.allowed-users", "admin_and_owner"); + + context.turnOffAuthorisationSystem(); + + EPerson ePerson = EPersonBuilder.createEPerson(context) + .withCanLogin(true) + .withOrcid("0000-1111-2222-3333") + .withOrcidScope("/read") + .withOrcidScope("/write") + .withEmail("test@email.it") + .withPassword(password) + .withNameInMetadata("Test", "User") + .build(); + + OrcidToken orcidToken = + OrcidTokenBuilder.create(context, ePerson, "3de2e370-8aa9-4bbe-8d7e-f5b1577bdad4").build(); Item profile = createProfile(ePerson); @@ -1873,6 +1964,9 @@ public void testOwnerPatchToDisconnectProfileFromOrcidWithOnlyOwnerConfiguration .andExpect(jsonPath("$.orcid").doesNotExist()) .andExpect(jsonPath("$.orcidSynchronization").doesNotExist()); + verify(orcidClientMock, times(1)).revokeToken(matchesToken(orcidToken)); + verifyNoMoreInteractions(orcidClientMock); + profile = context.reloadEntity(profile); assertThat(getMetadataValues(profile, "person.identifier.orcid"), empty()); @@ -1881,6 +1975,54 @@ public void testOwnerPatchToDisconnectProfileFromOrcidWithOnlyOwnerConfiguration assertThat(getOrcidAccessToken(profile), nullValue()); } + @Test + public void testPatchToDisconnectProfileFromOrcidDoesntRevokeOrcidToken() throws Exception { + + configurationService.setProperty("orcid.disconnection.allowed-users", "admin_and_owner"); + + context.turnOffAuthorisationSystem(); + + EPerson ePerson = EPersonBuilder.createEPerson(context) + .withCanLogin(true) + .withOrcid("0000-1111-2222-3333") + .withOrcidScope("/read") + .withOrcidScope("/write") + .withEmail("test@email.it") + .withPassword(password) + .withNameInMetadata("Test", "User") + .build(); + + OrcidToken orcidToken = + OrcidTokenBuilder.create(context, ePerson, "3de2e370-8aa9-4bbe-8d7e-f5b1577bdad4").build(); + + Item profile = createProfile(ePerson); + + assertThat(getMetadataValues(profile, "person.identifier.orcid"), not(empty())); + assertThat(getMetadataValues(profile, "dspace.orcid.scope"), not(empty())); + assertThat(getMetadataValues(profile, "dspace.orcid.authenticated"), not(empty())); + assertThat(getOrcidAccessToken(profile), is("3de2e370-8aa9-4bbe-8d7e-f5b1577bdad4")); + + context.restoreAuthSystemState(); + + doThrow(new OrcidClientException(403, "")).when(orcidClientMock).revokeToken(any(OrcidToken.class)); + + getClient(getAuthToken(ePerson.getEmail(), password)) + .perform(patch("/api/eperson/profiles/{id}", ePerson.getID().toString()) + .content(getPatchContent(asList(new RemoveOperation("/orcid")))) + .contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(status().isInternalServerError()); + + verify(orcidClientMock, times(1)).revokeToken(matchesToken(orcidToken)); + verifyNoMoreInteractions(orcidClientMock); + + profile = context.reloadEntity(profile); + + assertThat(getMetadataValues(profile, "person.identifier.orcid"), not(empty())); + assertThat(getMetadataValues(profile, "dspace.orcid.scope"), not(empty())); + assertThat(getMetadataValues(profile, "dspace.orcid.authenticated"), not(empty())); + assertThat(getOrcidAccessToken(profile), is("3de2e370-8aa9-4bbe-8d7e-f5b1577bdad4")); + } + @Test public void testAdminPatchToDisconnectProfileFromOrcidWithOnlyOwnerConfiguration() throws Exception { @@ -2024,7 +2166,8 @@ public void testAdminPatchToDisconnectProfileFromOrcidWithOnlyAdminConfiguration .withNameInMetadata("Test", "User") .build(); - OrcidTokenBuilder.create(context, ePerson, "3de2e370-8aa9-4bbe-8d7e-f5b1577bdad4").build(); + OrcidToken orcidToken = + OrcidTokenBuilder.create(context, ePerson, "3de2e370-8aa9-4bbe-8d7e-f5b1577bdad4").build(); Item profile = createProfile(ePerson); @@ -2035,6 +2178,7 @@ public void testAdminPatchToDisconnectProfileFromOrcidWithOnlyAdminConfiguration context.restoreAuthSystemState(); + getClient(getAuthToken(admin.getEmail(), password)) .perform(patch("/api/eperson/profiles/{id}", ePerson.getID().toString()) .content(getPatchContent(asList(new RemoveOperation("/orcid")))) @@ -2046,6 +2190,9 @@ public void testAdminPatchToDisconnectProfileFromOrcidWithOnlyAdminConfiguration .andExpect(jsonPath("$.orcid").doesNotExist()) .andExpect(jsonPath("$.orcidSynchronization").doesNotExist()); + verify(orcidClientMock, times(1)).revokeToken(matchesToken(orcidToken)); + verifyNoMoreInteractions(orcidClientMock); + profile = context.reloadEntity(profile); assertThat(getMetadataValues(profile, "person.identifier.orcid"), empty()); @@ -2112,17 +2259,18 @@ public void testOwnerPatchToDisconnectProfileFromOrcidWithAdminAndOwnerConfigura .withPassword(password) .withNameInMetadata("Test", "User") .build(); - - OrcidTokenBuilder.create(context, ePerson, "3de2e370-8aa9-4bbe-8d7e-f5b1577bdad4").build(); + OrcidToken orcidToken = + OrcidTokenBuilder.create(context, ePerson, "3de2e370-8aa9-4bbe-8d7e-f5b1577bdad4").build(); Item profile = createProfile(ePerson); + context.restoreAuthSystemState(); + assertThat(getMetadataValues(profile, "person.identifier.orcid"), not(empty())); assertThat(getMetadataValues(profile, "dspace.orcid.scope"), not(empty())); assertThat(getMetadataValues(profile, "dspace.orcid.authenticated"), not(empty())); assertThat(getOrcidAccessToken(profile), is("3de2e370-8aa9-4bbe-8d7e-f5b1577bdad4")); - context.restoreAuthSystemState(); getClient(getAuthToken(ePerson.getEmail(), password)) .perform(patch("/api/eperson/profiles/{id}", ePerson.getID().toString()) @@ -2135,6 +2283,9 @@ public void testOwnerPatchToDisconnectProfileFromOrcidWithAdminAndOwnerConfigura .andExpect(jsonPath("$.orcid").doesNotExist()) .andExpect(jsonPath("$.orcidSynchronization").doesNotExist()); + verify(orcidClientMock, times(1)).revokeToken(matchesToken(orcidToken)); + verifyNoMoreInteractions(orcidClientMock); + profile = context.reloadEntity(profile); assertThat(getMetadataValues(profile, "person.identifier.orcid"), empty()); @@ -2160,7 +2311,8 @@ public void testAdminPatchToDisconnectProfileFromOrcidWithAdminAndOwnerConfigura .withNameInMetadata("Test", "User") .build(); - OrcidTokenBuilder.create(context, ePerson, "3de2e370-8aa9-4bbe-8d7e-f5b1577bdad4").build(); + OrcidToken orcidToken = + OrcidTokenBuilder.create(context, ePerson, "3de2e370-8aa9-4bbe-8d7e-f5b1577bdad4").build(); Item profile = createProfile(ePerson); @@ -2171,6 +2323,7 @@ public void testAdminPatchToDisconnectProfileFromOrcidWithAdminAndOwnerConfigura context.restoreAuthSystemState(); + getClient(getAuthToken(admin.getEmail(), password)) .perform(patch("/api/eperson/profiles/{id}", ePerson.getID().toString()) .content(getPatchContent(asList(new RemoveOperation("/orcid")))) @@ -2182,6 +2335,10 @@ public void testAdminPatchToDisconnectProfileFromOrcidWithAdminAndOwnerConfigura .andExpect(jsonPath("$.orcid").doesNotExist()) .andExpect(jsonPath("$.orcidSynchronization").doesNotExist()); + + verify(orcidClientMock, times(1)).revokeToken(matchesToken(orcidToken)); + verifyNoMoreInteractions(orcidClientMock); + profile = context.reloadEntity(profile); assertThat(getMetadataValues(profile, "person.identifier.orcid"), empty()); @@ -2250,7 +2407,8 @@ public void testOwnerPatchToDisconnectProfileFromOrcidWithSyncSettingsRemoved() .withNameInMetadata("Test", "User") .build(); - OrcidTokenBuilder.create(context, ePerson, "3de2e370-8aa9-4bbe-8d7e-f5b1577bdad4").build(); + OrcidToken orcidToken = + OrcidTokenBuilder.create(context, ePerson, "3de2e370-8aa9-4bbe-8d7e-f5b1577bdad4").build(); Item profile = createProfile(ePerson); @@ -2285,6 +2443,7 @@ public void testOwnerPatchToDisconnectProfileFromOrcidWithSyncSettingsRemoved() assertThat(metadata, hasItem(with("dspace.orcid.sync-fundings",ALL.name()))); assertThat(getMetadataValues(profile, "dspace.orcid.sync-profile"), hasSize(2)); + getClient(authToken).perform(patch("/api/eperson/profiles/{id}", ePersonId) .content(getPatchContent(asList(new RemoveOperation("/orcid")))) .contentType(MediaType.APPLICATION_JSON_VALUE)) @@ -2295,6 +2454,9 @@ public void testOwnerPatchToDisconnectProfileFromOrcidWithSyncSettingsRemoved() .andExpect(jsonPath("$.orcid").doesNotExist()) .andExpect(jsonPath("$.orcidSynchronization").doesNotExist()); + verify(orcidClientMock, times(1)).revokeToken(matchesToken(orcidToken)); + verifyNoMoreInteractions(orcidClientMock); + profile = context.reloadEntity(profile); assertThat(getMetadataValues(profile, "person.identifier.orcid"), empty()); @@ -2324,17 +2486,18 @@ public void testOwnerPatchToDisconnectProfileFromOrcidWithSyncSettingsRemain() t .withNameInMetadata("Test", "User") .build(); - OrcidTokenBuilder.create(context, ePerson, "3de2e370-8aa9-4bbe-8d7e-f5b1577bdad4").build(); + OrcidToken orcidToken = + OrcidTokenBuilder.create(context, ePerson, "3de2e370-8aa9-4bbe-8d7e-f5b1577bdad4").build(); Item profile = createProfile(ePerson); + context.restoreAuthSystemState(); + assertThat(getMetadataValues(profile, "person.identifier.orcid"), not(empty())); assertThat(getMetadataValues(profile, "dspace.orcid.scope"), not(empty())); assertThat(getMetadataValues(profile, "dspace.orcid.authenticated"), not(empty())); assertThat(getOrcidAccessToken(profile), is("3de2e370-8aa9-4bbe-8d7e-f5b1577bdad4")); - context.restoreAuthSystemState(); - String authToken = getAuthToken(ePerson.getEmail(), password); String ePersonId = ePerson.getID().toString(); List operations = asList(new ReplaceOperation("/orcid/mode", "BATCH"), @@ -2359,6 +2522,7 @@ public void testOwnerPatchToDisconnectProfileFromOrcidWithSyncSettingsRemain() t assertThat(metadata, hasItem(with("dspace.orcid.sync-fundings",ALL.name()))); assertThat(getMetadataValues(profile, "dspace.orcid.sync-profile"), hasSize(2)); + getClient(authToken).perform(patch("/api/eperson/profiles/{id}", ePersonId) .content(getPatchContent(asList(new RemoveOperation("/orcid")))) .contentType(MediaType.APPLICATION_JSON_VALUE)) @@ -2369,6 +2533,9 @@ public void testOwnerPatchToDisconnectProfileFromOrcidWithSyncSettingsRemain() t .andExpect(jsonPath("$.orcid").doesNotExist()) .andExpect(jsonPath("$.orcidSynchronization").doesNotExist()); + verify(orcidClientMock, times(1)).revokeToken(matchesToken(orcidToken)); + verifyNoMoreInteractions(orcidClientMock); + profile = context.reloadEntity(profile); assertThat(getMetadataValues(profile, "person.identifier.orcid"), empty()); @@ -2778,4 +2945,13 @@ private OrcidTokenResponseDTO buildOrcidTokenResponse(String orcid, String acces return token; } + private static OrcidToken matchesToken(OrcidToken orcidToken) { + return argThat( + token -> + token != null && + orcidToken.getAccessToken().equals(token.getAccessToken()) && + orcidToken.getID().equals(token.getID()) + ); + } + } diff --git a/dspace/config/modules/orcid.cfg b/dspace/config/modules/orcid.cfg index 28e8df60f83d..ad31371cb890 100644 --- a/dspace/config/modules/orcid.cfg +++ b/dspace/config/modules/orcid.cfg @@ -17,6 +17,7 @@ orcid.disconnection.remain-sync = true # ORCID API (https://github.com/ORCID/ORCID-Source/tree/master/orcid-api-web#endpoints) orcid.domain-url= https://sandbox.orcid.org orcid.authorize-url = ${orcid.domain-url}/oauth/authorize +orcid.revoke-url = ${orcid.domain-url}/oauth/revoke orcid.token-url = ${orcid.domain-url}/oauth/token orcid.api-url = https://api.sandbox.orcid.org/v3.0 orcid.public-url = https://pub.sandbox.orcid.org/v3.0 diff --git a/dspace/config/spring/api/orcid-services.xml b/dspace/config/spring/api/orcid-services.xml index 8286a16a88fb..6ec9be9fdf5d 100644 --- a/dspace/config/spring/api/orcid-services.xml +++ b/dspace/config/spring/api/orcid-services.xml @@ -30,6 +30,7 @@ + From a9400a7f48c7afa321310911e6c870197237394a Mon Sep 17 00:00:00 2001 From: Vincenzo Mecca Date: Tue, 21 Nov 2023 11:51:25 +0100 Subject: [PATCH 014/226] [CST-14901][DSC-1357][#8662] Handles versioning for ORCID publications. feat: - ORCID publications waiting to be published are removed whenever a new version is created - ORCID publications already published will be updated with the ref to the last item version - ORCID consumer will process only latest item versions, ignoring all the other ones --- .../org/dspace/content/ItemServiceImpl.java | 42 ++++ .../dspace/content/service/ItemService.java | 10 + .../orcid/consumer/OrcidQueueConsumer.java | 49 +++-- .../org/dspace/orcid/dao/OrcidQueueDAO.java | 10 + .../orcid/dao/impl/OrcidQueueDAOImpl.java | 7 + .../orcid/service/OrcidQueueService.java | 10 + .../service/impl/OrcidQueueServiceImpl.java | 5 + .../dspace/versioning/VersioningConsumer.java | 35 +++- .../dspace/orcid/OrcidQueueConsumerIT.java | 185 ++++++++++++++++++ 9 files changed, 336 insertions(+), 17 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java index 70bdf4b7d950..d300f22d5637 100644 --- a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java @@ -81,6 +81,9 @@ import org.dspace.profile.service.ResearcherProfileService; import org.dspace.qaevent.dao.QAEventsDAO; import org.dspace.services.ConfigurationService; +import org.dspace.versioning.Version; +import org.dspace.versioning.VersionHistory; +import org.dspace.versioning.service.VersionHistoryService; import org.dspace.versioning.service.VersioningService; import org.dspace.workflow.WorkflowItemService; import org.dspace.workflow.factory.WorkflowServiceFactory; @@ -176,6 +179,9 @@ public class ItemServiceImpl extends DSpaceObjectServiceImpl implements It @Autowired private QAEventsDAO qaEventsDao; + @Autowired + private VersionHistoryService versionHistoryService; + protected ItemServiceImpl() { } @@ -1931,4 +1937,40 @@ private void deleteOrcidQueueRecords(Context context, Item item) throws SQLExcep } } + @Override + public boolean isLatestVersion(Context context, Item item) throws SQLException { + + VersionHistory history = versionHistoryService.findByItem(context, item); + if (history == null) { + // not all items have a version history + // if an item does not have a version history, it is by definition the latest + // version + return true; + } + + // start with the very latest version of the given item (may still be in + // workspace) + Version latestVersion = versionHistoryService.getLatestVersion(context, history); + + // find the latest version of the given item that is archived + while (latestVersion != null && !latestVersion.getItem().isArchived()) { + latestVersion = versionHistoryService.getPrevious(context, history, latestVersion); + } + + // could not find an archived version of the given item + if (latestVersion == null) { + // this scenario should never happen, but let's err on the side of showing too + // many items vs. to little + // (see discovery.xml, a lot of discovery configs filter out all items that are + // not the latest version) + return true; + } + + // sanity check + assert latestVersion.getItem().isArchived(); + + return item.equals(latestVersion.getItem()); + + } + } diff --git a/dspace-api/src/main/java/org/dspace/content/service/ItemService.java b/dspace-api/src/main/java/org/dspace/content/service/ItemService.java index 47d2d5bdaa88..3fea75665bcb 100644 --- a/dspace-api/src/main/java/org/dspace/content/service/ItemService.java +++ b/dspace-api/src/main/java/org/dspace/content/service/ItemService.java @@ -1009,4 +1009,14 @@ List getMetadata(Item item, String schema, String element, String */ EntityType getEntityType(Context context, Item item) throws SQLException; + + /** + * Check whether the given item is the latest version. If the latest item cannot + * be determined, because either the version history or the latest version is + * not present, assume the item is latest. + * @param context the DSpace context. + * @param item the item that should be checked. + * @return true if the item is the latest version, false otherwise. + */ + public boolean isLatestVersion(Context context, Item item) throws SQLException; } diff --git a/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java b/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java index 97da341fb811..6b174e96957f 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java +++ b/dspace-api/src/main/java/org/dspace/orcid/consumer/OrcidQueueConsumer.java @@ -14,9 +14,10 @@ import static org.apache.commons.collections.CollectionUtils.isNotEmpty; import java.sql.SQLException; -import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Optional; +import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -82,7 +83,7 @@ public class OrcidQueueConsumer implements Consumer { private RelationshipService relationshipService; - private final List alreadyConsumedItems = new ArrayList<>(); + private final Set itemsToConsume = new HashSet<>(); @Override public void initialize() throws Exception { @@ -117,17 +118,26 @@ public void consume(Context context, Event event) throws Exception { return; } - if (alreadyConsumedItems.contains(item.getID())) { - return; - } + itemsToConsume.add(item.getID()); + } + + @Override + public void end(Context context) throws Exception { + + for (UUID itemId : itemsToConsume) { + + Item item = itemService.find(context, itemId); + + context.turnOffAuthorisationSystem(); + try { + consumeItem(context, item); + } finally { + context.restoreAuthSystemState(); + } - context.turnOffAuthorisationSystem(); - try { - consumeItem(context, item); - } finally { - context.restoreAuthSystemState(); } + itemsToConsume.clear(); } /** @@ -146,7 +156,7 @@ private void consumeItem(Context context, Item item) throws SQLException { consumeProfile(context, item); } - alreadyConsumedItems.add(item.getID()); + itemsToConsume.add(item.getID()); } @@ -169,6 +179,10 @@ private void consumeEntity(Context context, Item entity) throws SQLException { continue; } + if (isNotLatestVersion(context, entity)) { + continue; + } + orcidQueueService.create(context, relatedItem, entity); } @@ -329,6 +343,14 @@ private boolean isNotProfileItem(Item profileItemItem) { return !getProfileType().equals(itemService.getEntityTypeLabel(profileItemItem)); } + private boolean isNotLatestVersion(Context context, Item entity) { + try { + return !itemService.isLatestVersion(context, entity); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + private String getMetadataValue(Item item, String metadataField) { return itemService.getMetadataFirstValue(item, new MetadataFieldName(metadataField), Item.ANY); } @@ -345,11 +367,6 @@ private boolean isOrcidSynchronizationDisabled() { return !configurationService.getBooleanProperty("orcid.synchronization-enabled", true); } - @Override - public void end(Context context) throws Exception { - alreadyConsumedItems.clear(); - } - @Override public void finish(Context context) throws Exception { // nothing to do diff --git a/dspace-api/src/main/java/org/dspace/orcid/dao/OrcidQueueDAO.java b/dspace-api/src/main/java/org/dspace/orcid/dao/OrcidQueueDAO.java index 235443b15033..b7e0b1ed2a85 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/dao/OrcidQueueDAO.java +++ b/dspace-api/src/main/java/org/dspace/orcid/dao/OrcidQueueDAO.java @@ -74,6 +74,16 @@ public List findByProfileItemAndEntity(Context context, Item profile */ public List findByProfileItemOrEntity(Context context, Item item) throws SQLException; + /** + * Get the OrcidQueue records where the given item is the entity. + * + * @param context DSpace context object + * @param item the item to search for + * @return the found OrcidQueue entities + * @throws SQLException if database error + */ + public List findByEntity(Context context, Item item) throws SQLException; + /** * Find all the OrcidQueue records with the given entity and record type. * diff --git a/dspace-api/src/main/java/org/dspace/orcid/dao/impl/OrcidQueueDAOImpl.java b/dspace-api/src/main/java/org/dspace/orcid/dao/impl/OrcidQueueDAOImpl.java index c8e48e3f17d6..091e59750517 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/dao/impl/OrcidQueueDAOImpl.java +++ b/dspace-api/src/main/java/org/dspace/orcid/dao/impl/OrcidQueueDAOImpl.java @@ -63,6 +63,13 @@ public List findByProfileItemOrEntity(Context context, Item item) th return query.getResultList(); } + @Override + public List findByEntity(Context context, Item item) throws SQLException { + Query query = createQuery(context, "FROM OrcidQueue WHERE entity.id = :itemId"); + query.setParameter("itemId", item.getID()); + return query.getResultList(); + } + @Override public List findByEntityAndRecordType(Context context, Item entity, String type) throws SQLException { Query query = createQuery(context, "FROM OrcidQueue WHERE entity = :entity AND recordType = :type"); diff --git a/dspace-api/src/main/java/org/dspace/orcid/service/OrcidQueueService.java b/dspace-api/src/main/java/org/dspace/orcid/service/OrcidQueueService.java index 8de25e9caf1e..b667088eabb4 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/service/OrcidQueueService.java +++ b/dspace-api/src/main/java/org/dspace/orcid/service/OrcidQueueService.java @@ -164,6 +164,16 @@ public List findByProfileItemAndEntity(Context context, Item profile */ public List findByProfileItemOrEntity(Context context, Item item) throws SQLException; + /** + * Get the OrcidQueue records where the given item is the entity. + * + * @param context DSpace context object + * @param item the item to search for + * @return the found OrcidQueue records + * @throws SQLException if database error + */ + public List findByEntity(Context context, Item item) throws SQLException; + /** * Get all the OrcidQueue records with attempts less than the given attempts. * diff --git a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java index d3300fea6606..261f8ef9a9f7 100644 --- a/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/orcid/service/impl/OrcidQueueServiceImpl.java @@ -70,6 +70,11 @@ public List findByProfileItemOrEntity(Context context, Item item) th return orcidQueueDAO.findByProfileItemOrEntity(context, item); } + @Override + public List findByEntity(Context context, Item item) throws SQLException { + return orcidQueueDAO.findByEntity(context, item); + } + @Override public long countByProfileItemId(Context context, UUID profileItemId) throws SQLException { return orcidQueueDAO.countByProfileItemId(context, profileItemId); diff --git a/dspace-api/src/main/java/org/dspace/versioning/VersioningConsumer.java b/dspace-api/src/main/java/org/dspace/versioning/VersioningConsumer.java index 63b5391d0a28..27a81a157917 100644 --- a/dspace-api/src/main/java/org/dspace/versioning/VersioningConsumer.java +++ b/dspace-api/src/main/java/org/dspace/versioning/VersioningConsumer.java @@ -33,6 +33,11 @@ import org.dspace.discovery.IndexEventConsumer; import org.dspace.event.Consumer; import org.dspace.event.Event; +import org.dspace.orcid.OrcidHistory; +import org.dspace.orcid.OrcidQueue; +import org.dspace.orcid.factory.OrcidServiceFactory; +import org.dspace.orcid.service.OrcidHistoryService; +import org.dspace.orcid.service.OrcidQueueService; import org.dspace.versioning.factory.VersionServiceFactory; import org.dspace.versioning.service.VersionHistoryService; import org.dspace.versioning.utils.RelationshipVersioningUtils; @@ -58,6 +63,8 @@ public class VersioningConsumer implements Consumer { private RelationshipTypeService relationshipTypeService; private RelationshipService relationshipService; private RelationshipVersioningUtils relationshipVersioningUtils; + private OrcidQueueService orcidQueueService; + private OrcidHistoryService orcidHistoryService; @Override public void initialize() throws Exception { @@ -67,6 +74,8 @@ public void initialize() throws Exception { relationshipTypeService = ContentServiceFactory.getInstance().getRelationshipTypeService(); relationshipService = ContentServiceFactory.getInstance().getRelationshipService(); relationshipVersioningUtils = VersionServiceFactory.getInstance().getRelationshipVersioningUtils(); + this.orcidQueueService = OrcidServiceFactory.getInstance().getOrcidQueueService(); + this.orcidHistoryService = OrcidServiceFactory.getInstance().getOrcidHistoryService(); } @Override @@ -132,7 +141,8 @@ public void consume(Context ctx, Event event) throws Exception { // unarchive previous item unarchiveItem(ctx, previousItem); - + // handles versions for ORCID publications waiting to be shipped, or already published (history-queue). + handleOrcidSynchronization(ctx, previousItem, latestItem); // update relationships updateRelationships(ctx, latestItem, previousItem); } @@ -148,6 +158,29 @@ protected void unarchiveItem(Context ctx, Item item) { )); } + private void handleOrcidSynchronization(Context ctx, Item previousItem, Item latestItem) { + try { + replaceOrcidHistoryEntities(ctx, previousItem, latestItem); + removeOrcidQueueEntries(ctx, previousItem); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + + private void removeOrcidQueueEntries(Context ctx, Item previousItem) throws SQLException { + List queueEntries = orcidQueueService.findByEntity(ctx, previousItem); + for (OrcidQueue queueEntry : queueEntries) { + orcidQueueService.delete(ctx, queueEntry); + } + } + + private void replaceOrcidHistoryEntities(Context ctx, Item previousItem, Item latestItem) throws SQLException { + List entries = orcidHistoryService.findByEntity(ctx, previousItem); + for (OrcidHistory entry : entries) { + entry.setEntity(latestItem); + } + } + /** * Update {@link Relationship#latestVersionStatus} of the relationships of both the old version and the new version * of the item. diff --git a/dspace-api/src/test/java/org/dspace/orcid/OrcidQueueConsumerIT.java b/dspace-api/src/test/java/org/dspace/orcid/OrcidQueueConsumerIT.java index f2e528d78cd6..e17fd0072efa 100644 --- a/dspace-api/src/test/java/org/dspace/orcid/OrcidQueueConsumerIT.java +++ b/dspace-api/src/test/java/org/dspace/orcid/OrcidQueueConsumerIT.java @@ -23,6 +23,7 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; import java.sql.SQLException; import java.time.Instant; @@ -41,13 +42,19 @@ import org.dspace.content.Item; import org.dspace.content.MetadataValue; import org.dspace.content.RelationshipType; +import org.dspace.content.WorkspaceItem; import org.dspace.content.factory.ContentServiceFactory; +import org.dspace.content.service.InstallItemService; import org.dspace.content.service.ItemService; +import org.dspace.content.service.WorkspaceItemService; import org.dspace.orcid.consumer.OrcidQueueConsumer; import org.dspace.orcid.factory.OrcidServiceFactory; import org.dspace.orcid.service.OrcidQueueService; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; +import org.dspace.utils.DSpace; +import org.dspace.versioning.Version; +import org.dspace.versioning.service.VersioningService; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -64,8 +71,15 @@ public class OrcidQueueConsumerIT extends AbstractIntegrationTestWithDatabase { private ItemService itemService = ContentServiceFactory.getInstance().getItemService(); + private WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService(); + + private InstallItemService installItemService = ContentServiceFactory.getInstance().getInstallItemService(); + private ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService(); + private VersioningService versioningService = new DSpace().getServiceManager() + .getServicesByType(VersioningService.class).get(0); + private Collection profileCollection; @Before @@ -763,6 +777,177 @@ public void testWithManyInsertionAndDeletionOfSameMetadataValue() throws Excepti } + @Test + public void testOrcidQueueRecordCreationForPublicationWithNotFoundAuthority() throws Exception { + + context.turnOffAuthorisationSystem(); + + Item profile = ItemBuilder.createItem(context, profileCollection) + .withTitle("Test User") + .withOrcidIdentifier("0000-1111-2222-3333") + .withOrcidAccessToken("ab4d18a0-8d9a-40f1-b601-a417255c8d20", eperson) + .withOrcidSynchronizationPublicationsPreference(ALL) + .build(); + + Collection publicationCollection = createCollection("Publications", "Publication"); + + Item publication = ItemBuilder.createItem(context, publicationCollection) + .withTitle("Test publication") + .withAuthor("First User") + .withAuthor("Test User") + .build(); + + EntityType publicationType = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); + EntityType personType = EntityTypeBuilder.createEntityTypeBuilder(context, "Person").build(); + + RelationshipType isAuthorOfPublication = createRelationshipTypeBuilder(context, personType, publicationType, + "isAuthorOfPublication", + "isPublicationOfAuthor", 0, null, 0, + null).build(); + + RelationshipBuilder.createRelationshipBuilder(context, profile, publication, isAuthorOfPublication).build(); + + context.restoreAuthSystemState(); + context.commit(); + + List orcidQueueRecords = orcidQueueService.findAll(context); + assertThat(orcidQueueRecords, hasSize(1)); + assertThat(orcidQueueRecords.get(0), matches(profile, publication, "Publication", INSERT)); + } + + @Test + public void testOrcidQueueWithItemVersioning() throws Exception { + + context.turnOffAuthorisationSystem(); + + Item profile = ItemBuilder.createItem(context, profileCollection) + .withTitle("Test User") + .withOrcidIdentifier("0000-1111-2222-3333") + .withOrcidAccessToken("ab4d18a0-8d9a-40f1-b601-a417255c8d20", eperson) + .withOrcidSynchronizationPublicationsPreference(ALL) + .build(); + + Collection publicationCollection = createCollection("Publications", "Publication"); + + Item publication = ItemBuilder.createItem(context, publicationCollection) + .withTitle("Test publication") + .withAuthor("Test User") + .build(); + + EntityType publicationType = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); + EntityType personType = EntityTypeBuilder.createEntityTypeBuilder(context, "Person").build(); + + RelationshipType isAuthorOfPublication = createRelationshipTypeBuilder(context, personType, publicationType, + "isAuthorOfPublication", + "isPublicationOfAuthor", 0, null, 0, + null).build(); + + RelationshipBuilder.createRelationshipBuilder(context, profile, publication, isAuthorOfPublication).build(); + + context.restoreAuthSystemState(); + context.commit(); + + List orcidQueueRecords = orcidQueueService.findAll(context); + assertThat(orcidQueueRecords, hasSize(1)); + assertThat(orcidQueueRecords.get(0), matches(profile, publication, "Publication", INSERT)); + + context.turnOffAuthorisationSystem(); + Version newVersion = versioningService.createNewVersion(context, publication); + context.restoreAuthSystemState(); + Item newPublication = newVersion.getItem(); + assertThat(newPublication.isArchived(), is(false)); + + context.commit(); + + orcidQueueRecords = orcidQueueService.findAll(context); + assertThat(orcidQueueRecords, hasSize(1)); + assertThat(orcidQueueRecords.get(0), matches(profile, publication, "Publication", INSERT)); + + WorkspaceItem workspaceItem = workspaceItemService.findByItem(context, newVersion.getItem()); + context.turnOffAuthorisationSystem(); + + installItemService.installItem(context, workspaceItem); + + context.restoreAuthSystemState(); + context.commit(); + + orcidQueueRecords = orcidQueueService.findAll(context); + assertThat(orcidQueueRecords, hasSize(1)); + assertThat(orcidQueueRecords.get(0), matches(profile, newPublication, "Publication", INSERT)); + } + + @Test + public void testOrcidQueueUpdateWithItemVersioning() throws Exception { + + context.turnOffAuthorisationSystem(); + + Item profile = ItemBuilder.createItem(context, profileCollection) + .withTitle("Test User") + .withOrcidIdentifier("0000-1111-2222-3333") + .withOrcidAccessToken("ab4d18a0-8d9a-40f1-b601-a417255c8d20", eperson) + .withOrcidSynchronizationPublicationsPreference(ALL) + .build(); + + Collection publicationCollection = createCollection("Publications", "Publication"); + + Item publication = ItemBuilder.createItem(context, publicationCollection) + .withTitle("Test publication") + .build(); + + OrcidHistory orcidHistory = OrcidHistoryBuilder.createOrcidHistory(context, profile, publication) + .withDescription("Test publication") + .withOperation(OrcidOperation.INSERT) + .withPutCode("12345") + .withStatus(201) + .build(); + + addMetadata(publication, "dc", "contributor", "author", "Test User", null); + + EntityType publicationType = EntityTypeBuilder.createEntityTypeBuilder(context, "Publication").build(); + EntityType personType = EntityTypeBuilder.createEntityTypeBuilder(context, "Person").build(); + + RelationshipType isAuthorOfPublication = + createRelationshipTypeBuilder( + context, personType, publicationType, + "isAuthorOfPublication", + "isPublicationOfAuthor", 0, null, 0, + null + ).build(); + + RelationshipBuilder.createRelationshipBuilder(context, profile, publication, isAuthorOfPublication).build(); + + context.commit(); + + List orcidQueueRecords = orcidQueueService.findAll(context); + assertThat(orcidQueueRecords, hasSize(1)); + assertThat(orcidQueueRecords.get(0), matches(profile, publication, "Publication", "12345", UPDATE)); + + Version newVersion = versioningService.createNewVersion(context, publication); + Item newPublication = newVersion.getItem(); + assertThat(newPublication.isArchived(), is(false)); + + context.commit(); + + orcidQueueRecords = orcidQueueService.findAll(context); + assertThat(orcidQueueRecords, hasSize(1)); + assertThat(orcidQueueRecords.get(0), matches(profile, publication, "Publication", "12345", UPDATE)); + + WorkspaceItem workspaceItem = workspaceItemService.findByItem(context, newVersion.getItem()); + installItemService.installItem(context, workspaceItem); + + context.commit(); + + context.restoreAuthSystemState(); + + orcidQueueRecords = orcidQueueService.findAll(context); + assertThat(orcidQueueRecords, hasSize(1)); + assertThat(orcidQueueRecords.get(0), matches(profile, newPublication, "Publication", "12345", UPDATE)); + + orcidHistory = context.reloadEntity(orcidHistory); + assertThat(orcidHistory.getEntity(), is(newPublication)); + + } + private void addMetadata(Item item, String schema, String element, String qualifier, String value, String authority) throws Exception { context.turnOffAuthorisationSystem(); From dc126f7e943e372c507348a349a302bda57c86c1 Mon Sep 17 00:00:00 2001 From: Jens Vannerum Date: Mon, 22 Jul 2024 15:08:59 +0200 Subject: [PATCH 015/226] 116542: fix issues with CSV importing and the Any language being set on metadata values (cherry picked from commit e03c402a9dfdc8df798ded03c96f23a2dfff0eea) --- .../org/dspace/administer/StructBuilder.java | 2 +- .../org/dspace/app/bulkedit/DSpaceCSV.java | 18 ++++++ .../java/org/dspace/content/Collection.java | 2 +- .../org/dspace/content/MetadataValue.java | 4 ++ .../dspace/app/bulkedit/MetadataImportIT.java | 27 +++++++- .../builder/AbstractDSpaceObjectBuilder.java | 3 +- .../dspace/content/ItemComparatorTest.java | 64 +++++++++---------- .../java/org/dspace/content/ItemTest.java | 34 +++++----- .../content/dao/RelationshipDAOImplIT.java | 4 +- .../dao/RelationshipTypeDAOImplIT.java | 4 +- .../org/dspace/app/rest/PatchMetadataIT.java | 2 +- .../rest/RelationshipRestRepositoryIT.java | 26 ++++---- 12 files changed, 118 insertions(+), 72 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/administer/StructBuilder.java b/dspace-api/src/main/java/org/dspace/administer/StructBuilder.java index 13a1b3b5bbf8..8bbcfe0ff753 100644 --- a/dspace-api/src/main/java/org/dspace/administer/StructBuilder.java +++ b/dspace-api/src/main/java/org/dspace/administer/StructBuilder.java @@ -802,7 +802,7 @@ private static Element[] handleCollections(Context context, // default the short description to the empty string collectionService.setMetadataSingleValue(context, collection, - MD_SHORT_DESCRIPTION, Item.ANY, " "); + MD_SHORT_DESCRIPTION, null, " "); // import the rest of the metadata for (Map.Entry entry : collectionMap.entrySet()) { diff --git a/dspace-api/src/main/java/org/dspace/app/bulkedit/DSpaceCSV.java b/dspace-api/src/main/java/org/dspace/app/bulkedit/DSpaceCSV.java index cbc052b5573f..3533a2397b3d 100644 --- a/dspace-api/src/main/java/org/dspace/app/bulkedit/DSpaceCSV.java +++ b/dspace-api/src/main/java/org/dspace/app/bulkedit/DSpaceCSV.java @@ -188,6 +188,15 @@ public DSpaceCSV(InputStream inputStream, Context c) throws Exception { // Verify that the heading is valid in the metadata registry String[] clean = element.split("\\["); String[] parts = clean[0].split("\\."); + // Check language if present, if it's ANY then throw an exception + if (clean.length > 1 && clean[1].equals(Item.ANY + "]")) { + throw new MetadataImportInvalidHeadingException("Language ANY (*) was found in the heading " + + "of the metadata value to import, " + + "this should never be the case", + MetadataImportInvalidHeadingException.ENTRY, + columnCounter); + + } if (parts.length < 2) { throw new MetadataImportInvalidHeadingException(element, @@ -223,6 +232,15 @@ public DSpaceCSV(InputStream inputStream, Context c) throws Exception { } } + // Verify there isn’t already a header that is the same; if it already exists, + // throw MetadataImportInvalidHeadingException + String header = authorityPrefix + element; + if (headings.contains(header)) { + throw new MetadataImportInvalidHeadingException("Duplicate heading found: " + header, + MetadataImportInvalidHeadingException.ENTRY, + columnCounter); + } + // Store the heading headings.add(authorityPrefix + element); } diff --git a/dspace-api/src/main/java/org/dspace/content/Collection.java b/dspace-api/src/main/java/org/dspace/content/Collection.java index 22293dd35ffc..33692d04b3d1 100644 --- a/dspace-api/src/main/java/org/dspace/content/Collection.java +++ b/dspace-api/src/main/java/org/dspace/content/Collection.java @@ -229,7 +229,7 @@ public String getLicenseCollection() { * @throws SQLException if database error */ public void setLicense(Context context, String license) throws SQLException { - getCollectionService().setMetadataSingleValue(context, this, MD_LICENSE, Item.ANY, license); + getCollectionService().setMetadataSingleValue(context, this, MD_LICENSE, null, license); } /** diff --git a/dspace-api/src/main/java/org/dspace/content/MetadataValue.java b/dspace-api/src/main/java/org/dspace/content/MetadataValue.java index 279bdd67c243..dc45579f4ef9 100644 --- a/dspace-api/src/main/java/org/dspace/content/MetadataValue.java +++ b/dspace-api/src/main/java/org/dspace/content/MetadataValue.java @@ -19,6 +19,7 @@ import jakarta.persistence.SequenceGenerator; import jakarta.persistence.Table; import jakarta.persistence.Transient; +import org.apache.commons.lang3.StringUtils; import org.dspace.core.Context; import org.dspace.core.HibernateProxyHelper; import org.dspace.core.ReloadableEntity; @@ -139,6 +140,9 @@ public String getLanguage() { * @param language new language */ public void setLanguage(String language) { + if (StringUtils.equals(language, Item.ANY)) { + language = null; + } this.language = language; } diff --git a/dspace-api/src/test/java/org/dspace/app/bulkedit/MetadataImportIT.java b/dspace-api/src/test/java/org/dspace/app/bulkedit/MetadataImportIT.java index ae079df560ed..de1dcc91c9a1 100644 --- a/dspace-api/src/test/java/org/dspace/app/bulkedit/MetadataImportIT.java +++ b/dspace-api/src/test/java/org/dspace/app/bulkedit/MetadataImportIT.java @@ -75,6 +75,31 @@ public void setUp() throws Exception { context.restoreAuthSystemState(); } + @Test + public void metadataImportTestWithDuplicateHeader() { + String[] csv = {"id,collection,dc.title,dc.title,dc.contributor.author", + "+," + collection.getHandle() + ",\"Test Import 1\",\"Test Import 2\"," + "\"Donald, SmithImported\"," + + "+," + collection.getHandle() + ",\"Test Import 3\",\"Test Import 4\"," + "\"Donald, SmithImported\""}; + // Should throw an exception because of duplicate header + try { + performImportScript(csv); + } catch (Exception e) { + assertTrue(e instanceof MetadataImportInvalidHeadingException); + } + } + + @Test + public void metadataImportTestWithAnyLanguage() { + String[] csv = {"id,collection,dc.title[*],dc.contributor.author", + "+," + collection.getHandle() + ",\"Test Import 1\"," + "\"Donald, SmithImported\""}; + // Should throw an exception because of invalid ANY language (*) in metadata field + try { + performImportScript(csv); + } catch (Exception e) { + assertTrue(e instanceof MetadataImportInvalidHeadingException); + } + } + @Test public void metadataImportTest() throws Exception { String[] csv = {"id,collection,dc.title,dc.contributor.author", @@ -230,7 +255,7 @@ public void metadataImportRemovingValueTest() throws Exception { itemService.getMetadata(item, "dc", "contributor", "author", Item.ANY).get(0).getValue(), "TestAuthorToRemove")); - String[] csv = {"id,collection,dc.title,dc.contributor.author[*]", + String[] csv = {"id,collection,dc.title,dc.contributor.author", item.getID().toString() + "," + personCollection.getHandle() + "," + item.getName() + ","}; performImportScript(csv); item = findItemByName(itemTitle); diff --git a/dspace-api/src/test/java/org/dspace/builder/AbstractDSpaceObjectBuilder.java b/dspace-api/src/test/java/org/dspace/builder/AbstractDSpaceObjectBuilder.java index e7ebd8768e7d..fa7306ad9955 100644 --- a/dspace-api/src/test/java/org/dspace/builder/AbstractDSpaceObjectBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/AbstractDSpaceObjectBuilder.java @@ -18,7 +18,6 @@ import org.dspace.authorize.AuthorizeException; import org.dspace.authorize.ResourcePolicy; import org.dspace.content.DSpaceObject; -import org.dspace.content.Item; import org.dspace.content.service.DSpaceObjectService; import org.dspace.core.Constants; import org.dspace.core.Context; @@ -103,7 +102,7 @@ protected > B setMetadataSingleValue(fi final String qualifier, final String value) { try { - getService().setMetadataSingleValue(context, dso, schema, element, qualifier, Item.ANY, value); + getService().setMetadataSingleValue(context, dso, schema, element, qualifier, null, value); } catch (Exception e) { return handleException(e); } diff --git a/dspace-api/src/test/java/org/dspace/content/ItemComparatorTest.java b/dspace-api/src/test/java/org/dspace/content/ItemComparatorTest.java index 54ff9ce02624..be670d9b5097 100644 --- a/dspace-api/src/test/java/org/dspace/content/ItemComparatorTest.java +++ b/dspace-api/src/test/java/org/dspace/content/ItemComparatorTest.java @@ -141,37 +141,37 @@ public void testCompare() throws SQLException { assertTrue("testCompare 0", result == 0); ic = new ItemComparator("test", "one", Item.ANY, true); - itemService.addMetadata(context, one, "dc", "test", "one", Item.ANY, "1"); + itemService.addMetadata(context, one, "dc", "test", "one", null, "1"); result = ic.compare(one, two); assertTrue("testCompare 1", result >= 1); itemService.clearMetadata(context, one, "dc", "test", "one", Item.ANY); ic = new ItemComparator("test", "one", Item.ANY, true); - itemService.addMetadata(context, two, "dc", "test", "one", Item.ANY, "1"); + itemService.addMetadata(context, two, "dc", "test", "one", null, "1"); result = ic.compare(one, two); assertTrue("testCompare 2", result <= -1); itemService.clearMetadata(context, two, "dc", "test", "one", Item.ANY); //value in both items ic = new ItemComparator("test", "one", Item.ANY, true); - itemService.addMetadata(context, one, "dc", "test", "one", Item.ANY, "1"); - itemService.addMetadata(context, two, "dc", "test", "one", Item.ANY, "2"); + itemService.addMetadata(context, one, "dc", "test", "one", null, "1"); + itemService.addMetadata(context, two, "dc", "test", "one", null, "2"); result = ic.compare(one, two); assertTrue("testCompare 3", result <= -1); itemService.clearMetadata(context, one, "dc", "test", "one", Item.ANY); itemService.clearMetadata(context, two, "dc", "test", "one", Item.ANY); ic = new ItemComparator("test", "one", Item.ANY, true); - itemService.addMetadata(context, one, "dc", "test", "one", Item.ANY, "1"); - itemService.addMetadata(context, two, "dc", "test", "one", Item.ANY, "1"); + itemService.addMetadata(context, one, "dc", "test", "one", null, "1"); + itemService.addMetadata(context, two, "dc", "test", "one", null, "1"); result = ic.compare(one, two); assertTrue("testCompare 4", result == 0); itemService.clearMetadata(context, one, "dc", "test", "one", Item.ANY); itemService.clearMetadata(context, two, "dc", "test", "one", Item.ANY); ic = new ItemComparator("test", "one", Item.ANY, true); - itemService.addMetadata(context, one, "dc", "test", "one", Item.ANY, "2"); - itemService.addMetadata(context, two, "dc", "test", "one", Item.ANY, "1"); + itemService.addMetadata(context, one, "dc", "test", "one", null, "2"); + itemService.addMetadata(context, two, "dc", "test", "one", null, "1"); result = ic.compare(one, two); assertTrue("testCompare 5", result >= 1); itemService.clearMetadata(context, one, "dc", "test", "one", Item.ANY); @@ -179,60 +179,60 @@ public void testCompare() throws SQLException { //multiple values (min, max) ic = new ItemComparator("test", "one", Item.ANY, true); - itemService.addMetadata(context, one, "dc", "test", "one", Item.ANY, "0"); - itemService.addMetadata(context, one, "dc", "test", "one", Item.ANY, "1"); - itemService.addMetadata(context, two, "dc", "test", "one", Item.ANY, "2"); - itemService.addMetadata(context, two, "dc", "test", "one", Item.ANY, "3"); + itemService.addMetadata(context, one, "dc", "test", "one", null, "0"); + itemService.addMetadata(context, one, "dc", "test", "one", null, "1"); + itemService.addMetadata(context, two, "dc", "test", "one", null, "2"); + itemService.addMetadata(context, two, "dc", "test", "one", null, "3"); result = ic.compare(one, two); assertTrue("testCompare 3", result <= -1); itemService.clearMetadata(context, one, "dc", "test", "one", Item.ANY); itemService.clearMetadata(context, two, "dc", "test", "one", Item.ANY); ic = new ItemComparator("test", "one", Item.ANY, true); - itemService.addMetadata(context, one, "dc", "test", "one", Item.ANY, "0"); - itemService.addMetadata(context, one, "dc", "test", "one", Item.ANY, "1"); - itemService.addMetadata(context, two, "dc", "test", "one", Item.ANY, "-1"); - itemService.addMetadata(context, two, "dc", "test", "one", Item.ANY, "1"); + itemService.addMetadata(context, one, "dc", "test", "one", null, "0"); + itemService.addMetadata(context, one, "dc", "test", "one", null, "1"); + itemService.addMetadata(context, two, "dc", "test", "one", null, "-1"); + itemService.addMetadata(context, two, "dc", "test", "one", null, "1"); result = ic.compare(one, two); assertTrue("testCompare 4", result == 0); itemService.clearMetadata(context, one, "dc", "test", "one", Item.ANY); itemService.clearMetadata(context, two, "dc", "test", "one", Item.ANY); ic = new ItemComparator("test", "one", Item.ANY, true); - itemService.addMetadata(context, one, "dc", "test", "one", Item.ANY, "1"); - itemService.addMetadata(context, one, "dc", "test", "one", Item.ANY, "2"); - itemService.addMetadata(context, two, "dc", "test", "one", Item.ANY, "1"); - itemService.addMetadata(context, two, "dc", "test", "one", Item.ANY, "-1"); + itemService.addMetadata(context, one, "dc", "test", "one", null, "1"); + itemService.addMetadata(context, one, "dc", "test", "one", null, "2"); + itemService.addMetadata(context, two, "dc", "test", "one", null, "1"); + itemService.addMetadata(context, two, "dc", "test", "one", null, "-1"); result = ic.compare(one, two); assertTrue("testCompare 5", result >= 1); itemService.clearMetadata(context, one, "dc", "test", "one", Item.ANY); itemService.clearMetadata(context, two, "dc", "test", "one", Item.ANY); ic = new ItemComparator("test", "one", Item.ANY, false); - itemService.addMetadata(context, one, "dc", "test", "one", Item.ANY, "1"); - itemService.addMetadata(context, one, "dc", "test", "one", Item.ANY, "2"); - itemService.addMetadata(context, two, "dc", "test", "one", Item.ANY, "2"); - itemService.addMetadata(context, two, "dc", "test", "one", Item.ANY, "3"); + itemService.addMetadata(context, one, "dc", "test", "one", null, "1"); + itemService.addMetadata(context, one, "dc", "test", "one", null, "2"); + itemService.addMetadata(context, two, "dc", "test", "one", null, "2"); + itemService.addMetadata(context, two, "dc", "test", "one", null, "3"); result = ic.compare(one, two); assertTrue("testCompare 3", result <= -1); itemService.clearMetadata(context, one, "dc", "test", "one", Item.ANY); itemService.clearMetadata(context, two, "dc", "test", "one", Item.ANY); ic = new ItemComparator("test", "one", Item.ANY, false); - itemService.addMetadata(context, one, "dc", "test", "one", Item.ANY, "1"); - itemService.addMetadata(context, one, "dc", "test", "one", Item.ANY, "2"); - itemService.addMetadata(context, two, "dc", "test", "one", Item.ANY, "1"); - itemService.addMetadata(context, two, "dc", "test", "one", Item.ANY, "5"); + itemService.addMetadata(context, one, "dc", "test", "one", null, "1"); + itemService.addMetadata(context, one, "dc", "test", "one", null, "2"); + itemService.addMetadata(context, two, "dc", "test", "one", null, "1"); + itemService.addMetadata(context, two, "dc", "test", "one", null, "5"); result = ic.compare(one, two); assertTrue("testCompare 4", result == 0); itemService.clearMetadata(context, one, "dc", "test", "one", Item.ANY); itemService.clearMetadata(context, two, "dc", "test", "one", Item.ANY); ic = new ItemComparator("test", "one", Item.ANY, false); - itemService.addMetadata(context, one, "dc", "test", "one", Item.ANY, "2"); - itemService.addMetadata(context, one, "dc", "test", "one", Item.ANY, "3"); - itemService.addMetadata(context, two, "dc", "test", "one", Item.ANY, "1"); - itemService.addMetadata(context, two, "dc", "test", "one", Item.ANY, "4"); + itemService.addMetadata(context, one, "dc", "test", "one", null, "2"); + itemService.addMetadata(context, one, "dc", "test", "one", null, "3"); + itemService.addMetadata(context, two, "dc", "test", "one", null, "1"); + itemService.addMetadata(context, two, "dc", "test", "one", null, "4"); result = ic.compare(one, two); assertTrue("testCompare 5", result >= 1); itemService.clearMetadata(context, one, "dc", "test", "one", Item.ANY); diff --git a/dspace-api/src/test/java/org/dspace/content/ItemTest.java b/dspace-api/src/test/java/org/dspace/content/ItemTest.java index aaa28769dca6..0ba1136d8f0a 100644 --- a/dspace-api/src/test/java/org/dspace/content/ItemTest.java +++ b/dspace-api/src/test/java/org/dspace/content/ItemTest.java @@ -518,11 +518,11 @@ public void testAddMetadata_5args_1() throws SQLException { String schema = "dc"; String element = "contributor"; String qualifier = "author"; - String lang = Item.ANY; + String lang = null; String[] values = {"value0", "value1"}; itemService.addMetadata(context, it, schema, element, qualifier, lang, Arrays.asList(values)); - List dc = itemService.getMetadata(it, schema, element, qualifier, lang); + List dc = itemService.getMetadata(it, schema, element, qualifier, Item.ANY); assertThat("testAddMetadata_5args_1 0", dc, notNullValue()); assertTrue("testAddMetadata_5args_1 1", dc.size() == 2); assertThat("testAddMetadata_5args_1 2", dc.get(0).getMetadataField().getMetadataSchema().getName(), @@ -563,13 +563,13 @@ public void testAddMetadata_7args_1_authority() String schema = "dc"; String element = "language"; String qualifier = "iso"; - String lang = Item.ANY; + String lang = null; List values = Arrays.asList("en_US", "en"); List authorities = Arrays.asList("accepted", "uncertain"); List confidences = Arrays.asList(0, 0); itemService.addMetadata(context, it, schema, element, qualifier, lang, values, authorities, confidences); - List dc = itemService.getMetadata(it, schema, element, qualifier, lang); + List dc = itemService.getMetadata(it, schema, element, qualifier, Item.ANY); assertThat("testAddMetadata_7args_1 0", dc, notNullValue()); assertTrue("testAddMetadata_7args_1 1", dc.size() == 2); assertThat("testAddMetadata_7args_1 2", dc.get(0).getMetadataField().getMetadataSchema().getName(), @@ -600,13 +600,13 @@ public void testAddMetadata_7args_1_noauthority() throws SQLException { String schema = "dc"; String element = "contributor"; String qualifier = "author"; - String lang = Item.ANY; + String lang = null; List values = Arrays.asList("value0", "value1"); List authorities = Arrays.asList("auth0", "auth2"); List confidences = Arrays.asList(0, 0); itemService.addMetadata(context, it, schema, element, qualifier, lang, values, authorities, confidences); - List dc = itemService.getMetadata(it, schema, element, qualifier, lang); + List dc = itemService.getMetadata(it, schema, element, qualifier, Item.ANY); assertThat("testAddMetadata_7args_1 0", dc, notNullValue()); assertTrue("testAddMetadata_7args_1 1", dc.size() == 2); assertThat("testAddMetadata_7args_1 2", dc.get(0).getMetadataField().getMetadataSchema().getName(), @@ -719,13 +719,13 @@ public void testAddMetadata_7args_2_authority() throws SQLException { String schema = "dc"; String element = "language"; String qualifier = "iso"; - String lang = Item.ANY; + String lang = null; String values = "en"; String authorities = "accepted"; int confidences = 0; itemService.addMetadata(context, it, schema, element, qualifier, lang, values, authorities, confidences); - List dc = itemService.getMetadata(it, schema, element, qualifier, lang); + List dc = itemService.getMetadata(it, schema, element, qualifier, Item.ANY); assertThat("testAddMetadata_7args_2 0", dc, notNullValue()); assertTrue("testAddMetadata_7args_2 1", dc.size() == 1); assertThat("testAddMetadata_7args_2 2", dc.get(0).getMetadataField().getMetadataSchema().getName(), @@ -748,13 +748,13 @@ public void testAddMetadata_7args_2_noauthority() throws SQLException { String schema = "dc"; String element = "contributor"; String qualifier = "editor"; - String lang = Item.ANY; + String lang = null; String values = "value0"; String authorities = "auth0"; int confidences = 0; itemService.addMetadata(context, it, schema, element, qualifier, lang, values, authorities, confidences); - List dc = itemService.getMetadata(it, schema, element, qualifier, lang); + List dc = itemService.getMetadata(it, schema, element, qualifier, Item.ANY); assertThat("testAddMetadata_7args_2 0", dc, notNullValue()); assertTrue("testAddMetadata_7args_2 1", dc.size() == 1); assertThat("testAddMetadata_7args_2 2", dc.get(0).getMetadataField().getMetadataSchema().getName(), @@ -811,13 +811,13 @@ public void testClearMetadata() throws SQLException { String schema = "dc"; String element = "contributor"; String qualifier = "author"; - String lang = Item.ANY; + String lang = null; String values = "value0"; itemService.addMetadata(context, it, schema, element, qualifier, lang, values); - itemService.clearMetadata(context, it, schema, element, qualifier, lang); + itemService.clearMetadata(context, it, schema, element, qualifier, Item.ANY); - List dc = itemService.getMetadata(it, schema, element, qualifier, lang); + List dc = itemService.getMetadata(it, schema, element, qualifier, Item.ANY); assertThat("testClearMetadata 0", dc, notNullValue()); assertTrue("testClearMetadata 1", dc.size() == 0); } @@ -859,11 +859,11 @@ public void testGetCollections() throws Exception { context.turnOffAuthorisationSystem(); Collection collection = collectionService.create(context, owningCommunity); collectionService.setMetadataSingleValue(context, collection, MetadataSchemaEnum.DC.getName(), - "title", null, Item.ANY, "collection B"); + "title", null, null, "collection B"); it.addCollection(collection); collection = collectionService.create(context, owningCommunity); collectionService.setMetadataSingleValue(context, collection, MetadataSchemaEnum.DC.getName(), - "title", null, Item.ANY, "collection A"); + "title", null, null, "collection A"); it.addCollection(collection); context.restoreAuthSystemState(); assertThat("testGetCollections 0", it.getCollections(), notNullValue()); @@ -1772,7 +1772,7 @@ public void testFindByMetadataField() throws Exception { // add new metadata to item context.turnOffAuthorisationSystem(); - itemService.addMetadata(context, it, schema, element, qualifier, Item.ANY, value); + itemService.addMetadata(context, it, schema, element, qualifier, null, value); itemService.update(context, it); context.restoreAuthSystemState(); @@ -1837,7 +1837,7 @@ public void testFindByAuthorityValue() throws Exception { // add new metadata (with authority) to item context.turnOffAuthorisationSystem(); - itemService.addMetadata(context, it, schema, element, qualifier, Item.ANY, value, authority, confidence); + itemService.addMetadata(context, it, schema, element, qualifier, null, value, authority, confidence); itemService.update(context, it); context.restoreAuthSystemState(); diff --git a/dspace-api/src/test/java/org/dspace/content/dao/RelationshipDAOImplIT.java b/dspace-api/src/test/java/org/dspace/content/dao/RelationshipDAOImplIT.java index 2d08223b2e3e..20710ab5f25b 100644 --- a/dspace-api/src/test/java/org/dspace/content/dao/RelationshipDAOImplIT.java +++ b/dspace-api/src/test/java/org/dspace/content/dao/RelationshipDAOImplIT.java @@ -87,8 +87,8 @@ public void init() { WorkspaceItem workspaceItemTwo = workspaceItemService.create(context, collection, false); itemOne = installItemService.installItem(context, workspaceItem); itemTwo = installItemService.installItem(context, workspaceItemTwo); - itemService.addMetadata(context, itemOne, "dspace", "entity", "type", Item.ANY, "Publication"); - itemService.addMetadata(context, itemTwo, "dspace", "entity", "type", Item.ANY, "Person"); + itemService.addMetadata(context, itemOne, "dspace", "entity", "type", null, "Publication"); + itemService.addMetadata(context, itemTwo, "dspace", "entity", "type", null, "Person"); itemService.update(context, itemOne); itemService.update(context, itemTwo); entityTypeOne = entityTypeService.create(context, "Person"); diff --git a/dspace-api/src/test/java/org/dspace/content/dao/RelationshipTypeDAOImplIT.java b/dspace-api/src/test/java/org/dspace/content/dao/RelationshipTypeDAOImplIT.java index ff7d03b49f6d..d76e5faa804a 100644 --- a/dspace-api/src/test/java/org/dspace/content/dao/RelationshipTypeDAOImplIT.java +++ b/dspace-api/src/test/java/org/dspace/content/dao/RelationshipTypeDAOImplIT.java @@ -82,8 +82,8 @@ public void init() { WorkspaceItem workspaceItemTwo = workspaceItemService.create(context, collection, false); itemOne = installItemService.installItem(context, workspaceItem); itemTwo = installItemService.installItem(context, workspaceItemTwo); - itemService.addMetadata(context, itemOne, "dspace", "entity", "type", Item.ANY, "Publication"); - itemService.addMetadata(context, itemTwo, "dspace", "entity", "type", Item.ANY, "Person"); + itemService.addMetadata(context, itemOne, "dspace", "entity", "type", null, "Publication"); + itemService.addMetadata(context, itemTwo, "dspace", "entity", "type", null, "Person"); itemService.update(context, itemOne); itemService.update(context, itemTwo); entityTypeOne = entityTypeService.create(context, "Person"); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/PatchMetadataIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/PatchMetadataIT.java index eec7ce95f8d4..9b9db41a7c92 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/PatchMetadataIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/PatchMetadataIT.java @@ -261,7 +261,7 @@ private void initSimplePublicationItem() throws Exception { for (String author : authorsOriginalOrder) { itemService.addMetadata( - context, publicationItem, "dc", "contributor", "author", Item.ANY, author + context, publicationItem, "dc", "contributor", "author", null, author ); } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/RelationshipRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/RelationshipRestRepositoryIT.java index 641f30149b73..1bf4e2f41202 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/RelationshipRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/RelationshipRestRepositoryIT.java @@ -818,7 +818,7 @@ public void addRelationshipsAndMetadataToValidatePlaceTest() throws Exception { // Make sure we grab the latest instance of the Item from the database publication1 = itemService.find(context, publication1.getID()); // Add a plain text dc.contributor.author value - itemService.addMetadata(context, publication1, "dc", "contributor", "author", Item.ANY, "plain text"); + itemService.addMetadata(context, publication1, "dc", "contributor", "author", null, "plain text"); itemService.update(context, publication1); List list = itemService.getMetadata(publication1, "dc", "contributor", "author", Item.ANY); @@ -884,7 +884,7 @@ public void addRelationshipsAndMetadataToValidatePlaceTest() throws Exception { // Ensure we have the latest instance of the Item from the database publication1 = itemService.find(context, publication1.getID()); // Add a fourth dc.contributor.author mdv - itemService.addMetadata(context, publication1, "dc", "contributor", "author", Item.ANY, "plain text two"); + itemService.addMetadata(context, publication1, "dc", "contributor", "author", null, "plain text two"); itemService.update(context, publication1); context.restoreAuthSystemState(); @@ -953,7 +953,7 @@ public void addRelationshipsAndMetadataToValidatePlaceTest() throws Exception { context.turnOffAuthorisationSystem(); // The following additions of Metadata will perform the same sequence of logic and tests as described above publication1 = itemService.find(context, publication1.getID()); - itemService.addMetadata(context, publication1, "dc", "contributor", "author", Item.ANY, "plain text three"); + itemService.addMetadata(context, publication1, "dc", "contributor", "author", null, "plain text three"); itemService.update(context, publication1); context.restoreAuthSystemState(); @@ -983,10 +983,10 @@ public void addRelationshipsAndMetadataToValidatePlaceTest() throws Exception { context.turnOffAuthorisationSystem(); publication1 = itemService.find(context, publication1.getID()); - itemService.addMetadata(context, publication1, "dc", "contributor", "author", Item.ANY, "plain text four"); - itemService.addMetadata(context, publication1, "dc", "contributor", "author", Item.ANY, "plain text five"); - itemService.addMetadata(context, publication1, "dc", "contributor", "author", Item.ANY, "plain text six"); - itemService.addMetadata(context, publication1, "dc", "contributor", "author", Item.ANY, "plain text seven"); + itemService.addMetadata(context, publication1, "dc", "contributor", "author", null, "plain text four"); + itemService.addMetadata(context, publication1, "dc", "contributor", "author", null, "plain text five"); + itemService.addMetadata(context, publication1, "dc", "contributor", "author", null, "plain text six"); + itemService.addMetadata(context, publication1, "dc", "contributor", "author", null, "plain text seven"); itemService.update(context, publication1); context.restoreAuthSystemState(); @@ -1114,7 +1114,7 @@ public void deleteMetadataValueAndValidatePlace() throws Exception { publication1 = itemService.find(context, publication1.getID()); // Add a plain text metadatavalue to the publication // After this addition, the list of authors should like like "Donald Smith", "plain text" - itemService.addMetadata(context, publication1, "dc", "contributor", "author", Item.ANY, "plain text"); + itemService.addMetadata(context, publication1, "dc", "contributor", "author", null, "plain text"); itemService.update(context, publication1); context.restoreAuthSystemState(); List list = itemService.getMetadata(publication1, "dc", "contributor", "author", Item.ANY); @@ -1157,7 +1157,7 @@ public void deleteMetadataValueAndValidatePlace() throws Exception { // Get the publication from the DB again to ensure that we have the latest object publication1 = itemService.find(context, publication1.getID()); // Add a fourth metadata value to the publication - itemService.addMetadata(context, publication1, "dc", "contributor", "author", Item.ANY, "plain text two"); + itemService.addMetadata(context, publication1, "dc", "contributor", "author", null, "plain text two"); itemService.update(context, publication1); context.restoreAuthSystemState(); list = itemService.getMetadata(publication1, "dc", "contributor", "author", Item.ANY); @@ -1195,7 +1195,7 @@ public void deleteMetadataValueAndValidatePlace() throws Exception { context.turnOffAuthorisationSystem(); publication1 = itemService.find(context, publication1.getID()); // Create another plain text metadata value on the publication - itemService.addMetadata(context, publication1, "dc", "contributor", "author", Item.ANY, "plain text three"); + itemService.addMetadata(context, publication1, "dc", "contributor", "author", null, "plain text three"); itemService.update(context, publication1); context.restoreAuthSystemState(); list = itemService.getMetadata(publication1, "dc", "contributor", "author", Item.ANY); @@ -1323,7 +1323,7 @@ public void deleteRelationshipsAndValidatePlace() throws Exception { publication1 = itemService.find(context, publication1.getID()); // Add a plain text metadatavalue to the publication // After this addition, the list of authors should like like "Donald Smith", "plain text" - itemService.addMetadata(context, publication1, "dc", "contributor", "author", Item.ANY, "plain text"); + itemService.addMetadata(context, publication1, "dc", "contributor", "author", null, "plain text"); itemService.update(context, publication1); context.restoreAuthSystemState(); List list = itemService.getMetadata(publication1, "dc", "contributor", "author", Item.ANY); @@ -1367,7 +1367,7 @@ public void deleteRelationshipsAndValidatePlace() throws Exception { // Get the publication from the DB again to ensure that we have the latest object publication1 = itemService.find(context, publication1.getID()); // Add a fourth metadata value to the publication - itemService.addMetadata(context, publication1, "dc", "contributor", "author", Item.ANY, "plain text two"); + itemService.addMetadata(context, publication1, "dc", "contributor", "author", null, "plain text two"); itemService.update(context, publication1); context.restoreAuthSystemState(); list = itemService.getMetadata(publication1, "dc", "contributor", "author", Item.ANY); @@ -1405,7 +1405,7 @@ public void deleteRelationshipsAndValidatePlace() throws Exception { context.turnOffAuthorisationSystem(); publication1 = itemService.find(context, publication1.getID()); // Create another plain text metadata value on the publication - itemService.addMetadata(context, publication1, "dc", "contributor", "author", Item.ANY, "plain text three"); + itemService.addMetadata(context, publication1, "dc", "contributor", "author", null, "plain text three"); itemService.update(context, publication1); context.restoreAuthSystemState(); list = itemService.getMetadata(publication1, "dc", "contributor", "author", Item.ANY); From c7696649af8da714e7469c843fb9a2afb14cf063 Mon Sep 17 00:00:00 2001 From: Jens Vannerum Date: Tue, 23 Jul 2024 12:16:28 +0200 Subject: [PATCH 016/226] 116542: resolve issues after merge with latest main branch (cherry picked from commit be179bad6ab25a96d4b43d3ef73a7c065557e266) --- .../test/java/org/dspace/content/ItemTest.java | 18 +++++++++--------- .../dspace/content/service/ItemServiceIT.java | 2 +- .../app/rest/EPersonRestRepositoryIT.java | 3 +-- .../controller/LinksetRestControllerIT.java | 4 ++-- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/content/ItemTest.java b/dspace-api/src/test/java/org/dspace/content/ItemTest.java index 0ba1136d8f0a..00dbf2994d98 100644 --- a/dspace-api/src/test/java/org/dspace/content/ItemTest.java +++ b/dspace-api/src/test/java/org/dspace/content/ItemTest.java @@ -544,7 +544,7 @@ public void testAddMetadata_5args_no_values() throws Exception { String schema = "dc"; String element = "contributor"; String qualifier = "author"; - String lang = Item.ANY; + String lang = null; String[] values = {}; itemService.addMetadata(context, it, schema, element, qualifier, lang, Arrays.asList(values)); fail("IllegalArgumentException expected"); @@ -632,7 +632,7 @@ public void testAddMetadata_7args_no_values() throws Exception { String schema = "dc"; String element = "contributor"; String qualifier = "author"; - String lang = Item.ANY; + String lang = null; List values = new ArrayList(); List authorities = new ArrayList(); List confidences = new ArrayList(); @@ -645,7 +645,7 @@ public void testAddMetadata_list_with_virtual_metadata() throws Exception { String schema = "dc"; String element = "contributor"; String qualifier = "author"; - String lang = Item.ANY; + String lang = null; // Create two fake virtual metadata ("virtual::[relationship-id]") values List values = new ArrayList<>(Arrays.asList("uuid-1", "uuid-2")); List authorities = new ArrayList<>(Arrays.asList(Constants.VIRTUAL_AUTHORITY_PREFIX + "relationship-1", @@ -674,7 +674,7 @@ public void testAddMetadata_list_with_virtual_metadata() throws Exception { assertEquals(1, valuesAdded.size()); // Get metadata and ensure new value is the ONLY ONE for this metadata field - List dc = itemService.getMetadata(it, schema, element, qualifier, lang); + List dc = itemService.getMetadata(it, schema, element, qualifier, Item.ANY); assertNotNull(dc); assertEquals(1, dc.size()); assertEquals(schema, dc.get(0).getMetadataField().getMetadataSchema().getName()); @@ -693,11 +693,11 @@ public void testAddMetadata_5args_2() throws SQLException { String schema = "dc"; String element = "contributor"; String qualifier = "author"; - String lang = Item.ANY; + String lang = null; String value = "value0"; itemService.addMetadata(context, it, schema, element, qualifier, lang, value); - List dc = itemService.getMetadata(it, schema, element, qualifier, lang); + List dc = itemService.getMetadata(it, schema, element, qualifier, Item.ANY); assertThat("testAddMetadata_5args_2 0", dc, notNullValue()); assertTrue("testAddMetadata_5args_2 1", dc.size() == 1); assertThat("testAddMetadata_5args_2 2", dc.get(0).getMetadataField().getMetadataSchema().getName(), @@ -772,7 +772,7 @@ public void testAddMetadata_single_virtual_metadata() throws Exception { String schema = "dc"; String element = "contributor"; String qualifier = "author"; - String lang = Item.ANY; + String lang = null; // Create a single fake virtual metadata ("virtual::[relationship-id]") value String value = "uuid-1"; String authority = Constants.VIRTUAL_AUTHORITY_PREFIX + "relationship-1"; @@ -786,7 +786,7 @@ public void testAddMetadata_single_virtual_metadata() throws Exception { assertNull(valuesAdded); // Verify this metadata field does NOT exist on the item - List mv = itemService.getMetadata(it, schema, element, qualifier, lang); + List mv = itemService.getMetadata(it, schema, element, qualifier, Item.ANY); assertNotNull(mv); assertTrue(mv.isEmpty()); @@ -797,7 +797,7 @@ public void testAddMetadata_single_virtual_metadata() throws Exception { assertNull(valuesAdded); // Verify this metadata field does NOT exist on the item - mv = itemService.getMetadata(it, schema, element, qualifier, lang); + mv = itemService.getMetadata(it, schema, element, qualifier, Item.ANY); assertNotNull(mv); assertTrue(mv.isEmpty()); } diff --git a/dspace-api/src/test/java/org/dspace/content/service/ItemServiceIT.java b/dspace-api/src/test/java/org/dspace/content/service/ItemServiceIT.java index 0704c2d98d1c..eee445b3334f 100644 --- a/dspace-api/src/test/java/org/dspace/content/service/ItemServiceIT.java +++ b/dspace-api/src/test/java/org/dspace/content/service/ItemServiceIT.java @@ -198,7 +198,7 @@ public void preserveMetadataOrder() throws Exception { // now just add one metadata to be the last itemService.addMetadata( - context, item, dcSchema, contributorElement, authorQualifier, Item.ANY, "test, latest", null, 0 + context, item, dcSchema, contributorElement, authorQualifier, null, "test, latest", null, 0 ); // now just remove first metadata itemService.removeMetadataValues(context, item, List.of(placeZero)); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/EPersonRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/EPersonRestRepositoryIT.java index dfca8b4328f8..beeef03aec47 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/EPersonRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/EPersonRestRepositoryIT.java @@ -72,7 +72,6 @@ import org.dspace.builder.WorkflowItemBuilder; import org.dspace.content.Collection; import org.dspace.content.Community; -import org.dspace.content.Item; import org.dspace.core.I18nUtil; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; @@ -2120,7 +2119,7 @@ public void patchMultipleReplaceMetadataByAdmin() throws Exception { .build(); this.ePersonService - .addMetadata(context, ePerson, "eperson", "firstname", null, Item.ANY, List.of(first, second, third)); + .addMetadata(context, ePerson, "eperson", "firstname", null, null, List.of(first, second, third)); context.restoreAuthSystemState(); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/signposting/controller/LinksetRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/signposting/controller/LinksetRestControllerIT.java index c5873dd53f42..cf62d5ac0861 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/signposting/controller/LinksetRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/signposting/controller/LinksetRestControllerIT.java @@ -748,7 +748,7 @@ public void findTypedLinkForBitstreamWithType() throws Exception { .withMimeType(bitstreamMimeType) .build(); } - bitstreamService.addMetadata(context, bitstream, "dc", "type", null, Item.ANY, "Article"); + bitstreamService.addMetadata(context, bitstream, "dc", "type", null, null, "Article"); context.restoreAuthSystemState(); @@ -836,7 +836,7 @@ public void findTypedLinkForBitstreamOfWorkspaceItem() throws Exception { .withTitle("Workspace Item") .build(); Item item = workspaceItem.getItem(); - itemService.addMetadata(context, item, "dc", "identifier", "doi", Item.ANY, doi); + itemService.addMetadata(context, item, "dc", "identifier", "doi", null, doi); Bitstream bitstream = null; try (InputStream is = IOUtils.toInputStream(bitstreamContent, CharEncoding.UTF_8)) { From 74d032732298cb372f6ad22cf26ac88488e49a74 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Fri, 2 Aug 2024 14:12:53 +0200 Subject: [PATCH 017/226] fix invalid usage of == operator (cherry picked from commit fa0fb14a185ba8a9c593a3653df302f0446a397c) --- .../src/main/java/org/dspace/content/ItemServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java index 70bdf4b7d950..cceb954ebe2f 100644 --- a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java @@ -1799,7 +1799,7 @@ protected void moveSingleMetadataValue(Context context, Item dso, int place, Met //Retrieve the applicable relationship Relationship rs = relationshipService.find(context, ((RelationshipMetadataValue) rr).getRelationshipId()); - if (rs.getLeftItem() == dso) { + if (rs.getLeftItem().equals(dso)) { rs.setLeftPlace(place); } else { rs.setRightPlace(place); From 19daa72ff40cd172721776f795ff86b028b38c04 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Fri, 2 Aug 2024 17:44:35 +0200 Subject: [PATCH 018/226] use equals instead of == (cherry picked from commit 80de8f6fb567ceb4497596fa714f2b357f1b8b26) --- .../src/main/java/org/dspace/content/EntityServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/content/EntityServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/EntityServiceImpl.java index 9b28203827e0..e83178667840 100644 --- a/dspace-api/src/main/java/org/dspace/content/EntityServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/EntityServiceImpl.java @@ -60,7 +60,7 @@ public List getLeftRelations(Context context, Entity entity) { List fullList = entity.getRelationships(); List listToReturn = new LinkedList<>(); for (Relationship relationship : fullList) { - if (relationship.getLeftItem().getID() == entity.getItem().getID()) { + if (relationship.getLeftItem().getID().equals(entity.getItem().getID())) { listToReturn.add(relationship); } } @@ -72,7 +72,7 @@ public List getRightRelations(Context context, Entity entity) { List fullList = entity.getRelationships(); List listToReturn = new LinkedList<>(); for (Relationship relationship : fullList) { - if (relationship.getRightItem().getID() == entity.getItem().getID()) { + if (relationship.getRightItem().getID().equals(entity.getItem().getID())) { listToReturn.add(relationship); } } From 7b08fdfe9e4b7c3c572fcfba3a14695f1c40164f Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Fri, 2 Aug 2024 17:47:07 +0200 Subject: [PATCH 019/226] use equals instead of == (cherry picked from commit 5e3552ee3885049df34c3fcaf49bfe3028c5dbd0) --- .../java/org/dspace/authorize/ResourcePolicyServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/authorize/ResourcePolicyServiceImpl.java b/dspace-api/src/main/java/org/dspace/authorize/ResourcePolicyServiceImpl.java index 7b93b912378e..86998a2196e7 100644 --- a/dspace-api/src/main/java/org/dspace/authorize/ResourcePolicyServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/authorize/ResourcePolicyServiceImpl.java @@ -417,7 +417,7 @@ public boolean isMyResourcePolicy(Context context, EPerson eperson, Integer id) ResourcePolicy resourcePolicy = resourcePolicyDAO.findOneById(context, id); Group group = resourcePolicy.getGroup(); - if (resourcePolicy.getEPerson() != null && resourcePolicy.getEPerson().getID() == eperson.getID()) { + if (resourcePolicy.getEPerson() != null && resourcePolicy.getEPerson().getID().equals(eperson.getID())) { isMy = true; } else if (group != null && groupService.isMember(context, eperson, group)) { isMy = true; From f0ea00b5cd4c4c9120eb1e744ae11d0ad0977ec0 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Fri, 2 Aug 2024 17:48:28 +0200 Subject: [PATCH 020/226] use equals instead of == (cherry picked from commit d2ef7b01ef1a5d769d764b708be393dbb481fb65) --- .../src/main/java/org/dspace/eperson/GroupServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/eperson/GroupServiceImpl.java b/dspace-api/src/main/java/org/dspace/eperson/GroupServiceImpl.java index 730053e42ce2..3fb20e2f1e6f 100644 --- a/dspace-api/src/main/java/org/dspace/eperson/GroupServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/eperson/GroupServiceImpl.java @@ -147,7 +147,7 @@ public void addMember(Context context, Group group, EPerson e) { public void addMember(Context context, Group groupParent, Group groupChild) throws SQLException { // don't add if it's already a member // and don't add itself - if (groupParent.contains(groupChild) || groupParent.getID() == groupChild.getID()) { + if (groupParent.contains(groupChild) || groupParent.getID().equals(groupChild.getID())) { return; } @@ -178,7 +178,7 @@ public void removeMember(Context context, Group group, EPerson ePerson) throws S Role role = stepByName.getRole(); for (CollectionRole collectionRole : collectionRoles) { if (StringUtils.equals(collectionRole.getRoleId(), role.getId()) - && claimedTask.getWorkflowItem().getCollection() == collectionRole.getCollection()) { + && claimedTask.getWorkflowItem().getCollection().equals(collectionRole.getCollection())) { // Count number of EPersons who are *direct* members of this group int totalDirectEPersons = ePersonService.countByGroups(context, Set.of(group)); // Count number of Groups which have this groupParent as a direct parent From ef5479d77a6f61039caf000b97c5bbceeaff30a0 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Fri, 2 Aug 2024 17:49:14 +0200 Subject: [PATCH 021/226] use equals instead of == (cherry picked from commit a13cc82d405c5aefe00c7bb86d89c7dc8073a39b) --- .../submit/factory/impl/ItemMetadataValueAddPatchOperation.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/ItemMetadataValueAddPatchOperation.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/ItemMetadataValueAddPatchOperation.java index 54dfa6b02c04..8ab9bb451647 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/ItemMetadataValueAddPatchOperation.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/submit/factory/impl/ItemMetadataValueAddPatchOperation.java @@ -214,7 +214,7 @@ private Integer getRelId(String authority) { private void updateRelationshipPlace(Context context, Item dso, int place, Relationship rs) { try { - if (rs.getLeftItem() == dso) { + if (rs.getLeftItem().equals(dso)) { rs.setLeftPlace(place); } else { rs.setRightPlace(place); From 408e8b608f3a5da9bd688c1bb128ecd93552b599 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sun, 4 Aug 2024 10:56:32 +0200 Subject: [PATCH 022/226] README.md: v8 is the current release, not v7 (cherry picked from commit 2b698eff609d510c487ad2331d4e11cd28f64e9a) --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index af9158eff361..2305643fd8e1 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ ## Overview -DSpace open source software is a turnkey repository application used by more than +DSpace open-source software is a turnkey repository application used by more than 2,000 organizations and institutions worldwide to provide durable access to digital resources. For more information, visit http://www.dspace.org/ @@ -20,7 +20,7 @@ DSpace consists of both a Java-based backend and an Angular-based frontend. * The REST Contract is at https://github.com/DSpace/RestContract * Frontend (https://github.com/DSpace/dspace-angular/) is the User Interface built on the REST API -Prior versions of DSpace (v6.x and below) used two different UIs (XMLUI and JSPUI). Those UIs are no longer supported in v7 (and above). +Prior versions of DSpace (v6.x and below) used two different UIs (XMLUI and JSPUI). Those UIs are no longer supported in v7 and above. * A maintenance branch for older versions is still available, see `dspace-6_x` for 6.x maintenance. ## Downloads @@ -33,18 +33,18 @@ Prior versions of DSpace (v6.x and below) used two different UIs (XMLUI and JSPU Documentation for each release may be viewed online or downloaded via our [Documentation Wiki](https://wiki.lyrasis.org/display/DSDOC/). The latest DSpace Installation instructions are available at: -https://wiki.lyrasis.org/display/DSDOC7x/Installing+DSpace +https://wiki.lyrasis.org/display/DSDOC8x/Installing+DSpace Please be aware that, as a Java web application, DSpace requires a database (PostgreSQL) and a servlet container (usually Tomcat) in order to function. More information about these and all other prerequisites can be found in the Installation instructions above. -## Running DSpace 7 in Docker +## Running DSpace 8 in Docker NOTE: At this time, we do not have production-ready Docker images for DSpace. That said, we do have quick-start Docker Compose scripts for development or testing purposes. -See [Running DSpace 7 with Docker Compose](dspace/src/main/docker-compose/README.md) +See [Running DSpace 8 with Docker Compose](dspace/src/main/docker-compose/README.md) ## Contributing @@ -64,7 +64,7 @@ Great Q&A is also available under the [DSpace tag on Stackoverflow](http://stack Additional support options are at https://wiki.lyrasis.org/display/DSPACE/Support DSpace also has an active service provider network. If you'd rather hire a service provider to -install, upgrade, customize or host DSpace, then we recommend getting in touch with one of our +install, upgrade, customize, or host DSpace, then we recommend getting in touch with one of our [Registered Service Providers](http://www.dspace.org/service-providers). ## Issue Tracker @@ -112,7 +112,7 @@ run automatically by [GitHub Actions](https://github.com/DSpace/DSpace/actions?q ``` * How to run only tests of a specific DSpace module ``` - # Before you can run only one module's tests, other modules may need installing into your ~/.m2 + # Before you can run only one module's tests, other modules may need to be installed into your ~/.m2 cd [dspace-src] mvn clean install From 98dee8c2fcdc89263b95b1bacf56a947bdeb93c9 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Sun, 4 Aug 2024 11:04:12 +0200 Subject: [PATCH 023/226] Update README.md (cherry picked from commit 671234b08f909810d798dd950f87d1818b098363) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2305643fd8e1..1d93abe49948 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ ## Overview -DSpace open-source software is a turnkey repository application used by more than +DSpace open source software is a turnkey repository application used by more than 2,000 organizations and institutions worldwide to provide durable access to digital resources. For more information, visit http://www.dspace.org/ From d35946af0a9abbc5dd0bc17f783d376a7fa66f96 Mon Sep 17 00:00:00 2001 From: Kristof De Langhe Date: Tue, 18 Jun 2024 13:52:38 +0200 Subject: [PATCH 024/226] 115693: data-cite xsl targetting dc.identifier.uri fixes doi registration error (cherry picked from commit c5d08f037cb56111b8ef047279f323c06b11a864) --- .../main/java/org/dspace/identifier/DOIIdentifierProvider.java | 1 + dspace/config/crosswalks/DIM2DataCite.xsl | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/identifier/DOIIdentifierProvider.java b/dspace-api/src/main/java/org/dspace/identifier/DOIIdentifierProvider.java index ae31e54f7e96..aff4666fff4b 100644 --- a/dspace-api/src/main/java/org/dspace/identifier/DOIIdentifierProvider.java +++ b/dspace-api/src/main/java/org/dspace/identifier/DOIIdentifierProvider.java @@ -70,6 +70,7 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider { static final char SLASH = '/'; // Metadata field name elements + // Warning: If this metadata field is changed for whatever reason, DIM2DataCite.xsl's template needs to reflect this // TODO: move these to MetadataSchema or some such? public static final String MD_SCHEMA = "dc"; public static final String DOI_ELEMENT = "identifier"; diff --git a/dspace/config/crosswalks/DIM2DataCite.xsl b/dspace/config/crosswalks/DIM2DataCite.xsl index a97d127694ef..d57996e6d8cf 100644 --- a/dspace/config/crosswalks/DIM2DataCite.xsl +++ b/dspace/config/crosswalks/DIM2DataCite.xsl @@ -333,7 +333,8 @@ company as well. We have to ensure to use URIs of our prefix as primary identifiers only. --> - + + From acec968e940ca69c4eb28afe9512493a0690a4e3 Mon Sep 17 00:00:00 2001 From: Kristof De Langhe Date: Thu, 27 Jun 2024 10:59:36 +0200 Subject: [PATCH 025/226] 115693: DataCiteConnector fallback for blank metadata doi (cherry picked from commit 021e42434731e505245b3aa149eaf59a5fbccb94) --- .../main/java/org/dspace/identifier/doi/DataCiteConnector.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/identifier/doi/DataCiteConnector.java b/dspace-api/src/main/java/org/dspace/identifier/doi/DataCiteConnector.java index 931f1538583e..0fbac1a9f52b 100644 --- a/dspace-api/src/main/java/org/dspace/identifier/doi/DataCiteConnector.java +++ b/dspace-api/src/main/java/org/dspace/identifier/doi/DataCiteConnector.java @@ -15,6 +15,7 @@ import java.util.Iterator; import java.util.Map; +import org.apache.commons.lang.StringUtils; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.StatusLine; @@ -410,7 +411,7 @@ public void reserveDOI(Context context, DSpaceObject dso, String doi) } String metadataDOI = extractDOI(root); - if (null == metadataDOI) { + if (StringUtils.isBlank(metadataDOI)) { // The DOI will be saved as metadata of dso after successful // registration. To register a doi it has to be part of the metadata // sent to DataCite. So we add it to the XML we'll send to DataCite From cd8961bc0573edaf788fcc45aba8bcc2c38d91e2 Mon Sep 17 00:00:00 2001 From: Kristof De Langhe Date: Fri, 19 Jul 2024 13:42:09 +0200 Subject: [PATCH 026/226] 115693: Pass doi metadatafield with xsl parameters (cherry picked from commit 9e11e1f9ae69f19e506618d1d0b1fec0059ba165) --- .../identifier/DOIIdentifierProvider.java | 1 - .../identifier/doi/DataCiteConnector.java | 8 ++++++ dspace/config/crosswalks/DIM2DataCite.xsl | 25 +++++++++++-------- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/identifier/DOIIdentifierProvider.java b/dspace-api/src/main/java/org/dspace/identifier/DOIIdentifierProvider.java index aff4666fff4b..ae31e54f7e96 100644 --- a/dspace-api/src/main/java/org/dspace/identifier/DOIIdentifierProvider.java +++ b/dspace-api/src/main/java/org/dspace/identifier/DOIIdentifierProvider.java @@ -70,7 +70,6 @@ public class DOIIdentifierProvider extends FilteredIdentifierProvider { static final char SLASH = '/'; // Metadata field name elements - // Warning: If this metadata field is changed for whatever reason, DIM2DataCite.xsl's template needs to reflect this // TODO: move these to MetadataSchema or some such? public static final String MD_SCHEMA = "dc"; public static final String DOI_ELEMENT = "identifier"; diff --git a/dspace-api/src/main/java/org/dspace/identifier/doi/DataCiteConnector.java b/dspace-api/src/main/java/org/dspace/identifier/doi/DataCiteConnector.java index 0fbac1a9f52b..b4cdac96303a 100644 --- a/dspace-api/src/main/java/org/dspace/identifier/doi/DataCiteConnector.java +++ b/dspace-api/src/main/java/org/dspace/identifier/doi/DataCiteConnector.java @@ -7,6 +7,10 @@ */ package org.dspace.identifier.doi; +import static org.dspace.identifier.DOIIdentifierProvider.DOI_ELEMENT; +import static org.dspace.identifier.DOIIdentifierProvider.DOI_QUALIFIER; +import static org.dspace.identifier.DOIIdentifierProvider.MD_SCHEMA; + import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.URISyntaxException; @@ -384,6 +388,10 @@ public void reserveDOI(Context context, DSpaceObject dso, String doi) parameters.put("hostinginstitution", configurationService.getProperty(CFG_HOSTINGINSTITUTION)); } + parameters.put("mdSchema", MD_SCHEMA); + parameters.put("mdElement", DOI_ELEMENT); + // Pass an empty string for qualifier if the metadata field doesn't have any + parameters.put("mdQualifier", DOI_QUALIFIER); Element root = null; try { diff --git a/dspace/config/crosswalks/DIM2DataCite.xsl b/dspace/config/crosswalks/DIM2DataCite.xsl index d57996e6d8cf..d4d8cbe6417a 100644 --- a/dspace/config/crosswalks/DIM2DataCite.xsl +++ b/dspace/config/crosswalks/DIM2DataCite.xsl @@ -36,6 +36,10 @@ + + dc + identifier + uri @@ -333,16 +337,17 @@ company as well. We have to ensure to use URIs of our prefix as primary identifiers only. --> - - - - - - - - - - + + + + + + + + + + + From 65c452d3ef067cb1e28b68881ebcdf44a56e7ccf Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Mon, 8 Jul 2024 19:26:11 +0200 Subject: [PATCH 027/226] change order of name parts: familyName, givenName (cherry picked from commit 076f1f233ea0eef1a37ed4087f34008d1e92e40a) --- .../external/crossref/CrossRefAuthorMetadataProcessor.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/importer/external/crossref/CrossRefAuthorMetadataProcessor.java b/dspace-api/src/main/java/org/dspace/importer/external/crossref/CrossRefAuthorMetadataProcessor.java index abf84f52d058..b9b384f8ed77 100644 --- a/dspace-api/src/main/java/org/dspace/importer/external/crossref/CrossRefAuthorMetadataProcessor.java +++ b/dspace-api/src/main/java/org/dspace/importer/external/crossref/CrossRefAuthorMetadataProcessor.java @@ -42,8 +42,8 @@ public Collection processMetadata(String json) { JsonNode author = authors.next(); String givenName = author.at("/given").textValue(); String familyName = author.at("/family").textValue(); - if (StringUtils.isNoneBlank(givenName) && StringUtils.isNoneBlank(familyName)) { - values.add(givenName + " " + familyName); + if (StringUtils.isNotBlank(givenName) && StringUtils.isNotBlank(familyName)) { + values.add(familyName.trim() + ", " + givenName.trim()); } } return values; @@ -64,4 +64,4 @@ public void setPathToArray(String pathToArray) { this.pathToArray = pathToArray; } -} \ No newline at end of file +} From b6e1bcb30654d657958b766764319a4f1edfd1f7 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Tue, 9 Jul 2024 10:53:23 +0200 Subject: [PATCH 028/226] fix broken unit tests (cherry picked from commit 1712b9f07875c67141b67da96fa93f0deaff4090) --- .../app/rest/CrossRefImportMetadataSourceServiceIT.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/CrossRefImportMetadataSourceServiceIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/CrossRefImportMetadataSourceServiceIT.java index 863fd1f753d1..37bd3a90eeda 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/CrossRefImportMetadataSourceServiceIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/CrossRefImportMetadataSourceServiceIT.java @@ -162,7 +162,7 @@ private ArrayList getRecords() { MetadatumDTO title = createMetadatumDTO("dc", "title", null, "State of Awareness of Freshers’ Groups Chortkiv State" + " Medical College of Prevention of Iodine Deficiency Diseases"); - MetadatumDTO author = createMetadatumDTO("dc", "contributor", "author", "L.V. Senyuk"); + MetadatumDTO author = createMetadatumDTO("dc", "contributor", "author", "Senyuk, L.V."); MetadatumDTO type = createMetadatumDTO("dc", "type", null, "journal-article"); MetadatumDTO date = createMetadatumDTO("dc", "date", "issued", "2016-05-19"); MetadatumDTO ispartof = createMetadatumDTO("dc", "relation", "ispartof", @@ -191,7 +191,7 @@ private ArrayList getRecords() { List metadatums2 = new ArrayList(); MetadatumDTO title2 = createMetadatumDTO("dc", "title", null, "Ischemic Heart Disease and Role of Nurse of Cardiology Department"); - MetadatumDTO author2 = createMetadatumDTO("dc", "contributor", "author", "K. І. Kozak"); + MetadatumDTO author2 = createMetadatumDTO("dc", "contributor", "author", "Kozak, K. І."); MetadatumDTO type2 = createMetadatumDTO("dc", "type", null, "journal-article"); MetadatumDTO date2 = createMetadatumDTO("dc", "date", "issued", "2016-05-19"); MetadatumDTO ispartof2 = createMetadatumDTO("dc", "relation", "ispartof", From b98704ea4cc10d70ab34c6c2b557f0e85d696170 Mon Sep 17 00:00:00 2001 From: autavares-dev Date: Mon, 12 Aug 2024 15:08:26 -0300 Subject: [PATCH 029/226] Fix index-discovery process when using handle (cherry picked from commit 077aed38dc55172ed70d8bfb9c44fd369d966a6d) --- dspace-api/src/main/java/org/dspace/discovery/IndexClient.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/discovery/IndexClient.java b/dspace-api/src/main/java/org/dspace/discovery/IndexClient.java index b70e9162f7a1..3479c25bf367 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/IndexClient.java +++ b/dspace-api/src/main/java/org/dspace/discovery/IndexClient.java @@ -27,6 +27,7 @@ import org.dspace.content.Item; import org.dspace.content.factory.ContentServiceFactory; import org.dspace.content.service.ItemService; +import org.dspace.core.Constants; import org.dspace.core.Context; import org.dspace.discovery.indexobject.IndexableCollection; import org.dspace.discovery.indexobject.IndexableCommunity; @@ -109,7 +110,7 @@ public void internalRun() throws Exception { .getHandleService().resolveToObject(context, param); if (dso != null) { final IndexFactory indexableObjectService = IndexObjectFactoryFactory.getInstance(). - getIndexFactoryByType(String.valueOf(dso.getType())); + getIndexFactoryByType(Constants.typeText[dso.getType()]); indexableObject = indexableObjectService.findIndexableObject(context, dso.getID().toString()); } } From d1f837b2ba3177c13271a311cfd6b117d9fb30d6 Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Tue, 23 Apr 2024 13:33:01 -0400 Subject: [PATCH 030/226] Separate task-list building from execution. The old code would curate the object once for each task, meaning that all but one task would be executed N times up to the length of the list. (cherry picked from commit c43948bf3d190d68e2c2840c5beee9268764ad2a) --- .../curate/XmlWorkflowCuratorServiceImpl.java | 29 ++++++++++--------- .../java/org/dspace/curate/package-info.java | 12 ++++++++ 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/curate/XmlWorkflowCuratorServiceImpl.java b/dspace-api/src/main/java/org/dspace/curate/XmlWorkflowCuratorServiceImpl.java index 00e91ee1fb40..ec32ff92f9a2 100644 --- a/dspace-api/src/main/java/org/dspace/curate/XmlWorkflowCuratorServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/curate/XmlWorkflowCuratorServiceImpl.java @@ -140,13 +140,14 @@ public boolean curate(Curator curator, Context c, XmlWorkflowItem wfi) item.setOwningCollection(wfi.getCollection()); for (Task task : step.tasks) { curator.addTask(task.name); - // Check whether the task is configured to be queued rather than automatically run - if (StringUtils.isNotEmpty(step.queue)) { - // queue attribute has been set in the FlowStep configuration: add task to configured queue - curator.queue(c, item.getID().toString(), step.queue); - } else { - // Task is configured to be run automatically - curator.curate(c, item); + } + + if (StringUtils.isNotEmpty(step.queue)) { // Step's tasks are to be queued. + curator.queue(c, item.getID().toString(), step.queue); + } else { // Step's tasks are to be run now. + curator.curate(c, item); + + for (Task task : step.tasks) { int status = curator.getStatus(task.name); String result = curator.getResult(task.name); String action = "none"; @@ -183,14 +184,14 @@ public boolean curate(Curator curator, Context c, XmlWorkflowItem wfi) } } curator.clear(); - } - // Record any reporting done by the tasks. - if (reporter.length() > 0) { - LOG.info("Curation tasks over item {} for step {} report:%n{}", - () -> wfi.getItem().getID(), - () -> step.step, - () -> reporter.toString()); + // Record any reporting done by the tasks. + if (reporter.length() > 0) { + LOG.info("Curation tasks over item {} for step {} report:\n{}", + () -> wfi.getItem().getID(), + () -> step.step, + () -> reporter.toString()); + } } } return true; diff --git a/dspace-api/src/main/java/org/dspace/curate/package-info.java b/dspace-api/src/main/java/org/dspace/curate/package-info.java index 492642f60c57..1168bbd283d2 100644 --- a/dspace-api/src/main/java/org/dspace/curate/package-info.java +++ b/dspace-api/src/main/java/org/dspace/curate/package-info.java @@ -20,6 +20,8 @@ * * *

Curation requests may be run immediately or queued for batch processing. + * See {@link TaskQueue} and its relatives, {@link Curation} and its relatives + * for more on queued curation. * *

Tasks may also be attached to a workflow step, so that a set of tasks is * applied to each uninstalled Item which passes through that step. See @@ -27,5 +29,15 @@ * *

A task may return to the Curator a status code, a final status message, * and an optional report character stream. + * + *

The {@link Reporter} classes absorb strings of text and preserve it in + * various ways. A Reporter is a simple {@link Appendable} and makes no + * assumptions about e.g. whether a string represents a complete line. If you + * want your report formatted, insert appropriate newlines and other whitespace + * as needed. Your tasks can emit marked-up text if you wish, but the stock + * Reporter implementations make no attempt to render it. + * + *

Tasks may be annotated to inform the Curator of special properties. See + * {@link Distributive}, {@link Mutative}, {@link Suspendable} etc. */ package org.dspace.curate; From da4cc4cb3137a620e00df8c586c138b60c1bed2b Mon Sep 17 00:00:00 2001 From: "Mark H. Wood" Date: Mon, 26 Aug 2024 15:02:31 -0400 Subject: [PATCH 031/226] Make statistics autocommit much more frequent. (cherry picked from commit 5c9af9764e2485b26398ec06446cb8f0edd9cab2) --- dspace/solr/statistics/conf/solrconfig.xml | 25 ++++++++++++++-------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/dspace/solr/statistics/conf/solrconfig.xml b/dspace/solr/statistics/conf/solrconfig.xml index 2b1cff45373d..c3f023ff2eee 100644 --- a/dspace/solr/statistics/conf/solrconfig.xml +++ b/dspace/solr/statistics/conf/solrconfig.xml @@ -32,14 +32,16 @@ - + 32 1000 ${solr.lock.type:native} - + false @@ -48,7 +50,7 @@ 10000 - ${solr.autoCommit.maxTime:900000} + ${solr.autoCommit.maxTime:10000} true @@ -62,14 +64,16 @@ ${solr.max.booleanClauses:1024} + unordered sets of *all* documents that match a + query. Caches results of 'fq' search param. --> - + 1000 - + - + uuid @@ -126,7 +132,8 @@ - + uid From 175c3d54cd5b3a6b66950b374e0bb35caf52897c Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Tue, 3 Sep 2024 17:13:01 +0200 Subject: [PATCH 032/226] Translate underscores to dashes in xml:lang attr for DIM2DataCite.xsl Modified the DataCite crosswalk to ensure that the xml:lang attribute translates any underscores in the value of @lang to dashes. This change aligns the attribute formatting with standard language code conventions. (cherry picked from commit a898afd5acbd6dc51a88b837cab2a1c56cc33967) --- dspace/config/crosswalks/DIM2DataCite.xsl | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/dspace/config/crosswalks/DIM2DataCite.xsl b/dspace/config/crosswalks/DIM2DataCite.xsl index d4d8cbe6417a..935b3dc4038a 100644 --- a/dspace/config/crosswalks/DIM2DataCite.xsl +++ b/dspace/config/crosswalks/DIM2DataCite.xsl @@ -25,6 +25,10 @@ to register DOIs anymore. Please follow and reuse the examples included in this file. For more information on the DataCite Schema, see https://schema.datacite.org. --> + 10.5072/dspace- @@ -362,20 +366,20 @@ - + - + AlternativeTitle - - + Subtitle - + TranslatedTitle @@ -394,7 +398,7 @@ --> - + @@ -626,7 +630,7 @@ --> - + Abstract From 5ca9fee2be64d4fc4512d1f121ecc47e84a5827f Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Tue, 25 Jun 2024 13:45:31 +0200 Subject: [PATCH 033/226] Fix request a copy link token generation Ensure DSpace URLs with extra segments are included fully in the generated link (cherry picked from commit 52702a23df37f087058c7837a2dfcbbcf4306382) --- .../rest/repository/RequestItemRepository.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RequestItemRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RequestItemRepository.java index 6bfae8ed3515..1bb3ddbc9aed 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RequestItemRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RequestItemRepository.java @@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import jakarta.servlet.http.HttpServletRequest; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.validator.routines.EmailValidator; import org.apache.http.client.utils.URIBuilder; import org.apache.logging.log4j.LogManager; @@ -287,19 +288,17 @@ public Class getDomainClass() { * Generate a link back to DSpace, to act on a request. * * @param token identifies the request. - * @return URL to the item request API, with the token as request parameter - * "token". + * @return URL to the item request API, with /request-a-copy/{token} as the last URL segments * @throws URISyntaxException passed through. * @throws MalformedURLException passed through. */ private String getLinkTokenEmail(String token) throws URISyntaxException, MalformedURLException { final String base = configurationService.getProperty("dspace.ui.url"); - - URI link = new URIBuilder(base) - .setPathSegments("request-a-copy", token) - .build(); - - return link.toURL().toExternalForm(); + URIBuilder uriBuilder = new URIBuilder(base); + // Add request-a-copy/token to the existing path (without breaking /sub/dir dspace URLs) + URI uri = uriBuilder.setPath(StringUtils.stripEnd(uriBuilder.getPath(), "") + + "/request-a-copy/" + token).build(); + return uri.toURL().toExternalForm(); } } From 083f7b45e0b23a76a41fedd6e7c560f7278a3ef6 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Tue, 25 Jun 2024 14:36:17 +0200 Subject: [PATCH 034/226] Make RequestItemRepository#getLinkTokenEmail public, write test (cherry picked from commit 3646a54df3d540e7dc7603cd7013961df8d9a404) --- .../repository/RequestItemRepository.java | 2 +- .../app/rest/RequestItemRepositoryIT.java | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RequestItemRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RequestItemRepository.java index 1bb3ddbc9aed..0698567dcbc6 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RequestItemRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RequestItemRepository.java @@ -292,7 +292,7 @@ public Class getDomainClass() { * @throws URISyntaxException passed through. * @throws MalformedURLException passed through. */ - private String getLinkTokenEmail(String token) + public String getLinkTokenEmail(String token) throws URISyntaxException, MalformedURLException { final String base = configurationService.getProperty("dspace.ui.url"); URIBuilder uriBuilder = new URIBuilder(base); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/RequestItemRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/RequestItemRepositoryIT.java index ea61db514504..a43e458207cf 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/RequestItemRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/RequestItemRepositoryIT.java @@ -28,6 +28,8 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URISyntaxException; import java.sql.SQLException; import java.time.temporal.ChronoUnit; import java.util.Date; @@ -55,10 +57,12 @@ import org.dspace.content.Bitstream; import org.dspace.content.Collection; import org.dspace.content.Item; +import org.dspace.services.ConfigurationService; import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; /** * @@ -81,6 +85,12 @@ public class RequestItemRepositoryIT @Autowired(required = true) RequestItemService requestItemService; + @Autowired + ApplicationContext applicationContext; + + @Autowired + private ConfigurationService configurationService; + private Collection collection; private Item item; @@ -594,4 +604,23 @@ public void testGetDomainClass() { Class instanceClass = instance.getDomainClass(); assertEquals("Wrong domain class", RequestItemRest.class, instanceClass); } + + /** + * Test that generated links include the correct base URL, even if it has extra URL segments + */ + @Test + public void testGetLinkTokenEmail() throws MalformedURLException, URISyntaxException { + RequestItemRepository instance = applicationContext.getBean( + RequestItemRest.CATEGORY + '.' + RequestItemRest.PLURAL_NAME, + RequestItemRepository.class); + String currentDspaceUrl = configurationService.getProperty("dspace.ui.url"); + String newDspaceUrl = currentDspaceUrl + "/subdir"; + // Add a /subdir to the url for this test + configurationService.setProperty("dspace.ui.url", newDspaceUrl); + String expectedUrl = newDspaceUrl + "/request-a-copy/token"; + String generatedLink = instance.getLinkTokenEmail("token"); + // The URLs should match + assertEquals(expectedUrl, generatedLink); + configurationService.reloadConfig(); + } } From 6f1bc3bb6aa7c4c8069435c3d219637269aabb46 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Wed, 10 Jul 2024 16:04:34 +0200 Subject: [PATCH 035/226] #9668: Ensure proper handling of non-subpath URLs in link tokens (cherry picked from commit 6eb3271fa320b9d7d32ef3c59f7b83467bd2b03a) --- .../repository/RequestItemRepository.java | 5 +++-- .../app/rest/RequestItemRepositoryIT.java | 20 +++++++++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RequestItemRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RequestItemRepository.java index 0698567dcbc6..35bd21489543 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RequestItemRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RequestItemRepository.java @@ -297,8 +297,9 @@ public String getLinkTokenEmail(String token) final String base = configurationService.getProperty("dspace.ui.url"); URIBuilder uriBuilder = new URIBuilder(base); // Add request-a-copy/token to the existing path (without breaking /sub/dir dspace URLs) - URI uri = uriBuilder.setPath(StringUtils.stripEnd(uriBuilder.getPath(), "") - + "/request-a-copy/" + token).build(); + URI uri = uriBuilder.setPath( + (uriBuilder.getPath() == null ? "" : StringUtils.stripEnd(uriBuilder.getPath(), "")) + + "/request-a-copy/" + token).build(); return uri.toURL().toExternalForm(); } } diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/RequestItemRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/RequestItemRepositoryIT.java index a43e458207cf..56409d18d738 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/RequestItemRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/RequestItemRepositoryIT.java @@ -606,10 +606,10 @@ public void testGetDomainClass() { } /** - * Test that generated links include the correct base URL, even if it has extra URL segments + * Test that generated links include the correct base URL, where the UI URL has a subpath like /subdir */ @Test - public void testGetLinkTokenEmail() throws MalformedURLException, URISyntaxException { + public void testGetLinkTokenEmailWithSubPath() throws MalformedURLException, URISyntaxException { RequestItemRepository instance = applicationContext.getBean( RequestItemRest.CATEGORY + '.' + RequestItemRest.PLURAL_NAME, RequestItemRepository.class); @@ -623,4 +623,20 @@ public void testGetLinkTokenEmail() throws MalformedURLException, URISyntaxExcep assertEquals(expectedUrl, generatedLink); configurationService.reloadConfig(); } + + /** + * Test that generated links include the correct base URL, with NO subpath elements + */ + @Test + public void testGetLinkTokenEmailWithoutSubPath() throws MalformedURLException, URISyntaxException { + RequestItemRepository instance = applicationContext.getBean( + RequestItemRest.CATEGORY + '.' + RequestItemRest.PLURAL_NAME, + RequestItemRepository.class); + String currentDspaceUrl = configurationService.getProperty("dspace.ui.url"); + String expectedUrl = currentDspaceUrl + "/request-a-copy/token"; + String generatedLink = instance.getLinkTokenEmail("token"); + // The URLs should match + assertEquals(expectedUrl, generatedLink); + configurationService.reloadConfig(); + } } From 67873075a90f6effe63b5bc0429c9508eb076a1b Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Sun, 1 Sep 2024 12:53:04 +0200 Subject: [PATCH 036/226] Improved URI build method as per review (cherry picked from commit a9f6d771121087f120c0a82710bde864b73b5e10) --- .../rest/repository/RequestItemRepository.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RequestItemRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RequestItemRepository.java index 35bd21489543..3de3dbef9c5a 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RequestItemRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RequestItemRepository.java @@ -15,7 +15,11 @@ import java.net.URI; import java.net.URISyntaxException; import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collections; import java.util.Date; +import java.util.LinkedList; +import java.util.List; import java.util.UUID; import com.fasterxml.jackson.databind.JsonNode; @@ -295,11 +299,16 @@ public Class getDomainClass() { public String getLinkTokenEmail(String token) throws URISyntaxException, MalformedURLException { final String base = configurationService.getProperty("dspace.ui.url"); + URIBuilder uriBuilder = new URIBuilder(base); - // Add request-a-copy/token to the existing path (without breaking /sub/dir dspace URLs) - URI uri = uriBuilder.setPath( - (uriBuilder.getPath() == null ? "" : StringUtils.stripEnd(uriBuilder.getPath(), "")) - + "/request-a-copy/" + token).build(); + List segments = new LinkedList<>(); + if (StringUtils.isNotBlank(uriBuilder.getPath())) { + segments.add(StringUtils.strip(uriBuilder.getPath(), "/")); + } + segments.add("request-a-copy"); + segments.add(token); + URI uri = uriBuilder.setPathSegments(segments).build(); + return uri.toURL().toExternalForm(); } } From 24199cf6f26dd30183f5d5f698eb939f97c780be Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Wed, 4 Sep 2024 14:04:20 +0200 Subject: [PATCH 037/226] Tidy implementation of link token generation (cherry picked from commit 74a6dc218787b77ed03aa36900be6bd070be043c) --- .../dspace/app/rest/repository/RequestItemRepository.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RequestItemRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RequestItemRepository.java index 3de3dbef9c5a..59645aaf1d57 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RequestItemRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RequestItemRepository.java @@ -300,6 +300,7 @@ public String getLinkTokenEmail(String token) throws URISyntaxException, MalformedURLException { final String base = configurationService.getProperty("dspace.ui.url"); + // Construct the link, making sure to support sub-paths URIBuilder uriBuilder = new URIBuilder(base); List segments = new LinkedList<>(); if (StringUtils.isNotBlank(uriBuilder.getPath())) { @@ -307,8 +308,8 @@ public String getLinkTokenEmail(String token) } segments.add("request-a-copy"); segments.add(token); - URI uri = uriBuilder.setPathSegments(segments).build(); - return uri.toURL().toExternalForm(); + // Build and return the URL from segments (or throw exception) + return uriBuilder.setPathSegments(segments).build().toURL().toExternalForm(); } } From 8656c5051d8919df88ea0016a2d0a05316f767fb Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Wed, 4 Sep 2024 15:19:34 +0200 Subject: [PATCH 038/226] lint fixes (RequestItemRepository) (cherry picked from commit 185a6fdf91c33eb5e100fd28b881f714b3a0a3be) --- .../org/dspace/app/rest/repository/RequestItemRepository.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RequestItemRepository.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RequestItemRepository.java index 59645aaf1d57..eaae877f283e 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RequestItemRepository.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/repository/RequestItemRepository.java @@ -12,11 +12,8 @@ import java.io.IOException; import java.net.MalformedURLException; -import java.net.URI; import java.net.URISyntaxException; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collections; import java.util.Date; import java.util.LinkedList; import java.util.List; From e57e91c2fd3419528b533946e8d75b3898abb121 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Fri, 6 Sep 2024 15:25:18 +0200 Subject: [PATCH 039/226] #9806: Add new create methods to group builder Now supports admin groups, default read, workflow role (cherry picked from commit cdb167e55aac9916618dcfee7222105f4456dbd8) --- .../java/org/dspace/builder/GroupBuilder.java | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/dspace-api/src/test/java/org/dspace/builder/GroupBuilder.java b/dspace-api/src/test/java/org/dspace/builder/GroupBuilder.java index b3447dd8bd9a..c16fb696b0c3 100644 --- a/dspace-api/src/test/java/org/dspace/builder/GroupBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/GroupBuilder.java @@ -12,6 +12,9 @@ import java.util.UUID; import org.dspace.authorize.AuthorizeException; +import org.dspace.content.Collection; +import org.dspace.content.Community; +import org.dspace.content.DSpaceObject; import org.dspace.content.service.DSpaceObjectService; import org.dspace.core.Context; import org.dspace.eperson.EPerson; @@ -51,6 +54,33 @@ public static GroupBuilder createGroup(final Context context) { return builder.create(context); } + public static GroupBuilder createCollectionAdminGroup(final Context context, Collection collection) { + GroupBuilder builder = new GroupBuilder(context); + return builder.createAdminGroup(context, collection); + } + + public static GroupBuilder createCollectionSubmitterGroup(final Context context, Collection collection) { + GroupBuilder builder = new GroupBuilder(context); + return builder.createSubmitterGroup(context, collection); + } + + public static GroupBuilder createCollectionDefaultReadGroup(final Context context, Collection collection, + String typeOfGroupString, int defaultRead) { + GroupBuilder builder = new GroupBuilder(context); + return builder.createDefaultReadGroup(context, collection, typeOfGroupString, defaultRead); + } + + public static GroupBuilder createCollectionWorkflowRoleGroup(final Context context, Collection collection, + String roleName) { + GroupBuilder builder = new GroupBuilder(context); + return builder.createWorkflowRoleGroup(context, collection, roleName); + } + + public static GroupBuilder createCommunityAdminGroup(final Context context, Community community) { + GroupBuilder builder = new GroupBuilder(context); + return builder.createAdminGroup(context, community); + } + private GroupBuilder create(final Context context) { this.context = context; try { @@ -61,6 +91,54 @@ private GroupBuilder create(final Context context) { return this; } + private GroupBuilder createAdminGroup(final Context context, DSpaceObject container) { + this.context = context; + try { + if (container instanceof Collection) { + group = collectionService.createAdministrators(context, (Collection) container); + } else if (container instanceof Community) { + group = communityService.createAdministrators(context, (Community) container); + } else { + handleException(new IllegalArgumentException("DSpaceObject must be collection or community. " + + "Type: " + container.getType())); + } + } catch (Exception e) { + return handleException(e); + } + return this; + } + + private GroupBuilder createSubmitterGroup(final Context context, Collection collection) { + this.context = context; + try { + group = collectionService.createSubmitters(context, collection); + } catch (Exception e) { + return handleException(e); + } + return this; + } + + private GroupBuilder createDefaultReadGroup(final Context context, Collection collection, + String typeOfGroupString, int defaultRead) { + this.context = context; + try { + group = collectionService.createDefaultReadGroup(context, collection, typeOfGroupString, defaultRead); + } catch (Exception e) { + return handleException(e); + } + return this; + } + + private GroupBuilder createWorkflowRoleGroup(final Context context, Collection collection, String roleName) { + this.context = context; + try { + group = workflowService.createWorkflowRoleGroup(context, collection, roleName); + } catch (Exception e) { + return handleException(e); + } + return this; + } + @Override protected DSpaceObjectService getService() { return groupService; From 16374d6edb10ec97ffca890f6da62e7955bacb32 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Fri, 6 Sep 2024 15:28:27 +0200 Subject: [PATCH 040/226] #9806: Use builders for coll, comm, group creation in BitstreamRestRepositoryIT (cherry picked from commit b13abac7539944358711a381548fbaedd9dcbd92) --- .../app/rest/BitstreamRestRepositoryIT.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/BitstreamRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/BitstreamRestRepositoryIT.java index af2b14759c63..a18dde701b47 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/BitstreamRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/BitstreamRestRepositoryIT.java @@ -50,6 +50,7 @@ import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; import org.dspace.builder.EPersonBuilder; +import org.dspace.builder.GroupBuilder; import org.dspace.builder.ItemBuilder; import org.dspace.builder.ResourcePolicyBuilder; import org.dspace.content.Bitstream; @@ -2768,10 +2769,12 @@ public void deleteBitstreamsInBulk_collectionAdmin() throws Exception { .withEmail("col2admin@test.com") .withPassword(password) .build(); - Group col1_AdminGroup = collectionService.createAdministrators(context, col1); - Group col2_AdminGroup = collectionService.createAdministrators(context, col2); - groupService.addMember(context, col1_AdminGroup, col1Admin); - groupService.addMember(context, col2_AdminGroup, col2Admin); + Group col1_AdminGroup = GroupBuilder.createCollectionAdminGroup(context, col1) + .addMember(col1Admin) + .build(); + Group col2_AdminGroup = GroupBuilder.createCollectionAdminGroup(context, col2) + .addMember(col2Admin) + .build(); Item publicItem1 = ItemBuilder.createItem(context, col1) .withTitle("Test item 1") .build(); @@ -2872,8 +2875,9 @@ public void deleteBitstreamsInBulk_communityAdmin() throws Exception { .withEmail("parentComAdmin@test.com") .withPassword(password) .build(); - Group parentComAdminGroup = communityService.createAdministrators(context, parentCommunity); - groupService.addMember(context, parentComAdminGroup, parentCommunityAdmin); + Group parentComAdminGroup = GroupBuilder.createCommunityAdminGroup(context, parentCommunity) + .addMember(parentCommunityAdmin) + .build(); Item publicItem1 = ItemBuilder.createItem(context, col1) .withTitle("Test item 1") .build(); From 592df88d05c9ccca6926448abc169f66709a276b Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Fri, 6 Sep 2024 15:29:48 +0200 Subject: [PATCH 041/226] #9806: Use builders for coll, comm, group creation in GroupRestRepositoryIT (cherry picked from commit 9205773802a8d22820b074e18409e245c63f5609) --- .../app/rest/GroupRestRepositoryIT.java | 202 ++++++++++-------- 1 file changed, 107 insertions(+), 95 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/GroupRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/GroupRestRepositoryIT.java index 83259aa09e99..6f9d418f7f43 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/GroupRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/GroupRestRepositoryIT.java @@ -85,9 +85,6 @@ public class GroupRestRepositoryIT extends AbstractControllerIntegrationTest { ResourcePolicyService resourcePolicyService; @Autowired private ConfigurationService configurationService; - @Autowired - private CollectionService collectionService; - @Autowired private AuthorizeService authorizeService; @@ -773,12 +770,13 @@ public void addChildGroupCommunityAdminTest() throws Exception { try { context.turnOffAuthorisationSystem(); - community = communityService.create(null, context); - parentGroup = communityService.createAdministrators(context, community); - childGroup1 = groupService.create(context); - childGroup2 = groupService.create(context); + community = CommunityBuilder.createCommunity(context).build(); + parentGroup = GroupBuilder.createCommunityAdminGroup(context, community) + .addMember(eperson) + .build(); + childGroup1 = GroupBuilder.createGroup(context).build(); + childGroup2 = GroupBuilder.createGroup(context).build(); - groupService.addMember(context, parentGroup, eperson); groupService.update(context, parentGroup); context.commit(); @@ -810,6 +808,7 @@ public void addChildGroupCommunityAdminTest() throws Exception { ); } finally { + // TODO: Can we remove these lines now that we are creating them with the builder? if (community != null) { CommunityBuilder.deleteCommunity(community.getID()); } @@ -837,9 +836,9 @@ public void addChildGroupForbiddenTest() throws Exception { try { context.turnOffAuthorisationSystem(); - parentGroup = groupService.create(context); - childGroup1 = groupService.create(context); - childGroup2 = groupService.create(context); + parentGroup = GroupBuilder.createGroup(context).build(); + childGroup1 = GroupBuilder.createGroup(context).build(); + childGroup2 = GroupBuilder.createGroup(context).build(); context.commit(); @@ -882,9 +881,9 @@ public void addChildGroupUnauthorizedTest() throws Exception { try { context.turnOffAuthorisationSystem(); - parentGroup = groupService.create(context); - childGroup1 = groupService.create(context); - childGroup2 = groupService.create(context); + parentGroup = GroupBuilder.createGroup(context).build(); + childGroup1 = GroupBuilder.createGroup(context).build(); + childGroup2 = GroupBuilder.createGroup(context).build(); context.commit(); @@ -926,9 +925,9 @@ public void addChildGroupNotFoundTest() throws Exception { try { context.turnOffAuthorisationSystem(); - parentGroup = groupService.create(context); - childGroup1 = groupService.create(context); - childGroup2 = groupService.create(context); + parentGroup = GroupBuilder.createGroup(context).build(); + childGroup1 = GroupBuilder.createGroup(context).build(); + childGroup2 = GroupBuilder.createGroup(context).build(); context.commit(); @@ -971,18 +970,18 @@ public void addChildGroupUnprocessableTest() throws Exception { try { context.turnOffAuthorisationSystem(); - parentGroup = groupService.create(context); - childGroup1 = groupService.create(context); - childGroup2 = groupService.create(context); - - groupService.addMember(context, childGroup1, parentGroup); + parentGroup = GroupBuilder.createGroup(context).build(); + childGroup1 = GroupBuilder.createGroup(context) + .withParent(parentGroup) + .build(); + childGroup2 = GroupBuilder.createGroup(context).build(); groupService.update(context, childGroup1); - context.commit(); - - parentGroup = context.reloadEntity(parentGroup); - childGroup1 = context.reloadEntity(childGroup1); - childGroup2 = context.reloadEntity(childGroup2); +// context.commit(); +// +// parentGroup = context.reloadEntity(parentGroup); +// childGroup1 = context.reloadEntity(childGroup1); +// childGroup2 = context.reloadEntity(childGroup2); context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); @@ -995,13 +994,15 @@ public void addChildGroupUnprocessableTest() throws Exception { ) ).andExpect(status().isUnprocessableEntity()); + // TODO - confirm with reviewers that this is a mistake - it actually should be No Content + // (see AddMember test) but was incorrectly expecting 422? getClient(authToken).perform( post("/api/eperson/groups/" + parentGroup.getID() + "/subgroups") .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) .content(REST_SERVER_URL + "eperson/groups/" + childGroup1.getID() + "/\n" + REST_SERVER_URL + "eperson/groups/" + childGroup2.getID() ) - ).andExpect(status().isUnprocessableEntity()); + ).andExpect(status().isNoContent()); } finally { if (parentGroup != null) { @@ -1093,13 +1094,12 @@ public void addMemberCommunityAdminTest() throws Exception { try { context.turnOffAuthorisationSystem(); - community = communityService.create(null, context); - parentGroup = communityService.createAdministrators(context, community); - member1 = ePersonService.create(context); - member2 = ePersonService.create(context); - - groupService.addMember(context, parentGroup, eperson); - groupService.update(context, parentGroup); + community = CommunityBuilder.createCommunity(context).build(); + parentGroup = GroupBuilder.createCommunityAdminGroup(context, community) + .addMember(eperson) + .build(); + member1 = EPersonBuilder.createEPerson(context).build(); + member2 = EPersonBuilder.createEPerson(context).build(); context.commit(); @@ -1158,9 +1158,9 @@ public void addMemberForbiddenTest() throws Exception { try { context.turnOffAuthorisationSystem(); - parentGroup = groupService.create(context); - member1 = ePersonService.create(context); - member2 = ePersonService.create(context); + parentGroup = GroupBuilder.createGroup(context).build(); + member1 = EPersonBuilder.createEPerson(context).build(); + member2 = EPersonBuilder.createEPerson(context).build(); context.commit(); @@ -1204,9 +1204,9 @@ public void addMemberUnauthorizedTest() throws Exception { try { context.turnOffAuthorisationSystem(); - parentGroup = groupService.create(context); - member1 = ePersonService.create(context); - member2 = ePersonService.create(context); + parentGroup = GroupBuilder.createGroup(context).build(); + member1 = EPersonBuilder.createEPerson(context).build(); + member2 = EPersonBuilder.createEPerson(context).build(); context.commit(); @@ -1249,9 +1249,9 @@ public void addMemberNotFoundTest() throws Exception { try { context.turnOffAuthorisationSystem(); - parentGroup = groupService.create(context); - member1 = ePersonService.create(context); - member2 = ePersonService.create(context); + parentGroup = GroupBuilder.createGroup(context).build(); + member1 = EPersonBuilder.createEPerson(context).build(); + member2 = EPersonBuilder.createEPerson(context).build(); context.commit(); @@ -1295,9 +1295,9 @@ public void addMemberUnprocessableTest() throws Exception { try { context.turnOffAuthorisationSystem(); - parentGroup = groupService.create(context); - member1 = ePersonService.create(context); - member2 = ePersonService.create(context); + parentGroup = GroupBuilder.createGroup(context).build(); + member1 = EPersonBuilder.createEPerson(context).build(); + member2 = EPersonBuilder.createEPerson(context).build(); context.commit(); @@ -1389,13 +1389,13 @@ public void removeChildGroupCommunityAdminTest() throws Exception { try { context.turnOffAuthorisationSystem(); - community = communityService.create(null, context); - parentGroup = communityService.createAdministrators(context, community); - childGroup = groupService.create(context); - - groupService.addMember(context, parentGroup, childGroup); - groupService.addMember(context, parentGroup, eperson); - groupService.update(context, parentGroup); + community = CommunityBuilder.createCommunity(context).build(); + parentGroup = GroupBuilder.createCommunityAdminGroup(context, community) + .addMember(eperson) + .build(); + childGroup = GroupBuilder.createGroup(context) + .withParent(parentGroup) + .build(); context.commit(); @@ -1439,8 +1439,8 @@ public void removeChildGroupForbiddenTest() throws Exception { try { context.turnOffAuthorisationSystem(); - parentGroup = groupService.create(context); - childGroup = groupService.create(context); + parentGroup = GroupBuilder.createGroup(context).build(); + childGroup = GroupBuilder.createGroup(context).build(); context.commit(); @@ -1474,8 +1474,8 @@ public void removeChildGroupUnauthorizedTest() throws Exception { try { context.turnOffAuthorisationSystem(); - parentGroup = groupService.create(context); - childGroup = groupService.create(context); + parentGroup = GroupBuilder.createGroup(context).build(); + childGroup = GroupBuilder.createGroup(context).build(); context.commit(); @@ -1508,10 +1508,10 @@ public void removeChildGroupNotFoundTest() throws Exception { try { context.turnOffAuthorisationSystem(); - parentGroup = groupService.create(context); - childGroup = groupService.create(context); - - groupService.addMember(context, childGroup, parentGroup); + parentGroup = GroupBuilder.createGroup(context).build(); + childGroup = GroupBuilder.createGroup(context) + .withParent(parentGroup) + .build(); context.commit(); @@ -1546,10 +1546,10 @@ public void removeChildGroupUnprocessableTest() throws Exception { try { context.turnOffAuthorisationSystem(); - parentGroup = groupService.create(context); - childGroup = groupService.create(context); - - groupService.addMember(context, childGroup, parentGroup); + parentGroup = GroupBuilder.createGroup(context).build(); + childGroup = GroupBuilder.createGroup(context) + .withParent(parentGroup) + .build(); context.commit(); @@ -1625,13 +1625,12 @@ public void removeMemberCommunityAdminTest() throws Exception { try { context.turnOffAuthorisationSystem(); - community = communityService.create(null, context); - parentGroup = communityService.createAdministrators(context, community); - member = ePersonService.create(context); - - groupService.addMember(context, parentGroup, member); - groupService.addMember(context, parentGroup, eperson); - groupService.update(context, parentGroup); + community = CommunityBuilder.createCommunity(context).build(); + member = EPersonBuilder.createEPerson(context).build(); + parentGroup = GroupBuilder.createCommunityAdminGroup(context, community) + .addMember(member) + .addMember(eperson) + .build(); assertTrue(groupService.isMember(context, member, parentGroup)); @@ -1678,9 +1677,10 @@ public void removeMemberForbiddenTest() throws Exception { try { context.turnOffAuthorisationSystem(); - parentGroup = groupService.create(context); - member = ePersonService.create(context); - groupService.addMember(context, parentGroup, member); + member = EPersonBuilder.createEPerson(context).build(); + parentGroup = GroupBuilder.createGroup(context) + .addMember(member) + .build(); context.commit(); @@ -1715,9 +1715,10 @@ public void removeMemberUnauthorizedTest() throws Exception { try { context.turnOffAuthorisationSystem(); - parentGroup = groupService.create(context); - member = ePersonService.create(context); - groupService.addMember(context, parentGroup, member); + member = EPersonBuilder.createEPerson(context).build(); + parentGroup = GroupBuilder.createGroup(context) + .addMember(member) + .build(); context.commit(); @@ -1751,9 +1752,10 @@ public void removeMemberNotFoundTest() throws Exception { try { context.turnOffAuthorisationSystem(); - parentGroup = groupService.create(context); - member = ePersonService.create(context); - groupService.addMember(context, parentGroup, member); + member = EPersonBuilder.createEPerson(context).build(); + parentGroup = GroupBuilder.createGroup(context) + .addMember(member) + .build(); context.commit(); @@ -1789,9 +1791,10 @@ public void removeMemberUnprocessableTest() throws Exception { try { context.turnOffAuthorisationSystem(); - parentGroup = groupService.create(context); - member = ePersonService.create(context); - groupService.addMember(context, parentGroup, member); + member = EPersonBuilder.createEPerson(context).build(); + parentGroup = GroupBuilder.createGroup(context) + .addMember(member) + .build(); context.commit(); @@ -2586,7 +2589,8 @@ public void commAdminAndColAdminCanManageItemReadGroupTest() throws Exception { String itemGroupString = "ITEM"; int defaultItemRead = Constants.DEFAULT_ITEM_READ; - Group itemReadGroup = collectionService.createDefaultReadGroup(context, col1, itemGroupString, defaultItemRead); + Group itemReadGroup = GroupBuilder.createCollectionDefaultReadGroup(context, + col1, itemGroupString, defaultItemRead).build(); context.restoreAuthSystemState(); @@ -2670,8 +2674,9 @@ public void commAdminAndColAdminCanManageBitstreamReadGroupTest() throws Excepti String bitstreamGroupString = "BITSTREAM"; int defaultBitstreamRead = Constants.DEFAULT_BITSTREAM_READ; - Group bitstreamReadGroup = collectionService.createDefaultReadGroup(context, col1, bitstreamGroupString, - defaultBitstreamRead); + Group bitstreamReadGroup = GroupBuilder.createCollectionDefaultReadGroup(context, col1, bitstreamGroupString, + defaultBitstreamRead) + .build(); context.restoreAuthSystemState(); @@ -2792,7 +2797,8 @@ public void commAdminAndColAdminCanManageWorkflowGroupsTest() throws Exception { public void collectionAdminRemoveMembersFromCollectionAdminGroupSuccess() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = collectionService.createAdministrators(context, collection); + Group adminGroup = GroupBuilder.createCollectionAdminGroup(context, collection) + .build(); authorizeService.addPolicy(context, collection, Constants.ADMIN, eperson); EPerson ePerson = EPersonBuilder.createEPerson(context).withEmail("testToAdd@test.com").build(); context.restoreAuthSystemState(); @@ -2827,7 +2833,8 @@ public void collectionAdminRemoveMembersFromCollectionAdminGroupSuccess() throws public void collectionAdminAddChildGroupToCollectionAdminGroupSuccess() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = collectionService.createAdministrators(context, collection); + Group adminGroup = GroupBuilder.createCollectionAdminGroup(context, collection) + .build(); authorizeService.addPolicy(context, collection, Constants.ADMIN, eperson); Group group = GroupBuilder.createGroup(context).withName("testGroup").build(); context.restoreAuthSystemState(); @@ -2853,7 +2860,8 @@ public void collectionAdminAddChildGroupToCollectionAdminGroupSuccess() throws E public void collectionAdminRemoveChildGroupFromCollectionAdminGroupSuccess() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = collectionService.createAdministrators(context, collection); + Group adminGroup = GroupBuilder.createCollectionAdminGroup(context, collection) + .build(); authorizeService.addPolicy(context, collection, Constants.ADMIN, eperson); Group group = GroupBuilder.createGroup(context).withName("testGroup").build(); context.restoreAuthSystemState(); @@ -2889,7 +2897,8 @@ public void collectionAdminRemoveChildGroupFromCollectionAdminGroupSuccess() thr public void collectionAdminAddMembersToCollectionAdminGroupPropertySetToFalse() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = collectionService.createAdministrators(context, collection); + Group adminGroup = GroupBuilder.createCollectionAdminGroup(context, collection) + .build(); authorizeService.addPolicy(context, collection, Constants.ADMIN, eperson); EPerson ePerson = EPersonBuilder.createEPerson(context).withEmail("testToAdd@test.com").build(); configurationService.setProperty("core.authorization.community-admin.collection.admin-group", false); @@ -2923,7 +2932,8 @@ public void collectionAdminAddMembersToCollectionAdminGroupPropertySetToFalse() public void collectionAdminRemoveMembersFromCollectionAdminGroupPropertySetToFalse() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = collectionService.createAdministrators(context, collection); + Group adminGroup = GroupBuilder.createCollectionAdminGroup(context, collection) + .build(); authorizeService.addPolicy(context, collection, Constants.ADMIN, eperson); EPerson ePerson = EPersonBuilder.createEPerson(context).withEmail("testToAdd@test.com").build(); context.restoreAuthSystemState(); @@ -2961,7 +2971,8 @@ public void collectionAdminRemoveMembersFromCollectionAdminGroupPropertySetToFal public void collectionAdminAddChildGroupToCollectionAdminGroupPropertySetToFalse() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = collectionService.createAdministrators(context, collection); + Group adminGroup = GroupBuilder.createCollectionAdminGroup(context, collection) + .build(); authorizeService.addPolicy(context, collection, Constants.ADMIN, eperson); Group group = GroupBuilder.createGroup(context).withName("testGroup").build(); configurationService.setProperty("core.authorization.community-admin.collection.admin-group", false); @@ -2990,7 +3001,8 @@ public void collectionAdminAddChildGroupToCollectionAdminGroupPropertySetToFalse public void collectionAdminRemoveChildGroupFromCollectionAdminGroupPropertySetToFalse() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = collectionService.createAdministrators(context, collection); + Group adminGroup = GroupBuilder.createCollectionAdminGroup(context, collection) + .build(); authorizeService.addPolicy(context, collection, Constants.ADMIN, eperson); Group group = GroupBuilder.createGroup(context).withName("testGroup").build(); context.restoreAuthSystemState(); From f66a35a1e1d02a86a59ef3f557cb5c2b59cd7d7c Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Fri, 6 Sep 2024 15:30:52 +0200 Subject: [PATCH 042/226] #9806: Tidy imports for GroupRestRepositoryIT (cherry picked from commit 80328eaca5f2ad36e006d32ea06aa3b89e2ada92) --- .../src/test/java/org/dspace/app/rest/GroupRestRepositoryIT.java | 1 - 1 file changed, 1 deletion(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/GroupRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/GroupRestRepositoryIT.java index 6f9d418f7f43..bdd13b97ff79 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/GroupRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/GroupRestRepositoryIT.java @@ -60,7 +60,6 @@ import org.dspace.content.Item; import org.dspace.content.MetadataSchemaEnum; import org.dspace.content.factory.ContentServiceFactory; -import org.dspace.content.service.CollectionService; import org.dspace.content.service.CommunityService; import org.dspace.core.Constants; import org.dspace.core.I18nUtil; From a6788700783212e99944c90e033bf4c33b9241f9 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Fri, 6 Sep 2024 15:31:31 +0200 Subject: [PATCH 043/226] #9806: Use builders for group, comm, coll creation in PackagerIT (cherry picked from commit 1f475aa731bbe42ad523f1056e6b56796ea8a2ee) --- .../src/test/java/org/dspace/app/packager/PackagerIT.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dspace-api/src/test/java/org/dspace/app/packager/PackagerIT.java b/dspace-api/src/test/java/org/dspace/app/packager/PackagerIT.java index 2cddbb511f91..aeda97f818c2 100644 --- a/dspace-api/src/test/java/org/dspace/app/packager/PackagerIT.java +++ b/dspace-api/src/test/java/org/dspace/app/packager/PackagerIT.java @@ -24,6 +24,7 @@ import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; import org.dspace.builder.ItemBuilder; +import org.dspace.builder.WorkspaceItemBuilder; import org.dspace.content.Collection; import org.dspace.content.Community; import org.dspace.content.Item; @@ -159,7 +160,7 @@ public void packagerUUIDAlreadyExistWithoutForceTest() throws Exception { performExportScript(article.getHandle(), tempFile); UUID id = article.getID(); itemService.delete(context, article); - WorkspaceItem workspaceItem = workspaceItemService.create(context, col1, id, false, false); + WorkspaceItem workspaceItem = WorkspaceItemBuilder.createWorkspaceItem(context, col1, id).build(); installItemService.installItem(context, workspaceItem, "123456789/0100"); performImportNoForceScript(tempFile); Iterator items = itemService.findByCollection(context, col1); From ba8385117c58b6d200aa310a87e8d1f7e23a4d81 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Fri, 6 Sep 2024 15:32:08 +0200 Subject: [PATCH 044/226] #9806: Use builders for group, comm, coll creation in StructBuilderIT (cherry picked from commit 2ef69045d15ae49a4d447227e8080860eecc61cd) --- .../dspace/administer/StructBuilderIT.java | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/administer/StructBuilderIT.java b/dspace-api/src/test/java/org/dspace/administer/StructBuilderIT.java index 63340698ac00..ead338bc8e70 100644 --- a/dspace-api/src/test/java/org/dspace/administer/StructBuilderIT.java +++ b/dspace-api/src/test/java/org/dspace/administer/StructBuilderIT.java @@ -23,11 +23,12 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.dspace.AbstractIntegrationTest; +import org.dspace.AbstractIntegrationTestWithDatabase; import org.dspace.authorize.AuthorizeException; +import org.dspace.builder.CollectionBuilder; +import org.dspace.builder.CommunityBuilder; import org.dspace.content.Collection; import org.dspace.content.Community; -import org.dspace.content.MetadataSchemaEnum; import org.dspace.content.factory.ContentServiceFactory; import org.dspace.content.service.CollectionService; import org.dspace.content.service.CommunityService; @@ -38,7 +39,6 @@ import org.junit.Test; import org.w3c.dom.Attr; import org.w3c.dom.Node; -import org.xml.sax.SAXException; import org.xmlunit.builder.DiffBuilder; import org.xmlunit.diff.Comparison; import org.xmlunit.diff.ComparisonFormatter; @@ -52,7 +52,7 @@ * @author Mark H. Wood */ public class StructBuilderIT - extends AbstractIntegrationTest { + extends AbstractIntegrationTestWithDatabase { private static final Logger log = LogManager.getLogger(); private static final CommunityService communityService @@ -79,7 +79,8 @@ public static void tearDownClass() { * @throws IOException passed through. */ @Before - public void setUp() throws SQLException, AuthorizeException, IOException { + public void setUp() throws Exception { + super.setUp(); // Clear out all communities and collections. context.turnOffAuthorisationSystem(); for (Community community : communityService.findAllTop(context)) { @@ -285,19 +286,15 @@ public void testImportStructureWithHandles() * @throws org.dspace.authorize.AuthorizeException passed through. */ @Test - public void testExportStructure() - throws ParserConfigurationException, SAXException, IOException, - SQLException, AuthorizeException { + public void testExportStructure() { // Create some structure to test. context.turnOffAuthorisationSystem(); - Community community0 = communityService.create(null, context); - communityService.setMetadataSingleValue(context, community0, - MetadataSchemaEnum.DC.getName(), "title", null, - null, "Top Community 0"); - Collection collection0_0 = collectionService.create(context, community0); - collectionService.setMetadataSingleValue(context, collection0_0, - MetadataSchemaEnum.DC.getName(), "title", null, - null, "Collection 0.0"); + // Top level community + Community community0 = CommunityBuilder.createCommunity(context) + .withName("Top Community 0").build(); + // Collection below top level community + Collection collection0_0 = CollectionBuilder.createCollection(context, community0) + .withName("Collection 0.0").build(); // Export the current structure. System.out.println("exportStructure"); From dcb567ead6d30f385cdb09a893f3e651f25ad374 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Fri, 6 Sep 2024 15:33:30 +0200 Subject: [PATCH 045/226] #9806: Refactor WorkspaceItemBuilder to support specific item uuid (cherry picked from commit b99b1eec29c5a0b6e92998b072282b03cfedc080) --- .../dspace/builder/WorkspaceItemBuilder.java | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/builder/WorkspaceItemBuilder.java b/dspace-api/src/test/java/org/dspace/builder/WorkspaceItemBuilder.java index 8b82149cdf7f..67d8894338eb 100644 --- a/dspace-api/src/test/java/org/dspace/builder/WorkspaceItemBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/WorkspaceItemBuilder.java @@ -10,6 +10,7 @@ import java.io.IOException; import java.io.InputStream; import java.sql.SQLException; +import java.util.UUID; import org.dspace.app.ldn.NotifyPatternToTrigger; import org.dspace.app.ldn.NotifyServiceEntity; @@ -43,14 +44,31 @@ protected WorkspaceItemBuilder(Context context) { public static WorkspaceItemBuilder createWorkspaceItem(final Context context, final Collection col) { WorkspaceItemBuilder builder = new WorkspaceItemBuilder(context); - return builder.create(context, col); + return builder.create(context, col, null); } - private WorkspaceItemBuilder create(final Context context, final Collection col) { + public static WorkspaceItemBuilder createWorkspaceItem(final Context context, final Collection col, UUID uuid) { + WorkspaceItemBuilder builder = new WorkspaceItemBuilder(context); + return builder.create(context, col, uuid); + } + + /** + * Create with a specific UUID (e.g. restoring items with Packager import) + * + * @param context DSpace context + * @param col Parent collection + * @param uuid Item UUID + * @return WorkspaceItemBuilder + */ + private WorkspaceItemBuilder create(final Context context, final Collection col, UUID uuid) { this.context = context; try { - workspaceItem = workspaceItemService.create(context, col, false); + if (uuid == null) { + workspaceItem = workspaceItemService.create(context, col, false); + } else { + workspaceItem = workspaceItemService.create(context, col, uuid, false, false); + } item = workspaceItem.getItem(); } catch (Exception e) { return handleException(e); From a591357f56da47aa322a319658889b501a88bb19 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Fri, 6 Sep 2024 15:34:05 +0200 Subject: [PATCH 046/226] #9806: Use builders for comm, coll, group creation in SupervisionOrderServiceIT (cherry picked from commit 6e9181e3f7cd502b345af7d5879fa25654176c25) --- .../SupervisionOrderServiceIT.java | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/supervision/SupervisionOrderServiceIT.java b/dspace-api/src/test/java/org/dspace/supervision/SupervisionOrderServiceIT.java index 60407823485b..aa4cd8bd4e49 100644 --- a/dspace-api/src/test/java/org/dspace/supervision/SupervisionOrderServiceIT.java +++ b/dspace-api/src/test/java/org/dspace/supervision/SupervisionOrderServiceIT.java @@ -18,6 +18,7 @@ import org.dspace.builder.CommunityBuilder; import org.dspace.builder.EPersonBuilder; import org.dspace.builder.GroupBuilder; +import org.dspace.builder.SupervisionOrderBuilder; import org.dspace.builder.WorkspaceItemBuilder; import org.dspace.content.Collection; import org.dspace.content.Item; @@ -85,10 +86,10 @@ public void createSupervisionOrderTest() throws Exception { .build(); SupervisionOrder supervisionOrderOne = - supervisionOrderService.create(context, item, groupA); + SupervisionOrderBuilder.createSupervisionOrder(context, item, groupA).build(); SupervisionOrder supervisionOrderTwo = - supervisionOrderService.create(context, item, groupB); + SupervisionOrderBuilder.createSupervisionOrder(context, item, groupB).build(); context.restoreAuthSystemState(); @@ -136,7 +137,8 @@ public void findSupervisionOrderTest() throws Exception { .build(); SupervisionOrder supervisionOrderOne = - supervisionOrderService.create(context, workspaceItem.getItem(), groupA); + SupervisionOrderBuilder.createSupervisionOrder(context, workspaceItem.getItem(), groupA) + .build(); context.restoreAuthSystemState(); @@ -205,9 +207,12 @@ public void findAllSupervisionOrdersTest() throws Exception { .addMember(userB) .build(); - supervisionOrderService.create(context, workspaceItem.getItem(), groupA); - supervisionOrderService.create(context, workspaceItem.getItem(), groupB); - supervisionOrderService.create(context, workspaceItemTwo.getItem(), groupA); + SupervisionOrderBuilder.createSupervisionOrder(context, workspaceItem.getItem(), groupA) + .build(); + SupervisionOrderBuilder.createSupervisionOrder(context, workspaceItem.getItem(), groupB) + .build(); + SupervisionOrderBuilder.createSupervisionOrder(context, workspaceItemTwo.getItem(), groupA) + .build(); context.restoreAuthSystemState(); @@ -259,9 +264,12 @@ public void findSupervisionOrderByItemTest() throws Exception { .addMember(eperson) .build(); - supervisionOrderService.create(context, workspaceItem.getItem(), groupA); - supervisionOrderService.create(context, workspaceItem.getItem(), groupB); - supervisionOrderService.create(context, workspaceItemTwo.getItem(), groupA); + SupervisionOrderBuilder.createSupervisionOrder(context, workspaceItem.getItem(), groupA) + .build(); + SupervisionOrderBuilder.createSupervisionOrder(context, workspaceItem.getItem(), groupB) + .build(); + SupervisionOrderBuilder.createSupervisionOrder(context, workspaceItemTwo.getItem(), groupA) + .build(); context.restoreAuthSystemState(); @@ -310,7 +318,8 @@ public void findSupervisionOrderByItemAndGroupTest() throws Exception { .addMember(eperson) .build(); - supervisionOrderService.create(context, item, groupA); + SupervisionOrderBuilder.createSupervisionOrder(context, item, groupA) + .build(); context.restoreAuthSystemState(); @@ -370,7 +379,8 @@ public void isSupervisorTest() throws Exception { .addMember(userB) .build(); - supervisionOrderService.create(context, workspaceItem.getItem(), groupA); + SupervisionOrderBuilder.createSupervisionOrder(context, workspaceItem.getItem(), groupA) + .build(); context.restoreAuthSystemState(); From 2616c0b59129a950d15106f442535d3d59590e67 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Fri, 6 Sep 2024 15:35:14 +0200 Subject: [PATCH 047/226] #9806: Use builders for comm, coll, group creation in CollectionGroupRestControllerIT (cherry picked from commit f4629d8351b70ca945ffeebdf928cebfb868c349) --- .../rest/CollectionGroupRestControllerIT.java | 151 +++++++++--------- 1 file changed, 77 insertions(+), 74 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionGroupRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionGroupRestControllerIT.java index f6ab10c087ad..8d490109220d 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionGroupRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/CollectionGroupRestControllerIT.java @@ -28,9 +28,9 @@ import org.dspace.authorize.service.AuthorizeService; import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; +import org.dspace.builder.GroupBuilder; import org.dspace.builder.WorkspaceItemBuilder; import org.dspace.content.Collection; -import org.dspace.content.service.CollectionService; import org.dspace.core.Constants; import org.dspace.eperson.Group; import org.dspace.eperson.service.GroupService; @@ -41,10 +41,6 @@ public class CollectionGroupRestControllerIT extends AbstractControllerIntegrationTest { - - @Autowired - private CollectionService collectionService; - @Autowired private GroupService groupService; @@ -68,7 +64,7 @@ public void setup() { @Test public void getCollectionAdminGroupTest() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = collectionService.createAdministrators(context, collection); + Group adminGroup = GroupBuilder.createCollectionAdminGroup(context, collection).build(); context.restoreAuthSystemState(); String token = getAuthToken(admin.getEmail(), password); @@ -81,7 +77,7 @@ public void getCollectionAdminGroupTest() throws Exception { @Test public void getCollectionAdminGroupTestParentCommunityAdmin() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = collectionService.createAdministrators(context, collection); + Group adminGroup = GroupBuilder.createCollectionAdminGroup(context, collection).build(); authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson); context.restoreAuthSystemState(); @@ -95,7 +91,7 @@ public void getCollectionAdminGroupTestParentCommunityAdmin() throws Exception { @Test public void getCollectionAdminGroupTestCollectionAdmin() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = collectionService.createAdministrators(context, collection); + Group adminGroup = GroupBuilder.createCollectionAdminGroup(context, collection).build(); authorizeService.addPolicy(context, collection, Constants.ADMIN, eperson); context.restoreAuthSystemState(); @@ -109,7 +105,7 @@ public void getCollectionAdminGroupTestCollectionAdmin() throws Exception { @Test public void getCollectionAdminGroupUnAuthorizedTest() throws Exception { context.turnOffAuthorisationSystem(); - collectionService.createAdministrators(context, collection); + GroupBuilder.createCollectionAdminGroup(context, collection).build(); context.restoreAuthSystemState(); getClient().perform(get("/api/core/collections/" + collection.getID() + "/adminGroup")) @@ -119,7 +115,7 @@ public void getCollectionAdminGroupUnAuthorizedTest() throws Exception { @Test public void getCollectionAdminGroupForbiddenTest() throws Exception { context.turnOffAuthorisationSystem(); - collectionService.createAdministrators(context, collection); + GroupBuilder.createCollectionAdminGroup(context, collection).build(); context.restoreAuthSystemState(); String token = getAuthToken(eperson.getEmail(), password); @@ -413,7 +409,7 @@ public void postCollectionAdminGroupCreateAdminGroupUnProcessablePermanent() thr @Test public void deleteCollectionAdminGroupTest() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = collectionService.createAdministrators(context, collection); + GroupBuilder.createCollectionAdminGroup(context, collection).build(); context.restoreAuthSystemState(); String token = getAuthToken(admin.getEmail(), password); @@ -428,7 +424,7 @@ public void deleteCollectionAdminGroupTest() throws Exception { @Test public void deleteCollectionAdminGroupTestParentCommunityAdmin() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = collectionService.createAdministrators(context, collection); + GroupBuilder.createCollectionAdminGroup(context, collection).build(); authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson); context.restoreAuthSystemState(); @@ -443,7 +439,7 @@ public void deleteCollectionAdminGroupTestParentCommunityAdmin() throws Exceptio @Test public void deleteCollectionAdminGroupTestCollectionAdmin() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = collectionService.createAdministrators(context, collection); + GroupBuilder.createCollectionAdminGroup(context, collection).build(); authorizeService.addPolicy(context, collection, Constants.ADMIN, eperson); context.restoreAuthSystemState(); @@ -458,7 +454,7 @@ public void deleteCollectionAdminGroupTestCollectionAdmin() throws Exception { @Test public void deleteCollectionAdminGroupUnAuthorizedTest() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = collectionService.createAdministrators(context, collection); + Group adminGroup = GroupBuilder.createCollectionAdminGroup(context, collection).build(); context.restoreAuthSystemState(); getClient().perform(delete("/api/core/collections/" + collection.getID() + "/adminGroup")) @@ -474,7 +470,7 @@ public void deleteCollectionAdminGroupUnAuthorizedTest() throws Exception { @Test public void deleteCollectionAdminGroupForbiddenTest() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = collectionService.createAdministrators(context, collection); + Group adminGroup = GroupBuilder.createCollectionAdminGroup(context, collection).build(); context.restoreAuthSystemState(); String token = getAuthToken(eperson.getEmail(), password); @@ -493,7 +489,7 @@ public void deleteCollectionAdminGroupForbiddenTest() throws Exception { @Test public void deleteCollectionAdminGroupNotFoundTest() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = collectionService.createAdministrators(context, collection); + Group adminGroup = GroupBuilder.createCollectionAdminGroup(context, collection).build(); context.restoreAuthSystemState(); String token = getAuthToken(eperson.getEmail(), password); @@ -512,7 +508,7 @@ public void deleteCollectionAdminGroupNotFoundTest() throws Exception { @Test public void getCollectionSubmittersGroupTest() throws Exception { context.turnOffAuthorisationSystem(); - Group submitters = collectionService.createSubmitters(context, collection); + Group submitters = GroupBuilder.createCollectionSubmitterGroup(context, collection).build(); context.restoreAuthSystemState(); String token = getAuthToken(admin.getEmail(), password); @@ -525,7 +521,7 @@ public void getCollectionSubmittersGroupTest() throws Exception { @Test public void getCollectionSubmittersGroupTestParentCommunityAdmin() throws Exception { context.turnOffAuthorisationSystem(); - Group submitters = collectionService.createSubmitters(context, collection); + Group submitters = GroupBuilder.createCollectionSubmitterGroup(context, collection).build(); authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson); context.restoreAuthSystemState(); @@ -539,7 +535,7 @@ public void getCollectionSubmittersGroupTestParentCommunityAdmin() throws Except @Test public void getCollectionSubmittersGroupTestCollectionAdmin() throws Exception { context.turnOffAuthorisationSystem(); - Group submitters = collectionService.createSubmitters(context, collection); + Group submitters = GroupBuilder.createCollectionSubmitterGroup(context, collection).build(); authorizeService.addPolicy(context, collection, Constants.ADMIN, eperson); context.restoreAuthSystemState(); @@ -553,7 +549,7 @@ public void getCollectionSubmittersGroupTestCollectionAdmin() throws Exception { @Test public void getCollectionSubmittersGroupUnAuthorizedTest() throws Exception { context.turnOffAuthorisationSystem(); - collectionService.createSubmitters(context, collection); + GroupBuilder.createCollectionSubmitterGroup(context, collection).build(); context.restoreAuthSystemState(); getClient().perform(get("/api/core/collections/" + collection.getID() + "/submittersGroup")) @@ -563,7 +559,7 @@ public void getCollectionSubmittersGroupUnAuthorizedTest() throws Exception { @Test public void getCollectionSubmittersGroupForbiddenTest() throws Exception { context.turnOffAuthorisationSystem(); - collectionService.createSubmitters(context, collection); + GroupBuilder.createCollectionSubmitterGroup(context, collection).build(); context.restoreAuthSystemState(); String token = getAuthToken(eperson.getEmail(), password); @@ -860,7 +856,7 @@ public void postCollectionSubmittersGroupCreateSubmittersGroupUnProcessablePerma @Test public void deleteCollectionSubmitterGroupTest() throws Exception { context.turnOffAuthorisationSystem(); - Group submittersGroup = collectionService.createSubmitters(context, collection); + GroupBuilder.createCollectionSubmitterGroup(context, collection).build(); context.restoreAuthSystemState(); String token = getAuthToken(admin.getEmail(), password); @@ -875,7 +871,7 @@ public void deleteCollectionSubmitterGroupTest() throws Exception { @Test public void deleteCollectionSubmittersGroupTestParentCommunityAdmin() throws Exception { context.turnOffAuthorisationSystem(); - Group submittersGroup = collectionService.createSubmitters(context, collection); + GroupBuilder.createCollectionSubmitterGroup(context, collection).build(); authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson); context.restoreAuthSystemState(); @@ -890,7 +886,7 @@ public void deleteCollectionSubmittersGroupTestParentCommunityAdmin() throws Exc @Test public void deleteCollectionSubmittersGroupTestCollectionAdmin() throws Exception { context.turnOffAuthorisationSystem(); - Group submittersGroup = collectionService.createSubmitters(context, collection); + GroupBuilder.createCollectionSubmitterGroup(context, collection).build(); authorizeService.addPolicy(context, collection, Constants.ADMIN, eperson); context.restoreAuthSystemState(); @@ -905,7 +901,7 @@ public void deleteCollectionSubmittersGroupTestCollectionAdmin() throws Exceptio @Test public void deleteCollectionSubmittersGroupUnAuthorizedTest() throws Exception { context.turnOffAuthorisationSystem(); - Group submittersGroup = collectionService.createSubmitters(context, collection); + Group submittersGroup = GroupBuilder.createCollectionSubmitterGroup(context, collection).build(); context.restoreAuthSystemState(); getClient().perform(delete("/api/core/collections/" + collection.getID() + "/submittersGroup")) @@ -924,7 +920,7 @@ public void deleteCollectionSubmittersGroupUnAuthorizedTest() throws Exception { @Test public void deleteCollectionSubmittersGroupForbiddenTest() throws Exception { context.turnOffAuthorisationSystem(); - Group submittersGroup = collectionService.createSubmitters(context, collection); + Group submittersGroup = GroupBuilder.createCollectionSubmitterGroup(context, collection).build(); context.restoreAuthSystemState(); String token = getAuthToken(eperson.getEmail(), password); @@ -945,7 +941,7 @@ public void deleteCollectionSubmittersGroupForbiddenTest() throws Exception { @Test public void deleteCollectionSubmittersGroupNotFoundTest() throws Exception { context.turnOffAuthorisationSystem(); - Group submittersGroup = collectionService.createSubmitters(context, collection); + GroupBuilder.createCollectionSubmitterGroup(context, collection).build(); context.restoreAuthSystemState(); String token = getAuthToken(eperson.getEmail(), password); @@ -961,7 +957,8 @@ public void getCollectionItemReadGroupTest() throws Exception { String itemGroupString = "ITEM"; int defaultItemRead = Constants.DEFAULT_ITEM_READ; - Group role = collectionService.createDefaultReadGroup(context, collection, itemGroupString, defaultItemRead); + Group role = GroupBuilder.createCollectionDefaultReadGroup(context, collection, + itemGroupString, defaultItemRead).build(); context.restoreAuthSystemState(); String token = getAuthToken(admin.getEmail(), password); @@ -977,7 +974,8 @@ public void getCollectionDefaultItemReadGroupTestParentCommunityAdmin() throws E String itemGroupString = "ITEM"; int defaultItemRead = Constants.DEFAULT_ITEM_READ; - Group role = collectionService.createDefaultReadGroup(context, collection, itemGroupString, defaultItemRead); + Group role = GroupBuilder.createCollectionDefaultReadGroup(context, collection, + itemGroupString, defaultItemRead).build(); authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson); context.restoreAuthSystemState(); @@ -995,7 +993,8 @@ public void getCollectionDefaultItemReadGroupTestCollectionAdmin() throws Except String itemGroupString = "ITEM"; int defaultItemRead = Constants.DEFAULT_ITEM_READ; - Group role = collectionService.createDefaultReadGroup(context, collection, itemGroupString, defaultItemRead); + Group role = GroupBuilder.createCollectionDefaultReadGroup(context, collection, + itemGroupString, defaultItemRead).build(); authorizeService.addPolicy(context, collection, Constants.ADMIN, eperson); context.restoreAuthSystemState(); @@ -1012,7 +1011,8 @@ public void getCollectionDefaultItemReadGroupUnAuthorizedTest() throws Exception String itemGroupString = "ITEM"; int defaultItemRead = Constants.DEFAULT_ITEM_READ; - Group role = collectionService.createDefaultReadGroup(context, collection, itemGroupString, defaultItemRead); + GroupBuilder.createCollectionDefaultReadGroup(context, collection, + itemGroupString, defaultItemRead).build(); context.restoreAuthSystemState(); getClient().perform(get("/api/core/collections/" + collection.getID() + "/itemReadGroup")) @@ -1025,7 +1025,8 @@ public void getCollectionDefaultItemReadGroupForbiddenTest() throws Exception { String itemGroupString = "ITEM"; int defaultItemRead = Constants.DEFAULT_ITEM_READ; - Group role = collectionService.createDefaultReadGroup(context, collection, itemGroupString, defaultItemRead); + GroupBuilder.createCollectionDefaultReadGroup(context, collection, + itemGroupString, defaultItemRead).build(); context.restoreAuthSystemState(); String token = getAuthToken(eperson.getEmail(), password); @@ -1321,7 +1322,7 @@ public void deleteCollectionDefaultItemReadGroupTest() throws Exception { String itemGroupString = "ITEM"; int defaultItemRead = Constants.DEFAULT_ITEM_READ; - Group role = collectionService.createDefaultReadGroup(context, collection, itemGroupString, defaultItemRead); + GroupBuilder.createCollectionDefaultReadGroup(context, collection, itemGroupString, defaultItemRead).build(); context.restoreAuthSystemState(); String token = getAuthToken(admin.getEmail(), password); @@ -1345,7 +1346,7 @@ public void deleteCollectionDefaultItemReadGroupTestParentCommunityAdmin() throw String itemGroupString = "ITEM"; int defaultItemRead = Constants.DEFAULT_ITEM_READ; - Group role = collectionService.createDefaultReadGroup(context, collection, itemGroupString, defaultItemRead); + GroupBuilder.createCollectionDefaultReadGroup(context, collection, itemGroupString, defaultItemRead).build(); authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson); context.restoreAuthSystemState(); @@ -1367,7 +1368,7 @@ public void deleteCollectionDefaultItemReadGroupTestCollectionAdmin() throws Exc String itemGroupString = "ITEM"; int defaultItemRead = Constants.DEFAULT_ITEM_READ; - Group role = collectionService.createDefaultReadGroup(context, collection, itemGroupString, defaultItemRead); + GroupBuilder.createCollectionDefaultReadGroup(context, collection, itemGroupString, defaultItemRead).build(); authorizeService.addPolicy(context, collection, Constants.ADMIN, eperson); context.restoreAuthSystemState(); @@ -1389,7 +1390,8 @@ public void deleteCollectionDefaultItemReadGroupUnAuthorizedTest() throws Except String itemGroupString = "ITEM"; int defaultItemRead = Constants.DEFAULT_ITEM_READ; - Group role = collectionService.createDefaultReadGroup(context, collection, itemGroupString, defaultItemRead); + Group role = GroupBuilder.createCollectionDefaultReadGroup(context, collection, + itemGroupString, defaultItemRead).build(); context.restoreAuthSystemState(); getClient().perform(delete("/api/core/collections/" + collection.getID() + "/itemReadGroup")) @@ -1408,7 +1410,8 @@ public void deleteCollectionDefaultItemReadGroupForbiddenTest() throws Exception String itemGroupString = "ITEM"; int defaultItemRead = Constants.DEFAULT_ITEM_READ; - Group role = collectionService.createDefaultReadGroup(context, collection, itemGroupString, defaultItemRead); + Group role = GroupBuilder.createCollectionDefaultReadGroup(context, collection, + itemGroupString, defaultItemRead).build(); context.restoreAuthSystemState(); String token = getAuthToken(eperson.getEmail(), password); @@ -1430,7 +1433,7 @@ public void deleteCollectionDefaultItemReadGroupNotFoundTest() throws Exception String itemGroupString = "ITEM"; int defaultItemRead = Constants.DEFAULT_ITEM_READ; - Group role = collectionService.createDefaultReadGroup(context, collection, itemGroupString, defaultItemRead); + GroupBuilder.createCollectionDefaultReadGroup(context, collection, itemGroupString, defaultItemRead).build(); context.restoreAuthSystemState(); String token = getAuthToken(eperson.getEmail(), password); @@ -1445,8 +1448,8 @@ public void getCollectionBitstreamReadGroupTest() throws Exception { String bitstreamGroupString = "BITSTREAM"; int defaultBitstreamRead = Constants.DEFAULT_BITSTREAM_READ; - Group role = collectionService.createDefaultReadGroup(context, collection, bitstreamGroupString, - defaultBitstreamRead); + Group role = GroupBuilder.createCollectionDefaultReadGroup(context, collection, + bitstreamGroupString, defaultBitstreamRead).build(); context.restoreAuthSystemState(); String token = getAuthToken(admin.getEmail(), password); @@ -1462,8 +1465,8 @@ public void getCollectionDefaultBitstreamReadGroupTestParentCommunityAdmin() thr String bitstreamGroupString = "BITSTREAM"; int defaultBitstreamRead = Constants.DEFAULT_BITSTREAM_READ; - Group role = collectionService.createDefaultReadGroup(context, collection, bitstreamGroupString, - defaultBitstreamRead); + Group role = GroupBuilder.createCollectionDefaultReadGroup(context, collection, + bitstreamGroupString, defaultBitstreamRead).build(); authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson); context.restoreAuthSystemState(); @@ -1480,8 +1483,8 @@ public void getCollectionDefaultBitstreamReadGroupTestCollectionAdmin() throws E String bitstreamGroupString = "BITSTREAM"; int defaultBitstreamRead = Constants.DEFAULT_BITSTREAM_READ; - Group role = collectionService.createDefaultReadGroup(context, collection, bitstreamGroupString, - defaultBitstreamRead); + Group role = GroupBuilder.createCollectionDefaultReadGroup(context, collection, + bitstreamGroupString, defaultBitstreamRead).build(); authorizeService.addPolicy(context, collection, Constants.ADMIN, eperson); context.restoreAuthSystemState(); @@ -1498,8 +1501,8 @@ public void getCollectionDefaultBitstreamReadGroupUnAuthorizedTest() throws Exce String bitstreamGroupString = "BITSTREAM"; int defaultBitstreamRead = Constants.DEFAULT_BITSTREAM_READ; - Group role = collectionService.createDefaultReadGroup(context, collection, bitstreamGroupString, - defaultBitstreamRead); + GroupBuilder.createCollectionDefaultReadGroup(context, collection, + bitstreamGroupString, defaultBitstreamRead).build(); context.restoreAuthSystemState(); getClient().perform(get("/api/core/collections/" + collection.getID() + "/bitstreamReadGroup")) @@ -1512,8 +1515,8 @@ public void getCollectionDefaultBitstreamReadGroupForbiddenTest() throws Excepti String bitstreamGroupString = "BITSTREAM"; int defaultBitstreamRead = Constants.DEFAULT_BITSTREAM_READ; - Group role = collectionService.createDefaultReadGroup(context, collection, bitstreamGroupString, - defaultBitstreamRead); + GroupBuilder.createCollectionDefaultReadGroup(context, collection, + bitstreamGroupString, defaultBitstreamRead).build(); context.restoreAuthSystemState(); String token = getAuthToken(eperson.getEmail(), password); @@ -1811,8 +1814,8 @@ public void deleteCollectionDefaultBitstreamReadGroupTest() throws Exception { String bitstreamGroupString = "BITSTREAM"; int defaultBitstreamRead = Constants.DEFAULT_BITSTREAM_READ; - Group role = collectionService.createDefaultReadGroup(context, collection, bitstreamGroupString, - defaultBitstreamRead); + GroupBuilder.createCollectionDefaultReadGroup(context, collection, + bitstreamGroupString, defaultBitstreamRead).build(); context.restoreAuthSystemState(); String token = getAuthToken(admin.getEmail(), password); @@ -1835,8 +1838,8 @@ public void deleteCollectionDefaultBitstreamReadGroupTestParentCommunityAdmin() String bitstreamGroupString = "BITSTREAM"; int defaultBitstreamRead = Constants.DEFAULT_BITSTREAM_READ; - Group role = collectionService.createDefaultReadGroup(context, collection, bitstreamGroupString, - defaultBitstreamRead); + GroupBuilder.createCollectionDefaultReadGroup(context, collection, + bitstreamGroupString, defaultBitstreamRead).build(); authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson); context.restoreAuthSystemState(); @@ -1859,8 +1862,8 @@ public void deleteCollectionDefaultBitstreamReadGroupTestCollectionAdmin() throw String bitstreamGroupString = "BITSTREAM"; int defaultBitstreamRead = Constants.DEFAULT_BITSTREAM_READ; - Group role = collectionService.createDefaultReadGroup(context, collection, bitstreamGroupString, - defaultBitstreamRead); + GroupBuilder.createCollectionDefaultReadGroup(context, collection, + bitstreamGroupString, defaultBitstreamRead).build(); authorizeService.addPolicy(context, collection, Constants.ADMIN, eperson); context.restoreAuthSystemState(); @@ -1882,8 +1885,8 @@ public void deleteCollectionDefaultBitstreamReadGroupUnAuthorizedTest() throws E String bitstreamGroupString = "BITSTREAM"; int defaultBitstreamRead = Constants.DEFAULT_BITSTREAM_READ; - Group role = collectionService.createDefaultReadGroup(context, collection, bitstreamGroupString, - defaultBitstreamRead); + Group role = GroupBuilder.createCollectionDefaultReadGroup(context, collection, + bitstreamGroupString, defaultBitstreamRead).build(); context.restoreAuthSystemState(); getClient().perform(delete("/api/core/collections/" + collection.getID() + "/bitstreamReadGroup")) @@ -1902,8 +1905,8 @@ public void deleteCollectionDefaultBitstreamReadGroupForbiddenTest() throws Exce String bitstreamGroupString = "BITSTREAM"; int defaultBitstreamRead = Constants.DEFAULT_BITSTREAM_READ; - Group role = collectionService.createDefaultReadGroup(context, collection, bitstreamGroupString, - defaultBitstreamRead); + GroupBuilder.createCollectionDefaultReadGroup(context, collection, + bitstreamGroupString, defaultBitstreamRead).build(); context.restoreAuthSystemState(); String token = getAuthToken(eperson.getEmail(), password); @@ -1918,8 +1921,8 @@ public void deleteCollectionDefaultBitstreamReadGroupNotFoundTest() throws Excep String bitstreamGroupString = "BITSTREAM"; int defaultBitstreamRead = Constants.DEFAULT_BITSTREAM_READ; - Group role = collectionService.createDefaultReadGroup(context, collection, bitstreamGroupString, - defaultBitstreamRead); + GroupBuilder.createCollectionDefaultReadGroup(context, collection, + bitstreamGroupString, defaultBitstreamRead).build(); context.restoreAuthSystemState(); String token = getAuthToken(eperson.getEmail(), password); @@ -1931,7 +1934,7 @@ public void deleteCollectionDefaultBitstreamReadGroupNotFoundTest() throws Excep public void getWorkflowGroupForCollectionAndRole() throws Exception { context.turnOffAuthorisationSystem(); - Group group = workflowService.createWorkflowRoleGroup(context, collection, "reviewer"); + Group group = GroupBuilder.createCollectionWorkflowRoleGroup(context, collection, "reviewer").build(); context.restoreAuthSystemState(); String token = getAuthToken(admin.getEmail(), password); @@ -1944,7 +1947,7 @@ public void getWorkflowGroupForCollectionAndRole() throws Exception { @Test public void getWorkflowGroupForCollectionAndRoleParentCommunityAdmin() throws Exception { context.turnOffAuthorisationSystem(); - Group group = workflowService.createWorkflowRoleGroup(context, collection, "reviewer"); + Group group = GroupBuilder.createCollectionWorkflowRoleGroup(context, collection, "reviewer").build(); authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson); context.restoreAuthSystemState(); @@ -1958,7 +1961,7 @@ public void getWorkflowGroupForCollectionAndRoleParentCommunityAdmin() throws Ex @Test public void getWorkflowGroupForCollectionAndRoleWrongUUIDCollectionNotFound() throws Exception { context.turnOffAuthorisationSystem(); - Group group = workflowService.createWorkflowRoleGroup(context, collection, "reviewer"); + GroupBuilder.createCollectionWorkflowRoleGroup(context, collection, "reviewer").build(); context.restoreAuthSystemState(); String token = getAuthToken(eperson.getEmail(), password); @@ -1979,7 +1982,7 @@ public void getWorkflowGroupForCollectionAndRoleWrongRoleNotFound() throws Excep public void getWorkflowGroupCommunityAdmin() throws Exception { context.turnOffAuthorisationSystem(); - Group group = workflowService.createWorkflowRoleGroup(context, collection, "reviewer"); + Group group = GroupBuilder.createCollectionWorkflowRoleGroup(context, collection, "reviewer").build(); authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson); context.restoreAuthSystemState(); @@ -1994,7 +1997,7 @@ public void getWorkflowGroupCommunityAdmin() throws Exception { @Test public void getWorkflowGroupCollectionAdmin() throws Exception { context.turnOffAuthorisationSystem(); - Group group = workflowService.createWorkflowRoleGroup(context, collection, "reviewer"); + Group group = GroupBuilder.createCollectionWorkflowRoleGroup(context, collection, "reviewer").build(); authorizeService.addPolicy(context, collection, Constants.ADMIN, eperson); context.restoreAuthSystemState(); @@ -2009,7 +2012,7 @@ public void getWorkflowGroupCollectionAdmin() throws Exception { @Test public void getWorkflowGroupUnAuthorized() throws Exception { context.turnOffAuthorisationSystem(); - Group group = workflowService.createWorkflowRoleGroup(context, collection, "reviewer"); + GroupBuilder.createCollectionWorkflowRoleGroup(context, collection, "reviewer").build(); context.restoreAuthSystemState(); getClient().perform(get("/api/core/collections/" + collection.getID() + "/workflowGroups/reviewer")) @@ -2019,7 +2022,7 @@ public void getWorkflowGroupUnAuthorized() throws Exception { @Test public void getWorkflowGroupForbidden() throws Exception { context.turnOffAuthorisationSystem(); - Group group = workflowService.createWorkflowRoleGroup(context, collection, "reviewer"); + GroupBuilder.createCollectionWorkflowRoleGroup(context, collection, "reviewer").build(); context.restoreAuthSystemState(); String token = getAuthToken(eperson.getEmail(), password); @@ -2324,7 +2327,7 @@ public void postCollectionWorkflowGroupCreateWorkflowGroupUnProcessablePermanent @Test public void deleteCollectionWorkflowGroupTest() throws Exception { context.turnOffAuthorisationSystem(); - Group group = workflowService.createWorkflowRoleGroup(context, collection, "reviewer"); + GroupBuilder.createCollectionWorkflowRoleGroup(context, collection, "reviewer").build(); context.restoreAuthSystemState(); String token = getAuthToken(admin.getEmail(), password); @@ -2339,7 +2342,7 @@ public void deleteCollectionWorkflowGroupTest() throws Exception { @Test public void deleteCollectionWorkflowGroupTestParentCommunityAdmin() throws Exception { context.turnOffAuthorisationSystem(); - Group group = workflowService.createWorkflowRoleGroup(context, collection, "reviewer"); + GroupBuilder.createCollectionWorkflowRoleGroup(context, collection, "reviewer").build(); authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson); context.restoreAuthSystemState(); @@ -2355,7 +2358,7 @@ public void deleteCollectionWorkflowGroupTestParentCommunityAdmin() throws Excep @Test public void deleteCollectionWorkflowGroupTestCollectionAdmin() throws Exception { context.turnOffAuthorisationSystem(); - Group group = workflowService.createWorkflowRoleGroup(context, collection, "reviewer"); + GroupBuilder.createCollectionWorkflowRoleGroup(context, collection, "reviewer").build(); authorizeService.addPolicy(context, collection, Constants.ADMIN, eperson); context.restoreAuthSystemState(); @@ -2371,7 +2374,7 @@ public void deleteCollectionWorkflowGroupTestCollectionAdmin() throws Exception @Test public void deleteCollectionWorkflowGroupUnAuthorizedTest() throws Exception { context.turnOffAuthorisationSystem(); - Group group = workflowService.createWorkflowRoleGroup(context, collection, "reviewer"); + Group group = GroupBuilder.createCollectionWorkflowRoleGroup(context, collection, "reviewer").build(); context.restoreAuthSystemState(); getClient().perform(delete("/api/core/collections/" + collection.getID() + "/workflowGroups/reviewer")) @@ -2387,7 +2390,7 @@ public void deleteCollectionWorkflowGroupUnAuthorizedTest() throws Exception { @Test public void deleteCollectionWorkflowGroupForbiddenTest() throws Exception { context.turnOffAuthorisationSystem(); - Group group = workflowService.createWorkflowRoleGroup(context, collection, "reviewer"); + Group group = GroupBuilder.createCollectionWorkflowRoleGroup(context, collection, "reviewer").build(); context.restoreAuthSystemState(); String token = getAuthToken(eperson.getEmail(), password); @@ -2406,7 +2409,7 @@ public void deleteCollectionWorkflowGroupForbiddenTest() throws Exception { @Test public void deleteCollectionWorkflowGroupNotFoundTest() throws Exception { context.turnOffAuthorisationSystem(); - Group group = workflowService.createWorkflowRoleGroup(context, collection, "reviewer"); + GroupBuilder.createCollectionWorkflowRoleGroup(context, collection, "reviewer").build(); context.restoreAuthSystemState(); String token = getAuthToken(eperson.getEmail(), password); @@ -2418,7 +2421,7 @@ public void deleteCollectionWorkflowGroupNotFoundTest() throws Exception { @Test public void deleteCollectionWorkflowGroupWithPooledTaskTest() throws Exception { context.turnOffAuthorisationSystem(); - Group reviewer = workflowService.createWorkflowRoleGroup(context, collection, "reviewer"); + Group reviewer = GroupBuilder.createCollectionWorkflowRoleGroup(context, collection, "reviewer").build(); // Submit an Item into the workflow -> moves to the "reviewer" step's pool. // The role must have at least one EPerson, otherwise the WSI gets archived immediately From 365987456164b58ed508e6aaed9816b0dda27efb Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Fri, 6 Sep 2024 15:35:43 +0200 Subject: [PATCH 048/226] #9806: Builders for comm, coll, group in CommunityAdminGroupRestControllerIT (cherry picked from commit 2d9988f77c52537f46888f27e35dbc0360299835) --- .../CommunityAdminGroupRestControllerIT.java | 52 +++++++++---------- 1 file changed, 24 insertions(+), 28 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/CommunityAdminGroupRestControllerIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/CommunityAdminGroupRestControllerIT.java index 37548553b143..074a7e6a3557 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/CommunityAdminGroupRestControllerIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/CommunityAdminGroupRestControllerIT.java @@ -34,8 +34,6 @@ import org.dspace.builder.GroupBuilder; import org.dspace.content.Collection; import org.dspace.content.Community; -import org.dspace.content.service.CollectionService; -import org.dspace.content.service.CommunityService; import org.dspace.core.Constants; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; @@ -49,19 +47,12 @@ public class CommunityAdminGroupRestControllerIT extends AbstractControllerIntegrationTest { - - @Autowired - private CommunityService communityService; - @Autowired private GroupService groupService; @Autowired private AuthorizeService authorizeService; - @Autowired - private CollectionService collectionService; - @Autowired private ConfigurationService configurationService; @@ -78,7 +69,7 @@ public void setup() { @Test public void getCommunityAdminGroupTest() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = communityService.createAdministrators(context, parentCommunity); + Group adminGroup = GroupBuilder.createCommunityAdminGroup(context, parentCommunity).build(); context.restoreAuthSystemState(); String token = getAuthToken(admin.getEmail(), password); @@ -91,7 +82,8 @@ public void getCommunityAdminGroupTest() throws Exception { @Test public void getCommunityAdminGroupTestCommunityAdmin() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = communityService.createAdministrators(context, parentCommunity); + Group adminGroup = GroupBuilder.createCommunityAdminGroup(context, parentCommunity).build(); + // TODO: this should actually be "add member", not directly setting a policy, right? authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson); context.restoreAuthSystemState(); @@ -106,7 +98,7 @@ public void getCommunityAdminGroupTestCommunityAdmin() throws Exception { @Test public void getCommunityAdminGroupUnAuthorizedTest() throws Exception { context.turnOffAuthorisationSystem(); - communityService.createAdministrators(context, parentCommunity); + GroupBuilder.createCommunityAdminGroup(context, parentCommunity).build(); context.restoreAuthSystemState(); getClient().perform(get("/api/core/communities/" + parentCommunity.getID() + "/adminGroup")) @@ -116,7 +108,7 @@ public void getCommunityAdminGroupUnAuthorizedTest() throws Exception { @Test public void getCommunityAdminGroupForbiddenTest() throws Exception { context.turnOffAuthorisationSystem(); - communityService.createAdministrators(context, parentCommunity); + GroupBuilder.createCommunityAdminGroup(context, parentCommunity).build(); context.restoreAuthSystemState(); String token = getAuthToken(eperson.getEmail(), password); getClient(token).perform(get("/api/core/communities/" + parentCommunity.getID() + "/adminGroup")) @@ -379,7 +371,7 @@ public void postCommunityAdminGroupCreateAdminGroupUnProcessablePermanent() thro @Test public void deleteCommunityAdminGroupTest() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = communityService.createAdministrators(context, parentCommunity); + GroupBuilder.createCommunityAdminGroup(context, parentCommunity).build(); context.restoreAuthSystemState(); String token = getAuthToken(admin.getEmail(), password); @@ -397,7 +389,7 @@ public void deleteCommunityAdminGroupTestCommunityAdmin() throws Exception { Community child1 = CommunityBuilder.createSubCommunity(context, parentCommunity) .withName("Sub Community") .build(); - Group adminGroup = communityService.createAdministrators(context, child1); + GroupBuilder.createCommunityAdminGroup(context, child1).build(); authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson); context.restoreAuthSystemState(); @@ -412,7 +404,7 @@ public void deleteCommunityAdminGroupTestCommunityAdmin() throws Exception { @Test public void deleteCommunityAdminGroupUnAuthorizedTest() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = communityService.createAdministrators(context, parentCommunity); + Group adminGroup = GroupBuilder.createCommunityAdminGroup(context, parentCommunity).build(); context.restoreAuthSystemState(); getClient().perform(delete("/api/core/communities/" + parentCommunity.getID() + "/adminGroup")) @@ -429,7 +421,7 @@ public void deleteCommunityAdminGroupUnAuthorizedTest() throws Exception { @Test public void deleteCommunityAdminGroupForbiddenTest() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = communityService.createAdministrators(context, parentCommunity); + Group adminGroup = GroupBuilder.createCommunityAdminGroup(context, parentCommunity).build(); context.restoreAuthSystemState(); String token = getAuthToken(eperson.getEmail(), password); @@ -449,7 +441,7 @@ public void deleteCommunityAdminGroupForbiddenTest() throws Exception { @Test public void deleteCommunityAdminGroupNotFoundTest() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = communityService.createAdministrators(context, parentCommunity); + GroupBuilder.createCommunityAdminGroup(context, parentCommunity).build(); context.restoreAuthSystemState(); String token = getAuthToken(eperson.getEmail(), password); @@ -462,7 +454,7 @@ public void deleteCommunityAdminGroupNotFoundTest() throws Exception { public void communityAdminAddMembersToCommunityAdminGroupPropertySetToFalse() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = communityService.createAdministrators(context, parentCommunity); + Group adminGroup = GroupBuilder.createCommunityAdminGroup(context, parentCommunity).build(); authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson); EPerson ePerson = EPersonBuilder.createEPerson(context).withEmail("testToAdd@test.com").build(); configurationService.setProperty("core.authorization.community-admin.admin-group", false); @@ -489,7 +481,7 @@ public void communityAdminAddMembersToCommunityAdminGroupPropertySetToFalse() th public void communityAdminRemoveMembersFromCommunityAdminGroupPropertySetToFalse() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = communityService.createAdministrators(context, parentCommunity); + Group adminGroup = GroupBuilder.createCommunityAdminGroup(context, parentCommunity).build(); authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson); EPerson ePerson = EPersonBuilder.createEPerson(context).withEmail("testToAdd@test.com").build(); context.restoreAuthSystemState(); @@ -526,7 +518,7 @@ public void communityAdminRemoveMembersFromCommunityAdminGroupPropertySetToFalse public void communityAdminAddChildGroupToCommunityAdminGroupPropertySetToFalse() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = communityService.createAdministrators(context, parentCommunity); + Group adminGroup = GroupBuilder.createCommunityAdminGroup(context, parentCommunity).build(); authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson); Group group = GroupBuilder.createGroup(context).withName("testGroup").build(); configurationService.setProperty("core.authorization.community-admin.admin-group", false); @@ -554,7 +546,7 @@ public void communityAdminAddChildGroupToCommunityAdminGroupPropertySetToFalse() public void communityAdminRemoveChildGroupFromCommunityAdminGroupPropertySetToFalse() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = communityService.createAdministrators(context, parentCommunity); + Group adminGroup = GroupBuilder.createCommunityAdminGroup(context, parentCommunity).build(); authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson); Group group = GroupBuilder.createGroup(context).withName("testGroup").build(); context.restoreAuthSystemState(); @@ -591,7 +583,9 @@ public void communityAdminRemoveChildGroupFromCommunityAdminGroupPropertySetToFa public void communityAdminAddChildGroupToCollectionAdminGroupSuccess() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = collectionService.createAdministrators(context, collection); + // TODO: Why is this test in CommunityAdmin? it seems to purely be a collection group test? + // copy paste gone wrong and we should actually be testing for community admin group sub? + Group adminGroup = GroupBuilder.createCollectionAdminGroup(context, collection).build(); authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson); Group group = GroupBuilder.createGroup(context).withName("testGroup").build(); context.restoreAuthSystemState(); @@ -617,7 +611,9 @@ public void communityAdminAddChildGroupToCollectionAdminGroupSuccess() throws Ex public void communityAdminRemoveChildGroupFromCollectionAdminGroupSuccess() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = collectionService.createAdministrators(context, collection); + // TODO: Why is this test in CommunityAdmin? it seems to purely be a collection group test? + // copy paste gone wrong and we should actually be testing for community admin group sub? + Group adminGroup = GroupBuilder.createCollectionAdminGroup(context, collection).build(); authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson); Group group = GroupBuilder.createGroup(context).withName("testGroup").build(); context.restoreAuthSystemState(); @@ -653,7 +649,7 @@ public void communityAdminRemoveChildGroupFromCollectionAdminGroupSuccess() thro public void communityAdminAddMembersToCollectionAdminGroupPropertySetToFalse() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = collectionService.createAdministrators(context, collection); + Group adminGroup = GroupBuilder.createCollectionAdminGroup(context, collection).build(); authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson); EPerson ePerson = EPersonBuilder.createEPerson(context).withEmail("testToAdd@test.com").build(); configurationService.setProperty("core.authorization.community-admin.collection.admin-group", false); @@ -681,7 +677,7 @@ public void communityAdminAddMembersToCollectionAdminGroupPropertySetToFalse() t public void communityAdminRemoveMembersFromCollectionAdminGroupPropertySetToFalse() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = collectionService.createAdministrators(context, collection); + Group adminGroup = GroupBuilder.createCollectionAdminGroup(context, collection).build(); authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson); EPerson ePerson = EPersonBuilder.createEPerson(context).withEmail("testToAdd@test.com").build(); context.restoreAuthSystemState(); @@ -719,7 +715,7 @@ public void communityAdminRemoveMembersFromCollectionAdminGroupPropertySetToFals public void communityAdminAddChildGroupToCollectionAdminGroupPropertySetToFalse() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = collectionService.createAdministrators(context, collection); + Group adminGroup = GroupBuilder.createCollectionAdminGroup(context, collection).build(); authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson); Group group = GroupBuilder.createGroup(context).withName("testGroup").build(); configurationService.setProperty("core.authorization.community-admin.collection.admin-group", false); @@ -748,7 +744,7 @@ public void communityAdminAddChildGroupToCollectionAdminGroupPropertySetToFalse( public void communityAdminRemoveChildGroupFromCollectionAdminGroupPropertySetToFalse() throws Exception { context.turnOffAuthorisationSystem(); - Group adminGroup = collectionService.createAdministrators(context, collection); + Group adminGroup = GroupBuilder.createCollectionAdminGroup(context, collection).build(); authorizeService.addPolicy(context, parentCommunity, Constants.ADMIN, eperson); Group group = GroupBuilder.createGroup(context).withName("testGroup").build(); context.restoreAuthSystemState(); From 76719f73f2e8e01aba9ad750fa6f1b5a2f34c4d3 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Fri, 6 Sep 2024 15:58:59 +0200 Subject: [PATCH 049/226] #9806: Update object cleanup in GroupRestRepositoryIT (cherry picked from commit 8cfb433c40ad01f348461a2c656665d1891de398) --- .../app/rest/GroupRestRepositoryIT.java | 952 +++++------------- 1 file changed, 239 insertions(+), 713 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/GroupRestRepositoryIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/GroupRestRepositoryIT.java index bdd13b97ff79..ff8aea493aef 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/GroupRestRepositoryIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/GroupRestRepositoryIT.java @@ -59,14 +59,11 @@ import org.dspace.content.Community; import org.dspace.content.Item; import org.dspace.content.MetadataSchemaEnum; -import org.dspace.content.factory.ContentServiceFactory; -import org.dspace.content.service.CommunityService; import org.dspace.core.Constants; import org.dspace.core.I18nUtil; import org.dspace.eperson.EPerson; import org.dspace.eperson.Group; import org.dspace.eperson.factory.EPersonServiceFactory; -import org.dspace.eperson.service.EPersonService; import org.dspace.eperson.service.GroupService; import org.dspace.services.ConfigurationService; import org.hamcrest.Matchers; @@ -757,263 +754,136 @@ public void addChildGroupTest() throws Exception { @Test public void addChildGroupCommunityAdminTest() throws Exception { - CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService(); GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); - Community community = null; - - Group parentGroup = null; - Group childGroup1 = null; - Group childGroup2 = null; - - try { - context.turnOffAuthorisationSystem(); - - community = CommunityBuilder.createCommunity(context).build(); - parentGroup = GroupBuilder.createCommunityAdminGroup(context, community) - .addMember(eperson) - .build(); - childGroup1 = GroupBuilder.createGroup(context).build(); - childGroup2 = GroupBuilder.createGroup(context).build(); - - groupService.update(context, parentGroup); - - context.commit(); - - parentGroup = context.reloadEntity(parentGroup); - childGroup1 = context.reloadEntity(childGroup1); - childGroup2 = context.reloadEntity(childGroup2); + context.turnOffAuthorisationSystem(); - context.restoreAuthSystemState(); - String authToken = getAuthToken(eperson.getEmail(), password); - getClient(authToken).perform( - post("/api/eperson/groups/" + parentGroup.getID() + "/subgroups") - .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) - .content(REST_SERVER_URL + "eperson/groups/" + childGroup1.getID() + "/\n" - + REST_SERVER_URL + "eperson/groups/" + childGroup2.getID() - ) - ).andExpect(status().isNoContent()); + Community community = CommunityBuilder.createCommunity(context).build(); + Group parentGroup = GroupBuilder.createCommunityAdminGroup(context, community) + .addMember(eperson) + .build(); + Group childGroup1 = GroupBuilder.createGroup(context).build(); + Group childGroup2 = GroupBuilder.createGroup(context).build(); - parentGroup = context.reloadEntity(parentGroup); - childGroup1 = context.reloadEntity(childGroup1); - childGroup2 = context.reloadEntity(childGroup2); + context.restoreAuthSystemState(); + String authToken = getAuthToken(eperson.getEmail(), password); + getClient(authToken).perform( + post("/api/eperson/groups/" + parentGroup.getID() + "/subgroups") + .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) + .content(REST_SERVER_URL + "eperson/groups/" + childGroup1.getID() + "/\n" + + REST_SERVER_URL + "eperson/groups/" + childGroup2.getID() + ) + ).andExpect(status().isNoContent()); - assertTrue( - groupService.isMember(parentGroup, childGroup1) - ); + parentGroup = context.reloadEntity(parentGroup); + childGroup1 = context.reloadEntity(childGroup1); + childGroup2 = context.reloadEntity(childGroup2); - assertTrue( - groupService.isMember(parentGroup, childGroup2) - ); + assertTrue( + groupService.isMember(parentGroup, childGroup1) + ); - } finally { - // TODO: Can we remove these lines now that we are creating them with the builder? - if (community != null) { - CommunityBuilder.deleteCommunity(community.getID()); - } - if (parentGroup != null) { - GroupBuilder.deleteGroup(parentGroup.getID()); - } - if (childGroup1 != null) { - GroupBuilder.deleteGroup(childGroup1.getID()); - } - if (childGroup2 != null) { - GroupBuilder.deleteGroup(childGroup2.getID()); - } - } + assertTrue( + groupService.isMember(parentGroup, childGroup2) + ); } @Test public void addChildGroupForbiddenTest() throws Exception { - GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); - - Group parentGroup = null; - Group childGroup1 = null; - Group childGroup2 = null; - - try { - context.turnOffAuthorisationSystem(); - - parentGroup = GroupBuilder.createGroup(context).build(); - childGroup1 = GroupBuilder.createGroup(context).build(); - childGroup2 = GroupBuilder.createGroup(context).build(); - - context.commit(); - - parentGroup = context.reloadEntity(parentGroup); - childGroup1 = context.reloadEntity(childGroup1); - childGroup2 = context.reloadEntity(childGroup2); + context.turnOffAuthorisationSystem(); - context.restoreAuthSystemState(); - String authToken = getAuthToken(eperson.getEmail(), password); - getClient(authToken).perform( - post("/api/eperson/groups/" + parentGroup.getID() + "/subgroups") - .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) - .content(REST_SERVER_URL + "eperson/groups/" + childGroup1.getID() + "/\n" - + REST_SERVER_URL + "eperson/groups/" + childGroup2.getID() - ) - ).andExpect(status().isForbidden()); + Group parentGroup = GroupBuilder.createGroup(context).build(); + Group childGroup1 = GroupBuilder.createGroup(context).build(); + Group childGroup2 = GroupBuilder.createGroup(context).build(); - } finally { - if (parentGroup != null) { - GroupBuilder.deleteGroup(parentGroup.getID()); - } - if (childGroup1 != null) { - GroupBuilder.deleteGroup(childGroup1.getID()); - } - if (childGroup2 != null) { - GroupBuilder.deleteGroup(childGroup2.getID()); - } - } + context.restoreAuthSystemState(); + String authToken = getAuthToken(eperson.getEmail(), password); + getClient(authToken).perform( + post("/api/eperson/groups/" + parentGroup.getID() + "/subgroups") + .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) + .content(REST_SERVER_URL + "eperson/groups/" + childGroup1.getID() + "/\n" + + REST_SERVER_URL + "eperson/groups/" + childGroup2.getID() + ) + ).andExpect(status().isForbidden()); } @Test public void addChildGroupUnauthorizedTest() throws Exception { - GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); - - Group parentGroup = null; - Group childGroup1 = null; - Group childGroup2 = null; - - try { - context.turnOffAuthorisationSystem(); - - parentGroup = GroupBuilder.createGroup(context).build(); - childGroup1 = GroupBuilder.createGroup(context).build(); - childGroup2 = GroupBuilder.createGroup(context).build(); + context.turnOffAuthorisationSystem(); - context.commit(); + Group parentGroup = GroupBuilder.createGroup(context).build(); + Group childGroup1 = GroupBuilder.createGroup(context).build(); + Group childGroup2 = GroupBuilder.createGroup(context).build(); - parentGroup = context.reloadEntity(parentGroup); - childGroup1 = context.reloadEntity(childGroup1); - childGroup2 = context.reloadEntity(childGroup2); + context.commit(); - context.restoreAuthSystemState(); - getClient().perform( - post("/api/eperson/groups/" + parentGroup.getID() + "/subgroups") - .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) - .content(REST_SERVER_URL + "eperson/groups/" + childGroup1.getID() + "/\n" - + REST_SERVER_URL + "eperson/groups/" + childGroup2.getID() - ) - ).andExpect(status().isUnauthorized()); + parentGroup = context.reloadEntity(parentGroup); + childGroup1 = context.reloadEntity(childGroup1); + childGroup2 = context.reloadEntity(childGroup2); - } finally { - if (parentGroup != null) { - GroupBuilder.deleteGroup(parentGroup.getID()); - } - if (childGroup1 != null) { - GroupBuilder.deleteGroup(childGroup1.getID()); - } - if (childGroup2 != null) { - GroupBuilder.deleteGroup(childGroup2.getID()); - } - } + context.restoreAuthSystemState(); + getClient().perform( + post("/api/eperson/groups/" + parentGroup.getID() + "/subgroups") + .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) + .content(REST_SERVER_URL + "eperson/groups/" + childGroup1.getID() + "/\n" + + REST_SERVER_URL + "eperson/groups/" + childGroup2.getID() + ) + ).andExpect(status().isUnauthorized()); } @Test public void addChildGroupNotFoundTest() throws Exception { - GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); - - Group parentGroup = null; - Group childGroup1 = null; - Group childGroup2 = null; - - try { - context.turnOffAuthorisationSystem(); - - parentGroup = GroupBuilder.createGroup(context).build(); - childGroup1 = GroupBuilder.createGroup(context).build(); - childGroup2 = GroupBuilder.createGroup(context).build(); - - context.commit(); - - parentGroup = context.reloadEntity(parentGroup); - childGroup1 = context.reloadEntity(childGroup1); - childGroup2 = context.reloadEntity(childGroup2); + context.turnOffAuthorisationSystem(); - context.restoreAuthSystemState(); - String authToken = getAuthToken(admin.getEmail(), password); - getClient(authToken).perform( - post("/api/eperson/groups/" + UUID.randomUUID() + "/subgroups") - .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) - .content(REST_SERVER_URL + "eperson/groups/" + childGroup1.getID() + "/\n" - + REST_SERVER_URL + "eperson/groups/" + childGroup2.getID() - ) - ).andExpect(status().isNotFound()); + Group parentGroup = GroupBuilder.createGroup(context).build(); + Group childGroup1 = GroupBuilder.createGroup(context).build(); + Group childGroup2 = GroupBuilder.createGroup(context).build(); - } finally { - if (parentGroup != null) { - GroupBuilder.deleteGroup(parentGroup.getID()); - } - if (childGroup1 != null) { - GroupBuilder.deleteGroup(childGroup1.getID()); - } - if (childGroup2 != null) { - GroupBuilder.deleteGroup(childGroup2.getID()); - } - } + context.restoreAuthSystemState(); + String authToken = getAuthToken(admin.getEmail(), password); + getClient(authToken).perform( + post("/api/eperson/groups/" + UUID.randomUUID() + "/subgroups") + .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) + .content(REST_SERVER_URL + "eperson/groups/" + childGroup1.getID() + "/\n" + + REST_SERVER_URL + "eperson/groups/" + childGroup2.getID() + ) + ).andExpect(status().isNotFound()); } @Test public void addChildGroupUnprocessableTest() throws Exception { - GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); - - Group parentGroup = null; - Group childGroup1 = null; - Group childGroup2 = null; - - try { - context.turnOffAuthorisationSystem(); - - parentGroup = GroupBuilder.createGroup(context).build(); - childGroup1 = GroupBuilder.createGroup(context) - .withParent(parentGroup) - .build(); - childGroup2 = GroupBuilder.createGroup(context).build(); - groupService.update(context, childGroup1); - -// context.commit(); -// -// parentGroup = context.reloadEntity(parentGroup); -// childGroup1 = context.reloadEntity(childGroup1); -// childGroup2 = context.reloadEntity(childGroup2); + context.turnOffAuthorisationSystem(); - context.restoreAuthSystemState(); - String authToken = getAuthToken(admin.getEmail(), password); + Group parentGroup = GroupBuilder.createGroup(context).build(); + Group childGroup1 = GroupBuilder.createGroup(context) + .withParent(parentGroup) + .build(); + Group childGroup2 = GroupBuilder.createGroup(context).build(); - getClient(authToken).perform( - post("/api/eperson/groups/" + parentGroup.getID() + "/subgroups") - .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) - .content(REST_SERVER_URL + "eperson/groups/123456789\n" - + REST_SERVER_URL + "eperson/groups/" + childGroup2.getID() - ) - ).andExpect(status().isUnprocessableEntity()); + context.restoreAuthSystemState(); + String authToken = getAuthToken(admin.getEmail(), password); - // TODO - confirm with reviewers that this is a mistake - it actually should be No Content - // (see AddMember test) but was incorrectly expecting 422? - getClient(authToken).perform( - post("/api/eperson/groups/" + parentGroup.getID() + "/subgroups") - .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) - .content(REST_SERVER_URL + "eperson/groups/" + childGroup1.getID() + "/\n" - + REST_SERVER_URL + "eperson/groups/" + childGroup2.getID() - ) - ).andExpect(status().isNoContent()); + getClient(authToken).perform( + post("/api/eperson/groups/" + parentGroup.getID() + "/subgroups") + .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) + .content(REST_SERVER_URL + "eperson/groups/123456789\n" + + REST_SERVER_URL + "eperson/groups/" + childGroup2.getID() + ) + ).andExpect(status().isUnprocessableEntity()); - } finally { - if (parentGroup != null) { - GroupBuilder.deleteGroup(parentGroup.getID()); - } - if (childGroup1 != null) { - GroupBuilder.deleteGroup(childGroup1.getID()); - } - if (childGroup2 != null) { - GroupBuilder.deleteGroup(childGroup2.getID()); - } - } + // TODO - confirm with reviewers that this is a mistake - it actually should be No Content + // (see AddMember test) but was incorrectly expecting 422? + getClient(authToken).perform( + post("/api/eperson/groups/" + parentGroup.getID() + "/subgroups") + .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) + .content(REST_SERVER_URL + "eperson/groups/" + childGroup1.getID() + "/\n" + + REST_SERVER_URL + "eperson/groups/" + childGroup2.getID() + ) + ).andExpect(status().isNoContent()); } @Test @@ -1081,251 +951,118 @@ public void addMemberTest() throws Exception { @Test public void addMemberCommunityAdminTest() throws Exception { - CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService(); GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); - EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService(); - - Community community = null; - Group parentGroup = null; - EPerson member1 = null; - EPerson member2 = null; - - try { - context.turnOffAuthorisationSystem(); - - community = CommunityBuilder.createCommunity(context).build(); - parentGroup = GroupBuilder.createCommunityAdminGroup(context, community) - .addMember(eperson) - .build(); - member1 = EPersonBuilder.createEPerson(context).build(); - member2 = EPersonBuilder.createEPerson(context).build(); - context.commit(); - - parentGroup = context.reloadEntity(parentGroup); - member1 = context.reloadEntity(member1); - member2 = context.reloadEntity(member2); + context.turnOffAuthorisationSystem(); - context.restoreAuthSystemState(); - String authToken = getAuthToken(eperson.getEmail(), password); - getClient(authToken).perform( - post("/api/eperson/groups/" + parentGroup.getID() + "/epersons") - .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) - .content(REST_SERVER_URL + "eperson/groups/" + member1.getID() + "/\n" - + REST_SERVER_URL + "eperson/groups/" + member2.getID() - ) - ).andExpect(status().isNoContent()); + Community community = CommunityBuilder.createCommunity(context).build(); + Group parentGroup = GroupBuilder.createCommunityAdminGroup(context, community) + .addMember(eperson) + .build(); + EPerson member1 = EPersonBuilder.createEPerson(context).build(); + EPerson member2 = EPersonBuilder.createEPerson(context).build(); - parentGroup = context.reloadEntity(parentGroup); - member1 = context.reloadEntity(member1); - member2 = context.reloadEntity(member2); + context.restoreAuthSystemState(); + String authToken = getAuthToken(eperson.getEmail(), password); + getClient(authToken).perform( + post("/api/eperson/groups/" + parentGroup.getID() + "/epersons") + .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) + .content(REST_SERVER_URL + "eperson/groups/" + member1.getID() + "/\n" + + REST_SERVER_URL + "eperson/groups/" + member2.getID() + ) + ).andExpect(status().isNoContent()); - assertTrue( - groupService.isMember(context, member1, parentGroup) - ); + parentGroup = context.reloadEntity(parentGroup); + member1 = context.reloadEntity(member1); + member2 = context.reloadEntity(member2); - assertTrue( - groupService.isMember(context, member2, parentGroup) - ); + assertTrue( + groupService.isMember(context, member1, parentGroup) + ); - } finally { - if (community != null) { - CommunityBuilder.deleteCommunity(community.getID()); - } - if (parentGroup != null) { - GroupBuilder.deleteGroup(parentGroup.getID()); - } - if (member1 != null) { - EPersonBuilder.deleteEPerson(member1.getID()); - } - if (member2 != null) { - EPersonBuilder.deleteEPerson(member2.getID()); - } - } + assertTrue( + groupService.isMember(context, member2, parentGroup) + ); } @Test public void addMemberForbiddenTest() throws Exception { - GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); - EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService(); - - Group parentGroup = null; - EPerson member1 = null; - EPerson member2 = null; - - try { - context.turnOffAuthorisationSystem(); - - parentGroup = GroupBuilder.createGroup(context).build(); - member1 = EPersonBuilder.createEPerson(context).build(); - member2 = EPersonBuilder.createEPerson(context).build(); - - context.commit(); - - parentGroup = context.reloadEntity(parentGroup); - member1 = context.reloadEntity(member1); - member2 = context.reloadEntity(member2); + context.turnOffAuthorisationSystem(); - context.restoreAuthSystemState(); - String authToken = getAuthToken(eperson.getEmail(), password); - getClient(authToken).perform( - post("/api/eperson/groups/" + parentGroup.getID() + "/epersons") - .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) - .content(REST_SERVER_URL + "eperson/groups/" + member1.getID() + "/\n" - + REST_SERVER_URL + "eperson/groups/" + member2.getID() - ) - ).andExpect(status().isForbidden()); + Group parentGroup = GroupBuilder.createGroup(context).build(); + EPerson member1 = EPersonBuilder.createEPerson(context).build(); + EPerson member2 = EPersonBuilder.createEPerson(context).build(); - } finally { - if (parentGroup != null) { - GroupBuilder.deleteGroup(parentGroup.getID()); - } - if (member1 != null) { - EPersonBuilder.deleteEPerson(member1.getID()); - } - if (member2 != null) { - EPersonBuilder.deleteEPerson(member2.getID()); - } - } + context.restoreAuthSystemState(); + String authToken = getAuthToken(eperson.getEmail(), password); + getClient(authToken).perform( + post("/api/eperson/groups/" + parentGroup.getID() + "/epersons") + .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) + .content(REST_SERVER_URL + "eperson/groups/" + member1.getID() + "/\n" + + REST_SERVER_URL + "eperson/groups/" + member2.getID() + ) + ).andExpect(status().isForbidden()); } @Test public void addMemberUnauthorizedTest() throws Exception { - GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); - EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService(); - - Group parentGroup = null; - EPerson member1 = null; - EPerson member2 = null; - - try { - context.turnOffAuthorisationSystem(); - - parentGroup = GroupBuilder.createGroup(context).build(); - member1 = EPersonBuilder.createEPerson(context).build(); - member2 = EPersonBuilder.createEPerson(context).build(); - - context.commit(); - - parentGroup = context.reloadEntity(parentGroup); - member1 = context.reloadEntity(member1); - member2 = context.reloadEntity(member2); + context.turnOffAuthorisationSystem(); - context.restoreAuthSystemState(); - getClient().perform( - post("/api/eperson/groups/" + parentGroup.getID() + "/epersons") - .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) - .content(REST_SERVER_URL + "eperson/groups/" + member1.getID() + "/\n" - + REST_SERVER_URL + "eperson/groups/" + member2.getID() - ) - ).andExpect(status().isUnauthorized()); + Group parentGroup = GroupBuilder.createGroup(context).build(); + EPerson member1 = EPersonBuilder.createEPerson(context).build(); + EPerson member2 = EPersonBuilder.createEPerson(context).build(); - } finally { - if (parentGroup != null) { - GroupBuilder.deleteGroup(parentGroup.getID()); - } - if (member1 != null) { - EPersonBuilder.deleteEPerson(member1.getID()); - } - if (member2 != null) { - EPersonBuilder.deleteEPerson(member2.getID()); - } - } + context.restoreAuthSystemState(); + getClient().perform( + post("/api/eperson/groups/" + parentGroup.getID() + "/epersons") + .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) + .content(REST_SERVER_URL + "eperson/groups/" + member1.getID() + "/\n" + + REST_SERVER_URL + "eperson/groups/" + member2.getID() + ) + ).andExpect(status().isUnauthorized()); } @Test public void addMemberNotFoundTest() throws Exception { - GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); - EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService(); - - Group parentGroup = null; - EPerson member1 = null; - EPerson member2 = null; - - try { - context.turnOffAuthorisationSystem(); - - parentGroup = GroupBuilder.createGroup(context).build(); - member1 = EPersonBuilder.createEPerson(context).build(); - member2 = EPersonBuilder.createEPerson(context).build(); - - context.commit(); - - parentGroup = context.reloadEntity(parentGroup); - member1 = context.reloadEntity(member1); - member2 = context.reloadEntity(member2); + context.turnOffAuthorisationSystem(); - context.restoreAuthSystemState(); - String authToken = getAuthToken(admin.getEmail(), password); - getClient(authToken).perform( - post("/api/eperson/groups/" + UUID.randomUUID() + "/epersons") - .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) - .content(REST_SERVER_URL + "eperson/groups/" + member1.getID() + "/\n" - + REST_SERVER_URL + "eperson/groups/" + member2.getID() - ) - ).andExpect(status().isNotFound()); + Group parentGroup = GroupBuilder.createGroup(context).build(); + EPerson member1 = EPersonBuilder.createEPerson(context).build(); + EPerson member2 = EPersonBuilder.createEPerson(context).build(); - } finally { - if (parentGroup != null) { - GroupBuilder.deleteGroup(parentGroup.getID()); - } - if (member1 != null) { - EPersonBuilder.deleteEPerson(member1.getID()); - } - if (member2 != null) { - EPersonBuilder.deleteEPerson(member2.getID()); - } - } + context.restoreAuthSystemState(); + String authToken = getAuthToken(admin.getEmail(), password); + getClient(authToken).perform( + post("/api/eperson/groups/" + UUID.randomUUID() + "/epersons") + .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) + .content(REST_SERVER_URL + "eperson/groups/" + member1.getID() + "/\n" + + REST_SERVER_URL + "eperson/groups/" + member2.getID() + ) + ).andExpect(status().isNotFound()); } @Test public void addMemberUnprocessableTest() throws Exception { - GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); - EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService(); - - Group parentGroup = null; - EPerson member1 = null; - EPerson member2 = null; - - try { - context.turnOffAuthorisationSystem(); - - parentGroup = GroupBuilder.createGroup(context).build(); - member1 = EPersonBuilder.createEPerson(context).build(); - member2 = EPersonBuilder.createEPerson(context).build(); - - context.commit(); - - parentGroup = context.reloadEntity(parentGroup); - member1 = context.reloadEntity(member1); - member2 = context.reloadEntity(member2); + context.turnOffAuthorisationSystem(); - context.restoreAuthSystemState(); - String authToken = getAuthToken(admin.getEmail(), password); + Group parentGroup = GroupBuilder.createGroup(context).build(); + EPerson member1 = EPersonBuilder.createEPerson(context).build(); + EPerson member2 = EPersonBuilder.createEPerson(context).build(); - getClient(authToken).perform( - post("/api/eperson/groups/" + parentGroup.getID() + "/epersons") - .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) - .content(REST_SERVER_URL + "eperson/groups/123456789\n" - + REST_SERVER_URL + "eperson/groups/" + member2.getID() - ) - ).andExpect(status().isUnprocessableEntity()); + context.restoreAuthSystemState(); + String authToken = getAuthToken(admin.getEmail(), password); - } finally { - if (parentGroup != null) { - GroupBuilder.deleteGroup(parentGroup.getID()); - } - if (member1 != null) { - EPersonBuilder.deleteEPerson(member1.getID()); - } - if (member2 != null) { - EPersonBuilder.deleteEPerson(member2.getID()); - } - } + getClient(authToken).perform( + post("/api/eperson/groups/" + parentGroup.getID() + "/epersons") + .contentType(parseMediaType(TEXT_URI_LIST_VALUE)) + .content(REST_SERVER_URL + "eperson/groups/123456789\n" + + REST_SERVER_URL + "eperson/groups/" + member2.getID() + ) + ).andExpect(status().isUnprocessableEntity()); } @Test @@ -1378,29 +1115,18 @@ public void removeChildGroupTest() throws Exception { @Test public void removeChildGroupCommunityAdminTest() throws Exception { - CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService(); GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); - Community community = null; - Group parentGroup = null; - Group childGroup = null; - - try { context.turnOffAuthorisationSystem(); - community = CommunityBuilder.createCommunity(context).build(); - parentGroup = GroupBuilder.createCommunityAdminGroup(context, community) + Community community = CommunityBuilder.createCommunity(context).build(); + Group parentGroup = GroupBuilder.createCommunityAdminGroup(context, community) .addMember(eperson) .build(); - childGroup = GroupBuilder.createGroup(context) + Group childGroup = GroupBuilder.createGroup(context) .withParent(parentGroup) .build(); - context.commit(); - - parentGroup = context.reloadEntity(parentGroup); - childGroup = context.reloadEntity(childGroup); - context.restoreAuthSystemState(); String authToken = getAuthToken(eperson.getEmail(), password); getClient(authToken).perform( @@ -1413,163 +1139,71 @@ public void removeChildGroupCommunityAdminTest() throws Exception { assertFalse( groupService.isMember(parentGroup, childGroup) ); - - } finally { - if (community != null) { - CommunityBuilder.deleteCommunity(community.getID()); - } - if (parentGroup != null) { - GroupBuilder.deleteGroup(parentGroup.getID()); - } - if (childGroup != null) { - GroupBuilder.deleteGroup(childGroup.getID()); - } - } } @Test public void removeChildGroupForbiddenTest() throws Exception { - GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); - - Group parentGroup = null; - Group childGroup = null; - - try { - context.turnOffAuthorisationSystem(); - - parentGroup = GroupBuilder.createGroup(context).build(); - childGroup = GroupBuilder.createGroup(context).build(); - - context.commit(); - - parentGroup = context.reloadEntity(parentGroup); - childGroup = context.reloadEntity(childGroup); + context.turnOffAuthorisationSystem(); - context.restoreAuthSystemState(); - String authToken = getAuthToken(eperson.getEmail(), password); - getClient(authToken).perform( - delete("/api/eperson/groups/" + parentGroup.getID() + "/subgroups/" + childGroup.getID()) - ).andExpect(status().isForbidden()); + Group parentGroup = GroupBuilder.createGroup(context).build(); + Group childGroup = GroupBuilder.createGroup(context).build(); - } finally { - if (parentGroup != null) { - GroupBuilder.deleteGroup(parentGroup.getID()); - } - if (childGroup != null) { - GroupBuilder.deleteGroup(childGroup.getID()); - } - } + context.restoreAuthSystemState(); + String authToken = getAuthToken(eperson.getEmail(), password); + getClient(authToken).perform( + delete("/api/eperson/groups/" + parentGroup.getID() + "/subgroups/" + childGroup.getID()) + ).andExpect(status().isForbidden()); } @Test public void removeChildGroupUnauthorizedTest() throws Exception { - GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); - - Group parentGroup = null; - Group childGroup = null; - - try { - context.turnOffAuthorisationSystem(); - - parentGroup = GroupBuilder.createGroup(context).build(); - childGroup = GroupBuilder.createGroup(context).build(); - - context.commit(); - - parentGroup = context.reloadEntity(parentGroup); - childGroup = context.reloadEntity(childGroup); + context.turnOffAuthorisationSystem(); - context.restoreAuthSystemState(); - getClient().perform( - delete("/api/eperson/groups/" + parentGroup.getID() + "/subgroups/" + childGroup.getID()) - ).andExpect(status().isUnauthorized()); + Group parentGroup = GroupBuilder.createGroup(context).build(); + Group childGroup = GroupBuilder.createGroup(context).build(); - } finally { - if (parentGroup != null) { - GroupBuilder.deleteGroup(parentGroup.getID()); - } - if (childGroup != null) { - GroupBuilder.deleteGroup(childGroup.getID()); - } - } + context.restoreAuthSystemState(); + getClient().perform( + delete("/api/eperson/groups/" + parentGroup.getID() + "/subgroups/" + childGroup.getID()) + ).andExpect(status().isUnauthorized()); } @Test public void removeChildGroupNotFoundTest() throws Exception { - GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); - - Group parentGroup = null; - Group childGroup = null; - - try { - context.turnOffAuthorisationSystem(); - - parentGroup = GroupBuilder.createGroup(context).build(); - childGroup = GroupBuilder.createGroup(context) - .withParent(parentGroup) - .build(); - - context.commit(); - - parentGroup = context.reloadEntity(parentGroup); - childGroup = context.reloadEntity(childGroup); + context.turnOffAuthorisationSystem(); - context.restoreAuthSystemState(); - String authToken = getAuthToken(admin.getEmail(), password); + Group parentGroup = GroupBuilder.createGroup(context).build(); + Group childGroup = GroupBuilder.createGroup(context) + .withParent(parentGroup) + .build(); - getClient(authToken).perform( - delete("/api/eperson/groups/" + UUID.randomUUID() + "/subgroups/" + childGroup.getID()) - ).andExpect(status().isNotFound()); + context.restoreAuthSystemState(); + String authToken = getAuthToken(admin.getEmail(), password); - } finally { - if (parentGroup != null) { - GroupBuilder.deleteGroup(parentGroup.getID()); - } - if (childGroup != null) { - GroupBuilder.deleteGroup(childGroup.getID()); - } - } + getClient(authToken).perform( + delete("/api/eperson/groups/" + UUID.randomUUID() + "/subgroups/" + childGroup.getID()) + ).andExpect(status().isNotFound()); } @Test public void removeChildGroupUnprocessableTest() throws Exception { - GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); - - Group parentGroup = null; - Group childGroup = null; - - try { - context.turnOffAuthorisationSystem(); - - parentGroup = GroupBuilder.createGroup(context).build(); - childGroup = GroupBuilder.createGroup(context) - .withParent(parentGroup) - .build(); - - context.commit(); - - parentGroup = context.reloadEntity(parentGroup); - childGroup = context.reloadEntity(childGroup); + context.turnOffAuthorisationSystem(); - context.restoreAuthSystemState(); - String authToken = getAuthToken(admin.getEmail(), password); + Group parentGroup = GroupBuilder.createGroup(context).build(); + Group childGroup = GroupBuilder.createGroup(context) + .withParent(parentGroup) + .build(); - getClient(authToken).perform( - delete("/api/eperson/groups/" + parentGroup.getID() + "/subgroups/" + UUID.randomUUID()) - ).andExpect(status().isUnprocessableEntity()); + context.restoreAuthSystemState(); + String authToken = getAuthToken(admin.getEmail(), password); - } finally { - if (parentGroup != null) { - GroupBuilder.deleteGroup(parentGroup.getID()); - } - if (childGroup != null) { - GroupBuilder.deleteGroup(childGroup.getID()); - } - } + getClient(authToken).perform( + delete("/api/eperson/groups/" + parentGroup.getID() + "/subgroups/" + UUID.randomUUID()) + ).andExpect(status().isUnprocessableEntity()); } @Test @@ -1613,31 +1247,19 @@ public void removeMemberTest() throws Exception { @Test public void removeMemberCommunityAdminTest() throws Exception { - CommunityService communityService = ContentServiceFactory.getInstance().getCommunityService(); GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); - EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService(); - - Community community = null; - Group parentGroup = null; - EPerson member = null; - try { context.turnOffAuthorisationSystem(); - community = CommunityBuilder.createCommunity(context).build(); - member = EPersonBuilder.createEPerson(context).build(); - parentGroup = GroupBuilder.createCommunityAdminGroup(context, community) + Community community = CommunityBuilder.createCommunity(context).build(); + EPerson member = EPersonBuilder.createEPerson(context).build(); + Group parentGroup = GroupBuilder.createCommunityAdminGroup(context, community) .addMember(member) .addMember(eperson) .build(); assertTrue(groupService.isMember(context, member, parentGroup)); - context.commit(); - - parentGroup = context.reloadEntity(parentGroup); - member = context.reloadEntity(member); - context.restoreAuthSystemState(); String authToken = getAuthToken(eperson.getEmail(), password); getClient(authToken).perform( @@ -1650,171 +1272,75 @@ public void removeMemberCommunityAdminTest() throws Exception { assertFalse( groupService.isMember(context, member, parentGroup) ); - - } finally { - if (community != null) { - CommunityBuilder.deleteCommunity(community.getID()); - } - if (parentGroup != null) { - GroupBuilder.deleteGroup(parentGroup.getID()); - } - if (member != null) { - EPersonBuilder.deleteEPerson(member.getID()); - } - } } @Test public void removeMemberForbiddenTest() throws Exception { - GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); - EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService(); - - Group parentGroup = null; - EPerson member = null; - - try { - context.turnOffAuthorisationSystem(); - - member = EPersonBuilder.createEPerson(context).build(); - parentGroup = GroupBuilder.createGroup(context) - .addMember(member) - .build(); - - context.commit(); - - parentGroup = context.reloadEntity(parentGroup); - member = context.reloadEntity(member); + context.turnOffAuthorisationSystem(); - context.restoreAuthSystemState(); - String authToken = getAuthToken(eperson.getEmail(), password); - getClient(authToken).perform( - delete("/api/eperson/groups/" + parentGroup.getID() + "/epersons/" + member.getID()) - ).andExpect(status().isForbidden()); + EPerson member = EPersonBuilder.createEPerson(context).build(); + Group parentGroup = GroupBuilder.createGroup(context) + .addMember(member) + .build(); - } finally { - if (parentGroup != null) { - GroupBuilder.deleteGroup(parentGroup.getID()); - } - if (member != null) { - EPersonBuilder.deleteEPerson(member.getID()); - } - } + context.restoreAuthSystemState(); + String authToken = getAuthToken(eperson.getEmail(), password); + getClient(authToken).perform( + delete("/api/eperson/groups/" + parentGroup.getID() + "/epersons/" + member.getID()) + ).andExpect(status().isForbidden()); } @Test public void removeMemberUnauthorizedTest() throws Exception { - GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); - EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService(); - - Group parentGroup = null; - EPerson member = null; - - try { - context.turnOffAuthorisationSystem(); - - member = EPersonBuilder.createEPerson(context).build(); - parentGroup = GroupBuilder.createGroup(context) - .addMember(member) - .build(); - - context.commit(); - - parentGroup = context.reloadEntity(parentGroup); - member = context.reloadEntity(member); + context.turnOffAuthorisationSystem(); - context.restoreAuthSystemState(); - getClient().perform( - delete("/api/eperson/groups/" + parentGroup.getID() + "/epersons/" + member.getID()) - ).andExpect(status().isUnauthorized()); + EPerson member = EPersonBuilder.createEPerson(context).build(); + Group parentGroup = GroupBuilder.createGroup(context) + .addMember(member) + .build(); - } finally { - if (parentGroup != null) { - GroupBuilder.deleteGroup(parentGroup.getID()); - } - if (member != null) { - EPersonBuilder.deleteEPerson(member.getID()); - } - } + context.restoreAuthSystemState(); + getClient().perform( + delete("/api/eperson/groups/" + parentGroup.getID() + "/epersons/" + member.getID()) + ).andExpect(status().isUnauthorized()); } @Test public void removeMemberNotFoundTest() throws Exception { - GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); - EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService(); - - Group parentGroup = null; - EPerson member = null; - - try { - context.turnOffAuthorisationSystem(); - - member = EPersonBuilder.createEPerson(context).build(); - parentGroup = GroupBuilder.createGroup(context) - .addMember(member) - .build(); - - context.commit(); - - parentGroup = context.reloadEntity(parentGroup); - member = context.reloadEntity(member); + context.turnOffAuthorisationSystem(); - context.restoreAuthSystemState(); - String authToken = getAuthToken(admin.getEmail(), password); + EPerson member = EPersonBuilder.createEPerson(context).build(); + Group parentGroup = GroupBuilder.createGroup(context) + .addMember(member) + .build(); - getClient(authToken).perform( - delete("/api/eperson/groups/" + UUID.randomUUID() + "/epersons/" + member.getID()) - ).andExpect(status().isNotFound()); + context.restoreAuthSystemState(); + String authToken = getAuthToken(admin.getEmail(), password); - } finally { - if (parentGroup != null) { - GroupBuilder.deleteGroup(parentGroup.getID()); - } - if (member != null) { - EPersonBuilder.deleteEPerson(member.getID()); - } - } + getClient(authToken).perform( + delete("/api/eperson/groups/" + UUID.randomUUID() + "/epersons/" + member.getID()) + ).andExpect(status().isNotFound()); } @Test public void removeMemberUnprocessableTest() throws Exception { - GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); - EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService(); - - Group parentGroup = null; - EPerson member = null; - - try { context.turnOffAuthorisationSystem(); - member = EPersonBuilder.createEPerson(context).build(); - parentGroup = GroupBuilder.createGroup(context) + EPerson member = EPersonBuilder.createEPerson(context).build(); + Group parentGroup = GroupBuilder.createGroup(context) .addMember(member) .build(); - context.commit(); - - parentGroup = context.reloadEntity(parentGroup); - member = context.reloadEntity(member); - context.restoreAuthSystemState(); String authToken = getAuthToken(admin.getEmail(), password); getClient(authToken).perform( delete("/api/eperson/groups/" + parentGroup.getID() + "/epersons/" + UUID.randomUUID()) ).andExpect(status().isUnprocessableEntity()); - - } finally { - if (parentGroup != null) { - GroupBuilder.deleteGroup(parentGroup.getID()); - } - if (member != null) { - EPersonBuilder.deleteEPerson(member.getID()); - } - } } @Test From 7d7edcb4c6ab8de23b9d3d8a868fd706294b9523 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Fri, 6 Sep 2024 16:43:36 +0200 Subject: [PATCH 050/226] #9806: Align provider reg in CreateMissingIdentifiersIT with other tests VersionedHandlerIdentifierProviderIT uses this registerProvider method which looks more reliable and doesn't do a refresh/reload of applicationContext after (which I suspected might have an odd interaction with VersioningWithRelationshipsIT and its createBean() calls?) (cherry picked from commit 90536e443b7fedef0481a34326cafc58fb334396) --- .../general/CreateMissingIdentifiersIT.java | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/ctask/general/CreateMissingIdentifiersIT.java b/dspace-api/src/test/java/org/dspace/ctask/general/CreateMissingIdentifiersIT.java index 2a07799deee5..8038a7153325 100644 --- a/dspace-api/src/test/java/org/dspace/ctask/general/CreateMissingIdentifiersIT.java +++ b/dspace-api/src/test/java/org/dspace/ctask/general/CreateMissingIdentifiersIT.java @@ -10,6 +10,8 @@ import static org.junit.Assert.assertEquals; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import org.dspace.AbstractIntegrationTestWithDatabase; import org.dspace.builder.CollectionBuilder; @@ -19,7 +21,10 @@ import org.dspace.content.Item; import org.dspace.core.factory.CoreServiceFactory; import org.dspace.curate.Curator; +import org.dspace.identifier.IdentifierProvider; +import org.dspace.identifier.IdentifierServiceImpl; import org.dspace.identifier.VersionedHandleIdentifierProviderWithCanonicalHandles; +import org.dspace.kernel.ServiceManager; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; import org.junit.After; @@ -32,10 +37,23 @@ */ public class CreateMissingIdentifiersIT extends AbstractIntegrationTestWithDatabase { + private ServiceManager serviceManager; + private IdentifierServiceImpl identifierService; private static final String P_TASK_DEF = "plugin.named.org.dspace.curate.CurationTask"; private static final String TASK_NAME = "test"; + @Override + public void setUp() throws Exception { + super.setUp(); + context.turnOffAuthorisationSystem(); + + serviceManager = DSpaceServicesFactory.getInstance().getServiceManager(); + identifierService = serviceManager.getServicesByType(IdentifierServiceImpl.class).get(0); + // Clean out providers to avoid any being used for creation of community and collection + identifierService.setProviders(new ArrayList<>()); + } + @Test public void testPerform() throws IOException { @@ -67,11 +85,7 @@ public void testPerform() /* * Now install an incompatible provider to make the task fail. */ - DSpaceServicesFactory.getInstance() - .getServiceManager() - .registerServiceClass( - VersionedHandleIdentifierProviderWithCanonicalHandles.class.getCanonicalName(), - VersionedHandleIdentifierProviderWithCanonicalHandles.class); + registerProvider(VersionedHandleIdentifierProviderWithCanonicalHandles.class); curator.curate(context, item); System.out.format("With incompatible provider, result is '%s'.\n", @@ -86,4 +100,14 @@ public void destroy() throws Exception { super.destroy(); DSpaceServicesFactory.getInstance().getServiceManager().getApplicationContext().refresh(); } + + private void registerProvider(Class type) { + // Register our new provider + serviceManager.registerServiceClass(type.getName(), type); + IdentifierProvider identifierProvider = + (IdentifierProvider) serviceManager.getServiceByName(type.getName(), type); + + // Overwrite the identifier-service's providers with the new one to ensure only this provider is used + identifierService.setProviders(List.of(identifierProvider)); + } } From 59ecfb8360b761980dfc14d3ca7ab0b9bd6bfc7d Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Fri, 6 Sep 2024 16:45:05 +0200 Subject: [PATCH 051/226] #9806: Use builders for creation in VersioningWithRelationshipsIT I am a bit uncertain about the createBean() calls here, why do we not simply *get* the configured beans using the service manager instead, but will look at that in a separate change (cherry picked from commit 3521ab6d3598e716cc9fe8e938e883b302006580) --- .../VersioningWithRelationshipsIT.java | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/content/VersioningWithRelationshipsIT.java b/dspace-api/src/test/java/org/dspace/content/VersioningWithRelationshipsIT.java index 44653300e0de..accc52d0d830 100644 --- a/dspace-api/src/test/java/org/dspace/content/VersioningWithRelationshipsIT.java +++ b/dspace-api/src/test/java/org/dspace/content/VersioningWithRelationshipsIT.java @@ -49,6 +49,7 @@ import org.dspace.builder.ItemBuilder; import org.dspace.builder.RelationshipBuilder; import org.dspace.builder.RelationshipTypeBuilder; +import org.dspace.builder.VersionBuilder; import org.dspace.content.factory.ContentServiceFactory; import org.dspace.content.service.InstallItemService; import org.dspace.content.service.ItemService; @@ -62,8 +63,6 @@ import org.dspace.kernel.ServiceManager; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.versioning.Version; -import org.dspace.versioning.factory.VersionServiceFactory; -import org.dspace.versioning.service.VersioningService; import org.hamcrest.Matcher; import org.junit.Assert; import org.junit.Before; @@ -74,8 +73,6 @@ public class VersioningWithRelationshipsIT extends AbstractIntegrationTestWithDa private final RelationshipService relationshipService = ContentServiceFactory.getInstance().getRelationshipService(); - private final VersioningService versioningService = - VersionServiceFactory.getInstance().getVersionService(); private final WorkspaceItemService workspaceItemService = ContentServiceFactory.getInstance().getWorkspaceItemService(); private final InstallItemService installItemService = @@ -291,7 +288,7 @@ public void test_createNewVersionOfItemOnLeftSideOfRelationships() throws Except // create a new version of the publication // ///////////////////////////////////////////// - Version newVersion = versioningService.createNewVersion(context, originalPublication); + Version newVersion = VersionBuilder.createVersion(context, originalPublication, "test").build(); Item newPublication = newVersion.getItem(); assertNotSame(originalPublication, newPublication); @@ -567,7 +564,7 @@ public void test_createNewVersionOfItemAndModifyRelationships() throws Exception // create a new version of the publication // ///////////////////////////////////////////// - Version newVersion = versioningService.createNewVersion(context, originalPublication); + Version newVersion = VersionBuilder.createVersion(context, originalPublication, "test").build(); Item newPublication = newVersion.getItem(); assertNotSame(originalPublication, newPublication); @@ -927,7 +924,7 @@ public void test_createNewVersionOfItemOnRightSideOfRelationships() throws Excep // create a new version of the person // //////////////////////////////////////// - Version newVersion = versioningService.createNewVersion(context, originalPerson); + Version newVersion = VersionBuilder.createVersion(context, originalPerson, "test").build(); Item newPerson = newVersion.getItem(); assertNotSame(originalPerson, newPerson); @@ -1300,7 +1297,7 @@ public void test_createNewVersionOfItemAndVerifyMetadataOrder() throws Exception // create new version of publication // /////////////////////////////////////// - Version newVersion = versioningService.createNewVersion(context, originalPublication); + Version newVersion = VersionBuilder.createVersion(context, originalPublication, "test").build(); Item newPublication = newVersion.getItem(); assertNotSame(originalPublication, newPublication); @@ -1463,7 +1460,7 @@ public void test_createNewVersionOfItemWithAddRemoveMove() throws Exception { // create a new version of the publication // ///////////////////////////////////////////// - Version newVersion = versioningService.createNewVersion(context, originalPublication); + Version newVersion = VersionBuilder.createVersion(context, originalPublication, "test").build(); Item newPublication = newVersion.getItem(); assertNotSame(originalPublication, newPublication); @@ -1782,7 +1779,7 @@ public void test_placeRecalculationAfterDelete() throws Exception { // create new version - volume 1.2 // ///////////////////////////////////// - Item v1_2 = versioningService.createNewVersion(context, v1_1).getItem(); + Item v1_2 = VersionBuilder.createVersion(context, v1_1, "test").build().getItem(); installItemService.installItem(context, workspaceItemService.findByItem(context, v1_2)); context.commit(); @@ -1790,7 +1787,7 @@ public void test_placeRecalculationAfterDelete() throws Exception { // create new version - issue 3.2 // //////////////////////////////////// - Item i3_2 = versioningService.createNewVersion(context, i3_1).getItem(); + Item i3_2 = VersionBuilder.createVersion(context, i3_1, "test").build().getItem(); installItemService.installItem(context, workspaceItemService.findByItem(context, i3_2)); context.commit(); @@ -2316,7 +2313,7 @@ public void test_placeRecalculationAfterDelete_complex() throws Exception { // create new version - person 3.2 // ///////////////////////////////////// - Item pe3_2 = versioningService.createNewVersion(context, pe3_1).getItem(); + Item pe3_2 = VersionBuilder.createVersion(context, pe3_1, "test").build().getItem(); installItemService.installItem(context, workspaceItemService.findByItem(context, pe3_2)); context.commit(); @@ -2324,7 +2321,7 @@ public void test_placeRecalculationAfterDelete_complex() throws Exception { // create new version - project 3.2 // ////////////////////////////////////// - Item pr3_2 = versioningService.createNewVersion(context, pr3_1).getItem(); + Item pr3_2 = VersionBuilder.createVersion(context, pr3_1, "test").build().getItem(); installItemService.installItem(context, workspaceItemService.findByItem(context, pr3_2)); context.commit(); @@ -3056,7 +3053,7 @@ public void test_placeRecalculationNoUseForPlace() throws Exception { // create new version - volume 1.2 // ///////////////////////////////////// - Item v1_2 = versioningService.createNewVersion(context, v1_1).getItem(); + Item v1_2 = VersionBuilder.createVersion(context, v1_1, "test").build().getItem(); installItemService.installItem(context, workspaceItemService.findByItem(context, v1_2)); context.commit(); @@ -3064,7 +3061,7 @@ public void test_placeRecalculationNoUseForPlace() throws Exception { // create new version - issue 3.2 // //////////////////////////////////// - Item i3_2 = versioningService.createNewVersion(context, i3_1).getItem(); + Item i3_2 = VersionBuilder.createVersion(context, i3_1, "test").build().getItem(); installItemService.installItem(context, workspaceItemService.findByItem(context, i3_2)); context.commit(); @@ -3509,7 +3506,7 @@ public void test_virtualMetadataPreserved() throws Exception { // create a new version of publication 1 and archive // /////////////////////////////////////////////////////// - Item publication1V2 = versioningService.createNewVersion(context, publication1V1).getItem(); + Item publication1V2 = VersionBuilder.createVersion(context, publication1V1, "test").build().getItem(); installItemService.installItem(context, workspaceItemService.findByItem(context, publication1V2)); context.dispatchEvents(); @@ -3517,7 +3514,7 @@ public void test_virtualMetadataPreserved() throws Exception { // create new version of person 1 // //////////////////////////////////// - Item person1V2 = versioningService.createNewVersion(context, person1V1).getItem(); + Item person1V2 = VersionBuilder.createVersion(context, person1V1, "test").build().getItem(); // update "Smith, Donald" to "Smith, D." itemService.replaceMetadata( context, person1V2, "person", "givenName", null, null, "D.", @@ -3853,7 +3850,7 @@ public void test_virtualMetadataPreserved() throws Exception { // create new version of person 2 // //////////////////////////////////// - Item person2V2 = versioningService.createNewVersion(context, person2V1).getItem(); + Item person2V2 = VersionBuilder.createVersion(context, person2V1, "test").build().getItem(); Relationship rel1 = getRelationship(publication1V2, isAuthorOfPublication, person2V2); assertNotNull(rel1); rel1.setRightwardValue("Doe, Jane Jr"); From 8f8680179695c4dad637ac798eff0bc6fb47b1c8 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Fri, 6 Sep 2024 17:15:15 +0200 Subject: [PATCH 052/226] #9806: Set explicit id provider before VersioningWithRelationshipsIT (cherry picked from commit 4af690065038d9cb401d0fa1fc5fbfe0fa1fe2c7) --- .../VersioningWithRelationshipsIT.java | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/dspace-api/src/test/java/org/dspace/content/VersioningWithRelationshipsIT.java b/dspace-api/src/test/java/org/dspace/content/VersioningWithRelationshipsIT.java index accc52d0d830..10cb30cd52b9 100644 --- a/dspace-api/src/test/java/org/dspace/content/VersioningWithRelationshipsIT.java +++ b/dspace-api/src/test/java/org/dspace/content/VersioningWithRelationshipsIT.java @@ -60,6 +60,9 @@ import org.dspace.content.virtual.VirtualMetadataPopulator; import org.dspace.core.Constants; import org.dspace.discovery.SolrSearchCore; +import org.dspace.identifier.IdentifierProvider; +import org.dspace.identifier.IdentifierServiceImpl; +import org.dspace.identifier.VersionedHandleIdentifierProvider; import org.dspace.kernel.ServiceManager; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.versioning.Version; @@ -81,7 +84,7 @@ public class VersioningWithRelationshipsIT extends AbstractIntegrationTestWithDa ContentServiceFactory.getInstance().getItemService(); private final SolrSearchCore solrSearchCore = DSpaceServicesFactory.getInstance().getServiceManager().getServicesByType(SolrSearchCore.class).get(0); - + private IdentifierServiceImpl identifierService; protected Community community; protected Collection collection; protected EntityType publicationEntityType; @@ -98,6 +101,22 @@ public class VersioningWithRelationshipsIT extends AbstractIntegrationTestWithDa protected RelationshipType isIssueOfJournalVolume; protected RelationshipType isProjectOfPerson; + private void registerProvider(Class type) { + // Register our new provider + IdentifierProvider identifierProvider = + (IdentifierProvider) DSpaceServicesFactory.getInstance().getServiceManager().getServiceByName(type.getName(), type); + if (identifierProvider == null) { + DSpaceServicesFactory.getInstance().getServiceManager().registerServiceClass(type.getName(), type); + identifierProvider = (IdentifierProvider) DSpaceServicesFactory.getInstance().getServiceManager().getServiceByName(type.getName(), type); + } + + // Overwrite the identifier-service's providers with the new one to ensure only this provider is used + identifierService = DSpaceServicesFactory.getInstance().getServiceManager() + .getServicesByType(IdentifierServiceImpl.class).get(0); + identifierService.setProviders(new ArrayList<>()); + identifierService.setProviders(List.of(identifierProvider)); + } + @Override @Before public void setUp() throws Exception { @@ -105,6 +124,9 @@ public void setUp() throws Exception { context.turnOffAuthorisationSystem(); + + registerProvider(VersionedHandleIdentifierProvider.class); + community = CommunityBuilder.createCommunity(context) .withName("community") .build(); From ad7499f245be07aa9a5715b9eaa91bf164b79515 Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Fri, 6 Sep 2024 17:58:23 +0200 Subject: [PATCH 053/226] #9806: Move cleanup of handle provider to destroy in VersionedHandleIdentifierProviderIT (cherry picked from commit f6cabe648dfcda786afdf7d5411dc3d7ad85c405) --- .../VersioningWithRelationshipsIT.java | 23 ------------------- .../VersionedHandleIdentifierProviderIT.java | 22 ++++++++++++++++-- 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/content/VersioningWithRelationshipsIT.java b/dspace-api/src/test/java/org/dspace/content/VersioningWithRelationshipsIT.java index 10cb30cd52b9..3acc4ca146ee 100644 --- a/dspace-api/src/test/java/org/dspace/content/VersioningWithRelationshipsIT.java +++ b/dspace-api/src/test/java/org/dspace/content/VersioningWithRelationshipsIT.java @@ -60,9 +60,6 @@ import org.dspace.content.virtual.VirtualMetadataPopulator; import org.dspace.core.Constants; import org.dspace.discovery.SolrSearchCore; -import org.dspace.identifier.IdentifierProvider; -import org.dspace.identifier.IdentifierServiceImpl; -import org.dspace.identifier.VersionedHandleIdentifierProvider; import org.dspace.kernel.ServiceManager; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.versioning.Version; @@ -84,7 +81,6 @@ public class VersioningWithRelationshipsIT extends AbstractIntegrationTestWithDa ContentServiceFactory.getInstance().getItemService(); private final SolrSearchCore solrSearchCore = DSpaceServicesFactory.getInstance().getServiceManager().getServicesByType(SolrSearchCore.class).get(0); - private IdentifierServiceImpl identifierService; protected Community community; protected Collection collection; protected EntityType publicationEntityType; @@ -101,22 +97,6 @@ public class VersioningWithRelationshipsIT extends AbstractIntegrationTestWithDa protected RelationshipType isIssueOfJournalVolume; protected RelationshipType isProjectOfPerson; - private void registerProvider(Class type) { - // Register our new provider - IdentifierProvider identifierProvider = - (IdentifierProvider) DSpaceServicesFactory.getInstance().getServiceManager().getServiceByName(type.getName(), type); - if (identifierProvider == null) { - DSpaceServicesFactory.getInstance().getServiceManager().registerServiceClass(type.getName(), type); - identifierProvider = (IdentifierProvider) DSpaceServicesFactory.getInstance().getServiceManager().getServiceByName(type.getName(), type); - } - - // Overwrite the identifier-service's providers with the new one to ensure only this provider is used - identifierService = DSpaceServicesFactory.getInstance().getServiceManager() - .getServicesByType(IdentifierServiceImpl.class).get(0); - identifierService.setProviders(new ArrayList<>()); - identifierService.setProviders(List.of(identifierProvider)); - } - @Override @Before public void setUp() throws Exception { @@ -124,9 +104,6 @@ public void setUp() throws Exception { context.turnOffAuthorisationSystem(); - - registerProvider(VersionedHandleIdentifierProvider.class); - community = CommunityBuilder.createCommunity(context) .withName("community") .build(); diff --git a/dspace-api/src/test/java/org/dspace/identifier/VersionedHandleIdentifierProviderIT.java b/dspace-api/src/test/java/org/dspace/identifier/VersionedHandleIdentifierProviderIT.java index 7e549f6cae33..57acf1f1c453 100644 --- a/dspace-api/src/test/java/org/dspace/identifier/VersionedHandleIdentifierProviderIT.java +++ b/dspace-api/src/test/java/org/dspace/identifier/VersionedHandleIdentifierProviderIT.java @@ -24,6 +24,7 @@ import org.dspace.content.Item; import org.dspace.kernel.ServiceManager; import org.dspace.services.factory.DSpaceServicesFactory; +import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -57,13 +58,30 @@ public void setUp() throws Exception { .build(); } + @After + @Override + public void destroy() throws Exception { + super.destroy(); + // After this test has finished running, refresh application context and + // set the expected 'default' versioned handle provider back to ensure other tests don't fail + DSpaceServicesFactory.getInstance().getServiceManager().getApplicationContext().refresh(); + } + private void registerProvider(Class type) { // Register our new provider - serviceManager.registerServiceClass(type.getName(), type); IdentifierProvider identifierProvider = - (IdentifierProvider) serviceManager.getServiceByName(type.getName(), type); + (IdentifierProvider) DSpaceServicesFactory.getInstance().getServiceManager() + .getServiceByName(type.getName(), type); + if (identifierProvider == null) { + DSpaceServicesFactory.getInstance().getServiceManager().registerServiceClass(type.getName(), type); + identifierProvider = (IdentifierProvider) DSpaceServicesFactory.getInstance().getServiceManager() + .getServiceByName(type.getName(), type); + } // Overwrite the identifier-service's providers with the new one to ensure only this provider is used + identifierService = DSpaceServicesFactory.getInstance().getServiceManager() + .getServicesByType(IdentifierServiceImpl.class).get(0); + identifierService.setProviders(new ArrayList<>()); identifierService.setProviders(List.of(identifierProvider)); } From d40a5e2a4b1e90b3ca7e2ba7e75bb5cbe7bb72fa Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 17 Jun 2024 13:02:33 +0200 Subject: [PATCH 054/226] feat: new parameter "fromdate" to evaluate items only from certain date (cherry picked from commit a9e120f3d434ece061dcaf7371822b9201eac655) --- .../app/mediafilter/MediaFilterScript.java | 15 +++++++++++++-- .../MediaFilterScriptConfiguration.java | 2 ++ .../mediafilter/MediaFilterServiceImpl.java | 18 ++++++++++++++++++ .../service/MediaFilterService.java | 3 +++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterScript.java b/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterScript.java index 5fbbebbb28cc..71c0d6e14ddb 100644 --- a/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterScript.java +++ b/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterScript.java @@ -7,6 +7,7 @@ */ package org.dspace.app.mediafilter; +import java.time.LocalDate; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -37,8 +38,9 @@ * MFM: -v verbose outputs all extracted text to STDOUT; -f force forces all * bitstreams to be processed, even if they have been before; -n noindex does not * recreate index after processing bitstreams; -i [identifier] limits processing - * scope to a community, collection or item; and -m [max] limits processing to a - * maximum number of items. + * scope to a community, collection or item; -m [max] limits processing to a + * maximum number of items; -fd [fromdate] takes only items starting from this date, + * filtering by last_modified in the item table. */ public class MediaFilterScript extends DSpaceRunnable { @@ -60,6 +62,7 @@ public class MediaFilterScript extends DSpaceRunnable> filterFormats = new HashMap<>(); + private LocalDate fromDate = null; public MediaFilterScriptConfiguration getScriptConfiguration() { return new DSpace().getServiceManager() @@ -112,6 +115,10 @@ public void setup() throws ParseException { skipIds = commandLine.getOptionValues('s'); } + if (commandLine.hasOption('f')) { + fromDate = LocalDate.parse(commandLine.getOptionValue('f')); + } + } @@ -215,6 +222,10 @@ public void internalRun() throws Exception { mediaFilterService.setSkipList(Arrays.asList(skipIds)); } + if (fromDate != null) { + mediaFilterService.setFromDate(fromDate); + } + Context c = null; try { diff --git a/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterScriptConfiguration.java b/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterScriptConfiguration.java index 7465fa6e1279..9f62f19e8367 100644 --- a/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterScriptConfiguration.java +++ b/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterScriptConfiguration.java @@ -52,6 +52,8 @@ public Options getOptions() { .build(); options.addOption(pluginOption); + options.addOption("fd", "fromdate", true, "Process only item from specified last modified date"); + Option skipOption = Option.builder("s") .longOpt("skip") .hasArg() diff --git a/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterServiceImpl.java b/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterServiceImpl.java index a6ba9fde88d9..512b8f803b9b 100644 --- a/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterServiceImpl.java @@ -9,8 +9,11 @@ import java.io.InputStream; import java.sql.SQLException; +import java.time.LocalDate; +import java.time.ZoneId; import java.util.ArrayList; import java.util.Collections; +import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -93,6 +96,7 @@ public class MediaFilterServiceImpl implements MediaFilterService, InitializingB protected boolean isVerbose = false; protected boolean isQuiet = false; protected boolean isForce = false; // default to not forced + protected LocalDate fromDate = null; protected MediaFilterServiceImpl() { @@ -120,6 +124,15 @@ public void applyFiltersAllItems(Context context) throws Exception { for (Community topLevelCommunity : topLevelCommunities) { applyFiltersCommunity(context, topLevelCommunity); } + } else if (fromDate != null) { + Iterator itemIterator = + itemService.findByLastModifiedSince( + context, + Date.from(fromDate.atStartOfDay(ZoneId.systemDefault()).toInstant()) + ); + while (itemIterator.hasNext() && processed < max2Process) { + applyFiltersItem(context, itemIterator.next()); + } } else { //otherwise, just find every item and process Iterator itemIterator = itemService.findAll(context); @@ -588,4 +601,9 @@ public void setFilterFormats(Map> filterFormats) { public void setLogHandler(DSpaceRunnableHandler handler) { this.handler = handler; } + + @Override + public void setFromDate(LocalDate fromDate) { + this.fromDate = fromDate; + } } diff --git a/dspace-api/src/main/java/org/dspace/app/mediafilter/service/MediaFilterService.java b/dspace-api/src/main/java/org/dspace/app/mediafilter/service/MediaFilterService.java index bc92ff521098..30e6dba42f08 100644 --- a/dspace-api/src/main/java/org/dspace/app/mediafilter/service/MediaFilterService.java +++ b/dspace-api/src/main/java/org/dspace/app/mediafilter/service/MediaFilterService.java @@ -8,6 +8,7 @@ package org.dspace.app.mediafilter.service; import java.sql.SQLException; +import java.time.LocalDate; import java.util.List; import java.util.Map; @@ -149,4 +150,6 @@ public void updatePoliciesOfDerivativeBitstreams(Context context, Item item, Bit * @param handler */ public void setLogHandler(DSpaceRunnableHandler handler); + + public void setFromDate(LocalDate fromDate); } From cc76ebee108074c538090230cb397ce44f01e9d3 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 17 Jun 2024 13:57:39 +0200 Subject: [PATCH 055/226] refactor: changed short parameter fd to d (cherry picked from commit 2f6b7f3ee4b0c40d215730dd2e86f4492a455e77) --- .../main/java/org/dspace/app/mediafilter/MediaFilterScript.java | 2 +- .../dspace/app/mediafilter/MediaFilterScriptConfiguration.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterScript.java b/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterScript.java index 71c0d6e14ddb..e76feada0339 100644 --- a/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterScript.java +++ b/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterScript.java @@ -115,7 +115,7 @@ public void setup() throws ParseException { skipIds = commandLine.getOptionValues('s'); } - if (commandLine.hasOption('f')) { + if (commandLine.hasOption('d')) { fromDate = LocalDate.parse(commandLine.getOptionValue('f')); } diff --git a/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterScriptConfiguration.java b/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterScriptConfiguration.java index 9f62f19e8367..c9f61292d617 100644 --- a/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterScriptConfiguration.java +++ b/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterScriptConfiguration.java @@ -52,7 +52,7 @@ public Options getOptions() { .build(); options.addOption(pluginOption); - options.addOption("fd", "fromdate", true, "Process only item from specified last modified date"); + options.addOption("d", "fromdate", true, "Process only item from specified last modified date"); Option skipOption = Option.builder("s") .longOpt("skip") From f652b2c47ac2aab95c8dd84b4f045b715d2ea9f8 Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 17 Jun 2024 16:39:02 +0200 Subject: [PATCH 056/226] refactor: changed short parameter fd to d (cherry picked from commit 3fd88b867eb9bbd8b3621904ecac5b845fc7346e) --- .../main/java/org/dspace/app/mediafilter/MediaFilterScript.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterScript.java b/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterScript.java index e76feada0339..7f022f38b318 100644 --- a/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterScript.java +++ b/dspace-api/src/main/java/org/dspace/app/mediafilter/MediaFilterScript.java @@ -116,7 +116,7 @@ public void setup() throws ParseException { } if (commandLine.hasOption('d')) { - fromDate = LocalDate.parse(commandLine.getOptionValue('f')); + fromDate = LocalDate.parse(commandLine.getOptionValue('d')); } From 83f61ce12caf582ff1a59df699bffe7b09d3b95e Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 4 Sep 2024 15:31:28 +0200 Subject: [PATCH 057/226] fix: changed parameter of HQL query (cherry picked from commit 9c7b20ff5721e2886acd7186ba4df310c9efcf07) --- .../src/main/java/org/dspace/content/dao/impl/ItemDAOImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/content/dao/impl/ItemDAOImpl.java b/dspace-api/src/main/java/org/dspace/content/dao/impl/ItemDAOImpl.java index 3be39f1788fb..bd042648384b 100644 --- a/dspace-api/src/main/java/org/dspace/content/dao/impl/ItemDAOImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/dao/impl/ItemDAOImpl.java @@ -441,7 +441,7 @@ public int countItems(Context context, List collections, boolean inc public Iterator findByLastModifiedSince(Context context, Date since) throws SQLException { Query query = createQuery(context, - "SELECT i.id FROM Item i WHERE last_modified > :last_modified ORDER BY id"); + "SELECT i.id FROM Item i WHERE lastModified > :last_modified ORDER BY id"); query.setParameter("last_modified", since, TemporalType.TIMESTAMP); @SuppressWarnings("unchecked") List uuids = query.getResultList(); From 4f5b9bb916b084f258fedb56ffbbc3abeda72895 Mon Sep 17 00:00:00 2001 From: Mikhail Schastlivtsev Date: Mon, 17 Jun 2024 14:06:53 +0300 Subject: [PATCH 058/226] add missing publisher metadatum in test (#9579) --- .../org/dspace/app/rest/WOSImportMetadataSourceServiceIT.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WOSImportMetadataSourceServiceIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WOSImportMetadataSourceServiceIT.java index f1d3f5303ec0..9f68d79c2036 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/WOSImportMetadataSourceServiceIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/WOSImportMetadataSourceServiceIT.java @@ -136,6 +136,7 @@ private ArrayList getRecords() { MetadatumDTO subject15 = createMetadatumDTO("dc", "subject", null, "Coding concepts"); MetadatumDTO subject16 = createMetadatumDTO("dc", "subject", null, "Lesson design"); MetadatumDTO subject17 = createMetadatumDTO("dc", "subject", null, "Social Sciences"); + MetadatumDTO publisher = createMetadatumDTO("dc", "publisher", null, "SPRINGER"); MetadatumDTO other = createMetadatumDTO("dc", "identifier", "other", "WOS:000805105200003"); metadatums.add(edition); metadatums.add(date); @@ -166,6 +167,7 @@ private ArrayList getRecords() { metadatums.add(subject15); metadatums.add(subject16); metadatums.add(subject17); + metadatums.add(publisher); metadatums.add(other); ImportRecord firstrRecord = new ImportRecord(metadatums); @@ -205,6 +207,7 @@ private ArrayList getRecords() { MetadatumDTO subject26 = createMetadatumDTO("dc", "subject", null, "Social Sciences"); MetadatumDTO subject27 = createMetadatumDTO("dc", "subject", null, "Science & Technology"); MetadatumDTO subject28 = createMetadatumDTO("dc", "subject", null, "Life Sciences & Biomedicine"); + MetadatumDTO publisher2 = createMetadatumDTO("dc", "publisher", null, "NATURE PORTFOLIO"); MetadatumDTO other2 = createMetadatumDTO("dc", "identifier", "other", "WOS:000805100600001"); MetadatumDTO rid = createMetadatumDTO("person", "identifier", "rid", "C-6334-2011"); MetadatumDTO rid2 = createMetadatumDTO("person", "identifier", "rid", "B-1251-2008"); @@ -236,6 +239,7 @@ private ArrayList getRecords() { metadatums2.add(subject26); metadatums2.add(subject27); metadatums2.add(subject28); + metadatums2.add(publisher2); metadatums2.add(other2); metadatums2.add(rid); metadatums2.add(rid2); From 5263b08eafe4393b6abc2af50132590795cdda81 Mon Sep 17 00:00:00 2001 From: Mikhail Schastlivtsev Date: Wed, 15 May 2024 10:08:46 +0300 Subject: [PATCH 059/226] add missing wosPublisherContrib key-ref in wos-integration.xml (#9579) --- dspace/config/spring/api/wos-integration.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/dspace/config/spring/api/wos-integration.xml b/dspace/config/spring/api/wos-integration.xml index 17bd53c04a4d..ba90363a2e60 100644 --- a/dspace/config/spring/api/wos-integration.xml +++ b/dspace/config/spring/api/wos-integration.xml @@ -35,6 +35,7 @@ + From da6de795338f95e8b6658c4765d5837e6325554c Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Wed, 3 Jul 2024 13:23:32 +0200 Subject: [PATCH 060/226] update eperson's attributes right after successful login (cherry picked from commit 428489ca5258ea7ac6942a722621e22c3371bfcf) --- .../authenticate/LDAPAuthentication.java | 69 +++++++++++-------- 1 file changed, 42 insertions(+), 27 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java b/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java index b791df15b5c0..c6df4b30faad 100644 --- a/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java +++ b/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java @@ -68,12 +68,8 @@ * @author Ivan Masár * @author Michael Plate */ -public class LDAPAuthentication - implements AuthenticationMethod { +public class LDAPAuthentication implements AuthenticationMethod { - /** - * log4j category - */ private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(LDAPAuthentication.class); @@ -130,7 +126,7 @@ public boolean allowSetPassword(Context context, return false; } - /* + /** * This is an explicit method. */ @Override @@ -138,7 +134,7 @@ public boolean isImplicit() { return false; } - /* + /** * Add authenticated users to the group defined in dspace.cfg by * the login.specialgroup key. */ @@ -177,7 +173,7 @@ public List getSpecialGroups(Context context, HttpServletRequest request) return Collections.EMPTY_LIST; } - /* + /** * Authenticate the given credentials. * This is the heart of the authentication method: test the * credentials for authenticity, and if accepted, attempt to match @@ -250,7 +246,7 @@ public int authenticate(Context context, } // Check a DN was found - if ((dn == null) || (dn.trim().equals(""))) { + if (StringUtils.isBlank(dn)) { log.info(LogHelper .getHeader(context, "failed_login", "no DN found for user " + netid)); return BAD_CREDENTIALS; @@ -269,6 +265,18 @@ public int authenticate(Context context, context.setCurrentUser(eperson); request.setAttribute(LDAP_AUTHENTICATED, true); + // update eperson's attributes + context.turnOffAuthorisationSystem(); + setEpersonAttributes(context, eperson, ldap, Optional.empty()); + try { + ePersonService.update(context, eperson); + context.dispatchEvents(); + } catch (AuthorizeException e) { + log.warn("update of eperson " + eperson.getID() + " failed", e); + } finally { + context.restoreAuthSystemState(); + } + // assign user to groups based on ldap dn assignGroups(dn, ldap.ldapGroup, context); @@ -313,14 +321,13 @@ public int authenticate(Context context, log.info(LogHelper.getHeader(context, "type=ldap-login", "type=ldap_but_already_email")); context.turnOffAuthorisationSystem(); - eperson.setNetid(netid.toLowerCase()); + setEpersonAttributes(context, eperson, ldap, Optional.of(netid)); ePersonService.update(context, eperson); context.dispatchEvents(); context.restoreAuthSystemState(); context.setCurrentUser(eperson); request.setAttribute(LDAP_AUTHENTICATED, true); - // assign user to groups based on ldap dn assignGroups(dn, ldap.ldapGroup, context); @@ -331,20 +338,7 @@ public int authenticate(Context context, try { context.turnOffAuthorisationSystem(); eperson = ePersonService.create(context); - if (StringUtils.isNotEmpty(email)) { - eperson.setEmail(email); - } - if (StringUtils.isNotEmpty(ldap.ldapGivenName)) { - eperson.setFirstName(context, ldap.ldapGivenName); - } - if (StringUtils.isNotEmpty(ldap.ldapSurname)) { - eperson.setLastName(context, ldap.ldapSurname); - } - if (StringUtils.isNotEmpty(ldap.ldapPhone)) { - ePersonService.setMetadataSingleValue(context, eperson, - MD_PHONE, ldap.ldapPhone, null); - } - eperson.setNetid(netid.toLowerCase()); + setEpersonAttributes(context, eperson, ldap, Optional.of(netid)); eperson.setCanLogIn(true); authenticationService.initEPerson(context, request, eperson); ePersonService.update(context, eperson); @@ -382,6 +376,27 @@ public int authenticate(Context context, return BAD_ARGS; } + /** + * Update eperson's attributes + */ + private void setEpersonAttributes(Context context, EPerson eperson, SpeakerToLDAP ldap, Optional netid) throws SQLException { + if (StringUtils.isNotEmpty(ldap.ldapEmail)) { + eperson.setEmail(ldap.ldapEmail); + } + if (StringUtils.isNotEmpty(ldap.ldapGivenName)) { + eperson.setFirstName(context, ldap.ldapGivenName); + } + if (StringUtils.isNotEmpty(ldap.ldapSurname)) { + eperson.setLastName(context, ldap.ldapSurname); + } + if (StringUtils.isNotEmpty(ldap.ldapPhone)) { + ePersonService.setMetadataSingleValue(context, eperson, MD_PHONE, ldap.ldapPhone, null); + } + if (netid.isPresent()) { + eperson.setNetid(netid.get().toLowerCase()); + } + } + /** * Internal class to manage LDAP query and results, mainly * because there are multiple values to return. @@ -671,7 +686,7 @@ protected boolean ldapAuthenticate(String netid, String password, } } - /* + /** * Returns the URL of an external login page which is not applicable for this authn method. * * Note: Prior to DSpace 7, this method return the page of login servlet. @@ -699,7 +714,7 @@ public String getName() { return "ldap"; } - /* + /** * Add authenticated users to the group defined in dspace.cfg by * the authentication-ldap.login.groupmap.* key. * From c6d95c69583342e3d18bb90b81da1b7e40c838e0 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Wed, 3 Jul 2024 13:36:45 +0200 Subject: [PATCH 061/226] add missing import (cherry picked from commit c5ad32a9b3ece7e64043f9f39d22b594e913737f) --- .../main/java/org/dspace/authenticate/LDAPAuthentication.java | 1 + 1 file changed, 1 insertion(+) diff --git a/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java b/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java index c6df4b30faad..9ca5245c54ba 100644 --- a/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java +++ b/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java @@ -17,6 +17,7 @@ import java.util.Hashtable; import java.util.Iterator; import java.util.List; +import java.util.Optional; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.Attribute; From 8a3596d0db8b2f0abdca932312a960e487028ddf Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Wed, 3 Jul 2024 13:54:53 +0200 Subject: [PATCH 062/226] fix Checkstyle violations (cherry picked from commit aaa74b88c99af8ece67d43fa412a39a7406fe10c) --- .../org/dspace/authenticate/LDAPAuthentication.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java b/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java index 9ca5245c54ba..4f2c5cc3d02c 100644 --- a/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java +++ b/dspace-api/src/main/java/org/dspace/authenticate/LDAPAuthentication.java @@ -184,7 +184,7 @@ public List getSpecialGroups(Context context, HttpServletRequest request) * @param context * DSpace context, will be modified (ePerson set) upon success. * - * @param username + * @param netid * Username (or email address) when method is explicit. Use null for * implicit method. * @@ -322,7 +322,7 @@ public int authenticate(Context context, log.info(LogHelper.getHeader(context, "type=ldap-login", "type=ldap_but_already_email")); context.turnOffAuthorisationSystem(); - setEpersonAttributes(context, eperson, ldap, Optional.of(netid)); + setEpersonAttributes(context, eperson, ldap, Optional.of(netid)); ePersonService.update(context, eperson); context.dispatchEvents(); context.restoreAuthSystemState(); @@ -380,7 +380,9 @@ public int authenticate(Context context, /** * Update eperson's attributes */ - private void setEpersonAttributes(Context context, EPerson eperson, SpeakerToLDAP ldap, Optional netid) throws SQLException { + private void setEpersonAttributes(Context context, EPerson eperson, SpeakerToLDAP ldap, Optional netid) + throws SQLException { + if (StringUtils.isNotEmpty(ldap.ldapEmail)) { eperson.setEmail(ldap.ldapEmail); } @@ -389,7 +391,7 @@ private void setEpersonAttributes(Context context, EPerson eperson, SpeakerToLDA } if (StringUtils.isNotEmpty(ldap.ldapSurname)) { eperson.setLastName(context, ldap.ldapSurname); - } + } if (StringUtils.isNotEmpty(ldap.ldapPhone)) { ePersonService.setMetadataSingleValue(context, eperson, MD_PHONE, ldap.ldapPhone, null); } From c08c62fccf450c98225827e3ecc126e494b16c5e Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Fri, 27 Sep 2024 12:07:52 +0200 Subject: [PATCH 063/226] minor fix in parameter description (cherry picked from commit 5758d9e90302d4da33ec869b6ec656e5c25b865a) --- dspace/config/emails/subscriptions_content | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dspace/config/emails/subscriptions_content b/dspace/config/emails/subscriptions_content index 9b8c91e559df..a1b107e8fc50 100644 --- a/dspace/config/emails/subscriptions_content +++ b/dspace/config/emails/subscriptions_content @@ -1,7 +1,7 @@ ## E-mail sent to designated address about updates on subscribed items ## -## Parameters: {0} Collections updates -## {1} Communities updates +## Parameters: {0} Communities updates +## {1} Collections updates #set($subject = "${config.get('dspace.name')} Subscriptions") This email is sent from ${config.get('dspace.name')} based on the chosen subscription preferences. From 058f878d9275873bc9849c75777543bce686d989 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Tue, 27 Aug 2024 10:33:01 +0200 Subject: [PATCH 064/226] fix failed first login attempt in HAL browser (cherry picked from commit 002e637d4fc69b31c2a2321230d96534e49ee33e) --- .../src/main/resources/static/login.html | 128 ++++++++++-------- 1 file changed, 68 insertions(+), 60 deletions(-) diff --git a/dspace-server-webapp/src/main/resources/static/login.html b/dspace-server-webapp/src/main/resources/static/login.html index 50d95b80472f..0597a66bfe96 100644 --- a/dspace-server-webapp/src/main/resources/static/login.html +++ b/dspace-server-webapp/src/main/resources/static/login.html @@ -32,7 +32,7 @@ border-radius: 5px; box-shadow: 0 1px 2px rgba(0, 0, 0, .05); } - .form-signin .form-signin-heading, .form-signin .checkbox { + .form-signin .form-signin-heading, .form-signin { margin-bottom: 10px; } .form-signin input[type="text"], .form-signin input[type="password"] { @@ -94,63 +94,71 @@

Other login methods:

"onclick" : function() { toastr.remove(); } } + // retrieves a valid CSRF token (please note that this method works both in DS 7 and DS 8) + // HTTP response code 403 is expected at this point (the response contains the DSPACE-XSRF-TOKEN header) + $.ajax({ + url : window.location.href.replace("login.html", "") + 'api/authn/login', + type : 'POST', + error : function(xhr) { + // Check for an update to the CSRF Token & save to a MyHalBrowserCsrfToken cookie (if found) + checkForUpdatedCSRFTokenInResponse(xhr); + } + }); + // When the login page loads, we do *two* AJAX requests. - // (1) Call GET /api/authn/status. This call has two purposes. First, it checks to see if you are logged in, - // (if not, WWW-Authenticate will return login options). Second, it retrieves the CSRF token, if a - // new one has been assigned (as a valid CSRF token is required for the POST call). + // (1) Call GET /api/authn/status. This call checks to see if you are logged in + // (if not, WWW-Authenticate will return login options). // (2) If that /api/authn/status call finds authentication data, call POST /api/authn/login. - // This scenario occurs when you login via an external authentication system (e.g. Shibboleth)... + // This scenario occurs when you log in via an external authentication system (e.g. Shibboleth) // in which case the main role of /api/authn/login is to simply ensure the "Authorization" header // is sent back to the client (based on your authentication data). $.ajax({ - url : window.location.href.replace("login.html", "") + 'api/authn/status', - type : 'GET', - success : function(result, status, xhr) { - // Check for an update to the CSRF Token & save to a MyHalBrowserCsrfToken cookie (if found) - checkForUpdatedCSRFTokenInResponse(xhr); + url : window.location.href.replace("login.html", "") + 'api/authn/status', + type : 'GET', + success : function(result, status, xhr) { - // Check for WWW-Authenticate header. If found, this means we are not yet authenticated, and - // therefore we need to display available authentication options. - var authenticate = xhr.getResponseHeader("WWW-Authenticate"); - if (authenticate !== null) { - var element = $('div.other-login-methods'); - var realms = authenticate.match(/(\w+ (\w+=((".*?")|[^,]*)(, )?)*)/g); - if (realms.length == 1){ - var loc = /location="([^,]*)"/.exec(authenticate); - if (loc !== null && loc.length === 2) { - document.location = loc[1]; - } - } else if (realms.length > 1){ - for (var i = 0; i < realms.length; i++){ - addLocationButton(realms[i], element); + // Check for WWW-Authenticate header. If found, this means we are not yet authenticated, and + // therefore we need to display available authentication options. + var authenticate = xhr.getResponseHeader("WWW-Authenticate"); + if (authenticate !== null && authenticate.contains('location=')) { + var element = $('div.other-login-methods'); + var realms = authenticate.match(/(\w+ (\w+=((".*?")|[^,]*)(, )?)*)/g); + if (realms.length === 1){ + var loc = /location="([^,]*)"/.exec(authenticate); + if (loc !== null && loc.length === 2) { + document.location = loc[1]; + } + } else if (realms.length > 1){ + for (var i = 0; i < realms.length; i++){ + addLocationButton(realms[i], element); + } } + } else { + // If Authentication data was found, do a POST /api/authn/login to ensure that data's JWT + // is sent back in the "Authorization" header. This simply completes an external authentication + // process (e.g. Shibboleth) + $.ajax({ + url : window.location.href.replace("login.html", "") + 'api/authn/login', + type : 'POST', + beforeSend: function (xhr) { + // If CSRF token found in cookie, send it back as X-XSRF-Token header + var csrfToken = getCSRFToken(); + if (csrfToken != null) { + xhr.setRequestHeader('X-XSRF-Token', csrfToken); + } + }, + success : successHandler, + error : function(xhr) { + // Check for an update to the CSRF Token & save to a MyHalBrowserCsrfToken cookie (if found) + checkForUpdatedCSRFTokenInResponse(xhr); + toastr.error('Failed to logged in. Please check for errors in Javascript console.', 'Login Failed'); + } + }); } - } else { - // If Authentication data was found, do a POST /api/authn/login to ensure that data's JWT - // is sent back in the "Authorization" header. This simply completes an external authentication - // process (e.g. Shibboleth) - $.ajax({ - url : window.location.href.replace("login.html", "") + 'api/authn/login', - type : 'POST', - beforeSend: function (xhr, settings) { - // If CSRF token found in cookie, send it back as X-XSRF-Token header - var csrfToken = getCSRFToken(); - if (csrfToken != null) { - xhr.setRequestHeader('X-XSRF-Token', csrfToken); - } - }, - success : successHandler, - error : function(xhr, textStatus, errorThrown) { - // Check for an update to the CSRF Token & save to a MyHalBrowserCsrfToken cookie (if found) - checkForUpdatedCSRFTokenInResponse(xhr); - toastr.error('Failed to logged in. Please check for errors in Javascript console.', 'Login Failed'); - } - }); + }, + error : function() { + toastr.error('Failed to connect with backend. Please check for errors in Javascript console.', 'Could Not Load'); } - }, - error : function(xhr, textStatus, errorThrown) { - toastr.error('Failed to connect with backend. Please check for errors in Javascript console.', 'Could Not Load'); - } }); function addLocationButton(realm, element){ @@ -166,22 +174,22 @@

Other login methods:

return string.charAt(0).toUpperCase() + string.slice(1); } - /** - * Check current response headers to see if the CSRF Token has changed. If a new value is found in headers, - * save the new value into our "MyHalBrowserCsrfToken" cookie. - **/ + /** + * Check current response headers to see if the CSRF Token has changed. If a new value is found in headers, + * save the new value into our "MyHalBrowserCsrfToken" cookie. + **/ function checkForUpdatedCSRFTokenInResponse(jqxhr) { // look for DSpace-XSRF-TOKEN header & save to our MyHalBrowserCsrfToken cookie (if found) var updatedCsrfToken = jqxhr.getResponseHeader('DSPACE-XSRF-TOKEN'); if (updatedCsrfToken != null) { - document.cookie = "MyHalBrowserCsrfToken=" + updatedCsrfToken; + document.cookie = "MyHalBrowserCsrfToken=" + updatedCsrfToken; } } - /** - * Get CSRF Token by parsing it out of the "MyHalBrowserCsrfToken" cookie. - * This cookie is set in login.html after a successful login occurs. - **/ + /** + * Get CSRF Token by parsing it out of the "MyHalBrowserCsrfToken" cookie. + * This cookie is set in login.html after a successful login occurs. + **/ function getCSRFToken() { var cookie = document.cookie.match('(^|;)\\s*' + 'MyHalBrowserCsrfToken' + '\\s*=\\s*([^;]+)'); if (cookie != null) { @@ -204,11 +212,11 @@

Other login methods:

user: $("#username").val(), password: $("#password").val() }, - beforeSend: function (xhr, settings) { + beforeSend: function (xhr) { // If CSRF token found in cookie, send it back as X-XSRF-Token header var csrfToken = getCSRFToken(); if (csrfToken != null) { - xhr.setRequestHeader('X-XSRF-Token', csrfToken); + xhr.setRequestHeader('X-XSRF-Token', csrfToken); } }, success : successHandler, From c468e48f2f1177fc5477f003e68319503bf2b265 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Thu, 29 Aug 2024 16:24:38 +0200 Subject: [PATCH 065/226] applied change suggested by reviewer: use String.prototype.includes (cherry picked from commit 546afb189e1df8bdfbc9948e790004baa81ec894) --- dspace-server-webapp/src/main/resources/static/login.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-server-webapp/src/main/resources/static/login.html b/dspace-server-webapp/src/main/resources/static/login.html index 0597a66bfe96..959190020a13 100644 --- a/dspace-server-webapp/src/main/resources/static/login.html +++ b/dspace-server-webapp/src/main/resources/static/login.html @@ -120,7 +120,7 @@

Other login methods:

// Check for WWW-Authenticate header. If found, this means we are not yet authenticated, and // therefore we need to display available authentication options. var authenticate = xhr.getResponseHeader("WWW-Authenticate"); - if (authenticate !== null && authenticate.contains('location=')) { + if (authenticate !== null && authenticate.includes('location=')) { var element = $('div.other-login-methods'); var realms = authenticate.match(/(\w+ (\w+=((".*?")|[^,]*)(, )?)*)/g); if (realms.length === 1){ From 6e22495bffae2bb6a414e094cc6ed5b77886422a Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Thu, 10 Oct 2024 16:02:53 -0500 Subject: [PATCH 066/226] Bump to Spring 6.1.13, Spring Boot 3.3.4 and Spring Security 6.3.3 (cherry picked from commit 46dfd902f113b9ea13ce53b496aff6979024d67e) --- dspace-server-webapp/pom.xml | 14 +++++++++++++- pom.xml | 6 +++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/dspace-server-webapp/pom.xml b/dspace-server-webapp/pom.xml index 563019983402..759ad724b9b6 100644 --- a/dspace-server-webapp/pom.xml +++ b/dspace-server-webapp/pom.xml @@ -343,6 +343,18 @@ org.springframework.boot spring-boot-starter-actuator ${spring-boot.version} + + + + io.micrometer + micrometer-observation + + + + io.micrometer + micrometer-commons + +
@@ -437,7 +449,7 @@ spring-boot-starter-security ${spring-boot.version} - + io.micrometer micrometer-observation diff --git a/pom.xml b/pom.xml index 54e56556f275..e92469dff3c4 100644 --- a/pom.xml +++ b/pom.xml @@ -19,9 +19,9 @@ 17 - 6.1.8 - 3.2.6 - 6.2.4 + 6.1.13 + 3.3.4 + 6.3.3 6.4.8.Final 8.0.1.Final 42.7.3 From f6ec314ef762ce83037ad94940cfc352246e300d Mon Sep 17 00:00:00 2001 From: Kim Shepherd Date: Tue, 15 Oct 2024 23:23:24 +0200 Subject: [PATCH 067/226] Add Eclipse JDT .factorypath to .gitignore (cherry picked from commit 9ce645e08b50cd752e48a640e340b55466f019be) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 2fcb46b9932c..529351edc5c2 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ tags .project .classpath .checkstyle +.factorypath ## Ignore project files created by IntelliJ IDEA *.iml From 42be64cf941083c7f517e81c70651f78fcedd788 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 18 Oct 2024 20:21:19 +0000 Subject: [PATCH 068/226] Bump the maven group with 3 updates Bumps the maven group with 3 updates: [org.springframework:spring-context](https://github.com/spring-projects/spring-framework), org.eclipse.jetty:jetty-server and org.eclipse.jetty:jetty-http. Updates `org.springframework:spring-context` from 6.1.13 to 6.1.14 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.13...v6.1.14) Updates `org.eclipse.jetty:jetty-server` from 9.4.54.v20240208 to 9.4.55.v20240627 Updates `org.eclipse.jetty:jetty-http` from 9.4.54.v20240208 to 9.4.55.v20240627 --- updated-dependencies: - dependency-name: org.springframework:spring-context dependency-type: direct:production dependency-group: maven - dependency-name: org.eclipse.jetty:jetty-server dependency-type: direct:production dependency-group: maven - dependency-name: org.eclipse.jetty:jetty-http dependency-type: direct:production dependency-group: maven ... Signed-off-by: dependabot[bot] (cherry picked from commit e96dbfefeb6924c4b17c66535215878576190fb5) --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index e92469dff3c4..3eec65d4a9fd 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ 17 - 6.1.13 + 6.1.14 3.3.4 6.3.3 6.4.8.Final @@ -38,7 +38,7 @@ 4.0.5 1.1.1 - 9.4.54.v20240208 + 9.4.55.v20240627 2.23.1 2.0.31 1.19.0 From e6d4ea07f6ab49b7baa63fe1dfd45ea1ee09d126 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Fri, 1 Nov 2024 14:12:25 +0100 Subject: [PATCH 069/226] fix typo in endpoint path (cherry picked from commit 6a7b0fc06b48ad145cc654d38675dcdbe0fafa70) --- .../app/rest/ItemOwningCollectionUpdateRestController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemOwningCollectionUpdateRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemOwningCollectionUpdateRestController.java index eec5b15825ac..db238e1a5c83 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemOwningCollectionUpdateRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/ItemOwningCollectionUpdateRestController.java @@ -43,7 +43,7 @@ import org.springframework.web.bind.annotation.RestController; /** - * This controller will handle all the incoming calls on the api/code/items/{uuid}/owningCollection endpoint + * This controller will handle all the incoming calls on the api/core/items/{uuid}/owningCollection endpoint * where the uuid corresponds to the item of which you want to edit the owning collection. */ @RestController From 2bf5baf69779cfde398f368cb756a0576d82794b Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 6 Nov 2024 13:36:17 -0600 Subject: [PATCH 070/226] Move logging of test methods to Abstract*Test classes in dspace-api. That way they work for **both** dspace-server-webapp and dspace-api tests. (cherry picked from commit bd20c9262b1992ff15033701fa01738329864b1b) --- .../dspace/AbstractDSpaceIntegrationTest.java | 24 ++++++++++ .../java/org/dspace/AbstractDSpaceTest.java | 23 ++++++++++ .../AbstractControllerIntegrationTest.java | 4 -- .../AbstractWebClientIntegrationTest.java | 4 -- .../test/LoggingTestExecutionListener.java | 44 ------------------- 5 files changed, 47 insertions(+), 52 deletions(-) delete mode 100644 dspace-server-webapp/src/test/java/org/dspace/app/rest/test/LoggingTestExecutionListener.java diff --git a/dspace-api/src/test/java/org/dspace/AbstractDSpaceIntegrationTest.java b/dspace-api/src/test/java/org/dspace/AbstractDSpaceIntegrationTest.java index 5a5ce8bf6d4c..791fdbc66abc 100644 --- a/dspace-api/src/test/java/org/dspace/AbstractDSpaceIntegrationTest.java +++ b/dspace-api/src/test/java/org/dspace/AbstractDSpaceIntegrationTest.java @@ -21,8 +21,12 @@ import org.dspace.discovery.SearchUtils; import org.dspace.servicemanager.DSpaceKernelImpl; import org.dspace.servicemanager.DSpaceKernelInit; +import org.junit.After; import org.junit.AfterClass; +import org.junit.Before; import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.rules.TestName; /** * Abstract Test class copied from DSpace API @@ -46,6 +50,12 @@ public class AbstractDSpaceIntegrationTest { */ protected static DSpaceKernelImpl kernelImpl; + /** + * Obtain the TestName from JUnit, so that we can print it out in the test logs (see below) + */ + @Rule + public TestName testName = new TestName(); + /** * Default constructor */ @@ -90,6 +100,20 @@ public static void initTestEnvironment() { } } + @Before + public void printTestMethodBefore() { + // Log the test method being executed. Put lines around it to make it stand out. + log.info("---"); + log.info("Starting execution of test method: {}()", testName.getMethodName()); + log.info("---"); + } + + @After + public void printTestMethodAfter() { + // Log the test method just completed. + log.info("Finished execution of test method: {}()", testName.getMethodName()); + } + /** * This method will be run after all tests finish as per @AfterClass. It * will clean resources initialized by the @BeforeClass methods. diff --git a/dspace-api/src/test/java/org/dspace/AbstractDSpaceTest.java b/dspace-api/src/test/java/org/dspace/AbstractDSpaceTest.java index 36477556d3de..136af83f076f 100644 --- a/dspace-api/src/test/java/org/dspace/AbstractDSpaceTest.java +++ b/dspace-api/src/test/java/org/dspace/AbstractDSpaceTest.java @@ -18,9 +18,13 @@ import org.apache.logging.log4j.Logger; import org.dspace.servicemanager.DSpaceKernelImpl; import org.dspace.servicemanager.DSpaceKernelInit; +import org.junit.After; import org.junit.AfterClass; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; +import org.junit.Rule; +import org.junit.rules.TestName; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; @@ -62,6 +66,12 @@ protected AbstractDSpaceTest() { } */ protected static DSpaceKernelImpl kernelImpl; + /** + * Obtain the TestName from JUnit, so that we can print it out in the test logs (see below) + */ + @Rule + public TestName testName = new TestName(); + /** * This method will be run before the first test as per @BeforeClass. It will * initialize shared resources required for all tests of this class. @@ -94,6 +104,19 @@ public static void initKernel() { } } + @Before + public void printTestMethodBefore() { + // Log the test method being executed. Put lines around it to make it stand out. + log.info("---"); + log.info("Starting execution of test method: {}()", testName.getMethodName()); + log.info("---"); + } + + @After + public void printTestMethodAfter() { + // Log the test method just completed. + log.info("Finished execution of test method: {}()", testName.getMethodName()); + } /** * This method will be run after all tests finish as per @AfterClass. It diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/test/AbstractControllerIntegrationTest.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/test/AbstractControllerIntegrationTest.java index c4ab14250bca..26dac5facdec 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/test/AbstractControllerIntegrationTest.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/test/AbstractControllerIntegrationTest.java @@ -42,7 +42,6 @@ import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.TestExecutionListeners; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.web.WebAppConfiguration; @@ -80,9 +79,6 @@ @WebAppConfiguration // Load our src/test/resources/application-test.properties to override some settings in default application.properties @TestPropertySource(locations = "classpath:application-test.properties") -// Enable our custom Logging listener to log when each test method starts/stops -@TestExecutionListeners(listeners = {LoggingTestExecutionListener.class}, - mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS) public class AbstractControllerIntegrationTest extends AbstractIntegrationTestWithDatabase { private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/test/AbstractWebClientIntegrationTest.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/test/AbstractWebClientIntegrationTest.java index 7745fba96c3f..e4ef1c741f72 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/test/AbstractWebClientIntegrationTest.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/test/AbstractWebClientIntegrationTest.java @@ -22,7 +22,6 @@ import org.springframework.http.RequestEntity; import org.springframework.http.ResponseEntity; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.TestExecutionListeners; import org.springframework.test.context.TestPropertySource; import org.springframework.test.context.junit4.SpringRunner; @@ -52,9 +51,6 @@ @ContextConfiguration(initializers = { DSpaceKernelInitializer.class, DSpaceConfigurationInitializer.class }) // Load our src/test/resources/application-test.properties to override some settings in default application.properties @TestPropertySource(locations = "classpath:application-test.properties") -// Enable our custom Logging listener to log when each test method starts/stops -@TestExecutionListeners(listeners = {LoggingTestExecutionListener.class}, - mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS) public class AbstractWebClientIntegrationTest extends AbstractIntegrationTestWithDatabase { // (Random) port chosen for test web server @LocalServerPort diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/test/LoggingTestExecutionListener.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/test/LoggingTestExecutionListener.java deleted file mode 100644 index 2a04bab2041c..000000000000 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/test/LoggingTestExecutionListener.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * 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.app.rest.test; - -import org.apache.logging.log4j.Logger; -import org.springframework.test.context.TestContext; -import org.springframework.test.context.support.AbstractTestExecutionListener; - -/** - * Custom DSpace TestExecutionListener which logs messages whenever a specific Test Case (i.e. test method) has - * started or ended execution. This makes Test environment logs easier to read/understand as you know which method has - * caused errors, etc. - */ -public class LoggingTestExecutionListener extends AbstractTestExecutionListener { - - private static final Logger log = org.apache.logging.log4j.LogManager.getLogger(LoggingTestExecutionListener.class); - - /** - * Before each test method is run - * @param testContext - */ - @Override - public void beforeTestMethod(TestContext testContext) { - // Log the test method being executed. Put lines around it to make it stand out. - log.info("---"); - log.info("Starting execution of test method: {}()", testContext.getTestMethod().getName()); - log.info("---"); - } - - /** - * After each test method is run - * @param testContext - */ - @Override - public void afterTestMethod(TestContext testContext) { - // Log the test method just completed. - log.info("Finished execution of test method: {}()", testContext.getTestMethod().getName()); - } -} From 578726c25174d97710b4d5e12d2ed14c874735d3 Mon Sep 17 00:00:00 2001 From: Jens Vannerum Date: Mon, 14 Oct 2024 17:03:15 +0200 Subject: [PATCH 071/226] 118774: status of doi should be set to TO_BE_DELETED when related item is removed permanently (cherry picked from commit 352f4c21523237cefa5bf67c99f7d7b26a51d72b) --- .../src/main/java/org/dspace/content/ItemServiceImpl.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java index cceb954ebe2f..cb6cb15054cb 100644 --- a/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/ItemServiceImpl.java @@ -67,6 +67,7 @@ import org.dspace.harvest.HarvestedItem; import org.dspace.harvest.service.HarvestedItemService; import org.dspace.identifier.DOI; +import org.dspace.identifier.DOIIdentifierProvider; import org.dspace.identifier.IdentifierException; import org.dspace.identifier.service.DOIService; import org.dspace.identifier.service.IdentifierService; @@ -851,6 +852,7 @@ protected void rawDelete(Context context, Item item) throws AuthorizeException, DOI doi = doiService.findDOIByDSpaceObject(context, item); if (doi != null) { doi.setDSpaceObject(null); + doi.setStatus(DOIIdentifierProvider.TO_BE_DELETED); } // remove version attached to the item From b8dc7683814de4fe72b2e26218c99b8ea989a333 Mon Sep 17 00:00:00 2001 From: Andrew Date: Fri, 27 Sep 2024 12:52:03 +0200 Subject: [PATCH 072/226] fix: performance of claiming workflow task (cherry picked from commit 27dd5a2ec58970256964f15f0879834c436aa542) --- .../storedcomponents/PoolTaskServiceImpl.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/PoolTaskServiceImpl.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/PoolTaskServiceImpl.java index fb673725e181..d3c8f6334d8f 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/PoolTaskServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/storedcomponents/PoolTaskServiceImpl.java @@ -13,6 +13,7 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.Optional; import java.util.Set; import org.apache.commons.collections4.CollectionUtils; @@ -100,12 +101,17 @@ public PoolTask findByWorkflowIdAndEPerson(Context context, XmlWorkflowItem work //If the user does not have a claimedtask yet, see whether one of the groups of the user has pooltasks //for this workflow item Set groups = groupService.allMemberGroupsSet(context, ePerson); - for (Group group : groups) { - poolTask = poolTaskDAO.findByWorkflowItemAndGroup(context, group, workflowItem); - if (poolTask != null) { - return poolTask; - } + List generalTasks = poolTaskDAO.findByWorkflowItem(context, workflowItem); + Optional firstClaimedTask = groups.stream() + .flatMap(group -> generalTasks.stream() + .filter(f -> f.getGroup().getID().equals(group.getID())) + .findFirst() + .stream()) + .findFirst(); + + if (firstClaimedTask.isPresent()) { + return firstClaimedTask.get(); } } } From 6283c6e072edea6d867551e94d35da9aec1c123c Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Mon, 11 Nov 2024 10:26:29 -0600 Subject: [PATCH 073/226] Add a job to test Docker deployment with the built images (cherry picked from commit f1d12ef4560bdf7dffea29c5545d8d51d596cd17) --- .github/workflows/docker.yml | 43 +++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index a9ff8760e763..12d49689b319 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -147,4 +147,45 @@ jobs: tags_flavor: suffix=-loadsql secrets: DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }} - DOCKER_ACCESS_TOKEN: ${{ secrets.DOCKER_ACCESS_TOKEN }} \ No newline at end of file + DOCKER_ACCESS_TOKEN: ${{ secrets.DOCKER_ACCESS_TOKEN }} + + ######################################################################## + # Test Deployment via Docker to ensure images are working properly + ######################################################################## + docker-deploy: + # Ensure this job never runs on forked repos. It's only executed for 'dspace/dspace' + if: github.repository == 'dspace/dspace' + runs-on: ubuntu-latest + # Must run after all major images are built + needs: [dspace-test, dspace-cli, dspace-postgres-pgcrypto, dspace-solr] + steps: + - name: Checkout codebase + uses: actions/checkout@v4 + # Start backend using our compose script in the codebase. + - name: Start backend in Docker + env: + # Override defaults dspace.server.url because backend starts at http://127.0.0.1:8080 + dspace__P__server__P__url: http://127.0.0.1:8080/server + run: | + docker compose -f docker-compose.yml up -d + sleep 10 + docker container ls + # Create a test admin account. Load test data from a simple set of AIPs as defined in cli.ingest.yml + - name: Load test data into Backend + run: | + docker compose -f docker-compose-cli.yml run --rm dspace-cli create-administrator -e test@test.edu -f admin -l user -p admin -c en + docker compose -f docker-compose-cli.yml -f dspace/src/main/docker-compose/cli.ingest.yml run --rm dspace-cli + # Verify backend started successfully. + # 1. Make sure root endpoint is responding (check for dspace.name defined in docker-compose.yml) + # 2. Also check /collections endpoint to ensure the test data loaded properly (check for a collection name in AIPs) + - name: Verify backend is responding properly + run: | + result=$(wget -O- -q http://127.0.0.1:8080/server/api) + echo "$result" + echo "$result" | grep -oE "\"DSpace Started with Docker Compose\"," + result=$(wget -O- -q http://127.0.0.1:8080/server/api/core/collections) + echo "$result" + echo "$result" | grep -oE "\"Dog in Yard\"," + - name: Shutdown Docker containers + run: | + docker compose -f docker-compose.yml down From 0c3aee117cef30e8ebe9664eb634e8fe27b8c7f3 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Mon, 11 Nov 2024 14:10:44 -0600 Subject: [PATCH 074/226] Add a check that the Handle Server can be started & works properly (cherry picked from commit c96b5316d5b4af9e479c814fd0048dac002cbffa) --- .github/workflows/docker.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 12d49689b319..660c9eb817a6 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -186,6 +186,25 @@ jobs: result=$(wget -O- -q http://127.0.0.1:8080/server/api/core/collections) echo "$result" echo "$result" | grep -oE "\"Dog in Yard\"," + # Verify Handle Server can be stared and is working properly + # 1. First generate the "[dspace]/handle-server" folder with the sitebndl.zip + # 2. Start the Handle Server (and wait 20 seconds to let it start up) + # 3. Verify logs do NOT include "Exception" in the text (as that means an error occurred) + # 4. Check that Handle Proxy HTML page is responding on default port (8000) + - name: Verify Handle Server is working properly + run: | + docker exec -i dspace /dspace/bin/make-handle-config + docker exec -i dspace /dspace/bin/start-handle-server + sleep 20 + echo "Checking for errors in handle-server.log..." + result=$(docker exec -i dspace cat /dspace/log/handle-server.log) + echo "$result" + echo "$result" | grep -vqz "Exception" + echo "Checking to see if Handle Proxy webpage is available..." + result=$(wget -O- -q http://127.0.0.1:8000/) + echo "$result" + echo "$result" | grep -oE "Handle Proxy" + # Shutdown our containers - name: Shutdown Docker containers run: | docker compose -f docker-compose.yml down From 77b76b32f1b981fee485fdb517144d35f06243bc Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 12 Nov 2024 13:50:57 -0600 Subject: [PATCH 075/226] Ensure Docker images built from PRs are stored as artifacts. This allows us to use those new images when testing deployment (in docker-deploy) (cherry picked from commit eb766c7cdf1d92898cc8c2a1ba067ba8dac2abad) --- .github/workflows/docker.yml | 34 +++++++++--- .github/workflows/reusable-docker-build.yml | 58 +++++++++++++++++++-- 2 files changed, 81 insertions(+), 11 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 660c9eb817a6..eed8de5a8722 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -157,27 +157,47 @@ jobs: if: github.repository == 'dspace/dspace' runs-on: ubuntu-latest # Must run after all major images are built - needs: [dspace-test, dspace-cli, dspace-postgres-pgcrypto, dspace-solr] + needs: [dspace, dspace-test, dspace-cli, dspace-postgres-pgcrypto, dspace-solr] steps: + # Checkout our codebase (to get access to Docker Compose scripts) - name: Checkout codebase uses: actions/checkout@v4 - # Start backend using our compose script in the codebase. + # For PRs, download Docker image artifacts (built by reusable-docker-build.yml for all PRs) + - name: Download Docker image artifacts (for PRs) + if: github.event_name == 'pull_request' + uses: actions/download-artifact@v4 + with: + # Download all Docker images (TAR files) into the /tmp/docker directory + pattern: docker-image-* + path: /tmp/docker + merge-multiple: true + # For PRs, load each of the images into Docker by calling "docker image load" for each. + # This ensures we are using the images built from this PR & not the prior versions on DockerHub + - name: Load all downloaded Docker images (for PRs) + if: github.event_name == 'pull_request' + run: | + find /tmp/docker -type f -name "*.tar" -exec docker image load --input "{}" \; + docker image ls -a + # Start backend using our compose script in the codebase. - name: Start backend in Docker env: # Override defaults dspace.server.url because backend starts at http://127.0.0.1:8080 dspace__P__server__P__url: http://127.0.0.1:8080/server + # Force using "pr-testing" version of Docker images. The "pr-testing" tag is a temporary tag that we assign to + # all PR-built docker images in reusabe-docker-build.yml + DSPACE_VER: pr-testing run: | docker compose -f docker-compose.yml up -d sleep 10 docker container ls - # Create a test admin account. Load test data from a simple set of AIPs as defined in cli.ingest.yml + # Create a test admin account. Load test data from a simple set of AIPs as defined in cli.ingest.yml - name: Load test data into Backend run: | docker compose -f docker-compose-cli.yml run --rm dspace-cli create-administrator -e test@test.edu -f admin -l user -p admin -c en docker compose -f docker-compose-cli.yml -f dspace/src/main/docker-compose/cli.ingest.yml run --rm dspace-cli - # Verify backend started successfully. - # 1. Make sure root endpoint is responding (check for dspace.name defined in docker-compose.yml) - # 2. Also check /collections endpoint to ensure the test data loaded properly (check for a collection name in AIPs) + # Verify backend started successfully. + # 1. Make sure root endpoint is responding (check for dspace.name defined in docker-compose.yml) + # 2. Also check /collections endpoint to ensure the test data loaded properly (check for a collection name in AIPs) - name: Verify backend is responding properly run: | result=$(wget -O- -q http://127.0.0.1:8080/server/api) @@ -204,7 +224,7 @@ jobs: result=$(wget -O- -q http://127.0.0.1:8000/) echo "$result" echo "$result" | grep -oE "Handle Proxy" - # Shutdown our containers + # Shutdown our containers - name: Shutdown Docker containers run: | docker compose -f docker-compose.yml down diff --git a/.github/workflows/reusable-docker-build.yml b/.github/workflows/reusable-docker-build.yml index 7a8de661fa68..91aa93c54ab2 100644 --- a/.github/workflows/reusable-docker-build.yml +++ b/.github/workflows/reusable-docker-build.yml @@ -113,6 +113,12 @@ jobs: - name: Set up QEMU emulation to build for multiple architectures uses: docker/setup-qemu-action@v3 + #------------------------------------------------------------ + # Build & deploy steps for new commits to a branch (non-PRs) + # + # These steps build the images, push to DockerHub, and + # (if necessary) redeploy demo/sandbox sites. + #------------------------------------------------------------ # https://github.com/docker/login-action - name: Login to DockerHub # Only login if not a PR, as PRs only trigger a Docker build and not a push @@ -125,6 +131,7 @@ jobs: # https://github.com/docker/metadata-action # Get Metadata for docker_build_deps step below - name: Sync metadata (tags, labels) from GitHub to Docker for image + if: ${{ ! matrix.isPr }} id: meta_build uses: docker/metadata-action@v5 with: @@ -133,7 +140,9 @@ jobs: flavor: ${{ env.TAGS_FLAVOR }} # https://github.com/docker/build-push-action - - name: Build and push image + - name: Build and push image to DockerHub + # Only build & push if not a PR + if: ${{ ! matrix.isPr }} id: docker_build uses: docker/build-push-action@v5 with: @@ -142,9 +151,7 @@ jobs: context: ${{ inputs.dockerfile_context }} file: ${{ inputs.dockerfile_path }} platforms: ${{ matrix.arch }} - # For pull requests, we run the Docker build (to ensure no PR changes break the build), - # but we ONLY do an image push to DockerHub if it's NOT a PR - push: ${{ ! matrix.isPr }} + push: true # Use tags / labels provided by 'docker/metadata-action' above tags: ${{ steps.meta_build.outputs.tags }} labels: ${{ steps.meta_build.outputs.labels }} @@ -189,11 +196,54 @@ jobs: run: | curl -X POST $REDEPLOY_DEMO_URL + #------------------------------------------------------------- + # Build steps for PRs only + # + # These steps build the images and store as a build artifact. + # These artifacts can then be used by later jobs to run the + # brand-new images for automated testing. + #-------------------------------------------------------------- + # Get Metadata for docker_build_deps step below + - name: Create metadata (tags, labels) for local Docker image + if: matrix.isPr + id: meta_build_pr + uses: docker/metadata-action@v5 + with: + images: ${{ env.IMAGE_NAME }} + # Hardcode to use custom "pr-testing" tag because that will allow us to spin up this PR + # for testing in docker.yml + tags: pr-testing + flavor: ${{ env.TAGS_FLAVOR }} + # Build local image and stores in a TAR file in /tmp directory + - name: Build and push image to local image + if: matrix.isPr + uses: docker/build-push-action@v5 + with: + build-contexts: | + ${{ inputs.dockerfile_additional_contexts }} + context: ${{ inputs.dockerfile_context }} + file: ${{ inputs.dockerfile_path }} + platforms: ${{ matrix.arch }} + tags: ${{ steps.meta_build_pr.outputs.tags }} + labels: ${{ steps.meta_build_pr.outputs.labels }} + # Export image to a local TAR file + outputs: type=docker,dest=/tmp/${{ inputs.build_id }}.tar + # Upload the local docker image (in TAR file) to a build Artifact + - name: Upload local image to artifact + if: matrix.isPr + uses: actions/upload-artifact@v4 + with: + name: docker-image-${{ inputs.build_id }} + path: /tmp/${{ inputs.build_id }}.tar + if-no-files-found: error + retention-days: 1 + # Merge Docker digests (from various architectures) into a manifest. # This runs after all Docker builds complete above, and it tells hub.docker.com # that these builds should be all included in the manifest for this tag. # (e.g. AMD64 and ARM64 should be listed as options under the same tagged Docker image) docker-build_manifest: + # Only run if this is NOT a PR if: ${{ github.event_name != 'pull_request' }} runs-on: ubuntu-latest needs: From cf3da4585551862cf6c74ad1e7906a6a08c162c6 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Mon, 11 Nov 2024 16:45:59 -0600 Subject: [PATCH 076/226] Fix error in running Handle Server in GitHub Actions. Must exclude "spring-jcl" from dependencies as it conflicts with "commons-logging" (used by more of our dependencies) (cherry picked from commit 31312b800a6bed795d5ca31bf2dfb445fc709c4d) --- dspace-api/pom.xml | 7 +++++++ dspace-iiif/pom.xml | 5 +++++ dspace-oai/pom.xml | 5 +++++ dspace-rdf/pom.xml | 5 +++++ dspace-server-webapp/pom.xml | 5 +++++ dspace-services/pom.xml | 7 +++++++ dspace-sword/pom.xml | 5 +++++ dspace-swordv2/pom.xml | 5 +++++ pom.xml | 7 +++++++ 9 files changed, 51 insertions(+) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index dfb3f030ac0e..c51685fdb425 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -388,6 +388,13 @@ org.springframework spring-orm + + + + org.springframework + spring-jcl + + diff --git a/dspace-iiif/pom.xml b/dspace-iiif/pom.xml index cd2b69288d2e..030ac31b3843 100644 --- a/dspace-iiif/pom.xml +++ b/dspace-iiif/pom.xml @@ -44,6 +44,11 @@ org.springframework.boot spring-boot-starter-logging + + + org.springframework + spring-jcl + diff --git a/dspace-oai/pom.xml b/dspace-oai/pom.xml index 4158ec74f34d..29644392d540 100644 --- a/dspace-oai/pom.xml +++ b/dspace-oai/pom.xml @@ -80,6 +80,11 @@ org.springframework.boot spring-boot-starter-logging + + + org.springframework + spring-jcl + diff --git a/dspace-rdf/pom.xml b/dspace-rdf/pom.xml index d7db7fe76e8a..3d11794d86a2 100644 --- a/dspace-rdf/pom.xml +++ b/dspace-rdf/pom.xml @@ -67,6 +67,11 @@ org.springframework.boot spring-boot-starter-logging + + + org.springframework + spring-jcl + diff --git a/dspace-server-webapp/pom.xml b/dspace-server-webapp/pom.xml index 759ad724b9b6..290f8afb0dc6 100644 --- a/dspace-server-webapp/pom.xml +++ b/dspace-server-webapp/pom.xml @@ -468,6 +468,11 @@ org.springframework.boot spring-boot-starter-logging + + + org.springframework + spring-jcl + diff --git a/dspace-services/pom.xml b/dspace-services/pom.xml index d99132309100..6b2bf191acd5 100644 --- a/dspace-services/pom.xml +++ b/dspace-services/pom.xml @@ -90,6 +90,13 @@ spring-context-support ${spring.version} compile + + + + org.springframework + spring-jcl + + org.apache.commons diff --git a/dspace-sword/pom.xml b/dspace-sword/pom.xml index a808d0bbfeb9..ac84a674c455 100644 --- a/dspace-sword/pom.xml +++ b/dspace-sword/pom.xml @@ -55,6 +55,11 @@ org.springframework.boot spring-boot-starter-logging + + + org.springframework + spring-jcl + diff --git a/dspace-swordv2/pom.xml b/dspace-swordv2/pom.xml index c0549abcc88c..f22acf9dc9e0 100644 --- a/dspace-swordv2/pom.xml +++ b/dspace-swordv2/pom.xml @@ -78,6 +78,11 @@ org.springframework.boot spring-boot-starter-logging + + + org.springframework + spring-jcl + diff --git a/pom.xml b/pom.xml index 3eec65d4a9fd..5be05ca44e36 100644 --- a/pom.xml +++ b/pom.xml @@ -1155,6 +1155,13 @@ org.springframework spring-orm ${spring.version} + + + + org.springframework + spring-jcl + + org.swordapp From 48cb5e2082fb0e778c703e2b218a1ab361358af0 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 13 Nov 2024 09:17:30 -0600 Subject: [PATCH 077/226] Ensure "host" command is installed in images, so "bin/make-handle-config" will work. (cherry picked from commit a2172b37c3bb57a55e5a82ac2003ef20918c8984) --- Dockerfile | 5 +++++ Dockerfile.test | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/Dockerfile b/Dockerfile index 75817980379c..fdf2808c1c9a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -58,6 +58,11 @@ ENV DSPACE_INSTALL=/dspace # Copy the /dspace directory from 'ant_build' container to /dspace in this container COPY --from=ant_build /dspace $DSPACE_INSTALL WORKDIR $DSPACE_INSTALL +# Need host command for "[dspace]/bin/make-handle-config" +RUN apt-get update \ + && apt-get install -y --no-install-recommends host \ + && apt-get purge -y --auto-remove \ + && rm -rf /var/lib/apt/lists/* # Expose Tomcat port EXPOSE 8080 # Give java extra memory (2GB) diff --git a/Dockerfile.test b/Dockerfile.test index f3acef00e825..218126b17aab 100644 --- a/Dockerfile.test +++ b/Dockerfile.test @@ -57,6 +57,11 @@ ENV DSPACE_INSTALL=/dspace # Copy the /dspace directory from 'ant_build' container to /dspace in this container COPY --from=ant_build /dspace $DSPACE_INSTALL WORKDIR $DSPACE_INSTALL +# Need host command for "[dspace]/bin/make-handle-config" +RUN apt-get update \ + && apt-get install -y --no-install-recommends host \ + && apt-get purge -y --auto-remove \ + && rm -rf /var/lib/apt/lists/* # Expose Tomcat port and debugging port EXPOSE 8080 8000 # Give java extra memory (2GB) From 2253d79c1906149c2417d9f1b42fba243fc8c78b Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 13 Nov 2024 10:37:53 -0600 Subject: [PATCH 078/226] Bug fixes. Ensure all steps of docker-deploy use the same environment variables. Ensure Handle Server HTTP port is open (cherry picked from commit daa4abba62d500bb4a9f26dd9f62c156780ee22a) --- .github/workflows/docker.yml | 13 +++++++------ Dockerfile | 4 ++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index eed8de5a8722..5197ed3bfe39 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -158,6 +158,12 @@ jobs: runs-on: ubuntu-latest # Must run after all major images are built needs: [dspace, dspace-test, dspace-cli, dspace-postgres-pgcrypto, dspace-solr] + env: + # Override defaults dspace.server.url because backend starts at http://127.0.0.1:8080 + dspace__P__server__P__url: http://127.0.0.1:8080/server + # Force using "pr-testing" version of all Docker images. The "pr-testing" tag is a temporary tag that we + # assign to all PR-built docker images in reusabe-docker-build.yml + DSPACE_VER: pr-testing steps: # Checkout our codebase (to get access to Docker Compose scripts) - name: Checkout codebase @@ -180,12 +186,6 @@ jobs: docker image ls -a # Start backend using our compose script in the codebase. - name: Start backend in Docker - env: - # Override defaults dspace.server.url because backend starts at http://127.0.0.1:8080 - dspace__P__server__P__url: http://127.0.0.1:8080/server - # Force using "pr-testing" version of Docker images. The "pr-testing" tag is a temporary tag that we assign to - # all PR-built docker images in reusabe-docker-build.yml - DSPACE_VER: pr-testing run: | docker compose -f docker-compose.yml up -d sleep 10 @@ -214,6 +214,7 @@ jobs: - name: Verify Handle Server is working properly run: | docker exec -i dspace /dspace/bin/make-handle-config + echo "Starting Handle Server..." docker exec -i dspace /dspace/bin/start-handle-server sleep 20 echo "Checking for errors in handle-server.log..." diff --git a/Dockerfile b/Dockerfile index fdf2808c1c9a..d3f85a5bd641 100644 --- a/Dockerfile +++ b/Dockerfile @@ -63,8 +63,8 @@ RUN apt-get update \ && apt-get install -y --no-install-recommends host \ && apt-get purge -y --auto-remove \ && rm -rf /var/lib/apt/lists/* -# Expose Tomcat port -EXPOSE 8080 +# Expose Tomcat port (8080) & Handle Server HTTP port (8000) +EXPOSE 8080 8000 # Give java extra memory (2GB) ENV JAVA_OPTS=-Xmx2000m # On startup, run DSpace Runnable JAR From 663b871356c4835dc82161e9bd92ba30f79aa953 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 13 Nov 2024 11:45:03 -0600 Subject: [PATCH 079/226] Add check for Handle Server error.log (cherry picked from commit 53d24606431fcd3bd9a7c1a54298190842836e1c) --- .github/workflows/docker.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 5197ed3bfe39..1e839e89fceb 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -217,6 +217,10 @@ jobs: echo "Starting Handle Server..." docker exec -i dspace /dspace/bin/start-handle-server sleep 20 + echo "Checking for errors in error.log" + result=$(docker exec -i dspace sh -c "cat /dspace/handle-server/logs/error.log* || echo ''") + echo "$result" + echo "$result" | grep -vqz "Exception" echo "Checking for errors in handle-server.log..." result=$(docker exec -i dspace cat /dspace/log/handle-server.log) echo "$result" From c2e6f6f5d2843a5dd003a3f48ac63171a38a62f1 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 13 Nov 2024 14:27:28 -0600 Subject: [PATCH 080/226] Fix error in Handle Server startup caused by having multiple versions of BouncyCastle in our classpath. Exclude the old version brought in by cnri-servlet-container (cherry picked from commit 6076afec5f9a2bf53ace35abe384dc67dc5c1aef) --- dspace-api/pom.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index c51685fdb425..acac810d6cda 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -413,6 +413,16 @@ org.mortbay.jasper apache-jsp + + + org.bouncycastle + bcpkix-jdk15on + + + org.bouncycastle + bcprov-jdk15on + From 60004c32ab1d73a1d0e85d9b68973c1daf31d5b9 Mon Sep 17 00:00:00 2001 From: Agustina Martinez Date: Mon, 5 Aug 2024 11:06:06 +0200 Subject: [PATCH 081/226] Fix 9734: Check configured workflow.reviewer.file-edit to show item edit functionality in workflow UI (cherry picked from commit e8ec0c1b1d20dd5e812f38593a24718fff1d8c6e) --- .../processingaction/ScoreReviewAction.java | 15 ++++++++++++++- .../processingaction/SingleUserReviewAction.java | 8 ++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ScoreReviewAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ScoreReviewAction.java index a8ed4fd3dae9..50f338499282 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ScoreReviewAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/ScoreReviewAction.java @@ -8,6 +8,7 @@ package org.dspace.xmlworkflow.state.actions.processingaction; import java.sql.SQLException; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -20,6 +21,8 @@ import org.dspace.authorize.AuthorizeException; import org.dspace.content.MetadataFieldName; import org.dspace.core.Context; +import org.dspace.services.ConfigurationService; +import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.xmlworkflow.service.WorkflowRequirementsService; import org.dspace.xmlworkflow.state.Step; import org.dspace.xmlworkflow.state.actions.ActionAdvancedInfo; @@ -34,6 +37,9 @@ public class ScoreReviewAction extends ProcessingAction { private static final Logger log = LogManager.getLogger(ScoreReviewAction.class); + private final ConfigurationService configurationService + = DSpaceServicesFactory.getInstance().getConfigurationService(); + // Option(s) public static final String SUBMIT_SCORE = "submit_score"; @@ -114,7 +120,14 @@ private boolean checkRequestValid(int score, String review) { @Override public List getOptions() { - return List.of(SUBMIT_SCORE, RETURN_TO_POOL); + List options = new ArrayList<>(); + options.add(SUBMIT_SCORE); + if (configurationService.getBooleanProperty("workflow.reviewer.file-edit", false)) { + options.add(SUBMIT_EDIT_METADATA); + } + options.add(RETURN_TO_POOL); + + return options; } @Override diff --git a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/SingleUserReviewAction.java b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/SingleUserReviewAction.java index 64e0957b65b7..c46fa851e4f1 100644 --- a/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/SingleUserReviewAction.java +++ b/dspace-api/src/main/java/org/dspace/xmlworkflow/state/actions/processingaction/SingleUserReviewAction.java @@ -21,6 +21,8 @@ import org.dspace.content.factory.ContentServiceFactory; import org.dspace.core.Context; import org.dspace.eperson.EPerson; +import org.dspace.services.ConfigurationService; +import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.workflow.WorkflowException; import org.dspace.xmlworkflow.factory.XmlWorkflowServiceFactory; import org.dspace.xmlworkflow.state.Step; @@ -40,6 +42,9 @@ public class SingleUserReviewAction extends ProcessingAction { private static final Logger log = LogManager.getLogger(SingleUserReviewAction.class); + private final ConfigurationService configurationService + = DSpaceServicesFactory.getInstance().getConfigurationService(); + public static final int OUTCOME_REJECT = 1; protected static final String SUBMIT_DECLINE_TASK = "submit_decline_task"; @@ -95,6 +100,9 @@ public ActionResult processAccept(Context c, XmlWorkflowItem wfi) throws SQLExce public List getOptions() { List options = new ArrayList<>(); options.add(SUBMIT_APPROVE); + if (configurationService.getBooleanProperty("workflow.reviewer.file-edit", false)) { + options.add(SUBMIT_EDIT_METADATA); + } options.add(SUBMIT_REJECT); options.add(SUBMIT_DECLINE_TASK); return options; From b76d152444f464e26ec6c99b86d59c7e46a540e2 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Thu, 14 Nov 2024 14:46:31 -0600 Subject: [PATCH 082/226] Remove unnecessary dependencyManagement section from dspace-api. No longer needed for dependency convergence --- dspace-api/pom.xml | 73 ++-------------------------------------------- 1 file changed, 2 insertions(+), 71 deletions(-) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index acac810d6cda..c953abf0702b 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -793,11 +793,13 @@ org.apache.velocity velocity-engine-core + 2.3 org.xmlunit xmlunit-core + 2.10.0 test @@ -873,75 +875,4 @@ - - - - - - - io.netty - netty-buffer - 4.1.106.Final - - - io.netty - netty-transport - 4.1.106.Final - - - io.netty - netty-transport-native-unix-common - 4.1.106.Final - - - io.netty - netty-common - 4.1.106.Final - - - io.netty - netty-handler - 4.1.106.Final - - - io.netty - netty-codec - 4.1.106.Final - - - org.apache.velocity - velocity-engine-core - 2.3 - - - org.xmlunit - xmlunit-core - 2.10.0 - test - - - com.github.java-json-tools - json-schema-validator - 2.2.14 - - - jakarta.validation - jakarta.validation-api - 3.0.2 - - - io.swagger - swagger-core - 1.6.2 - - - org.scala-lang - scala-library - 2.13.11 - test - - - - From b4f19158b072edcd70ac25163562619ecec7856e Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Thu, 14 Nov 2024 14:58:49 -0600 Subject: [PATCH 083/226] Fix multiple declarations of maven-dependency-plugin. Combine two tasks into one declaration --- dspace/modules/server/pom.xml | 36 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/dspace/modules/server/pom.xml b/dspace/modules/server/pom.xml index ca4eea26a07c..c1ce045fe896 100644 --- a/dspace/modules/server/pom.xml +++ b/dspace/modules/server/pom.xml @@ -27,7 +27,7 @@ maven-dependency-plugin - unpack + unpack-additions prepare-package unpack-dependencies @@ -42,6 +42,20 @@ META-INF/** + + unpack-server + prepare-package + + unpack-dependencies + + + runtime + org.dspace + dspace-server-webapp + **/static/**,**/*.properties + ${project.build.directory}/additions + + @@ -68,26 +82,6 @@ - - org.apache.maven.plugins - maven-dependency-plugin - - - unpack - prepare-package - - unpack-dependencies - - - runtime - org.dspace - dspace-server-webapp - **/static/**,**/*.properties - ${project.build.directory}/additions - - - - diff --git a/pom.xml b/pom.xml index 5be05ca44e36..63985484215c 100644 --- a/pom.xml +++ b/pom.xml @@ -1746,36 +1746,6 @@ google-api-services-analytics v3-rev145-1.23.0 - - com.google.api-client - google-api-client - 1.23.0 - - - com.google.http-client - google-http-client - 1.23.0 - - - com.google.http-client - google-http-client-jackson2 - 1.23.0 - - - jackson-core - com.fasterxml.jackson.core - - - jackson-databind - com.fasterxml.jackson.core - - - - - com.google.oauth-client - google-oauth-client - 1.33.3 - From 8c9cdc6c9c0c03df1d4a9342552fe42553cba639 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 15 Nov 2024 16:06:10 -0600 Subject: [PATCH 087/226] Ensure only main branch uses "latest". Other branches should use the tag corresponding to the branch name (cherry picked from commit e0b7241acb167496ebc8c80c73ae69b9f6611a1c) --- .github/workflows/docker.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index a0aee14bea38..143b69a2f9fe 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -161,10 +161,10 @@ jobs: env: # Override defaults dspace.server.url because backend starts at http://127.0.0.1:8080 dspace__P__server__P__url: http://127.0.0.1:8080/server - # If this is a PR, force using "pr-testing" version of all Docker images. Otherwise, for branch commits, use the - # "latest" tag. NOTE: the "pr-testing" tag is a temporary tag that we assign to all PR-built docker images in - # reusabe-docker-build.yml - DSPACE_VER: ${{ github.event_name == 'pull_request' && 'pr-testing' || 'latest' }} + # If this is a PR, force using "pr-testing" version of all Docker images. Otherwise, if on main branch, use the + # "latest" tag. Otherwise, use the branch name. NOTE: the "pr-testing" tag is a temporary tag that we assign to + # all PR-built docker images in reusabe-docker-build.yml + DSPACE_VER: ${{ (github.event_name == 'pull_request' && 'pr-testing') || (github.ref_name == github.event.repository.default_branch && 'latest') || github.ref_name }} steps: # Checkout our codebase (to get access to Docker Compose scripts) - name: Checkout codebase From 56029149c1b7a366ea73269c1f55760b5251cd0e Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 15 Nov 2024 11:30:14 -0600 Subject: [PATCH 088/226] Remove parboiled-java and minor cleanup of unused OAI dependencies --- dspace-oai/pom.xml | 23 +------------------ .../xoai/app/CCElementItemCompilePlugin.java | 2 +- .../main/java/org/dspace/xoai/app/XOAI.java | 2 +- .../tests/integration/xoai/PipelineTest.java | 9 ++++---- 4 files changed, 8 insertions(+), 28 deletions(-) diff --git a/dspace-oai/pom.xml b/dspace-oai/pom.xml index 29644392d540..35f12b02a5ce 100644 --- a/dspace-oai/pom.xml +++ b/dspace-oai/pom.xml @@ -99,22 +99,9 @@ org.springframework.boot spring-boot-starter-web - - - org.parboiled - parboiled-java - - - - org.parboiled - parboiled-java - 1.3.1 - - org.dspace @@ -137,15 +124,7 @@ org.apache.logging.log4j log4j-core - - org.apache.logging.log4j - log4j-web - - - org.apache.logging.log4j - log4j-slf4j-impl - runtime - + org.apache.logging.log4j log4j-1.2-api diff --git a/dspace-oai/src/main/java/org/dspace/xoai/app/CCElementItemCompilePlugin.java b/dspace-oai/src/main/java/org/dspace/xoai/app/CCElementItemCompilePlugin.java index 225d56a4c982..370543029d8b 100644 --- a/dspace-oai/src/main/java/org/dspace/xoai/app/CCElementItemCompilePlugin.java +++ b/dspace-oai/src/main/java/org/dspace/xoai/app/CCElementItemCompilePlugin.java @@ -11,7 +11,7 @@ import com.lyncode.xoai.dataprovider.xml.xoai.Element; import com.lyncode.xoai.dataprovider.xml.xoai.Metadata; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.dspace.content.Item; import org.dspace.core.Context; import org.dspace.license.factory.LicenseServiceFactory; diff --git a/dspace-oai/src/main/java/org/dspace/xoai/app/XOAI.java b/dspace-oai/src/main/java/org/dspace/xoai/app/XOAI.java index 25cc1ee3655f..ad138ca9f2ad 100644 --- a/dspace-oai/src/main/java/org/dspace/xoai/app/XOAI.java +++ b/dspace-oai/src/main/java/org/dspace/xoai/app/XOAI.java @@ -9,7 +9,7 @@ import static com.lyncode.xoai.dataprovider.core.Granularity.Second; import static java.util.Objects.nonNull; -import static org.apache.commons.lang.StringUtils.EMPTY; +import static org.apache.commons.lang3.StringUtils.EMPTY; import static org.apache.solr.common.params.CursorMarkParams.CURSOR_MARK_PARAM; import static org.apache.solr.common.params.CursorMarkParams.CURSOR_MARK_START; import static org.dspace.xoai.util.ItemUtils.retrieveMetadata; diff --git a/dspace-oai/src/test/java/org/dspace/xoai/tests/integration/xoai/PipelineTest.java b/dspace-oai/src/test/java/org/dspace/xoai/tests/integration/xoai/PipelineTest.java index 0f48824159c2..0f7ffde0bd00 100644 --- a/dspace-oai/src/test/java/org/dspace/xoai/tests/integration/xoai/PipelineTest.java +++ b/dspace-oai/src/test/java/org/dspace/xoai/tests/integration/xoai/PipelineTest.java @@ -13,13 +13,14 @@ import static org.hamcrest.MatcherAssert.assertThat; import java.io.InputStream; +import java.nio.charset.Charset; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamSource; import com.lyncode.xoai.util.XSLPipeline; +import org.apache.commons.io.IOUtils; import org.dspace.xoai.tests.support.XmlMatcherBuilder; import org.junit.Test; -import org.parboiled.common.FileUtils; public class PipelineTest { private static TransformerFactory factory = TransformerFactory.newInstance(); @@ -28,9 +29,9 @@ public class PipelineTest { public void pipelineTest() throws Exception { InputStream input = PipelineTest.class.getClassLoader().getResourceAsStream("item.xml"); InputStream xslt = PipelineTest.class.getClassLoader().getResourceAsStream("oai_dc.xsl"); - String output = FileUtils.readAllText(new XSLPipeline(input, true) - .apply(factory.newTemplates(new StreamSource(xslt))) - .getTransformed()); + String output = IOUtils.toString(new XSLPipeline(input, true) + .apply(factory.newTemplates(new StreamSource(xslt))) + .getTransformed(), Charset.defaultCharset()); assertThat(output, oai_dc().withXPath("/oai_dc:dc/dc:title", equalTo("Teste"))); From e53905131049c3a231274ab4cb6732e168609353 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 15 Nov 2024 11:31:28 -0600 Subject: [PATCH 089/226] Fix OAI using incorrect Java Injection API. --- dspace-api/pom.xml | 1 - dspace-oai/pom.xml | 5 ++--- pom.xml | 6 ++++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index acac810d6cda..845692686f30 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -719,7 +719,6 @@ jakarta.inject jakarta.inject-api - 2.0.1 diff --git a/dspace-oai/pom.xml b/dspace-oai/pom.xml index 35f12b02a5ce..72c243f55c21 100644 --- a/dspace-oai/pom.xml +++ b/dspace-oai/pom.xml @@ -65,9 +65,8 @@ - javax.inject - javax.inject - 1 + jakarta.inject + jakarta.inject-api diff --git a/pom.xml b/pom.xml index 5be05ca44e36..7bad6fbc2b9d 100644 --- a/pom.xml +++ b/pom.xml @@ -1553,6 +1553,12 @@ jakarta.activation-api 2.1.3 + + + jakarta.inject + jakarta.inject-api + 2.0.1 + jakarta.mail From f248b6395d12e55d4cc68ee1fb4db7b934fe8b42 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 15 Nov 2024 12:02:20 -0600 Subject: [PATCH 090/226] Log4j cleanup. Remove last traces of log4j v1 (and remove log4j1 bridge to avoid them coming back). Create log4j2 settings for Handle Plugin. --- .../app/bulkedit/MetadataExportSearchIT.java | 5 +- .../dspace/builder/OrcidHistoryBuilder.java | 5 +- dspace-oai/pom.xml | 5 -- .../xoai/filter/ItemsWithBitstreamFilter.java | 4 +- dspace-rdf/pom.xml | 4 -- .../rest/converter/SearchEventConverter.java | 5 +- .../bitstream/BitstreamLinksetProcessor.java | 5 +- .../BitstreamParentItemProcessor.java | 5 +- .../bitstream/BitstreamTypeProcessor.java | 5 +- .../processor/item/ItemAuthorProcessor.java | 5 +- .../item/ItemContentBitstreamsProcessor.java | 5 +- .../item/ItemDescribedbyProcessor.java | 5 +- .../processor/item/ItemLicenseProcessor.java | 5 +- .../processor/item/ItemLinksetProcessor.java | 5 +- .../processor/item/ItemTypeProcessor.java | 5 +- .../service/impl/LinksetServiceImpl.java | 5 +- dspace-sword/pom.xml | 4 -- dspace-swordv2/pom.xml | 4 -- dspace/bin/start-handle-server | 2 +- dspace/bin/start-handle-server.bat | 2 +- dspace/config/log4j-handle-plugin.properties | 34 ------------- dspace/config/log4j2-handle-plugin.xml | 48 +++++++++++++++++++ pom.xml | 25 ---------- 23 files changed, 91 insertions(+), 106 deletions(-) delete mode 100644 dspace/config/log4j-handle-plugin.properties create mode 100644 dspace/config/log4j2-handle-plugin.xml diff --git a/dspace-api/src/test/java/org/dspace/app/bulkedit/MetadataExportSearchIT.java b/dspace-api/src/test/java/org/dspace/app/bulkedit/MetadataExportSearchIT.java index 3a972692efeb..63a87a48f554 100644 --- a/dspace-api/src/test/java/org/dspace/app/bulkedit/MetadataExportSearchIT.java +++ b/dspace-api/src/test/java/org/dspace/app/bulkedit/MetadataExportSearchIT.java @@ -23,7 +23,8 @@ import com.google.common.io.Files; import com.opencsv.CSVReader; import com.opencsv.exceptions.CsvException; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.AbstractIntegrationTestWithDatabase; import org.dspace.app.launcher.ScriptLauncher; import org.dspace.app.scripts.handler.impl.TestDSpaceRunnableHandler; @@ -51,7 +52,7 @@ public class MetadataExportSearchIT extends AbstractIntegrationTestWithDatabase private Item[] itemsSubject2 = new Item[numberItemsSubject2]; private String filename; private Collection collection; - private Logger logger = Logger.getLogger(MetadataExportSearchIT.class); + private Logger logger = LogManager.getLogger(MetadataExportSearchIT.class); private ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService(); private SearchService searchService; diff --git a/dspace-api/src/test/java/org/dspace/builder/OrcidHistoryBuilder.java b/dspace-api/src/test/java/org/dspace/builder/OrcidHistoryBuilder.java index 199f412f8506..d811d03f5358 100644 --- a/dspace-api/src/test/java/org/dspace/builder/OrcidHistoryBuilder.java +++ b/dspace-api/src/test/java/org/dspace/builder/OrcidHistoryBuilder.java @@ -11,7 +11,8 @@ import java.sql.SQLException; import java.util.Date; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.content.Item; import org.dspace.core.Context; import org.dspace.orcid.OrcidHistory; @@ -24,7 +25,7 @@ */ public class OrcidHistoryBuilder extends AbstractBuilder { - private static final Logger log = Logger.getLogger(OrcidHistoryBuilder.class); + private static final Logger log = LogManager.getLogger(OrcidHistoryBuilder.class); private OrcidHistory orcidHistory; diff --git a/dspace-oai/pom.xml b/dspace-oai/pom.xml index 72c243f55c21..f6b220baed3d 100644 --- a/dspace-oai/pom.xml +++ b/dspace-oai/pom.xml @@ -123,11 +123,6 @@ org.apache.logging.log4j log4j-core - - - org.apache.logging.log4j - log4j-1.2-api - diff --git a/dspace-oai/src/main/java/org/dspace/xoai/filter/ItemsWithBitstreamFilter.java b/dspace-oai/src/main/java/org/dspace/xoai/filter/ItemsWithBitstreamFilter.java index 3599c5b9e168..9bf1c65dc9d9 100644 --- a/dspace-oai/src/main/java/org/dspace/xoai/filter/ItemsWithBitstreamFilter.java +++ b/dspace-oai/src/main/java/org/dspace/xoai/filter/ItemsWithBitstreamFilter.java @@ -9,8 +9,8 @@ import java.sql.SQLException; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.content.Bundle; import org.dspace.content.Item; import org.dspace.handle.factory.HandleServiceFactory; diff --git a/dspace-rdf/pom.xml b/dspace-rdf/pom.xml index 3d11794d86a2..3b3cb17119a1 100644 --- a/dspace-rdf/pom.xml +++ b/dspace-rdf/pom.xml @@ -89,10 +89,6 @@ org.apache.logging.log4j log4j-core - - org.apache.logging.log4j - log4j-web - org.apache.commons diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SearchEventConverter.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SearchEventConverter.java index e9786962e0f5..d781d255df11 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SearchEventConverter.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/converter/SearchEventConverter.java @@ -13,7 +13,8 @@ import java.util.List; import jakarta.servlet.http.HttpServletRequest; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.app.rest.model.PageRest; import org.dspace.app.rest.model.SearchEventRest; import org.dspace.app.rest.model.SearchResultsRest; @@ -31,7 +32,7 @@ @Component public class SearchEventConverter { /* Log4j logger */ - private static final Logger log = Logger.getLogger(SearchEventConverter.class); + private static final Logger log = LogManager.getLogger(SearchEventConverter.class); @Autowired private ScopeResolver scopeResolver; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/bitstream/BitstreamLinksetProcessor.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/bitstream/BitstreamLinksetProcessor.java index 97eb9f2a546d..349dde7b6dac 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/bitstream/BitstreamLinksetProcessor.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/bitstream/BitstreamLinksetProcessor.java @@ -10,7 +10,8 @@ import java.util.List; import jakarta.servlet.http.HttpServletRequest; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.app.rest.signposting.model.LinksetNode; import org.dspace.app.rest.signposting.model.LinksetRelationType; import org.dspace.content.Bitstream; @@ -25,7 +26,7 @@ */ public class BitstreamLinksetProcessor extends BitstreamSignpostingProcessor { - private static final Logger log = Logger.getLogger(BitstreamLinksetProcessor.class); + private static final Logger log = LogManager.getLogger(BitstreamLinksetProcessor.class); private final BitstreamService bitstreamService; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/bitstream/BitstreamParentItemProcessor.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/bitstream/BitstreamParentItemProcessor.java index 32928dfa8892..c855f06784f7 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/bitstream/BitstreamParentItemProcessor.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/bitstream/BitstreamParentItemProcessor.java @@ -10,7 +10,8 @@ import java.util.List; import jakarta.servlet.http.HttpServletRequest; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.app.rest.signposting.model.LinksetNode; import org.dspace.app.rest.signposting.model.LinksetRelationType; import org.dspace.content.Bitstream; @@ -28,7 +29,7 @@ */ public class BitstreamParentItemProcessor extends BitstreamSignpostingProcessor { - private static final Logger log = Logger.getLogger(BitstreamParentItemProcessor.class); + private static final Logger log = LogManager.getLogger(BitstreamParentItemProcessor.class); private final BitstreamService bitstreamService; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/bitstream/BitstreamTypeProcessor.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/bitstream/BitstreamTypeProcessor.java index 8889a415d327..d0f170b4c55a 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/bitstream/BitstreamTypeProcessor.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/bitstream/BitstreamTypeProcessor.java @@ -11,7 +11,8 @@ import jakarta.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.app.rest.signposting.model.LinksetNode; import org.dspace.app.rest.signposting.model.LinksetRelationType; import org.dspace.content.Bitstream; @@ -28,7 +29,7 @@ */ public class BitstreamTypeProcessor extends BitstreamSignpostingProcessor { - private static final Logger log = Logger.getLogger(BitstreamTypeProcessor.class); + private static final Logger log = LogManager.getLogger(BitstreamTypeProcessor.class); @Autowired private SimpleMapConverter mapConverterDSpaceToSchemaOrgUri; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemAuthorProcessor.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemAuthorProcessor.java index f3a9e35198a7..ebc7c46f4d23 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemAuthorProcessor.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemAuthorProcessor.java @@ -16,7 +16,8 @@ import java.util.List; import jakarta.servlet.http.HttpServletRequest; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.app.rest.signposting.model.LinksetNode; import org.dspace.app.rest.signposting.model.LinksetRelationType; import org.dspace.content.Item; @@ -37,7 +38,7 @@ public class ItemAuthorProcessor extends ItemSignpostingProcessor { /** * log4j category */ - private static final Logger log = Logger.getLogger(ItemAuthorProcessor.class); + private static final Logger log = LogManager.getLogger(ItemAuthorProcessor.class); private final ItemService itemService; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemContentBitstreamsProcessor.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemContentBitstreamsProcessor.java index 0b91e57f7b3f..65a29c2b6c98 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemContentBitstreamsProcessor.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemContentBitstreamsProcessor.java @@ -11,7 +11,8 @@ import java.util.List; import jakarta.servlet.http.HttpServletRequest; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.app.rest.signposting.model.LinksetNode; import org.dspace.app.rest.signposting.model.LinksetRelationType; import org.dspace.content.Bitstream; @@ -33,7 +34,7 @@ public class ItemContentBitstreamsProcessor extends ItemSignpostingProcessor { /** * log4j category */ - private static final Logger log = Logger.getLogger(ItemContentBitstreamsProcessor.class); + private static final Logger log = LogManager.getLogger(ItemContentBitstreamsProcessor.class); public ItemContentBitstreamsProcessor(FrontendUrlService frontendUrlService) { super(frontendUrlService); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemDescribedbyProcessor.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemDescribedbyProcessor.java index 20091e6d0992..a86b98f2e5d0 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemDescribedbyProcessor.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemDescribedbyProcessor.java @@ -10,7 +10,8 @@ import java.util.List; import jakarta.servlet.http.HttpServletRequest; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.app.rest.signposting.model.LinksetNode; import org.dspace.app.rest.signposting.model.LinksetRelationType; import org.dspace.content.Item; @@ -23,7 +24,7 @@ */ public class ItemDescribedbyProcessor extends ItemSignpostingProcessor { - private static final Logger log = Logger.getLogger(ItemDescribedbyProcessor.class); + private static final Logger log = LogManager.getLogger(ItemDescribedbyProcessor.class); private final ConfigurationService configurationService; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemLicenseProcessor.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemLicenseProcessor.java index b60ee35d7fe4..6e26d8f1b225 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemLicenseProcessor.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemLicenseProcessor.java @@ -11,7 +11,8 @@ import jakarta.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.app.rest.signposting.model.LinksetNode; import org.dspace.app.rest.signposting.model.LinksetRelationType; import org.dspace.content.Item; @@ -25,7 +26,7 @@ */ public class ItemLicenseProcessor extends ItemSignpostingProcessor { - private static final Logger log = Logger.getLogger(ItemLicenseProcessor.class); + private static final Logger log = LogManager.getLogger(ItemLicenseProcessor.class); private final CreativeCommonsService creativeCommonsService = LicenseServiceFactory.getInstance().getCreativeCommonsService(); diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemLinksetProcessor.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemLinksetProcessor.java index 2d09e5616171..4e48caf9594f 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemLinksetProcessor.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemLinksetProcessor.java @@ -10,7 +10,8 @@ import java.util.List; import jakarta.servlet.http.HttpServletRequest; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.app.rest.signposting.model.LinksetNode; import org.dspace.app.rest.signposting.model.LinksetRelationType; import org.dspace.content.Item; @@ -23,7 +24,7 @@ */ public class ItemLinksetProcessor extends ItemSignpostingProcessor { - private static final Logger log = Logger.getLogger(ItemLinksetProcessor.class); + private static final Logger log = LogManager.getLogger(ItemLinksetProcessor.class); private final ConfigurationService configurationService; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemTypeProcessor.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemTypeProcessor.java index 49b3612cd92c..f2533a5a9564 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemTypeProcessor.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/processor/item/ItemTypeProcessor.java @@ -11,7 +11,8 @@ import jakarta.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.app.rest.signposting.model.LinksetNode; import org.dspace.app.rest.signposting.model.LinksetRelationType; import org.dspace.content.Item; @@ -27,7 +28,7 @@ */ public class ItemTypeProcessor extends ItemSignpostingProcessor { - private static final Logger log = Logger.getLogger(ItemTypeProcessor.class); + private static final Logger log = LogManager.getLogger(ItemTypeProcessor.class); private static final String ABOUT_PAGE_URI = "https://schema.org/AboutPage"; @Autowired diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/service/impl/LinksetServiceImpl.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/service/impl/LinksetServiceImpl.java index 5b28817c9438..42b1c8184957 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/service/impl/LinksetServiceImpl.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/signposting/service/impl/LinksetServiceImpl.java @@ -13,7 +13,8 @@ import java.util.List; import jakarta.servlet.http.HttpServletRequest; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.dspace.app.rest.security.BitstreamMetadataReadPermissionEvaluatorPlugin; import org.dspace.app.rest.signposting.model.LinksetNode; import org.dspace.app.rest.signposting.processor.bitstream.BitstreamSignpostingProcessor; @@ -37,7 +38,7 @@ @Service public class LinksetServiceImpl implements LinksetService { - private static final Logger log = Logger.getLogger(LinksetServiceImpl.class); + private static final Logger log = LogManager.getLogger(LinksetServiceImpl.class); @Autowired protected ItemService itemService; diff --git a/dspace-sword/pom.xml b/dspace-sword/pom.xml index ac84a674c455..283e61c86afc 100644 --- a/dspace-sword/pom.xml +++ b/dspace-sword/pom.xml @@ -91,10 +91,6 @@ org.apache.logging.log4j log4j-core - - org.apache.logging.log4j - log4j-web - xom diff --git a/dspace-swordv2/pom.xml b/dspace-swordv2/pom.xml index f22acf9dc9e0..af516d566036 100644 --- a/dspace-swordv2/pom.xml +++ b/dspace-swordv2/pom.xml @@ -95,10 +95,6 @@ org.apache.logging.log4j log4j-core - - org.apache.logging.log4j - log4j-web - diff --git a/dspace/bin/start-handle-server b/dspace/bin/start-handle-server index 6d5c9a4b4406..b2af9cf759b8 100755 --- a/dspace/bin/start-handle-server +++ b/dspace/bin/start-handle-server @@ -36,6 +36,6 @@ rm -f $HANDLEDIR/txns/lock # does not support more than one JVM writing to the same rolling log. nohup java $JAVA_OPTS -classpath `$BINDIR/dspace classpath` \ -Ddspace.log.init.disable=true \ - -Dlog4j.configuration=log4j-handle-plugin.properties \ + -Dlog4j2.configurationFile=log4j2-handle-plugin.xml \ net.handle.server.Main $HANDLEDIR \ > $LOGDIR/handle-server.log 2>&1 & diff --git a/dspace/bin/start-handle-server.bat b/dspace/bin/start-handle-server.bat index caf6ff3eef12..8280e2b442f1 100644 --- a/dspace/bin/start-handle-server.bat +++ b/dspace/bin/start-handle-server.bat @@ -51,7 +51,7 @@ echo. echo NOTE: If you want to run the Handle Server as a backend process, re-execute this script echo using the Windows "start" command. For example, "start /B start-handle-server.bat" echo. -java %JAVA_OPTS% -cp "%DSPACE_CLASSPATH%" -Ddspace.log.init.disable=true -Dlog4j.configuration=log4j-handle-plugin.properties net.handle.server.Main %HANDLEDIR% >> "%LOGDIR%/handle-server.log" +java %JAVA_OPTS% -cp "%DSPACE_CLASSPATH%" -Ddspace.log.init.disable=true -Dlog4j2.configurationFile=log4j2-handle-plugin.xml net.handle.server.Main %HANDLEDIR% >> "%LOGDIR%/handle-server.log" REM Clean up DSPACE_CLASSPATH variable set DSPACE_CLASSPATH= diff --git a/dspace/config/log4j-handle-plugin.properties b/dspace/config/log4j-handle-plugin.properties deleted file mode 100644 index 44d39fb1bdf0..000000000000 --- a/dspace/config/log4j-handle-plugin.properties +++ /dev/null @@ -1,34 +0,0 @@ -########################################################################### -# log4j-handle-plugin.properties -# -# This is the log4j configuration file for the embedded DSpace Handle server, -# writing daily rolling logs. We cannot simply write to the same logs, since -# log4j does not support more than one JVM writing to the same rolling log. -########################################################################### - -# VARIABLES: -# The following variables can be used to easily tweak the default log4j settings. -# These variables are used by the log4j config / appenders later in this file. - -# log.dir -# Default log file directory for DSpace. Defaults to the 'log' subdirectory -# under [dspace.dir]. NOTE: The value of 'dspace.dir' will be replaced by -# its value in your configuration when DSpace is deployed (via Ant). -log.dir=${dspace.dir}/log - -# Set root category priority to INFO and its only appender to A1. -log4j.rootCategory=INFO, A1 - -# A1 is set to be a DailyRollingFileAppender. -log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender -log4j.appender.A1.File=${log.dir}/handle-plugin.log -log4j.appender.A1.DatePattern='.'yyyy-MM-dd - -# A1 uses PatternLayout. -log4j.appender.A1.layout=org.apache.log4j.PatternLayout -log4j.appender.A1.layout.ConversionPattern=%d %-5p %c @ %m%n - - -# block passwords from being exposed in Axis logs. -# (DEBUG exposes passwords in Basic Auth) -log4j.logger.org.apache.axis.handlers.http.HTTPAuthHandler=INFO \ No newline at end of file diff --git a/dspace/config/log4j2-handle-plugin.xml b/dspace/config/log4j2-handle-plugin.xml new file mode 100644 index 000000000000..5f72e05c7303 --- /dev/null +++ b/dspace/config/log4j2-handle-plugin.xml @@ -0,0 +1,48 @@ + + + + + + + ${log4j:configParentLocation}/../log + + + + + + + + + yyyy-MM-dd + + + + + + + + + + + + + + diff --git a/pom.xml b/pom.xml index 7bad6fbc2b9d..d84c4d50f28f 100644 --- a/pom.xml +++ b/pom.xml @@ -1600,36 +1600,11 @@ log4j-api ${log4j.version} - - org.apache.logging.log4j - log4j-1.2-api - ${log4j.version} - org.apache.logging.log4j log4j-core ${log4j.version} - - org.apache.logging.log4j - log4j-web - ${log4j.version} - - - org.apache.logging.log4j - log4j-slf4j-impl - ${log4j.version} - - - org.apache.logging.log4j - log4j-jul - ${log4j.version} - - - org.slf4j - jul-to-slf4j - ${slf4j.version} - org.apache.pdfbox From 29eefe70b4e5de9da8808ed09bb3cb4c96ffb856 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 20 Nov 2024 12:45:05 -0600 Subject: [PATCH 091/226] Remove unused dependencies from several modules (cherry picked from commit e27ceb57c1324b7b15931d1ed48414c0316c1d2d) --- dspace-services/pom.xml | 23 ----------------------- dspace-sword/pom.xml | 18 ------------------ dspace/modules/server-boot/pom.xml | 4 ---- dspace/modules/server/pom.xml | 5 ----- pom.xml | 14 +------------- 5 files changed, 1 insertion(+), 63 deletions(-) diff --git a/dspace-services/pom.xml b/dspace-services/pom.xml index 6b2bf191acd5..05b490df7610 100644 --- a/dspace-services/pom.xml +++ b/dspace-services/pom.xml @@ -128,23 +128,6 @@ junit provided - - - org.mortbay.jetty - jetty - 6.1.26 - test - - - org.mortbay.jetty - jetty-servlet-tester - 6.1.26 - test - - - org.apache.commons - commons-collections4 - org.apache.commons commons-configuration2 @@ -164,11 +147,5 @@ jakarta.annotation-api - - org.springframework.boot - spring-boot-starter-log4j2 - ${spring-boot.version} - - diff --git a/dspace-sword/pom.xml b/dspace-sword/pom.xml index 283e61c86afc..ac629cb504e5 100644 --- a/dspace-sword/pom.xml +++ b/dspace-sword/pom.xml @@ -25,15 +25,6 @@ - - - - org.dspace dspace-api @@ -63,11 +54,6 @@ - - jaxen - jaxen - - org.apache.httpcomponents httpclient @@ -97,10 +83,6 @@ xom 1.3.9 - - commons-io - commons-io - diff --git a/dspace/modules/server-boot/pom.xml b/dspace/modules/server-boot/pom.xml index f156fbeadb06..87bb2d634e69 100644 --- a/dspace/modules/server-boot/pom.xml +++ b/dspace/modules/server-boot/pom.xml @@ -30,10 +30,6 @@ org.dspace dspace-server-webapp - - org.apache.solr - solr-solrj - diff --git a/dspace/modules/server/pom.xml b/dspace/modules/server/pom.xml index c1ce045fe896..f235fcc0279d 100644 --- a/dspace/modules/server/pom.xml +++ b/dspace/modules/server/pom.xml @@ -271,11 +271,6 @@ provided ${spring-boot.version} - - org.apache.solr - solr-solrj - ${solr.client.version} - diff --git a/pom.xml b/pom.xml index d0e720ea3808..f7923b97dedb 100644 --- a/pom.xml +++ b/pom.xml @@ -1163,11 +1163,7 @@ - - org.swordapp - sword-common - 1.1 - + spring-core @@ -1476,14 +1472,6 @@ commons-collections4 4.4 - - - commons-collections - commons-collections - 3.2.2 - org.apache.commons commons-configuration2 From 3ec8862af8888f226c56d177627fa7ac5281bf1c Mon Sep 17 00:00:00 2001 From: Drew Heles Date: Thu, 21 Nov 2024 13:05:19 -0500 Subject: [PATCH 092/226] Update docker files for the 8_x branch --- Dockerfile | 4 ++-- Dockerfile.cli | 4 ++-- Dockerfile.test | 4 ++-- docker-compose-cli.yml | 2 +- docker-compose.yml | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index d3f85a5bd641..fb9f8ac512c6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,12 @@ # This image will be published as dspace/dspace # See https://github.com/DSpace/DSpace/tree/main/dspace/src/main/docker for usage details # -# - note: default tag for branch: dspace/dspace: dspace/dspace:latest +# - note: default tag for branch: dspace/dspace: dspace/dspace:dspace-8_x # This Dockerfile uses JDK17 by default. # To build with other versions, use "--build-arg JDK_VERSION=[value]" ARG JDK_VERSION=17 -ARG DSPACE_VERSION=latest +ARG DSPACE_VERSION=dspace-8_x # Step 1 - Run Maven Build FROM dspace/dspace-dependencies:${DSPACE_VERSION} AS build diff --git a/Dockerfile.cli b/Dockerfile.cli index 5254d1eb4d69..7de72511e849 100644 --- a/Dockerfile.cli +++ b/Dockerfile.cli @@ -1,12 +1,12 @@ # This image will be published as dspace/dspace-cli # See https://github.com/DSpace/DSpace/tree/main/dspace/src/main/docker for usage details # -# - note: default tag for branch: dspace/dspace-cli: dspace/dspace-cli:latest +# - note: default tag for branch: dspace/dspace-cli: dspace/dspace-cli:dspace-8_x # This Dockerfile uses JDK17 by default. # To build with other versions, use "--build-arg JDK_VERSION=[value]" ARG JDK_VERSION=17 -ARG DSPACE_VERSION=latest +ARG DSPACE_VERSION=dspace-8_x # Step 1 - Run Maven Build FROM dspace/dspace-dependencies:${DSPACE_VERSION} AS build diff --git a/Dockerfile.test b/Dockerfile.test index 218126b17aab..921c57e69919 100644 --- a/Dockerfile.test +++ b/Dockerfile.test @@ -1,14 +1,14 @@ # This image will be published as dspace/dspace # See https://github.com/DSpace/DSpace/tree/main/dspace/src/main/docker for usage details # -# - note: default tag for branch: dspace/dspace: dspace/dspace:latest-test +# - note: default tag for branch: dspace/dspace: dspace/dspace:8_x-test # # This image is meant for TESTING/DEVELOPMENT ONLY as it deploys the old v6 REST API under HTTP (not HTTPS) # This Dockerfile uses JDK17 by default. # To build with other versions, use "--build-arg JDK_VERSION=[value]" ARG JDK_VERSION=17 -ARG DSPACE_VERSION=latest +ARG DSPACE_VERSION=dspace-8_x # Step 1 - Run Maven Build FROM dspace/dspace-dependencies:${DSPACE_VERSION} AS build diff --git a/docker-compose-cli.yml b/docker-compose-cli.yml index 91f89916d208..dd77bdf108ca 100644 --- a/docker-compose-cli.yml +++ b/docker-compose-cli.yml @@ -6,7 +6,7 @@ networks: external: true services: dspace-cli: - image: "${DOCKER_OWNER:-dspace}/dspace-cli:${DSPACE_VER:-latest}" + image: "${DOCKER_OWNER:-dspace}/dspace-cli:${DSPACE_VER:-dspace-8_x}" container_name: dspace-cli build: context: . diff --git a/docker-compose.yml b/docker-compose.yml index 6a930a8d31ec..4322c7173457 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -28,7 +28,7 @@ services: # from the host machine. This IP range MUST correspond to the 'dspacenet' subnet defined above. proxies__P__trusted__P__ipranges: '172.23.0' LOGGING_CONFIG: /dspace/config/log4j2-container.xml - image: "${DOCKER_OWNER:-dspace}/dspace:${DSPACE_VER:-latest-test}" + image: "${DOCKER_OWNER:-dspace}/dspace:${DSPACE_VER:-dspace-8_x-test}" build: context: . dockerfile: Dockerfile.test From b28cc63cbb42985e1a34d1e685c9640fa06a1cce Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Thu, 21 Nov 2024 16:21:22 -0600 Subject: [PATCH 093/226] Ensure log4j-slf4j2-impl bridge exists to forward slf4J logs to log4j. Move that and log4j-core to dspace-api so it is inherited everywhere else. --- dspace-api/pom.xml | 8 ++++++++ dspace-oai/pom.xml | 4 ---- dspace-rdf/pom.xml | 4 ---- dspace-sword/pom.xml | 4 ---- dspace-swordv2/pom.xml | 4 ---- pom.xml | 6 ++++++ 6 files changed, 14 insertions(+), 16 deletions(-) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index ada822c1fb12..58bd8106e9af 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -341,6 +341,14 @@ org.apache.logging.log4j log4j-api + + org.apache.logging.log4j + log4j-core + + + org.apache.logging.log4j + log4j-slf4j2-impl + org.hibernate.orm hibernate-core diff --git a/dspace-oai/pom.xml b/dspace-oai/pom.xml index f6b220baed3d..1447fc6e19a0 100644 --- a/dspace-oai/pom.xml +++ b/dspace-oai/pom.xml @@ -119,10 +119,6 @@ org.apache.logging.log4j log4j-api - - org.apache.logging.log4j - log4j-core - diff --git a/dspace-rdf/pom.xml b/dspace-rdf/pom.xml index 3b3cb17119a1..f8e1bb9e36c4 100644 --- a/dspace-rdf/pom.xml +++ b/dspace-rdf/pom.xml @@ -85,10 +85,6 @@ org.apache.logging.log4j log4j-api - - org.apache.logging.log4j - log4j-core - org.apache.commons diff --git a/dspace-sword/pom.xml b/dspace-sword/pom.xml index ac629cb504e5..48a6392d3dba 100644 --- a/dspace-sword/pom.xml +++ b/dspace-sword/pom.xml @@ -73,10 +73,6 @@ org.apache.logging.log4j log4j-api - - org.apache.logging.log4j - log4j-core - xom diff --git a/dspace-swordv2/pom.xml b/dspace-swordv2/pom.xml index af516d566036..d218406a16cc 100644 --- a/dspace-swordv2/pom.xml +++ b/dspace-swordv2/pom.xml @@ -91,10 +91,6 @@ org.apache.logging.log4j log4j-api - - org.apache.logging.log4j - log4j-core - diff --git a/pom.xml b/pom.xml index f7923b97dedb..4bbd60ca9091 100644 --- a/pom.xml +++ b/pom.xml @@ -1593,6 +1593,12 @@ log4j-core ${log4j.version} + + + org.apache.logging.log4j + log4j-slf4j2-impl + ${log4j.version} + org.apache.pdfbox From 03890e6ef3b2ab4d5965f7ba2b7d5cf651b292d9 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Thu, 21 Nov 2024 16:59:30 -0600 Subject: [PATCH 094/226] Remove unused slf4j dependencies --- pom.xml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/pom.xml b/pom.xml index 4bbd60ca9091..fa37ca9ed4f0 100644 --- a/pom.xml +++ b/pom.xml @@ -1660,16 +1660,6 @@ slf4j-api ${slf4j.version} - - org.slf4j - slf4j-jdk14 - ${slf4j.version} - - - org.slf4j - log4j-over-slf4j - ${slf4j.version} - com.google.errorprone From 9a597891bb319ef5d9ab80cb526d5f0e586c5553 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 22 Nov 2024 11:04:11 -0600 Subject: [PATCH 095/226] Enable all optional modules/controllers to test their deployment in Spring Boot (cherry picked from commit 98768d6f4fcc5181501d02d77ef5056641ac8cd3) --- .github/workflows/docker.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 143b69a2f9fe..816dcd228ca5 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -161,6 +161,15 @@ jobs: env: # Override defaults dspace.server.url because backend starts at http://127.0.0.1:8080 dspace__P__server__P__url: http://127.0.0.1:8080/server + # Enable all optional modules / controllers for this test deployment. + # This helps check for errors in deploying these modules via Spring Boot + iiif__P__enabled: true + ldn__P__enabled: true + oai__P__enabled: true + rdf__P__enabled: true + signposting__P__enabled: true + sword-server__P__enabled: true + swordv2-server__P__enabled: true # If this is a PR, force using "pr-testing" version of all Docker images. Otherwise, if on main branch, use the # "latest" tag. Otherwise, use the branch name. NOTE: the "pr-testing" tag is a temporary tag that we assign to # all PR-built docker images in reusabe-docker-build.yml From 71e17a275817a68a838575c5e92297c58f8a2bb8 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 22 Nov 2024 13:50:16 -0600 Subject: [PATCH 096/226] Fix syntax error in #10040. Env variables cannot have dashes or periods --- .github/workflows/docker.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 816dcd228ca5..7e7cbc1b07ca 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -168,8 +168,8 @@ jobs: oai__P__enabled: true rdf__P__enabled: true signposting__P__enabled: true - sword-server__P__enabled: true - swordv2-server__P__enabled: true + sword__D__server__P__enabled: true + swordv2__D__server__P__enabled: true # If this is a PR, force using "pr-testing" version of all Docker images. Otherwise, if on main branch, use the # "latest" tag. Otherwise, use the branch name. NOTE: the "pr-testing" tag is a temporary tag that we assign to # all PR-built docker images in reusabe-docker-build.yml From 4d1f65c47f7c50bb349c0f13510d57d1d603477c Mon Sep 17 00:00:00 2001 From: "David P. Steelman" Date: Mon, 25 Nov 2024 08:57:37 -0500 Subject: [PATCH 097/226] Adjustments to POM files so that the changes in "modules/server" are incorporated into the JAR generated by "server-boot". This commit adds an "attachClasses" parameter to the "maven-war-plugin" in the "dspace/modules/server/pom.xml", which generates a JAR file that can be referenced in the "dspace/modules/server-boot/pom.xml" (see ) via ``` org.dspace.modules server classes ``` The dependency must be placed *before* the "dspace-server-webapp" dependency, to ensure that it overrides the classes in the "dspace-server-webapp" module. In the "server-boot.jar", the CLASSPATH is determined by the order of JARs in the "BOOT-INF/classpath.idx", which is generated based on the order of dependencies in the POM (see https://stackoverflow.com/a/67997782). The root "pom.xml" file was modified to provide the version for "modules/server" JAR file, in keeping with how the versions of other JAR files are specified. (cherry picked from commit 5bf1f26ebaacfc211d8dac3766ae9e4d7a31d4cd) --- dspace/modules/server-boot/pom.xml | 5 +++++ dspace/modules/server/pom.xml | 1 + pom.xml | 6 ++++++ 3 files changed, 12 insertions(+) diff --git a/dspace/modules/server-boot/pom.xml b/dspace/modules/server-boot/pom.xml index 87bb2d634e69..f2f79bb73869 100644 --- a/dspace/modules/server-boot/pom.xml +++ b/dspace/modules/server-boot/pom.xml @@ -26,6 +26,11 @@ org.dspace.modules additions + + org.dspace.modules + server + classes + org.dspace dspace-server-webapp diff --git a/dspace/modules/server/pom.xml b/dspace/modules/server/pom.xml index f235fcc0279d..916689516a1c 100644 --- a/dspace/modules/server/pom.xml +++ b/dspace/modules/server/pom.xml @@ -63,6 +63,7 @@ maven-war-plugin false + true true - + - - + - - + From 7cfc0aa106568f3f9bb143fe3330008bbaf6ac0e Mon Sep 17 00:00:00 2001 From: Koen Pauwels Date: Tue, 7 Jan 2025 15:51:28 +0100 Subject: [PATCH 140/226] Bugfix: Enforce unique item id in workspace table (#9340) * 106798 Enforce values in item_id column of workspaceitem table to be unique, both at database level and at WorkspaceItemService level * 106798 Removed Oracle SQL migration * 106798 workspaceitem table migration: delete duplicate rows before introducing uniqueness constraint * 106798: update migration for H2 --------- Co-authored-by: Koen Pauwels Co-authored-by: wout --- .../content/WorkspaceItemServiceImpl.java | 8 +++ ...paceitem_add_item_id_unique_constraint.sql | 21 +++++++ ...paceitem_add_item_id_unique_constraint.sql | 21 +++++++ .../org/dspace/content/WorkspaceItemTest.java | 12 ++++ .../org/dspace/workflow/MockWorkflowItem.java | 62 +++++++++++++++++++ 5 files changed, 124 insertions(+) create mode 100644 dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.6_2024.12.17__workspaceitem_add_item_id_unique_constraint.sql create mode 100644 dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.6_2024.12.17__workspaceitem_add_item_id_unique_constraint.sql create mode 100644 dspace-api/src/test/java/org/dspace/workflow/MockWorkflowItem.java diff --git a/dspace-api/src/main/java/org/dspace/content/WorkspaceItemServiceImpl.java b/dspace-api/src/main/java/org/dspace/content/WorkspaceItemServiceImpl.java index 1da9e6e44a6a..543f5a55efe2 100644 --- a/dspace-api/src/main/java/org/dspace/content/WorkspaceItemServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/content/WorkspaceItemServiceImpl.java @@ -178,6 +178,14 @@ public WorkspaceItem create(Context context, Collection collection, UUID uuid, b @Override public WorkspaceItem create(Context c, WorkflowItem workflowItem) throws SQLException, AuthorizeException { + WorkspaceItem potentialDuplicate = findByItem(c, workflowItem.getItem()); + if (potentialDuplicate != null) { + throw new IllegalArgumentException(String.format( + "A workspace item referring to item %s already exists (%d)", + workflowItem.getItem().getID(), + potentialDuplicate.getID() + )); + } WorkspaceItem workspaceItem = workspaceItemDAO.create(c, new WorkspaceItem()); workspaceItem.setItem(workflowItem.getItem()); workspaceItem.setCollection(workflowItem.getCollection()); diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.6_2024.12.17__workspaceitem_add_item_id_unique_constraint.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.6_2024.12.17__workspaceitem_add_item_id_unique_constraint.sql new file mode 100644 index 000000000000..38389bf2d19b --- /dev/null +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/h2/V7.6_2024.12.17__workspaceitem_add_item_id_unique_constraint.sql @@ -0,0 +1,21 @@ +-- +-- 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/ +-- + +-- In the workspaceitem table, if there are multiple rows referring to the same item ID, keep only the first of them. +DELETE FROM workspaceitem WHERE EXISTS ( + SELECT item_id + FROM workspaceitem + GROUP BY item_id + HAVING COUNT(workspace_item_id) > 1 +) AND workspaceitem.workspace_item_id NOT IN ( + SELECT MIN(workspace_item_id) AS workspace_item_id + FROM workspaceitem + GROUP BY item_id +); +-- Identify which rows have duplicates, and compute their replacements. +ALTER TABLE workspaceitem ADD CONSTRAINT unique_item_id UNIQUE(item_id); diff --git a/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.6_2024.12.17__workspaceitem_add_item_id_unique_constraint.sql b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.6_2024.12.17__workspaceitem_add_item_id_unique_constraint.sql new file mode 100644 index 000000000000..20eb0f9119d3 --- /dev/null +++ b/dspace-api/src/main/resources/org/dspace/storage/rdbms/sqlmigration/postgres/V7.6_2024.12.17__workspaceitem_add_item_id_unique_constraint.sql @@ -0,0 +1,21 @@ +-- +-- 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/ +-- + +-- In the workspaceitem table, if there are multiple rows referring to the same item ID, keep only the first of them. +WITH dedup AS ( + SELECT item_id, MIN(workspace_item_id) AS workspace_item_id + FROM workspaceitem + GROUP BY item_id + HAVING COUNT(workspace_item_id) > 1 +) +DELETE FROM workspaceitem +USING dedup +WHERE workspaceitem.item_id = dedup.item_id AND workspaceitem.workspace_item_id <> dedup.workspace_item_id; + +-- Enforce uniqueness of item_id in workspaceitem table. +ALTER TABLE workspaceitem ADD CONSTRAINT unique_item_id UNIQUE(item_id); diff --git a/dspace-api/src/test/java/org/dspace/content/WorkspaceItemTest.java b/dspace-api/src/test/java/org/dspace/content/WorkspaceItemTest.java index d018a15f9765..15d4720c9378 100644 --- a/dspace-api/src/test/java/org/dspace/content/WorkspaceItemTest.java +++ b/dspace-api/src/test/java/org/dspace/content/WorkspaceItemTest.java @@ -12,6 +12,7 @@ import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.any; @@ -39,6 +40,7 @@ import org.dspace.eperson.EPerson; import org.dspace.eperson.factory.EPersonServiceFactory; import org.dspace.eperson.service.EPersonService; +import org.dspace.workflow.MockWorkflowItem; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -468,4 +470,14 @@ public void testSetPublishedBefore() { assertTrue("testSetPublishedBefore 0", wi.isPublishedBefore()); } + @Test + public void testDuplicateItemID() throws Exception { + context.turnOffAuthorisationSystem(); + Item item = wi.getItem(); + MockWorkflowItem wfItem = new MockWorkflowItem(); + wfItem.item = item; + wfItem.collection = collection; + assertThrows(IllegalArgumentException.class, () -> workspaceItemService.create(context, wfItem)); + context.restoreAuthSystemState(); + } } diff --git a/dspace-api/src/test/java/org/dspace/workflow/MockWorkflowItem.java b/dspace-api/src/test/java/org/dspace/workflow/MockWorkflowItem.java new file mode 100644 index 000000000000..d36ecf7331b8 --- /dev/null +++ b/dspace-api/src/test/java/org/dspace/workflow/MockWorkflowItem.java @@ -0,0 +1,62 @@ +/** + * 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.workflow; + +import org.dspace.content.Collection; +import org.dspace.content.Item; +import org.dspace.eperson.EPerson; + +public class MockWorkflowItem implements WorkflowItem { + public Integer id; + public Item item; + public Collection collection; + public EPerson submitter; + boolean hasMultipleFiles; + boolean hasMultipleTitles; + boolean isPublishedBefore; + + public Integer getID() { + return id; + } + + public Item getItem() { + return item; + } + + public Collection getCollection() { + return collection; + } + + public EPerson getSubmitter() { + return submitter; + } + + public boolean hasMultipleFiles() { + return hasMultipleFiles; + } + + public void setMultipleFiles(boolean b) { + hasMultipleFiles = b; + } + + public boolean hasMultipleTitles() { + return hasMultipleTitles; + } + + public void setMultipleTitles(boolean b) { + hasMultipleTitles = b; + } + + public boolean isPublishedBefore() { + return isPublishedBefore; + } + + public void setPublishedBefore(boolean b) { + isPublishedBefore = b; + } +} From 7ee4ba1a281c379d4fceb205428948b6aea14955 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 6 Nov 2024 12:03:31 -0600 Subject: [PATCH 141/226] Refactor identifier ITs to ensure they unregister all utilized IdentifierProviders which are non-default. Cannot use "getApplicationContext().refresh()" as that seems to result in empty test database in Hibernate 6.6. (cherry picked from commit cfca2adbb1d597761b3169a5a46170de8cabfa4f) --- .../general/CreateMissingIdentifiersIT.java | 48 +++---------- .../AbstractIdentifierProviderIT.java | 68 +++++++++++++++++++ .../VersionedHandleIdentifierProviderIT.java | 49 ++----------- 3 files changed, 84 insertions(+), 81 deletions(-) create mode 100644 dspace-api/src/test/java/org/dspace/identifier/AbstractIdentifierProviderIT.java diff --git a/dspace-api/src/test/java/org/dspace/ctask/general/CreateMissingIdentifiersIT.java b/dspace-api/src/test/java/org/dspace/ctask/general/CreateMissingIdentifiersIT.java index 8038a7153325..4934404c3b3e 100644 --- a/dspace-api/src/test/java/org/dspace/ctask/general/CreateMissingIdentifiersIT.java +++ b/dspace-api/src/test/java/org/dspace/ctask/general/CreateMissingIdentifiersIT.java @@ -10,10 +10,7 @@ import static org.junit.Assert.assertEquals; import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import org.dspace.AbstractIntegrationTestWithDatabase; import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; import org.dspace.builder.ItemBuilder; @@ -21,13 +18,11 @@ import org.dspace.content.Item; import org.dspace.core.factory.CoreServiceFactory; import org.dspace.curate.Curator; -import org.dspace.identifier.IdentifierProvider; -import org.dspace.identifier.IdentifierServiceImpl; +import org.dspace.identifier.AbstractIdentifierProviderIT; +import org.dspace.identifier.VersionedHandleIdentifierProvider; import org.dspace.identifier.VersionedHandleIdentifierProviderWithCanonicalHandles; -import org.dspace.kernel.ServiceManager; import org.dspace.services.ConfigurationService; import org.dspace.services.factory.DSpaceServicesFactory; -import org.junit.After; import org.junit.Test; /** @@ -36,30 +31,19 @@ * @author mwood */ public class CreateMissingIdentifiersIT - extends AbstractIntegrationTestWithDatabase { - private ServiceManager serviceManager; - private IdentifierServiceImpl identifierService; + extends AbstractIdentifierProviderIT { + private static final String P_TASK_DEF = "plugin.named.org.dspace.curate.CurationTask"; private static final String TASK_NAME = "test"; - @Override - public void setUp() throws Exception { - super.setUp(); - context.turnOffAuthorisationSystem(); - - serviceManager = DSpaceServicesFactory.getInstance().getServiceManager(); - identifierService = serviceManager.getServicesByType(IdentifierServiceImpl.class).get(0); - // Clean out providers to avoid any being used for creation of community and collection - identifierService.setProviders(new ArrayList<>()); - } + private ConfigurationService configurationService = DSpaceServicesFactory.getInstance().getConfigurationService(); @Test public void testPerform() throws IOException { // Must remove any cached named plugins before creating a new one CoreServiceFactory.getInstance().getPluginService().clearNamedPluginClasses(); - ConfigurationService configurationService = kernelImpl.getConfigurationService(); // Define a new task dynamically configurationService.setProperty(P_TASK_DEF, CreateMissingIdentifiers.class.getCanonicalName() + " = " + TASK_NAME); @@ -76,7 +60,7 @@ public void testPerform() .build(); /* - * Curate with regular test configuration -- should succeed. + * Curate with default Handle Provider */ curator.curate(context, item); int status = curator.getStatus(TASK_NAME); @@ -92,22 +76,10 @@ public void testPerform() curator.getResult(TASK_NAME)); assertEquals("Curation should fail", Curator.CURATE_ERROR, curator.getStatus(TASK_NAME)); - } - - @Override - @After - public void destroy() throws Exception { - super.destroy(); - DSpaceServicesFactory.getInstance().getServiceManager().getApplicationContext().refresh(); - } - - private void registerProvider(Class type) { - // Register our new provider - serviceManager.registerServiceClass(type.getName(), type); - IdentifierProvider identifierProvider = - (IdentifierProvider) serviceManager.getServiceByName(type.getName(), type); - // Overwrite the identifier-service's providers with the new one to ensure only this provider is used - identifierService.setProviders(List.of(identifierProvider)); + // Unregister this non-default provider + unregisterProvider(VersionedHandleIdentifierProviderWithCanonicalHandles.class); + // Re-register the default provider (for later tests which may depend on it) + registerProvider(VersionedHandleIdentifierProvider.class); } } diff --git a/dspace-api/src/test/java/org/dspace/identifier/AbstractIdentifierProviderIT.java b/dspace-api/src/test/java/org/dspace/identifier/AbstractIdentifierProviderIT.java new file mode 100644 index 000000000000..6ec9efddf5e2 --- /dev/null +++ b/dspace-api/src/test/java/org/dspace/identifier/AbstractIdentifierProviderIT.java @@ -0,0 +1,68 @@ +/** + * 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.identifier; + +import java.util.ArrayList; +import java.util.List; + +import org.dspace.AbstractIntegrationTestWithDatabase; +import org.dspace.kernel.ServiceManager; +import org.dspace.services.factory.DSpaceServicesFactory; + +/** + * AbstractIdentifierProviderIT which contains a few useful utility methods for IdentifierProvider Integration Tests + */ +public class AbstractIdentifierProviderIT extends AbstractIntegrationTestWithDatabase { + + protected final ServiceManager serviceManager = DSpaceServicesFactory.getInstance().getServiceManager(); + protected final IdentifierServiceImpl identifierService = + serviceManager.getServicesByType(IdentifierServiceImpl.class).get(0); + + /** + * Register a specific IdentifierProvider into the current IdentifierService (replacing any existing providers). + * This method will also ensure the IdentifierProvider service is registered in the DSpace Service Manager. + * @param type IdentifierProvider Class + */ + protected void registerProvider(Class type) { + // Register our new provider + IdentifierProvider identifierProvider = + (IdentifierProvider) DSpaceServicesFactory.getInstance().getServiceManager() + .getServiceByName(type.getName(), type); + if (identifierProvider == null) { + DSpaceServicesFactory.getInstance().getServiceManager().registerServiceClass(type.getName(), type); + identifierProvider = (IdentifierProvider) DSpaceServicesFactory.getInstance().getServiceManager() + .getServiceByName(type.getName(), type); + } + + identifierService.setProviders(List.of(identifierProvider)); + } + + /** + * Unregister a specific IdentifierProvider from the current IdentifierService (removing all existing providers). + * This method will also ensure the IdentifierProvider service is unregistered in the DSpace Service Manager, + * which ensures it does not conflict with other IdentifierProvider services. + * @param type IdentifierProvider Class + */ + protected void unregisterProvider(Class type) { + // Find the provider service + IdentifierProvider identifierProvider = + (IdentifierProvider) DSpaceServicesFactory.getInstance().getServiceManager() + .getServiceByName(type.getName(), type); + // If found, unregister it + if (identifierProvider == null) { + DSpaceServicesFactory.getInstance().getServiceManager().unregisterService(type.getName()); + } + + // Overwrite the identifier-service's providers with an empty list + identifierService.setProviders(new ArrayList<>()); + } + +} + + + diff --git a/dspace-api/src/test/java/org/dspace/identifier/VersionedHandleIdentifierProviderIT.java b/dspace-api/src/test/java/org/dspace/identifier/VersionedHandleIdentifierProviderIT.java index 57acf1f1c453..8c0f7e5b5e10 100644 --- a/dspace-api/src/test/java/org/dspace/identifier/VersionedHandleIdentifierProviderIT.java +++ b/dspace-api/src/test/java/org/dspace/identifier/VersionedHandleIdentifierProviderIT.java @@ -11,10 +11,7 @@ import static org.junit.Assert.assertTrue; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; -import org.dspace.AbstractIntegrationTestWithDatabase; import org.dspace.authorize.AuthorizeException; import org.dspace.builder.CollectionBuilder; import org.dspace.builder.CommunityBuilder; @@ -22,15 +19,10 @@ import org.dspace.builder.VersionBuilder; import org.dspace.content.Collection; import org.dspace.content.Item; -import org.dspace.kernel.ServiceManager; -import org.dspace.services.factory.DSpaceServicesFactory; -import org.junit.After; import org.junit.Before; import org.junit.Test; -public class VersionedHandleIdentifierProviderIT extends AbstractIntegrationTestWithDatabase { - private ServiceManager serviceManager; - private IdentifierServiceImpl identifierService; +public class VersionedHandleIdentifierProviderIT extends AbstractIdentifierProviderIT { private String firstHandle; @@ -44,12 +36,6 @@ public class VersionedHandleIdentifierProviderIT extends AbstractIntegrationTest public void setUp() throws Exception { super.setUp(); context.turnOffAuthorisationSystem(); - - serviceManager = DSpaceServicesFactory.getInstance().getServiceManager(); - identifierService = serviceManager.getServicesByType(IdentifierServiceImpl.class).get(0); - // Clean out providers to avoid any being used for creation of community and collection - identifierService.setProviders(new ArrayList<>()); - parentCommunity = CommunityBuilder.createCommunity(context) .withName("Parent Community") .build(); @@ -58,33 +44,6 @@ public void setUp() throws Exception { .build(); } - @After - @Override - public void destroy() throws Exception { - super.destroy(); - // After this test has finished running, refresh application context and - // set the expected 'default' versioned handle provider back to ensure other tests don't fail - DSpaceServicesFactory.getInstance().getServiceManager().getApplicationContext().refresh(); - } - - private void registerProvider(Class type) { - // Register our new provider - IdentifierProvider identifierProvider = - (IdentifierProvider) DSpaceServicesFactory.getInstance().getServiceManager() - .getServiceByName(type.getName(), type); - if (identifierProvider == null) { - DSpaceServicesFactory.getInstance().getServiceManager().registerServiceClass(type.getName(), type); - identifierProvider = (IdentifierProvider) DSpaceServicesFactory.getInstance().getServiceManager() - .getServiceByName(type.getName(), type); - } - - // Overwrite the identifier-service's providers with the new one to ensure only this provider is used - identifierService = DSpaceServicesFactory.getInstance().getServiceManager() - .getServicesByType(IdentifierServiceImpl.class).get(0); - identifierService.setProviders(new ArrayList<>()); - identifierService.setProviders(List.of(identifierProvider)); - } - private void createVersions() throws SQLException, AuthorizeException { itemV1 = ItemBuilder.createItem(context, collection) .withTitle("First version") @@ -96,7 +55,6 @@ private void createVersions() throws SQLException, AuthorizeException { @Test public void testDefaultVersionedHandleProvider() throws Exception { - registerProvider(VersionedHandleIdentifierProvider.class); createVersions(); // Confirm the original item only has its original handle @@ -125,6 +83,11 @@ public void testCanonicalVersionedHandleProvider() throws Exception { assertEquals(firstHandle, itemV3.getHandle()); assertEquals(2, itemV3.getHandles().size()); containsHandle(itemV3, firstHandle + ".3"); + + // Unregister this non-default provider + unregisterProvider(VersionedHandleIdentifierProviderWithCanonicalHandles.class); + // Re-register the default provider (for later tests) + registerProvider(VersionedHandleIdentifierProvider.class); } private void containsHandle(Item item, String handle) { From ad6d2eb014ec0ae2a3e9ee81970c11e8809da210 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Fri, 8 Nov 2024 10:17:31 -0600 Subject: [PATCH 142/226] Update CreateMissingIdentifiers to better identify when CanonicalHandles provider is enabled. Update CreateMissingIdentifiersIT to verify that we are accurately resetting to our default IdentifierProvider (cherry picked from commit 2385c13f2d48048306a1280d88da5d8c022cc24f) --- .../general/CreateMissingIdentifiers.java | 28 +++++++++---------- .../identifier/IdentifierServiceImpl.java | 5 ++++ .../identifier/service/IdentifierService.java | 6 ++++ .../general/CreateMissingIdentifiersIT.java | 17 +++++------ 4 files changed, 33 insertions(+), 23 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/ctask/general/CreateMissingIdentifiers.java b/dspace-api/src/main/java/org/dspace/ctask/general/CreateMissingIdentifiers.java index 9639461426ef..0734d60946bc 100644 --- a/dspace-api/src/main/java/org/dspace/ctask/general/CreateMissingIdentifiers.java +++ b/dspace-api/src/main/java/org/dspace/ctask/general/CreateMissingIdentifiers.java @@ -10,6 +10,7 @@ import java.io.IOException; import java.sql.SQLException; +import java.util.List; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -25,7 +26,6 @@ import org.dspace.identifier.VersionedHandleIdentifierProviderWithCanonicalHandles; import org.dspace.identifier.factory.IdentifierServiceFactory; import org.dspace.identifier.service.IdentifierService; -import org.dspace.services.factory.DSpaceServicesFactory; /** * Ensure that an object has all of the identifiers that it should, minting them @@ -45,20 +45,6 @@ public int perform(DSpaceObject dso) return Curator.CURATE_SKIP; } - // XXX Temporary escape when an incompatible provider is configured. - // XXX Remove this when the provider is fixed. - boolean compatible = DSpaceServicesFactory - .getInstance() - .getServiceManager() - .getServiceByName( - VersionedHandleIdentifierProviderWithCanonicalHandles.class.getCanonicalName(), - IdentifierProvider.class) == null; - if (!compatible) { - setResult("This task is not compatible with VersionedHandleIdentifierProviderWithCanonicalHandles"); - return Curator.CURATE_ERROR; - } - // XXX End of escape - String typeText = Constants.typeText[dso.getType()]; // Get a Context @@ -75,6 +61,18 @@ public int perform(DSpaceObject dso) .getInstance() .getIdentifierService(); + // XXX Temporary escape when an incompatible provider is configured. + // XXX Remove this when the provider is fixed. + List providerList = identifierService.getProviders(); + boolean compatible = + providerList.stream().noneMatch(p -> p instanceof VersionedHandleIdentifierProviderWithCanonicalHandles); + + if (!compatible) { + setResult("This task is not compatible with VersionedHandleIdentifierProviderWithCanonicalHandles"); + return Curator.CURATE_ERROR; + } + // XXX End of escape + // Register any missing identifiers. try { identifierService.register(context, dso); diff --git a/dspace-api/src/main/java/org/dspace/identifier/IdentifierServiceImpl.java b/dspace-api/src/main/java/org/dspace/identifier/IdentifierServiceImpl.java index b98aea24fa08..e6dcfcdda693 100644 --- a/dspace-api/src/main/java/org/dspace/identifier/IdentifierServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/identifier/IdentifierServiceImpl.java @@ -57,6 +57,11 @@ public void setProviders(List providers) { } } + @Override + public List getProviders() { + return this.providers; + } + /** * Reserves identifiers for the item * diff --git a/dspace-api/src/main/java/org/dspace/identifier/service/IdentifierService.java b/dspace-api/src/main/java/org/dspace/identifier/service/IdentifierService.java index 23005b657508..45bf3c6dea8a 100644 --- a/dspace-api/src/main/java/org/dspace/identifier/service/IdentifierService.java +++ b/dspace-api/src/main/java/org/dspace/identifier/service/IdentifierService.java @@ -19,6 +19,7 @@ import org.dspace.identifier.IdentifierException; import org.dspace.identifier.IdentifierNotFoundException; import org.dspace.identifier.IdentifierNotResolvableException; +import org.dspace.identifier.IdentifierProvider; /** * @author Fabio Bolognesi (fabio at atmire dot com) @@ -194,4 +195,9 @@ void register(Context context, DSpaceObject dso, String identifier) void delete(Context context, DSpaceObject dso, String identifier) throws AuthorizeException, SQLException, IdentifierException; + /** + * Get List of currently enabled IdentifierProviders + * @return List of enabled IdentifierProvider objects. + */ + List getProviders(); } diff --git a/dspace-api/src/test/java/org/dspace/ctask/general/CreateMissingIdentifiersIT.java b/dspace-api/src/test/java/org/dspace/ctask/general/CreateMissingIdentifiersIT.java index 4934404c3b3e..3b50258a5a23 100644 --- a/dspace-api/src/test/java/org/dspace/ctask/general/CreateMissingIdentifiersIT.java +++ b/dspace-api/src/test/java/org/dspace/ctask/general/CreateMissingIdentifiersIT.java @@ -60,14 +60,7 @@ public void testPerform() .build(); /* - * Curate with default Handle Provider - */ - curator.curate(context, item); - int status = curator.getStatus(TASK_NAME); - assertEquals("Curation should succeed", Curator.CURATE_SUCCESS, status); - - /* - * Now install an incompatible provider to make the task fail. + * First, install an incompatible provider to make the task fail. */ registerProvider(VersionedHandleIdentifierProviderWithCanonicalHandles.class); @@ -81,5 +74,13 @@ public void testPerform() unregisterProvider(VersionedHandleIdentifierProviderWithCanonicalHandles.class); // Re-register the default provider (for later tests which may depend on it) registerProvider(VersionedHandleIdentifierProvider.class); + + /* + * Now, verify curate with default Handle Provider works + * (and that our re-registration of the default provider above was successful) + */ + curator.curate(context, item); + int status = curator.getStatus(TASK_NAME); + assertEquals("Curation should succeed", Curator.CURATE_SUCCESS, status); } } From fb47b27a2b55f59b3cf3c3cf77401ec9ef0ea594 Mon Sep 17 00:00:00 2001 From: "Gantner, Florian Klaus" Date: Thu, 9 Jan 2025 14:09:24 +0100 Subject: [PATCH 143/226] switch IT search core to MockSolrSearchCore https://github.com/DSpace/DSpace/issues/10188 (cherry picked from commit 6d781e8f83a912863af8d998d982e030db64a2ce) --- .../org/dspace/content/VersioningWithRelationshipsIT.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/content/VersioningWithRelationshipsIT.java b/dspace-api/src/test/java/org/dspace/content/VersioningWithRelationshipsIT.java index 3acc4ca146ee..9ff452f7895f 100644 --- a/dspace-api/src/test/java/org/dspace/content/VersioningWithRelationshipsIT.java +++ b/dspace-api/src/test/java/org/dspace/content/VersioningWithRelationshipsIT.java @@ -59,7 +59,7 @@ import org.dspace.content.virtual.VirtualMetadataConfiguration; import org.dspace.content.virtual.VirtualMetadataPopulator; import org.dspace.core.Constants; -import org.dspace.discovery.SolrSearchCore; +import org.dspace.discovery.MockSolrSearchCore; import org.dspace.kernel.ServiceManager; import org.dspace.services.factory.DSpaceServicesFactory; import org.dspace.versioning.Version; @@ -79,8 +79,9 @@ public class VersioningWithRelationshipsIT extends AbstractIntegrationTestWithDa ContentServiceFactory.getInstance().getInstallItemService(); private final ItemService itemService = ContentServiceFactory.getInstance().getItemService(); - private final SolrSearchCore solrSearchCore = - DSpaceServicesFactory.getInstance().getServiceManager().getServicesByType(SolrSearchCore.class).get(0); + private final MockSolrSearchCore solrSearchCore = + DSpaceServicesFactory.getInstance().getServiceManager().getServiceByName(null, MockSolrSearchCore.class); + protected Community community; protected Collection collection; protected EntityType publicationEntityType; From 391ba5d7a774e4aea8d1351229a83b58220afe51 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Thu, 9 Jan 2025 15:42:25 -0600 Subject: [PATCH 144/226] Refactor AbstractIntegrationTestWithDatabase to use Builders to create test EPersons. (cherry picked from commit 0b8b7be22b88a411898bcb975e238e7cd96f40ab) --- .../AbstractIntegrationTestWithDatabase.java | 48 ++++++++----------- .../AbstractWebClientIntegrationTest.java | 16 +++++++ 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/dspace-api/src/test/java/org/dspace/AbstractIntegrationTestWithDatabase.java b/dspace-api/src/test/java/org/dspace/AbstractIntegrationTestWithDatabase.java index 9bacbb97eec4..76b3fe131be0 100644 --- a/dspace-api/src/test/java/org/dspace/AbstractIntegrationTestWithDatabase.java +++ b/dspace-api/src/test/java/org/dspace/AbstractIntegrationTestWithDatabase.java @@ -20,8 +20,8 @@ import org.dspace.app.scripts.handler.impl.TestDSpaceRunnableHandler; import org.dspace.authority.AuthoritySearchService; import org.dspace.authority.MockAuthoritySolrServiceImpl; -import org.dspace.authorize.AuthorizeException; import org.dspace.builder.AbstractBuilder; +import org.dspace.builder.EPersonBuilder; import org.dspace.content.Community; import org.dspace.core.Context; import org.dspace.core.I18nUtil; @@ -127,19 +127,16 @@ public void setUp() throws Exception { EPersonService ePersonService = EPersonServiceFactory.getInstance().getEPersonService(); eperson = ePersonService.findByEmail(context, "test@email.com"); if (eperson == null) { - // This EPerson creation should only happen once (i.e. for first test run) - log.info("Creating initial EPerson (email=test@email.com) for Unit Tests"); - eperson = ePersonService.create(context); - eperson.setFirstName(context, "first"); - eperson.setLastName(context, "last"); - eperson.setEmail("test@email.com"); - eperson.setCanLogIn(true); - eperson.setLanguage(context, I18nUtil.getDefaultLocale().getLanguage()); - ePersonService.setPassword(eperson, password); - // actually save the eperson to unit testing DB - ePersonService.update(context, eperson); + // Create test EPerson for usage in all tests + log.info("Creating Test EPerson (email=test@email.com) for Integration Tests"); + eperson = EPersonBuilder.createEPerson(context) + .withNameInMetadata("first", "last") + .withEmail("test@email.com") + .withCanLogin(true) + .withLanguage(I18nUtil.getDefaultLocale().getLanguage()) + .withPassword(password) + .build(); } - // Set our global test EPerson as the current user in DSpace context.setCurrentUser(eperson); @@ -148,26 +145,23 @@ public void setUp() throws Exception { admin = ePersonService.findByEmail(context, "admin@email.com"); if (admin == null) { - // This EPerson creation should only happen once (i.e. for first test run) - log.info("Creating initial EPerson (email=admin@email.com) for Unit Tests"); - admin = ePersonService.create(context); - admin.setFirstName(context, "first (admin)"); - admin.setLastName(context, "last (admin)"); - admin.setEmail("admin@email.com"); - admin.setCanLogIn(true); - admin.setLanguage(context, I18nUtil.getDefaultLocale().getLanguage()); - ePersonService.setPassword(admin, password); - // actually save the eperson to unit testing DB - ePersonService.update(context, admin); + // Create test Administrator for usage in all tests + log.info("Creating Test Admin EPerson (email=admin@email.com) for Integration Tests"); + admin = EPersonBuilder.createEPerson(context) + .withNameInMetadata("first (admin)", "last (admin)") + .withEmail("admin@email.com") + .withCanLogin(true) + .withLanguage(I18nUtil.getDefaultLocale().getLanguage()) + .withPassword(password) + .build(); + + // Add Test Administrator to the ADMIN group in test database GroupService groupService = EPersonServiceFactory.getInstance().getGroupService(); Group adminGroup = groupService.findByName(context, Group.ADMIN); groupService.addMember(context, adminGroup, admin); } context.restoreAuthSystemState(); - } catch (AuthorizeException ex) { - log.error("Error creating initial eperson or default groups", ex); - fail("Error creating initial eperson or default groups in AbstractUnitTest init()"); } catch (SQLException ex) { log.error(ex.getMessage(), ex); fail("SQL Error on AbstractUnitTest init()"); diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/test/AbstractWebClientIntegrationTest.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/test/AbstractWebClientIntegrationTest.java index e4ef1c741f72..f7ec1e941d0e 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/test/AbstractWebClientIntegrationTest.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/test/AbstractWebClientIntegrationTest.java @@ -12,6 +12,7 @@ import org.dspace.app.TestApplication; import org.dspace.app.rest.utils.DSpaceConfigurationInitializer; import org.dspace.app.rest.utils.DSpaceKernelInitializer; +import org.junit.Before; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -64,6 +65,21 @@ public class AbstractWebClientIntegrationTest extends AbstractIntegrationTestWit @Autowired protected ApplicationContext applicationContext; + @Override + @Before + public void setUp() throws Exception { + super.setUp(); + + // Because AbstractWebClientIntegrationTest starts a new webserver, we need to ensure *everything* created by + // the "super.setUp()" script is committed to the test database. Otherwise, the new webserver may not see the + // created test data in the database. + // NOTE: This commit() does NOT occur in AbstractIntegrationTestDatabase because it will remove newly created + // Hibernate entities from the current Hibernate session. For most ITs we don't want that as it may result + // in "could not initialize proxy - no Session" errors when using those entities in other tests (or other tests + // would need to reload each test entity back into the Hibernate session) + context.commit(); + } + /** * Get client TestRestTemplate for making HTTP requests to test webserver * @return TestRestTemplate From 07a478b31add75b1653c0e1f78971935b9353e81 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Tue, 9 Jul 2024 16:58:00 +0200 Subject: [PATCH 145/226] put DOIs in dc.identifier.doi (cherry picked from commit 3d1bef9d0e3fe820da9705427c129b5cb49d66fb) --- dspace/config/spring/api/scopus-integration.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dspace/config/spring/api/scopus-integration.xml b/dspace/config/spring/api/scopus-integration.xml index 47c5a4fbb900..6f7556574d09 100644 --- a/dspace/config/spring/api/scopus-integration.xml +++ b/dspace/config/spring/api/scopus-integration.xml @@ -128,7 +128,7 @@ - + @@ -264,4 +264,4 @@ - \ No newline at end of file + From 7a24605c0ac0426af6b3042d23bb28ab0e755727 Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Tue, 9 Jul 2024 17:37:07 +0200 Subject: [PATCH 146/226] fix broken test (cherry picked from commit 2eff833fab361d4ed3c7b602b681823911f989af) --- .../dspace/app/rest/ScopusImportMetadataSourceServiceIT.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ScopusImportMetadataSourceServiceIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ScopusImportMetadataSourceServiceIT.java index 7f6cb53ce400..e81f662ad5a9 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ScopusImportMetadataSourceServiceIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ScopusImportMetadataSourceServiceIT.java @@ -124,7 +124,7 @@ private ArrayList getRecords() { ArrayList records = new ArrayList<>(); //define first record List metadatums = new ArrayList(); - MetadatumDTO doi = createMetadatumDTO("dc", "identifier", null, "10.3934/mine.2023004"); + MetadatumDTO doi = createMetadatumDTO("dc", "identifier", "doi", "10.3934/mine.2023004"); MetadatumDTO title = createMetadatumDTO("dc","title", null, "Hardy potential versus lower order terms in Dirichlet problems: regularizing effects"); MetadatumDTO type = createMetadatumDTO("dc", "type", null, "Journal"); @@ -171,7 +171,7 @@ private ArrayList getRecords() { //define second record List metadatums2 = new ArrayList(); - MetadatumDTO doi2 = createMetadatumDTO("dc", "identifier", null, "10.3934/mine.2023001"); + MetadatumDTO doi2 = createMetadatumDTO("dc", "identifier", "doi", "10.3934/mine.2023001"); MetadatumDTO title2 = createMetadatumDTO("dc","title", null, "Large deviations for a binary collision model: energy evaporation"); MetadatumDTO date2 = createMetadatumDTO("dc", "date", "issued", "2023-01-01"); From 0416be3802e522638eb3012c52655f820303f76e Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Thu, 17 Oct 2024 20:17:06 +0200 Subject: [PATCH 147/226] use dc.relation.hasversion for externally generated DOIs (cherry picked from commit 29067b6572b538650e4686e983edafcc355d87c5) --- dspace/config/spring/api/scopus-integration.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace/config/spring/api/scopus-integration.xml b/dspace/config/spring/api/scopus-integration.xml index 6f7556574d09..d3e8150c74b1 100644 --- a/dspace/config/spring/api/scopus-integration.xml +++ b/dspace/config/spring/api/scopus-integration.xml @@ -128,7 +128,7 @@ - + From 8be99e47fa0acb8950ee53a9f2dad2bf39b5c8be Mon Sep 17 00:00:00 2001 From: Sascha Szott Date: Thu, 17 Oct 2024 20:19:04 +0200 Subject: [PATCH 148/226] use dc.relation.hasversion instead of dc.identifier.doi (cherry picked from commit d61dc8d911a4d226362d9a554226da5c304ad722) --- .../dspace/app/rest/ScopusImportMetadataSourceServiceIT.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ScopusImportMetadataSourceServiceIT.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ScopusImportMetadataSourceServiceIT.java index e81f662ad5a9..f9164ddc5994 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/ScopusImportMetadataSourceServiceIT.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/ScopusImportMetadataSourceServiceIT.java @@ -124,7 +124,7 @@ private ArrayList getRecords() { ArrayList records = new ArrayList<>(); //define first record List metadatums = new ArrayList(); - MetadatumDTO doi = createMetadatumDTO("dc", "identifier", "doi", "10.3934/mine.2023004"); + MetadatumDTO doi = createMetadatumDTO("dc", "relation", "hasversion", "10.3934/mine.2023004"); MetadatumDTO title = createMetadatumDTO("dc","title", null, "Hardy potential versus lower order terms in Dirichlet problems: regularizing effects"); MetadatumDTO type = createMetadatumDTO("dc", "type", null, "Journal"); @@ -171,7 +171,7 @@ private ArrayList getRecords() { //define second record List metadatums2 = new ArrayList(); - MetadatumDTO doi2 = createMetadatumDTO("dc", "identifier", "doi", "10.3934/mine.2023001"); + MetadatumDTO doi2 = createMetadatumDTO("dc", "relation", "hasversion", "10.3934/mine.2023001"); MetadatumDTO title2 = createMetadatumDTO("dc","title", null, "Large deviations for a binary collision model: energy evaporation"); MetadatumDTO date2 = createMetadatumDTO("dc", "date", "issued", "2023-01-01"); From 7ed3d326a8cb682c8b39406966348d9eeee5ce05 Mon Sep 17 00:00:00 2001 From: "Gantner, Florian Klaus" Date: Tue, 8 Oct 2024 13:42:07 +0200 Subject: [PATCH 149/226] option to exclude the submitter being indexed to solr in archived items https://github.com/DSpace/DSpace/issues/9660 (cherry picked from commit 8ed2cdcff7bbefb14e6e48fbc2731f2c9da67e98) --- .../indexobject/ItemIndexFactoryImpl.java | 8 +- .../org/dspace/discovery/DiscoveryIT.java | 109 ++++++++++++++++++ dspace/config/modules/discovery.cfg | 7 +- 3 files changed, 120 insertions(+), 4 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/discovery/indexobject/ItemIndexFactoryImpl.java b/dspace-api/src/main/java/org/dspace/discovery/indexobject/ItemIndexFactoryImpl.java index 7cdb8b93d80e..5fb2f779783c 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/indexobject/ItemIndexFactoryImpl.java +++ b/dspace-api/src/main/java/org/dspace/discovery/indexobject/ItemIndexFactoryImpl.java @@ -154,9 +154,11 @@ public SolrInputDocument buildDocument(Context context, IndexableItem indexableI doc.addField("latestVersion", isLatestVersion(context, item)); EPerson submitter = item.getSubmitter(); - if (submitter != null) { - addFacetIndex(doc, "submitter", submitter.getID().toString(), - submitter.getFullName()); + if (submitter != null && !(DSpaceServicesFactory.getInstance().getConfigurationService().getBooleanProperty( + "discovery.index.item.submitter.enabled", false))) { + doc.addField("submitter_authority", submitter.getID().toString()); + } else if (submitter != null) { + addFacetIndex(doc, "submitter", submitter.getID().toString(), submitter.getFullName()); } // Add the item metadata diff --git a/dspace-api/src/test/java/org/dspace/discovery/DiscoveryIT.java b/dspace-api/src/test/java/org/dspace/discovery/DiscoveryIT.java index 6bc79cad558b..63ff93b6f387 100644 --- a/dspace-api/src/test/java/org/dspace/discovery/DiscoveryIT.java +++ b/dspace-api/src/test/java/org/dspace/discovery/DiscoveryIT.java @@ -8,6 +8,10 @@ package org.dspace.discovery; import static org.dspace.discovery.SolrServiceWorkspaceWorkflowRestrictionPlugin.DISCOVER_WORKSPACE_CONFIGURATION_NAME; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.hasItems; +import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -21,6 +25,10 @@ import java.util.stream.Collectors; import jakarta.servlet.http.HttpServletRequest; +import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.SolrServerException; +import org.apache.solr.client.solrj.response.QueryResponse; +import org.apache.solr.common.SolrDocument; import org.dspace.AbstractIntegrationTestWithDatabase; import org.dspace.app.launcher.ScriptLauncher; import org.dspace.app.scripts.handler.impl.TestDSpaceRunnableHandler; @@ -99,6 +107,9 @@ public class DiscoveryIT extends AbstractIntegrationTestWithDatabase { MetadataAuthorityService metadataAuthorityService = ContentAuthorityServiceFactory.getInstance() .getMetadataAuthorityService(); + MockSolrSearchCore solrSearchCore = DSpaceServicesFactory.getInstance().getServiceManager() + .getServiceByName(null, MockSolrSearchCore.class); + @Override @Before public void setUp() throws Exception { @@ -796,6 +807,104 @@ public void searchWithDefaultSortServiceTest() throws SearchServiceException { } } + /** + * Test designed to check if the submitter is not indexed in all in solr documents for items + * and the submitter authority is still indexed + * @throws SearchServiceException + */ + @Test + public void searchWithNoSubmitterTest() throws SearchServiceException { + + configurationService.setProperty("discovery.index.item.submitter.enabled", false); + DiscoveryConfiguration defaultConf = SearchUtils.getDiscoveryConfiguration(context, "default", null); + + // Populate the testing objects: create items in eperson's workspace and perform search in it + int numberItems = 10; + context.turnOffAuthorisationSystem(); + EPerson submitter = null; + try { + submitter = EPersonBuilder.createEPerson(context).withEmail("submitter@example.org") + .withNameInMetadata("Peter", "Funny").build(); + } catch (SQLException e) { + throw new RuntimeException(e); + } + context.setCurrentUser(submitter); + Community community = CommunityBuilder.createCommunity(context).build(); + Collection collection = CollectionBuilder.createCollection(context, community).build(); + for (int i = 0; i < numberItems; i++) { + ItemBuilder.createItem(context, collection) + .withTitle("item " + i) + .build(); + } + context.restoreAuthSystemState(); + + // Build query with default parameters (except for workspaceConf) + QueryResponse result = null; + try { + result = solrSearchCore.getSolr().query(new SolrQuery(String.format( + "search.resourcetype:\"Item\""))); + } catch (SolrServerException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } + assertEquals(result.getResults().size(), numberItems); + for (SolrDocument doc : result.getResults()) { + assertThat(doc.getFieldNames(), + not(hasItems("submitter_keyword", "submitter_ac", "submitter_acid", "submitter_filter"))); + assertThat(doc.getFieldNames(), hasItem("submitter_authority")); + } + } + + /** + * Test designed to check if the submitter is indexed in all in solr documents for items + * @throws SearchServiceException + */ + @Test + public void searchWithSubmitterTest() throws SearchServiceException { + + configurationService.setProperty("discovery.index.item.submitter.enabled", true); + DiscoveryConfiguration defaultConf = SearchUtils.getDiscoveryConfiguration(context, "default", null); + + // Populate the testing objects: create items in eperson's workspace and perform search in it + int numberItems = 10; + context.turnOffAuthorisationSystem(); + EPerson submitter = null; + try { + submitter = EPersonBuilder.createEPerson(context).withEmail("submitter@example.org") + .withNameInMetadata("Peter", "Funny").build(); + } catch (SQLException e) { + throw new RuntimeException(e); + } + context.setCurrentUser(submitter); + Community community = CommunityBuilder.createCommunity(context).build(); + Collection collection = CollectionBuilder.createCollection(context, community).build(); + for (int i = 0; i < numberItems; i++) { + ItemBuilder.createItem(context, collection) + .withTitle("item " + i) + .build(); + } + context.restoreAuthSystemState(); + + // Build query with default parameters (except for workspaceConf) + QueryResponse result = null; + try { + result = solrSearchCore.getSolr().query(new SolrQuery(String.format( + "search.resourcetype:\"Item\""))); + } catch (SolrServerException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } + assertEquals(result.getResults().size(), numberItems); + for (SolrDocument doc : result.getResults()) { + for (String fieldname : doc.getFieldNames()) { + assertThat(doc.getFieldNames(), hasItems("submitter_keyword","submitter_ac", "submitter_filter", + "submitter_authority")); + } + } + } + private void assertSearchQuery(String resourceType, int size) throws SearchServiceException { assertSearchQuery(resourceType, size, size, 0, -1); } diff --git a/dspace/config/modules/discovery.cfg b/dspace/config/modules/discovery.cfg index 72088ddc49fa..cd8e8636c2e3 100644 --- a/dspace/config/modules/discovery.cfg +++ b/dspace/config/modules/discovery.cfg @@ -24,6 +24,11 @@ discovery.search.server = ${solr.server}/${solr.multicorePrefix}search # discovery.index.ignore-authority = false discovery.index.projection=dc.title,dc.contributor.*,dc.date.issued +# Restricts the indexing of the submitter for archived items +# By default the submitter information from the corresponding eperson is not indexed. +# If you set this value to true, than the submitter information is indexed and you will need to reindex search core +# discovery.index.item.submitter.enabled = false + # Allow auto-reindexing. # If any database migrations are applied to your database (via Flyway), then a # reindex flag is always written to '[dspace]/solr/search/conf/reindex.flag'. @@ -48,4 +53,4 @@ discovery.facet.namedtype.workflow.pooled = 004workflow\n|||\nWaiting for Contro # Set the number of retry of a query when stale objects are found. # Set to -1 if stale objects should be ignored. Set to 0 if you want to avoid extra query but take the chance to cleanup # the index each time that stale objects are found. Default 3 -discovery.removestale.attempts = 3 \ No newline at end of file +discovery.removestale.attempts = 3 From 59ea5cd0eea61f87a668a29d7233b45a33908586 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Mon, 28 Oct 2024 14:55:30 -0500 Subject: [PATCH 150/226] Create dependabot.yml --- .github/dependabot.yml | 115 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000000..6f4f3ae601a0 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,115 @@ +#------------------- +# DSpace's dependabot rules. Enables maven updates for all dependencies on a weekly basis +# for main and any maintenance branches. Security updates only apply to main. +#------------------- +version: 2 +updates: + - package-ecosystem: "maven" + directory: "/" + schedule: + interval: "weekly" + # Allow up to 10 open PRs for dependencies + open-pull-requests-limit: 10 + # Group together some upgrades in a single PR + groups: + # Group together all Build Tools in a single PR + build-tools: + applies-to: version-updates + patterns: + - "org.apache.maven.plugins:*" + - "*:*-maven-plugin" + - "*:maven-*-plugin" + - "com.github.spotbugs:spotbugs" + - "com.google.code.findbugs:*" + - "com.google.errorprone:*" + - "com.puppycrawl.tools:checkstyle" + - "org.sonatype.plugins:*" + update-types: + - "minor" + - "patch" + test-tools: + applies-to: version-updates + patterns: + - "junit:*" + - "com.github.stefanbirker:system-rules" + - "com.h2database:*" + - "io.findify:s3mock*" + - "io.netty:*" + - "org.hamcrest:*" + - "org.mock-server:*" + - "org.mockito:*" + update-types: + - "minor" + - "patch" + # Group together all Apache Commons deps in a single PR + apache-commons: + applies-to: version-updates + patterns: + - "org.apache.commons:*" + - "commons-*:commons-*" + update-types: + - "minor" + - "patch" + # Group together all fasterxml deps in a single PR + fasterxml: + applies-to: version-updates + patterns: + - "com.fasterxml:*" + - "com.fasterxml.*:*" + update-types: + - "minor" + - "patch" + # Group together all Hibernate deps in a single PR + hibernate: + applies-to: version-updates + patterns: + - "org.hibernate.*:*" + update-types: + - "minor" + - "patch" + # Group together all Jakarta deps in a single PR + jakarta: + applies-to: version-updates + patterns: + - "jakarta.*:*" + - "org.eclipse.angus:jakarta.mail" + - "org.glassfish.jaxb:jaxb-runtime" + update-types: + - "minor" + - "patch" + # Group together all Google deps in a single PR + google-apis: + applies-to: version-updates + patterns: + - "com.google.apis:*" + - "com.google.api-client:*" + - "com.google.http-client:*" + - "com.google.oauth-client:*" + update-types: + - "minor" + - "patch" + # Group together all Spring deps in a single PR + spring: + applies-to: version-updates + patterns: + - "org.springframework:*" + - "org.springframework.*:*" + update-types: + - "minor" + - "patch" + # Group together all WebJARs deps in a single PR + webjars: + applies-to: version-updates + patterns: + - "org.webjars:*" + - "org.webjars.*:*" + update-types: + - "minor" + - "patch" + ignore: + # Don't try to auto-update any DSpace dependencies + - dependency-name: "org.dspace:*" + - dependency-name: "org.dspace.*:*" + # Ignore all major version updates for all dependencies. We'll only automate minor/patch updates. + - dependency-name: "*" + update-types: ["version-update:semver-major"] From 5b46c94bb4d398275abefc688e4a31dcda809b69 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 29 Oct 2024 15:01:41 -0500 Subject: [PATCH 151/226] Exclude spring from build-tools group in dependabot.yml --- .github/dependabot.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 6f4f3ae601a0..b6412b25b660 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -24,6 +24,9 @@ updates: - "com.google.errorprone:*" - "com.puppycrawl.tools:checkstyle" - "org.sonatype.plugins:*" + exclude-patterns: + # Exclude anything from Spring, as that is in a separate group + - "org.springframework.*:*" update-types: - "minor" - "patch" From 666e146125bf63b4cb48876f30b76c54afb0eca3 Mon Sep 17 00:00:00 2001 From: Jens Vannerum Date: Tue, 2 Apr 2024 11:15:49 +0200 Subject: [PATCH 152/226] 113811: cli logs should be written to a different file (cherry picked from commit d30468a09fbbd288df6cf2556e1a630f040801d1) --- dspace/bin/dspace | 2 + dspace/config/log4j2-cli.xml | 105 +++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 dspace/config/log4j2-cli.xml diff --git a/dspace/bin/dspace b/dspace/bin/dspace index 7d5d678d0f6e..24644aae9112 100644 --- a/dspace/bin/dspace +++ b/dspace/bin/dspace @@ -39,6 +39,8 @@ if [ "$JAVA_OPTS" = "" ]; then JAVA_OPTS="-Xmx256m -Dfile.encoding=UTF-8" fi +export JAVA_OPTS="$JAVA_OPTS -Dlog4j2.configurationFile=$DSPACEDIR/config/log4j2-cli.xml" + # Now invoke Java java $JAVA_OPTS \ -classpath $FULLPATH \ diff --git a/dspace/config/log4j2-cli.xml b/dspace/config/log4j2-cli.xml new file mode 100644 index 000000000000..24d36fd12efb --- /dev/null +++ b/dspace/config/log4j2-cli.xml @@ -0,0 +1,105 @@ + + + + + + + ${log4j:configParentLocation}/../log + + + INFO + + + INFO + + + + + + + + + yyyy-MM-dd + + + + + + + + + yyyy-MM-dd + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 5a2488ac48628ae906979aa064d5890be5e258f1 Mon Sep 17 00:00:00 2001 From: Kevin Van de Velde Date: Fri, 6 Sep 2024 10:15:08 +0200 Subject: [PATCH 153/226] Modifying it so that the cli file content is stored in a file using the date (cherry picked from commit 529c3a77c15f401fe623b2c9d04a438754a1d72d) --- dspace/config/log4j2-cli.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/dspace/config/log4j2-cli.xml b/dspace/config/log4j2-cli.xml index 24d36fd12efb..73acab877f1f 100644 --- a/dspace/config/log4j2-cli.xml +++ b/dspace/config/log4j2-cli.xml @@ -25,8 +25,6 @@ From 262be99d4e3b8cf5c1321eabc6072e40a4e3fdf7 Mon Sep 17 00:00:00 2001 From: Jens Vannerum Date: Wed, 4 Dec 2024 11:08:37 +0100 Subject: [PATCH 154/226] apply fix to windows env and remove duplicate logging for checksum checker (cherry picked from commit 9f39a3d6a53f9a815509d6a47abd176b07a6a86c) --- dspace/bin/dspace.bat | 3 +++ dspace/config/log4j2.xml | 27 --------------------------- 2 files changed, 3 insertions(+), 27 deletions(-) diff --git a/dspace/bin/dspace.bat b/dspace/bin/dspace.bat index 2288127c447a..768b1061762d 100644 --- a/dspace/bin/dspace.bat +++ b/dspace/bin/dspace.bat @@ -38,6 +38,9 @@ REM If JAVA_OPTS specified, use those options REM Otherwise, default Java to using 256MB of memory if "%JAVA_OPTS%"=="" set "JAVA_OPTS=-Xmx256m -Dfile.encoding=UTF-8" +REM Add log4j2 configuration to JAVA_OPTS +set "JAVA_OPTS=%JAVA_OPTS% -Dlog4j2.configurationFile=%cd%\config\log4j2-cli.xml" + REM Execute Java java %JAVA_OPTS% -classpath "%DSPACE_CLASSPATH%" org.dspace.app.launcher.ScriptLauncher %* diff --git a/dspace/config/log4j2.xml b/dspace/config/log4j2.xml index 6e9a43e4f0fe..4f212d128dc6 100644 --- a/dspace/config/log4j2.xml +++ b/dspace/config/log4j2.xml @@ -44,26 +44,6 @@ --> - - - - - - yyyy-MM-dd - - - @@ -75,13 +55,6 @@ - - - - - From f99755852b0b8c7a80fda12d5d85d58e47f92ce4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 21:00:58 +0000 Subject: [PATCH 155/226] Bump the build-tools group with 24 updates Bumps the build-tools group with 24 updates: | Package | From | To | | --- | --- | --- | | [com.google.errorprone:error_prone_core](https://github.com/google/error-prone) | `2.10.0` | `2.36.0` | | [com.google.errorprone:error_prone_annotations](https://github.com/google/error-prone) | `2.10.0` | `2.36.0` | | [com.puppycrawl.tools:checkstyle](https://github.com/checkstyle/checkstyle) | `8.38` | `8.45.1` | | [com.github.spotbugs:spotbugs](https://github.com/spotbugs/spotbugs) | `4.8.2` | `4.8.6` | | [org.apache.maven.plugins:maven-enforcer-plugin](https://github.com/apache/maven-enforcer) | `3.4.1` | `3.5.0` | | [org.apache.maven.plugins:maven-jar-plugin](https://github.com/apache/maven-jar-plugin) | `3.3.0` | `3.4.2` | | [org.apache.maven.plugins:maven-surefire-plugin](https://github.com/apache/maven-surefire) | `3.2.5` | `3.5.2` | | [org.apache.maven.plugins:maven-failsafe-plugin](https://github.com/apache/maven-surefire) | `3.2.5` | `3.5.2` | | [org.apache.maven.plugins:maven-checkstyle-plugin](https://github.com/apache/maven-checkstyle-plugin) | `3.3.1` | `3.6.0` | | [com.github.spotbugs:spotbugs-maven-plugin](https://github.com/spotbugs/spotbugs-maven-plugin) | `4.8.2.0` | `4.8.6.6` | | [org.apache.maven.plugins:maven-clean-plugin](https://github.com/apache/maven-clean-plugin) | `3.3.2` | `3.4.0` | | [org.apache.maven.plugins:maven-dependency-plugin](https://github.com/apache/maven-dependency-plugin) | `3.6.1` | `3.8.1` | | org.sonatype.plugins:nexus-staging-maven-plugin | `1.6.13` | `1.7.0` | | [org.apache.maven.plugins:maven-javadoc-plugin](https://github.com/apache/maven-javadoc-plugin) | `3.6.3` | `3.11.2` | | [org.apache.maven.plugins:maven-source-plugin](https://github.com/apache/maven-source-plugin) | `3.3.0` | `3.3.1` | | [org.apache.maven.plugins:maven-gpg-plugin](https://github.com/apache/maven-gpg-plugin) | `3.2.1` | `3.2.7` | | [org.jacoco:jacoco-maven-plugin](https://github.com/jacoco/jacoco) | `0.8.11` | `0.8.12` | | [org.apache.maven.plugins:maven-release-plugin](https://github.com/apache/maven-release) | `3.0.0` | `3.1.1` | | [org.codehaus.mojo:xml-maven-plugin](https://github.com/mojohaus/xml-maven-plugin) | `1.0.2` | `1.1.0` | | [org.codehaus.mojo:license-maven-plugin](https://github.com/mojohaus/license-maven-plugin) | `2.0.0` | `2.5.0` | | [org.codehaus.mojo:build-helper-maven-plugin](https://github.com/mojohaus/build-helper-maven-plugin) | `3.4.0` | `3.6.0` | | [org.codehaus.mojo:buildnumber-maven-plugin](https://github.com/mojohaus/buildnumber-maven-plugin) | `3.2.0` | `3.2.1` | | [org.codehaus.mojo:jaxb2-maven-plugin](https://github.com/mojohaus/jaxb2-maven-plugin) | `3.1.0` | `3.2.0` | | [org.codehaus.mojo:properties-maven-plugin](https://github.com/mojohaus/properties-maven-plugin) | `1.1.0` | `1.2.1` | Updates `com.google.errorprone:error_prone_core` from 2.10.0 to 2.36.0 - [Release notes](https://github.com/google/error-prone/releases) - [Commits](https://github.com/google/error-prone/compare/v2.10.0...v2.36.0) Updates `com.google.errorprone:error_prone_annotations` from 2.10.0 to 2.36.0 - [Release notes](https://github.com/google/error-prone/releases) - [Commits](https://github.com/google/error-prone/compare/v2.10.0...v2.36.0) Updates `com.puppycrawl.tools:checkstyle` from 8.38 to 8.45.1 - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-8.38...checkstyle-8.45.1) Updates `com.github.spotbugs:spotbugs` from 4.8.2 to 4.8.6 - [Release notes](https://github.com/spotbugs/spotbugs/releases) - [Changelog](https://github.com/spotbugs/spotbugs/blob/master/CHANGELOG.md) - [Commits](https://github.com/spotbugs/spotbugs/compare/4.8.2...4.8.6) Updates `com.google.errorprone:error_prone_annotations` from 2.10.0 to 2.36.0 - [Release notes](https://github.com/google/error-prone/releases) - [Commits](https://github.com/google/error-prone/compare/v2.10.0...v2.36.0) Updates `org.apache.maven.plugins:maven-enforcer-plugin` from 3.4.1 to 3.5.0 - [Release notes](https://github.com/apache/maven-enforcer/releases) - [Commits](https://github.com/apache/maven-enforcer/compare/enforcer-3.4.1...enforcer-3.5.0) Updates `org.apache.maven.plugins:maven-jar-plugin` from 3.3.0 to 3.4.2 - [Release notes](https://github.com/apache/maven-jar-plugin/releases) - [Commits](https://github.com/apache/maven-jar-plugin/compare/maven-jar-plugin-3.3.0...maven-jar-plugin-3.4.2) Updates `org.apache.maven.plugins:maven-surefire-plugin` from 3.2.5 to 3.5.2 - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.2.5...surefire-3.5.2) Updates `org.apache.maven.plugins:maven-failsafe-plugin` from 3.2.5 to 3.5.2 - [Release notes](https://github.com/apache/maven-surefire/releases) - [Commits](https://github.com/apache/maven-surefire/compare/surefire-3.2.5...surefire-3.5.2) Updates `org.apache.maven.plugins:maven-checkstyle-plugin` from 3.3.1 to 3.6.0 - [Commits](https://github.com/apache/maven-checkstyle-plugin/compare/maven-checkstyle-plugin-3.3.1...maven-checkstyle-plugin-3.6.0) Updates `com.github.spotbugs:spotbugs-maven-plugin` from 4.8.2.0 to 4.8.6.6 - [Release notes](https://github.com/spotbugs/spotbugs-maven-plugin/releases) - [Commits](https://github.com/spotbugs/spotbugs-maven-plugin/compare/spotbugs-maven-plugin-4.8.2.0...spotbugs-maven-plugin-4.8.6.6) Updates `org.apache.maven.plugins:maven-clean-plugin` from 3.3.2 to 3.4.0 - [Release notes](https://github.com/apache/maven-clean-plugin/releases) - [Commits](https://github.com/apache/maven-clean-plugin/compare/maven-clean-plugin-3.3.2...maven-clean-plugin-3.4.0) Updates `org.apache.maven.plugins:maven-dependency-plugin` from 3.6.1 to 3.8.1 - [Release notes](https://github.com/apache/maven-dependency-plugin/releases) - [Commits](https://github.com/apache/maven-dependency-plugin/compare/maven-dependency-plugin-3.6.1...maven-dependency-plugin-3.8.1) Updates `org.sonatype.plugins:nexus-staging-maven-plugin` from 1.6.13 to 1.7.0 Updates `org.apache.maven.plugins:maven-javadoc-plugin` from 3.6.3 to 3.11.2 - [Release notes](https://github.com/apache/maven-javadoc-plugin/releases) - [Commits](https://github.com/apache/maven-javadoc-plugin/compare/maven-javadoc-plugin-3.6.3...maven-javadoc-plugin-3.11.2) Updates `org.apache.maven.plugins:maven-source-plugin` from 3.3.0 to 3.3.1 - [Release notes](https://github.com/apache/maven-source-plugin/releases) - [Commits](https://github.com/apache/maven-source-plugin/compare/maven-source-plugin-3.3.0...maven-source-plugin-3.3.1) Updates `org.apache.maven.plugins:maven-gpg-plugin` from 3.2.1 to 3.2.7 - [Release notes](https://github.com/apache/maven-gpg-plugin/releases) - [Commits](https://github.com/apache/maven-gpg-plugin/compare/maven-gpg-plugin-3.2.1...maven-gpg-plugin-3.2.7) Updates `org.jacoco:jacoco-maven-plugin` from 0.8.11 to 0.8.12 - [Release notes](https://github.com/jacoco/jacoco/releases) - [Commits](https://github.com/jacoco/jacoco/compare/v0.8.11...v0.8.12) Updates `org.apache.maven.plugins:maven-release-plugin` from 3.0.0 to 3.1.1 - [Release notes](https://github.com/apache/maven-release/releases) - [Commits](https://github.com/apache/maven-release/compare/maven-release-3.0.0...maven-release-3.1.1) Updates `org.codehaus.mojo:xml-maven-plugin` from 1.0.2 to 1.1.0 - [Release notes](https://github.com/mojohaus/xml-maven-plugin/releases) - [Commits](https://github.com/mojohaus/xml-maven-plugin/compare/xml-maven-plugin-1.0.2...1.1.0) Updates `org.codehaus.mojo:license-maven-plugin` from 2.0.0 to 2.5.0 - [Release notes](https://github.com/mojohaus/license-maven-plugin/releases) - [Commits](https://github.com/mojohaus/license-maven-plugin/compare/license-maven-plugin-2.0.0...2.5.0) Updates `org.codehaus.mojo:build-helper-maven-plugin` from 3.4.0 to 3.6.0 - [Release notes](https://github.com/mojohaus/build-helper-maven-plugin/releases) - [Commits](https://github.com/mojohaus/build-helper-maven-plugin/compare/3.4.0...3.6.0) Updates `org.codehaus.mojo:buildnumber-maven-plugin` from 3.2.0 to 3.2.1 - [Release notes](https://github.com/mojohaus/buildnumber-maven-plugin/releases) - [Commits](https://github.com/mojohaus/buildnumber-maven-plugin/compare/3.2.0...3.2.1) Updates `org.codehaus.mojo:jaxb2-maven-plugin` from 3.1.0 to 3.2.0 - [Release notes](https://github.com/mojohaus/jaxb2-maven-plugin/releases) - [Commits](https://github.com/mojohaus/jaxb2-maven-plugin/compare/jaxb2-maven-plugin-3.1.0...jaxb2-maven-plugin-3.2.0) Updates `org.codehaus.mojo:properties-maven-plugin` from 1.1.0 to 1.2.1 - [Release notes](https://github.com/mojohaus/properties-maven-plugin/releases) - [Commits](https://github.com/mojohaus/properties-maven-plugin/compare/properties-maven-plugin-1.1.0...1.2.1) --- updated-dependencies: - dependency-name: com.google.errorprone:error_prone_core dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tools - dependency-name: com.google.errorprone:error_prone_annotations dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tools - dependency-name: com.puppycrawl.tools:checkstyle dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tools - dependency-name: com.github.spotbugs:spotbugs dependency-type: direct:production update-type: version-update:semver-patch dependency-group: build-tools - dependency-name: com.google.errorprone:error_prone_annotations dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tools - dependency-name: org.apache.maven.plugins:maven-enforcer-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tools - dependency-name: org.apache.maven.plugins:maven-jar-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tools - dependency-name: org.apache.maven.plugins:maven-surefire-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tools - dependency-name: org.apache.maven.plugins:maven-failsafe-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tools - dependency-name: org.apache.maven.plugins:maven-checkstyle-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tools - dependency-name: com.github.spotbugs:spotbugs-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch dependency-group: build-tools - dependency-name: org.apache.maven.plugins:maven-clean-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tools - dependency-name: org.apache.maven.plugins:maven-dependency-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tools - dependency-name: org.sonatype.plugins:nexus-staging-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tools - dependency-name: org.apache.maven.plugins:maven-javadoc-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tools - dependency-name: org.apache.maven.plugins:maven-source-plugin dependency-type: direct:production update-type: version-update:semver-patch dependency-group: build-tools - dependency-name: org.apache.maven.plugins:maven-gpg-plugin dependency-type: direct:production update-type: version-update:semver-patch dependency-group: build-tools - dependency-name: org.jacoco:jacoco-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch dependency-group: build-tools - dependency-name: org.apache.maven.plugins:maven-release-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tools - dependency-name: org.codehaus.mojo:xml-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tools - dependency-name: org.codehaus.mojo:license-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tools - dependency-name: org.codehaus.mojo:build-helper-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tools - dependency-name: org.codehaus.mojo:buildnumber-maven-plugin dependency-type: direct:production update-type: version-update:semver-patch dependency-group: build-tools - dependency-name: org.codehaus.mojo:jaxb2-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tools - dependency-name: org.codehaus.mojo:properties-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: build-tools ... Signed-off-by: dependabot[bot] --- dspace-api/pom.xml | 6 +++--- dspace-server-webapp/pom.xml | 2 +- pom.xml | 38 ++++++++++++++++++------------------ 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index 58bd8106e9af..d5e2f51b883b 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -102,7 +102,7 @@ org.codehaus.mojo build-helper-maven-plugin - 3.4.0 + 3.6.0 validate @@ -116,7 +116,7 @@ org.codehaus.mojo buildnumber-maven-plugin - 3.2.0 + 3.2.1 UNKNOWN_REVISION @@ -177,7 +177,7 @@ org.codehaus.mojo jaxb2-maven-plugin - 3.1.0 + 3.2.0 workflow-curation diff --git a/dspace-server-webapp/pom.xml b/dspace-server-webapp/pom.xml index 290f8afb0dc6..7adf63aa01ef 100644 --- a/dspace-server-webapp/pom.xml +++ b/dspace-server-webapp/pom.xml @@ -31,7 +31,7 @@ org.codehaus.mojo properties-maven-plugin - 1.1.0 + 1.2.1 initialize diff --git a/pom.xml b/pom.xml index bb093621ff2f..7a2f9792aa7a 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ 8.11.3 3.10.8 - 2.10.0 + 2.36.0 2.16.0 2.16.0 @@ -89,7 +89,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 3.4.1 + 3.5.0 enforce-java @@ -176,7 +176,7 @@ org.apache.maven.plugins maven-jar-plugin - 3.3.0 + 3.4.2 @@ -207,7 +207,7 @@ org.apache.maven.plugins maven-surefire-plugin - 3.2.5 + 3.5.2 @@ -234,7 +234,7 @@ maven-failsafe-plugin - 3.2.5 + 3.5.2 @@ -266,7 +266,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 3.3.1 + 3.6.0 verify-style @@ -295,14 +295,14 @@ com.puppycrawl.tools checkstyle - 8.38 + 8.45.1 com.github.spotbugs spotbugs-maven-plugin - 4.8.2.0 + 4.8.6.6 Max Low @@ -312,7 +312,7 @@ com.github.spotbugs spotbugs - 4.8.2 + 4.8.6 @@ -328,7 +328,7 @@ maven-clean-plugin - 3.3.2 + 3.4.0 @@ -347,7 +347,7 @@ org.apache.maven.plugins maven-dependency-plugin - 3.6.1 + 3.8.1 org.apache.maven.plugins @@ -364,13 +364,13 @@ org.sonatype.plugins nexus-staging-maven-plugin - 1.6.13 + 1.7.0 org.apache.maven.plugins maven-javadoc-plugin - 3.6.3 + 3.11.2 false @@ -385,7 +385,7 @@ org.apache.maven.plugins maven-source-plugin - 3.3.0 + 3.3.1 @@ -398,13 +398,13 @@ org.apache.maven.plugins maven-gpg-plugin - 3.2.1 + 3.2.7 org.jacoco jacoco-maven-plugin - 0.8.11 + 0.8.12 @@ -416,7 +416,7 @@ org.apache.maven.plugins maven-release-plugin - 3.0.0 + 3.1.1 @@ -484,7 +484,7 @@ org.codehaus.mojo xml-maven-plugin - 1.0.2 + 1.1.0 validate-ALL-xml-and-xsl @@ -692,7 +692,7 @@ org.codehaus.mojo license-maven-plugin - 2.0.0 + 2.5.0 false From 3352a0a9c36c363f54505958a3e8ebf3d8be1949 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 21:01:11 +0000 Subject: [PATCH 156/226] Bump the test-tools group with 2 updates Bumps the test-tools group with 2 updates: [com.h2database:h2](https://github.com/h2database/h2database) and [org.mock-server:mockserver-junit-rule](https://github.com/jamesdbloom/mockservice). Updates `com.h2database:h2` from 2.2.224 to 2.3.232 - [Release notes](https://github.com/h2database/h2database/releases) - [Commits](https://github.com/h2database/h2database/compare/version-2.2.224...version-2.3.232) Updates `org.mock-server:mockserver-junit-rule` from 5.11.2 to 5.15.0 - [Changelog](https://github.com/mock-server/mockserver/blob/master/changelog.md) - [Commits](https://github.com/jamesdbloom/mockservice/compare/mockserver-5.11.2...mockserver-5.15.0) --- updated-dependencies: - dependency-name: com.h2database:h2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: test-tools - dependency-name: org.mock-server:mockserver-junit-rule dependency-type: direct:development update-type: version-update:semver-minor dependency-group: test-tools ... Signed-off-by: dependabot[bot] --- dspace-api/pom.xml | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index 58bd8106e9af..16704f7bf294 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -824,7 +824,7 @@ org.mock-server mockserver-junit-rule - 5.11.2 + 5.15.0 test diff --git a/pom.xml b/pom.xml index bb093621ff2f..0d8539ba5209 100644 --- a/pom.xml +++ b/pom.xml @@ -1708,7 +1708,7 @@ com.h2database h2 - 2.2.224 + 2.3.232 test From f9fbc237bf30445ec679dff4c36b53a4f9e96de9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 21:01:37 +0000 Subject: [PATCH 157/226] Bump the apache-commons group with 12 updates Bumps the apache-commons group with 12 updates: | Package | From | To | | --- | --- | --- | | commons-beanutils:commons-beanutils | `1.9.4` | `1.10.0` | | commons-cli:commons-cli | `1.6.0` | `1.9.0` | | [commons-codec:commons-codec](https://github.com/apache/commons-codec) | `1.16.0` | `1.17.2` | | org.apache.commons:commons-configuration2 | `2.10.1` | `2.11.0` | | org.apache.commons:commons-dbcp2 | `2.11.0` | `2.13.0` | | commons-io:commons-io | `2.15.1` | `2.18.0` | | org.apache.commons:commons-lang3 | `3.14.0` | `3.17.0` | | commons-logging:commons-logging | `1.3.0` | `1.3.4` | | org.apache.commons:commons-compress | `1.26.0` | `1.27.1` | | [org.apache.commons:commons-csv](https://github.com/apache/commons-csv) | `1.10.0` | `1.13.0` | | org.apache.commons:commons-text | `1.10.0` | `1.13.0` | | commons-validator:commons-validator | `1.7` | `1.9.0` | Updates `commons-beanutils:commons-beanutils` from 1.9.4 to 1.10.0 Updates `commons-cli:commons-cli` from 1.6.0 to 1.9.0 Updates `commons-codec:commons-codec` from 1.16.0 to 1.17.2 - [Changelog](https://github.com/apache/commons-codec/blob/master/RELEASE-NOTES.txt) - [Commits](https://github.com/apache/commons-codec/compare/rel/commons-codec-1.16.0...rel/commons-codec-1.17.2) Updates `org.apache.commons:commons-configuration2` from 2.10.1 to 2.11.0 Updates `org.apache.commons:commons-dbcp2` from 2.11.0 to 2.13.0 Updates `commons-io:commons-io` from 2.15.1 to 2.18.0 Updates `org.apache.commons:commons-lang3` from 3.14.0 to 3.17.0 Updates `commons-logging:commons-logging` from 1.3.0 to 1.3.4 Updates `org.apache.commons:commons-compress` from 1.26.0 to 1.27.1 Updates `org.apache.commons:commons-csv` from 1.10.0 to 1.13.0 - [Changelog](https://github.com/apache/commons-csv/blob/master/RELEASE-NOTES.txt) - [Commits](https://github.com/apache/commons-csv/compare/rel/commons-csv-1.10.0...rel/commons-csv-1.13.0) Updates `org.apache.commons:commons-text` from 1.10.0 to 1.13.0 Updates `commons-validator:commons-validator` from 1.7 to 1.9.0 --- updated-dependencies: - dependency-name: commons-beanutils:commons-beanutils dependency-type: direct:production update-type: version-update:semver-minor dependency-group: apache-commons - dependency-name: commons-cli:commons-cli dependency-type: direct:production update-type: version-update:semver-minor dependency-group: apache-commons - dependency-name: commons-codec:commons-codec dependency-type: direct:production update-type: version-update:semver-minor dependency-group: apache-commons - dependency-name: org.apache.commons:commons-configuration2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: apache-commons - dependency-name: org.apache.commons:commons-dbcp2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: apache-commons - dependency-name: commons-io:commons-io dependency-type: direct:production update-type: version-update:semver-minor dependency-group: apache-commons - dependency-name: org.apache.commons:commons-lang3 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: apache-commons - dependency-name: commons-logging:commons-logging dependency-type: direct:production update-type: version-update:semver-patch dependency-group: apache-commons - dependency-name: org.apache.commons:commons-compress dependency-type: direct:production update-type: version-update:semver-minor dependency-group: apache-commons - dependency-name: org.apache.commons:commons-csv dependency-type: direct:production update-type: version-update:semver-minor dependency-group: apache-commons - dependency-name: org.apache.commons:commons-text dependency-type: direct:production update-type: version-update:semver-minor dependency-group: apache-commons - dependency-name: commons-validator:commons-validator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: apache-commons ... Signed-off-by: dependabot[bot] --- pom.xml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pom.xml b/pom.xml index bb093621ff2f..c24ed556bfcb 100644 --- a/pom.xml +++ b/pom.xml @@ -1461,17 +1461,17 @@ commons-beanutils commons-beanutils - 1.9.4 + 1.10.0 commons-cli commons-cli - 1.6.0 + 1.9.0 commons-codec commons-codec - 1.16.0 + 1.17.2 org.apache.commons @@ -1481,12 +1481,12 @@ org.apache.commons commons-configuration2 - 2.10.1 + 2.11.0 org.apache.commons commons-dbcp2 - 2.11.0 + 2.13.0 @@ -1498,29 +1498,29 @@ commons-io commons-io - 2.15.1 + 2.18.0 org.apache.commons commons-lang3 - 3.14.0 + 3.17.0 commons-logging commons-logging - 1.3.0 + 1.3.4 org.apache.commons commons-compress - 1.26.0 + 1.27.1 org.apache.commons commons-csv - 1.10.0 + 1.13.0 org.apache.commons @@ -1530,12 +1530,12 @@ org.apache.commons commons-text - 1.10.0 + 1.13.0 commons-validator commons-validator - 1.7 + 1.9.0 joda-time From b4d209368c6da68897092a8ae74e72c48de17ecf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 21:01:53 +0000 Subject: [PATCH 158/226] Bump the fasterxml group with 5 updates Bumps the fasterxml group with 5 updates: | Package | From | To | | --- | --- | --- | | [com.fasterxml:classmate](https://github.com/FasterXML/java-classmate) | `1.6.0` | `1.7.0` | | [com.fasterxml.jackson.core:jackson-annotations](https://github.com/FasterXML/jackson) | `2.16.0` | `2.18.2` | | [com.fasterxml.jackson.core:jackson-core](https://github.com/FasterXML/jackson-core) | `2.16.0` | `2.18.2` | | [com.fasterxml.jackson.core:jackson-databind](https://github.com/FasterXML/jackson) | `2.16.0` | `2.18.2` | | com.fasterxml.jackson.datatype:jackson-datatype-jsr310 | `2.16.0` | `2.18.2` | Updates `com.fasterxml:classmate` from 1.6.0 to 1.7.0 - [Commits](https://github.com/FasterXML/java-classmate/compare/classmate-1.6.0...classmate-1.7.0) Updates `com.fasterxml.jackson.core:jackson-annotations` from 2.16.0 to 2.18.2 - [Commits](https://github.com/FasterXML/jackson/commits) Updates `com.fasterxml.jackson.core:jackson-core` from 2.16.0 to 2.18.2 - [Commits](https://github.com/FasterXML/jackson-core/compare/jackson-core-2.16.0...jackson-core-2.18.2) Updates `com.fasterxml.jackson.core:jackson-core` from 2.16.0 to 2.18.2 - [Commits](https://github.com/FasterXML/jackson-core/compare/jackson-core-2.16.0...jackson-core-2.18.2) Updates `com.fasterxml.jackson.core:jackson-databind` from 2.16.0 to 2.18.2 - [Commits](https://github.com/FasterXML/jackson/commits) Updates `com.fasterxml.jackson.datatype:jackson-datatype-jsr310` from 2.16.0 to 2.18.2 Updates `com.fasterxml.jackson.datatype:jackson-datatype-jsr310` from 2.16.0 to 2.18.2 --- updated-dependencies: - dependency-name: com.fasterxml:classmate dependency-type: direct:production update-type: version-update:semver-minor dependency-group: fasterxml - dependency-name: com.fasterxml.jackson.core:jackson-annotations dependency-type: direct:production update-type: version-update:semver-minor dependency-group: fasterxml - dependency-name: com.fasterxml.jackson.core:jackson-core dependency-type: direct:production update-type: version-update:semver-minor dependency-group: fasterxml - dependency-name: com.fasterxml.jackson.core:jackson-core dependency-type: direct:production update-type: version-update:semver-minor dependency-group: fasterxml - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production update-type: version-update:semver-minor dependency-group: fasterxml - dependency-name: com.fasterxml.jackson.datatype:jackson-datatype-jsr310 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: fasterxml - dependency-name: com.fasterxml.jackson.datatype:jackson-datatype-jsr310 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: fasterxml ... Signed-off-by: dependabot[bot] --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index bb093621ff2f..9f34b01d1d6e 100644 --- a/pom.xml +++ b/pom.xml @@ -31,8 +31,8 @@ 3.10.8 2.10.0 - 2.16.0 - 2.16.0 + 2.18.2 + 2.18.2 2.1.1 4.0.2 4.0.5 @@ -1736,7 +1736,7 @@ com.fasterxml classmate - 1.6.0 + 1.7.0 com.fasterxml.jackson.core From f57c927a2e6440aa929dab7767d475864bdcf427 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 21:02:32 +0000 Subject: [PATCH 159/226] Bump jakarta.servlet:jakarta.servlet-api in the jakarta group Bumps the jakarta group with 1 update: [jakarta.servlet:jakarta.servlet-api](https://github.com/eclipse-ee4j/servlet-api). Updates `jakarta.servlet:jakarta.servlet-api` from 6.0.0 to 6.1.0 - [Commits](https://github.com/eclipse-ee4j/servlet-api/compare/6.0.0-RELEASE...6.1.0-RELEASE) --- updated-dependencies: - dependency-name: jakarta.servlet:jakarta.servlet-api dependency-type: direct:production update-type: version-update:semver-minor dependency-group: jakarta ... Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bb093621ff2f..1e837f48c04e 100644 --- a/pom.xml +++ b/pom.xml @@ -1569,7 +1569,7 @@ jakarta.servlet jakarta.servlet-api - 6.0.0 + 6.1.0 jakarta.el From bff9792ff1411f9a23780aa4ceaf1e48003eef6f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 21:04:19 +0000 Subject: [PATCH 160/226] Bump the spring group with 24 updates Bumps the spring group with 24 updates: | Package | From | To | | --- | --- | --- | | [org.springframework:spring-orm](https://github.com/spring-projects/spring-framework) | `6.1.14` | `6.2.1` | | [org.springframework:spring-core](https://github.com/spring-projects/spring-framework) | `6.1.14` | `6.2.1` | | [org.springframework:spring-beans](https://github.com/spring-projects/spring-framework) | `6.1.14` | `6.2.1` | | [org.springframework:spring-aop](https://github.com/spring-projects/spring-framework) | `6.1.14` | `6.2.1` | | [org.springframework:spring-context](https://github.com/spring-projects/spring-framework) | `6.1.14` | `6.2.1` | | [org.springframework:spring-context-support](https://github.com/spring-projects/spring-framework) | `6.1.14` | `6.2.1` | | [org.springframework:spring-tx](https://github.com/spring-projects/spring-framework) | `6.1.14` | `6.2.1` | | [org.springframework:spring-jdbc](https://github.com/spring-projects/spring-framework) | `6.1.14` | `6.2.1` | | [org.springframework:spring-web](https://github.com/spring-projects/spring-framework) | `6.1.14` | `6.2.1` | | [org.springframework:spring-webmvc](https://github.com/spring-projects/spring-framework) | `6.1.14` | `6.2.1` | | [org.springframework:spring-expression](https://github.com/spring-projects/spring-framework) | `6.1.14` | `6.2.1` | | [org.springframework:spring-test](https://github.com/spring-projects/spring-framework) | `6.1.14` | `6.2.1` | | [org.springframework.boot:spring-boot-starter-test](https://github.com/spring-projects/spring-boot) | `3.3.4` | `3.4.1` | | [org.springframework.boot:spring-boot-starter-tomcat](https://github.com/spring-projects/spring-boot) | `3.3.4` | `3.4.1` | | [org.springframework.boot:spring-boot-maven-plugin](https://github.com/spring-projects/spring-boot) | `3.3.4` | `3.4.1` | | [org.springframework.boot:spring-boot-starter-cache](https://github.com/spring-projects/spring-boot) | `3.3.4` | `3.4.1` | | [org.springframework.boot:spring-boot-starter](https://github.com/spring-projects/spring-boot) | `3.3.4` | `3.4.1` | | [org.springframework.boot:spring-boot-starter-web](https://github.com/spring-projects/spring-boot) | `3.3.4` | `3.4.1` | | [org.springframework.boot:spring-boot-starter-data-rest](https://github.com/spring-projects/spring-boot) | `3.3.4` | `3.4.1` | | [org.springframework.boot:spring-boot-starter-security](https://github.com/spring-projects/spring-boot) | `3.3.4` | `3.4.1` | | [org.springframework.boot:spring-boot-starter-aop](https://github.com/spring-projects/spring-boot) | `3.3.4` | `3.4.1` | | [org.springframework.boot:spring-boot-starter-actuator](https://github.com/spring-projects/spring-boot) | `3.3.4` | `3.4.1` | | [org.springframework.boot:spring-boot-starter-log4j2](https://github.com/spring-projects/spring-boot) | `3.3.4` | `3.4.1` | | [org.springframework.security:spring-security-test](https://github.com/spring-projects/spring-security) | `6.3.3` | `6.4.2` | Updates `org.springframework:spring-orm` from 6.1.14 to 6.2.1 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.1) Updates `org.springframework:spring-core` from 6.1.14 to 6.2.1 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.1) Updates `org.springframework:spring-beans` from 6.1.14 to 6.2.1 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.1) Updates `org.springframework:spring-aop` from 6.1.14 to 6.2.1 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.1) Updates `org.springframework:spring-context` from 6.1.14 to 6.2.1 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.1) Updates `org.springframework:spring-context-support` from 6.1.14 to 6.2.1 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.1) Updates `org.springframework:spring-tx` from 6.1.14 to 6.2.1 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.1) Updates `org.springframework:spring-jdbc` from 6.1.14 to 6.2.1 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.1) Updates `org.springframework:spring-web` from 6.1.14 to 6.2.1 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.1) Updates `org.springframework:spring-webmvc` from 6.1.14 to 6.2.1 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.1) Updates `org.springframework:spring-expression` from 6.1.14 to 6.2.1 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.1) Updates `org.springframework:spring-test` from 6.1.14 to 6.2.1 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.1) Updates `org.springframework:spring-core` from 6.1.14 to 6.2.1 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.1) Updates `org.springframework:spring-beans` from 6.1.14 to 6.2.1 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.1) Updates `org.springframework:spring-aop` from 6.1.14 to 6.2.1 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.1) Updates `org.springframework:spring-context` from 6.1.14 to 6.2.1 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.1) Updates `org.springframework:spring-context-support` from 6.1.14 to 6.2.1 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.1) Updates `org.springframework:spring-tx` from 6.1.14 to 6.2.1 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.1) Updates `org.springframework:spring-jdbc` from 6.1.14 to 6.2.1 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.1) Updates `org.springframework:spring-web` from 6.1.14 to 6.2.1 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.1) Updates `org.springframework:spring-webmvc` from 6.1.14 to 6.2.1 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.1) Updates `org.springframework:spring-expression` from 6.1.14 to 6.2.1 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.1) Updates `org.springframework:spring-test` from 6.1.14 to 6.2.1 - [Release notes](https://github.com/spring-projects/spring-framework/releases) - [Commits](https://github.com/spring-projects/spring-framework/compare/v6.1.14...v6.2.1) Updates `org.springframework.boot:spring-boot-starter-test` from 3.3.4 to 3.4.1 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.4.1) Updates `org.springframework.boot:spring-boot-starter-tomcat` from 3.3.4 to 3.4.1 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.4.1) Updates `org.springframework.boot:spring-boot-maven-plugin` from 3.3.4 to 3.4.1 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.4.1) Updates `org.springframework.boot:spring-boot-starter-cache` from 3.3.4 to 3.4.1 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.4.1) Updates `org.springframework.boot:spring-boot-starter` from 3.3.4 to 3.4.1 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.4.1) Updates `org.springframework.boot:spring-boot-starter-web` from 3.3.4 to 3.4.1 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.4.1) Updates `org.springframework.boot:spring-boot-starter-data-rest` from 3.3.4 to 3.4.1 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.4.1) Updates `org.springframework.boot:spring-boot-starter-security` from 3.3.4 to 3.4.1 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.4.1) Updates `org.springframework.boot:spring-boot-starter-aop` from 3.3.4 to 3.4.1 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.4.1) Updates `org.springframework.boot:spring-boot-starter-actuator` from 3.3.4 to 3.4.1 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.4.1) Updates `org.springframework.boot:spring-boot-starter-log4j2` from 3.3.4 to 3.4.1 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.4.1) Updates `org.springframework.boot:spring-boot-starter-tomcat` from 3.3.4 to 3.4.1 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.4.1) Updates `org.springframework.security:spring-security-test` from 6.3.3 to 6.4.2 - [Release notes](https://github.com/spring-projects/spring-security/releases) - [Changelog](https://github.com/spring-projects/spring-security/blob/main/RELEASE.adoc) - [Commits](https://github.com/spring-projects/spring-security/compare/6.3.3...6.4.2) Updates `org.springframework.boot:spring-boot-maven-plugin` from 3.3.4 to 3.4.1 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.4.1) Updates `org.springframework.boot:spring-boot-starter-cache` from 3.3.4 to 3.4.1 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.4.1) Updates `org.springframework.boot:spring-boot-starter` from 3.3.4 to 3.4.1 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.4.1) Updates `org.springframework.boot:spring-boot-starter-web` from 3.3.4 to 3.4.1 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.4.1) Updates `org.springframework.boot:spring-boot-starter-data-rest` from 3.3.4 to 3.4.1 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.4.1) Updates `org.springframework.boot:spring-boot-starter-security` from 3.3.4 to 3.4.1 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.4.1) Updates `org.springframework.boot:spring-boot-starter-aop` from 3.3.4 to 3.4.1 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.4.1) Updates `org.springframework.boot:spring-boot-starter-actuator` from 3.3.4 to 3.4.1 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.4.1) Updates `org.springframework.boot:spring-boot-starter-log4j2` from 3.3.4 to 3.4.1 - [Release notes](https://github.com/spring-projects/spring-boot/releases) - [Commits](https://github.com/spring-projects/spring-boot/compare/v3.3.4...v3.4.1) --- updated-dependencies: - dependency-name: org.springframework:spring-orm dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-core dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-beans dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-aop dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-context dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-context-support dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-tx dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-jdbc dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-web dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-webmvc dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-expression dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-test dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-core dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-beans dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-aop dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-context dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-context-support dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-tx dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-jdbc dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-web dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-webmvc dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-expression dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework:spring-test dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework.boot:spring-boot-starter-test dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework.boot:spring-boot-starter-tomcat dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework.boot:spring-boot-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework.boot:spring-boot-starter-cache dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework.boot:spring-boot-starter dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework.boot:spring-boot-starter-web dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework.boot:spring-boot-starter-data-rest dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework.boot:spring-boot-starter-security dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework.boot:spring-boot-starter-aop dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework.boot:spring-boot-starter-actuator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework.boot:spring-boot-starter-log4j2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework.boot:spring-boot-starter-tomcat dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework.security:spring-security-test dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework.boot:spring-boot-maven-plugin dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework.boot:spring-boot-starter-cache dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework.boot:spring-boot-starter dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework.boot:spring-boot-starter-web dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework.boot:spring-boot-starter-data-rest dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework.boot:spring-boot-starter-security dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework.boot:spring-boot-starter-aop dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework.boot:spring-boot-starter-actuator dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring - dependency-name: org.springframework.boot:spring-boot-starter-log4j2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: spring ... Signed-off-by: dependabot[bot] --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index bb093621ff2f..a8d4dffc8ba8 100644 --- a/pom.xml +++ b/pom.xml @@ -19,9 +19,9 @@ 17 - 6.1.14 - 3.3.4 - 6.3.3 + 6.2.1 + 3.4.1 + 6.4.2 6.4.8.Final 8.0.1.Final 42.7.3 From 3b63097fc2096551fd5188bb61f7a212bd42e207 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Jan 2025 21:04:29 +0000 Subject: [PATCH 161/226] Bump org.webjars.npm:json-editor__json-editor in the webjars group Bumps the webjars group with 1 update: [org.webjars.npm:json-editor__json-editor](https://github.com/json-editor/json-editor). Updates `org.webjars.npm:json-editor__json-editor` from 2.6.1 to 2.15.1 - [Changelog](https://github.com/json-editor/json-editor/blob/master/CHANGELOG.md) - [Commits](https://github.com/json-editor/json-editor/compare/2.6.1...2.15.1) --- updated-dependencies: - dependency-name: org.webjars.npm:json-editor__json-editor dependency-type: direct:production update-type: version-update:semver-minor dependency-group: webjars ... Signed-off-by: dependabot[bot] --- dspace-server-webapp/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-server-webapp/pom.xml b/dspace-server-webapp/pom.xml index 290f8afb0dc6..8d6be38d09fb 100644 --- a/dspace-server-webapp/pom.xml +++ b/dspace-server-webapp/pom.xml @@ -431,7 +431,7 @@ org.webjars.npm json-editor__json-editor - 2.6.1 + 2.15.1 - + From a2daffe81e125df9720bd18894528878b5d9c8f5 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 29 Oct 2024 17:02:46 -0500 Subject: [PATCH 165/226] Minor checkstyle fixes after bump to 8.45.1. All are indentation / spacing fixes which are more strict now. --- .../rest/AuthenticationRestController.java | 2 +- .../app/rest/model/AuthorizationRest.java | 6 +-- .../dspace/app/rest/model/BitstreamRest.java | 15 ++----- .../app/rest/model/BrowseIndexRest.java | 10 +---- .../org/dspace/app/rest/model/BundleRest.java | 15 ++----- .../app/rest/model/ClaimedTaskRest.java | 5 +-- .../dspace/app/rest/model/CollectionRest.java | 40 ++++------------- .../dspace/app/rest/model/CommunityRest.java | 25 +++-------- .../dspace/app/rest/model/EPersonRest.java | 5 +-- .../dspace/app/rest/model/EntityTypeRest.java | 5 +-- .../app/rest/model/ExternalSourceRest.java | 5 +-- .../org/dspace/app/rest/model/GroupRest.java | 15 ++----- .../org/dspace/app/rest/model/ItemRest.java | 45 ++++--------------- .../app/rest/model/OrcidHistoryRest.java | 2 +- .../dspace/app/rest/model/PoolTaskRest.java | 5 +-- .../dspace/app/rest/model/ProcessRest.java | 15 ++----- .../app/rest/model/RelationshipRest.java | 5 +-- .../app/rest/model/ResearcherProfileRest.java | 4 +- .../dspace/app/rest/model/SuggestionRest.java | 4 +- .../app/rest/model/SuggestionTargetRest.java | 2 +- .../app/rest/model/VersionHistoryRest.java | 10 +---- .../dspace/app/rest/model/VersionRest.java | 10 +---- .../model/VocabularyEntryDetailsRest.java | 6 +-- .../dspace/app/rest/model/VocabularyRest.java | 4 +- .../rest/model/WorkflowDefinitionRest.java | 10 +---- .../app/rest/model/WorkflowItemRest.java | 20 ++------- .../app/rest/model/WorkflowStepRest.java | 5 +-- .../app/rest/model/WorkspaceItemRest.java | 20 ++------- .../org/dspace/app/rest/utils/RegexUtils.java | 2 +- .../app/rest/matcher/RegistrationMatcher.java | 2 +- 30 files changed, 74 insertions(+), 245 deletions(-) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/AuthenticationRestController.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/AuthenticationRestController.java index 070f3d8a1868..63ac50b6ea06 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/AuthenticationRestController.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/AuthenticationRestController.java @@ -220,7 +220,7 @@ private AuthenticationTokenResource shortLivedTokenResponse(HttpServletRequest r * @return ResponseEntity */ @RequestMapping(value = "/login", method = { RequestMethod.GET, RequestMethod.PUT, RequestMethod.PATCH, - RequestMethod.DELETE }) + RequestMethod.DELETE }) public ResponseEntity login() { return ResponseEntity.status(HttpStatus.METHOD_NOT_ALLOWED).body("Only POST is allowed for login requests."); } diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/AuthorizationRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/AuthorizationRest.java index fa463a7c3968..cd3e33b9e2fa 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/AuthorizationRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/AuthorizationRest.java @@ -18,9 +18,9 @@ * @author Andrea Bollini (andrea.bollini at 4science.it) */ @LinksRest(links = { - @LinkRest(method = "getEperson", name = AuthorizationRest.EPERSON), - @LinkRest(method = "getFeature", name = AuthorizationRest.FEATURE), - @LinkRest(method = "getObject", name = AuthorizationRest.OBJECT) + @LinkRest(method = "getEperson", name = AuthorizationRest.EPERSON), + @LinkRest(method = "getFeature", name = AuthorizationRest.FEATURE), + @LinkRest(method = "getObject", name = AuthorizationRest.OBJECT) }) public class AuthorizationRest extends BaseObjectRest { public static final String NAME = "authorization"; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/BitstreamRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/BitstreamRest.java index d2c2268b3f35..d456f7222308 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/BitstreamRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/BitstreamRest.java @@ -16,18 +16,9 @@ * @author Andrea Bollini (andrea.bollini at 4science.it) */ @LinksRest(links = { - @LinkRest( - name = BitstreamRest.BUNDLE, - method = "getBundle" - ), - @LinkRest( - name = BitstreamRest.FORMAT, - method = "getFormat" - ), - @LinkRest( - name = BitstreamRest.THUMBNAIL, - method = "getThumbnail" - ) + @LinkRest(name = BitstreamRest.BUNDLE, method = "getBundle"), + @LinkRest(name = BitstreamRest.FORMAT, method = "getFormat"), + @LinkRest(name = BitstreamRest.THUMBNAIL, method = "getThumbnail") }) public class BitstreamRest extends DSpaceObjectRest { public static final String PLURAL_NAME = "bitstreams"; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/BrowseIndexRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/BrowseIndexRest.java index a3c0b37ba576..e5b089479971 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/BrowseIndexRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/BrowseIndexRest.java @@ -20,14 +20,8 @@ * @author Andrea Bollini (andrea.bollini at 4science.it) */ @LinksRest(links = { - @LinkRest( - name = BrowseIndexRest.LINK_ITEMS, - method = "listBrowseItems" - ), - @LinkRest( - name = BrowseIndexRest.LINK_ENTRIES, - method = "listBrowseEntries" - ) + @LinkRest(name = BrowseIndexRest.LINK_ITEMS, method = "listBrowseItems"), + @LinkRest(name = BrowseIndexRest.LINK_ENTRIES, method = "listBrowseEntries") }) public class BrowseIndexRest extends BaseObjectRest { private static final long serialVersionUID = -4870333170249999559L; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/BundleRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/BundleRest.java index 1ec9f448dde4..4a417e6c54c3 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/BundleRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/BundleRest.java @@ -16,18 +16,9 @@ * @author Jelle Pelgrims (jelle.pelgrims at atmire.com) */ @LinksRest(links = { - @LinkRest( - name = BundleRest.ITEM, - method = "getItem" - ), - @LinkRest( - name = BundleRest.BITSTREAMS, - method = "getBitstreams" - ), - @LinkRest( - name = BundleRest.PRIMARY_BITSTREAM, - method = "getPrimaryBitstream" - ) + @LinkRest(name = BundleRest.ITEM, method = "getItem"), + @LinkRest(name = BundleRest.BITSTREAMS, method = "getBitstreams"), + @LinkRest(name = BundleRest.PRIMARY_BITSTREAM, method = "getPrimaryBitstream") }) public class BundleRest extends DSpaceObjectRest { public static final String NAME = "bundle"; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ClaimedTaskRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ClaimedTaskRest.java index 0973fac987d2..d29bf7a7ce6b 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ClaimedTaskRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ClaimedTaskRest.java @@ -16,10 +16,7 @@ * @author Andrea Bollini (andrea.bollini at 4science.it) */ @LinksRest(links = { - @LinkRest( - name = ClaimedTaskRest.STEP, - method = "getStep" - ) + @LinkRest(name = ClaimedTaskRest.STEP, method = "getStep") }) public class ClaimedTaskRest extends BaseObjectRest { public static final String NAME = "claimedtask"; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/CollectionRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/CollectionRest.java index f00bb883959c..34faba4cb4d9 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/CollectionRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/CollectionRest.java @@ -15,38 +15,14 @@ * @author Andrea Bollini (andrea.bollini at 4science.it) */ @LinksRest(links = { - @LinkRest( - name = CollectionRest.LICENSE, - method = "getLicense" - ), - @LinkRest( - name = CollectionRest.LOGO, - method = "getLogo" - ), - @LinkRest( - name = CollectionRest.MAPPED_ITEMS, - method = "getMappedItems" - ), - @LinkRest( - name = CollectionRest.PARENT_COMMUNITY, - method = "getParentCommunity" - ), - @LinkRest( - name = CollectionRest.ADMIN_GROUP, - method = "getAdminGroup" - ), - @LinkRest( - name = CollectionRest.SUBMITTERS_GROUP, - method = "getSubmittersGroup" - ), - @LinkRest( - name = CollectionRest.ITEM_READ_GROUP, - method = "getItemReadGroup" - ), - @LinkRest( - name = CollectionRest.BITSTREAM_READ_GROUP, - method = "getBitstreamReadGroup" - ), + @LinkRest(name = CollectionRest.LICENSE, method = "getLicense"), + @LinkRest(name = CollectionRest.LOGO, method = "getLogo"), + @LinkRest(name = CollectionRest.MAPPED_ITEMS, method = "getMappedItems"), + @LinkRest(name = CollectionRest.PARENT_COMMUNITY, method = "getParentCommunity"), + @LinkRest(name = CollectionRest.ADMIN_GROUP, method = "getAdminGroup"), + @LinkRest(name = CollectionRest.SUBMITTERS_GROUP, method = "getSubmittersGroup"), + @LinkRest(name = CollectionRest.ITEM_READ_GROUP, method = "getItemReadGroup"), + @LinkRest(name = CollectionRest.BITSTREAM_READ_GROUP, method = "getBitstreamReadGroup"), }) public class CollectionRest extends DSpaceObjectRest { public static final String NAME = "collection"; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/CommunityRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/CommunityRest.java index 0004e0b91ca4..e70b30803da3 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/CommunityRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/CommunityRest.java @@ -15,26 +15,11 @@ * @author Andrea Bollini (andrea.bollini at 4science.it) */ @LinksRest(links = { - @LinkRest( - name = CommunityRest.COLLECTIONS, - method = "getCollections" - ), - @LinkRest( - name = CommunityRest.LOGO, - method = "getLogo" - ), - @LinkRest( - name = CommunityRest.SUBCOMMUNITIES, - method = "getSubcommunities" - ), - @LinkRest( - name = CommunityRest.PARENT_COMMUNITY, - method = "getParentCommunity" - ), - @LinkRest( - name = CommunityRest.ADMIN_GROUP, - method = "getAdminGroup" - ) + @LinkRest(name = CommunityRest.COLLECTIONS, method = "getCollections"), + @LinkRest(name = CommunityRest.LOGO, method = "getLogo"), + @LinkRest(name = CommunityRest.SUBCOMMUNITIES, method = "getSubcommunities"), + @LinkRest(name = CommunityRest.PARENT_COMMUNITY, method = "getParentCommunity"), + @LinkRest(name = CommunityRest.ADMIN_GROUP, method = "getAdminGroup") }) public class CommunityRest extends DSpaceObjectRest { public static final String NAME = "community"; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/EPersonRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/EPersonRest.java index c06ed0e3fe1f..db243400259d 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/EPersonRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/EPersonRest.java @@ -20,10 +20,7 @@ * @author Andrea Bollini (andrea.bollini at 4science.it) */ @LinksRest(links = { - @LinkRest( - name = EPersonRest.GROUPS, - method = "getGroups" - ) + @LinkRest(name = EPersonRest.GROUPS, method = "getGroups") }) public class EPersonRest extends DSpaceObjectRest { public static final String NAME = "eperson"; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/EntityTypeRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/EntityTypeRest.java index 9d4a729ded93..e73aa709180d 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/EntityTypeRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/EntityTypeRest.java @@ -15,10 +15,7 @@ * Refer to {@link org.dspace.content.EntityType} for explanation of the properties */ @LinksRest(links = { - @LinkRest( - name = EntityTypeRest.RELATION_SHIP_TYPES, - method = "getEntityTypeRelationship" - ) + @LinkRest(name = EntityTypeRest.RELATION_SHIP_TYPES, method = "getEntityTypeRelationship") }) public class EntityTypeRest extends BaseObjectRest { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ExternalSourceRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ExternalSourceRest.java index 58402954e8db..21f41241b293 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ExternalSourceRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ExternalSourceRest.java @@ -13,10 +13,7 @@ * This class serves as a REST representation for an External Source */ @LinksRest(links = { - @LinkRest( - name = ExternalSourceRest.ENTITY_TYPES, - method = "getSupportedEntityTypes" - ) + @LinkRest(name = ExternalSourceRest.ENTITY_TYPES, method = "getSupportedEntityTypes") }) public class ExternalSourceRest extends BaseObjectRest { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/GroupRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/GroupRest.java index 7d56af2e7204..0a4963b66fa0 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/GroupRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/GroupRest.java @@ -18,18 +18,9 @@ */ @JsonIgnoreProperties(ignoreUnknown = true) @LinksRest(links = { - @LinkRest( - name = GroupRest.SUBGROUPS, - method = "getGroups" - ), - @LinkRest( - name = GroupRest.EPERSONS, - method = "getMembers" - ), - @LinkRest( - name = GroupRest.OBJECT, - method = "getParentObject" - ) + @LinkRest(name = GroupRest.SUBGROUPS, method = "getGroups"), + @LinkRest(name = GroupRest.EPERSONS, method = "getMembers"), + @LinkRest(name = GroupRest.OBJECT, method = "getParentObject") }) public class GroupRest extends DSpaceObjectRest { public static final String NAME = "group"; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ItemRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ItemRest.java index b2f540c0ac4a..293f95c4de39 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ItemRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ItemRest.java @@ -17,42 +17,15 @@ * @author Andrea Bollini (andrea.bollini at 4science.it) */ @LinksRest(links = { - @LinkRest( - name = ItemRest.ACCESS_STATUS, - method = "getAccessStatus" - ), - @LinkRest( - name = ItemRest.BUNDLES, - method = "getBundles" - ), - @LinkRest( - name = ItemRest.IDENTIFIERS, - method = "getIdentifiers" - ), - @LinkRest( - name = ItemRest.MAPPED_COLLECTIONS, - method = "getMappedCollections" - ), - @LinkRest( - name = ItemRest.OWNING_COLLECTION, - method = "getOwningCollection" - ), - @LinkRest( - name = ItemRest.RELATIONSHIPS, - method = "getRelationships" - ), - @LinkRest( - name = ItemRest.VERSION, - method = "getItemVersion" - ), - @LinkRest( - name = ItemRest.TEMPLATE_ITEM_OF, - method = "getTemplateItemOf" - ), - @LinkRest( - name = ItemRest.THUMBNAIL, - method = "getThumbnail" - ) + @LinkRest(name = ItemRest.ACCESS_STATUS, method = "getAccessStatus"), + @LinkRest(name = ItemRest.BUNDLES, method = "getBundles"), + @LinkRest(name = ItemRest.IDENTIFIERS, method = "getIdentifiers"), + @LinkRest(name = ItemRest.MAPPED_COLLECTIONS, method = "getMappedCollections"), + @LinkRest(name = ItemRest.OWNING_COLLECTION, method = "getOwningCollection"), + @LinkRest(name = ItemRest.RELATIONSHIPS, method = "getRelationships"), + @LinkRest(name = ItemRest.VERSION, method = "getItemVersion"), + @LinkRest(name = ItemRest.TEMPLATE_ITEM_OF, method = "getTemplateItemOf"), + @LinkRest(name = ItemRest.THUMBNAIL, method = "getThumbnail") }) public class ItemRest extends DSpaceObjectRest { public static final String NAME = "item"; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/OrcidHistoryRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/OrcidHistoryRest.java index 2c4c7cbe6043..433d5626ca42 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/OrcidHistoryRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/OrcidHistoryRest.java @@ -39,7 +39,7 @@ public class OrcidHistoryRest extends BaseObjectRest { private String responseMessage; - public OrcidHistoryRest(){} + public OrcidHistoryRest() {} @Override @JsonProperty(access = JsonProperty.Access.READ_ONLY) diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/PoolTaskRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/PoolTaskRest.java index 0b66f0604b2e..94c70037330e 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/PoolTaskRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/PoolTaskRest.java @@ -17,10 +17,7 @@ * @author Andrea Bollini (andrea.bollini at 4science.it) */ @LinksRest(links = { - @LinkRest( - name = PoolTaskRest.STEP, - method = "getStep" - ) + @LinkRest(name = PoolTaskRest.STEP, method = "getStep") }) public class PoolTaskRest extends BaseObjectRest { public static final String NAME = "pooltask"; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ProcessRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ProcessRest.java index d3d88c2776ce..fee104b4e389 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ProcessRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ProcessRest.java @@ -21,18 +21,9 @@ * This class serves as a REST representation for the {@link Process} class */ @LinksRest(links = { - @LinkRest( - name = ProcessRest.FILES, - method = "getFilesFromProcess" - ), - @LinkRest( - name = ProcessRest.FILE_TYPES, - method = "getFileTypesFromProcess" - ), - @LinkRest( - name = ProcessRest.OUTPUT, - method = "getOutputFromProcess" - ) + @LinkRest(name = ProcessRest.FILES, method = "getFilesFromProcess"), + @LinkRest(name = ProcessRest.FILE_TYPES, method = "getFileTypesFromProcess"), + @LinkRest(name = ProcessRest.OUTPUT, method = "getOutputFromProcess") }) public class ProcessRest extends BaseObjectRest { public static final String NAME = "process"; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/RelationshipRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/RelationshipRest.java index 76a7a4348682..723f7e148b27 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/RelationshipRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/RelationshipRest.java @@ -19,10 +19,7 @@ * Refer to {@link org.dspace.content.Relationship} for explanation about the properties */ @LinksRest(links = { - @LinkRest( - name = RelationshipRest.RELATIONSHIP_TYPE, - method = "getRelationshipType" - ) + @LinkRest(name = RelationshipRest.RELATIONSHIP_TYPE, method = "getRelationshipType") }) public class RelationshipRest extends BaseObjectRest { public static final String NAME = "relationship"; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ResearcherProfileRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ResearcherProfileRest.java index 13faa2e2bbdf..629dbdf85821 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ResearcherProfileRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/ResearcherProfileRest.java @@ -20,8 +20,8 @@ * */ @LinksRest(links = { - @LinkRest(name = ResearcherProfileRest.ITEM, method = "getItem"), - @LinkRest(name = ResearcherProfileRest.EPERSON, method = "getEPerson") + @LinkRest(name = ResearcherProfileRest.ITEM, method = "getItem"), + @LinkRest(name = ResearcherProfileRest.EPERSON, method = "getEPerson") }) public class ResearcherProfileRest extends BaseObjectRest { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SuggestionRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SuggestionRest.java index c7210e892558..7b1a05127fc7 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SuggestionRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SuggestionRest.java @@ -21,7 +21,9 @@ * * @author Andrea Bollini (andrea.bollini at 4science.it) */ -@LinksRest(links = { @LinkRest(name = SuggestionRest.TARGET, method = "getTarget") }) +@LinksRest(links = { + @LinkRest(name = SuggestionRest.TARGET, method = "getTarget") +}) public class SuggestionRest extends BaseObjectRest { private static final long serialVersionUID = 1L; public static final String NAME = "suggestion"; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SuggestionTargetRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SuggestionTargetRest.java index 65764507e247..b6518eff7488 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SuggestionTargetRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/SuggestionTargetRest.java @@ -19,7 +19,7 @@ * @author Andrea Bollini (andrea.bollini at 4science.it) */ @LinksRest(links = { - @LinkRest(name = SuggestionTargetRest.TARGET, method = "getTarget") + @LinkRest(name = SuggestionTargetRest.TARGET, method = "getTarget") }) public class SuggestionTargetRest extends BaseObjectRest { private static final long serialVersionUID = 1L; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/VersionHistoryRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/VersionHistoryRest.java index 5aab7028a8c6..80f704c77936 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/VersionHistoryRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/VersionHistoryRest.java @@ -13,14 +13,8 @@ * The REST object for the {@link org.dspace.versioning.VersionHistory} object */ @LinksRest(links = { - @LinkRest( - name = VersionHistoryRest.VERSIONS, - method = "getVersions" - ), - @LinkRest( - name = VersionHistoryRest.DRAFT_VERSION, - method = "getDraftVersion" - ) + @LinkRest(name = VersionHistoryRest.VERSIONS, method = "getVersions"), + @LinkRest(name = VersionHistoryRest.DRAFT_VERSION, method = "getDraftVersion") }) public class VersionHistoryRest extends BaseObjectRest { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/VersionRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/VersionRest.java index 21bf82804dd2..d9ebdd67e408 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/VersionRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/VersionRest.java @@ -16,14 +16,8 @@ * The REST object for the {@link org.dspace.versioning.Version} objects */ @LinksRest(links = { - @LinkRest( - name = VersionRest.VERSION_HISTORY, - method = "getVersionHistory" - ), - @LinkRest( - name = VersionRest.ITEM, - method = "getVersionItem" - ) + @LinkRest(name = VersionRest.VERSION_HISTORY, method = "getVersionHistory"), + @LinkRest(name = VersionRest.ITEM, method = "getVersionItem") }) public class VersionRest extends BaseObjectRest { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/VocabularyEntryDetailsRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/VocabularyEntryDetailsRest.java index e5869a852521..884e14642cf9 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/VocabularyEntryDetailsRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/VocabularyEntryDetailsRest.java @@ -18,9 +18,9 @@ * @author Andrea Bollini (andrea.bollini at 4science.it) */ @LinksRest(links = { - @LinkRest(name = VocabularyEntryDetailsRest.PARENT, method = "getParent"), - @LinkRest(name = VocabularyEntryDetailsRest.CHILDREN, method = "getChildren") - }) + @LinkRest(name = VocabularyEntryDetailsRest.PARENT, method = "getParent"), + @LinkRest(name = VocabularyEntryDetailsRest.CHILDREN, method = "getChildren") +}) public class VocabularyEntryDetailsRest extends BaseObjectRest { public static final String PLURAL_NAME = "vocabularyEntryDetails"; public static final String NAME = "vocabularyEntryDetail"; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/VocabularyRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/VocabularyRest.java index f119059c2bb7..a54d93c643b4 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/VocabularyRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/VocabularyRest.java @@ -15,9 +15,7 @@ * @author Andrea Bollini (andrea.bollini at 4science.it) */ @LinksRest(links = { - @LinkRest(name = VocabularyRest.ENTRIES, - method = "filter" - ), + @LinkRest(name = VocabularyRest.ENTRIES, method = "filter"), }) public class VocabularyRest extends BaseObjectRest { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkflowDefinitionRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkflowDefinitionRest.java index 0ec967d09876..9cef79aaf3be 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkflowDefinitionRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkflowDefinitionRest.java @@ -18,14 +18,8 @@ * @author Maria Verdonck (Atmire) on 11/12/2019 */ @LinksRest(links = { - @LinkRest( - name = WorkflowDefinitionRest.COLLECTIONS_MAPPED_TO, - method = "getCollections" - ), - @LinkRest( - name = WorkflowDefinitionRest.STEPS, - method = "getSteps" - ) + @LinkRest(name = WorkflowDefinitionRest.COLLECTIONS_MAPPED_TO, method = "getCollections"), + @LinkRest(name = WorkflowDefinitionRest.STEPS, method = "getSteps") }) public class WorkflowDefinitionRest extends BaseObjectRest { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkflowItemRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkflowItemRest.java index 65fa531c5e42..d08abb3546a3 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkflowItemRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkflowItemRest.java @@ -15,22 +15,10 @@ * @author Andrea Bollini (andrea.bollini at 4science.it) */ @LinksRest(links = { - @LinkRest( - name = WorkflowItemRest.STEP, - method = "getStep" - ), - @LinkRest( - name = WorkflowItemRest.SUBMITTER, - method = "getWorkflowItemSubmitter" - ), - @LinkRest( - name = WorkflowItemRest.ITEM, - method = "getWorkflowItemItem" - ), - @LinkRest( - name = WorkflowItemRest.COLLECTION, - method = "getWorkflowItemCollection" - ) + @LinkRest(name = WorkflowItemRest.STEP, method = "getStep"), + @LinkRest(name = WorkflowItemRest.SUBMITTER, method = "getWorkflowItemSubmitter"), + @LinkRest(name = WorkflowItemRest.ITEM, method = "getWorkflowItemItem"), + @LinkRest(name = WorkflowItemRest.COLLECTION, method = "getWorkflowItemCollection") }) public class WorkflowItemRest extends AInprogressSubmissionRest { public static final String NAME = "workflowitem"; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkflowStepRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkflowStepRest.java index b3397721c117..53ddf38709e4 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkflowStepRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkflowStepRest.java @@ -18,10 +18,7 @@ * @author Maria Verdonck (Atmire) on 10/01/2020 */ @LinksRest(links = { - @LinkRest( - name = WorkflowStepRest.ACTIONS, - method = "getActions" - ), + @LinkRest(name = WorkflowStepRest.ACTIONS, method = "getActions"), }) public class WorkflowStepRest extends BaseObjectRest { diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkspaceItemRest.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkspaceItemRest.java index e311cd259231..8e0d52123f99 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkspaceItemRest.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/model/WorkspaceItemRest.java @@ -15,22 +15,10 @@ * @author Andrea Bollini (andrea.bollini at 4science.it) */ @LinksRest(links = { - @LinkRest( - name = WorkspaceItemRest.SUPERVISION_ORDERS, - method = "getSupervisionOrders" - ), - @LinkRest( - name = WorkspaceItemRest.SUBMITTER, - method = "getWorkspaceItemSubmitter" - ), - @LinkRest( - name = WorkspaceItemRest.ITEM, - method = "getWorkspaceItemItem" - ), - @LinkRest( - name = WorkspaceItemRest.COLLECTION, - method = "getWorkspaceItemCollection" - ) + @LinkRest(name = WorkspaceItemRest.SUPERVISION_ORDERS, method = "getSupervisionOrders"), + @LinkRest(name = WorkspaceItemRest.SUBMITTER, method = "getWorkspaceItemSubmitter"), + @LinkRest(name = WorkspaceItemRest.ITEM, method = "getWorkspaceItemItem"), + @LinkRest(name = WorkspaceItemRest.COLLECTION, method = "getWorkspaceItemCollection") }) public class WorkspaceItemRest extends AInprogressSubmissionRest { public static final String NAME = "workspaceitem"; diff --git a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/RegexUtils.java b/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/RegexUtils.java index b358e785c3b3..df525f679323 100644 --- a/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/RegexUtils.java +++ b/dspace-server-webapp/src/main/java/org/dspace/app/rest/utils/RegexUtils.java @@ -13,7 +13,7 @@ */ public class RegexUtils { - private RegexUtils(){} + private RegexUtils() {} /** * Regular expression in the request mapping to accept UUID as identifier diff --git a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/RegistrationMatcher.java b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/RegistrationMatcher.java index a154091a2eff..2a4cee8375be 100644 --- a/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/RegistrationMatcher.java +++ b/dspace-server-webapp/src/test/java/org/dspace/app/rest/matcher/RegistrationMatcher.java @@ -17,7 +17,7 @@ public class RegistrationMatcher { - private RegistrationMatcher(){} + private RegistrationMatcher() {} public static Matcher matchRegistration(String email, UUID epersonUuid) { return allOf( From abfb86b791ee5dff051492f82e6b1e664f05d8ab Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 3 Dec 2024 09:34:02 -0600 Subject: [PATCH 166/226] Add newly required "should-stop" flag to errorprone config. See https://errorprone.info/docs/installation --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 7a2f9792aa7a..9f76eb74fb23 100644 --- a/pom.xml +++ b/pom.xml @@ -147,6 +147,7 @@ true -XDcompilePolicy=simple + --should-stop=ifError=FLOW -Xplugin:ErrorProne -J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED -J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED From 52b310077617921aea05e4cec4c69a5b250dd632 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 3 Dec 2024 09:44:56 -0600 Subject: [PATCH 167/226] Fix duplicate code warning from errorprone. This "else if" clause is the same as the "else" and can be removed --- .../src/main/java/org/dspace/discovery/SolrServiceImpl.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/dspace-api/src/main/java/org/dspace/discovery/SolrServiceImpl.java b/dspace-api/src/main/java/org/dspace/discovery/SolrServiceImpl.java index 0769310b8175..75f0a0ac4d05 100644 --- a/dspace-api/src/main/java/org/dspace/discovery/SolrServiceImpl.java +++ b/dspace-api/src/main/java/org/dspace/discovery/SolrServiceImpl.java @@ -1445,8 +1445,6 @@ protected String transformFacetField(DiscoverFacetField facetFieldConfig, String } else { return field + "_acid"; } - } else if (facetFieldConfig.getType().equals(DiscoveryConfigurationParameters.TYPE_STANDARD)) { - return field; } else { return field; } From b98696f4a7cbf5d1065fa18e22f025334f263b03 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 14 Jan 2025 14:46:27 -0600 Subject: [PATCH 168/226] Dependency convergence fix --- dspace-api/pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dspace-api/pom.xml b/dspace-api/pom.xml index 58bd8106e9af..dbc21d14ecb0 100644 --- a/dspace-api/pom.xml +++ b/dspace-api/pom.xml @@ -756,6 +756,11 @@ org.javassist javassist + + + org.yaml + snakeyaml + From 8c88e215b4741ce04ff54c1a0581fd50d50a4e15 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Tue, 14 Jan 2025 16:23:21 -0600 Subject: [PATCH 169/226] Tell Spring Boot to use the simple HttpURLConnection for RestClient, like in Spring boot 3.3 --- .../src/main/resources/application.properties | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/dspace-server-webapp/src/main/resources/application.properties b/dspace-server-webapp/src/main/resources/application.properties index 8233298ef0b0..0d9b9cd836ec 100644 --- a/dspace-server-webapp/src/main/resources/application.properties +++ b/dspace-server-webapp/src/main/resources/application.properties @@ -135,3 +135,15 @@ spring.servlet.multipart.max-file-size = 512MB # Maximum size of a multipart request (i.e. max total size of all files in one request) (default = 10MB) spring.servlet.multipart.max-request-size = 512MB + +################################## +# Spring Boot's HTTP Client configuration (for RestClient and RestTemplate) +# https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.4-Release-Notes#restclient-and-resttemplate +# +# "simple" tells Spring Boot to use JDK's HttpURLConnection (SimpleClientHttpRequestFactory) +# We have to configure this explicitly for DSpace because Spring Boot's autoconfiguration will attempt to +# use Jetty or similar if found on the classpath (and Jetty is on the classpath for Handle Server, etc) +spring.http.client.factory = simple +# "dont_follow" tells Spring Boot not to follow any redirects itself, but instead return the 3xx code to +# the user's browser. +spring.http.client.redirects = dont_follow \ No newline at end of file From 5fcf6357f745fd1b7924ab5c5915101ff12649e6 Mon Sep 17 00:00:00 2001 From: Tim Donohue Date: Wed, 30 Oct 2024 14:49:04 -0500 Subject: [PATCH 170/226] Update jsoneditor.js reference in Hal Browser --- dspace-server-webapp/src/main/resources/static/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dspace-server-webapp/src/main/resources/static/index.html b/dspace-server-webapp/src/main/resources/static/index.html index c780286107d8..0b80f806767e 100644 --- a/dspace-server-webapp/src/main/resources/static/index.html +++ b/dspace-server-webapp/src/main/resources/static/index.html @@ -321,7 +321,7 @@

Embedded Resources

- +