Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEATURE: WIP state of Neos 9 compatibility #7

Draft
wants to merge 16 commits into
base: main
Choose a base branch
from
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
79 changes: 79 additions & 0 deletions Classes/Command/NodeIndexCommandController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?php
declare(strict_types=1);

namespace Sandstorm\LightweightElasticsearch\Command;

/*
* This file is part of the Sandstorm.LightweightElasticsearch package.
*
* (c) Contributors of the Neos Project - www.neos.io
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/

use Neos\ContentRepository\Core\SharedModel\ContentRepository\ContentRepositoryId;
use Neos\ContentRepository\Core\SharedModel\Workspace\WorkspaceName;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Cli\CommandController;
use Neos\Flow\Log\Backend\ConsoleBackend;
use Neos\Flow\Log\Psr\Logger;
use Neos\Flow\Log\Utility\LogEnvironment;
use Neos\Utility\Files;
use Sandstorm\LightweightElasticsearch\Factory\ElasticsearchFactory;

/**
* Provides CLI features for index handling
*/
#[Flow\Scope("singleton")]
class NodeIndexCommandController extends CommandController
{
#[Flow\Inject]
protected ElasticsearchFactory $elasticsearchFactory;

/**
* Index all nodes by creating a new index and when everything was completed, switch the index alias.
*
* This command (re-)indexes all nodes contained in the content repository and sets the schema beforehand.
*
* @param string $workspace name of the workspace which should be indexed
* @param bool $verbose output extra details
*/
public function buildCommand(string $workspace = 'live', bool $verbose = false): void
{
$consoleLogBackend = new ConsoleBackend();
if ($verbose) {
$consoleLogBackend->setSeverityThreshold(LOG_DEBUG);
}
$logger = new Logger([$consoleLogBackend]);

$elasticsearch = $this->elasticsearchFactory->build(ContentRepositoryId::fromString('default'), $logger);


$elasticsearch->indexWorkspace(WorkspaceName::fromString($workspace));
$this->outputMemoryUsage();
}

/**
* Clean up old indexes (i.e. all but the current one)
*
* @return void
*/
public function cleanupCommand(string $workspace = 'live', bool $verbose = false): void
{
$consoleLogBackend = new ConsoleBackend();
if ($verbose) {
$consoleLogBackend->setSeverityThreshold(LOG_DEBUG);
}
$logger = new Logger([$consoleLogBackend]);

$elasticsearch = $this->elasticsearchFactory->build(ContentRepositoryId::fromString('default'), $logger);
$elasticsearch->removeObsoleteIndices(WorkspaceName::fromString($workspace));
}

private function outputMemoryUsage(): void
{
$this->outputLine('! Memory usage %s', [Files::bytesToSizeString(memory_get_usage(true))]);
}
}
103 changes: 103 additions & 0 deletions Classes/Command/NodeIndexMappingCommandController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?php
declare(strict_types=1);

namespace Sandstorm\LightweightElasticsearch\Command;

/*
* This file is part of the Flowpack.ElasticSearch.ContentRepositoryAdaptor package.
*
* (c) Contributors of the Neos Project - www.neos.io
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/

use Flowpack\ElasticSearch\ContentRepositoryAdaptor\Driver\NodeTypeMappingBuilderInterface;
use Flowpack\ElasticSearch\ContentRepositoryAdaptor\Exception;
use Flowpack\ElasticSearch\ContentRepositoryAdaptor\Indexer\NodeIndexer;
use Flowpack\ElasticSearch\ContentRepositoryAdaptor\Service\DimensionsService;
use Flowpack\ElasticSearch\Domain\Model\Mapping;
use Neos\ContentRepository\Domain\Service\ContentDimensionCombinator;
use Neos\ContentRepositoryRegistry\ContentRepositoryRegistry;
use Neos\Flow\Annotations as Flow;
use Neos\Flow\Cli\CommandController;
use Symfony\Component\Yaml\Yaml;
use function json_encode;

/**
* Provides CLI features for checking mapping information
*/
#[Flow\Scope('singleton')]
class NodeIndexMappingCommandController extends CommandController
{
#[Flow\Inject]
protected ContentRepositoryRegistry $contentRepositoryRegistry;

/**
* Shows the mapping between dimensions presets and index name
*
* @throws Exception
*/
public function indicesCommand(): void
{
$indexName = $this->nodeIndexer->getIndexName();

$headers = ['Dimension Preset', 'Index Name'];
$rows = [];
$contentRepository = $this->contentRepositoryRegistry->get(\Neos\ContentRepository\Core\Factory\ContentRepositoryId::fromString('default'));
$dimensionSpacePoints = $contentRepository->getInterDimensionalVariationGraph()->getDimensionSpacePoints();
// TODO 9.0 migration: try to directly work with $dimensionSpacePoints, instead of converting them to the legacy dimension format


foreach (array_map(fn(\Neos\ContentRepository\Core\DimensionSpace\DimensionSpacePoint $dimensionSpacePoint) => $dimensionSpacePoint->toLegacyDimensionArray(), iterator_to_array($dimensionSpacePoints)) as $dimensionValues) {
$rows[] = [
json_encode($dimensionValues),
sprintf('%s-%s', $indexName, $this->dimensionsService->hash($dimensionValues))
];
}

$this->output->outputTable($rows, $headers);
}

/**
* Show the mapping which would be sent to the ElasticSearch server
*
* @return void
*/
public function mappingCommand(): void
{
try {
$nodeTypeMappingCollection = $this->nodeTypeMappingBuilder->buildMappingInformation($this->nodeIndexer->getIndex());
} catch (\Exception $e) {
$this->outputLine('Unable to get the current index');
$this->sendAndExit(1);
}

foreach ($nodeTypeMappingCollection as $mapping) {
/** @var Mapping $mapping */
$this->output(Yaml::dump($mapping->asArray(), 5, 2));
$this->outputLine();
}
$this->outputLine('------------');

$mappingErrors = $this->nodeTypeMappingBuilder->getLastMappingErrors();
if ($mappingErrors->hasErrors()) {
$this->outputLine('<b>Mapping Errors</b>');
foreach ($mappingErrors->getFlattenedErrors() as $errors) {
foreach ($errors as $error) {
$this->outputLine('<error>%s</error>', [$error]);
}
}
}

if ($mappingErrors->hasWarnings()) {
$this->outputLine('<b>Mapping Warnings</b>');
foreach ($mappingErrors->getFlattenedWarnings() as $warnings) {
foreach ($warnings as $warning) {
$this->outputLine('<comment>%s</comment>', [$warning]);
}
}
}
}
}
Loading