From 599e257e78d1836c82311caad3aae64c2d658ae4 Mon Sep 17 00:00:00 2001 From: dennisvang <29799340+dennisvang@users.noreply.github.com> Date: Thu, 26 Mar 2026 15:12:31 +0100 Subject: [PATCH 01/45] bump version to 1.20.0 the ability to save/load full sparql queries is a new feature --- SECURITY.md | 4 ++-- pom.xml | 2 +- src/main/resources/application.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 70fa28bd0..2c2b9d08e 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -7,8 +7,8 @@ For older versions, we highly recommend upgrading to the latest version. | Version | Supported | |---------| ------------------ | -| 1.19.x | :white_check_mark: | -| < 1.19 | :x: | +| 1.20.x | :white_check_mark: | +| < 1.20 | :x: | ## Current Recommendations diff --git a/pom.xml b/pom.xml index bd53d0a48..5fa744a25 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.fairdatateam fairdatapoint - 1.19.1 + 1.20.0 jar FairDataPoint diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index f391064f7..4184e92d9 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -65,7 +65,7 @@ metadataProperties: openapi: title: FAIR Data Point API - version: 1.19.1 + version: 1.20.0 description: "The reference implementation of the metadata registration service: A service implementing the API specification. It contains an authentication system to allow maintainers to define and update metadata. Read-only access to the data is public." contact: name: Luiz Bonino From 2e89c249946000ce077d962f9037d5dae743b996 Mon Sep 17 00:00:00 2001 From: dennisvang <29799340+dennisvang@users.noreply.github.com> Date: Wed, 18 Mar 2026 09:48:32 +0100 Subject: [PATCH 02/45] add SearchSavedSparql entity similar to SearchSavedQuery --- .../entity/search/SearchSavedSparql.java | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 src/main/java/org/fairdatateam/fairdatapoint/entity/search/SearchSavedSparql.java diff --git a/src/main/java/org/fairdatateam/fairdatapoint/entity/search/SearchSavedSparql.java b/src/main/java/org/fairdatateam/fairdatapoint/entity/search/SearchSavedSparql.java new file mode 100644 index 000000000..ffdca37c3 --- /dev/null +++ b/src/main/java/org/fairdatateam/fairdatapoint/entity/search/SearchSavedSparql.java @@ -0,0 +1,79 @@ +/** + * The MIT License + * Copyright © 2017 DTL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package nl.dtls.fairdatapoint.entity.search; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.bson.types.ObjectId; +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +import java.time.Instant; + +@Document +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +public class SearchSavedSparql { + + @Id + private ObjectId id; + + private String uuid; + + private String userUuid; + + private AccessLevel accessLevel; + + private Instant createdAt; + + private Instant updatedAt; + + private String name; + + private String description; + + private String query; + + private String defaultGraphUri; + + private String namedGraphUri; + + @Getter + public enum AccessLevel { + // todo: update SearchSavedQuery and SearchSavedQueryType to match this + AUTHENTICATED("all authenticated users have access"), + CREATOR("only creator has access"); + + private final String description; + + AccessLevel(String description) { + this.description = description; + } + } + +} From ac2ecbb010807714c1f9fc29dc9b9900b63be7cf Mon Sep 17 00:00:00 2001 From: dennisvang <29799340+dennisvang@users.noreply.github.com> Date: Wed, 18 Mar 2026 10:18:06 +0100 Subject: [PATCH 03/45] move SearchSavedQueryType enum into SearchSavedQuery class to improve encapsulation and readability --- .../api/dto/search/SearchSavedQueryChangeDTO.java | 4 ++-- .../api/dto/search/SearchSavedQueryDTO.java | 4 ++-- .../search/SearchSavedQueryFixtures.java | 7 +++---- .../entity/search/SearchSavedQuery.java | 9 ++++++++- .../search/query/SearchSavedQueryService.java | 5 ++--- .../search/query/saved/Detail_DELETE.java | 5 ----- .../acceptance/search/query/saved/Detail_PUT.java | 13 ++++++------- .../acceptance/search/query/saved/List_POST.java | 8 +++----- 8 files changed, 26 insertions(+), 29 deletions(-) diff --git a/src/main/java/org/fairdatateam/fairdatapoint/api/dto/search/SearchSavedQueryChangeDTO.java b/src/main/java/org/fairdatateam/fairdatapoint/api/dto/search/SearchSavedQueryChangeDTO.java index ec6632172..d97c6b12b 100644 --- a/src/main/java/org/fairdatateam/fairdatapoint/api/dto/search/SearchSavedQueryChangeDTO.java +++ b/src/main/java/org/fairdatateam/fairdatapoint/api/dto/search/SearchSavedQueryChangeDTO.java @@ -26,7 +26,7 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import lombok.*; -import org.fairdatateam.fairdatapoint.entity.search.SearchSavedQueryType; +import org.fairdatateam.fairdatapoint.entity.search.SearchSavedQuery; @NoArgsConstructor @AllArgsConstructor @@ -42,7 +42,7 @@ public class SearchSavedQueryChangeDTO { private String description; @NotNull - private SearchSavedQueryType type; + private SearchSavedQuery.Type type; @Valid @NotNull diff --git a/src/main/java/org/fairdatateam/fairdatapoint/api/dto/search/SearchSavedQueryDTO.java b/src/main/java/org/fairdatateam/fairdatapoint/api/dto/search/SearchSavedQueryDTO.java index 5b15ef74b..29705b3c5 100644 --- a/src/main/java/org/fairdatateam/fairdatapoint/api/dto/search/SearchSavedQueryDTO.java +++ b/src/main/java/org/fairdatateam/fairdatapoint/api/dto/search/SearchSavedQueryDTO.java @@ -28,7 +28,7 @@ import jakarta.validation.constraints.NotNull; import lombok.*; import org.fairdatateam.fairdatapoint.api.dto.user.UserDTO; -import org.fairdatateam.fairdatapoint.entity.search.SearchSavedQueryType; +import org.fairdatateam.fairdatapoint.entity.search.SearchSavedQuery; import java.time.Instant; @@ -49,7 +49,7 @@ public class SearchSavedQueryDTO { private String description; @NotNull - private SearchSavedQueryType type; + private SearchSavedQuery.Type type; @Valid @JsonInclude diff --git a/src/main/java/org/fairdatateam/fairdatapoint/database/mongo/migration/development/search/SearchSavedQueryFixtures.java b/src/main/java/org/fairdatateam/fairdatapoint/database/mongo/migration/development/search/SearchSavedQueryFixtures.java index 2fcf379e9..46cf9ee14 100644 --- a/src/main/java/org/fairdatateam/fairdatapoint/database/mongo/migration/development/search/SearchSavedQueryFixtures.java +++ b/src/main/java/org/fairdatateam/fairdatapoint/database/mongo/migration/development/search/SearchSavedQueryFixtures.java @@ -24,7 +24,6 @@ import org.fairdatateam.fairdatapoint.api.dto.search.SearchQueryVariablesDTO; import org.fairdatateam.fairdatapoint.entity.search.SearchSavedQuery; -import org.fairdatateam.fairdatapoint.entity.search.SearchSavedQueryType; import org.fairdatateam.fairdatapoint.util.KnownUUIDs; import org.springframework.stereotype.Service; @@ -42,7 +41,7 @@ public SearchSavedQuery savedQueryPublic01() { .uuid(UUID.randomUUID().toString()) .name("All datasets") .description("Quickly query all datasets (DCAT)") - .type(SearchSavedQueryType.PUBLIC) + .type(SearchSavedQuery.Type.PUBLIC) .userUuid(KnownUUIDs.USER_ALBERT_UUID) .variables(SearchQueryVariablesDTO.builder() .prefixes(PREFIX_DCAT) @@ -60,7 +59,7 @@ public SearchSavedQuery savedQueryInternal01() { .uuid(UUID.randomUUID().toString()) .name("All distributions") .description("Quickly query all distributions (DCAT)") - .type(SearchSavedQueryType.INTERNAL) + .type(SearchSavedQuery.Type.INTERNAL) .userUuid(KnownUUIDs.USER_ADMIN_UUID) .variables(SearchQueryVariablesDTO.builder() .prefixes(PREFIX_DCAT) @@ -78,7 +77,7 @@ public SearchSavedQuery savedQueryPrivate01() { .uuid(UUID.randomUUID().toString()) .name("Things with data") .description("This is private query of Nikola Tesla.") - .type(SearchSavedQueryType.PRIVATE) + .type(SearchSavedQuery.Type.PRIVATE) .userUuid(KnownUUIDs.USER_NIKOLA_UUID) .variables(SearchQueryVariablesDTO.builder() .prefixes("") diff --git a/src/main/java/org/fairdatateam/fairdatapoint/entity/search/SearchSavedQuery.java b/src/main/java/org/fairdatateam/fairdatapoint/entity/search/SearchSavedQuery.java index 31d9e7d44..faf69eedd 100644 --- a/src/main/java/org/fairdatateam/fairdatapoint/entity/search/SearchSavedQuery.java +++ b/src/main/java/org/fairdatateam/fairdatapoint/entity/search/SearchSavedQuery.java @@ -49,11 +49,18 @@ public class SearchSavedQuery { private String userUuid; - private SearchSavedQueryType type; + private Type type; private Instant createdAt; private Instant updatedAt; private SearchQueryVariablesDTO variables; + + public enum Type { + PUBLIC, + PRIVATE, + INTERNAL + } + } diff --git a/src/main/java/org/fairdatateam/fairdatapoint/service/search/query/SearchSavedQueryService.java b/src/main/java/org/fairdatateam/fairdatapoint/service/search/query/SearchSavedQueryService.java index 266112681..4e04a74ef 100644 --- a/src/main/java/org/fairdatateam/fairdatapoint/service/search/query/SearchSavedQueryService.java +++ b/src/main/java/org/fairdatateam/fairdatapoint/service/search/query/SearchSavedQueryService.java @@ -27,7 +27,6 @@ import org.fairdatateam.fairdatapoint.database.mongo.repository.SearchSavedQueryRepository; import org.fairdatateam.fairdatapoint.entity.exception.ForbiddenException; import org.fairdatateam.fairdatapoint.entity.search.SearchSavedQuery; -import org.fairdatateam.fairdatapoint.entity.search.SearchSavedQueryType; import org.fairdatateam.fairdatapoint.entity.user.User; import org.fairdatateam.fairdatapoint.entity.user.UserRole; import org.fairdatateam.fairdatapoint.service.security.CurrentUserProvider; @@ -108,7 +107,7 @@ public Optional update(String uuid, SearchSavedQueryChangeD } private boolean canSeeQuery(Optional optionalUser, SearchSavedQuery query) { - return query.getType().equals(SearchSavedQueryType.PUBLIC) + return query.getType().equals(SearchSavedQuery.Type.PUBLIC) || optionalUser .filter(user -> user.getRole().equals(UserRole.ADMIN)) .isPresent() @@ -118,7 +117,7 @@ private boolean canSeeQuery(Optional optionalUser, SearchSavedQuery query) } private boolean isOwnOrInternal(User user, SearchSavedQuery query) { - return query.getType().equals(SearchSavedQueryType.INTERNAL) + return query.getType().equals(SearchSavedQuery.Type.INTERNAL) || Objects.equals(query.getUserUuid(), user.getUuid()); } diff --git a/src/test/java/org/fairdatateam/fairdatapoint/acceptance/search/query/saved/Detail_DELETE.java b/src/test/java/org/fairdatateam/fairdatapoint/acceptance/search/query/saved/Detail_DELETE.java index da3452670..a45e5d545 100644 --- a/src/test/java/org/fairdatateam/fairdatapoint/acceptance/search/query/saved/Detail_DELETE.java +++ b/src/test/java/org/fairdatateam/fairdatapoint/acceptance/search/query/saved/Detail_DELETE.java @@ -23,14 +23,9 @@ package org.fairdatateam.fairdatapoint.acceptance.search.query.saved; import org.fairdatateam.fairdatapoint.WebIntegrationTest; -import org.fairdatateam.fairdatapoint.api.dto.search.SearchQueryVariablesDTO; -import org.fairdatateam.fairdatapoint.api.dto.search.SearchSavedQueryChangeDTO; -import org.fairdatateam.fairdatapoint.api.dto.search.SearchSavedQueryDTO; import org.fairdatateam.fairdatapoint.database.mongo.migration.development.search.SearchSavedQueryFixtures; import org.fairdatateam.fairdatapoint.database.mongo.repository.SearchSavedQueryRepository; import org.fairdatateam.fairdatapoint.entity.search.SearchSavedQuery; -import org.fairdatateam.fairdatapoint.entity.search.SearchSavedQueryType; -import org.fairdatateam.fairdatapoint.util.KnownUUIDs; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/src/test/java/org/fairdatateam/fairdatapoint/acceptance/search/query/saved/Detail_PUT.java b/src/test/java/org/fairdatateam/fairdatapoint/acceptance/search/query/saved/Detail_PUT.java index 54cdb1764..a926022c1 100644 --- a/src/test/java/org/fairdatateam/fairdatapoint/acceptance/search/query/saved/Detail_PUT.java +++ b/src/test/java/org/fairdatateam/fairdatapoint/acceptance/search/query/saved/Detail_PUT.java @@ -29,7 +29,6 @@ import org.fairdatateam.fairdatapoint.database.mongo.migration.development.search.SearchSavedQueryFixtures; import org.fairdatateam.fairdatapoint.database.mongo.repository.SearchSavedQueryRepository; import org.fairdatateam.fairdatapoint.entity.search.SearchSavedQuery; -import org.fairdatateam.fairdatapoint.entity.search.SearchSavedQueryType; import org.fairdatateam.fairdatapoint.util.KnownUUIDs; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -73,7 +72,7 @@ public void res403_anonymousUser() { SearchSavedQueryChangeDTO.builder() .name("Edited query") .description("") - .type(SearchSavedQueryType.PUBLIC) + .type(SearchSavedQuery.Type.PUBLIC) .variables(SearchQueryVariablesDTO.builder() .prefixes("A") .graphPattern("B") @@ -107,7 +106,7 @@ public void res403_nonOwnerUser() { SearchSavedQueryChangeDTO.builder() .name("Edited query") .description("") - .type(SearchSavedQueryType.PUBLIC) + .type(SearchSavedQuery.Type.PUBLIC) .variables(SearchQueryVariablesDTO.builder() .prefixes("A") .graphPattern("B") @@ -141,7 +140,7 @@ public void res200_owner() { SearchSavedQueryChangeDTO.builder() .name("Edited query") .description("") - .type(SearchSavedQueryType.INTERNAL) + .type(SearchSavedQuery.Type.INTERNAL) .variables(SearchQueryVariablesDTO.builder() .prefixes("A") .graphPattern("B") @@ -159,7 +158,7 @@ public void res200_owner() { // THEN: assertThat(result.getStatusCode(), is(equalTo(HttpStatus.OK))); assertThat(result.getBody().getUser().getUuid(), is(equalTo(KnownUUIDs.USER_ALBERT_UUID))); - assertThat(result.getBody().getType(), is(equalTo(SearchSavedQueryType.INTERNAL))); + assertThat(result.getBody().getType(), is(equalTo(SearchSavedQuery.Type.INTERNAL))); assertThat(result.getBody().getName(), is(equalTo("Edited query"))); assertThat(result.getBody().getVariables().getPrefixes(), is(equalTo("A"))); assertThat(result.getBody().getVariables().getGraphPattern(), is(equalTo("B"))); @@ -181,7 +180,7 @@ public void res200_admin() { SearchSavedQueryChangeDTO.builder() .name("Edited query") .description("") - .type(SearchSavedQueryType.INTERNAL) + .type(SearchSavedQuery.Type.INTERNAL) .variables(SearchQueryVariablesDTO.builder() .prefixes("A") .graphPattern("B") @@ -199,7 +198,7 @@ public void res200_admin() { // THEN: assertThat(result.getStatusCode(), is(equalTo(HttpStatus.OK))); assertThat(result.getBody().getUser().getUuid(), is(equalTo(KnownUUIDs.USER_ALBERT_UUID))); - assertThat(result.getBody().getType(), is(equalTo(SearchSavedQueryType.INTERNAL))); + assertThat(result.getBody().getType(), is(equalTo(SearchSavedQuery.Type.INTERNAL))); assertThat(result.getBody().getName(), is(equalTo("Edited query"))); assertThat(result.getBody().getVariables().getPrefixes(), is(equalTo("A"))); assertThat(result.getBody().getVariables().getGraphPattern(), is(equalTo("B"))); diff --git a/src/test/java/org/fairdatateam/fairdatapoint/acceptance/search/query/saved/List_POST.java b/src/test/java/org/fairdatateam/fairdatapoint/acceptance/search/query/saved/List_POST.java index 259ff3942..3e3dc82b2 100644 --- a/src/test/java/org/fairdatateam/fairdatapoint/acceptance/search/query/saved/List_POST.java +++ b/src/test/java/org/fairdatateam/fairdatapoint/acceptance/search/query/saved/List_POST.java @@ -26,10 +26,8 @@ import org.fairdatateam.fairdatapoint.api.dto.search.SearchQueryVariablesDTO; import org.fairdatateam.fairdatapoint.api.dto.search.SearchSavedQueryChangeDTO; import org.fairdatateam.fairdatapoint.api.dto.search.SearchSavedQueryDTO; -import org.fairdatateam.fairdatapoint.database.mongo.migration.development.search.SearchSavedQueryFixtures; import org.fairdatateam.fairdatapoint.database.mongo.repository.SearchSavedQueryRepository; import org.fairdatateam.fairdatapoint.entity.search.SearchSavedQuery; -import org.fairdatateam.fairdatapoint.entity.search.SearchSavedQueryType; import org.fairdatateam.fairdatapoint.util.KnownUUIDs; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -70,7 +68,7 @@ public void res403_anonymousUser() { SearchSavedQueryChangeDTO.builder() .name("New query") .description("") - .type(SearchSavedQueryType.PUBLIC) + .type(SearchSavedQuery.Type.PUBLIC) .variables(SearchQueryVariablesDTO.builder() .prefixes("") .graphPattern("") @@ -104,7 +102,7 @@ public void res201() { SearchSavedQueryChangeDTO.builder() .name("New query") .description("") - .type(SearchSavedQueryType.PUBLIC) + .type(SearchSavedQuery.Type.PUBLIC) .variables(SearchQueryVariablesDTO.builder() .prefixes("") .graphPattern("") @@ -122,7 +120,7 @@ public void res201() { // THEN: assertThat(result.getStatusCode(), is(equalTo(HttpStatus.CREATED))); assertThat(result.getBody().getUser().getUuid(), is(equalTo(KnownUUIDs.USER_NIKOLA_UUID))); - assertThat(result.getBody().getType(), is(equalTo(SearchSavedQueryType.PUBLIC))); + assertThat(result.getBody().getType(), is(equalTo(SearchSavedQuery.Type.PUBLIC))); assertThat(searchSavedQueryRepository.count(), is(equalTo(1L))); } } From 1d3f9827640bdcbd6530e06beb46086eaa6040ad Mon Sep 17 00:00:00 2001 From: dennisvang <29799340+dennisvang@users.noreply.github.com> Date: Mon, 23 Mar 2026 09:44:07 +0100 Subject: [PATCH 04/45] add sequence diagram for saved query (wip) --- docs/diagrams/sequence-save-query.mermaid | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 docs/diagrams/sequence-save-query.mermaid diff --git a/docs/diagrams/sequence-save-query.mermaid b/docs/diagrams/sequence-save-query.mermaid new file mode 100644 index 000000000..75685f2f7 --- /dev/null +++ b/docs/diagrams/sequence-save-query.mermaid @@ -0,0 +1,3 @@ +sequenceDiagram + user ->> fdp-client: GET /search/query + fdp-client ->> fdp: POST From 1ff6cbf1ef05ca944543a56fe5954c7e9f2cff33 Mon Sep 17 00:00:00 2001 From: dennisvang <29799340+dennisvang@users.noreply.github.com> Date: Mon, 23 Mar 2026 11:34:48 +0100 Subject: [PATCH 05/45] fix package name for SearchSavedSparql --- .../fairdatapoint/entity/search/SearchSavedSparql.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/fairdatateam/fairdatapoint/entity/search/SearchSavedSparql.java b/src/main/java/org/fairdatateam/fairdatapoint/entity/search/SearchSavedSparql.java index ffdca37c3..f737cd0f5 100644 --- a/src/main/java/org/fairdatateam/fairdatapoint/entity/search/SearchSavedSparql.java +++ b/src/main/java/org/fairdatateam/fairdatapoint/entity/search/SearchSavedSparql.java @@ -21,7 +21,7 @@ * THE SOFTWARE. */ -package nl.dtls.fairdatapoint.entity.search; +package org.fairdatateam.fairdatapoint.entity.search; import lombok.AllArgsConstructor; import lombok.Getter; From 243341f95702fc24bf50b240737cff5ee71fc782 Mon Sep 17 00:00:00 2001 From: dennisvang <29799340+dennisvang@users.noreply.github.com> Date: Mon, 23 Mar 2026 13:10:41 +0100 Subject: [PATCH 06/45] complete saved-query sequence diagram --- docs/diagrams/sequence-save-query.mermaid | 48 ++++++++++++++++++++++- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/docs/diagrams/sequence-save-query.mermaid b/docs/diagrams/sequence-save-query.mermaid index 75685f2f7..6d22dd654 100644 --- a/docs/diagrams/sequence-save-query.mermaid +++ b/docs/diagrams/sequence-save-query.mermaid @@ -1,3 +1,47 @@ +%% restricted sparql query execution and saving in fdp v1.18.x sequenceDiagram - user ->> fdp-client: GET /search/query - fdp-client ->> fdp: POST +%% simple search or switch to advanced search + user ->> fdp-client: use search box
or click "Advanced" under search box + fdp-client ->> fdp-client: /search + fdp-client ->> fdp: GET /search/query + fdp-client ->> fdp: GET /search/filters + fdp-client ->> fdp: GET /search/query/saved + fdp-client ->> fdp: POST /search/query

{"graphPattern": str, "ordering": str, "prefixes": str} + fdp ->> fdp-client: Status 200
{"template":