This guide provides detailed instructions for setting up your development environment to work on Otto Config.
- Java 21 or later
- Gradle (wrapper included)
- Docker (optional, for local Vault testing)
- AWS CLI configured (for AWS integration testing)
- Git
# Clone the repository
git clone https://github.com/otto-de/otto-config.git
cd otto-config
# Build the project
./gradlew clean build
# Run tests
./gradlew test
# Generate JavaDoc
./gradlew javadocWhen developing or testing Otto Config locally, you can use file-based configuration sources instead of connecting to AWS or Vault.
Create src/main/resources/properties.json in your application or demo project:
{
"properties": {
"database.url": "jdbc:h2:mem:testdb",
"feature.search.enabled": "true",
"cache.timeout": "3600"
},
"toggles": {
"new_feature": { "enabled": true },
"beta_ui": { "enabled": false }
}
}Configure your application to use the local profile:
Spring Boot:
--spring.profiles.active=localHelidon:
-Dmp.config.profile=localPlain Java:
System.setProperty("otto.config.profile", "local");Via Environment Variable:
export OTTO_CONFIG_SOURCES_ENABLED=fileWith the local profile set, Otto Config will automatically load configuration from your local properties.json file. This allows you to test configuration changes without connecting to external services.
Otto Config includes three demo projects showcasing integration with different frameworks:
cd demo/java
./gradlew runcd demo/spring
./gradlew bootRun --args='--spring.profiles.active=local'cd demo/helidon
./gradlew run -Pmp.config.profile=localFor testing Hashicorp Vault integration locally:
# From project root
./demo/ci/start_vault.shThis script:
- Starts Vault in dev mode on
http://localhost:8200 - Configures AppRole authentication
- Sets up test secrets
- Outputs the
VAULT_ROLE_IDandVAULT_SECRET_IDfor use in your application
./demo/ci/stop_vault.shCreate .vscode/tasks.json to start Vault automatically:
{
"version": "2.0.0",
"tasks": [
{
"label": "vault",
"type": "shell",
"command": "${workspaceFolder}/demo/ci/start_vault.sh",
"problemMatcher": []
}
]
}Create .vscode/launch.json for debugging demo applications:
{
"version": "0.2.0",
"configurations": [
{
"type": "java",
"name": "Java Demo",
"request": "launch",
"mainClass": "de.otto.config.demo.Main",
"projectName": "java",
"env": {
"OTTO_CONFIG_HASHICORP_VAULT_AUTH_TYPE": "approle",
"OTTO_CONFIG_HASHICORP_VAULT_URL": "http://localhost:8200",
"OTTO_CONFIG_SOURCES_ENABLED": "file"
},
"preLaunchTask": "vault"
},
{
"type": "java",
"name": "Spring Boot Demo",
"request": "launch",
"mainClass": "de.otto.config.demo.DemoApplication",
"projectName": "spring",
"args": [
"--spring.profiles.active=local"
],
"env": {
"OTTO_CONFIG_HASHICORP_VAULT_AUTH_TYPE": "approle",
"OTTO_CONFIG_HASHICORP_VAULT_URL": "http://localhost:8200",
"OTTO_CONFIG_SOURCES_ENABLED": "file"
},
"preLaunchTask": "vault"
},
{
"type": "java",
"name": "Helidon Demo",
"request": "launch",
"mainClass": "io.helidon.microprofile.cdi.Main",
"projectName": "helidon",
"vmArgs": "-Dmp.config.profile=local",
"env": {
"OTTO_CONFIG_HASHICORP_VAULT_AUTH_TYPE": "approle",
"OTTO_CONFIG_HASHICORP_VAULT_URL": "http://localhost:8200",
"OTTO_CONFIG_SOURCES_ENABLED": "file"
},
"preLaunchTask": "vault"
}
]
}Create a .env file in the project root (add to .gitignore):
# For local Vault testing (get these values from start_vault.sh output)
VAULT_ROLE_ID=your-role-id-here
VAULT_SECRET_ID=your-secret-id-here
# AWS Configuration (for AWS integration testing)
# AWS_PROFILE=your-profile-name
# AWS_REGION=us-east-1
# Optional: AWS resource ARNs for testing
# OTTO_CONFIG_AWS_SECRETS_ARN=arn:aws:secretsmanager:...
# OTTO_CONFIG_AWS_SSM_PATH_PREFIX=/your/pathUse the built-in file-based configuration:
- Create
src/main/resources/properties.jsonin your demo project - Set profile to
localortest - Run the application
{
"properties": {
"database.url": "jdbc:h2:mem:testdb",
"feature.enabled": "true"
},
"toggles": {
"new_feature": { "enabled": true }
}
}To test with real AWS services:
-
Configure AWS credentials:
aws configure
-
Deploy test infrastructure:
cd demo/terraform terraform init terraform apply -
Update your environment variables with the created resource ARNs
-
Run the demo with AWS sources enabled:
OTTO_CONFIG_SOURCES_ENABLED=aws.appconfig.properties,aws.secrets,aws.ssm ./gradlew bootRun
otto-config/
├── src/main/java/de/otto/config/
│ ├── core/ # Core interfaces and implementations
│ ├── integration/ # Framework integrations (Spring, Helidon)
│ └── source/ # Configuration source implementations
├── src/test/java/ # Unit and integration tests
├── demo/
│ ├── java/ # Plain Java demo
│ ├── spring/ # Spring Boot demo
│ ├── helidon/ # Helidon demo
│ └── terraform/ # Test infrastructure
├── docs/ # Documentation
└── gradle/ # Gradle configuration
# Run all tests
./gradlew test
# Run tests for a specific module
./gradlew :demo:spring:test
# Run with coverage
./gradlew test jacocoTestReport
# Run integration tests (requires AWS credentials)
./gradlew integrationTestThe project uses:
- Lombok for reducing boilerplate
- SLF4J for logging
- Standard Java naming conventions
Run the formatter before committing:
./gradlew spotlessApplyAdd to application.properties or logback.xml:
logging.level.de.otto.config=DEBUGIssue: Vault connection failed
- Solution: Ensure Vault is running (
./demo/ci/start_vault.sh)
Issue: AWS credentials not found
- Solution: Run
aws configureor setAWS_PROFILEenvironment variable
Issue: Tests failing with SourceException
- Solution: Check that local profile is active or test resources exist
Issue: VS Code - Application properties not loading (resources not found)
- Root Cause: VS Code's Java extension uses the
bin/directory (Eclipse-style) for compiled classes and resources, while Gradle usesbuild/. When debugging from VS Code, the application can't find resources because they're only inbuild/resources/and not inbin/. - Solution: The project includes Gradle tasks (
syncResourcesToVSCodeandsyncTestResourcesToVSCode) that automatically copy resources frombuild/resources/tobin/after processing. These run automatically when you build or run./gradlew processResources. - Manual Trigger: If resources are stale, run
./gradlew processResources processTestResources - Note: This issue is specific to VS Code's Java extension and does not occur in IntelliJ IDEA or production environments
See CONTRIBUTING.md for contribution guidelines.
- Open an issue
- Contact the maintainers (see MAINTAINERS)