Skip to content

Commit

Permalink
Merge pull request #5378 from mhsdesign/feature/content-repository-ma…
Browse files Browse the repository at this point in the history
…intainer

FEATURE: Introduce `ContentRepositoryMaintainer` and restore projection cli commands
  • Loading branch information
mhsdesign authored Nov 27, 2024
2 parents 6726d73 + d84c2a4 commit fd768da
Show file tree
Hide file tree
Showing 57 changed files with 1,243 additions and 595 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@
use Behat\Gherkin\Node\TableNode;
use Doctrine\DBAL\Connection;
use Neos\ContentRepository\Core\ContentRepository;
use Neos\ContentRepository\Core\Service\SubscriptionServiceFactory;
use Neos\ContentRepository\Core\Service\ContentRepositoryMaintainerFactory;
use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId;
use Neos\ContentRepository\Core\Subscription\Engine\SubscriptionEngine;
use Neos\ContentRepository\TestSuite\Behavior\Features\Bootstrap\Helpers\GherkinTableNodeBasedContentDimensionSource;
use Neos\ContentRepository\TestSuite\Fakes\FakeContentDimensionSourceFactory;
use Neos\ContentRepository\TestSuite\Fakes\FakeNodeTypeManagerFactory;
use Neos\EventStore\EventStoreInterface;
use PHPUnit\Framework\Assert;
use Symfony\Component\Yaml\Yaml;

/**
Expand Down Expand Up @@ -179,20 +181,26 @@ protected function setUpContentRepository(ContentRepositoryId $contentRepository
* Catch Up process and the testcase reset.
*/
$contentRepository = $this->createContentRepository($contentRepositoryId);
$subscriptionService = $this->contentRepositoryRegistry->buildService($contentRepositoryId, new SubscriptionServiceFactory());
$contentRepositoryMaintainer = $this->contentRepositoryRegistry->buildService($contentRepositoryId, new ContentRepositoryMaintainerFactory());
if (!in_array($contentRepository->id, self::$alreadySetUpContentRepositories)) {
$subscriptionService->setupEventStore();
$subscriptionService->subscriptionEngine->setup();
$result = $contentRepositoryMaintainer->setUp();
Assert::assertNull($result);
self::$alreadySetUpContentRepositories[] = $contentRepository->id;
}
// todo we TRUNCATE here and do not want to use $contentRepositoryMaintainer->prune(); here as it would not reset the autoincrement sequence number making some assertions impossible
/** @var EventStoreInterface $eventStore */
$eventStore = (new \ReflectionClass($contentRepository))->getProperty('eventStore')->getValue($contentRepository);
/** @var Connection $databaseConnection */
$databaseConnection = (new \ReflectionClass($eventStore))->getProperty('connection')->getValue($eventStore);
$eventTableName = sprintf('cr_%s_events', $contentRepositoryId->value);
$databaseConnection->executeStatement('TRUNCATE ' . $eventTableName);
$subscriptionService->subscriptionEngine->reset();
$subscriptionService->subscriptionEngine->boot();

/** @var SubscriptionEngine $subscriptionEngine */
$subscriptionEngine = (new \ReflectionClass($contentRepositoryMaintainer))->getProperty('subscriptionEngine')->getValue($contentRepositoryMaintainer);
$result = $subscriptionEngine->reset();
Assert::assertNull($result->errors);
$result = $subscriptionEngine->boot();
Assert::assertNull($result->errors);

return $contentRepository;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,12 @@
use Neos\ContentRepository\Core\Projection\ProjectionInterface;
use Neos\ContentRepository\Core\Projection\ProjectionStateInterface;
use Neos\ContentRepository\Core\Projection\ProjectionStatus;
use Neos\ContentRepository\Core\Service\SubscriptionService;
use Neos\ContentRepository\Core\Service\SubscriptionServiceFactory;
use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId;
use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId;
use Neos\ContentRepository\Core\Subscription\DetachedSubscriptionStatus;
use Neos\ContentRepository\Core\Subscription\Engine\SubscriptionEngine;
use Neos\ContentRepository\Core\Subscription\Store\SubscriptionCriteria;
use Neos\ContentRepository\Core\Subscription\SubscriptionAndProjectionStatus;
use Neos\ContentRepository\Core\Subscription\Engine\SubscriptionEngineCriteria;
use Neos\ContentRepository\Core\Subscription\ProjectionSubscriptionStatus;
use Neos\ContentRepository\Core\Subscription\SubscriptionId;
use Neos\ContentRepository\Core\Subscription\SubscriptionStatus;
use Neos\ContentRepository\TestSuite\Fakes\FakeCatchUpHookFactory;
Expand All @@ -37,12 +36,13 @@
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

