All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.influxdb.client.InfluxDBClientOptions Maven / Gradle / Ivy

/*
 * The MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.influxdb.client;

import java.io.IOException;
import java.io.InputStream;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.Collections;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe;

import com.influxdb.LogLevel;
import com.influxdb.client.domain.WriteConsistency;
import com.influxdb.client.domain.WritePrecision;
import com.influxdb.client.write.PointSettings;
import com.influxdb.client.write.WriteParameters;
import com.influxdb.exceptions.InfluxException;
import com.influxdb.utils.Arguments;

import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Protocol;

/**
 * InfluxDBClientOptions are used to configure theInfluxDB 2.x connections.
 *
 * @author Jakub Bednar (bednar@github) (05/09/2018 10:22)
 */
public final class InfluxDBClientOptions {

    private static final Pattern TAGS_PROPERTY = Pattern.compile("(influx2\\.tags\\.)(.+)");
    private static final Pattern DURATION_PATTERN = Pattern.compile("^(\\d+)([a-zA-Z]{0,2})$");

    private final String url;
    private final String clientType;
    private final OkHttpClient.Builder okHttpClient;
    private final LogLevel logLevel;

    private final AuthScheme authScheme;
    private final char[] token;
    private final String username;
    private final char[] password;

    private final String org;
    private final String bucket;
    private final WritePrecision precision;
    private final WriteConsistency consistency;
    private final PointSettings pointSettings;

    private InfluxDBClientOptions(@Nonnull final InfluxDBClientOptions.Builder builder) {

        Arguments.checkNotNull(builder, "InfluxDBClientOptions.Builder");

        this.url = builder.url;
        this.clientType = builder.clientType;
        this.okHttpClient = builder.okHttpClient;
        this.logLevel = builder.logLevel;
        this.authScheme = builder.authScheme;
        this.token = builder.token;
        this.username = builder.username;
        this.password = builder.password;

        this.org = builder.org;
        this.bucket = builder.bucket;
        this.precision = builder.precision != null ? builder.precision : WriteParameters.DEFAULT_WRITE_PRECISION;
        this.consistency = builder.consistency;
        this.pointSettings = builder.pointSettings;
    }

    /**
     * The scheme uses to Authentication.
     */
    public enum AuthScheme {

        /**
         * Basic auth.
         */
        SESSION,

        /**
         * Authentication token.
         */
        TOKEN
    }

    /**
     * @return the url to connect to InfluxDB
     * @see InfluxDBClientOptions.Builder#url(String)
     */
    @Nonnull
    public String getUrl() {
        return url;
    }

    /**
     * If the {@code clientType} is not specified the `java`, `kotlin` or `scala` is used depends on the type of client.
     *
     * @return the client type to report as a part of User-Agent to remote server
     * @see InfluxDBClientOptions.Builder#clientType(String)
     */
    @Nullable
    public String getClientType() {
        return clientType;
    }

    /**
     * @return HTTP client to use for communication with InfluxDB
     * @see InfluxDBClientOptions.Builder#okHttpClient(OkHttpClient.Builder)
     */
    @Nonnull
    public OkHttpClient.Builder getOkHttpClient() {
        return okHttpClient;
    }

    /**
     * @return The log level for the request and response information.
     * @see InfluxDBClientOptions.Builder#logLevel(LogLevel)
     */
    @Nonnull
    public LogLevel getLogLevel() {
        return logLevel;
    }

    /**
     * @return the authorization scheme
     * @see InfluxDBClientOptions.Builder#authenticateToken(char[])
     * @see InfluxDBClientOptions.Builder#authenticate(String, char[]) (char[])
     */
    @Nullable
    public AuthScheme getAuthScheme() {
        return authScheme;
    }

    /**
     * @return the token to use for the authorization
     * @see InfluxDBClientOptions.Builder#authenticateToken(char[])
     */
    @Nullable
    public char[] getToken() {
        return token;
    }

    /**
     * @return the username to use in the basic auth
     * @see InfluxDBClientOptions.Builder#authenticate(String, char[])
     */
    @Nullable
    public String getUsername() {
        return username;
    }

    /**
     * @return the password to use in the basic auth
     * @see InfluxDBClientOptions.Builder#authenticate(String, char[])
     */
    @Nullable
    public char[] getPassword() {
        return password;
    }

