# Vert.x Config

Vert.x Config provides a way to configure your Vert.x application.

It:

- offers multiple configuration syntaxes (json, properties, yaml (extension), hocon (extension)…​

- offers multiple configuration stores (files, directories, http, git (extension), redis (extension), system properties, environment properties)…​

- lets you define the processing order and overloading

- supports runtime reconfiguration

## Concepts

The library is structured around:

- a Config Retriever instantiated and used by the Vert.x application. It configures a set of configuration store

- Configuration store defines a location from where the configuration data is read and and a syntax (json by default)

The configuration is retrieved as a JSON Object.

## Using the Config Retriever

To use the Config Retriever, add the following dependency to the dependencies section of your build descriptor:

- Maven (in your `pom.xml`):

    <dependency>
      <groupId>io.vertx</groupId>
      <artifactId>vertx-config</artifactId>
      <version>3.5.3.CR1</version>
    </dependency>

- Gradle (in your `build.gradle` file):

    compile 'io.vertx:vertx-config:3.5.3.CR1'

Once done, you first need to instantiate the `ConfigRetriever`:

    require 'vertx-config/config_retriever'
    retriever = VertxConfig::ConfigRetriever.create(vertx)

By default the Config Retriever is configured with the following stores (in this order):

- The Vert.x verticle `config()`

- The system properties

- The environment variables

- A `conf/config.json` file. This path can be overridden using the `vertx-config-path` system property or `VERTX_CONFIG_PATH` environment variable.

You can configure your own stores:

    require 'vertx-config/config_retriever'
    httpStore = {
      'type' => "http",
      'config' => {
        'host' => "localhost",
        'port' => 8080,
        'path' => "/conf"
      }
    }

    fileStore = {
      'type' => "file",
      'config' => {
        'path' => "my-config.json"
      }
    }

    sysPropsStore = {
      'type' => "sys"
    }

    options = {
      'stores' => [
        httpStore,
        fileStore,
        sysPropsStore
      ]
    }

    retriever = VertxConfig::ConfigRetriever.create(vertx, options)

More details about the overloading rules and available stores are available below. Each store can be marked as `optional`. If a failure is caught while retrieving (or processing) the configuration from an optional store, the failure is logged but the processing does not fail. Instead an empty JSON object is returned (`{}`). To mark a store as optional, use the `optional` attribute:

    require 'vertx-config/config_retriever'
    fileStore = {
      'type' => "file",
      'optional' => true,
      'config' => {
        'path' => "my-config.json"
      }
    }
    sysPropsStore = {
      'type' => "sys"
    }

    options = {
      'stores' => [
        fileStore,
        sysPropsStore
      ]
    }

    retriever = VertxConfig::ConfigRetriever.create(vertx, options)

Once you have the instance of the Config Retriever, retrieve the configuration as follows:

    retriever.get_config() { |ar_err,ar|
      if (ar_err != nil)
        # Failed to retrieve the configuration
      else
        config = ar
      end
    }

## Overloading rules

The declaration order of the configuration store is important as it defines the overloading. For conflicting key, configuration stores arriving last overloads the value provided by the previous configuration stores. Let’s take an example. We have 2 configuration stores:

- `A` provides `{a:value, b:1}`

- `B` provides `{a:value2, c:2}`

Declared in this order (A, B), the resulting configuration would be: `{a:value2, b:1, c:2}`.

If you declare them in the reverse order (B, A), you would get: * `{a:value, b:1, c:2}`.

## Available configuration stores

The Config Retriever provides a set of configuration store and format. Some more are available as extension and you can implement your own.

### Structure of the configuration

Each declared data store must specify the `type`. It can also define the `format`. If not set JSON is used.

Some configurations tore requires additional configuration (such a path…​). This configuration is passed as a Json Object using `config`

### File

This configuration store just read the configuration from a file. It supports all supported formats.

    file = {
      'type' => "file",
      'format' => "properties",
      'config' => {
        'path' => "path-to-file.properties"
      }
    }

The `path` configuration is required.

### JSON

The JSON configuration store just serves the given JSON config as it is.

    json = {
      'type' => "json",
      'config' => {
        'key' => "value"
      }
    }

The only supported format for this configuration store is JSON.

### Environment Variables

This configuration store maps environment variables to a Json Object contributed to the global configuration.

    json = {
      'type' => "env"
    }

This configuration store does not support the `format` configuration. By default, the retrieved value are transformed into JSON compatible structures (number, string, boolean, json object and json array). To avoid this conversion, configure the `raw-data` attribute:

    json = {
      'type' => "env",
      'config' => {
        'raw-data' => true
      }
    }

You can configure the `raw-data` attribute (`false` by default). If `raw-data` is `true` no attempts to convert values will be made and you’ll be able to get raw values using `config.getString(key)`.

If you want to select the set of keys to import, use the `keys` attributes. It filters out all non selected keys. Keys must be listed individually:

    json = {
      'type' => "env",
      'config' => {
        'keys' => [
          "SERVICE1_HOST",
          "SERVICE2_HOST"
        ]
      }
    }

### System Properties

This configuration store maps system properties to a Json Object contributed to the global configuration.

    json = {
      'type' => "sys",
      'config' => {
        'cache' => "false"
      }
    }

This configuration store does not support the `format` configuration.

You can configure the `cache` attribute (`true` by default) let you decide whether or not it caches the system properties on the first access and does not reload them.

### HTTP

This configuration stores retrieves the configuration from a HTTP location. It can use any supported format.

    http = {
      'type' => "http",
      'config' => {
        'host' => "localhost",
        'port' => 8080,
        'path' => "/A"
      }
    }

It creates a Vert.x HTTP Client with the store configuration (see next snippet). To ease the configuration, you can also configure the `host`, `port` and `path` with the `host`, `port` and `path` properties.

    http = {
      'type' => "http",
      'config' => {
        'defaultHost' => "localhost",
        'defaultPort' => 8080,
        'ssl' => true,
        'path' => "/A"
      }
    }

### Event Bus

This event bus configuration stores receives the configuration from the event bus. This stores let you distribute your configuration among your local and distributed components.

    eb = {
      'type' => "event-bus",
      'config' => {
        'address' => "address-getting-the-conf"
      }
    }

This configuration store supports any type of format.

### Directory

This configuration store is similar to the `file` configuration store, but instead of reading a single file, read several files from a directory.

This configuration store configuration requires:

- a `path` - the root directory in which files are located

- at least one `fileset` - an object to select the files

Each `fileset` contains: * a `pattern` : a Ant style pattern to select files. The pattern is applied on the relative path of the files location in the directory. * an optional `format` indicating the format of the files (each fileset can use a different format, BUT files in a fileset must share the same format).

    dir = {
      'type' => "directory",
      'config' => {
        'path' => "config",
        'filesets' => [
          {
            'pattern' => "dir/*json"
          },
          {
            'pattern' => "dir/*.properties",
            'format' => "properties"
          }
        ]
      }
    }

## Listening for configuration changes

The Configuration Retriever periodically retrieve the configuration and if the outcome is different from the current one, your application can be reconfigured. By default the configuration is reloaded every 5 seconds.

    require 'vertx/vertx'
    require 'vertx-config/config_retriever'
    options = {
      'scanPeriod' => 2000,
      'stores' => [
        store1,
        store2
      ]
    }

    retriever = VertxConfig::ConfigRetriever.create(Vertx::Vertx.vertx(), options)
    retriever.get_config() { |json_err,json|
      # Initial retrieval of the configuration
    }

    retriever.listen() { |change|
      # Previous configuration
      previous = change['previousConfiguration']
      # New configuration
      conf = change['newConfiguration']
    }

## Retrieving the last retrieved configuration

You can retrieved the last retrieved configuration without "waiting" to be retrieved using:

    last = retriever.get_cached_config()

## Reading configuration as a stream

The `ConfigRetriever` provide a way to access the stream of configuration. It’s a `ReadStream` of `JsonObject`. By registering the right set of handlers you are notified:

- when a new configuration is retrieved

- when an error occur while retrieving a configuration

- when the configuration retriever is closed (the `endHandler` is called).

    require 'vertx/vertx'
    require 'vertx-config/config_retriever'
    options = {
      'scanPeriod' => 2000,
      'stores' => [
        store1,
        store2
      ]
    }

    retriever = VertxConfig::ConfigRetriever.create(Vertx::Vertx.vertx(), options)
    retriever.config_stream().end_handler() { |v|
      # retriever closed
    }.exception_handler() { |t|
      # an error has been caught while retrieving the configuration
    }.handler() { |conf|
      # the configuration
    }

## Retrieving the configuration as a Future

The `ConfigRetriever` provide a way to retrieve the configuration as a `Future`:

    require 'vertx-config/config_retriever'
    future = VertxConfig::ConfigRetriever.get_config_as_future(retriever)
    future.set_handler() { |ar_err,ar|
      if (ar_err != nil)
        # Failed to retrieve the configuration
      else
        config = ar
      end
    }

## Extending the Config Retriever

You can extend the configuration by implementing:

- the `ConfigProcessor` SPI to add support for a format

- the `ConfigStoreFactory` SPI to add support for configuration store (place from where the configuration data is retrieved)

## Additional formats

In addition of the out of the box format supported by this library, Vert.x Config provides additional formats you can use in your application.

### Hocon Configuration Format

The Hocon Configuration Format extends the Vert.x Configuration Retriever and provides the support for the HOCON(https://github.com/typesafehub/config/blob/master/HOCON.md) format.

It supports includes, json, properties, macros…​

#### Using the Hocon Configuration Format

To use the Hocon Configuration Format, add the following dependency to the dependencies section of your build descriptor:

- Maven (in your `pom.xml`):

    <dependency>
      <groupId>io.vertx</groupId>
      <artifactId>vertx-config-hocon</artifactId>
      <version>3.5.3.CR1</version>
    </dependency>
    <dependency>
      <groupId>io.vertx</groupId>
      <artifactId>vertx-config</artifactId>
      <version>3.5.3.CR1</version>
    </dependency>

- Gradle (in your `build.gradle` file):

    compile 'io.vertx:vertx-config:3.5.3.CR1'
    compile 'io.vertx:vertx-config-hocon:3.5.3.CR1'

#### Configuring the store to use HOCON

Once added to your classpath or dependencies, you need to configure the `ConfigRetriever` to use this format:

    require 'vertx-config/config_retriever'
    store = {
      'type' => "file",
      'format' => "hocon",
      'config' => {
        'path' => "my-config.conf"
      }
    }

    retriever = VertxConfig::ConfigRetriever.create(vertx, {
      'stores' => [
        store
      ]
    })

You just need to set `format` to `hocon`.

### Yaml Configuration Format

The Yaml Configuration Format extends the Vert.x Configuration Retriever and provides the support for the Yaml Configuration Format format.

#### Using the Yaml Configuration Format

To use the Yaml Configuration Format, add the following dependency to the dependencies section of your build descriptor:

- Maven (in your `pom.xml`):

    <dependency>
      <groupId>io.vertx</groupId>
      <artifactId>vertx-config-yaml</artifactId>
      <version>3.5.3.CR1</version>
    </dependency>
    <dependency>
      <groupId>io.vertx</groupId>
      <artifactId>vertx-config</artifactId>
      <version>3.5.3.CR1</version>
    </dependency>

- Gradle (in your `build.gradle` file):

    compile 'io.vertx:vertx-config:3.5.3.CR1'
    compile 'io.vertx:vertx-config-yaml:3.5.3.CR1'

#### Configuring the store to use YAML

Once added to your classpath or dependencies, you need to configure the `ConfigRetriever` to use this format:

    require 'vertx-config/config_retriever'
    store = {
      'type' => "file",
      'format' => "yaml",
      'config' => {
        'path' => "my-config.yaml"
      }
    }

    retriever = VertxConfig::ConfigRetriever.create(vertx, {
      'stores' => [
        store
      ]
    })

You just need to set `format` to `yaml`.

## Additional stores

In addition of the out of the box stores supported by this library, Vert.x Config provides additional stores you can use in your application.

### Git Configuration Store

The Git Configuration Store is an extension to the Vert.x Configuration Retriever to retrieve configuration from a Git repository.

#### Using the Git Configuration Store

To use the Git Configuration, add the following dependency to the dependencies section of your build descriptor:

- Maven (in your `pom.xml`):

    <dependency>
      <groupId>io.vertx</groupId>
      <artifactId>vertx-config-git</artifactId>
      <version>3.5.3.CR1</version>
    </dependency>
    <dependency>
      <groupId>io.vertx</groupId>
      <artifactId>vertx-config</artifactId>
      <version>3.5.3.CR1</version>
    </dependency>

- Gradle (in your `build.gradle` file):

    compile 'io.vertx:vertx-config:3.5.3.CR1'
    compile 'io.vertx:vertx-config-git:3.5.3.CR1'

#### Configuring the store

Once added to your classpath or dependencies, you need to configure the `ConfigRetriever` to use this store:

    require 'vertx-config/config_retriever'

    git = {
      'type' => "git",
      'config' => {
        'url' => "https://github.com/cescoffier/vertx-config-test.git",
        'path' => "local",
        'filesets' => [
          {
            'pattern' => "*.json"
          }
        ]
      }
    }

    retriever = VertxConfig::ConfigRetriever.create(vertx, {
      'stores' => [
        git
      ]
    })

The configuration requires:

- the `url` of the repository

- the `path` where the repository is cloned (local directory)

- at least `fileset` indicating the set of files to read (same behavior as the directory configuration store).

You can also configure the `branch` (`master` by default) to use and the name of the `remote` repository (`origin` by default).

#### How does it works

If the local `path` does not exist, the configuration store clones the repository into this directory. Then it reads the file matching the different file sets.

It the local `path` exist, it tried to update it (it switches branch if needed)). If the update failed the configuration retrieval fails.

Periodically, the repositories is updated to check if the configuration has been updated.

### Kubernetes ConfigMap Store

The Kubernetes ConfigMap Store extends the Vert.x Configuration Retriever and provides support Kubernetes Config Map and Secrets.

So, configuration is retrieved by reading the config map or the secrets.

#### Using the Kubernetes ConfigMap Store

To use the Kubernetes ConfigMap Store, add the following dependency to the dependencies section of your build descriptor:

- Maven (in your `pom.xml`):

    <dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-config-kubernetes-configmap</artifactId>
    <version>3.5.3.CR1</version>
    </dependency>
    <dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-config</artifactId>
    <version>3.5.3.CR1</version>
    </dependency>

- Gradle (in your `build.gradle` file):

    compile 'io.vertx:vertx-config:3.5.3.CR1'
    compile 'io.vertx:vertx-config-kubernetes-configmap:3.5.3.CR1'

#### Configuring the store

Once added to your classpath or dependencies, you need to configure the `ConfigRetriever` to use this store:

    require 'vertx-config/config_retriever'
    store = {
      'type' => "configmap",
      'config' => {
        'namespace' => "my-project-namespace",
        'name' => "configmap-name"
      }
    }

    retriever = VertxConfig::ConfigRetriever.create(vertx, {
      'stores' => [
        store
      ]
    })

You need to configure the store to find the right configmap. this is done with:

- `namespace` - the project namespace, `default` by default. If the `KUBERNETES_NAMESPACE` ENV variable is set, it uses this value.

- `name` - the name of the config map

- `optional` - whether or not the config map is optional (`true` by default)

If the config map is composed by several element, you can use the `key` parameter to tell which `key` is read

The application must have the permissions to read the config map.

To read data from a secret, just configure the `secret` property to `true`:

    require 'vertx-config/config_retriever'
    store = {
      'type' => "configmap",
      'config' => {
        'namespace' => "my-project-namespace",
        'name' => "my-secret",
        'secret' => true
      }
    }

    retriever = VertxConfig::ConfigRetriever.create(vertx, {
      'stores' => [
        store
      ]
    })

If the config map is not available, an empty JSON object is passed as configuration chunk. To disable this behavior and explicitly fail, you can set the `optional` configuration to `false`.

### Redis Configuration Store

The Redis Configuration Store extends the Vert.x Configuration Retriever and provides the way to retrieve configuration from a Redis server.

#### Using the Redis Configuration Store

To use the Redis Configuration Store, add the following dependency to the dependencies section of your build descriptor:

- Maven (in your `pom.xml`):

    <dependency>
      <groupId>io.vertx</groupId>
      <artifactId>vertx-config-redis</artifactId>
      <version>3.5.3.CR1</version>
    </dependency>
    <dependency>
      <groupId>io.vertx</groupId>
      <artifactId>vertx-config</artifactId>
      <version>3.5.3.CR1</version>
    </dependency>

- Gradle (in your `build.gradle` file):

    compile 'io.vertx:vertx-config:3.5.3.CR1'
    compile 'io.vertx:vertx-config-redis:3.5.3.CR1'

#### Configuring the store

Once added to your classpath or dependencies, you need to configure the `ConfigRetriever` to use this store:

    require 'vertx-config/config_retriever'
    store = {
      'type' => "redis",
      'config' => {
        'host' => "localhost",
        'port' => 6379,
        'key' => "my-configuration"
      }
    }

    retriever = VertxConfig::ConfigRetriever.create(vertx, {
      'stores' => [
        store
      ]
    })

The store configuration is used to create an instance of `RedisClient`. check the documentation of the Vert.x Redis Client for further details.

In addition, you can set the `key` instructing the store in which field the configuration is stored. `configuration` is used by default.

The created Redis client retrieves the configuration using the `HGETALL` configuration.

### Zookeeper Configuration Store

The Zookeeper Configuration Store extends the Vert.x Configuration Retriever and provides the way to retrieve configuration from a Zookeeper server.

It uses Apache Curator as client.

#### Using the Zookeeper Configuration Store

To use the Redis Configuration Store, add the following dependency to the dependencies section of your build descriptor:

- Maven (in your `pom.xml`):

    <dependency>
      <groupId>io.vertx</groupId>
      <artifactId>vertx-config-zookeeper</artifactId>
      <version>3.5.3.CR1</version>
    </dependency>
    <dependency>
      <groupId>io.vertx</groupId>
      <artifactId>vertx-config</artifactId>
      <version>3.5.3.CR1</version>
    </dependency>

- Gradle (in your `build.gradle` file):

    compile 'io.vertx:vertx-config:3.5.3.CR1'
    compile 'io.vertx:vertx-config-zookeeper:3.5.3.CR1'

#### Configuring the store

Once added to your classpath or dependencies, you need to configure the `ConfigRetriever` to use this store:

    require 'vertx-config/config_retriever'
    store = {
      'type' => "zookeeper",
      'config' => {
        'connection' => "localhost:2181",
        'path' => "/path/to/my/conf"
      }
    }

    retriever = VertxConfig::ConfigRetriever.create(vertx, {
      'stores' => [
        store
      ]
    })

The store configuration is used to configure the Apache Curator client and the path of the Zookeeper node containing the configuration. Notice that the format of the configuration can be JSON, or any supported format.

The configuration requires the `configuration` attribute indicating the connection string of the Zookeeper server, and the `path` attribute indicating the path of the node containing the configuration.

In addition you can configure:

- `maxRetries`: the number of connection attempt, 3 by default

- `baseSleepTimeBetweenRetries`: the amount of milliseconds to wait between retries (exponential backoff strategy). 1000 ms by default.

### Consul Configuration Store

The Consul Configuration Store extends the Vert.x Configuration Retriever and provides the way to retrieve configuration from a Consul.

#### Using the Consul Configuration Store

To use the Consul Configuration Store, add the following dependency to the dependencies section of your build descriptor:

- Maven (in your `pom.xml`):

    <dependency>
      <groupId>io.vertx</groupId>
      <artifactId>vertx-config-consul</artifactId>
      <version>3.5.3.CR1</version>
    </dependency>
    <dependency>
      <groupId>io.vertx</groupId>
      <artifactId>vertx-config</artifactId>
      <version>3.5.3.CR1</version>
    </dependency>

- Gradle (in your `build.gradle` file):

    compile 'io.vertx:vertx-config:3.5.3.CR1'
    compile 'io.vertx:vertx-config-consul:3.5.3.CR1'

#### Configuring the store

Once added to your classpath or dependencies, you need to configure the `ConfigRetriever` to use this store:

    require 'vertx-config/config_retriever'
    store = {
      'type' => "consul",
      'config' => {
        'host' => "localhost",
        'port' => 8500,
        'prefix' => "foo"
      }
    }

    retriever = VertxConfig::ConfigRetriever.create(vertx, {
      'stores' => [
        store
      ]
    })

The store configuration is used to create an instance of `ConsulClient`. Check the documentation of the Vert.x Consul Client for further details. And this is the parameters specific to the Consul Configuration Store:

`prefix`

  A prefix that will not be taken into account when building the configuration tree. Defaults to empty.

`delimiter`

  Symbol that used to split keys in the Consul storage to obtain levels in the configuration tree. Defaults to "/".

### Spring Config Server Store

The Spring Config Server Store extends the Vert.x Configuration Retriever and provides the a way to retrieve configuration from a Spring Server.

#### Using the Spring Config Server Store

To use the Spring Config Server Store, add the following dependency to the dependencies section of your build descriptor:

- Maven (in your `pom.xml`):

    <dependency>
      <groupId>io.vertx</groupId>
      <artifactId>vertx-config-spring-config-server</artifactId>
      <version>3.5.3.CR1</version>
    </dependency>
    <dependency>
      <groupId>io.vertx</groupId>
      <artifactId>vertx-config</artifactId>
      <version>3.5.3.CR1</version>
    </dependency>

- Gradle (in your `build.gradle` file):

    compile 'io.vertx:vertx-config:3.5.3.CR1'
    compile 'io.vertx:vertx-config-spring-config-server:3.5.3.CR1'

#### Configuring the store

Once added to your classpath or dependencies, you need to configure the `ConfigRetriever` to use this store:

    require 'vertx-config/config_retriever'
    store = {
      'type' => "spring-config-server",
      'config' => {
        'url' => "http://localhost:8888/foo/development"
      }
    }

    retriever = VertxConfig::ConfigRetriever.create(vertx, {
      'stores' => [
        store
      ]
    })

Configurable attributes are:

- `url` - the `url` to retrieve the configuration (mandatory)

- `timeout` - the timeout (in milliseconds) to retrieve the configuration, 3000 by default

- `user` - the `user` (no authentication by default)

- `password` - the `password`

- `httpClientConfiguration` - the configuration of the underlying HTTP client

### Vault Config Store

The Vault Store extends the Vert.x Configuration Retriever and provides support for Vault (https://www.vaultproject.io/).

So, configuration (secrets) is retrieved from Vault.

#### Using the Vault Config Store

To use the Vault Config Store, add the following dependency to the dependencies section of your build descriptor:

- Maven (in your `pom.xml`):

    <dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-config-vault</artifactId>
    <version>3.5.3.CR1</version>
    </dependency>
    <dependency>
    <groupId>io.vertx</groupId>
    <artifactId>vertx-config</artifactId>
    <version>3.5.3.CR1</version>
    </dependency>

- Gradle (in your `build.gradle` file):

    compile 'io.vertx:vertx-config:3.5.3.CR1'
    compile 'io.vertx:vertx-config-vault:3.5.3.CR1'

#### Configuring the store

Once added to your classpath or dependencies, you need to configure the `ConfigRetriever` to use this store:

    require 'vertx-config/config_retriever'
    store = {
      'type' => "vault",
      'config' => config
    }

    retriever = VertxConfig::ConfigRetriever.create(vertx, {
      'stores' => [
        store
      ]
    })

To use the Vault config store, set the `type` to `vault`. The configuration is provided as Json. It configures the access to Vault, authentication and the path of the secret to retrieve:

    Code not translatable}

The `vault_config` object can contain the HTTP client / Web client configuration such as trust stores, timeout, certificates, port and host. The `path` and `host` entries are mandatory. The `path` indicates the secret to retrieve. The `host` is the hostname of the Vault server. By default the port 8200 is used. SSL is disabled by default, but you should enable it for production settings.

Then, you need to use one of the following method to configure the token to use or the authentication mechanism.

#### Using an existing token

If you know the token to use, set the `token` entry in the configuration:

    require 'vertx-config/config_retriever'
    vault_config = {
    }

    # ...

    # Path to the secret to read.
    vault_config['path'] = "secret/my-secret"

    # The token
    vault_config['token'] = token

    store = {
      'type' => "vault",
      'config' => vault_config
    }

    retriever = VertxConfig::ConfigRetriever.create(vertx, {
      'stores' => [
        store
      ]
    })

You can use the root token, but it’s not recommended. When the token is revoked, the access to the secret is blocked. If the token is renewable, the token is renewed when it expires.

#### Generating a token

If you have a token allowing you to generate new token, you can request the token generation:

    require 'vertx-config/config_retriever'
    vault_config = {
    }

    # ...

    # Path to the secret to read.
    vault_config['path'] = "secret/my-secret"

    # Configure the token generation

    # Configure the token request (https://www.vaultproject.io/docs/auth/token.html)
    tokenRequest = {
      'ttl' => "1h",
      'noDefault' => true,
      'token' => token
    }

    vault_config['auth-backend'] = "token"['renew-window'] = 5000['token-request'] = tokenRequest

    store = {
      'type' => "vault",
      'config' => vault_config
    }

    retriever = VertxConfig::ConfigRetriever.create(vertx, {
      'stores' => [
        store
      ]
    })

When using this approach, no token must be provided in the root configuration, the the token use to request the generation is passed in the nested JSON structure. If the generated token is renewable, it will be renewed automatically upon expiration. The `renew-window` is the time window to add to the token validity to renew it. If the generated token is revoked, the access to the secret is blocked.

#### Using certificates

You can use TLS certificates as authentication mechanism. So, you don’t need to know a token, the token is generated automatically.

    Code not translatable

Check out the HTTP client and Web client configuration to pass the certificates. If the generated token is renewable, it will be renewed. If not, the store attempts to authenticate again.

#### Using AppRole

`AppRole` is used when your application is known by Vault and you have the `appRoleId` and `secretId`. You don’t need a token, the token being generated automatically:

    require 'vertx-config/config_retriever'
    vault_config = {
    }

    # ...

    vault_config['auth-backend'] = "approle"['approle'] = {
      'role-id' => appRoleId,
      'secret-id' => secretId
    }

    # Path to the secret to read.
    vault_config['path'] = "secret/my-secret"

    store = {
      'type' => "vault",
      'config' => vault_config
    }

    retriever = VertxConfig::ConfigRetriever.create(vertx, {
      'stores' => [
        store
      ]
    })

If the generated token is renewable, it will be renewed. If not, the store attempts to authenticate again.

#### Using username and password

The `userpass` auth backend is used when the user / app is authenticated using a username/password. You don’t need a token as the token is generated during the authentication process:

    require 'vertx-config/config_retriever'
    vault_config = {
    }

    # ...

    vault_config['auth-backend'] = "userpass"['user-credentials'] = {
      'username' => username,
      'password' => password
    }

    # Path to the secret to read.
    vault_config['path'] = "secret/my-secret"

    store = {
      'type' => "vault",
      'config' => vault_config
    }

    retriever = VertxConfig::ConfigRetriever.create(vertx, {
      'stores' => [
        store
      ]
    })

If the generated token is renewable, it will be renewed. If not, the store attempts to authenticate again.

### Consul Configuration Store

The Consul Configuration Store extends the Vert.x Configuration Retriever and provides the way to retrieve configuration from a Consul.

#### Using the Consul Configuration Store

To use the Consul Configuration Store, add the following dependency to the dependencies section of your build descriptor:

- Maven (in your `pom.xml`):

    <dependency>
      <groupId>io.vertx</groupId>
      <artifactId>vertx-config-consul</artifactId>
      <version>3.5.3.CR1</version>
    </dependency>
    <dependency>
      <groupId>io.vertx</groupId>
      <artifactId>vertx-config</artifactId>
      <version>3.5.3.CR1</version>
    </dependency>

- Gradle (in your `build.gradle` file):

    compile 'io.vertx:vertx-config:3.5.3.CR1'
    compile 'io.vertx:vertx-config-consul:3.5.3.CR1'

#### Configuring the store

Once added to your classpath or dependencies, you need to configure the `ConfigRetriever` to use this store:

    require 'vertx-config/config_retriever'
    store = {
      'type' => "consul",
      'config' => {
        'host' => "localhost",
        'port' => 8500,
        'prefix' => "foo"
      }
    }

    retriever = VertxConfig::ConfigRetriever.create(vertx, {
      'stores' => [
        store
      ]
    })

The store configuration is used to create an instance of `ConsulClient`. Check the documentation of the Vert.x Consul Client for further details. And this is the parameters specific to the Consul Configuration Store:

`prefix`

  A prefix that will not be taken into account when building the configuration tree. Defaults to empty.

`delimiter`

  Symbol that used to split keys in the Consul storage to obtain levels in the configuration tree. Defaults to "/".