Skip to content

Commit

Permalink
Merge pull request #3856 from IQSS/3855-cannot-create-dataset
Browse files Browse the repository at this point in the history
prevent NullPointerException when creating dataset #3855
  • Loading branch information
kcondon authored May 25, 2017
2 parents 2054db2 + 6f28f26 commit cb0e38f
Show file tree
Hide file tree
Showing 9 changed files with 42 additions and 32 deletions.
2 changes: 2 additions & 0 deletions scripts/database/homebrew/run-post-create-post-deploy
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#!/bin/sh
scripts/database/homebrew/run-reference_data.sql > /tmp/run-reference_data.sql
psql dataverse_db -f doc/sphinx-guides/source/_static/util/createsequence.sql
psql -c 'ALTER TABLE datasetidentifier_seq OWNER TO "dataverse_app";' dataverse_db
cd scripts/api
./setup-all.sh --insecure > /tmp/setup-all.sh.out 2> /tmp/setup-all.sh.err
cd ../..
3 changes: 2 additions & 1 deletion src/main/java/edu/harvard/iq/dataverse/DatasetPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -1259,7 +1259,8 @@ private String init(boolean initFull) {
dataset.setProtocol(protocol);
dataset.setAuthority(authority);
dataset.setDoiSeparator(separator);
dataset.setIdentifier(datasetService.generateDatasetIdentifier(protocol, authority, separator));
//Wait until the create command before actually getting an identifier
//dataset.setIdentifier(datasetService.generateDatasetIdentifier(protocol, authority, separator));

if (dataset.getOwner() == null) {
return permissionsWrapper.notFound();
Expand Down
34 changes: 18 additions & 16 deletions src/main/java/edu/harvard/iq/dataverse/DatasetServiceBean.java
Original file line number Diff line number Diff line change
Expand Up @@ -221,30 +221,30 @@ public Dataset findByGlobalId(String globalId) {
return foundDataset;
}

public String generateDatasetIdentifier(String protocol, String authority, String separator) {
public String generateDatasetIdentifier(Dataset dataset, IdServiceBean idServiceBean) {
String doiIdentifierType = settingsService.getValueForKey(SettingsServiceBean.Key.IdentifierGenerationStyle, "randomString");
switch (doiIdentifierType) {
case "randomString":
return generateIdentifierAsRandomString(protocol, authority, separator);
return generateIdentifierAsRandomString(dataset, idServiceBean);
case "sequentialNumber":
return generateIdentifierAsSequentialNumber(protocol, authority, separator);
return generateIdentifierAsSequentialNumber(dataset, idServiceBean);
default:
/* Should we throw an exception instead?? -- L.A. 4.6.2 */
return generateIdentifierAsRandomString(protocol, authority, separator);
return generateIdentifierAsRandomString(dataset, idServiceBean);
}
}

private String generateIdentifierAsRandomString(String protocol, String authority, String separator) {
private String generateIdentifierAsRandomString(Dataset dataset, IdServiceBean idServiceBean) {

String identifier = null;
do {
identifier = RandomStringUtils.randomAlphanumeric(6).toUpperCase();
} while (!isIdentifierUniqueInDatabase(identifier, protocol, authority, separator));
} while (!isIdentifierUniqueInDatabase(identifier, dataset, idServiceBean));

return identifier;
}

private String generateIdentifierAsSequentialNumber(String protocol, String authority, String separator) {
private String generateIdentifierAsSequentialNumber(Dataset dataset, IdServiceBean idServiceBean) {

String identifier;
do {
Expand All @@ -257,7 +257,7 @@ private String generateIdentifierAsSequentialNumber(String protocol, String auth
return null;
}
identifier = identifierNumeric.toString();
} while (!isIdentifierUniqueInDatabase(identifier, protocol, authority, separator));
} while (!isIdentifierUniqueInDatabase(identifier, dataset, idServiceBean));

return identifier;
}
Expand All @@ -267,19 +267,21 @@ private String generateIdentifierAsSequentialNumber(String protocol, String auth
* for any other study in this Dataverse Network) alos check for duplicate
* in EZID if needed
*/
public boolean isIdentifierUniqueInDatabase(String userIdentifier, String protocol, String authority, String separator) {
public boolean isIdentifierUniqueInDatabase(String userIdentifier, Dataset dataset, IdServiceBean idServiceBean) {
String query = "SELECT d FROM Dataset d WHERE d.identifier = '" + userIdentifier + "'";
query += " and d.protocol ='" + protocol + "'";
query += " and d.authority = '" + authority + "'";
query += " and d.protocol ='" + dataset.getProtocol() + "'";
query += " and d.authority = '" + dataset.getAuthority() + "'";
boolean u = em.createQuery(query).getResultList().size() == 0;
String nonNullDefaultIfKeyNotFound = "";
String doiProvider = settingsService.getValueForKey(SettingsServiceBean.Key.DoiProvider, nonNullDefaultIfKeyNotFound);
if (protocol.equals("doi") && doiProvider.equals("EZID")) {
// TODO would need CommandContext to use IdServiceBean.getBean, then replace condition above with something like idServiceBean.registerWhenPublished
if (!doiEZIdServiceBean.lookupMetadataFromIdentifier(protocol, authority, separator, userIdentifier).isEmpty()) {

try{
if (idServiceBean.alreadyExists(dataset)) {
u = false;
}
} catch (Exception e){
//we can live with failure - means identifier not found remotely
}


return u;
}

Expand Down
4 changes: 3 additions & 1 deletion src/main/java/edu/harvard/iq/dataverse/IdServiceBean.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ static IdServiceBean getBean(String protocol, CommandContext ctxt) {
logger.log(Level.FINE,"getting bean, protocol=" + protocol);
String nonNullDefaultIfKeyNotFound = "";
String doiProvider = ctxt.settings().getValueForKey(SettingsServiceBean.Key.DoiProvider, nonNullDefaultIfKeyNotFound);

if (protocol == null){
protocol = ctxt.settings().getValueForKey(SettingsServiceBean.Key.Protocol, nonNullDefaultIfKeyNotFound);
}
if ("hdl".equals(protocol))
return (ctxt.handleNet());
else if (protocol.equals("doi"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ public DepositReceipt createNew(String collectionUri, Deposit deposit, AuthCrede
dataset.setProtocol(protocol);
dataset.setAuthority(authority);
dataset.setDoiSeparator(separator);
dataset.setIdentifier(datasetService.generateDatasetIdentifier(protocol, authority, separator));
//Wait until the create command before actually getting an identifier
//dataset.setIdentifier(datasetService.generateDatasetIdentifier(protocol, authority, separator));
logger.log(Level.FINE, "DS Deposit identifier: {0}", dataset.getIdentifier());

CreateDatasetCommand createDatasetCommand = new CreateDatasetCommand(dataset, dvReq, false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,14 @@ public CreateDatasetCommand(Dataset theDataset, DataverseRequest aRequest, boole
@Override
public Dataset execute(CommandContext ctxt) throws CommandException {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-hh.mm.ss");

if ( (importType != ImportType.MIGRATION && importType != ImportType.HARVEST) && !ctxt.datasets().isIdentifierUniqueInDatabase(theDataset.getIdentifier(), theDataset.getProtocol(), theDataset.getAuthority(), theDataset.getDoiSeparator()) ) {



IdServiceBean idServiceBean = IdServiceBean.getBean(theDataset.getProtocol(), ctxt);
if(theDataset.getIdentifier() == null || theDataset.getIdentifier().isEmpty()){
theDataset.setIdentifier(ctxt.datasets().generateDatasetIdentifier(theDataset, idServiceBean));
}
if ( (importType != ImportType.MIGRATION && importType != ImportType.HARVEST) && !ctxt.datasets().isIdentifierUniqueInDatabase(theDataset.getIdentifier(), theDataset, idServiceBean)) {
throw new IllegalCommandException(String.format("Dataset with identifier '%s', protocol '%s' and authority '%s' already exists",
theDataset.getIdentifier(), theDataset.getProtocol(), theDataset.getAuthority()),
this);
Expand Down Expand Up @@ -143,15 +149,15 @@ by the Dataset page (in CREATE mode), it already has the persistent
-- L.A. 4.6.2
*/

theDataset.setIdentifier(ctxt.datasets().generateDatasetIdentifier(theDataset.getProtocol(), theDataset.getAuthority(), theDataset.getDoiSeparator()));
theDataset.setIdentifier(ctxt.datasets().generateDatasetIdentifier(theDataset, idServiceBean));

}
logger.log(Level.FINE,"doiProvider={0} protocol={1} importType={2} GlobalIdCreateTime=={3}", new Object[]{doiProvider, protocol, importType, theDataset.getGlobalIdCreateTime()});
// Attempt the registration if importing dataset through the API, or the app (but not harvest or migrate)
if ((importType == null || importType.equals(ImportType.NEW))
&& theDataset.getGlobalIdCreateTime() == null) {
String doiRetString = "";
IdServiceBean idServiceBean = IdServiceBean.getBean(ctxt);
idServiceBean = IdServiceBean.getBean(ctxt);
try{
logger.log(Level.FINE,"creating identifier");
doiRetString = idServiceBean.createIdentifier(theDataset);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,15 +81,11 @@ protected void executeImpl(CommandContext ctxt) throws CommandException {
ctxt.em().remove(ra);
}

//Register Cache
if(ctxt.settings().getValueForKey(SettingsServiceBean.Key.DoiProvider, "").equals("DataCite")){
// TODO make ignorant of configured bean
ctxt.doiDataCite().deleteRecordFromCache(doomed);
}

IdServiceBean idServiceBean = IdServiceBean.getBean(ctxt);
try{
idServiceBean.deleteIdentifier(doomed);
if(idServiceBean.alreadyExists(doomed)){
idServiceBean.deleteIdentifier(doomed);
}
} catch (Exception e) {
logger.log(Level.WARNING, "Identifier deletion was not successfull:",e.getMessage());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public Dataset execute(CommandContext ctxt) throws CommandException {
int attempts = 0;

while (idServiceBean.alreadyExists(theDataset) && attempts < FOOLPROOF_RETRIAL_ATTEMPTS_LIMIT) {
theDataset.setIdentifier(ctxt.datasets().generateDatasetIdentifier(protocol, authority, theDataset.getDoiSeparator()));
theDataset.setIdentifier(ctxt.datasets().generateDatasetIdentifier(theDataset, idServiceBean));
attempts++;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ public Dataset save(CommandContext ctxt) throws CommandException {
// enough number of values will be legitimately registered
// by another entity sharing the same authority...)

theDataset.setIdentifier(ctxt.datasets().generateDatasetIdentifier(theDataset.getProtocol(), theDataset.getAuthority(), theDataset.getDoiSeparator()));
theDataset.setIdentifier(ctxt.datasets().generateDatasetIdentifier(theDataset, idServiceBean));
doiRetString = idServiceBean.createIdentifier(theDataset);

attempts++;
Expand Down

0 comments on commit cb0e38f

Please sign in to comment.