EBernhardson has submitted this change and it was merged.

Change subject: Flow ES config
......................................................................


Flow ES config

This script is the Flow version of CirrusSearch's updateSearchIndexConfig.php

Just run:
    $ php maintenance/FlowSearchConfig.php

Fixes T78787

Bug: T78787
Change-Id: I65f649a8093da42a14617de2a10a00944173b060
---
M Flow.php
M autoload.php
A includes/Search/Connection.php
A includes/Search/maintenance/MappingConfigBuilder.php
A maintenance/FlowSearchConfig.php
5 files changed, 620 insertions(+), 0 deletions(-)

Approvals:
  EBernhardson: Looks good to me, approved



diff --git a/Flow.php b/Flow.php
index e66bd23..88e0bf4 100644
--- a/Flow.php
+++ b/Flow.php
@@ -329,6 +329,35 @@
 // Flow code; WMF sometimes overrides this globally in 
wmf-config/CommonSettings.php
 $wgFlowCacheVersion = '4.5';
 
+// ElasticSearch servers
+$wgFlowSearchServers = array( 'localhost' );
+
+// Flow search config setting - akin to CirrusSearch
+// See CirrusSearch.php for documentation for these params, which have similar
+// variable names (s/FlowSearch/CirrusSearch/)
+$wgFlowSearchConnectionAttempts = 1; // see $wgCirrusSearchConnectionAttempts
+$wgFlowSearchBannedPlugins = array(); // see $wgCirrusSearchBannedPlugins
+$wgFlowSearchOptimizeIndexForExperimentalHighlighter = false; // see 
$wgCirrusSearchOptimizeIndexForExperimentalHighlighter
+$wgFlowSearchMaxShardsPerNode = array(); // see $wgCirrusSearchMaxShardsPerNode
+$wgFlowSearchRefreshInterval = 1; // see $wgCirrusSearchRefreshInterval
+$wgFlowSearchMaintenanceTimeout = 3600; // see 
$wgCirrusSearchMaintenanceTimeout
+$wgFlowSearchReplicas = '0-2'; // see $wgCirrusSearchReplicas
+$wgFlowSearchShardCount = array( 'flow' => 4 ); // see 
$wgCirrusSearchShardCount
+$wgFlowSearchCacheWarmers = array(); // see $wgCirrusSearchCacheWarmers
+$wgFlowSearchMergeSettings = array(
+       'flow' => array(
+               'max_merge_at_once' => 10,
+               'segments_per_tier' => 10,
+               'reclaim_deletes_weight' => 2.0,
+               'max_merged_segment' => '5g',
+       ),
+); // see $wgCirrusSearchMergeSettings
+$wgFlowSearchIndexAllocation = array(
+       'include' => array(),
+       'exclude' => array(),
+       'require' => array(),
+); // see $wgCirrusSearchIndexAllocation
+
 // Custom group name for AbuseFilter
 // Acceptable values:
 // * a specific value for flow-specific filters
diff --git a/autoload.php b/autoload.php
index 2609b7c..643d2d2 100644
--- a/autoload.php
+++ b/autoload.php
@@ -259,6 +259,8 @@
        'Flow\\Repository\\UserName\\TwoStepUserNameQuery' => __DIR__ . 
'/includes/Repository/UserName/TwoStepUserNameQuery.php',
        'Flow\\Repository\\UserName\\UserNameQuery' => __DIR__ . 
'/includes/Repository/UserName/UserNameQuery.php',
        'Flow\\RevisionActionPermissions' => __DIR__ . 
'/includes/RevisionActionPermissions.php',
+       'Flow\\Search\\Connection' => __DIR__ . 
'/includes/Search/Connection.php',
+       'Flow\\Search\\Maintenance\\MappingConfigBuilder' => __DIR__ . 
'/includes/Search/maintenance/MappingConfigBuilder.php',
        'Flow\\SpamFilter\\AbuseFilter' => __DIR__ . 
'/includes/SpamFilter/AbuseFilter.php',
        'Flow\\SpamFilter\\ConfirmEdit' => __DIR__ . 
'/includes/SpamFilter/ConfirmEdit.php',
        'Flow\\SpamFilter\\ContentLengthFilter' => __DIR__ . 
