Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support deletion of saved searches #10198

Merged
merged 16 commits into from
Aug 27, 2024

Conversation

luddaniel
Copy link
Contributor

@luddaniel luddaniel commented Dec 20, 2023

What this PR does / why we need it:

  • Allow to delete saved search by calling DELETE /api/admin/savedsearches/{id}
  • Allow to delete saved search and unlink links related to the deleted saved search by adding ?unlink=true

Which issue(s) this PR closes:

Is there a release notes update needed for this change?:

Suggestions on how to test this:

This is how I tested it :

Create Data

create 1 collection + 2 datasets under + publish all with subject "Agricultural Sciences"

Create saved search

create another collection that will be contain linked Data)

savedSearch.json contains :

{
    "query": "*",
    "creatorId": 1,
    "definitionPointId": 5,
    "filterQueries": [
        "subject_ss:Agricultural Sciences"
    ]
}

curl http://localhost:8080/api/admin/savedsearches -X POST -H 'Content-type:application/json' --upload-file savedSearch.json | jq .
curl -X PUT http://localhost:8080/api/admin/savedsearches/makelinks/all?debug=true | jq .

Now collection2 contains 3 linked Dvobject.

Remove without unlink

curl http://localhost:8080/api/admin/savedsearches/list | jq . -> 1 item id = 1
curl -X DELETE http://localhost:8080/api/admin/savedsearches/1 | jq . -> OK
curl http://localhost:8080/api/admin/savedsearches/list | jq . -> no item

Links are still here

Re-Create saved search

curl -s http://localhost:8080/api/admin/savedsearches -X POST -H 'Content-type:application/json' --upload-file savedSearch.json | jq .
curl -X PUT http://localhost:8080/api/admin/savedsearches/makelinks/all?debug=true | jq .

Remove with unlink

curl http://localhost:8080/api/admin/savedsearches/list | jq . -> 1 item id = 2
curl -X DELETE http://localhost:8080/api/admin/savedsearches/2?unlink=true | jq . -> OK
curl http://localhost:8080/api/admin/savedsearches/list | jq . -> no item

Links are deleted and not visible in collection2

Docs

Preview updated docs at https://dataverse-guide--10198.org.readthedocs.build/en/10198/api/native-api.html#saved-search

@coveralls
Copy link

coveralls commented Dec 20, 2023

Coverage Status

coverage: 20.62% (-0.008%) from 20.628%
when pulling 008507b on Recherche-Data-Gouv:9317-delete-saved-search
into 9bfa6ac on IQSS:develop.

Copy link
Member

@pdurbin pdurbin left a comment

Choose a reason for hiding this comment

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

This is a great start! @luddaniel how do you feel about adding API tests, an update to the API Guide, and a release note snippet?

@pdurbin pdurbin added the Size: 3 A percentage of a sprint. 2.1 hours. label Feb 28, 2024
@luddaniel
Copy link
Contributor Author

luddaniel commented Mar 6, 2024

This is a great start! @luddaniel how do you feel about adding API tests, an update to the API Guide, and a release note snippet?

Hello @pdurbin, everything has been added to the PR :

  • API Guide update
  • Release note snippet
  • Integration tests (which revealed that API endpoints were not restricted to Superusers only 🤣), tests were kept simple for now.
  • Superusers only fix

@pdurbin pdurbin changed the title #9317 - Allowing to delete saved search Support deletion of saved searches Mar 14, 2024
@pdurbin pdurbin self-assigned this Jun 7, 2024
Copy link
Member

@pdurbin pdurbin left a comment

Choose a reason for hiding this comment

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

@luddaniel overall this is looking good but I added a few questions.

Copy link
Member

@pdurbin pdurbin left a comment

Choose a reason for hiding this comment

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

I just added some more feedback.

doc/sphinx-guides/source/api/native-api.rst Outdated Show resolved Hide resolved
doc/sphinx-guides/source/api/native-api.rst Outdated Show resolved Hide resolved
doc/sphinx-guides/source/api/native-api.rst Outdated Show resolved Hide resolved
Copy link
Member

@pdurbin pdurbin left a comment

