= DeltaSpike Configuration Mechanism

:Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR  CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

== Introduction

The goal of the DeltaSpike configuration mechanism is to make it
obsolete to touch released binaries for changing the configuration of
your project. All values which are needed in your code (but should not
be hardcoded as static final constants) can be maintained via
DeltaSpike's own configuration mechanism in a very flexible and powerful
way.

=== Benefits for Production

Once a binary like a WAR file or an EAR got created and tested, it must
_not_ get changed anymore. The exact same binary which got created by
the release manager will get moved to the Test system, then further
propagated to the Staging environment and finally (if all people are
happy with it) will get moved to the Production system. And all this
without any changes on the binary itself!

The Apache DeltaSpike configuration system makes this possible by
providing a default configuration inside the binary and allowing to
amend this configuration (e.g. database credentials, some URLs from
remote REST or SOAP endpoints, etc) from outside like environment
settings, JNDI or the current <<projectstage.adoc#,ProjectStage>>.


=== Drop-In Configuration

This mechanism also allows for dynamic configuration in case of a JAR
drop-in. By adding some JAR to the classpath, all its contained
configuration will get picked up and considered in the property value
evaluation. You could also use this mechanism to switch implementations
of some SPI (Service Provider Interface) in your own code.

=== CDI-Extension Configuration

In some cases low-level configs are needed, for example during the bootstrapping
process of the CDI container.

The good news: our DeltaSpike configuration mechanism does not rely on
any other EE mechanism to be booted. Which means it can perfectly get
used to even configure those parts itself. Since the mechanism does not
rely on CDI it can for example be used to configure CDI-Extensions.

Currently this is, for example, used to configure the value of the current <<projectstage.adoc#,ProjectStage>>, configured values which can be
used in the expressions for `@Exclude`, 'Deactivatable', etc. DeltaSpike
needs such a low-level approach for several features internally, but
users can utilize it for their own needs as well. This is done by using
the `ConfigResolver` which resolves and caches `ConfigSource`s per
application.


== Accessing configured values using ConfigResolver

The `ConfigResolver` is the central point to access configuration in DeltaSpike. There are several different APIs
 and ways to access the individual configured values, each suitable for a different purpose:

 * `ConfigResolver` methods for easy programmatic access to values
 * `TypedResolver` API for typed configuration values and precise control over resolution
 * `@ConfigProperty` for injection of configured values into beans

All three mechanisms are described in the following sections.

=== ConfigResolver methods

ConfigResolver offers several methods for easy access to String values of configured properties.

==== getPropertyValue()

The method `ConfigResolver#getPropertyValue(String key)` returns the value configured for a given key
as `String`, or `null` if no value has been found.

`ConfigResolver#getAllPropertyValues(String key)` has a similar contract
but it returns a list which might be empty if there are no configured
values for the given key.

This is a code excerpt about how to do a simple lookup in the deltaspike
configuration:

[source,java]
-------------------------------------------------------------------------------
String dbUserName = ConfigResolver.getPropertyValue("databaseconfig.username");
-------------------------------------------------------------------------------

==== getProjectStageAwarePropertyValue()

The method
`ConfigResolver#getProjectStageAwarePropertyValue(String key)` utilizes
the <<projectstage.adoc#,DeltaSpike ProjectStage>> mechanism to allow
configured values to depend on the current `ProjectStage` of the running system.

This is done by first looking up the ProjectStage (this internally
happens with the DeltaSpike ConfigResolver as well) and then go down the
following lookup chain until we found a configured value.

* key + '.' + projectStage , e.g. "databaseconfig.username.Production"
* key alone , e.g. "databaseconfig.username"

==== getPropertyAwarePropertyValue()

The method
`ConfigResolver#getPropertyAwarePropertyValue(String key, String property)`
first looks up the configured value of the given property and uses this
value to determine the final lookup path. All those lookups take the
<<projectstage.adoc#,DeltaSpike ProjectStage>> mechanism into account.

[source,java]
--------------------------------------------------------------------------------------------------------
String dbUserName = ConfigResolver.getPropertyAwarePropertyValue("databaseconfig.username", "dbvendor");
--------------------------------------------------------------------------------------------------------

===== Property value resolution sequence

The following lookup sequence will be performed until a value is found:
First, the value of the _parameter_ property is resolved:

