Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 43 |
|
0.00% |
0 / 4 |
CRAP | |
0.00% |
0 / 1 |
MappingValidator | |
0.00% |
0 / 43 |
|
0.00% |
0 / 4 |
132 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
isNaturalSortConfigured | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
validate | |
0.00% |
0 / 26 |
|
0.00% |
0 / 1 |
56 | |||
compareMappingToActual | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
6 |
1 | <?php |
2 | |
3 | namespace CirrusSearch\Maintenance\Validators; |
4 | |
5 | use CirrusSearch\ElasticaErrorHandler; |
6 | use CirrusSearch\Maintenance\Printer; |
7 | use Elastica\Exception\ExceptionInterface; |
8 | use Elastica\Index; |
9 | use Elastica\Mapping; |
10 | use MediaWiki\Language\RawMessage; |
11 | use MediaWiki\Status\Status; |
12 | use Wikimedia\Assert\Assert; |
13 | |
14 | class MappingValidator extends Validator { |
15 | /** |
16 | * @var Index |
17 | */ |
18 | private $index; |
19 | |
20 | /** |
21 | * @var string |
22 | */ |
23 | private $masterTimeout; |
24 | |
25 | /** |
26 | * @var bool |
27 | */ |
28 | private $optimizeIndexForExperimentalHighlighter; |
29 | |
30 | /** |
31 | * @var array |
32 | */ |
33 | private $availablePlugins; |
34 | |
35 | /** |
36 | * @var array |
37 | */ |
38 | private $mappingConfig; |
39 | |
40 | /** |
41 | * @todo this constructor takes way too much arguments - refactor |
42 | * |
43 | * @param Index $index |
44 | * @param string $masterTimeout |
45 | * @param bool $optimizeIndexForExperimentalHighlighter |
46 | * @param array $availablePlugins |
47 | * @param array $mappingConfig |
48 | * @param Printer|null $out |
49 | */ |
50 | public function __construct( |
51 | Index $index, |
52 | $masterTimeout, |
53 | $optimizeIndexForExperimentalHighlighter, |
54 | array $availablePlugins, |
55 | array $mappingConfig, |
56 | Printer $out = null |
57 | ) { |
58 | parent::__construct( $out ); |
59 | |
60 | $this->index = $index; |
61 | $this->masterTimeout = $masterTimeout; |
62 | $this->optimizeIndexForExperimentalHighlighter = $optimizeIndexForExperimentalHighlighter; |
63 | $this->availablePlugins = $availablePlugins; |
64 | // Could be supported, but prefer consistency |
65 | Assert::parameter( isset( $mappingConfig['properties'] ), '$mappingConfig', |
66 | 'Mapping types are no longer supported, properties must be top level' ); |
67 | $this->mappingConfig = $mappingConfig; |
68 | } |
69 | |
70 | private function isNaturalSortConfigured() { |
71 | // awkward much? |
72 | return isset( $this->mappingConfig['properties']['title']['fields']['natural_sort'] ); |
73 | } |
74 | |
75 | /** |
76 | * @return Status |
77 | */ |
78 | public function validate() { |
79 | $this->outputIndented( "Validating mappings..." ); |
80 | if ( $this->optimizeIndexForExperimentalHighlighter && |
81 | !in_array( 'experimental-highlighter', $this->availablePlugins ) ) { |
82 | $this->output( "impossible!\n" ); |
83 | return Status::newFatal( new RawMessage( |
84 | "wgCirrusSearchOptimizeIndexForExperimentalHighlighter is set to true but the " . |
85 | "'experimental-highlighter' plugin is not installed on all hosts." ) ); |
86 | } |
87 | if ( $this->isNaturalSortConfigured() && |
88 | !in_array( 'analysis-icu', $this->availablePlugins ) ) { |
89 | $this->output( "impossible!\n" ); |
90 | return Status::newFatal( new RawMessage( |
91 | "wgCirrusSearchNaturalTitleSort is set to build but the " . |
92 | "'analysis-icu' plugin is not installed on all hosts." ) ); |
93 | } |
94 | |
95 | if ( !$this->compareMappingToActual() ) { |
96 | $action = new Mapping( $this->mappingConfig['properties'] ); |
97 | $action->setParam( "dynamic", false ); |
98 | |
99 | try { |
100 | $action->send( $this->index, [ |
101 | 'master_timeout' => $this->masterTimeout, |
102 | ] ); |
103 | $this->output( "corrected\n" ); |
104 | } catch ( ExceptionInterface $e ) { |
105 | $this->output( "failed!\n" ); |
106 | $message = ElasticaErrorHandler::extractMessage( $e ); |
107 | return Status::newFatal( new RawMessage( |
108 | "Couldn't update existing mappings. You may need to reindex.\nHere is elasticsearch's error message: $message\n" ) ); |
109 | } |
110 | } |
111 | |
112 | return Status::newGood(); |
113 | } |
114 | |
115 | /** |
116 | * Check that the mapping returned from Elasticsearch is as we want it. |
117 | * |
118 | * @return bool is the mapping good enough for us? |
119 | */ |
120 | private function compareMappingToActual() { |
121 | $actualMappings = $this->index->getMapping(); |
122 | $this->output( "\n" ); |
123 | $this->outputIndented( "\tValidating mapping..." ); |
124 | if ( $this->checkConfig( $actualMappings, $this->mappingConfig ) ) { |
125 | $this->output( "ok\n" ); |
126 | return true; |
127 | } else { |
128 | $this->output( "different..." ); |
129 | return false; |
130 | } |
131 | } |
132 | } |