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

import java.util.Map;

import javax.annotation.Generated;

/**
 * Generated by camel-package-maven-plugin - do not edit this file!
 */
@Generated("org.apache.camel.maven.packaging.SpringBootAutoConfigurationMojo")
public class EtcdServiceCallServiceDiscoveryConfigurationCommon {

    /**
     * The URIs the client can connect to.
     */
    private String uris;
    /**
     * The user name to use for basic authentication.
     */
    private String userName;
    /**
     * The password to use for basic authentication.
     */
    private String password;
    /**
     * To set the maximum time an action could take to complete.
     */
    private Long timeout;
    /**
     * The path to look for for service discovery
     */
    private String servicePath = "/services/";
    /**
     * To set the discovery type, valid values are on-demand and watch.
     */
    private String type = "on-demand";
    /**
     * Set client properties to use. These properties are specific to what
     * service call implementation are in use. For example if using ribbon, then
     * the client properties are define in
     * com.netflix.client.config.CommonClientConfigKey.
     */
    private Map<String, String> properties;

    public String getUris() {
        return uris;
    }

    public void setUris(String uris) {
        this.uris = uris;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Long getTimeout() {
        return timeout;
    }

    public void setTimeout(Long timeout) {
        this.timeout = timeout;
    }

    public String getServicePath() {
        return servicePath;
    }

    public void setServicePath(String servicePath) {
        this.servicePath = servicePath;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public Map<String, String> getProperties() {
        return properties;
    }

    public void setProperties(Map<String, String> properties) {
        this.properties = properties;
    }
}
