= Meecrowave Configuration
:jbake-date: 2016-10-24
:jbake-type: page
:jbake-status: published
:jbake-meecrowavepdf:
:jbake-meecrowavetitleicon: icon icon_puzzle_alt
:jbake-meecrowavecolor: body-blue
:icons: font

Meecrowave configuration is centralized in `org.apache.meecrowave.Meecrowave$Builder` class.

Here are the main properties:

include::../../../../../target/generated-doc/Configuration.adoc[]

NOTE: the class also provides some helper methods for programmatic use case like `randomHttpPort()`
to automatically set an available port to `httpPort`.

You can also write a `Consumer<Builder>` to configure programmatically the `Builder`
and make it active using `addCustomizer(Consumer<Builder>)`.

Example:

[source,java]
----
new Meecrowave(new Builder() {{
        randomHttpPort();
        setTomcatScanning(false);
        setTomcatAutoSetup(false);
        setRealm(new JAASRealm());
        user("admin", "secret");
     }})
    .bake()
    .await();
----

== CDI SE API

CDI 2.0 introduces a "SE API" for CDI. It looks like:

[source,java]
----
try (final SeContainer container = SeContainerInitializer.newInstance()
        .disableDiscovery()
        .addBeanClasses(Configured.class)
        .initialize()) {
    // your main
}
----

Meecrowave inherits from OpenWebBeans SE API implementation and therefore this SE API will work out of the box.

It is implemented as a `bake()` and you can still access the `Builder` configuration or even `Meecrowave` itself if needed:

[source,java]
----
try (final SeContainer container = SeContainerInitializer.newInstance()
        .disableDiscovery()
        .addBeanClasses(Configured.class)
        .initialize()) {

    // use the configuration to access extensions, custom config or even server port
    Configuration config = container.select(Configuration.class).get();
    // or
    Meecrowave.Builder config2 = container.select(Meecrowave.Builder.class).get();
    int port = config.getHttpPort();

    // default wait implementation relying on tomcat one
    container.select(Meecrowave.class).get().await(); // wait for the program to be killed (tomcat.await() equivalent)

}
----

All the configuration of meecrowave is still available using properties:

[source,java]
----
try (final SeContainer container = SeContainerInitializer.newInstance()
     .addProperty("nameOfTheProperty", instanceInTheRightType)
     .initialize()) {
    container.select(Meecrowave.class).get().await();
}
----

The type should match the type expected by the `Builder` instance. Note you can also just pass directly a `Builder` instance as value
(the property name is not important) if you want something preconfigured:

[source,java]
----
try (final SeContainer container = SeContainerInitializer.newInstance()
     .addProperty("meecrowaveConfiguration", new Meecrowave.Builder().randomPort())
     .initialize()) {
    container.select(Meecrowave.class).get().await();
}
----

== Automatic configuration

The `org.apache.meecrowave.Meecrowave$Builder` class also provides `loadFromProperties(Properties)`
and `loadFrom(String)`. The last one uses the parameter to locate a propertiers file (file path or at classpath)
and delegate the processing to the first one.

`loadFromProperties(Propertiers)` loads the configuraton from the properties.

The matching is alsmot 1-1 with previous table excepted for these entries:

- if `httpPort` is `-1` then `randomHttpPort` is called
- `properties.x=y` will set the property (`properties` entry) `x` with the value `y`
- `users.x=y` will create the user `x` with the password `y`
- `roles.x=y` will create the role `x` with the users `y` (comma separated if multiple users)
- `cxf.servlet.params.x=y` will force the CXF servlet init parameter `x` to be `y`
- `connector.x=y` will pass the property `x` to be `y` on the connector.
 See the https://tomcat.apache.org/tomcat-9.0-doc/config/http.html[Apache Tomcat 9 Connector Documentation]
- `connector.attributes.x=y` will use the property `x` with value `y` to create the connector (set a property on the instance of ̀`org.apache.catalina.connector.Connector`)
 See the Connector attributes referenced in the  https://tomcat.apache.org/tomcat-9.0-doc/config/http.html[Apache Tomcat 9 Connector Documentation]
