8000 feature #42257 [Messenger] Allow using user's serializer for message … · symfony/symfony@d1fd413 · GitHub
[go: up one dir, main page]

Skip to content

Commit d1fd413

Browse files
committed
feature #42257 [Messenger] Allow using user's serializer for message do not fit the expected JSON structure (welcoMattic)
This PR was submitted for the 5.3 branch but it was merged into the 5.4 branch instead. Discussion ---------- [Messenger] Allow using user's serializer for message do not fit the expected JSON structure | Q | A | ------------- | --- | Branch? | 5.3 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #42072 | License | MIT | Doc PR | symfony/symfony-docs#... <!-- required for new features --> It allows user to use their own serializer to decode messages that do not fit the expected JSON structure (`{ "message": { "body": "", "headers": {} } }`). Once this PR will be ok, I'll report the fix in Beanstalkd, SQS, and Doctrine Transports Commits ------- 3d0d8a3 Allow using user's serializer for message do not fit the expected JSON structure
2 parents 6b1d9b8 + 3d0d8a3 commit d1fd413

File tree

12 files changed

+247
-81
lines changed

12 files changed

+247
-81
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace Symfony\Component\Messenger\Bridge\Redis\Tests\Fixtures;
4+
5+
class ExternalMessage
6+
{
7+
private $foo;
8+
private $bar = [];
9+
10+
public function __construct(string $foo)
11+
{
12+
$this->foo = $foo;
13+
}
14+
15+
public function getFoo(): string
16+
{
17+
return $this->foo;
18+
}
19+
20+
public function setBar(array $bar): self
21+
{
22+
$this->bar = $bar;
23+
24+
return $this;
25+
}
26+
27+
public function getBar(): array
28+
{
29+
return $this->bar;
30+
}
31+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace Symfony\Component\Messenger\Bridge\Redis\Tests\Fixtures;
4+
5+
use Symfony\Component\Messenger\Envelope;
6+
use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface;
7+
8+
class ExternalMessageSerializer implements SerializerInterface
9+
{
10+
public function decode(array $encodedEnvelope): Envelope
11+
{
12+
$message = new ExternalMessage($encodedEnvelope['foo']);
13+
$message->setBar($encodedEnvelope['bar']);
14+
15+
return new Envelope($message);
16+
}
17+
18+
public function encode(Envelope $envelope): array
19+
{
20+
return [
21+
'body' => $envelope->getMessage(),
22+
'headers' => [],
23+
];
24+
}
25+
}

src/Symfony/Component/Messenger/Bridge/Redis/Tests/Transport/ConnectionTest.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,17 @@ public function testGetPendingMessageFirst()
251251
->willReturn(['queue' => [['message' => '{"body":"1","headers":[]}']]]);
252252

253253
$connection = Connection::fromDsn('redis://localhost/queue', ['delete_after_ack' => true], $redis);
254-
$connection->get();
254+
$message = $connection->get();
255+
256+
$this->assertSame([
257+
'id' => 0,
258+
'data' => [
259+
'message' => json_encode([
260+
'body' => '1',
261+
'headers' => [],
262+
]),
263+
],
264+
], $message);
255265
}
256266

257267
public function testClaimAbandonedMessageWithRaceCondition()

src/Symfony/Component/Messenger/Bridge/Redis/Tests/Transport/RedisExtIntegrationTest.php

Lines changed: 88 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -45,21 +45,33 @@ protected function setUp(): void
4545
public function testConnectionSendAndGet()
4646
{
4747
$this->connection->add('{"message": "Hi"}', ['type' => DummyMessage::class]);
48-
$encoded = $this->connection->get();
49-
$this->assertEquals('{"message": "Hi"}', $encoded['body']);
50-
$this->assertEquals(['type' => DummyMessage::class], $encoded['headers']);
48+
$message = $this->connection->get();
49+
$this->assertEquals([
50+
'message' => json_encode([
51+
'body' => '{"message": "Hi"}',
52+
'headers' => ['type' => DummyMessage::class],
53+
]),
54+
], $message['data']);
5155
}
5256

