Skip to content

Commit

Permalink
Merge pull request #7118 from IQSS/6918-locking-improvements
Browse files Browse the repository at this point in the history
6918 locking improvements
  • Loading branch information
kcondon committed Aug 3, 2020
2 parents b84873d + e9d3e74 commit 8ca934b
Show file tree
Hide file tree
Showing 15 changed files with 427 additions and 176 deletions.
6 changes: 6 additions & 0 deletions doc/release-notes/6918-publishing-lock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
The setting :PIDAsynchRegFileCount is deprecated as of v5.0.

It used to specify the number of datafiles in the dataset to warrant
adding a lock during publishing. As of v5.0 all datasets get
locked for the duration of the publishing process. The setting will be
ignored if present.
20 changes: 3 additions & 17 deletions doc/sphinx-guides/source/installation/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,6 @@ Here are the configuration options for DOIs:
- :ref:`:IdentifierGenerationStyle <:IdentifierGenerationStyle>` (optional)
- :ref:`:DataFilePIDFormat <:DataFilePIDFormat>` (optional)
- :ref:`:FilePIDsEnabled <:FilePIDsEnabled>` (optional, defaults to true)
- :ref:`:PIDAsynchRegFileCount <:PIDAsynchRegFileCount>` (optional, defaults to 10)

Configuring Dataverse for Handles
+++++++++++++++++++++++++++++++++
Expand Down Expand Up @@ -1446,24 +1445,13 @@ Note that in either case, when using the ``sequentialNumber`` option, datasets a
:FilePIDsEnabled
++++++++++++++++

Toggles publishing of file-based PIDs for the entire installation. By default this setting is absent and Dataverse assumes it to be true.
Toggles publishing of file-based PIDs for the entire installation. By default this setting is absent and Dataverse assumes it to be true. If enabled, the registration will be performed asynchronously (in the background) during publishing of a dataset.

If you don't want to register file-based PIDs for your installation, set:

``curl -X PUT -d 'false' http://localhost:8080/api/admin/settings/:FilePIDsEnabled``

Note: File-level PID registration was added in 4.9 and is required until version 4.9.3.

Note: The dataset will be locked, and the registration will be performed asynchronously, when there are more than N files in the dataset, where N is configured by the database setting ``:PIDAsynchRegFileCount`` (default: 10).

.. _:PIDAsynchRegFileCount:

:PIDAsynchRegFileCount
++++++++++++++++++++++

Configures the number of files in the dataset to warrant performing the registration of persistent identifiers (section above) and/or file validation asynchronously during publishing. The setting is optional, and the default value is 10.

``curl -X PUT -d '100' http://localhost:8080/api/admin/settings/:PIDAsynchRegFileCount``
Note: File-level PID registration was added in 4.9; it could not be disabled until version 4.9.3.

.. _:IndependentHandleService:

Expand All @@ -1480,14 +1468,12 @@ By default this setting is absent and Dataverse assumes it to be false.
:FileValidationOnPublishEnabled
+++++++++++++++++++++++++++++++

Toggles validation of the physical files in the dataset when it's published, by recalculating the checksums and comparing against the values stored in the DataFile table. By default this setting is absent and Dataverse assumes it to be true.
Toggles validation of the physical files in the dataset when it's published, by recalculating the checksums and comparing against the values stored in the DataFile table. By default this setting is absent and Dataverse assumes it to be true. If enabled, the validation will be performed asynchronously, similarly to how we handle assigning persistent identifiers to datafiles, with the dataset locked for the duration of the publishing process.

If you don't want the datafiles to be validated on publish, set:

``curl -X PUT -d 'false' http://localhost:8080/api/admin/settings/:FileValidationOnPublishEnabled``

Note: The dataset will be locked, and the validation will be performed asynchronously, similarly to how we handle assigning persistend identifiers to datafiles, when there are more than N files in the dataset, where N is configured by the database setting ``:PIDAsynchRegFileCount`` (default: 10).


:ApplicationTermsOfUse
++++++++++++++++++++++
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/edu/harvard/iq/dataverse/DatasetPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -2658,7 +2658,7 @@ private String releaseDataset(boolean minor) {
} else {
JsfHelper.addErrorMessage(BundleUtil.getStringFromBundle("dataset.message.only.authenticatedUsers"));
}
return returnToDatasetOnly();
return returnToDraftVersion();
}

