This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 1f918dd83cf8d5049b04f79b0a2b5eeeb63991f9
Author: Claus Ibsen <[email protected]>
AuthorDate: Sun Aug 24 09:49:35 2025 +0200

    CAMEL-22370: camel-graphql - Allow to use custom HttpClient
---
 .../apache/camel/catalog/components/graphql.json   | 12 ++++----
 .../graphql/GraphqlComponentConfigurer.java        |  6 ++++
 .../graphql/GraphqlEndpointConfigurer.java         |  6 ++++
 .../graphql/GraphqlEndpointUriFactory.java         |  3 +-
 .../apache/camel/component/graphql/graphql.json    | 12 ++++----
 .../camel/component/graphql/GraphqlComponent.java  | 19 +++++++++++-
 .../camel/component/graphql/GraphqlEndpoint.java   | 31 ++++++++------------
 .../camel/component/graphql/GraphqlProducer.java   | 24 ++++++++++++++-
 .../dsl/GraphqlComponentBuilderFactory.java        | 19 ++++++++++++
 .../dsl/GraphqlEndpointBuilderFactory.java         | 34 ++++++++++++++++++++++
 10 files changed, 134 insertions(+), 32 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/graphql.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/graphql.json
index 24099e5e37d..8851ae4678c 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/graphql.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/graphql.json
@@ -25,7 +25,8 @@
   },
   "componentProperties": {
     "lazyStartProducer": { "index": 0, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
-    "autowiredEnabled": { "index": 1, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
+    "autowiredEnabled": { "index": 1, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
+    "httpClient": { "index": 2, "kind": "property", "displayName": "Http 
Client", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "org.apache.hc.client5.http.classic.HttpClient", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
use a custom pre-existing Http Client. Beware that when using this, then other 
configurations such as proxy, access token, is not applied and all this must be 
pre-configured on the Http Client." }
   },
   "properties": {
     "httpUri": { "index": 0, "kind": "path", "displayName": "Http Uri", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.net.URI", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The GraphQL server URI." },
@@ -37,9 +38,10 @@
     "variables": { "index": 6, "kind": "parameter", "displayName": 
"Variables", "group": "producer", "label": "", "required": false, "type": 
"object", "javaType": "org.apache.camel.util.json.JsonObject", "deprecated": 
false, "autowired": false, "secret": false, "description": "The JsonObject 
instance containing the operation variables." },
     "variablesHeader": { "index": 7, "kind": "parameter", "displayName": 
"Variables Header", "group": "producer", "label": "", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "The name of a header 
containing a JsonObject instance containing the operation variables." },
     "lazyStartProducer": { "index": 8, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produc [...]
-    "accessToken": { "index": 9, "kind": "parameter", "displayName": "Access 
Token", "group": "security", "label": "security", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": true, "description": "The access token sent in the 
Authorization header." },
-    "jwtAuthorizationType": { "index": 10, "kind": "parameter", "displayName": 
"Jwt Authorization Type", "group": "security", "label": "security", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "Bearer", "description": 
"The JWT Authorization type. Default is Bearer." },
-    "password": { "index": 11, "kind": "parameter", "displayName": "Password", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "description": "The password for Basic authentication." },
-    "username": { "index": 12, "kind": "parameter", "displayName": "Username", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "description": "The username for Basic authentication." }
+    "httpClient": { "index": 9, "kind": "parameter", "displayName": "Http 
Client", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "org.apache.hc.client5.http.classic.HttpClient", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
use a custom pre-existing Http Client. Beware that when using this, then other 
configurations such as proxy, access token, is not applied and all this must be 
pre-configured on the Http Client." },
+    "accessToken": { "index": 10, "kind": "parameter", "displayName": "Access 
Token", "group": "security", "label": "security", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": true, "description": "The access token sent in the 
Authorization header." },
+    "jwtAuthorizationType": { "index": 11, "kind": "parameter", "displayName": 
"Jwt Authorization Type", "group": "security", "label": "security", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "Bearer", "description": 
"The JWT Authorization type. Default is Bearer." },
+    "password": { "index": 12, "kind": "parameter", "displayName": "Password", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "description": "The password for Basic authentication." },
+    "username": { "index": 13, "kind": "parameter", "displayName": "Username", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "description": "The username for Basic authentication." }
   }
 }
diff --git 
a/components/camel-graphql/src/generated/java/org/apache/camel/component/graphql/GraphqlComponentConfigurer.java
 
b/components/camel-graphql/src/generated/java/org/apache/camel/component/graphql/GraphqlComponentConfigurer.java
index 3d0cf2a4684..f706783f4d4 100644
--- 
a/components/camel-graphql/src/generated/java/org/apache/camel/component/graphql/GraphqlComponentConfigurer.java
+++ 
b/components/camel-graphql/src/generated/java/org/apache/camel/component/graphql/GraphqlComponentConfigurer.java
@@ -25,6 +25,8 @@ public class GraphqlComponentConfigurer extends 
PropertyConfigurerSupport implem
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "autowiredenabled":
         case "autowiredEnabled": 
target.setAutowiredEnabled(property(camelContext, boolean.class, value)); 
return true;
+        case "httpclient":
+        case "httpClient": target.setHttpClient(property(camelContext, 
org.apache.hc.client5.http.classic.HttpClient.class, value)); return true;
         case "lazystartproducer":
         case "lazyStartProducer": 
target.setLazyStartProducer(property(camelContext, boolean.class, value)); 
return true;
         default: return false;
@@ -36,6 +38,8 @@ public class GraphqlComponentConfigurer extends 
PropertyConfigurerSupport implem
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "autowiredenabled":
         case "autowiredEnabled": return boolean.class;
+        case "httpclient":
+        case "httpClient": return 
org.apache.hc.client5.http.classic.HttpClient.class;
         case "lazystartproducer":
         case "lazyStartProducer": return boolean.class;
         default: return null;
@@ -48,6 +52,8 @@ public class GraphqlComponentConfigurer extends 
PropertyConfigurerSupport implem
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "autowiredenabled":
         case "autowiredEnabled": return target.isAutowiredEnabled();
+        case "httpclient":
+        case "httpClient": return target.getHttpClient();
         case "lazystartproducer":
         case "lazyStartProducer": return target.isLazyStartProducer();
         default: return null;
diff --git 
a/components/camel-graphql/src/generated/java/org/apache/camel/component/graphql/GraphqlEndpointConfigurer.java
 
b/components/camel-graphql/src/generated/java/org/apache/camel/component/graphql/GraphqlEndpointConfigurer.java
index 483eb09004d..29ac803713a 100644
--- 
a/components/camel-graphql/src/generated/java/org/apache/camel/component/graphql/GraphqlEndpointConfigurer.java
+++ 
b/components/camel-graphql/src/generated/java/org/apache/camel/component/graphql/GraphqlEndpointConfigurer.java
@@ -25,6 +25,8 @@ public class GraphqlEndpointConfigurer extends 
PropertyConfigurerSupport impleme
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "accesstoken":
         case "accessToken": target.setAccessToken(property(camelContext, 
java.lang.String.class, value)); return true;
+        case "httpclient":
+        case "httpClient": target.setHttpClient(property(camelContext, 
org.apache.hc.client5.http.classic.HttpClient.class, value)); return true;
         case "jwtauthorizationtype":
         case "jwtAuthorizationType": 
target.setJwtAuthorizationType(property(camelContext, java.lang.String.class, 
value)); return true;
         case "lazystartproducer":
@@ -52,6 +54,8 @@ public class GraphqlEndpointConfigurer extends 
PropertyConfigurerSupport impleme
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "accesstoken":
         case "accessToken": return java.lang.String.class;
+        case "httpclient":
+        case "httpClient": return 
org.apache.hc.client5.http.classic.HttpClient.class;
         case "jwtauthorizationtype":
         case "jwtAuthorizationType": return java.lang.String.class;
         case "lazystartproducer":
@@ -80,6 +84,8 @@ public class GraphqlEndpointConfigurer extends 
PropertyConfigurerSupport impleme
         switch (ignoreCase ? name.toLowerCase() : name) {
         case "accesstoken":
         case "accessToken": return target.getAccessToken();
+        case "httpclient":
+        case "httpClient": return target.getHttpClient();
         case "jwtauthorizationtype":
         case "jwtAuthorizationType": return target.getJwtAuthorizationType();
         case "lazystartproducer":
diff --git 
a/components/camel-graphql/src/generated/java/org/apache/camel/component/graphql/GraphqlEndpointUriFactory.java
 
b/components/camel-graphql/src/generated/java/org/apache/camel/component/graphql/GraphqlEndpointUriFactory.java
index d99e34187d0..6e1f931d731 100644
--- 
a/components/camel-graphql/src/generated/java/org/apache/camel/component/graphql/GraphqlEndpointUriFactory.java
+++ 
b/components/camel-graphql/src/generated/java/org/apache/camel/component/graphql/GraphqlEndpointUriFactory.java
@@ -23,8 +23,9 @@ public class GraphqlEndpointUriFactory extends 
org.apache.camel.support.componen
     private static final Set<String> SECRET_PROPERTY_NAMES;
     private static final Set<String> MULTI_VALUE_PREFIXES;
     static {
-        Set<String> props = new HashSet<>(13);
+        Set<String> props = new HashSet<>(14);
         props.add("accessToken");
+        props.add("httpClient");
         props.add("httpUri");
         props.add("jwtAuthorizationType");
         props.add("lazyStartProducer");
diff --git 
a/components/camel-graphql/src/generated/resources/META-INF/org/apache/camel/component/graphql/graphql.json
 
b/components/camel-graphql/src/generated/resources/META-INF/org/apache/camel/component/graphql/graphql.json
index 24099e5e37d..8851ae4678c 100644
--- 
a/components/camel-graphql/src/generated/resources/META-INF/org/apache/camel/component/graphql/graphql.json
+++ 
b/components/camel-graphql/src/generated/resources/META-INF/org/apache/camel/component/graphql/graphql.json
@@ -25,7 +25,8 @@
   },
   "componentProperties": {
     "lazyStartProducer": { "index": 0, "kind": "property", "displayName": 
"Lazy Start Producer", "group": "producer", "label": "producer", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether the producer should be started lazy (on the first message). By 
starting lazy you can use this to allow CamelContext and routes to startup in 
situations where a producer may otherwise fail [...]
-    "autowiredEnabled": { "index": 1, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
+    "autowiredEnabled": { "index": 1, "kind": "property", "displayName": 
"Autowired Enabled", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, "description": 
"Whether autowiring is enabled. This is used for automatic autowiring options 
(the option must be marked as autowired) by looking up in the registry to find 
if there is a single instance of matching t [...]
+    "httpClient": { "index": 2, "kind": "property", "displayName": "Http 
Client", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "org.apache.hc.client5.http.classic.HttpClient", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
use a custom pre-existing Http Client. Beware that when using this, then other 
configurations such as proxy, access token, is not applied and all this must be 
pre-configured on the Http Client." }
   },
   "properties": {
     "httpUri": { "index": 0, "kind": "path", "displayName": "Http Uri", 
"group": "producer", "label": "", "required": true, "type": "string", 
"javaType": "java.net.URI", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The GraphQL server URI." },
@@ -37,9 +38,10 @@
     "variables": { "index": 6, "kind": "parameter", "displayName": 
"Variables", "group": "producer", "label": "", "required": false, "type": 
"object", "javaType": "org.apache.camel.util.json.JsonObject", "deprecated": 
false, "autowired": false, "secret": false, "description": "The JsonObject 
instance containing the operation variables." },
     "variablesHeader": { "index": 7, "kind": "parameter", "displayName": 
"Variables Header", "group": "producer", "label": "", "required": false, 
"type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "description": "The name of a header 
containing a JsonObject instance containing the operation variables." },
     "lazyStartProducer": { "index": 8, "kind": "parameter", "displayName": 
"Lazy Start Producer", "group": "producer (advanced)", "label": 
"producer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "description": "Whether the producer should be started 
lazy (on the first message). By starting lazy you can use this to allow 
CamelContext and routes to startup in situations where a produc [...]
-    "accessToken": { "index": 9, "kind": "parameter", "displayName": "Access 
Token", "group": "security", "label": "security", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": true, "description": "The access token sent in the 
Authorization header." },
-    "jwtAuthorizationType": { "index": 10, "kind": "parameter", "displayName": 
"Jwt Authorization Type", "group": "security", "label": "security", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "Bearer", "description": 
"The JWT Authorization type. Default is Bearer." },
-    "password": { "index": 11, "kind": "parameter", "displayName": "Password", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "description": "The password for Basic authentication." },
-    "username": { "index": 12, "kind": "parameter", "displayName": "Username", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "description": "The username for Basic authentication." }
+    "httpClient": { "index": 9, "kind": "parameter", "displayName": "Http 
Client", "group": "advanced", "label": "advanced", "required": false, "type": 
"object", "javaType": "org.apache.hc.client5.http.classic.HttpClient", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
use a custom pre-existing Http Client. Beware that when using this, then other 
configurations such as proxy, access token, is not applied and all this must be 
pre-configured on the Http Client." },
+    "accessToken": { "index": 10, "kind": "parameter", "displayName": "Access 
Token", "group": "security", "label": "security", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": true, "description": "The access token sent in the 
Authorization header." },
+    "jwtAuthorizationType": { "index": 11, "kind": "parameter", "displayName": 
"Jwt Authorization Type", "group": "security", "label": "security", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "Bearer", "description": 
"The JWT Authorization type. Default is Bearer." },
+    "password": { "index": 12, "kind": "parameter", "displayName": "Password", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "description": "The password for Basic authentication." },
+    "username": { "index": 13, "kind": "parameter", "displayName": "Username", 
"group": "security", "label": "security", "required": false, "type": "string", 
"javaType": "java.lang.String", "deprecated": false, "autowired": false, 
"secret": true, "description": "The username for Basic authentication." }
   }
 }
diff --git 
a/components/camel-graphql/src/main/java/org/apache/camel/component/graphql/GraphqlComponent.java
 
b/components/camel-graphql/src/main/java/org/apache/camel/component/graphql/GraphqlComponent.java
index 605a08b0408..5fdb1e1b643 100644
--- 
a/components/camel-graphql/src/main/java/org/apache/camel/component/graphql/GraphqlComponent.java
+++ 
b/components/camel-graphql/src/main/java/org/apache/camel/component/graphql/GraphqlComponent.java
@@ -20,16 +20,22 @@ import java.net.URI;
 import java.util.Map;
 
 import org.apache.camel.Endpoint;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.annotations.Component;
 import org.apache.camel.support.DefaultComponent;
 import org.apache.camel.util.URISupport;
+import org.apache.hc.client5.http.classic.HttpClient;
 
 @Component("graphql")
 public class GraphqlComponent extends DefaultComponent {
 
+    @Metadata(label = "advanced")
+    private HttpClient httpClient;
+
     @Override
     protected Endpoint createEndpoint(String uri, String remaining, 
Map<String, Object> parameters) throws Exception {
         GraphqlEndpoint endpoint = new GraphqlEndpoint(uri, this);
+        endpoint.setHttpClient(httpClient);
         endpoint.setHttpUri(new URI(remaining));
         setProperties(endpoint, parameters);
         return endpoint;
@@ -38,7 +44,6 @@ public class GraphqlComponent extends DefaultComponent {
     @Override
     protected void afterConfiguration(String uri, String remaining, Endpoint 
endpoint, Map<String, Object> parameters)
             throws Exception {
-
         GraphqlEndpoint graphqlEndpoint = (GraphqlEndpoint) endpoint;
         if (!parameters.isEmpty()) {
             URI httpUri = 
URISupport.createRemainingURI(graphqlEndpoint.getHttpUri(), parameters);
@@ -46,4 +51,16 @@ public class GraphqlComponent extends DefaultComponent {
         }
     }
 
+    public HttpClient getHttpClient() {
+        return httpClient;
+    }
+
+    /**
+     * To use a custom pre-existing Http Client. Beware that when using this, 
then other configurations such as proxy,
+     * access token, is not applied and all this must be pre-configured on the 
Http Client.
+     */
+    public void setHttpClient(HttpClient httpClient) {
+        this.httpClient = httpClient;
+    }
+
 }
diff --git 
a/components/camel-graphql/src/main/java/org/apache/camel/component/graphql/GraphqlEndpoint.java
 
b/components/camel-graphql/src/main/java/org/apache/camel/component/graphql/GraphqlEndpoint.java
index 31e513f2195..f7f5672e3c3 100644
--- 
a/components/camel-graphql/src/main/java/org/apache/camel/component/graphql/GraphqlEndpoint.java
+++ 
b/components/camel-graphql/src/main/java/org/apache/camel/component/graphql/GraphqlEndpoint.java
@@ -39,6 +39,7 @@ import org.apache.camel.util.json.JsonObject;
 import org.apache.hc.client5.http.auth.AuthScope;
 import org.apache.hc.client5.http.auth.CredentialsStore;
 import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
+import org.apache.hc.client5.http.classic.HttpClient;
 import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
 import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
 import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
@@ -54,6 +55,8 @@ import org.apache.hc.core5.http.message.BasicHeader;
              category = { Category.API }, producerOnly = true, 
lenientProperties = true)
 public class GraphqlEndpoint extends DefaultEndpoint implements 
EndpointServiceLocation {
 
+    private boolean closeHttpClient;
+
     @UriPath
     @Metadata(required = true)
     private URI httpUri;
@@ -79,8 +82,8 @@ public class GraphqlEndpoint extends DefaultEndpoint 
implements EndpointServiceL
     private String variablesHeader;
     @UriParam
     private String queryHeader;
-
-    private CloseableHttpClient httpClient;
+    @UriParam(label = "advanced")
+    private HttpClient httpClient;
 
     public GraphqlEndpoint(String uri, Component component) {
         super(uri, component);
@@ -107,13 +110,6 @@ public class GraphqlEndpoint extends DefaultEndpoint 
implements EndpointServiceL
         return "rest";
     }
 
-    @Override
-    protected void doStop() throws Exception {
-        if (httpClient != null) {
-            httpClient.close();
-        }
-    }
-
     @Override
     public Producer createProducer() throws Exception {
         return new GraphqlProducer(this);
@@ -124,14 +120,7 @@ public class GraphqlEndpoint extends DefaultEndpoint 
implements EndpointServiceL
         throw new UnsupportedOperationException("You cannot receive messages 
at this endpoint: " + getEndpointUri());
     }
 
-    public CloseableHttpClient getHttpclient() {
-        if (httpClient == null) {
-            this.httpClient = createHttpClient();
-        }
-        return httpClient;
-    }
-
-    private CloseableHttpClient createHttpClient() {
+    CloseableHttpClient createHttpClient() {
         HttpClientBuilder httpClientBuilder = HttpClients.custom();
         if (proxyHost != null) {
             String[] parts = proxyHost.split(":");
@@ -296,11 +285,15 @@ public class GraphqlEndpoint extends DefaultEndpoint 
implements EndpointServiceL
         this.queryHeader = queryHeader;
     }
 
-    public CloseableHttpClient getHttpClient() {
+    public HttpClient getHttpClient() {
         return httpClient;
     }
 
-    public void setHttpClient(CloseableHttpClient httpClient) {
+    /**
+     * To use a custom pre-existing Http Client. Beware that when using this, 
then other configurations such as proxy,
+     * access token, is not applied and all this must be pre-configured on the 
Http Client.
+     */
+    public void setHttpClient(HttpClient httpClient) {
         this.httpClient = httpClient;
     }
 
diff --git 
a/components/camel-graphql/src/main/java/org/apache/camel/component/graphql/GraphqlProducer.java
 
b/components/camel-graphql/src/main/java/org/apache/camel/component/graphql/GraphqlProducer.java
index 7bbfab7ec45..aa607339bab 100644
--- 
a/components/camel-graphql/src/main/java/org/apache/camel/component/graphql/GraphqlProducer.java
+++ 
b/components/camel-graphql/src/main/java/org/apache/camel/component/graphql/GraphqlProducer.java
@@ -22,7 +22,9 @@ import org.apache.camel.AsyncCallback;
 import org.apache.camel.Exchange;
 import org.apache.camel.InvalidPayloadException;
 import org.apache.camel.support.DefaultAsyncProducer;
+import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.json.JsonObject;
+import org.apache.hc.client5.http.classic.HttpClient;
 import org.apache.hc.client5.http.classic.methods.HttpPost;
 import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
 import org.apache.hc.core5.http.ContentType;
@@ -37,6 +39,27 @@ public class GraphqlProducer extends DefaultAsyncProducer {
         super(endpoint);
     }
 
+    private HttpClient httpClient;
+    private boolean closeHttpClient;
+
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+
+        httpClient = getEndpoint().getHttpClient();
+        if (httpClient == null) {
+            httpClient = getEndpoint().createHttpClient();
+            closeHttpClient = true;
+        }
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        if (closeHttpClient && httpClient instanceof CloseableHttpClient chc) {
+            IOHelper.close(chc);
+        }
+    }
+
     @Override
     public GraphqlEndpoint getEndpoint() {
         return (GraphqlEndpoint) super.getEndpoint();
@@ -45,7 +68,6 @@ public class GraphqlProducer extends DefaultAsyncProducer {
     @Override
     public boolean process(Exchange exchange, AsyncCallback callback) {
         try {
-            CloseableHttpClient httpClient = getEndpoint().getHttpclient();
             URI httpUri = getEndpoint().getHttpUri();
             String requestBody = buildRequestBody(getQuery(exchange), 
getEndpoint().getOperationName(),
                     getVariables(exchange));
diff --git 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/GraphqlComponentBuilderFactory.java
 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/GraphqlComponentBuilderFactory.java
index 80d807cf848..6d52e8c9439 100644
--- 
a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/GraphqlComponentBuilderFactory.java
+++ 
b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/GraphqlComponentBuilderFactory.java
@@ -96,6 +96,24 @@ public interface GraphqlComponentBuilderFactory {
             doSetProperty("autowiredEnabled", autowiredEnabled);
             return this;
         }
+    
+        /**
+         * To use a custom pre-existing Http Client. Beware that when using
+         * this, then other configurations such as proxy, access token, is not
+         * applied and all this must be pre-configured on the Http Client.
+         * 
+         * The option is a:
+         * 
&lt;code&gt;org.apache.hc.client5.http.classic.HttpClient&lt;/code&gt; type.
+         * 
+         * Group: advanced
+         * 
+         * @param httpClient the value to set
+         * @return the dsl builder
+         */
+        default GraphqlComponentBuilder 
httpClient(org.apache.hc.client5.http.classic.HttpClient httpClient) {
+            doSetProperty("httpClient", httpClient);
+            return this;
+        }
     }
 
     class GraphqlComponentBuilderImpl
@@ -113,6 +131,7 @@ public interface GraphqlComponentBuilderFactory {
             switch (name) {
             case "lazyStartProducer": ((GraphqlComponent) 
component).setLazyStartProducer((boolean) value); return true;
             case "autowiredEnabled": ((GraphqlComponent) 
component).setAutowiredEnabled((boolean) value); return true;
+            case "httpClient": ((GraphqlComponent) 
component).setHttpClient((org.apache.hc.client5.http.classic.HttpClient) 
value); return true;
             default: return false;
             }
         }
diff --git 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/GraphqlEndpointBuilderFactory.java
 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/GraphqlEndpointBuilderFactory.java
index 4ac9da1547f..e28df13f7a0 100644
--- 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/GraphqlEndpointBuilderFactory.java
+++ 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/GraphqlEndpointBuilderFactory.java
@@ -274,6 +274,40 @@ public interface GraphqlEndpointBuilderFactory {
             doSetProperty("lazyStartProducer", lazyStartProducer);
             return this;
         }
+        /**
+         * To use a custom pre-existing Http Client. Beware that when using
+         * this, then other configurations such as proxy, access token, is not
+         * applied and all this must be pre-configured on the Http Client.
+         * 
+         * The option is a:
+         * <code>org.apache.hc.client5.http.classic.HttpClient</code> type.
+         * 
+         * Group: advanced
+         * 
+         * @param httpClient the value to set
+         * @return the dsl builder
+         */
+        default AdvancedGraphqlEndpointBuilder 
httpClient(org.apache.hc.client5.http.classic.HttpClient httpClient) {
+            doSetProperty("httpClient", httpClient);
+            return this;
+        }
+        /**
+         * To use a custom pre-existing Http Client. Beware that when using
+         * this, then other configurations such as proxy, access token, is not
+         * applied and all this must be pre-configured on the Http Client.
+         * 
+         * The option will be converted to a
+         * <code>org.apache.hc.client5.http.classic.HttpClient</code> type.
+         * 
+         * Group: advanced
+         * 
+         * @param httpClient the value to set
+         * @return the dsl builder
+         */
+        default AdvancedGraphqlEndpointBuilder httpClient(String httpClient) {
+            doSetProperty("httpClient", httpClient);
+            return this;
+        }
     }
 
     public interface GraphqlBuilders {

Reply via email to