Skip to content

Commit f902089

Browse files
authored
Not using _type to store class type (as _type is already deprecated in ES and will be removed soon) (#33)
* Added feature: optionally use the type field or a payload field to store the class mapping * Updating PR based on comments. - BC is not needed so cleaning up flags. - Adding tests for trying to insert 2 different classes in the same repository. - Adapting the code to the php_cs_fixer requirements * Updating PR based on comments. - BC is not needed so cleaning up flags. - Adding tests for trying to insert 2 different classes in the same repository. - Adapting the code to the php_cs_fixer requirements * Updating PR based on comments. - Renamed test methods to snake case - Removed a couple of variables not needed - Added conf in phpcs to enable snake case * Adding missing case with not needed params variable * Added custom exception and trying to simplify the save method * Adding newline at the end of the file
1 parent 5b1823c commit f902089

6 files changed

+112
-49
lines changed

.php_cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,8 @@ $config->setFinder(
1010
])
1111
);
1212

13+
$config->setRules([
14+
'php_unit_method_casing' => ['case' => 'snake_case']
15+
]);
16+
1317
return $config;

src/ElasticSearchRepository.php

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@
1313

1414
namespace Broadway\ReadModel\ElasticSearch;
1515

16-
use Assert\Assertion;
16+
use Broadway\ReadModel\ElasticSearch\Exception\MultiTypeIndexNotAllowedException;
1717
use Broadway\ReadModel\Identifiable;
1818
use Broadway\ReadModel\Repository;
1919
use Broadway\Serializer\Serializer;
2020
use Elasticsearch\Client;
2121
use Elasticsearch\Common\Exceptions\Missing404Exception;
22+
use stdClass;
2223

2324
/**
2425
* Repository implementation using Elasticsearch as storage.
@@ -35,7 +36,7 @@ class ElasticSearchRepository implements Repository
3536
private $index;
3637

3738
/** @var string */
38-
private $class;
39+
private $class_type;
3940

4041
/** @var string[] */
4142
private $notAnalyzedFields;
@@ -44,34 +45,35 @@ public function __construct(
4445
Client $client,
4546
Serializer $serializer,
4647
string $index,
47-
string $class,
48+
string $class_type,
4849
array $notAnalyzedFields = []
4950
) {
5051
$this->client = $client;
5152
$this->serializer = $serializer;
5253
$this->index = $index;
53-
$this->class = $class;
54+
$this->class_type = $class_type;
5455
$this->notAnalyzedFields = $notAnalyzedFields;
5556
}
5657

5758
/**
58-
* {@inheritdoc}
59+
* @param Identifiable $data
60+
* @throws MultiTypeIndexNotAllowedException
5961
*/
6062
public function save(Identifiable $data): void
6163
{
62-
Assertion::isInstanceOf($data, $this->class);
64+
if (!$data instanceof $this->class_type) {
65+
throw new MultiTypeIndexNotAllowedException(
66+
"Data object should be of type {$this->class_type}, as declared on the repository definition."
67+
);
68+
}
6369

6470
$serializedReadModel = $this->serializer->serialize($data);
65-
66-
$params = [
71+
$this->client->index([
6772
'index' => $this->index,
68-
'type' => $serializedReadModel['class'],
6973
'id' => $data->getId(),
7074
'body' => $serializedReadModel['payload'],
7175
'refresh' => true,
72-
];
73-
74-
$this->client->index($params);
76+
]);
7577
}
7678

