Skip to content

Commit bbd67c9

Browse files
committed
Merge branch 'PIDFailTracking' of https://github.com/QualitativeDataRepository/dataverse.git into PIDFailTracking
2 parents 8eb4f62 + 155c06b commit bbd67c9

File tree

15 files changed

+395
-40
lines changed

15 files changed

+395
-40
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Release Notes
2+
3+
## Templates API fixes
4+
- Added the missing `isDefault` field to the **Get Dataset Templates** API response.
5+
- Added the missing `fileAccessRequest` field of terms of use and access to the **Get Dataset Templates** API response.
6+
- Added the missing `contactForAccess` field of terms of use and access to the **Get Dataset Templates** API response.
7+
- Resolved an API **500 error** that occurred when working with templates containing custom license terms.
8+
- Updated API behavior so templates are **no longer returned from parent dataverses** when the "Include Templates from Root" option is unchecked in the UI.
9+
10+
## Notifications API fixes
11+
- Fixed API errors caused by NullPointerException when retrieving notifications without a requestor.
12+
13+
See #11704

doc/sphinx-guides/source/developers/deployment.rst

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,16 @@ Migrating Datafiles from Local Storage to S3
110110

111111
A number of pilot Dataverse installations start on local storage, then administrators are tasked with migrating datafiles into S3 or similar object stores. The files may be copied with a command-line utility such as `s3cmd <https://s3tools.org/s3cmd>`_. You will want to retain the local file hierarchy, keeping the authority (for example: 10.5072) at the bucket "root."
112112

113-
The below example queries may assist with updating dataset and datafile locations in the Dataverse installation's PostgresQL database. Depending on the initial version of the Dataverse Software and subsequent upgrade path, Datafile storage identifiers may or may not include a ``file://`` prefix, so you'll want to catch both cases.
113+
The below example queries may assist with updating dataset and datafile locations in the Dataverse installation's PostgresQL database. Depending on the initial version of the Dataverse Software and subsequent upgrade path, Datafile storage identifiers may or may not include a ``file://`` prefix, so you'll want to catch both cases.
114+
115+
In the following queries, ``<id>://`` refers to the ``id`` you have set for the datastore in the configuration (see the :ref:`file-storage` section of the Installation Guide).
114116

115117
To Update Dataset Location to S3, Assuming a ``file://`` Prefix
116118
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
117119

118120
::
119121

120-
UPDATE dvobject SET storageidentifier=REPLACE(storageidentifier,'file://','s3://')
122+
UPDATE dvobject SET storageidentifier=REPLACE(storageidentifier,'file://','<id>://')
121123
WHERE dtype='Dataset';
122124

123125
To Update Datafile Location to your-s3-bucket, Assuming a ``file://`` Prefix
@@ -126,17 +128,17 @@ To Update Datafile Location to your-s3-bucket, Assuming a ``file://`` Prefix
126128
::
127129

128130
UPDATE dvobject
129-
SET storageidentifier=REPLACE(storageidentifier,'file://','s3://your-s3-bucket:')
131+
SET storageidentifier=REPLACE(storageidentifier,'file://','<id>://your-s3-bucket:')
130132
WHERE id IN (SELECT o.id FROM dvobject o, dataset s WHERE o.dtype = 'DataFile'
131133
AND s.id = o.owner_id AND s.harvestingclient_id IS null
132-
AND o.storageidentifier NOT LIKE 's3://%');
134+
AND o.storageidentifier NOT LIKE '<id>://%');
133135

134136
To Update Datafile Location to your-s3-bucket, Assuming no ``file://`` Prefix
135137
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
136138

137139
::
138140

139-
UPDATE dvobject SET storageidentifier=CONCAT('s3://your-s3-bucket:', storageidentifier)
141+
UPDATE dvobject SET storageidentifier=CONCAT('<id>://your-s3-bucket:', storageidentifier)
140142
WHERE id IN (SELECT o.id FROM dvobject o, dataset s WHERE o.dtype = 'DataFile'
141143
AND s.id = o.owner_id AND s.harvestingclient_id IS null
142144
AND o.storageidentifier NOT LIKE '%://%');