5357
public function testGetTheFirstAvailableMessage()
5458
{
5559
$this->connection->add('{"message": "Hi1"}', ['type' => DummyMessage::class]);
5660
$this->connection->add('{"message": "Hi2"}', ['type' => DummyMessage::class]);
57-
$encoded = $this->connection->get();
58-
$this->assertEquals('{"message": "Hi1"}', $encoded['body']);
59-
$this->assertEquals(['type' => DummyMessage::class], $encoded['headers']);
60-
$encoded = $this->connection->get();
61-
$this->assertEquals('{"message": "Hi2"}', $encoded['body']);
62-
$this->assertEquals(['type' => DummyMessage::class], $encoded['headers']);
61+
$message = $this->connection->get();
62+
$this->assertEquals([
63+
'message' => json_encode([
64+
'body' => '{"message": "Hi1"}',
65+
'headers' => ['type' => DummyMessage::class],
66+
]),
67+
], $message['data']);
68+
$message = $this->connection->get();
69+
$this->assertEquals([
70+
'message' => json_encode([
71+
'body' => '{"message": "Hi2"}',
72+
'headers' => ['type' => DummyMessage::class],
73+
]),
74+
], $message['data']);
6375
}
6476

6577
public function testConnectionSendWithSameContent()
@@ -70,24 +82,36 @@ public function testConnectionSendWithSameContent()
7082
$this->connection->add($body, $headers);
7183
$this->connection->add($body, $headers);
7284

73-
$encoded = $this->connection->get();
74-
$this->assertEquals($body, $encoded['body']);
75-
$this->assertEquals($headers, $encoded['headers']);
76-
77-
$encoded = $this->connection->get();
78-
$this->assertEquals($body, $encoded['body']);
79-
$this->assertEquals($headers, $encoded['headers']);
85+
$message = $this->connection->get();
86+
$this->assertEquals([
87+
'message' => json_encode([
88+
'body' => $body,
89+
'headers' => $headers,
90+
]),
91+
], $message['data']);
92+
93+
$message = $this->connection->get();
94+
$this->assertEquals([
95+
'message' => json_encode([
96+
'body' => $body,
97+
'headers' => $headers,
98+
]),
99+
], $message['data']);
80100
}
81101

82102
public function testConnectionSendAndGetDelayed()
83103
{
84104
$this->connection->add('{"message": "Hi"}', ['type' => DummyMessage::class], 500);
85-
$encoded = $this->connection->get();
86-
$this->assertNull($encoded);
105+
$message = $this->connection->get();
106+
$this->assertNull($message);
87107
sleep(2);
88-
$encoded = $this->connection->get();
89-
$this->assertEquals('{"message": "Hi"}', $encoded['body']);
90-
$this->assertEquals(['type' => DummyMessage::class], $encoded['headers']);
108+
$message = $this->connection->get();
109+
$this->assertEquals([
110+
'message' => json_encode([
111+
'body' => '{"message": "Hi"}',
112+
'headers' => ['type' => DummyMessage::class],
113+
]),
114+
], $message['data']);
91115
}
92116

93117
public function testConnectionSendDelayedMessagesWithSameContent()
@@ -98,13 +122,21 @@ public function testConnectionSendDelayedMessagesWithSameContent()
98122
$this->connection->add($body, $headers, 500);
99123
$this->connection->add($body, $headers, 500);
100124
sleep(2);
101-
$encoded = $this->connection->get();
102-
$this->assertEquals($body, $encoded['body']);
103-
$this->assertEquals($headers, $encoded['headers']);
104-
105-
$encoded = $this->connection->get();
106-
$this->assertEquals($body, $encoded['body']);
107-
$this->assertEquals($headers, $encoded['headers']);
125+
$message = $this->connection->get();
126+
$this->assertEquals([
127+
'message' => json_encode([
128+
'body' => $body,
129+
'headers' => $headers,
130+
]),
131+
], $message['data']);
132+
133+
$message = $this->connection->get();
134+
$this->assertEquals([
135+
'message' => json_encode([
136+
'body' => $body,
137+
'headers' => $headers,
138+
]),
139+
], $message['data']);
108140
}
109141

