Package net.blockhost.commons.config.migration
@NullMarked
package net.blockhost.commons.config.migration
Configuration migration framework for versioned YAML configurations.
This package provides a complete solution for managing configuration schema changes over time. It allows you to define migrations that transform configuration data from older versions to newer versions, ensuring backward compatibility as your application evolves.
Overview
The migration system is built around these core components:
| Component | Purpose |
|---|---|
Migration |
Defines a single migration step between versions |
MigrationContext |
Provides access to config data and utility methods |
MigrationRegistry |
Stores and manages registered migrations |
MigrationExecutor |
Executes migrations in sequence |
ConfigMigrator |
High-level API combining all components |
RawYamlLoader |
Low-level YAML loading/saving with SnakeYAML |
Quick Start
1. Define a versioned configuration
Extend VersionAwareConfiguration to add version tracking:
@Configuration
public class ServerConfig extends VersionAwareConfiguration {
private static final int CURRENT_VERSION = 3;
private String hostname = "localhost";
private int port = 25565;
private int timeout = 30;
public ServerConfig() {
super(CURRENT_VERSION);
}
}
2. Create migrations
Implement Migration or use the factory methods:
Migration addTimeout = Migration.of(2, "Add timeout field", ctx -> {
ctx.setDefault("timeout", 30);
});
Migration renameHost = Migration.of(3, "Rename host to hostname", ctx -> {
ctx.rename("host", "hostname");
});
3. Configure and use the migrator
ConfigMigrator migrator = ConfigMigrator.builder()
.createBackups(true)
.register(addTimeout)
.register(renameHost)
.beforeMigration(m -> logger.info("Applying: " + m.description()))
.build();
// Load config with automatic migration
ServerConfig config = migrator.migrateAndLoad(
configPath,
ServerConfig.class,
ServerConfig.CURRENT_VERSION
);
Migration Implementation
Migrations transform raw YAML data represented as Map<String, Object>:
public class MigrateV2ToV3 implements Migration {
@Override
public int targetVersion() {
return 3;
}
@Override
public String description() {
return "Reorganize database settings into nested structure";
}
@Override
public void migrate(MigrationContext context) {
// Move flat fields into a nested 'database' section
context.moveToNested("dbHost", "database", "host");
context.moveToNested("dbPort", "database", "port");
context.moveToNested("dbName", "database", "name");
// Add new field with default
context.getOrCreateNestedMap("database")
.putIfAbsent("poolSize", 10);
}
}
Version Semantics
- Version
0indicates a config without version tracking (legacy) - Version
1is typically the first tracked version - Migrations are applied sequentially: 1 -> 2 -> 3 -> ...
- The
Migration.sourceVersion()defaults totargetVersion - 1 - After migration, the
versionfield is automatically updated
Error Handling
Migrations can fail for various reasons. The system provides:
MigrationExceptionfor all migration-related errorsMigrationResultto inspect success/failure details- Optional backup creation before migration
- Detailed step-by-step progress tracking
MigrationResult result = migrator.migrate(configPath, 5);
if (!result.isSuccess()) {
MigrationException error = result.error().orElseThrow();
logger.error("Migration failed at version " + result.toVersion(), error);
// Restore from backup if needed
}
Thread Safety
MigrationRegistryis thread-safe for concurrent accessMigrationExecutorandConfigMigratorare not thread-safe- Create separate executor/migrator instances for concurrent use
- See Also:
-
ClassDescriptionHigh-level API for migrating configuration files.Builder for creating
ConfigMigratorinstances.Represents a single configuration migration step from one version to the next.Functional interface for migration actions.Holds the state and data for a configuration migration.Exception thrown when a configuration migration fails.Executes configuration migrations sequentially by version.Callback interface for post-migration notifications.Registry for managing configuration migrations indexed by version.Encapsulates the outcome of a configuration migration operation.Builder for creating migration results incrementally.Represents a failed migration result.Represents a single migration step that was applied.Represents a successful migration result.Utility class for loading and saving raw YAML files asMapstructures.