7779
/**
@@ -81,7 +83,6 @@ public function find($id): ?Identifiable
8183
{
8284
$params = [
8385
'index' => $this->index,
84-
'type' => $this->class,
8586
'id' => (string) $id,
8687
];
8788

@@ -123,10 +124,10 @@ public function remove($id): void
123124
$this->client->delete([
124125
'id' => (string) $id,
125126
'index' => $this->index,
126-
'type' => $this->class,
127127
'refresh' => true,
128128
]);
129-
} catch (Missing404Exception $e) { // It was already deleted or never existed, fine by us!
129+
} catch (Missing404Exception $e) {
130+
// It was already deleted or never existed, fine by us!
130131
}
131132
}
132133

@@ -150,7 +151,6 @@ protected function search(array $query, array $facets = [], int $size = 500): ar
150151
try {
151152
return $this->client->search([
152153
'index' => $this->index,
153-
'type' => $this->class,
154154
'body' => [
155155
'query' => $query,
156156
'facets' => $facets,
@@ -164,16 +164,13 @@ protected function search(array $query, array $facets = [], int $size = 500): ar
164164

165165
protected function query(array $query): array
166166
{
167-
return $this->searchAndDeserializeHits(
168-
[
169-
'index' => $this->index,
170-
'type' => $this->class,
171-
'body' => [
172-
'query' => $query,
173-
],
174-
'size' => 500,
175-
]
176-
);
167+
return $this->searchAndDeserializeHits([
168+
'index' => $this->index,
169+
'body' => [
170+
'query' => $query,
171+
],
172+
'size' => 500,
173+
]);
177174
}
178175

179176
private function buildFindByQuery(array $fields): array
@@ -188,15 +185,15 @@ private function buildFindByQuery(array $fields): array
188185
private function buildFindAllQuery(): array
189186
{
190187
return [
191-
'match_all' => new \stdClass(),
188+
'match_all' => new stdClass(),
192189
];
193190
}
194191

195192
private function deserializeHit(array $hit): Identifiable
196193
{
197194
return $this->serializer->deserialize(
198195
[
199-
'class' => $hit['_type'],
196+
'class' => $this->class_type,
200197
'payload' => $hit['_source'],
201198
]
202199
);
@@ -225,8 +222,6 @@ private function buildFilter(array $filter): array
225222
*/
226223
public function createIndex(): bool
227224
{
228-
$class = $this->class;
229-
230225
$indexParams = [
231226
'index' => $this->index,
232227
];
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Broadway\ReadModel\ElasticSearch\Exception;
6+
7+
use Exception;
8+
9+
final class MultiTypeIndexNotAllowedException extends Exception
10+
{
11+
12+
}

test/ElasticSearchRepositoryFactoryTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class ElasticSearchRepositoryFactoryTest extends TestCase
2222
/**
2323
* @test
2424
*/
25-
public function it_creates_an_elastic_search_repository()
25+
public function it_creates_an_elastic_search_repository(): void
2626
{
2727
$serializer = $this->getMockBuilder(Serializer::class)
2828
->getMock();
@@ -33,13 +33,13 @@ public function it_creates_an_elastic_search_repository()
3333
$repository = new ElasticSearchRepository($client, $serializer, 'test', 'Class');
3434
$factory = new ElasticSearchRepositoryFactory($client, $serializer);
3535

36-
$this->assertEquals($repository, $factory->create('test', 'Class'));
36+
self::assertEquals($repository, $factory->create('test', 'Class'));
3737
}
3838

3939
/**
4040
* @test
4141
*/
42-
public function it_creates_an_elastic_search_repository_containing_index_metadata()
42+
public function it_creates_an_elastic_search_repository_containing_index_metadata(): void
4343
{
4444
$serializer = $this->getMockBuilder(Serializer::class)
4545
->getMock();
@@ -50,6 +50,6 @@ public function it_creates_an_elastic_search_repository_containing_index_metadat
5050
$repository = new ElasticSearchRepository($client, $serializer, 'test', 'Class', ['id']);
5151
$factory = new ElasticSearchRepositoryFactory($client, $serializer);
5252

53-
$this->assertEquals($repository, $factory->create('test', 'Class', ['id']));
53+
self::assertEquals($repository, $factory->create('test', 'Class', ['id']));
5454
}
5555
}

test/ElasticSearchRepositoryTest.php

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
namespace Broadway\ReadModel\ElasticSearch;
1515

16+
use Broadway\ReadModel\ElasticSearch\Exception\MultiTypeIndexNotAllowedException;
17+
use Broadway\ReadModel\ElasticSearch\Utils\AnotherRepositoryTestReadModel;
1618
use Broadway\ReadModel\Repository;
1719
use Broadway\ReadModel\Testing\RepositoryTestCase;
1820
use Broadway\ReadModel\Testing\RepositoryTestReadModel;
@@ -42,15 +44,19 @@ protected function createRepository(): Repository
4244
);
4345
}
4446

