From 4c33cfd747f11e08c2132063ba3c537d93782e51 Mon Sep 17 00:00:00 2001 From: Piotr Findeisen Date: Sun, 14 Apr 2024 03:29:12 +0200 Subject: [PATCH] Close HTTP client owned by MinioClient (#1546) --- .../main/java/io/minio/MinioAsyncClient.java | 11 ++++-- api/src/main/java/io/minio/MinioClient.java | 9 ++++- api/src/main/java/io/minio/S3Base.java | 38 ++++++++++++++++++- functional/TestUserAgent.java | 2 +- 4 files changed, 54 insertions(+), 6 deletions(-) diff --git a/api/src/main/java/io/minio/MinioAsyncClient.java b/api/src/main/java/io/minio/MinioAsyncClient.java index 405ecd589..a19cde085 100644 --- a/api/src/main/java/io/minio/MinioAsyncClient.java +++ b/api/src/main/java/io/minio/MinioAsyncClient.java @@ -139,7 +139,8 @@ private MinioAsyncClient( boolean useVirtualStyle, String region, Provider provider, - OkHttpClient httpClient) { + OkHttpClient httpClient, + boolean closeHttpClient) { super( baseUrl, awsS3Prefix, @@ -148,7 +149,8 @@ private MinioAsyncClient( useVirtualStyle, region, provider, - httpClient); + httpClient, + closeHttpClient); } protected MinioAsyncClient(MinioAsyncClient client) { @@ -3338,10 +3340,12 @@ public MinioAsyncClient build() { "Region missing in Amazon S3 China endpoint " + this.baseUrl); } + boolean closeHttpClient = false; if (this.httpClient == null) { this.httpClient = HttpUtils.newDefaultHttpClient( DEFAULT_CONNECTION_TIMEOUT, DEFAULT_CONNECTION_TIMEOUT, DEFAULT_CONNECTION_TIMEOUT); + closeHttpClient = true; } return new MinioAsyncClient( @@ -3352,7 +3356,8 @@ public MinioAsyncClient build() { useVirtualStyle, region, provider, - httpClient); + httpClient, + closeHttpClient); } } } diff --git a/api/src/main/java/io/minio/MinioClient.java b/api/src/main/java/io/minio/MinioClient.java index 0015d1728..5795c1180 100644 --- a/api/src/main/java/io/minio/MinioClient.java +++ b/api/src/main/java/io/minio/MinioClient.java @@ -95,7 +95,7 @@ * .build(); * } */ -public class MinioClient { +public class MinioClient implements AutoCloseable { private MinioAsyncClient asyncClient = null; private MinioClient(MinioAsyncClient asyncClient) { @@ -2450,6 +2450,13 @@ public void setAwsS3Prefix(String awsS3Prefix) { asyncClient.setAwsS3Prefix(awsS3Prefix); } + @Override + public void close() throws Exception { + if (asyncClient != null) { + asyncClient.close(); + } + } + public static Builder builder() { return new Builder(); } diff --git a/api/src/main/java/io/minio/S3Base.java b/api/src/main/java/io/minio/S3Base.java index f9aca6086..18115370e 100644 --- a/api/src/main/java/io/minio/S3Base.java +++ b/api/src/main/java/io/minio/S3Base.java @@ -99,7 +99,7 @@ import okhttp3.ResponseBody; /** Core S3 API client. */ -public abstract class S3Base { +public abstract class S3Base implements AutoCloseable { static { try { RequestBody.create(new byte[] {}, null); @@ -136,7 +136,10 @@ public abstract class S3Base { protected String region; protected Provider provider; protected OkHttpClient httpClient; + protected boolean closeHttpClient; + /** @deprecated This method is no longer supported. */ + @Deprecated protected S3Base( HttpUrl baseUrl, String awsS3Prefix, @@ -146,6 +149,28 @@ protected S3Base( String region, Provider provider, OkHttpClient httpClient) { + this( + baseUrl, + awsS3Prefix, + awsDomainSuffix, + awsDualstack, + useVirtualStyle, + region, + provider, + httpClient, + false); + } + + protected S3Base( + HttpUrl baseUrl, + String awsS3Prefix, + String awsDomainSuffix, + boolean awsDualstack, + boolean useVirtualStyle, + String region, + Provider provider, + OkHttpClient httpClient, + boolean closeHttpClient) { this.baseUrl = baseUrl; this.awsS3Prefix = awsS3Prefix; this.awsDomainSuffix = awsDomainSuffix; @@ -154,6 +179,7 @@ protected S3Base( this.region = region; this.provider = provider; this.httpClient = httpClient; + this.closeHttpClient = closeHttpClient; } /** @deprecated This method is no longer supported. */ @@ -182,6 +208,7 @@ protected S3Base( this.region = region; this.provider = provider; this.httpClient = httpClient; + this.closeHttpClient = false; } protected S3Base(S3Base client) { @@ -193,6 +220,7 @@ protected S3Base(S3Base client) { this.region = client.region; this.provider = client.provider; this.httpClient = client.httpClient; + this.closeHttpClient = client.closeHttpClient; } /** Check whether argument is valid or not. */ @@ -3757,4 +3785,12 @@ protected CompletableFuture uploadPartCopyAsync( } }); } + + @Override + public void close() throws Exception { + if (closeHttpClient) { + httpClient.dispatcher().executorService().shutdown(); + httpClient.connectionPool().evictAll(); + } + } } diff --git a/functional/TestUserAgent.java b/functional/TestUserAgent.java index fca96cfb1..51180f99f 100644 --- a/functional/TestUserAgent.java +++ b/functional/TestUserAgent.java @@ -23,7 +23,7 @@ public class TestUserAgent { public static void main(String[] args) throws Exception { - MinioClient client = MinioClient.builder().endpoint("http://example.org").build(); + MinioClient client = MinioClient.builder().endpoint("http://httpbin.org").build(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); client.traceOn(baos); client.bucketExists(BucketExistsArgs.builder().bucket("any-bucket-name-works").build());