Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IQSS/6497 migrate dataset api #7504

Merged
Show file tree
Hide file tree
Changes from 88 commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
b45336c
add replace param
qqmyers Dec 1, 2020
83c8794
remove OREMap parameter
qqmyers Dec 1, 2020
6d537ce
fix error handling
qqmyers Dec 1, 2020
6ee7499
append to current terms
qqmyers Dec 1, 2020
8827a0c
handle append on terms - fix cut/paste errors
qqmyers Dec 2, 2020
92328cb
fix logic
qqmyers Dec 2, 2020
2a83a70
specify default
qqmyers Dec 2, 2020
d75fb78
make replace still append for multiple val fields
qqmyers Dec 2, 2020
782d5ec
add migrating switch
qqmyers Dec 2, 2020
be978e9
expose uri in datasetField api
qqmyers Dec 3, 2020
faa92f6
track defined namespaces
qqmyers Dec 3, 2020
fb08a38
define equals, avoid duplicates in list
qqmyers Dec 3, 2020
ece3bff
replace string with const
qqmyers Dec 4, 2020
8b737dd
constant for CC0_URI
qqmyers Dec 4, 2020
63362d9
GET/DELETE endpoints
qqmyers Dec 4, 2020
849f6f8
7130-handle missing contact name
qqmyers Dec 8, 2020
8321f62
Fix multiple description logic for info file
qqmyers Dec 11, 2020
5050e93
put is always for :draft version
qqmyers Dec 11, 2020
11292c0
don't cast to String[]
qqmyers Dec 11, 2020
cbbb084
add more logging
qqmyers Dec 11, 2020
fd14226
add method that can return JsonObjectBuilder
qqmyers Dec 11, 2020
7fe0249
log details on failure
qqmyers Dec 11, 2020
24cfcfa
multiple updates/fixes, added logging
qqmyers Dec 11, 2020
8d889c1
Merge remote-tracking branch 'IQSS/develop' into IQSS/6497-migrate_da…
qqmyers Dec 22, 2020
a01c421
merge issues
qqmyers Dec 22, 2020
6ce3a1c
fix terms retrieval
qqmyers Dec 22, 2020
0bde4e8
merge issue
qqmyers Dec 22, 2020
e6366e4
add note
qqmyers Jan 8, 2021
043420a
Merge remote-tracking branch 'IQSS/develop' into IQSS/6497-migrate_da…
qqmyers Jan 8, 2021
f2f7468
Merge branch 'iqssdevelop' into IQSS/6497-migrate_dataset_api
qqmyers Jan 14, 2021
cb20416
Merge branch 'IQSS/6497-semantic_api' into IQSS/6497-migrate_dataset_api
qqmyers Jan 29, 2021
b91ad4c
missed merge issue
qqmyers Jan 29, 2021
509746c
adding a create from json-ld to mirror the other api calls
qqmyers Feb 2, 2021
d4c15cc
handle null terms on new dataset
qqmyers Feb 2, 2021
346d061
Merge remote-tracking branch 'IQSS/develop' into
qqmyers Feb 8, 2021
05e1441
initial documentation commit
qqmyers Feb 9, 2021
d885d63
cleanup
qqmyers Feb 9, 2021
d0e1301
links and cleanup
qqmyers Feb 9, 2021
8059af8
Merge remote-tracking branch 'IQSS/develop' into IQSS/6497-migrate_da…
qqmyers Feb 9, 2021
8851fe3
comments/cleanup
qqmyers Feb 9, 2021
b161473
adding first draft of release notes
djbrooke Feb 10, 2021
94c926f
Update doc/sphinx-guides/source/developers/dataset-migration-api.rst
qqmyers Feb 10, 2021
9e05baa
Update doc/sphinx-guides/source/developers/dataset-semantic-metadata-…
qqmyers Feb 10, 2021
45e5853
doc updates from code review
djbrooke Feb 10, 2021
85e82ef
Merge branch 'IQSS/6497-migrate_dataset_api' of https://github.com/Gl…
djbrooke Feb 10, 2021
1d995ff
adding ref to #5899 support
djbrooke Feb 10, 2021
5305e75
Merge remote-tracking branch 'IQSS/develop' into
qqmyers Feb 23, 2021
049347f
Merge branch 'IQSS/6497-migrate_dataset_api' of https://github.com/Gl…
qqmyers Feb 23, 2021
3a32354
method dropped in merge
qqmyers Mar 22, 2021
65d80a3
use dataset pub date for files in migrate case
qqmyers Mar 22, 2021
9ca0768
make sure release user is set
qqmyers Mar 24, 2021
1e7fcd1
Merge remote-tracking branch 'IQSS/develop' into
qqmyers Mar 24, 2021
4b5ad66
Assign a version if not set
qqmyers Mar 30, 2021
a17c4bb
Don't call archiver directly
qqmyers Mar 30, 2021
c3b1219
add @POST per Chris Muller
qqmyers Mar 31, 2021
58a2317
handle mutliple versions, setting pub/release dates correctly
qqmyers Apr 1, 2021
b441a15
Merge branch 'IQSS/6497-semantic_api' into IQSS/6497-migrate_dataset_api
qqmyers Apr 7, 2021
8bb781e
Merge remote-tracking branch 'IQSS/develop' into IQSS/6497-migrate_da…
qqmyers Apr 13, 2021
fb2b52c
don't used deprecated Long constructor
qqmyers Apr 14, 2021
e584d6f
add pre-pub wf to migrate
qqmyers Apr 14, 2021
313ec40
Merge branch 'IQSS/6497-semantic_api' into IQSS/6497-migrate_dataset_api
qqmyers Apr 26, 2021
faa944e
mirror responses from publish command - accepted(w /wf) or ok
qqmyers Apr 26, 2021
f702a61
Merge branch 'IQSS/6497-semantic_api' into IQSS/6497-migrate_dataset_api
qqmyers May 20, 2021
60f474d
Merge remote-tracking branch 'IQSS/develop' into IQSS/6497-migrate_da…
qqmyers Jun 3, 2021
3864150
checkstyle fixes
qqmyers Jun 3, 2021
c6c7d40
move metadataOnOrig out of citation block
qqmyers Jun 23, 2021
0fa89fc
Merge remote-tracking branch 'IQSS/develop' into IQSS/6497-migrate_da…
qqmyers Jun 23, 2021
12aa736
doc fixes, update for ld+json type
qqmyers Jun 25, 2021
ff2419b
support application/ld+json(new) application/json-ld (old/non-standard)
qqmyers Jun 25, 2021
da9c9e9
initial test commit
qqmyers Jun 25, 2021
d2eddcd
fix isSet method
qqmyers Jun 29, 2021
4cd2669
update tests, incr. titanium
qqmyers Jun 29, 2021
21829ec
Bug fixes/cleanup
qqmyers Jun 29, 2021
5f53e15
finish tests
qqmyers Jun 29, 2021
e1c1bfe
Merge remote-tracking branch 'IQSS/develop' into IQSS/6497-migrate_da…
qqmyers Jun 30, 2021
d857009
fix test
qqmyers Jul 2, 2021
ba653ee
update example
qqmyers Jul 2, 2021
048975e
Merge branch 'IQSS/6497-semantic_api' into IQSS/6497-migrate_dataset_api
qqmyers Jul 2, 2021
caca844
merge issues
qqmyers Jul 2, 2021
d451f87
update solr version
djbrooke Jul 8, 2021
68fd420
Merge branch 'IQSS/6497-semantic_api' into IQSS/6497-migrate_dataset_api
qqmyers Jul 8, 2021
4b4671d
Merge branch 'IQSS/6497-migrate_dataset_api' of https://github.com/Gl…
qqmyers Jul 8, 2021
cd30129
Update doc/sphinx-guides/source/developers/dataset-migration-api.rst
qqmyers Jul 8, 2021
95eaec2
Update doc/sphinx-guides/source/developers/dataset-migration-api.rst
qqmyers Jul 8, 2021
f4097bc
Update doc/sphinx-guides/source/developers/dataset-migration-api.rst
qqmyers Jul 8, 2021
64ed2b0
Update doc/sphinx-guides/source/developers/dataset-migration-api.rst
qqmyers Jul 8, 2021
e96c24a
Merge remote-tracking branch 'IQSS/develop' into
qqmyers Jul 13, 2021
68f33a6
Merge branch 'IQSS/6497-migrate_dataset_api' of https://github.com/Gl…
qqmyers Jul 13, 2021
b1acb2b
add dev guide links to list of APIs #6497
pdurbin Jul 21, 2021
e074c1e
Merge pull request #13 from IQSS/6497-api-list
qqmyers Jul 22, 2021
30d131c
Merge remote-tracking branch 'IQSS/develop' into IQSS/6497-migrate_da…
qqmyers Jul 22, 2021
52fbc93
lost test update
qqmyers Jul 23, 2021
e544a9a
Merge remote-tracking branch 'IQSS/develop' into IQSS/6497-migrate_da…
qqmyers Jul 23, 2021
8f749e7
respond to QA comments
qqmyers Jul 23, 2021
c833eb9
handle version 1.0 info already set
qqmyers Jul 27, 2021
d549f72
enable DOI updates
qqmyers Jul 27, 2021
93481bd
cut/pasted to the wrong place
qqmyers Jul 27, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions doc/release-notes/6497-migrate-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Release Highlights

