> For the complete documentation index, see [llms.txt](https://www.andhowconfig.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.andhowconfig.org/simple-usage-examples.md).

# Simple Usage Examples

This page does some walk-throughs of simple code examples.  You might try the [Live-Code Quickstart](/live-code-quickstart.md) to try using AndHow right in the browser.  The Live-Code is more fun, but this page is much more comprehensive.

## Complete Usage Example

```java
package simple;
import org.yarnandtail.andhow.property.*;

public class HelloWorld {

  // 1 Declare AndHow Properties
  private static final StrProp NAME = StrProp.builder().defaultValue("Dave").build();
  public static final IntProp REPEAT_COUNT = IntProp.builder().defaultValue(2).build();

  public static void main(String[] args) {

    // 2 Use AndHow Properties
    for (int i = 0; i < REPEAT_COUNT.getValue(); i++) {
      System.out.println("Hello, " + NAME.getValue());
    }
  }
}
```

[>> Complete code <<](https://github.com/eeverman/andhow-samples/blob/homepage/01-hello-world/src/main/java/simple/HelloWorld.java)

### // 1 : Declare AndHow Properties

`StrProp` & `IntProp` are AndHow `Property`s. Properties and their values are constants, so they are always `static final` but may be `private` or any scope. Properties are ***strongly typed***, so their value, default value and validation are type specific.

### // 2 : Using AndHow Properties

Properties are used just like static final constants with `.getValue()` tacked on: `NAME.getValue()` returns a `String`, `REPEAT_COUNT.getValue()` returns an `Integer`.

The Properties in the example have defaults, so with no other configuration, running `HelloWorld.main()` will print **`Hello, Dave`** twice. One way (of many) to configure values is to add an `andhow.properties` file on the classpath like this:

```
# andhow.properties file at the classpath root

simple.HelloWorld.NAME: Kathy
SIMPLE.HELLOWWORLD.repeat_count: 4
```

Resulting in **`Hello, Kathy`** x4 - AndHow ignores capitalization when reading Property values. Unlike most configuration utilities, we didn't have to specify a 'name' for NAME. AndHow builds a logical name for each property by combining the canonical name of the containing class with the variable name, e.g.:\
&#x20;`[Java canonical class name].[AndHow Property name]` --> `simple.HelloWorld.NAME`\
&#x20;Thus, naming isn't something you have to worry about and Java itself ensures name uniqueness. Let's extends this example a bit...

## Adding validation and command line arguments

```java
package simple;  // Imports left out for simplicity

public class HelloWorld2 {

  // 1 Declare
  private static interface Config {
    StrProp NAME = StrProp.builder().mustStartWith("D").defaultValue("Dave").build();
    IntProp REPEAT_COUNT = IntProp.builder()mustBeGreaterThan(0)
      .mustBeLessThan(5).defaultValue(2).build();
  }

  public static void main(String[] args) {

    AndHow.findConfig().setCmdLineArgs(args);  //2 Add cmd line arguments

    // Use
    for (int i = 0; i < Config.REPEAT_COUNT.getValue(); i++) {
      System.out.println("Hello, " + Config.NAME.getValue());
    }
  }
}
```

[>> Complete code <<](https://github.com/eeverman/andhow-samples/blob/homepage/02-hello-world-better/src/main/java/simple/HelloWorld2.java)

### // 1 : Declare AndHow Properties with validation

`Property` values can have validation. At startup, AndHow ***discovers and validates all Properties in your entire application***, ensuring that a mis-configuration application [*fails fast*](https://www.martinfowler.com/ieeeSoftware/failFast.pdf) at startup, rather than mysteriously failing later.

Placing `Property`'s in an interface is best practice for organization and access control. Only code able to 'see' a `Property` can retrieve its value - standard Java visibility rules. Fields in an interface are implicitly `static final`, saving a bit of typing.

### // 2 : Add command line arguments

AndHow loads Property values from several configuration sources in a [well established order](https://sites.google.com/view/andhow/user-guide/value-loaders). At startup, AndHow scans `System.Properties`, environment variables, JNDI values, the `andhow.properties` file, etc., automatically.

Reading from commandline requires a bit of help from the application. The code `AndHow.findConfig().setCmdLineArgs(args);` passes the command line arguments in to AndHow.

Running from cmd line to set `NAME` to 'Dar' would look like this:

```bash
  java -Dsimple.HelloWorld2.Config.NAME=Dar -cp [classpath] simple.HelloWorld2
```

What happens if we try to set NAME to "Bar" and violate the 'D' validation rule? AndHow throws a `RuntimeException` to stop app startup and prints a clear message about the cause:

```
================================================================================
== Problem report from AndHow!  ================================================
================================================================================
Property simple.HelloWorld2.Config.NAME loaded from string key value pairs:
  The value 'Bar' must start with 'D'
================================================================================
A configuration template for this application has been written to: [...tmp file location...]
```

AndHow uses Property metadata to generate precise error messages. When errors prevent startup, AndHow also creates a *configuration template* with all your application's `Property`s, validation requirements, types, defaults and more. Here is what that would look like for this app:

```
==/==/==/==/==/== Excerpt from a configuration template ==/==/==/==/==/==
# NAME (String)
# Default Value: Dave
# The property value must start with 'D'
simple.HelloWorld2.Config.NAME = Dave

# REPEAT_COUNT (Integer)
# Default Value: 2
# The property value must be less than 5
simple.HelloWorld2.Config.REPEAT_COUNT = 2
```

You can create a configuration template on demand by setting the `AHForceCreateSamples` flag:  `java -DAHForceCreateSamples=true -cp [classpath] simple.HelloWorld2`

Let's look at a larger, more enterprise-y example.

## Example with a database connection, aliases and exports

In this example, assume we need to configure an ORM framework like [Hibernate](http://hibernate.org). 3rd party frameworks have their own configuration property names and typically accept properties as a `Map` or `util.Properties`. This example is in two parts: A Handler class which might be an AWS Lambda, and a DAO (Data Access Object) which stores data to a DB using Hibernate.

```java
package simple;  // Both classes are in 'simple'.  Imports left out for simplicity.

public class SaleHandler {

  // 1 Declare configuration Property's for this class
  public static interface Config {
    BigDecProp TAX_RATE = BigDecProp.builder().mustBeGreaterThan(BigDecimal.ZERO)
        .mustBeNonNull().desc("Tax rate as a decimal, eg .10").aliasIn("tax").build();
  }

  public Object handle(BigDecimal saleAmount) throws Exception {

    // TAX_RATE.getValue() returns a BigDecimal
    BigDecimal tax = saleAmount.multiply(Config.TAX_RATE.getValue());
    return new SaleDao().storeSale(saleAmount.add(tax));
  }
}
```

[>> Complete code <<](https://github.com/eeverman/andhow-samples/blob/homepage/99-larger-example/src/main/java/simple/SaleHandler.java)

### // 1 : Declare configuration Property's for this class

AndHow best practice: ***Place Properties in the class that uses them***.  This makes intuitive sense and there is no need to gather them all into a central *Config* class - AndHow will find, load and validate them all ***and*** create a configuration template listing them all.

The `TAX_RATE` Property uses `.aliasIn("tax")`, which adds an alternate name recognized when reading this property from a configuration source. Handy for values that may need to be specified on cmd line.

Lets look at how the DAO class uses AndHow:

```java
public class SaleDao {

  // 2 Declare DB connection Properties
  @ManualExportAllowed
  private static interface Db {
    StrProp URL = StrProp.builder().mustStartWith("jdbc://").mustBeNonNull()
        .aliasInAndOut("hibernate.connection.url").build();
    StrProp PWD = StrProp.builder().mustBeNonNull()
        .aliasInAndOut("hibernate.connection.password").build();
  }

  // 3 Export Db properties to java Properties instance
  java.util.Properties getExportedConfig() throws Exception {
    Properties props = AndHow.instance().export(Db.class)
        .collect(ExportCollector.stringProperties(""));

    return props;
  }

  // Pretend database storage call
  Object storeSale(Object sale) throws Exception {
    Hibernate h = new Hibernate(getExportedConfig());
    return h.save(sale);
  }
}
```

[>> Complete code <<](https://github.com/eeverman/andhow-samples/blob/homepage/99-larger-example/src/main/java/simple/SaleDao.java)

### // 3 : Declare DB connection Properties

The Properties bundled together in `Db` are annotated with `@ManualExportAllowed`, allowing them to be exported to a `Map` or other structure. `.aliasInAndOut()` adds an *in* name just like 'tax' above, but the name is also used when exporting (out).

### // 4 : Export Db properties to a java.util.Properties instance

Property exports use the Java `stream()` API. Exports are done at the class level: `AndHow.instance().export(class...)` specifies one or more `@ManualExportAllowed` annotated classes containing AndHow Properties. `ExportCollector` has collectors to turn a stream of Properties into collections: `ExportCollector.stringProperties("")` turns AndHow Properties into `java.util.Properties` with String values (using "" for null values).

Since we specified alias *out* names for the Db Properties, the *Hibernate* compatible aliases are used for the export. AndHow provides validation at startup, configuration from multiple sources, and more... and can do that for 3rd party frameworks!

## Testing Applications with AndHow

AndHow makes testing with multiple configurations easy. Let's test the `SaleHandler` from above and assume an \`andhow\.properties' file like this:

```
simple.SaleDao.Db.PWD = changeme
simple.SaleDao.Db.URL = jdbc://mydb
simple.SaleHandler.Config.TAX_RATE = .11
```

We can verify the tax rate is set as expected:

```java
  @Test  //This verifies that the tax rate is .11 from the andhow.properties file
  public void defaultConfigTaxRateShouldBe_11Percent() throws Exception {
    SaleHandler handler = new SaleHandler();

    // Total sale should be 10.00 + (10.00 * .11)
    assertEquals(new BigDecimal("11.10"), handler.handle(BigDecimal.TEN));
  }
```

Now lets test the handler with the tax rate configured to 12%:

```java
  @Test @KillAndHowBeforeThisTest  // 1 'Kill' the current AndHow configuration
  public void verifyTaxRateAt_12Percent() throws Exception {

    // 2 Set a new configured value for TAX_RATE
    AndHow.findConfig().addFixedValue(SaleHandler.Config.TAX_RATE, new BigDecimal(".12"));

    SaleHandler handler = new SaleHandler();

    // Total sale should be 10.00 + (10.00 * .12)
    assertEquals(new BigDecimal("11.20"), handler.handle(BigDecimal.TEN));
  }  // 3 Cleanup after the test
```

[>> Complete code <<](https://github.com/eeverman/andhow-samples/blob/homepage/99-larger-example/src/test/java/simple/SaleHandlerTest.java)

### // 1 : 'Kill' the current AndHow configuration

The annotation `@KillAndHowBeforeThisTest` erases AndHow's state before the test.

### // 2 : Set a new configured value for TAX\_RATE

`AndHow.findConfig()` grabs the configuration of AndHow itself to add a 'fixed value' for `TAX_RATE`, ignoring any other configured value for that property.

### // 3 : Cleanup after the test

The tax rate is `.12` just for this test. When the test is done, AndHow is restored to its previous state. This isn't allowed in production: Remember, ***AndHow Property values are constant and once initialized at startup, do not change***. The `@KillAndHow...` annotation uses reflection to bend the rules to make testing easy.

***&?!***
