Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 57 |
|
0.00% |
0 / 9 |
CRAP | |
0.00% |
0 / 1 |
ConfigDump | |
0.00% |
0 / 57 |
|
0.00% |
0 / 9 |
420 | |
0.00% |
0 / 1 |
execute | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
56 | |||
addGlobals | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
12 | |||
addConcreteNamespaceMap | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
6 | |||
addReplicaGroup | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
addProfiles | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
addUserTesting | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
addExpectedIndices | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
getAllowedParams | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
2 | |||
getExamplesMessages | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace CirrusSearch\Api; |
4 | |
5 | use CirrusSearch\Maintenance\ExpectedIndicesBuilder; |
6 | use CirrusSearch\Profile\SearchProfileService; |
7 | use CirrusSearch\SearchConfig; |
8 | use CirrusSearch\UserTestingEngine; |
9 | use MediaWiki\Api\ApiBase; |
10 | use MediaWiki\Api\ApiResult; |
11 | use MediaWiki\MediaWikiServices; |
12 | use Wikimedia\ParamValidator\ParamValidator; |
13 | |
14 | /** |
15 | * Dumps CirrusSearch configuration for easy viewing. |
16 | * |
17 | * This program is free software; you can redistribute it and/or modify |
18 | * it under the terms of the GNU General Public License as published by |
19 | * the Free Software Foundation; either version 2 of the License, or |
20 | * (at your option) any later version. |
21 | * |
22 | * This program is distributed in the hope that it will be useful, |
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
25 | * GNU General Public License for more details. |
26 | * |
27 | * You should have received a copy of the GNU General Public License along |
28 | * with this program; if not, write to the Free Software Foundation, Inc., |
29 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
30 | * http://www.gnu.org/copyleft/gpl.html |
31 | */ |
32 | class ConfigDump extends ApiBase { |
33 | use ApiTrait; |
34 | |
35 | /** @var string[] */ |
36 | public static $PUBLICLY_SHAREABLE_CONFIG_VARS = [ |
37 | 'CirrusSearchDisableUpdate', |
38 | 'CirrusSearchConnectionAttempts', |
39 | 'CirrusSearchSlowSearch', |
40 | 'CirrusSearchUseExperimentalHighlighter', |
41 | 'CirrusSearchOptimizeIndexForExperimentalHighlighter', |
42 | 'CirrusSearchNamespaceMappings', |
43 | 'CirrusSearchExtraIndexes', |
44 | 'CirrusSearchExtraIndexClusters', |
45 | 'CirrusSearchFetchConfigFromApi', |
46 | 'CirrusSearchUpdateShardTimeout', |
47 | 'CirrusSearchClientSideUpdateTimeout', |
48 | 'CirrusSearchSearchShardTimeout', |
49 | 'CirrusSearchClientSizeSearchTimeout', |
50 | 'CirrusSearchMaintenanceTimeout', |
51 | 'CirrusSearchPrefixSearchStartsWithAnyWord', |
52 | 'CirrusSearchPhraseSlop', |
53 | 'CirrusSearchPhraseRescoreBoost', |
54 | 'CirrusSearchPhraseRescoreWindowSize', |
55 | 'CirrusSearchFunctionRescoreWindowSize', |
56 | 'CirrusSearchMoreAccurateScoringMode', |
57 | 'CirrusSearchPhraseSuggestUseText', |
58 | 'CirrusSearchPhraseSuggestUseOpeningText', |
59 | 'CirrusSearchIndexedRedirects', |
60 | 'CirrusSearchLinkedArticlesToUpdate', |
61 | 'CirrusSearchUnlikedArticlesToUpdate', |
62 | 'CirrusSearchWeights', |
63 | 'CirrusSearchBoostOpening', |
64 | 'CirrusSearchNearMatchWeight', |
65 | 'CirrusSearchStemmedWeight', |
66 | 'CirrusSearchNamespaceWeights', |
67 | 'CirrusSearchDefaultNamespaceWeight', |
68 | 'CirrusSearchTalkNamespaceWeight', |
69 | 'CirrusSearchLanguageWeight', |
70 | 'CirrusSearchPreferRecentDefaultDecayPortion', |
71 | 'CirrusSearchPreferRecentUnspecifiedDecayPortion', |
72 | 'CirrusSearchPreferRecentDefaultHalfLife', |
73 | 'CirrusSearchMoreLikeThisConfig', |
74 | 'CirrusSearchInterwikiSources', |
75 | 'CirrusSearchRefreshInterval', |
76 | 'CirrusSearchFragmentSize', |
77 | 'CirrusSearchIndexAllocation', |
78 | 'CirrusSearchFullTextQueryBuilderProfile', |
79 | 'CirrusSearchRescoreProfile', |
80 | 'CirrusSearchPrefixSearchRescoreProfile', |
81 | 'CirrusSearchSimilarityProfile', |
82 | 'CirrusSearchCrossProjectProfiles', |
83 | 'CirrusSearchCrossProjectOrder', |
84 | 'CirrusSearchCrossProjectSearchBlockList', |
85 | 'CirrusSearchExtraIndexBoostTemplates', |
86 | 'CirrusSearchEnableCrossProjectSearch', |
87 | 'CirrusSearchEnableAltLanguage', |
88 | 'CirrusSearchEnableArchive', |
89 | 'CirrusSearchUseIcuFolding', |
90 | 'CirrusSearchUseIcuTokenizer', |
91 | 'CirrusSearchPhraseSuggestProfiles', |
92 | 'CirrusSearchCrossProjectBlockScorerProfiles', |
93 | 'CirrusSearchSimilarityProfiles', |
94 | 'CirrusSearchRescoreFunctionChains', |
95 | 'CirrusSearchCompletionProfiles', |
96 | 'CirrusSearchCompletionSettings', |
97 | 'CirrusSearchCompletionSuggesterUseDefaultSort', |
98 | // All the config below was added when moving this data |
99 | // from CirrusSearch config to a static array in this class |
100 | 'CirrusSearchDevelOptions', |
101 | 'CirrusSearchPrefixIds', |
102 | 'CirrusSearchMoreLikeThisFields', |
103 | 'CirrusSearchMoreLikeThisTTL', |
104 | 'CirrusSearchFiletypeAliases', |
105 | 'CirrusSearchDefaultCluster', |
106 | 'CirrusSearchClientSideConnectTimeout', |
107 | 'CirrusSearchReplicaGroup', |
108 | 'CirrusSearchExtraBackendLatency', |
109 | 'CirrusSearchAllowLeadingWildcard', |
110 | 'CirrusSearchClientSideSearchTimeout', |
111 | 'CirrusSearchStripQuestionMarks', |
112 | 'CirrusSearchFullTextQueryBuilderProfiles', |
113 | 'CirrusSearchEnableRegex', |
114 | 'CirrusSearchWikimediaExtraPlugin', |
115 | 'CirrusSearchRegexMaxDeterminizedStates', |
116 | 'CirrusSearchMaxIncategoryOptions', |
117 | 'CirrusSearchEnablePhraseSuggest', |
118 | 'CirrusSearchClusterOverrides', |
119 | 'CirrusSearchRescoreProfiles', |
120 | 'CirrusSearchRescoreFunctionScoreChains', |
121 | 'CirrusSearchNumCrossProjectSearchResults', |
122 | 'CirrusSearchLanguageToWikiMap', |
123 | 'CirrusSearchWikiToNameMap', |
124 | 'CirrusSearchIncLinksAloneW', |
125 | 'CirrusSearchIncLinksAloneK', |
126 | 'CirrusSearchIncLinksAloneA', |
127 | 'CirrusSearchNewCrossProjectPage', |
128 | 'CirrusSearchQueryStringMaxDeterminizedStates', |
129 | 'CirrusSearchElasticQuirks', |
130 | 'CirrusSearchPhraseSuggestMaxErrors', |
131 | 'CirrusSearchPhraseSuggestReverseField', |
132 | 'CirrusSearchBoostTemplates', |
133 | 'CirrusSearchIgnoreOnWikiBoostTemplates', |
134 | 'CirrusSearchIndexBaseName', |
135 | 'CirrusSearchInterleaveConfig', |
136 | 'CirrusSearchMaxPhraseTokens', |
137 | 'LanguageCode', |
138 | 'ContentNamespaces', |
139 | 'NamespacesToBeSearchedDefault', |
140 | 'CirrusSearchCategoryDepth', |
141 | 'CirrusSearchCategoryMax', |
142 | 'CirrusSearchCategoryEndpoint', |
143 | 'CirrusSearchFallbackProfile', |
144 | 'CirrusSearchFallbackProfiles', |
145 | ]; |
146 | |
147 | public function execute() { |
148 | $result = $this->getResult(); |
149 | $props = array_flip( $this->extractRequestParams()[ 'prop' ] ); |
150 | if ( isset( $props['globals'] ) ) { |
151 | $this->addGlobals( $result ); |
152 | } |
153 | if ( isset( $props['namespacemap'] ) ) { |
154 | $this->addConcreteNamespaceMap( $result ); |
155 | } |
156 | if ( isset( $props['profiles'] ) ) { |
157 | $this->addProfiles( $result ); |
158 | } |
159 | if ( isset( $props['replicagroup'] ) ) { |
160 | $this->addReplicaGroup( $result ); |
161 | } |
162 | if ( isset( $props['usertesting'] ) ) { |
163 | $this->addUserTesting( $result ); |
164 | } |
165 | if ( isset( $props['expectedindices'] ) ) { |
166 | $this->addExpectedIndices( $result ); |
167 | } |
168 | } |
169 | |
170 | /** |
171 | * @param ApiResult $result |
172 | * @return void |
173 | */ |
174 | protected function addGlobals( ApiResult $result ): void { |
175 | $config = $this->getConfig(); |
176 | foreach ( self::$PUBLICLY_SHAREABLE_CONFIG_VARS as $key ) { |
177 | if ( $config->has( $key ) ) { |
178 | $result->addValue( null, $key, $config->get( $key ) ); |
179 | } |
180 | } |
181 | } |
182 | |
183 | /** |
184 | * Include a complete mapping from namespace id to index containing pages. |
185 | * |
186 | * Intended for external services/users that need to interact |
187 | * with elasticsearch or cirrussearch dumps directly. |
188 | * |
189 | * @param ApiResult $result Impl to write results to |
190 | */ |
191 | private function addConcreteNamespaceMap( ApiResult $result ) { |
192 | $nsInfo = MediaWikiServices::getInstance()->getNamespaceInfo(); |
193 | $conn = $this->getCirrusConnection(); |
194 | $indexBaseName = $conn->getConfig()->get( SearchConfig::INDEX_BASE_NAME ); |
195 | foreach ( $nsInfo->getValidNamespaces() as $ns ) { |
196 | $indexSuffix = $conn->getIndexSuffixForNamespace( $ns ); |
197 | $indexName = $conn->getIndexName( $indexBaseName, $indexSuffix ); |
198 | $result->addValue( 'CirrusSearchConcreteNamespaceMap', $ns, $indexName ); |
199 | } |
200 | } |
201 | |
202 | private function addReplicaGroup( ApiResult $result ) { |
203 | $result->addValue( null, 'CirrusSearchConcreteReplicaGroup', |
204 | $this->getCirrusConnection()->getConfig()->getClusterAssignment()->getCrossClusterName() ); |
205 | } |
206 | |
207 | /** |
208 | * Profile names and types |
209 | * @var string[] |
210 | */ |
211 | private static $PROFILES = [ |
212 | 'CirrusSearchPhraseSuggestProfiles' => SearchProfileService::PHRASE_SUGGESTER, |
213 | 'CirrusSearchCrossProjectBlockScorerProfiles' => SearchProfileService::CROSS_PROJECT_BLOCK_SCORER, |
214 | 'CirrusSearchSimilarityProfiles' => SearchProfileService::SIMILARITY, |
215 | 'CirrusSearchRescoreFunctionChains' => SearchProfileService::RESCORE_FUNCTION_CHAINS, |
216 | 'CirrusSearchCompletionProfiles' => SearchProfileService::COMPLETION, |
217 | 'CirrusSearchFullTextQueryBuilderProfiles' => SearchProfileService::FT_QUERY_BUILDER, |
218 | 'CirrusSearchRescoreProfiles' => SearchProfileService::RESCORE, |
219 | ]; |
220 | |
221 | /** |
222 | * Add data from profiles |
223 | * @param ApiResult $result |
224 | */ |
225 | private function addProfiles( ApiResult $result ) { |
226 | $config = new SearchConfig(); |
227 | $profileService = $config->getProfileService(); |
228 | foreach ( self::$PROFILES as $var => $profileType ) { |
229 | $data = $profileService->listExposedProfiles( $profileType ); |
230 | $this->getResult()->addValue( null, $var, $data, ApiResult::OVERRIDE ); |
231 | } |
232 | } |
233 | |
234 | /** |
235 | * @param ApiResult $result |
236 | * @return void |
237 | * @throws \CirrusSearch\NoActiveTestException |
238 | */ |
239 | protected function addUserTesting( ApiResult $result ): void { |
240 | // UserTesting only automatically assigns test buckets during web requests. |
241 | // This api call is different from a typical search request though, this is |
242 | // used from non-search pages to find out what bucket to provide to a new |
243 | // autocomplete session. |
244 | $engine = UserTestingEngine::fromConfig( $this->getConfig() ); |
245 | $status = $engine->decideTestByAutoenroll(); |
246 | $result->addValue( null, 'CirrusSearchActiveUserTest', |
247 | $status->isActive() ? $status->getTrigger() : '' ); |
248 | } |
249 | |
250 | /** |
251 | * @param ApiResult $result |
252 | * @return void |
253 | */ |
254 | protected function addExpectedIndices( ApiResult $result ): void { |
255 | $builder = new ExpectedIndicesBuilder( $this->getSearchConfig() ); |
256 | $result->addValue( null, 'CirrusSearchExpectedIndices', |
257 | $builder->build( false, null ) ); |
258 | } |
259 | |
260 | public function getAllowedParams() { |
261 | return [ |
262 | 'prop' => [ |
263 | ParamValidator::PARAM_DEFAULT => 'globals|namespacemap|profiles|replicagroup', |
264 | ParamValidator::PARAM_TYPE => [ |
265 | 'globals', |
266 | 'namespacemap', |
267 | 'profiles', |
268 | 'replicagroup', |
269 | 'usertesting', |
270 | 'expectedindices' |
271 | ], |
272 | ParamValidator::PARAM_ISMULTI => true, |
273 | ], |
274 | ]; |
275 | } |
276 | |
277 | /** |
278 | * @see ApiBase::getExamplesMessages |
279 | * @return array |
280 | */ |
281 | protected function getExamplesMessages() { |
282 | return [ |
283 | 'action=cirrus-config-dump' => |
284 | 'apihelp-cirrus-config-dump-example' |
285 | ]; |
286 | } |
287 | |
288 | } |