Skip navigation links

µb microbean-settings 0.0.4

Provides classes and interfaces that help with acquiring settings from CDI-based programs.

See: Description

Packages 
Package Description
org.microbean.settings
Provides classes and interfaces that help with acquiring settings from CDI-based programs.
org.microbean.settings.converter
Provides classes and interfaces that help with settings conversion.

Provides classes and interfaces that help with acquiring settings from CDI-based programs.

microBean™ Settings

The microBean™ Settings framework serves as a single locus from which a CDI-based Java program may read settings: deployment-time information and configuration often packaged externally with respect to the program that tailors that program to its runtime environment.

Essential Settings Terminology

Setting

A setting is a non-specific conceptual entity that loosely and imprecisely describes an aspect of something that can be externally configured.

The term setting as commonly used is slippery and ambiguous. Sometimes people use "setting" to mean the name of a property or attribute that can be externally configured in some way ("the setting that controls debug information", "what's the debug setting set to?"). Other times people use "setting" to mean a particular value of something that can be externally configured ("what's the setting for the debug property?"). Still other times people use "setting" to mean an environmentally specific particular value of something that can be configured ("use the staging setting for debug").

Due in part to this ambiguity, this project deliberately does not represent a setting in Java code. Instead, this project carefully distinguishes between setting names, setting values, and qualifiers.

Setting Name

A setting name is fundamentally a String. It is not hierarchical. It is treated as a unique key that, together with qualifiers, which will be discussed later, can pick out a maximally suitable setting value from among many possible suitable setting values.

For example, the setting name for a hypothetical debug setting should be, simply, debug, even if there could be many potentially suitable setting values for this setting name. Potentially suitable (and potentially incompatible) setting values might include:

…and so on.

To belabor the point, and most notably in this example, the setting name would not be anything like production.debug, or development.debug or east.debug, because setting names are not hierarchical. It would be, simply, debug. The mechanism to distinguish between these hypothetical setting values in the absence of hierarchical setting names, qualifiers, will be discussed below.

Setting Value

A setting value is, fundamentally, deliberately and canonically a textual value, since that is the form in which most setting values are stored, and also particularly since, being configuration information, setting values are designed to be human-editable.

Setting values conceptually are always paired with the setting name they are associated with. Bear in mind, however, that several potential setting values may be associated with any given setting name. Some of them may be more or less suitable for one particular application but not for another. Suitability is covered later below.

Source

A setting value conceptually originates from a source, which is simply and somewhat circularly any furnisher of (definitionally textual) setting values. Sources are represented in Java code in this project by instances of the Source class.

In this project, a Source is the atomic unit of setting value acquisition and serves as a façade on top of systems ranging from simple text files to entire configuration subsystems. Colloquially speaking, you can ask a Source for a Value that is suitable for a setting named by a particular setting name, and it will respond with zero or one of them.

Setting Value Acquisition

Setting value acquisition is the process of acquiring a setting value given a setting name and some information about the settings space in which the setting value acquisition is taking place.

This settings space information is more precisely known as qualifiers.

Qualifiers

A qualifier is a conceptual pairing of a named environmental aspect and its value that, together, pick out a single coordinate in an overall settings space.

Consider a hypothetical, deliberately simplified organization that deploys many programs across east and west data center regions, and places them into development, staging and production environments, and conducts named featureTests across them. A program running in this world has coordinates—qualifiers—in this settings space. Specifically, a program's settings space qualifiers distinguish it in this hypothetical world by qualifying its location in settings space: along the environment axis (environment=development, or environment=staging, or environment=production), its location along the region axis (region=east or region=west), and its location along the featureTest axis (featureTest=blinkTag or featureTest=autoplay or a potentially infinite number of other possibilities).

It is extremely important to understand that qualifiers, like setting names, are not inherently hierarchichal. For example, given two setting values, one qualified with environment=development and region=east, and another qualified with environment=development and featureTest=blinkTag, which is "best" for an application in the development environment, running in the east region and undergoing the blinkTag feature test? It is not immediately clear, and this is why setting names and qualifiers are not expressed in terms of a hierarchical namespace.

