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

Expose export formats in native API #10739

Merged
merged 11 commits into from
Nov 22, 2024

Conversation

julian-schneider
Copy link
Contributor

@julian-schneider julian-schneider commented Aug 2, 2024

What this PR does / why we need it: The PR adds a method that exposes the full list of available exporters (display- and format names). This is especially useful for instances that have added custom formats.

Which issue(s) this PR closes: I know no pre-existing issues for this.

Suggestions on how to test this: New method found here: /api/info/exportFormats

Does this PR introduce a user interface change? If mockups are available, please link/include them here: No, just API and documentation changes.

API answer looks like this:

{
  "status": "OK",
  "data": [
    {
      "displayName": "OAI_ORE",
      "formatName": "OAI_ORE"
    },
    {
      "displayName": "DataCite",
      "formatName": "Datacite"
    },
    {
      "displayName": "Dublin Core",
      "formatName": "oai_dc"
    },
    {
      "displayName": "OpenAIRE",
      "formatName": "oai_datacite"
    },
    {
      "displayName": "Schema.org JSON-LD",
      "formatName": "schema.org"
    },
    {
      "displayName": "DDI",
      "formatName": "ddi"
    },
    {
      "displayName": "Dublin Core",
      "formatName": "dcterms"
    },
    {
      "displayName": "DDI HTML Codebook",
      "formatName": "html"
    },
    {
      "displayName": "JSON",
      "formatName": "dataverse_json"
    },
    {
      "displayName": "DDI",
      "formatName": "oai_ddi"
    }
  ]
}

Rendered docs entry looks like this:
image

Live version: https://dataverse-guide--10739.org.readthedocs.build/en/10739/api/native-api.html#get-export-formats

Is there a release notes update needed for this change?:
New API method for listing the available exporters. Found at /api/info/exportFormats, produces display names and format names.

@pdurbin pdurbin added Size: 3 A percentage of a sprint. 2.1 hours. Type: Feature a feature request labels Aug 2, 2024
Copy link
Member

@pdurbin pdurbin left a comment

Choose a reason for hiding this comment

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

@julian-schneider good idea! Thanks for the pull request. I left you some comments.

src/main/java/edu/harvard/iq/dataverse/api/Info.java Outdated Show resolved Hide resolved
src/main/java/edu/harvard/iq/dataverse/api/Info.java Outdated Show resolved Hide resolved
doc/sphinx-guides/source/api/native-api.rst Show resolved Hide resolved
Get Export Formats
~~~~~~~~~~~~~~~~~~~~~~~~~~~

Get the available export formats. The response contains a list of objects each containing the display name and format name for an available exporter.
Copy link
Member

Choose a reason for hiding this comment

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

Does this include external exporters? I assume so. Can we please mention they are included as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As far as I know, all exporters, standard and custom, are managed by the ExportService, and are consequently all listed. I improved the docs in 3b2c8e5.

@julian-schneider
Copy link
Contributor Author

Thanks for your feedback @pdurbin - I will be absent for two weeks, so some time will pass before I revise this. See you then!

@julian-schneider
Copy link
Contributor Author

The response is now an object, and contains more properties per format, as suggested.

New response looks like this:

