Passed
Push — task/3376-TYPO3_12_compatibili... ( dc7e5a...379ca7 )
by Rafael
40:48
created

SolrStatus::checkPingTime()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 10
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the TYPO3 CMS project.
7
 *
8
 * It is free software; you can redistribute it and/or modify it under
9
 * the terms of the GNU General Public License, either version 2
10
 * of the License, or any later version.
11
 *
12
 * For the full copyright and license information, please read the
13
 * LICENSE.txt file that was distributed with this source code.
14
 *
15
 * The TYPO3 project - inspiring people to share!
16
 */
17
18
namespace ApacheSolrForTypo3\Solr\Report;
19
20
use ApacheSolrForTypo3\Solr\ConnectionManager;
21
use ApacheSolrForTypo3\Solr\Domain\Site\SiteRepository;
22
use ApacheSolrForTypo3\Solr\PingFailedException;
23
use ApacheSolrForTypo3\Solr\System\Solr\Service\SolrAdminService;
24
use Doctrine\DBAL\Driver\Exception as DBALDriverException;
25
use Throwable;
26
use TYPO3\CMS\Core\Type\ContextualFeedbackSeverity;
27
use TYPO3\CMS\Core\Utility\GeneralUtility;
28
use TYPO3\CMS\Reports\Status;
29
30
/**
31
 * Provides a status report about whether a connection to the Solr server can
32
 * be established.
33
 *
34
 * @author Ingo Renner <[email protected]>
35
 */
