Skip to content

Commit 771d940

Browse files
darthf1Frank Verschuren
and
Frank Verschuren
authored
feat(elasticsearch): re-introduce v7 support (api-platform#6827)
* feat(elasticsearch): re-introduce v7 support * feat(elasticsearch): re-introduce v7 support * feat(elasticsearch): re-introduce v7 support * feat(elasticsearch): re-introduce v7 support * fix: use global namespace * style: apply cs * fix: ignore es7/8 related phpstan issues --------- Co-authored-by: Frank Verschuren <[email protected]> Co-authored-by: darthf1 <[email protected]>
1 parent e6130cb commit 771d940

File tree

10 files changed

+110
-20
lines changed

10 files changed

+110
-20
lines changed

.github/workflows/ci.yml

+53
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,59 @@ jobs:
773773
- name: Run Behat tests
774774
run: vendor/bin/behat --out=std --format=progress --profile=elasticsearch --no-interaction
775775

776+
elasticsearch-v7:
777+
name: Behat (PHP ${{ matrix.php }}) (Elasticsearch v7)
778+
runs-on: ubuntu-latest
779+
timeout-minutes: 20
780+
strategy:
781+
matrix:
782+
php:
783+
- '8.3'
784+
fail-fast: false
785+
env:
786+
APP_ENV: elasticsearch
787+
steps:
788+
- name: Checkout
789+
uses: actions/checkout@v4
790+
- name: Configure sysctl limits
791+
run: |
792+
sudo swapoff -a
793+
sudo sysctl -w vm.swappiness=1
794+
sudo sysctl -w fs.file-max=262144
795+
sudo sysctl -w vm.max_map_count=262144
796+
- name: Runs Elasticsearch
797+
uses: elastic/elastic-github-actions/elasticsearch@master
798+
with:
799+
stack-version: '7.17.0'
800+
security-enabled: false
801+
- name: Setup PHP
802+
uses: shivammathur/setup-php@v2
803+
with:
804+
php-version: ${{ matrix.php }}
805+
tools: pecl, composer
806+
extensions: intl, bcmath, curl, openssl, mbstring, mongodb
807+
coverage: none
808+
ini-values: memory_limit=-1
809+
- name: Get composer cache directory
810+
id: composercache
811+
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
812+
- name: Cache dependencies
813+
uses: actions/cache@v4
814+
with:
815+
path: ${{ steps.composercache.outputs.dir }}
816+
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}
817+
restore-keys: ${{ runner.os }}-composer-
818+
- name: Update project dependencies
819+
run: |
820+
composer global require soyuka/pmu
821+
composer global config allow-plugins.soyuka/pmu true --no-interaction
822+
composer global link .
823+
composer update elasticsearch/elasticsearch --prefer-lowest
824+
- name: Clear test app cache
825+
run: tests/Fixtures/app/console cache:clear --ansi
826+
- name: Run Behat tests
827+
run: vendor/bin/behat --out=std --format=progress --profile=elasticsearch --no-interaction
828+
776829
phpunit-no-deprecations:
777830
name: PHPUnit (PHP ${{ matrix.php }}) (no deprecations)
778831
runs-on: ubuntu-latest

composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@
127127
"doctrine/mongodb-odm": "^2.10",
128128
"doctrine/mongodb-odm-bundle": "^4.0 || ^5.0",
129129
"doctrine/orm": "^2.17 || ^3.0",
130-
"elasticsearch/elasticsearch": "^8.4",
130+
"elasticsearch/elasticsearch": "^7.17 || ^8.4",
131131
"friends-of-behat/mink-browserkit-driver": "^1.3.1",
132132
"friends-of-behat/mink-extension": "^2.2",
133133
"friends-of-behat/symfony-extension": "^2.1",

src/Elasticsearch/State/CollectionProvider.php

+13-4
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
use Elastic\Elasticsearch\Client;
2525
use Elastic\Elasticsearch\Exception\ClientResponseException;
2626
use Elastic\Elasticsearch\Response\Elasticsearch;
27+
use Elasticsearch\Client as V7Client;
28+
use Elasticsearch\Common\Exceptions\Missing404Exception as V7Missing404Exception;
2729
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
2830

