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
The following commit(s) were added to refs/heads/main by this push:
new ef4bf6700094 CAMEL-22562_extend_camel-http (#21648)
ef4bf6700094 is described below
commit ef4bf6700094fe890dde078b6bbfbbe64bf97e50
Author: Jono Morris <[email protected]>
AuthorDate: Mon Mar 2 20:50:41 2026 +1300
CAMEL-22562_extend_camel-http (#21648)
---
components/camel-graphql/pom.xml | 11 +
.../camel/component/graphql/GraphqlEndpoint.java | 52 ++--
.../camel/component/graphql/GraphqlProducer.java | 269 ++++-----------------
.../camel/component/graphql/BaseGraphqlTest.java | 72 ++++++
.../graphql/GraphqlBasicAuthenticationTest.java | 91 +++++++
.../camel/component/graphql/GraphqlClientTest.java | 119 +++++++++
.../graphql/GraphqlHeaderFilterStrategyTest.java | 121 +++++++++
.../graphql/GraphqlProxyNonProxyHostsTest.java | 88 +++++++
.../GraphqlThrowExceptionOnFailureTest.java | 102 ++++++++
.../graphql/GraphqlTokenAuthenticationTest.java | 81 +++++++
.../handler/BearerTokenValidationHandler.java | 54 +++++
components/camel-http/pom.xml | 16 ++
12 files changed, 835 insertions(+), 241 deletions(-)
diff --git a/components/camel-graphql/pom.xml b/components/camel-graphql/pom.xml
index 2f84202bc295..0170a0357cc6 100644
--- a/components/camel-graphql/pom.xml
+++ b/components/camel-graphql/pom.xml
@@ -37,6 +37,10 @@
<groupId>org.apache.camel</groupId>
<artifactId>camel-support</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-http</artifactId>
+ </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-http-base</artifactId>
@@ -53,6 +57,13 @@
</dependency>
<!-- for testing -->
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-http</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-test-junit6</artifactId>
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 ba6ce89b7be6..e3af5fa246a6 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
@@ -28,6 +28,7 @@ import org.apache.camel.Consumer;
import org.apache.camel.Processor;
import org.apache.camel.Producer;
import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.component.http.HttpClientConfigurer;
import org.apache.camel.http.base.HttpHeaderFilterStrategy;
import org.apache.camel.spi.EndpointServiceLocation;
import org.apache.camel.spi.HeaderFilterStrategy;
@@ -44,9 +45,7 @@ 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;
-import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.HttpHeaders;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.message.BasicHeader;
@@ -135,30 +134,35 @@ public class GraphqlEndpoint extends DefaultEndpoint
implements EndpointServiceL
throw new UnsupportedOperationException("You cannot receive messages
at this endpoint: " + getEndpointUri());
}
- CloseableHttpClient createHttpClient() {
- HttpClientBuilder httpClientBuilder = HttpClients.custom();
- if (proxyHost != null) {
- String[] parts = proxyHost.split(":");
- String hostname = parts[0];
- int port = Integer.parseInt(parts[1]);
- httpClientBuilder.setProxy(new HttpHost(hostname, port));
- }
- if (accessToken != null) {
- String authType = "Bearer";
- if (this.jwtAuthorizationType != null) {
- authType = this.jwtAuthorizationType;
+ HttpClientConfigurer createHttpClientConfigurer() {
+ return new AuthClientConfigurer();
+ }
+
+ private class AuthClientConfigurer implements HttpClientConfigurer {
+ @Override
+ public void configureHttpClient(HttpClientBuilder httpClientBuilder) {
+ if (proxyHost != null) {
+ String[] parts = proxyHost.split(":");
+ String hostname = parts[0];
+ int port = Integer.parseInt(parts[1]);
+ httpClientBuilder.setProxy(new HttpHost(hostname, port));
+ }
+ if (accessToken != null) {
+ String authType = "Bearer";
+ if (jwtAuthorizationType != null) {
+ authType = jwtAuthorizationType;
+ }
+ httpClientBuilder.setDefaultHeaders(
+ Arrays.asList(new
BasicHeader(HttpHeaders.AUTHORIZATION, authType + " " + accessToken)));
+ }
+ if (username != null && password != null) {
+ CredentialsStore credentialsProvider = new
BasicCredentialsProvider();
+ credentialsProvider.setCredentials(
+ new AuthScope(null, -1),
+ new UsernamePasswordCredentials(username,
password.toCharArray()));
+
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
- httpClientBuilder.setDefaultHeaders(
- Arrays.asList(new BasicHeader(HttpHeaders.AUTHORIZATION,
authType + " " + accessToken)));
- }
- if (username != null && password != null) {
- CredentialsStore credentialsProvider = new
BasicCredentialsProvider();
- credentialsProvider.setCredentials(
- new AuthScope(null, -1),
- new UsernamePasswordCredentials(username,
password.toCharArray()));
-
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
- return httpClientBuilder.build();
}
public URI getHttpUri() {
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 47b75a5c5374..2783ffab6170 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
@@ -16,52 +16,23 @@
*/
package org.apache.camel.component.graphql;
-import java.io.IOException;
-import java.net.URI;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
import org.apache.camel.AsyncCallback;
+import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
-import org.apache.camel.ExchangePropertyKey;
import org.apache.camel.InvalidPayloadException;
-import org.apache.camel.Message;
-import org.apache.camel.TypeConverter;
-import org.apache.camel.http.base.HttpHelper;
-import org.apache.camel.http.base.HttpOperationFailedException;
+import org.apache.camel.Producer;
+import org.apache.camel.component.http.HttpConstants;
import org.apache.camel.spi.HeaderFilterStrategy;
+import org.apache.camel.spi.Registry;
import org.apache.camel.support.DefaultAsyncProducer;
-import org.apache.camel.support.ObjectHelper;
-import org.apache.camel.support.http.HttpUtil;
-import org.apache.camel.util.IOHelper;
+import org.apache.camel.support.MessageHelper;
+import org.apache.camel.support.service.ServiceHelper;
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.classic.methods.HttpUriRequest;
-import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
-import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.ContentType;
-import org.apache.hc.core5.http.Header;
-import org.apache.hc.core5.http.HttpEntity;
-import org.apache.hc.core5.http.HttpHeaders;
-import org.apache.hc.core5.http.ParseException;
-import org.apache.hc.core5.http.io.entity.EntityUtils;
-import org.apache.hc.core5.http.io.entity.StringEntity;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
public class GraphqlProducer extends DefaultAsyncProducer {
- private static final Logger LOG =
LoggerFactory.getLogger(GraphqlProducer.class);
-
- private static final Integer OK_RESPONSE_CODE = 200;
- private static final String OK_STATUS_RANGE = "200-299";
-
- private HttpClient httpClient;
- private boolean closeHttpClient;
+ private Producer http;
public GraphqlProducer(GraphqlEndpoint endpoint) {
super(endpoint);
@@ -71,18 +42,39 @@ public class GraphqlProducer extends DefaultAsyncProducer {
protected void doStart() throws Exception {
super.doStart();
- httpClient = getEndpoint().getHttpClient();
- if (httpClient == null) {
- httpClient = getEndpoint().createHttpClient();
- closeHttpClient = true;
+ Registry registry = getEndpoint().getCamelContext().getRegistry();
+ String hash =
Integer.toHexString(getEndpoint().getEndpointUri().hashCode());
+
+ StringBuilder sb = new StringBuilder(getEndpoint().getServiceUrl());
+ sb.append("?httpMethod=POST");
+
sb.append("&throwExceptionOnFailure=").append(getEndpoint().isThrowExceptionOnFailure());
+
+ String clientConfigurerName = "graphqlHttpClientConfigurer-" + hash;
+ registry.bind(clientConfigurerName,
getEndpoint().createHttpClientConfigurer());
+ sb.append("&httpClientConfigurer=#").append(clientConfigurerName);
+
+ HeaderFilterStrategy headerFilterStrategy =
getEndpoint().getHeaderFilterStrategy();
+ if (headerFilterStrategy != null) {
+ String filterStrategyName = "graphqlHeaderFilterStrategy-" + hash;
+ registry.bind(filterStrategyName, headerFilterStrategy);
+ sb.append("&headerFilterStrategy=#").append(filterStrategyName);
+ }
+
+ HttpClient httpClient = getEndpoint().getHttpClient();
+ if (httpClient != null) {
+ String httpClientName = "graphqlHttpClient-" + hash;
+ registry.bind(httpClientName, httpClient);
+ sb.append("&httpClient=#").append(httpClientName);
}
+
+ Endpoint httpEndpoint =
getEndpoint().getCamelContext().getEndpoint(sb.toString());
+ http = httpEndpoint.createProducer();
+ ServiceHelper.startService(http);
}
@Override
protected void doStop() throws Exception {
- if (closeHttpClient && httpClient instanceof CloseableHttpClient chc) {
- IOHelper.close(chc);
- }
+ ServiceHelper.stopService(http);
}
@Override
@@ -92,45 +84,26 @@ public class GraphqlProducer extends DefaultAsyncProducer {
@Override
public boolean process(Exchange exchange, AsyncCallback callback) {
- try {
- URI httpUri = getEndpoint().getHttpUri();
- String requestBody = buildRequestBody(getQuery(exchange),
getEndpoint().getOperationName(),
- getVariables(exchange));
- try (HttpEntity requestEntity = new StringEntity(requestBody,
ContentType.APPLICATION_JSON)) {
- HttpPost httpPost = new HttpPost(httpUri);
- httpPost.setHeader(HttpHeaders.CONTENT_TYPE,
"application/json");
- httpPost.setHeader(HttpHeaders.ACCEPT, "application/json");
- httpPost.setHeader(HttpHeaders.ACCEPT_ENCODING, "gzip");
- httpPost.setEntity(requestEntity);
- populateRequestHeaders(exchange, httpPost);
- httpClient.execute(httpPost, httpResponse -> {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Finished executing http: {} method: {}",
httpUri, HttpPost.METHOD_NAME);
- }
- int responseCode = httpResponse.getCode();
- if (LOG.isDebugEnabled()) {
- LOG.debug("Http responseCode: {}", responseCode);
- }
- if (!getEndpoint().isThrowExceptionOnFailure()) {
- // if we do not use failed exception then populate
response for all response codes
- populateResponse(exchange, httpResponse,
getEndpoint().getHeaderFilterStrategy(), responseCode);
- } else {
- boolean ok = HttpHelper.isStatusCodeOk(responseCode,
OK_STATUS_RANGE);
- if (ok) {
- // only populate response for OK response
- populateResponse(exchange, httpResponse,
getEndpoint().getHeaderFilterStrategy(), responseCode);
- } else {
- // also store response code when throwing exception
- populateResponseCode(exchange.getMessage(),
httpResponse, responseCode);
+ Exchange httpExchange = getEndpoint().createExchange();
+ httpExchange.getIn().setHeader(HttpConstants.HTTP_METHOD, "post");
+ httpExchange.getIn().setHeader("Content-Type", "application/json");
+ httpExchange.getIn().setHeader("Accept", "application/json");
+ httpExchange.getIn().setHeader("Accept-Encoding", "gzip");
+ MessageHelper.copyHeaders(exchange.getMessage(), httpExchange.getIn(),
true);
- // operation failed so populate exception to throw
-
exchange.setException(populateHttpOperationFailedException(exchange,
httpResponse, responseCode));
- }
- }
- return null;
- });
+ try {
+ String requestBody
+ = buildRequestBody(getQuery(exchange),
getEndpoint().getOperationName(), getVariables(exchange));
+ httpExchange.getIn().setBody(requestBody);
+ try {
+ http.process(httpExchange);
+ String data = httpExchange.getMessage().getBody(String.class);
+ exchange.getIn().setBody(data);
+ } catch (Exception e) {
+ exchange.setException(e);
}
+ MessageHelper.copyHeaders(httpExchange.getMessage(),
exchange.getIn(), true);
} catch (Exception e) {
exchange.setException(e);
}
@@ -139,144 +112,6 @@ public class GraphqlProducer extends DefaultAsyncProducer
{
return true;
}
- private void populateRequestHeaders(Exchange exchange, HttpPost
httpRequest) {
- HeaderFilterStrategy strategy =
getEndpoint().getHeaderFilterStrategy();
- final TypeConverter tc = exchange.getContext().getTypeConverter();
- for (Map.Entry<String, Object> entry :
exchange.getMessage().getHeaders().entrySet()) {
- String key = entry.getKey();
- // we should not add known headers
-
- // skip known headers from graphql
- boolean skip = getEndpoint().getQueryHeader() != null &&
key.equalsIgnoreCase(getEndpoint().getQueryHeader())
- || getEndpoint().getVariablesHeader() != null &&
key.equalsIgnoreCase(getEndpoint().getVariablesHeader());
- if (skip) {
- continue;
- }
-
- Object headerValue = entry.getValue();
- if (headerValue != null) {
- if (headerValue instanceof String || headerValue instanceof
Integer || headerValue instanceof Long
- || headerValue instanceof Boolean || headerValue
instanceof Date) {
- // optimise for common types
- String value = headerValue.toString();
- if (!strategy.applyFilterToCamelHeaders(key, value,
exchange)) {
- httpRequest.addHeader(key, value);
- }
- continue;
- }
-
- // use an iterator as there can be multiple values. (must not
use a delimiter, and allow empty values)
- final Iterator<?> it =
ObjectHelper.createIterator(headerValue, null, true);
-
- HttpUtil.applyHeader(strategy, exchange, it, tc, key,
- (multiValues, prev) -> applyHeader(httpRequest, key,
multiValues, prev));
- }
- }
- }
-
- private static void applyHeader(HttpUriRequest httpRequest, String key,
List<String> multiValues, String prev) {
- // add the value(s) as a http request header
- if (multiValues != null) {
- // use the default toString of a ArrayList to create in the form
[xxx, yyy]
- // if multi valued, for a single value, then just output the value
as is
- String s = multiValues.size() > 1 ? multiValues.toString() :
multiValues.get(0);
- httpRequest.addHeader(key, s);
- } else if (prev != null) {
- httpRequest.addHeader(key, prev);
- }
- }
-
- private static void populateResponseCode(Message message,
ClassicHttpResponse httpResponse, int responseCode) {
- // optimize for 200 response code as the boxing is outside the cached
integers
- if (responseCode == 200) {
- message.setHeader(Exchange.HTTP_RESPONSE_CODE, OK_RESPONSE_CODE);
- } else {
- message.setHeader(Exchange.HTTP_RESPONSE_CODE, responseCode);
- }
- if (httpResponse.getReasonPhrase() != null) {
- message.setHeader(Exchange.HTTP_RESPONSE_TEXT,
httpResponse.getReasonPhrase());
- }
- }
-
- protected Exception populateHttpOperationFailedException(
- Exchange exchange, ClassicHttpResponse httpResponse, int
responseCode)
- throws IOException, ParseException {
- Exception answer;
-
- String statusText = httpResponse.getReasonPhrase() != null ?
httpResponse.getReasonPhrase() : null;
- Map<String, String> headers =
extractResponseHeaders(httpResponse.getHeaders());
-
- Object responseBody = EntityUtils.toString(httpResponse.getEntity());
-
- // make a defensive copy of the response body in the exception so its
detached from the cache
- String copy = null;
- if (responseBody != null) {
- copy =
exchange.getContext().getTypeConverter().convertTo(String.class, exchange,
responseBody);
- }
-
- Header locationHeader = httpResponse.getFirstHeader("location");
- String uri = getEndpoint().getHttpUri().toString();
- if (locationHeader != null && responseCode >= 300 && responseCode <
400) {
- answer = new HttpOperationFailedException(
- uri, responseCode, statusText, locationHeader.getValue(),
headers, copy);
- } else {
- answer = new HttpOperationFailedException(uri, responseCode,
statusText, null, headers, copy);
- }
-
- return answer;
- }
-
- protected void populateResponse(
- Exchange exchange, ClassicHttpResponse httpResponse,
- HeaderFilterStrategy strategy, int responseCode)
- throws IOException, ParseException {
-
- Message answer = exchange.getMessage();
- populateResponseCode(answer, httpResponse, responseCode);
-
- // We just make the out message is not create when extractResponseBody
throws exception
- Object responseBody = EntityUtils.toString(httpResponse.getEntity());
- answer.setBody(responseBody);
-
- // optimize to walk headers with an iterator which does not create a
new array as getAllHeaders does
- boolean found = false;
- Iterator<Header> it = httpResponse.headerIterator();
- while (it.hasNext()) {
- Header header = it.next();
- String name = header.getName();
- String value = header.getValue();
- if (!found && name.equalsIgnoreCase("content-type")) {
- name = Exchange.CONTENT_TYPE;
- exchange.setProperty(ExchangePropertyKey.CHARSET_NAME,
IOHelper.getCharsetNameFromContentType(value));
- found = true;
- }
- // use http helper to extract parameter value as it may contain
multiple values
- Object extracted = HttpHelper.extractHttpParameterValue(value);
- if (strategy != null &&
!strategy.applyFilterToExternalHeaders(name, extracted, exchange)) {
- HttpHelper.appendHeader(answer.getHeaders(), name, extracted);
- }
- }
- }
-
- /**
- * Extracts the response headers
- *
- * @param responseHeaders the headers
- * @return the extracted headers or an empty map if no
headers existed
- */
- protected static Map<String, String> extractResponseHeaders(Header[]
responseHeaders) {
- if (responseHeaders == null || responseHeaders.length == 0) {
- return Map.of();
- }
-
- Map<String, String> answer = new HashMap<>();
- for (Header header : responseHeaders) {
- answer.put(header.getName(), header.getValue());
- }
-
- return answer;
- }
-
protected static String buildRequestBody(String query, String
operationName, JsonObject variables) {
JsonObject jsonObject = new JsonObject();
jsonObject.put("query", query);
diff --git
a/components/camel-graphql/src/test/java/org/apache/camel/component/graphql/BaseGraphqlTest.java
b/components/camel-graphql/src/test/java/org/apache/camel/component/graphql/BaseGraphqlTest.java
new file mode 100644
index 000000000000..b39125bf790e
--- /dev/null
+++
b/components/camel-graphql/src/test/java/org/apache/camel/component/graphql/BaseGraphqlTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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.camel.component.graphql;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.http.BaseHttpTest;
+import org.apache.camel.component.http.interceptor.RequestBasicAuth;
+import org.apache.camel.component.http.interceptor.ResponseBasicUnauthorized;
+import org.apache.camel.http.base.HttpOperationFailedException;
+import org.apache.hc.core5.http.HttpRequestInterceptor;
+import org.apache.hc.core5.http.HttpResponseInterceptor;
+import org.apache.hc.core5.http.HttpStatus;
+import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
+import org.apache.hc.core5.http.protocol.HttpProcessor;
+import org.apache.hc.core5.http.protocol.RequestValidateHost;
+import org.apache.hc.core5.http.protocol.ResponseContent;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+public class BaseGraphqlTest extends BaseHttpTest {
+
+ protected void assertUnauthorizedResponse(Exchange exchange) {
+ assertNotNull(exchange);
+
+ Exception ex = exchange.getException();
+ assertNotNull(ex, "Should have thrown an exception");
+
+ HttpOperationFailedException cause =
assertInstanceOf(HttpOperationFailedException.class, ex);
+ assertEquals(HttpStatus.SC_UNAUTHORIZED, cause.getStatusCode());
+
+ Message in = exchange.getIn();
+ assertNotNull(in);
+
+ Map<String, Object> headers = in.getHeaders();
+ assertEquals(HttpStatus.SC_UNAUTHORIZED,
headers.get(Exchange.HTTP_RESPONSE_CODE));
+ assertEquals("Unauthorized", headers.get(Exchange.HTTP_RESPONSE_TEXT));
+ }
+
+ @Override
+ protected HttpProcessor getBasicHttpProcessor() {
+ List<HttpRequestInterceptor> requestInterceptors = new ArrayList<>();
+ requestInterceptors.add(new RequestValidateHost());
+ requestInterceptors.add(new RequestBasicAuth());
+
+ List<HttpResponseInterceptor> responseInterceptors = new ArrayList<>();
+ responseInterceptors.add(new ResponseContent());
+ responseInterceptors.add(new ResponseBasicUnauthorized());
+
+ return new DefaultHttpProcessor(requestInterceptors,
responseInterceptors);
+ }
+}
diff --git
a/components/camel-graphql/src/test/java/org/apache/camel/component/graphql/GraphqlBasicAuthenticationTest.java
b/components/camel-graphql/src/test/java/org/apache/camel/component/graphql/GraphqlBasicAuthenticationTest.java
new file mode 100644
index 000000000000..0dcdebfe72c6
--- /dev/null
+++
b/components/camel-graphql/src/test/java/org/apache/camel/component/graphql/GraphqlBasicAuthenticationTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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.camel.component.graphql;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.http.handler.AuthenticationValidationHandler;
+import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
+import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
+import org.junit.jupiter.api.Test;
+
+import static org.apache.camel.component.http.HttpMethods.POST;
+
+/**
+ * Verify 'AuthClientConfigurer' instances registered with Basic credentials.
+ */
+public class GraphqlBasicAuthenticationTest extends BaseGraphqlTest {
+
+ private final String user = "camel";
+ private final String password = "password";
+ private HttpServer localServer;
+
+ @Override
+ public void setupResources() throws Exception {
+ localServer = ServerBootstrap.bootstrap()
+
.setCanonicalHostName("localhost").setHttpProcessor(getBasicHttpProcessor())
+ .register("/graphql",
+ new AuthenticationValidationHandler(
+ POST.name(), null, null, getExpectedContent(),
user, password))
+ .create();
+ localServer.start();
+ }
+
+ @Override
+ public void cleanupResources() {
+ if (localServer != null) {
+ localServer.stop();
+ }
+ }
+
+ // verify that an endpoint configured with the correct credentials passes
authentication
+ @Test
+ public void shouldPassAuthentication() {
+ Exchange exchange = template.request("direct:start1", exchange1 -> {
+ });
+
+ assertExchange(exchange);
+ }
+
+ // verify that an endpoint configured with wrong credentials fails
authentication
+ @Test
+ public void shouldFailAuthorisation() {
+ Exchange exchange = template.request("direct:start2", exchange1 -> {
+ });
+
+ assertUnauthorizedResponse(exchange);
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+ // multiple routes to verify registration of multiple configurers
+ @Override
+ public void configure() {
+ from("direct:start1")
+ .to("graphql://http://localhost:" +
localServer.getLocalPort()
+ + "/graphql?query={books{id name}}"
+ + "&username=" + user + "&password=" + password);
+
+ from("direct:start2")
+ .to("graphql://http://localhost:" +
localServer.getLocalPort()
+ + "/graphql?query={books{id name}}"
+ + "&username=" + user + "&password=wrongPassword");
+ }
+ };
+ }
+}
diff --git
a/components/camel-graphql/src/test/java/org/apache/camel/component/graphql/GraphqlClientTest.java
b/components/camel-graphql/src/test/java/org/apache/camel/component/graphql/GraphqlClientTest.java
new file mode 100644
index 000000000000..43cf3f9d3eb9
--- /dev/null
+++
b/components/camel-graphql/src/test/java/org/apache/camel/component/graphql/GraphqlClientTest.java
@@ -0,0 +1,119 @@
+/*
+ * 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.camel.component.graphql;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.http.handler.AuthenticationValidationHandler;
+import org.apache.camel.spi.Registry;
+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.impl.auth.BasicCredentialsProvider;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
+import org.apache.hc.client5.http.impl.classic.HttpClients;
+import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
+import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
+import org.junit.jupiter.api.Test;
+
+import static org.apache.camel.component.http.HttpMethods.POST;
+
+/**
+ * Verify 'HttpClient' instances registered with Basic credentials.
+ */
+public class GraphqlClientTest extends BaseGraphqlTest {
+
+ private final String user = "camel";
+ private final String password = "password";
+ private HttpServer localServer;
+
+ @Override
+ public void setupResources() throws Exception {
+ localServer = ServerBootstrap.bootstrap()
+
.setCanonicalHostName("localhost").setHttpProcessor(getBasicHttpProcessor())
+ .register("/graphql",
+ new AuthenticationValidationHandler(
+ POST.name(), null, null,
+ getExpectedContent(), user, password))
+ .create();
+ localServer.start();
+ }
+
+ @Override
+ public void cleanupResources() {
+ if (localServer != null) {
+ localServer.stop();
+ }
+ }
+
+ // verify that a httpClient configured with the correct credentials passes
authentication
+ @Test
+ public void shouldPassAuthentication() {
+ Exchange exchange = template.request("direct:start1", exchange1 -> {
+ });
+
+ assertExchange(exchange);
+ }
+
+ // verify that a httpClient configured with wrong credentials fails
authentication
+ @Test
+ public void shouldFailAuthorisation() {
+ Exchange exchange = template.request("direct:start2", exchange1 -> {
+ });
+
+ assertUnauthorizedResponse(exchange);
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+ // multiple routes to verify registration of multiple 'httpClient'
instances
+ @Override
+ public void configure() {
+ from("direct:start1")
+ .to("graphql://http://localhost:" +
localServer.getLocalPort()
+ + "/graphql?query={books{id name}}"
+ + "&httpClient=#httpClient");
+
+ from("direct:start2")
+ .to("graphql://http://localhost:" +
localServer.getLocalPort()
+ + "/graphql?query={books{id name}}"
+ + "&httpClient=#httpClientWrongPassword");
+ }
+ };
+ }
+
+ @Override
+ protected void bindToRegistry(Registry registry) {
+ registry.bind("httpClient", createHttpClient(user, password));
+ registry.bind("httpClientWrongPassword", createHttpClient(user,
"wrongPassword"));
+ }
+
+ // create a HttpClient instance with the provided credentials
+ private CloseableHttpClient createHttpClient(String user, String password)
{
+ CredentialsStore credentialsProvider = new BasicCredentialsProvider();
+ // set credentials on the http-client instead of the endpoint for
purpose of this test
+ credentialsProvider.setCredentials(
+ new AuthScope(null, -1),
+ new UsernamePasswordCredentials(user, password.toCharArray()));
+ HttpClientBuilder httpClientBuilder = HttpClients.custom();
+ httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
+
+ return httpClientBuilder.build();
+ }
+}
diff --git
a/components/camel-graphql/src/test/java/org/apache/camel/component/graphql/GraphqlHeaderFilterStrategyTest.java
b/components/camel-graphql/src/test/java/org/apache/camel/component/graphql/GraphqlHeaderFilterStrategyTest.java
new file mode 100644
index 000000000000..043d67788d0c
--- /dev/null
+++
b/components/camel-graphql/src/test/java/org/apache/camel/component/graphql/GraphqlHeaderFilterStrategyTest.java
@@ -0,0 +1,121 @@
+/*
+ * 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.camel.component.graphql;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.http.BaseHttpTest;
+import org.apache.camel.component.http.handler.BasicValidationHandler;
+import org.apache.camel.http.base.HttpHeaderFilterStrategy;
+import org.apache.camel.spi.Registry;
+import org.apache.hc.core5.http.HeaderElements;
+import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
+import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
+import org.junit.jupiter.api.Test;
+
+import static org.apache.camel.component.http.HttpMethods.POST;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * Verify that registered 'HttpHeaderFilterStrategy' instances can be used to
allow specific headers.
+ */
+public class GraphqlHeaderFilterStrategyTest extends BaseHttpTest {
+
+ private HttpServer localServer;
+
+ @Override
+ public void setupResources() throws Exception {
+ localServer = ServerBootstrap.bootstrap()
+ .setCanonicalHostName("localhost")
+ .register("/graphql",
+ new BasicValidationHandler(POST.name(), null, null,
getExpectedContent()))
+ .create();
+ localServer.start();
+ }
+
+ @Override
+ public void cleanupResources() {
+ if (localServer != null) {
+ localServer.stop();
+ }
+ }
+
+ @Test
+ public void allowConnectionCloseHeader() {
+ Exchange exchange = template.request(
+ "direct:start1",
+ exchange1 -> {
+ exchange1.getIn().setHeader("connection",
HeaderElements.CLOSE);
+ });
+
+ assertEquals(HeaderElements.CLOSE,
exchange.getMessage().getHeader("connection"));
+ assertExchange(exchange);
+ }
+
+ @Test
+ public void allowWarningHeader() {
+ Exchange exchange2 = template.request(
+ "direct:start2",
+ exchange1 -> {
+ exchange1.getIn().setHeader("warning", "test warning");
+ });
+
+ assertEquals("test warning",
exchange2.getMessage().getHeader("warning"));
+ assertExchange(exchange2);
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ // multiple routes to verify registration of multiple
'headerFilterStrategy' instances
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+ from("direct:start1")
+ .to("graphql://http://localhost:" +
localServer.getLocalPort()
+ + "/graphql?query={books{id name}}"
+ +
"&headerFilterStrategy=#allowConnectionCloseFilter");
+
+ from("direct:start2")
+ .to("graphql://http://localhost:" +
localServer.getLocalPort()
+ + "/graphql?query={books{id name}}"
+ + "&headerFilterStrategy=#allowWarningFilter");
+ }
+ };
+ }
+
+ @Override
+ protected void bindToRegistry(Registry registry) {
+ registry.bind("allowConnectionCloseFilter", new
AllowConnectionCloseHeader());
+ registry.bind("allowWarningFilter", new AllowWarningHeader());
+ }
+
+ private static class AllowConnectionCloseHeader extends
HttpHeaderFilterStrategy {
+ @Override
+ protected void initialize() {
+ super.initialize();
+ getOutFilter().remove("connection");
+ }
+ }
+
+ private static class AllowWarningHeader extends HttpHeaderFilterStrategy {
+ @Override
+ protected void initialize() {
+ super.initialize();
+ getOutFilter().remove("warning");
+ }
+ }
+}
diff --git
a/components/camel-graphql/src/test/java/org/apache/camel/component/graphql/GraphqlProxyNonProxyHostsTest.java
b/components/camel-graphql/src/test/java/org/apache/camel/component/graphql/GraphqlProxyNonProxyHostsTest.java
new file mode 100644
index 000000000000..746d2bafd547
--- /dev/null
+++
b/components/camel-graphql/src/test/java/org/apache/camel/component/graphql/GraphqlProxyNonProxyHostsTest.java
@@ -0,0 +1,88 @@
+/*
+ * 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.camel.component.graphql;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.http.BaseHttpTest;
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.HttpStatus;
+import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
+import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
+import org.apache.hc.core5.http.io.HttpRequestHandler;
+import org.apache.hc.core5.http.io.entity.StringEntity;
+import org.apache.hc.core5.http.protocol.HttpContext;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * Verify the 'AuthClientConfigurer' 'proxyHost' configuration.
+ */
+public class GraphqlProxyNonProxyHostsTest extends BaseHttpTest {
+
+ private final AtomicInteger proxyRequestCount = new AtomicInteger(0);
+ private HttpServer proxy;
+
+ @BeforeEach
+ @Override
+ public void setupResources() throws Exception {
+ proxy = ServerBootstrap.bootstrap()
+ .setHttpProcessor(getBasicHttpProcessor())
+ .setRequestRouter((request, context) -> new
ProxyServerHandler())
+ .create();
+ proxy.start();
+ }
+
+ @AfterEach
+ @Override
+ public void cleanupResources() {
+ if (proxy != null) {
+ proxy.stop();
+ }
+ }
+
+ @Test
+ public void usesProxyWhenConfigured() {
+ proxyRequestCount.set(0);
+
+ Exchange exchange = template.request(
+ // placeholder localhost port since proxy returns a dummy
response
+ "graphql://http://localhost:8080"
+ + "/graphql?query={books{id
name}}"
+ + "&proxyHost=127.0.0.1:" +
proxy.getLocalPort(),
+ exchange1 -> {
+ });
+
+ assertExchange(exchange);
+ assertEquals(1, proxyRequestCount.get());
+ }
+
+ private class ProxyServerHandler implements HttpRequestHandler {
+ @Override
+ public void handle(
+ ClassicHttpRequest request, ClassicHttpResponse response,
HttpContext context) {
+ proxyRequestCount.incrementAndGet();
+ response.setCode(HttpStatus.SC_SUCCESS);
+ response.setEntity(new StringEntity(getExpectedContent()));
+ }
+ }
+}
diff --git
a/components/camel-graphql/src/test/java/org/apache/camel/component/graphql/GraphqlThrowExceptionOnFailureTest.java
b/components/camel-graphql/src/test/java/org/apache/camel/component/graphql/GraphqlThrowExceptionOnFailureTest.java
new file mode 100644
index 000000000000..e288ea87230b
--- /dev/null
+++
b/components/camel-graphql/src/test/java/org/apache/camel/component/graphql/GraphqlThrowExceptionOnFailureTest.java
@@ -0,0 +1,102 @@
+/*
+ * 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.camel.component.graphql;
+
+import java.util.Map;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.http.BaseHttpTest;
+import org.apache.camel.component.http.handler.BasicValidationHandler;
+import org.apache.camel.http.base.HttpOperationFailedException;
+import org.apache.hc.core5.http.HttpStatus;
+import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
+import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
+import org.junit.jupiter.api.Test;
+
+import static org.apache.camel.component.http.HttpMethods.POST;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+/**
+ * Verify the 'throwExceptionOnFailure' option.
+ */
+public class GraphqlThrowExceptionOnFailureTest extends BaseHttpTest {
+
+ private HttpServer localServer;
+ private String baseUrl;
+
+ @Override
+ public void setupResources() throws Exception {
+ localServer = ServerBootstrap.bootstrap()
+ .setCanonicalHostName("localhost")
+ .register("/",
+ new BasicValidationHandler(POST.name(), null, null,
getExpectedContent()))
+ .create();
+ localServer.start();
+ baseUrl = "graphql://http://localhost:" + localServer.getLocalPort();
+ }
+
+ @Override
+ public void cleanupResources() {
+ if (localServer != null) {
+ localServer.stop();
+ }
+ }
+
+ @Test
+ public void shouldNotThrowExceptionOnFailure() {
+ Exchange exchange
+ = template.request(baseUrl + "/xxx?query={books{id
name}}&throwExceptionOnFailure=false",
+ exchange1 -> {
+ });
+
+ assertNotNull(exchange);
+
+ Message out = exchange.getMessage();
+ assertNotNull(out);
+
+ Map<String, Object> headers = out.getHeaders();
+ assertEquals(HttpStatus.SC_NOT_IMPLEMENTED,
headers.get(Exchange.HTTP_RESPONSE_CODE));
+ assertEquals("0", headers.get("Content-Length"));
+ }
+
+ @Test
+ public void shouldThrowExceptionOnFailure() {
+ Exchange exchange = template.request(baseUrl
+ + "/xxx?query={books{id
name}}&throwExceptionOnFailure=true",
+ exchange1 -> {
+ exchange1.getMessage().setHeader("cheese", "gauda");
+ });
+
+ Exception ex = exchange.getException();
+ assertNotNull(ex, "Should have thrown an exception");
+
+ HttpOperationFailedException cause =
assertInstanceOf(HttpOperationFailedException.class, ex);
+ assertEquals(HttpStatus.SC_NOT_IMPLEMENTED, cause.getStatusCode());
+
+ Message out = exchange.getMessage();
+ assertNotNull(out);
+
+ Map<String, Object> headers = out.getHeaders();
+ assertEquals(HttpStatus.SC_NOT_IMPLEMENTED,
headers.get(Exchange.HTTP_RESPONSE_CODE));
+ assertEquals("Not Implemented",
headers.get(Exchange.HTTP_RESPONSE_TEXT));
+ // header should be preserved
+ assertEquals("gauda", out.getHeaders().get("cheese"));
+ }
+}
diff --git
a/components/camel-graphql/src/test/java/org/apache/camel/component/graphql/GraphqlTokenAuthenticationTest.java
b/components/camel-graphql/src/test/java/org/apache/camel/component/graphql/GraphqlTokenAuthenticationTest.java
new file mode 100644
index 000000000000..07e3a1008823
--- /dev/null
+++
b/components/camel-graphql/src/test/java/org/apache/camel/component/graphql/GraphqlTokenAuthenticationTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.camel.component.graphql;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.graphql.handler.BearerTokenValidationHandler;
+import org.apache.camel.component.http.BaseHttpTest;
+import org.apache.hc.core5.http.HttpRequestInterceptor;
+import org.apache.hc.core5.http.HttpResponseInterceptor;
+import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
+import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
+import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
+import org.apache.hc.core5.http.protocol.HttpProcessor;
+import org.apache.hc.core5.http.protocol.RequestValidateHost;
+import org.apache.hc.core5.http.protocol.ResponseContent;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Verify 'AuthClientConfigurer' instances registered with an accessToken.
+ */
+public class GraphqlTokenAuthenticationTest extends BaseHttpTest {
+
+ private final String accessToken = "accessToken";
+ private HttpServer localServer;
+
+ @Override
+ public void setupResources() throws Exception {
+ localServer = ServerBootstrap.bootstrap()
+ .setCanonicalHostName("localhost")
+ .setHttpProcessor(getBasicHttpProcessor())
+ .register("/graphql", new
BearerTokenValidationHandler(accessToken, getExpectedContent()))
+ .create();
+ localServer.start();
+ }
+
+ @Override
+ public void cleanupResources() {
+ if (localServer != null) {
+ localServer.stop();
+ }
+ }
+
+ @Test
+ public void bearerTokenAuthenticationShouldSucceed() {
+ Exchange exchange = template.request(
+ "graphql://http://localhost:" + localServer.getLocalPort()
+ + "/graphql?query={books{id
name}}"
+ + "&accessToken=" + accessToken,
+ exchange1 -> {
+ });
+
+ assertExchange(exchange);
+ }
+
+ @Override
+ protected HttpProcessor getBasicHttpProcessor() {
+ List<HttpRequestInterceptor> requestInterceptors
+ = Collections.singletonList(new RequestValidateHost());
+ List<HttpResponseInterceptor> responseInterceptors
+ = Collections.singletonList(new ResponseContent());
+
+ return new DefaultHttpProcessor(requestInterceptors,
responseInterceptors);
+ }
+}
diff --git
a/components/camel-graphql/src/test/java/org/apache/camel/component/graphql/handler/BearerTokenValidationHandler.java
b/components/camel-graphql/src/test/java/org/apache/camel/component/graphql/handler/BearerTokenValidationHandler.java
new file mode 100644
index 000000000000..6625407ffc3b
--- /dev/null
+++
b/components/camel-graphql/src/test/java/org/apache/camel/component/graphql/handler/BearerTokenValidationHandler.java
@@ -0,0 +1,54 @@
+/*
+ * 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.camel.component.graphql.handler;
+
+import java.nio.charset.StandardCharsets;
+
+import org.apache.hc.core5.http.ClassicHttpRequest;
+import org.apache.hc.core5.http.ClassicHttpResponse;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpHeaders;
+import org.apache.hc.core5.http.HttpStatus;
+import org.apache.hc.core5.http.io.HttpRequestHandler;
+import org.apache.hc.core5.http.io.entity.StringEntity;
+import org.apache.hc.core5.http.protocol.HttpContext;
+
+public class BearerTokenValidationHandler implements HttpRequestHandler {
+
+ private final String expectedToken;
+ private final String content;
+
+ public BearerTokenValidationHandler(String expectedToken, String content) {
+ this.expectedToken = expectedToken;
+ this.content = content;
+ }
+
+ @Override
+ public void handle(ClassicHttpRequest request, ClassicHttpResponse
response, HttpContext context)
+ throws HttpException {
+
+ Header header = request.getHeader(HttpHeaders.AUTHORIZATION);
+ String auth = header != null ? header.getValue() : null;
+ if (auth == null || !auth.equals("Bearer " + expectedToken)) {
+ response.setCode(HttpStatus.SC_UNAUTHORIZED);
+ return;
+ }
+ response.setCode(HttpStatus.SC_OK);
+ response.setEntity(new StringEntity(content,
StandardCharsets.US_ASCII));
+ }
+}
diff --git a/components/camel-http/pom.xml b/components/camel-http/pom.xml
index 022fa5c3a11a..a5374236ae4f 100644
--- a/components/camel-http/pom.xml
+++ b/components/camel-http/pom.xml
@@ -164,6 +164,22 @@
</execution>
</executions>
</plugin>
+ <!-- generate the attached tests jar -->
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>test-jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <excludes>
+ <exclude>log4j2.properties</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
</plugins>
</build>