* propertyValue = property + '.' + projectStage, e.g. "dbvendor.Production"
* if nothing found: propertyValue = property, e.g. "dbvendor"

Let's assume we found the value 'mysql' for our dbvendor. In this case
the following lookup chain is used until a value got found:

* key + '.' + propertyValue + '.' + projectstage, e.g. "databaseconfig.username.mysql.Production"
* key + '.' + propertyValue, e.g. "databaseconfig.username.mysql"
* key + '.' + projectStage, e.g. "databaseconfig.username.Production"
* key, e.g. "databaseconfig.username"

==== Handling of Default Values

There is a 2nd variant of all those methods where it is possible to
provide a default value which gets returned instead of `null` or if the
final result is an empty String.

.Performance Hint
TIP: The only `ConfigResolver` operation which is cached is the determination
of the `ConfigSources`. The various getPropertyValue operations are not
cached in the ConfigResolver but might be cached in the ConfigSources.
This makes the overall calculation a bit slower, but allows for values
to change dynamically if someone likes to for example implement a
`JmxConfigSource` (not yet part of DeltaSpike, but easily implementable).

=== TypedResolver API

Very often the configured values represent more than just strings -- number types and booleans are commonly used as
configuration types. ConfigResolver provides a builder-style API to access configuration values as specific types.

The API is accessed by a call to `ConfigResolver.resolve(propertyKey)`.

The simplest usage of the API is resolution of a String property, equivalent to a call to
`ConfigResolver.getPropertyValue(propertyKey)`.

.Simple example of TypedResolver
[source,java]
-----------------------------------------------------------------
String userName = ConfigResolver.resolve("user.name").getValue();
-----------------------------------------------------------------

The call to `ConfigResolver.resolve(..)` returns a builder which has methods to refine the resolution, including the
following:

* `as(Class<N> clazz)` -- defines the return type of the property
* `parameterizedBy(String propertyName)` -- sets a parameter for the resolution, similarly as in
<<_getpropertyawarepropertyvalue, ConfigResolver.getPropertyAwarePropertyValue>>
* `withCurrentProjectStage(boolean with)` -- indicates whether the current ProjectStage should be taken into account
for the resolution
* `strictly(boolean strictly)` -- indicates, whether the <<_property_value_resolution_sequence, property value
resolution sequence>> should be taken into account. When set to true, the sequence is not followed.
* `withDefault(T value)` -- sets the default value, used in case the resolution returns `null`
* `getValue()` -- terminates the builder and returns the resolved value with the appropriate type

.A more complete example of TypedResolver
[source,java]
-----------------------------------------------------------------
Integer dbPort = ConfigResolver
    .resolve("db.port")
    .as(Integer.class)
    .withProjectStage(true)
    .parameterizedBy("db.vendor")
    .withDefault(3306)
    .getValue();
-----------------------------------------------------------------

==== Supported types

The types supported out of the box include: String, Integer, Long, Float, Double, Boolean, Class.
Custom types can be supported by providing an implementation of the `ConfigResolver.Converter` interface.

[source,java]
---------------------------------------------------------------------------------------------------------
Date deadline = ConfigResolver.resolve("deadline").as(Date.class, new CustomDateConverter()).getValue());
---------------------------------------------------------------------------------------------------------

[source,java]
------------------------------------------------------------------------------------------
public class CustomDateConverter implements ConfigResolver.Converter<Date> {

    @Override
    public Date convert(String value)
    {
        String[] parts = value.split("-");
        return new GregorianCalendar(Integer.valueOf(parts[0]), Integer.valueOf(parts[1]),
                Integer.valueOf(parts[2])).getTime();
    }
}
------------------------------------------------------------------------------------------

=== Injection of configured values into beans using @ConfigProperty

DeltaSpike provides a way to inject configured values into your code via the qualifier `@ConfigProperty`.
The supported types are the same as the <<_supported_types,supported types of the TypedResolver>>.

[source,java]
------------------------------------------------------
@ApplicationScoped
public class SomeRandomService
{
    @Inject
    @ConfigProperty(name = "endpoint.poll.interval")
    private Integer pollInterval;

    @Inject
    @ConfigProperty(name = "endpoint.poll.servername")
    private String pollUrl;

    ...
 }
------------------------------------------------------

