io.aviso.config

A system for reading and coercing configuration data.

Configuration data is in the form of a set of files (mostly on the classpath) that follow a naming convention:

conf/<profile>-<variant>.edn

The list of profiles and variants is provided by the application.

The configuration data is read from an appropriate set of such files, and merged together.

Each component’s individual configuration is validated and conformed against a spec that is specific to the component.

assemble-configuration

(assemble-configuration options)

Reads the configuration, as specified by the options.

When the EDN files are read, a set of reader macros are enabled to allow for some dynamicism in the parsed content: this represents overrides from either shell environment variables, JVM system properties, or the :properties option.

:additional-files
A seq of absolute file paths that, if they exist, will be loaded last, after all normal resources. This is typically used to provide an editable (outside the classpath) file for final production configuration overrides.
:overrides
A map of configuration data that is overlayed (using a deep merge) on the configuration data read from the files, before validation and coercion.
:profiles
A seq of keywords that identify which profiles should be loaded and in what order. The default is an empty list. configure-using will provide default profiles based on the config key specified by with-config-spec.
:properties
An optional map of additional properties that may be substituted (using the #config/prop reader macro). Explicit properties have higher precendence than JVM system properties, which have higher precendence than environment variables; however the convention is that environment variable names are all upper case, and properties are all lower case, so actual conflicts should not occur.
The keys of the properties map are converted to strings via name, so they may be strings or symbols, or more frequently, keywords.
Most often the properties map is used for specific overrides in testing, or to expose some bit of configuration that cannot be directly extracted from environment variables or JVM system properties.
:variants
The variants searched for, for each profile.
default-variants provides the default list of variants. A nil variant is always prefixed on the provided list.
:resource-path
A function that builds resource paths from profile and variant.
The default is default-resource-path, but this could be overridden to (for example), use a directory structure to organize configuration files rather than splitting up the different components of the name using dashes.

Any additional files are loaded after all profile and variant files.

The contents of each file are deep-merged together; later files override earlier files.

Overrides via the :overrides key are applied last; these are typically used only for testing purposes.

Configurable

protocol

Optional (but preferred) protocol for components.

When a component declares its configuration with with-config-spec, but does not implement this protocol, it will instead have a :configuration key associated with it.

members

configure

(configure this configuration)

Passes a component’s individual configuration to the component, as defined by with-config-spec.

The component’s configuration is extracted from the merged system configuration and conformed; the conformed configuration is passed to the component.

When this is invoked (see configure-components), a component’s dependencies will be available, but in an un-started state.

configure-components

added in 0.1.9

(configure-components system configuration)

Configures the components in the system map, returning an updated system map.

Typically, this should be invoked before the system is started, as most components are expected to need configuration in order to start.

This function has effectively been replaced by configure-using.

configure-using

added in v20161206

(configure-using system options)

Configures the components in the system map, returning an updated system map.

The options are enhanced and passed to assemble-configuraton; the resulting configuration is applied using configure-components.

The system map is scanned for components that have used the with-config-spec function; the configuration key is extracted (in dependency order) and prefixes any values provided in the :profiles option key.

default-resource-path

(default-resource-path profile variant)

Default mapping of a resource path from profile and variant.

profile - keyword
profile to add to path
variant - keyword
variant to add to the path, or nil

The result is typically “conf/profile-variant.edn”.

However, the “-variant” portion is omitted when variant is nil.

Returns a seq of files. Although this implementation only returns a single value, supporting a seq of values makes it easier to extend (rather than replace) the default behavior with an override.

default-variants

added in 0.1.9

The default list of variants. The combination of profile and variant is the main way that resource file names are created (combined with a fixed prefix and a supported extension).

The order of the variants determine load order, which is relevant.

A nil variant is always prefixed to this list; this represents loading default configuration for the profile.

Typically, a library creates a component or other entity that is represented within config as a profile.

The local variant may be used for test-specific overrides, or overrides for a user’s development (say, to redirect a database connection to a local database), or even used in production.

with-config-spec

(with-config-spec component config-key config-spec)

Adds metadata to the component to define the configuration spec for the component.

This defines a top-level configuration key (e.g., :web-service) and a spec for just that key.

The component’s specific configuration is extracted from the merged configuration, and the component’s config spec is used to conform it. The conformed configuration is passed to the component.

The component will receive just it’s individual, conformed configuration in its :configuration key.

Alternately, the component may implement the Configurable protocol. It will be passed the conformed configuration.