From 35160cfc82ef9cf7fd1392d15468075495ff7913 Mon Sep 17 00:00:00 2001 From: Frank Verschuren <2994563-darthf1@users.noreply.gitlab.com> Date: Sun, 22 Dec 2024 08:39:06 +0100 Subject: [PATCH] feat(elasticsearch): re-introduce v7 support --- composer.json | 2 +- src/Elasticsearch/State/CollectionProvider.php | 8 ++++++-- src/Elasticsearch/State/ItemProvider.php | 8 ++++++-- src/Elasticsearch/composer.json | 2 +- .../Bundle/DependencyInjection/ApiPlatformExtension.php | 6 +++++- .../Compiler/ElasticsearchClientPass.php | 2 ++ src/Symfony/Bundle/DependencyInjection/Configuration.php | 7 ++++++- tests/Behat/ElasticsearchContext.php | 3 ++- .../Compiler/ElasticsearchClientPassTest.php | 8 +++++++- 9 files changed, 36 insertions(+), 10 deletions(-) diff --git a/composer.json b/composer.json index 290828ac782..65521de951d 100644 --- a/composer.json +++ b/composer.json @@ -127,7 +127,7 @@ "doctrine/mongodb-odm": "^2.6", "doctrine/mongodb-odm-bundle": "^4.0 || ^5.0", "doctrine/orm": "^2.17 || ^3.0", - "elasticsearch/elasticsearch": "^8.4", + "elasticsearch/elasticsearch": "^7.17 || ^8.4", "friends-of-behat/mink-browserkit-driver": "^1.3.1", "friends-of-behat/mink-extension": "^2.2", "friends-of-behat/symfony-extension": "^2.1", diff --git a/src/Elasticsearch/State/CollectionProvider.php b/src/Elasticsearch/State/CollectionProvider.php index e4ade908821..a366d5449bd 100644 --- a/src/Elasticsearch/State/CollectionProvider.php +++ b/src/Elasticsearch/State/CollectionProvider.php @@ -24,6 +24,8 @@ use Elastic\Elasticsearch\Client; use Elastic\Elasticsearch\Exception\ClientResponseException; use Elastic\Elasticsearch\Response\Elasticsearch; +use Elasticsearch\Client as V7Client; +use Elasticsearch\Common\Exceptions\Missing404Exception as V7Missing404Exception; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; /** @@ -37,7 +39,7 @@ final class CollectionProvider implements ProviderInterface /** * @param RequestBodySearchCollectionExtensionInterface[] $collectionExtensions */ - public function __construct(private readonly Client $client, private readonly ?DenormalizerInterface $denormalizer = null, private readonly ?Pagination $pagination = null, private readonly iterable $collectionExtensions = [], private readonly ?InflectorInterface $inflector = new Inflector()) + public function __construct(private readonly V7Client|Client $client, private readonly ?DenormalizerInterface $denormalizer = null, private readonly ?Pagination $pagination = null, private readonly iterable $collectionExtensions = [], private readonly ?InflectorInterface $inflector = new Inflector()) { } @@ -69,12 +71,14 @@ public function provide(Operation $operation, array $uriVariables = [], array $c try { $documents = $this->client->search($params); + } catch (V7Missing404Exception $e) { + throw new Error(status: $e->getCode(), detail: $e->getMessage(), title: $e->getMessage(), originalTrace: $e->getTrace()); } catch (ClientResponseException $e) { $response = $e->getResponse(); throw new Error(status: $response->getStatusCode(), detail: (string) $response->getBody(), title: $response->getReasonPhrase(), originalTrace: $e->getTrace()); } - if ($documents instanceof Elasticsearch) { + if (class_exists(Elastic\Elasticsearch\Response\Elasticsearch::class) && $documents instanceof Elasticsearch) { $documents = $documents->asArray(); } diff --git a/src/Elasticsearch/State/ItemProvider.php b/src/Elasticsearch/State/ItemProvider.php index 7828145f89d..e77e28bbec8 100644 --- a/src/Elasticsearch/State/ItemProvider.php +++ b/src/Elasticsearch/State/ItemProvider.php @@ -23,6 +23,8 @@ use Elastic\Elasticsearch\Client; use Elastic\Elasticsearch\Exception\ClientResponseException; use Elastic\Elasticsearch\Response\Elasticsearch; +use Elasticsearch\Client as V7Client; +use Elasticsearch\Common\Exceptions\Missing404Exception as V7Missing404Exception; use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; @@ -34,7 +36,7 @@ */ final class ItemProvider implements ProviderInterface { - public function __construct(private readonly Client $client, private readonly ?DenormalizerInterface $denormalizer = null, private readonly ?InflectorInterface $inflector = new Inflector()) + public function __construct(private readonly V7Client|Client $client, private readonly ?DenormalizerInterface $denormalizer = null, private readonly ?InflectorInterface $inflector = new Inflector()) { } @@ -56,6 +58,8 @@ public function provide(Operation $operation, array $uriVariables = [], array $c try { $document = $this->client->get($params); + } catch (V7Missing404Exception) { + return null; } catch (ClientResponseException $e) { $response = $e->getResponse(); if (404 === $response->getStatusCode()) { @@ -65,7 +69,7 @@ public function provide(Operation $operation, array $uriVariables = [], array $c throw new Error(status: $response->getStatusCode(), detail: (string) $response->getBody(), title: $response->getReasonPhrase(), originalTrace: $e->getTrace()); } - if ($document instanceof Elasticsearch) { + if (class_exists(Elastic\Elasticsearch\Response\Elasticsearch::class) && $documents instanceof Elasticsearch) { $document = $document->asArray(); } diff --git a/src/Elasticsearch/composer.json b/src/Elasticsearch/composer.json index 7d4961afef3..3507b2f5411 100644 --- a/src/Elasticsearch/composer.json +++ b/src/Elasticsearch/composer.json @@ -27,7 +27,7 @@ "api-platform/metadata": "^3.4 || ^4.0", "api-platform/serializer": "^3.4 || ^4.0", "api-platform/state": "^3.4 || ^4.0", - "elasticsearch/elasticsearch": "^8.4", + "elasticsearch/elasticsearch": "^7.17 || ^8.4", "symfony/cache": "^6.4 || ^7.0", "symfony/console": "^6.4 || ^7.0", "symfony/property-access": "^6.4 || ^7.0", diff --git a/src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php b/src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php index 4a3f09df3cb..a5fb2fa8f57 100644 --- a/src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php +++ b/src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php @@ -810,7 +810,11 @@ private function registerElasticsearchConfiguration(ContainerBuilder $container, return; } - $clientClass = class_exists(\Elasticsearch\Client::class) ? \Elasticsearch\Client::class : \Elastic\Elasticsearch\Client::class; + $clientClass = class_exists(\Elasticsearch\Client::class) + // ES v8 and up + ? \Elasticsearch\Client::class + // ES v7 + : \Elastic\Elasticsearch\Client::class; $clientDefinition = new Definition($clientClass); $container->setDefinition('api_platform.elasticsearch.client', $clientDefinition); diff --git a/src/Symfony/Bundle/DependencyInjection/Compiler/ElasticsearchClientPass.php b/src/Symfony/Bundle/DependencyInjection/Compiler/ElasticsearchClientPass.php index 1be89c71010..574f35f5d75 100644 --- a/src/Symfony/Bundle/DependencyInjection/Compiler/ElasticsearchClientPass.php +++ b/src/Symfony/Bundle/DependencyInjection/Compiler/ElasticsearchClientPass.php @@ -40,8 +40,10 @@ public function process(ContainerBuilder $container): void } if (class_exists(\Elasticsearch\ClientBuilder::class)) { + // ES v7 $builderName = \Elasticsearch\ClientBuilder::class; } else { + // ES v8 and up $builderName = \Elastic\Elasticsearch\ClientBuilder::class; } diff --git a/src/Symfony/Bundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/DependencyInjection/Configuration.php index e7895b10ae8..c9029b94dd4 100644 --- a/src/Symfony/Bundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/DependencyInjection/Configuration.php @@ -468,7 +468,12 @@ private function addElasticsearchSection(ArrayNodeDefinition $rootNode): void ->validate() ->ifTrue() ->then(static function (bool $v): bool { - if (!(class_exists(\Elasticsearch\Client::class) || class_exists(\Elastic\Elasticsearch\Client::class))) { + if ( + // ES v8 and up + !class_exists(\Elasticsearch\Client::class) + // ES v7 + && !class_exists(\Elastic\Elasticsearch\Client::class) + ) { throw new InvalidConfigurationException('The elasticsearch/elasticsearch package is required for Elasticsearch support.'); } diff --git a/tests/Behat/ElasticsearchContext.php b/tests/Behat/ElasticsearchContext.php index 37737cd562f..0395e56f293 100644 --- a/tests/Behat/ElasticsearchContext.php +++ b/tests/Behat/ElasticsearchContext.php @@ -15,6 +15,7 @@ use Behat\Behat\Context\Context; use Elastic\Elasticsearch\Client; +use Elasticsearch\Client as V7Client; use Symfony\Component\Finder\Finder; /** @@ -24,7 +25,7 @@ */ final class ElasticsearchContext implements Context { - public function __construct(private readonly Client $client, private readonly string $elasticsearchMappingsPath, private readonly string $elasticsearchFixturesPath) + public function __construct(private readonly V7Client|Client $client, private readonly string $elasticsearchMappingsPath, private readonly string $elasticsearchFixturesPath) { } diff --git a/tests/Symfony/Bundle/DependencyInjection/Compiler/ElasticsearchClientPassTest.php b/tests/Symfony/Bundle/DependencyInjection/Compiler/ElasticsearchClientPassTest.php index 2245b50df0c..1376fcd0be9 100644 --- a/tests/Symfony/Bundle/DependencyInjection/Compiler/ElasticsearchClientPassTest.php +++ b/tests/Symfony/Bundle/DependencyInjection/Compiler/ElasticsearchClientPassTest.php @@ -36,6 +36,7 @@ public function testConstruct(): void public function testProcess(): void { + // ES v7 if (class_exists(\Elasticsearch\ClientBuilder::class)) { $clientBuilder = \Elasticsearch\ClientBuilder::class; @@ -45,6 +46,7 @@ public function testProcess(): void Argument::withEntry('tracer', Argument::type(Reference::class)), Argument::size(3), ]; + // ES v8 and up } else { $clientBuilder = \Elastic\Elasticsearch\ClientBuilder::class; @@ -75,7 +77,11 @@ public function testProcess(): void public function testProcessWithoutConfiguration(): void { - $clientBuilder = class_exists(\Elasticsearch\ClientBuilder::class) ? \Elasticsearch\ClientBuilder::class : \Elastic\Elasticsearch\ClientBuilder::class; + $clientBuilder = class_exists(\Elasticsearch\ClientBuilder::class) + // ES v7 + ? \Elasticsearch\ClientBuilder::class + // ES v8 and up + : \Elastic\Elasticsearch\ClientBuilder::class; $clientDefinitionProphecy = $this->prophesize(Definition::class); $clientDefinitionProphecy->setFactory([$clientBuilder, 'build'])->willReturn($clientDefinitionProphecy->reveal())->shouldBeCalled();