/*
 * 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.List;
import java.util.Map;
import java.util.Properties;
import javax.annotation.Generated;
import org.apache.camel.ExchangePattern;
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;

/**
 * The atomix-queue component is used to access Atomix's distributed queue.
 * 
 * Generated by camel-package-maven-plugin - do not edit this file!
 */
@Generated("org.apache.camel.maven.packaging.EndpointDslMojo")
public interface AtomixQueueEndpointBuilderFactory {


    /**
     * Builder for endpoint consumers for the Atomix Queue component.
     */
    public interface AtomixQueueEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default AdvancedAtomixQueueEndpointConsumerBuilder advanced() {
            return (AdvancedAtomixQueueEndpointConsumerBuilder) this;
        }
        /**
         * The Atomix instance to use.
         * 
         * The option is a: <code>io.atomix.AtomixClient</code> type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointConsumerBuilder atomix(Object atomix) {
            doSetProperty("atomix", atomix);
            return this;
        }
        /**
         * The Atomix instance to use.
         * 
         * The option will be converted to a <code>io.atomix.AtomixClient</code>
         * type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointConsumerBuilder atomix(String atomix) {
            doSetProperty("atomix", atomix);
            return this;
        }
        /**
         * The Atomix configuration uri.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointConsumerBuilder configurationUri(
                String configurationUri) {
            doSetProperty("configurationUri", configurationUri);
            return this;
        }
        /**
         * The default action.
         * 
         * The option is a:
         * <code>org.apache.camel.component.atomix.client.queue.AtomixQueue$Action</code> type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointConsumerBuilder defaultAction(
                Action defaultAction) {
            doSetProperty("defaultAction", defaultAction);
            return this;
        }
        /**
         * The default action.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.atomix.client.queue.AtomixQueue$Action</code> type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointConsumerBuilder defaultAction(
                String defaultAction) {
            doSetProperty("defaultAction", defaultAction);
            return this;
        }
        /**
         * The address of the nodes composing the cluster.
         * 
         * The option is a:
         * <code>java.util.List&lt;io.atomix.catalyst.transport.Address&gt;</code> type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointConsumerBuilder nodes(List<Object> nodes) {
            doSetProperty("nodes", nodes);
            return this;
        }
        /**
         * The address of the nodes composing the cluster.
         * 
         * The option will be converted to a
         * <code>java.util.List&lt;io.atomix.catalyst.transport.Address&gt;</code> type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointConsumerBuilder nodes(String nodes) {
            doSetProperty("nodes", nodes);
            return this;
        }
        /**
         * The header that wil carry the result.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointConsumerBuilder resultHeader(
                String resultHeader) {
            doSetProperty("resultHeader", resultHeader);
            return this;
        }
        /**
         * The class name (fqn) of the Atomix transport.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointConsumerBuilder transportClassName(
                String transportClassName) {
            doSetProperty("transportClassName", transportClassName);
            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.
         * 
         * Group: consumer
         */
        default AtomixQueueEndpointConsumerBuilder 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.
         * 
         * Group: consumer
         */
        default AtomixQueueEndpointConsumerBuilder bridgeErrorHandler(
                String bridgeErrorHandler) {
            doSetProperty("bridgeErrorHandler", bridgeErrorHandler);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint consumers for the Atomix Queue component.
     */
    public interface AdvancedAtomixQueueEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default AtomixQueueEndpointConsumerBuilder basic() {
            return (AtomixQueueEndpointConsumerBuilder) 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 AdvancedAtomixQueueEndpointConsumerBuilder 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 AdvancedAtomixQueueEndpointConsumerBuilder 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 AdvancedAtomixQueueEndpointConsumerBuilder 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 AdvancedAtomixQueueEndpointConsumerBuilder exchangePattern(
                String exchangePattern) {
            doSetProperty("exchangePattern", exchangePattern);
            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.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointConsumerBuilder 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.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointConsumerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * The cluster wide default resource configuration.
         * 
         * The option is a: <code>java.util.Properties</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointConsumerBuilder defaultResourceConfig(
                Properties defaultResourceConfig) {
            doSetProperty("defaultResourceConfig", defaultResourceConfig);
            return this;
        }
        /**
         * The cluster wide default resource configuration.
         * 
         * The option will be converted to a <code>java.util.Properties</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointConsumerBuilder defaultResourceConfig(
                String defaultResourceConfig) {
            doSetProperty("defaultResourceConfig", defaultResourceConfig);
            return this;
        }
        /**
         * The local default resource options.
         * 
         * The option is a: <code>java.util.Properties</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointConsumerBuilder defaultResourceOptions(
                Properties defaultResourceOptions) {
            doSetProperty("defaultResourceOptions", defaultResourceOptions);
            return this;
        }
        /**
         * The local default resource options.
         * 
         * The option will be converted to a <code>java.util.Properties</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointConsumerBuilder defaultResourceOptions(
                String defaultResourceOptions) {
            doSetProperty("defaultResourceOptions", defaultResourceOptions);
            return this;
        }
        /**
         * Sets if the local member should join groups as PersistentMember or
         * not. If set to ephemeral the local member will receive an auto
         * generated ID thus the local one is ignored.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointConsumerBuilder ephemeral(
                boolean ephemeral) {
            doSetProperty("ephemeral", ephemeral);
            return this;
        }
        /**
         * Sets if the local member should join groups as PersistentMember or
         * not. If set to ephemeral the local member will receive an auto
         * generated ID thus the local one is ignored.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointConsumerBuilder ephemeral(
                String ephemeral) {
            doSetProperty("ephemeral", ephemeral);
            return this;
        }
        /**
         * The read consistency level.
         * 
         * The option is a: <code>io.atomix.resource.ReadConsistency</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointConsumerBuilder readConsistency(
                ReadConsistency readConsistency) {
            doSetProperty("readConsistency", readConsistency);
            return this;
        }
        /**
         * The read consistency level.
         * 
         * The option will be converted to a
         * <code>io.atomix.resource.ReadConsistency</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointConsumerBuilder readConsistency(
                String readConsistency) {
            doSetProperty("readConsistency", readConsistency);
            return this;
        }
        /**
         * Cluster wide resources configuration.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.util.Properties&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointConsumerBuilder resourceConfigs(
                Map<String, Properties> resourceConfigs) {
            doSetProperty("resourceConfigs", resourceConfigs);
            return this;
        }
        /**
         * Cluster wide resources configuration.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String,
         * java.util.Properties&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointConsumerBuilder resourceConfigs(
                String resourceConfigs) {
            doSetProperty("resourceConfigs", resourceConfigs);
            return this;
        }
        /**
         * Local resources configurations.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.util.Properties&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointConsumerBuilder resourceOptions(
                Map<String, Properties> resourceOptions) {
            doSetProperty("resourceOptions", resourceOptions);
            return this;
        }
        /**
         * Local resources configurations.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String,
         * java.util.Properties&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointConsumerBuilder resourceOptions(
                String resourceOptions) {
            doSetProperty("resourceOptions", resourceOptions);
            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.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointConsumerBuilder 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.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointConsumerBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
    }

    /**
     * Builder for endpoint producers for the Atomix Queue component.
     */
    public interface AtomixQueueEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default AdvancedAtomixQueueEndpointProducerBuilder advanced() {
            return (AdvancedAtomixQueueEndpointProducerBuilder) this;
        }
        /**
         * The Atomix instance to use.
         * 
         * The option is a: <code>io.atomix.AtomixClient</code> type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointProducerBuilder atomix(Object atomix) {
            doSetProperty("atomix", atomix);
            return this;
        }
        /**
         * The Atomix instance to use.
         * 
         * The option will be converted to a <code>io.atomix.AtomixClient</code>
         * type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointProducerBuilder atomix(String atomix) {
            doSetProperty("atomix", atomix);
            return this;
        }
        /**
         * The Atomix configuration uri.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointProducerBuilder configurationUri(
                String configurationUri) {
            doSetProperty("configurationUri", configurationUri);
            return this;
        }
        /**
         * The default action.
         * 
         * The option is a:
         * <code>org.apache.camel.component.atomix.client.queue.AtomixQueue$Action</code> type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointProducerBuilder defaultAction(
                Action defaultAction) {
            doSetProperty("defaultAction", defaultAction);
            return this;
        }
        /**
         * The default action.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.atomix.client.queue.AtomixQueue$Action</code> type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointProducerBuilder defaultAction(
                String defaultAction) {
            doSetProperty("defaultAction", defaultAction);
            return this;
        }
        /**
         * The address of the nodes composing the cluster.
         * 
         * The option is a:
         * <code>java.util.List&lt;io.atomix.catalyst.transport.Address&gt;</code> type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointProducerBuilder nodes(List<Object> nodes) {
            doSetProperty("nodes", nodes);
            return this;
        }
        /**
         * The address of the nodes composing the cluster.
         * 
         * The option will be converted to a
         * <code>java.util.List&lt;io.atomix.catalyst.transport.Address&gt;</code> type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointProducerBuilder nodes(String nodes) {
            doSetProperty("nodes", nodes);
            return this;
        }
        /**
         * The header that wil carry the result.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointProducerBuilder resultHeader(
                String resultHeader) {
            doSetProperty("resultHeader", resultHeader);
            return this;
        }
        /**
         * The class name (fqn) of the Atomix transport.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointProducerBuilder transportClassName(
                String transportClassName) {
            doSetProperty("transportClassName", transportClassName);
            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.
         * 
         * Group: producer
         */
        default AtomixQueueEndpointProducerBuilder 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.
         * 
         * Group: producer
         */
        default AtomixQueueEndpointProducerBuilder lazyStartProducer(
                String lazyStartProducer) {
            doSetProperty("lazyStartProducer", lazyStartProducer);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint producers for the Atomix Queue component.
     */
    public interface AdvancedAtomixQueueEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default AtomixQueueEndpointProducerBuilder basic() {
            return (AtomixQueueEndpointProducerBuilder) 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.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointProducerBuilder 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.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointProducerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * The cluster wide default resource configuration.
         * 
         * The option is a: <code>java.util.Properties</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointProducerBuilder defaultResourceConfig(
                Properties defaultResourceConfig) {
            doSetProperty("defaultResourceConfig", defaultResourceConfig);
            return this;
        }
        /**
         * The cluster wide default resource configuration.
         * 
         * The option will be converted to a <code>java.util.Properties</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointProducerBuilder defaultResourceConfig(
                String defaultResourceConfig) {
            doSetProperty("defaultResourceConfig", defaultResourceConfig);
            return this;
        }
        /**
         * The local default resource options.
         * 
         * The option is a: <code>java.util.Properties</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointProducerBuilder defaultResourceOptions(
                Properties defaultResourceOptions) {
            doSetProperty("defaultResourceOptions", defaultResourceOptions);
            return this;
        }
        /**
         * The local default resource options.
         * 
         * The option will be converted to a <code>java.util.Properties</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointProducerBuilder defaultResourceOptions(
                String defaultResourceOptions) {
            doSetProperty("defaultResourceOptions", defaultResourceOptions);
            return this;
        }
        /**
         * Sets if the local member should join groups as PersistentMember or
         * not. If set to ephemeral the local member will receive an auto
         * generated ID thus the local one is ignored.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointProducerBuilder ephemeral(
                boolean ephemeral) {
            doSetProperty("ephemeral", ephemeral);
            return this;
        }
        /**
         * Sets if the local member should join groups as PersistentMember or
         * not. If set to ephemeral the local member will receive an auto
         * generated ID thus the local one is ignored.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointProducerBuilder ephemeral(
                String ephemeral) {
            doSetProperty("ephemeral", ephemeral);
            return this;
        }
        /**
         * The read consistency level.
         * 
         * The option is a: <code>io.atomix.resource.ReadConsistency</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointProducerBuilder readConsistency(
                ReadConsistency readConsistency) {
            doSetProperty("readConsistency", readConsistency);
            return this;
        }
        /**
         * The read consistency level.
         * 
         * The option will be converted to a
         * <code>io.atomix.resource.ReadConsistency</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointProducerBuilder readConsistency(
                String readConsistency) {
            doSetProperty("readConsistency", readConsistency);
            return this;
        }
        /**
         * Cluster wide resources configuration.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.util.Properties&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointProducerBuilder resourceConfigs(
                Map<String, Properties> resourceConfigs) {
            doSetProperty("resourceConfigs", resourceConfigs);
            return this;
        }
        /**
         * Cluster wide resources configuration.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String,
         * java.util.Properties&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointProducerBuilder resourceConfigs(
                String resourceConfigs) {
            doSetProperty("resourceConfigs", resourceConfigs);
            return this;
        }
        /**
         * Local resources configurations.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.util.Properties&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointProducerBuilder resourceOptions(
                Map<String, Properties> resourceOptions) {
            doSetProperty("resourceOptions", resourceOptions);
            return this;
        }
        /**
         * Local resources configurations.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String,
         * java.util.Properties&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointProducerBuilder resourceOptions(
                String resourceOptions) {
            doSetProperty("resourceOptions", resourceOptions);
            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.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointProducerBuilder 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.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointProducerBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
    }

    /**
     * Builder for endpoint for the Atomix Queue component.
     */
    public interface AtomixQueueEndpointBuilder
            extends
                AtomixQueueEndpointConsumerBuilder, AtomixQueueEndpointProducerBuilder {
        default AdvancedAtomixQueueEndpointBuilder advanced() {
            return (AdvancedAtomixQueueEndpointBuilder) this;
        }
        /**
         * The Atomix instance to use.
         * 
         * The option is a: <code>io.atomix.AtomixClient</code> type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointBuilder atomix(Object atomix) {
            doSetProperty("atomix", atomix);
            return this;
        }
        /**
         * The Atomix instance to use.
         * 
         * The option will be converted to a <code>io.atomix.AtomixClient</code>
         * type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointBuilder atomix(String atomix) {
            doSetProperty("atomix", atomix);
            return this;
        }
        /**
         * The Atomix configuration uri.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointBuilder configurationUri(
                String configurationUri) {
            doSetProperty("configurationUri", configurationUri);
            return this;
        }
        /**
         * The default action.
         * 
         * The option is a:
         * <code>org.apache.camel.component.atomix.client.queue.AtomixQueue$Action</code> type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointBuilder defaultAction(Action defaultAction) {
            doSetProperty("defaultAction", defaultAction);
            return this;
        }
        /**
         * The default action.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.atomix.client.queue.AtomixQueue$Action</code> type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointBuilder defaultAction(String defaultAction) {
            doSetProperty("defaultAction", defaultAction);
            return this;
        }
        /**
         * The address of the nodes composing the cluster.
         * 
         * The option is a:
         * <code>java.util.List&lt;io.atomix.catalyst.transport.Address&gt;</code> type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointBuilder nodes(List<Object> nodes) {
            doSetProperty("nodes", nodes);
            return this;
        }
        /**
         * The address of the nodes composing the cluster.
         * 
         * The option will be converted to a
         * <code>java.util.List&lt;io.atomix.catalyst.transport.Address&gt;</code> type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointBuilder nodes(String nodes) {
            doSetProperty("nodes", nodes);
            return this;
        }
        /**
         * The header that wil carry the result.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointBuilder resultHeader(String resultHeader) {
            doSetProperty("resultHeader", resultHeader);
            return this;
        }
        /**
         * The class name (fqn) of the Atomix transport.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default AtomixQueueEndpointBuilder transportClassName(
                String transportClassName) {
            doSetProperty("transportClassName", transportClassName);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint for the Atomix Queue component.
     */
    public interface AdvancedAtomixQueueEndpointBuilder
            extends
                AdvancedAtomixQueueEndpointConsumerBuilder, AdvancedAtomixQueueEndpointProducerBuilder {
        default AtomixQueueEndpointBuilder basic() {
            return (AtomixQueueEndpointBuilder) 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.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointBuilder 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.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * The cluster wide default resource configuration.
         * 
         * The option is a: <code>java.util.Properties</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointBuilder defaultResourceConfig(
                Properties defaultResourceConfig) {
            doSetProperty("defaultResourceConfig", defaultResourceConfig);
            return this;
        }
        /**
         * The cluster wide default resource configuration.
         * 
         * The option will be converted to a <code>java.util.Properties</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointBuilder defaultResourceConfig(
                String defaultResourceConfig) {
            doSetProperty("defaultResourceConfig", defaultResourceConfig);
            return this;
        }
        /**
         * The local default resource options.
         * 
         * The option is a: <code>java.util.Properties</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointBuilder defaultResourceOptions(
                Properties defaultResourceOptions) {
            doSetProperty("defaultResourceOptions", defaultResourceOptions);
            return this;
        }
        /**
         * The local default resource options.
         * 
         * The option will be converted to a <code>java.util.Properties</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointBuilder defaultResourceOptions(
                String defaultResourceOptions) {
            doSetProperty("defaultResourceOptions", defaultResourceOptions);
            return this;
        }
        /**
         * Sets if the local member should join groups as PersistentMember or
         * not. If set to ephemeral the local member will receive an auto
         * generated ID thus the local one is ignored.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointBuilder ephemeral(boolean ephemeral) {
            doSetProperty("ephemeral", ephemeral);
            return this;
        }
        /**
         * Sets if the local member should join groups as PersistentMember or
         * not. If set to ephemeral the local member will receive an auto
         * generated ID thus the local one is ignored.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointBuilder ephemeral(String ephemeral) {
            doSetProperty("ephemeral", ephemeral);
            return this;
        }
        /**
         * The read consistency level.
         * 
         * The option is a: <code>io.atomix.resource.ReadConsistency</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointBuilder readConsistency(
                ReadConsistency readConsistency) {
            doSetProperty("readConsistency", readConsistency);
            return this;
        }
        /**
         * The read consistency level.
         * 
         * The option will be converted to a
         * <code>io.atomix.resource.ReadConsistency</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointBuilder readConsistency(
                String readConsistency) {
            doSetProperty("readConsistency", readConsistency);
            return this;
        }
        /**
         * Cluster wide resources configuration.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.util.Properties&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointBuilder resourceConfigs(
                Map<String, Properties> resourceConfigs) {
            doSetProperty("resourceConfigs", resourceConfigs);
            return this;
        }
        /**
         * Cluster wide resources configuration.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String,
         * java.util.Properties&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointBuilder resourceConfigs(
                String resourceConfigs) {
            doSetProperty("resourceConfigs", resourceConfigs);
            return this;
        }
        /**
         * Local resources configurations.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.util.Properties&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointBuilder resourceOptions(
                Map<String, Properties> resourceOptions) {
            doSetProperty("resourceOptions", resourceOptions);
            return this;
        }
        /**
         * Local resources configurations.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String,
         * java.util.Properties&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointBuilder resourceOptions(
                String resourceOptions) {
            doSetProperty("resourceOptions", resourceOptions);
            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.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointBuilder 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.
         * 
         * Group: advanced
         */
        default AdvancedAtomixQueueEndpointBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
    }

    /**
     * Proxy enum for
     * <code>org.apache.camel.component.atomix.client.queue.AtomixQueue$Action</code> enum.
     */
    enum Action {
        ADD,
        OFFER,
        PEEK,
        POLL,
        CLEAR,
        CONTAINS,
        IS_EMPTY,
        REMOVE,
        SIZE;
    }

    /**
     * Proxy enum for <code>io.atomix.resource.ReadConsistency</code> enum.
     */
    enum ReadConsistency {
        ATOMIC,
        ATOMIC_LEASE,
        SEQUENTIAL,
        LOCAL;
    }
    /**
     * Atomix Queue (camel-atomix)
     * The atomix-queue component is used to access Atomix's distributed queue.
     * 
     * Category: clustering
     * Since: 2.20
     * Maven coordinates: org.apache.camel:camel-atomix
     * 
     * Syntax: <code>atomix-queue:resourceName</code>
     * 
     * Path parameter: resourceName (required)
     * The distributed resource name
     */
    default AtomixQueueEndpointBuilder atomixQueue(String path) {
        class AtomixQueueEndpointBuilderImpl extends AbstractEndpointBuilder implements AtomixQueueEndpointBuilder, AdvancedAtomixQueueEndpointBuilder {
            public AtomixQueueEndpointBuilderImpl(String path) {
                super("atomix-queue", path);
            }
        }
        return new AtomixQueueEndpointBuilderImpl(path);
    }
}