/*
 * 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 javax.annotation.Generated;
import org.apache.camel.builder.EndpointConsumerBuilder;
import org.apache.camel.builder.EndpointProducerBuilder;
import org.apache.camel.builder.endpoint.AbstractEndpointBuilder;

/**
 * The elasticsearch component is used for interfacing with ElasticSearch server
 * using REST API.
 * 
 * Generated by camel-package-maven-plugin - do not edit this file!
 */
@Generated("org.apache.camel.maven.packaging.EndpointDslMojo")
public interface ElasticsearchEndpointBuilderFactory {


    /**
     * Builder for endpoint for the Elastichsearch Rest component.
     */
    public interface ElasticsearchEndpointBuilder
            extends
                EndpointProducerBuilder {
        default AdvancedElasticsearchEndpointBuilder advanced() {
            return (AdvancedElasticsearchEndpointBuilder) this;
        }
        /**
         * The time in ms to wait before connection will timeout.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: producer
         */
        default ElasticsearchEndpointBuilder connectionTimeout(
                int connectionTimeout) {
            doSetProperty("connectionTimeout", connectionTimeout);
            return this;
        }
        /**
         * The time in ms to wait before connection will timeout.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: producer
         */
        default ElasticsearchEndpointBuilder connectionTimeout(
                String connectionTimeout) {
            doSetProperty("connectionTimeout", connectionTimeout);
            return this;
        }
        /**
         * Disconnect after it finish calling the producer.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer
         */
        default ElasticsearchEndpointBuilder disconnect(boolean disconnect) {
            doSetProperty("disconnect", disconnect);
            return this;
        }
        /**
         * Disconnect after it finish calling the producer.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer
         */
        default ElasticsearchEndpointBuilder disconnect(String disconnect) {
            doSetProperty("disconnect", disconnect);
            return this;
        }
        /**
         * Enable SSL.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer
         */
        default ElasticsearchEndpointBuilder enableSSL(boolean enableSSL) {
            doSetProperty("enableSSL", enableSSL);
            return this;
        }
        /**
         * Enable SSL.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer
         */
        default ElasticsearchEndpointBuilder enableSSL(String enableSSL) {
            doSetProperty("enableSSL", enableSSL);
            return this;
        }
        /**
         * Comma separated list with ip:port formatted remote transport
         * addresses to use.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Required: true
         * Group: producer
         */
        default ElasticsearchEndpointBuilder hostAddresses(String hostAddresses) {
            doSetProperty("hostAddresses", hostAddresses);
            return this;
        }
        /**
         * The name of the index to act against.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer
         */
        default ElasticsearchEndpointBuilder indexName(String indexName) {
            doSetProperty("indexName", indexName);
            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 ElasticsearchEndpointBuilder 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 ElasticsearchEndpointBuilder lazyStartProducer(
                String lazyStartProducer) {
            doSetProperty("lazyStartProducer", lazyStartProducer);
            return this;
        }
        /**
         * The time in ms before retry.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: producer
         */
        default ElasticsearchEndpointBuilder maxRetryTimeout(int maxRetryTimeout) {
            doSetProperty("maxRetryTimeout", maxRetryTimeout);
            return this;
        }
        /**
         * The time in ms before retry.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: producer
         */
        default ElasticsearchEndpointBuilder maxRetryTimeout(
                String maxRetryTimeout) {
            doSetProperty("maxRetryTimeout", maxRetryTimeout);
            return this;
        }
        /**
         * What operation to perform.
         * 
         * The option is a:
         * <code>org.apache.camel.component.elasticsearch.ElasticsearchOperation</code> type.
         * 
         * Group: producer
         */
        default ElasticsearchEndpointBuilder operation(
                ElasticsearchOperation operation) {
            doSetProperty("operation", operation);
            return this;
        }
        /**
         * What operation to perform.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.elasticsearch.ElasticsearchOperation</code> type.
         * 
         * Group: producer
         */
        default ElasticsearchEndpointBuilder operation(String operation) {
            doSetProperty("operation", operation);
            return this;
        }
        /**
         * Time in ms during which elasticsearch will keep search context alive.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: producer
         */
        default ElasticsearchEndpointBuilder scrollKeepAliveMs(
                int scrollKeepAliveMs) {
            doSetProperty("scrollKeepAliveMs", scrollKeepAliveMs);
            return this;
        }
        /**
         * Time in ms during which elasticsearch will keep search context alive.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: producer
         */
        default ElasticsearchEndpointBuilder scrollKeepAliveMs(
                String scrollKeepAliveMs) {
            doSetProperty("scrollKeepAliveMs", scrollKeepAliveMs);
            return this;
        }
        /**
         * The timeout in ms to wait before the socket will timeout.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: producer
         */
        default ElasticsearchEndpointBuilder socketTimeout(int socketTimeout) {
            doSetProperty("socketTimeout", socketTimeout);
            return this;
        }
        /**
         * The timeout in ms to wait before the socket will timeout.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: producer
         */
        default ElasticsearchEndpointBuilder socketTimeout(String socketTimeout) {
            doSetProperty("socketTimeout", socketTimeout);
            return this;
        }
        /**
         * Enable scroll usage.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer
         */
        default ElasticsearchEndpointBuilder useScroll(boolean useScroll) {
            doSetProperty("useScroll", useScroll);
            return this;
        }
        /**
         * Enable scroll usage.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer
         */
        default ElasticsearchEndpointBuilder useScroll(String useScroll) {
            doSetProperty("useScroll", useScroll);
            return this;
        }
        /**
         * Index creation waits for the write consistency number of shards to be
         * available.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: producer
         */
        default ElasticsearchEndpointBuilder waitForActiveShards(
                int waitForActiveShards) {
            doSetProperty("waitForActiveShards", waitForActiveShards);
            return this;
        }
        /**
         * Index creation waits for the write consistency number of shards to be
         * available.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: producer
         */
        default ElasticsearchEndpointBuilder waitForActiveShards(
                String waitForActiveShards) {
            doSetProperty("waitForActiveShards", waitForActiveShards);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint for the Elastichsearch Rest component.
     */
    public interface AdvancedElasticsearchEndpointBuilder
            extends
                EndpointProducerBuilder {
        default ElasticsearchEndpointBuilder basic() {
            return (ElasticsearchEndpointBuilder) 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 AdvancedElasticsearchEndpointBuilder 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 AdvancedElasticsearchEndpointBuilder 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 AdvancedElasticsearchEndpointBuilder 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 AdvancedElasticsearchEndpointBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
    }

    /**
     * Proxy enum for
     * <code>org.apache.camel.component.elasticsearch.ElasticsearchOperation</code> enum.
     */
    enum ElasticsearchOperation {
        Index,
        Update,
        Bulk,
        BulkIndex,
        GetById,
        MultiGet,
        MultiSearch,
        Delete,
        DeleteIndex,
        Search,
        Exists,
        Ping;
    }
    /**
     * Elastichsearch Rest (camel-elasticsearch-rest)
     * The elasticsearch component is used for interfacing with ElasticSearch
     * server using REST API.
     * 
     * Category: monitoring,search
     * Since: 2.21
     * Maven coordinates: org.apache.camel:camel-elasticsearch-rest
     * 
     * Syntax: <code>elasticsearch-rest:clusterName</code>
     * 
     * Path parameter: clusterName (required)
     * Name of the cluster
     */
    default ElasticsearchEndpointBuilder elasticsearchRest(String path) {
        class ElasticsearchEndpointBuilderImpl extends AbstractEndpointBuilder implements ElasticsearchEndpointBuilder, AdvancedElasticsearchEndpointBuilder {
            public ElasticsearchEndpointBuilderImpl(String path) {
                super("elasticsearch-rest", path);
            }
        }
        return new ElasticsearchEndpointBuilderImpl(path);
    }
}