This is an automated email from the ASF dual-hosted git repository.
arnebdt pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/jena.git
The following commit(s) were added to refs/heads/main by this push:
new 37dcaffe23 GH-2756: Lazy initialization of HttpClient in RDFParser -
when no custom HttpClient is provided by RDFParserBuilder
37dcaffe23 is described below
commit 37dcaffe23c0101a1ece85a5ec29be9beb41f1ea
Author: arne-bdt <[email protected]>
AuthorDate: Fri Oct 4 09:03:52 2024 +0200
GH-2756: Lazy initialization of HttpClient in RDFParser - when no custom
HttpClient is provided by RDFParserBuilder
- made org.apache.jena.riot.RDFParserBuilder#httpHeader available again by
uncommenting it
- moved initalization of httpClient with HttpEnv.getDftHttpClient() from
org.apache.jena.riot.RDFParserBuilder#build
to org.apache.jena.riot.RDFParser#openTypedInputStream in the case when
the RDFParserBuilder has not been initialized
with a custom httpClient. That way, it HttpEnv is not necessarily
initialized when reading files but only when needed.
- added org.apache.jena.http.TestHttpRDFParserBuilder
---
.../main/java/org/apache/jena/riot/RDFParser.java | 7 +-
.../org/apache/jena/riot/RDFParserBuilder.java | 22 ++---
.../apache/jena/http/TestHttpRDFParserBuilder.java | 100 +++++++++++++++++++++
3 files changed, 116 insertions(+), 13 deletions(-)
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/RDFParser.java
b/jena-arq/src/main/java/org/apache/jena/riot/RDFParser.java
index f9e04c747c..cb446647ac 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/RDFParser.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/RDFParser.java
@@ -39,6 +39,7 @@ import org.apache.jena.atlas.lib.InternalErrorException;
import org.apache.jena.atlas.web.ContentType;
import org.apache.jena.atlas.web.TypedInputStream;
import org.apache.jena.graph.Graph;
+import org.apache.jena.http.HttpEnv;
import org.apache.jena.http.HttpLib;
import org.apache.jena.irix.IRIs;
import org.apache.jena.irix.IRIxResolver;
@@ -95,7 +96,7 @@ public class RDFParser {
// Accept choice by the application
private final String appAcceptHeader;
private final Map<String, String> httpHeaders;
- private final HttpClient httpClient;
+ private final HttpClient httpClient; // The httpClient might be
provided by the RDFParserBuilder, but it might also be null
private final Lang hintLang;
private final Lang forceLang;
private final String baseURI;
@@ -484,7 +485,9 @@ public class RDFParser {
httpHeaders.forEach(b::header);
b.setHeader(HttpNames.hAccept, acceptHeader);
});
- HttpResponse<InputStream> response = HttpLib.execute(httpClient,
request);
+ // Setup of the HTTP client, if not provided by RDFParserBuilder
+ final var httpClientToUse = ( httpClient != null ) ? httpClient :
HttpEnv.getDftHttpClient();
+ HttpResponse<InputStream> response =
HttpLib.execute(httpClientToUse, request);
in = HttpLib.handleResponseTypedInputStream(response);
} else {
// Already mapped.
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/RDFParserBuilder.java
b/jena-arq/src/main/java/org/apache/jena/riot/RDFParserBuilder.java
index 99c39cadfd..d9bdf77d0a 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/RDFParserBuilder.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/RDFParserBuilder.java
@@ -29,7 +29,6 @@ import java.util.Optional;
import org.apache.jena.atlas.lib.IRILib;
import org.apache.jena.graph.Graph;
-import org.apache.jena.http.HttpEnv;
import org.apache.jena.irix.IRIs;
import org.apache.jena.irix.IRIxResolver;
import org.apache.jena.query.Dataset;
@@ -278,13 +277,16 @@ public class RDFParserBuilder {
return this;
}
-// /** Set the HttpClient to use.
-// * This will override any HTTP header settings set for this builder.
-// */
-// public RDFParserBuilder httpClient(HttpClient httpClient) {
-// this.httpClient = httpClient;
-// return this;
-// }
+ /**
+ * Set an HTTP client. Any previous setting is lost.
+ * <p>
+ * Consider setting up an {@link HttpClient} if more complicated
+ * setting to an HTTP request is required.
+ */
+ public RDFParserBuilder httpClient(HttpClient httpClient) {
+ this.httpClient = httpClient;
+ return this;
+ }
/** Set the base URI for parsing. The default is to have no base URI. */
public RDFParserBuilder base(String base) { this.baseURI = base ; return
this; }
@@ -647,8 +649,6 @@ public class RDFParserBuilder {
throw new RiotException("No source specified");
Context context = contextAcc.context();
- // Setup the HTTP client.
- HttpClient clientJDK = ( httpClient != null ) ? httpClient :
HttpEnv.getDftHttpClient();
FactoryRDF factory$ = buildFactoryRDF();
ErrorHandler errorHandler$ = errorHandler;
if ( errorHandler$ == null )
@@ -676,7 +676,7 @@ public class RDFParserBuilder {
// Can't build the profile here as it is Lang/conneg dependent.
return new RDFParser(uri, path, stringToParse, inputStream,
javaReader, sMgr,
appAcceptHeader, httpHeaders,
- clientJDK,
+ httpClient,
hintLang, forceLang,
parserBaseURI, strict, checking,
canonicalValues, langTagForm,
diff --git
a/jena-integration-tests/src/test/java/org/apache/jena/http/TestHttpRDFParserBuilder.java
b/jena-integration-tests/src/test/java/org/apache/jena/http/TestHttpRDFParserBuilder.java
new file mode 100644
index 0000000000..583ea03c42
--- /dev/null
+++
b/jena-integration-tests/src/test/java/org/apache/jena/http/TestHttpRDFParserBuilder.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.jena.http;
+
+import org.apache.jena.graph.Graph;
+import org.apache.jena.riot.RDFParserBuilder;
+import org.apache.jena.sparql.graph.GraphFactory;
+import org.apache.jena.sparql.sse.SSE;
+import org.apache.jena.test.conn.EnvTest;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.net.*;
+import java.net.http.HttpClient;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+public class TestHttpRDFParserBuilder {
+ // The HttpRDF machinery (much of which is package visible) get tested by
other
+ // subsystems built on top of HttpRDF. This test suite is for the public
API.
+ private static EnvTest env;
+ @BeforeClass public static void beforeClass() {
+ env = EnvTest.create("/ds");
+ }
+
+ @Before public void before() {
+ env.clear();
+ }
+
+ @AfterClass public static void afterClass() {
+ EnvTest.stop(env);
+ }
+
+ private String url(String path) { return env.datasetPath(path); }
+
+ @Test public void RDFParser_using_default_http_environment() {
+ Graph graph1 = SSE.parseGraph("(graph (:s :p 1) (:s :p 2))");
+ HttpRDF.httpPutGraph(url("/ds?default"), graph1);
+ var graph2 = GraphFactory.createGraphMem();
+ var builder = RDFParserBuilder.create()
+ .source(url("/ds?default"))
+ .build();
+ builder.parse(graph2);
+ assertTrue(graph1.isIsomorphicWith(graph2));
+ }
+
+ @Test public void RDFParser_using_custom_http_environment() {
+ Graph graph1 = SSE.parseGraph("(graph (:s :p 1) (:s :p 2))");
+ HttpRDF.httpPutGraph(url("/ds?default"), graph1);
+ final boolean[] proxyHasBeenCalled = {false};
+ final var url = url("/ds?default");
+ // create a custom httpClient and validate that it has been used
+ var customHttpEnv = HttpClient.newBuilder()
+ .proxy(new ProxySelector() {
+ @Override
+ public List<Proxy> select(URI uri) {
+ //validate the given url
+ assertEquals(url, uri.toString());
+ //memorize that the custom proxy selector has been
called
+ proxyHasBeenCalled[0] = true;
+ return List.of();
+ }
+
+ @Override
+ public void connectFailed(URI uri, SocketAddress sa,
IOException ioe) {
+ fail("can't connect to " + uri);
+ }
+
+ })
+ .build();
+ var graph2 = GraphFactory.createGraphMem();
+ var builder = RDFParserBuilder.create()
+ .source(url)
+ .httpClient(customHttpEnv)
+ .build();
+ builder.parse(graph2);
+ assertTrue(graph1.isIsomorphicWith(graph2));
+ assertTrue("ProxySelector in custom HttpClient has not been called.",
proxyHasBeenCalled[0]);
+ }
+}