@Deprecated
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/edu/harvard/iq/dataverse/MailServiceBean.java
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,13 @@ public String getMessageTextBasedOnNotification(UserNotification userNotificatio
version.getDataset().getOwner().getDisplayName(), getDataverseLink(version.getDataset().getOwner())};
messageText += MessageFormat.format(pattern, paramArrayPublishedDataset);
return messageText;
case PUBLISHFAILED_PIDREG:
version = (DatasetVersion) targetObject;
pattern = BundleUtil.getStringFromBundle("notification.email.publishFailedPidReg");
String[] paramArrayPublishFailedDatasetPidReg = {version.getDataset().getDisplayName(), getDatasetLink(version.getDataset()),
version.getDataset().getOwner().getDisplayName(), getDataverseLink(version.getDataset().getOwner())};
messageText += MessageFormat.format(pattern, paramArrayPublishFailedDatasetPidReg);
return messageText;
case RETURNEDDS:
version = (DatasetVersion) targetObject;
pattern = BundleUtil.getStringFromBundle("notification.email.wasReturnedByReviewer");
Expand Down Expand Up @@ -597,6 +604,7 @@ private Object getObjectOfNotification (UserNotification userNotification){
case CREATEDS:
case SUBMITTEDDS:
case PUBLISHEDDS:
case PUBLISHFAILED_PIDREG:
case RETURNEDDS:
return versionService.find(userNotification.getObjectId());
case CREATEACC:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

public class UserNotification implements Serializable {
public enum Type {
ASSIGNROLE, REVOKEROLE, CREATEDV, CREATEDS, CREATEACC, MAPLAYERUPDATED, MAPLAYERDELETEFAILED, SUBMITTEDDS, RETURNEDDS, PUBLISHEDDS, REQUESTFILEACCESS, GRANTFILEACCESS, REJECTFILEACCESS, FILESYSTEMIMPORT, CHECKSUMIMPORT, CHECKSUMFAIL, CONFIRMEMAIL, APIGENERATED, INGESTCOMPLETED, INGESTCOMPLETEDWITHERRORS
ASSIGNROLE, REVOKEROLE, CREATEDV, CREATEDS, CREATEACC, MAPLAYERUPDATED, MAPLAYERDELETEFAILED, SUBMITTEDDS, RETURNEDDS, PUBLISHEDDS, REQUESTFILEACCESS, GRANTFILEACCESS, REJECTFILEACCESS, FILESYSTEMIMPORT, CHECKSUMIMPORT, CHECKSUMFAIL, CONFIRMEMAIL, APIGENERATED, INGESTCOMPLETED, INGESTCOMPLETEDWITHERRORS, PUBLISHFAILED_PIDREG
};

private static final long serialVersionUID = 1L;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.inject.Named;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
Expand Down Expand Up @@ -83,6 +85,11 @@ public void delete(UserNotification userNotification) {
em.remove(em.merge(userNotification));
}

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void sendNotificationInNewTransaction(AuthenticatedUser dataverseUser, Timestamp sendDate, Type type, Long objectId) {
sendNotification(dataverseUser, sendDate, type, objectId, "");
}

public void sendNotification(AuthenticatedUser dataverseUser, Timestamp sendDate, Type type, Long objectId) {
sendNotification(dataverseUser, sendDate, type, objectId, "");
}
Expand All @@ -106,10 +113,9 @@ public void sendNotification(AuthenticatedUser dataverseUser, Timestamp sendDate
if (mailService.sendNotificationEmail(userNotification, comment, requestor, isHtmlContent)) {
logger.fine("email was sent");
userNotification.setEmailed(true);
save(userNotification);
} else {
logger.fine("email was not sent");
save(userNotification);
}
save(userNotification);
}
}
15 changes: 9 additions & 6 deletions src/main/java/edu/harvard/iq/dataverse/api/Admin.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@

import java.util.List;
import edu.harvard.iq.dataverse.authorization.AuthTestDataServiceBean;
import edu.harvard.iq.dataverse.authorization.AuthenticationProvidersRegistrationServiceBean;
import edu.harvard.iq.dataverse.authorization.RoleAssignee;
import edu.harvard.iq.dataverse.authorization.UserRecordIdentifier;
import edu.harvard.iq.dataverse.authorization.groups.impl.explicit.ExplicitGroupServiceBean;
Expand Down Expand Up @@ -114,6 +115,8 @@ public class Admin extends AbstractApiBean {

private static final Logger logger = Logger.getLogger(Admin.class.getName());

@EJB
AuthenticationProvidersRegistrationServiceBean authProvidersRegistrationSvc;
@EJB
BuiltinUserServiceBean builtinUserService;
@EJB
Expand Down Expand Up @@ -223,9 +226,9 @@ public Response addProvider(AuthenticationProviderRow row) {
managed = row;
}
if (managed.isEnabled()) {
AuthenticationProvider provider = authSvc.loadProvider(managed);
authSvc.deregisterProvider(provider.getId());
authSvc.registerProvider(provider);
AuthenticationProvider provider = authProvidersRegistrationSvc.loadProvider(managed);
authProvidersRegistrationSvc.deregisterProvider(provider.getId());
authProvidersRegistrationSvc.registerProvider(provider);
}
return created("/api/admin/authenticationProviders/" + managed.getId(), json(managed));
} catch (AuthorizationSetupException e) {
Expand Down Expand Up @@ -271,7 +274,7 @@ public Response enableAuthenticationProvider(@PathParam("id") String id, String
return ok(String.format("Authentication provider '%s' already enabled", id));
}
try {
authSvc.registerProvider(authSvc.loadProvider(row));
authProvidersRegistrationSvc.registerProvider(authProvidersRegistrationSvc.loadProvider(row));
return ok(String.format("Authentication Provider %s enabled", row.getId()));

} catch (AuthenticationProviderFactoryNotFoundException ex) {
Expand All @@ -285,7 +288,7 @@ public Response enableAuthenticationProvider(@PathParam("id") String id, String

} else {
// disable a provider
authSvc.deregisterProvider(id);
authProvidersRegistrationSvc.deregisterProvider(id);
return ok("Authentication Provider '" + id + "' disabled. "
+ (authSvc.getAuthenticationProviderIds().isEmpty()
? "WARNING: no enabled authentication providers left."
Expand All @@ -309,7 +312,7 @@ public Response checkAuthenticationProviderEnabled(@PathParam("id") String id) {
@DELETE
@Path("authenticationProviders/{id}/")
public Response deleteAuthenticationProvider(@PathParam("id") String id) {
authSvc.deregisterProvider(id);
authProvidersRegistrationSvc.deregisterProvider(id);
AuthenticationProviderRow row = em.find(AuthenticationProviderRow.class, id);
if (row != null) {
em.remove(row);
Expand Down

0 comments on commit 8ca934b

Please sign in to comment.