diff --git a/docs/UPGRADE-4.0.md b/docs/UPGRADE-4.0.md new file mode 100644 index 00000000..1db502ab --- /dev/null +++ b/docs/UPGRADE-4.0.md @@ -0,0 +1,212 @@ +--- +searchable: false +--- +# Upgrade 4.0 + +## Dependencies + +The bundle now requires `patchlevel/event-sourcing` 4.0 and `patchlevel/hydrator` 2.0. +Both libraries bring their own breaking changes, for example renamed identifier classes, +removed stores or a new upcaster interface. +Follow the [event-sourcing upgrade guide](https://github.com/patchlevel/event-sourcing/blob/4.0.x/docs/UPGRADE-4.0.md) +and the [hydrator upgrade guide](https://github.com/patchlevel/hydrator/blob/2.0.x/UPGRADE-2.0.md) for these. +This guide only covers the changes of the bundle itself. + +## Subscription + +### Retry Strategy + +The deprecated `retry_strategy` option has been removed. Use `retry_strategies` instead. +The `Patchlevel\EventSourcing\Subscription\RetryStrategy\RetryStrategy` service alias has been removed too, +inject the `RetryStrategyRepository` instead. + +before: + +```yaml +patchlevel_event_sourcing: + subscription: + retry_strategy: + base_delay: 5 + delay_factor: 2 + max_attempts: 5 +``` +after: + +```yaml +patchlevel_event_sourcing: + subscription: + retry_strategies: + default: + type: clock_based + options: + base_delay: 5 + delay_factor: 2 + max_attempts: 5 +``` +### SubscriberHelper + +The `SubscriberHelper` service is no longer registered, because the class has been removed from the library. +See the [event-sourcing upgrade guide](https://github.com/patchlevel/event-sourcing/blob/4.0.x/docs/UPGRADE-4.0.md#subscriberhelper-and-subscriberutil) +for the replacement. + +## Store + +### Store Type + +The store type `dbal_aggregate` has been removed together with the `DoctrineDbalStore`. +The default store type is now `dbal_stream`. +The new store type `dbal_taggable` is available for the DCB feature. + +before: + +```yaml +patchlevel_event_sourcing: + store: + type: dbal_aggregate +``` +after: + +```yaml +patchlevel_event_sourcing: + store: + type: dbal_stream +``` +:::danger +The `dbal_stream` store uses a different table structure than `dbal_aggregate`. +Migrate your events with the `migrate_to_new_store` option and the `event-sourcing:store:migrate` command +while you are still on 3.x, otherwise your events can no longer be read. +::: + +### Read Only Mode + +`read_only` is now only supported by the `dbal_stream` store. +For `dbal_taggable`, `in_memory` and `custom` an exception is thrown at container compile time. + +### StoreMigrateCommand + +The deprecated `Patchlevel\EventSourcingBundle\Command\StoreMigrateCommand` has been removed. +Use `Patchlevel\EventSourcing\Console\Command\StoreMigrateCommand` from the library instead. +The command name `event-sourcing:store:migrate` stays the same. + +## Hydrator + +### Legacy Hydrator + +The legacy `MetadataHydrator` has been removed, the bundle always uses the `StackHydrator` now. +For this reason the `hydrator.enabled` option has been removed too. +Remove `hydrator: true` or `enabled` from your configuration, the other `hydrator` options stay the same. + +before: + +```yaml +patchlevel_event_sourcing: + hydrator: + enabled: true + default_lazy: true +``` +after: + +```yaml +patchlevel_event_sourcing: + hydrator: + default_lazy: true +``` + +Together with the legacy hydrator, the guesser integration has been removed: +the `event_sourcing.hydrator.guesser` tag and the autoconfiguration for `Patchlevel\Hydrator\Guesser\Guesser` no longer exist. +Register your guesser in a hydrator extension with `$builder->addGuesser()` instead. +Services implementing `Patchlevel\Hydrator\Extension` are registered automatically. + +### Cryptography + +The root `cryptography` option has been removed. Use `hydrator.cryptography` instead. +The options `use_encrypted_field_name` and `fallback_to_field_name` have been removed without replacement. + +before: + +```yaml +patchlevel_event_sourcing: + cryptography: + algorithm: 'aes-256-gcm' + use_encrypted_field_name: true +``` +after: + +```yaml +patchlevel_event_sourcing: + hydrator: + cryptography: + algorithm: 'aes-256-gcm' +``` +:::danger +Data encrypted with the legacy cryptography can no longer be decrypted. +Migrate your store and snapshots to the new format while you are still on 3.x, +see the [event-sourcing upgrade guide](https://github.com/patchlevel/event-sourcing/blob/4.0.x/docs/UPGRADE-4.0.md#sensitive-data). +::: + +### Upcaster + +The `UpcasterChain` service and the `Patchlevel\EventSourcing\Serializer\Upcast\Upcaster` alias have been removed. +Upcasters now implement `Patchlevel\Hydrator\Extension\Upcast\Upcaster` and are registered automatically. +The bundle adds them to the `UpcastExtension` of the hydrator. +Services tagged with `event_sourcing.upcaster` still work and are sorted by the `priority` attribute. + +### SymfonyUuidNormalizer + +The deprecated `Patchlevel\EventSourcingBundle\Normalizer\SymfonyUuidNormalizer` has been removed. +Use `Patchlevel\EventSourcingBundle\Normalizer\UidNormalizer` instead. + +before: + +```php +use Patchlevel\EventSourcingBundle\Normalizer\SymfonyUuidNormalizer; +use Symfony\Component\Uid\Uuid; + +final class ProfileCreated +{ + public function __construct( + #[SymfonyUuidNormalizer] + public readonly Uuid $profileId, + ) { + } +} +``` +after: + +```php +use Patchlevel\EventSourcingBundle\Normalizer\UidNormalizer; +use Symfony\Component\Uid\Uuid; + +final class ProfileCreated +{ + public function __construct( + #[UidNormalizer] + public readonly Uuid $profileId, + ) { + } +} +``` +## Command Bus + +The deprecated `aggregate_handlers` option has been removed. Use `command_bus` instead. + +before: + +```yaml +patchlevel_event_sourcing: + aggregate_handlers: + bus: command.bus +``` +after: + +```yaml +patchlevel_event_sourcing: + command_bus: + service: command.bus +``` +## Value Resolver + +`Patchlevel\EventSourcingBundle\ValueResolver\AggregateRootIdValueResolver` has been renamed to +`Patchlevel\EventSourcingBundle\ValueResolver\IdentifierValueResolver`. +It now resolves every controller argument that implements `Patchlevel\EventSourcing\Identifier\Identifier`. +You only have to change something if you reference the class directly, e.g. in `#[ValueResolver]`. diff --git a/docs/configuration.md b/docs/configuration.md index 285fc9c1..8beb9871 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -216,8 +216,8 @@ patchlevel_event_sourcing: ``` Following store types are available: -- `dbal_aggregate` *default (deprecated)* -- `dbal_stream` *recommended* +- `dbal_stream` *default* +- `dbal_taggable` *required for DCB* - `in_memory` - `custom` @@ -237,7 +237,7 @@ patchlevel_event_sourcing: ``` ### Read Only Mode -For `dbal_aggregate` and `dbal_stream` store types you can activate the read only mode. +For the `dbal_stream` store type you can activate the read only mode. Readings are possible, but if you try to write, an exception `StoreIsReadOnly` is thrown. ```yaml @@ -286,17 +286,18 @@ patchlevel_event_sourcing: If you want to migrate from your current store to a new store, you can use the following configuration. This register a new store and a new cli command `event-sourcing:store:migrate`. You can define translators to translate the old events to the new store. -Here is an example for a migration from `dbal_aggregate` to `dbal_stream`. +Here is an example for a migration from `dbal_stream` to `dbal_taggable`, +which adds the event tags to the existing events. ```yaml patchlevel_event_sourcing: store: migrate_to_new_store: - type: 'dbal_stream' + type: 'dbal_taggable' options: - table_name: 'my_stream_store' + table_name: 'my_taggable_store' translators: - - Patchlevel\EventSourcing\Message\Translator\AggregateToStreamHeaderTranslator + - Patchlevel\EventSourcing\Message\Translator\ExtractEventTagTranslator ``` :::danger Make sure that you use different table names for the old and new store. @@ -669,29 +670,25 @@ You can find out more about snapshots [here](https://event-sourcing.patchlevel.i ## Cryptography -You can use the library to encrypt and decrypt personal data. -For this you need to enable the crypto shredding. +You can use the library to encrypt and decrypt sensitive data. +For this you need to enable the cryptography extension of the hydrator. ```yaml patchlevel_event_sourcing: - cryptography: - use_encrypted_field_name: true + hydrator: + cryptography: true ``` -:::tip -You should activate `use_encrypted_field_name` to mark the fields that are encrypted. -That allows you later to migrate not encrypted fields to encrypted fields. -If you have already encrypted fields, you can activate `fallback_to_field_name` to use the old field name as fallback. -::: - +The cipher keys are stored in the same database as the event store. If you want to use another algorithm, you can specify this here: ```yaml patchlevel_event_sourcing: - cryptography: - algorithm: 'aes-256-gcm' + hydrator: + cryptography: + algorithm: 'aes-256-gcm' ``` :::note -You can find out more about personal data [here](https://event-sourcing.patchlevel.io/latest/personal_data/). +You can find out more about sensitive data [here](https://event-sourcing.patchlevel.io/latest/sensitive-data/). ::: ## Clock diff --git a/docs/installation.md b/docs/installation.md index bef677db..f023176d 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -49,8 +49,8 @@ patchlevel_event_sourcing: gap_detection: ~ # enable this if you want to use sensitive data encryption - #cryptography: ~ - # use_encrypted_field_name: true + #hydrator: + # cryptography: true when@dev: patchlevel_event_sourcing: diff --git a/docs/project.json b/docs/project.json index cfdca365..0dde3ec6 100644 --- a/docs/project.json +++ b/docs/project.json @@ -19,6 +19,10 @@ { "title": "Usage", "file": "usage.md" + }, + { + "title": "Upgrade from 3.x", + "file": "UPGRADE-4.0.md" } ] } diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index e16f314e..85096bff 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -82,7 +82,6 @@ * clock: array{freeze: ?string, service: ?string}, * dcb: array{enabled: bool}, * hydrator: array{ - * enabled: bool, * default_lazy: bool, * cryptography: array{ * enabled: bool, @@ -335,7 +334,6 @@ public function getConfigTreeBuilder(): TreeBuilder ->end() ->arrayNode('hydrator') - ->canBeDisabled() ->addDefaultsIfNotSet() ->children() ->booleanNode('default_lazy')->defaultFalse()->end() diff --git a/tests/Unit/PatchlevelEventSourcingBundleTest.php b/tests/Unit/PatchlevelEventSourcingBundleTest.php index cb4e2736..48944bf6 100644 --- a/tests/Unit/PatchlevelEventSourcingBundleTest.php +++ b/tests/Unit/PatchlevelEventSourcingBundleTest.php @@ -1360,7 +1360,6 @@ public function testHydrator(): void 'patchlevel_event_sourcing' => [ 'connection' => ['service' => 'doctrine.dbal.eventstore_connection'], 'hydrator' => [ - 'enabled' => true, 'lifecycle' => ['enabled' => true], 'cryptography' => ['enabled' => true], ],