diff --git a/api/src/main/java/com/inrupt/client/ClientHttpException.java b/api/src/main/java/com/inrupt/client/ClientHttpException.java
new file mode 100644
index 00000000000..abe1fbbc505
--- /dev/null
+++ b/api/src/main/java/com/inrupt/client/ClientHttpException.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright Inrupt Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+ * Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.inrupt.client;
+
+/**
+ * A runtime exception representing an HTTP error response carrying a structured representation of the problem. The
+ * problem description is embedded in a {@link ProblemDetails} instance.
+ */
+public class ClientHttpException extends InruptClientException {
+ private final ProblemDetails problemDetails;
+
+ /**
+ * Create a ClientHttpException.
+ * @param problemDetails the {@link ProblemDetails} instance
+ * @param message the exception message
+ */
+ public ClientHttpException(final ProblemDetails problemDetails, final String message) {
+ super(message);
+ this.problemDetails = problemDetails;
+ }
+
+ /**
+ * Create a ClientHttpException.
+ * @param problemDetails the {@link ProblemDetails} instance
+ * @param message the exception message
+ * @param cause a wrapped exception cause
+ */
+ public ClientHttpException(final ProblemDetails problemDetails, final String message, final Exception cause) {
+ super(message, cause);
+ this.problemDetails = problemDetails;
+ }
+
+ public ProblemDetails getProblemDetails() {
+ return this.problemDetails;
+ }
+}
diff --git a/api/src/main/java/com/inrupt/client/HttpStatus.java b/api/src/main/java/com/inrupt/client/HttpStatus.java
new file mode 100644
index 00000000000..52f72c14464
--- /dev/null
+++ b/api/src/main/java/com/inrupt/client/HttpStatus.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright Inrupt Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+ * Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.inrupt.client;
+
+import java.util.Arrays;
+
+public final class HttpStatus {
+
+ public static final int BAD_REQUEST = 400;
+ public static final int UNAUTHORIZED = 401;
+ public static final int FORBIDDEN = 403;
+ public static final int NOT_FOUND = 404;
+ public static final int METHOD_NOT_ALLOWED = 405;
+ public static final int NOT_ACCEPTABLE = 406;
+ public static final int CONFLICT = 409;
+ public static final int GONE = 410;
+ public static final int PRECONDITION_FAILED = 412;
+ public static final int UNSUPPORTED_MEDIA_TYPE = 415;
+ public static final int TOO_MANY_REQUESTS = 429;
+ public static final int INTERNAL_SERVER_ERROR = 500;
+
+ enum StatusMessages {
+ BAD_REQUEST(HttpStatus.BAD_REQUEST, "Bad Request"),
+ UNAUTHORIZED(HttpStatus.UNAUTHORIZED, "Unauthorized"),
+ FORBIDDEN(HttpStatus.FORBIDDEN, "Forbidden"),
+ NOT_FOUND(HttpStatus.NOT_FOUND, "Not Found"),
+ METHOD_NOT_ALLOWED(HttpStatus.METHOD_NOT_ALLOWED, "Method Not Allowed"),
+ NOT_ACCEPTABLE(HttpStatus.NOT_ACCEPTABLE, "Not Acceptable"),
+ CONFLICT(HttpStatus.CONFLICT, "Conflict"),
+ GONE(HttpStatus.GONE, "Gone"),
+ PRECONDITION_FAILED(HttpStatus.PRECONDITION_FAILED, "Precondition Failed"),
+ UNSUPPORTED_MEDIA_TYPE(HttpStatus.UNSUPPORTED_MEDIA_TYPE, "Unsupported Media Type"),
+ TOO_MANY_REQUESTS(HttpStatus.TOO_MANY_REQUESTS, "Too Many Requests"),
+ INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "Internal Server Error");
+
+ private final int code;
+ final String message;
+
+ StatusMessages(final int code, final String message) {
+ this.code = code;
+ this.message = message;
+ }
+
+ static String getStatusMessage(final int statusCode) {
+ return Arrays.stream(StatusMessages.values())
+ .filter(status -> status.code == statusCode)
+ .findFirst()
+ .map(knownStatus -> knownStatus.message)
+ .orElseGet(() -> {
+ // If the status is unknown, default to 400 for client errors and 500 for server errors
+ if (statusCode >= 400 && statusCode <= 499) {
+ return BAD_REQUEST.message;
+ }
+ return INTERNAL_SERVER_ERROR.message;
+ });
+ }
+ }
+
+ // Prevents instantiation.
+ private HttpStatus() {
+ /* no-op */
+ }
+}
diff --git a/api/src/main/java/com/inrupt/client/ProblemDetails.java b/api/src/main/java/com/inrupt/client/ProblemDetails.java
new file mode 100644
index 00000000000..d804755ebee
--- /dev/null
+++ b/api/src/main/java/com/inrupt/client/ProblemDetails.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright Inrupt Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+ * Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.inrupt.client;
+
+import com.inrupt.client.spi.JsonService;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * A data class representing a structured problem description sent by the server on error response.
+ *
+ * @see RFC 9457 Problem Details for HTTP APIs
+ */
+public class ProblemDetails {
+ public static final String MIME_TYPE = "application/problem+json";
+ public static final String DEFAULT_TYPE = "about:blank";
+ private final URI type;
+ private final String title;
+ private final String details;
+ private final int status;
+ private final URI instance;
+
+ public ProblemDetails(
+ final URI type,
+ final String title,
+ final String details,
+ final int status,
+ final URI instance
+ ) {
+ // The `type` is not mandatory in RFC9457, so we want to set
+ // a default value here even when deserializing from JSON.
+ if (type != null) {
+ this.type = type;
+ } else {
+ this.type = URI.create(DEFAULT_TYPE);
+ }
+ this.title = title;
+ this.details = details;
+ this.status = status;
+ this.instance = instance;
+ }
+
+ public URI getType() {
+ return this.type;
+ };
+
+ public String getTitle() {
+ return this.title;
+ };
+
+ public String getDetails() {
+ return this.details;
+ };
+
+ public int getStatus() {
+ return this.status;
+ };
+
+ public URI getInstance() {
+ return this.instance;
+ };
+
+ public static ProblemDetails fromErrorResponse(
+ final int statusCode,
+ final Headers headers,
+ final byte[] body,
+ final JsonService jsonService
+ ) {
+ if (jsonService == null
+ || (headers != null && !headers.allValues("Content-Type").contains(ProblemDetails.MIME_TYPE))) {
+ return new ProblemDetails(
+ null,
+ HttpStatus.StatusMessages.getStatusMessage(statusCode),
+ null,
+ statusCode,
+ null
+ );
+ }
+ try {
+ // ProblemDetails doesn't have a default constructor, and we can't use JSON mapping annotations because
+ // the JSON service is an abstraction over JSON-B and Jackson, so we deserialize the JSON object in a Map
+ // and build the ProblemDetails from the Map values.
+ final Map pdData = jsonService.fromJson(
+ new ByteArrayInputStream(body),
+ new HashMap(){}.getClass().getGenericSuperclass()
+ );
+ final String title = Optional.ofNullable((String) pdData.get("title"))
+ .orElse(HttpStatus.StatusMessages.getStatusMessage(statusCode));
+ final String details = (String) pdData.get("details");
+ final URI type = Optional.ofNullable(pdData.get("type"))
+ .map(t -> URI.create((String) t))
+ .orElse(null);
+ final URI instance = Optional.ofNullable(pdData.get("instance"))
+ .map(i -> URI.create((String) i))
+ .orElse(null);
+ // Note that the status code is disregarded from the body, and reused from the HTTP response directly,
+ // as they must be the same as per https://www.rfc-editor.org/rfc/rfc9457.html#name-status.
+ return new ProblemDetails(type, title, details, statusCode, instance);
+ } catch (IOException e) {
+ return new ProblemDetails(
+ null,
+ HttpStatus.StatusMessages.getStatusMessage(statusCode),
+ null,
+ statusCode,
+ null
+ );
+ }
+ }
+}
diff --git a/api/src/test/java/com/inrupt/client/HttpStatusTest.java b/api/src/test/java/com/inrupt/client/HttpStatusTest.java
new file mode 100644
index 00000000000..35126cb23c0
--- /dev/null
+++ b/api/src/test/java/com/inrupt/client/HttpStatusTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright Inrupt Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+ * Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.inrupt.client;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+public class HttpStatusTest {
+ @Test
+ void checkHttpStatusSearchKnownStatus() {
+ assertEquals(
+ HttpStatus.StatusMessages.getStatusMessage(HttpStatus.NOT_FOUND),
+ HttpStatus.StatusMessages.NOT_FOUND.message
+ );
+ }
+
+ @Test
+ void checkHttpStatusSearchUnknownClientError () {
+ assertEquals(
+ HttpStatus.StatusMessages.getStatusMessage(418),
+ HttpStatus.StatusMessages.BAD_REQUEST.message
+ );
+ }
+
+ @Test
+ void checkHttpStatusSearchUnknownServerError () {
+ assertEquals(
+ HttpStatus.StatusMessages.getStatusMessage(555),
+ HttpStatus.StatusMessages.INTERNAL_SERVER_ERROR.message
+ );
+ assertEquals(
+ HttpStatus.StatusMessages.getStatusMessage(999),
+ HttpStatus.StatusMessages.INTERNAL_SERVER_ERROR.message
+ );
+ assertEquals(
+ HttpStatus.StatusMessages.getStatusMessage(-1),
+ HttpStatus.StatusMessages.INTERNAL_SERVER_ERROR.message
+ );
+ assertEquals(
+ HttpStatus.StatusMessages.getStatusMessage(15),
+ HttpStatus.StatusMessages.INTERNAL_SERVER_ERROR.message
+ );
+ }
+}
diff --git a/solid/pom.xml b/solid/pom.xml
index 15163ab2e65..3be4e20184b 100644
--- a/solid/pom.xml
+++ b/solid/pom.xml
@@ -79,6 +79,12 @@
${project.version}
test
+
+ com.inrupt.client
+ inrupt-client-jackson
+ ${project.version}
+ test
+
org.slf4j
slf4j-api
diff --git a/solid/src/main/java/com/inrupt/client/solid/BadRequestException.java b/solid/src/main/java/com/inrupt/client/solid/BadRequestException.java
index 3fc0ad547f1..3e86a0ec5b4 100644
--- a/solid/src/main/java/com/inrupt/client/solid/BadRequestException.java
+++ b/solid/src/main/java/com/inrupt/client/solid/BadRequestException.java
@@ -21,6 +21,8 @@
package com.inrupt.client.solid;
import com.inrupt.client.Headers;
+import com.inrupt.client.HttpStatus;
+import com.inrupt.client.ProblemDetails;
import java.net.URI;
@@ -32,7 +34,7 @@
public class BadRequestException extends SolidClientException {
private static final long serialVersionUID = -3379457428921025570L;
- public static final int STATUS_CODE = 400;
+ public static final int STATUS_CODE = HttpStatus.BAD_REQUEST;
/**
* Create a BadRequestException exception.
@@ -41,6 +43,7 @@ public class BadRequestException extends SolidClientException {
* @param uri the uri
* @param headers the response headers
* @param body the body
+ * @deprecated
*/
public BadRequestException(
final String message,
@@ -49,4 +52,22 @@ public BadRequestException(
final String body) {
super(message, uri, STATUS_CODE, headers, body);
}
+
+ /**
+ * Create a BadRequestException exception.
+ *
+ * @param message the message
+ * @param pd the ProblemDetails instance
+ * @param uri the uri
+ * @param headers the response headers
+ * @param body the body
+ */
+ public BadRequestException(
+ final String message,
+ final ProblemDetails pd,
+ final URI uri,
+ final Headers headers,
+ final String body) {
+ super(message, pd, uri, headers, body);
+ }
}
diff --git a/solid/src/main/java/com/inrupt/client/solid/ConflictException.java b/solid/src/main/java/com/inrupt/client/solid/ConflictException.java
index d88386eb724..80b63b7decf 100644
--- a/solid/src/main/java/com/inrupt/client/solid/ConflictException.java
+++ b/solid/src/main/java/com/inrupt/client/solid/ConflictException.java
@@ -21,6 +21,8 @@
package com.inrupt.client.solid;
import com.inrupt.client.Headers;
+import com.inrupt.client.HttpStatus;
+import com.inrupt.client.ProblemDetails;
import java.net.URI;
@@ -32,7 +34,7 @@
public class ConflictException extends SolidClientException {
private static final long serialVersionUID = -203198307847520748L;
- public static final int STATUS_CODE = 409;
+ public static final int STATUS_CODE = HttpStatus.CONFLICT;
/**
* Create a ConflictException exception.
@@ -41,6 +43,7 @@ public class ConflictException extends SolidClientException {
* @param uri the uri
* @param headers the response headers
* @param body the body
+ * @deprecated
*/
public ConflictException(
final String message,
@@ -49,4 +52,22 @@ public ConflictException(
final String body) {
super(message, uri, STATUS_CODE, headers, body);
}
+
+ /**
+ * Create a ConflictException exception.
+ *
+ * @param message the message
+ * @param pd the ProblemDetails instance
+ * @param uri the uri
+ * @param headers the response headers
+ * @param body the body
+ */
+ public ConflictException(
+ final String message,
+ final ProblemDetails pd,
+ final URI uri,
+ final Headers headers,
+ final String body) {
+ super(message, pd, uri, headers, body);
+ }
}
diff --git a/solid/src/main/java/com/inrupt/client/solid/ForbiddenException.java b/solid/src/main/java/com/inrupt/client/solid/ForbiddenException.java
index 7aeb3219bec..9fd94a4fb9e 100644
--- a/solid/src/main/java/com/inrupt/client/solid/ForbiddenException.java
+++ b/solid/src/main/java/com/inrupt/client/solid/ForbiddenException.java
@@ -21,6 +21,8 @@
package com.inrupt.client.solid;
import com.inrupt.client.Headers;
+import com.inrupt.client.HttpStatus;
+import com.inrupt.client.ProblemDetails;
import java.net.URI;
@@ -32,7 +34,7 @@
public class ForbiddenException extends SolidClientException {
private static final long serialVersionUID = 3299286274724874244L;
- public static final int STATUS_CODE = 403;
+ public static final int STATUS_CODE = HttpStatus.FORBIDDEN;
/**
* Create a ForbiddenException exception.
@@ -41,6 +43,7 @@ public class ForbiddenException extends SolidClientException {
* @param uri the uri
* @param headers the response headers
* @param body the body
+ * @deprecated
*/
public ForbiddenException(
final String message,
@@ -49,4 +52,22 @@ public ForbiddenException(
final String body) {
super(message, uri, STATUS_CODE, headers, body);
}
+
+ /**
+ * Create a ForbiddenException exception.
+ *
+ * @param message the message
+ * @param pd the ProblemDetails instance
+ * @param uri the uri
+ * @param headers the response headers
+ * @param body the body
+ */
+ public ForbiddenException(
+ final String message,
+ final ProblemDetails pd,
+ final URI uri,
+ final Headers headers,
+ final String body) {
+ super(message, pd, uri, headers, body);
+ }
}
diff --git a/solid/src/main/java/com/inrupt/client/solid/GoneException.java b/solid/src/main/java/com/inrupt/client/solid/GoneException.java
index 0882302e27b..511b5ca947a 100644
--- a/solid/src/main/java/com/inrupt/client/solid/GoneException.java
+++ b/solid/src/main/java/com/inrupt/client/solid/GoneException.java
@@ -21,6 +21,8 @@
package com.inrupt.client.solid;
import com.inrupt.client.Headers;
+import com.inrupt.client.HttpStatus;
+import com.inrupt.client.ProblemDetails;
import java.net.URI;
@@ -32,7 +34,7 @@
public class GoneException extends SolidClientException {
private static final long serialVersionUID = -6892345582498100242L;
- public static final int STATUS_CODE = 410;
+ public static final int STATUS_CODE = HttpStatus.GONE;
/**
* Create a GoneException exception.
@@ -41,6 +43,7 @@ public class GoneException extends SolidClientException {
* @param uri the uri
* @param headers the response headers
* @param body the body
+ * @deprecated
*/
public GoneException(
final String message,
@@ -49,4 +52,22 @@ public GoneException(
final String body) {
super(message, uri, STATUS_CODE, headers, body);
}
+
+ /**
+ * Create a GoneException exception.
+ *
+ * @param message the message
+ * @param pd the ProblemDetails instance
+ * @param uri the uri
+ * @param headers the response headers
+ * @param body the body
+ */
+ public GoneException(
+ final String message,
+ final ProblemDetails pd,
+ final URI uri,
+ final Headers headers,
+ final String body) {
+ super(message, pd, uri, headers, body);
+ }
}
diff --git a/solid/src/main/java/com/inrupt/client/solid/InternalServerErrorException.java b/solid/src/main/java/com/inrupt/client/solid/InternalServerErrorException.java
index ea9acb1c56e..43a216fd307 100644
--- a/solid/src/main/java/com/inrupt/client/solid/InternalServerErrorException.java
+++ b/solid/src/main/java/com/inrupt/client/solid/InternalServerErrorException.java
@@ -21,6 +21,8 @@
package com.inrupt.client.solid;
import com.inrupt.client.Headers;
+import com.inrupt.client.HttpStatus;
+import com.inrupt.client.ProblemDetails;
import java.net.URI;
@@ -32,7 +34,7 @@
public class InternalServerErrorException extends SolidClientException {
private static final long serialVersionUID = -6672490715281719330L;
- public static final int STATUS_CODE = 500;
+ public static final int STATUS_CODE = HttpStatus.INTERNAL_SERVER_ERROR;
/**
* Create an InternalServerErrorException exception.
@@ -41,6 +43,7 @@ public class InternalServerErrorException extends SolidClientException {
* @param uri the uri
* @param headers the response headers
* @param body the body
+ * @deprecated
*/
public InternalServerErrorException(
final String message,
@@ -49,4 +52,22 @@ public InternalServerErrorException(
final String body) {
super(message, uri, STATUS_CODE, headers, body);
}
+
+ /**
+ * Create an InternalServerErrorException exception.
+ *
+ * @param message the message
+ * @param pd the ProblemDetails instance
+ * @param uri the uri
+ * @param headers the response headers
+ * @param body the body
+ */
+ public InternalServerErrorException(
+ final String message,
+ final ProblemDetails pd,
+ final URI uri,
+ final Headers headers,
+ final String body) {
+ super(message, pd, uri, headers, body);
+ }
}
diff --git a/solid/src/main/java/com/inrupt/client/solid/MethodNotAllowedException.java b/solid/src/main/java/com/inrupt/client/solid/MethodNotAllowedException.java
index d472b5fcbd3..378e166b2a0 100644
--- a/solid/src/main/java/com/inrupt/client/solid/MethodNotAllowedException.java
+++ b/solid/src/main/java/com/inrupt/client/solid/MethodNotAllowedException.java
@@ -21,6 +21,8 @@
package com.inrupt.client.solid;
import com.inrupt.client.Headers;
+import com.inrupt.client.HttpStatus;
+import com.inrupt.client.ProblemDetails;
import java.net.URI;
@@ -32,7 +34,7 @@
public class MethodNotAllowedException extends SolidClientException {
private static final long serialVersionUID = -9125437562813923030L;
- public static final int STATUS_CODE = 405;
+ public static final int STATUS_CODE = HttpStatus.METHOD_NOT_ALLOWED;
/**
* Create a MethodNotAllowedException exception.
@@ -41,6 +43,7 @@ public class MethodNotAllowedException extends SolidClientException {
* @param uri the uri
* @param headers the response headers
* @param body the body
+ * @deprecated
*/
public MethodNotAllowedException(
final String message,
@@ -49,4 +52,22 @@ public MethodNotAllowedException(
final String body) {
super(message, uri, STATUS_CODE, headers, body);
}
+
+ /**
+ * Create a MethodNotAllowedException exception.
+ *
+ * @param message the message
+ * @param pd the ProblemDetails instance
+ * @param uri the uri
+ * @param headers the response headers
+ * @param body the body
+ */
+ public MethodNotAllowedException(
+ final String message,
+ final ProblemDetails pd,
+ final URI uri,
+ final Headers headers,
+ final String body) {
+ super(message, pd, uri, headers, body);
+ }
}
diff --git a/solid/src/main/java/com/inrupt/client/solid/NotAcceptableException.java b/solid/src/main/java/com/inrupt/client/solid/NotAcceptableException.java
index 53744c0b2e8..f1509073ef0 100644
--- a/solid/src/main/java/com/inrupt/client/solid/NotAcceptableException.java
+++ b/solid/src/main/java/com/inrupt/client/solid/NotAcceptableException.java
@@ -21,6 +21,8 @@
package com.inrupt.client.solid;
import com.inrupt.client.Headers;
+import com.inrupt.client.HttpStatus;
+import com.inrupt.client.ProblemDetails;
import java.net.URI;
@@ -32,7 +34,7 @@
public class NotAcceptableException extends SolidClientException {
private static final long serialVersionUID = 6594993822477388733L;
- public static final int STATUS_CODE = 406;
+ public static final int STATUS_CODE = HttpStatus.NOT_ACCEPTABLE;
/**
* Create a NotAcceptableException exception.
@@ -41,6 +43,7 @@ public class NotAcceptableException extends SolidClientException {
* @param uri the uri
* @param headers the response headers
* @param body the body
+ * @deprecated
*/
public NotAcceptableException(
final String message,
@@ -49,4 +52,22 @@ public NotAcceptableException(
final String body) {
super(message, uri, STATUS_CODE, headers, body);
}
+
+ /**
+ * Create a NotAcceptableException exception.
+ *
+ * @param message the message
+ * @param pd the ProblemDetails instance
+ * @param uri the uri
+ * @param headers the response headers
+ * @param body the body
+ */
+ public NotAcceptableException(
+ final String message,
+ final ProblemDetails pd,
+ final URI uri,
+ final Headers headers,
+ final String body) {
+ super(message, pd, uri, headers, body);
+ }
}
diff --git a/solid/src/main/java/com/inrupt/client/solid/NotFoundException.java b/solid/src/main/java/com/inrupt/client/solid/NotFoundException.java
index 466bed74894..71e4dc16361 100644
--- a/solid/src/main/java/com/inrupt/client/solid/NotFoundException.java
+++ b/solid/src/main/java/com/inrupt/client/solid/NotFoundException.java
@@ -21,6 +21,8 @@
package com.inrupt.client.solid;
import com.inrupt.client.Headers;
+import com.inrupt.client.HttpStatus;
+import com.inrupt.client.ProblemDetails;
import java.net.URI;
@@ -32,7 +34,7 @@
public class NotFoundException extends SolidClientException {
private static final long serialVersionUID = -2256628528500739683L;
- public static final int STATUS_CODE = 404;
+ public static final int STATUS_CODE = HttpStatus.NOT_FOUND;
/**
* Create a NotFoundException exception.
@@ -41,6 +43,7 @@ public class NotFoundException extends SolidClientException {
* @param uri the uri
* @param headers the response headers
* @param body the body
+ * @deprecated
*/
public NotFoundException(
final String message,
@@ -49,4 +52,22 @@ public NotFoundException(
final String body) {
super(message, uri, STATUS_CODE, headers, body);
}
+
+ /**
+ * Create a NotFoundException exception.
+ *
+ * @param message the message
+ * @param pd the ProblemDetails instance
+ * @param uri the uri
+ * @param headers the response headers
+ * @param body the body
+ */
+ public NotFoundException(
+ final String message,
+ final ProblemDetails pd,
+ final URI uri,
+ final Headers headers,
+ final String body) {
+ super(message, pd, uri, headers, body);
+ }
}
diff --git a/solid/src/main/java/com/inrupt/client/solid/PreconditionFailedException.java b/solid/src/main/java/com/inrupt/client/solid/PreconditionFailedException.java
index 461c937a0eb..4c1d30f0065 100644
--- a/solid/src/main/java/com/inrupt/client/solid/PreconditionFailedException.java
+++ b/solid/src/main/java/com/inrupt/client/solid/PreconditionFailedException.java
@@ -21,6 +21,8 @@
package com.inrupt.client.solid;
import com.inrupt.client.Headers;
+import com.inrupt.client.HttpStatus;
+import com.inrupt.client.ProblemDetails;
import java.net.URI;
@@ -32,7 +34,7 @@
public class PreconditionFailedException extends SolidClientException {
private static final long serialVersionUID = 4205761003697773528L;
- public static final int STATUS_CODE = 412;
+ public static final int STATUS_CODE = HttpStatus.PRECONDITION_FAILED;
/**
* Create a PreconditionFailedException exception.
@@ -41,6 +43,7 @@ public class PreconditionFailedException extends SolidClientException {
* @param uri the uri
* @param headers the response headers
* @param body the body
+ * @deprecated
*/
public PreconditionFailedException(
final String message,
@@ -49,4 +52,22 @@ public PreconditionFailedException(
final String body) {
super(message, uri, STATUS_CODE, headers, body);
}
+
+ /**
+ * Create a PreconditionFailedException exception.
+ *
+ * @param message the message
+ * @param pd the ProblemDetails instance
+ * @param uri the uri
+ * @param headers the response headers
+ * @param body the body
+ */
+ public PreconditionFailedException(
+ final String message,
+ final ProblemDetails pd,
+ final URI uri,
+ final Headers headers,
+ final String body) {
+ super(message, pd, uri, headers, body);
+ }
}
diff --git a/solid/src/main/java/com/inrupt/client/solid/SolidClientException.java b/solid/src/main/java/com/inrupt/client/solid/SolidClientException.java
index 668df265d3d..f6c67683626 100644
--- a/solid/src/main/java/com/inrupt/client/solid/SolidClientException.java
+++ b/solid/src/main/java/com/inrupt/client/solid/SolidClientException.java
@@ -20,15 +20,16 @@
*/
package com.inrupt.client.solid;
+import com.inrupt.client.ClientHttpException;
import com.inrupt.client.Headers;
-import com.inrupt.client.InruptClientException;
+import com.inrupt.client.ProblemDetails;
import java.net.URI;
/**
* A runtime exception for use with SolidClient HTTP operations.
*/
-public class SolidClientException extends InruptClientException {
+public class SolidClientException extends ClientHttpException {
private static final long serialVersionUID = 2868432164225689934L;
@@ -45,16 +46,31 @@ public class SolidClientException extends InruptClientException {
* @param statusCode the HTTP status code
* @param headers the response headers
* @param body the body
+ * @deprecated
*/
public SolidClientException(final String message, final URI uri, final int statusCode,
final Headers headers, final String body) {
- super(message);
+ super(null, message);
this.uri = uri;
this.statusCode = statusCode;
this.headers = headers;
this.body = body;
}
+ public SolidClientException(
+ final String message,
+ final ProblemDetails pd,
+ final URI uri,
+ final Headers headers,
+ final String body
+ ) {
+ super(pd, message);
+ this.uri = uri;
+ this.statusCode = pd.getStatus();
+ this.headers = headers;
+ this.body = body;
+ }
+
/**
* Retrieve the URI associated with this exception.
*
@@ -91,6 +107,16 @@ public String getBody() {
return body;
}
+ /**
+ *
+ * @param message the resulting exception message
+ * @param uri the request URL
+ * @param statusCode the response status code
+ * @param headers the response {@link Headers}
+ * @param body the response body
+ * @return an appropriate exception based on the status code.
+ * @deprecated
+ */
public static SolidClientException handle(
final String message,
final URI uri,
@@ -126,5 +152,51 @@ public static SolidClientException handle(
return new SolidClientException(message, uri, statusCode, headers, body);
}
}
+
+ /**
+ *
+ * @param message the resulting exception message
+ * @param pd the {@link ProblemDetails} instance
+ * @param uri the request URL
+ * @param headers the response {@link Headers}
+ * @param body the response body
+ * @return an appropriate exception based on the status code.
+ */
+ public static SolidClientException handle(
+ final String message,
+ final ProblemDetails pd,
+ final URI uri,
+ final Headers headers,
+ final String body
+ ) {
+ switch (pd.getStatus()) {
+ case BadRequestException.STATUS_CODE:
+ return new BadRequestException(message, pd, uri, headers, body);
+ case UnauthorizedException.STATUS_CODE:
+ return new UnauthorizedException(message, pd, uri, headers, body);
+ case ForbiddenException.STATUS_CODE:
+ return new ForbiddenException(message, pd, uri, headers, body);
+ case NotFoundException.STATUS_CODE:
+ return new NotFoundException(message, pd, uri, headers, body);
+ case MethodNotAllowedException.STATUS_CODE:
+ return new MethodNotAllowedException(message, pd, uri, headers, body);
+ case NotAcceptableException.STATUS_CODE:
+ return new NotAcceptableException(message, pd, uri, headers, body);
+ case ConflictException.STATUS_CODE:
+ return new ConflictException(message, pd, uri, headers, body);
+ case GoneException.STATUS_CODE:
+ return new GoneException(message, pd, uri, headers, body);
+ case PreconditionFailedException.STATUS_CODE:
+ return new PreconditionFailedException(message, pd, uri, headers, body);
+ case UnsupportedMediaTypeException.STATUS_CODE:
+ return new UnsupportedMediaTypeException(message, pd, uri, headers, body);
+ case TooManyRequestsException.STATUS_CODE:
+ return new TooManyRequestsException(message, pd, uri, headers, body);
+ case InternalServerErrorException.STATUS_CODE:
+ return new InternalServerErrorException(message, pd, uri, headers, body);
+ default:
+ return new SolidClientException(message, pd, uri, headers, body);
+ }
+ }
}
diff --git a/solid/src/main/java/com/inrupt/client/solid/TooManyRequestsException.java b/solid/src/main/java/com/inrupt/client/solid/TooManyRequestsException.java
index 4f299fc9492..d05b2f255fd 100644
--- a/solid/src/main/java/com/inrupt/client/solid/TooManyRequestsException.java
+++ b/solid/src/main/java/com/inrupt/client/solid/TooManyRequestsException.java
@@ -21,6 +21,8 @@
package com.inrupt.client.solid;
import com.inrupt.client.Headers;
+import com.inrupt.client.HttpStatus;
+import com.inrupt.client.ProblemDetails;
import java.net.URI;
@@ -32,7 +34,7 @@
public class TooManyRequestsException extends SolidClientException {
private static final long serialVersionUID = -1798491190232642824L;
- public static final int STATUS_CODE = 429;
+ public static final int STATUS_CODE = HttpStatus.TOO_MANY_REQUESTS;
/**
* Create a TooManyRequestsException exception.
@@ -41,6 +43,7 @@ public class TooManyRequestsException extends SolidClientException {
* @param uri the uri
* @param headers the response headers
* @param body the body
+ * @deprecated
*/
public TooManyRequestsException(
final String message,
@@ -49,4 +52,22 @@ public TooManyRequestsException(
final String body) {
super(message, uri, STATUS_CODE, headers, body);
}
+
+ /**
+ * Create a TooManyRequestsException exception.
+ *
+ * @param message the message
+ * @param pd the ProblemDetails instance
+ * @param uri the uri
+ * @param headers the response headers
+ * @param body the body
+ */
+ public TooManyRequestsException(
+ final String message,
+ final ProblemDetails pd,
+ final URI uri,
+ final Headers headers,
+ final String body) {
+ super(message, pd, uri, headers, body);
+ }
}
diff --git a/solid/src/main/java/com/inrupt/client/solid/UnauthorizedException.java b/solid/src/main/java/com/inrupt/client/solid/UnauthorizedException.java
index db8615df958..e9d2d98571d 100644
--- a/solid/src/main/java/com/inrupt/client/solid/UnauthorizedException.java
+++ b/solid/src/main/java/com/inrupt/client/solid/UnauthorizedException.java
@@ -21,6 +21,8 @@
package com.inrupt.client.solid;
import com.inrupt.client.Headers;
+import com.inrupt.client.HttpStatus;
+import com.inrupt.client.ProblemDetails;
import java.net.URI;
@@ -32,7 +34,7 @@
public class UnauthorizedException extends SolidClientException {
private static final long serialVersionUID = -3219668517323678497L;
- public static final int STATUS_CODE = 401;
+ public static final int STATUS_CODE = HttpStatus.UNAUTHORIZED;
/**
* Create an UnauthorizedException exception.
@@ -41,6 +43,7 @@ public class UnauthorizedException extends SolidClientException {
* @param uri the uri
* @param headers the response headers
* @param body the body
+ * @deprecated
*/
public UnauthorizedException(
final String message,
@@ -49,4 +52,22 @@ public UnauthorizedException(
final String body) {
super(message, uri, STATUS_CODE, headers, body);
}
+
+ /**
+ * Create a UnauthorizedException exception.
+ *
+ * @param message the message
+ * @param pd the ProblemDetails instance
+ * @param uri the uri
+ * @param headers the response headers
+ * @param body the body
+ */
+ public UnauthorizedException(
+ final String message,
+ final ProblemDetails pd,
+ final URI uri,
+ final Headers headers,
+ final String body) {
+ super(message, pd, uri, headers, body);
+ }
}
diff --git a/solid/src/main/java/com/inrupt/client/solid/UnsupportedMediaTypeException.java b/solid/src/main/java/com/inrupt/client/solid/UnsupportedMediaTypeException.java
index 27e9c96953d..4d90c434efc 100644
--- a/solid/src/main/java/com/inrupt/client/solid/UnsupportedMediaTypeException.java
+++ b/solid/src/main/java/com/inrupt/client/solid/UnsupportedMediaTypeException.java
@@ -21,6 +21,8 @@
package com.inrupt.client.solid;
import com.inrupt.client.Headers;
+import com.inrupt.client.HttpStatus;
+import com.inrupt.client.ProblemDetails;
import java.net.URI;
@@ -32,7 +34,7 @@
public class UnsupportedMediaTypeException extends SolidClientException {
private static final long serialVersionUID = 1312856145838280673L;
- public static final int STATUS_CODE = 415;
+ public static final int STATUS_CODE = HttpStatus.UNSUPPORTED_MEDIA_TYPE;
/**
* Create an UnsupportedMediaTypeException exception.
@@ -41,6 +43,7 @@ public class UnsupportedMediaTypeException extends SolidClientException {
* @param uri the uri
* @param headers the response headers
* @param body the body
+ * @deprecated
*/
public UnsupportedMediaTypeException(
final String message,
@@ -49,4 +52,22 @@ public UnsupportedMediaTypeException(
final String body) {
super(message, uri, STATUS_CODE, headers, body);
}
+
+ /**
+ * Create a UnsupportedMediaTypeException exception.
+ *
+ * @param message the message
+ * @param pd the ProblemDetails instance
+ * @param uri the uri
+ * @param headers the response headers
+ * @param body the body
+ */
+ public UnsupportedMediaTypeException(
+ final String message,
+ final ProblemDetails pd,
+ final URI uri,
+ final Headers headers,
+ final String body) {
+ super(message, pd, uri, headers, body);
+ }
}
diff --git a/solid/src/test/java/com/inrupt/client/solid/ProblemDetailsTest.java b/solid/src/test/java/com/inrupt/client/solid/ProblemDetailsTest.java
new file mode 100644
index 00000000000..2cd6f500a86
--- /dev/null
+++ b/solid/src/test/java/com/inrupt/client/solid/ProblemDetailsTest.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright Inrupt Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+ * Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+package com.inrupt.client.solid;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+import com.inrupt.client.Headers;
+import com.inrupt.client.ProblemDetails;
+import com.inrupt.client.spi.JsonService;
+import com.inrupt.client.spi.ServiceProvider;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+// Ideally, this class should be in the api module,
+// but it creates a circular dependency with the JSON module implementation.
+public class ProblemDetailsTest {
+ Headers mockProblemDetailsHeader() {
+ final List headerValues = new ArrayList<>();
+ headerValues.add("application/problem+json");
+ final Map> headerMap = new HashMap<>();
+ headerMap.put("Content-Type", headerValues);
+ return Headers.of(headerMap);
+ }
+
+ final JsonService jsonService = ServiceProvider.getJsonService();
+ @Test
+ void testEmptyProblemDetails() {
+ final int statusCode = 400;
+ final ProblemDetails pd = ProblemDetails.fromErrorResponse(
+ statusCode,
+ mockProblemDetailsHeader(),
+ "{}".getBytes(),
+ jsonService
+ );
+ assertEquals(ProblemDetails.DEFAULT_TYPE, pd.getType().toString());
+ assertEquals(statusCode, pd.getStatus());
+ Assertions.assertEquals("Bad Request", pd.getTitle());
+ assertNull(pd.getDetails());
+ assertNull(pd.getInstance());
+ }
+ @Test
+ void testCompleteProblemDetails() {
+ final int statusCode = 400;
+ final ProblemDetails pd = ProblemDetails.fromErrorResponse(
+ statusCode,
+ mockProblemDetailsHeader(),
+ ("{" +
+ "\"title\":\"Some title\"," +
+ "\"status\":400," +
+ "\"details\":\"Some details\"," +
+ "\"instance\":\"https://example.org/instance\"," +
+ "\"type\":\"https://example.org/type\"" +
+ "}").getBytes(),
+ jsonService
+ );
+ assertEquals("https://example.org/type", pd.getType().toString());
+ assertEquals(statusCode, pd.getStatus());
+ Assertions.assertEquals("Some title", pd.getTitle());
+ assertEquals("Some details", pd.getDetails());
+ assertEquals("https://example.org/instance", pd.getInstance().toString());
+ }
+
+ @Test
+ void testIgnoreUnknownProblemDetails() {
+ final int statusCode = 400;
+ final ProblemDetails pd = ProblemDetails.fromErrorResponse(
+ statusCode,
+ mockProblemDetailsHeader(),
+ ("{" +
+ "\"title\":\"Some title\"," +
+ "\"status\":400," +
+ "\"details\":\"Some details\"," +
+ "\"instance\":\"https://example.org/instance\"," +
+ "\"type\":\"https://example.org/type\"," +
+ "\"unknown\":\"Some unknown property\"" +
+ "}").getBytes(),
+ jsonService
+ );
+ assertEquals("https://example.org/type", pd.getType().toString());
+ assertEquals(statusCode, pd.getStatus());
+ Assertions.assertEquals("Some title", pd.getTitle());
+ assertEquals("Some details", pd.getDetails());
+ assertEquals("https://example.org/instance", pd.getInstance().toString());
+ }
+
+ @Test
+ void testInvalidStatusProblemDetails() {
+ final int statusCode = 400;
+ final ProblemDetails pd = ProblemDetails.fromErrorResponse(
+ statusCode,
+ mockProblemDetailsHeader(),
+ ("{" +
+ "\"status\":\"Some invalid status\"," +
+ "}").getBytes(),
+ jsonService
+ );
+ assertEquals(statusCode, pd.getStatus());
+ }
+
+ @Test
+ void testMismatchingStatusProblemDetails() {
+ final int statusCode = 400;
+ final ProblemDetails pd = ProblemDetails.fromErrorResponse(
+ statusCode,
+ mockProblemDetailsHeader(),
+ ("{" +
+ "\"status\":500," +
+ "}").getBytes(),
+ jsonService
+ );
+ assertEquals(statusCode, pd.getStatus());
+ }
+
+ @Test
+ void testInvalidTypeProblemDetails() {
+ final ProblemDetails pd = ProblemDetails.fromErrorResponse(
+ 400,
+ mockProblemDetailsHeader(),
+ ("{" +
+ "\"type\":\"Some invalid type\"," +
+ "}").getBytes(),
+ jsonService
+ );
+ assertEquals(ProblemDetails.DEFAULT_TYPE, pd.getType().toString());
+ }
+
+ @Test
+ void testInvalidInstanceProblemDetails() {
+ final ProblemDetails pd = ProblemDetails.fromErrorResponse(
+ 400,
+ mockProblemDetailsHeader(),
+ ("{" +
+ "\"instance\":\"Some invalid instance\"," +
+ "}").getBytes(),
+ jsonService
+ );
+ assertNull(pd.getInstance());
+ }
+}
diff --git a/solid/src/test/java/com/inrupt/client/solid/SolidExceptionTest.java b/solid/src/test/java/com/inrupt/client/solid/SolidExceptionTest.java
index 15220345d68..bfab701eb77 100644
--- a/solid/src/test/java/com/inrupt/client/solid/SolidExceptionTest.java
+++ b/solid/src/test/java/com/inrupt/client/solid/SolidExceptionTest.java
@@ -22,6 +22,10 @@
import static org.junit.jupiter.api.Assertions.*;
+import com.inrupt.client.ProblemDetails;
+
+import java.net.URI;
+
import org.junit.jupiter.api.Test;
class SolidExceptionTest {
@@ -41,4 +45,21 @@ void checkSolidWrappedException() {
assertEquals(upstream, err.getCause());
assertEquals(msg, err.getMessage());
}
+
+ @Test
+ void checkSolidClientException() {
+ final String msg = "Error";
+ final ProblemDetails pd = new ProblemDetails(
+ URI.create("https://example.org/problem"),
+ "Some title",
+ "Some details",
+ 123,
+ URI.create("https://example.org/instance")
+ );
+ final SolidClientException err = new SolidClientException(
+ msg, pd, URI.create("https://example.org/request"), null, "some body"
+ );
+ assertEquals(msg, err.getMessage());
+ assertEquals(pd, err.getProblemDetails());
+ }
}
diff --git a/test/src/main/java/com/inrupt/client/test/RdfMockService.java b/test/src/main/java/com/inrupt/client/test/RdfMockService.java
index 768a2ba1aec..619814b1f16 100644
--- a/test/src/main/java/com/inrupt/client/test/RdfMockService.java
+++ b/test/src/main/java/com/inrupt/client/test/RdfMockService.java
@@ -24,6 +24,7 @@
import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
+import com.inrupt.client.ProblemDetails;
import java.util.Collections;
import java.util.Map;
@@ -44,35 +45,48 @@ public int getPort() {
return wireMockServer.port();
}
+ private static final String CONTENT_TYPE = "Content-Type";
+
private void setupMocks() {
wireMockServer.stubFor(get(urlEqualTo("/oneTriple"))
.willReturn(aResponse()
.withStatus(200)
- .withHeader("Content-Type", "text/turtle")
+ .withHeader(CONTENT_TYPE, "text/turtle")
.withBody(" .")));
wireMockServer.stubFor(post(urlEqualTo("/postOneTriple"))
.withRequestBody(matching(
".*\\s+" +
"\\s+\"object\"\\s+\\..*"))
- .withHeader("Content-Type", containing("text/turtle"))
+ .withHeader(CONTENT_TYPE, containing("text/turtle"))
.willReturn(aResponse()
.withStatus(204)));
wireMockServer.stubFor(get(urlEqualTo("/example"))
.willReturn(aResponse()
.withStatus(200)
- .withHeader("Content-Type", "text/turtle")
+ .withHeader(CONTENT_TYPE, "text/turtle")
.withBody(getExampleTTL())));
wireMockServer.stubFor(patch(urlEqualTo("/sparqlUpdate"))
- .withHeader("Content-Type", containing("application/sparql-update"))
+ .withHeader(CONTENT_TYPE, containing("application/sparql-update"))
.withRequestBody(matching(
"INSERT DATA\\s+\\{\\s*\\s+" +
"\\s+\\s*\\.\\s*\\}\\s*"))
.willReturn(aResponse()
.withStatus(204)));
+
+ wireMockServer.stubFor(get(urlEqualTo("/error"))
+ .willReturn(aResponse()
+ .withStatus(429)
+ .withHeader(CONTENT_TYPE, ProblemDetails.MIME_TYPE)
+ .withBody("{" +
+ "\"title\":\"Too Many Requests\"," +
+ "\"status\":429," +
+ "\"details\":\"Some details\"," +
+ "\"instance\":\"https://example.org/instance\"," +
+ "\"type\":\"https://example.org/type\"}")));
}
private String getExampleTTL() {