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

OAI-PMH error handling: meaningful errors in XML for verb processing #10205

Merged
merged 9 commits into from
Jan 17, 2024
4 changes: 4 additions & 0 deletions doc/release-notes/9275-harvest-invalid-query-params.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
OAI-PMH error handling has been improved to display a machine-readable error in XML rather than a 500 error with no further information.

- /oai?foo=bar will show "No argument 'verb' found"
- /oai?verb=foo&verb=bar will show "Verb must be singular, given: '[foo, bar]'"
3 changes: 3 additions & 0 deletions docker-compose-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ services:
DATAVERSE_AUTH_OIDC_CLIENT_SECRET: 94XHrfNRwXsjqTqApRrwWmhDLDHpIYV8
DATAVERSE_AUTH_OIDC_AUTH_SERVER_URL: http://keycloak.mydomain.com:8090/realms/test
DATAVERSE_JSF_REFRESH_PERIOD: "1"
# to get HarvestingServerIT to pass
dataverse_oai_server_maxidentifiers: "2"
dataverse_oai_server_maxrecords: "2"
JVM_ARGS: -Ddataverse.files.storage-driver-id=file1
-Ddataverse.files.file1.type=file
-Ddataverse.files.file1.label=Filesystem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import edu.harvard.iq.dataverse.settings.SettingsServiceBean;
import edu.harvard.iq.dataverse.util.MailUtil;
import edu.harvard.iq.dataverse.util.SystemConfig;
import io.gdcc.xoai.exceptions.BadVerbException;
import io.gdcc.xoai.exceptions.OAIException;
import io.gdcc.xoai.model.oaipmh.Granularity;
import io.gdcc.xoai.services.impl.SimpleResumptionTokenFormat;
Expand All @@ -48,6 +49,7 @@
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.util.Map;
import javax.xml.stream.XMLStreamException;
import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.ConfigProvider;
Expand Down Expand Up @@ -256,10 +258,16 @@ private void processRequest(HttpServletRequest httpServletRequest, HttpServletRe
"Sorry. OAI Service is disabled on this Dataverse node.");
return;
}

RawRequest rawRequest = RequestBuilder.buildRawRequest(httpServletRequest.getParameterMap());

OAIPMH handle = dataProvider.handle(rawRequest);

Map<String, String[]> params = httpServletRequest.getParameterMap();
OAIPMH handle;
try {
RawRequest rawRequest = RequestBuilder.buildRawRequest(params);
handle = dataProvider.handle(rawRequest);
} catch (BadVerbException bve) {
handle = dataProvider.handle(params);
pdurbin marked this conversation as resolved.
Show resolved Hide resolved
}

response.setContentType("text/xml;charset=UTF-8");

try (XmlWriter xmlWriter = new XmlWriter(response.getOutputStream(), repositoryConfiguration);) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -860,7 +860,38 @@ public void testMultiRecordOaiSet() throws InterruptedException {
logger.info("deleteResponse.getStatusCode(): " + deleteResponse.getStatusCode());
assertEquals(200, deleteResponse.getStatusCode(), "Failed to delete the control multi-record set");
}


@Test
public void testInvalidQueryParams() {

// The query parameter "verb" must appear.
Response noVerbArg = given().get("/oai?foo=bar");
noVerbArg.prettyPrint();
noVerbArg.then().assertThat()
.statusCode(OK.getStatusCode())
.body("oai.error.@code", equalTo("badVerb"))
pdurbin marked this conversation as resolved.
Show resolved Hide resolved
.body("oai.error", equalTo("No argument 'verb' found"));

// The query parameter "verb" cannot appear more than once.
Response repeated = given().get( "/oai?verb=foo&verb=bar");
repeated.prettyPrint();
repeated.then().assertThat()
.statusCode(OK.getStatusCode())
.body("oai.error.@code", equalTo("badVerb"))
.body("oai.error", equalTo("Verb must be singular, given: '[foo, bar]'"));

}

@Test
public void testNoSuchSetError() {
Response noSuchSet = given().get("/oai?verb=ListIdentifiers&set=census&metadataPrefix=dc");
noSuchSet.prettyPrint();
noSuchSet.then().assertThat()
.statusCode(OK.getStatusCode())
.body("oai.error.@code", equalTo("noRecordsMatch"))
.body("oai.error", equalTo("Requested set 'census' does not exist"));
}

// TODO:
// What else can we test?
// Some ideas:
Expand Down
Loading