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