Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 55
MappingValidator
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 3
90
0.00% covered (danger)
0.00%
0 / 55
 __construct
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 16
 validate
0.00% covered (danger)
0.00%
0 / 1
42
0.00% covered (danger)
0.00%
0 / 28
 compareMappingToActual
0.00% covered (danger)
0.00%
0 / 1
6
0.00% covered (danger)
0.00%
0 / 11
<?php
namespace CirrusSearch\Maintenance\Validators;
use CirrusSearch\ElasticaErrorHandler;
use CirrusSearch\Maintenance\Printer;
use CirrusSearch\Util;
use Elastica\Exception\ExceptionInterface;
use Elastica\Index;
use Elastica\Type\Mapping;
use RawMessage;
use Status;
use Wikimedia\Assert\Assert;
class MappingValidator extends Validator {
    /**
     * @var Index
     */
    private $index;
    /**
     * @var string
     */
    private $masterTimeout;
    /**
     * @var bool
     */
    private $optimizeIndexForExperimentalHighlighter;
    /**
     * @var array
     */
    private $availablePlugins;
    /**
     * @var array
     */
    private $mappingConfig;
    /**
     * @todo this constructor takes way too much arguments - refactor
     *
     * @param Index $index
     * @param string $masterTimeout
     * @param bool $optimizeIndexForExperimentalHighlighter
     * @param array $availablePlugins
     * @param array $mappingConfig
     * @param Printer|null $out
     */
    public function __construct(
        Index $index,
        $masterTimeout,
        $optimizeIndexForExperimentalHighlighter,
        array $availablePlugins,
        array $mappingConfig,
        Printer $out = null
    ) {
        parent::__construct( $out );
        $this->index = $index;
        $this->masterTimeout = $masterTimeout;
        $this->optimizeIndexForExperimentalHighlighter = $optimizeIndexForExperimentalHighlighter;
        $this->availablePlugins = $availablePlugins;
        // Could be supported, but prefer consistency
        Assert::parameter( isset( $mappingConfig['properties'] ), '$mappingConfig',
            'Mapping types are no longer supported, properties must be top level' );
        $this->mappingConfig = $mappingConfig;
    }
    /**
     * @return Status
     */
    public function validate() {
        $this->outputIndented( "Validating mappings..." );
        if ( $this->optimizeIndexForExperimentalHighlighter &&
            !in_array( 'experimental-highlighter', $this->availablePlugins ) ) {
            $this->output( "impossible!\n" );
            return Status::newFatal( new RawMessage(
                "wgCirrusSearchOptimizeIndexForExperimentalHighlighter is set to true but the " .
                "'experimental-highlighter' plugin is not installed on all hosts." ) );
        }
        if ( !$this->compareMappingToActual() ) {
            // TODO: remove references to type (T308044)
            $action = new Mapping( $this->index->getType( '_doc' ) );
            foreach ( $this->mappingConfig as $key => $value ) {
                $action->setParam( $key, $value );
            }
            try {
                $action->send( [
                    'master_timeout' => $this->masterTimeout,
                    'include_type_name' => 'true',
                ] );
                $this->output( "corrected\n" );
            } catch ( ExceptionInterface $e ) {
                $this->output( "failed!\n" );
                $message = ElasticaErrorHandler::extractMessage( $e );
                return Status::newFatal( new RawMessage(
                    "Couldn't update existing mappings. You may need to reindex.\nHere is elasticsearch's error message: $message\n" ) );
            }
        }
        return Status::newGood();
    }
    /**
     * Check that the mapping returned from Elasticsearch is as we want it.
     *
     * @return bool is the mapping good enough for us?
     */
    private function compareMappingToActual() {
        $actualMappings = Util::getIndexMapping( $this->index );
        $this->output( "\n" );
        $this->outputIndented( "\tValidating mapping..." );
        if ( $this->checkConfig( $actualMappings, $this->mappingConfig ) ) {
            $this->output( "ok\n" );
            return true;
        } else {
            $this->output( "different..." );
            return false;
        }
    }
}