Skip to content

Commit 649da16

Browse files
authored
fix(elasticsearch): verify whether mapping type is supported (#4726)
* fix: verify whether doc type is supported * fix: verify whether doc type is supported * review: remove comment
1 parent 334fa25 commit 649da16

File tree

10 files changed

+113
-20
lines changed

10 files changed

+113
-20
lines changed

src/Core/Bridge/Elasticsearch/DataProvider/CollectionDataProvider.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use ApiPlatform\Elasticsearch\Exception\NonUniqueIdentifierException;
2323
use ApiPlatform\Elasticsearch\Extension\RequestBodySearchCollectionExtensionInterface;
2424
use ApiPlatform\Elasticsearch\Metadata\Document\Factory\DocumentMetadataFactoryInterface;
25+
use ApiPlatform\Elasticsearch\Util\ElasticsearchVersion;
2526
use ApiPlatform\Exception\ResourceClassNotFoundException;
2627
use ApiPlatform\Metadata\Resource\Factory\ResourceMetadataCollectionFactoryInterface;
2728
use ApiPlatform\State\Pagination\Pagination;
@@ -126,11 +127,16 @@ public function getCollection(string $resourceClass, ?string $operationName = nu
126127
$limit = $body['size'] = $body['size'] ?? $this->pagination->getLimit($resourceClass, $operationName, $context);
127128
$offset = $body['from'] = $body['from'] ?? $this->pagination->getOffset($resourceClass, $operationName, $context);
128129

129-
$documents = $this->client->search([
130+
$params = [
130131
'index' => $documentMetadata->getIndex(),
131-
'type' => $documentMetadata->getType(),
132132
'body' => $body,
133-
]);
133+
];
134+
135+
if (ElasticsearchVersion::supportsMappingType()) {
136+
$params['type'] = $documentMetadata->getType();
137+
}
138+
139+
$documents = $this->client->search($params);
134140

135141
return new Paginator(
136142
$this->denormalizer,

src/Core/Bridge/Elasticsearch/DataProvider/ItemDataProvider.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use ApiPlatform\Elasticsearch\Exception\NonUniqueIdentifierException;
2222
use ApiPlatform\Elasticsearch\Metadata\Document\Factory\DocumentMetadataFactoryInterface;
2323
use ApiPlatform\Elasticsearch\Serializer\DocumentNormalizer;
24+
use ApiPlatform\Elasticsearch\Util\ElasticsearchVersion;
2425
use ApiPlatform\Exception\ResourceClassNotFoundException;
2526
use Elasticsearch\Client;
2627
use Elasticsearch\Common\Exceptions\Missing404Exception;
@@ -92,11 +93,16 @@ public function getItem(string $resourceClass, $id, ?string $operationName = nul
9293
$documentMetadata = $this->documentMetadataFactory->create($resourceClass);
9394

9495
try {
95-
$document = $this->client->get([
96+
$params = [
9697
'index' => $documentMetadata->getIndex(),
97-
'type' => $documentMetadata->getType(),
9898
'id' => (string) $id,
99-
]);
99+
];
100+
101+
if (ElasticsearchVersion::supportsMappingType()) {
102+
$params['type'] = $documentMetadata->getType();
103+
}
104+
105+
$document = $this->client->get($params);
100106
} catch (Missing404Exception $e) {
101107
return null;
102108
}

src/Elasticsearch/State/CollectionProvider.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use ApiPlatform\Elasticsearch\Extension\RequestBodySearchCollectionExtensionInterface;
1717
use ApiPlatform\Elasticsearch\Metadata\Document\Factory\DocumentMetadataFactoryInterface;
1818
use ApiPlatform\Elasticsearch\Paginator;
19+
use ApiPlatform\Elasticsearch\Util\ElasticsearchVersion;
1920
use ApiPlatform\Metadata\Operation;
2021
use ApiPlatform\State\Pagination\Pagination;
2122
use ApiPlatform\State\ProviderInterface;
@@ -73,11 +74,16 @@ public function provide(Operation $operation, array $uriVariables = [], array $c
7374
$limit = $body['size'] = $body['size'] ?? $this->pagination->getLimit($resourceClass, $operationName, $context);
7475
$offset = $body['from'] = $body['from'] ?? $this->pagination->getOffset($resourceClass, $operationName, $context);
7576

76-
$documents = $this->client->search([
77+
$params = [
7778
'index' => $documentMetadata->getIndex(),
78-
'type' => $documentMetadata->getType(),
7979
'body' => $body,
80-
]);
80+
];
81+
82+
if (ElasticsearchVersion::supportsMappingType()) {
83+
$params['type'] = $documentMetadata->getType();
84+
}
85+
86+
$documents = $this->client->search($params);
8187

8288
return new Paginator(
8389
$this->denormalizer,

src/Elasticsearch/State/ItemProvider.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
use ApiPlatform\Elasticsearch\Metadata\Document\Factory\DocumentMetadataFactoryInterface;
1717
use ApiPlatform\Elasticsearch\Serializer\DocumentNormalizer;
18+
use ApiPlatform\Elasticsearch\Util\ElasticsearchVersion;
1819
use ApiPlatform\Metadata\Operation;
1920
use ApiPlatform\State\ProviderInterface;
2021
use Elasticsearch\Client;
@@ -52,11 +53,16 @@ public function provide(Operation $operation, array $uriVariables = [], array $c
5253
$documentMetadata = $this->documentMetadataFactory->create($resourceClass);
5354

5455
try {
55-
$document = $this->client->get([
56+
$params = [
5657
'index' => $documentMetadata->getIndex(),
57-
'type' => $documentMetadata->getType(),
5858
'id' => (string) reset($uriVariables),
59-
]);
59+
];
60+
61+
if (ElasticsearchVersion::supportsMappingType()) {
62+
$params['type'] = $documentMetadata->getType();
63+
}
64+
65+
$document = $this->client->get($params);
6066
} catch (Missing404Exception $e) {
6167
return null;
6268
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Elasticsearch\Util;
15+
16+
use Elasticsearch\Client;
17+
18+
class ElasticsearchVersion
19+
{
20+
public const REGEX_PATTERN = '/\d(.*)/';
21+
22+
/**
23+
* Detect whether the current ES version supports passing mapping type as a search parameter.
24+
*
25+
* @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/removal-of-types.html#_schedule_for_removal_of_mapping_types
26+
*/
27+
public static function supportsMappingType(string $version = Client::VERSION): bool
28+
{
29+
$matchResult = preg_match(self::REGEX_PATTERN, $version, $matches);
30+
31+
return \is_int($matchResult) && $matchResult > 0 && (int) $matches[0] < 7;
32+
}
33+
}

tests/Core/Bridge/Elasticsearch/DataProvider/CollectionDataProviderTest.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,6 @@ public function testGetCollection()
150150
->search(
151151
Argument::allOf(
152152
Argument::withEntry('index', 'foo'),
153-
Argument::withEntry('type', DocumentMetadata::DEFAULT_TYPE),
154153
Argument::withEntry('body', Argument::allOf(
155154
Argument::withEntry('size', 2),
156155
Argument::withEntry('from', 0),
@@ -160,7 +159,7 @@ public function testGetCollection()
160159
)),
161160
Argument::size(3)
162161
)),
163-
Argument::size(3)
162+
Argument::size(2)
164163
)
165164
)
166165
->willReturn($documents)

tests/Core/Bridge/Elasticsearch/DataProvider/ItemDataProviderTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ public function testGetItem()
117117
$foo->setBar('erèinissor');
118118

119119
$clientProphecy = $this->prophesize(Client::class);
120-
$clientProphecy->get(['index' => 'foo', 'type' => DocumentMetadata::DEFAULT_TYPE, 'id' => '1'])->willReturn($document)->shouldBeCalled();
120+
$clientProphecy->get(['index' => 'foo', 'id' => '1'])->willReturn($document)->shouldBeCalled();
121121

122122
$denormalizerProphecy = $this->prophesize(DenormalizerInterface::class);
123123
$denormalizerProphecy->denormalize($document, Foo::class, DocumentNormalizer::FORMAT, [AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => true])->willReturn($foo)->shouldBeCalled();
@@ -138,7 +138,7 @@ public function testGetItemWithMissing404Exception()
138138
$identifierExtractorProphecy->getIdentifierFromResourceClass(Foo::class)->willReturn('id')->shouldBeCalled();
139139

140140
$clientProphecy = $this->prophesize(Client::class);
141-
$clientProphecy->get(['index' => 'foo', 'type' => DocumentMetadata::DEFAULT_TYPE, 'id' => '404'])->willThrow(new Missing404Exception())->shouldBeCalled();
141+
$clientProphecy->get(['index' => 'foo', 'id' => '404'])->willThrow(new Missing404Exception())->shouldBeCalled();
142142

143143
$resourceMetadataFactoryProphecy = $this->prophesize(ResourceMetadataFactoryInterface::class);
144144

tests/Elasticsearch/State/CollectionProviderTest.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ public function testGetCollection()
108108
->search(
109109
Argument::allOf(
110110
Argument::withEntry('index', 'foo'),
111-
Argument::withEntry('type', DocumentMetadata::DEFAULT_TYPE),
112111
Argument::withEntry('body', Argument::allOf(
113112
Argument::withEntry('size', 2),
114113
Argument::withEntry('from', 0),
@@ -118,7 +117,7 @@ public function testGetCollection()
118117
)),
119118
Argument::size(3)
120119
)),
121-
Argument::size(3)
120+
Argument::size(2)
122121
)
123122
)
124123
->willReturn($documents)

tests/Elasticsearch/State/ItemProviderTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public function testGetItem()
7373
$foo->setBar('erèinissor');
7474

7575
$clientProphecy = $this->prophesize(Client::class);
76-
$clientProphecy->get(['index' => 'foo', 'type' => DocumentMetadata::DEFAULT_TYPE, 'id' => '1'])->willReturn($document)->shouldBeCalled();
76+
$clientProphecy->get(['index' => 'foo', 'id' => '1'])->willReturn($document)->shouldBeCalled();
7777

7878
$denormalizerProphecy = $this->prophesize(DenormalizerInterface::class);
7979
$denormalizerProphecy->denormalize($document, Foo::class, DocumentNormalizer::FORMAT, [AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => true])->willReturn($foo)->shouldBeCalled();
@@ -89,7 +89,7 @@ public function testGetItemWithMissing404Exception()
8989
$documentMetadataFactoryProphecy->create(Foo::class)->willReturn(new DocumentMetadata('foo'))->shouldBeCalled();
9090

9191
$clientProphecy = $this->prophesize(Client::class);
92-
$clientProphecy->get(['index' => 'foo', 'type' => DocumentMetadata::DEFAULT_TYPE, 'id' => '404'])->willThrow(new Missing404Exception())->shouldBeCalled();
92+
$clientProphecy->get(['index' => 'foo', 'id' => '404'])->willThrow(new Missing404Exception())->shouldBeCalled();
9393

9494
$resourceMetadataCollectionFactoryProphecy = $this->prophesize(ResourceMetadataCollectionFactoryInterface::class);
9595

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace ApiPlatform\Tests\Elasticsearch\Util;
15+
16+
use ApiPlatform\Elasticsearch\Util\ElasticsearchVersion;
17+
use PHPUnit\Framework\TestCase;
18+
19+
class ElasticsearchVersionTest extends TestCase
20+
{
21+
/**
22+
* @dataProvider supportsDocumentTypeProvider
23+
*/
24+
public function testSupportsDocumentType(string $version, bool $expected): void
25+
{
26+
self::assertSame($expected, ElasticsearchVersion::supportsMappingType($version));
27+
}
28+
29+
public function supportsDocumentTypeProvider(): \Generator
30+
{
31+
yield 'ES 5' => ['5.5.0', true];
32+
yield 'ES 5 dev' => ['5.x', true];
33+
yield 'ES 6' => ['6.8.2', true];
34+
yield 'ES 7' => ['7.17.0', false];
35+
yield 'ES 8' => ['8.1.0', false];
36+
yield 'ES 8 dev' => ['8.x', false];
37+
}
38+
}

0 commit comments

Comments
 (0)