36
class SolrStatus extends AbstractSolrStatus
37
{
38
    /**
39
     * Site Repository
40
     *
41
     * @var SiteRepository
42
     */
43
    protected SiteRepository $siteRepository;
44
45
    /**
46
     * Connection Manager
47
     *
48
     * @var ConnectionManager
49
     */
50
    protected ConnectionManager $connectionManager;
51
52
    /**
53
     * Holds the response status
54
     *
55
     * @var ContextualFeedbackSeverity
56
     */
57
    protected ContextualFeedbackSeverity $responseStatus = ContextualFeedbackSeverity::OK;
58
59
    /**
60
     * Holds the response message build by the checks
61
     *
62
     * @var string
63
     */
64
    protected string $responseMessage = '';
65
66
    /**
67
     * SolrStatus constructor.
68
     * @param SiteRepository|null $siteRepository
69
     * @param ConnectionManager|null $connectionManager
70
     */
71
    public function __construct(SiteRepository $siteRepository = null, ConnectionManager $connectionManager = null)
72
    {
73
        $this->siteRepository = $siteRepository ?? GeneralUtility::makeInstance(SiteRepository::class);
74
        $this->connectionManager = $connectionManager ?? GeneralUtility::makeInstance(ConnectionManager::class);
75
    }
76
77
    /**
78
     * Compiles a collection of status checks against each configured Solr server.
79
     *
80
     * @return array
81
     *
82
     * @throws DBALDriverException
83
     * @throws Throwable
84
     */
85
    public function getStatus(): array
86
    {
87
        $reports = [];
88
        foreach ($this->siteRepository->getAvailableSites() as $site) {
89
            foreach ($site->getAllSolrConnectionConfigurations() as $solrConfiguration) {
90
                $reports[] = $this->getConnectionStatus($solrConfiguration);
91
            }
92
        }
93
94
        return $reports;
95
    }
96
97
    /**
98
     * {@inheritDoc}
99
     */
100
    public function getLabel(): string
101
    {
102
        return 'solr/status';
103
    }
104
105
    /**
106
     * Checks whether a Solr server is available and provides some information.
107
     *
108
     * @param array $solrConnection Solr connection parameters
109
     * @return Status Status of the Solr connection
110
     */
111
    protected function getConnectionStatus(array $solrConnection): Status
112
    {
113
        $header = 'Your site has contacted the Apache Solr server.';
114
        $this->responseStatus = ContextualFeedbackSeverity::OK;
115
116
        $solrAdmin = $this->connectionManager
117
            ->getSolrConnectionForNodes($solrConnection['read'], $solrConnection['write'])
118
            ->getAdminService();
119
120
        $solrVersion = $this->checkSolrVersion($solrAdmin);
121
        $accessFilter = $this->checkAccessFilter($solrAdmin);
122
        $pingTime = $this->checkPingTime($solrAdmin);
123
        $configName = $this->checkSolrConfigName($solrAdmin);
124
        $schemaName = $this->checkSolrSchemaName($solrAdmin);
125
126
        if ($this->responseStatus !== ContextualFeedbackSeverity::OK) {
127
            $header = 'Failed contacting the Solr server.';
128
        }
129
130
        $variables = [
131
            'header' => $header,
132
            'connection' => $solrConnection,
133
            'solr' => $solrAdmin,
134
            'solrVersion' => $solrVersion,
135
            'pingTime' => $pingTime,
136
            'configName' => $configName,
137
            'schemaName' => $schemaName,
138
            'accessFilter' => $accessFilter,
139
        ];
140
141
        $report = $this->getRenderedReport('SolrStatus.html', $variables);
142
        return GeneralUtility::makeInstance(
143
            Status::class,
144
            /** @scrutinizer ignore-type */
145
            'Apache Solr',
146
            /** @scrutinizer ignore-type */
147
            '',
148
            /** @scrutinizer ignore-type */
149
            $report,
150
            /** @scrutinizer ignore-type */
151
            $this->responseStatus
152
        );
153
    }
154
155
    /**
156
     * Checks the solr version and adds it to the report.
157
     *
158
     * @param SolrAdminService $solr
159
     * @return string solr version
160
     */
161
    protected function checkSolrVersion(SolrAdminService $solr): string
162
    {
163
        try {
164
            $solrVersion = $this->formatSolrVersion($solr->getSolrServerVersion());
165
        } catch (Throwable $e) {
166
            $this->responseStatus = ContextualFeedbackSeverity::ERROR;
167
            $solrVersion = 'Error getting solr version: ' . $e->getMessage();
168
        }
169
170
        return $solrVersion;
171
    }
172
173
    /**
174
     * Checks the access filter setup and adds it to the report.
175
     *
176
     * @param SolrAdminService $solrAdminService
177
     * @return string
178
     */
179
    protected function checkAccessFilter(SolrAdminService $solrAdminService): string
180
    {
181
        try {
182
            $accessFilterPluginStatus = GeneralUtility::makeInstance(AccessFilterPluginInstalledStatus::class);
183
            $accessFilterPluginVersion = $accessFilterPluginStatus->getInstalledPluginVersion($solrAdminService);
184
            $accessFilterMessage = $accessFilterPluginVersion;
185
        } catch (Throwable $e) {
186
            $this->responseStatus = ContextualFeedbackSeverity::ERROR;
187
            $accessFilterMessage = 'Error getting access filter: ' . $e->getMessage();
188
        }
189
        return $accessFilterMessage;
190
    }
191
192
    /**
193
     * Checks the ping time and adds it to the report.
194
     *
195
     * @param SolrAdminService $solrAdminService
196
     * @return string
197
     */
198
    protected function checkPingTime(SolrAdminService $solrAdminService): string
199
    {
200
        try {
201
            $pingQueryTime = $solrAdminService->getPingRoundTripRuntime();
202
            $pingMessage = (int)$pingQueryTime . ' ms';
203
        } catch (PingFailedException $e) {
204
            $this->responseStatus = ContextualFeedbackSeverity::ERROR;
205
            $pingMessage = 'Ping error: ' . $e->getMessage();
206
        }
207
        return $pingMessage;
208
    }
209
210
    /**
211
     * Checks the solr config name and adds it to the report.
212
     *
213
     * @param SolrAdminService $solrAdminService
214
     * @return string
215
     */
216
    protected function checkSolrConfigName(SolrAdminService $solrAdminService): string
217
    {
218
        try {
219
            $solrConfigMessage = $solrAdminService->getSolrconfigName();
220
        } catch (Throwable $e) {
221
            $this->responseStatus = ContextualFeedbackSeverity::ERROR;
222
            $solrConfigMessage = 'Error determining solr config: ' . $e->getMessage();
223
        }
224
225
        return $solrConfigMessage;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $solrConfigMessage could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
226
    }
227
228
    /**
229
     * Checks the solr schema name and adds it to the report.
230
     *
231
     * @param SolrAdminService $solrAdminService
232
     * @return string
233
     */
234
    protected function checkSolrSchemaName(SolrAdminService $solrAdminService): string
235
    {
236
        try {
237
            $solrSchemaMessage = $solrAdminService->getSchema()->getName();
238
        } catch (Throwable $e) {
239
            $this->responseStatus = ContextualFeedbackSeverity::ERROR;
240
            $solrSchemaMessage = 'Error determining schema name: ' . $e->getMessage();
241
        }
242
243
        return $solrSchemaMessage;
244
    }
245
246
    /**
247
     * Formats the Apache Solr server version number. By default, this is going
248
     * to be the simple major.minor.patch-level version. Custom Builds provide
249
     * more information though, in case of custom-builds, their complete
250
     * version will be added, too.
251
     *
252
     * @param string $solrVersion Unformatted Apache Solr version number a provided by Solr.
253
     * @return string formatted short version number, in case of custom-builds followed by the complete version number
254
     */
255
    protected function formatSolrVersion(string $solrVersion): string
256
    {
257
        $explodedSolrVersion = explode('.', $solrVersion);
258
259
        $shortSolrVersion = $explodedSolrVersion[0]
260
            . '.' . $explodedSolrVersion[1]
261
            . '.' . $explodedSolrVersion[2];
262
263
        $formattedSolrVersion = $shortSolrVersion;
264
265
        if ($solrVersion != $shortSolrVersion) {
266
            $formattedSolrVersion .= ' (' . $solrVersion . ')';
267
        }
268
269
        return $formattedSolrVersion;
270
    }
271
}
272