Bug 19542: Add a check for ES configuration health
authorTomas Cohen Arazi <tomascohen@theke.io>
Tue, 31 Oct 2017 14:26:36 +0000 (11:26 -0300)
committerJonathan Druart <jonathan.druart@bugs.koha-community.org>
Mon, 11 Dec 2017 17:30:42 +0000 (14:30 -0300)
This patch adds a new statuc function to Koha::SearchEngine::ElasticSearch
which is instended to replace most of get_elasticsearch_params. This function
reads the configuration from C4::Context->config('elasticsearch') and raises
relevant exceptions when mandatory entries are missing.

Its behaviour is covered by tests.

To test:
- Run:
  $ kshell
 k$ prove t/Koha/SearchEngine/Elasticsearch.t
=> SUCCESS: Tests pass!
- Sign off :-D

Signed-off-by: David Bourgault <david.bourgault@inlibro.com>

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>

Koha/Exceptions/Config.pm [new file with mode: 0644]
Koha/SearchEngine/Elasticsearch.pm
t/Koha/SearchEngine/Elasticsearch.t [new file with mode: 0644]

diff --git a/Koha/Exceptions/Config.pm b/Koha/Exceptions/Config.pm
new file mode 100644 (file)
index 0000000..14ae315
--- /dev/null
@@ -0,0 +1,16 @@
+package Koha::Exceptions::Config;
+
+use Modern::Perl;
+
+use Exception::Class (
+
+    'Koha::Exceptions::Config' => {
+        description => 'Something went wrong!',
+    },
+    'Koha::Exceptions::Config::MissingEntry' => {
+        isa => 'Koha::Exceptions::Config',
+        description => 'The required entry is missing in the configuration file'
+    }
+);
+
+1;
index 85a20a9..d859a39 100644 (file)
@@ -22,6 +22,7 @@ use base qw(Class::Accessor);
 use C4::Context;
 
 use Koha::Database;
+use Koha::Exceptions::Config;
 use Koha::SearchFields;
 use Koha::SearchMarcMaps;
 
@@ -29,6 +30,8 @@ use Carp;
 use JSON;
 use Modern::Perl;
 use Readonly;
+use Search::Elasticsearch;
+use Try::Tiny;
 use YAML::Syck;
 
 use Data::Dumper;    # TODO remove
@@ -475,6 +478,65 @@ sub process_error {
     return "Unable to perform your search. Please try again.\n";
 }
 
+=head2 _read_configuration
+
+    my $conf = _read_configuration();
+
+Reads the I<configuration file> and returns a hash structure with the
+configuration information. It raises an exception if mandatory entries
+are missing.
+
+The hashref structure has the following form:
+
+    {
+        'nodes' => ['127.0.0.1:9200', 'anotherserver:9200'],
+        'index_name' => 'koha_instance',
+    }
+
+This is configured by the following in the C<config> block in koha-conf.xml:
+
+    <elasticsearch>
+        <server>127.0.0.1:9200</server>
+        <server>anotherserver:9200</server>
+        <index_name>koha_instance</index_name>
+    </elasticsearch>
+
+=cut
+
+sub _read_configuration {
+
+    my $configuration;
+
+    my $conf = C4::Context->config('elasticsearch');
+    Koha::Exceptions::Config::MissingEntry->throw(
+        "Missing 'elasticsearch' block in config file")
+      unless defined $conf;
+
+    if ( $conf && $conf->{server} ) {
+        my $nodes = $conf->{server};
+        if ( ref($nodes) eq 'ARRAY' ) {
+            $configuration->{nodes} = $nodes;
+        }
+        else {
+            $configuration->{nodes} = [$nodes];
+        }
+    }
+    else {
+        Koha::Exceptions::Config::MissingEntry->throw(
+            "Missing 'server' entry in config file for elasticsearch");
+    }
+
+    if ( defined $conf->{index_name} ) {
+        $configuration->{index_name} = $conf->{index_name};
+    }
+    else {
+        Koha::Exceptions::Config::MissingEntry->throw(
+            "Missing 'index_name' entry in config file for elasticsearch");
+    }
+
+    return $configuration;
+}
+
 1;
 
 __END__
diff --git a/t/Koha/SearchEngine/Elasticsearch.t b/t/Koha/SearchEngine/Elasticsearch.t
new file mode 100644 (file)
index 0000000..f7a7f27
--- /dev/null
@@ -0,0 +1,86 @@
+#!/usr/bin/perl
+#
+# This file is part of Koha.
+#
+# Koha is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# Koha is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Koha; if not, see <http://www.gnu.org/licenses>.
+
+use Modern::Perl;
+
+use Test::More tests => 1;
+use Test::Exception;
+
+use t::lib::Mocks;
+
+use Koha::SearchEngine::Elasticsearch;
+
+subtest '_read_configuration() tests' => sub {
+
+    plan tests => 10;
+
+    my $configuration;
+    t::lib::Mocks::mock_config( 'elasticsearch', undef );
+
+    # 'elasticsearch' missing in configuration
+    throws_ok {
+        $configuration = Koha::SearchEngine::Elasticsearch::_read_configuration;
+    }
+    'Koha::Exceptions::Config::MissingEntry',
+      'Configuration problem, exception thrown';
+    is(
+        $@->message,
+        "Missing 'elasticsearch' block in config file",
+        'Exception message is correct'
+    );
+
+    # 'elasticsearch' present but no 'server' entry
+    t::lib::Mocks::mock_config( 'elasticsearch', {} );
+    throws_ok {
+        $configuration = Koha::SearchEngine::Elasticsearch::_read_configuration;
+    }
+    'Koha::Exceptions::Config::MissingEntry',
+      'Configuration problem, exception thrown';
+    is(
+        $@->message,
+        "Missing 'server' entry in config file for elasticsearch",
+        'Exception message is correct'
+    );
+
+    # 'elasticsearch' and 'server' entries present, but no 'index_name'
+    t::lib::Mocks::mock_config( 'elasticsearch', { server => 'a_server' } );
+    throws_ok {
+        $configuration = Koha::SearchEngine::Elasticsearch::_read_configuration;
+    }
+    'Koha::Exceptions::Config::MissingEntry',
+      'Configuration problem, exception thrown';
+    is(
+        $@->message,
+        "Missing 'index_name' entry in config file for elasticsearch",
+        'Exception message is correct'
+    );
+
+    # Correct configuration, only one server
+    t::lib::Mocks::mock_config( 'elasticsearch',  { server => 'a_server', index_name => 'index' } );
+
+    $configuration = Koha::SearchEngine::Elasticsearch::_read_configuration;
+    is( $configuration->{index_name}, 'index', 'Index configuration parsed correctly' );
+    is_deeply( $configuration->{nodes}, ['a_server'], 'Server configuration parsed correctly' );
+
+    # Correct configuration, two servers
+    my @servers = ('a_server', 'another_server');
+    t::lib::Mocks::mock_config( 'elasticsearch', { server => \@servers, index_name => 'index' } );
+
+    $configuration = Koha::SearchEngine::Elasticsearch::_read_configuration;
+    is( $configuration->{index_name}, 'index', 'Index configuration parsed correctly' );
+    is_deeply( $configuration->{nodes}, \@servers , 'Server configuration parsed correctly' );
+};