==== Custom ConfigProperty types

Custom types can be injected using `@ConfigProperty` by providing a custom producer.
DeltaSpike provides a base implementation for custom producers in the class `BaseConfigPropertyProducer`
which offers the following methods:
* `getStringPropertyValue` -- looks for the property name in `@ConfigProperty` annotation on the injection point.
If not found, it looks for it in other annotations on the injection point.
* `getPropertyValue` -- a shortcut to <<_configresolver, ConfigResolver#getProjectStageAwarePropertyValue>>
* `getAnnotation` -- extracts any annotation type from the injection point, useful when a custom annotation
is used instead of `@ConfigProperty`

The following example uses `getStringPropertyValue` and a custom `@Location` annotation annotated `@ConfigProperty`.
In such case, the `@Location` annotation is bound to a single fixed property name and acts as a type-safe replacement
for `@ConfigProperty(name = "locationId")`.

[source,java]
--------------------------------------------------------------------
@ApplicationScoped
public class CustomConfigPropertyProducer extends BaseConfigPropertyProducer {

    @Produces
    @Dependent
    @Location
    public LocationId produceLocationId(InjectionPoint injectionPoint)
    {
        String configuredValue = getStringPropertyValue(injectionPoint);

        return LocationId.valueOf(configuredValue.trim().toUpperCase());
    }
}
--------------------------------------------------------------------

[source,java]
-----------------------------------------------------------------
@Target({ FIELD, METHOD })
@Retention(RUNTIME)
@ConfigProperty(name = "locationId", defaultValue = "LOCATION_X")
@Qualifier
public @interface Location {}
-----------------------------------------------------------------

The `@ConfigProperty` annotation doesn't need to be used at all. Instead, a custom annotation can be provided and
obtained in the producer using `getAnnotation` and `getPropertyValue`:

[source,java]
------------------------------------------------------------------------------------------------------
@ApplicationScoped
public class NumberConfigPropertyProducer extends BaseConfigPropertyProducer
{
    @Produces
    @Dependent
    @NumberConfig(name = "unused")
    public Float produceNumberProperty(InjectionPoint injectionPoint) throws ParseException
    {
        // resolve the annotation
        NumberConfig metaData = getAnnotation(injectionPoint, NumberConfig.class);

        // get the configured value from the underlying configuration system
        String configuredValue = getPropertyValue(metaData.name(), metaData.defaultValue());

        // format according to the given pattern
        DecimalFormat df = new DecimalFormat(metaData.pattern(), new DecimalFormatSymbols(Locale.US));
        return df.parse(configuredValue).floatValue();
    }
}
------------------------------------------------------------------------------------------------------

[source,java]
-------------------------------------------------------------------
@Qualifier
public @interface NumberConfig
{
    @Nonbinding
    String name();

    @Nonbinding
    String defaultValue() default ConfigProperty.NULL;

    @Nonbinding
    String pattern() default "#0.00";
}
-------------------------------------------------------------------


== Providing configuration using ConfigSources

A `ConfigSource` is exactly what its name says: a source for configured
values. The `ConfigResolver` uses all configured implementations of
`ConfigSource` to lookup the property in question.

Each 'ConfigSource' has a specified 'ordinal' which can be configured
using the key `deltaspike_ordinal`. This ordinal get's used to determine
the importance of the values taken from the very ConfigSource. A higher
ordinal means that the values taken from this ConfigSource will override
values from less important ConfigSources. This is the trick which allows
to amend configuration from outside a binary - given those outside
ConfigSources have a higher `deltaspike_ordinal` than the ones who
pickup the values from within the release binaries.

=== ConfigSources Provided by Default

By default there are implementations for the following configuration sources
(listed in the lookup order):

* System properties (deltaspike_ordinal = 400)
* Environment properties (deltaspike_ordinal = 300)
* JNDI values (deltaspike_ordinal = 200, the base name is "java:comp/env/deltaspike/")
* Properties file values (apache-deltaspike.properties) (deltaspike_ordinal = 100, default filename is "META-INF/apache-deltaspike.properties")

*It is possible to change this order and to add custom configuration sources.*

