/*
 * 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.Set;
import java.util.function.BiFunction;
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;

/**
 * For reading/writing from/to Infinispan distributed key/value store and data
 * grid.
 * 
 * Generated by camel-package-maven-plugin - do not edit this file!
 */
@Generated("org.apache.camel.maven.packaging.EndpointDslMojo")
public interface InfinispanEndpointBuilderFactory {


    /**
     * Builder for endpoint consumers for the Infinispan component.
     */
    public interface InfinispanEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default AdvancedInfinispanEndpointConsumerBuilder advanced() {
            return (AdvancedInfinispanEndpointConsumerBuilder) this;
        }
        /**
         * Specifies the host of the cache on Infinispan instance.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default InfinispanEndpointConsumerBuilder hosts(String hosts) {
            doSetProperty("hosts", hosts);
            return this;
        }
        /**
         * Specifies the query builder.
         * 
         * The option is a:
         * <code>org.apache.camel.component.infinispan.InfinispanQueryBuilder</code> type.
         * 
         * Group: common
         */
        default InfinispanEndpointConsumerBuilder queryBuilder(
                Object queryBuilder) {
            doSetProperty("queryBuilder", queryBuilder);
            return this;
        }
        /**
         * Specifies the query builder.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.infinispan.InfinispanQueryBuilder</code> type.
         * 
         * Group: common
         */
        default InfinispanEndpointConsumerBuilder queryBuilder(
                String queryBuilder) {
            doSetProperty("queryBuilder", queryBuilder);
            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 InfinispanEndpointConsumerBuilder 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 InfinispanEndpointConsumerBuilder bridgeErrorHandler(
                String bridgeErrorHandler) {
            doSetProperty("bridgeErrorHandler", bridgeErrorHandler);
            return this;
        }
        /**
         * If true, the listener will be installed for the entire cluster.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default InfinispanEndpointConsumerBuilder clusteredListener(
                boolean clusteredListener) {
            doSetProperty("clusteredListener", clusteredListener);
            return this;
        }
        /**
         * If true, the listener will be installed for the entire cluster.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default InfinispanEndpointConsumerBuilder clusteredListener(
                String clusteredListener) {
            doSetProperty("clusteredListener", clusteredListener);
            return this;
        }
        /**
         * The operation to perform.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer
         */
        @Deprecated
        default InfinispanEndpointConsumerBuilder command(String command) {
            doSetProperty("command", command);
            return this;
        }
        /**
         * Returns the custom listener in use, if provided.
         * 
         * The option is a:
         * <code>org.apache.camel.component.infinispan.InfinispanCustomListener</code> type.
         * 
         * Group: consumer
         */
        default InfinispanEndpointConsumerBuilder customListener(
                Object customListener) {
            doSetProperty("customListener", customListener);
            return this;
        }
        /**
         * Returns the custom listener in use, if provided.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.infinispan.InfinispanCustomListener</code> type.
         * 
         * Group: consumer
         */
        default InfinispanEndpointConsumerBuilder customListener(
                String customListener) {
            doSetProperty("customListener", customListener);
            return this;
        }
        /**
         * Specifies the set of event types to register by the consumer.
         * Multiple event can be separated by comma. The possible event types
         * are: CACHE_ENTRY_ACTIVATED, CACHE_ENTRY_PASSIVATED,
         * CACHE_ENTRY_VISITED, CACHE_ENTRY_LOADED, CACHE_ENTRY_EVICTED,
         * CACHE_ENTRY_CREATED, CACHE_ENTRY_REMOVED, CACHE_ENTRY_MODIFIED,
         * TRANSACTION_COMPLETED, TRANSACTION_REGISTERED,
         * CACHE_ENTRY_INVALIDATED, DATA_REHASHED, TOPOLOGY_CHANGED,
         * PARTITION_STATUS_CHANGED.
         * 
         * The option is a: <code>java.util.Set&lt;java.lang.String&gt;</code>
         * type.
         * 
         * Group: consumer
         */
        default InfinispanEndpointConsumerBuilder eventTypes(
                Set<String> eventTypes) {
            doSetProperty("eventTypes", eventTypes);
            return this;
        }
        /**
         * Specifies the set of event types to register by the consumer.
         * Multiple event can be separated by comma. The possible event types
         * are: CACHE_ENTRY_ACTIVATED, CACHE_ENTRY_PASSIVATED,
         * CACHE_ENTRY_VISITED, CACHE_ENTRY_LOADED, CACHE_ENTRY_EVICTED,
         * CACHE_ENTRY_CREATED, CACHE_ENTRY_REMOVED, CACHE_ENTRY_MODIFIED,
         * TRANSACTION_COMPLETED, TRANSACTION_REGISTERED,
         * CACHE_ENTRY_INVALIDATED, DATA_REHASHED, TOPOLOGY_CHANGED,
         * PARTITION_STATUS_CHANGED.
         * 
         * The option will be converted to a
         * <code>java.util.Set&lt;java.lang.String&gt;</code> type.
         * 
         * Group: consumer
         */
        default InfinispanEndpointConsumerBuilder eventTypes(String eventTypes) {
            doSetProperty("eventTypes", eventTypes);
            return this;
        }
        /**
         * If true, the consumer will receive notifications synchronously.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default InfinispanEndpointConsumerBuilder sync(boolean sync) {
            doSetProperty("sync", sync);
            return this;
        }
        /**
         * If true, the consumer will receive notifications synchronously.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default InfinispanEndpointConsumerBuilder sync(String sync) {
            doSetProperty("sync", sync);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint consumers for the Infinispan component.
     */
    public interface AdvancedInfinispanEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default InfinispanEndpointConsumerBuilder basic() {
            return (InfinispanEndpointConsumerBuilder) 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 AdvancedInfinispanEndpointConsumerBuilder 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 AdvancedInfinispanEndpointConsumerBuilder 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 AdvancedInfinispanEndpointConsumerBuilder 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 AdvancedInfinispanEndpointConsumerBuilder 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 AdvancedInfinispanEndpointConsumerBuilder 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 AdvancedInfinispanEndpointConsumerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Specifies the cache Container to connect.
         * 
         * The option is a:
         * <code>org.infinispan.commons.api.BasicCacheContainer</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointConsumerBuilder cacheContainer(
                Object cacheContainer) {
            doSetProperty("cacheContainer", cacheContainer);
            return this;
        }
        /**
         * Specifies the cache Container to connect.
         * 
         * The option will be converted to a
         * <code>org.infinispan.commons.api.BasicCacheContainer</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointConsumerBuilder cacheContainer(
                String cacheContainer) {
            doSetProperty("cacheContainer", cacheContainer);
            return this;
        }
        /**
         * The CacheContainer configuration. Uses if the cacheContainer is not
         * defined. Must be the following types:
         * org.infinispan.client.hotrod.configuration.Configuration - for remote
         * cache interaction configuration;
         * org.infinispan.configuration.cache.Configuration - for embedded cache
         * interaction configuration;.
         * 
         * The option is a: <code>java.lang.Object</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointConsumerBuilder cacheContainerConfiguration(
                Object cacheContainerConfiguration) {
            doSetProperty("cacheContainerConfiguration", cacheContainerConfiguration);
            return this;
        }
        /**
         * The CacheContainer configuration. Uses if the cacheContainer is not
         * defined. Must be the following types:
         * org.infinispan.client.hotrod.configuration.Configuration - for remote
         * cache interaction configuration;
         * org.infinispan.configuration.cache.Configuration - for embedded cache
         * interaction configuration;.
         * 
         * The option will be converted to a <code>java.lang.Object</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointConsumerBuilder cacheContainerConfiguration(
                String cacheContainerConfiguration) {
            doSetProperty("cacheContainerConfiguration", cacheContainerConfiguration);
            return this;
        }
        /**
         * Implementation specific properties for the CacheManager.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.String&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointConsumerBuilder configurationProperties(
                Map<String, String> configurationProperties) {
            doSetProperty("configurationProperties", configurationProperties);
            return this;
        }
        /**
         * Implementation specific properties for the CacheManager.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String, java.lang.String&gt;</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointConsumerBuilder configurationProperties(
                String configurationProperties) {
            doSetProperty("configurationProperties", configurationProperties);
            return this;
        }
        /**
         * An implementation specific URI for the CacheManager.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointConsumerBuilder configurationUri(
                String configurationUri) {
            doSetProperty("configurationUri", configurationUri);
            return this;
        }
        /**
         * A comma separated list of Flag to be applied by default on each cache
         * invocation, not applicable to remote caches.
         * 
         * The option is a: <code>org.infinispan.context.Flag[]</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointConsumerBuilder flags(Flag[] flags) {
            doSetProperty("flags", flags);
            return this;
        }
        /**
         * A comma separated list of Flag to be applied by default on each cache
         * invocation, not applicable to remote caches.
         * 
         * The option will be converted to a
         * <code>org.infinispan.context.Flag[]</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointConsumerBuilder flags(String flags) {
            doSetProperty("flags", flags);
            return this;
        }
        /**
         * Set a specific remappingFunction to use in a compute operation.
         * 
         * The option is a: <code>java.util.function.BiFunction</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointConsumerBuilder remappingFunction(
                BiFunction remappingFunction) {
            doSetProperty("remappingFunction", remappingFunction);
            return this;
        }
        /**
         * Set a specific remappingFunction to use in a compute operation.
         * 
         * The option will be converted to a
         * <code>java.util.function.BiFunction</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointConsumerBuilder remappingFunction(
                String remappingFunction) {
            doSetProperty("remappingFunction", remappingFunction);
            return this;
        }
        /**
         * Store the operation result in a header instead of the message body.
         * By default, resultHeader == null and the query result is stored in
         * the message body, any existing content in the message body is
         * discarded. If resultHeader is set, the value is used as the name of
         * the header to store the query result and the original message body is
         * preserved. This value can be overridden by an in message header
         * named: CamelInfinispanOperationResultHeader.
         * 
         * The option is a: <code>java.lang.Object</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointConsumerBuilder resultHeader(
                Object resultHeader) {
            doSetProperty("resultHeader", resultHeader);
            return this;
        }
        /**
         * Store the operation result in a header instead of the message body.
         * By default, resultHeader == null and the query result is stored in
         * the message body, any existing content in the message body is
         * discarded. If resultHeader is set, the value is used as the name of
         * the header to store the query result and the original message body is
         * preserved. This value can be overridden by an in message header
         * named: CamelInfinispanOperationResultHeader.
         * 
         * The option will be converted to a <code>java.lang.Object</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointConsumerBuilder resultHeader(
                String resultHeader) {
            doSetProperty("resultHeader", resultHeader);
            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 AdvancedInfinispanEndpointConsumerBuilder 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 AdvancedInfinispanEndpointConsumerBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
    }

    /**
     * Builder for endpoint producers for the Infinispan component.
     */
    public interface InfinispanEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default AdvancedInfinispanEndpointProducerBuilder advanced() {
            return (AdvancedInfinispanEndpointProducerBuilder) this;
        }
        /**
         * Specifies the host of the cache on Infinispan instance.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default InfinispanEndpointProducerBuilder hosts(String hosts) {
            doSetProperty("hosts", hosts);
            return this;
        }
        /**
         * Specifies the query builder.
         * 
         * The option is a:
         * <code>org.apache.camel.component.infinispan.InfinispanQueryBuilder</code> type.
         * 
         * Group: common
         */
        default InfinispanEndpointProducerBuilder queryBuilder(
                Object queryBuilder) {
            doSetProperty("queryBuilder", queryBuilder);
            return this;
        }
        /**
         * Specifies the query builder.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.infinispan.InfinispanQueryBuilder</code> type.
         * 
         * Group: common
         */
        default InfinispanEndpointProducerBuilder queryBuilder(
                String queryBuilder) {
            doSetProperty("queryBuilder", queryBuilder);
            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 InfinispanEndpointProducerBuilder 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 InfinispanEndpointProducerBuilder lazyStartProducer(
                String lazyStartProducer) {
            doSetProperty("lazyStartProducer", lazyStartProducer);
            return this;
        }
        /**
         * The operation to perform.
         * 
         * The option is a:
         * <code>org.apache.camel.component.infinispan.InfinispanOperation</code> type.
         * 
         * Group: producer
         */
        default InfinispanEndpointProducerBuilder operation(
                InfinispanOperation operation) {
            doSetProperty("operation", operation);
            return this;
        }
        /**
         * The operation to perform.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.infinispan.InfinispanOperation</code> type.
         * 
         * Group: producer
         */
        default InfinispanEndpointProducerBuilder operation(String operation) {
            doSetProperty("operation", operation);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint producers for the Infinispan component.
     */
    public interface AdvancedInfinispanEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default InfinispanEndpointProducerBuilder basic() {
            return (InfinispanEndpointProducerBuilder) 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 AdvancedInfinispanEndpointProducerBuilder 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 AdvancedInfinispanEndpointProducerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Specifies the cache Container to connect.
         * 
         * The option is a:
         * <code>org.infinispan.commons.api.BasicCacheContainer</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointProducerBuilder cacheContainer(
                Object cacheContainer) {
            doSetProperty("cacheContainer", cacheContainer);
            return this;
        }
        /**
         * Specifies the cache Container to connect.
         * 
         * The option will be converted to a
         * <code>org.infinispan.commons.api.BasicCacheContainer</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointProducerBuilder cacheContainer(
                String cacheContainer) {
            doSetProperty("cacheContainer", cacheContainer);
            return this;
        }
        /**
         * The CacheContainer configuration. Uses if the cacheContainer is not
         * defined. Must be the following types:
         * org.infinispan.client.hotrod.configuration.Configuration - for remote
         * cache interaction configuration;
         * org.infinispan.configuration.cache.Configuration - for embedded cache
         * interaction configuration;.
         * 
         * The option is a: <code>java.lang.Object</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointProducerBuilder cacheContainerConfiguration(
                Object cacheContainerConfiguration) {
            doSetProperty("cacheContainerConfiguration", cacheContainerConfiguration);
            return this;
        }
        /**
         * The CacheContainer configuration. Uses if the cacheContainer is not
         * defined. Must be the following types:
         * org.infinispan.client.hotrod.configuration.Configuration - for remote
         * cache interaction configuration;
         * org.infinispan.configuration.cache.Configuration - for embedded cache
         * interaction configuration;.
         * 
         * The option will be converted to a <code>java.lang.Object</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointProducerBuilder cacheContainerConfiguration(
                String cacheContainerConfiguration) {
            doSetProperty("cacheContainerConfiguration", cacheContainerConfiguration);
            return this;
        }
        /**
         * Implementation specific properties for the CacheManager.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.String&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointProducerBuilder configurationProperties(
                Map<String, String> configurationProperties) {
            doSetProperty("configurationProperties", configurationProperties);
            return this;
        }
        /**
         * Implementation specific properties for the CacheManager.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String, java.lang.String&gt;</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointProducerBuilder configurationProperties(
                String configurationProperties) {
            doSetProperty("configurationProperties", configurationProperties);
            return this;
        }
        /**
         * An implementation specific URI for the CacheManager.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointProducerBuilder configurationUri(
                String configurationUri) {
            doSetProperty("configurationUri", configurationUri);
            return this;
        }
        /**
         * A comma separated list of Flag to be applied by default on each cache
         * invocation, not applicable to remote caches.
         * 
         * The option is a: <code>org.infinispan.context.Flag[]</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointProducerBuilder flags(Flag[] flags) {
            doSetProperty("flags", flags);
            return this;
        }
        /**
         * A comma separated list of Flag to be applied by default on each cache
         * invocation, not applicable to remote caches.
         * 
         * The option will be converted to a
         * <code>org.infinispan.context.Flag[]</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointProducerBuilder flags(String flags) {
            doSetProperty("flags", flags);
            return this;
        }
        /**
         * Set a specific remappingFunction to use in a compute operation.
         * 
         * The option is a: <code>java.util.function.BiFunction</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointProducerBuilder remappingFunction(
                BiFunction remappingFunction) {
            doSetProperty("remappingFunction", remappingFunction);
            return this;
        }
        /**
         * Set a specific remappingFunction to use in a compute operation.
         * 
         * The option will be converted to a
         * <code>java.util.function.BiFunction</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointProducerBuilder remappingFunction(
                String remappingFunction) {
            doSetProperty("remappingFunction", remappingFunction);
            return this;
        }
        /**
         * Store the operation result in a header instead of the message body.
         * By default, resultHeader == null and the query result is stored in
         * the message body, any existing content in the message body is
         * discarded. If resultHeader is set, the value is used as the name of
         * the header to store the query result and the original message body is
         * preserved. This value can be overridden by an in message header
         * named: CamelInfinispanOperationResultHeader.
         * 
         * The option is a: <code>java.lang.Object</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointProducerBuilder resultHeader(
                Object resultHeader) {
            doSetProperty("resultHeader", resultHeader);
            return this;
        }
        /**
         * Store the operation result in a header instead of the message body.
         * By default, resultHeader == null and the query result is stored in
         * the message body, any existing content in the message body is
         * discarded. If resultHeader is set, the value is used as the name of
         * the header to store the query result and the original message body is
         * preserved. This value can be overridden by an in message header
         * named: CamelInfinispanOperationResultHeader.
         * 
         * The option will be converted to a <code>java.lang.Object</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointProducerBuilder resultHeader(
                String resultHeader) {
            doSetProperty("resultHeader", resultHeader);
            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 AdvancedInfinispanEndpointProducerBuilder 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 AdvancedInfinispanEndpointProducerBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
    }

    /**
     * Builder for endpoint for the Infinispan component.
     */
    public interface InfinispanEndpointBuilder
            extends
                InfinispanEndpointConsumerBuilder, InfinispanEndpointProducerBuilder {
        default AdvancedInfinispanEndpointBuilder advanced() {
            return (AdvancedInfinispanEndpointBuilder) this;
        }
        /**
         * Specifies the host of the cache on Infinispan instance.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default InfinispanEndpointBuilder hosts(String hosts) {
            doSetProperty("hosts", hosts);
            return this;
        }
        /**
         * Specifies the query builder.
         * 
         * The option is a:
         * <code>org.apache.camel.component.infinispan.InfinispanQueryBuilder</code> type.
         * 
         * Group: common
         */
        default InfinispanEndpointBuilder queryBuilder(Object queryBuilder) {
            doSetProperty("queryBuilder", queryBuilder);
            return this;
        }
        /**
         * Specifies the query builder.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.infinispan.InfinispanQueryBuilder</code> type.
         * 
         * Group: common
         */
        default InfinispanEndpointBuilder queryBuilder(String queryBuilder) {
            doSetProperty("queryBuilder", queryBuilder);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint for the Infinispan component.
     */
    public interface AdvancedInfinispanEndpointBuilder
            extends
                AdvancedInfinispanEndpointConsumerBuilder, AdvancedInfinispanEndpointProducerBuilder {
        default InfinispanEndpointBuilder basic() {
            return (InfinispanEndpointBuilder) 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 AdvancedInfinispanEndpointBuilder 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 AdvancedInfinispanEndpointBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Specifies the cache Container to connect.
         * 
         * The option is a:
         * <code>org.infinispan.commons.api.BasicCacheContainer</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointBuilder cacheContainer(
                Object cacheContainer) {
            doSetProperty("cacheContainer", cacheContainer);
            return this;
        }
        /**
         * Specifies the cache Container to connect.
         * 
         * The option will be converted to a
         * <code>org.infinispan.commons.api.BasicCacheContainer</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointBuilder cacheContainer(
                String cacheContainer) {
            doSetProperty("cacheContainer", cacheContainer);
            return this;
        }
        /**
         * The CacheContainer configuration. Uses if the cacheContainer is not
         * defined. Must be the following types:
         * org.infinispan.client.hotrod.configuration.Configuration - for remote
         * cache interaction configuration;
         * org.infinispan.configuration.cache.Configuration - for embedded cache
         * interaction configuration;.
         * 
         * The option is a: <code>java.lang.Object</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointBuilder cacheContainerConfiguration(
                Object cacheContainerConfiguration) {
            doSetProperty("cacheContainerConfiguration", cacheContainerConfiguration);
            return this;
        }
        /**
         * The CacheContainer configuration. Uses if the cacheContainer is not
         * defined. Must be the following types:
         * org.infinispan.client.hotrod.configuration.Configuration - for remote
         * cache interaction configuration;
         * org.infinispan.configuration.cache.Configuration - for embedded cache
         * interaction configuration;.
         * 
         * The option will be converted to a <code>java.lang.Object</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointBuilder cacheContainerConfiguration(
                String cacheContainerConfiguration) {
            doSetProperty("cacheContainerConfiguration", cacheContainerConfiguration);
            return this;
        }
        /**
         * Implementation specific properties for the CacheManager.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.String&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointBuilder configurationProperties(
                Map<String, String> configurationProperties) {
            doSetProperty("configurationProperties", configurationProperties);
            return this;
        }
        /**
         * Implementation specific properties for the CacheManager.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String, java.lang.String&gt;</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointBuilder configurationProperties(
                String configurationProperties) {
            doSetProperty("configurationProperties", configurationProperties);
            return this;
        }
        /**
         * An implementation specific URI for the CacheManager.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointBuilder configurationUri(
                String configurationUri) {
            doSetProperty("configurationUri", configurationUri);
            return this;
        }
        /**
         * A comma separated list of Flag to be applied by default on each cache
         * invocation, not applicable to remote caches.
         * 
         * The option is a: <code>org.infinispan.context.Flag[]</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointBuilder flags(Flag[] flags) {
            doSetProperty("flags", flags);
            return this;
        }
        /**
         * A comma separated list of Flag to be applied by default on each cache
         * invocation, not applicable to remote caches.
         * 
         * The option will be converted to a
         * <code>org.infinispan.context.Flag[]</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointBuilder flags(String flags) {
            doSetProperty("flags", flags);
            return this;
        }
        /**
         * Set a specific remappingFunction to use in a compute operation.
         * 
         * The option is a: <code>java.util.function.BiFunction</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointBuilder remappingFunction(
                BiFunction remappingFunction) {
            doSetProperty("remappingFunction", remappingFunction);
            return this;
        }
        /**
         * Set a specific remappingFunction to use in a compute operation.
         * 
         * The option will be converted to a
         * <code>java.util.function.BiFunction</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointBuilder remappingFunction(
                String remappingFunction) {
            doSetProperty("remappingFunction", remappingFunction);
            return this;
        }
        /**
         * Store the operation result in a header instead of the message body.
         * By default, resultHeader == null and the query result is stored in
         * the message body, any existing content in the message body is
         * discarded. If resultHeader is set, the value is used as the name of
         * the header to store the query result and the original message body is
         * preserved. This value can be overridden by an in message header
         * named: CamelInfinispanOperationResultHeader.
         * 
         * The option is a: <code>java.lang.Object</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointBuilder resultHeader(
                Object resultHeader) {
            doSetProperty("resultHeader", resultHeader);
            return this;
        }
        /**
         * Store the operation result in a header instead of the message body.
         * By default, resultHeader == null and the query result is stored in
         * the message body, any existing content in the message body is
         * discarded. If resultHeader is set, the value is used as the name of
         * the header to store the query result and the original message body is
         * preserved. This value can be overridden by an in message header
         * named: CamelInfinispanOperationResultHeader.
         * 
         * The option will be converted to a <code>java.lang.Object</code> type.
         * 
         * Group: advanced
         */
        default AdvancedInfinispanEndpointBuilder resultHeader(
                String resultHeader) {
            doSetProperty("resultHeader", resultHeader);
            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 AdvancedInfinispanEndpointBuilder 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 AdvancedInfinispanEndpointBuilder synchronous(String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
    }

    /**
     * Proxy enum for
     * <code>org.apache.camel.component.infinispan.InfinispanOperation</code>
     * enum.
     */
    enum InfinispanOperation {
        PUT,
        PUTASYNC,
        PUTALL,
        PUTALLASYNC,
        PUTIFABSENT,
        PUTIFABSENTASYNC,
        GET,
        GETORDEFAULT,
        CONTAINSKEY,
        CONTAINSVALUE,
        REMOVE,
        REMOVEASYNC,
        REPLACE,
        REPLACEASYNC,
        SIZE,
        CLEAR,
        CLEARASYNC,
        QUERY,
        STATS,
        COMPUTE,
        COMPUTEASYNC;
    }

    /**
     * Proxy enum for <code>org.infinispan.context.Flag</code> enum.
     */
    enum Flag {
        ZERO_LOCK_ACQUISITION_TIMEOUT,
        CACHE_MODE_LOCAL,
        SKIP_LOCKING,
        FORCE_WRITE_LOCK,
        SKIP_CACHE_STATUS_CHECK,
        FORCE_ASYNCHRONOUS,
        FORCE_SYNCHRONOUS,
        SKIP_CACHE_STORE,
        SKIP_CACHE_LOAD,
        FAIL_SILENTLY,
        SKIP_REMOTE_LOOKUP,
        SKIP_INDEXING,
        PUT_FOR_EXTERNAL_READ,
        PUT_FOR_STATE_TRANSFER,
        PUT_FOR_X_SITE_STATE_TRANSFER,
        SKIP_SHARED_CACHE_STORE,
        SKIP_OWNERSHIP_CHECK,
        IGNORE_RETURN_VALUES,
        SKIP_XSITE_BACKUP,
        SKIP_LISTENER_NOTIFICATION,
        SKIP_STATISTICS,
        OPERATION_HOTROD,
        OPERATION_MEMCACHED,
        SKIP_INDEX_CLEANUP,
        COMMAND_RETRY,
        ROLLING_UPGRADE,
        REMOTE_ITERATION,
        SKIP_SIZE_OPTIMIZATION;
    }
    /**
     * Infinispan (camel-infinispan)
     * For reading/writing from/to Infinispan distributed key/value store and
     * data grid.
     * 
     * Category: cache,datagrid,clustering
     * Since: 2.13
     * Maven coordinates: org.apache.camel:camel-infinispan
     * 
     * Syntax: <code>infinispan:cacheName</code>
     * 
     * Path parameter: cacheName (required)
     * The cache to use
     */
    default InfinispanEndpointBuilder infinispan(String path) {
        class InfinispanEndpointBuilderImpl extends AbstractEndpointBuilder implements InfinispanEndpointBuilder, AdvancedInfinispanEndpointBuilder {
            public InfinispanEndpointBuilderImpl(String path) {
                super("infinispan", path);
            }
        }
        return new InfinispanEndpointBuilderImpl(path);
    }
}