110142
public function testConnectionBelowRedeliverTimeout()
@@ -162,16 +194,24 @@ public function testConnectionClaimAndRedeliver()
162194
);
163195

164196
// Queue will return the pending message first because redeliver_timeout = 0
165-
$encoded = $connection->get();
166-
$this->assertEquals($body1, $encoded['body']);
167-
$this->assertEquals($headers, $encoded['headers']);
168-
$connection->ack($encoded['id']);
197+
$message = $connection->get();
198+
$this->assertEquals([
199+
'message' => json_encode([
200+
'body' => $body1,
201+
'headers' => $headers,
202+
]),
203+
], $message['data']);
204+
$connection->ack($message['id']);
169205

170206
// Queue will return the second message
171-
$encoded = $connection->get();
172-
$this->assertEquals($body2, $encoded['body']);
173-
$this->assertEquals($headers, $encoded['headers']);
174-
$connection->ack($encoded['id']);
207+
$message = $connection->get();
208+
$this->assertEquals([
209+
'message' => json_encode([
210+
'body' => $body2,
211+
'headers' => $headers,
212+
]),
213+
], $message['data']);
214+
$connection->ack($message['id']);
175215
}
176216

177217
public function testLazyCluster()
@@ -186,7 +226,12 @@ public function testLazyCluster()
186226

187227
$connection->add('1', []);
188228
$this->assertNotEmpty($message = $connection->get());
189-
$this->assertSame('1', $message['body']);
229+
$this->assertSame([
230+
'message' => json_encode([
231+
'body' => '1',
232+
'headers' => [],
233+
]),
234+
], $message['data']);
190235
$connection->reject($message['id']);
191236
$connection->cleanup();
192237
}
@@ -198,7 +243,12 @@ public function testLazy()
198243

199244
$connection->add('1', []);
200245
$this->assertNotEmpty($message = $connection->get());
201-
$this->assertSame('1', $message['body']);
246+
$this->assertSame([
247+
'message' => json_encode([
248+
'body' => '1',
249+
'headers' => [],
250+
]),
251+
], $message['data']);
202252
$connection->reject($message['id']);
203253
$redis->del('messenger-lazy');
204254
}

src/Symfony/Component/Messenger/Bridge/Redis/Tests/Transport/RedisReceiverTest.php

Lines changed: 65 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,64 +13,109 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Messenger\Bridge\Redis\Tests\Fixtures\DummyMessage;
16+
use Symfony\Component\Messenger\Bridge\Redis\Tests\Fixtures\ExternalMessage;
17+
use Symfony\Component\Messenger\Bridge\Redis\Tests\Fixtures\ExternalMessageSerializer;
1618
use Symfony\Component\Messenger\Bridge\Redis\Transport\Connection;
1719
use Symfony\Component\Messenger\Bridge\Redis\Transport\RedisReceiver;
1820
use Symfony\Component\Messenger\Exception\MessageDecodingFailedException;
1921
use Symfony\Component\Messenger\Transport\Serialization\PhpSerializer;
2022
use Symfony\Component\Messenger\Transport\Serialization\Serializer;
23+
use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface;
2124
use Symfony\Component\Serializer as SerializerComponent;
2225
use Symfony\Component\Serializer\Encoder\JsonEncoder;
2326
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
2427