.Important Tips Especially for Custom Implementations
TIP: - The config-source with the highest ordinal gets used first. - If a custom
implementation should be invoked _before_ the default implementations,
use an ordinal-value > 400. - If a custom implementation should be
invoked _after_ the default implementations, use an ordinal-value < 100.
- The `ConfigResolver` performs no caching. If your custom ConfigSource
operation is expensive, then you might think about introducing some
caching.

=== Reordering of the Default Order of ConfigSources

To change the lookup order, you have to configure the ordinal in the
corresponding configuration source (e.g. to change the configuration ordinal of the
configuration source for system properties, you have to set the system property
with the ordinal key 'deltaspike_ordinal' and the new value).

Example with `/META-INF/apache-deltaspike.properties`: If the properties
file/s should be used *before* the other implementations, you have to
configure an ordinal > 400. That means, you have to add for example
`deltaspike_ordinal=401`.

Each single property file is treated as own `ConfigSource` and thus can
have different `deltaspike_ordinal` values!

NOTE: In case of *property files* which are supported by default
(`/META-INF/apache-deltaspike.properties`) every file is handled as
independent config-source, but all of them have ordinal 400 by default
(and can be reordered in a fine-grained manner).

=== Custom ConfigSources

ConfigSources are picked up using the `java.util.ServiceLoader'
mechanism.

To add a custom config-source, you have to implement the interface
`ConfigSource` and register your implementation in a file
`/META-INF/services/org.apache.deltaspike.core.spi.config.ConfigSource`
by writing the fully qualified class name of the custom implementation/s
into it.

If you need dynamic ConfigSources you can also register a
`ConfigSourceProvider` in a similar way. This is useful if you like to
dynamically pick up multiple ConfigSources of the same kind. For example, if you
like to pick up all `myproject.properties` files from all the JARs in
your classpath.

Please note that a single `ConfigSource` should be either registered
directly or via a `ConfigSourceProvider`, but never both ways.

TIP: Have a look at the abstract base-implementation of `ConfigSource`
DeltaSpike is using internally, if a custom implementation should load
the ordinal value from the config-source like the default
implementations provided by DeltaSpike do.

==== PropertyFileConfig

For registering all your own property files of a certain name in your
classpath to get picked up as ConfigSources you can also provide a
class which implements the `PropertyFileConfig` interface.

The method `isOptional` indicates whether your custom property file is mandatory.
If a mandatory property file is not found during deployment, DeltaSpike throws
an `IllegalStateException` and stops the deployment.


[source,java]
---------------------------------------------------------------------
public class MyCustomPropertyFileConfig implements PropertyFileConfig
{
    @Override
    public String getPropertyFileName()
    {
        return "myconfig.properties";
    }

    @Override
    public boolean isOptional()
    {
        return false;
    }
}
---------------------------------------------------------------------

_Note: If you are using WildFly with EAR packaging and with
ear-subdeployments-isolated=true, then your EAR should have a deployment
dependency to the module that contains the property file._

[source,xml]
---------------------------------------------------------------------------------------------------
<jboss-deployment-structure>
    <ear-subdeployments-isolated>true</ear-subdeployments-isolated>
      <deployment>
            <dependencies>
            <!-- This module contains the custom PropertyFileConfig and the property file -->
                  <module name="deployment.yourproject.ear.yoursubmodule.jar"  meta-inf="import" />
            </dependencies>
     </deployment>
</jboss-deployment-structure>
---------------------------------------------------------------------------------------------------

== Filtering configured values

It is possible to perform filtering on all configured values on their way between the ConfigSource and user code.
This might be useful for example for decryption of values from an encrypted ConfigSource or to hide passwords from a
log.

DeltaSpike doesn't provide any filters by default but custom filters can be provided by implementing the
`ConfigFilter` interface. This is then enabled either using the ServiceLoader mechanism or by calling
`ConfigResolver.addConfigFilter(ConfigFilter)`. Provided ConfigFilters are then enabled for the whole application.

Once some filters are provided, all operations of ConfigResolver return filtered values.

.A custom ConfigFilter
[source,java]
-------------------------------------------------------------
public class DecryptingConfigFilter implements ConfigFilter
{
    @Override
    public String filterValue(String key, String value)
    {
        if (key.contains("encrypted"))
        {
            return decrypt(value);
        }
        return value;
    }

    @Override
    public String filterValueForLog(String key, String value)
    {
        return "<value encrypted>";
    }
}