From 7fdf2623950214733527025ec9aaf6aeb7bdcf28 Mon Sep 17 00:00:00 2001 From: ojooss Date: Mon, 20 Feb 2023 20:54:02 +0100 Subject: [PATCH 1/2] add elasticsearch 8 support --- composer.json | 3 +- examples/standalone.php | 11 ++++-- src/Check/ElasticsearchCheck.php | 36 +++++++++++++++----- tests/Check/ElasticsearchCheckTest.php | 47 ++++++++++++++++++++++---- 4 files changed, 77 insertions(+), 20 deletions(-) diff --git a/composer.json b/composer.json index e5d55c1..201e064 100644 --- a/composer.json +++ b/composer.json @@ -20,9 +20,10 @@ "twig/twig": "^2.0||^3.0" }, "require-dev": { + "dg/bypass-finals": "^1.4", "doctrine/dbal": "~3.2", "doctrine/migrations": "^3.3", - "elasticsearch/elasticsearch": "^6.0||^7.0", + "elasticsearch/elasticsearch": "^6.0||^7.0||^8.0", "mongodb/mongodb": "^1.4", "monolog/monolog": "^2.3", "nyholm/psr7": "^1.5", diff --git a/examples/standalone.php b/examples/standalone.php index 6f9dcdc..0e546a3 100644 --- a/examples/standalone.php +++ b/examples/standalone.php @@ -11,7 +11,7 @@ $checker = new StatusChecker(); $group01 = new StatusCheckerGroup('General'); -$group01->addCheck(new PhpVersionCheck('PHP Version', '7.0.0', '7.2.0')); +$group01->addCheck(new PhpVersionCheck('PHP Version', '8.0.0', '8.2.0')); $group01->addCheck(new PhpMemoryLimitCheck('memory_limit', 128)); $checker->addGroup($group01); @@ -39,6 +39,11 @@ $checker->addCheck(new PhpExtensionCheck('PHP Extension / libxml', 'libxml')); $checker->addCheck(new PhpExtensionCheck('PHP Extension / SimpleXML', 'SimpleXML')); +$client = \Elastic\Elasticsearch\ClientBuilder::create() + ->setHosts(['localhost:9200']) + ->build(); +$checker->addCheck(new \BretRZaun\StatusPage\Check\ElasticsearchCheck('Elasticsearch', $client, ['foo', 'bar'])); + // run the checks $checker->check(); @@ -47,8 +52,8 @@ $showDetails = (bool)preg_match('|(?mi-Us)' . $whitelistPattern . '|', $_SERVER['REMOTE_ADDR']); // use the built-in Twig template -$loader = new Twig_Loader_Filesystem(__DIR__ . '/../resources/views/'); -$twig = new Twig_Environment($loader, ['autoescape' => false]); +$loader = new Twig\Loader\FilesystemLoader(__DIR__ . '/../resources/views/'); +$twig = new Twig\Environment($loader, ['autoescape' => false]); $content = $twig->render( 'status.twig', diff --git a/src/Check/ElasticsearchCheck.php b/src/Check/ElasticsearchCheck.php index 6390d7b..1af3ad7 100644 --- a/src/Check/ElasticsearchCheck.php +++ b/src/Check/ElasticsearchCheck.php @@ -2,14 +2,14 @@ namespace BretRZaun\StatusPage\Check; use BretRZaun\StatusPage\Result; -use Elasticsearch\Client; use Exception; +use function PHPUnit\Framework\isEmpty; class ElasticsearchCheck extends AbstractCheck { /** - * @var Client + * @var \Elasticsearch\Client|\Elastic\Elasticsearch\Client */ protected $client; @@ -22,12 +22,13 @@ class ElasticsearchCheck extends AbstractCheck * Constructor * * @param string $label - * @param Client $client + * @param \Elasticsearch\Client|\Elastic\Elasticsearch\Client $client * @param array $indices Indices to check for */ - public function __construct(string $label, Client $client, array $indices = []) + public function __construct(string $label, \Elasticsearch\Client|\Elastic\Elasticsearch\Client $client, array $indices = []) { parent::__construct($label); + $this->client = $client; $this->indices = $indices; } @@ -41,13 +42,30 @@ public function checkStatus(): Result { $result = new Result($this->label); try { - if ($this->client->ping() !== true) { - $result->setSuccess(false); - return $result; + $info = $this->client->info(); + $versionParts = explode('.', $info['version']['number']); + $esMajorVersion = (int)array_shift($versionParts); + if ($esMajorVersion >= 8) { + if ($this->client->ping()->asBool() !== true) { + $result->setError("Elasticsearch is not reachable (ping failed)"); + return $result; + } + } else { + if ($this->client->ping() !== true) { + $result->setError("Elasticsearch is not reachable (ping failed)"); + return $result; + } } + foreach ($this->indices as $index) { - if (!$this->client->indices()->exists(['index' => $index])) { - $result->setError("Index '$index' does not exist"); + if ($esMajorVersion >= 8) { + if (!$this->client->indices()->exists(['index' => $index])->asBool()) { + $result->setError("Index '$index' does not exist"); + } + } else { + if (!$this->client->indices()->exists(['index' => $index])) { + $result->setError("Index '$index' does not exist"); + } } } } catch (Exception $e) { diff --git a/tests/Check/ElasticsearchCheckTest.php b/tests/Check/ElasticsearchCheckTest.php index 3dc69c3..59424f6 100644 --- a/tests/Check/ElasticsearchCheckTest.php +++ b/tests/Check/ElasticsearchCheckTest.php @@ -2,19 +2,32 @@ namespace BretRZaun\StatusPage\Tests\Check; use BretRZaun\StatusPage\Check\ElasticsearchCheck; -use Elasticsearch\Client; -use Elasticsearch\Namespaces\IndicesNamespace; +use DG\BypassFinals; +use Elastic\Elasticsearch\Client; +use Elastic\Elasticsearch\Endpoints\Indices; +use Elastic\Elasticsearch\Response\Elasticsearch; use PHPUnit\Framework\TestCase; +// enable mock final classes +BypassFinals::enable(); + class ElasticsearchCheckTest extends TestCase { public function testSuccess(): void { + /** @noinspection PhpUnitInvalidMockingEntityInspection */ $client = $this->createMock(Client::class); $client->expects($this->once()) - ->method('ping') + ->method('info') + ->willReturn(['version' => ['number' => '8.1.2']]); + $ping = $this->createMock(Elasticsearch::class); + $ping->expects($this->once()) + ->method('asBool') ->willReturn(true); + $client->expects($this->any()) + ->method('ping') + ->willReturn($ping); $check = new ElasticsearchCheck('elasticsearch test', $client); $result = $check->checkStatus(); @@ -25,10 +38,18 @@ public function testSuccess(): void public function testFailure(): void { + /** @noinspection PhpUnitInvalidMockingEntityInspection */ $client = $this->createMock(Client::class); $client->expects($this->once()) - ->method('ping') + ->method('info') + ->willReturn(['version' => ['number' => '8.1.2']]); + $ping = $this->createMock(Elasticsearch::class); + $ping->expects($this->once()) + ->method('asBool') ->willReturn(false); + $client->expects($this->any()) + ->method('ping') + ->willReturn($ping); $check = new ElasticsearchCheck('elasticsearch test', $client); $result = $check->checkStatus(); @@ -38,16 +59,28 @@ public function testFailure(): void public function testMissingIndex(): void { + /** @noinspection PhpUnitInvalidMockingEntityInspection */ $client = $this->createMock(Client::class); $client->expects($this->once()) - ->method('ping') + ->method('info') + ->willReturn(['version' => ['number' => '8.1.2']]); + $ping = $this->createMock(Elasticsearch::class); + $ping->expects($this->once()) + ->method('asBool') ->willReturn(true); + $client->expects($this->any()) + ->method('ping') + ->willReturn($ping); - $incidesMock = $this->createMock(IndicesNamespace::class); + $exists = $this->createMock(Elasticsearch::class); + $exists->expects($this->once()) + ->method('asBool') + ->willReturn(false); + $incidesMock = $this->createMock(Indices::class); $incidesMock->expects($this->once()) ->method('exists') ->with(['index' => 'notexisting-test-index']) - ->willReturn(false); + ->willReturn($exists); $client->expects($this->once()) ->method('indices') From b61e789e1df2a12bfb8ba8c62deed047e4473be7 Mon Sep 17 00:00:00 2001 From: ojooss Date: Mon, 20 Feb 2023 21:23:25 +0100 Subject: [PATCH 2/2] run elasticsearch test in seperate process due to side effects of BypassFinals::enable() elasticsearch tests --- tests/Check/ElasticsearchCheckTest.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/Check/ElasticsearchCheckTest.php b/tests/Check/ElasticsearchCheckTest.php index 59424f6..3a63bb0 100644 --- a/tests/Check/ElasticsearchCheckTest.php +++ b/tests/Check/ElasticsearchCheckTest.php @@ -9,13 +9,17 @@ use PHPUnit\Framework\TestCase; // enable mock final classes -BypassFinals::enable(); +/** + * @runTestsInSeparateProcesses + */ class ElasticsearchCheckTest extends TestCase { public function testSuccess(): void { + BypassFinals::enable(); + /** @noinspection PhpUnitInvalidMockingEntityInspection */ $client = $this->createMock(Client::class); $client->expects($this->once()) @@ -38,6 +42,8 @@ public function testSuccess(): void public function testFailure(): void { + BypassFinals::enable(); + /** @noinspection PhpUnitInvalidMockingEntityInspection */ $client = $this->createMock(Client::class); $client->expects($this->once()) @@ -59,6 +65,8 @@ public function testFailure(): void public function testMissingIndex(): void { + BypassFinals::enable(); + /** @noinspection PhpUnitInvalidMockingEntityInspection */ $client = $this->createMock(Client::class); $client->expects($this->once())