(expand response)
{
  "status": "OK",
  "data": {
    "OAI_ORE": {
      "displayName": "OAI_ORE",
      "mediaType": "application/json",
      "isHarvestable": false,
      "isVisibleInUserInterface": true
    },
    "Datacite": {
      "displayName": "DataCite",
      "mediaType": "application/xml",
      "isHarvestable": true,
      "isVisibleInUserInterface": true,
      "XMLNameSpace": "http://datacite.org/schema/kernel-3",
      "XMLSchemaLocation": "http://datacite.org/schema/kernel-3 http://schema.datacite.org/meta/kernel-3/metadata.xsd",
      "XMLSchemaVersion": "3.0"
    },
    "oai_dc": {
      "displayName": "Dublin Core",
      "mediaType": "application/xml",
      "isHarvestable": true,
      "isVisibleInUserInterface": false,
      "XMLNameSpace": "http://www.openarchives.org/OAI/2.0/oai_dc/",
      "XMLSchemaLocation": "http://www.openarchives.org/OAI/2.0/oai_dc.xsd",
      "XMLSchemaVersion": "2.0"
    },
    "oai_datacite": {
      "displayName": "OpenAIRE",
      "mediaType": "application/xml",
      "isHarvestable": true,
      "isVisibleInUserInterface": true,
      "XMLNameSpace": "http://datacite.org/schema/kernel-4",
      "XMLSchemaLocation": "http://schema.datacite.org/meta/kernel-4.1/metadata.xsd",
      "XMLSchemaVersion": "4.1"
    },
    "schema.org": {
      "displayName": "Schema.org JSON-LD",
      "mediaType": "application/json",
      "isHarvestable": false,
      "isVisibleInUserInterface": true
    },
    "ddi": {
      "displayName": "DDI",
      "mediaType": "application/xml",
      "isHarvestable": false,
      "isVisibleInUserInterface": true,
      "XMLNameSpace": "ddi:codebook:2_5",
      "XMLSchemaLocation": "https://ddialliance.org/Specification/DDI-Codebook/2.5/XMLSchema/codebook.xsd",
      "XMLSchemaVersion": "2.5"
    },
    "dcterms": {
      "displayName": "Dublin Core",
      "mediaType": "application/xml",
      "isHarvestable": false,
      "isVisibleInUserInterface": true,
      "XMLNameSpace": "http://purl.org/dc/terms/",
      "XMLSchemaLocation": "http://dublincore.org/schemas/xmls/qdc/dcterms.xsd",
      "XMLSchemaVersion": "2.0"
    },
    "html": {
      "displayName": "DDI HTML Codebook",
      "mediaType": "text/html",
      "isHarvestable": false,
      "isVisibleInUserInterface": true
    },
    "dataverse_json": {
      "displayName": "JSON",
      "mediaType": "application/json",
      "isHarvestable": true,
      "isVisibleInUserInterface": true
    },
    "oai_ddi": {
      "displayName": "DDI",
      "mediaType": "application/xml",
      "isHarvestable": true,
      "isVisibleInUserInterface": false,
      "XMLNameSpace": "ddi:codebook:2_5",
      "XMLSchemaLocation": "https://ddialliance.org/Specification/DDI-Codebook/2.5/XMLSchema/codebook.xsd",
      "XMLSchemaVersion": "2.5"
    }
  }
}
New docs look like this:

Screenshot from 2024-08-28 11-05-16

@julian-schneider
Copy link
Contributor Author

@pdurbin I believe I have addressed all the feedback you gave, have a nice day!

@coveralls
Copy link

Coverage Status

coverage: 20.76% (+0.02%) from 20.741%
when pulling 3f81981 on julian-schneider:expose-export-formats
into 0d27957 on IQSS:develop.

@johannes-darms
Copy link
Contributor

@pdurbin @GPortas could be get this API into the next release? This is a rather simple feature needed for the SPA to display the list of export formats.

Copy link
Member

@pdurbin pdurbin left a comment

Choose a reason for hiding this comment

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

I haven't run the code yet (or in a while, I forget) but I left a couple more suggestions.

Please also merge the latest from develop.

src/test/resources/json/export-formats.json Outdated Show resolved Hide resolved
src/test/java/edu/harvard/iq/dataverse/api/InfoIT.java Outdated Show resolved Hide resolved
@pdurbin
Copy link
Member

pdurbin commented Oct 15, 2024

@johannes-darms I do like the PR a lot. @cmbz @scolapasta what do you think? Can we put a 6.5 milestone on it or at least put it in "sprint ready"?

Also, I agree with Johannes that the SPA will need this some day. We might want to see what @ekraffmiller @ChengShi-1 @GPortas and @g-saracca think about the output, if they are happy with it.

@pdurbin pdurbin added the Champion: pdurbin Championed by @pdurbin for inclusion in the next release label Oct 15, 2024
@cmbz cmbz added this to the 6.5 milestone Oct 15, 2024
@cmbz
Copy link

cmbz commented Oct 15, 2024

2024/10/15: Added to sprint ready after conversation with @pdurbin

@cmbz cmbz added the FY25 Sprint 10 FY25 Sprint 10 (2024-11-06 - 2024-11-20) label Nov 7, 2024
@pdurbin pdurbin removed the Champion: pdurbin Championed by @pdurbin for inclusion in the next release label Nov 12, 2024
Copy link
Member

@pdurbin pdurbin left a comment

Choose a reason for hiding this comment

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

