Skip to main content
Version: v0.13

Configuration Providers

The configuration system uses property sources (also called providers) to supply configuration values. Multiple providers can be active simultaneously, with values resolved by priority order.

Available Providers

ProviderModulePriorityDescription
Environment VariablesIDK CoreHighestSystem environment variables
System PropertiesIDK CoreHighJVM -D properties
Azure App ConfigurationEDKHighCloud-based configuration from Azure
REST Config ClientEDKHighConfiguration from a REST API server
Database (PostgreSQL)VDXMediumPersisted settings in PostgreSQL
Database (MySQL)VDXMediumPersisted settings in MySQL
Database (SQLite)VDXMediumPersisted settings in SQLite
Properties FilesIDK CoreLowapplication-{profile}.properties
Programmatic MapsIDK CoreLowestCode-defined configuration

Auto-Registration

Providers are automatically registered when their module is on the classpath. You don't need to write any code to enable them - just add the dependency and configure connection details.

build.gradle.kts
dependencies {
// Adding this dependency automatically enables Azure App Configuration
implementation("com.sphereon.edk:lib-conf-azure-app-config:$version")

// Adding this enables REST-based configuration
implementation("com.sphereon.edk:lib-conf-config-rest-client:$version")
}

When the application starts, the PropertySourceBootstrap service:

  1. Discovers all available providers via dependency injection
  2. Checks if each provider is enabled (via configuration)
  3. Registers enabled providers with the appropriate ConfigService
  4. Initializes providers that need async setup (like cloud providers)

Enabling and Disabling Providers

Each provider has a unique ID used to control whether it's enabled:

ProviderProvider IDEnable/Disable Key
Azure App Configazure-app-configconfig.providers.azure-app-config.enabled
REST Config Clientrest-configconfig.providers.rest-config.enabled
PostgreSQL Databasepostgresql-dbconfig.providers.postgresql-db.enabled
MySQL Databasemysql-dbconfig.providers.mysql-db.enabled
SQLite Databasesqlite-dbconfig.providers.sqlite-db.enabled

Disabling a Provider

Providers are enabled by default when their module is on the classpath. To disable a provider:

# Disable Azure App Configuration
export CONFIG_PROVIDERS_AZURE_APP_CONFIG_ENABLED=false

# Disable database provider
export CONFIG_PROVIDERS_POSTGRESQL_DB_ENABLED=false

Conditional Enablement

Some providers only enable themselves when properly configured. For example, Azure App Configuration only registers if connection details are provided:

# Azure provider enables itself when these are set
export AZURE_APPCONFIG_CONNECTION_STRING=Endpoint=https://myconfig.azconfig.io;...

# Or using endpoint + managed identity
export AZURE_APPCONFIG_ENDPOINT=https://myconfig.azconfig.io

Built-in Providers (IDK Core)

These providers are always available in IDK applications.

Environment Variables

Automatically reads all system environment variables. Keys are converted:

  • API_BASE_URLapi.base.url
  • Uppercase with underscores → lowercase with dots

Priority: Highest (always wins)

System Properties

Reads JVM system properties set via -D flags:

java -Dapi.base.url=https://api.example.com -jar myapp.jar

Priority: High

Properties Files

Reads application-{profile}.properties from the classpath:

application-production.properties
api.base.url=https://api.production.example.com
http.timeout.ms=30000

The profile is set during app initialization via profile parameter.

Priority: Low

Programmatic Maps

Add configuration programmatically using MapPropertySource:

val defaults = MapPropertySource(
name = "app-defaults",
source = mapOf(
"http.timeout.ms" to 30000,
"retry.max.attempts" to 3
)
)
configService.addPropertySource(defaults)

Priority: Lowest

Cloud Providers (EDK)

Cloud providers fetch configuration from external services and provide:

  • Centralized configuration management
  • Dynamic configuration updates
  • Offline caching for resilience

See Cloud Providers for detailed configuration.

Azure App Configuration

Fetches configuration from Azure App Configuration service.

Module: lib-conf-azure-app-config

Configuration:

azure.appconfig.connection-string=Endpoint=https://myconfig.azconfig.io;Id=...;Secret=...
# Or use endpoint with managed identity
azure.appconfig.endpoint=https://myconfig.azconfig.io

