Skip to content

Commit

Permalink
Merge pull request #10778 from johannes-darms/feat/10171-versions-sma…
Browse files Browse the repository at this point in the history
…ller-response

Extension of API `{id}/versions` and `{id}/versions/{versionId}` with an optional ``excludeMetadataBlocks`` parameter
  • Loading branch information
sekmiller authored Jan 8, 2025
2 parents 3352bb7 + bada794 commit 6d6a509
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 13 deletions.
4 changes: 4 additions & 0 deletions doc/release-notes/10171-exlude-metadatablocks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Extension of API `{id}/versions` and `{id}/versions/{versionId}` with an optional ``excludeMetadataBlocks`` parameter,
that specifies whether the metadataBlocks should be listed in the output. It defaults to ``false``, preserving backward
compatibility. (Note that for a dataset with a large number of versions and/or metadataBlocks having the metadata blocks
included can dramatically increase the volume of the output). See also [the guides](https://dataverse-guide--10778.org.readthedocs.build/en/10778/api/native-api.html#list-versions-of-a-dataset), #10778, and #10171.
8 changes: 8 additions & 0 deletions doc/sphinx-guides/source/api/native-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1295,6 +1295,8 @@ It returns a list of versions with their metadata, and file list:
The optional ``excludeFiles`` parameter specifies whether the files should be listed in the output. It defaults to ``true``, preserving backward compatibility. (Note that for a dataset with a large number of versions and/or files having the files included can dramatically increase the volume of the output). A separate ``/files`` API can be used for listing the files, or a subset thereof in a given version.

The optional ``excludeMetadataBlocks`` parameter specifies whether the metadata blocks should be listed in the output. It defaults to ``false``, preserving backward compatibility. (Note that for a dataset with a large number of versions and/or metadata blocks having the metadata blocks included can dramatically increase the volume of the output).

The optional ``offset`` and ``limit`` parameters can be used to specify the range of the versions list to be shown. This can be used to paginate through the list in a dataset with a large number of versions.


Expand All @@ -1319,6 +1321,12 @@ The fully expanded example above (without environment variables) looks like this
The optional ``excludeFiles`` parameter specifies whether the files should be listed in the output (defaults to ``true``). Note that a separate ``/files`` API can be used for listing the files, or a subset thereof in a given version.

.. code-block:: bash
curl "https://demo.dataverse.org/api/datasets/24/versions/1.0?excludeMetadataBlocks=false"
The optional ``excludeMetadataBlocks`` parameter specifies whether the metadata blocks should be listed in the output (defaults to ``false``).


By default, deaccessioned dataset versions are not included in the search when applying the :latest or :latest-published identifiers. Additionally, when filtering by a specific version tag, you will get a "not found" error if the version is deaccessioned and you do not enable the ``includeDeaccessioned`` option described below.

Expand Down
11 changes: 7 additions & 4 deletions src/main/java/edu/harvard/iq/dataverse/api/Datasets.java
Original file line number Diff line number Diff line change
Expand Up @@ -421,15 +421,16 @@ public Response useDefaultCitationDate(@Context ContainerRequestContext crc, @Pa
@GET
@AuthRequired
@Path("{id}/versions")
public Response listVersions(@Context ContainerRequestContext crc, @PathParam("id") String id, @QueryParam("excludeFiles") Boolean excludeFiles, @QueryParam("limit") Integer limit, @QueryParam("offset") Integer offset) {
public Response listVersions(@Context ContainerRequestContext crc, @PathParam("id") String id, @QueryParam("excludeFiles") Boolean excludeFiles,@QueryParam("excludeMetadataBlocks") Boolean excludeMetadataBlocks, @QueryParam("limit") Integer limit, @QueryParam("offset") Integer offset) {

return response( req -> {
Dataset dataset = findDatasetOrDie(id);
Boolean deepLookup = excludeFiles == null ? true : !excludeFiles;
Boolean includeMetadataBlocks = excludeMetadataBlocks == null ? true : !excludeMetadataBlocks;

return ok( execCommand( new ListVersionsCommand(req, dataset, offset, limit, deepLookup) )
.stream()
.map( d -> json(d, deepLookup) )
.map( d -> json(d, deepLookup, includeMetadataBlocks) )
.collect(toJsonArray()));
}, getRequestUser(crc));
}
Expand All @@ -441,6 +442,7 @@ public Response getVersion(@Context ContainerRequestContext crc,
@PathParam("id") String datasetId,
@PathParam("versionId") String versionId,
@QueryParam("excludeFiles") Boolean excludeFiles,
@QueryParam("excludeMetadataBlocks") Boolean excludeMetadataBlocks,
@QueryParam("includeDeaccessioned") boolean includeDeaccessioned,
@QueryParam("returnOwners") boolean returnOwners,
@Context UriInfo uriInfo,
Expand All @@ -466,11 +468,12 @@ public Response getVersion(@Context ContainerRequestContext crc,
if (excludeFiles == null ? true : !excludeFiles) {
requestedDatasetVersion = datasetversionService.findDeep(requestedDatasetVersion.getId());
}
Boolean includeMetadataBlocks = excludeMetadataBlocks == null ? true : !excludeMetadataBlocks;

JsonObjectBuilder jsonBuilder = json(requestedDatasetVersion,
null,
excludeFiles == null ? true : !excludeFiles,
returnOwners);
excludeFiles == null ? true : !excludeFiles,
returnOwners, includeMetadataBlocks);
return ok(jsonBuilder);

}, getRequestUser(crc));
Expand Down
23 changes: 15 additions & 8 deletions src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java
Original file line number Diff line number Diff line change
Expand Up @@ -423,11 +423,17 @@ public static JsonObjectBuilder json(FileDetailsHolder ds) {
}

public static JsonObjectBuilder json(DatasetVersion dsv, boolean includeFiles) {
return json(dsv, null, includeFiles, false);
return json(dsv, null, includeFiles, false,true);
}
public static JsonObjectBuilder json(DatasetVersion dsv, boolean includeFiles, boolean includeMetadataBlocks) {
return json(dsv, null, includeFiles, false, includeMetadataBlocks);
}
public static JsonObjectBuilder json(DatasetVersion dsv, List<String> anonymizedFieldTypeNamesList,
boolean includeFiles, boolean returnOwners) {
return json( dsv, anonymizedFieldTypeNamesList, includeFiles, returnOwners,true);
}

public static JsonObjectBuilder json(DatasetVersion dsv, List<String> anonymizedFieldTypeNamesList,
boolean includeFiles, boolean returnOwners) {
boolean includeFiles, boolean returnOwners, boolean includeMetadataBlocks) {
Dataset dataset = dsv.getDataset();
JsonObjectBuilder bld = jsonObjectBuilder()
.add("id", dsv.getId()).add("datasetId", dataset.getId())
Expand Down Expand Up @@ -472,11 +478,12 @@ public static JsonObjectBuilder json(DatasetVersion dsv, List<String> anonymized
.add("sizeOfCollection", dsv.getTermsOfUseAndAccess().getSizeOfCollection())
.add("studyCompletion", dsv.getTermsOfUseAndAccess().getStudyCompletion())
.add("fileAccessRequest", dsv.getTermsOfUseAndAccess().isFileAccessRequest());

bld.add("metadataBlocks", (anonymizedFieldTypeNamesList != null) ?
jsonByBlocks(dsv.getDatasetFields(), anonymizedFieldTypeNamesList)
: jsonByBlocks(dsv.getDatasetFields())
);
if(includeMetadataBlocks) {
bld.add("metadataBlocks", (anonymizedFieldTypeNamesList != null) ?
jsonByBlocks(dsv.getDatasetFields(), anonymizedFieldTypeNamesList)
: jsonByBlocks(dsv.getDatasetFields())
);
}
if(returnOwners){
bld.add("isPartOf", getOwnersFromDvObject(dataset));
}
Expand Down
36 changes: 36 additions & 0 deletions src/test/java/edu/harvard/iq/dataverse/api/DatasetsIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,42 @@ public void testCreatePublishDestroyDataset() {

}

@Test
public void testHideMetadataBlocksInDatasetVersionsAPI() {

// Create user
String apiToken = UtilIT.createRandomUserGetToken();

// Create user with no permission
String apiTokenNoPerms = UtilIT.createRandomUserGetToken();

// Create Collection
String collectionAlias = UtilIT.createRandomCollectionGetAlias(apiToken);

// Create Dataset
Response createDataset = UtilIT.createRandomDatasetViaNativeApi(collectionAlias, apiToken);
createDataset.then().assertThat()
.statusCode(CREATED.getStatusCode());

Integer datasetId = UtilIT.getDatasetIdFromResponse(createDataset);
String datasetPid = JsonPath.from(createDataset.asString()).getString("data.persistentId");

// Now check that the metadata is NOT shown, when we ask the versions api to dos o.
boolean excludeMetadata = true;
Response unpublishedDraft = UtilIT.getDatasetVersion(datasetPid, DS_VERSION_DRAFT, apiToken, true,excludeMetadata, false);
unpublishedDraft.prettyPrint();
unpublishedDraft.then().assertThat()
.statusCode(OK.getStatusCode())
.body("data.metadataBlocks", equalTo(null));

// Now check that the metadata is shown, when we ask the versions api to dos o.
excludeMetadata = false;
unpublishedDraft = UtilIT.getDatasetVersion(datasetPid, DS_VERSION_DRAFT, apiToken,true, excludeMetadata, false);
unpublishedDraft.prettyPrint();
unpublishedDraft.then().assertThat()
.statusCode(OK.getStatusCode())
.body("data.metadataBlocks", notNullValue() );
}
/**
* The apis (/api/datasets/{id}/versions and /api/datasets/{id}/versions/{vid}
* are already called from other RestAssured tests, in this class and also in FilesIT.
Expand Down
6 changes: 5 additions & 1 deletion src/test/java/edu/harvard/iq/dataverse/api/UtilIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -1623,14 +1623,18 @@ static Response getDatasetVersion(String persistentId, String versionNumber, Str
}

static Response getDatasetVersion(String persistentId, String versionNumber, String apiToken, boolean excludeFiles, boolean includeDeaccessioned) {
return getDatasetVersion(persistentId,versionNumber,apiToken,excludeFiles,false,includeDeaccessioned);
}
static Response getDatasetVersion(String persistentId, String versionNumber, String apiToken, boolean excludeFiles,boolean excludeMetadataBlocks, boolean includeDeaccessioned) {
return given()
.header(API_TOKEN_HTTP_HEADER, apiToken)
.queryParam("includeDeaccessioned", includeDeaccessioned)
.get("/api/datasets/:persistentId/versions/"
+ versionNumber
+ "?persistentId="
+ persistentId
+ (excludeFiles ? "&excludeFiles=true" : ""));
+ (excludeFiles ? "&excludeFiles=true" : "")
+ (excludeMetadataBlocks ? "&excludeMetadataBlocks=true" : ""));
}
static Response compareDatasetVersions(String persistentId, String versionNumber1, String versionNumber2, String apiToken) {
return given()
Expand Down

0 comments on commit 6d6a509

Please sign in to comment.