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

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

/**
 * The splunk component allows to publish or search for events in Splunk.
 * 
 * Generated by camel-package-maven-plugin - do not edit this file!
 */
@Generated("org.apache.camel.maven.packaging.EndpointDslMojo")
public interface SplunkEndpointBuilderFactory {


    /**
     * Builder for endpoint consumers for the Splunk component.
     */
    public interface SplunkEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default AdvancedSplunkEndpointConsumerBuilder advanced() {
            return (AdvancedSplunkEndpointConsumerBuilder) this;
        }
        /**
         * Splunk app.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default SplunkEndpointConsumerBuilder app(String app) {
            doSetProperty("app", app);
            return this;
        }
        /**
         * Timeout in MS when connecting to Splunk server.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: common
         */
        default SplunkEndpointConsumerBuilder connectionTimeout(
                int connectionTimeout) {
            doSetProperty("connectionTimeout", connectionTimeout);
            return this;
        }
        /**
         * Timeout in MS when connecting to Splunk server.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: common
         */
        default SplunkEndpointConsumerBuilder connectionTimeout(
                String connectionTimeout) {
            doSetProperty("connectionTimeout", connectionTimeout);
            return this;
        }
        /**
         * Splunk host.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default SplunkEndpointConsumerBuilder host(String host) {
            doSetProperty("host", host);
            return this;
        }
        /**
         * Splunk owner.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default SplunkEndpointConsumerBuilder owner(String owner) {
            doSetProperty("owner", owner);
            return this;
        }
        /**
         * Splunk port.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: common
         */
        default SplunkEndpointConsumerBuilder port(int port) {
            doSetProperty("port", port);
            return this;
        }
        /**
         * Splunk port.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: common
         */
        default SplunkEndpointConsumerBuilder port(String port) {
            doSetProperty("port", port);
            return this;
        }
        /**
         * Splunk scheme.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default SplunkEndpointConsumerBuilder scheme(String scheme) {
            doSetProperty("scheme", scheme);
            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 SplunkEndpointConsumerBuilder 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 SplunkEndpointConsumerBuilder bridgeErrorHandler(
                String bridgeErrorHandler) {
            doSetProperty("bridgeErrorHandler", bridgeErrorHandler);
            return this;
        }
        /**
         * A number that indicates the maximum number of entities to return.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: consumer
         */
        default SplunkEndpointConsumerBuilder count(int count) {
            doSetProperty("count", count);
            return this;
        }
        /**
         * A number that indicates the maximum number of entities to return.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: consumer
         */
        default SplunkEndpointConsumerBuilder count(String count) {
            doSetProperty("count", count);
            return this;
        }
        /**
         * Earliest time of the search time window.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer
         */
        default SplunkEndpointConsumerBuilder earliestTime(String earliestTime) {
            doSetProperty("earliestTime", earliestTime);
            return this;
        }
        /**
         * Initial start offset of the first search.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer
         */
        default SplunkEndpointConsumerBuilder initEarliestTime(
                String initEarliestTime) {
            doSetProperty("initEarliestTime", initEarliestTime);
            return this;
        }
        /**
         * Latest time of the search time window.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer
         */
        default SplunkEndpointConsumerBuilder latestTime(String latestTime) {
            doSetProperty("latestTime", latestTime);
            return this;
        }
        /**
         * The name of the query saved in Splunk to run.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer
         */
        default SplunkEndpointConsumerBuilder savedSearch(String savedSearch) {
            doSetProperty("savedSearch", savedSearch);
            return this;
        }
        /**
         * The Splunk query to run.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: consumer
         */
        default SplunkEndpointConsumerBuilder search(String search) {
            doSetProperty("search", search);
            return this;
        }
        /**
         * If the polling consumer did not poll any files, you can enable this
         * option to send an empty message (no body) instead.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default SplunkEndpointConsumerBuilder sendEmptyMessageWhenIdle(
                boolean sendEmptyMessageWhenIdle) {
            doSetProperty("sendEmptyMessageWhenIdle", sendEmptyMessageWhenIdle);
            return this;
        }
        /**
         * If the polling consumer did not poll any files, you can enable this
         * option to send an empty message (no body) instead.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default SplunkEndpointConsumerBuilder sendEmptyMessageWhenIdle(
                String sendEmptyMessageWhenIdle) {
            doSetProperty("sendEmptyMessageWhenIdle", sendEmptyMessageWhenIdle);
            return this;
        }
        /**
         * Sets streaming mode. Streaming mode sends exchanges as they are
         * received, rather than in a batch.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default SplunkEndpointConsumerBuilder streaming(boolean streaming) {
            doSetProperty("streaming", streaming);
            return this;
        }
        /**
         * Sets streaming mode. Streaming mode sends exchanges as they are
         * received, rather than in a batch.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default SplunkEndpointConsumerBuilder streaming(String streaming) {
            doSetProperty("streaming", streaming);
            return this;
        }
        /**
         * The number of subsequent error polls (failed due some error) that
         * should happen before the backoffMultipler should kick-in.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder backoffErrorThreshold(
                int backoffErrorThreshold) {
            doSetProperty("backoffErrorThreshold", backoffErrorThreshold);
            return this;
        }
        /**
         * The number of subsequent error polls (failed due some error) that
         * should happen before the backoffMultipler should kick-in.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder backoffErrorThreshold(
                String backoffErrorThreshold) {
            doSetProperty("backoffErrorThreshold", backoffErrorThreshold);
            return this;
        }
        /**
         * The number of subsequent idle polls that should happen before the
         * backoffMultipler should kick-in.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder backoffIdleThreshold(
                int backoffIdleThreshold) {
            doSetProperty("backoffIdleThreshold", backoffIdleThreshold);
            return this;
        }
        /**
         * The number of subsequent idle polls that should happen before the
         * backoffMultipler should kick-in.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder backoffIdleThreshold(
                String backoffIdleThreshold) {
            doSetProperty("backoffIdleThreshold", backoffIdleThreshold);
            return this;
        }
        /**
         * To let the scheduled polling consumer backoff if there has been a
         * number of subsequent idles/errors in a row. The multiplier is then
         * the number of polls that will be skipped before the next actual
         * attempt is happening again. When this option is in use then
         * backoffIdleThreshold and/or backoffErrorThreshold must also be
         * configured.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder backoffMultiplier(
                int backoffMultiplier) {
            doSetProperty("backoffMultiplier", backoffMultiplier);
            return this;
        }
        /**
         * To let the scheduled polling consumer backoff if there has been a
         * number of subsequent idles/errors in a row. The multiplier is then
         * the number of polls that will be skipped before the next actual
         * attempt is happening again. When this option is in use then
         * backoffIdleThreshold and/or backoffErrorThreshold must also be
         * configured.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder backoffMultiplier(
                String backoffMultiplier) {
            doSetProperty("backoffMultiplier", backoffMultiplier);
            return this;
        }
        /**
         * Milliseconds before the next poll. You can also specify time values
         * using units, such as 60s (60 seconds), 5m30s (5 minutes and 30
         * seconds), and 1h (1 hour).
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder delay(long delay) {
            doSetProperty("delay", delay);
            return this;
        }
        /**
         * Milliseconds before the next poll. You can also specify time values
         * using units, such as 60s (60 seconds), 5m30s (5 minutes and 30
         * seconds), and 1h (1 hour).
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder delay(String delay) {
            doSetProperty("delay", delay);
            return this;
        }
        /**
         * If greedy is enabled, then the ScheduledPollConsumer will run
         * immediately again, if the previous run polled 1 or more messages.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder greedy(boolean greedy) {
            doSetProperty("greedy", greedy);
            return this;
        }
        /**
         * If greedy is enabled, then the ScheduledPollConsumer will run
         * immediately again, if the previous run polled 1 or more messages.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder greedy(String greedy) {
            doSetProperty("greedy", greedy);
            return this;
        }
        /**
         * Milliseconds before the first poll starts. You can also specify time
         * values using units, such as 60s (60 seconds), 5m30s (5 minutes and 30
         * seconds), and 1h (1 hour).
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder initialDelay(long initialDelay) {
            doSetProperty("initialDelay", initialDelay);
            return this;
        }
        /**
         * Milliseconds before the first poll starts. You can also specify time
         * values using units, such as 60s (60 seconds), 5m30s (5 minutes and 30
         * seconds), and 1h (1 hour).
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder initialDelay(String initialDelay) {
            doSetProperty("initialDelay", initialDelay);
            return this;
        }
        /**
         * Specifies a maximum limit of number of fires. So if you set it to 1,
         * the scheduler will only fire once. If you set it to 5, it will only
         * fire five times. A value of zero or negative means fire forever.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder repeatCount(long repeatCount) {
            doSetProperty("repeatCount", repeatCount);
            return this;
        }
        /**
         * Specifies a maximum limit of number of fires. So if you set it to 1,
         * the scheduler will only fire once. If you set it to 5, it will only
         * fire five times. A value of zero or negative means fire forever.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder repeatCount(String repeatCount) {
            doSetProperty("repeatCount", repeatCount);
            return this;
        }
        /**
         * The consumer logs a start/complete log line when it polls. This
         * option allows you to configure the logging level for that.
         * 
         * The option is a: <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder runLoggingLevel(
                LoggingLevel runLoggingLevel) {
            doSetProperty("runLoggingLevel", runLoggingLevel);
            return this;
        }
        /**
         * The consumer logs a start/complete log line when it polls. This
         * option allows you to configure the logging level for that.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.LoggingLevel</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder runLoggingLevel(
                String runLoggingLevel) {
            doSetProperty("runLoggingLevel", runLoggingLevel);
            return this;
        }
        /**
         * Allows for configuring a custom/shared thread pool to use for the
         * consumer. By default each consumer has its own single threaded thread
         * pool.
         * 
         * The option is a:
         * <code>java.util.concurrent.ScheduledExecutorService</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder scheduledExecutorService(
                ScheduledExecutorService scheduledExecutorService) {
            doSetProperty("scheduledExecutorService", scheduledExecutorService);
            return this;
        }
        /**
         * Allows for configuring a custom/shared thread pool to use for the
         * consumer. By default each consumer has its own single threaded thread
         * pool.
         * 
         * The option will be converted to a
         * <code>java.util.concurrent.ScheduledExecutorService</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder scheduledExecutorService(
                String scheduledExecutorService) {
            doSetProperty("scheduledExecutorService", scheduledExecutorService);
            return this;
        }
        /**
         * To use a cron scheduler from either camel-spring or camel-quartz
         * component.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder scheduler(String scheduler) {
            doSetProperty("scheduler", scheduler);
            return this;
        }
        /**
         * To configure additional properties when using a custom scheduler or
         * any of the Quartz, Spring based scheduler.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.Object&gt;</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder schedulerProperties(
                Map<String, Object> schedulerProperties) {
            doSetProperty("schedulerProperties", schedulerProperties);
            return this;
        }
        /**
         * To configure additional properties when using a custom scheduler or
         * any of the Quartz, Spring based scheduler.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String, java.lang.Object&gt;</code>
         * type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder schedulerProperties(
                String schedulerProperties) {
            doSetProperty("schedulerProperties", schedulerProperties);
            return this;
        }
        /**
         * Whether the scheduler should be auto started.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder startScheduler(
                boolean startScheduler) {
            doSetProperty("startScheduler", startScheduler);
            return this;
        }
        /**
         * Whether the scheduler should be auto started.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder startScheduler(
                String startScheduler) {
            doSetProperty("startScheduler", startScheduler);
            return this;
        }
        /**
         * Time unit for initialDelay and delay options.
         * 
         * The option is a: <code>java.util.concurrent.TimeUnit</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder timeUnit(TimeUnit timeUnit) {
            doSetProperty("timeUnit", timeUnit);
            return this;
        }
        /**
         * Time unit for initialDelay and delay options.
         * 
         * The option will be converted to a
         * <code>java.util.concurrent.TimeUnit</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder timeUnit(String timeUnit) {
            doSetProperty("timeUnit", timeUnit);
            return this;
        }
        /**
         * Controls if fixed delay or fixed rate is used. See
         * ScheduledExecutorService in JDK for details.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder useFixedDelay(
                boolean useFixedDelay) {
            doSetProperty("useFixedDelay", useFixedDelay);
            return this;
        }
        /**
         * Controls if fixed delay or fixed rate is used. See
         * ScheduledExecutorService in JDK for details.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: scheduler
         */
        default SplunkEndpointConsumerBuilder useFixedDelay(String useFixedDelay) {
            doSetProperty("useFixedDelay", useFixedDelay);
            return this;
        }
        /**
         * Password for Splunk.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SplunkEndpointConsumerBuilder password(String password) {
            doSetProperty("password", password);
            return this;
        }
        /**
         * Set the ssl protocol to use.
         * 
         * The option is a: <code>com.splunk.SSLSecurityProtocol</code> type.
         * 
         * Group: security
         */
        default SplunkEndpointConsumerBuilder sslProtocol(
                SSLSecurityProtocol sslProtocol) {
            doSetProperty("sslProtocol", sslProtocol);
            return this;
        }
        /**
         * Set the ssl protocol to use.
         * 
         * The option will be converted to a
         * <code>com.splunk.SSLSecurityProtocol</code> type.
         * 
         * Group: security
         */
        default SplunkEndpointConsumerBuilder sslProtocol(String sslProtocol) {
            doSetProperty("sslProtocol", sslProtocol);
            return this;
        }
        /**
         * Username for Splunk.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SplunkEndpointConsumerBuilder username(String username) {
            doSetProperty("username", username);
            return this;
        }
        /**
         * Use sun.net.www.protocol.https.Handler Https handler to establish the
         * Splunk Connection. Can be useful when running in application servers
         * to avoid app. server https handling.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: security
         */
        default SplunkEndpointConsumerBuilder useSunHttpsHandler(
                boolean useSunHttpsHandler) {
            doSetProperty("useSunHttpsHandler", useSunHttpsHandler);
            return this;
        }
        /**
         * Use sun.net.www.protocol.https.Handler Https handler to establish the
         * Splunk Connection. Can be useful when running in application servers
         * to avoid app. server https handling.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: security
         */
        default SplunkEndpointConsumerBuilder useSunHttpsHandler(
                String useSunHttpsHandler) {
            doSetProperty("useSunHttpsHandler", useSunHttpsHandler);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint consumers for the Splunk component.
     */
    public interface AdvancedSplunkEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default SplunkEndpointConsumerBuilder basic() {
            return (SplunkEndpointConsumerBuilder) 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 AdvancedSplunkEndpointConsumerBuilder 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 AdvancedSplunkEndpointConsumerBuilder 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 AdvancedSplunkEndpointConsumerBuilder 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 AdvancedSplunkEndpointConsumerBuilder exchangePattern(
                String exchangePattern) {
            doSetProperty("exchangePattern", exchangePattern);
            return this;
        }
        /**
         * A pluggable org.apache.camel.PollingConsumerPollingStrategy allowing
         * you to provide your custom implementation to control error handling
         * usually occurred during the poll operation before an Exchange have
         * been created and being routed in Camel.
         * 
         * The option is a:
         * <code>org.apache.camel.spi.PollingConsumerPollStrategy</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedSplunkEndpointConsumerBuilder pollStrategy(
                PollingConsumerPollStrategy pollStrategy) {
            doSetProperty("pollStrategy", pollStrategy);
            return this;
        }
        /**
         * A pluggable org.apache.camel.PollingConsumerPollingStrategy allowing
         * you to provide your custom implementation to control error handling
         * usually occurred during the poll operation before an Exchange have
         * been created and being routed in Camel.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.spi.PollingConsumerPollStrategy</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedSplunkEndpointConsumerBuilder pollStrategy(
                String pollStrategy) {
            doSetProperty("pollStrategy", pollStrategy);
            return this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSplunkEndpointConsumerBuilder 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 AdvancedSplunkEndpointConsumerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSplunkEndpointConsumerBuilder 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 AdvancedSplunkEndpointConsumerBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
    }

    /**
     * Builder for endpoint producers for the Splunk component.
     */
    public interface SplunkEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default AdvancedSplunkEndpointProducerBuilder advanced() {
            return (AdvancedSplunkEndpointProducerBuilder) this;
        }
        /**
         * Splunk app.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default SplunkEndpointProducerBuilder app(String app) {
            doSetProperty("app", app);
            return this;
        }
        /**
         * Timeout in MS when connecting to Splunk server.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: common
         */
        default SplunkEndpointProducerBuilder connectionTimeout(
                int connectionTimeout) {
            doSetProperty("connectionTimeout", connectionTimeout);
            return this;
        }
        /**
         * Timeout in MS when connecting to Splunk server.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: common
         */
        default SplunkEndpointProducerBuilder connectionTimeout(
                String connectionTimeout) {
            doSetProperty("connectionTimeout", connectionTimeout);
            return this;
        }
        /**
         * Splunk host.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default SplunkEndpointProducerBuilder host(String host) {
            doSetProperty("host", host);
            return this;
        }
        /**
         * Splunk owner.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default SplunkEndpointProducerBuilder owner(String owner) {
            doSetProperty("owner", owner);
            return this;
        }
        /**
         * Splunk port.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: common
         */
        default SplunkEndpointProducerBuilder port(int port) {
            doSetProperty("port", port);
            return this;
        }
        /**
         * Splunk port.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: common
         */
        default SplunkEndpointProducerBuilder port(String port) {
            doSetProperty("port", port);
            return this;
        }
        /**
         * Splunk scheme.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default SplunkEndpointProducerBuilder scheme(String scheme) {
            doSetProperty("scheme", scheme);
            return this;
        }
        /**
         * Override the default Splunk event host field.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer
         */
        default SplunkEndpointProducerBuilder eventHost(String eventHost) {
            doSetProperty("eventHost", eventHost);
            return this;
        }
        /**
         * Splunk index to write to.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer
         */
        default SplunkEndpointProducerBuilder index(String index) {
            doSetProperty("index", index);
            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 SplunkEndpointProducerBuilder 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 SplunkEndpointProducerBuilder lazyStartProducer(
                String lazyStartProducer) {
            doSetProperty("lazyStartProducer", lazyStartProducer);
            return this;
        }
        /**
         * Should the payload be inserted raw.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer
         */
        default SplunkEndpointProducerBuilder raw(boolean raw) {
            doSetProperty("raw", raw);
            return this;
        }
        /**
         * Should the payload be inserted raw.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer
         */
        default SplunkEndpointProducerBuilder raw(String raw) {
            doSetProperty("raw", raw);
            return this;
        }
        /**
         * Splunk source argument.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer
         */
        default SplunkEndpointProducerBuilder source(String source) {
            doSetProperty("source", source);
            return this;
        }
        /**
         * Splunk sourcetype argument.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer
         */
        default SplunkEndpointProducerBuilder sourceType(String sourceType) {
            doSetProperty("sourceType", sourceType);
            return this;
        }
        /**
         * Splunk tcp receiver port.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: producer
         */
        default SplunkEndpointProducerBuilder tcpReceiverPort(
                int tcpReceiverPort) {
            doSetProperty("tcpReceiverPort", tcpReceiverPort);
            return this;
        }
        /**
         * Splunk tcp receiver port.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: producer
         */
        default SplunkEndpointProducerBuilder tcpReceiverPort(
                String tcpReceiverPort) {
            doSetProperty("tcpReceiverPort", tcpReceiverPort);
            return this;
        }
        /**
         * Password for Splunk.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SplunkEndpointProducerBuilder password(String password) {
            doSetProperty("password", password);
            return this;
        }
        /**
         * Set the ssl protocol to use.
         * 
         * The option is a: <code>com.splunk.SSLSecurityProtocol</code> type.
         * 
         * Group: security
         */
        default SplunkEndpointProducerBuilder sslProtocol(
                SSLSecurityProtocol sslProtocol) {
            doSetProperty("sslProtocol", sslProtocol);
            return this;
        }
        /**
         * Set the ssl protocol to use.
         * 
         * The option will be converted to a
         * <code>com.splunk.SSLSecurityProtocol</code> type.
         * 
         * Group: security
         */
        default SplunkEndpointProducerBuilder sslProtocol(String sslProtocol) {
            doSetProperty("sslProtocol", sslProtocol);
            return this;
        }
        /**
         * Username for Splunk.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SplunkEndpointProducerBuilder username(String username) {
            doSetProperty("username", username);
            return this;
        }
        /**
         * Use sun.net.www.protocol.https.Handler Https handler to establish the
         * Splunk Connection. Can be useful when running in application servers
         * to avoid app. server https handling.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: security
         */
        default SplunkEndpointProducerBuilder useSunHttpsHandler(
                boolean useSunHttpsHandler) {
            doSetProperty("useSunHttpsHandler", useSunHttpsHandler);
            return this;
        }
        /**
         * Use sun.net.www.protocol.https.Handler Https handler to establish the
         * Splunk Connection. Can be useful when running in application servers
         * to avoid app. server https handling.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: security
         */
        default SplunkEndpointProducerBuilder useSunHttpsHandler(
                String useSunHttpsHandler) {
            doSetProperty("useSunHttpsHandler", useSunHttpsHandler);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint producers for the Splunk component.
     */
    public interface AdvancedSplunkEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default SplunkEndpointProducerBuilder basic() {
            return (SplunkEndpointProducerBuilder) 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 AdvancedSplunkEndpointProducerBuilder 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 AdvancedSplunkEndpointProducerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSplunkEndpointProducerBuilder 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 AdvancedSplunkEndpointProducerBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
    }

    /**
     * Builder for endpoint for the Splunk component.
     */
    public interface SplunkEndpointBuilder
            extends
                SplunkEndpointConsumerBuilder, SplunkEndpointProducerBuilder {
        default AdvancedSplunkEndpointBuilder advanced() {
            return (AdvancedSplunkEndpointBuilder) this;
        }
        /**
         * Splunk app.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default SplunkEndpointBuilder app(String app) {
            doSetProperty("app", app);
            return this;
        }
        /**
         * Timeout in MS when connecting to Splunk server.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: common
         */
        default SplunkEndpointBuilder connectionTimeout(int connectionTimeout) {
            doSetProperty("connectionTimeout", connectionTimeout);
            return this;
        }
        /**
         * Timeout in MS when connecting to Splunk server.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: common
         */
        default SplunkEndpointBuilder connectionTimeout(String connectionTimeout) {
            doSetProperty("connectionTimeout", connectionTimeout);
            return this;
        }
        /**
         * Splunk host.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default SplunkEndpointBuilder host(String host) {
            doSetProperty("host", host);
            return this;
        }
        /**
         * Splunk owner.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default SplunkEndpointBuilder owner(String owner) {
            doSetProperty("owner", owner);
            return this;
        }
        /**
         * Splunk port.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: common
         */
        default SplunkEndpointBuilder port(int port) {
            doSetProperty("port", port);
            return this;
        }
        /**
         * Splunk port.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: common
         */
        default SplunkEndpointBuilder port(String port) {
            doSetProperty("port", port);
            return this;
        }
        /**
         * Splunk scheme.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default SplunkEndpointBuilder scheme(String scheme) {
            doSetProperty("scheme", scheme);
            return this;
        }
        /**
         * Password for Splunk.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SplunkEndpointBuilder password(String password) {
            doSetProperty("password", password);
            return this;
        }
        /**
         * Set the ssl protocol to use.
         * 
         * The option is a: <code>com.splunk.SSLSecurityProtocol</code> type.
         * 
         * Group: security
         */
        default SplunkEndpointBuilder sslProtocol(
                SSLSecurityProtocol sslProtocol) {
            doSetProperty("sslProtocol", sslProtocol);
            return this;
        }
        /**
         * Set the ssl protocol to use.
         * 
         * The option will be converted to a
         * <code>com.splunk.SSLSecurityProtocol</code> type.
         * 
         * Group: security
         */
        default SplunkEndpointBuilder sslProtocol(String sslProtocol) {
            doSetProperty("sslProtocol", sslProtocol);
            return this;
        }
        /**
         * Username for Splunk.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default SplunkEndpointBuilder username(String username) {
            doSetProperty("username", username);
            return this;
        }
        /**
         * Use sun.net.www.protocol.https.Handler Https handler to establish the
         * Splunk Connection. Can be useful when running in application servers
         * to avoid app. server https handling.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: security
         */
        default SplunkEndpointBuilder useSunHttpsHandler(
                boolean useSunHttpsHandler) {
            doSetProperty("useSunHttpsHandler", useSunHttpsHandler);
            return this;
        }
        /**
         * Use sun.net.www.protocol.https.Handler Https handler to establish the
         * Splunk Connection. Can be useful when running in application servers
         * to avoid app. server https handling.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: security
         */
        default SplunkEndpointBuilder useSunHttpsHandler(
                String useSunHttpsHandler) {
            doSetProperty("useSunHttpsHandler", useSunHttpsHandler);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint for the Splunk component.
     */
    public interface AdvancedSplunkEndpointBuilder
            extends
                AdvancedSplunkEndpointConsumerBuilder, AdvancedSplunkEndpointProducerBuilder {
        default SplunkEndpointBuilder basic() {
            return (SplunkEndpointBuilder) 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 AdvancedSplunkEndpointBuilder 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 AdvancedSplunkEndpointBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedSplunkEndpointBuilder 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 AdvancedSplunkEndpointBuilder synchronous(String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
    }

    /**
     * Proxy enum for <code>com.splunk.SSLSecurityProtocol</code> enum.
     */
    enum SSLSecurityProtocol {
        TLSv1_2,
        TLSv1_1,
        TLSv1,
        SSLv3;
    }
    /**
     * Splunk (camel-splunk)
     * The splunk component allows to publish or search for events in Splunk.
     * 
     * Category: log,monitoring
     * Since: 2.13
     * Maven coordinates: org.apache.camel:camel-splunk
     * 
     * Syntax: <code>splunk:name</code>
     * 
     * Path parameter: name (required)
     * Name has no purpose
     */
    default SplunkEndpointBuilder splunk(String path) {
        class SplunkEndpointBuilderImpl extends AbstractEndpointBuilder implements SplunkEndpointBuilder, AdvancedSplunkEndpointBuilder {
            public SplunkEndpointBuilderImpl(String path) {
                super("splunk", path);
            }
        }
        return new SplunkEndpointBuilderImpl(path);
    }
}