Choose a reason for hiding this comment

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

@luddaniel thanks again for this pull request. I finally looked a bit closer the code and I'm concerned about all the backward-incompatible changes. Should we really do them now? Let's see what others on the team think.

Also, I'm out for the next two weeks so I'll move this PR back to "ready for review" and unassign myself so someone else can take a look.

return wr.getResponse();
}
if (superuser == null || !superuser.isSuperuser()) {
return error(Response.Status.UNAUTHORIZED, "Superusers only.");
Copy link
Member

Choose a reason for hiding this comment

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

Do we need this backward-incompatible change? I'm only going to leave this comment once but it applies to all endpoints that formerly were not superuser-only.

@luddaniel I know we talked about this a bit at https://dataverse.zulipchat.com/#narrow/stream/379673-dev/topic/admin.20API.20and.20superuser.20authorization/near/443079852 but my understanding was that we were talking theoretically about the future. I didn't realize you were thinking about making backward-incompatible changes now, in the name of consistency. We should probably pause and get rough consensus from more of the core team and decide on the timing for introducing these changes, if at all.

@@ -5745,8 +5745,7 @@ The ``$identifier`` should start with an ``@`` if it's a user. Groups start with
Saved Search
~~~~~~~~~~~~

The Saved Search, Linked Dataverses, and Linked Datasets features shipped with Dataverse 4.0, but as a "`superuser-only <https://github.com/IQSS/dataverse/issues/90#issuecomment-86094663>`_" because they are **experimental** (see `#1364 <https://github.com/IQSS/dataverse/issues/1364>`_, `#1813 <https://github.com/IQSS/dataverse/issues/1813>`_, `#1840 <https://github.com/IQSS/dataverse/issues/1840>`_, `#1890 <https://github.com/IQSS/dataverse/issues/1890>`_, `#1939 <https://github.com/IQSS/dataverse/issues/1939>`_, `#2167 <https://github.com/IQSS/dataverse/issues/2167>`_, `#2186 <https://github.com/IQSS/dataverse/issues/2186>`_, `#2053 <https://github.com/IQSS/dataverse/issues/2053>`_, and `#2543 <https://github.com/IQSS/dataverse/issues/2543>`_). The following API endpoints were added to help people with access to the "admin" API make use of these features in their current form. There is a known issue (`#1364 <https://github.com/IQSS/dataverse/issues/1364>`_) that once a link to a Dataverse collection or dataset is created, it cannot be removed (apart from database manipulation and reindexing) which is why a ``DELETE`` endpoint for saved searches is neither documented nor functional. The Linked Dataverse collections feature is `powered by Saved Search <https://github.com/IQSS/dataverse/issues/1852>`_ and therefore requires that the "makelinks" endpoint be executed on a periodic basis as well.
Copy link
Member

Choose a reason for hiding this comment

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

There's a conversation going on in #10628 about how these docs used to explain to people that they might have to wait up to 24 hours for their saved search to show results. Should we add that back as part of this pull request?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated with The update of all saved search is run by a timer once a week (See :ref:saved-search-timer) so if you just created a saved search, you can run manually makelinks endpoint that will find new dataverses and datasets that match the saved search and then link the search results to the dataverse in which the saved search is defined.

doc/sphinx-guides/source/api/native-api.rst Outdated Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

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

I'm going to leave comments below about backward incompatible changes. I'm pretty sure my preference is to NOT introduce any backward-incompatible changes but if we do the should be listed in doc/sphinx-guides/source/api/changelog.rst and the release notes should give an overview of backward-incompatible changes and tell people to check that changelog.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree, I removed every authentication requirement for /api/admin/savedsearches

doc/release-notes/9317-delete-saved-search.md Outdated Show resolved Hide resolved
doc/sphinx-guides/source/api/native-api.rst Show resolved Hide resolved
@luddaniel luddaniel requested a review from pdurbin July 3, 2024 15:35
@sekmiller sekmiller self-assigned this Jul 16, 2024
boolean wasDeleted = savedSearchSvc.delete(doomedId);
boolean wasDeleted;
try {
wasDeleted = savedSearchSvc.delete(doomedId, unlink);
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we want to put this in a command? There's a "CreateSavedSearchCommand"

Copy link
Contributor Author

@luddaniel luddaniel Aug 23, 2024

Choose a reason for hiding this comment

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

Hey @sekmiller, if my understanding is correct Command are used to share the same code between UI and API endpoints.

I note that CreateSavedSearchCommand is not used anymore (it was used in DataversePage.java for UI purposes in the past).
I note that adding Saved Search using POST API is not using CreateSavedSearchCommand.
I note that the code has been initiated back in 2015 and has been for a long time labelled experimental.

It could be prematured to create a Command that could be called from interface. What do you think ?
Sorry, but I'm more "quick win and no refactor while it's not needed" kind of mind.

Copy link
Contributor

Choose a reason for hiding this comment

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

One reason that I suggested the command was because commands also check for permissions. I didn't notice that this is a superuser only feature - so that permission check wouldn't be available in the command.
We can leave it be for now, but if we ever open it up to other users we might want to revisit the command issue.

Copy link
Contributor

@sekmiller sekmiller left a comment

Choose a reason for hiding this comment

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

@luddaniel I made a few comments throughout the code. The most important one is a suggestion that we add a Delete Saved Search command. Please take a look. Thanks!

@sekmiller sekmiller added the Status: Needs Input Applied to issues in need of input from someone currently unavailable label Jul 17, 2024
@DS-INRAE
Copy link
Member

Just a quick update on this PR : @luddaniel is currently in vacations, he'll be able to come back to this PR after August 19th.

@sekmiller
Copy link
Contributor

@luddaniel Please note my questions above and resolve the merge conflicts with our develop branch. Thanks!

@pdurbin pdurbin removed the Status: Needs Input Applied to issues in need of input from someone currently unavailable label Aug 23, 2024
Copy link
Contributor

@sekmiller sekmiller left a comment

Choose a reason for hiding this comment

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

Thanks for the updates and responses.

@pdurbin pdurbin self-assigned this Aug 26, 2024
@pdurbin
Copy link
Member

pdurbin commented Aug 26, 2024

Hmm, Jenkins hasn't run on this PR since June 14. I just kicked off a run manually: https://jenkins.dataverse.org/job/IQSS-Dataverse-Develop-PR/view/change-requests/job/PR-10198/

I did run mvn test -Dtest=SavedSearchIT locally, and it passed.

@pdurbin
Copy link
Member

pdurbin commented Aug 27, 2024

@pdurbin
Copy link
Member

pdurbin commented Aug 27, 2024

Nice feature. Seems to work fine. I tested it with this:

curl -H "X-Dataverse-key:$API_TOKEN" -X DELETE "http://localhost:8080/api/admin/savedsearches/3?unlink=true"

Merging! Thanks, @luddaniel! ❤️

@pdurbin pdurbin merged commit 3da42b4 into IQSS:develop Aug 27, 2024
11 of 12 checks passed
@pdurbin pdurbin added this to the 6.4 milestone Aug 27, 2024
@pdurbin pdurbin removed their assignment Aug 27, 2024
@pdurbin
Copy link
Member

pdurbin commented Aug 27, 2024

I'd be remiss if I didn't say that if I had access to push to https://github.com/Recherche-Data-Gouv I would have made the following small tweaks (and, if I had the energy, would have convert the old style API docs to the new style with environment variables).

This is all minor stuff though and not worth holding up progress. Perhaps it could go in a future pull request.

pdurbin@beamish dataverse % git diff --word-diff doc 
diff --git a/doc/sphinx-guides/source/api/native-api.rst b/doc/sphinx-guides/source/api/native-api.rst
index b16ea55bd2..9725602df4 100644
--- a/doc/sphinx-guides/source/api/native-api.rst
+++ b/doc/sphinx-guides/source/api/native-api.rst
@@ -5853,7 +5853,7 @@ Saved Search
~~~~~~~~~~~~

The Saved Search, Linked Dataverses, and Linked Datasets features are only accessible to superusers except for linking a dataset. The following API endpoints were added to help people with access to the "admin" API make use of these features in their current form. Keep in mind that they are partially experimental.
The update of all saved search is run by a timer once a week (See :ref:`saved-search-timer`) so if you just created a saved search, you can run manually {+the+} ``makelinks`` endpoint that will find new dataverses and datasets that match the saved search and then link the search results to the dataverse in which the saved search is defined.

List all saved searches. ::

@@ -5865,7 +5865,7 @@ List a saved search by database id. ::

Delete a saved search by database id.

The ``unlink=true`` query parameter unlinks all links (linked dataset or Dataverse collection) associated with the deleted saved search. Use of this parameter should be well considered as you cannot know if the links were created manually or by the saved search. After deleting a saved search with ``unlink=true``, we recommend running ``/makelinks/all`` just in case there was a dataset that was linked by another saved search. (Saved searches can link the same dataset.) Reindexing might be necessary as [-well.::-]{+well. ::+}

  DELETE http://$SERVER/api/admin/savedsearches/$id?unlink=true

pdurbin@beamish dataverse % git diff src            
diff --git a/src/main/java/edu/harvard/iq/dataverse/api/SavedSearches.java b/src/main/java/edu/harvard/iq/dataverse/api/SavedSearches.java
index 33a11a2df2..e6519c9ff3 100644
--- a/src/main/java/edu/harvard/iq/dataverse/api/SavedSearches.java
+++ b/src/main/java/edu/harvard/iq/dataverse/api/SavedSearches.java
@@ -181,7 +181,7 @@ public class SavedSearches extends AbstractApiBean {
         try {
             wasDeleted = savedSearchSvc.delete(doomedId, unlink);
         } catch (Exception e) {
-            return error(INTERNAL_SERVER_ERROR, "Problem while trying to unlink links of saved search id " + doomedId);
+            return error(INTERNAL_SERVER_ERROR, "Problem while trying to unlink links of saved search id " + doomedId + ". Exception: " + e.getLocalizedMessage());
         }
 
         if (wasDeleted) {
diff --git a/src/test/java/edu/harvard/iq/dataverse/api/SavedSearchIT.java b/src/test/java/edu/harvard/iq/dataverse/api/SavedSearchIT.java
index 90357596c2..cdcd92d930 100644
--- a/src/test/java/edu/harvard/iq/dataverse/api/SavedSearchIT.java
+++ b/src/test/java/edu/harvard/iq/dataverse/api/SavedSearchIT.java
@@ -22,7 +22,7 @@ public class SavedSearchIT {
 
     @BeforeAll
     public static void setUpClass() {
-
+        RestAssured.baseURI = UtilIT.getRestAssuredBaseUri();
     }
 
     @AfterAll
@@ -52,6 +52,7 @@ public class SavedSearchIT {
         createDatasetResponse2.prettyPrint();
         Integer datasetId2 = UtilIT.getDatasetIdFromResponse(createDatasetResponse2);
 
+        // TODO: put all these methods in UtilIT
         // missing body
         Response resp = RestAssured.given()
                 .contentType("application/json")
pdurbin@beamish dataverse % 

@DS-INRAE
Copy link
Member

DS-INRAE commented Sep 2, 2024

Thanks for the suggestions Phil!
We'll address them in a future PR indeed.
Just in case for future PRs, I've also invited you to Recherche-Data-Gouv :)

@pdurbin
Copy link
Member

pdurbin commented Sep 3, 2024

@DS-INRA I joined! Thanks!

@DS-INRAE
Copy link
Member

@pdurbin I added your suggestions in a new issue so we don't forget them :) :

@pdurbin
Copy link
Member

pdurbin commented Sep 30, 2024

@DS-INRAE thanks! No big deal. It's minor stuff. And next time I'll push little changes like this myself before merging, now that you've given me access. 😄 😈

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Size: 3 A percentage of a sprint. 2.1 hours.
Projects
Status: Interested
Status: Done 🧹
Status: Done
Development

Successfully merging this pull request may close these issues.

Improving Saved Search feature Allow deletion of saved searches
5 participants