Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
22.45% |
11 / 49 |
|
40.00% |
2 / 5 |
CRAP | |
0.00% |
0 / 1 |
SpecificAliasValidator | |
22.45% |
11 / 49 |
|
40.00% |
2 / 5 |
119.94 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
1 | |||
updateIndices | |
0.00% |
0 / 31 |
|
0.00% |
0 / 1 |
90 | |||
updateFreeIndices | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
2 | |||
swapAliases | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
6 | |||
shouldRemoveFromAlias | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace CirrusSearch\Maintenance\Validators; |
4 | |
5 | use CirrusSearch\Maintenance\Printer; |
6 | use CirrusSearch\Maintenance\Reindexer; |
7 | use Elastica\Client; |
8 | use MediaWiki\Language\RawMessage; |
9 | use Status; |
10 | |
11 | class SpecificAliasValidator extends IndexAliasValidator { |
12 | /** |
13 | * @var Reindexer |
14 | */ |
15 | private $reindexer; |
16 | |
17 | /** |
18 | * @var array |
19 | */ |
20 | private $reindexParams; |
21 | |
22 | /** |
23 | * @var Validator[] |
24 | */ |
25 | private $reindexValidators; |
26 | |
27 | /** |
28 | * @var bool |
29 | */ |
30 | private $reindexAndRemoveOk; |
31 | |
32 | /** |
33 | * @param Client $client |
34 | * @param string $aliasName |
35 | * @param string $specificIndexName |
36 | * @param bool $startOver |
37 | * @param Reindexer $reindexer |
38 | * @param array $reindexParams |
39 | * @param Validator[] $reindexValidators |
40 | * @param bool $reindexAndRemoveOk |
41 | * @param Printer|null $out |
42 | */ |
43 | public function __construct( |
44 | Client $client, |
45 | $aliasName, |
46 | $specificIndexName, |
47 | $startOver, |
48 | Reindexer $reindexer, |
49 | array $reindexParams, |
50 | array $reindexValidators, |
51 | $reindexAndRemoveOk, |
52 | Printer $out = null |
53 | ) { |
54 | // @todo: this constructor takes too many arguments - refactor! |
55 | |
56 | parent::__construct( $client, $aliasName, $specificIndexName, $startOver, $out ); |
57 | |
58 | $this->reindexer = $reindexer; |
59 | $this->reindexParams = $reindexParams; |
60 | $this->reindexValidators = $reindexValidators; |
61 | $this->reindexAndRemoveOk = $reindexAndRemoveOk; |
62 | } |
63 | |
64 | /** |
65 | * @param string[] $add |
66 | * @param string[] $remove |
67 | * @return Status |
68 | */ |
69 | protected function updateIndices( array $add, array $remove ) { |
70 | if ( !$remove ) { |
71 | return $this->updateFreeIndices( $add ); |
72 | } |
73 | |
74 | if ( !$this->reindexAndRemoveOk ) { |
75 | $this->output( "cannot correct!\n" ); |
76 | return Status::newFatal( new RawMessage( |
77 | "The alias is held by another index which means it might be actively serving\n" . |
78 | "queries. You can solve this problem by running this program again with\n" . |
79 | "--reindexAndRemoveOk. Make sure you understand the consequences of either\n" . |
80 | "choice." ) ); |
81 | } |
82 | |
83 | try { |
84 | $this->output( "is taken...\n" ); |
85 | $this->outputIndented( "\tReindexing...\n" ); |
86 | $this->reindexer->reindex( ...$this->reindexParams ); |
87 | # Expecting this to usually be a noop, index should have been created with |
88 | # appropriate settings and reindexer should restore all the settings it |
89 | # changed, but it couldn't hurt to check again. |
90 | foreach ( $this->reindexValidators as $validator ) { |
91 | $status = $validator->validate(); |
92 | if ( !$status->isOK() ) { |
93 | return $status; |
94 | } |
95 | } |
96 | // Validators might have changed replica counts, wait for everything to |
97 | // get to green. |
98 | $this->reindexer->waitForGreen(); |
99 | } catch ( \Exception $e ) { |
100 | return Status::newFatal( new RawMessage( $e->getMessage() ) ); |
101 | } |
102 | |
103 | // now add alias & remove indices for real |
104 | $status = Status::newGood(); |
105 | $status->merge( $this->swapAliases( $add ) ); |
106 | $toRemove = []; |
107 | foreach ( $remove as $indexToRemove ) { |
108 | $resp = $this->client->request( $indexToRemove . '/_alias', 'GET' ); |
109 | if ( !$resp->isOk() ) { |
110 | return Status::newFatal( "Cannot fetch aliases of the old index $indexToRemove" ); |
111 | } |
112 | if ( count( $resp->getData()[$indexToRemove]['aliases'] ?? [] ) > 0 ) { |
113 | $this->outputIndented( "\t$indexToRemove still have active aliases, cannot remove.\n" ); |
114 | } else { |
115 | $toRemove[] = $indexToRemove; |
116 | } |
117 | } |
118 | $status->merge( parent::updateIndices( [], $toRemove ) ); |
119 | return $status; |
120 | } |
121 | |
122 | /** |
123 | * @param string[] $add |
124 | * @return Status |
125 | */ |
126 | public function updateFreeIndices( array $add ) { |
127 | $this->output( "alias is free..." ); |
128 | |
129 | foreach ( $add as $indexName ) { |
130 | $index = $this->client->getIndex( $indexName ); |
131 | $index->addAlias( $this->aliasName, false ); |
132 | } |
133 | |
134 | $this->output( "corrected\n" ); |
135 | |
136 | return Status::newGood(); |
137 | } |
138 | |
139 | /** |
140 | * @param array $add |
141 | * @return Status |
142 | */ |
143 | public function swapAliases( array $add ) { |
144 | $this->outputIndented( "\tSwapping alias..." ); |
145 | |
146 | foreach ( $add as $indexName ) { |
147 | $index = $this->client->getIndex( $indexName ); |
148 | $index->addAlias( $this->aliasName, true ); |
149 | } |
150 | |
151 | $this->output( "done\n" ); |
152 | |
153 | return Status::newGood(); |
154 | } |
155 | |
156 | /** |
157 | * @param string $name |
158 | * @return bool |
159 | */ |
160 | protected function shouldRemoveFromAlias( $name ) { |
161 | return true; |
162 | } |
163 | } |