doc/sphinx-guides/source/installation/config.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3797,6 +3797,9 @@ please find all known feature flags below. Any of these flags can be activated u
37973797
* - shibboleth-use-localhost
37983798
- A Shibboleth-using Dataverse instance needs to make network calls to the locally-running ``shibd`` service. The default behavior is to use the address configured via the ``siteUrl`` setting. There are however situations (firewalls, etc.) where localhost would be preferable.
37993799
- ``Off``
3800+
* - add-local-contexts-permission-check
3801+
- Adds a permission check to ensure that the user calling the /api/localcontexts/datasets/{id} API can edit the dataset with that id. This is currently the only use case - see https://github.com/gdcc/dataverse-external-vocab-support/tree/main/packages/local_contexts. The flag adds additional security to stop other uses, but would currently have to be used in conjunction with the api-session-auth feature flag (the security implications of which have not been fully investigated) to still allow adding Local Contexts metadata to a dataset.
3802+
- ``Off``
38003803
* - enable-pid-failure-log
38013804
- Turns on creation of a monthly log file (logs/PIDFailures_<yyyy-MM>.log) showing failed requests for dataset/file PIDs. Can be used directly or with scripts at https://github.com/gdcc/dataverse-recipes/python/pid_reports to alert admins.
38023805
- ``Off``