2528
class RedisReceiverTest extends TestCase
2629
{
27-
public function testItReturnsTheDecodedMessageToTheHandler()
30+
/**
31+
* @dataProvider redisEnvelopeProvider
32+
*/
33+
public function testItReturnsTheDecodedMessageToTheHandler(array $redisEnvelope, $expectedMessage, SerializerInterface $serializer)
2834
{
29-
$serializer = $this->createSerializer();
30-
31-
$redisEnvelop = $this->createRedisEnvelope();
3235
$connection = $this->createMock(Connection::class);
33-
$connection->method('get')->willReturn($redisEnvelop);
36+
$connection->method('get')->willReturn($redisEnvelope);
3437

3538
$receiver = new RedisReceiver($connection, $serializer);
3639
$actualEnvelopes = $receiver->get();
3740
$this->assertCount(1, $actualEnvelopes);
38-
$this->assertEquals(new DummyMessage('Hi'), $actualEnvelopes[0]->getMessage());
41+
$this->assertEquals($expectedMessage, $actualEnvelopes[0]->getMessage());
3942
}
4043

41-
public function testItRejectTheMessageIfThereIsAMessageDecodingFailedException()
44+
/**
45+
* @dataProvider rejectedRedisEnvelopeProvider
46+
*/
47+
public function testItRejectTheMessageIfThereIsAMessageDecodingFailedException(array $redisEnvelope)
4248
{
4349
$this->expectException(MessageDecodingFailedException::class);
4450

4551
$serializer = $this->createMock(PhpSerializer::class);
4652
$serializer->method('decode')->willThrowException(new MessageDecodingFailedException());
4753

48-
$redisEnvelop = $this->createRedisEnvelope();
4954
$connection = $this->createMock(Connection::class);
50-
$connection->method('get')->willReturn($redisEnvelop);
55+
$connection->method('get')->willReturn($redisEnvelope);
5156
$connection->expects($this->once())->method('reject');
5257

5358
$receiver = new RedisReceiver($connection, $serializer);
5459
$receiver->get();
5560
}
5661

57-
private function createRedisEnvelope(): array
62+
public function redisEnvelopeProvider(): \Generator
5863
{
59-
return [
60-
'id' => 1,
61-
'body' => '{"message": "Hi"}',
62-
'headers' => [
63-
'type' => DummyMessage::class,
64+
yield [
65+
[
66+
'id' => 1,
67+
'data' => json_encode([
68+
'body' => '{"message": "Hi"}',
69+
'headers' => [
70+
'type' => DummyMessage::class,
71+
],
72+
]),
73+
],
74+
new DummyMessage('Hi'),
75+
new Serializer(
76+
new SerializerComponent\Serializer([new ObjectNormalizer()], ['json' => new JsonEncoder()])
77+
),
78+
];
79+
80+
yield [
81+
[
82+
'id' => 2,
83+
'data' => json_encode([
84+
'foo' => 'fooValue',
85+
'bar' => [
86+
'baz' => 'bazValue',
87+
],
88+
]),
6489
],
90+
(new ExternalMessage('fooValue'))->setBar(['baz' => 'bazValue']),
91+
new ExternalMessageSerializer(),
6592
];
6693
}
6794

68-
private function createSerializer(): Serializer
95+
public function rejectedRedisEnvelopeProvider(): \Generator
6996
{
70-
$serializer = new Serializer(
71-
new SerializerComponent\Serializer([new ObjectNormalizer()], ['json' => new JsonEncoder()])
72-
);
97+
yield [
98+
[
99+
'id' => 1,
100+
'data' => json_encode([
101+
'body' => '{"message": "Hi"}',
102+
'headers' => [
103+
'type' => DummyMessage::class,
104+
],
105+
]),
106+
],
107+
];
73108

74-
return $serializer;
109+
yield [
110+
[
111+
'id' => 2,
112+
'data' => json_encode([
113+
'foo' => 'fooValue',
114+
'bar' => [
115+
'baz' => 'bazValue',
116+
],
117+
]),
118+
],
119+
];
75120
}
76121
}

0 commit comments

Comments
 (0)
0