Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ phpunit.xml
phpstan.neon
infection.html
infection.log
/docs_php
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
],
"require": {
"php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0",
"patchlevel/event-sourcing": "^3.13.0",
"patchlevel/event-sourcing": "^3.18.0",
"symfony/cache": "^6.4.0 || ^7.0.0 || ^8.0.0",
"symfony/config": "^6.4.0 || ^7.0.0 || ^8.0.0",
"symfony/console": "^6.4.1 || ^7.0.1 || ^8.0.0",
Expand Down
2 changes: 1 addition & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/Command/StoreMigrateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

use function count;

/** @deprecated since version 3.15.0, to be removed in 4.0.0. Use the StoreMigrateCommand from the patchlevel/event-sourcing package instead. */
#[AsCommand(
'event-sourcing:store:migrate',
'migrate events from one store to another',
Expand Down
30 changes: 30 additions & 0 deletions src/DependencyInjection/DoctrineCleanupCompilerPass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Patchlevel\EventSourcingBundle\DependencyInjection;

use Patchlevel\EventSourcing\Subscription\Cleanup\Dbal\DbalCleanupTaskHandler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

final class DoctrineCleanupCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container): void
{
if ($container->has('doctrine')) {
$container->register(DbalCleanupTaskHandler::class, DbalCleanupTaskHandler::class)
->setArguments([
new Reference('doctrine'),
])
->addTag('event_sourcing.cleanup_task_handler');
} elseif ($container->has('event_sourcing.dbal_public_connection')) {
$container->register(DbalCleanupTaskHandler::class, DbalCleanupTaskHandler::class)
->setArguments([
new Reference('event_sourcing.dbal_public_connection'),
])
->addTag('event_sourcing.cleanup_task_handler');
}
}
}
23 changes: 22 additions & 1 deletion src/DependencyInjection/PatchlevelEventSourcingExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@
use Patchlevel\EventSourcing\Console\Command\SchemaUpdateCommand;
use Patchlevel\EventSourcing\Console\Command\ShowAggregateCommand;
use Patchlevel\EventSourcing\Console\Command\ShowCommand;
use Patchlevel\EventSourcing\Console\Command\StoreMigrateCommand;
use Patchlevel\EventSourcing\Console\Command\SubscriptionBootCommand;
use Patchlevel\EventSourcing\Console\Command\SubscriptionPauseCommand;
use Patchlevel\EventSourcing\Console\Command\SubscriptionReactivateCommand;
use Patchlevel\EventSourcing\Console\Command\SubscriptionRefreshCommand;
use Patchlevel\EventSourcing\Console\Command\SubscriptionRemoveCommand;
use Patchlevel\EventSourcing\Console\Command\SubscriptionRunCommand;
use Patchlevel\EventSourcing\Console\Command\SubscriptionSetupCommand;
Expand Down Expand Up @@ -94,6 +96,9 @@
use Patchlevel\EventSourcing\Store\Store;
use Patchlevel\EventSourcing\Store\StreamDoctrineDbalStore;
use Patchlevel\EventSourcing\Store\StreamReadOnlyStore;
use Patchlevel\EventSourcing\Subscription\Cleanup\Cleaner;
use Patchlevel\EventSourcing\Subscription\Cleanup\CleanupTaskHandler;
use Patchlevel\EventSourcing\Subscription\Cleanup\DefaultCleaner;
use Patchlevel\EventSourcing\Subscription\Engine\CatchUpSubscriptionEngine;
use Patchlevel\EventSourcing\Subscription\Engine\DefaultSubscriptionEngine;
use Patchlevel\EventSourcing\Subscription\Engine\GapResolverStoreMessageLoader;
Expand All @@ -116,7 +121,6 @@
use Patchlevel\EventSourcing\Subscription\Subscriber\SubscriberHelper;
use Patchlevel\EventSourcingBundle\Attribute\AsListener;
use Patchlevel\EventSourcingBundle\Clock\FrozenClockFactory;
use Patchlevel\EventSourcingBundle\Command\StoreMigrateCommand;
use Patchlevel\EventSourcingBundle\CommandBus\SymfonyCommandBus;
use Patchlevel\EventSourcingBundle\DataCollector\EventSourcingCollector;
use Patchlevel\EventSourcingBundle\DataCollector\MessageCollectorEventBus;
Expand Down Expand Up @@ -516,13 +520,24 @@