# Optional settings
azure.appconfig.key-filter=myapp/*
azure.appconfig.label-filter=production
azure.appconfig.key-prefix=myapp/
azure.appconfig.trim-key-prefix=true

REST Configuration Client

Fetches configuration from a VDX or compatible REST API server.

Module: lib-conf-config-rest-client

Configuration:

rest.config.base-url=https://config.example.com
rest.config.tenant-id=my-tenant
rest.config.profile=production

# Authentication
rest.config.auth.method=API_KEY
rest.config.auth.api-key=my-api-key
rest.config.auth.api-key-header=X-API-Key

Database Providers (VDX)

Database providers store and retrieve configuration from SQL databases, supporting:

  • Persistent configuration storage
  • Multi-tenant isolation
  • Profile-aware settings
  • In-memory caching for performance

See Settings Persistence for detailed configuration.

PostgreSQL

Module: vdx-conf-settings-persistence-postgresql

Stores settings in a PostgreSQL database with caching.

MySQL

Module: vdx-conf-settings-persistence-mysql

Stores settings in a MySQL database with caching.

SQLite

Module: vdx-conf-settings-persistence-sqlite

Stores settings in a SQLite database. Ideal for embedded or single-server deployments.

Provider Priority

When the same key exists in multiple providers, the highest-priority provider wins:

Environment Variable: api.url=https://env.example.com     ← WINS
Azure App Config: api.url=https://azure.example.com
Database: api.url=https://db.example.com
Properties File: api.url=https://file.example.com

This allows you to:

  • Define defaults in property files
  • Override with cloud configuration
  • Override everything with environment variables in production

Creating Custom Providers

To create a custom configuration provider:

  1. Implement PropertySource:
class MyCustomPropertySource(
private val dataSource: MyDataSource
) : AbstractPropertySource<MyDataSource>(
name = "my-custom-source",
source = dataSource,
order = Order.MEDIUM.orderValue
) {
override fun <T : Any> getProperty(name: String, targetType: KClass<T>): T? {
val value = dataSource.getValue(name) ?: return null
// Convert and return value
return convertValue(value, targetType)
}

override fun getAllPropertyNames(): Set<String> {
return dataSource.getAllKeys()
}

override val isPlatformSupported: Boolean = true
}
  1. Create a contribution for auto-registration (optional):
@Inject
@SingleIn(AppScope::class)
@ContributesBinding(AppScope::class, boundType = PropertySourceContribution::class, multibinding = true)
class MyCustomProviderContribution(
private val dataSource: MyDataSource
) : PropertySourceContribution {

override val configLevel = ConfigLevel.APP
override val providerId = "my-custom-provider"

override fun isEnabled(resolver: PropertyResolver): Boolean {
val disabled = resolver.getProperty(
"config.providers.my-custom-provider.enabled",
Boolean::class
)
return disabled != false && dataSource.isConfigured
}

override fun getPropertySource(): PropertySource<*> {
return MyCustomPropertySource(dataSource)
}

override fun getOrder(): Int = Order.MEDIUM.orderValue
}
  1. Register manually (if not using auto-registration):
val mySource = MyCustomPropertySource(dataSource)
configService.addPropertySource(mySource)

Caching

Providers use caching to improve performance:

Provider TypeCache TypePurpose
Cloud ProvidersOfflineConfigCachePersists config to disk for network failure resilience
Database ProvidersSettingsCacheIn-memory cache to reduce database queries

Offline Cache

Cloud providers (Azure, REST) can persist configuration locally. When the cloud service is unavailable, the cached configuration is used:

# Enable offline caching (enabled by default when available)
azure.appconfig.offline-cache.enabled=true

Database Cache

Database providers cache query results in memory with TTL-based expiration:

  • Cache hit: Returns immediately from memory
  • Cache miss: Queries database, caches result
  • Write/Delete: Invalidates relevant cache entries

Troubleshooting

Provider Not Registering

  1. Check module is on classpath: Verify the dependency is in your build file
  2. Check enable flag: Ensure config.providers.{id}.enabled isn't set to false
  3. Check required config: Some providers need connection details to enable

Wrong Value Being Used

  1. Check provider priority: Higher priority sources override lower ones
  2. Check key normalization: api.baseUrl and api.base.url resolve to the same key
  3. Enable debug logging: Set logging.level.config=DEBUG to see resolution details

Cloud Provider Failing

  1. Check credentials: Verify connection strings, API keys, or managed identity setup
  2. Check network: Ensure firewall allows connections to cloud service
  3. Check offline cache: If available, cached values may be returned during outages