View Javadoc
1   /*
2    * Copyright 2020-2026 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.bremersee.minio;
18  
19  import io.minio.BucketExistsArgs;
20  import io.minio.CloseableIterator;
21  import io.minio.ComposeObjectArgs;
22  import io.minio.CopyObjectArgs;
23  import io.minio.DeleteBucketCorsArgs;
24  import io.minio.DeleteBucketEncryptionArgs;
25  import io.minio.DeleteBucketLifecycleArgs;
26  import io.minio.DeleteBucketNotificationArgs;
27  import io.minio.DeleteBucketPolicyArgs;
28  import io.minio.DeleteBucketReplicationArgs;
29  import io.minio.DeleteBucketTagsArgs;
30  import io.minio.DeleteObjectLockConfigurationArgs;
31  import io.minio.DeleteObjectTagsArgs;
32  import io.minio.DisableObjectLegalHoldArgs;
33  import io.minio.DownloadObjectArgs;
34  import io.minio.EnableObjectLegalHoldArgs;
35  import io.minio.GetBucketCorsArgs;
36  import io.minio.GetBucketEncryptionArgs;
37  import io.minio.GetBucketLifecycleArgs;
38  import io.minio.GetBucketNotificationArgs;
39  import io.minio.GetBucketPolicyArgs;
40  import io.minio.GetBucketReplicationArgs;
41  import io.minio.GetBucketTagsArgs;
42  import io.minio.GetBucketVersioningArgs;
43  import io.minio.GetObjectAclArgs;
44  import io.minio.GetObjectArgs;
45  import io.minio.GetObjectAttributesArgs;
46  import io.minio.GetObjectAttributesResponse;
47  import io.minio.GetObjectLockConfigurationArgs;
48  import io.minio.GetObjectRetentionArgs;
49  import io.minio.GetObjectTagsArgs;
50  import io.minio.GetPresignedObjectUrlArgs;
51  import io.minio.IsObjectLegalHoldEnabledArgs;
52  import io.minio.ListBucketsArgs;
53  import io.minio.ListObjectsArgs;
54  import io.minio.ListenBucketNotificationArgs;
55  import io.minio.MakeBucketArgs;
56  import io.minio.MinioClient;
57  import io.minio.ObjectWriteResponse;
58  import io.minio.PostPolicy;
59  import io.minio.PromptObjectArgs;
60  import io.minio.PromptObjectResponse;
61  import io.minio.PutObjectArgs;
62  import io.minio.PutObjectFanOutArgs;
63  import io.minio.PutObjectFanOutResponse;
64  import io.minio.RemoveBucketArgs;
65  import io.minio.RemoveObjectArgs;
66  import io.minio.RemoveObjectsArgs;
67  import io.minio.RestoreObjectArgs;
68  import io.minio.Result;
69  import io.minio.SelectObjectContentArgs;
70  import io.minio.SelectResponseStream;
71  import io.minio.SetBucketCorsArgs;
72  import io.minio.SetBucketEncryptionArgs;
73  import io.minio.SetBucketLifecycleArgs;
74  import io.minio.SetBucketNotificationArgs;
75  import io.minio.SetBucketPolicyArgs;
76  import io.minio.SetBucketReplicationArgs;
77  import io.minio.SetBucketTagsArgs;
78  import io.minio.SetBucketVersioningArgs;
79  import io.minio.SetObjectLockConfigurationArgs;
80  import io.minio.SetObjectRetentionArgs;
81  import io.minio.SetObjectTagsArgs;
82  import io.minio.StatObjectArgs;
83  import io.minio.StatObjectResponse;
84  import io.minio.UploadObjectArgs;
85  import io.minio.messages.AccessControlPolicy;
86  import io.minio.messages.CORSConfiguration;
87  import io.minio.messages.DeleteResult;
88  import io.minio.messages.Item;
89  import io.minio.messages.LifecycleConfiguration;
90  import io.minio.messages.ListAllMyBucketsResult;
91  import io.minio.messages.NotificationConfiguration;
92  import io.minio.messages.NotificationRecords;
93  import io.minio.messages.ObjectLockConfiguration;
94  import io.minio.messages.ReplicationConfiguration;
95  import io.minio.messages.Retention;
96  import io.minio.messages.SseConfiguration;
97  import io.minio.messages.Tags;
98  import io.minio.messages.VersioningConfiguration;
99  import java.io.InputStream;
100 import java.nio.file.Files;
101 import java.nio.file.Path;
102 import java.nio.file.Paths;
103 import java.util.List;
104 import java.util.Map;
105 import java.util.Optional;
106 
107 /**
108  * The minio operations.
109  *
110  * @author Christian Bremer
111  */
112 public interface MinioOperations {
113 
114   /**
115    * Execute minio callback.
116    *
117    * @param <T> the type of the result
118    * @param callback the callback
119    * @return the result
120    */
121   <T> T execute(MinioClientCallback<T> callback);
122 
123   // Bucket operations
124 
125   /**
126    * Checks if a bucket exists.
127    *
128    * <p>Example:
129    * <pre>
130    * boolean found = minioClient
131    *     .bucketExists(BucketExistsArgs.builder().bucket("my-bucketname").build());
132    * if (found) {
133    *   System.out.println("my-bucketname exists");
134    * } else {
135    *   System.out.println("my-bucketname does not exist");
136    * }
137    * </pre>
138    *
139    * @param args the bucket exists arguments
140    * @return true if the bucket exists
141    */
142   default boolean bucketExists(BucketExistsArgs args) {
143     return execute(minioClient -> minioClient.bucketExists(args));
144   }
145 
146   /**
147    * Deletes CORS configuration of a bucket.
148    *
149    * <p>Example:
150    * <pre>
151    * minioClient.deleteBucketCors(DeleteBucketCorsArgs.builder().bucket("my-bucketname").build());
152    * </pre>
153    *
154    * @param args {@link DeleteBucketCorsArgs} object.
155    */
156   default void deleteBucketCors(DeleteBucketCorsArgs args) {
157     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
158         .deleteBucketCors(args));
159   }
160 
161   /**
162    * Deletes encryption configuration of a bucket.
163    *
164    * <p>Example:
165    * <pre>
166    * minioClient.deleteBucketEncryption(
167    *     DeleteBucketEncryptionArgs.builder().bucket("my-bucketname").build());
168    * </pre>
169    *
170    * @param args delete bucket encryption arguments
171    */
172   default void deleteBucketEncryption(DeleteBucketEncryptionArgs args) {
173     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
174         .deleteBucketEncryption(args));
175   }
176 
177   /**
178    * Deletes lifecycle configuration of a bucket.
179    *
180    * <p>Example:
181    * <pre>
182    * deleteBucketLifecycle(DeleteBucketLifecycleArgs.builder().bucket("my-bucketname").build());
183    * </pre>
184    *
185    * @param args {@link DeleteBucketLifecycleArgs} object.
186    */
187   default void deleteBucketLifecycle(DeleteBucketLifecycleArgs args) {
188     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
189         .deleteBucketLifecycle(args));
190   }
191 
192   /**
193    * Deletes tags of a bucket.
194    *
195    * <p>Example:
196    * <pre>
197    * minioClient.deleteBucketTags(DeleteBucketTagsArgs.builder().bucket("my-bucketname").build());
198    * </pre>
199    *
200    * @param args the delete bucket tags arguments
201    */
202   default void deleteBucketTags(DeleteBucketTagsArgs args) {
203     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
204         .deleteBucketTags(args));
205   }
206 
207   /**
208    * Deletes bucket policy configuration to a bucket.
209    *
210    * <p>Example:
211    * <pre>
212    * minioClient.deleteBucketPolicy(DeleteBucketPolicyArgs.builder().bucket("my-bucketname"));
213    * </pre>
214    *
215    * @param args delete bucket policy arguments
216    */
217   default void deleteBucketPolicy(DeleteBucketPolicyArgs args) {
218     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
219         .deleteBucketPolicy(args));
220   }
221 
222   /**
223    * Deletes bucket replication configuration from a bucket.
224    *
225    * <p>Example:
226    * <pre>
227    * minioClient.deleteBucketReplication(
228    *     DeleteBucketReplicationArgs.builder().bucket("my-bucketname"));
229    * </pre>
230    *
231    * @param args delete bucket replication arguments
232    */
233   default void deleteBucketReplication(DeleteBucketReplicationArgs args) {
234     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
235         .deleteBucketReplication(args));
236   }
237 
238   /**
239    * Deletes notification configuration of a bucket.
240    *
241    * <p>Example:
242    * <pre>
243    * minioClient.deleteBucketNotification(
244    *     DeleteBucketNotificationArgs.builder().bucket("my-bucketname").build());
245    * </pre>
246    *
247    * @param args delete bucket notification arguments
248    */
249   default void deleteBucketNotification(DeleteBucketNotificationArgs args) {
250     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
251         .deleteBucketNotification(args));
252   }
253 
254   /**
255    * Deletes default object retention in a bucket.
256    *
257    * <p>Example:
258    * <pre>
259    * minioClient.deleteObjectLockConfiguration(
260    *     DeleteObjectLockConfigurationArgs.builder().bucket("my-bucketname").build());
261    * </pre>
262    *
263    * @param args delete object retention configuration arguments
264    */
265   default void deleteObjectLockConfiguration(DeleteObjectLockConfigurationArgs args) {
266     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
267         .deleteObjectLockConfiguration(args));
268   }
269 
270   /**
271    * Gets CORS configuration of a bucket.
272    *
273    * <p>Example:
274    * <pre>
275    * CORSConfiguration config =
276    *     minioClient.getBucketCors(GetBucketCorsArgs.builder().bucket("my-bucketname").build());
277    * </pre>
278    *
279    * @param args {@link GetBucketCorsArgs} object.
280    * @return {@link CORSConfiguration} - CORSConfiguration.
281    */
282   default CORSConfiguration getBucketCors(GetBucketCorsArgs args) {
283     return execute(minioClient -> minioClient.getBucketCors(args));
284   }
285 
286   /**
287    * Gets encryption configuration of a bucket.
288    *
289    * <p>Example:
290    * <pre>
291    * SseConfiguration config =
292    *     minioClient.getBucketEncryption(
293    *         GetBucketEncryptionArgs.builder().bucket("my-bucketname").build());
294    * </pre>
295    *
296    * @param args get bucket encryption arguments
297    * @return server -side encryption configuration
298    */
299   default SseConfiguration getBucketEncryption(GetBucketEncryptionArgs args) {
300     return execute(minioClient -> minioClient.getBucketEncryption(args));
301   }
302 
303   /**
304    * Gets lifecycle configuration of a bucket.
305    *
306    * <p>Example:
307    * <pre>
308    * LifecycleConfiguration config =
309    *     minioClient.getBucketLifecycle(
310    *         GetBucketLifecycleArgs.builder().bucket("my-bucketname").build());
311    * </pre>
312    *
313    * @param args get bucket lifecycle arguments
314    * @return the lifecycle configuration
315    */
316   default Optional<LifecycleConfiguration> getBucketLifecycle(GetBucketLifecycleArgs args) {
317     return execute(minioClient -> Optional.ofNullable(minioClient.getBucketLifecycle(args)));
318   }
319 
320   /**
321    * Gets notification configuration of a bucket.
322    *
323    * <p>Example:
324    * <pre>
325    * NotificationConfiguration config =
326    *     minioClient.getBucketNotification(
327    *         GetBucketNotificationArgs.builder().bucket("my-bucketname").build());
328    * </pre>
329    *
330    * @param args get bucket notification arguments
331    * @return the notification configuration
332    */
333   default NotificationConfiguration getBucketNotification(GetBucketNotificationArgs args) {
334     return execute(minioClient -> minioClient.getBucketNotification(args));
335   }
336 
337   /**
338    * Gets bucket policy configuration of a bucket.
339    *
340    * <p>Example:
341    * <pre>
342    * String config =
343    *     minioClient.getBucketPolicy(GetBucketPolicyArgs.builder().bucket("my-bucketname").build());
344    * </pre>
345    *
346    * @param args get bucket policy arguments
347    * @return bucket policy configuration as JSON string
348    */
349   default String getBucketPolicy(GetBucketPolicyArgs args) {
350     return execute(minioClient -> minioClient.getBucketPolicy(args));
351   }
352 
353   /**
354    * Gets bucket replication configuration of a bucket.
355    *
356    * <p>Example:
357    * <pre>
358    * ReplicationConfiguration config =
359    *     minioClient.getBucketReplication(
360    *         GetBucketReplicationArgs.builder().bucket("my-bucketname").build());
361    * </pre>
362    *
363    * @param args get bucket replication arguments
364    * @return the replication configuration
365    */
366   default Optional<ReplicationConfiguration> getBucketReplication(GetBucketReplicationArgs args) {
367     return execute(minioClient -> Optional.ofNullable(minioClient.getBucketReplication(args)));
368   }
369 
370   /**
371    * Gets tags of a bucket.
372    *
373    * <p>Example:
374    * <pre>
375    * Tags tags =
376    *     minioClient.getBucketTags(GetBucketTagsArgs.builder().bucket("my-bucketname").build());
377    * </pre>
378    *
379    * @param args get bucket tags arguments
380    * @return the tags
381    */
382   default Tags getBucketTags(GetBucketTagsArgs args) {
383     return execute(minioClient -> minioClient.getBucketTags(args));
384   }
385 
386   /**
387    * Gets versioning configuration of a bucket.
388    *
389    * <p>Example:
390    * <pre>
391    * VersioningConfiguration config =
392    *     minioClient.getBucketVersioning(
393    *         GetBucketVersioningArgs.builder().bucket("my-bucketname").build());
394    * </pre>
395    *
396    * @param args get bucket version arguments
397    * @return the versioning configuration.
398    */
399   default VersioningConfiguration getBucketVersioning(GetBucketVersioningArgs args) {
400     return execute(minioClient -> minioClient.getBucketVersioning(args));
401   }
402 
403   /**
404    * Gets default object retention in a bucket.
405    *
406    * <p>Example:
407    * <pre>
408    * ObjectLockConfiguration config =
409    *     minioClient.getObjectLockConfiguration(
410    *         GetObjectLockConfigurationArgs.builder().bucket("my-bucketname").build());
411    * System.out.println("Mode: " + config.mode());
412    * System.out.println(
413    *     "Duration: " + config.duration().duration() + " " + config.duration().unit());
414    * </pre>
415    *
416    * @param args get object retention configuration arguments
417    * @return the default retention configuration
418    */
419   default ObjectLockConfiguration getObjectLockConfiguration(GetObjectLockConfigurationArgs args) {
420     return execute(minioClient -> minioClient.getObjectLockConfiguration(args));
421   }
422 
423   /**
424    * Lists bucket information of all buckets.
425    *
426    * <p>Example:
427    * <pre>
428    * List&lt;ListAllMyBucketsResult.Bucket&gt; bucketList = minioOperations.listBuckets();
429    * for (ListAllMyBucketsResult.Bucket bucket : bucketList) {
430    *   System.out.println(bucket.creationDate() + ", " + bucket.name());
431    * }
432    * </pre>
433    *
434    * @return list of bucket information
435    */
436   default List<ListAllMyBucketsResult.Bucket> listBuckets() {
437     return execute(MinioClient::listBuckets);
438   }
439 
440   /**
441    * Lists bucket information of all buckets.
442    *
443    * <p>Example:
444    * <pre>
445    * Iterable&lt;Result&lt;ListAllMyBucketsResult.Bucket&gt;&gt; results = minioClient
446    *     .listBuckets(ListBucketsArgs.builder().extraHeaders(headers).build());
447    * for (Result&lt;ListAllMyBucketsResult.Bucket&gt; result : results) {
448    *   System.out.println(result.get().creationDate() + ", " + result.get().name());
449    * }
450    * </pre>
451    *
452    * @param args the list buckets arguments
453    * @return list of bucket information
454    */
455   default Iterable<Result<ListAllMyBucketsResult.Bucket>> listBuckets(ListBucketsArgs args) {
456     return execute(minioClient -> minioClient.listBuckets(args));
457   }
458 
459   /**
460    * Listens events of object prefix and suffix of a bucket. The returned closable iterator is
461    * lazily evaluated hence its required to iterate to get new records and must be used with
462    * try-with-resource to release underneath network resources.
463    *
464    * <p>Example:
465    * <pre>
466    * String[] events = {"s3:ObjectCreated:*", "s3:ObjectAccessed:*"};
467    * try (CloseableIterator&lt;Result&lt;NotificationRecords&gt;&gt; ci =
468    *     minioClient.listenBucketNotification(
469    *         ListenBucketNotificationArgs.builder()
470    *             .bucket("bucketName")
471    *             .prefix("")
472    *             .suffix("")
473    *             .events(events)
474    *             .build())) {
475    *   while (ci.hasNext()) {
476    *     NotificationRecords records = ci.next().get();
477    *     for (Event event : records.events()) {
478    *       System.out.println("Event " + event.eventType() + " occurred at "
479    *           + event.eventTime() + " for " + event.bucketName() + "/"
480    *           + event.objectName());
481    *     }
482    *   }
483    * }
484    * </pre>
485    *
486    * @param args the listen bucket notification arguments
487    * @return lazy closable iterator contains event records
488    */
489   default CloseableIterator<Result<NotificationRecords>> listenBucketNotification(
490       ListenBucketNotificationArgs args) {
491     return execute(minioClient -> minioClient.listenBucketNotification(args));
492   }
493 
494   /**
495    * Creates a bucket with region and object lock.
496    *
497    * <p>Example:
498    * <pre>
499    * // Create bucket with default region.
500    * minioClient.makeBucket(
501    *     MakeBucketArgs.builder()
502    *         .bucket("my-bucketname")
503    *         .build());
504    *
505    * // Create bucket with specific region.
506    * minioClient.makeBucket(
507    *     MakeBucketArgs.builder()
508    *         .bucket("my-bucketname")
509    *         .region("us-west-1")
510    *         .build());
511    *
512    * // Create object-lock enabled bucket with specific region.
513    * minioClient.makeBucket(
514    *     MakeBucketArgs.builder()
515    *         .bucket("my-bucketname")
516    *         .region("us-west-1")
517    *         .objectLock(true)
518    *         .build());
519    * </pre>
520    *
521    * @param args object with bucket name, region and lock functionality
522    */
523   default void makeBucket(MakeBucketArgs args) {
524     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
525         .makeBucket(args));
526   }
527 
528   /**
529    * Removes an empty bucket using arguments.
530    *
531    * <p>Example:
532    * <pre>
533    * minioClient.removeBucket(RemoveBucketArgs.builder().bucket("my-bucketname").build());
534    * </pre>
535    *
536    * @param args the remove bucket arguments
537    */
538   default void removeBucket(RemoveBucketArgs args) {
539     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
540         .removeBucket(args));
541   }
542 
543   /**
544    * Sets CORS configuration to a bucket.
545    *
546    * <p>Example:
547    * <pre>
548    * CORSConfiguration config =
549    *     new CORSConfiguration(
550    *         Arrays.asList(
551    *             new CORSConfiguration.CORSRule[] {
552    *               // Rule 1
553    *               new CORSConfiguration.CORSRule(
554    *                   Arrays.asList(new String[] {"*"}), // Allowed headers
555    *                   Arrays.asList(new String[] {"PUT", "POST", "DELETE"}), // Allowed methods
556    *                   Arrays.asList(new String[] {"https://www.example.com"}), // Allowed origins
557    *                   Arrays.asList(
558    *                       new String[] {"x-amz-server-side-encryption"}), // Expose headers
559    *                   null, // ID
560    *                   3000), // Maximum age seconds
561    *               // Rule 2
562    *               new CORSConfiguration.CORSRule(
563    *                   null, // Allowed headers
564    *                   Arrays.asList(new String[] {"GET"}), // Allowed methods
565    *                   Arrays.asList(new String[] {"*"}), // Allowed origins
566    *                   null, // Expose headers
567    *                   null, // ID
568    *                   null // Maximum age seconds
569    *                   )
570    *             }));
571    * minioClient.setBucketCors(
572    *     SetBucketCorsArgs.builder().bucket("my-bucketname").config(config).build());
573    * </pre>
574    *
575    * @param args {@link SetBucketCorsArgs} object.
576    */
577   @SuppressWarnings("JavadocLinkAsPlainText")
578   default void setBucketCors(SetBucketCorsArgs args) {
579     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
580         .setBucketCors(args));
581   }
582 
583   /**
584    * Sets encryption configuration of a bucket.
585    *
586    * <p>Example:
587    * <pre>
588    * minioClient.setBucketEncryption(
589    *     SetBucketEncryptionArgs.builder().bucket("my-bucketname").config(config).build());
590    * </pre>
591    *
592    * @param args bucket encryption arguments
593    */
594   default void setBucketEncryption(SetBucketEncryptionArgs args) {
595     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
596         .setBucketEncryption(args));
597   }
598 
599   /**
600    * Sets lifecycle configuration to a bucket.
601    *
602    * <p>Example:
603    * <pre>
604    * List&lt;LifecycleRule&gt; rules = new LinkedList&lt;&gt;();
605    * rules.add(
606    *     new LifecycleRule(
607    *         Status.ENABLED,
608    *         null,
609    *         new Expiration((ZonedDateTime) null, 365, null),
610    *         new RuleFilter("logs/"),
611    *         "rule2",
612    *         null,
613    *         null,
614    *         null));
615    * LifecycleConfiguration config = new LifecycleConfiguration(rules);
616    * minioClient.setBucketLifecycle(
617    *     SetBucketLifecycleArgs.builder().bucket("my-bucketname").config(config).build());
618    * </pre>
619    *
620    * @param args set bucket lifecycle arguments
621    */
622   default void setBucketLifecycle(SetBucketLifecycleArgs args) {
623     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
624         .setBucketLifecycle(args));
625   }
626 
627   /**
628    * Sets notification configuration to a bucket.
629    *
630    * <p>Example:
631    * <pre>
632    * List&lt;EventType&gt; eventList = new LinkedList&lt;&gt;();
633    * eventList.add(EventType.OBJECT_CREATED_PUT);
634    * eventList.add(EventType.OBJECT_CREATED_COPY);
635    *
636    * QueueConfiguration queueConfiguration = new QueueConfiguration();
637    * queueConfiguration.setQueue("arn:minio:sqs::1:webhook");
638    * queueConfiguration.setEvents(eventList);
639    * queueConfiguration.setPrefixRule("images");
640    * queueConfiguration.setSuffixRule("pg");
641    *
642    * List&lt;QueueConfiguration&gt; queueConfigurationList = new LinkedList&lt;&gt;();
643    * queueConfigurationList.add(queueConfiguration);
644    *
645    * NotificationConfiguration config = new NotificationConfiguration();
646    * config.setQueueConfigurationList(queueConfigurationList);
647    *
648    * minioClient.setBucketNotification(
649    *     SetBucketNotificationArgs.builder().bucket("my-bucketname").config(config).build());
650    * </pre>
651    *
652    * @param args set bucket notification arguments
653    */
654   default void setBucketNotification(SetBucketNotificationArgs args) {
655     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
656         .setBucketNotification(args));
657   }
658 
659   /**
660    * Sets bucket policy configuration to a bucket.
661    *
662    * <p>Example:
663    * <pre>
664    * // Assume policyJson contains below JSON string;
665    * // {
666    * //     "Statement": [
667    * //         {
668    * //             "Action": [
669    * //                 "s3:GetBucketLocation",
670    * //                 "s3:ListBucket"
671    * //             ],
672    * //             "Effect": "Allow",
673    * //             "Principal": "*",
674    * //             "Resource": "arn:aws:s3:::my-bucketname"
675    * //         },
676    * //         {
677    * //             "Action": "s3:GetObject",
678    * //             "Effect": "Allow",
679    * //             "Principal": "*",
680    * //             "Resource": "arn:aws:s3:::my-bucketname/myobject*"
681    * //         }
682    * //     ],
683    * //     "Version": "2012-10-17"
684    * // }
685    * //
686    * minioClient.setBucketPolicy(
687    *     SetBucketPolicyArgs.builder().bucket("my-bucketname").config(policyJson).build());
688    * </pre>
689    *
690    * @param args set bucket policy arguments
691    */
692   default void setBucketPolicy(SetBucketPolicyArgs args) {
693     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
694         .setBucketPolicy(args));
695   }
696 
697   /**
698    * Sets bucket replication configuration to a bucket.
699    *
700    * <p>Example:
701    * <pre>
702    * Map&lt;String, String&gt; tags = new HashMap&lt;&gt;();
703    * tags.put("key1", "value1");
704    * tags.put("key2", "value2");
705    *
706    * ReplicationRule rule =
707    *     new ReplicationRule(
708    *         new DeleteMarkerReplication(Status.DISABLED),
709    *         new ReplicationDestination(
710    *             null, null, "REPLACE-WITH-ACTUAL-DESTINATION-BUCKET-ARN", null, null, null, null),
711    *         null,
712    *         new RuleFilter(new AndOperator("TaxDocs", tags)),
713    *         "rule1",
714    *         null,
715    *         1,
716    *         null,
717    *         Status.ENABLED);
718    *
719    * List&lt;ReplicationRule&gt; rules = new LinkedList&lt;&gt;();
720    * rules.add(rule);
721    *
722    * ReplicationConfiguration config =
723    *     new ReplicationConfiguration("REPLACE-WITH-ACTUAL-ROLE", rules);
724    *
725    * minioClient.setBucketReplication(
726    *     SetBucketReplicationArgs.builder().bucket("my-bucketname").config(config).build());
727    * </pre>
728    *
729    * @param args set bucket replication arguments
730    */
731   default void setBucketReplication(SetBucketReplicationArgs args) {
732     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
733         .setBucketReplication(args));
734   }
735 
736   /**
737    * Sets tags to a bucket.
738    *
739    * <p>Example:
740    * <pre>
741    * Map&lt;String, String&gt; map = new HashMap&lt;&gt;();
742    * map.put("Project", "Project One");
743    * map.put("User", "jsmith");
744    * minioClient.setBucketTags(
745    *     SetBucketTagsArgs.builder().bucket("my-bucketname").tags(map).build());
746    * </pre>
747    *
748    * @param args the set bucket tags arguments
749    */
750   default void setBucketTags(SetBucketTagsArgs args) {
751     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
752         .setBucketTags(args));
753   }
754 
755   /**
756    * Sets versioning configuration of a bucket.
757    *
758    * <p>Example:
759    * <pre>
760    * minioClient.setBucketVersioning(
761    *     SetBucketVersioningArgs.builder().bucket("my-bucketname").config(config).build());
762    * </pre>
763    *
764    * @param args set bucket versioning arguments
765    */
766   default void setBucketVersioning(SetBucketVersioningArgs args) {
767     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
768         .setBucketVersioning(args));
769   }
770 
771   /**
772    * Sets default object retention in a bucket.
773    *
774    * <p>Example:
775    * <pre>
776    * ObjectLockConfiguration config = new ObjectLockConfiguration(
777    *     RetentionMode.COMPLIANCE, new RetentionDurationDays(100));
778    * minioClient.setObjectLockConfiguration(
779    *     SetObjectLockConfigurationArgs.builder().bucket("my-bucketname").config(config).build());
780    * </pre>
781    *
782    * @param args the default object retention configuration arguments
783    */
784   default void setObjectLockConfiguration(SetObjectLockConfigurationArgs args) {
785     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
786         .setObjectLockConfiguration(args));
787   }
788 
789   // Object operations
790 
791   /**
792    * Creates an object by combining data from different source objects using server-side copy.
793    *
794    * <p>Example:
795    * <pre>
796    * List<ComposeSource> sourceObjectList = new ArrayList<ComposeSource>();
797    *
798    * sourceObjectList.add(
799    *    ComposeSource.builder().bucket("my-job-bucket").object("my-objectname-part-one").build());
800    * sourceObjectList.add(
801    *    ComposeSource.builder().bucket("my-job-bucket").object("my-objectname-part-two").build());
802    * sourceObjectList.add(
803    *    ComposeSource.builder().bucket("my-job-bucket").object("my-objectname-part-three").build());
804    *
805    * // Create my-bucketname/my-objectname by combining source object list.
806    * minioClient.composeObject(
807    *    ComposeObjectArgs.builder()
808    *        .bucket("my-bucketname")
809    *        .object("my-objectname")
810    *        .sources(sourceObjectList)
811    *        .build());
812    *
813    * // Create my-bucketname/my-objectname with user metadata by combining source object
814    * // list.
815    * Map<String, String> userMetadata = new HashMap<>();
816    * userMetadata.put("My-Project", "Project One");
817    * minioClient.composeObject(
818    *     ComposeObjectArgs.builder()
819    *        .bucket("my-bucketname")
820    *        .object("my-objectname")
821    *        .sources(sourceObjectList)
822    *        .userMetadata(userMetadata)
823    *        .build());
824    *
825    * // Create my-bucketname/my-objectname with user metadata and server-side encryption
826    * // by combining source object list.
827    * minioClient.composeObject(
828    *   ComposeObjectArgs.builder()
829    *        .bucket("my-bucketname")
830    *        .object("my-objectname")
831    *        .sources(sourceObjectList)
832    *        .userMetadata(userMetadata)
833    *        .ssec(sse)
834    *        .build());
835    * </pre>
836    *
837    * @param args {@link ComposeObjectArgs} object.
838    * @return {@link ObjectWriteResponse} object.
839    */
840   default ObjectWriteResponse composeObject(ComposeObjectArgs args) {
841     return execute(minioClient -> minioClient.composeObject(args));
842   }
843 
844   /**
845    * Creates an object by server-side copying data from another object.
846    *
847    * @param args copy object arguments
848    * @return the object write response
849    */
850   default ObjectWriteResponse copyObject(CopyObjectArgs args) {
851     return execute(minioClient -> minioClient.copyObject(args));
852   }
853 
854   /**
855    * Deletes tags of an object.
856    *
857    * <p>Example:
858    * <pre>
859    * minioClient.deleteObjectTags(
860    *     DeleteObjectTags.builder().bucket("my-bucketname").object("my-objectname").build());
861    * </pre>
862    *
863    * @param args delete object tags arguments
864    */
865   default void deleteObjectTags(DeleteObjectTagsArgs args) {
866     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
867         .deleteObjectTags(args));
868   }
869 
870   /**
871    * Disables legal hold on an object.
872    *
873    * <p>Example:
874    * <pre>
875    * minioClient.disableObjectLegalHold(
876    *    DisableObjectLegalHoldArgs.builder()
877    *        .bucket("my-bucketname")
878    *        .object("my-objectname")
879    *        .versionId("object-versionId")
880    *        .build());
881    * </pre>
882    *
883    * @param args disable object legal hold arguments
884    */
885   default void disableObjectLegalHold(DisableObjectLegalHoldArgs args) {
886     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
887         .disableObjectLegalHold(args));
888   }
889 
890   /**
891    * Downloads data of a SSE-C encrypted object to file.
892    *
893    * <p>Example:
894    * <pre>
895    * minioClient.downloadObject(
896    *   GetObjectArgs.builder()
897    *     .bucket("my-bucketname")
898    *     .object("my-objectname")
899    *     .ssec(ssec)
900    *     .fileName("my-filename")
901    *     .build());
902    * </pre>
903    *
904    * @param args download object arguments
905    */
906   default void downloadObject(DownloadObjectArgs args) {
907     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
908         .downloadObject(args));
909   }
910 
911   /**
912    * Enables legal hold on an object.
913    *
914    * <p>Example:
915    * <pre>
916    * minioClient.enableObjectLegalHold(
917    *    EnableObjectLegalHoldArgs.builder()
918    *        .bucket("my-bucketname")
919    *        .object("my-objectname")
920    *        .versionId("object-versionId")
921    *        .build());
922    * </pre>
923    *
924    * @param args enable object legal hold arguments
925    */
926   default void enableObjectLegalHold(EnableObjectLegalHoldArgs args) {
927     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
928         .enableObjectLegalHold(args));
929   }
930 
931   /**
932    * Gets data from offset to length of a SSE-C encrypted object. Returned {@link InputStream} must
933    * be closed after use to release network resources.
934    *
935    * <p>Example:
936    * <pre>
937    * try (InputStream stream =
938    *     minioClient.getObject(
939    *   GetObjectArgs.builder()
940    *     .bucket("my-bucketname")
941    *     .object("my-objectname")
942    *     .offset(offset)
943    *     .length(len)
944    *     .ssec(ssec)
945    *     .build()
946    * ) {
947    *   // Read data from stream
948    * }
949    * </pre>
950    *
951    * @param args the get object arguments
952    * @return the input stream
953    */
954   default InputStream getObject(GetObjectArgs args) {
955     return execute(minioClient -> minioClient.getObject(args));
956   }
957 
958   /**
959    * Gets access control policy of an object.
960    *
961    * <p>Example:
962    * <pre>
963    * AccessControlPolicy policy =
964    *     minioClient.getObjectAcl(
965    *         GetObjectAclArgs.builder().bucket("my-bucketname").object("my-objectname").build());
966    * </pre>
967    *
968    * @param args {@link GetObjectAclArgs} object.
969    * @return {@link AccessControlPolicy} - Access control policy object.
970    */
971   default AccessControlPolicy getObjectAcl(GetObjectAclArgs args) {
972     return execute(minioClient -> minioClient.getObjectAcl(args));
973   }
974 
975   /**
976    * Gets attributes of an object.
977    *
978    * <p>Example:
979    * <pre>Example:
980    * GetObjectAttributesResponse response =
981    *     minioClient.getObjectAttributes(
982    *         GetObjectAttributesArgs.builder()
983    *             .bucket("my-bucketname")
984    *             .object("my-objectname")
985    *             .objectAttributes(
986    *                 new String[] {
987    *                   "ETag", "Checksum", "ObjectParts", "StorageClass", "ObjectSize"
988    *                 })
989    *             .build());
990    * </pre>
991    *
992    * @param args {@link GetObjectAttributesArgs} object.
993    * @return {@link GetObjectAttributesResponse} - Response object.
994    */
995   default GetObjectAttributesResponse getObjectAttributes(GetObjectAttributesArgs args) {
996     return execute(minioClient -> minioClient.getObjectAttributes(args));
997   }
998 
999   /**
1000    * Gets retention configuration of an object.
1001    *
1002    * <p>Example:
1003    * <pre>
1004    * Retention retention =
1005    *     minioClient.getObjectRetention(GetObjectRetentionArgs.builder()
1006    *        .bucket(bucketName)
1007    *        .object(objectName)
1008    *        .versionId(versionId)
1009    *        .build()););
1010    * System.out.println(
1011    *     "mode: " + retention.mode() + "until: " + retention.retainUntilDate());
1012    * </pre>
1013    *
1014    * @param args get object retention arguments
1015    * @return object retention configuration
1016    */
1017   default Retention getObjectRetention(GetObjectRetentionArgs args) {
1018     return execute(minioClient -> minioClient.getObjectRetention(args));
1019   }
1020 
1021   /**
1022    * Gets tags of an object.
1023    *
1024    * <p>Example:
1025    * <pre>
1026    * Tags tags =
1027    *     minioClient.getObjectTags(
1028    *         GetObjectTagsArgs.builder().bucket("my-bucketname").object("my-objectname").build());
1029    * </pre>
1030    *
1031    * @param args get object tags arguments
1032    * @return the tags
1033    */
1034   default Tags getObjectTags(GetObjectTagsArgs args) {
1035     return execute(minioClient -> minioClient.getObjectTags(args));
1036   }
1037 
1038   /**
1039    * Gets presigned URL of an object for HTTP method, expiry time and custom request parameters.
1040    *
1041    * <p>Example:
1042    * <pre>
1043    * // Get presigned URL string to delete 'my-objectname' in 'my-bucketname' and its life time
1044    * // is one day.
1045    * String url =
1046    *    minioClient.getPresignedObjectUrl(
1047    *        GetPresignedObjectUrlArgs.builder()
1048    *            .method(Method.DELETE)
1049    *            .bucket("my-bucketname")
1050    *            .object("my-objectname")
1051    *            .expiry(24 * 60 * 60)
1052    *            .build());
1053    * System.out.println(url);
1054    *
1055    * // Get presigned URL string to upload 'my-objectname' in 'my-bucketname'
1056    * // with response-content-type as application/json and life time as one day.
1057    * Map&lt;String, String&gt; reqParams = new HashMap&lt;String, String&gt;();
1058    * reqParams.put("response-content-type", "application/json");
1059    *
1060    * String url =
1061    *    minioClient.getPresignedObjectUrl(
1062    *        GetPresignedObjectUrlArgs.builder()
1063    *            .method(Method.PUT)
1064    *            .bucket("my-bucketname")
1065    *            .object("my-objectname")
1066    *            .expiry(1, TimeUnit.DAYS)
1067    *            .extraQueryParams(reqParams)
1068    *            .build());
1069    * System.out.println(url);
1070    *
1071    * // Get presigned URL string to download 'my-objectname' in 'my-bucketname' and its life time
1072    * // is 2 hours.
1073    * String url =
1074    *    minioClient.getPresignedObjectUrl(
1075    *        GetPresignedObjectUrlArgs.builder()
1076    *            .method(Method.GET)
1077    *            .bucket("my-bucketname")
1078    *            .object("my-objectname")
1079    *            .expiry(2, TimeUnit.HOURS)
1080    *            .build());
1081    * System.out.println(url);
1082    * </pre>
1083    *
1084    * @param args get pre-signed object url arguments
1085    * @return the pre-signed URL
1086    */
1087   default String getPresignedObjectUrl(GetPresignedObjectUrlArgs args) {
1088     return execute(minioClient -> minioClient.getPresignedObjectUrl(args));
1089   }
1090 
1091   /**
1092    * Gets form-data of {@link PostPolicy} of an object to upload its data using POST method.
1093    *
1094    * <p>Example:
1095    * <pre>
1096    * // Create new post policy for 'my-bucketname' with 7 days expiry from now.
1097    * PostPolicy policy = new PostPolicy("my-bucketname", ZonedDateTime.now().plusDays(7));
1098    *
1099    * // Add condition that 'key' (object name) equals to 'my-objectname'.
1100    * policy.addEqualsCondition("key", "my-objectname");
1101    *
1102    * // Add condition that 'Content-Type' starts with 'image/'.
1103    * policy.addStartsWithCondition("Content-Type", "image/");
1104    *
1105    * // Add condition that 'content-length-range' is between 64kiB to 10MiB.
1106    * policy.addContentLengthRangeCondition(64 * 1024, 10 * 1024 * 1024);
1107    *
1108    * Map&lt;String, String&gt; formData = minioClient.getPresignedPostFormData(policy);
1109    *
1110    * // Upload an image using POST object with form-data.
1111    * MultipartBody.Builder multipartBuilder = new MultipartBody.Builder();
1112    * multipartBuilder.setType(MultipartBody.FORM);
1113    * for (Map.Entry&lt;String, String&gt; entry : formData.entrySet()) {
1114    *   multipartBuilder.addFormDataPart(entry.getKey(), entry.getValue());
1115    * }
1116    * multipartBuilder.addFormDataPart("key", "my-objectname");
1117    * multipartBuilder.addFormDataPart("Content-Type", "image/png");
1118    *
1119    * // "file" must be added at last.
1120    * multipartBuilder.addFormDataPart(
1121    *     "file", "my-objectname", RequestBody.create(new File("Pictures/avatar.png"), null));
1122    *
1123    * Request request =
1124    *     new Request.Builder()
1125    *         .url("https://play.min.io/my-bucketname")
1126    *         .post(multipartBuilder.build())
1127    *         .build();
1128    * OkHttpClient httpClient = new OkHttpClient().newBuilder().build();
1129    * Response response = httpClient.newCall(request).execute();
1130    * if (response.isSuccessful()) {
1131    *   System.out.println("Pictures/avatar.png is uploaded successfully using POST object");
1132    * } else {
1133    *   System.out.println("Failed to upload Pictures/avatar.png");
1134    * }
1135    * </pre>
1136    *
1137    * @param policy post policy of an object
1138    * @return contains form-data to upload an object using POST method
1139    */
1140   @SuppressWarnings("JavadocLinkAsPlainText")
1141   default Map<String, String> getPresignedPostFormData(PostPolicy policy) {
1142     return execute(minioClient -> minioClient.getPresignedPostFormData(policy));
1143   }
1144 
1145   /**
1146    * Returns true if legal hold is enabled on an object.
1147    *
1148    * <p>Example:
1149    * <pre>
1150    * boolean status =
1151    *     s3Client.isObjectLegalHoldEnabled(
1152    *        IsObjectLegalHoldEnabledArgs.builder()
1153    *             .bucket("my-bucketname")
1154    *             .object("my-objectname")
1155    *             .versionId("object-versionId")
1156    *             .build());
1157    * if (status) {
1158    *   System.out.println("Legal hold is on");
1159    *  } else {
1160    *   System.out.println("Legal hold is off");
1161    *  }
1162    * </pre>
1163    *
1164    * @param args is object legel hold enabled arguments
1165    * @return true if legal hold is enabled
1166    */
1167   default boolean isObjectLegalHoldEnabled(IsObjectLegalHoldEnabledArgs args) {
1168     return execute(minioClient -> minioClient.isObjectLegalHoldEnabled(args));
1169   }
1170 
1171   /**
1172    * Lists objects information optionally with versions of a bucket. Supports both the versions 1
1173    * and 2 of the S3 API. By default, the <a
1174    * href="https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html">version 2</a> API
1175    * is used. <br>
1176    * <a href="https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjects.html">Version 1</a>
1177    * can be used by passing the optional argument {@code useVersion1} as {@code true}.
1178    *
1179    * <p>Example:
1180    * <pre>
1181    * // Lists objects information.
1182    * Iterable&lt;Result&lt;Item&gt;&gt; results = minioClient.listObjects(
1183    *     ListObjectsArgs.builder().bucket("my-bucketname").build());
1184    *
1185    * // Lists objects information recursively.
1186    * Iterable&lt;Result&lt;Item&gt;&gt; results = minioClient.listObjects(
1187    *     ListObjectsArgs.builder().bucket("my-bucketname").recursive(true).build());
1188    *
1189    * // Lists maximum 100 objects information those names starts with 'E' and after
1190    * // 'ExampleGuide.pdf'.
1191    * Iterable&lt;Result&lt;Item&gt;&gt; results = minioClient.listObjects(
1192    *     ListObjectsArgs.builder()
1193    *         .bucket("my-bucketname")
1194    *         .startAfter("ExampleGuide.pdf")
1195    *         .prefix("E")
1196    *         .maxKeys(100)
1197    *         .build());
1198    *
1199    * // Lists maximum 100 objects information with version those names starts with 'E' and after
1200    * // 'ExampleGuide.pdf'.
1201    * Iterable&lt;Result&lt;Item&gt;&gt; results = minioClient.listObjects(
1202    *     ListObjectsArgs.builder()
1203    *         .bucket("my-bucketname")
1204    *         .startAfter("ExampleGuide.pdf")
1205    *         .prefix("E")
1206    *         .maxKeys(100)
1207    *         .includeVersions(true)
1208    *         .build());
1209    * </pre>
1210    *
1211    * @param args list objects arguments
1212    * @return lazy iterator contains object information
1213    */
1214   default Iterable<Result<Item>> listObjects(ListObjectsArgs args) {
1215     return execute(minioClient -> minioClient.listObjects(args));
1216   }
1217 
1218   /**
1219    * Check whether an object exists or not.
1220    *
1221    * @param args status object arguments
1222    * @return {@code true} if the object exists, otherwise {@code false}
1223    */
1224   default boolean objectExists(StatObjectArgs args) {
1225     try {
1226       return statObject(args) != null;
1227     } catch (MinioException e) {
1228       if (404 == e.status()) {
1229         return false;
1230       }
1231       throw e;
1232     }
1233   }
1234 
1235   /**
1236    * Performs language model inference with the prompt and referenced object as context.
1237    *
1238    * @param args {@link PromptObjectArgs} object.
1239    * @return {@link PromptObjectResponse} object.
1240    */
1241   default PromptObjectResponse promptObject(PromptObjectArgs args) {
1242     return execute(minioClient -> minioClient.promptObject(args));
1243   }
1244 
1245   /**
1246    * Uploads data from a stream to an object.
1247    *
1248    * <p>Example:
1249    * <pre>
1250    * // Upload known sized input stream.
1251    * minioClient.putObject(
1252    *     PutObjectArgs.builder().bucket("my-bucketname").object("my-objectname").stream(
1253    *             inputStream, size, -1)
1254    *         .contentType("video/mp4")
1255    *         .build());
1256    *
1257    * // Upload unknown sized input stream.
1258    * minioClient.putObject(
1259    *     PutObjectArgs.builder().bucket("my-bucketname").object("my-objectname").stream(
1260    *             inputStream, -1, 10485760)
1261    *         .contentType("video/mp4")
1262    *         .build());
1263    *
1264    * // Create object ends with '/' (also called as folder or directory).
1265    * minioClient.putObject(
1266    *     PutObjectArgs.builder().bucket("my-bucketname").object("path/to/").stream(
1267    *             new ByteArrayInputStream(new byte[] {}), 0, -1)
1268    *         .build());
1269    *
1270    * // Upload input stream with headers and user metadata.
1271    * Map&lt;String, String&gt; headers = new HashMap&lt;&gt;();
1272    * headers.put("X-Amz-Storage-Class", "REDUCED_REDUNDANCY");
1273    * Map&lt;String, String&gt; userMetadata = new HashMap&lt;&gt;();
1274    * userMetadata.put("My-Project", "Project One");
1275    * minioClient.putObject(
1276    *     PutObjectArgs.builder().bucket("my-bucketname").object("my-objectname").stream(
1277    *             inputStream, size, -1)
1278    *         .headers(headers)
1279    *         .userMetadata(userMetadata)
1280    *         .build());
1281    *
1282    * // Upload input stream with server-side encryption.
1283    * minioClient.putObject(
1284    *     PutObjectArgs.builder().bucket("my-bucketname").object("my-objectname").stream(
1285    *             inputStream, size, -1)
1286    *         .sse(sse)
1287    *         .build());
1288    * </pre>
1289    *
1290    * @param args put object arguments
1291    * @return the object write response
1292    */
1293   default ObjectWriteResponse putObject(PutObjectArgs args) {
1294     return execute(minioClient -> minioClient.putObject(args));
1295   }
1296 
1297   /**
1298    * Uploads multiple objects with same content from single stream with optional metadata and tags.
1299    *
1300    * <p>Example:
1301    * <pre>
1302    * Map<String, String> map = new HashMap<>();
1303    * map.put("Project", "Project One");
1304    * map.put("User", "jsmith");
1305    * PutObjectFanOutResponse future =
1306    *     minioClient.putObjectFanOut(
1307    *         PutObjectFanOutArgs.builder().bucket("my-bucketname").stream(
1308    *                 new ByteArrayInputStream("somedata".getBytes(StandardCharsets.UTF_8)), 8)
1309    *             .entries(
1310    *                 Arrays.asList(
1311    *                     new PutObjectFanOutEntry[] {
1312    *                       PutObjectFanOutEntry.builder().key("fan-out.0").build(),
1313    *                       PutObjectFanOutEntry.builder().key("fan-out.1").tags(map).build()
1314    *                     }))
1315    *             .build());
1316    * </pre>
1317    *
1318    * @param args {@link PutObjectFanOutArgs} object.
1319    * @return {@link PutObjectFanOutResponse} object.
1320    */
1321   default PutObjectFanOutResponse putObjectFanOut(PutObjectFanOutArgs args) {
1322     return execute(minioClient -> minioClient.putObjectFanOut(args));
1323   }
1324 
1325   /**
1326    * Removes an object.
1327    *
1328    * <p>Example:
1329    * <pre>
1330    * // Remove object.
1331    * minioClient.removeObject(
1332    *     RemoveObjectArgs.builder().bucket("my-bucketname").object("my-objectname").build());
1333    *
1334    * // Remove versioned object.
1335    * minioClient.removeObject(
1336    *     RemoveObjectArgs.builder()
1337    *         .bucket("my-bucketname")
1338    *         .object("my-versioned-objectname")
1339    *         .versionId("my-versionid")
1340    *         .build());
1341    *
1342    * // Remove versioned object bypassing Governance mode.
1343    * minioClient.removeObject(
1344    *     RemoveObjectArgs.builder()
1345    *         .bucket("my-bucketname")
1346    *         .object("my-versioned-objectname")
1347    *         .versionId("my-versionid")
1348    *         .bypassRetentionMode(true)
1349    *         .build());
1350    * </pre>
1351    *
1352    * @param args remove object arguments
1353    */
1354   default void removeObject(RemoveObjectArgs args) {
1355     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
1356         .removeObject(args));
1357   }
1358 
1359   /**
1360    * Removes multiple objects lazily. Its required to iterate the returned Iterable to perform
1361    * removal.
1362    *
1363    * <p>Example:
1364    * <pre>
1365    * List&lt;DeleteObject&gt; objects = new LinkedList&lt;&gt;();
1366    * objects.add(new DeleteObject("my-objectname1"));
1367    * objects.add(new DeleteObject("my-objectname2"));
1368    * objects.add(new DeleteObject("my-objectname3"));
1369    * Iterable&lt;Result&lt;DeleteResult.Error&gt;&gt; results =
1370    *     minioClient.removeObjects(
1371    *         RemoveObjectsArgs.builder().bucket("my-bucketname").objects(objects).build());
1372    * for (Result&lt;DeleteResult.Error&gt; result : results) {
1373    *   DeleteResult.Error error = errorResult.get();
1374    *   System.out.println(
1375    *       "Error in deleting object " + error.objectName() + "; " + error.message());
1376    * }
1377    * </pre>
1378    *
1379    * @param args the objects to remove
1380    * @return lazy iterator contains object removal status
1381    */
1382   default Iterable<Result<DeleteResult.Error>> removeObjects(RemoveObjectsArgs args) {
1383     return execute(minioClient -> minioClient.removeObjects(args));
1384   }
1385 
1386   /**
1387    * Restores an object.
1388    *
1389    * <p>Example:
1390    * <pre>
1391    * // Restore object.
1392    * minioClient.restoreObject(
1393    *     RestoreObjectArgs.builder()
1394    *         .bucket("my-bucketname")
1395    *         .object("my-objectname")
1396    *         .request(new RestoreRequest(null, null, null, null, null, null))
1397    *         .build());
1398    *
1399    * // Restore versioned object.
1400    * minioClient.restoreObject(
1401    *     RestoreObjectArgs.builder()
1402    *         .bucket("my-bucketname")
1403    *         .object("my-versioned-objectname")
1404    *         .versionId("my-versionid")
1405    *         .request(new RestoreRequest(null, null, null, null, null, null))
1406    *         .build());
1407    * </pre>
1408    *
1409    * @param args {@link RestoreObjectArgs} object.
1410    */
1411   default void restoreObject(RestoreObjectArgs args) {
1412     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
1413         .restoreObject(args));
1414   }
1415 
1416   /**
1417    * Selects content of an object by SQL expression.
1418    *
1419    * <p>Example:
1420    * <pre>
1421    * String sqlExpression = "select * from S3Object";
1422    * InputSerialization is =
1423    *     new InputSerialization(null, false, null, null, FileHeaderInfo.USE, null, null,
1424    *         null);
1425    * OutputSerialization os =
1426    *     new OutputSerialization(null, null, null, QuoteFields.ASNEEDED, null);
1427    * SelectResponseStream stream =
1428    *     minioClient.selectObjectContent(
1429    *       SelectObjectContentArgs.builder()
1430    *       .bucket("my-bucketname")
1431    *       .object("my-objectname")
1432    *       .sqlExpression(sqlExpression)
1433    *       .inputSerialization(is)
1434    *       .outputSerialization(os)
1435    *       .requestProgress(true)
1436    *       .build());
1437    *
1438    * byte[] buf = new byte[512];
1439    * int bytesRead = stream.read(buf, 0, buf.length);
1440    * System.out.println(new String(buf, 0, bytesRead, StandardCharsets.UTF_8));
1441    *
1442    * Stats stats = stream.stats();
1443    * System.out.println("bytes scanned: " + stats.bytesScanned());
1444    * System.out.println("bytes processed: " + stats.bytesProcessed());
1445    * System.out.println("bytes returned: " + stats.bytesReturned());
1446    *
1447    * stream.close();
1448    * </pre>
1449    *
1450    * @param args the select object content arguments
1451    * @return the select response stream
1452    */
1453   default SelectResponseStream selectObjectContent(SelectObjectContentArgs args) {
1454     return execute(minioClient -> minioClient.selectObjectContent(args));
1455   }
1456 
1457   /**
1458    * Sets retention configuration to an object.
1459    *
1460    * <p>Example:
1461    * <pre>
1462    *  Retention retention = new Retention(
1463    *       RetentionMode.COMPLIANCE, ZonedDateTime.now().plusYears(1));
1464    *  minioClient.setObjectRetention(
1465    *      SetObjectRetentionArgs.builder()
1466    *          .bucket("my-bucketname")
1467    *          .object("my-objectname")
1468    *          .config(config)
1469    *          .bypassGovernanceMode(true)
1470    *          .build());
1471    * </pre>
1472    *
1473    * @param args set object retention arguments
1474    */
1475   default void setObjectRetention(SetObjectRetentionArgs args) {
1476     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
1477         .setObjectRetention(args));
1478   }
1479 
1480   /**
1481    * Sets tags to an object.
1482    *
1483    * <p>Example:
1484    * <pre>
1485    * Map&lt;String, String&gt; map = new HashMap&lt;&gt;();
1486    * map.put("Project", "Project One");
1487    * map.put("User", "jsmith");
1488    * minioClient.setObjectTags(
1489    *     SetObjectTagsArgs.builder()
1490    *         .bucket("my-bucketname")
1491    *         .object("my-objectname")
1492    *         .tags((map)
1493    *         .build());
1494    * </pre>
1495    *
1496    * @param args set object tags arguments
1497    */
1498   default void setObjectTags(SetObjectTagsArgs args) {
1499     execute((MinioClientCallbackWithoutResult) minioClient -> minioClient
1500         .setObjectTags(args));
1501   }
1502 
1503   /**
1504    * Gets information of an object.
1505    *
1506    * <p>Example:
1507    * <pre>
1508    * // Get information of an object.
1509    * ObjectStat objectStat =
1510    *     minioClient.statObject(
1511    *         StatObjectArgs.builder().bucket("my-bucketname").object("my-objectname").build());
1512    *
1513    * // Get information of SSE-C encrypted object.
1514    * ObjectStat objectStat =
1515    *     minioClient.statObject(
1516    *         StatObjectArgs.builder()
1517    *             .bucket("my-bucketname")
1518    *             .object("my-objectname")
1519    *             .ssec(ssec)
1520    *             .build());
1521    *
1522    * // Get information of a versioned object.
1523    * ObjectStat objectStat =
1524    *     minioClient.statObject(
1525    *         StatObjectArgs.builder()
1526    *             .bucket("my-bucketname")
1527    *             .object("my-objectname")
1528    *             .versionId("version-id")
1529    *             .build());
1530    *
1531    * // Get information of a SSE-C encrypted versioned object.
1532    * ObjectStat objectStat =
1533    *     minioClient.statObject(
1534    *         StatObjectArgs.builder()
1535    *             .bucket("my-bucketname")
1536    *             .object("my-objectname")
1537    *             .versionId("version-id")
1538    *             .ssec(ssec)
1539    *             .build());
1540    * </pre>
1541    *
1542    * @param args status object arguments
1543    * @return populated object information and metadata
1544    */
1545   default StatObjectResponse statObject(StatObjectArgs args) {
1546     return execute(minioClient -> minioClient.statObject(args));
1547   }
1548 
1549   /**
1550    * Uploads data from a file to an object.
1551    *
1552    * <p>Example:
1553    * <pre>
1554    * // Upload an JSON file.
1555    * minioClient.uploadObject(
1556    *     UploadObjectArgs.builder()
1557    *         .bucket("my-bucketname").object("my-objectname").filename("person.json").build());
1558    *
1559    * // Upload a video file.
1560    * minioClient.uploadObject(
1561    *     UploadObjectArgs.builder()
1562    *         .bucket("my-bucketname")
1563    *         .object("my-objectname")
1564    *         .filename("my-video.avi")
1565    *         .contentType("video/mp4")
1566    *         .build());
1567    * </pre>
1568    *
1569    * @param args upload object arguments
1570    * @param deleteMode delete mode
1571    * @return the object write response
1572    */
1573   default ObjectWriteResponse uploadObject(UploadObjectArgs args, DeleteMode deleteMode) {
1574     final Path file = Paths.get(args.filename());
1575     try {
1576       return execute(minioClient -> {
1577         ObjectWriteResponse response = minioClient.uploadObject(args);
1578         if (DeleteMode.ON_SUCCESS == deleteMode) {
1579           Files.delete(file);
1580         }
1581         return response;
1582       });
1583 
1584     } finally {
1585       if (DeleteMode.ALWAYS == deleteMode) {
1586         execute((MinioClientCallbackWithoutResult) minioClient -> Files.delete(file));
1587       }
1588     }
1589   }
1590 
1591 }