src/main/java/edu/harvard/iq/dataverse/CustomizationFilesServlet.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import jakarta.servlet.http.HttpServletRequest;
2323
import jakarta.servlet.http.HttpServletResponse;
2424
import edu.harvard.iq.dataverse.settings.SettingsServiceBean;
25+
import edu.harvard.iq.dataverse.util.FileUtil;
2526
import jakarta.ejb.EJB;
2627
import org.apache.commons.io.IOUtils;
2728
import org.apache.tika.Tika;
@@ -60,13 +61,11 @@ protected void processRequest(HttpServletRequest request, HttpServletResponse re
6061
try {
6162
File fileIn = physicalPath.toFile();
6263
if (fileIn != null) {
63-
Tika tika = new Tika();
64-
try {
65-
String mimeType = tika.detect(fileIn);
66-
response.setContentType(mimeType);
67-
} catch (Exception e) {
68-
logger.info("Error getting MIME Type for " + filePath + " : " + e.getMessage());
69-
}
64+
String filename = physicalPath.getFileName().toString();
65+
int dotIndex = filename.lastIndexOf('.');
66+
String ext = dotIndex >= 0 ? filename.substring(dotIndex) : "";
67+
String mimeType = FileUtil.lookupFileTypeByExtension(ext);
68+
response.setContentType(mimeType);
7069
inputStream = new FileInputStream(fileIn);
7170

7271
in = new BufferedReader(new InputStreamReader(inputStream));

src/main/java/edu/harvard/iq/dataverse/api/dto/NewTemplateDTO.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public Template toTemplate() {
3838
template.updateInstructions();
3939
template.setCreateTime(new Timestamp(new Date().getTime()));
4040
template.setUsageCount(0L);
41+
template.setIsDefaultForDataverse(isDefault);
4142

4243
return template;
4344
}

src/main/java/edu/harvard/iq/dataverse/engine/command/impl/CreateTemplateCommand.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,14 @@ public Template execute(CommandContext ctxt) throws CommandException {
4848
DatasetFieldUtil.tidyUpFields(template.getDatasetFields(), false);
4949
}
5050

51-
return ctxt.templates().save(template);
51+
Template createdTemplate = ctxt.templates().save(template);
52+
53+
if (initialize && template.isIsDefaultForDataverse()) {
54+
dataverse.setDefaultTemplate(createdTemplate);
55+
ctxt.em().merge(dataverse);
56+
}
57+
58+
return template;
5259
}
5360

5461
private static void updateTermsOfUseAndAccess(CommandContext ctxt, Template template) {

src/main/java/edu/harvard/iq/dataverse/engine/command/impl/ListDataverseTemplatesCommand.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,22 @@ public ListDataverseTemplatesCommand(DataverseRequest request, Dataverse dataver
2626

2727
@Override
2828
public List<Template> execute(CommandContext ctxt) throws CommandException {
29-
List<Template> templates = new ArrayList<>();
29+
List<Template> availableTemplates = new ArrayList<>(dataverse.getTemplates());
3030

31-
if (dataverse.getOwner() != null) {
32-
templates.addAll(dataverse.getParentTemplates());
31+
if (!dataverse.isTemplateRoot() && dataverse.getOwner() != null) {
32+
availableTemplates.addAll(dataverse.getParentTemplates());
3333
}
3434

35-
templates.addAll(dataverse.getTemplates());
35+
setDefaultTemplate(availableTemplates);
3636

37-
return templates;
37+
return availableTemplates;
38+
}
39+
40+
private void setDefaultTemplate(List<Template> availableTemplates) {
41+
Optional.ofNullable(dataverse.getDefaultTemplate())
42+
.map(Template::getId).flatMap(defaultTemplateId -> availableTemplates.stream()
43+
.filter(template -> template.getId().equals(defaultTemplateId))
44+
.findFirst())
45+
.ifPresent(template -> template.setIsDefaultForDataverse(true));
3846
}
3947
}

src/main/java/edu/harvard/iq/dataverse/util/FileUtil.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,10 @@ public static String determineFileTypeByNameAndExtension(final String fileName)
598598
return lookupFileTypeByExtension(fileName);
599599
}
600600

601-
private static String lookupFileTypeByExtension(final String fileName) {
601+
/** determineFileTypeByNameAndExtension should be used instead for any user supplied content.
602+
*
603+
*/
604+
public static String lookupFileTypeByExtension(final String fileName) {
602605
final String mimetypesFileTypeMapResult = MIME_TYPE_MAP.getContentType(fileName);
603606
logger.fine("MimetypesFileTypeMap type by extension, for " + fileName + ": " + mimetypesFileTypeMapResult);
604607
if (mimetypesFileTypeMapResult == null) {

src/main/java/edu/harvard/iq/dataverse/util/json/InAppNotificationsJsonPrinter.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,11 @@ private void addDatasetCreatedFields(final NullSafeJsonBuilder notificationJson,
195195
}
196196

197197
private void addRequestorFields(final NullSafeJsonBuilder notificationJson, final AuthenticatedUser requestor) {
198-
notificationJson.add(KEY_REQUESTOR_FIRST_NAME, requestor.getFirstName());
199-
notificationJson.add(KEY_REQUESTOR_LAST_NAME, requestor.getLastName());
200-
notificationJson.add(KEY_REQUESTOR_EMAIL, requestor.getEmail());
198+
if (requestor != null) {
199+
notificationJson.add(KEY_REQUESTOR_FIRST_NAME, requestor.getFirstName());
200+
notificationJson.add(KEY_REQUESTOR_LAST_NAME, requestor.getLastName());
201+
notificationJson.add(KEY_REQUESTOR_EMAIL, requestor.getEmail());
202+
}
201203
}
202204

203205
private void addDatasetFields(final NullSafeJsonBuilder notificationJson, final UserNotification userNotification) {

src/main/java/edu/harvard/iq/dataverse/util/json/JsonPrinter.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1592,6 +1592,7 @@ public static JsonObjectBuilder jsonTemplate(Template template) {
15921592
return jsonObjectBuilder()
15931593
.add("id", template.getId())
15941594
.add("name", template.getName())
1595+
.add("isDefault", template.isIsDefaultForDataverse())
15951596
.add("usageCount", template.getUsageCount())
15961597
.add("createTime", template.getCreateTime().toString())
15971598
.add("createDate", template.getCreateDate())
@@ -1602,9 +1603,10 @@ public static JsonObjectBuilder jsonTemplate(Template template) {
16021603
}
16031604

16041605
public static JsonObjectBuilder jsonTermsOfUseAndAccess(TermsOfUseAndAccess termsOfUseAndAccess) {
1606+
License license = termsOfUseAndAccess.getLicense();
16051607
return jsonObjectBuilder()
16061608
.add("id", termsOfUseAndAccess.getId())
1607-
.add("license", json(termsOfUseAndAccess.getLicense()))
1609+
.add("license", license != null ? json(license) : null)
16081610
.add("termsOfUse", termsOfUseAndAccess.getTermsOfUse())
16091611
.add("termsOfAccess", termsOfUseAndAccess.getTermsOfAccess())
16101612
.add("confidentialityDeclaration", termsOfUseAndAccess.getConfidentialityDeclaration())
@@ -1618,7 +1620,9 @@ public static JsonObjectBuilder jsonTermsOfUseAndAccess(TermsOfUseAndAccess term
16181620
.add("originalArchive", termsOfUseAndAccess.getOriginalArchive())
16191621
.add("availabilityStatus", termsOfUseAndAccess.getAvailabilityStatus())
16201622
.add("sizeOfCollection", termsOfUseAndAccess.getSizeOfCollection())
1621-
.add("studyCompletion", termsOfUseAndAccess.getStudyCompletion());
1623+
.add("studyCompletion", termsOfUseAndAccess.getStudyCompletion())
1624+
.add("contactForAccess", termsOfUseAndAccess.getContactForAccess())
1625+
.add("fileAccessRequest", termsOfUseAndAccess.isFileAccessRequest());
16221626
}
16231627

16241628
public static JsonArrayBuilder jsonTemplateInstructions(Map<String, String> templateInstructions) {

0 commit comments

Comments
 (0)