Skip to content

Commit

Permalink
Merge pull request #8940 from ErykKul/8822_incomplete_datasets_via_api
Browse files Browse the repository at this point in the history
8822 incomplete datasets via api
  • Loading branch information
kcondon authored May 22, 2023
2 parents 3d8ca99 + fe46cde commit 55179da
Show file tree
Hide file tree
Showing 34 changed files with 403 additions and 49 deletions.
5 changes: 5 additions & 0 deletions conf/solr/8.11.1/schema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,9 @@
<field name="geolocation" type="location_rpt" multiValued="true" stored="true" indexed="true"/>
<!-- https://solr.apache.org/guide/8_11/spatial-search.html#bboxfield -->
<field name="boundingBox" type="bbox" multiValued="true" stored="true" indexed="true"/>

<!-- incomplete datasets issue 8822 -->
<field name="datasetValid" type="boolean" stored="true" indexed="true" multiValued="false"/>

<!--
METADATA SCHEMA FIELDS
Expand Down Expand Up @@ -470,6 +473,8 @@
<!-- <copyField source="*_ss" dest="_text_" maxChars="3000"/> -->
<!-- <copyField source="*_i" dest="_text_" maxChars="3000"/> -->

<copyField source="datasetValid" dest="_text_" maxChars="3000"/>

<!--
METADATA SCHEMA FIELDS
Now following: copyFields to copy the contents of the metadata fields above to a
Expand Down
14 changes: 14 additions & 0 deletions doc/release-notes/8822-incomplete-datasets-via-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
### Creating datasets with incomplete metadata through API

