From 23fc1be8336f4bb5017a0dafcd80540afc637428 Mon Sep 17 00:00:00 2001 From: David Monllao Date: Thu, 24 Mar 2016 18:10:49 +0800 Subject: [PATCH] MDL-53535 search_solr: Solr version restrictions Also removing is_server_ready call from execute_query as in production workflows search is done through \core_search\manager::search and \core_search\manager::instance already checks is_server_ready. In testing environment setUp functions should check that the server is ready before performing other actions. --- search/classes/engine.php | 2 - search/classes/manager.php | 2 + search/engine/solr/classes/engine.php | 52 ++++++++++++++++------ search/engine/solr/classes/schema.php | 22 +++++++++ search/engine/solr/lang/en/search_solr.php | 2 + search/engine/solr/setup_schema.php | 20 ++++++++- 6 files changed, 82 insertions(+), 18 deletions(-) diff --git a/search/classes/engine.php b/search/classes/engine.php index b157d83f00c..757e6f369f2 100644 --- a/search/classes/engine.php +++ b/search/classes/engine.php @@ -79,8 +79,6 @@ abstract class engine { * * Search engine availability should be checked separately. * - * @see self::is_installed - * @see self::is_server_ready * @return void */ public function __construct() { diff --git a/search/classes/manager.php b/search/classes/manager.php index 47d8b0518dd..cc2547a69d7 100644 --- a/search/classes/manager.php +++ b/search/classes/manager.php @@ -109,6 +109,8 @@ class manager { /** * Returns an initialised \core_search instance. * + * @see \core_search\engine::is_installed + * @see \core_search\engine::is_server_ready * @throws \core_search\engine_exception * @return \core_search\manager */ diff --git a/search/engine/solr/classes/engine.php b/search/engine/solr/classes/engine.php index 3b0c4894522..a88b181fb07 100644 --- a/search/engine/solr/classes/engine.php +++ b/search/engine/solr/classes/engine.php @@ -112,11 +112,6 @@ class engine extends \core_search\engine { // If there is any problem we trigger the exception as soon as possible. $client = $this->get_search_client(); - $serverstatus = $this->is_server_ready(); - if ($serverstatus !== true) { - throw new \core_search\engine_exception('engineserverstatus', 'search'); - } - $query = new \SolrDisMaxQuery(); $maxrows = \core_search\manager::MAX_RESULTS; if ($this->file_indexing_enabled()) { @@ -948,6 +943,29 @@ class engine extends \core_search\engine { */ public function is_server_ready() { + $configured = $this->is_server_configured(); + if ($configured !== true) { + return $configured; + } + + // Check that the schema is already set up. + try { + $schema = new \search_solr\schema(); + $schema->validate_setup(); + } catch (\moodle_exception $e) { + return $e->getMessage(); + } + + return true; + } + + /** + * Is the solr server properly configured?. + * + * @return true|string Returns true if all good or an error string. + */ + public function is_server_configured() { + if (empty($this->config->server_hostname) || empty($this->config->indexname)) { return 'No solr configuration found'; } @@ -957,24 +975,30 @@ class engine extends \core_search\engine { } try { - @$client->ping(); + if ($this->get_solr_major_version() < 4) { + // Minimum solr 4.0. + return get_string('minimumsolr4', 'search_solr'); + } } catch (\SolrClientException $ex) { return 'Solr client error: ' . $ex->getMessage(); } catch (\SolrServerException $ex) { return 'Solr server error: ' . $ex->getMessage(); } - // Check that setup schema has already run. - try { - $schema = new \search_solr\schema(); - $schema->validate_setup(); - } catch (\moodle_exception $e) { - return $e->getMessage(); - } - return true; } + /** + * Returns the solr server major version. + * + * @return int + */ + public function get_solr_major_version() { + $systemdata = $this->get_search_client()->system(); + $solrversion = $systemdata->getResponse()->offsetGet('lucene')->offsetGet('solr-spec-version'); + return intval(substr($solrversion, 0, strpos($solrversion, '.'))); + } + /** * Checks if the PHP Solr extension is available. * diff --git a/search/engine/solr/classes/schema.php b/search/engine/solr/classes/schema.php index 63dfdd20ae9..ed854ce075a 100644 --- a/search/engine/solr/classes/schema.php +++ b/search/engine/solr/classes/schema.php @@ -79,6 +79,28 @@ class schema { $this->curl->setHeader('Content-type: application/json'); } + /** + * Can setup be executed against the configured server. + * + * @return true|string True or error message. + */ + public function can_setup_server() { + + $engine = new \search_solr\engine(); + $status = $engine->is_server_configured(); + if ($status !== true) { + return $status; + } + + // We know that the server is ready here. + if ($engine->get_solr_major_version() < 5) { + // Schema setup script only available for 5.0 onwards. + return get_string('schemasetupfromsolr5', 'search_solr'); + } + + return true; + } + /** * Setup solr stuff required by moodle. * diff --git a/search/engine/solr/lang/en/search_solr.php b/search/engine/solr/lang/en/search_solr.php index ca06662247a..9b8613f1f83 100644 --- a/search/engine/solr/lang/en/search_solr.php +++ b/search/engine/solr/lang/en/search_solr.php @@ -32,11 +32,13 @@ $string['fileindexing_help'] = 'If your Solr install supports it, this feature a $string['fileindexsettings'] = 'File indexing settings'; $string['maxindexfilekb'] = 'Maximum file size to index (kB)'; $string['maxindexfilekb_help'] = 'Files larger than this number of kilobytes will be skipped for search indexing. 0 to index files of any size.'; +$string['minimumsolr4'] = 'Solr 4.0 is the minimum version required for Moodle'; $string['missingconfig'] = 'Your Apache Solr server is not yet configured in Moodle.'; $string['multivaluedfield'] = 'Field "{$a}" returned an array instead of a scalar, the field is probably defined in Solr with "Multivalued" to true, this means that Solr autocreated the field for you when you indexed data because you forgot to run search/engine/solr/cli/setup_schema.php. Please delete the current index, create a new one and run setup_schema.php before indexing data in Solr.'; $string['nodatafromserver'] = 'No data from server'; $string['pluginname'] = 'Solr'; $string['schemafieldautocreated'] = 'Field "{$a}" already exists in Solr schema. You probably forgot to run this script before indexing data and fields were autocreated by Solr. Please delete the current index, create a new one and run setup_schema.php again before indexing data in Solr.'; +$string['schemasetupfromsolr5'] = 'Your Solr server version is lower than 5.0, this script can only set your schema if your Solr version is 5.0 or higher. You need to manually set the fields in your schema according to \\search_solr\\document::get_default_fields_definition()'; $string['searchinfo'] = 'Search queries'; $string['searchinfo_help'] = 'Features you can use while performing search queries: diff --git a/search/engine/solr/setup_schema.php b/search/engine/solr/setup_schema.php index 4ea17e218e3..b38fe0658b3 100644 --- a/search/engine/solr/setup_schema.php +++ b/search/engine/solr/setup_schema.php @@ -34,8 +34,24 @@ require_once($CFG->libdir.'/adminlib.php'); require_login(null, false); require_capability('moodle/site:config', context_system::instance()); +$returnurl = new moodle_url('/admin/settings.php', array('section' => 'manageglobalsearch')); + $schema = new \search_solr\schema(); + +$status = $schema->can_setup_server(); +if ($status !== true) { + + $PAGE->set_context(context_system::instance()); + $PAGE->set_url(new moodle_url('/search/engine/solr/setup_schema.php')); + + echo $OUTPUT->header(); + echo $OUTPUT->notification($status, \core\output\notification::NOTIFY_ERROR); + echo $OUTPUT->box($OUTPUT->action_link($returnurl, get_string('continue')), 'generalbox centerpara'); + echo $OUTPUT->footer(); + + exit(1); +} + $schema->setup(); -$url = new moodle_url('/admin/settings.php', array('section' => 'manageglobalsearch')); -redirect($url, get_string('setupok', 'search_solr'), 4); +redirect($returnurl, get_string('setupok', 'search_solr'), 4);