Skip to content

Commit

Permalink
Revert "JCL-402: HTTP error handling in JenaBodyHandlers (#1159)"
Browse files Browse the repository at this point in the history
This reverts commit 89534b4.
  • Loading branch information
acoburn committed May 8, 2024
1 parent 83c6046 commit 2517f63
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 195 deletions.
6 changes: 0 additions & 6 deletions jena/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,6 @@
<version>${slf4j.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.inrupt.client</groupId>
<artifactId>inrupt-client-jackson</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.wiremock</groupId>
<artifactId>wiremock</artifactId>
Expand Down
109 changes: 22 additions & 87 deletions jena/src/main/java/com/inrupt/client/jena/JenaBodyHandlers.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,11 @@
*/
package com.inrupt.client.jena;

import com.inrupt.client.ClientHttpException;
import com.inrupt.client.Response;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;

import org.apache.jena.atlas.web.ContentType;
import org.apache.jena.graph.Graph;
Expand All @@ -46,20 +44,13 @@ public final class JenaBodyHandlers {

private static final String CONTENT_TYPE = "Content-Type";

private static void throwOnError(final Response.ResponseInfo responseInfo) {
if (!Response.isSuccess(responseInfo.statusCode())) {
throw new ClientHttpException(
"Could not map to a Jena entity.",
responseInfo.uri(),
responseInfo.statusCode(),
responseInfo.headers(),
new String(responseInfo.body().array(), StandardCharsets.UTF_8)
);
}
}

private static Model responseToModel(final Response.ResponseInfo responseInfo) {
return responseInfo.headers().firstValue(CONTENT_TYPE)
/**
* Populate a Jena {@link Model} with an HTTP response body.
*
* @return an HTTP body handler
*/
public static Response.BodyHandler<Model> ofModel() {
return responseInfo -> responseInfo.headers().firstValue(CONTENT_TYPE)
.map(JenaBodyHandlers::toJenaLang).map(lang -> {
try (final var input = new ByteArrayInputStream(responseInfo.body().array())) {
final var model = ModelFactory.createDefaultModel();
Expand All @@ -74,29 +65,12 @@ private static Model responseToModel(final Response.ResponseInfo responseInfo) {
}

/**
* Populate a Jena {@link Model} with an HTTP response body.
*
* @return an HTTP body handler
* @deprecated Use {@link JenaBodyHandlers#ofJenaModel()} instead for consistent HTTP error handling.
*/
public static Response.BodyHandler<Model> ofModel() {
return JenaBodyHandlers::responseToModel;
}

/**
* Populate a Jena {@link Model} with an HTTP response body.
* Populate a Jena {@link Graph} with an HTTP response.
*
* @return an HTTP body handler
*/
public static Response.BodyHandler<Model> ofJenaModel() {
return responseInfo -> {
JenaBodyHandlers.throwOnError(responseInfo);
return JenaBodyHandlers.responseToModel(responseInfo);
};
}

private static Graph responseToGraph(final Response.ResponseInfo responseInfo) {
return responseInfo.headers().firstValue(CONTENT_TYPE)
public static Response.BodyHandler<Graph> ofGraph() {
return responseInfo -> responseInfo.headers().firstValue(CONTENT_TYPE)
.map(JenaBodyHandlers::toJenaLang).map(lang -> {
try (final var input = new ByteArrayInputStream(responseInfo.body().array())) {
final var graph = GraphMemFactory.createDefaultGraph();
Expand All @@ -110,63 +84,24 @@ private static Graph responseToGraph(final Response.ResponseInfo responseInfo) {
.orElseGet(GraphMemFactory::createDefaultGraph);
}

/**
* Populate a Jena {@link Graph} with an HTTP response.
*
* @return an HTTP body handler
* @deprecated Use {@link JenaBodyHandlers#ofJenaGraph} instead for consistent HTTP error handling.
*/
public static Response.BodyHandler<Graph> ofGraph() {
return JenaBodyHandlers::responseToGraph;
}

/**
* Populate a Jena {@link Graph} with an HTTP response.
*
* @return an HTTP body handler
*/
public static Response.BodyHandler<Graph> ofJenaGraph() {
return responseInfo -> {
JenaBodyHandlers.throwOnError(responseInfo);
return JenaBodyHandlers.responseToGraph(responseInfo);
};
}

private static Dataset responseToDataset(final Response.ResponseInfo responseInfo) {
return responseInfo.headers().firstValue(CONTENT_TYPE)
.map(JenaBodyHandlers::toJenaLang).map(lang -> {
try (final var input = new ByteArrayInputStream(responseInfo.body().array())) {
final var dataset = DatasetFactory.create();
RDFDataMgr.read(dataset, input, responseInfo.uri().toString(), lang);
return dataset;
} catch (final IOException ex) {
throw new UncheckedIOException(
"An I/O error occurred while data was read from the InputStream into a Dataset", ex);
}
})
.orElseGet(DatasetFactory::create);
}

/**
* Populate a Jena {@link Dataset} with an HTTP response.
*
* @return an HTTP body handler
* @deprecated Use {@link JenaBodyHandlers#ofJenaDataset} instead for consistent HTTP error handling.
*/
public static Response.BodyHandler<Dataset> ofDataset() {
return JenaBodyHandlers::responseToDataset;
}

/**
* Populate a Jena {@link Dataset} with an HTTP response.
*
* @return an HTTP body handler
*/
public static Response.BodyHandler<Dataset> ofJenaDataset() {
return responseInfo -> {
JenaBodyHandlers.throwOnError(responseInfo);
return JenaBodyHandlers.responseToDataset(responseInfo);
};
return responseInfo -> responseInfo.headers().firstValue(CONTENT_TYPE)
.map(JenaBodyHandlers::toJenaLang).map(lang -> {
try (final var input = new ByteArrayInputStream(responseInfo.body().array())) {
final var dataset = DatasetFactory.create();
RDFDataMgr.read(dataset, input, responseInfo.uri().toString(), lang);
return dataset;
} catch (final IOException ex) {
throw new UncheckedIOException(
"An I/O error occurred while data was read from the InputStream into a Dataset", ex);
}
})
.orElseGet(DatasetFactory::create);
}

static Lang toJenaLang(final String mediaType) {
Expand Down
100 changes: 16 additions & 84 deletions jena/src/test/java/com/inrupt/client/jena/JenaBodyHandlersTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

import static org.junit.jupiter.api.Assertions.*;

import com.inrupt.client.ClientHttpException;
import com.inrupt.client.Request;
import com.inrupt.client.Response;
import com.inrupt.client.spi.HttpService;
Expand All @@ -33,7 +32,6 @@
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutionException;

import org.apache.jena.graph.NodeFactory;
Expand All @@ -59,14 +57,14 @@ static void teardown() {
}

@Test
void testOfJenaModelHandler() throws IOException,
void testOfModelHandler() throws IOException,
InterruptedException {
final Request request = Request.newBuilder()
.uri(URI.create(config.get("rdf_uri") + "/oneTriple"))
.GET()
.build();

final var response = client.send(request, JenaBodyHandlers.ofJenaModel())
final var response = client.send(request, JenaBodyHandlers.ofModel())
.toCompletableFuture().join();

assertEquals(200, response.statusCode());
Expand All @@ -80,15 +78,15 @@ void testOfJenaModelHandler() throws IOException,
}

@Test
void testOfJenaModelHandlerAsync() throws IOException,
void testOfModelHandlerAsync() throws IOException,
InterruptedException, ExecutionException {
final Request request = Request.newBuilder()
.uri(URI.create(config.get("rdf_uri") + "/oneTriple"))
.header("Accept", "text/turtle")
.GET()
.build();

final var asyncResponse = client.send(request, JenaBodyHandlers.ofJenaModel());
final var asyncResponse = client.send(request, JenaBodyHandlers.ofModel());

final int statusCode = asyncResponse.thenApply(Response::statusCode).toCompletableFuture().join();
assertEquals(200, statusCode);
Expand All @@ -103,13 +101,13 @@ void testOfJenaModelHandlerAsync() throws IOException,
}

@Test
void testOfJenaModelHandlerWithURL() throws IOException, InterruptedException {
void testOfModelHandlerWithURL() throws IOException, InterruptedException {
final Request request = Request.newBuilder()
.uri(URI.create(config.get("rdf_uri") + "/example"))
.GET()
.build();

final var response = client.send(request, JenaBodyHandlers.ofJenaModel())
final var response = client.send(request, JenaBodyHandlers.ofModel())
.toCompletableFuture().join();

assertEquals(200, response.statusCode());
Expand All @@ -122,36 +120,14 @@ void testOfJenaModelHandlerWithURL() throws IOException, InterruptedException {
}

@Test
void testOfJenaModelHandlerError() throws IOException,
InterruptedException {
final Request request = Request.newBuilder()
.uri(URI.create(config.get("rdf_uri") + "/error"))
.GET()
.build();

final CompletionException completionException = assertThrows(
CompletionException.class,
() -> client.send(request, JenaBodyHandlers.ofJenaModel()).toCompletableFuture().join()
);

final ClientHttpException httpException = (ClientHttpException) completionException.getCause();

assertEquals(429, httpException.getProblemDetails().getStatus());
assertEquals("Too Many Requests", httpException.getProblemDetails().getTitle());
assertEquals("Some details", httpException.getProblemDetails().getDetails());
assertEquals("https://example.org/type", httpException.getProblemDetails().getType().toString());
assertEquals("https://example.org/instance", httpException.getProblemDetails().getInstance().toString());
}

@Test
void testOfJenaDatasetHandler() throws IOException,
void testOfDatasetHandler() throws IOException,
InterruptedException {
final Request request = Request.newBuilder()
.uri(URI.create(config.get("rdf_uri") + "/oneTriple"))
.GET()
.build();

final var response = client.send(request, JenaBodyHandlers.ofJenaDataset())
final var response = client.send(request, JenaBodyHandlers.ofDataset())
.toCompletableFuture().join();

assertEquals(200, response.statusCode());
Expand All @@ -166,13 +142,13 @@ void testOfJenaDatasetHandler() throws IOException,
}

@Test
void testOfJenaDatasetHandlerWithURL() throws IOException, InterruptedException {
void testOfDatasetHandlerWithURL() throws IOException, InterruptedException {
final Request request = Request.newBuilder()
.uri(URI.create(config.get("rdf_uri") + "/example"))
.GET()
.build();

final var response = client.send(request, JenaBodyHandlers.ofJenaDataset())
final var response = client.send(request, JenaBodyHandlers.ofDataset())
.toCompletableFuture().join();

assertEquals(200, response.statusCode());
Expand All @@ -187,37 +163,15 @@ void testOfJenaDatasetHandlerWithURL() throws IOException, InterruptedException
}

@Test
void testOfJenaDatasetHandlerError() throws IOException,
InterruptedException {
final Request request = Request.newBuilder()
.uri(URI.create(config.get("rdf_uri") + "/error"))
.GET()
.build();

final CompletionException completionException = assertThrows(
CompletionException.class,
() -> client.send(request, JenaBodyHandlers.ofJenaDataset()).toCompletableFuture().join()
);

final ClientHttpException httpException = (ClientHttpException) completionException.getCause();

assertEquals(429, httpException.getProblemDetails().getStatus());
assertEquals("Too Many Requests", httpException.getProblemDetails().getTitle());
assertEquals("Some details", httpException.getProblemDetails().getDetails());
assertEquals("https://example.org/type", httpException.getProblemDetails().getType().toString());
assertEquals("https://example.org/instance", httpException.getProblemDetails().getInstance().toString());
}

@Test
void testOfJenaGraphHandlerAsync() throws IOException,
void testOfGraphHandlerAsync() throws IOException,
InterruptedException, ExecutionException {
final Request request = Request.newBuilder()
.uri(URI.create(config.get("rdf_uri") + "/oneTriple"))
.header("Accept", "text/turtle")
.GET()
.build();

final var asyncResponse = client.send(request, JenaBodyHandlers.ofJenaGraph());
final var asyncResponse = client.send(request, JenaBodyHandlers.ofGraph());

final int statusCode = asyncResponse.thenApply(Response::statusCode).toCompletableFuture().join();
assertEquals(200, statusCode);
Expand All @@ -232,14 +186,14 @@ void testOfJenaGraphHandlerAsync() throws IOException,
}

@Test
void testOfJenaGraphHandler() throws IOException,
void testOfGraphHandler() throws IOException,
InterruptedException {
final Request request = Request.newBuilder()
.uri(URI.create(config.get("rdf_uri") + "/oneTriple"))
.GET()
.build();

final var response = client.send(request, JenaBodyHandlers.ofJenaGraph())
final var response = client.send(request, JenaBodyHandlers.ofGraph())
.toCompletableFuture().join();

assertEquals(200, response.statusCode());
Expand All @@ -253,13 +207,13 @@ void testOfJenaGraphHandler() throws IOException,
}

@Test
void testOfJenaGraphHandlerWithURL() throws IOException, InterruptedException {
void testOfGraphHandlerWithURL() throws IOException, InterruptedException {
final Request request = Request.newBuilder()
.uri(URI.create(config.get("rdf_uri") + "/example"))
.GET()
.build();

final var response = client.send(request, JenaBodyHandlers.ofJenaGraph())
final var response = client.send(request, JenaBodyHandlers.ofGraph())
.toCompletableFuture().join();

assertEquals(200, response.statusCode());
Expand All @@ -271,26 +225,4 @@ void testOfJenaGraphHandlerWithURL() throws IOException, InterruptedException {
null)
);
}

@Test
void testOfJenaGraphHandlerError() throws IOException,
InterruptedException {
final Request request = Request.newBuilder()
.uri(URI.create(config.get("rdf_uri") + "/error"))
.GET()
.build();

final CompletionException completionException = assertThrows(
CompletionException.class,
() -> client.send(request, JenaBodyHandlers.ofJenaGraph()).toCompletableFuture().join()
);

final ClientHttpException httpException = (ClientHttpException) completionException.getCause();

assertEquals(429, httpException.getProblemDetails().getStatus());
assertEquals("Too Many Requests", httpException.getProblemDetails().getTitle());
assertEquals("Some details", httpException.getProblemDetails().getDetails());
assertEquals("https://example.org/type", httpException.getProblemDetails().getType().toString());
assertEquals("https://example.org/instance", httpException.getProblemDetails().getInstance().toString());
}
}
Loading

0 comments on commit 2517f63

Please sign in to comment.