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

***&?!***


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.andhowconfig.org/simple-usage-examples.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
