diff --git a/doc/release-notes/11588-search-api-doesnt-return-image-url.md b/doc/release-notes/11588-search-api-doesnt-return-image-url.md new file mode 100644 index 00000000000..6d0a474281c --- /dev/null +++ b/doc/release-notes/11588-search-api-doesnt-return-image-url.md @@ -0,0 +1,4 @@ +## BUG ## +Search API doesn't return image_url after newly created dataset is published. + +The Dataset thumbnail will be created automatically when a Dataset is published under the following conditions: The Dataset has no existing thumbnail; The Dataset has image files that can be converted to a thumbnail; The Feature Flag "disable-dataset-thumbnail-autoselect" is not enabled; diff --git a/src/main/java/edu/harvard/iq/dataverse/Dataset.java b/src/main/java/edu/harvard/iq/dataverse/Dataset.java index 71686adbc4b..39dccdcd4ea 100644 --- a/src/main/java/edu/harvard/iq/dataverse/Dataset.java +++ b/src/main/java/edu/harvard/iq/dataverse/Dataset.java @@ -763,6 +763,10 @@ public void setThumbnailFile(DataFile thumbnailFile) { this.thumbnailFile = thumbnailFile; } + public String getThumbnailUrl() { + return thumbnailFile != null ? SystemConfig.getDataverseSiteUrlStatic() + "/api/datasets/" + this.getId() + "/logo" : null; + } + public boolean isUseGenericThumbnail() { return useGenericThumbnail; } diff --git a/src/main/java/edu/harvard/iq/dataverse/ThumbnailServiceWrapper.java b/src/main/java/edu/harvard/iq/dataverse/ThumbnailServiceWrapper.java index 46736da73d4..eca3f470938 100644 --- a/src/main/java/edu/harvard/iq/dataverse/ThumbnailServiceWrapper.java +++ b/src/main/java/edu/harvard/iq/dataverse/ThumbnailServiceWrapper.java @@ -208,11 +208,11 @@ public String getDatasetCardImageAsUrl(Dataset dataset, Long versionId, boolean // If no other logo we attempt to auto-select via the optimized, native // query-based method // from the DatasetVersionService: - if (!hasDatasetLogo && datasetVersionService.getThumbnailByVersionId(versionId) == null) { + if (!hasDatasetLogo && (!autoselect || datasetVersionService.getThumbnailByVersionId(versionId) == null)) { return null; } } - String url = SystemConfig.getDataverseSiteUrlStatic() + "/api/datasets/" + dataset.getId() + "/logo"; + String url = dataset.getThumbnailUrl(); logger.fine("getDatasetCardImageAsUrl: " + url); this.dvobjectThumbnailsMap.put(datasetId,url); return url; diff --git a/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/FinalizeDatasetPublicationCommand.java b/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/FinalizeDatasetPublicationCommand.java index 51e37efe2b2..e5bf93f283d 100644 --- a/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/FinalizeDatasetPublicationCommand.java +++ b/src/main/java/edu/harvard/iq/dataverse/engine/command/impl/FinalizeDatasetPublicationCommand.java @@ -1,5 +1,6 @@ package edu.harvard.iq.dataverse.engine.command.impl; +import com.rometools.utils.Lists; import edu.harvard.iq.dataverse.ControlledVocabularyValue; import edu.harvard.iq.dataverse.CurationStatus; import edu.harvard.iq.dataverse.DataFile; @@ -17,6 +18,8 @@ import edu.harvard.iq.dataverse.UserNotification; import edu.harvard.iq.dataverse.authorization.Permission; import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser; +import edu.harvard.iq.dataverse.dataaccess.ImageThumbConverter; +import edu.harvard.iq.dataverse.dataset.DatasetThumbnail; import edu.harvard.iq.dataverse.dataset.DatasetUtil; import edu.harvard.iq.dataverse.engine.command.CommandContext; import edu.harvard.iq.dataverse.engine.command.DataverseRequest; @@ -24,6 +27,7 @@ import edu.harvard.iq.dataverse.engine.command.exception.CommandException; import edu.harvard.iq.dataverse.pidproviders.PidProvider; import edu.harvard.iq.dataverse.privateurl.PrivateUrl; +import edu.harvard.iq.dataverse.settings.FeatureFlags; import edu.harvard.iq.dataverse.util.BundleUtil; import edu.harvard.iq.dataverse.workflow.WorkflowContext; import edu.harvard.iq.dataverse.workflow.WorkflowContext.TriggerType; @@ -171,7 +175,12 @@ public Dataset execute(CommandContext ctxt) throws CommandException { //Use dataset pub date (which may not be the current date for migrated datasets) updateFiles(new Timestamp(version.getReleaseTime().getTime()), ctxt); - + + // Populate thumbnail if needed and allowed + if (theDataset.getThumbnailFile() == null && !theDataset.isUseGenericThumbnail()) { + ctxt.datasetVersion().getThumbnailByVersionId(version.getId()); + } + // // TODO: Not sure if this .merge() is necessary here - ? // I'm moving a bunch of code from PublishDatasetCommand here; and this .merge() diff --git a/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java b/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java index 729596fb3d4..8f975a3c976 100644 --- a/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java +++ b/src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java @@ -551,6 +551,7 @@ public static JsonObjectBuilder json(Dataset ds, Boolean returnOwners) { .add("separator", ds.getSeparator()) .add("publisher", BrandingUtil.getInstallationBrandName()) .add("publicationDate", ds.getPublicationDateFormattedYYYYMMDD()) + .add("image_url", ds.getThumbnailUrl()) .add("storageIdentifier", ds.getStorageIdentifier()); if (ds.getGuestbook() != null) { bld.add("guestbookId", ds.getGuestbook().getId()); diff --git a/src/test/java/edu/harvard/iq/dataverse/api/SearchIT.java b/src/test/java/edu/harvard/iq/dataverse/api/SearchIT.java index 2692b6e464f..df1477c6e59 100644 --- a/src/test/java/edu/harvard/iq/dataverse/api/SearchIT.java +++ b/src/test/java/edu/harvard/iq/dataverse/api/SearchIT.java @@ -37,8 +37,8 @@ import static java.lang.Thread.sleep; import java.nio.file.Path; import java.nio.file.Paths; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.is; + +import static org.hamcrest.CoreMatchers.*; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; @@ -2422,4 +2422,58 @@ public void testFileAddedAfterPublicationIsIndexed() { .statusCode(OK.getStatusCode()); } + @Test + public void testWithThumbnailAutoSelect() { + Response createUser = UtilIT.createRandomUser(); + createUser.prettyPrint(); + createUser.then().assertThat().statusCode(OK.getStatusCode()); + String apiToken = UtilIT.getApiTokenFromResponse(createUser); + + Response createDataverseResponse = UtilIT.createRandomDataverse(apiToken); + createDataverseResponse.prettyPrint(); + createDataverseResponse.then().assertThat().statusCode(CREATED.getStatusCode()); + String dataverseAlias = UtilIT.getAliasFromResponse(createDataverseResponse); + UtilIT.publishDataverseViaNativeApi(dataverseAlias, apiToken); + + Response createDatasetResponse = UtilIT.createRandomDatasetViaNativeApi(dataverseAlias, apiToken); + createDatasetResponse.prettyPrint(); + createDatasetResponse.then().assertThat().statusCode(CREATED.getStatusCode()); + Integer datasetId = UtilIT.getDatasetIdFromResponse(createDatasetResponse); + String persistentId = UtilIT.getDatasetPersistentIdFromResponse(createDatasetResponse); + + uploadFile(datasetId, "src/test/resources/tab/test.tab", apiToken); + uploadFile(datasetId, "src/main/webapp/resources/images/dataverse-icon-1200.png", apiToken); + uploadFile(datasetId, "src/main/webapp/resources/images/dataverseproject.png", apiToken); + Response publishResponse = UtilIT.publishDatasetViaNativeApi(datasetId, "major", apiToken); + publishResponse.prettyPrint(); + publishResponse.then().assertThat().statusCode(OK.getStatusCode()); + UtilIT.sleepForReindex(datasetId.toString(), apiToken, 4); + + Response search1 = UtilIT.search("id:dataset_" + datasetId, apiToken); + search1.prettyPrint(); + search1.then().assertThat() + .body("data.items[0].name", equalTo("Darwin's Finches")) + .body("data.items[0].image_url", notNullValue()) + .statusCode(OK.getStatusCode()); + + Response getDatasetResponse = UtilIT.getDatasetWithOwners(persistentId, apiToken, false); + getDatasetResponse.prettyPrint(); + getDatasetResponse.then().assertThat() + .body("data.image_url", notNullValue()) + .statusCode(OK.getStatusCode()); + } + + private long uploadFile(Integer datasetId, String pathToFile, String apiToken) { + JsonObjectBuilder json = Json.createObjectBuilder() + .add("description", "Test Data") + .add("directoryLabel", "data/subdir1") + .add("categories", Json.createArrayBuilder() + .add("Data") + ); + Response addResponse = UtilIT.uploadFileViaNative(datasetId.toString(), pathToFile, json.build(), apiToken); + addResponse.prettyPrint(); + addResponse.then().assertThat().statusCode(OK.getStatusCode()); + assertTrue(UtilIT.sleepForLock(datasetId.longValue(), "Ingest", apiToken, UtilIT.MAXIMUM_INGEST_LOCK_DURATION), "Failed test if Ingest Lock exceeds max duration " + pathToFile); + return UtilIT.getDataFileIdFromResponse(addResponse); + } }