From af074432877a4761500a38bda2dc90db74c792f0 Mon Sep 17 00:00:00 2001 From: frank-ulrich-weber Date: Tue, 5 Nov 2024 13:13:03 +0100 Subject: [PATCH] [FEATURE] Update schema using Solr Schema API (#1369) Co-authored-by: Sebastian Meyer --- Classes/Updates/UpdateSolrSchema.php | 205 ++++++++++++++++++++++++++ Documentation/Administrator/Index.rst | 3 + ext_localconf.php | 2 + 3 files changed, 210 insertions(+) create mode 100644 Classes/Updates/UpdateSolrSchema.php diff --git a/Classes/Updates/UpdateSolrSchema.php b/Classes/Updates/UpdateSolrSchema.php new file mode 100644 index 000000000..fdcbfae0e --- /dev/null +++ b/Classes/Updates/UpdateSolrSchema.php @@ -0,0 +1,205 @@ + + * + * This file is part of the Kitodo and TYPO3 projects. + * + * @license GNU General Public License version 3 or later. + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + */ + +namespace Kitodo\Dlf\Updates; + +use Kitodo\Dlf\Common\Solr\Solr; +use Solarium\Core\Client\Request; +use TYPO3\CMS\Core\Database\ConnectionPool; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Install\Updates\DatabaseUpdatedPrerequisite; +use TYPO3\CMS\Install\Updates\UpgradeWizardInterface; + +/** + * Class UpdateSolrSchema + * + * @package TYPO3 + * @subpackage dlf + * + * @internal + */ +class UpdateSolrSchema implements UpgradeWizardInterface +{ + + /** + * Return the identifier for this wizard + * This should be the same string as used in the ext_localconf class registration + * + * @access public + * + * @return string + */ + public function getIdentifier(): string + { + return self::class; + } + + /** + * Return the speaking name of this wizard + * + * @access public + * + * @return string + */ + public function getTitle(): string + { + return 'Update Solr schema'; + } + + /** + * Return the description for this wizard + * + * @access public + * + * @return string + */ + public function getDescription(): string + { + return 'This wizard updates the schema of all available Solr cores'; + } + + /** + * Execute the update + * + * Called when a wizard reports that an update is necessary + * + * @access public + * + * @return bool + */ + public function executeUpdate(): bool + { + $affectedSolrCores = $this->getAllAffectedSolrCores(); + + foreach ($affectedSolrCores as $affectedSolrCore) { + + $solr = Solr::getInstance($affectedSolrCore['uid']); + if (!$solr->ready) { + continue; + } + + $query = $solr->service->createApi( + [ + 'version' => Request::API_V1, + 'handler' => $affectedSolrCore['index_name'].'/schema', + 'method' => Request::METHOD_POST, + 'rawdata' => json_encode( + [ + 'replace-field' => [ + 'name' => 'autocomplete', + 'type' => 'autocomplete', + 'indexed' => true, + 'stored' => true, + 'multiValued' => true, + ], + ] + ), + ] + ); + $result = $solr->service->execute($query); + + if ($result->getResponse()->getStatusCode() == 400) { + return false; + } + } + return true; + } + + /** + * Is an update necessary? + * + * Looks for all affected Solr cores + * + * @access public + * + * @return bool + */ + public function updateNecessary(): bool + { + if (count($this->getAllAffectedSolrCores())) { + return true; + } + return false; + } + + /** + * Returns an array of class names of Prerequisite classes + * + * This way a wizard can define dependencies like "database up-to-date" or + * "reference index updated" + * + * @access public + * + * @return string[] + */ + public function getPrerequisites(): array + { + return [ + DatabaseUpdatedPrerequisite::class + ]; + } + + /** + * Returns all affected Solr cores + * + * @access private + * + * @return array + */ + private function getAllAffectedSolrCores(): array + { + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('tx_dlf_solrcores'); + + $allSolrCores = $queryBuilder->select('uid', 'index_name') + ->from('tx_dlf_solrcores') + ->execute() + ->fetchAllAssociative(); + + $affectedSolrCores = []; + + foreach ($allSolrCores as $solrCore) { + $solr = Solr::getInstance($solrCore['uid']); + if (!$solr->ready) { + continue; + } + + $query = $solr->service->createApi( + [ + 'version' => Request::API_V1, + 'handler' => $solrCore['index_name'].'/config/schemaFactory', + 'method' => Request::METHOD_GET + ] + ); + $result = $solr->service->execute($query)->getData(); + + if (!isset($result['config']['schemaFactory']['class']) || $result['config']['schemaFactory']['class'] != 'ManagedIndexSchemaFactory') { + continue; + } + + $query = $solr->service->createApi( + [ + 'version' => Request::API_V1, + 'handler' => $solrCore['index_name'].'/schema/fields/autocomplete', + 'method' => Request::METHOD_GET + ] + ); + $result = $solr->service->execute($query)->getData(); + + if (!isset($result['field']['stored']) || $result['field']['stored'] === true) { + continue; + } + + $affectedSolrCores[] = $solrCore; + } + return $affectedSolrCores; + } +} diff --git a/Documentation/Administrator/Index.rst b/Documentation/Administrator/Index.rst index c2a2ee85b..449e00bee 100644 --- a/Documentation/Administrator/Index.rst +++ b/Documentation/Administrator/Index.rst @@ -220,6 +220,9 @@ b. Rename solrconfig_8.11.2.xml in $SOLR_HOME/configsets/dlf/ to solrconfig.xml c. Restart Solr. d. Reindex all documents. This can be done by the kitodo:reindex CLI command with the '-a' (all) flag. See: :ref:`reindex_collections`. +Furthermore version 5.1 supports the use of Solr Managed Schemas to update the schemas automatically during the update of the extension. +To use this feature you have to change the schemaFactory within solrconfig.xml from "ClassicIndexSchemaFactory" to "ManagedIndexSchemaFactory". + ******* Logging ******* diff --git a/ext_localconf.php b/ext_localconf.php index d79f6abe9..09914da11 100644 --- a/ext_localconf.php +++ b/ext_localconf.php @@ -156,6 +156,8 @@ = \Kitodo\Dlf\Updates\MigrateSettings::class; $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'][\Kitodo\Dlf\Updates\FileLocationUpdater::class] = \Kitodo\Dlf\Updates\FileLocationUpdater::class; +$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install']['update'][\Kitodo\Dlf\Updates\UpdateSolrSchema::class] += \Kitodo\Dlf\Updates\UpdateSolrSchema::class; \TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin( 'Dlf',