/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.camel.builder.endpoint.dsl;

import java.time.ZonedDateTime;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.annotation.Generated;
import org.apache.camel.ExchangePattern;
import org.apache.camel.LoggingLevel;
import org.apache.camel.builder.EndpointConsumerBuilder;
import org.apache.camel.builder.EndpointProducerBuilder;
import org.apache.camel.builder.endpoint.AbstractEndpointBuilder;
import org.apache.camel.spi.ExceptionHandler;
import org.apache.camel.spi.PollingConsumerPollStrategy;

/**
 * Store and retrieve objects from Minio Storage Service using Minio SDK.
 * 
 * Generated by camel build tools - do NOT edit this file!
 */
@Generated("org.apache.camel.maven.packaging.EndpointDslMojo")
public interface MinioEndpointBuilderFactory {


    /**
     * Builder for endpoint consumers for the Minio component.
     */
    public interface MinioEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default AdvancedMinioEndpointConsumerBuilder advanced() {
            return (AdvancedMinioEndpointConsumerBuilder) this;
        }
        /**
         * Setting the autocreation of the bucket if bucket name not exist.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: true
         * Group: common
         */
        default MinioEndpointConsumerBuilder autoCreateBucket(
                boolean autoCreateBucket) {
            doSetProperty("autoCreateBucket", autoCreateBucket);
            return this;
        }
        /**
         * Setting the autocreation of the bucket if bucket name not exist.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: true
         * Group: common
         */
        default MinioEndpointConsumerBuilder autoCreateBucket(
                String autoCreateBucket) {
            doSetProperty("autoCreateBucket", autoCreateBucket);
            return this;
        }
        /**
         * Set custom HTTP client for authenticated access.
         * 
         * The option is a: <code>okhttp3.OkHttpClient</code> type.
         * 
         * Group: common
         */
        default MinioEndpointConsumerBuilder customHttpClient(
                Object customHttpClient) {
            doSetProperty("customHttpClient", customHttpClient);
            return this;
        }
        /**
         * Set custom HTTP client for authenticated access.
         * 
         * The option will be converted to a <code>okhttp3.OkHttpClient</code>
         * type.
         * 
         * Group: common
         */
        default MinioEndpointConsumerBuilder customHttpClient(
                String customHttpClient) {
            doSetProperty("customHttpClient", customHttpClient);
            return this;
        }
        /**
         * Endpoint can be an URL, domain name, IPv4 address or IPv6 address.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default MinioEndpointConsumerBuilder endpoint(String endpoint) {
            doSetProperty("endpoint", endpoint);
            return this;
        }
        /**
         * Reference to a Minio Client object in the registry.
         * 
         * The option is a: <code>io.minio.MinioClient</code> type.
         * 
         * Group: common
         */
        default MinioEndpointConsumerBuilder minioClient(Object minioClient) {
            doSetProperty("minioClient", minioClient);
            return this;
        }
        /**
         * Reference to a Minio Client object in the registry.
         * 
         * The option will be converted to a <code>io.minio.MinioClient</code>
         * type.
         * 
         * Group: common
         */
        default MinioEndpointConsumerBuilder minioClient(String minioClient) {
            doSetProperty("minioClient", minioClient);
            return this;
        }
        /**
         * Set when creating new bucket.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: common
         */
        default MinioEndpointConsumerBuilder objectLock(boolean objectLock) {
            doSetProperty("objectLock", objectLock);
            return this;
        }
        /**
         * Set when creating new bucket.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: common
         */
        default MinioEndpointConsumerBuilder objectLock(String objectLock) {
            doSetProperty("objectLock", objectLock);
            return this;
        }
        /**
         * The policy for this queue to set in the method.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default MinioEndpointConsumerBuilder policy(String policy) {
            doSetProperty("policy", policy);
            return this;
        }
        /**
         * TCP/IP port number. 80 and 443 are used as defaults for HTTP and
         * HTTPS.
         * 
         * The option is a: <code>java.lang.Integer</code> type.
         * 
         * Group: common
         */
        default MinioEndpointConsumerBuilder proxyPort(Integer proxyPort) {
            doSetProperty("proxyPort", proxyPort);
            return this;
        }
        /**
         * TCP/IP port number. 80 and 443 are used as defaults for HTTP and
         * HTTPS.
         * 
         * The option will be converted to a <code>java.lang.Integer</code>
         * type.
         * 
         * Group: common
         */
        default MinioEndpointConsumerBuilder proxyPort(String proxyPort) {
            doSetProperty("proxyPort", proxyPort);
            return this;
        }
        /**
         * The region in which Minio client needs to work. When using this
         * parameter, the configuration will expect the lowercase name of the
         * region (for example ap-east-1). You'll need to use the name
         * Region.EU_WEST_1.id().
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default MinioEndpointConsumerBuilder region(String region) {
            doSetProperty("region", region);
            return this;
        }
        /**
         * Flag to indicate to use secure connection to minio service or not.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: common
         */
        default MinioEndpointConsumerBuilder secure(boolean secure) {
            doSetProperty("secure", secure);
            return this;
        }
        /**
         * Flag to indicate to use secure connection to minio service or not.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: common
         */
        default MinioEndpointConsumerBuilder secure(String secure) {
            doSetProperty("secure", secure);
            return this;
        }
        /**
         * Server-side encryption.
         * 
         * The option is a: <code>io.minio.ServerSideEncryption</code> type.
         * 
         * Group: common
         */
        default MinioEndpointConsumerBuilder serverSideEncryption(
                Object serverSideEncryption) {
            doSetProperty("serverSideEncryption", serverSideEncryption);
            return this;
        }
        /**
         * Server-side encryption.
         * 
         * The option will be converted to a
         * <code>io.minio.ServerSideEncryption</code> type.
         * 
         * Group: common
         */
        default MinioEndpointConsumerBuilder serverSideEncryption(
                String serverSideEncryption) {
            doSetProperty("serverSideEncryption", serverSideEncryption);
            return this;
        }
        /**
         * Server-side encryption for source object while copy/move objects.
         * 
         * The option is a:
         * <code>io.minio.ServerSideEncryptionCustomerKey</code> type.
         * 
         * Group: common
         */
        default MinioEndpointConsumerBuilder serverSideEncryptionCustomerKey(
                Object serverSideEncryptionCustomerKey) {
            doSetProperty("serverSideEncryptionCustomerKey", serverSideEncryptionCustomerKey);
            return this;
        }
        /**
         * Server-side encryption for source object while copy/move objects.
         * 
         * The option will be converted to a
         * <code>io.minio.ServerSideEncryptionCustomerKey</code> type.
         * 
         * Group: common
         */
        default MinioEndpointConsumerBuilder serverSideEncryptionCustomerKey(
                String serverSideEncryptionCustomerKey) {
            doSetProperty("serverSideEncryptionCustomerKey", serverSideEncryptionCustomerKey);
            return this;
        }
        /**
         * If this option is true and includeBody is true, then the
         * MinioObject.close() method will be called on exchange completion.
         * This option is strongly related to includeBody option. In case of
         * setting includeBody to true and autocloseBody to false, it will be up
         * to the caller to close the MinioObject stream. Setting autocloseBody
         * to true, will close the MinioObject stream automatically.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: true
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder autoCloseBody(boolean autoCloseBody) {
            doSetProperty("autoCloseBody", autoCloseBody);
            return this;
        }
        /**
         * If this option is true and includeBody is true, then the
         * MinioObject.close() method will be called on exchange completion.
         * This option is strongly related to includeBody option. In case of
         * setting includeBody to true and autocloseBody to false, it will be up
         * to the caller to close the MinioObject stream. Setting autocloseBody
         * to true, will close the MinioObject stream automatically.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: true
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder autoCloseBody(String autoCloseBody) {
            doSetProperty("autoCloseBody", autoCloseBody);
            return this;
        }
        /**
         * Allows for bridging the consumer to the Camel routing Error Handler,
         * which mean any exceptions occurred while the consumer is trying to
         * pickup incoming messages, or the likes, will now be processed as a
         * message and handled by the routing Error Handler. By default the
         * consumer will use the org.apache.camel.spi.ExceptionHandler to deal
         * with exceptions, that will be logged at WARN or ERROR level and
         * ignored.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder bridgeErrorHandler(
                boolean bridgeErrorHandler) {
            doSetProperty("bridgeErrorHandler", bridgeErrorHandler);
            return this;
        }
        /**
         * Allows for bridging the consumer to the Camel routing Error Handler,
         * which mean any exceptions occurred while the consumer is trying to
         * pickup incoming messages, or the likes, will now be processed as a
         * message and handled by the routing Error Handler. By default the
         * consumer will use the org.apache.camel.spi.ExceptionHandler to deal
         * with exceptions, that will be logged at WARN or ERROR level and
         * ignored.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder bridgeErrorHandler(
                String bridgeErrorHandler) {
            doSetProperty("bridgeErrorHandler", bridgeErrorHandler);
            return this;
        }
        /**
         * Set this flag if you want to bypassGovernanceMode when deleting a
         * particular object.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder bypassGovernanceMode(
                boolean bypassGovernanceMode) {
            doSetProperty("bypassGovernanceMode", bypassGovernanceMode);
            return this;
        }
        /**
         * Set this flag if you want to bypassGovernanceMode when deleting a
         * particular object.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder bypassGovernanceMode(
                String bypassGovernanceMode) {
            doSetProperty("bypassGovernanceMode", bypassGovernanceMode);
            return this;
        }
        /**
         * Delete objects from Minio after they have been retrieved. The delete
         * is only performed if the Exchange is committed. If a rollback occurs,
         * the object is not deleted. If this option is false, then the same
         * objects will be retrieve over and over again on the polls. Therefore
         * you need to use the Idempotent Consumer EIP in the route to filter
         * out duplicates. You can filter using the MinioConstants#BUCKET_NAME
         * and MinioConstants#OBJECT_NAME headers, or only the
         * MinioConstants#OBJECT_NAME header.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: true
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder deleteAfterRead(
                boolean deleteAfterRead) {
            doSetProperty("deleteAfterRead", deleteAfterRead);
            return this;
        }
        /**
         * Delete objects from Minio after they have been retrieved. The delete
         * is only performed if the Exchange is committed. If a rollback occurs,
         * the object is not deleted. If this option is false, then the same
         * objects will be retrieve over and over again on the polls. Therefore
         * you need to use the Idempotent Consumer EIP in the route to filter
         * out duplicates. You can filter using the MinioConstants#BUCKET_NAME
         * and MinioConstants#OBJECT_NAME headers, or only the
         * MinioConstants#OBJECT_NAME header.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: true
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder deleteAfterRead(
                String deleteAfterRead) {
            doSetProperty("deleteAfterRead", deleteAfterRead);
            return this;
        }
        /**
         * The delimiter which is used in the ListObjectsRequest to only consume
         * objects we are interested in.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder delimiter(String delimiter) {
            doSetProperty("delimiter", delimiter);
            return this;
        }
        /**
         * Source bucket name.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder destinationBucketName(
                String destinationBucketName) {
            doSetProperty("destinationBucketName", destinationBucketName);
            return this;
        }
        /**
         * Source object name.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder destinationObjectName(
                String destinationObjectName) {
            doSetProperty("destinationObjectName", destinationObjectName);
            return this;
        }
        /**
         * If it is true, the exchange body will be set to a stream to the
         * contents of the file. If false, the headers will be set with the
         * Minio object metadata, but the body will be null. This option is
         * strongly related to autocloseBody option. In case of setting
         * includeBody to true and autocloseBody to false, it will be up to the
         * caller to close the MinioObject stream. Setting autocloseBody to
         * true, will close the MinioObject stream automatically.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: true
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder includeBody(boolean includeBody) {
            doSetProperty("includeBody", includeBody);
            return this;
        }
        /**
         * If it is true, the exchange body will be set to a stream to the
         * contents of the file. If false, the headers will be set with the
         * Minio object metadata, but the body will be null. This option is
         * strongly related to autocloseBody option. In case of setting
         * includeBody to true and autocloseBody to false, it will be up to the
         * caller to close the MinioObject stream. Setting autocloseBody to
         * true, will close the MinioObject stream automatically.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: true
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder includeBody(String includeBody) {
            doSetProperty("includeBody", includeBody);
            return this;
        }
        /**
         * The flag which is used in the ListObjectsRequest to set include
         * folders.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder includeFolders(
                boolean includeFolders) {
            doSetProperty("includeFolders", includeFolders);
            return this;
        }
        /**
         * The flag which is used in the ListObjectsRequest to set include
         * folders.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder includeFolders(
                String includeFolders) {
            doSetProperty("includeFolders", includeFolders);
            return this;
        }
        /**
         * The flag which is used in the ListObjectsRequest to get objects with
         * user meta data.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder includeUserMetadata(
                boolean includeUserMetadata) {
            doSetProperty("includeUserMetadata", includeUserMetadata);
            return this;
        }
        /**
         * The flag which is used in the ListObjectsRequest to get objects with
         * user meta data.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder includeUserMetadata(
                String includeUserMetadata) {
            doSetProperty("includeUserMetadata", includeUserMetadata);
            return this;
        }
        /**
         * The flag which is used in the ListObjectsRequest to get objects with
         * versioning.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder includeVersions(
                boolean includeVersions) {
            doSetProperty("includeVersions", includeVersions);
            return this;
        }
        /**
         * The flag which is used in the ListObjectsRequest to get objects with
         * versioning.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder includeVersions(
                String includeVersions) {
            doSetProperty("includeVersions", includeVersions);
            return this;
        }
        /**
         * Number of bytes of object data from offset.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder length(long length) {
            doSetProperty("length", length);
            return this;
        }
        /**
         * Number of bytes of object data from offset.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder length(String length) {
            doSetProperty("length", length);
            return this;
        }
        /**
         * Set match ETag parameter for get object(s).
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder matchETag(String matchETag) {
            doSetProperty("matchETag", matchETag);
            return this;
        }
        /**
         * Set the maxConnections parameter in the minio client configuration.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Default: 60
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder maxConnections(int maxConnections) {
            doSetProperty("maxConnections", maxConnections);
            return this;
        }
        /**
         * Set the maxConnections parameter in the minio client configuration.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Default: 60
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder maxConnections(
                String maxConnections) {
            doSetProperty("maxConnections", maxConnections);
            return this;
        }
        /**
         * Gets the maximum number of messages as a limit to poll at each
         * polling. Gets the maximum number of messages as a limit to poll at
         * each polling. The default value is 10. Use 0 or a negative number to
         * set it as unlimited.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Default: 10
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder maxMessagesPerPoll(
                int maxMessagesPerPoll) {
            doSetProperty("maxMessagesPerPoll", maxMessagesPerPoll);
            return this;
        }
        /**
         * Gets the maximum number of messages as a limit to poll at each
         * polling. Gets the maximum number of messages as a limit to poll at
         * each polling. The default value is 10. Use 0 or a negative number to
         * set it as unlimited.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Default: 10
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder maxMessagesPerPoll(
                String maxMessagesPerPoll) {
            doSetProperty("maxMessagesPerPoll", maxMessagesPerPoll);
            return this;
        }
        /**
         * Set modified since parameter for get object(s).
         * 
         * The option is a: <code>java.time.ZonedDateTime</code> type.
         * 
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder modifiedSince(
                ZonedDateTime modifiedSince) {
            doSetProperty("modifiedSince", modifiedSince);
            return this;
        }
        /**
         * Set modified since parameter for get object(s).
         * 
         * The option will be converted to a
         * <code>java.time.ZonedDateTime</code> type.
         * 
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder modifiedSince(String modifiedSince) {
            doSetProperty("modifiedSince", modifiedSince);
            return this;
        }
        /**
         * Move objects from bucket to a different bucket after they have been
         * retrieved. To accomplish the operation the destinationBucket option
         * must be set. The copy bucket operation is only performed if the
         * Exchange is committed. If a rollback occurs, the object is not moved.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder moveAfterRead(boolean moveAfterRead) {
            doSetProperty("moveAfterRead", moveAfterRead);
            return this;
        }
        /**
         * Move objects from bucket to a different bucket after they have been
         * retrieved. To accomplish the operation the destinationBucket option
         * must be set. The copy bucket operation is only performed if the
         * Exchange is committed. If a rollback occurs, the object is not moved.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder moveAfterRead(String moveAfterRead) {
            doSetProperty("moveAfterRead", moveAfterRead);
            return this;
        }
        /**
         * Set not match ETag parameter for get object(s).
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder notMatchETag(String notMatchETag) {
            doSetProperty("notMatchETag", notMatchETag);
            return this;
        }
        /**
         * To get the object from the bucket with the given object name.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder objectName(String objectName) {
            doSetProperty("objectName", objectName);
            return this;
        }
        /**
         * Start byte position of object data.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder offset(long offset) {
            doSetProperty("offset", offset);
            return this;
        }
        /**
         * Start byte position of object data.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder offset(String offset) {
            doSetProperty("offset", offset);
            return this;
        }
        /**
         * Object name starts with prefix.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder prefix(String prefix) {
            doSetProperty("prefix", prefix);
            return this;
        }
        /**
         * List recursively than directory structure emulation.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder recursive(boolean recursive) {
            doSetProperty("recursive", recursive);
            return this;
        }
        /**
         * List recursively than directory structure emulation.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder recursive(String recursive) {
            doSetProperty("recursive", recursive);
            return this;
        }
        /**
         * If the polling consumer did not poll any files, you can enable this
         * option to send an empty message (no body) instead.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder sendEmptyMessageWhenIdle(
                boolean sendEmptyMessageWhenIdle) {
            doSetProperty("sendEmptyMessageWhenIdle", sendEmptyMessageWhenIdle);
            return this;
        }
        /**
         * If the polling consumer did not poll any files, you can enable this
         * option to send an empty message (no body) instead.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder sendEmptyMessageWhenIdle(
                String sendEmptyMessageWhenIdle) {
            doSetProperty("sendEmptyMessageWhenIdle", sendEmptyMessageWhenIdle);
            return this;
        }
        /**
         * list objects in bucket after this object name.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder startAfter(String startAfter) {
            doSetProperty("startAfter", startAfter);
            return this;
        }
        /**
         * Set un modified since parameter for get object(s).
         * 
         * The option is a: <code>java.time.ZonedDateTime</code> type.
         * 
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder unModifiedSince(
                ZonedDateTime unModifiedSince) {
            doSetProperty("unModifiedSince", unModifiedSince);
            return this;
        }
        /**
         * Set un modified since parameter for get object(s).
         * 
         * The option will be converted to a
         * <code>java.time.ZonedDateTime</code> type.
         * 
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder unModifiedSince(
                String unModifiedSince) {
            doSetProperty("unModifiedSince", unModifiedSince);
            return this;
        }
        /**
         * when true, version 1 of REST API is used.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder useVersion1(boolean useVersion1) {
            doSetProperty("useVersion1", useVersion1);
            return this;
        }
        /**
         * when true, version 1 of REST API is used.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder useVersion1(String useVersion1) {
            doSetProperty("useVersion1", useVersion1);
            return this;
        }
        /**
         * Set specific version_ID of a object when deleting the object.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer
         */
        default MinioEndpointConsumerBuilder versionId(String versionId) {
            doSetProperty("versionId", versionId);
            return this;
        }
        /**
         * The number of subsequent error polls (failed due some error) that
         * should happen before the backoffMultipler should kick-in.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder backoffErrorThreshold(
                int backoffErrorThreshold) {
            doSetProperty("backoffErrorThreshold", backoffErrorThreshold);
            return this;
        }
        /**
         * The number of subsequent error polls (failed due some error) that
         * should happen before the backoffMultipler should kick-in.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder backoffErrorThreshold(
                String backoffErrorThreshold) {
            doSetProperty("backoffErrorThreshold", backoffErrorThreshold);
            return this;
        }
        /**
         * The number of subsequent idle polls that should happen before the
         * backoffMultipler should kick-in.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder backoffIdleThreshold(
                int backoffIdleThreshold) {
            doSetProperty("backoffIdleThreshold", backoffIdleThreshold);
            return this;
        }
        /**
         * The number of subsequent idle polls that should happen before the
         * backoffMultipler should kick-in.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder backoffIdleThreshold(
                String backoffIdleThreshold) {
            doSetProperty("backoffIdleThreshold", backoffIdleThreshold);
            return this;
        }
        /**
         * To let the scheduled polling consumer backoff if there has been a
         * number of subsequent idles/errors in a row. The multiplier is then
         * the number of polls that will be skipped before the next actual
         * attempt is happening again. When this option is in use then
         * backoffIdleThreshold and/or backoffErrorThreshold must also be
         * configured.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder backoffMultiplier(
                int backoffMultiplier) {
            doSetProperty("backoffMultiplier", backoffMultiplier);
            return this;
        }
        /**
         * To let the scheduled polling consumer backoff if there has been a
         * number of subsequent idles/errors in a row. The multiplier is then
         * the number of polls that will be skipped before the next actual
         * attempt is happening again. When this option is in use then
         * backoffIdleThreshold and/or backoffErrorThreshold must also be
         * configured.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder backoffMultiplier(
                String backoffMultiplier) {
            doSetProperty("backoffMultiplier", backoffMultiplier);
            return this;
        }
        /**
         * Milliseconds before the next poll.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Default: 500
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder delay(long delay) {
            doSetProperty("delay", delay);
            return this;
        }
        /**
         * Milliseconds before the next poll.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Default: 500
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder delay(String delay) {
            doSetProperty("delay", delay);
            return this;
        }
        /**
         * If greedy is enabled, then the ScheduledPollConsumer will run
         * immediately again, if the previous run polled 1 or more messages.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder greedy(boolean greedy) {
            doSetProperty("greedy", greedy);
            return this;
        }
        /**
         * If greedy is enabled, then the ScheduledPollConsumer will run
         * immediately again, if the previous run polled 1 or more messages.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder greedy(String greedy) {
            doSetProperty("greedy", greedy);
            return this;
        }
        /**
         * Milliseconds before the first poll starts.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Default: 1000
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder initialDelay(long initialDelay) {
            doSetProperty("initialDelay", initialDelay);
            return this;
        }
        /**
         * Milliseconds before the first poll starts.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Default: 1000
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder initialDelay(String initialDelay) {
            doSetProperty("initialDelay", initialDelay);
            return this;
        }
        /**
         * Specifies a maximum limit of number of fires. So if you set it to 1,
         * the scheduler will only fire once. If you set it to 5, it will only
         * fire five times. A value of zero or negative means fire forever.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Default: 0
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder repeatCount(long repeatCount) {
            doSetProperty("repeatCount", repeatCount);
            return this;
        }
        /**
         * Specifies a maximum limit of number of fires. So if you set it to 1,
         * the scheduler will only fire once. If you set it to 5, it will only
         * fire five times. A value of zero or negative means fire forever.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Default: 0
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder repeatCount(String repeatCount) {
            doSetProperty("repeatCount", repeatCount);
            return this;
        }
        /**
         * The consumer logs a start/complete log line when it polls. This
         * option allows you to configure the logging level for that.
         * 
         * The option is a: <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Default: TRACE
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder runLoggingLevel(
                LoggingLevel runLoggingLevel) {
            doSetProperty("runLoggingLevel", runLoggingLevel);
            return this;
        }
        /**
         * The consumer logs a start/complete log line when it polls. This
         * option allows you to configure the logging level for that.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Default: TRACE
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder runLoggingLevel(
                String runLoggingLevel) {
            doSetProperty("runLoggingLevel", runLoggingLevel);
            return this;
        }
        /**
         * Allows for configuring a custom/shared thread pool to use for the
         * consumer. By default each consumer has its own single threaded thread
         * pool.
         * 
         * The option is a:
         * <code>java.util.concurrent.ScheduledExecutorService</code> type.
         * 
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder scheduledExecutorService(
                ScheduledExecutorService scheduledExecutorService) {
            doSetProperty("scheduledExecutorService", scheduledExecutorService);
            return this;
        }
        /**
         * Allows for configuring a custom/shared thread pool to use for the
         * consumer. By default each consumer has its own single threaded thread
         * pool.
         * 
         * The option will be converted to a
         * <code>java.util.concurrent.ScheduledExecutorService</code> type.
         * 
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder scheduledExecutorService(
                String scheduledExecutorService) {
            doSetProperty("scheduledExecutorService", scheduledExecutorService);
            return this;
        }
        /**
         * To use a cron scheduler from either camel-spring or camel-quartz
         * component.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Default: none
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder scheduler(String scheduler) {
            doSetProperty("scheduler", scheduler);
            return this;
        }
        /**
         * To configure additional properties when using a custom scheduler or
         * any of the Quartz, Spring based scheduler.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.Object&gt;</code> type.
         * The option is multivalued, and you can use the
         * schedulerProperties(String, Object) method to add a value (call the
         * method multiple times to set more values).
         * 
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder schedulerProperties(
                String key,
                Object value) {
            doSetMultiValueProperty("schedulerProperties", "scheduler." + key, value);
            return this;
        }
        /**
         * To configure additional properties when using a custom scheduler or
         * any of the Quartz, Spring based scheduler.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.Object&gt;</code> type.
         * The option is multivalued, and you can use the
         * schedulerProperties(String, Object) method to add a value (call the
         * method multiple times to set more values).
         * 
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder schedulerProperties(Map values) {
            doSetMultiValueProperties("schedulerProperties", "scheduler.", values);
            return this;
        }
        /**
         * Whether the scheduler should be auto started.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: true
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder startScheduler(
                boolean startScheduler) {
            doSetProperty("startScheduler", startScheduler);
            return this;
        }
        /**
         * Whether the scheduler should be auto started.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: true
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder startScheduler(
                String startScheduler) {
            doSetProperty("startScheduler", startScheduler);
            return this;
        }
        /**
         * Time unit for initialDelay and delay options.
         * 
         * The option is a: <code>java.util.concurrent.TimeUnit</code> type.
         * 
         * Default: MILLISECONDS
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder timeUnit(TimeUnit timeUnit) {
            doSetProperty("timeUnit", timeUnit);
            return this;
        }
        /**
         * Time unit for initialDelay and delay options.
         * 
         * The option will be converted to a
         * <code>java.util.concurrent.TimeUnit</code> type.
         * 
         * Default: MILLISECONDS
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder timeUnit(String timeUnit) {
            doSetProperty("timeUnit", timeUnit);
            return this;
        }
        /**
         * Controls if fixed delay or fixed rate is used. See
         * ScheduledExecutorService in JDK for details.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: true
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder useFixedDelay(boolean useFixedDelay) {
            doSetProperty("useFixedDelay", useFixedDelay);
            return this;
        }
        /**
         * Controls if fixed delay or fixed rate is used. See
         * ScheduledExecutorService in JDK for details.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: true
         * Group: scheduler
         */
        default MinioEndpointConsumerBuilder useFixedDelay(String useFixedDelay) {
            doSetProperty("useFixedDelay", useFixedDelay);
            return this;
        }
        /**
         * Amazon AWS Secret Access Key or Minio Access Key. If not set camel
         * will connect to service for anonymous access.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default MinioEndpointConsumerBuilder accessKey(String accessKey) {
            doSetProperty("accessKey", accessKey);
            return this;
        }
        /**
         * Amazon AWS Access Key Id or Minio Secret Key. If not set camel will
         * connect to service for anonymous access.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default MinioEndpointConsumerBuilder secretKey(String secretKey) {
            doSetProperty("secretKey", secretKey);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint consumers for the Minio component.
     */
    public interface AdvancedMinioEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default MinioEndpointConsumerBuilder basic() {
            return (MinioEndpointConsumerBuilder) this;
        }
        /**
         * To let the consumer use a custom ExceptionHandler. Notice if the
         * option bridgeErrorHandler is enabled then this option is not in use.
         * By default the consumer will deal with exceptions, that will be
         * logged at WARN or ERROR level and ignored.
         * 
         * The option is a: <code>org.apache.camel.spi.ExceptionHandler</code>
         * type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedMinioEndpointConsumerBuilder exceptionHandler(
                ExceptionHandler exceptionHandler) {
            doSetProperty("exceptionHandler", exceptionHandler);
            return this;
        }
        /**
         * To let the consumer use a custom ExceptionHandler. Notice if the
         * option bridgeErrorHandler is enabled then this option is not in use.
         * By default the consumer will deal with exceptions, that will be
         * logged at WARN or ERROR level and ignored.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.spi.ExceptionHandler</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedMinioEndpointConsumerBuilder exceptionHandler(
                String exceptionHandler) {
            doSetProperty("exceptionHandler", exceptionHandler);
            return this;
        }
        /**
         * Sets the exchange pattern when the consumer creates an exchange.
         * 
         * The option is a: <code>org.apache.camel.ExchangePattern</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedMinioEndpointConsumerBuilder exchangePattern(
                ExchangePattern exchangePattern) {
            doSetProperty("exchangePattern", exchangePattern);
            return this;
        }
        /**
         * Sets the exchange pattern when the consumer creates an exchange.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.ExchangePattern</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedMinioEndpointConsumerBuilder exchangePattern(
                String exchangePattern) {
            doSetProperty("exchangePattern", exchangePattern);
            return this;
        }
        /**
         * A pluggable org.apache.camel.PollingConsumerPollingStrategy allowing
         * you to provide your custom implementation to control error handling
         * usually occurred during the poll operation before an Exchange have
         * been created and being routed in Camel.
         * 
         * The option is a:
         * <code>org.apache.camel.spi.PollingConsumerPollStrategy</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedMinioEndpointConsumerBuilder pollStrategy(
                PollingConsumerPollStrategy pollStrategy) {
            doSetProperty("pollStrategy", pollStrategy);
            return this;
        }
        /**
         * A pluggable org.apache.camel.PollingConsumerPollingStrategy allowing
         * you to provide your custom implementation to control error handling
         * usually occurred during the poll operation before an Exchange have
         * been created and being routed in Camel.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.spi.PollingConsumerPollStrategy</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedMinioEndpointConsumerBuilder pollStrategy(
                String pollStrategy) {
            doSetProperty("pollStrategy", pollStrategy);
            return this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: advanced
         */
        default AdvancedMinioEndpointConsumerBuilder basicPropertyBinding(
                boolean basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: advanced
         */
        default AdvancedMinioEndpointConsumerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: advanced
         */
        default AdvancedMinioEndpointConsumerBuilder synchronous(
                boolean synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: advanced
         */
        default AdvancedMinioEndpointConsumerBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
    }

    /**
     * Builder for endpoint producers for the Minio component.
     */
    public interface MinioEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default AdvancedMinioEndpointProducerBuilder advanced() {
            return (AdvancedMinioEndpointProducerBuilder) this;
        }
        /**
         * Setting the autocreation of the bucket if bucket name not exist.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: true
         * Group: common
         */
        default MinioEndpointProducerBuilder autoCreateBucket(
                boolean autoCreateBucket) {
            doSetProperty("autoCreateBucket", autoCreateBucket);
            return this;
        }
        /**
         * Setting the autocreation of the bucket if bucket name not exist.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: true
         * Group: common
         */
        default MinioEndpointProducerBuilder autoCreateBucket(
                String autoCreateBucket) {
            doSetProperty("autoCreateBucket", autoCreateBucket);
            return this;
        }
        /**
         * Set custom HTTP client for authenticated access.
         * 
         * The option is a: <code>okhttp3.OkHttpClient</code> type.
         * 
         * Group: common
         */
        default MinioEndpointProducerBuilder customHttpClient(
                Object customHttpClient) {
            doSetProperty("customHttpClient", customHttpClient);
            return this;
        }
        /**
         * Set custom HTTP client for authenticated access.
         * 
         * The option will be converted to a <code>okhttp3.OkHttpClient</code>
         * type.
         * 
         * Group: common
         */
        default MinioEndpointProducerBuilder customHttpClient(
                String customHttpClient) {
            doSetProperty("customHttpClient", customHttpClient);
            return this;
        }
        /**
         * Endpoint can be an URL, domain name, IPv4 address or IPv6 address.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default MinioEndpointProducerBuilder endpoint(String endpoint) {
            doSetProperty("endpoint", endpoint);
            return this;
        }
        /**
         * Reference to a Minio Client object in the registry.
         * 
         * The option is a: <code>io.minio.MinioClient</code> type.
         * 
         * Group: common
         */
        default MinioEndpointProducerBuilder minioClient(Object minioClient) {
            doSetProperty("minioClient", minioClient);
            return this;
        }
        /**
         * Reference to a Minio Client object in the registry.
         * 
         * The option will be converted to a <code>io.minio.MinioClient</code>
         * type.
         * 
         * Group: common
         */
        default MinioEndpointProducerBuilder minioClient(String minioClient) {
            doSetProperty("minioClient", minioClient);
            return this;
        }
        /**
         * Set when creating new bucket.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: common
         */
        default MinioEndpointProducerBuilder objectLock(boolean objectLock) {
            doSetProperty("objectLock", objectLock);
            return this;
        }
        /**
         * Set when creating new bucket.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: common
         */
        default MinioEndpointProducerBuilder objectLock(String objectLock) {
            doSetProperty("objectLock", objectLock);
            return this;
        }
        /**
         * The policy for this queue to set in the method.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default MinioEndpointProducerBuilder policy(String policy) {
            doSetProperty("policy", policy);
            return this;
        }
        /**
         * TCP/IP port number. 80 and 443 are used as defaults for HTTP and
         * HTTPS.
         * 
         * The option is a: <code>java.lang.Integer</code> type.
         * 
         * Group: common
         */
        default MinioEndpointProducerBuilder proxyPort(Integer proxyPort) {
            doSetProperty("proxyPort", proxyPort);
            return this;
        }
        /**
         * TCP/IP port number. 80 and 443 are used as defaults for HTTP and
         * HTTPS.
         * 
         * The option will be converted to a <code>java.lang.Integer</code>
         * type.
         * 
         * Group: common
         */
        default MinioEndpointProducerBuilder proxyPort(String proxyPort) {
            doSetProperty("proxyPort", proxyPort);
            return this;
        }
        /**
         * The region in which Minio client needs to work. When using this
         * parameter, the configuration will expect the lowercase name of the
         * region (for example ap-east-1). You'll need to use the name
         * Region.EU_WEST_1.id().
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default MinioEndpointProducerBuilder region(String region) {
            doSetProperty("region", region);
            return this;
        }
        /**
         * Flag to indicate to use secure connection to minio service or not.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: common
         */
        default MinioEndpointProducerBuilder secure(boolean secure) {
            doSetProperty("secure", secure);
            return this;
        }
        /**
         * Flag to indicate to use secure connection to minio service or not.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: common
         */
        default MinioEndpointProducerBuilder secure(String secure) {
            doSetProperty("secure", secure);
            return this;
        }
        /**
         * Server-side encryption.
         * 
         * The option is a: <code>io.minio.ServerSideEncryption</code> type.
         * 
         * Group: common
         */
        default MinioEndpointProducerBuilder serverSideEncryption(
                Object serverSideEncryption) {
            doSetProperty("serverSideEncryption", serverSideEncryption);
            return this;
        }
        /**
         * Server-side encryption.
         * 
         * The option will be converted to a
         * <code>io.minio.ServerSideEncryption</code> type.
         * 
         * Group: common
         */
        default MinioEndpointProducerBuilder serverSideEncryption(
                String serverSideEncryption) {
            doSetProperty("serverSideEncryption", serverSideEncryption);
            return this;
        }
        /**
         * Server-side encryption for source object while copy/move objects.
         * 
         * The option is a:
         * <code>io.minio.ServerSideEncryptionCustomerKey</code> type.
         * 
         * Group: common
         */
        default MinioEndpointProducerBuilder serverSideEncryptionCustomerKey(
                Object serverSideEncryptionCustomerKey) {
            doSetProperty("serverSideEncryptionCustomerKey", serverSideEncryptionCustomerKey);
            return this;
        }
        /**
         * Server-side encryption for source object while copy/move objects.
         * 
         * The option will be converted to a
         * <code>io.minio.ServerSideEncryptionCustomerKey</code> type.
         * 
         * Group: common
         */
        default MinioEndpointProducerBuilder serverSideEncryptionCustomerKey(
                String serverSideEncryptionCustomerKey) {
            doSetProperty("serverSideEncryptionCustomerKey", serverSideEncryptionCustomerKey);
            return this;
        }
        /**
         * Delete file object after the Minio file has been uploaded.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: producer
         */
        default MinioEndpointProducerBuilder deleteAfterWrite(
                boolean deleteAfterWrite) {
            doSetProperty("deleteAfterWrite", deleteAfterWrite);
            return this;
        }
        /**
         * Delete file object after the Minio file has been uploaded.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: producer
         */
        default MinioEndpointProducerBuilder deleteAfterWrite(
                String deleteAfterWrite) {
            doSetProperty("deleteAfterWrite", deleteAfterWrite);
            return this;
        }
        /**
         * Setting the key name for an element in the bucket through endpoint
         * parameter.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer
         */
        default MinioEndpointProducerBuilder keyName(String keyName) {
            doSetProperty("keyName", keyName);
            return this;
        }
        /**
         * Whether the producer should be started lazy (on the first message).
         * By starting lazy you can use this to allow CamelContext and routes to
         * startup in situations where a producer may otherwise fail during
         * starting and cause the route to fail being started. By deferring this
         * startup to be lazy then the startup failure can be handled during
         * routing messages via Camel's routing error handlers. Beware that when
         * the first message is processed then creating and starting the
         * producer may take a little time and prolong the total processing time
         * of the processing.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: producer
         */
        default MinioEndpointProducerBuilder lazyStartProducer(
                boolean lazyStartProducer) {
            doSetProperty("lazyStartProducer", lazyStartProducer);
            return this;
        }
        /**
         * Whether the producer should be started lazy (on the first message).
         * By starting lazy you can use this to allow CamelContext and routes to
         * startup in situations where a producer may otherwise fail during
         * starting and cause the route to fail being started. By deferring this
         * startup to be lazy then the startup failure can be handled during
         * routing messages via Camel's routing error handlers. Beware that when
         * the first message is processed then creating and starting the
         * producer may take a little time and prolong the total processing time
         * of the processing.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: producer
         */
        default MinioEndpointProducerBuilder lazyStartProducer(
                String lazyStartProducer) {
            doSetProperty("lazyStartProducer", lazyStartProducer);
            return this;
        }
        /**
         * The operation to do in case the user don't want to do only an upload.
         * 
         * The option is a:
         * <code>org.apache.camel.component.minio.MinioOperations</code> type.
         * 
         * Group: producer
         */
        default MinioEndpointProducerBuilder operation(MinioOperations operation) {
            doSetProperty("operation", operation);
            return this;
        }
        /**
         * The operation to do in case the user don't want to do only an upload.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.minio.MinioOperations</code> type.
         * 
         * Group: producer
         */
        default MinioEndpointProducerBuilder operation(String operation) {
            doSetProperty("operation", operation);
            return this;
        }
        /**
         * If we want to use a POJO request as body or not.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: producer
         */
        default MinioEndpointProducerBuilder pojoRequest(boolean pojoRequest) {
            doSetProperty("pojoRequest", pojoRequest);
            return this;
        }
        /**
         * If we want to use a POJO request as body or not.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: producer
         */
        default MinioEndpointProducerBuilder pojoRequest(String pojoRequest) {
            doSetProperty("pojoRequest", pojoRequest);
            return this;
        }
        /**
         * The storage class to set in the request.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer
         */
        default MinioEndpointProducerBuilder storageClass(String storageClass) {
            doSetProperty("storageClass", storageClass);
            return this;
        }
        /**
         * Amazon AWS Secret Access Key or Minio Access Key. If not set camel
         * will connect to service for anonymous access.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default MinioEndpointProducerBuilder accessKey(String accessKey) {
            doSetProperty("accessKey", accessKey);
            return this;
        }
        /**
         * Amazon AWS Access Key Id or Minio Secret Key. If not set camel will
         * connect to service for anonymous access.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default MinioEndpointProducerBuilder secretKey(String secretKey) {
            doSetProperty("secretKey", secretKey);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint producers for the Minio component.
     */
    public interface AdvancedMinioEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default MinioEndpointProducerBuilder basic() {
            return (MinioEndpointProducerBuilder) this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: advanced
         */
        default AdvancedMinioEndpointProducerBuilder basicPropertyBinding(
                boolean basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: advanced
         */
        default AdvancedMinioEndpointProducerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: advanced
         */
        default AdvancedMinioEndpointProducerBuilder synchronous(
                boolean synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: advanced
         */
        default AdvancedMinioEndpointProducerBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
    }

    /**
     * Builder for endpoint for the Minio component.
     */
    public interface MinioEndpointBuilder
            extends
                MinioEndpointConsumerBuilder,
                MinioEndpointProducerBuilder {
        default AdvancedMinioEndpointBuilder advanced() {
            return (AdvancedMinioEndpointBuilder) this;
        }
        /**
         * Setting the autocreation of the bucket if bucket name not exist.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: true
         * Group: common
         */
        default MinioEndpointBuilder autoCreateBucket(boolean autoCreateBucket) {
            doSetProperty("autoCreateBucket", autoCreateBucket);
            return this;
        }
        /**
         * Setting the autocreation of the bucket if bucket name not exist.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: true
         * Group: common
         */
        default MinioEndpointBuilder autoCreateBucket(String autoCreateBucket) {
            doSetProperty("autoCreateBucket", autoCreateBucket);
            return this;
        }
        /**
         * Set custom HTTP client for authenticated access.
         * 
         * The option is a: <code>okhttp3.OkHttpClient</code> type.
         * 
         * Group: common
         */
        default MinioEndpointBuilder customHttpClient(Object customHttpClient) {
            doSetProperty("customHttpClient", customHttpClient);
            return this;
        }
        /**
         * Set custom HTTP client for authenticated access.
         * 
         * The option will be converted to a <code>okhttp3.OkHttpClient</code>
         * type.
         * 
         * Group: common
         */
        default MinioEndpointBuilder customHttpClient(String customHttpClient) {
            doSetProperty("customHttpClient", customHttpClient);
            return this;
        }
        /**
         * Endpoint can be an URL, domain name, IPv4 address or IPv6 address.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default MinioEndpointBuilder endpoint(String endpoint) {
            doSetProperty("endpoint", endpoint);
            return this;
        }
        /**
         * Reference to a Minio Client object in the registry.
         * 
         * The option is a: <code>io.minio.MinioClient</code> type.
         * 
         * Group: common
         */
        default MinioEndpointBuilder minioClient(Object minioClient) {
            doSetProperty("minioClient", minioClient);
            return this;
        }
        /**
         * Reference to a Minio Client object in the registry.
         * 
         * The option will be converted to a <code>io.minio.MinioClient</code>
         * type.
         * 
         * Group: common
         */
        default MinioEndpointBuilder minioClient(String minioClient) {
            doSetProperty("minioClient", minioClient);
            return this;
        }
        /**
         * Set when creating new bucket.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: common
         */
        default MinioEndpointBuilder objectLock(boolean objectLock) {
            doSetProperty("objectLock", objectLock);
            return this;
        }
        /**
         * Set when creating new bucket.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: common
         */
        default MinioEndpointBuilder objectLock(String objectLock) {
            doSetProperty("objectLock", objectLock);
            return this;
        }
        /**
         * The policy for this queue to set in the method.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default MinioEndpointBuilder policy(String policy) {
            doSetProperty("policy", policy);
            return this;
        }
        /**
         * TCP/IP port number. 80 and 443 are used as defaults for HTTP and
         * HTTPS.
         * 
         * The option is a: <code>java.lang.Integer</code> type.
         * 
         * Group: common
         */
        default MinioEndpointBuilder proxyPort(Integer proxyPort) {
            doSetProperty("proxyPort", proxyPort);
            return this;
        }
        /**
         * TCP/IP port number. 80 and 443 are used as defaults for HTTP and
         * HTTPS.
         * 
         * The option will be converted to a <code>java.lang.Integer</code>
         * type.
         * 
         * Group: common
         */
        default MinioEndpointBuilder proxyPort(String proxyPort) {
            doSetProperty("proxyPort", proxyPort);
            return this;
        }
        /**
         * The region in which Minio client needs to work. When using this
         * parameter, the configuration will expect the lowercase name of the
         * region (for example ap-east-1). You'll need to use the name
         * Region.EU_WEST_1.id().
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default MinioEndpointBuilder region(String region) {
            doSetProperty("region", region);
            return this;
        }
        /**
         * Flag to indicate to use secure connection to minio service or not.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: common
         */
        default MinioEndpointBuilder secure(boolean secure) {
            doSetProperty("secure", secure);
            return this;
        }
        /**
         * Flag to indicate to use secure connection to minio service or not.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: common
         */
        default MinioEndpointBuilder secure(String secure) {
            doSetProperty("secure", secure);
            return this;
        }
        /**
         * Server-side encryption.
         * 
         * The option is a: <code>io.minio.ServerSideEncryption</code> type.
         * 
         * Group: common
         */
        default MinioEndpointBuilder serverSideEncryption(
                Object serverSideEncryption) {
            doSetProperty("serverSideEncryption", serverSideEncryption);
            return this;
        }
        /**
         * Server-side encryption.
         * 
         * The option will be converted to a
         * <code>io.minio.ServerSideEncryption</code> type.
         * 
         * Group: common
         */
        default MinioEndpointBuilder serverSideEncryption(
                String serverSideEncryption) {
            doSetProperty("serverSideEncryption", serverSideEncryption);
            return this;
        }
        /**
         * Server-side encryption for source object while copy/move objects.
         * 
         * The option is a:
         * <code>io.minio.ServerSideEncryptionCustomerKey</code> type.
         * 
         * Group: common
         */
        default MinioEndpointBuilder serverSideEncryptionCustomerKey(
                Object serverSideEncryptionCustomerKey) {
            doSetProperty("serverSideEncryptionCustomerKey", serverSideEncryptionCustomerKey);
            return this;
        }
        /**
         * Server-side encryption for source object while copy/move objects.
         * 
         * The option will be converted to a
         * <code>io.minio.ServerSideEncryptionCustomerKey</code> type.
         * 
         * Group: common
         */
        default MinioEndpointBuilder serverSideEncryptionCustomerKey(
                String serverSideEncryptionCustomerKey) {
            doSetProperty("serverSideEncryptionCustomerKey", serverSideEncryptionCustomerKey);
            return this;
        }
        /**
         * Amazon AWS Secret Access Key or Minio Access Key. If not set camel
         * will connect to service for anonymous access.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default MinioEndpointBuilder accessKey(String accessKey) {
            doSetProperty("accessKey", accessKey);
            return this;
        }
        /**
         * Amazon AWS Access Key Id or Minio Secret Key. If not set camel will
         * connect to service for anonymous access.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default MinioEndpointBuilder secretKey(String secretKey) {
            doSetProperty("secretKey", secretKey);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint for the Minio component.
     */
    public interface AdvancedMinioEndpointBuilder
            extends
                AdvancedMinioEndpointConsumerBuilder,
                AdvancedMinioEndpointProducerBuilder {
        default MinioEndpointBuilder basic() {
            return (MinioEndpointBuilder) this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: advanced
         */
        default AdvancedMinioEndpointBuilder basicPropertyBinding(
                boolean basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: advanced
         */
        default AdvancedMinioEndpointBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Default: false
         * Group: advanced
         */
        default AdvancedMinioEndpointBuilder synchronous(boolean synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Default: false
         * Group: advanced
         */
        default AdvancedMinioEndpointBuilder synchronous(String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
    }

    /**
     * Proxy enum for
     * <code>org.apache.camel.component.minio.MinioOperations</code> enum.
     */
    enum MinioOperations {
        copyObject,
        listObjects,
        deleteObject,
        deleteObjects,
        deleteBucket,
        listBuckets,
        getObject,
        getPartialObject;
    }

    public interface MinioBuilders {
        /**
         * Minio (camel-minio)
         * Store and retrieve objects from Minio Storage Service using Minio
         * SDK.
         * 
         * Category: cloud,file
         * Since: 3.5
         * Maven coordinates: org.apache.camel:camel-minio
         * 
         * Syntax: <code>minio:bucketName</code>
         * 
         * Path parameter: bucketName (required)
         * Bucket name
         * 
         * @param path bucketName
         */
        default MinioEndpointBuilder minio(String path) {
            return MinioEndpointBuilderFactory.endpointBuilder("minio", path);
        }
        /**
         * Minio (camel-minio)
         * Store and retrieve objects from Minio Storage Service using Minio
         * SDK.
         * 
         * Category: cloud,file
         * Since: 3.5
         * Maven coordinates: org.apache.camel:camel-minio
         * 
         * Syntax: <code>minio:bucketName</code>
         * 
         * Path parameter: bucketName (required)
         * Bucket name
         * 
         * @param componentName to use a custom component name for the endpoint
         * instead of the default name
         * @param path bucketName
         */
        default MinioEndpointBuilder minio(String componentName, String path) {
            return MinioEndpointBuilderFactory.endpointBuilder(componentName, path);
        }
    }
    static MinioEndpointBuilder endpointBuilder(
            String componentName,
            String path) {
        class MinioEndpointBuilderImpl extends AbstractEndpointBuilder implements MinioEndpointBuilder, AdvancedMinioEndpointBuilder {
            public MinioEndpointBuilderImpl(String path) {
                super(componentName, path);
            }
        }
        return new MinioEndpointBuilderImpl(path);
    }
}