@julian-schneider this is looking really good. I left you a few comments and a PR-for-this-PR ( julian-schneider#1 ) to consider. Also, can you please merge the latest from "develop" into your branch? Thanks!

doc/release-notes/expose-export-formats.md Outdated Show resolved Hide resolved
doc/sphinx-guides/source/api/native-api.rst Show resolved Hide resolved
Comment on lines +105 to +107
for (String[] labels : instance.getExportersLabels()) {
try {
Exporter exporter = instance.getExporter(labels[1]);
Copy link
Member

Choose a reason for hiding this comment

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

This lookup seems a bit awkward but it's not your fault. I wonder if we should add a method to ExportService like this...

public Collection<Exporter> getExporters() {
    return exporterMap.values();
}

... so that it can be used like this in places like Info.java:

for (Exporter exporter : instance.getExporters()) {
    //...
}

But I dunno. Maybe there's a reason why we don't offer a "getExporters" method like this.

Copy link
Contributor Author

@julian-schneider julian-schneider Nov 20, 2024

Choose a reason for hiding this comment

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

I agree that the steps I had to use to get the exporters were a bit awkward. If you think it would be in scope, I can add a method like that to this PR.

Copy link
Member

Choose a reason for hiding this comment

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

No, let's think about it outside this PR. You're welcome to create an issue, though, if you like!

src/test/java/edu/harvard/iq/dataverse/api/InfoIT.java Outdated Show resolved Hide resolved
@pdurbin pdurbin added the Status: Needs Input Applied to issues in need of input from someone currently unavailable label Nov 19, 2024
@pdurbin pdurbin removed the Status: Needs Input Applied to issues in need of input from someone currently unavailable label Nov 20, 2024
@pdurbin
Copy link
Member

pdurbin commented Nov 20, 2024

@julian-schneider tests are failing in InfoIT.testGetExportFormats. Can you please take a look?

Error
data.Datacite.XMLNameSpace
Expected: http://datacite.org/schema/kernel-3
     got: http://datacite.org/schema/kernel-4
 ; data.Datacite.XMLSchemaLocation
Expected: http://datacite.org/schema/kernel-3 http://schema.datacite.org/meta/kernel-3/metadata.xsd
     got: http://datacite.org/schema/kernel-4 http://schema.datacite.org/meta/kernel-4.5/metadata.xsd
 ; data.Datacite.XMLSchemaVersion
Expected: 3.0
     got: 4.5
 ; data.ddi.displayName
Expected: DDI
     got: DDI Codebook v2
 ; data.oai_ddi.displayName
Expected: DDI
     got: DDI Codebook v2
Stacktrace
java.lang.AssertionError: 
data.Datacite.XMLNameSpace
Expected: http://datacite.org/schema/kernel-3
     got: http://datacite.org/schema/kernel-4
 ; data.Datacite.XMLSchemaLocation
Expected: http://datacite.org/schema/kernel-3 http://schema.datacite.org/meta/kernel-3/metadata.xsd
     got: http://datacite.org/schema/kernel-4 http://schema.datacite.org/meta/kernel-4.5/metadata.xsd
 ; data.Datacite.XMLSchemaVersion
Expected: 3.0
     got: 4.5
 ; data.ddi.displayName
Expected: DDI
     got: DDI Codebook v2
 ; data.oai_ddi.displayName
Expected: DDI
     got: DDI Codebook v2
	at org.skyscreamer.jsonassert.JSONAssert.assertEquals(JSONAssert.java:417)
	at org.skyscreamer.jsonassert.JSONAssert.assertEquals(JSONAssert.java:394)
	at org.skyscreamer.jsonassert.JSONAssert.assertEquals(JSONAssert.java:336)
	at edu.harvard.iq.dataverse.api.InfoIT.testGetExportFormats(InfoIT.java:99)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
Standard Output
{
    "status": "OK",
    "data": {
        "OAI_ORE": {
            "displayName": "OAI_ORE",
            "mediaType": "application/json",
            "isHarvestable": false,
            "isVisibleInUserInterface": true
        },
        "Datacite": {
            "displayName": "DataCite",
            "mediaType": "application/xml",
            "isHarvestable": true,
            "isVisibleInUserInterface": true,
            "XMLNameSpace": "http://datacite.org/schema/kernel-4",
            "XMLSchemaLocation": "http://datacite.org/schema/kernel-4 http://schema.datacite.org/meta/kernel-4.5/metadata.xsd",
            "XMLSchemaVersion": "4.5"
        },
        "oai_dc": {
            "displayName": "Dublin Core",
            "mediaType": "application/xml",
            "isHarvestable": true,
            "isVisibleInUserInterface": false,
            "XMLNameSpace": "http://www.openarchives.org/OAI/2.0/oai_dc/",
            "XMLSchemaLocation": "http://www.openarchives.org/OAI/2.0/oai_dc.xsd",
            "XMLSchemaVersion": "2.0"
        },
        "oai_datacite": {
            "displayName": "OpenAIRE",
            "mediaType": "application/xml",
            "isHarvestable": true,
            "isVisibleInUserInterface": true,
            "XMLNameSpace": "http://datacite.org/schema/kernel-4",
            "XMLSchemaLocation": "http://schema.datacite.org/meta/kernel-4.1/metadata.xsd",
            "XMLSchemaVersion": "4.1"
        },
        "schema.org": {
            "displayName": "Schema.org JSON-LD",
            "mediaType": "application/json",
            "isHarvestable": false,
            "isVisibleInUserInterface": true
        },
        "ddi": {
            "displayName": "DDI Codebook v2",
            "mediaType": "application/xml",
            "isHarvestable": false,
            "isVisibleInUserInterface": true,
            "XMLNameSpace": "ddi:codebook:2_5",
            "XMLSchemaLocation": "https://ddialliance.org/Specification/DDI-Codebook/2.5/XMLSchema/codebook.xsd",
            "XMLSchemaVersion": "2.5"
        },
        "dcterms": {
            "displayName": "Dublin Core",
            "mediaType": "application/xml",
            "isHarvestable": false,
            "isVisibleInUserInterface": true,
            "XMLNameSpace": "http://purl.org/dc/terms/",
            "XMLSchemaLocation": "http://dublincore.org/schemas/xmls/qdc/dcterms.xsd",
            "XMLSchemaVersion": "2.0"
        },
        "html": {
            "displayName": "DDI HTML Codebook",
            "mediaType": "text/html",
            "isHarvestable": false,
            "isVisibleInUserInterface": true
        },
        "dataverse_json": {
            "displayName": "JSON",
            "mediaType": "application/json",
            "isHarvestable": true,
            "isVisibleInUserInterface": true
        },
        "oai_ddi": {
            "displayName": "DDI Codebook v2",
            "mediaType": "application/xml",
            "isHarvestable": true,
            "isVisibleInUserInterface": false,
            "XMLNameSpace": "ddi:codebook:2_5",
            "XMLSchemaLocation": "https://ddialliance.org/Specification/DDI-Codebook/2.5/XMLSchema/codebook.xsd",
            "XMLSchemaVersion": "2.5"
        }
    }
}

Copy link
Member

@pdurbin pdurbin left a comment

Choose a reason for hiding this comment

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

As of f3b72c6 tests are passing: https://jenkins.dataverse.org/job/IQSS-Dataverse-Develop-PR/job/PR-10739/9/testReport/

Thanks, @julian-schneider! Approved.

In DMs we did discuss how if there's a lot of churn in our formats we can do some mocking. Still, it's valuable to actually exercise the API endpoint itself, even if we make the assertions less strict in the future.

@cmbz cmbz added the FY25 Sprint 11 FY25 Sprint 11 (2024-11-20 - 2024-12-04) label Nov 21, 2024
@ofahimIQSS ofahimIQSS self-assigned this Nov 22, 2024
@ofahimIQSS
Copy link
Contributor

No issues with PR discovered.
Additional tests were done in internal before and after installing Croissant. As expected, Croissant did appear in /api/info/exportFormats after installation
Testing of 10739.docx

@ofahimIQSS ofahimIQSS merged commit b8e4758 into IQSS:develop Nov 22, 2024
12 checks passed
@ofahimIQSS ofahimIQSS removed their assignment Nov 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
FY25 Sprint 10 FY25 Sprint 10 (2024-11-06 - 2024-11-20) FY25 Sprint 11 FY25 Sprint 11 (2024-11-20 - 2024-12-04) Size: 3 A percentage of a sprint. 2.1 hours. Type: Feature a feature request
Projects
Status: Done 🧹
Development

Successfully merging this pull request may close these issues.

6 participants