The create dataset API call (POST to /api/dataverses/#dataverseId/datasets) is extended with the "doNotValidate" parameter. However, in order to be able to create a dataset with incomplete metadata, the solr configuration must be updated first with the new "schema.xml" file (do not forget to run the metadata fields update script when you use custom metadata). Reindexing is optional, but recommended. Also, even when this feature is not used, it is recommended to update the solar configuration and reindex the metadata. Finally, this new feature can be activated with the "dataverse.api.allow-incomplete-metadata" JVM option.

You can also enable a valid/incomplete metadata filter in the "My Data" page using the "dataverse.ui.show-validity-filter" JVM option. By default, this filter is not shown. When you wish to use this filter, you must reindex the datasets first, otherwise datasets with valid metadata will not be shown in the results.

It is not possible to publish datasets with incomplete or incomplete metadata. By default, you also cannot send such datasets for review. If you wish to enable sending for review of datasets with incomplete metadata, turn on the "dataverse.ui.allow-review-for-incomplete" JVM option.

In order to customize the wording and add translations to the UI sections extended by this feature, you can edit the "Bundle.properties" file and the localized versions of that file. The property keys used by this feature are:
- incomplete
- valid
- dataset.message.incomplete.warning
- mydataFragment.validity
- dataverses.api.create.dataset.error.mustIncludeAuthorName
75 changes: 75 additions & 0 deletions doc/sphinx-guides/source/api/native-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,60 @@ To create a dataset, you must supply a JSON file that contains at least the foll
- Description Text
- Subject

Submit Incomplete Dataset
^^^^^^^^^^^^^^^^^^^^^^^^^

**Note:** This feature requires :ref:`dataverse.api.allow-incomplete-metadata` to be enabled and your Solr
Schema to be up-to-date with the ``datasetValid`` field.

Providing a ``.../datasets?doNotValidate=true`` query parameter turns off the validation of metadata.
In this case, only the "Author Name" is required. For example, a minimal JSON file would look like this:

.. code-block:: json
:name: dataset-incomplete.json
{
"datasetVersion": {
"metadataBlocks": {
"citation": {
"fields": [
{
"value": [
{
"authorName": {
"value": "Finch, Fiona",
"typeClass": "primitive",
"multiple": false,
"typeName": "authorName"
}
}
],
"typeClass": "compound",
"multiple": true,
"typeName": "author"
}
],
"displayName": "Citation Metadata"
}
}
}
}
The following is an example HTTP call with deactivated validation:

.. code-block:: bash
export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
export PARENT=root
export SERVER_URL=https://demo.dataverse.org
curl -H X-Dataverse-key:$API_TOKEN -X POST "$SERVER_URL/api/dataverses/$PARENT/datasets?doNotValidate=true" --upload-file dataset-incomplete.json -H 'Content-type:application/json'
**Note:** You may learn about an instance's support for deposition of incomplete datasets via :ref:`info-incomplete-metadata`.

Submit Dataset
^^^^^^^^^^^^^^

As a starting point, you can download :download:`dataset-finch1.json <../../../../scripts/search/tests/data/dataset-finch1.json>` and modify it to meet your needs. (:download:`dataset-finch1_fr.json <../../../../scripts/api/data/dataset-finch1_fr.json>` is a variant of this file that includes setting the metadata language (see :ref:`:MetadataLanguages`) to French (fr). In addition to this minimal example, you can download :download:`dataset-create-new-all-default-fields.json <../../../../scripts/api/data/dataset-create-new-all-default-fields.json>` which populates all of the metadata fields that ship with a Dataverse installation.)

The curl command below assumes you have kept the name "dataset-finch1.json" and that this file is in your current working directory.
Expand Down Expand Up @@ -3191,6 +3245,27 @@ The fully expanded example above (without environment variables) looks like this
curl https://demo.dataverse.org/api/info/apiTermsOfUse
.. _info-incomplete-metadata:

Show Support Of Incomplete Metadata Deposition
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Learn if an instance has been configured to allow deposition of incomplete datasets via the API.
See also :ref:`create-dataset-command` and :ref:`dataverse.api.allow-incomplete-metadata`

.. code-block:: bash
export SERVER_URL=https://demo.dataverse.org
curl $SERVER_URL/api/info/settings/incompleteMetadataViaApi
The fully expanded example above (without environment variables) looks like this:

.. code-block:: bash
curl https://demo.dataverse.org/api/info/settings/incompleteMetadataViaApi
.. _metadata-blocks-api:

Metadata Blocks
Expand Down
36 changes: 36 additions & 0 deletions doc/sphinx-guides/source/installation/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2344,6 +2344,19 @@ Can also be set via any `supported MicroProfile Config API source`_, e.g. the en
**WARNING:** For security, do not use the sources "environment variable" or "system property" (JVM option) in a
production context! Rely on password alias, secrets directory or cloud based sources instead!

.. _dataverse.api.allow-incomplete-metadata:

dataverse.api.allow-incomplete-metadata
+++++++++++++++++++++++++++++++++++++++

When enabled, dataset with incomplete metadata can be submitted via API for later corrections.
See :ref:`create-dataset-command` for details.

Defaults to ``false``.

Can also be set via any `supported MicroProfile Config API source`_, e.g. the environment variable
``DATAVERSE_API_ALLOW_INCOMPLETE_METADATA``. Will accept ``[tT][rR][uU][eE]|1|[oO][nN]`` as "true" expressions.

.. _dataverse.signposting.level1-author-limit:

dataverse.signposting.level1-author-limit
Expand Down Expand Up @@ -2383,6 +2396,29 @@ The default is false.

Can also be set via *MicroProfile Config API* sources, e.g. the environment variable ``DATAVERSE_MAIL_CC_SUPPORT_ON_CONTACT_EMAIL``.

dataverse.ui.allow-review-for-incomplete
++++++++++++++++++++++++++++++++++++++++

Determines if dataset submitted via API with incomplete metadata (for later corrections) can be submitted for review
from the UI.

Defaults to ``false``.

Can also be set via any `supported MicroProfile Config API source`_, e.g. the environment variable
``DATAVERSE_UI_ALLOW_REVIEW_FOR_INCOMPLETE``. Will accept ``[tT][rR][uU][eE]|1|[oO][nN]`` as "true" expressions.

dataverse.ui.show-validity-filter
+++++++++++++++++++++++++++++++++

When enabled, the filter for validity of metadata is shown in "My Data" page.
**Note:** When you wish to use this filter, you must reindex the datasets first, otherwise datasets with valid metadata
will not be shown in the results.

Defaults to ``false``.

Can also be set via any `supported MicroProfile Config API source`_, e.g. the environment variable
``DATAVERSE_UI_SHOW_VALIDITY_FILTER``. Will accept ``[tT][rR][uU][eE]|1|[oO][nN]`` as "true" expressions.


.. _feature-flags:

Expand Down
2 changes: 2 additions & 0 deletions doc/sphinx-guides/source/user/account.rst
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ Microsoft Azure AD, GitHub, and Google Log In

You can also convert your Dataverse installation account to use authentication provided by GitHub, Microsoft, or Google. These options may be found in the "Other options" section of the log in page, and function similarly to how ORCID is outlined above. If you would like to convert your account away from using one of these services for log in, then you can follow the same steps as listed above for converting away from the ORCID log in.

.. _my-data:

My Data
-------

Expand Down
7 changes: 6 additions & 1 deletion src/main/java/edu/harvard/iq/dataverse/Dataset.java
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,12 @@ public <T> T accept(Visitor<T> v) {
@Override
public String getDisplayName() {
DatasetVersion dsv = getReleasedVersion();
return dsv != null ? dsv.getTitle() : getLatestVersion().getTitle();
String result = dsv != null ? dsv.getTitle() : getLatestVersion().getTitle();
boolean resultIsEmpty = result == null || "".equals(result);
if (resultIsEmpty && getGlobalId() != null) {
return getGlobalId().asString();
}
return result;
}

@Override
Expand Down
16 changes: 15 additions & 1 deletion src/main/java/edu/harvard/iq/dataverse/DatasetPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -2168,10 +2168,24 @@ private void displayPublishMessage(){
if (workingVersion.isDraft() && workingVersion.getId() != null && canUpdateDataset()
&& !dataset.isLockedFor(DatasetLock.Reason.finalizePublication)
&& (canPublishDataset() || !dataset.isLockedFor(DatasetLock.Reason.InReview) )){
JsfHelper.addWarningMessage(datasetService.getReminderString(dataset, canPublishDataset()));
JsfHelper.addWarningMessage(datasetService.getReminderString(dataset, canPublishDataset(), false, isValid()));
}
}

public boolean isValid() {
DatasetVersion version = dataset.getLatestVersion();
if (!version.isDraft()) {
return true;
}
DatasetVersion newVersion = version.cloneDatasetVersion();
newVersion.setDatasetFields(newVersion.initDatasetFields());
return newVersion.isValid();
}

public boolean isValidOrCanReviewIncomplete() {
return isValid() || JvmSettings.UI_ALLOW_REVIEW_INCOMPLETE.lookupOptional(Boolean.class).orElse(false);
}

private void displayLockInfo(Dataset dataset) {
// Various info messages, when the dataset is locked (for various reasons):
if (dataset.isLocked() && canUpdateDataset()) {
Expand Down
11 changes: 5 additions & 6 deletions src/main/java/edu/harvard/iq/dataverse/DatasetServiceBean.java
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,6 @@ public void exportAllDatasets(boolean forceReExport) {
}

}


@Asynchronous
public void reExportDatasetAsync(Dataset dataset) {
Expand Down Expand Up @@ -757,13 +756,9 @@ public void exportDataset(Dataset dataset, boolean forceReExport) {

}

public String getReminderString(Dataset dataset, boolean canPublishDataset) {
return getReminderString( dataset, canPublishDataset, false);
}

//get a string to add to save success message
//depends on page (dataset/file) and user privleges
public String getReminderString(Dataset dataset, boolean canPublishDataset, boolean filePage) {
public String getReminderString(Dataset dataset, boolean canPublishDataset, boolean filePage, boolean isValid) {

String reminderString;

Expand All @@ -789,6 +784,10 @@ public String getReminderString(Dataset dataset, boolean canPublishDataset, bool
}
}

if (!isValid) {
reminderString = reminderString + "<br/><b style=\"color:red;\"> " + BundleUtil.getStringFromBundle("dataset.message.incomplete.warning") + "</b>";
}

if (reminderString != null) {
return reminderString;
} else {
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/edu/harvard/iq/dataverse/DatasetVersion.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.StringUtils;

Expand All @@ -77,6 +76,7 @@
public class DatasetVersion implements Serializable {

private static final Logger logger = Logger.getLogger(DatasetVersion.class.getCanonicalName());
private static final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

/**
* Convenience comparator to compare dataset versions by their version number.
Expand Down Expand Up @@ -1706,8 +1706,6 @@ public String getSemanticVersion() {

public List<ConstraintViolation<DatasetField>> validateRequired() {
List<ConstraintViolation<DatasetField>> returnListreturnList = new ArrayList<>();
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
for (DatasetField dsf : this.getFlatDatasetFields()) {
dsf.setValidationMessage(null); // clear out any existing validation message
Set<ConstraintViolation<DatasetField>> constraintViolations = validator.validate(dsf);
Expand All @@ -1721,11 +1719,13 @@ public List<ConstraintViolation<DatasetField>> validateRequired() {
return returnListreturnList;
}

public boolean isValid() {
return validate().isEmpty();
}

public Set<ConstraintViolation> validate() {
Set<ConstraintViolation> returnSet = new HashSet<>();

ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();

for (DatasetField dsf : this.getFlatDatasetFields()) {
dsf.setValidationMessage(null); // clear out any existing validation message
Expand Down
11 changes: 10 additions & 1 deletion src/main/java/edu/harvard/iq/dataverse/FilePage.java
Original file line number Diff line number Diff line change
Expand Up @@ -266,10 +266,19 @@ public String init() {
private void displayPublishMessage(){
if (fileMetadata.getDatasetVersion().isDraft() && canUpdateDataset()
&& (canPublishDataset() || !fileMetadata.getDatasetVersion().getDataset().isLockedFor(DatasetLock.Reason.InReview))){
JsfHelper.addWarningMessage(datasetService.getReminderString(fileMetadata.getDatasetVersion().getDataset(), canPublishDataset(), true));
JsfHelper.addWarningMessage(datasetService.getReminderString(fileMetadata.getDatasetVersion().getDataset(), canPublishDataset(), true, isValid()));
}
}

public boolean isValid() {
if (!fileMetadata.getDatasetVersion().isDraft()) {
return true;
}
DatasetVersion newVersion = fileMetadata.getDatasetVersion().cloneDatasetVersion();
newVersion.setDatasetFields(newVersion.initDatasetFields());
return newVersion.isValid();
}

private boolean canViewUnpublishedDataset() {
return permissionsWrapper.canViewUnpublishedDataset( dvRequestService.getDataverseRequest(), fileMetadata.getDatasetVersion().getDataset());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import edu.harvard.iq.dataverse.util.MailUtil;
import edu.harvard.iq.dataverse.util.StringUtil;
import edu.harvard.iq.dataverse.util.SystemConfig;
import edu.harvard.iq.dataverse.util.json.JsonUtil;
import edu.harvard.iq.dataverse.UserNotification.Type;

import java.time.LocalDate;
Expand Down Expand Up @@ -708,4 +707,5 @@ public boolean isCustomLicenseAllowed() {
}
return customLicenseAllowed;
}

}
Loading

0 comments on commit 55179da

Please sign in to comment.