2931
/**
@@ -37,8 +39,13 @@ final class CollectionProvider implements ProviderInterface
3739
/**
3840
* @param RequestBodySearchCollectionExtensionInterface[] $collectionExtensions
3941
*/
40-
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())
41-
{
42+
public function __construct(
43+
private readonly V7Client|Client $client, // @phpstan-ignore-line
44+
private readonly ?DenormalizerInterface $denormalizer = null,
45+
private readonly ?Pagination $pagination = null,
46+
private readonly iterable $collectionExtensions = [],
47+
private readonly ?InflectorInterface $inflector = new Inflector(),
48+
) {
4249
}
4350

4451
/**
@@ -68,13 +75,15 @@ public function provide(Operation $operation, array $uriVariables = [], array $c
6875
];
6976

7077
try {
71-
$documents = $this->client->search($params);
78+
$documents = $this->client->search($params); // @phpstan-ignore-line
79+
} catch (V7Missing404Exception $e) { // @phpstan-ignore-line
80+
throw new Error(status: $e->getCode(), detail: $e->getMessage(), title: $e->getMessage(), originalTrace: $e->getTrace()); // @phpstan-ignore-line
7281
} catch (ClientResponseException $e) {
7382
$response = $e->getResponse();
7483
throw new Error(status: $response->getStatusCode(), detail: (string) $response->getBody(), title: $response->getReasonPhrase(), originalTrace: $e->getTrace());
7584
}
7685

77-
if ($documents instanceof Elasticsearch) {
86+
if (class_exists(Elasticsearch::class) && $documents instanceof Elasticsearch) {
7887
$documents = $documents->asArray();
7988
}
8089

src/Elasticsearch/State/ItemProvider.php

+11-4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
use Elastic\Elasticsearch\Client;
2424
use Elastic\Elasticsearch\Exception\ClientResponseException;
2525
use Elastic\Elasticsearch\Response\Elasticsearch;
26+
use Elasticsearch\Client as V7Client;
27+
use Elasticsearch\Common\Exceptions\Missing404Exception as V7Missing404Exception;
2628
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
2729
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
2830

@@ -34,8 +36,11 @@
3436
*/
3537
final class ItemProvider implements ProviderInterface
3638
{
37-
public function __construct(private readonly Client $client, private readonly ?DenormalizerInterface $denormalizer = null, private readonly ?InflectorInterface $inflector = new Inflector())
38-
{
39+
public function __construct(
40+
private readonly V7Client|Client $client, // @phpstan-ignore-line
41+
private readonly ?DenormalizerInterface $denormalizer = null,
42+
private readonly ?InflectorInterface $inflector = new Inflector(),
43+
) {
3944
}
4045

4146
/**
@@ -55,7 +60,9 @@ public function provide(Operation $operation, array $uriVariables = [], array $c
5560
];
5661

5762
try {
58-
$document = $this->client->get($params);
63+
$document = $this->client->get($params); // @phpstan-ignore-line
64+
} catch (V7Missing404Exception) { // @phpstan-ignore-line
65+
return null;
5966
} catch (ClientResponseException $e) {
6067
$response = $e->getResponse();
6168
if (404 === $response->getStatusCode()) {
@@ -65,7 +72,7 @@ public function provide(Operation $operation, array $uriVariables = [], array $c
6572
throw new Error(status: $response->getStatusCode(), detail: (string) $response->getBody(), title: $response->getReasonPhrase(), originalTrace: $e->getTrace());
6673
}
6774

68-
if ($document instanceof Elasticsearch) {
75+
if (class_exists(Elasticsearch::class) && $document instanceof Elasticsearch) {
6976
$document = $document->asArray();
7077
}
7178

src/Elasticsearch/composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"api-platform/metadata": "^3.4 || ^4.0",
2828
"api-platform/serializer": "^3.4 || ^4.0",
2929
"api-platform/state": "^3.4 || ^4.0",
30-
"elasticsearch/elasticsearch": "^8.4",
30+
"elasticsearch/elasticsearch": "^7.17 || ^8.4",
3131
"symfony/cache": "^6.4 || ^7.0",
3232
"symfony/console": "^6.4 || ^7.0",
3333
"symfony/property-access": "^6.4 || ^7.0",

src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php

+5-1
Original file line numberDiff line numberDiff line change
@@ -812,7 +812,11 @@ private function registerElasticsearchConfiguration(ContainerBuilder $container,
812812
return;
813813
}
814814

815-
$clientClass = class_exists(\Elasticsearch\Client::class) ? \Elasticsearch\Client::class : \Elastic\Elasticsearch\Client::class;
815+
$clientClass = !class_exists(\Elasticsearch\Client::class)
816+
// ES v7
817+
? \Elastic\Elasticsearch\Client::class
818+
// ES v8 and up
819+
: \Elasticsearch\Client::class;
816820

817821
$clientDefinition = new Definition($clientClass);
818822
$container->setDefinition('api_platform.elasticsearch.client', $clientDefinition);

src/Symfony/Bundle/DependencyInjection/Compiler/ElasticsearchClientPass.php

+2
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,10 @@ public function process(ContainerBuilder $container): void
4040
}
4141

4242
if (class_exists(\Elasticsearch\ClientBuilder::class)) {
43+
// ES v7
4344
$builderName = \Elasticsearch\ClientBuilder::class;
4445
} else {
46+
// ES v8 and up
4547
$builderName = \Elastic\Elasticsearch\ClientBuilder::class;
4648
}
4749

src/Symfony/Bundle/DependencyInjection/Configuration.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,12 @@ private function addElasticsearchSection(ArrayNodeDefinition $rootNode): void
470470
->validate()
471471
->ifTrue()
472472
->then(static function (bool $v): bool {
473-
if (!(class_exists(\Elasticsearch\Client::class) || class_exists(\Elastic\Elasticsearch\Client::class))) {
473+
if (
474+
// ES v7
475+
!class_exists(\Elasticsearch\Client::class)
476+
// ES v8 and up
477+
&& !class_exists(\Elastic\Elasticsearch\Client::class)
478+
) {
474479
throw new InvalidConfigurationException('The elasticsearch/elasticsearch package is required for Elasticsearch support.');
475480
}
476481

tests/Behat/ElasticsearchContext.php

+11-7
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
use Behat\Behat\Context\Context;
1717
use Elastic\Elasticsearch\Client;
18+
use Elasticsearch\Client as V7Client;
1819
use Symfony\Component\Finder\Finder;
1920

2021
/**
@@ -24,8 +25,11 @@
2425
*/
2526
final class ElasticsearchContext implements Context
2627
{
27-
public function __construct(private readonly Client $client, private readonly string $elasticsearchMappingsPath, private readonly string $elasticsearchFixturesPath)
28-
{
28+
public function __construct(
29+
private readonly V7Client|Client $client, // @phpstan-ignore-line
30+
private readonly string $elasticsearchMappingsPath,
31+
private readonly string $elasticsearchFixturesPath,
32+
) {
2933
}
3034

3135
/**
@@ -76,7 +80,7 @@ private function createIndexesAndMappings(): void
7680
$finder->files()->in($this->elasticsearchMappingsPath);
7781

7882
foreach ($finder as $file) {
79-
$this->client->indices()->create([
83+
$this->client->indices()->create([ // @phpstan-ignore-line
8084
'index' => $file->getBasename('.json'),
8185
'body' => json_decode($file->getContents(), true, 512, \JSON_THROW_ON_ERROR),
8286
]);
@@ -95,7 +99,7 @@ private function deleteIndexes(): void
9599
}
96100

97101
if ([] !== $indexes) {
98-
$this->client->indices()->delete([
102+
$this->client->indices()->delete([ // @phpstan-ignore-line
99103
'index' => implode(',', $indexes),
100104
'ignore_unavailable' => true,
101105
]);
@@ -107,7 +111,7 @@ private function loadFixtures(): void
107111
$finder = new Finder();
108112
$finder->files()->in($this->elasticsearchFixturesPath)->name('*.json');
109113

110-
$indexClient = $this->client->indices();
114+
$indexClient = $this->client->indices(); // @phpstan-ignore-line
111115

112116
foreach ($finder as $file) {
113117
$index = $file->getBasename('.json');
@@ -123,13 +127,13 @@ private function loadFixtures(): void
123127
$bulk[] = $document;
124128

125129
if (0 === (\count($bulk) % 50)) {
126-
$this->client->bulk(['body' => $bulk]);
130+
$this->client->bulk(['body' => $bulk]); // @phpstan-ignore-line
127131
$bulk = [];
128132
}
129133
}
130134

131135
if ($bulk) {
132-
$this->client->bulk(['body' => $bulk]);
136+
$this->client->bulk(['body' => $bulk]); // @phpstan-ignore-line
133137
}
134138

135139
$indexClient->refresh(['index' => $index]);

tests/Symfony/Bundle/DependencyInjection/Compiler/ElasticsearchClientPassTest.php

+7-1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public function testConstruct(): void
3636

3737
public function testProcess(): void
3838
{
39+
// ES v7
3940
if (class_exists(\Elasticsearch\ClientBuilder::class)) {
4041
$clientBuilder = \Elasticsearch\ClientBuilder::class;
4142

@@ -45,6 +46,7 @@ public function testProcess(): void
4546
Argument::withEntry('tracer', Argument::type(Reference::class)),
4647
Argument::size(3),
4748
];
49+
// ES v8 and up
4850
} else {
4951
$clientBuilder = \Elastic\Elasticsearch\ClientBuilder::class;
5052

@@ -75,7 +77,11 @@ public function testProcess(): void
7577

7678
public function testProcessWithoutConfiguration(): void
7779
{
78-
$clientBuilder = class_exists(\Elasticsearch\ClientBuilder::class) ? \Elasticsearch\ClientBuilder::class : \Elastic\Elasticsearch\ClientBuilder::class;
80+
$clientBuilder = class_exists(\Elasticsearch\ClientBuilder::class)
81+
// ES v7
82+
? \Elasticsearch\ClientBuilder::class
83+
// ES v8 and up
84+
: \Elastic\Elasticsearch\ClientBuilder::class;
7985

8086
$clientDefinitionProphecy = $this->prophesize(Definition::class);
8187
$clientDefinitionProphecy->setFactory([$clientBuilder, 'build'])->willReturn($clientDefinitionProphecy->reveal())->shouldBeCalled();

0 commit comments

Comments
 (0)