/**
* @internal, only for tests of the Neos.* namespace
*/
abstract class AbstractSubscriptionEngineTestCase extends TestCase // we don't use Flows functional test case as it would reset the database afterwards
{
protected ContentRepository $contentRepository;

protected SubscriptionService $subscriptionService;

protected SubscriptionEngine $subscriptionEngine;

protected EventStoreInterface $eventStore;
Expand Down Expand Up @@ -102,8 +102,6 @@ final protected function setupContentRepositoryDependencies(ContentRepositoryId
$contentRepositoryId
);

$this->subscriptionService = $this->getObject(ContentRepositoryRegistry::class)->buildService($contentRepositoryId, new SubscriptionServiceFactory());

$subscriptionEngineAndEventStoreAccessor = new class implements ContentRepositoryServiceFactoryInterface {
public EventStoreInterface|null $eventStore;
public SubscriptionEngine|null $subscriptionEngine;
Expand Down Expand Up @@ -140,9 +138,9 @@ final protected function resetDatabase(Connection $connection, ContentRepository
$connection->prepare('SET FOREIGN_KEY_CHECKS = 1;')->executeStatement();
}

final protected function subscriptionStatus(string $subscriptionId): ?SubscriptionAndProjectionStatus
final protected function subscriptionStatus(string $subscriptionId): ProjectionSubscriptionStatus|DetachedSubscriptionStatus|null
{
return $this->subscriptionService->subscriptionEngine->subscriptionStatuses(SubscriptionCriteria::create(ids: [SubscriptionId::fromString($subscriptionId)]))->first();
return $this->subscriptionEngine->subscriptionStatus(SubscriptionEngineCriteria::create(ids: [SubscriptionId::fromString($subscriptionId)]))->first();
}

final protected function commitExampleContentStreamEvent(): void
Expand All @@ -162,12 +160,12 @@ final protected function expectOkayStatus($subscriptionId, SubscriptionStatus $s
{
$actual = $this->subscriptionStatus($subscriptionId);
self::assertEquals(
SubscriptionAndProjectionStatus::create(
ProjectionSubscriptionStatus::create(
subscriptionId: SubscriptionId::fromString($subscriptionId),
subscriptionStatus: $status,
subscriptionPosition: $sequenceNumber,
subscriptionError: null,
projectionStatus: ProjectionStatus::ok(),
setupStatus: ProjectionStatus::ok(),
),
$actual
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use Neos\ContentRepository\Core\Feature\ContentStreamCreation\Event\ContentStreamWasCreated;
use Neos\ContentRepository\Core\Projection\ProjectionStatus;
use Neos\ContentRepository\Core\Subscription\Exception\CatchUpFailed;
use Neos\ContentRepository\Core\Subscription\SubscriptionAndProjectionStatus;
use Neos\ContentRepository\Core\Subscription\ProjectionSubscriptionStatus;
use Neos\ContentRepository\Core\Subscription\SubscriptionError;
use Neos\ContentRepository\Core\Subscription\SubscriptionId;
use Neos\ContentRepository\Core\Subscription\SubscriptionStatus;
Expand All @@ -18,11 +18,11 @@ final class CatchUpHookErrorTest extends AbstractSubscriptionEngineTestCase
/** @test */
public function error_onBeforeEvent_projectionIsNotRun()
{
$this->subscriptionService->setupEventStore();
$this->eventStore->setup();
$this->fakeProjection->expects(self::once())->method('setUp');
$this->fakeProjection->expects(self::once())->method('apply');
$this->subscriptionService->subscriptionEngine->setup();
$this->subscriptionService->subscriptionEngine->boot();
$this->subscriptionEngine->setup();
$this->subscriptionEngine->boot();

// commit an event
$this->commitExampleContentStreamEvent();
Expand All @@ -37,12 +37,12 @@ public function error_onBeforeEvent_projectionIsNotRun()

$this->secondFakeProjection->injectSaboteur(fn () => self::fail('Projection apply is not expected to be called!'));

$expectedFailure = SubscriptionAndProjectionStatus::create(
$expectedFailure = ProjectionSubscriptionStatus::create(
subscriptionId: SubscriptionId::fromString('Vendor.Package:SecondFakeProjection'),
subscriptionStatus: SubscriptionStatus::ERROR,
subscriptionPosition: SequenceNumber::none(),
subscriptionError: SubscriptionError::fromPreviousStatusAndException(SubscriptionStatus::ACTIVE, $exception),
projectionStatus: ProjectionStatus::ok(),
setupStatus: ProjectionStatus::ok(),
);

self::assertEmpty(
Expand All @@ -66,11 +66,11 @@ public function error_onBeforeEvent_projectionIsNotRun()
/** @test */
public function error_onAfterEvent_projectionIsRolledBack()
{
$this->subscriptionService->setupEventStore();
$this->eventStore->setup();
$this->fakeProjection->expects(self::once())->method('setUp');
$this->fakeProjection->expects(self::once())->method('apply');
$this->subscriptionService->subscriptionEngine->setup();
$this->subscriptionService->subscriptionEngine->boot();
$this->subscriptionEngine->setup();
$this->subscriptionEngine->boot();

// commit an event
$this->commitExampleContentStreamEvent();
Expand All @@ -83,12 +83,12 @@ public function error_onAfterEvent_projectionIsRolledBack()
// TODO pass the error subscription status to onAfterCatchUp, so that in case of an error it can be prevented that mails f.x. will be sent?
$this->catchupHookForFakeProjection->expects(self::once())->method('onAfterCatchUp');

$expectedFailure = SubscriptionAndProjectionStatus::create(
$expectedFailure = ProjectionSubscriptionStatus::create(
subscriptionId: SubscriptionId::fromString('Vendor.Package:SecondFakeProjection'),
subscriptionStatus: SubscriptionStatus::ERROR,
subscriptionPosition: SequenceNumber::none(),
subscriptionError: SubscriptionError::fromPreviousStatusAndException(SubscriptionStatus::ACTIVE, $exception),
projectionStatus: ProjectionStatus::ok(),
setupStatus: ProjectionStatus::ok(),
);

self::assertEmpty(
Expand All @@ -112,11 +112,11 @@ public function error_onAfterEvent_projectionIsRolledBack()
/** @test */
public function error_onBeforeCatchUp_abortsCatchup()
{
$this->subscriptionService->setupEventStore();
$this->eventStore->setup();
$this->fakeProjection->expects(self::once())->method('setUp');
$this->fakeProjection->expects(self::never())->method('apply');
$this->subscriptionService->subscriptionEngine->setup();
$this->subscriptionService->subscriptionEngine->boot();
$this->subscriptionEngine->setup();
$this->subscriptionEngine->boot();

$this->expectOkayStatus('Vendor.Package:SecondFakeProjection', SubscriptionStatus::ACTIVE, SequenceNumber::none());

Expand Down Expand Up @@ -158,11 +158,11 @@ public function error_onBeforeCatchUp_abortsCatchup()
/** @test */
public function error_onAfterCatchUp_abortsCatchupAndRollBack()
{
$this->subscriptionService->setupEventStore();
$this->eventStore->setup();
$this->fakeProjection->expects(self::once())->method('setUp');
$this->fakeProjection->expects(self::once())->method('apply');
$this->subscriptionService->subscriptionEngine->setup();
$this->subscriptionService->subscriptionEngine->boot();
$this->subscriptionEngine->setup();
$this->subscriptionEngine->boot();

$this->expectOkayStatus('Vendor.Package:SecondFakeProjection', SubscriptionStatus::ACTIVE, SequenceNumber::none());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ final class CatchUpHookTest extends AbstractSubscriptionEngineTestCase
/** @test */
public function catchUpHooksAreExecutedAndCanAccessTheCorrectProjectionsState()
{
$this->subscriptionService->setupEventStore();
$this->eventStore->setup();
$this->fakeProjection->expects(self::once())->method('setUp');
$this->fakeProjection->expects(self::once())->method('apply');
$this->subscriptionService->subscriptionEngine->setup();
$this->subscriptionService->subscriptionEngine->boot();
$this->subscriptionEngine->setup();
$this->subscriptionEngine->boot();

// commit an event
$this->commitExampleContentStreamEvent();
Expand Down
Loading

0 comments on commit fd768da

Please sign in to comment.