Skip to content

Commit

Permalink
[TASK:BP:11.6] Consider queue initialization status
Browse files Browse the repository at this point in the history
Queue initialization status returned by the QueueInitializationService
isn't considered in the backend module and a success message is always
shown. This commit adds a check for the returned status and displays an
error message similiar to the message that is shown if an exceptions
occured.

Ports: TYPO3-Solr#3764
Resolves: TYPO3-Solr#3763
  • Loading branch information
dkd-friedrich committed Mar 12, 2024
1 parent 65e1ef2 commit 1bb4381
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ abstract class AbstractModuleController extends ActionController
protected int $requestedPageUID;

/**
* @var ?Site
* @var Site|null
*/
protected ?Site $selectedSite = null;

Expand Down
137 changes: 103 additions & 34 deletions Classes/Controller/Backend/Search/IndexQueueModuleController.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
use ApacheSolrForTypo3\Solr\Domain\Index\Queue\QueueInitializationService;
use ApacheSolrForTypo3\Solr\IndexQueue\Queue;
use ApacheSolrForTypo3\Solr\IndexQueue\QueueInterface;
use ApacheSolrForTypo3\Solr\IndexQueue\QueueInitializationServiceAwareInterface;
use Psr\Http\Message\ResponseInterface;
use TYPO3\CMS\Backend\Form\Exception as BackendFormException;
use TYPO3\CMS\Core\Http\RedirectResponse;
Expand All @@ -32,25 +31,43 @@
/**
* Index Queue Module
*
* @todo: Support all index queues in actions beside "initializeIndexQueueAction" and
* "resetLogErrorsAction"
*
* @author Ingo Renner <[email protected]>
*/
class IndexQueueModuleController extends AbstractModuleController
{
/**
* The default Solr Queue
* @var QueueInterface
*/
protected QueueInterface $indexQueue;

/**
* Enabled Solr index queues
*
* @var QueueInterface[]
*/
protected array $enabledIndexQueues;

/**
* Initializes the controller before invoking an action method.
*/
protected function initializeAction()
{
parent::initializeAction();
$this->indexQueue = GeneralUtility::makeInstance(Queue::class);

$this->enabledIndexQueues = $this->getIndexQueues();
if (!empty($this->enabledIndexQueues)) {
$this->indexQueue = $this->enabledIndexQueues[Queue::class] ?? reset($this->enabledIndexQueues);
}
}

/**
* Sets the default queue to use
*
* @param QueueInterface $indexQueue
*/
public function setIndexQueue(QueueInterface $indexQueue)
Expand Down Expand Up @@ -88,6 +105,11 @@ protected function canQueueSelectedSite(): bool
if ($this->selectedSite === null || empty($this->solrConnectionManager->getConnectionsBySite($this->selectedSite))) {
return false;
}

if (!isset($this->indexQueue)) {
return false;
}

$enabledIndexQueueConfigurationNames = $this->selectedSite->getSolrConfiguration()->getEnabledIndexQueueConfigurationNames();
if (empty($enabledIndexQueueConfigurationNames)) {
return false;
Expand Down Expand Up @@ -122,24 +144,63 @@ public function initializeIndexQueueAction(): ResponseInterface

$indexingConfigurationsToInitialize = GeneralUtility::_POST('tx_solr-index-queue-initialization');
if ((!empty($indexingConfigurationsToInitialize)) && (is_array($indexingConfigurationsToInitialize))) {
// initialize selected indexing configuration
try {
if ($this->indexQueue instanceof QueueInitializationServiceAwareInterface) {
$initializationService = $this->indexQueue->getQueueInitializationService();
} else {
$initializationService = GeneralUtility::makeInstance(QueueInitializationService::class);
/** @var QueueInitializationService $initializationService */
$initializationService = GeneralUtility::makeInstance(QueueInitializationService::class);
foreach ($indexingConfigurationsToInitialize as $configurationToInitialize) {
$indexQueueClass = $this->selectedSite->getSolrConfiguration()->getIndexQueueClassByConfigurationName($configurationToInitialize);
$indexQueue = $this->enabledIndexQueues[$indexQueueClass];

try {
$status = $initializationService->initializeBySiteAndIndexConfigurations($this->selectedSite, [$configurationToInitialize]);
$initializedIndexingConfiguration = [
'status' => $status[$configurationToInitialize],
'statistic' => 0,
];
if ($status[$configurationToInitialize] === true) {
$initializedIndexingConfiguration['totalCount'] = $indexQueue->getStatisticsBySite($this->selectedSite, $configurationToInitialize)->getTotalCount();
}
$initializedIndexingConfigurations[$configurationToInitialize] = $initializedIndexingConfiguration;
} catch (\Throwable $e) {
$this->addFlashMessage(
sprintf(
LocalizationUtility::translate(
'solr.backend.index_queue_module.flashmessage.initialize_failure',
'Solr'
),
$e->getMessage(),
$e->getCode()
),
LocalizationUtility::translate(
'solr.backend.index_queue_module.flashmessage.initialize_failure.title',
'Solr'
),
FlashMessage::ERROR
);
}
}
} else {
$messageLabel = 'solr.backend.index_queue_module.flashmessage.initialize.no_selection';
$titleLabel = 'solr.backend.index_queue_module.flashmessage.not_initialized.title';
$this->addFlashMessage(
LocalizationUtility::translate($messageLabel, 'Solr'),
LocalizationUtility::translate($titleLabel, 'Solr'),
FlashMessage::WARNING
);
}

$initializedIndexingConfigurations = $initializationService->initializeBySiteAndIndexConfigurations($this->selectedSite, $indexingConfigurationsToInitialize);
} catch (\Throwable $e) {
$messagesForConfigurations = [];
foreach ($initializedIndexingConfigurations as $indexingConfigurationName => $initializationData) {
if ($initializationData['status'] === true) {
$messagesForConfigurations[] = $indexingConfigurationName . ' (' . $initializationData['totalCount'] . ' records)';
} else {
$this->addFlashMessage(
sprintf(
LocalizationUtility::translate(
'solr.backend.index_queue_module.flashmessage.initialize_failure',
'Solr'
),
$e->getMessage(),
$e->getCode()
$indexingConfigurationName,
1662117020
),
LocalizationUtility::translate(
'solr.backend.index_queue_module.flashmessage.initialize_failure.title',
Expand All @@ -148,22 +209,9 @@ public function initializeIndexQueueAction(): ResponseInterface
FlashMessage::ERROR
);
}
} else {
$messageLabel = 'solr.backend.index_queue_module.flashmessage.initialize.no_selection';
$titleLabel = 'solr.backend.index_queue_module.flashmessage.not_initialized.title';
$this->addFlashMessage(
LocalizationUtility::translate($messageLabel, 'Solr'),
LocalizationUtility::translate($titleLabel, 'Solr'),
FlashMessage::WARNING
);
}
$messagesForConfigurations = [];
foreach (array_keys($initializedIndexingConfigurations) as $indexingConfigurationName) {
$itemCount = $this->indexQueue->getStatisticsBySite($this->selectedSite, $indexingConfigurationName)->getTotalCount();
$messagesForConfigurations[] = $indexingConfigurationName . ' (' . $itemCount . ' records)';
}

if (!empty($initializedIndexingConfigurations)) {
if (!empty($messagesForConfigurations)) {
$messageLabel = 'solr.backend.index_queue_module.flashmessage.initialize.success';
$titleLabel = 'solr.backend.index_queue_module.flashmessage.initialize.title';
$this->addFlashMessage(
Expand All @@ -183,17 +231,19 @@ public function initializeIndexQueueAction(): ResponseInterface
*/
public function resetLogErrorsAction(): ResponseInterface
{
$resetResult = $this->indexQueue->resetAllErrors();
foreach ($this->enabledIndexQueues as $queue) {
$resetResult = $queue->resetAllErrors();

$label = 'solr.backend.index_queue_module.flashmessage.success.reset_errors';
$severity = FlashMessage::OK;
if (!$resetResult) {
$label = 'solr.backend.index_queue_module.flashmessage.error.reset_errors';
$severity = FlashMessage::ERROR;
}

$label = 'solr.backend.index_queue_module.flashmessage.success.reset_errors';
$severity = FlashMessage::OK;
if (!$resetResult) {
$label = 'solr.backend.index_queue_module.flashmessage.error.reset_errors';
$severity = FlashMessage::ERROR;
$this->addIndexQueueFlashMessage($label, $severity);
}

$this->addIndexQueueFlashMessage($label, $severity);

return new RedirectResponse($this->uriBuilder->uriFor('index'), 303);
}

Expand Down Expand Up @@ -278,4 +328,23 @@ protected function addIndexQueueFlashMessage(string $label, int $severity)
{
$this->addFlashMessage(LocalizationUtility::translate($label, 'Solr'), LocalizationUtility::translate('solr.backend.index_queue_module.flashmessage.title', 'Solr'), $severity);
}

/**
* Get index queues
*
* @return QueueInterface[]
*/
protected function getIndexQueues(): array
{
$queues = [];
$configuration = $this->selectedSite->getSolrConfiguration();
foreach ($configuration->getEnabledIndexQueueConfigurationNames() as $indexingConfiguration) {
$indexQueueClass = $configuration->getIndexQueueClassByConfigurationName($indexingConfiguration);
if (!isset($queues[$indexQueueClass])) {
$queues[$indexQueueClass] = GeneralUtility::makeInstance($indexQueueClass);
}
}

return $queues;
}
}
21 changes: 13 additions & 8 deletions Classes/Domain/Index/Queue/Statistic/QueueStatisticsRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@
*/
class QueueStatisticsRepository extends AbstractRepository
{
/**
* @var string
*/
protected string $table = 'tx_solr_indexqueue_item';
protected string $columnIndexed = 'indexed';
protected string $columnIndexingConfiguration = 'indexing_configuration';
protected string $columnChanged = 'changed';
protected string $columnErrors = 'errors';
protected string $columnRootpage = 'root';

/**
* Extracts the number of pending, indexed and erroneous items from the
Expand All @@ -53,23 +55,26 @@ public function findOneByRootPidAndOptionalIndexingConfigurationName(
$queryBuilder = $this->getQueryBuilder();
$queryBuilder
->add('select', vsprintf('(%s < %s) AS %s', [
$queryBuilder->quoteIdentifier('indexed'),
$queryBuilder->quoteIdentifier('changed'),
$queryBuilder->quoteIdentifier($this->columnIndexed),
$queryBuilder->quoteIdentifier($this->columnChanged),
$queryBuilder->quoteIdentifier('pending'),
]), true)
->add('select', vsprintf('(%s) AS %s', [
$queryBuilder->expr()->notLike('errors', $queryBuilder->createNamedParameter('')),
$queryBuilder->expr()->notLike($this->columnErrors, $queryBuilder->createNamedParameter('')),
$queryBuilder->quoteIdentifier('failed'),
]), true)
->add('select', $queryBuilder->expr()->count('*', 'count'), true)
->from($this->table)
->where(
$queryBuilder->expr()->eq('root', $queryBuilder->createNamedParameter($rootPid, PDO::PARAM_INT))
$queryBuilder->expr()->eq($this->columnRootpage, $queryBuilder->createNamedParameter($rootPid, PDO::PARAM_INT))
)->groupBy('pending', 'failed');

if (!empty($indexingConfigurationName)) {
$queryBuilder->andWhere(
$queryBuilder->expr()->eq('indexing_configuration', $queryBuilder->createNamedParameter($indexingConfigurationName))
$queryBuilder->expr()->eq(
$this->columnIndexingConfiguration,
$queryBuilder->createNamedParameter($indexingConfigurationName)
)
);
}

Expand Down

0 comments on commit 1bb4381

Please sign in to comment.