'/includes/SpamFilter/ContentLengthFilter.php',
diff --git a/includes/Search/Connection.php b/includes/Search/Connection.php
new file mode 100644
index 0000000..a78c210
--- /dev/null
+++ b/includes/Search/Connection.php
@@ -0,0 +1,80 @@
+<?php
+
+namespace Flow\Search;
+
+use Elastica\SearchableInterface;
+
+/**
+ * Provides the connection to the elasticsearch backend.
+ */
+class Connection extends \ElasticaConnection {
+       /**
+        * Name of the topic type.
+        *
+        * @var string
+        */
+       const TOPIC_TYPE_NAME = 'topic';
+
+       /**
+        * Name of the header type.
+        *
+        * @var string
+        */
+       const HEADER_TYPE_NAME = 'header';
+
+       /**
+        * Name of the index that holds Flow data.
+        *
+        * @var string
+        */
+       const FLOW_INDEX_TYPE = 'flow';
+
+       /**
+        * @return string[]
+        */
+       public function getServerList() {
+               global $wgFlowSearchServers;
+               return $wgFlowSearchServers;
+       }
+
+       /**
+        * @return int
+        */
+       public function getMaxConnectionAttempts() {
+               global $wgFlowSearchConnectionAttempts;
+               return $wgFlowSearchConnectionAttempts;
+       }
+
+       /**
+        * Get all indices we support.
+        *
+        * @return string[]
+        */
+       public static function getAllIndices() {
+               return array( static::FLOW_INDEX_TYPE );
+       }
+
+       /**
+        * Get all types we support.
+        *
+        * @return string[]
+        */
+       public static function getAllTypes() {
+               return array( static::TOPIC_TYPE_NAME, static::HEADER_TYPE_NAME 
);
+       }
+
+       /**
+        * @param string $name
+        * @param string|bool $type Type name or false to search entire index
+        * @return SearchableInterface
+        */
+       public static function getRevisionType( $name, $type = false ) {
+               $index = static::getSingleton()->getIndex2( $name, 
static::FLOW_INDEX_TYPE );
+
+               if ( $type ) {
+                       $index = $index->getType( $type );
+               }
+
+               return $index;
+       }
+}
diff --git a/includes/Search/maintenance/MappingConfigBuilder.php 
b/includes/Search/maintenance/MappingConfigBuilder.php
new file mode 100644
index 0000000..98c6307
--- /dev/null
+++ b/includes/Search/maintenance/MappingConfigBuilder.php
@@ -0,0 +1,64 @@
+<?php
+
+namespace Flow\Search\Maintenance;
+
+class MappingConfigBuilder extends 
\CirrusSearch\Maintenance\MappingConfigBuilder {
+       /**
+        * Build the mapping config.
+        *
+        * The 2 arguments are unused in Flow, but are needed for PHP Strict
+        * standards compliance: declaration should be compatible with parent.
+        *
+        * @param null $prefixSearchStartsWithAnyWord Unused
+        * @param null $phraseSuggestUseText Unused
+        * @return array the mapping config
+        */
+       public function buildConfig( $prefixSearchStartsWithAnyWord = null, 
$phraseSuggestUseText = null ) {
+               $config = array(
+                       'dynamic' => false,
+//                     '_all' => array( 'enabled' => false ),
+                       'properties' => array(
+                               'namespace' => $this->buildLongField(),
+                               'namespace_text' => $this->buildKeywordField(),
+                               'pageid' => $this->buildLongField(),
+                               // no need to analyze title, we won't be 
searching it
+                               'title' => $this->buildKeywordField(),
+                               'timestamp' => array(
+                                       'type' => 'date',
+                                       'format' => 'dateOptionalTime',
+                               ),
+                               'update_timestamp' => array(
+                                       'type' => 'date',
+                                       'format' => 'dateOptionalTime',
+                               ),
+                               'revisions' => array(
+                                       // object can be flattened (probably 
doesn't have to be
+                                       // "nested", which would allow them to 
be querried independently)
+                                       'type' => 'object',
+                                       'properties' => array(
+                                               'id' => 
$this->buildKeywordField(),
+                                               // @todo: Cirrus' config for 
'text' had some more - see if we need those?
+                                               'text' => 
$this->buildStringField( static::ENABLE_NORMS | static::SPEED_UP_HIGHLIGHTING ),
+                                               'source_text' => 
$this->buildStringField( static::MINIMAL ),
+                                               'moderation_state' => 
$this->buildKeywordField(),
+                                               'timestamp' => array(
+                                                       'type' => 'date',
+                                                       'format' => 
'dateOptionalTime',
+                                               ),
+                                               'update_timestamp' => array(
+                                                       'type' => 'date',
+                                                       'format' => 
'dateOptionalTime',
+                                               ),
+                                               'type' => 
$this->buildKeywordField(),
+                                       )
+                               )
+                       ),
+               );
+
+               // same config for both types (well, so far...)
+               return array(
+                       'topic' => $config,
+                       'header' => $config,
+               );
+       }
+}
diff --git a/maintenance/FlowSearchConfig.php b/maintenance/FlowSearchConfig.php
new file mode 100644
index 0000000..20f1f91
--- /dev/null
+++ b/maintenance/FlowSearchConfig.php
@@ -0,0 +1,445 @@
+<?php
+
+use Flow\Search\Connection;
+use Flow\Search\Maintenance\MappingConfigBuilder;
+use CirrusSearch\ElasticsearchIntermediary;
+use CirrusSearch\Maintenance\AnalysisConfigBuilder;
+use CirrusSearch\Maintenance\ConfigUtils;
+use CirrusSearch\Maintenance\Maintenance;
+use CirrusSearch\Maintenance\Reindexer;
+use CirrusSearch\Maintenance\Validators\AnalyzersValidator;
+use CirrusSearch\Maintenance\Validators\CacheWarmersValidator;
+use CirrusSearch\Maintenance\Validators\IndexAllAliasValidator;
+use CirrusSearch\Maintenance\Validators\IndexValidator;
+use CirrusSearch\Maintenance\Validators\MappingValidator;
+use CirrusSearch\Maintenance\Validators\MaxShardsPerNodeValidator;
+use CirrusSearch\Maintenance\Validators\NumberOfShardsValidator;
+use CirrusSearch\Maintenance\Validators\ReplicaRangeValidator;
+use CirrusSearch\Maintenance\Validators\ShardAllocationValidator;
+use CirrusSearch\Maintenance\Validators\SpecificAliasValidator;
+use CirrusSearch\Maintenance\Validators\Validator;
+use CirrusSearch\Util;
+
+require_once ( getenv( 'MW_INSTALL_PATH' ) !== false
+       ? getenv( 'MW_INSTALL_PATH' ) . '/maintenance/Maintenance.php'
+       : dirname( __FILE__ ) . '/../../../maintenance/Maintenance.php' );
+require_once( __DIR__ . 
'/../../CirrusSearch/includes/Maintenance/Maintenance.php' );
+
+/**
+ * Similar to CirrusSearch's UpdateOneSearchIndexConfig.
+ *
+ * @ingroup Maintenance
+ */
+class FlowSearchConfig extends Maintenance {
+       /**
+        * @var string
+        */
+       protected $indexType;
+
+       /**
+        * @var array
+        */
+       protected $maxShardsPerNode;
+
+       /**
+        * @var string[]
+        */
+       protected $cacheWarmers;
+
+       /**
+        * @var bool are we going to blow the index away and start from scratch?
+        */
+       protected $startOver;
+
+       /**
+        * @var int
+        */
+       protected $refreshInterval;
+
+       /**
+        * @var AnalysisConfigBuilder the builder for analysis config
+        */
+       protected $analysisConfigBuilder;
+
+       /**
+        * @var bool print config as it is being checked
+        */
+       protected $printDebugCheckConfig;
+
+       /**
+        * @var bool
+        */
+       protected $optimizeIndexForExperimentalHighlighter;
+
+       /**
+        * @var String[] list of available plugins
+        */
+       protected $availablePlugins;
+
+       /**
+        * @var bool are there too few replicas in the index we're making?
+        */
+       protected $tooFewReplicas;
+
+       /**
+        * @var bool
+        */
+       protected $reindexAndRemoveOk;
+
+       /**
+        * @var string
+        */
+       protected $indexBaseName;
+
+       /**
+        * @var string
+        */
+       protected $indexIdentifier;
+
+       /**
+        * @var int number of processes to use when reindexing
+        */
+       protected $reindexProcesses;
+
+       /**
+        * @var float how much can the reindexed copy of an index is allowed to 
deviate from the current
+        * copy without triggering a reindex failure
+        */
+       protected $reindexAcceptableCountDeviation;
+
+       /**
+        * @var int
+        */
+       protected $reindexChunkSize;
+
+       /**
+        * @var int
+        */
+       protected $reindexRetryAttempts;
+
+       /**
+        * @var array
+        */
+       protected $bannedPlugins;
+
+       /**
+        * @var string language code we're building for
+        */
+       protected $langCode;
+
+       /**
+        * @var array
+        */
+       protected $indexAllocation;
+
+       /**
+        * @var int
+        */
+       protected $maintenanceTimeout;
+
+       /**
+        * @var \ElasticaConnection
+        */
+       protected $connection;
+
+       /**
+        * @var ConfigUtils
+        */
+       protected $utils;
+
+       public function __construct() {
+               parent::__construct();
+
+               $this->addDescription( "Update the configuration or contents of 
one search index." );
+
+               $this->addOption( 'startOver', 'Blow away the identified index 
and rebuild it with ' .
+                       'no data.' );
+               $this->addOption( 'forceOpen', "Open the index but do nothing 
else.  Use this if " .
+                       "you've stuck the index closed and need it to start 
working right now." );
+               $this->addOption( 'indexIdentifier', "Set the identifier of the 
index to work on.  " .
+                       "You'll need this if you have an index in production 
serving queries and you have " .
+                       "to alter some portion of its configuration that cannot 
safely be done without " .
+                       "rebuilding it.  Once you specify a new indexIdentifier 
for this wiki you'll have to " .
+                       "run this script with the same identifier each time.  
Defaults to 'current' which " .
+                       "infers the currently in use identifier.  You can also 
use 'now' to set the identifier " .
+                       "to the current time in seconds which should give you a 
unique identifier.", false, true);
+               $this->addOption( 'reindexAndRemoveOk', "If the alias is held 
by another index then " .
+                       "reindex all documents from that index (via the alias) 
to this one, swing the " .
+                       "alias to this index, and then remove other index.  
You'll have to redo all updates ".
+                       "performed during this operation manually.  Defaults to 
false." );
+               $this->addOption( 'reindexProcesses', 'Number of processes to 
use in reindex.  ' .
+                       'Not supported on Windows.  Defaults to 1 on Windows 
and 5 otherwise.', false, true );
+               $this->addOption( 'reindexAcceptableCountDeviation', 'How much 
can the reindexed ' .
+                       'copy of an index is allowed to deviate from the 
current copy without triggering a ' .
+                       'reindex failure.  Defaults to 5%.', false, true );
+               $this->addOption( 'reindexChunkSize', 'Documents per shard to 
reindex in a batch.   ' .
+                       'Note when changing the number of shards that the old 
shard size is used, not the new ' .
+                       'one.  If you see many errors submitting documents in 
bulk but the automatic retry as ' .
+                       'singles works then lower this number.  Defaults to 
100.', false, true );
+               $this->addOption( 'reindexRetryAttempts', 'Number of times to 
back off and retry ' .
+                       'per failure.  Note that failures are not common but if 
Elasticsearch is in the process ' .
+                       'of moving a shard this can time out.  This will retry 
the attempt after some backoff ' .
+                       'rather than failing the whole reindex process.  
Defaults to 5.', false, true );
+               $this->addOption( 'baseName', 'What basename to use for all 
indexes, ' .
+                       'defaults to wiki id', false, true );
+               $this->addOption( 'debugCheckConfig', 'Print the configuration 
as it is checked ' .
+                       'to help debug unexpected configuration mismatches.' );
+               $this->addOption( 'justCacheWarmers', 'Just validate that the 
cache warmers are correct ' .
+                       'and perform no additional checking.  Use when you need 
to apply new cache warmers but ' .
+                       "want to be sure that you won't apply any other changes 
at an inopportune time." );
+               $this->addOption( 'justAllocation', 'Just validate the shard 
allocation settings.  Use ' .
+                       "when you need to apply new cache warmers but want to 
be sure that you won't apply any other " .
+                       'changes at an inopportune time.' );
+       }
+
+       protected function setProperties() {
+               global $wgLanguageCode,
+                       $wgFlowSearchBannedPlugins,
+                       $wgFlowSearchOptimizeIndexForExperimentalHighlighter,
+                       $wgFlowSearchIndexAllocation,
+                       $wgFlowSearchMaintenanceTimeout,
+                       $wgFlowSearchRefreshInterval,
+                       $wgFlowSearchMaxShardsPerNode,
+                       $wgFlowSearchCacheWarmers;
+
+               $this->connection = Connection::getSingleton();
+               $this->utils = new ConfigUtils( $this->getClient(), $this );
+
+               $this->indexType = 'flow'; // only 1 index for Flow
+               $this->startOver = $this->getOption( 'startOver', false );
+               $this->indexBaseName = $this->getOption( 'baseName', wfWikiId() 
);
+               $this->reindexAndRemoveOk = $this->getOption( 
'reindexAndRemoveOk', false );
+               $this->reindexProcesses = $this->getOption( 'reindexProcesses', 
wfIsWindows() ? 1 : 5 );
+               $this->reindexChunkSize = $this->getOption( 'reindexChunkSize', 
100 );
+               $this->reindexRetryAttempts = $this->getOption( 
'reindexRetryAttempts', 5 );
+               $this->printDebugCheckConfig = $this->getOption( 
'debugCheckConfig', false );
+
+               $this->langCode = $wgLanguageCode;
+               $this->bannedPlugins = $wgFlowSearchBannedPlugins;
+               $this->optimizeIndexForExperimentalHighlighter = 
$wgFlowSearchOptimizeIndexForExperimentalHighlighter;
+               $this->indexAllocation = $wgFlowSearchIndexAllocation;
+               $this->maintenanceTimeout = $wgFlowSearchMaintenanceTimeout;
+               $this->refreshInterval = $wgFlowSearchRefreshInterval;
+               $this->maxShardsPerNode = isset( 
$wgFlowSearchMaxShardsPerNode[$this->indexType] ) ? 
$wgFlowSearchMaxShardsPerNode[$this->indexType] : 'unlimited';
+               $this->cacheWarmers = isset( 
$wgFlowSearchCacheWarmers[$this->indexType] ) ? 
$wgFlowSearchCacheWarmers[$this->indexType] : array();
+
+               $this->indexIdentifier = 
$this->utils->pickIndexIdentifierFromOption( $this->getOption( 
'indexIdentifier', 'current' ), $this->getIndexTypeName() );
+               $this->reindexAcceptableCountDeviation = 
Util::parsePotentialPercent( $this->getOption( 
'reindexAcceptableCountDeviation', '5%' ) );
+               $this->availablePlugins = $this->utils->scanAvailablePlugins( 
$this->bannedPlugins );
+               $this->analysisConfigBuilder = $this->pickAnalyzer( 
$this->langCode, $this->availablePlugins );
+
+               $this->tooFewReplicas = $this->reindexAndRemoveOk && ( 
$this->startOver || !$this->getIndex()->exists() );
+       }
+
+       /**
+        * A couple of commonly used (together) validators.
+        *
+        * @return Validator[]
+        */
+       protected function getIndexSettingsValidators() {
+               $validators = array();
+
+               $validators[] = new NumberOfShardsValidator( $this->getIndex(), 
$this->getShardCount(), $this );
+               $validators[] = new ReplicaRangeValidator( $this->getIndex(), 
$this->getReplicaCount(), $this );
+               $validators[] = new ShardAllocationValidator( 
$this->getIndex(), $this->indexAllocation, $this );
+               $validators[] = new MaxShardsPerNodeValidator( 
$this->getIndex(), $this->indexType, $this->maxShardsPerNode, $this );
+
+               return $validators;
+       }
+
+       /**
+        * @return Validator[]
+        */
+       protected function getValidators() {
+               $validators = array();
+
+               if ( $this->getOption( 'justCacheWarmers', false ) ) {
+                       $validators[] = new CacheWarmersValidator( 
$this->indexType, $this->getTopicType(), $this->cacheWarmers, $this );
+                       $validators[] = new CacheWarmersValidator( 
$this->indexType, $this->getHeaderType(), $this->cacheWarmers, $this );
+                       return $validators;
+               }
+
+               if ( $this->getOption( 'justAllocation', false ) ) {
+                       $validators[] = new ShardAllocationValidator( 
$this->getIndex(), $this->indexAllocation, $this );
+                       return $validators;
+               }
+
+               $validators[] = new IndexValidator( $this->getIndex(), 
$this->startOver, $this->maxShardsPerNode, $this->getShardCount(), 
$this->getReplicaCount(), $this->refreshInterval, false, 
$this->analysisConfigBuilder, $this->getMergeSettings(), $this );
+
+               $validators = array_merge( $validators, 
$this->getIndexSettingsValidators() );
+
+               $validator = new AnalyzersValidator( $this->getIndex(), 
$this->analysisConfigBuilder, $this );
+               $validator->printDebugCheckConfig( $this->printDebugCheckConfig 
);
+               $validators[] = $validator;
+
+               $types = array( 'topic' => $this->getTopicType(), 'header' => 
$this->getHeaderType() );
+               $validator = new MappingValidator( $this->getIndex(), 
$this->optimizeIndexForExperimentalHighlighter, $this->availablePlugins, 
$this->getMappingConfig(), $types, $this );
+               $validator->printDebugCheckConfig( $this->printDebugCheckConfig 
);
+               $validators[] = $validator;
+
+               $validators[] = new CacheWarmersValidator( $this->indexType, 
$this->getTopicType(), $this->cacheWarmers, $this );
+               $validators[] = new CacheWarmersValidator( $this->indexType, 
$this->getHeaderType(), $this->cacheWarmers, $this );
+
+               $types = array( $this->getTopicType(), $this->getHeaderType() );
+               $oldTypes = array( $this->getOldTopicType(), 
$this->getOldHeaderType() );
+               $reindexer = new Reindexer( $this->getIndex(), 
Connection::getSingleton(), $types, $oldTypes, $this->getShardCount(), 
$this->getReplicaCount(), $this->maintenanceTimeout, $this->getMergeSettings(), 
$this->getMappingConfig(), $this );
+               $reindexParams = array( $this->reindexProcesses, 
$this->refreshInterval, $this->reindexRetryAttempts, $this->reindexChunkSize, 
$this->reindexAcceptableCountDeviation );
+               $reindexValidators = $this->getIndexSettingsValidators();
+               $validators[] = new SpecificAliasValidator( $this->getClient(), 
$this->getIndexTypeName(), $this->getSpecificIndexName(), $this->startOver, 
$reindexer, $reindexParams, $reindexValidators, $this->reindexAndRemoveOk, 
$this->tooFewReplicas, $this );
+
+               $validators[] = new IndexAllAliasValidator( $this->getClient(), 
$this->getIndexName(), $this->getSpecificIndexName(), $this->startOver, 
$this->getIndexTypeName(), $this );
+               if ( $this->tooFewReplicas ) {
+                       $validators = array_merge( $validators, 
$this->getIndexSettingsValidators() );
+               }
+
+               return $validators;
+       }
+
+       public function execute() {
+               // Make sure we don't flood the pool counter
+               global $wgPoolCounterConf;
+               unset( $wgPoolCounterConf['Flow-Search'] );
+
+               // Sets all of this class' properties that will be passed to 
validators
+               $this->setProperties();
+
+               // Set the timeout for maintenance actions
+               $this->setConnectionTimeout();
+
+               try {
+                       $indexTypes = $this->getAllIndices();
+                       if ( !in_array( $this->indexType, $indexTypes ) ) {
+                               $this->error( 'indexType option must be one of 
' .
+                                       implode( ', ', $indexTypes ), 1 );
+                       }
+
+                       $this->utils->checkElasticsearchVersion();
+
+                       $validators = $this->getValidators();
+                       foreach ( $validators as $validator ) {
+                               $status = $validator->validate();
+                               if ( !$status->isOK() ) {
+                                       $this->error( 
$status->getMessage()->text(), 1 );
+                               }
+                       }
+
+//                     $this->updateVersions(); // @todo: might need this some 
day? (see CirrusSearch's UpdateOneSearchIndexConfig::updateVersions)
+               } catch ( \Elastica\Exception\Connection\HttpException $e ) {
+                       $message = $e->getMessage();
+                       $this->output( "\nUnexpected Elasticsearch failure.\n" 
);
+                       $this->error( "Http error communicating with 
Elasticsearch:  $message.\n", 1 );
+               } catch ( \Elastica\Exception\ExceptionInterface $e ) {
+                       $type = get_class( $e );
+                       $message = ElasticsearchIntermediary::extractMessage( 
$e );
+                       $trace = $e->getTraceAsString();
+                       $this->output( "\nUnexpected Elasticsearch failure.\n" 
);
+                       $this->error( "Elasticsearch failed in an unexpected 
way.  This is always a bug in FlowSearch.\n" .
+                               "Error type: $type\n" .
+                               "Message: $message\n" .
+                               "Trace:\n" . $trace, 1 );
+               }
+       }
+
+       protected function getShardCount() {
+               global $wgFlowSearchShardCount;
+
+               if ( !isset( $wgFlowSearchShardCount[$this->indexType] ) ) {
+                       $this->error( 'Could not find a shard count for ' . 
$this->indexType . '.  Did you forget to add it ' .
+                               'to $wgFlowSearchShardCount?', 1 );
+               }
+
+               return $wgFlowSearchShardCount[$this->indexType];
+       }
+
+       protected function getReplicaCount() {
+               global $wgFlowSearchReplicas;
+
+               // If $wgFlowSearchReplicas is an array of index type to number 
of replicas then respect that
+               if ( is_array( $wgFlowSearchReplicas ) ) {
+                       if ( isset( $wgFlowSearchReplicas[$this->indexType] ) ) 
{
+                               return $wgFlowSearchReplicas[$this->indexType];
+                       } else {
+                               $this->error( 'If wgFlowSearchReplicas is an 
array it must contain all index types.', 1 );
+                       }
+               }
+
+               // Otherwise its just a raw scalar so we should respect that too
+               return $wgFlowSearchReplicas;
+       }
+
+       protected function getMergeSettings() {
+               global $wgFlowSearchMergeSettings;
+
+               if ( isset( $wgFlowSearchMergeSettings[$this->indexType] ) ) {
+                       return $wgFlowSearchMergeSettings[$this->indexType];
+               }
+               // If there aren't configured merge settings for this index 
type default to the content type.
+               return $wgFlowSearchMergeSettings['content'];
+       }
+
+       /**
+        * @param string $langCode
+        * @param array $availablePlugins
+        * @return AnalysisConfigBuilder
+        */
+       protected function pickAnalyzer( $langCode, array $availablePlugins = 
array() ) {
+               $analysisConfigBuilder = new AnalysisConfigBuilder( $langCode, 
$availablePlugins );
+               $this->outputIndented( 'Picking analyzer...' . 
$analysisConfigBuilder->getDefaultTextAnalyzerType() . "\n" );
+               return $analysisConfigBuilder;
+       }
+
+       /**
+        * @return array
+        */
+       protected function getMappingConfig() {
+               $builder = new MappingConfigBuilder( 
$this->optimizeIndexForExperimentalHighlighter );
+               return $builder->buildConfig();
+       }
+
+       protected function getClient() {
+               return $this->connection->getClient2();
+       }
+
+       protected function getIndex() {
+               return $this->connection->getIndex2( $this->indexBaseName, 
$this->indexType, $this->indexIdentifier );
+       }
+
+       protected function getIndexName() {
+               return $this->connection->getIndexName2( $this->indexBaseName );
+       }
+
+       protected function getSpecificIndexName() {
+               return $this->connection->getIndexName2( $this->indexBaseName, 
$this->indexType, $this->indexIdentifier );
+       }
+
+       protected function getIndexTypeName() {
+               return $this->connection->getIndexName2( $this->indexBaseName, 
$this->indexType );
+       }
+
+       protected function getTopicType() {
+               return $this->getIndex()->getType( Connection::TOPIC_TYPE_NAME 
);
+       }
+
+       protected function getHeaderType() {
+               return $this->getIndex()->getType( Connection::HEADER_TYPE_NAME 
);
+       }
+
+       protected function getOldTopicType() {
+               return Connection::getRevisionType( $this->indexBaseName, 
Connection::TOPIC_TYPE_NAME );
+       }
+
+       protected function getOldHeaderType() {
+               return Connection::getRevisionType( $this->indexBaseName, 
Connection::HEADER_TYPE_NAME );
+       }
+
+       protected function getAllIndices() {
+               return Connection::getAllIndices();
+       }
+
+       protected function setConnectionTimeout() {
+               $this->connection->setTimeout2( $this->maintenanceTimeout );
+       }
+}
+
+$maintClass = 'FlowSearchConfig';
+require_once RUN_MAINTENANCE_IF_MAIN;

-- 
To view, visit https://gerrit.wikimedia.org/r/161251
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I65f649a8093da42a14617de2a10a00944173b060
Gerrit-PatchSet: 28
Gerrit-Project: mediawiki/extensions/Flow
Gerrit-Branch: master
Gerrit-Owner: Matthias Mullie <[email protected]>
Gerrit-Reviewer: EBernhardson <[email protected]>
Gerrit-Reviewer: Matthias Mullie <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to