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

com.datastax.oss.driver.api.core.config.DriverConfigLoader Maven / Gradle / Ivy

/*
 * Copyright DataStax, Inc.
 *
 * Licensed 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 com.datastax.oss.driver.api.core.config;

import com.datastax.oss.driver.api.core.context.DriverContext;
import com.datastax.oss.driver.api.core.session.SessionBuilder;
import com.datastax.oss.driver.internal.core.config.composite.CompositeDriverConfigLoader;
import com.datastax.oss.driver.internal.core.config.map.MapBasedDriverConfigLoader;
import com.datastax.oss.driver.internal.core.config.typesafe.DefaultDriverConfigLoader;
import com.datastax.oss.driver.internal.core.config.typesafe.DefaultProgrammaticDriverConfigLoaderBuilder;
import edu.umd.cs.findbugs.annotations.NonNull;
import java.io.File;
import java.net.URL;
import java.nio.file.Path;
import java.util.concurrent.CompletionStage;

/**
 * Manages the initialization, and optionally the periodic reloading, of the driver configuration.
 *
 * @see SessionBuilder#withConfigLoader(DriverConfigLoader)
 */
public interface DriverConfigLoader extends AutoCloseable {

  /**
   * Builds an instance using the driver's default implementation (based on Typesafe config) except
   * that application-specific classpath resources will be located using the provided {@link
   * ClassLoader} instead of {@linkplain Thread#getContextClassLoader() the current thread's context
   * class loader}.
   *
   * 

The returned loader will honor the reload interval defined by the option {@code * basic.config-reload-interval}. */ @NonNull static DriverConfigLoader fromDefaults(@NonNull ClassLoader appClassLoader) { return new DefaultDriverConfigLoader(appClassLoader); } /** * Builds an instance using the driver's default implementation (based on Typesafe config), except * that application-specific options are loaded from a classpath resource with a custom name. * *

The class loader used to locate application-specific classpath resources is {@linkplain * Thread#getContextClassLoader() the current thread's context class loader}. This might not be * suitable for OSGi deployments, which should use {@link #fromClasspath(String, ClassLoader)} * instead. * *

More precisely, configuration properties are loaded and merged from the following * (first-listed are higher priority): * *

    *
  • system properties *
  • {@code .conf} (all resources on classpath with this name) *
  • {@code .json} (all resources on classpath with this name) *
  • {@code .properties} (all resources on classpath with this name) *
  • {@code reference.conf} (all resources on classpath with this name). In particular, this * will load the {@code reference.conf} included in the core driver JAR, that defines * default options for all mandatory options. *
* * The resulting configuration is expected to contain a {@code datastax-java-driver} section. * *

The returned loader will honor the reload interval defined by the option {@code * basic.config-reload-interval}. */ @NonNull static DriverConfigLoader fromClasspath(@NonNull String resourceBaseName) { return fromClasspath(resourceBaseName, Thread.currentThread().getContextClassLoader()); } /** * Just like {@link #fromClasspath(java.lang.String)} except that application-specific classpath * resources will be located using the provided {@link ClassLoader} instead of {@linkplain * Thread#getContextClassLoader() the current thread's context class loader}. */ @NonNull static DriverConfigLoader fromClasspath( @NonNull String resourceBaseName, @NonNull ClassLoader appClassLoader) { return DefaultDriverConfigLoader.fromClasspath(resourceBaseName, appClassLoader); } /** * Builds an instance using the driver's default implementation (based on Typesafe config), except * that application-specific options are loaded from the given path. * *

More precisely, configuration properties are loaded and merged from the following * (first-listed are higher priority): * *

    *
  • system properties *
  • the contents of {@code file} *
  • {@code reference.conf} (all resources on classpath with this name). In particular, this * will load the {@code reference.conf} included in the core driver JAR, that defines * default options for all mandatory options. *
* * The resulting configuration is expected to contain a {@code datastax-java-driver} section. * *

The returned loader will honor the reload interval defined by the option {@code * basic.config-reload-interval}. */ @NonNull static DriverConfigLoader fromPath(@NonNull Path file) { return fromFile(file.toFile()); } /** * Builds an instance using the driver's default implementation (based on Typesafe config), except * that application-specific options are loaded from the given file. * *

More precisely, configuration properties are loaded and merged from the following * (first-listed are higher priority): * *

    *
  • system properties *
  • the contents of {@code file} *
  • {@code reference.conf} (all resources on classpath with this name). In particular, this * will load the {@code reference.conf} included in the core driver JAR, that defines * default options for all mandatory options. *
* * The resulting configuration is expected to contain a {@code datastax-java-driver} section. * *

The returned loader will honor the reload interval defined by the option {@code * basic.config-reload-interval}. */ @NonNull static DriverConfigLoader fromFile(@NonNull File file) { return DefaultDriverConfigLoader.fromFile(file); } /** * Builds an instance using the driver's default implementation (based on Typesafe config), except * that application-specific options are loaded from the given URL. * *

More precisely, configuration properties are loaded and merged from the following * (first-listed are higher priority): * *

    *
  • system properties *
  • the contents of {@code url} *
  • {@code reference.conf} (all resources on classpath with this name). In particular, this * will load the {@code reference.conf} included in the core driver JAR, that defines * default options for all mandatory options. *
* * The resulting configuration is expected to contain a {@code datastax-java-driver} section. * *

The returned loader will honor the reload interval defined by the option {@code * basic.config-reload-interval}. */ @NonNull static DriverConfigLoader fromUrl(@NonNull URL url) { return DefaultDriverConfigLoader.fromUrl(url); } /** * Builds an instance using the driver's default implementation (based on Typesafe config), except * that application-specific options are parsed from the given string. * *

The string must be in HOCON format and contain a {@code datastax-java-driver} section. * Options must be separated by line breaks: * *

   * DriverConfigLoader.fromString(
   *         "datastax-java-driver.basic { session-name = my-app\nrequest.timeout = 1 millisecond }")
   * 
* *

More precisely, configuration properties are loaded and merged from the following * (first-listed are higher priority): * *

    *
  • system properties *
  • the config in {@code contents} *
  • {@code reference.conf} (all resources on classpath with this name). In particular, this * will load the {@code reference.conf} included in the core driver JAR, that defines * default options for all mandatory options. *
* *

This loader does not support runtime reloading. */ @NonNull static DriverConfigLoader fromString(@NonNull String contents) { return DefaultDriverConfigLoader.fromString(contents); } /** * Starts a builder that allows configuration options to be overridden programmatically. * *

Note that {@link #fromMap(OptionsMap)} provides an alternative approach for programmatic * configuration, that might be more convenient if you wish to completely bypass Typesafe config. * *

For example: * *

{@code
   * DriverConfigLoader loader =
   *     DriverConfigLoader.programmaticBuilder()
   *         .withDuration(DefaultDriverOption.REQUEST_TIMEOUT, Duration.ofSeconds(5))
   *         .startProfile("slow")
   *         .withDuration(DefaultDriverOption.REQUEST_TIMEOUT, Duration.ofSeconds(30))
   *         .endProfile()
   *         .build();
   * }
* * produces the same overrides as: * *
   * datastax-java-driver {
   *   basic.request.timeout = 5 seconds
   *   profiles {
   *     slow {
   *       basic.request.timeout = 30 seconds
   *     }
   *   }
   * }
   * 
* * The resulting loader still uses the driver's default implementation (based on Typesafe config), * except that the programmatic configuration takes precedence. More precisely, configuration * properties are loaded and merged from the following (first-listed are higher priority): * *
    *
  • system properties *
  • properties that were provided programmatically *
  • {@code application.conf} (all resources on classpath with this name) *
  • {@code application.json} (all resources on classpath with this name) *
  • {@code application.properties} (all resources on classpath with this name) *
  • {@code reference.conf} (all resources on classpath with this name). In particular, this * will load the {@code reference.conf} included in the core driver JAR, that defines * default options for all mandatory options. *
* * Note that {@code application.*} is entirely optional, you may choose to only rely on the * driver's built-in {@code reference.conf} and programmatic overrides. * *

The class loader used to locate application-specific classpath resources is {@linkplain * Thread#getContextClassLoader() the current thread's context class loader}. This might not be * suitable for OSGi deployments, which should use {@link #programmaticBuilder(ClassLoader)} * instead. * *

The resulting configuration is expected to contain a {@code datastax-java-driver} section. * *

The loader will honor the reload interval defined by the option {@code * basic.config-reload-interval}. * *

Note that the returned builder is not thread-safe. * * @see #fromMap(OptionsMap) */ @NonNull static ProgrammaticDriverConfigLoaderBuilder programmaticBuilder() { return new DefaultProgrammaticDriverConfigLoaderBuilder(); } /** * Just like {@link #programmaticBuilder()} except that application-specific classpath resources * will be located using the provided {@link ClassLoader} instead of {@linkplain * Thread#getContextClassLoader() the current thread's context class loader}. */ @NonNull static ProgrammaticDriverConfigLoaderBuilder programmaticBuilder( @NonNull ClassLoader appClassLoader) { return new DefaultProgrammaticDriverConfigLoaderBuilder(appClassLoader); } /** * Builds an instance backed by an {@link OptionsMap}, which holds all options in memory. * *

This is the simplest implementation. It is intended for clients who wish to completely * bypass Typesafe config, and instead manage the configuration programmatically. A typical * example is a third-party tool that already has its own configuration file, and doesn't want to * introduce a separate mechanism for driver options. * *

With this loader, the driver's built-in {@code reference.conf} file is ignored, the provided * {@link OptionsMap} must explicitly provide all mandatory options. Note however that {@link * OptionsMap#driverDefaults()} allows you to initialize an instance with the same default values * as {@code reference.conf}. * *

   * // This creates a configuration equivalent to the built-in reference.conf:
   * OptionsMap map = OptionsMap.driverDefaults();
   *
   * // Customize an option:
   * map.put(TypedDriverOption.REQUEST_TIMEOUT, Duration.ofSeconds(5));
   *
   * DriverConfigLoader loader = DriverConfigLoader.fromMap(map);
   * CqlSession session = CqlSession.builder()
   *     .withConfigLoader(loader)
   *     .build();
   * 
* *

If the {@link OptionsMap} is modified at runtime, this will be reflected immediately in the * configuration, you don't need to call {@link #reload()}. Note however that, depending on the * option, the driver might not react to a configuration change immediately, or ever (this is * documented in {@code reference.conf}). * * @since 4.6.0 */ @NonNull static DriverConfigLoader fromMap(@NonNull OptionsMap source) { return new MapBasedDriverConfigLoader(source, source.asRawMap()); } /** * Composes two existing config loaders to form a new one. * *

When the driver reads an option, the "primary" config will be queried first. If the option * is missing, then it will be looked up in the "fallback" config. * *

All execution profiles will be surfaced in the new config. If a profile is defined both in * the primary and the fallback config, its options will be merged using the same precedence rules * as described above. * *

The new config is reloadable if at least one of the input configs is. If you invoke {@link * DriverConfigLoader#reload()} on the new loader, it will reload whatever is reloadable, or fail * if nothing is. If the input loaders have periodic reloading built-in, each one will reload at * its own pace, and the changes will be reflected in the new config. */ @NonNull static DriverConfigLoader compose( @NonNull DriverConfigLoader primaryConfigLoader, @NonNull DriverConfigLoader fallbackConfigLoader) { return new CompositeDriverConfigLoader(primaryConfigLoader, fallbackConfigLoader); } /** * Loads the first configuration that will be used to initialize the driver. * *

If this loader {@linkplain #supportsReloading() supports reloading}, this object should be * mutable and reflect later changes when the configuration gets reloaded. */ @NonNull DriverConfig getInitialConfig(); /** * Called when the driver initializes. For loaders that periodically check for configuration * updates, this is a good time to grab an internal executor and schedule a recurring task. */ void onDriverInit(@NonNull DriverContext context); /** * Triggers an immediate reload attempt and returns a stage that completes once the attempt is * finished, with a boolean indicating whether the configuration changed as a result of this * reload. * *

If so, it's also guaranteed that internal driver components have been notified by that time; * note however that some react to the notification asynchronously, so they may not have * completely applied all resulting changes yet. * *

If this loader does not support programmatic reloading — which you can check by * calling {@link #supportsReloading()} before this method — the returned stage should fail * immediately with an {@link UnsupportedOperationException}. The default implementation of this * interface does support programmatic reloading however, and never returns a failed stage. */ @NonNull CompletionStage reload(); /** * Whether this implementation supports programmatic reloading with the {@link #reload()} method. * *

The default implementation of this interface does support programmatic reloading and always * returns true. */ boolean supportsReloading(); /** * Called when the session closes. This is a good time to release any external resource, for * example cancel a scheduled reloading task. */ @Override void close(); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy