Lightbend Config

repository·main·Indexed 27 days ago

https://github.com/lightbend/config

A configuration library for JVM languages (Java 8+) that provides immutable, thread-safe configuration objects. It supports Java properties, JSON, and HOCON formats, allowing for loading from files, URLs, or the classpath. Key features include automatic type conversion, duration and size parsing, HOCON substitutions, and the ability to override settings via Java system properties or environment variables.

Tokens
7.6K
Snippets
9
Records
50
Agent score
89%

What's inside lightbend-config

  1. Overview of Config library features

    main

    The Config library is a plain Java implementation with no dependencies that provides the following capabilities:

    • Supported Formats: Java properties, JSON, and HOCON (a human-friendly JSON superset).
    • Loading: Supports loading from files, URLs, or the classpath.
    • Merging: Merges multiple files across all supported formats.
    • Overrides: Users can override configuration using Java system properties (e.g., java -Dmyapp.foo.bar=10).
    • Type Conversion: Automatically converts types (e.g., string "yes" to boolean, or int to float).
    • Special Parsers: Parses duration and size settings (e.g., "512k" or "10 seconds").
    • HOCON Features: Supports comments, includes, substitutions (${bar}), and environment variable substitution (logdir=${HOME}/logs).
    • Immutability: Uses immutable Config instances for thread safety and predictable transformations.
  2. Understand HOCON (Human-Optimized Config Object Notation)

    main

    HOCON is a JSON superset used by this library for configuration files (typically with the .conf extension). It provides a more human-readable syntax than JSON while remaining compatible with it. After processing, a HOCON file results in a JSON tree.

    Key features include:

    • Comments using # or //.
    • Omitting braces {} around root objects.
    • Using = as a synonym for :.
    • Omitting separators (= or :) before {.
    • Omitting commas (as long as newlines are used).
    • Trailing commas in objects and arrays.
    • Unquoted strings for keys and values.
    • Dotted notation for nested objects (e.g., foo.bar=42 becomes foo { bar: 42 }).
    • Recursive merging of duplicate object keys.
    • The include feature to merge other files, URLs, or classpath resources.
    • Substitutions using ${} syntax.
    • Multi-line strings using triple quotes.
  3. Understand HOCON (Human-Optimized Config Object Notation)

    main

    HOCON is a human-optimized configuration format designed to be a superset of JSON. It maintains JSON's tree structure, types, and encoding/escaping semantics while providing features that make it easier for humans to edit.

    Key features include:

    • Less noisy/pedantic syntax compared to JSON.
    • Ability to refer to other parts of the configuration (substitutions).
    • Ability to import/include other configuration files.
    • Mapping to flat properties lists (like Java system properties).
    • Ability to retrieve values from environment variables.
    • Support for comments.

    Technical properties:

    • JSON Superset: All valid JSON is valid HOCON and produces the same in-memory data.
    • Deterministic: The format is not heuristic; invalid files generate clear errors.
    • Minimal Look-ahead: The parser requires minimal look-ahead (typically 2-3 characters).
  4. HOCON Syntax Overview

    main
    HOCON (Human-Optimized Config Object Notation) is a superset of JSON designed for human readability. It supports standard JSON types (string, number, object, array, boolean, null) and UTF-8 encoding. Key improvements over JSON include support for comments, omitted root braces, and more flexible whitespace/separator rules.
  5. Map Java properties to HOCON

    main

    To convert Java properties to HOCON:

    1. Split each key on the . character (including leading/trailing empty strings).
    2. Construct a tree of JSON-style objects using these path elements.
    3. Place the string value from the properties file at the end of the path.

    Important Constraints:

    • It is impossible to represent a key containing a . in a properties file.
    • If a properties file contains both a=hello and a.b=world, the object wins rule applies: a must be an object, so the string value hello is thrown out.
  6. Configure libraries and applications

    main

    Follow these best practices for distributing configuration:

    • Libraries: Should use a Config instance provided by the application. If none is provided, use ConfigFactory.load(). Libraries should place their default settings in a reference.conf file on the classpath.
    • Applications: Can create a Config using ConfigFactory.load() (the easiest method) or via ConfigValueFactory for custom data sources. Applications should provide the Config instance to their libraries.
  7. Concatenate values in HOCON

    main

    HOCON allows combining multiple values into one through concatenation rules:

    • String Concatenation: If multiple simple values (strings, numbers, booleans, nulls, or substitutions) are separated only by non-newline whitespace, they are concatenated into a single string. Leading and trailing whitespace is trimmed, but internal whitespace is preserved.
    • Array Concatenation: Multiple arrays (or substitutions resolving to arrays) can be concatenated into one large array. Newlines must not exist between the arrays for concatenation to occur.
    • Object Merging (Object Concatenation): Multiple objects can be concatenated (merged) into one. The second object overrides the first for shared non-object keys.

    Common Patterns:

    • Inheritance: Use object concatenation to extend base configurations.
    • Path Appending: Use array concatenation to add elements to existing paths.
  8. Concatenate strings, arrays, and objects in HOCON

    main

    Values on the same line are concatenated.

    String Concatenation

    Substitutions can be concatenated into unquoted strings. Note that the ${} syntax must be outside the quotes.

    tasks-url : ${base-url}/tasks
    path : "/bin"
    path : ${path}":/usr/bin"

    Array Concatenation

    You can append to arrays using the += shorthand:

    path : [ "/bin" ]
    path += "/usr/bin"

    Object Concatenation

    Objects are merged when placed next to each other on the same line:

    data-center-generic = { cluster-size = 6 }
    data-center-east = ${data-center-generic} { name = "east" }
  9. Use environment variables for substitution fallback

    main

    If a substitution is not found in the configuration tree, implementations may look up environment variables.

    Best Practices & Behavior:

    • Naming: Use lowercase for HOCON keys to avoid collisions with capitalized environment variables.
    • Blocking: To explicitly block an environment variable lookup, set the key to null in your configuration (e.g., HOME : null).
    • Empty Strings: Environment variables set to an empty string are treated as an empty string, not as undefined.
    • Types: Environment variables are always treated as strings, but automatic type conversion will apply if the application requests a different type.
  10. Use Self-Referential Substitutions and the `+=` Operator

    main

    HOCON supports self-referential fields, allowing a field to be defined based on its previous value (often used during object merging).

    • Self-Referential Fields: A field that refers to itself (e.g., path : ${path} ":d"). When merging, the substitution resolves to the previously defined value for that path.
    • The += Operator: This is a shorthand for appending an element to an existing array. It is equivalent to a = ${?a} [b].

    Warning: Unbreakable cycles (like a : { b : ${a} } or a : [${a}]) will generate an error. However, a : ${a} is valid if a was previously defined in the configuration or a merged object.

  11. Use unquoted strings in HOCON

    main

    HOCON allows unquoted strings to reduce boilerplate. A sequence of characters is treated as an unquoted string if it does not contain "forbidden characters" ($, ", {, }, [, ], :, =, ,, +, #, `, ^, ?, !, @, *, &, \, or whitespace) and does not start with a boolean (true, false), null, or a number.

    Note: Unquoted strings do not support escaping. If you need special characters, use quoted strings.

  12. Use HOCON substitutions and inheritance

    main

    Substitutions allow you to reuse values and implement inheritance patterns.

    Factor out common values

    standard-timeout = 10ms
    foo.timeout = ${standard-timeout}
    bar.timeout = ${standard-timeout}

    Inheritance via object merging

    Duplicate keys with object values are merged. You can use this to create base configurations and extend them:

    data-center-generic = { cluster-size = 6 }
    data-center-east = ${data-center-generic} { name = "east" }
    data-center-west = ${data-center-generic} { name = "west", cluster-size = 8 }