### Dataset Migration API (Experimental)
djbrooke marked this conversation as resolved.
Show resolved Hide resolved

Datasets can now imported/updated following the format of an OAI-ORE export (RDA-conformant Bags), allowing for not only easier migration from one Dataverse installation to another, but also for better support of import from other systems. This experimental endpoint also allows keeping the existing persistent identifier (where the authority and shoulder match those for which the software is configured) and publication dates. This endpoint also allows for the update of terms metadata (#5899).

This development was supported by the [Research Data Alliance](https://rd-alliance.org) and follows the recommendations from the [Research Data Repository Interoperability Working Group](http://dx.doi.org/10.15497/RDA00025).

### Additional Upgrade Steps

Update Solr Schema

- copy schema_dv_mdb_fields.xml and schema_dv_mdb_copies.xml to solr server, for example into /usr/local/solr/solr-8.8.1/server/solr/collection1/conf/ directory

- Restart Solr, or tell Solr to reload its configuration:

`curl "http://localhost:8983/solr/admin/cores?action=RELOAD&core=collection1"`
42 changes: 42 additions & 0 deletions doc/sphinx-guides/source/_static/api/dataset-migrate.jsonld
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"citation:Depositor": "Admin, Dataverse",
"Title": "Test Dataset",
"Subject": "Computer and Information Science",
"Creator": {
"author:Name": "Admin, Dataverse",
"author:Affiliation": "GDCC"
},
"Deposit Date": "2020-10-08",
"citation:Distributor": {
"distributor:Name": "Demo Dataverse Repository",
"distributor:Affiliation": "Dataverse Community",
"distributor:Abbreviation": "GDCC",
"distributor:URL": "https://dataverse.org/global-dataverse-community-consortium"
},
"citation:Contact": {
"datasetContact:Name": "Admin, Dataverse",
"datasetContact:Affiliation": "GDCC",
"datasetContact:E-mail": "admin@demo.dataverse.org"
},
"citation:Description": {
"dsDescription:Text": "A short description"
},
"@id": "doi:10.33564/FK27U7YBV",
"schema:version": "1.0",
"schema:license": "https://creativecommons.org/publicdomain/zero/1.0/",
"dvcore:fileTermsOfAccess": {
"dvcore:fileRequestAccess": false
},
"@context": {
"Creator": "http://purl.org/dc/terms/creator",
"Deposit Date": "http://purl.org/dc/terms/dateSubmitted",
"Subject": "http://purl.org/dc/terms/subject",
"Title": "http://purl.org/dc/terms/title",
"author": "https://dataverse.org/schema/citation/author#",
"citation": "https://dataverse.org/schema/citation/",
"datasetContact": "https://dataverse.org/schema/citation/datasetContact#",
"distributor": "https://dataverse.org/schema/citation/distributor#",
"dsDescription": "https://dataverse.org/schema/citation/dsDescription#",
"dvcore": "https://dataverse.org/schema/core#",
"schema": "http://schema.org/"
}}
2 changes: 1 addition & 1 deletion doc/sphinx-guides/source/admin/dashboard.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ This dashboard tool allows you to define sets of local datasets to make availabl
Metadata Export
---------------

This part of the Dashboard is simply a reminder message that metadata export happens through the Dataverse Software API. See the :doc:`metadataexport` section and the :doc:`/api/native-api` section of the API Guide for more details.
This part of the Dashboard is simply a reminder message that metadata export happens through the Dataverse Software API. See the :doc:`/admin/metadataexport` section and the :doc:`/api/native-api` section of the API Guide for more details.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW: unrelated - just found it when fixing another link


Users
-----
Expand Down
51 changes: 51 additions & 0 deletions doc/sphinx-guides/source/developers/dataset-migration-api.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
Dataset Migration API
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we're seeing a number of APIs show up under the Dev Guide, it's probably time to update the "List of Dataverse APIs" I started when I did a light re-write of the API Guide. As of https://guides.dataverse.org/en/5.5/api/intro.html#lists-of-dataverse-apis this is how it looks:

Screen Shot 2021-07-16 at 2 56 08 PM

@qqmyers can you please update the "Please note that some APIs are only documented in other guides that are more suited to their audience" section and add "Developer Guide" and under that recent APIs that have been added? (Please include aux files in this.) Thanks.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you please update the "Please note that some APIs are only documented in other guides that are more suited to their audience" section and add "Developer Guide" and under that recent APIs that have been added?

@qqmyers I just opened this pull request for this: GlobalDataverseCommunityConsortium#13

=====================

The Dataverse software includes several ways to add Datasets originally created elsewhere (not to mention Harvesting capabilities). These include the Sword API (see the :doc:`/api/sword` guide) and the /dataverses/{id}/datasets/:import methods (json and ddi) (see the :doc:`/api/native-api` guide).
djbrooke marked this conversation as resolved.
Show resolved Hide resolved

This experimental migration API offers an additional option with some potential advantages:

* metadata can be specified using the json-ld format used in the OAI-ORE metadata export
* existing PIDs can be maintained (currently limited to the case where the PID can be managed by the Dataverse software, e.g. where the authority and shoulder match those the software is configured for)
* adding files can be done via the standard APIs, including using direct-upload to S3
* the dataset can be published keeping the original publication date

This API consists of 2 calls: one to create an initial Dataset version, and one to publish the version with a specified publication date.
These calls can be used in concert with other API calls to add files, update metadata for additional versions, etc.


Start Migrating a Dataset into a Dataverse Collection
-----------------------------------------------------

.. note:: This action requires a Dataverse installation account with superuser permissions.

To import a dataset with an existing persistent identifier (PID), the provided json-ld metadata should include it.

.. code-block:: bash

export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
export SERVER_URL=https://demo.dataverse.org
export DATAVERSE_ID=root
export PERSISTENT_IDENTIFIER=doi:10.5072/FK27U7YBV

curl -H X-Dataverse-key:$API_TOKEN -X POST $SERVER_URL/api/dataverses/$DATAVERSE_ID/datasets/:startmigration --upload-file dataset-migrate.jsonld

An example jsonld file is available at :download:`dataset-migrate.jsonld <../_static/api/dataset-migrate.jsonld>`


Publish a Migrated Dataset
--------------------------

The call above creates a Dataset. Once it is created, other APIs can be used to add files, add additional metadata, etc. When a version is complete, the following call can be used to publish it with its original publication date.

.. note:: This action requires a Dataverse installation account with superuser permissions.

.. code-block:: bash

export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
export PERSISTENT_IDENTIFIER=doi:10.5072/FK27U7YBV
export SERVER_URL=https://demo.dataverse.org

curl -H 'Content-Type: application/jsonld' -H X-Dataverse-key:$API_TOKEN -X POST -d '{"schema:datePublished": "2020-10-26","@context":{ "schema":"http://schema.org/"}}' "$SERVER_URL/api/datasets/{id}/actions/:releasemigrated"

datePublished is the only metadata supported in this call.
1 change: 1 addition & 0 deletions doc/sphinx-guides/source/developers/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,5 @@ Developer Guide
aux-file-support
s3-direct-upload-api
dataset-semantic-metadata-api
dataset-migration-api
workflows
108 changes: 106 additions & 2 deletions src/main/java/edu/harvard/iq/dataverse/api/Datasets.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import edu.harvard.iq.dataverse.engine.command.impl.DeleteDatasetLinkingDataverseCommand;
import edu.harvard.iq.dataverse.engine.command.impl.DeletePrivateUrlCommand;
import edu.harvard.iq.dataverse.engine.command.impl.DestroyDatasetCommand;
import edu.harvard.iq.dataverse.engine.command.impl.FinalizeDatasetPublicationCommand;
import edu.harvard.iq.dataverse.engine.command.impl.GetDatasetCommand;
import edu.harvard.iq.dataverse.engine.command.impl.GetSpecificPublishedDatasetVersionCommand;
import edu.harvard.iq.dataverse.engine.command.impl.GetDraftDatasetVersionCommand;
Expand All @@ -77,7 +78,6 @@
import edu.harvard.iq.dataverse.ingest.IngestServiceBean;
import edu.harvard.iq.dataverse.privateurl.PrivateUrl;
import edu.harvard.iq.dataverse.S3PackageImporter;
import edu.harvard.iq.dataverse.api.AbstractApiBean.WrappedResponse;
import edu.harvard.iq.dataverse.api.dto.RoleAssignmentDTO;
import edu.harvard.iq.dataverse.batch.util.LoggingUtil;
import edu.harvard.iq.dataverse.dataaccess.DataAccess;
Expand All @@ -104,16 +104,23 @@
import edu.harvard.iq.dataverse.util.SystemConfig;
import edu.harvard.iq.dataverse.util.bagit.OREMap;
import edu.harvard.iq.dataverse.util.json.JSONLDUtil;
import edu.harvard.iq.dataverse.util.json.JsonLDTerm;
import edu.harvard.iq.dataverse.util.json.JsonParseException;
import edu.harvard.iq.dataverse.search.IndexServiceBean;
import static edu.harvard.iq.dataverse.util.json.JsonPrinter.*;
import static edu.harvard.iq.dataverse.util.json.NullSafeJsonBuilder.jsonObjectBuilder;
import edu.harvard.iq.dataverse.util.json.NullSafeJsonBuilder;
import edu.harvard.iq.dataverse.workflow.Workflow;
import edu.harvard.iq.dataverse.workflow.WorkflowContext;
import edu.harvard.iq.dataverse.workflow.WorkflowServiceBean;
import edu.harvard.iq.dataverse.workflow.WorkflowContext.TriggerType;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.sql.Timestamp;
import java.text.MessageFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
Expand All @@ -123,6 +130,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Level;
Expand All @@ -140,6 +148,7 @@
import javax.json.stream.JsonParsingException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.BadRequestException;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
Expand All @@ -158,13 +167,14 @@
import javax.ws.rs.core.Response.Status;
import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
import javax.ws.rs.core.UriInfo;

import org.apache.commons.lang3.StringUtils;
import org.apache.solr.client.solrj.SolrServerException;
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;

import com.amazonaws.services.s3.model.PartETag;
import edu.harvard.iq.dataverse.FileMetadata;

@Path("datasets")
public class Datasets extends AbstractApiBean {
Expand Down Expand Up @@ -224,6 +234,9 @@ public class Datasets extends AbstractApiBean {

@Inject
DataverseRequestServiceBean dvRequestService;

@Inject
WorkflowServiceBean wfService;

/**
* Used to consolidate the way we parse and handle dataset versions.
Expand Down Expand Up @@ -1190,6 +1203,97 @@ public Response publishDataset(@PathParam("id") String id, @QueryParam("type") S
}
}

@POST
@Path("{id}/actions/:releasemigrated")
@Consumes("application/ld+json, application/json-ld")
public Response publishMigratedDataset(String jsonldBody, @PathParam("id") String id) {
try {
AuthenticatedUser user = findAuthenticatedUserOrDie();
if (!user.isSuperuser()) {
return error(Response.Status.FORBIDDEN, "Only superusers can release migrated datasets");
}

Dataset ds = findDatasetOrDie(id);
try {
JsonObject metadata = JSONLDUtil.decontextualizeJsonLD(jsonldBody);
String pubDate = metadata.getString(JsonLDTerm.schemaOrg("datePublished").getUrl());
logger.fine("Submitted date: " + pubDate);
LocalDateTime dateTime = null;
if(!StringUtils.isEmpty(pubDate)) {
dateTime = JSONLDUtil.getDateTimeFrom(pubDate);
final Timestamp time = Timestamp.valueOf(dateTime);
//Set version release date
ds.getLatestVersion().setReleaseTime(new Date(time.getTime()));
}
// dataset.getPublicationDateFormattedYYYYMMDD())
// Assign a version number if not set
if (ds.getLatestVersion().getVersionNumber() == null) {

if (ds.getVersions().size() == 1) {
// First Release
ds.getLatestVersion().setVersionNumber(Long.valueOf(1));
ds.getLatestVersion().setMinorVersionNumber(Long.valueOf(0));
//Also set publication date if this is the first
if(dateTime != null) {
ds.setPublicationDate(Timestamp.valueOf(dateTime));
}
// Release User is only set in FinalizeDatasetPublicationCommand if the pub date
// is null, so set it here.
ds.setReleaseUser((AuthenticatedUser) user);

} else if (ds.getLatestVersion().isMinorUpdate()) {
ds.getLatestVersion().setVersionNumber(Long.valueOf(ds.getVersionNumber()));
ds.getLatestVersion().setMinorVersionNumber(Long.valueOf(ds.getMinorVersionNumber() + 1));

} else {
// major, non-first release
ds.getLatestVersion().setVersionNumber(Long.valueOf(ds.getVersionNumber() + 1));
ds.getLatestVersion().setMinorVersionNumber(Long.valueOf(0));
}

}
} catch (Exception e) {
logger.fine(e.getMessage());
throw new BadRequestException("Unable to set publication date ("
+ JsonLDTerm.schemaOrg("datePublished").getUrl() + "): " + e.getMessage());
}
/*
* Note: The code here mirrors that in the
* edu.harvard.iq.dataverse.DatasetPage:updateCurrentVersion method. Any changes
* to the core logic (i.e. beyond updating the messaging about results) should
* be applied to the code there as well.
*/
String errorMsg = null;
Optional<Workflow> prePubWf = wfService.getDefaultWorkflow(TriggerType.PrePublishDataset);

try {
// ToDo - should this be in onSuccess()? May relate to todo above
if (prePubWf.isPresent()) {
// Start the workflow, the workflow will call FinalizeDatasetPublication later
wfService.start(prePubWf.get(),
new WorkflowContext(createDataverseRequest(user), ds, TriggerType.PrePublishDataset, true),
false);
} else {
FinalizeDatasetPublicationCommand cmd = new FinalizeDatasetPublicationCommand(ds,
createDataverseRequest(user), true);
ds = commandEngine.submit(cmd);
}
} catch (CommandException ex) {
errorMsg = BundleUtil.getStringFromBundle("datasetversion.update.failure") + " - " + ex.toString();
logger.severe(ex.getMessage());
}

if (errorMsg != null) {
return error(Response.Status.INTERNAL_SERVER_ERROR, errorMsg);
} else {
return prePubWf.isPresent() ? accepted(json(ds)) : ok(json(ds));
}

} catch (WrappedResponse ex) {
return ex.getResponse();
}
}

@POST
@Path("{id}/move/{targetDataverseAlias}")
public Response moveDataset(@PathParam("id") String id, @PathParam("targetDataverseAlias") String targetDataverseAlias, @QueryParam("forceMove") Boolean force) {
Expand Down
54 changes: 54 additions & 0 deletions src/main/java/edu/harvard/iq/dataverse/api/Dataverses.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
import javax.json.stream.JsonParsingException;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.ws.rs.BadRequestException;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
Expand Down Expand Up @@ -450,6 +451,59 @@ public Response importDatasetDdi(String xml, @PathParam("identifier") String par
}
}

@POST
@Path("{identifier}/datasets/:startmigration")
@Consumes("application/ld+json, application/json-ld")
public Response recreateDataset(String jsonLDBody, @PathParam("identifier") String parentIdtf) {
try {
User u = findUserOrDie();
if (!u.isSuperuser()) {
return error(Status.FORBIDDEN, "Not a superuser");
}
Dataverse owner = findDataverseOrDie(parentIdtf);

Dataset ds = new Dataset();

ds.setOwner(owner);
ds = JSONLDUtil.updateDatasetMDFromJsonLD(ds, jsonLDBody, metadataBlockSvc, datasetFieldSvc, false, true);
//ToDo - verify PID is one Dataverse can manage (protocol/authority/shoulder match)
if(!
(ds.getAuthority().equals(settingsService.getValueForKey(SettingsServiceBean.Key.Authority))&&
ds.getProtocol().equals(settingsService.getValueForKey(SettingsServiceBean.Key.Protocol))&&
ds.getIdentifier().startsWith(settingsService.getValueForKey(SettingsServiceBean.Key.Shoulder)))) {
throw new BadRequestException("Cannot recreate a dataset that has a PID that doesn't match the server's settings");
}
if(!datasetSvc.isIdentifierLocallyUnique(ds)) {
throw new BadRequestException("Cannot recreate a dataset whose PID is already in use");
}



if (ds.getVersions().isEmpty()) {
return badRequest("Supplied json must contain a single dataset version.");
}

DatasetVersion version = ds.getVersions().get(0);
if (!version.isPublished()) {
throw new BadRequestException("Cannot recreate a dataset that hasn't been published.");
}
//While the datasetversion whose metadata we're importing has been published, we consider it in draft until the API caller adds files and then completes the migration
version.setVersionState(DatasetVersion.VersionState.DRAFT);

DataverseRequest request = createDataverseRequest(u);

Dataset managedDs = execCommand(new ImportDatasetCommand(ds, request));
JsonObjectBuilder responseBld = Json.createObjectBuilder()
.add("id", managedDs.getId())
.add("persistentId", managedDs.getGlobalId().toString());

return created("/datasets/" + managedDs.getId(), responseBld);

} catch (WrappedResponse ex) {
return ex.getResponse();
}
}

private Dataset parseDataset(String datasetJson) throws WrappedResponse {
try (StringReader rdr = new StringReader(datasetJson)) {
return jsonParser().parseDataset(Json.createReader(rdr).readObject());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,16 @@ public Dataset execute(CommandContext ctxt) throws CommandException {
}

// update metadata
theDataset.getLatestVersion().setReleaseTime(getTimestamp());
if (theDataset.getLatestVersion().getReleaseTime() == null) {
// Allow migrated versions to keep original release dates
theDataset.getLatestVersion().setReleaseTime(getTimestamp());
}
theDataset.getLatestVersion().setLastUpdateTime(getTimestamp());
theDataset.setModificationTime(getTimestamp());
theDataset.setFileAccessRequest(theDataset.getLatestVersion().getTermsOfUseAndAccess().isFileAccessRequest());

updateFiles(getTimestamp(), ctxt);
//Use dataset pub date (which may not be the current date for migrated datasets)
updateFiles(new Timestamp(theDataset.getLatestVersion().getReleaseTime().getTime()), ctxt);

//
// TODO: Not sure if this .merge() is necessary here - ?
Expand Down
Loading