A qualifier is represented in Java code in this project by instances of the Annotation class, following a similar concept in CDI.

Setting Value Request

A setting value request is the logical sending of a pair of a setting name and some qualifiers to one or more sources.

A well-behaved source that is provided with this information will either furnish exactly one setting value response for the conceptual setting identified by the setting value request, or will indicate that it can furnish no suitable setting value response.

If a source furnishes a setting value response, then the setting value response is said to be suitable to some degree.

Setting Value Response

A setting value response is the logical sending of a logical tuple consisting of a setting name, a suitable setting value, and a subset of the setting value request's qualifiers from which a degree of suitability is derived in response to the reception of a setting value request.

Suitability

A setting value response's suitability for its corresponding setting value request is a measure of how suited—how tailored, how specific—its associated setting value is for a given setting value request.

Setting value response suitability is represented by the fact that a setting value response has qualifiers, in a manner similar to how a setting value request has qualifiers. To be at all suitable, a setting value response's qualifiers must be either equal in kind and number to the set of qualifiers present in the corresponding setting value request, or a subset in kind and number of those qualifiers.

Therefore, a setting value response whose qualifiers are smaller in number than the qualifiers in its corresponding value acquisition request is less suitable for the setting in question than a setting value whose qualifiers are equal in number to the qualifiers in its corresponding setting value request.

Colloquially speaking, in other words: if a setting value request for a setting named debug arrives at a source with qualifiers {environment=production, region=east}, then a setting value response whose qualifiers are {environment=production} is less suitable for that setting value request than a setting value response whose qualifiers are {environment=production, region=east}, and a setting value response whose qualifiers are empty is the least suitable of all possible setting values for that value acquisition request.

Ambiguity and Value Arbitration

When each of two sources responds to a setting value request, a requester must choose between the two setting value responses received. Sometimes, choosing is easy: if there is only one suitable setting value response, then there is no question that its associated setting value is the one that should be used, or if there is one setting value response that is more suitable than another, then obviously the more suitable one should be chosen. But if two setting value requests are equally suitable, some other mechanism to disambiguate them must be used. This is called value arbitration.

Value arbitration is carried out by an arbiter. An arbiter is a notional resolver of otherwise ambiguous setting value responses. It receives two or more setting value responses with equal suitability and uses whatever heuristic it likes to choose between them. Arbiters are represented in Java code in this project by instances of the Arbiter class.

If an arbiter cannot arbitrate multiple ambiguous setting value responses, then the overall process of setting value acquisition fails.

Interpolation

A setting value may contain references to other setting names for which setting value requests should be issued. Processing these references is known as interpolation.

All interpolation in this project is carried out by an implementation of the Jakarta Expression Language.

For example, in this project, for a setting name of, say, javaHomeDescription, a potentially suitable setting value of "Your java.home variable is: ${settings['java.home']}" will be interpreted such that during setting value acquisition a setting value request will be issued for a setting named java.home, and any value received for that setting name will replace "${settings['java.home']}".

Conversion

Once a setting value has been successfully acquired, it might need to be converted into a different data type. For example, a setting value of "1"—a String—might be better represented within Java code as an Integer. Conversion is the process of transforming a (definitionally) textual-typed setting value (such as a String) into another data type representation (such as an Integer).

Converter

A converter is a notional, preferably stateless entity that can accept a (definitionally textual) setting value and, without changing its meaning, represent it using a particular programming language data type. Converters are represented in Java code in this project by implementations of the Converter interface.

Essential Classes

In this project, the Settings class encapsulates all aspects of setting value acquisition described above. A Settings instance gathers together Sources, Arbiters, Converters and a pluggable implementation of the Jakarta Expression Language to provide setting value acquisition services via methods like Settings.get(String, Set, Converter, BiFunction).

Author:
Laird Nelson
See Also:
Settings, Arbiter, Converter, Source, Value
Skip navigation links

Copyright © 2019–2020, microBean™. All rights reserved.