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]);
+    }
+}

Reply via email to