error management

This commit is contained in:
Michele Artini 2024-11-07 14:10:35 +01:00
parent 6fc507f056
commit 44b7be3ba6
4 changed files with 128 additions and 23 deletions

View File

@ -1,23 +1,20 @@
package eu.dnetlib.app.directindex.sword;
import eu.dnetlib.app.directindex.sword.model.SwordErrorType;
public class SwordException extends Exception {
private static final long serialVersionUID = -6401402258941503950L;
private final int httpCode;
private final String httpMessage;
private final SwordErrorType error;
public SwordException(final int httpCode, final String httpMessage) {
this.httpCode = httpCode;
this.httpMessage = httpMessage;
public SwordErrorType getError() {
return error;
}
public int getHttpCode() {
return httpCode;
}
public String getHttpMessage() {
return httpMessage;
public SwordException(final SwordErrorType error) {
super();
this.error = error;
}
}

View File

@ -22,9 +22,11 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import eu.dnetlib.app.directindex.service.DirectIndexService;
import eu.dnetlib.app.directindex.sword.model.SwordError;
import eu.dnetlib.app.directindex.sword.model.SwordErrorType;
import eu.dnetlib.app.directindex.sword.model.SwordMetadataDocument;
import eu.dnetlib.app.directindex.sword.model.SwordService;
import eu.dnetlib.app.directindex.sword.model.SwordStatusDocument;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
@RestController("/api/directindex/sword/3.0")
@ -48,15 +50,15 @@ public class SwordServiceUrlController {
@RequestHeader(value = "Metadata-Format", defaultValue = "http://purl.org/net/sword/3.0/types/Metadata") final String mdFormat,
@RequestHeader(value = "Packaging", defaultValue = "http://purl.org/net/sword/3.0/package/Binary") final String packaging,
@RequestHeader("Slug") final String slug,
@RequestBody final String json) {
@RequestBody final String json) throws SwordException {
// TODO: DIGEST Evaluate if the digest (md5) of the json string
if (!MediaType.APPLICATION_JSON_VALUE.equals(contentType)) { return new ResponseEntity<>(HttpStatus.UNSUPPORTED_MEDIA_TYPE); }
if (!MediaType.APPLICATION_JSON_VALUE.equals(contentType)) { throw new SwordException(SwordErrorType.ContentTypeNotAcceptable); }
if (!"attachment; metadata=true".equals(contentDisposition) || inProgress) { return new ResponseEntity<>(HttpStatus.METHOD_NOT_ALLOWED); }
if (!"attachment; metadata=true".equals(contentDisposition) || inProgress) { throw new SwordException(SwordErrorType.MethodNotAllowed); }
if (!"OAF".equals(mdFormat)) { return new ResponseEntity<>(HttpStatus.UNSUPPORTED_MEDIA_TYPE); }
if (!"OAF".equals(mdFormat)) { throw new SwordException(SwordErrorType.MetadataFormatNotAcceptable); }
// TODO
final SwordStatusDocument status = null;
@ -68,7 +70,7 @@ public class SwordServiceUrlController {
try {
service.prepareMetadataInsertion(parseMetadata(json));
} catch (final JsonProcessingException e) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
throw new SwordException(SwordErrorType.ContentMalformed);
}
return new ResponseEntity<>(status, responseHeaders, HttpStatus.ACCEPTED);
@ -124,13 +126,12 @@ public class SwordServiceUrlController {
}
@ExceptionHandler(Throwable.class)
public SwordError handleException(final HttpServletResponse req, final HttpServletResponse res, final Throwable e) throws IOException {
public SwordError handleException(final HttpServletRequest req, final HttpServletResponse res, final Throwable e) throws IOException {
if (e instanceof SwordException) {
final SwordException swe = (SwordException) e;
res.sendError(swe.getHttpCode(), swe.getHttpMessage());
res.setStatus(((SwordException) e).getError().getHttpCode());
} else {
res.sendError(HttpStatus.INTERNAL_SERVER_ERROR.value());
res.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
}
return new SwordError(req, e);

View File

@ -1,11 +1,72 @@
package eu.dnetlib.app.directindex.sword.model;
import jakarta.servlet.http.HttpServletResponse;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.time.LocalDateTime;
import org.apache.commons.lang3.exception.ExceptionUtils;
import com.fasterxml.jackson.annotation.JsonProperty;
import eu.dnetlib.app.directindex.sword.SwordException;
import jakarta.servlet.http.HttpServletRequest;
public class SwordError {
public SwordError(final HttpServletResponse req, final Throwable e) {
// TODO Auto-generated constructor stub
@JsonProperty("@context")
private final URL context;
@JsonProperty("@type")
private final SwordErrorType type;
private final LocalDateTime timestamp;
private final String error;
private final String log;
public SwordError(final HttpServletRequest req, final Throwable e) {
try {
// TODO
context = new URI("http://").toURL();
} catch (final MalformedURLException | URISyntaxException e1) {
throw new RuntimeException("Invalid URL");
}
if (e instanceof SwordException) {
type = ((SwordException) e).getError();
error = ((SwordException) e).getMessage();
} else {
type = SwordErrorType.BadRequest;
error = e.getMessage();
}
timestamp = LocalDateTime.now();
log = ExceptionUtils.getStackTrace(e);
}
public URL getContext() {
return context;
}
public SwordErrorType getType() {
return type;
}
public LocalDateTime getTimestamp() {
return timestamp;
}
public String getError() {
return error;
}
public String getLog() {
return log;
}
// @formatter:off

View File

@ -0,0 +1,46 @@
package eu.dnetlib.app.directindex.sword.model;
public enum SwordErrorType {
// @formatter:off
AuthenticationFailed(403, "The request supplied invalid credentials"),
AuthenticationRequired(401, "The request supplied no credentials, when the server was expecting to authenticate the request."),
BadRequest(400, "The request did not meet the standard specified by the SWORD protocol. This error can be used when no other error is appropriate"),
ByReferenceFileSizeExceeded(400, "The client supplied a By-Reference deposit file, which specified a file size which exceeded the server's limit"),
ByReferenceNotAllowed(412, "The client attempted to carry out a By-Reference deposit on a server which does not support it"),
ContentMalformed(400, "The body content of the request was malformed in some way, such that the server cannot read it correctly."),
ContentTypeNotAcceptable(415 , "The Content-Type header specifies a content type of the request which is in a format that the server cannot accept."),
DigestMismatch(412 , "One or more of the Digests that the server checked did not match the deposited content"),
ETagNotMatched(412 , "The client supplied an If-Match header which did not match the current ETag for the resource being updated."),
ETagRequired(412 , "The client did not supply an If-Match header, when one was required by the server"),
Forbidden(403 , "The client requested an operation that is not permitted by the server in this context."),
FormatHeaderMismatch(415 , "The Metadata-Format or Packaging header does not match what the server found when looking at the Metadata or Packaged Content supplied in a request."),
InvalidSegmentSize(400 , "The client sent a segment that was not the final segment, and was not the size that it indicated segments would be, or during segmented upload initialisation, the client specified a segment size which was not between minSegmentSize and maxSegmentSize."),
MaxAssembledSizeExceeded(400 , "During a segmented upload initialisation, the client specified a total file size which is larger than the maximum assembled file size supported by the server"),
MaxUploadSizeExceeded(413 , "The request supplied body content which is larger than that supported by the server."),
MetadataFormatNotAcceptable(415 , "The Metadata-Format header specifies a metadata format for the request which is in a format that the server cannot accept"),
MethodNotAllowed(405 , "The request is for a method on a resource that is not permitted. This may be permanent, temporary, and may depend on the clients credentials"),
OnBehalfOfNotAllowed(412 , "The request contained an On-Behalf-Of header, although the server indicates that it does not support this."),
PackagingFormatNotAcceptable(415 , "The Packaging header specifies a packaging format for the request which is in a format that the server cannot accept"),
SegmentedUploadTimedOut(410 , "The client's segmented upload URL has timed out. Servers MAY respond to this with a 404 and no explanation also."),
SegmentLimitExceeded(400 , "During a segmented upload initialisation, the client specified a total number of intended segments which is larger than the limit specified by the server"),
UnexpectedSegment(400 , "The client sent a segment that the server was not expecting; in particular the server may have recieved all the segments it was expecting, and this is an extra one");
// @formatter:on
private final int httpCode;
private final String message;
private SwordErrorType(final int httpCode, final String message) {
this.httpCode = httpCode;
this.message = message;
}
public int getHttpCode() {
return httpCode;
}
public String getMessage() {
return message;
}
}