This is an automated email from the ASF dual-hosted git repository.
lzljs3620320 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon.git
The following commit(s) were added to refs/heads/master by this push:
new df67c115d4 [core] Introduce HttpClientUtils to reuse methods
df67c115d4 is described below
commit df67c115d497f27ea45e64d2c1319abc313f04b4
Author: JingsongLi <[email protected]>
AuthorDate: Thu Jul 24 16:06:57 2025 +0800
[core] Introduce HttpClientUtils to reuse methods
---
.../java/org/apache/paimon/rest/HttpClient.java | 32 ++-------
.../org/apache/paimon/rest/HttpClientUtils.java | 77 ++++++++++++++++++++++
.../main/java/org/apache/paimon/rest/RESTUtil.java | 24 -------
.../org/apache/paimon/rest/SimpleHttpClient.java | 28 ++------
.../apache/paimon/rest/auth/DLFECSTokenLoader.java | 10 +--
.../actions/HttpReportMarkDoneAction.java | 9 +--
6 files changed, 92 insertions(+), 88 deletions(-)
diff --git a/paimon-api/src/main/java/org/apache/paimon/rest/HttpClient.java
b/paimon-api/src/main/java/org/apache/paimon/rest/HttpClient.java
index b8928786d9..a8a18a4155 100644
--- a/paimon-api/src/main/java/org/apache/paimon/rest/HttpClient.java
+++ b/paimon-api/src/main/java/org/apache/paimon/rest/HttpClient.java
@@ -23,7 +23,6 @@ import org.apache.paimon.rest.auth.RESTAuthFunction;
import org.apache.paimon.rest.auth.RESTAuthParameter;
import org.apache.paimon.rest.exceptions.RESTException;
import org.apache.paimon.rest.interceptor.LoggingInterceptor;
-import org.apache.paimon.rest.interceptor.TimingInterceptor;
import org.apache.paimon.rest.responses.ErrorResponse;
import org.apache.paimon.utils.StringUtils;
@@ -33,30 +32,24 @@ import
org.apache.hc.client5.http.classic.methods.HttpDelete;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase;
-import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
-import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
-import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.ParseException;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.http.message.BasicHeader;
-import org.apache.hc.core5.util.Timeout;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import java.util.function.Function;
+import static org.apache.paimon.rest.HttpClientUtils.createLoggingBuilder;
+
/** Apache HTTP client for REST catalog. */
public class HttpClient implements RESTClient {
- private static final CloseableHttpClient httpClient;
-
- static {
- httpClient = buildHttpClient();
- }
+ private static final CloseableHttpClient HTTP_CLIENT =
createLoggingBuilder().build();
private final String uri;
@@ -67,23 +60,6 @@ public class HttpClient implements RESTClient {
this.errorHandler = DefaultErrorHandler.getInstance();
}
- public static CloseableHttpClient buildHttpClient() {
- HttpClientBuilder clientBuilder = HttpClients.custom();
- RequestConfig requestConfig =
- RequestConfig.custom()
- .setConnectionRequestTimeout(Timeout.ofMinutes(3))
- .setResponseTimeout(Timeout.ofMinutes(3))
- .build();
- clientBuilder.setDefaultRequestConfig(requestConfig);
-
-
clientBuilder.setConnectionManager(RESTUtil.configureConnectionManager());
- clientBuilder.setRetryStrategy(new
ExponentialHttpRequestRetryStrategy(5));
- clientBuilder
- .addRequestInterceptorFirst(new TimingInterceptor())
- .addResponseInterceptorLast(new LoggingInterceptor());
- return clientBuilder.build();
- }
-
@Override
public <T extends RESTResponse> T get(
String path, Class<T> responseType, RESTAuthFunction
restAuthFunction) {
@@ -161,7 +137,7 @@ public class HttpClient implements RESTClient {
}
private <T extends RESTResponse> T exec(HttpUriRequestBase request,
Class<T> responseType) {
- try (CloseableHttpResponse response = httpClient.execute(request)) {
+ try (CloseableHttpResponse response = HTTP_CLIENT.execute(request)) {
String responseBodyStr =
RESTUtil.extractResponseBodyAsString(response);
if (!RESTUtil.isSuccessful(response)) {
ErrorResponse error;
diff --git
a/paimon-api/src/main/java/org/apache/paimon/rest/HttpClientUtils.java
b/paimon-api/src/main/java/org/apache/paimon/rest/HttpClientUtils.java
new file mode 100644
index 0000000000..28402eeadd
--- /dev/null
+++ b/paimon-api/src/main/java/org/apache/paimon/rest/HttpClientUtils.java
@@ -0,0 +1,77 @@
+/*
+ * 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.paimon.rest;
+
+import org.apache.paimon.rest.interceptor.LoggingInterceptor;
+import org.apache.paimon.rest.interceptor.TimingInterceptor;
+
+import org.apache.hc.client5.http.config.RequestConfig;
+import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
+import org.apache.hc.client5.http.impl.classic.HttpClients;
+import
org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
+import org.apache.hc.client5.http.io.HttpClientConnectionManager;
+import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
+import org.apache.hc.client5.http.ssl.HttpsSupport;
+import org.apache.hc.core5.reactor.ssl.SSLBufferMode;
+import org.apache.hc.core5.ssl.SSLContexts;
+import org.apache.hc.core5.util.Timeout;
+
+/** Utils for {@link HttpClientBuilder}. */
+public class HttpClientUtils {
+
+ public static HttpClientBuilder createLoggingBuilder() {
+ HttpClientBuilder clientBuilder = createBuilder();
+ clientBuilder
+ .addRequestInterceptorFirst(new TimingInterceptor())
+ .addResponseInterceptorLast(new LoggingInterceptor());
+ return clientBuilder;
+ }
+
+ public static HttpClientBuilder createBuilder() {
+ HttpClientBuilder clientBuilder = HttpClients.custom();
+ RequestConfig requestConfig =
+ RequestConfig.custom()
+ .setConnectionRequestTimeout(Timeout.ofMinutes(3))
+ .setResponseTimeout(Timeout.ofMinutes(3))
+ .build();
+ clientBuilder.setDefaultRequestConfig(requestConfig);
+
+ clientBuilder.setConnectionManager(configureConnectionManager());
+ clientBuilder.setRetryStrategy(new
ExponentialHttpRequestRetryStrategy(5));
+ return clientBuilder;
+ }
+
+ private static HttpClientConnectionManager configureConnectionManager() {
+ PoolingHttpClientConnectionManagerBuilder connectionManagerBuilder =
+ PoolingHttpClientConnectionManagerBuilder.create();
+
connectionManagerBuilder.useSystemProperties().setMaxConnTotal(100).setMaxConnPerRoute(100);
+
+ // support TLS
+ String[] tlsProtocols = {"TLSv1.2", "TLSv1.3"};
+ connectionManagerBuilder.setTlsSocketStrategy(
+ new DefaultClientTlsStrategy(
+ SSLContexts.createDefault(),
+ tlsProtocols,
+ null,
+ SSLBufferMode.STATIC,
+ HttpsSupport.getDefaultHostnameVerifier()));
+
+ return connectionManagerBuilder.build();
+ }
+}
diff --git a/paimon-api/src/main/java/org/apache/paimon/rest/RESTUtil.java
b/paimon-api/src/main/java/org/apache/paimon/rest/RESTUtil.java
index 651a134c8d..52a633b62a 100644
--- a/paimon-api/src/main/java/org/apache/paimon/rest/RESTUtil.java
+++ b/paimon-api/src/main/java/org/apache/paimon/rest/RESTUtil.java
@@ -28,16 +28,10 @@ import
org.apache.paimon.shade.guava30.com.google.common.collect.Maps;
import
org.apache.paimon.shade.jackson2.com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
-import
org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
-import org.apache.hc.client5.http.io.HttpClientConnectionManager;
-import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
-import org.apache.hc.client5.http.ssl.HttpsSupport;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.ParseException;
import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.net.URIBuilder;
-import org.apache.hc.core5.reactor.ssl.SSLBufferMode;
-import org.apache.hc.core5.ssl.SSLContexts;
import java.io.IOException;
import java.io.UncheckedIOException;
@@ -183,24 +177,6 @@ public class RESTUtil {
|| code == HttpStatus.SC_NO_CONTENT;
}
- public static HttpClientConnectionManager configureConnectionManager() {
- PoolingHttpClientConnectionManagerBuilder connectionManagerBuilder =
- PoolingHttpClientConnectionManagerBuilder.create();
-
connectionManagerBuilder.useSystemProperties().setMaxConnTotal(100).setMaxConnPerRoute(100);
-
- // support TLS
- String[] tlsProtocols = {"TLSv1.2", "TLSv1.3"};
- connectionManagerBuilder.setTlsSocketStrategy(
- new DefaultClientTlsStrategy(
- SSLContexts.createDefault(),
- tlsProtocols,
- null,
- SSLBufferMode.STATIC,
- HttpsSupport.getDefaultHostnameVerifier()));
-
- return connectionManagerBuilder.build();
- }
-
public static String buildRequestUrl(String url, Map<String, String>
queryParams) {
try {
if (queryParams != null && !queryParams.isEmpty()) {
diff --git
a/paimon-api/src/main/java/org/apache/paimon/rest/SimpleHttpClient.java
b/paimon-api/src/main/java/org/apache/paimon/rest/SimpleHttpClient.java
index 800bb83aef..e0e043fc1e 100644
--- a/paimon-api/src/main/java/org/apache/paimon/rest/SimpleHttpClient.java
+++ b/paimon-api/src/main/java/org/apache/paimon/rest/SimpleHttpClient.java
@@ -23,28 +23,28 @@ import org.apache.paimon.utils.StringUtils;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase;
-import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
-import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
-import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.Header;
import org.apache.hc.core5.http.ParseException;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.http.message.BasicHeader;
-import org.apache.hc.core5.util.Timeout;
import java.io.Closeable;
import java.io.IOException;
import java.util.Map;
-/** A simple client to wrap apache httpcompents client. */
+import static org.apache.paimon.rest.HttpClientUtils.createBuilder;
+
+/** A simple client to wrap {@link CloseableHttpClient}. */
public class SimpleHttpClient implements Closeable {
+ public static final SimpleHttpClient INSTANCE = new SimpleHttpClient();
+
private final CloseableHttpClient client;
- public SimpleHttpClient() {
- this.client = buildHttpClient();
+ private SimpleHttpClient() {
+ this.client = createBuilder().build();
}
public String post(String url, Object body, Map<String, String> headers)
throws IOException {
@@ -106,18 +106,4 @@ public class SimpleHttpClient implements Closeable {
throw new RuntimeException(e);
}
}
-
- private static CloseableHttpClient buildHttpClient() {
- HttpClientBuilder clientBuilder = HttpClients.custom();
- RequestConfig requestConfig =
- RequestConfig.custom()
- .setConnectionRequestTimeout(Timeout.ofMinutes(3))
- .setResponseTimeout(Timeout.ofMinutes(3))
- .build();
- clientBuilder.setDefaultRequestConfig(requestConfig);
-
-
clientBuilder.setConnectionManager(RESTUtil.configureConnectionManager());
- clientBuilder.setRetryStrategy(new
ExponentialHttpRequestRetryStrategy(5));
- return clientBuilder.build();
- }
}
diff --git
a/paimon-api/src/main/java/org/apache/paimon/rest/auth/DLFECSTokenLoader.java
b/paimon-api/src/main/java/org/apache/paimon/rest/auth/DLFECSTokenLoader.java
index 96a7815354..404cb49b8d 100644
---
a/paimon-api/src/main/java/org/apache/paimon/rest/auth/DLFECSTokenLoader.java
+++
b/paimon-api/src/main/java/org/apache/paimon/rest/auth/DLFECSTokenLoader.java
@@ -35,12 +35,6 @@ public class DLFECSTokenLoader implements DLFTokenLoader {
private static final Logger LOG =
LoggerFactory.getLogger(DLFECSTokenLoader.class);
- private static final SimpleHttpClient client;
-
- static {
- client = new SimpleHttpClient();
- }
-
private final String ecsMetadataURL;
private String roleName;
@@ -73,7 +67,7 @@ public class DLFECSTokenLoader implements DLFTokenLoader {
private static DLFToken getToken(String url) {
try {
- String token = client.get(url);
+ String token = SimpleHttpClient.INSTANCE.get(url);
return RESTApi.fromJson(token, DLFToken.class);
} catch (IOException e) {
throw new UncheckedIOException(e);
@@ -86,7 +80,7 @@ public class DLFECSTokenLoader implements DLFTokenLoader {
protected static String getResponseBody(String url) {
long startTime = System.currentTimeMillis();
try {
- String responseBodyStr = client.get(url);
+ String responseBodyStr = SimpleHttpClient.INSTANCE.get(url);
if (LOG.isDebugEnabled()) {
LOG.debug(
"get response success, url : {}, cost : {} ms",
diff --git
a/paimon-core/src/main/java/org/apache/paimon/partition/actions/HttpReportMarkDoneAction.java
b/paimon-core/src/main/java/org/apache/paimon/partition/actions/HttpReportMarkDoneAction.java
index bbe4a8001d..43fcf7c998 100644
---
a/paimon-core/src/main/java/org/apache/paimon/partition/actions/HttpReportMarkDoneAction.java
+++
b/paimon-core/src/main/java/org/apache/paimon/partition/actions/HttpReportMarkDoneAction.java
@@ -42,7 +42,6 @@ import static
org.apache.paimon.CoreOptions.PARTITION_MARK_DONE_ACTION_URL;
/** Report partition submission information to remote http server. */
public class HttpReportMarkDoneAction implements PartitionMarkDoneAction {
- private SimpleHttpClient client;
private String url;
private ObjectMapper mapper;
@@ -72,8 +71,6 @@ public class HttpReportMarkDoneAction implements
PartitionMarkDoneAction {
this.mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
false);
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
-
- this.client = new SimpleHttpClient();
}
@Override
@@ -95,9 +92,7 @@ public class HttpReportMarkDoneAction implements
PartitionMarkDoneAction {
}
@Override
- public void close() throws IOException {
- client.close();
- }
+ public void close() throws IOException {}
/** RestRequest only for HttpReportMarkDoneAction. */
@JsonIgnoreProperties(ignoreUnknown = true)
@@ -175,7 +170,7 @@ public class HttpReportMarkDoneAction implements
PartitionMarkDoneAction {
public HttpReportMarkDoneResponse post(
HttpReportMarkDoneRequest body, Map<String, String> headers)
throws IOException {
- String responseBodyStr = this.client.post(url, body, headers);
+ String responseBodyStr = SimpleHttpClient.INSTANCE.post(url, body,
headers);
return mapper.readValue(responseBodyStr,
HttpReportMarkDoneResponse.class);
}
}