- `valves.*` will be used to create valves. This prefix must be followed by a valve identifier then you can use the
built-in virtual attributes. These ones are `_order` to sort the valves (natural order) and `_className` to specify the class to instantiate.
Finally you can use any dotted attribute to configure the valve (see example after this list).
- `realm=y` will create an instance of `y` (qualified name of the class) as `realm`
- `realm.x=y` will set `x` property to `y` - needs previous property to be set
- `login=` will create a custom `org.apache.meecrowave.Meecrowave$LoginConfigBuilder`
- `login.x=y` will customize previous instance with `x` property
- `securityConstraint=` will create a custom `org.apache.meecrowave.Meecrowave$SecurityConstaintBuilder`
- `securityConstraint.x=y` will customize previous instance with `x` property
- `configurationCustomizer=y` will create an instance of `y` to customize the configuration
- `configurationCustomizer.x=y` will set `x` to `y` for the customizer

TIP: Out of the box, any `Builder` instance will read `meecrowave.properties`.
`meecrowave.properties` uses CLI names (without the leading `--`). It loads all available files from the classpath,
they are merged using `configuration.ordinal` key (exactly like Apache OpenWebBeans does for its configuration).
It also supports `configuration.complete=[true|false]` which enables a single file to host it with the `true` value
and will consider this file as the merged result of all potential files found in the classpath. It is useful to
avoid an implicit merging and can typically be used in `conf/meecrowave.properties` in bundle mode.
See link:{context_rootpath}/meecrowave-core/cli.html[CLI] page for the list.

=== Valve configuration

Here is an example to configure the `RemoteIpValve` and `LoadBalancerDrainingValve` using the `meecrowave.properties` syntax (which means
it uses the `properties.` prefix to specify properties, drop it if you use the CLI options):

[source,properties]
----
properties.valves.remote-ip._order = 1
properties.valves.remote-ip._className = org.apache.catalina.valves.RemoteIpValve
properties.valves.remote-ip.internalProxies = 192\\.168\\.0\\.10\|192\\.168\\.0\\.11
properties.valves.remote-ip.remoteIpHeader = x-forwarded-for
properties.valves.remote-ip.proxiesHeader = x-forwarded-by
properties.valves.remote-ip.trustedProxies = proxy1|proxy2

properties.valves.draining._order = 2
properties.valves.draining._className = org.apache.catalina.valves.LoadBalancerDrainingValve
properties.valves.draining.redirectStatusCode = 307
properties.valves.draining.ignoreCookieName = draining-action
properties.valves.draining.ignoreCookieValue = skip
----

This will define the `remote-ip` and `draining` valves in this order with the configuration defined thanks to the
properties not having an underscore at the beginning of their name.

== Logging

Meecrowave relies by default on Log4j2 (see http://logging.apache.org/log4j/2.x/). By default it uses an internal
configuration which is overridden by standard log4j mechanism.

== Passwords/Secrets

For the configuration requiring to be ciphered you can implement `org.apache.meecrowave.service.ValueTransformer`:

[source]
----
public class MyTransformer implements ValueTransformer {
    @Override
    public String name() {
        return "mine";
    }

    @Override
    public String apply(final String encodedPassword) {
        return ....;
    }
}
----

NOTE: this code being executed before the container starts you can't use CDI there.

To register your implementation just put the fully qualified name of your transformer in `META-INF/services/org.apache.meecrowave.service.ValueTransformer`.

Then to use it set the value to `decode:mine:encodedvalue`. General pattern is: `decode:<transformer name>:<value before decryption>`.

Note that by default the same ciphering algorithm than in TomEE is available (Static3DES).

This syntax is usable on the command line and in `meecrowave.properties`.

== Programmatic customization

`org.apache.meecrowave.Meecrowave$ConfigurationCustomizer` can be used to customize the configuration
programmatically before startup. It will take the `Builder` as parameter and you can change it at that moment.

`org.apache.meecrowave.Meecrowave$InstanceCustomizer` can be used to customize the configuration
programmatically before startup. It will take the `Tomcat` as parameter and you can change it at that moment. This
is very useful to automatically add valves and things like that.