45-
protected function createElasticSearchRepository(Client $client, Serializer $serializer, string $index, string $class)
46-
{
47-
return new ElasticSearchRepository($client, $serializer, $index, $class);
47+
protected function createElasticSearchRepository(
48+
Client $client,
49+
Serializer $serializer,
50+
string $index,
51+
string $class_type
52+
): ElasticSearchRepository {
53+
return new ElasticSearchRepository($client, $serializer, $index, $class_type);
4854
}
4955

5056
/**
5157
* @test
5258
*/
53-
public function it_creates_an_index_with_non_analyzed_terms()
59+
public function it_creates_an_index_with_non_analyzed_terms(): void
5460
{
5561
$type = 'class';
5662
$nonAnalyzedTerm = 'name';
@@ -78,25 +84,28 @@ public function it_creates_an_index_with_non_analyzed_terms()
7884
],
7985
],
8086
];
81-
$this->assertEquals($expectedMapping, $mapping);
87+
self::assertEquals($expectedMapping, $mapping);
8288
}
8389

8490
/**
8591
* @test
8692
*/
87-
public function it_throws_when_saving_a_readmodel_of_other_type_than_configured()
93+
public function it_throws_when_trying_to_save_different_class_types_in_the_same_repository(): void
8894
{
89-
$this->expectException('Assert\InvalidArgumentException');
90-
$readModel = $this->prophesize('\Broadway\ReadModel\Identifiable');
95+
$this->expectException(MultiTypeIndexNotAllowedException::class);
96+
$this->expectExceptionMessage('Data object should be of type');
9197

92-
$this->repository->save($readModel->reveal());
98+
$model1 = $this->createReadModel('1', 'othillo', 'bar');
99+
$this->repository->save($model1);
100+
101+
$model2 = new AnotherRepositoryTestReadModel('2', 'someoneelse');
102+
$this->repository->save($model2);
93103
}
94104

95105
/**
96106
* @test
97-
* {@inheritdoc}
98107
*/
99-
public function it_returns_all_read_models()
108+
public function it_returns_all_read_models(): void
100109
{
101110
$model1 = $this->createReadModel('1', 'othillo', 'bar');
102111
$model2 = $this->createReadModel('2', 'asm89', 'baz');
@@ -107,9 +116,9 @@ public function it_returns_all_read_models()
107116
$this->repository->save($model3);
108117

109118
$allReadModels = $this->repository->findAll();
110-
$this->assertTrue(in_array($model1, $allReadModels));
111-
$this->assertTrue(in_array($model2, $allReadModels));
112-
$this->assertTrue(in_array($model3, $allReadModels));
119+
self::assertContainsEquals($model1, $allReadModels);
120+
self::assertContainsEquals($model2, $allReadModels);
121+
self::assertContainsEquals($model3, $allReadModels);
113122
}
114123

115124
public function tearDown(): void
@@ -121,7 +130,7 @@ public function tearDown(): void
121130
}
122131
}
123132

124-
private function createClient()
133+
private function createClient(): Client
125134
{
126135
return (new ElasticSearchClientFactory())->create(['hosts' => ['localhost:9200']]);
127136
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Broadway\ReadModel\ElasticSearch\Utils;
6+
7+
use Broadway\ReadModel\SerializableReadModel;
8+
9+
class AnotherRepositoryTestReadModel implements SerializableReadModel
10+
{
11+
private $id;
12+
private $name;
13+
14+
/**
15+
* @param mixed $id
16+
* @param mixed $name
17+
*/
18+
public function __construct($id, string $name)
19+
{
20+
$this->id = (string) $id;
21+
$this->name = $name;
22+
}
23+
24+
public function getId(): string
25+
{
26+
return $this->id;
27+
}
28+
29+
public function getName(): string
30+
{
31+
return $this->name;
32+
}
33+
34+
public function serialize(): array
35+
{
36+
return get_object_vars($this);
37+
}
38+
39+
public static function deserialize(array $data): AnotherRepositoryTestReadModel
40+
{
41+
return new self($data['id'], $data['name']);
42+
}
43+
}

0 commit comments

Comments
 (0)