/*
 * 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.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;

/**
 * Send and receive messages to/from IronMQ an elastic and durable hosted
 * message queue as a service.
 * 
 * Generated by camel build tools - do NOT edit this file!
 */
@Generated("org.apache.camel.maven.packaging.EndpointDslMojo")
public interface IronMQEndpointBuilderFactory {


    /**
     * Builder for endpoint consumers for the IronMQ component.
     */
    public interface IronMQEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default AdvancedIronMQEndpointConsumerBuilder advanced() {
            return (AdvancedIronMQEndpointConsumerBuilder) this;
        }
        /**
         * Reference to a io.iron.ironmq.Client in the Registry.
         * 
         * The option is a: &lt;code&gt;io.iron.ironmq.Client&lt;/code&gt; type.
         * 
         * Group: common
         * 
         * @param client the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder client(Object client) {
            doSetProperty("client", client);
            return this;
        }
        /**
         * Reference to a io.iron.ironmq.Client in the Registry.
         * 
         * The option will be converted to a
         * &lt;code&gt;io.iron.ironmq.Client&lt;/code&gt; type.
         * 
         * Group: common
         * 
         * @param client the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder client(String client) {
            doSetProperty("client", client);
            return this;
        }
        /**
         * IronMq Cloud url. Urls for public clusters:
         * https://mq-aws-us-east-1-1.iron.io (US) and
         * https://mq-aws-eu-west-1-1.iron.io (EU).
         * 
         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
         * 
         * Default: https://mq-aws-us-east-1-1.iron.io
         * Group: common
         * 
         * @param ironMQCloud the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder ironMQCloud(String ironMQCloud) {
            doSetProperty("ironMQCloud", ironMQCloud);
            return this;
        }
        /**
         * Should message headers be preserved when publishing messages. This
         * will add the Camel headers to the Iron MQ message as a json payload
         * with a header list, and a message body. Useful when Camel is both
         * consumer and producer.
         * 
         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
         * 
         * Default: false
         * Group: common
         * 
         * @param preserveHeaders the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder preserveHeaders(
                boolean preserveHeaders) {
            doSetProperty("preserveHeaders", preserveHeaders);
            return this;
        }
        /**
         * Should message headers be preserved when publishing messages. This
         * will add the Camel headers to the Iron MQ message as a json payload
         * with a header list, and a message body. Useful when Camel is both
         * consumer and producer.
         * 
         * The option will be converted to a &lt;code&gt;boolean&lt;/code&gt;
         * type.
         * 
         * Default: false
         * Group: common
         * 
         * @param preserveHeaders the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder preserveHeaders(
                String preserveHeaders) {
            doSetProperty("preserveHeaders", preserveHeaders);
            return this;
        }
        /**
         * IronMQ projectId.
         * 
         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
         * 
         * Group: common
         * 
         * @param projectId the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder projectId(String projectId) {
            doSetProperty("projectId", projectId);
            return this;
        }
        /**
         * IronMQ token.
         * 
         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
         * 
         * Group: common
         * 
         * @param token the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder token(String token) {
            doSetProperty("token", token);
            return this;
        }
        /**
         * Should messages be deleted in one batch. This will limit the number
         * of api requests since messages are deleted in one request, instead of
         * one pr. exchange. If enabled care should be taken that the consumer
         * is idempotent when processing exchanges.
         * 
         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
         * 
         * Default: false
         * Group: consumer
         * 
         * @param batchDelete the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder batchDelete(boolean batchDelete) {
            doSetProperty("batchDelete", batchDelete);
            return this;
        }
        /**
         * Should messages be deleted in one batch. This will limit the number
         * of api requests since messages are deleted in one request, instead of
         * one pr. exchange. If enabled care should be taken that the consumer
         * is idempotent when processing exchanges.
         * 
         * The option will be converted to a &lt;code&gt;boolean&lt;/code&gt;
         * type.
         * 
         * Default: false
         * Group: consumer
         * 
         * @param batchDelete the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder batchDelete(String batchDelete) {
            doSetProperty("batchDelete", batchDelete);
            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: &lt;code&gt;boolean&lt;/code&gt; type.
         * 
         * Default: false
         * Group: consumer
         * 
         * @param bridgeErrorHandler the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder 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 &lt;code&gt;boolean&lt;/code&gt;
         * type.
         * 
         * Default: false
         * Group: consumer
         * 
         * @param bridgeErrorHandler the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder bridgeErrorHandler(
                String bridgeErrorHandler) {
            doSetProperty("bridgeErrorHandler", bridgeErrorHandler);
            return this;
        }
        /**
         * The number of concurrent consumers.
         * 
         * The option is a: &lt;code&gt;int&lt;/code&gt; type.
         * 
         * Default: 1
         * Group: consumer
         * 
         * @param concurrentConsumers the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder concurrentConsumers(
                int concurrentConsumers) {
            doSetProperty("concurrentConsumers", concurrentConsumers);
            return this;
        }
        /**
         * The number of concurrent consumers.
         * 
         * The option will be converted to a &lt;code&gt;int&lt;/code&gt; type.
         * 
         * Default: 1
         * Group: consumer
         * 
         * @param concurrentConsumers the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder concurrentConsumers(
                String concurrentConsumers) {
            doSetProperty("concurrentConsumers", concurrentConsumers);
            return this;
        }
        /**
         * Number of messages to poll pr. call. Maximum is 100.
         * 
         * The option is a: &lt;code&gt;int&lt;/code&gt; type.
         * 
         * Default: 1
         * Group: consumer
         * 
         * @param maxMessagesPerPoll the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder maxMessagesPerPoll(
                int maxMessagesPerPoll) {
            doSetProperty("maxMessagesPerPoll", maxMessagesPerPoll);
            return this;
        }
        /**
         * Number of messages to poll pr. call. Maximum is 100.
         * 
         * The option will be converted to a &lt;code&gt;int&lt;/code&gt; type.
         * 
         * Default: 1
         * Group: consumer
         * 
         * @param maxMessagesPerPoll the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder maxMessagesPerPoll(
                String maxMessagesPerPoll) {
            doSetProperty("maxMessagesPerPoll", maxMessagesPerPoll);
            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: &lt;code&gt;boolean&lt;/code&gt; type.
         * 
         * Default: false
         * Group: consumer
         * 
         * @param sendEmptyMessageWhenIdle the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder 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 &lt;code&gt;boolean&lt;/code&gt;
         * type.
         * 
         * Default: false
         * Group: consumer
         * 
         * @param sendEmptyMessageWhenIdle the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder sendEmptyMessageWhenIdle(
                String sendEmptyMessageWhenIdle) {
            doSetProperty("sendEmptyMessageWhenIdle", sendEmptyMessageWhenIdle);
            return this;
        }
        /**
         * After timeout (in seconds), item will be placed back onto the queue.
         * 
         * The option is a: &lt;code&gt;int&lt;/code&gt; type.
         * 
         * Default: 60
         * Group: consumer
         * 
         * @param timeout the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder timeout(int timeout) {
            doSetProperty("timeout", timeout);
            return this;
        }
        /**
         * After timeout (in seconds), item will be placed back onto the queue.
         * 
         * The option will be converted to a &lt;code&gt;int&lt;/code&gt; type.
         * 
         * Default: 60
         * Group: consumer
         * 
         * @param timeout the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder timeout(String timeout) {
            doSetProperty("timeout", timeout);
            return this;
        }
        /**
         * Time in seconds to wait for a message to become available. This
         * enables long polling. Default is 0 (does not wait), maximum is 30.
         * 
         * The option is a: &lt;code&gt;int&lt;/code&gt; type.
         * 
         * Group: consumer
         * 
         * @param wait the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder wait(int wait) {
            doSetProperty("wait", wait);
            return this;
        }
        /**
         * Time in seconds to wait for a message to become available. This
         * enables long polling. Default is 0 (does not wait), maximum is 30.
         * 
         * The option will be converted to a &lt;code&gt;int&lt;/code&gt; type.
         * 
         * Group: consumer
         * 
         * @param wait the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder wait(String wait) {
            doSetProperty("wait", wait);
            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: &lt;code&gt;int&lt;/code&gt; type.
         * 
         * Group: scheduler
         * 
         * @param backoffErrorThreshold the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder 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 &lt;code&gt;int&lt;/code&gt; type.
         * 
         * Group: scheduler
         * 
         * @param backoffErrorThreshold the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder 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: &lt;code&gt;int&lt;/code&gt; type.
         * 
         * Group: scheduler
         * 
         * @param backoffIdleThreshold the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder 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 &lt;code&gt;int&lt;/code&gt; type.
         * 
         * Group: scheduler
         * 
         * @param backoffIdleThreshold the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder 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: &lt;code&gt;int&lt;/code&gt; type.
         * 
         * Group: scheduler
         * 
         * @param backoffMultiplier the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder 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 &lt;code&gt;int&lt;/code&gt; type.
         * 
         * Group: scheduler
         * 
         * @param backoffMultiplier the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder backoffMultiplier(
                String backoffMultiplier) {
            doSetProperty("backoffMultiplier", backoffMultiplier);
            return this;
        }
        /**
         * Milliseconds before the next poll.
         * 
         * The option is a: &lt;code&gt;long&lt;/code&gt; type.
         * 
         * Default: 500
         * Group: scheduler
         * 
         * @param delay the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder delay(long delay) {
            doSetProperty("delay", delay);
            return this;
        }
        /**
         * Milliseconds before the next poll.
         * 
         * The option will be converted to a &lt;code&gt;long&lt;/code&gt; type.
         * 
         * Default: 500
         * Group: scheduler
         * 
         * @param delay the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder 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: &lt;code&gt;boolean&lt;/code&gt; type.
         * 
         * Default: false
         * Group: scheduler
         * 
         * @param greedy the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder 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 &lt;code&gt;boolean&lt;/code&gt;
         * type.
         * 
         * Default: false
         * Group: scheduler
         * 
         * @param greedy the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder greedy(String greedy) {
            doSetProperty("greedy", greedy);
            return this;
        }
        /**
         * Milliseconds before the first poll starts.
         * 
         * The option is a: &lt;code&gt;long&lt;/code&gt; type.
         * 
         * Default: 1000
         * Group: scheduler
         * 
         * @param initialDelay the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder initialDelay(long initialDelay) {
            doSetProperty("initialDelay", initialDelay);
            return this;
        }
        /**
         * Milliseconds before the first poll starts.
         * 
         * The option will be converted to a &lt;code&gt;long&lt;/code&gt; type.
         * 
         * Default: 1000
         * Group: scheduler
         * 
         * @param initialDelay the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder 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: &lt;code&gt;long&lt;/code&gt; type.
         * 
         * Default: 0
         * Group: scheduler
         * 
         * @param repeatCount the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder 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 &lt;code&gt;long&lt;/code&gt; type.
         * 
         * Default: 0
         * Group: scheduler
         * 
         * @param repeatCount the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder 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:
         * &lt;code&gt;org.apache.camel.LoggingLevel&lt;/code&gt; type.
         * 
         * Default: TRACE
         * Group: scheduler
         * 
         * @param runLoggingLevel the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder 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
         * &lt;code&gt;org.apache.camel.LoggingLevel&lt;/code&gt; type.
         * 
         * Default: TRACE
         * Group: scheduler
         * 
         * @param runLoggingLevel the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder 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:
         * &lt;code&gt;java.util.concurrent.ScheduledExecutorService&lt;/code&gt; type.
         * 
         * Group: scheduler
         * 
         * @param scheduledExecutorService the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder 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
         * &lt;code&gt;java.util.concurrent.ScheduledExecutorService&lt;/code&gt; type.
         * 
         * Group: scheduler
         * 
         * @param scheduledExecutorService the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder scheduledExecutorService(
                String scheduledExecutorService) {
            doSetProperty("scheduledExecutorService", scheduledExecutorService);
            return this;
        }
        /**
         * To use a cron scheduler from either camel-spring or camel-quartz
         * component. Use value spring or quartz for built in scheduler.
         * 
         * The option is a: &lt;code&gt;java.lang.Object&lt;/code&gt; type.
         * 
         * Default: none
         * Group: scheduler
         * 
         * @param scheduler the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder scheduler(Object scheduler) {
            doSetProperty("scheduler", scheduler);
            return this;
        }
        /**
         * To use a cron scheduler from either camel-spring or camel-quartz
         * component. Use value spring or quartz for built in scheduler.
         * 
         * The option will be converted to a
         * &lt;code&gt;java.lang.Object&lt;/code&gt; type.
         * 
         * Default: none
         * Group: scheduler
         * 
         * @param scheduler the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder 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: &lt;code&gt;java.util.Map&amp;lt;java.lang.String,
         * java.lang.Object&amp;gt;&lt;/code&gt; 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
         * 
         * @param key the option key
         * @param value the option value
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder 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: &lt;code&gt;java.util.Map&amp;lt;java.lang.String,
         * java.lang.Object&amp;gt;&lt;/code&gt; 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
         * 
         * @param values the values
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder schedulerProperties(Map values) {
            doSetMultiValueProperties("schedulerProperties", "scheduler.", values);
            return this;
        }
        /**
         * Whether the scheduler should be auto started.
         * 
         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
         * 
         * Default: true
         * Group: scheduler
         * 
         * @param startScheduler the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder startScheduler(
                boolean startScheduler) {
            doSetProperty("startScheduler", startScheduler);
            return this;
        }
        /**
         * Whether the scheduler should be auto started.
         * 
         * The option will be converted to a &lt;code&gt;boolean&lt;/code&gt;
         * type.
         * 
         * Default: true
         * Group: scheduler
         * 
         * @param startScheduler the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder startScheduler(
                String startScheduler) {
            doSetProperty("startScheduler", startScheduler);
            return this;
        }
        /**
         * Time unit for initialDelay and delay options.
         * 
         * The option is a:
         * &lt;code&gt;java.util.concurrent.TimeUnit&lt;/code&gt; type.
         * 
         * Default: MILLISECONDS
         * Group: scheduler
         * 
         * @param timeUnit the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder timeUnit(TimeUnit timeUnit) {
            doSetProperty("timeUnit", timeUnit);
            return this;
        }
        /**
         * Time unit for initialDelay and delay options.
         * 
         * The option will be converted to a
         * &lt;code&gt;java.util.concurrent.TimeUnit&lt;/code&gt; type.
         * 
         * Default: MILLISECONDS
         * Group: scheduler
         * 
         * @param timeUnit the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder 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: &lt;code&gt;boolean&lt;/code&gt; type.
         * 
         * Default: true
         * Group: scheduler
         * 
         * @param useFixedDelay the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder 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 &lt;code&gt;boolean&lt;/code&gt;
         * type.
         * 
         * Default: true
         * Group: scheduler
         * 
         * @param useFixedDelay the value to set
         * @return the dsl builder
         */
        default IronMQEndpointConsumerBuilder useFixedDelay(String useFixedDelay) {
            doSetProperty("useFixedDelay", useFixedDelay);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint consumers for the IronMQ component.
     */
    public interface AdvancedIronMQEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default IronMQEndpointConsumerBuilder basic() {
            return (IronMQEndpointConsumerBuilder) 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:
         * &lt;code&gt;org.apache.camel.spi.ExceptionHandler&lt;/code&gt; type.
         * 
         * Group: consumer (advanced)
         * 
         * @param exceptionHandler the value to set
         * @return the dsl builder
         */
        default AdvancedIronMQEndpointConsumerBuilder 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
         * &lt;code&gt;org.apache.camel.spi.ExceptionHandler&lt;/code&gt; type.
         * 
         * Group: consumer (advanced)
         * 
         * @param exceptionHandler the value to set
         * @return the dsl builder
         */
        default AdvancedIronMQEndpointConsumerBuilder exceptionHandler(
                String exceptionHandler) {
            doSetProperty("exceptionHandler", exceptionHandler);
            return this;
        }
        /**
         * Sets the exchange pattern when the consumer creates an exchange.
         * 
         * The option is a:
         * &lt;code&gt;org.apache.camel.ExchangePattern&lt;/code&gt; type.
         * 
         * Group: consumer (advanced)
         * 
         * @param exchangePattern the value to set
         * @return the dsl builder
         */
        default AdvancedIronMQEndpointConsumerBuilder 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
         * &lt;code&gt;org.apache.camel.ExchangePattern&lt;/code&gt; type.
         * 
         * Group: consumer (advanced)
         * 
         * @param exchangePattern the value to set
         * @return the dsl builder
         */
        default AdvancedIronMQEndpointConsumerBuilder 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:
         * &lt;code&gt;org.apache.camel.spi.PollingConsumerPollStrategy&lt;/code&gt; type.
         * 
         * Group: consumer (advanced)
         * 
         * @param pollStrategy the value to set
         * @return the dsl builder
         */
        default AdvancedIronMQEndpointConsumerBuilder 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
         * &lt;code&gt;org.apache.camel.spi.PollingConsumerPollStrategy&lt;/code&gt; type.
         * 
         * Group: consumer (advanced)
         * 
         * @param pollStrategy the value to set
         * @return the dsl builder
         */
        default AdvancedIronMQEndpointConsumerBuilder pollStrategy(
                String pollStrategy) {
            doSetProperty("pollStrategy", pollStrategy);
            return this;
        }
    }

    /**
     * Builder for endpoint producers for the IronMQ component.
     */
    public interface IronMQEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default AdvancedIronMQEndpointProducerBuilder advanced() {
            return (AdvancedIronMQEndpointProducerBuilder) this;
        }
        /**
         * Reference to a io.iron.ironmq.Client in the Registry.
         * 
         * The option is a: &lt;code&gt;io.iron.ironmq.Client&lt;/code&gt; type.
         * 
         * Group: common
         * 
         * @param client the value to set
         * @return the dsl builder
         */
        default IronMQEndpointProducerBuilder client(Object client) {
            doSetProperty("client", client);
            return this;
        }
        /**
         * Reference to a io.iron.ironmq.Client in the Registry.
         * 
         * The option will be converted to a
         * &lt;code&gt;io.iron.ironmq.Client&lt;/code&gt; type.
         * 
         * Group: common
         * 
         * @param client the value to set
         * @return the dsl builder
         */
        default IronMQEndpointProducerBuilder client(String client) {
            doSetProperty("client", client);
            return this;
        }
        /**
         * IronMq Cloud url. Urls for public clusters:
         * https://mq-aws-us-east-1-1.iron.io (US) and
         * https://mq-aws-eu-west-1-1.iron.io (EU).
         * 
         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
         * 
         * Default: https://mq-aws-us-east-1-1.iron.io
         * Group: common
         * 
         * @param ironMQCloud the value to set
         * @return the dsl builder
         */
        default IronMQEndpointProducerBuilder ironMQCloud(String ironMQCloud) {
            doSetProperty("ironMQCloud", ironMQCloud);
            return this;
        }
        /**
         * Should message headers be preserved when publishing messages. This
         * will add the Camel headers to the Iron MQ message as a json payload
         * with a header list, and a message body. Useful when Camel is both
         * consumer and producer.
         * 
         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
         * 
         * Default: false
         * Group: common
         * 
         * @param preserveHeaders the value to set
         * @return the dsl builder
         */
        default IronMQEndpointProducerBuilder preserveHeaders(
                boolean preserveHeaders) {
            doSetProperty("preserveHeaders", preserveHeaders);
            return this;
        }
        /**
         * Should message headers be preserved when publishing messages. This
         * will add the Camel headers to the Iron MQ message as a json payload
         * with a header list, and a message body. Useful when Camel is both
         * consumer and producer.
         * 
         * The option will be converted to a &lt;code&gt;boolean&lt;/code&gt;
         * type.
         * 
         * Default: false
         * Group: common
         * 
         * @param preserveHeaders the value to set
         * @return the dsl builder
         */
        default IronMQEndpointProducerBuilder preserveHeaders(
                String preserveHeaders) {
            doSetProperty("preserveHeaders", preserveHeaders);
            return this;
        }
        /**
         * IronMQ projectId.
         * 
         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
         * 
         * Group: common
         * 
         * @param projectId the value to set
         * @return the dsl builder
         */
        default IronMQEndpointProducerBuilder projectId(String projectId) {
            doSetProperty("projectId", projectId);
            return this;
        }
        /**
         * IronMQ token.
         * 
         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
         * 
         * Group: common
         * 
         * @param token the value to set
         * @return the dsl builder
         */
        default IronMQEndpointProducerBuilder token(String token) {
            doSetProperty("token", token);
            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: &lt;code&gt;boolean&lt;/code&gt; type.
         * 
         * Default: false
         * Group: producer
         * 
         * @param lazyStartProducer the value to set
         * @return the dsl builder
         */
        default IronMQEndpointProducerBuilder 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 &lt;code&gt;boolean&lt;/code&gt;
         * type.
         * 
         * Default: false
         * Group: producer
         * 
         * @param lazyStartProducer the value to set
         * @return the dsl builder
         */
        default IronMQEndpointProducerBuilder lazyStartProducer(
                String lazyStartProducer) {
            doSetProperty("lazyStartProducer", lazyStartProducer);
            return this;
        }
        /**
         * The item will not be available on the queue until this many seconds
         * have passed. Default is 0 seconds.
         * 
         * The option is a: &lt;code&gt;int&lt;/code&gt; type.
         * 
         * Group: producer
         * 
         * @param visibilityDelay the value to set
         * @return the dsl builder
         */
        default IronMQEndpointProducerBuilder visibilityDelay(
                int visibilityDelay) {
            doSetProperty("visibilityDelay", visibilityDelay);
            return this;
        }
        /**
         * The item will not be available on the queue until this many seconds
         * have passed. Default is 0 seconds.
         * 
         * The option will be converted to a &lt;code&gt;int&lt;/code&gt; type.
         * 
         * Group: producer
         * 
         * @param visibilityDelay the value to set
         * @return the dsl builder
         */
        default IronMQEndpointProducerBuilder visibilityDelay(
                String visibilityDelay) {
            doSetProperty("visibilityDelay", visibilityDelay);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint producers for the IronMQ component.
     */
    public interface AdvancedIronMQEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default IronMQEndpointProducerBuilder basic() {
            return (IronMQEndpointProducerBuilder) this;
        }
    }

    /**
     * Builder for endpoint for the IronMQ component.
     */
    public interface IronMQEndpointBuilder
            extends
                IronMQEndpointConsumerBuilder,
                IronMQEndpointProducerBuilder {
        default AdvancedIronMQEndpointBuilder advanced() {
            return (AdvancedIronMQEndpointBuilder) this;
        }
        /**
         * Reference to a io.iron.ironmq.Client in the Registry.
         * 
         * The option is a: &lt;code&gt;io.iron.ironmq.Client&lt;/code&gt; type.
         * 
         * Group: common
         * 
         * @param client the value to set
         * @return the dsl builder
         */
        default IronMQEndpointBuilder client(Object client) {
            doSetProperty("client", client);
            return this;
        }
        /**
         * Reference to a io.iron.ironmq.Client in the Registry.
         * 
         * The option will be converted to a
         * &lt;code&gt;io.iron.ironmq.Client&lt;/code&gt; type.
         * 
         * Group: common
         * 
         * @param client the value to set
         * @return the dsl builder
         */
        default IronMQEndpointBuilder client(String client) {
            doSetProperty("client", client);
            return this;
        }
        /**
         * IronMq Cloud url. Urls for public clusters:
         * https://mq-aws-us-east-1-1.iron.io (US) and
         * https://mq-aws-eu-west-1-1.iron.io (EU).
         * 
         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
         * 
         * Default: https://mq-aws-us-east-1-1.iron.io
         * Group: common
         * 
         * @param ironMQCloud the value to set
         * @return the dsl builder
         */
        default IronMQEndpointBuilder ironMQCloud(String ironMQCloud) {
            doSetProperty("ironMQCloud", ironMQCloud);
            return this;
        }
        /**
         * Should message headers be preserved when publishing messages. This
         * will add the Camel headers to the Iron MQ message as a json payload
         * with a header list, and a message body. Useful when Camel is both
         * consumer and producer.
         * 
         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
         * 
         * Default: false
         * Group: common
         * 
         * @param preserveHeaders the value to set
         * @return the dsl builder
         */
        default IronMQEndpointBuilder preserveHeaders(boolean preserveHeaders) {
            doSetProperty("preserveHeaders", preserveHeaders);
            return this;
        }
        /**
         * Should message headers be preserved when publishing messages. This
         * will add the Camel headers to the Iron MQ message as a json payload
         * with a header list, and a message body. Useful when Camel is both
         * consumer and producer.
         * 
         * The option will be converted to a &lt;code&gt;boolean&lt;/code&gt;
         * type.
         * 
         * Default: false
         * Group: common
         * 
         * @param preserveHeaders the value to set
         * @return the dsl builder
         */
        default IronMQEndpointBuilder preserveHeaders(String preserveHeaders) {
            doSetProperty("preserveHeaders", preserveHeaders);
            return this;
        }
        /**
         * IronMQ projectId.
         * 
         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
         * 
         * Group: common
         * 
         * @param projectId the value to set
         * @return the dsl builder
         */
        default IronMQEndpointBuilder projectId(String projectId) {
            doSetProperty("projectId", projectId);
            return this;
        }
        /**
         * IronMQ token.
         * 
         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
         * 
         * Group: common
         * 
         * @param token the value to set
         * @return the dsl builder
         */
        default IronMQEndpointBuilder token(String token) {
            doSetProperty("token", token);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint for the IronMQ component.
     */
    public interface AdvancedIronMQEndpointBuilder
            extends
                AdvancedIronMQEndpointConsumerBuilder,
                AdvancedIronMQEndpointProducerBuilder {
        default IronMQEndpointBuilder basic() {
            return (IronMQEndpointBuilder) this;
        }
    }

    public interface IronMQBuilders {
        /**
         * IronMQ (camel-ironmq)
         * Send and receive messages to/from IronMQ an elastic and durable
         * hosted message queue as a service.
         * 
         * Category: cloud,messaging
         * Since: 2.17
         * Maven coordinates: org.apache.camel:camel-ironmq
         * 
         * Syntax: <code>ironmq:queueName</code>
         * 
         * Path parameter: queueName (required)
         * The name of the IronMQ queue
         * 
         * @param path queueName
         * @return the dsl builder
         */
        default IronMQEndpointBuilder ironmq(String path) {
            return IronMQEndpointBuilderFactory.endpointBuilder("ironmq", path);
        }
        /**
         * IronMQ (camel-ironmq)
         * Send and receive messages to/from IronMQ an elastic and durable
         * hosted message queue as a service.
         * 
         * Category: cloud,messaging
         * Since: 2.17
         * Maven coordinates: org.apache.camel:camel-ironmq
         * 
         * Syntax: <code>ironmq:queueName</code>
         * 
         * Path parameter: queueName (required)
         * The name of the IronMQ queue
         * 
         * @param componentName to use a custom component name for the endpoint
         * instead of the default name
         * @param path queueName
         * @return the dsl builder
         */
        default IronMQEndpointBuilder ironmq(String componentName, String path) {
            return IronMQEndpointBuilderFactory.endpointBuilder(componentName, path);
        }
    }
    static IronMQEndpointBuilder endpointBuilder(
            String componentName,
            String path) {
        class IronMQEndpointBuilderImpl extends AbstractEndpointBuilder implements IronMQEndpointBuilder, AdvancedIronMQEndpointBuilder {
            public IronMQEndpointBuilderImpl(String path) {
                super(componentName, path);
            }
        }
        return new IronMQEndpointBuilderImpl(path);
    }
}