More Thoughts on Configuration

This is a distillation of the thoughts I had in my previous piece on configuration.

The key insight for me was that application configuration takes place within a configuration value space with one or more dimensions or axes.

Next, these dimensions or axes are not hierarchical (after all, how could a dimension or axis be hierarchical?) and have nothing to do with the name of the configuration setting (other than that it can be considered to be one of the dimensions or axes).

Following on from all of that, an application asks for configuration values suitable for where it sits in multidimensional configuration space.  (I know this sounds like I’m five miles above the earth, but I really think this is important.)  I like to call this location its configuration coordinates.  There are always more coordinates than you think (something like locale often slips through the cracks!) but the total number is still probably under 20 or 10 for almost any application.  Many simple applications probably have somewhere around only two or three.

Next, a (flexible, well-written) application is typically unaware of most (if not all) of its own configuration coordinates.  (An application, in other words, from the standpoint of its running code, doesn’t “know” whether it’s in the test environment or not.)  But these coordinates are always, whether you know it or not, implicit in a semantic configuration request.

Next, configuration systems or sources are capable of supplying configuration values that are more or less specific along one or more of the configuration space axes.  A configuration system might supply a value that is maximally specific along the name axis (db.url), and minimally specific along (but suitable for) all possible other axes (environment, phase, region, etc.).  The holy grail is a value that is exactly suited for all of and exactly those configuration coordinates expressed by the application. Non-holy grails are configuration values that are still suitable by virtue of applying to a wide range of configuration coordinates.  This is the only place where hierarchies come into play: for any given configuration axis, a more-specific configuration value always trumps (I hate that word) a less-specific configuration value, but if a more-specific value does not exist, then the less-specific value is suitable.

This lets us start theorizing clumsily about a procedure where an application can ask for configuration values suitable for its configuration coordinates:

  • The application asks the configuration system for a value for the db.url configuration key and expects a String back.
  • The configuration system figures out what the application’s coordinates are, and re-expresses the request in terms of those coordinates.  db.url becomes a value for the—I don’t know—configurationKey axis.
  • The configuration system grabs all of its sources or subsystems or providers or whatever they should be called.
    • For each one, it asks it for a configuration value suitable for the supplied coordinates—and expects back, in return, not just the value, but also the coordinates for which it is explicitly suited.  Also of note: if the subsystem returns a value with no coordinates, then this value matched, but minimally specifically.  It’s suitable, but as a last resort.
    • Each subsystem responds appropriately.
  • The configuration system loops through the results.  Any result is presumed or enforced to be a match for at least the (hypothetical) configurationKey axis!  (That is, if I ask for foo, and I get a value for bar back, regardless of other coordinates, something went wrong.)
    • If there are no results, then there are no matches, and either null is returned or an error is thrown.
    • If there is exactly one result, then the value is returned.
    • If there is exactly one exact match, then the value is returned.
    • If there is more than one exact match, then an error is thrown.
    • If there are no exact matches:
      • The configuration system sorts the results in terms of specificity.  There are some details to work out here, but loosely and hazily and sketchily speaking if a set of configuration coordinates is expressed as a Map, then a Map with a bigger size (assuming the same universe of possible keys) is more specific, let’s say, than a Map with a smaller size. For example, {a=b, c=d} is a more specific set of coordinates (let’s say) than {a=b}.  The mere presence of a value indicates some kind of match, so it is possible for a configuration subsystem to return a value with, say, empty configuration coordinates.  This would indicate that the match is least specific.  So the specificity of a configuration value can be said, I think, to be equal to the number of configuration coordinates it reports as having matched on.  Tersely, the greater the specificity, the greater the Map‘s size.
      • If there is exactly one value with a given specificity, then it is returned—it is a suitable match.
      • If there is more than one value with the same specificity of coordinates, then this represents a misconfiguration and an error is thrown. For example, one subsystem might report that it has a value for {b=c, d=e} and another might report that it has a value for {d=e, f=g} when asked for a value suitable for {b=c, d=e, f=g}. Since configuration axes are not (by definition) hierarchical, this represents a misconfiguration.

OK, I think I’ll leave it there for now and chew on this over the weekend.

Author: Laird Nelson

Devoted husband and father; working on Helidon at the intersection of Java, Jakarta EE, architecture, Kubernetes and microservices at Oracle; open source guy; Hammond B3 player and Bainbridge Islander.

2 thoughts on “More Thoughts on Configuration”

Comments are closed.

%d bloggers like this: