   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

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

-------------------------------------------------------------------------------
# README for Apache Fortress Configuration Subsystem
-------------------------------------------------------------------------------

## Table of Contents

 * SECTION 1. Fortress Configuration Subsystem Overview.
 * SECTION 2. Fortress Ant Property Files.
 * SECTION 3. Fortress Configuration Artifacts.
 * SECTION 4. Fortress Configuration Overrides.
 * SECTION 5. Order Artifacts found in the Fortress Configuration Subsystem.
 * SECTION 6. Configuration Subsystem Usage.

-------------------------------------------------------------------------------
## SECTION 1.  Fortress Configuration Subsystem Overview

Fortress uses interpolation to weave values located in source property files into target configuration files.
The list of possible parameters here: [README-PROPERTIES](./README-PROPERTIES.md) 

A. Option files containing environment specific values:
 - user.properties
 - [slapd.properties](./slapd.properties.example)
 - [build.properties](./build.properties.example)

B. Source files containing substitution expressions :
 - [fortress.properties.src](./config/fortress.properties.src)
 - [refreshLDAPData.xml.src](./ldap/setup/refreshLDAPData-src.xml)

C. Target files generated by Fortress:
 - [fortress.properties](./config/fortress.properties)
 - [refreshLDAPData.xml](./ldap/setup/refreshLDAPData.xml)

D. Apache Ant script with the mapping rules: A -> B = C:
 - [build-config.xml](./build-config.xml)

  The substitution parameters found in B, as **@name@**, are placeholders for the actual values found in A.  
  These are used by an Ant config task (D) to replace values into the actual files (C) needed by Fortress runtime.
  This interpolation process seeds implementation specific variables into configuration targets. 
  For example, host names, ports, pw's (ldap server coordinates) are loaded into the target, fortress.properties.
  
For Example:

A. Snip from [build.properties](./build.properties)
```
# These parameters point fortress to LDAP host:
ldap.host=ldapvip.net
ldap.port=389

# This is default, tells fortress what type of ldap server in use:
ldap.server.type=openldap
```

B. Snip from [fortress.properties.src](./config/fortress.properties.src)
```
# Host name and port of LDAP DIT:
host=@LDAP_HOST@
port=@LDAP_PORT@

# Options are openldap or apacheds (default):
ldap.server.type=@SERVER_TYPE@
```

C. Becomes snip from [fortress.properties](./config/fortress.properties):
```
# Host name and port of LDAP DIT:
host=ldapvip.net
port=389

# Options are openldap or apacheds (default):
ldap.server.type=openldap
```
- Note: Files from C are generated during build (```mvn install```) and not checked in as source.*

-------------------------------------------------------------------------------
## SECTION 2.  Fortress Ant Property Files

```
    _______________                
   ╱               ╲          ┌─────┐
  ╱                 ╲_________│ Use │
  ╲ user.properties ╱yes      └─────┘
   ╲_______________╱                                   
           │no                                               
           │                       
    _______▽________               
   ╱                ╲         ┌─────┐     
  ╱                  ╲________│ Use │     
  ╲ slapd.properties ╱yes     └─────┘     
   ╲________________╱                   
           │no                          
           │                     
  ┌────────▽───────────┐             
  │Use build.properties│             
  └────────────────────┘
```

Fortress configuration artifacts are seeded using Ant property files.
 - user.properties  - optional, when found, located in user's home directory.  Properties found here take precedence over those following.
 - slapd.properties - optional, when found, located in root folder of the package.  These props override those found in the build.properties file.
 - build.properties - this file is required and must be located in the root folder of the package.

-------------------------------------------------------------------------------
## SECTION 3.  Fortress Configuration Artifacts

The ant config task, **init-fortress-config**, uses the values found within the Ant property files to seed into the following targets:.
 * fortress.properties - contains name/value pairs inside of a property file.
 * refreshLDAPData.xml - load script to shape DIT and add fortress properties to a remote ldap entry.
 * slapd.conf files - (optional) used to bind fortress to openldap.

-------------------------------------------------------------------------------
## SECTION 4.  Fortress Configuration Overrides

### Optional - Used to override fortress properties at runtime.

 These fortress properties may be overridden at runtime by setting as Java System Properties:
 
 | system property name              | description                                                             | default  values                                                       |
 | --------------------------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------------- |
 | fortress.host                     | Hostname or ip address of ldap server                                   | localhost                                                             |
 | fortress.port                     | Port for the ldap server                                                | openldap:389, apacheds: 1389                                          |
 | fortress.admin.user               | Service account for access to ldap server                               | openldap: cn=manager,dc=example,dc=com, apacheds: uid=admin,ou=system |
 | fortress.admin.pw                 | service account password                                                | secret                                                                |
 | fortress.min.admin.conn           | minimum ldap a|min pool connections                                     | 1                                                                     |
 | fortress.max.admin.conn           | maximum ldap admin pool connections                                     | 10                                                                    |
 | fortress.enable.ldap.ssl          | true indicates LDAPS connectivity                                       | false                                                                 |
 | fortress.enable.ldap.ssl.debug    | true will output additional info to log                                 | false                                                                 |
 | fortress.trust.store              | Name of truststore (if on classpath) otherwise fully qualified name.    |                                                                       |
 | fortress.trust.store.password     | The password for Java truststore containing server certificate.         | none                                                                  |    
 | fortress.trust.store.onclasspath  | true indicates truststore is in Java classpath.                         | true                                                                  |
 | fortress.suffix                   | The suffix is the toplevel LDAP node of the Directory Information Tree. | dc=example,dc=com                                                     |
 | fortress.config.realm             | The name of the configuration node in LDAP.                             | Default                                                               |                                          
 | fortress.config.root              | The DN that points to the base of the LDAP config node.                 | ou=Config,dc=example,dc=com                                           |
 | fortress.is.arbac02               | Used in Apache Fortress Rest and Web to enforce administrative RBAC.    | false                                                                 |
 | fortress.ldap.server.type         | Used for non-standard processing like password policies and audits.     | Valid values: apacheds, openldap or other                             |
 
 The minimum system.properties to enable fortress apis to work (without a config file):
  * fortress.admin.user
  * fortress.admin.pw=secret
  * fortress.config.root=ou=Config,dc=example,dc=com

 If the ldap host and/or port are not the default (openldap localhost:389) or (apacheds localhost:1389) set these:
 * fortress.host
 * fortress.port
___________________________________________________________________________________
## SECTION 5.  Order of precedence of params in the Fortress Configuration Subsystem

```
    ___________                
   ╱           ╲          ┌────┐
  ╱             ╲_________│Use │
  ╲ config node ╱yes      └────┘
   ╲___________╱                
           │no                     
           │     
    _______▽_________               
   ╱                 ╲      ┌────┐     
  ╱                   ╲_____│Use │     
  ╲ system properties ╱yes  └────┘     
   ╲________________╱             
           │no                     
           │ 
  ┌────────▽──────────────┐             
  │Use fortress.properties│             
  └───────────────────────┘
```

This subsystem has been hard-wired to the following order of precedence:
 1. LDAP configuration node - found by config coordinates set in the fortress.properties or system properties.
 2. Java system properties - to override any of the 14 properties listed above.
 3. fortress.properties file - found on the classpath of that name.

Properties found in LDAP config node will override Java system properties which will override fortress.properties.
__________________________________________________________________________________
## SECTION 6.  Configuration Subsystem Usage

### How it works:
 - The general flow is the fortress.properties provide the coordinates to locate an ldap entry on a remote server.
 - That file is found on the runtime classpath during startup.  Some of its props may be overridden as Java system properties.
 - The combination of Fortress and Java system properties are used to connect to remote ldap server and read its configuration entry where the remainder of Fortress' properties are stored.

The remote server node's dn is constructed from fortress.property values:
```properties
config.realm=DEFAULT
config.root=ou=Config,@SUFFIX@
```

The above would be combined to create the dn: cn=Default, ou=Config, [whatever the @SUFFIX@ is]

When reinitialization of properties is needed, to the ldap config node or the DIT itself, re-run this command:
```bash
# mvn install
```

Followed by A:
 ```bash
 mvn install -Dload.file=./ldap/setup/refreshLDAPData.xml
 ```

Or B:
 ```bash
 mvn install -Dload.file=./ldap/setup/ConfigNodeUpdate.xml
 ```

A. refreshes the entire LDAP server DIT, deletes of all entries under the suffix, recreating the DIT node structure, and re-adding of the config node.
B. just updates the config node with the new values, preserving the other data.

### More notes:
 - Use caution when running the **refreshLDAPData.xml** script.  It deletes all nodes below the suffix before readding.
 - To change values in a config node, use a general purpose ldapbrowser.  Fortress has config apis for this (ConfigMgr) to perform CRUD on config data.
 - Another option is to use a script like **ConfigNodeUpdate.xml** to perform the CRUD ops.
 - For more info on which parameters are used where, look at the **init-fortress-config** target located inside the [build-config.xml](build-config.xml) file.

### Config Node Rationale:
 - The idea is to minimize the number of locations  where the same data must be stored.  
 - Imagine a network with hundreds, even thousands of fortress agents running.  We don't need to replicate the same data everywhere which is where remote config nodes help.

### A final note about Config Node:
 - You can also *simply* place the properties inside the fortress.properties file (only).
 - To disable config node completely, remove the config.realm property, or set its value to empty.:

```properties
# Setting this to empty will disable the remote Config Node
config.realm=
```
___________________________________________________________________________________
#### END OF README-CONFIG
