Passed
Push — release-11.5.x ( 385fe8...cd49eb )
by Rafael
53:22 queued 14:05
created

SolrStatus::checkSolrVersion()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.5

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 10
ccs 3
cts 6
cp 0.5
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2.5
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\Utility\GeneralUtility;
27
use TYPO3\CMS\Reports\Status;
28
29
/**
30
 * Provides a status report about whether a connection to the Solr server can
31
 * be established.
32
 *
33
 * @author Ingo Renner <[email protected]>
34
 */
35
class SolrStatus extends AbstractSolrStatus
36
{
37
    /**
38
     * Site Repository
39
     *
40
     * @var SiteRepository
41
     */
42
    protected $siteRepository;
43
44
    /**
45
     * Connection Manager
46
     *
47
     * @var ConnectionManager
48
     */
49
    protected $connectionManager;
50
51
    /**
52
     * Holds the response status
53
     *
54
     * @var int
55
     */
56
    protected int $responseStatus = Status::OK;
57
58
    /**
59
     * Holds the response message build by the checks
60
     *
61
     * @var string
62
     */
63
    protected string $responseMessage = '';
64
65
    /**
66
     * SolrStatus constructor.
67
     * @param SiteRepository|null $siteRepository
68
     * @param ConnectionManager|null $connectionManager
69
     */
70 2
    public function __construct(SiteRepository $siteRepository = null, ConnectionManager $connectionManager = null)
71
    {
72 2
        $this->siteRepository = $siteRepository ?? GeneralUtility::makeInstance(SiteRepository::class);
73 2
        $this->connectionManager = $connectionManager ?? GeneralUtility::makeInstance(ConnectionManager::class);
74
    }
75
76
    /**
77
     * Compiles a collection of status checks against each configured Solr server.
78
     *
79
     * @throws DBALDriverException
80
     * @throws Throwable
81
     *
82
     * @noinspection PhpMissingReturnTypeInspection see {@link \TYPO3\CMS\Reports\StatusProviderInterface::getStatus()}
83
     */
84 2
    public function getStatus()
85
    {
86 2
        $reports = [];
87 2
        foreach ($this->siteRepository->getAvailableSites() as $site) {
88 2
            foreach ($site->getAllSolrConnectionConfigurations() as $solrConfiguration) {
89 2
                $reports[] = $this->getConnectionStatus($solrConfiguration);
90
            }
91
        }
92
93 2
        return $reports;
94
    }
95
96
    /**
97
     * Checks whether a Solr server is available and provides some information.
98
     *
99
     * @param array $solrConnection Solr connection parameters
100
     * @return Status Status of the Solr connection
101
     */
102 2
    protected function getConnectionStatus(array $solrConnection): Status
103
    {
104 2
        $header = 'Your site has contacted the Apache Solr server.';
105 2
        $this->responseStatus = Status::OK;
106
107 2
        $solrAdmin = $this->connectionManager
108 2
            ->getSolrConnectionForNodes($solrConnection['read'], $solrConnection['write'])
109 2
            ->getAdminService();
110
111 2
        $solrVersion = $this->checkSolrVersion($solrAdmin);
112 2
        $accessFilter = $this->checkAccessFilter($solrAdmin);
113 2
        $pingTime = $this->checkPingTime($solrAdmin);
114 2
        $configName = $this->checkSolrConfigName($solrAdmin);
115 2
        $schemaName = $this->checkSolrSchemaName($solrAdmin);
116
117 2
        if ($this->responseStatus !== Status::OK) {
118 1
            $header = 'Failed contacting the Solr server.';
119
        }
120
121 2
        $variables = [
122 2
            'header' => $header,
123 2
            'connection' => $solrConnection,
124 2
            'solr' => $solrAdmin,
125 2
            'solrVersion' => $solrVersion,
126 2
            'pingTime' => $pingTime,
127 2
            'configName' => $configName,
128 2
            'schemaName' => $schemaName,
129 2
            'accessFilter' => $accessFilter,
130 2
        ];
131
132 2
        $report = $this->getRenderedReport('SolrStatus.html', $variables);
133 2
        return GeneralUtility::makeInstance(
134 2
            Status::class,
135
            /** @scrutinizer ignore-type */
136 2
            'Apache Solr',
137
            /** @scrutinizer ignore-type */
138 2
            '',
139
            /** @scrutinizer ignore-type */
140 2
            $report,
141
            /** @scrutinizer ignore-type */
142 2
            $this->responseStatus
143 2
        );
144
    }
145
146
    /**
147
     * Checks the solr version and adds it to the report.
148
     *
149
     * @param SolrAdminService $solr
150
     * @return string solr version
151
     */
152 2
    protected function checkSolrVersion(SolrAdminService $solr): string
153
    {
154
        try {
155 2
            $solrVersion = $this->formatSolrVersion($solr->getSolrServerVersion());
156
        } catch (Throwable $e) {
157
            $this->responseStatus = Status::ERROR;
158
            $solrVersion = 'Error getting solr version: ' . $e->getMessage();
159
        }
160
161 2
        return $solrVersion;
162
    }
163
164
    /**
165
     * Checks the access filter setup and adds it to the report.
166
     *
167
     * @param SolrAdminService $solrAdminService
168
     * @return string
169
     */
170 2
    protected function checkAccessFilter(SolrAdminService $solrAdminService): string
171
    {
172
        try {
173 2
            $accessFilterPluginStatus = GeneralUtility::makeInstance(AccessFilterPluginInstalledStatus::class);
174 2
            $accessFilterPluginVersion = $accessFilterPluginStatus->getInstalledPluginVersion($solrAdminService);
175 1
            $accessFilterMessage = $accessFilterPluginVersion;
176 1
        } catch (Throwable $e) {
177 1
            $this->responseStatus = Status::ERROR;
178 1
            $accessFilterMessage = 'Error getting access filter: ' . $e->getMessage();
179
        }
180 2
        return $accessFilterMessage;
181
    }
182
183
    /**
184
     * Checks the ping time and adds it to the report.
185
     *
186
     * @param SolrAdminService $solrAdminService
187
     * @return string
188
     */
189 2
    protected function checkPingTime(SolrAdminService $solrAdminService): string
190
    {
191
        try {
192 2
            $pingQueryTime = $solrAdminService->getPingRoundTripRuntime();
193 1
            $pingMessage = (int)$pingQueryTime . ' ms';
194 1
        } catch (PingFailedException $e) {
195 1
            $this->responseStatus = Status::ERROR;
196 1
            $pingMessage = 'Ping error: ' . $e->getMessage();
197
        }
198 2
        return $pingMessage;
199
    }
200
201
    /**
202
     * Checks the solr config name and adds it to the report.
203
     *
204
     * @param SolrAdminService $solrAdminService
205
     * @return string
206
     */
207 2
    protected function checkSolrConfigName(SolrAdminService $solrAdminService): string
208
    {
209
        try {
210 2
            $solrConfigMessage = $solrAdminService->getSolrconfigName();
211 1
        } catch (Throwable $e) {
212 1
            $this->responseStatus = Status::ERROR;
213 1
            $solrConfigMessage = 'Error determining solr config: ' . $e->getMessage();
214
        }
215
216 2
        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...
217
    }
218
219
    /**
220
     * Checks the solr schema name and adds it to the report.
221
     *
222
     * @param SolrAdminService $solrAdminService
223
     * @return string
224
     */
225 2
    protected function checkSolrSchemaName(SolrAdminService $solrAdminService): string
226
    {
227
        try {
228 2
            $solrSchemaMessage = $solrAdminService->getSchema()->getName();
229 1
        } catch (Throwable $e) {
230 1
            $this->responseStatus = Status::ERROR;
231 1
            $solrSchemaMessage = 'Error determining schema name: ' . $e->getMessage();
232
        }
233
234 2
        return $solrSchemaMessage;
235
    }
236
237
    /**
238
     * Formats the Apache Solr server version number. By default, this is going
239
     * to be the simple major.minor.patch-level version. Custom Builds provide
240
     * more information though, in case of custom-builds, their complete
241
     * version will be added, too.
242
     *
243
     * @param string $solrVersion Unformatted Apache Solr version number a provided by Solr.
244
     * @return string formatted short version number, in case of custom-builds followed by the complete version number
245
     */
246 2
    protected function formatSolrVersion(string $solrVersion): string
247
    {
248 2
        $explodedSolrVersion = explode('.', $solrVersion);
249
250 2
        $shortSolrVersion = $explodedSolrVersion[0]
251 2
            . '.' . $explodedSolrVersion[1]
252 2
            . '.' . $explodedSolrVersion[2];
253
254 2
        $formattedSolrVersion = $shortSolrVersion;
255
256 2
        if ($solrVersion != $shortSolrVersion) {
257 1
            $formattedSolrVersion .= ' (' . $solrVersion . ')';
258
        }
259
260 2
        return $formattedSolrVersion;
261
    }
262
}
263