//
// 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.
//

# Configuration for Java SE and EE

## Status

Implementation of the MicroProfile Config Specification Proposal.

== Rational

Many project artifacts (e.g. WAR, EAR) should only be created once and then get installed at different customers, stages, etc
They need to target those different execution environments without necessity of any repackaging.
In other words: depending on the situation they need different configuration.

This is easily achievable by having a set of default configuration values inside the project artifact.
But be able to overwrite those default values from external.

== History

This very configuration approach has it's roots in the Apache OpenWebBeans internal SPI configuration.
In 2010 it got moved over to the Apache MyFaces CODI project and enhanced to also fit the need of customer projects by Gerhard Petracek and Mark Struberg.
In 2011 we further enhanced it while moving CODI to the Apache DeltaSpike project.
Romain Manni-Bucau (Apache/Tomitribe), Ron Smeral (JBoss) and Anatole Tresch also gave appreciated input in the last years.

== How it works

A 'Configuration' consists of the information collected from the registered `ConfigSource` s.
These `ConfigSource`s get sorted according to their _ordinal_.
That way it is possible to overwrite configuration with lower importance from outside.

By default there are 3 default ConfigSources:

* `System.getenv()` (ordinal=400)
* `System.getProperties()` (ordinal=300)
* all `META-INF/microprofile-config.properties` files on the ClassPath. (ordinal=100, separately configurable via a config_ordinal property inside each file)

That means that I can put my default configuration in a `META-INF/microprofile-config.properties` anywhere on the classpath.
And I can later simply e.g set a system property to change this default configuration.

== Custom ConfigSources

It is possible to write and register custom `ConfigSource` s.
An example would be a ConfigSource which gets the configured values from a shared database table in a cluster.

== Building

`$> mvn clean install`

== Config API

The MicroProfile Config API and further information can be found at

https://github.com/eclipse/microprofile-config/

The API is also available as Maven Artifact

[source,xml]
----
<dependency>
    <groupId>org.eclipse.microprofile.config</groupId>
    <artifactId>microprofile-config-api</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
----