$container->setAlias(SubscriberAccessorRepository::class, MetadataSubscriberAccessorRepository::class);

$container->registerForAutoconfiguration(CleanupTaskHandler::class)

Check warning on line 523 in src/DependencyInjection/PatchlevelEventSourcingExtension.php

View workflow job for this annotation

GitHub Actions / Mutation tests on diff (locked, 8.5, ubuntu-latest)

Escaped Mutant for Mutator "MethodCallRemoval": @@ @@ $container->setAlias(SubscriberAccessorRepository::class, MetadataSubscriberAccessorRepository::class); - $container->registerForAutoconfiguration(CleanupTaskHandler::class) - ->addTag('event_sourcing.cleanup_task_handler'); + $container->register(DefaultCleaner::class) ->setArguments([
->addTag('event_sourcing.cleanup_task_handler');

$container->register(DefaultCleaner::class)
->setArguments([

Check warning on line 527 in src/DependencyInjection/PatchlevelEventSourcingExtension.php

View workflow job for this annotation

GitHub Actions / Mutation tests on diff (locked, 8.5, ubuntu-latest)

Escaped Mutant for Mutator "ArrayItemRemoval": @@ @@ ->addTag('event_sourcing.cleanup_task_handler'); $container->register(DefaultCleaner::class) - ->setArguments([ - new TaggedIteratorArgument('event_sourcing.cleanup_task_handler'), - ]); + ->setArguments([]); $container->setAlias(Cleaner::class, DefaultCleaner::class);
new TaggedIteratorArgument('event_sourcing.cleanup_task_handler'),
]);

$container->setAlias(Cleaner::class, DefaultCleaner::class);

$container->register(DefaultSubscriptionEngine::class)
->setArguments([
new Reference(MessageLoader::class),
new Reference(SubscriptionStore::class),
new Reference(SubscriberAccessorRepository::class),
new Reference(RetryStrategyRepository::class),
new Reference('logger', ContainerInterface::NULL_ON_INVALID_REFERENCE),
new Reference(Cleaner::class),
])
->addTag('monolog.logger', ['channel' => 'event_sourcing']);

Expand Down Expand Up @@ -981,6 +996,12 @@
new Reference(SubscriptionEngine::class),
])
->addTag('console.command');

$container->register(SubscriptionRefreshCommand::class)
->setArguments([
new Reference(SubscriptionEngine::class),
])
->addTag('console.command');
}

/** @param Config $config */
Expand Down
2 changes: 2 additions & 0 deletions src/PatchlevelEventSourcingBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Patchlevel\EventSourcingBundle;

use Patchlevel\EventSourcingBundle\DependencyInjection\CommandHandlerCompilerPass;
use Patchlevel\EventSourcingBundle\DependencyInjection\DoctrineCleanupCompilerPass;
use Patchlevel\EventSourcingBundle\DependencyInjection\HandlerServiceLocatorCompilerPass;
use Patchlevel\EventSourcingBundle\DependencyInjection\QueryHandlerCompilerPass;
use Patchlevel\EventSourcingBundle\DependencyInjection\RepositoryCompilerPass;
Expand All @@ -23,5 +24,6 @@ public function build(ContainerBuilder $container): void
$container->addCompilerPass(new QueryHandlerCompilerPass(), priority: 100);
$container->addCompilerPass(new HandlerServiceLocatorCompilerPass(), priority: -100);
$container->addCompilerPass(new TranslatorCompilerPass());
$container->addCompilerPass(new DoctrineCleanupCompilerPass());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

final class TestCaseAllPublicCompilerPass implements CompilerPassInterface
final class AllPublicCompilerPass implements CompilerPassInterface
{
private const SERVICE_PREFIX = 'event_sourcing.';
private const NAMESPACE_PREFIX = 'Patchlevel\\';
Expand All @@ -21,7 +21,7 @@ public function process(ContainerBuilder $container): void
}

