Skip to content

Commit

Permalink
!!! TASK: Declare ProjectionService as api to reset projections ins…
Browse files Browse the repository at this point in the history
…tead of ContentRepository
  • Loading branch information
mhsdesign committed Oct 16, 2024
1 parent 0b6e2fa commit bff61f3
Show file tree
Hide file tree
Showing 13 changed files with 80 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
use Neos\ContentRepository\Core\Feature\RootNodeCreation\Event\RootNodeAggregateWithNodeWasCreated;
use Neos\ContentRepository\Core\Feature\WorkspaceCreation\Command\CreateRootWorkspace;
use Neos\ContentRepository\Core\NodeType\NodeTypeName;
use Neos\ContentRepository\Core\Projection\Projections;
use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId;
use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateClassification;
use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId;
Expand All @@ -53,7 +54,8 @@ public function __construct(
private readonly EventPersister $eventPersister,
private readonly ContentRepository $contentRepository,
private readonly Connection $connection,
private readonly ContentRepositoryId $contentRepositoryId
private readonly ContentRepositoryId $contentRepositoryId,
private readonly Projections $projections,
) {
$this->contentStreamId = contentStreamId::fromString('cs-identifier');
$this->workspaceName = WorkspaceName::fromString('some-workspace');
Expand All @@ -74,7 +76,7 @@ public function removeEverything(): void
{
$eventTableName = DoctrineEventStoreFactory::databaseTableName($this->contentRepositoryId);
$this->connection->executeStatement('TRUNCATE ' . $this->connection->quoteIdentifier($eventTableName));
$this->contentRepository->resetProjectionStates();
$this->projections->resetAll();
}

public function createNodesForPerformanceTest(int $nodesPerLevel, int $levels): void
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ public function build(
$serviceFactoryDependencies->eventPersister,
$serviceFactoryDependencies->contentRepository,
$this->connection,
$serviceFactoryDependencies->contentRepositoryId
$serviceFactoryDependencies->contentRepositoryId,
$serviceFactoryDependencies->projections,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
use Behat\Gherkin\Node\TableNode;
use Doctrine\DBAL\Connection;
use Neos\ContentRepository\Core\ContentRepository;
use Neos\ContentRepository\Core\Service\ProjectionService;
use Neos\ContentRepository\Core\Service\ProjectionServiceFactory;
use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId;
use Neos\ContentRepository\TestSuite\Behavior\Features\Bootstrap\Helpers\GherkinTableNodeBasedContentDimensionSource;
use Neos\EventStore\EventStoreInterface;
Expand Down Expand Up @@ -179,7 +181,9 @@ protected function setUpContentRepository(ContentRepositoryId $contentRepository
$databaseConnection = (new \ReflectionClass($eventStore))->getProperty('connection')->getValue($eventStore);
$eventTableName = sprintf('cr_%s_events', $contentRepositoryId->value);
$databaseConnection->executeStatement('TRUNCATE ' . $eventTableName);
$contentRepository->resetProjectionStates();
/** @var ProjectionService $projectionService */
$projectionService = $this->contentRepositoryRegistry->buildService($contentRepositoryId, $this->getObject(ProjectionServiceFactory::class));
$projectionService->resetAllProjections();

return $contentRepository;
}
Expand Down
11 changes: 10 additions & 1 deletion Neos.ContentRepository.Core/Classes/Projection/Projections.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@

namespace Neos\ContentRepository\Core\Projection;

use Neos\ContentRepository\Core\Service\ProjectionService;

/**
* An immutable set of Content Repository projections ({@see ProjectionInterface}
*
* @implements \IteratorAggregate<ProjectionInterface>
* @internal
* @internal only used by framework code or services such as {@see ProjectionService}
*/
final class Projections implements \IteratorAggregate, \Countable
{
Expand Down Expand Up @@ -86,6 +88,13 @@ public function getClassNames(): array
return array_keys($this->projections);
}

public function resetAll(): void
{
foreach ($this->projections as $projection) {
$projection->reset();
}
}

/**
* @return \Traversable<ProjectionInterface<ProjectionStateInterface>>
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
<?php

declare(strict_types=1);

namespace Neos\ContentRepositoryRegistry\Service;
namespace Neos\ContentRepository\Core\Service;

use Neos\ContentRepository\Core\ContentRepository;
use Neos\ContentRepository\Core\EventStore\EventNormalizer;
use Neos\ContentRepository\Core\Factory\ContentRepositoryServiceInterface;
use Neos\ContentRepository\Core\Projection\CatchUpOptions;
use Neos\ContentRepository\Core\Projection\ProjectionInterface;
Expand All @@ -14,25 +16,22 @@
use Neos\EventStore\Model\EventStream\VirtualStreamName;

/**
* Content Repository service to perform Projection replays
*
* @internal this is currently only used by the {@see CrCommandController}
* @api
*/
final class ProjectionReplayService implements ContentRepositoryServiceInterface
class ProjectionService implements ContentRepositoryServiceInterface
{

public function __construct(
private readonly Projections $projections,
private readonly ContentRepository $contentRepository,
private readonly EventStoreInterface $eventStore,
private readonly EventStoreInterface $eventStore
) {
}

public function replayProjection(string $projectionAliasOrClassName, CatchUpOptions $options): void
{
$projectionClassName = $this->resolveProjectionClassName($projectionAliasOrClassName);
$this->contentRepository->resetProjectionState($projectionClassName);
$this->contentRepository->catchUpProjection($projectionClassName, $options);
$projection = $this->resolveProjection($projectionAliasOrClassName);
$projection->reset();
$this->contentRepository->catchUpProjection($projection::class, $options);
}

public function replayAllProjections(CatchUpOptions $options, ?\Closure $progressCallback = null): void
Expand All @@ -41,16 +40,15 @@ public function replayAllProjections(CatchUpOptions $options, ?\Closure $progres
if ($progressCallback) {
$progressCallback($classNamesAndAlias['alias']);
}
$this->contentRepository->resetProjectionState($classNamesAndAlias['className']);
$this->contentRepository->catchUpProjection($classNamesAndAlias['className'], $options);
$projection = $this->projections->get($classNamesAndAlias['className']);
$projection->reset();
$this->contentRepository->catchUpProjection($projection::class, $options);
}
}

public function resetAllProjections(): void
{
foreach ($this->projectionClassNamesAndAliases() as $classNamesAndAlias) {
$this->contentRepository->resetProjectionState($classNamesAndAlias['className']);
}
$this->projections->resetAll();
}

public function highestSequenceNumber(): SequenceNumber
Expand All @@ -67,15 +65,15 @@ public function numberOfProjections(): int
}

/**
* @return class-string<ProjectionInterface<ProjectionStateInterface>>
* @return ProjectionInterface<ProjectionStateInterface>
*/
private function resolveProjectionClassName(string $projectionAliasOrClassName): string
private function resolveProjection(string $projectionAliasOrClassName): ProjectionInterface
{
$lowerCaseProjectionName = strtolower($projectionAliasOrClassName);
$projectionClassNamesAndAliases = $this->projectionClassNamesAndAliases();
foreach ($projectionClassNamesAndAliases as $classNamesAndAlias) {
if (strtolower($classNamesAndAlias['className']) === $lowerCaseProjectionName || strtolower($classNamesAndAlias['alias']) === $lowerCaseProjectionName) {
return $classNamesAndAlias['className'];
return $this->projections->get($classNamesAndAlias['className']);
}
}
throw new \InvalidArgumentException(sprintf(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace Neos\ContentRepository\Core\Service;

use Neos\ContentRepository\Core\Factory\ContentRepositoryServiceFactoryDependencies;
use Neos\ContentRepository\Core\Factory\ContentRepositoryServiceFactoryInterface;

/**
* @implements ContentRepositoryServiceFactoryInterface<ProjectionService>
* @api
*/
class ProjectionServiceFactory implements ContentRepositoryServiceFactoryInterface
{
public function build(ContentRepositoryServiceFactoryDependencies $serviceFactoryDependencies): ProjectionService
{
return new ProjectionService(
$serviceFactoryDependencies->projections,
$serviceFactoryDependencies->contentRepository,
$serviceFactoryDependencies->eventStore,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@
use Doctrine\DBAL\Exception as DBALException;
use Doctrine\DBAL\Exception\ConnectionException;
use Neos\ContentRepository\Core\Projection\CatchUpOptions;
use Neos\ContentRepository\Core\Service\ProjectionServiceFactory;
use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId;
use Neos\ContentRepository\LegacyNodeMigration\LegacyMigrationService;
use Neos\ContentRepository\LegacyNodeMigration\LegacyMigrationServiceFactory;
use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry;
use Neos\ContentRepositoryRegistry\Factory\EventStore\DoctrineEventStoreFactory;
use Neos\ContentRepositoryRegistry\Service\ProjectionReplayServiceFactory;
use Neos\Flow\Cli\CommandController;
use Neos\Flow\Persistence\PersistenceManagerInterface;
use Neos\Flow\Property\PropertyMapper;
Expand All @@ -47,7 +47,7 @@ public function __construct(
private readonly PropertyMapper $propertyMapper,
private readonly ContentRepositoryRegistry $contentRepositoryRegistry,
private readonly SiteRepository $siteRepository,
private readonly ProjectionReplayServiceFactory $projectionReplayServiceFactory,
private readonly ProjectionServiceFactory $projectionServiceFactory,
) {
parent::__construct();
}
Expand Down Expand Up @@ -120,7 +120,7 @@ public function migrateLegacyDataCommand(bool $verbose = false, string $config =
}
$this->connection->executeStatement('TRUNCATE ' . $connection->quoteIdentifier($eventTableName));
// we also need to reset the projections; in order to ensure the system runs deterministically
$projectionService = $this->contentRepositoryRegistry->buildService($contentRepositoryId, $this->projectionReplayServiceFactory);
$projectionService = $this->contentRepositoryRegistry->buildService($contentRepositoryId, $this->projectionServiceFactory);
$projectionService->resetAllProjections();
$this->outputLine('Truncated events');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
use Neos\ContentRepository\Core\Projection\ContentGraph\VisibilityConstraints;
use Neos\ContentRepository\Core\Service\ContentStreamPruner;
use Neos\ContentRepository\Core\Service\ContentStreamPrunerFactory;
use Neos\ContentRepository\Core\Service\ProjectionService;
use Neos\ContentRepository\Core\Service\ProjectionServiceFactory;
use Neos\ContentRepository\Core\SharedModel\Exception\RootNodeAggregateDoesNotExist;
use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId;
use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId;
use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamState;
Expand Down Expand Up @@ -279,8 +282,9 @@ abstract protected function getContentRepositoryService(
*/
public function iReplayTheProjection(string $projectionName): void
{
$this->currentContentRepository->resetProjectionState($projectionName);
$this->currentContentRepository->catchUpProjection($projectionName, CatchUpOptions::create());
/** @var ProjectionService $projectionService */
$projectionService = $this->contentRepositoryRegistry->buildService($this->currentContentRepository->id, $this->getObject(ProjectionServiceFactory::class));
$projectionService->replayProjection($projectionName, CatchUpOptions::create());
}

protected function deserializeProperties(array $properties): PropertyValuesToWrite
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
use Neos\ContentRepository\Core\ContentRepository;
use Neos\ContentRepository\Core\Factory\ContentRepositoryServiceFactoryInterface;
use Neos\ContentRepository\Core\Factory\ContentRepositoryServiceInterface;
use Neos\ContentRepository\Core\Service\ProjectionService;
use Neos\ContentRepository\Core\Service\ProjectionServiceFactory;
use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId;
use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry;
use Neos\ContentRepositoryRegistry\Exception\ContentRepositoryNotFoundException;
Expand Down Expand Up @@ -66,7 +68,9 @@ public function iInitializeContentRepository(string $contentRepositoryId): void
$contentRepository->setUp();
self::$alreadySetUpContentRepositories[] = $contentRepository->id;
}
$contentRepository->resetProjectionStates();
/** @var ProjectionService $projectionService */
$projectionService = $this->contentRepositoryRegistry->buildService($contentRepository->id, $this->getObject(ProjectionServiceFactory::class));
$projectionService->resetAllProjections();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
use Neos\ContentRepository\Core\Projection\CatchUpOptions;
use Neos\ContentRepository\Core\Projection\ProjectionStatusType;
use Neos\ContentRepository\Core\Service\ContentStreamPrunerFactory;
use Neos\ContentRepository\Core\Service\ProjectionServiceFactory;
use Neos\ContentRepository\Core\Service\WorkspaceMaintenanceServiceFactory;
use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId;
use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry;
use Neos\ContentRepositoryRegistry\Service\ProjectionReplayServiceFactory;
use Neos\EventStore\Model\Event\SequenceNumber;
use Neos\EventStore\Model\EventStore\StatusType;
use Neos\Flow\Cli\CommandController;
Expand All @@ -22,7 +22,7 @@ final class CrCommandController extends CommandController

public function __construct(
private readonly ContentRepositoryRegistry $contentRepositoryRegistry,
private readonly ProjectionReplayServiceFactory $projectionServiceFactory,
private readonly ProjectionServiceFactory $projectionServiceFactory,
) {
parent::__construct();
}
Expand Down

This file was deleted.

6 changes: 3 additions & 3 deletions Neos.Neos/Classes/Command/CrCommandController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use League\Flysystem\Filesystem;
use League\Flysystem\Local\LocalFilesystemAdapter;
use Neos\ContentRepository\Core\Projection\CatchUpOptions;
use Neos\ContentRepository\Core\Service\ProjectionServiceFactory;
use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId;
use Neos\ContentRepository\Core\SharedModel\Workspace\ContentStreamId;
use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName;
Expand All @@ -15,7 +16,6 @@
use Neos\ContentRepository\Export\ImportService;
use Neos\ContentRepository\Export\ImportServiceFactory;
use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry;
use Neos\ContentRepositoryRegistry\Service\ProjectionReplayServiceFactory;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Cli\CommandController;
use Neos\Flow\Persistence\PersistenceManagerInterface;
Expand All @@ -42,7 +42,7 @@ public function __construct(
private readonly ResourceManager $resourceManager,
private readonly PersistenceManagerInterface $persistenceManager,
private readonly ContentRepositoryRegistry $contentRepositoryRegistry,
private readonly ProjectionReplayServiceFactory $projectionReplayServiceFactory,
private readonly ProjectionServiceFactory $projectionServiceFactory,
private readonly AssetUsageService $assetUsageService,
private readonly WorkspaceService $workspaceService,
) {
Expand Down Expand Up @@ -116,7 +116,7 @@ public function importCommand(string $path, string $contentRepository = 'default

$this->outputLine('Replaying projections');

$projectionService = $this->contentRepositoryRegistry->buildService($contentRepositoryId, $this->projectionReplayServiceFactory);
$projectionService = $this->contentRepositoryRegistry->buildService($contentRepositoryId, $this->projectionServiceFactory);
$projectionService->replayAllProjections(CatchUpOptions::create());

$this->outputLine('Assigning live workspace role');
Expand Down
4 changes: 0 additions & 4 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
parameters:
ignoreErrors:
-
message: "#^The internal method \"Neos\\\\ContentRepository\\\\Core\\\\Projection\\\\Projections\\:\\:getClassNames\" is called\\.$#"
count: 1
path: Neos.ContentRepositoryRegistry/Classes/Service/ProjectionReplayService.php

-
message: "#^Method Neos\\\\Neos\\\\Controller\\\\Backend\\\\MenuHelper\\:\\:buildModuleList\\(\\) return type has no value type specified in iterable type array\\.$#"
Expand Down

0 comments on commit bff61f3

Please sign in to comment.