
:jbake-type: page
:jbake-status: published


== The Tamaya High Level Design

Though Tamaya is a very powerful and flexible solution there are basically only a few simple core concepts required
that build the base of all the other mechanisms:

The *API* (package +org.apache.tamaya+) provides

* A simple but complete SE *API* for accessing key/value based _Configuration_:
  ** +Configuration+ hereby models configuration, the main interface of Tamaya, providing key/value pairs as raw
     (String-based) key/value pairs, allowing also access to typed values.
  ** +ConfigurationProvider+ provides the static entry point for accessing configuration.

The *SPI* (package +org.apache.tamaya.spi+) provides:
  ** A simple minimalistic model for configuration data, called _PropertySource_.
  ** Several extension points for adding additional configuration property sources or adapting the internal workings
     of the overall system.
  ** A +ServiceContext / ServiceContextManager+ that controls the loading of the components in Tamaya. This allows to
     adapt the behaviour depending on the runtime environment in use, e.g. a Java standalone application, an OSGI
     container or a Java EE application server.

Tamaya *Modules* finally allow to add additional functionality to customize your configuration solution with the
functionality you want. E.g. modules are providing features such as

* Configuration _injection_
* _Dynamic placeholders_ and resolution mechanism for configuration values
* Abstractions for reusable _configuration formats_
* Dynamic configuration updates and change events
* Support for OSGI/Java EE Classloading
* A configuration server/client
* and more...


== How Tamaya organizes Configuration
=== Overview

All the mentioned artifacts are used to organize configuration in a higly flexible and extendable way. Hereby the
+PropertySource+ is the key artifact. In general Tamaya organizes Configuration as follows:

image::../images/CoreDesign.png[]

Key abstraction hereby is the +ConfigurationContext+, which basically

* an ordered chain of +PropertySource+ instances. This chain is used to evaluate raw configuration values.
* a set of +PropertyFilter+ instances that filter the raw values evaluated from the property source chain.
* a set of +PropertyConverter+ that convert String values into typed values when needed.

In most standalone use cases only one +ConfigurationContext+ will be active at a time. But in more complex scenarios,
such as Java EE also multiple contexts could be active that are active depending on the current runtime context
(e.g. attached to the corresponding classloader(s)). These aspects are basically handled by the
+ConfigurationProvider+ and its corresponding SPIs.

=== Loading the current _ConfigurationContext_

The +ConfigurationContext+ is the core of Tamaya. It manages all configuration sources and additional components
required to evaluate a concrete configuration value:

* Tamaya loads all available +PropertySource+ instances. Hereby +PropertySource+ instances can be
  ** Directly registered (using the mechanism defined by the current +ServiceContext+ implementation, by default
     the Java +ServiceLoader+.
  ** Provided by a registered instance of +PropertySourceProvider+.
* All loaded property sources are _ordered based on each ordinal_, returned from +PropertySource.getOrdinal()+ as
  an ordered chain of PropertySources, building up the ordered chain of +PropertySource+ instances used for raw
  configuration value evaluation.
* Tamaya loads all available +PropertyFilter+ instances. Hereby +PropertyFilter+ instances can be registered
  by default using the Java +ServiceLoader+ API. The +PropertyFilter+ instances loaded are ordered based on the
  +@Priority+ annotations found on each filter. If no priority annotation is present, +0+ is assumed.
* Tamaya loads all available +PropertyConverter+ instances. Hereby +PropertyConverter+ instances can be registered
  by default using the Java +ServiceLoader+ API. The +PropertyConverter+ instances loaded are ordered based on the
  +@Priority+ annotations found on each filter. If no priority annotation is present, +0+ is assumed. It is
  possible to register multiple converters for the same target type.

=== Evaluating raw property values
When evaluating a concrete configuration value for a given key, Tamaya iterates through this chain of registered
PropertySources. Hereby the final value, by default, is determined by the last non-null value returned from a
+PropertySource+.

Since the ladder may not always be appropriate, e.g. when values should be combined instead of overridden, a
instance of +PropertyConverter+ actually has access to all values returned. This enables more complex value
evaluation algorithms, when needed.

Access to the complete configuration +Map+ is performing the same resolution algorithm, but for all
key/value pairs available.

=== Filtering the raw properties:
Each raw configuration value evaluated is filtered by the ordered filter chain, as long as there are any changes
applied by any of the filters called. This ensures that also transitive replacements by filters are possible.
If, after a configurable number of evaluation loops still values are changes during each loop, the filtering
process is aborted, since a non-resolvable circular filter issue is assumed.

The output is the final configuration value as type +String+.

=== Applying type conversion:
Finally, if the required target type, does not match +Java.ui.lang.String+, all registered +PropertyConverter+
instances targeting the corresponding target type are asked to convert the given (String-based) configuration
entry to the required (non String) target type.

Hereby the first _non-null_ value returned by a +PropertyConverter+ is used as the final typed configuration value and
returned to the caller.

=== Advanced Features
Basically the bahaviour of Tamaya can be customized using the following mechanisms. Basically configuration can be
provided using the following mechanism:

* Registering additional +PropertySource+ instances. Depending on their _ordinal value_ they
  will override or extend existing configuration.
* Registering additional +PropertySourceProvider+ instances, to provide multiple +PropertySource+
  instances.

Additionally Tamaya provides hooks for further adapting the internal workings:

* Adding additional support for new target types configurable by registering additional +PropertyConverter+
  instances. This can be used for adding support for new types as well as for adding support for additional
  formats.
* Complex extensions may adapt the complete +ConfigurationContext+.
* Registering additional +PropertyFilter+ instances, that filter the configuration values extracted.
* Registering an alternate +ServiceContext+ to support alternate runtime containers, e.g. a CDI container.
* A combination of all above.

Additionally instances of +ConfigOperator, ConfigQuery+ can be implemented that provide additional functionality.


== Component Loading

As mentioned the component loading of Tamaya can be adapted. By default the JDK +ServiceLoader+ API is used to determine
a +ServiceContext+ implementation that should control
Tamaya's overall component loading. If not found, a default implementation is registered, which relies on the
Java +hava.util.ServiceLoader+ mechanism. This behaviour can be changed by implementing your own version
of the +ServiceContext+ interface, annotating it with a +@Priority+ annotation and registering it using the
+java.util.ServiceLoader+ mechanism.

== Compatibility

The Tamaya API is compatible with Java 8 and beyond.


== Further Documentation

Being here we recommend to have a look at the more detailed documentation of Tamaya's link:documentation/api.html[API and SPI],
and of its current available link:documentation/extensions.html[modules].