foreach ($container->getAliases() as $id => $alias) {
if ($this->isOwnService($id)) {
if ($this->isOwnService($id) || $this->isOwnService((string)$alias)) {
$alias->setPublic(true);
}
}
Expand Down
16 changes: 16 additions & 0 deletions tests/Unit/NoLazyCompilerPass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace Patchlevel\EventSourcingBundle\Tests\Unit;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

final class NoLazyCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container): void
{
foreach ($container->getDefinitions() as $definition) {
$definition->setLazy(false);
}
}
}
86 changes: 78 additions & 8 deletions tests/Unit/PatchlevelEventSourcingBundleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

use ArrayObject;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
use Doctrine\Migrations\Tools\Console\Command\CurrentCommand;
use Doctrine\Migrations\Tools\Console\Command\DiffCommand;
use Doctrine\Migrations\Tools\Console\Command\ExecuteCommand;
use Doctrine\Migrations\Tools\Console\Command\MigrateCommand;
use Doctrine\Migrations\Tools\Console\Command\StatusCommand;
use Doctrine\Persistence\ManagerRegistry;
use InvalidArgumentException;
use Patchlevel\EventSourcing\Attribute\Aggregate;
use Patchlevel\EventSourcing\Attribute\Event;
Expand All @@ -26,9 +26,11 @@
use Patchlevel\EventSourcing\Console\Command\SchemaUpdateCommand;
use Patchlevel\EventSourcing\Console\Command\ShowAggregateCommand;
use Patchlevel\EventSourcing\Console\Command\ShowCommand;
use Patchlevel\EventSourcing\Console\Command\StoreMigrateCommand;
use Patchlevel\EventSourcing\Console\Command\SubscriptionBootCommand;
use Patchlevel\EventSourcing\Console\Command\SubscriptionPauseCommand;
use Patchlevel\EventSourcing\Console\Command\SubscriptionReactivateCommand;
use Patchlevel\EventSourcing\Console\Command\SubscriptionRefreshCommand;
use Patchlevel\EventSourcing\Console\Command\SubscriptionRemoveCommand;
use Patchlevel\EventSourcing\Console\Command\SubscriptionRunCommand;
use Patchlevel\EventSourcing\Console\Command\SubscriptionSetupCommand;
Expand Down Expand Up @@ -67,6 +69,9 @@
use Patchlevel\EventSourcing\Store\StreamDoctrineDbalStore;
use Patchlevel\EventSourcing\Store\StreamReadOnlyStore;
use Patchlevel\EventSourcing\Store\StreamStore;
use Patchlevel\EventSourcing\Subscription\Cleanup\Cleaner;
use Patchlevel\EventSourcing\Subscription\Cleanup\Dbal\DbalCleanupTaskHandler;
use Patchlevel\EventSourcing\Subscription\Cleanup\DefaultCleaner;
use Patchlevel\EventSourcing\Subscription\Engine\CatchUpSubscriptionEngine;
use Patchlevel\EventSourcing\Subscription\Engine\DefaultSubscriptionEngine;
use Patchlevel\EventSourcing\Subscription\Engine\GapResolverStoreMessageLoader;
Expand All @@ -82,8 +87,6 @@
use Patchlevel\EventSourcing\Subscription\Store\InMemorySubscriptionStore;
use Patchlevel\EventSourcing\Subscription\Store\SubscriptionStore;
use Patchlevel\EventSourcing\Subscription\Subscriber\MetadataSubscriberAccessorRepository;
use Patchlevel\EventSourcingBundle\Command\StoreMigrateCommand;
use Patchlevel\EventSourcingBundle\DependencyInjection\Configuration;
use Patchlevel\EventSourcingBundle\DependencyInjection\PatchlevelEventSourcingExtension;
use Patchlevel\EventSourcingBundle\EventBus\SymfonyEventBus;
use Patchlevel\EventSourcingBundle\PatchlevelEventSourcingBundle;
Expand Down Expand Up @@ -374,6 +377,7 @@ public function testMigrateStore(): void
$container = new ContainerBuilder();

$container->register('my_translator', ExcludeEventWithHeaderTranslator::class)
->setPublic(true)
->setArguments([ArchivedHeader::class]);