    /**
     * @return the default destination organization for writes and queries
     * @see InfluxDBClientOptions.Builder#org(String)
     */
    @Nullable
    public String getOrg() {
        return org;
    }

    /**
     * @return default destination bucket for writes
     * @see InfluxDBClientOptions.Builder#bucket(String)
     */
    @Nullable
    public String getBucket() {
        return bucket;
    }

    /**
     * @return default precision for unix timestamps in the line protocol
     * @see InfluxDBClientOptions.Builder#precision(WritePrecision)
     */
    @Nonnull
    public WritePrecision getPrecision() {
        return precision;
    }


    /**
     * The write consistency for the point.
     * 

* InfluxDB assumes that the write consistency is {@link WriteConsistency#ONE} if you do not specify consistency. * See the InfluxDB Enterprise documentation for * detailed descriptions of each consistency option. * * Available with InfluxDB Enterprise clusters only! * * @return the write consistency for the point. * @see InfluxDBClientOptions.Builder#consistency(WriteConsistency) */ @Nullable public WriteConsistency getConsistency() { return consistency; } /** * Default tags that will be use for writes by Point and POJO. * * @return default tags * @see InfluxDBClientOptions.Builder#addDefaultTag(String, String) */ @Nonnull public PointSettings getPointSettings() { return pointSettings; } /** * Creates a builder instance. * * @return a builder */ @Nonnull public static InfluxDBClientOptions.Builder builder() { return new InfluxDBClientOptions.Builder(); } /** * A builder for {@code InfluxDBClientOptions}. */ @NotThreadSafe public static class Builder { private String url; private String clientType; private OkHttpClient.Builder okHttpClient; private LogLevel logLevel; private AuthScheme authScheme; private char[] token; private String username; private char[] password; private String org; private String bucket; private WritePrecision precision; private WriteConsistency consistency; private final PointSettings pointSettings = new PointSettings(); /** * Set the url to connect to InfluxDB. *

* The url could be a connection string with various configurations. For more info * see: {@link #connectionString(String)}. *

* * @param url the url to connect to InfluxDB (required). Example: http://localhost:8086?readTimeout=5000 * @return {@code this} */ @Nonnull public InfluxDBClientOptions.Builder url(@Nonnull final String url) { Arguments.checkNonEmpty(url, "url"); connectionString(url); return this; } /** * Set the {@code clientType} to customize the User-Agent HTTP header. *

* If the {@code clientType} is set to "awesome-service" the User-Agent header will be: * influxdb-client-awesome-service/6.2.0. * * @param clientType the client type to report as a part of User-Agent to remote server * @return {@code this} */ @Nonnull public InfluxDBClientOptions.Builder clientType(@Nonnull final String clientType) { Arguments.checkNonEmpty(clientType, "clientType"); this.clientType = clientType; return this; } /** * Set the HTTP client to use for communication with InfluxDB. * * @param okHttpClient the HTTP client to use. * @return {@code this} */ @Nonnull public InfluxDBClientOptions.Builder okHttpClient(@Nonnull final OkHttpClient.Builder okHttpClient) { Arguments.checkNotNull(okHttpClient, "OkHttpClient.Builder"); this.okHttpClient = okHttpClient; return this; } /** * Set the log level for the request and response information. * * @param logLevel The log level for the request and response information. * @return {@code this} */ @Nonnull public InfluxDBClientOptions.Builder logLevel(@Nonnull final LogLevel logLevel) { Arguments.checkNotNull(logLevel, "logLevel"); this.logLevel = logLevel; return this; } /** * Setup authorization by {@link AuthScheme#SESSION}. * *

* The username/password auth is based on * HTTP "Basic" authentication. The authorization expires when the * time-to-live (TTL) (default 60 minutes) is reached * and client produces {@link com.influxdb.exceptions.UnauthorizedException}. *

* * @param username the username to use in the basic auth * @param password the password to use in the basic auth * @return {@code this} */ @Nonnull public InfluxDBClientOptions.Builder authenticate(@Nonnull final String username, @Nonnull final char[] password) { Arguments.checkNonEmpty(username, "username"); Arguments.checkNotNull(password, "password"); this.authScheme = AuthScheme.SESSION; this.username = username; this.password = password; return this; } /** * Setup authorization by {@link AuthScheme#TOKEN}. * * @param token the token to use for the authorization * @return {@code this} */ @Nonnull public InfluxDBClientOptions.Builder authenticateToken(final char[] token) { Arguments.checkNotNull(token, "token"); this.authScheme = AuthScheme.TOKEN; this.token = token; return this; } /** * Specify the default destination organization for writes and queries. * * @param org the default destination organization for writes and queries * @return {@code this} */ @Nonnull public InfluxDBClientOptions.Builder org(@Nullable final String org) { this.org = org; return this; } /** * Specify the default destination bucket for writes. * * @param bucket default destination bucket for writes * @return {@code this} */ @Nonnull public InfluxDBClientOptions.Builder bucket(@Nullable final String bucket) { this.bucket = bucket; return this; } /** * Specify the default precision for unix timestamps in the line protocol. * * @param precision default precision for unix timestamps in the line protocol * @return {@code this} */ @Nonnull public InfluxDBClientOptions.Builder precision(@Nullable final WritePrecision precision) { this.precision = precision; return this; } /** * Specify the write consistency for the point. *

* InfluxDB assumes that the write consistency is {@link WriteConsistency#ONE} * if you do not specify consistency. * See the InfluxDB Enterprise documentation for * detailed descriptions of each consistency option. * * Available with InfluxDB Enterprise clusters only! * * @param consistency The write consistency for the point. * @return {@code this} */ @Nonnull public InfluxDBClientOptions.Builder consistency(@Nullable final WriteConsistency consistency) { this.consistency = consistency; return this; } /** * Add default tag that will be use for writes by Point and POJO. *

* The expressions can be: *

    *
  • "California Miner" - static value
  • *
  • "${version}" - system property
  • *
  • "${env.hostname}" - environment property
  • *
* * @param key the tag name * @param expression the tag value expression * @return this */ @Nonnull public InfluxDBClientOptions.Builder addDefaultTag(@Nonnull final String key, @Nullable final String expression) { Arguments.checkNotNull(key, "tagName"); pointSettings.addDefaultTag(key, expression); return this; } /** * Configure Builder via connection string. The allowed configuration: * *
    *
  • org - default destination organization for writes and queries
  • *
  • bucket - default destination bucket for writes
  • *
  • token - the token to use for the authorization
  • *
  • logLevel - rest client verbosity level
  • *
  • readTimeout - read timeout
  • *
  • writeTimeout - write timeout
  • *
  • connectTimeout - socket timeout
  • *
  • precision - default precision for unix timestamps in the line protocol
  • *
  • consistency - specify the write consistency for the point
  • *
  • clientType - to customize the User-Agent HTTP header
  • *
*

* Connection string example: *

         * http://localhost:8086?readTimeout=30000&token=my-token&bucket=my-bucket&org=my-org
         * 
* * @return {@code this} */ @Nonnull public InfluxDBClientOptions.Builder connectionString(@Nonnull final String connectionString) { Arguments.checkNonEmpty(connectionString, "url"); ParsedUrl parsedUrl = new ParsedUrl(connectionString); HttpUrl parse = parsedUrl.httpUrl; String org = parse.queryParameter("org"); String bucket = parse.queryParameter("bucket"); String token = parse.queryParameter("token"); String logLevel = parse.queryParameter("logLevel"); String readTimeout = parse.queryParameter("readTimeout"); String writeTimeout = parse.queryParameter("writeTimeout"); String connectTimeout = parse.queryParameter("connectTimeout"); String precision = parse.queryParameter("precision"); String consistency = parse.queryParameter("consistency"); String clientType = parse.queryParameter("clientType"); String url = parsedUrl.urlWithoutParams; return configure(url, org, bucket, token, logLevel, readTimeout, writeTimeout, connectTimeout, precision, consistency, clientType); } /** * Configure Builder via {@code influx2.properties}. * * @return {@code this} */ @Nonnull public InfluxDBClientOptions.Builder loadProperties() { try (InputStream inputStream = this.getClass().getResourceAsStream("/influx2.properties")) { Properties properties = new Properties(); properties.load(inputStream); String url = properties.getProperty("influx2.url"); String org = properties.getProperty("influx2.org"); String bucket = properties.getProperty("influx2.bucket"); String token = properties.getProperty("influx2.token"); String logLevel = properties.getProperty("influx2.logLevel"); String readTimeout = properties.getProperty("influx2.readTimeout"); String writeTimeout = properties.getProperty("influx2.writeTimeout"); String connectTimeout = properties.getProperty("influx2.connectTimeout"); String precision = properties.getProperty("influx2.precision"); String consistency = properties.getProperty("influx2.consistency"); String clientType = properties.getProperty("influx2.clientType"); // // Default tags // properties.stringPropertyNames().forEach(key -> { Matcher matcher = TAGS_PROPERTY.matcher(key); if (matcher.matches()) { String tagKey = matcher.group(2); addDefaultTag(tagKey, properties.getProperty(key).trim()); } }); return configure(url, org, bucket, token, logLevel, readTimeout, writeTimeout, connectTimeout, precision, consistency, clientType); } catch (IOException e) { throw new IllegalStateException(e); } } /** * Build an instance of InfluxDBClientOptions. * * @return {@link InfluxDBClientOptions} */ @Nonnull public InfluxDBClientOptions build() { if (url == null) { throw new IllegalStateException("The url to connect to InfluxDB has to be defined."); } if (okHttpClient == null) { okHttpClient = new OkHttpClient.Builder() .protocols(Collections.singletonList(Protocol.HTTP_1_1)); } if (logLevel == null) { logLevel = LogLevel.NONE; } return new InfluxDBClientOptions(this); } @Nonnull private InfluxDBClientOptions.Builder configure(@Nonnull final String url, @Nullable final String org, @Nullable final String bucket, @Nullable final String token, @Nullable final String logLevel, @Nullable final String readTimeout, @Nullable final String writeTimeout, @Nullable final String connectTimeout, @Nullable final String precision, @Nullable final String consistency, @Nullable final String clientType) { this.url = new ParsedUrl(url).urlWithoutParams; if (org != null) { org(org); } if (bucket != null) { bucket(bucket); } if (token != null) { authenticateToken(token.toCharArray()); } if (logLevel != null) { logLevel(Enum.valueOf(LogLevel.class, logLevel)); } if (precision != null) { precision(Enum.valueOf(WritePrecision.class, precision)); } if (consistency != null) { consistency(Enum.valueOf(WriteConsistency.class, consistency)); } if (okHttpClient == null) { okHttpClient = new OkHttpClient.Builder() .protocols(Collections.singletonList(Protocol.HTTP_1_1)); } if (readTimeout != null) { okHttpClient.readTimeout(toDuration(readTimeout)); } if (writeTimeout != null) { okHttpClient.writeTimeout(toDuration(writeTimeout)); } if (connectTimeout != null) { okHttpClient.connectTimeout(toDuration(connectTimeout)); } if (clientType != null) { clientType(clientType); } return this; } @Nonnull private Duration toDuration(@Nonnull final String value) { Matcher matcher = DURATION_PATTERN.matcher(value); if (!matcher.matches()) { throw new InfluxException("'" + value + "' is not a valid duration"); } String amount = matcher.group(1); String unit = matcher.group(2); ChronoUnit chronoUnit; switch (unit != null && !unit.isEmpty() ? unit.toLowerCase() : "ms") { case "ms": chronoUnit = ChronoUnit.MILLIS; break; case "s": chronoUnit = ChronoUnit.SECONDS; break; case "m": chronoUnit = ChronoUnit.MINUTES; break; default: throw new InfluxException("unknown unit for '" + value + "'"); } return Duration.of(Long.parseLong(amount), chronoUnit); } private static final class ParsedUrl { @Nonnull private final String urlWithoutParams; @Nonnull private final HttpUrl httpUrl; private ParsedUrl(@Nonnull final String connectionString) { HttpUrl parse = HttpUrl.parse(connectionString); if (parse == null) { throw new InfluxException("Unable to parse connection string " + connectionString); } this.httpUrl = parse; HttpUrl url = this.httpUrl.newBuilder().build(); //detect IPV6 String host = url.host().contains(":") ? "[" + url.host() + "]" : url.host(); String urlWithoutParams = url.scheme() + "://" + host + ":" + url.port() + url.encodedPath(); this.urlWithoutParams = urlWithoutParams.endsWith("/") ? urlWithoutParams : urlWithoutParams + "/"; } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy