includes/Maintenance/Validators/ShardAllocationValidator.php
<?php
namespace CirrusSearch\Maintenance\Validators;
use CirrusSearch\Maintenance\Printer;
use Elastica\Index;
use MediaWiki\Status\Status;
class ShardAllocationValidator extends Validator {
/**
* @var Index
*/
private $index;
/**
* @var array
*/
private $indexAllocation;
/**
* @param Index $index
* @param array $indexAllocation
* @param Printer|null $out
*/
public function __construct( Index $index, array $indexAllocation, Printer $out = null ) {
parent::__construct( $out );
$this->index = $index;
$this->indexAllocation = $indexAllocation;
}
/**
* @return Status
*/
public function validate() {
$this->outputIndented( "\tValidating shard allocation settings..." );
$actual = $this->fetchActualAllocation();
$changed = false;
foreach ( [ 'include', 'exclude', 'require' ] as $type ) {
$desired = $this->indexAllocation[$type];
if ( $desired ) {
$this->output( "\n" );
$this->outputIndented( "\t\tUpdating '$type' allocations..." );
$this->set( $type, $desired );
$this->output( "done" );
$changed = true;
}
if ( isset( $actual[$type] ) ) {
$undesired = array_filter( array_keys( $actual[$type] ),
static function ( $key ) use ( $actual, $type, $desired ) {
return $actual[$type][$key] !== '' && !isset( $desired[$key] );
}
);
if ( $undesired ) {
$this->output( "\n" );
$this->outputIndented( "\t\tClearing '$type' allocations..." );
$this->set( $type, array_fill_keys( $undesired, '' ) );
$this->output( "done" );
$changed = true;
}
}
}
if ( $changed ) {
$this->output( "\n" );
} else {
$this->output( "done\n" );
}
return Status::newGood();
}
/**
* @return array
*/
private function fetchActualAllocation() {
$settings = $this->index->getSettings()->get();
return $settings['routing']['allocation'] ?? [];
}
/**
* @param string $type
* @param array $allocation
*/
private function set( $type, $allocation ) {
$this->index->getSettings()->set( [
'routing' => [
'allocation' => [
$type => $allocation,
]
]
] );
}
}