$this->compileContainer(
Expand Down Expand Up @@ -786,6 +790,66 @@ public function testGapDetectionWithExplicitValues(): void
self::assertInstanceOf(GapResolverStoreMessageLoader::class, $messageLoader);
}

public function testSubscriptionCleanupWithDoctrine(): void
{
$registry = $this->createMock(ManagerRegistry::class);

$container = new ContainerBuilder();
$container->set('doctrine', $registry);

$this->compileContainer(
$container,
[
'patchlevel_event_sourcing' => [
'connection' => [
'service' => 'doctrine.dbal.eventstore_connection',
],
'store' => [
'merge_orm_schema' => true,
],
],
]
);

$definition = $container->getDefinition(DbalCleanupTaskHandler::class);
$tags = $definition->getTag('event_sourcing.cleanup_task_handler');

self::assertCount(1, $tags);

$cleaner = $container->get(Cleaner::class);
self::assertInstanceOf(DefaultCleaner::class, $cleaner);

$cleanupTaskHandler = $container->get(DbalCleanupTaskHandler::class);
self::assertInstanceOf(DbalCleanupTaskHandler::class, $cleanupTaskHandler);
}

public function testSubscriptionCleanupWithProjectionConnection(): void
{
$container = new ContainerBuilder();
$this->compileContainer(
$container,
[
'patchlevel_event_sourcing' => [
'connection' => [
'url' => 'sqlite3:///:memory:',
'provide_dedicated_connection' => true,
],
],
]
);

$definition = $container->getDefinition(DbalCleanupTaskHandler::class);
$tags = $definition->getTag('event_sourcing.cleanup_task_handler');

self::assertCount(1, $tags);

$cleaner = $container->get(Cleaner::class);
self::assertInstanceOf(DefaultCleaner::class, $cleaner);

$cleanupTaskHandler = $container->get(DbalCleanupTaskHandler::class);
self::assertInstanceOf(DbalCleanupTaskHandler::class, $cleanupTaskHandler);
}

public function testSnapshotStore(): void
{
$container = new ContainerBuilder();
Expand Down Expand Up @@ -1013,6 +1077,7 @@ public function testCommands(): void
self::assertInstanceOf(SubscriptionSetupCommand::class, $container->get(SubscriptionSetupCommand::class));
self::assertInstanceOf(SubscriptionStatusCommand::class, $container->get(SubscriptionStatusCommand::class));
self::assertInstanceOf(SubscriptionTeardownCommand::class, $container->get(SubscriptionTeardownCommand::class));
self::assertInstanceOf(SubscriptionRefreshCommand::class, $container->get(SubscriptionRefreshCommand::class));
self::assertInstanceOf(SchemaCreateCommand::class, $container->get(SchemaCreateCommand::class));
self::assertInstanceOf(SchemaUpdateCommand::class, $container->get(SchemaUpdateCommand::class));
self::assertInstanceOf(SchemaDropCommand::class, $container->get(SchemaDropCommand::class));
Expand Down Expand Up @@ -1564,10 +1629,6 @@ private function compileContainer(ContainerBuilder $container, array $config): v
$container->setParameter('kernel.project_dir', __DIR__);

$connection = $this->createMock(Connection::class);
$connection
->expects($this->never())
->method('getDatabasePlatform')
->willReturn(new PostgreSQLPlatform());

$container->set('doctrine.dbal.eventstore_connection', $connection);
$container->set('event.bus', $this->createMock(MessageBusInterface::class));
Expand All @@ -1583,10 +1644,19 @@ private function compileContainer(ContainerBuilder $container, array $config): v

$compilerPassConfig = $container->getCompilerPassConfig();
$compilerPassConfig->setRemovingPasses([]);
$compilerPassConfig->addPass(new TestCaseAllPublicCompilerPass());
$compilerPassConfig->addPass(new AllPublicCompilerPass());
$compilerPassConfig->addPass(new NoLazyCompilerPass());

$container->compile();

foreach ($container->getServiceIds() as $id) {
if (str_ends_with($id, '.inner')) {
continue;
}

$container->get($id);
}

(new XmlDumper($container))->dump();
}
}
Loading