Skip to content

Commit e6d193b

Browse files
thePanznicolas-grekas
authored andcommitted
[Messenger] fixed RabbitMQ arguments not passed as integer values
1 parent 843698f commit e6d193b

File tree

2 files changed

+77
-4
lines changed

2 files changed

+77
-4
lines changed

Tests/Transport/AmqpExt/ConnectionTest.php

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Messenger\Tests\Transport\AmqpExt;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Messenger\Exception\InvalidArgumentException;
1516
use Symfony\Component\Messenger\Transport\AmqpExt\AmqpFactory;
1617
use Symfony\Component\Messenger\Transport\AmqpExt\Connection;
1718

@@ -96,17 +97,30 @@ public function testSetsParametersOnTheQueueAndExchange()
9697

9798
$amqpQueue->expects($this->once())->method('setArguments')->with([
9899
'x-dead-letter-exchange' => 'dead-exchange',
99-
'x-message-ttl' => '1200',
100+
'x-delay' => 100,
101+
'x-expires' => 150,
102+
'x-max-length' => 200,
103+
'x-max-length-bytes' => 300,
104+
'x-max-priority' => 4,
105+
'x-message-ttl' => 100,
100106
]);
101107

102108
$amqpExchange->expects($this->once())->method('setArguments')->with([
103109
'alternate-exchange' => 'alternate',
104110
]);
105111

106-
$connection = Connection::fromDsn('amqp://localhost/%2f/messages?queue[arguments][x-dead-letter-exchange]=dead-exchange', [
112+
$dsn = 'amqp://localhost/%2f/messages?'.
113+
'queue[arguments][x-dead-letter-exchange]=dead-exchange&'.
114+
'queue[arguments][x-message-ttl]=100&'.
115+
'queue[arguments][x-delay]=100&'.
116+
'queue[arguments][x-expires]=150&'
117+
;
118+
$connection = Connection::fromDsn($dsn, [
107119
'queue' => [
108120
'arguments' => [
109-
'x-message-ttl' => '1200',
121+
'x-max-length' => '200',
122+
'x-max-length-bytes' => '300',
123+
'x-max-priority' => '4',
110124
],
111125
],
112126
'exchange' => [
@@ -118,6 +132,36 @@ public function testSetsParametersOnTheQueueAndExchange()
118132
$connection->publish('body');
119133
}
120134

135+
public function invalidQueueArgumentsDataProvider(): iterable
136+
{
137+
$baseDsn = 'amqp://localhost/%2f/messages';
138+
yield [$baseDsn.'?queue[arguments][x-delay]=not-a-number', []];
139+
yield [$baseDsn.'?queue[arguments][x-expires]=not-a-number', []];
140+
yield [$baseDsn.'?queue[arguments][x-max-length]=not-a-number', []];
141+
yield [$baseDsn.'?queue[arguments][x-max-length-bytes]=not-a-number', []];
142+
yield [$baseDsn.'?queue[arguments][x-max-priority]=not-a-number', []];
143+
yield [$baseDsn.'?queue[arguments][x-message-ttl]=not-a-number', []];
144+
145+
// Ensure the exception is thrown when the arguments are passed via the array options
146+
yield [$baseDsn, ['queue' => ['arguments' => ['x-delay' => 'not-a-number']]]];
147+
yield [$baseDsn, ['queue' => ['arguments' => ['x-expires' => 'not-a-number']]]];
148+
yield [$baseDsn, ['queue' => ['arguments' => ['x-max-length' => 'not-a-number']]]];
149+
yield [$baseDsn, ['queue' => ['arguments' => ['x-max-length-bytes' => 'not-a-number']]]];
150+
yield [$baseDsn, ['queue' => ['arguments' => ['x-max-priority' => 'not-a-number']]]];
151+
yield [$baseDsn, ['queue' => ['arguments' => ['x-message-ttl' => 'not-a-number']]]];
152+
}
153+
154+
/**
155+
* @dataProvider invalidQueueArgumentsDataProvider
156+
*/
157+
public function testFromDsnWithInvalidValueOnQueueArguments(string $dsn, array $options)
158+
{
159+
$this->expectException(InvalidArgumentException::class);
160+
$this->expectExceptionMessage('Integer expected for queue argument');
161+
162+
Connection::fromDsn($dsn, $options);
163+
}
164+
121165
public function testItUsesANormalConnectionByDefault()
122166
{
123167
$factory = new TestAmqpFactory(

Transport/AmqpExt/Connection.php

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@
2424
*/
2525
class Connection
2626
{
27+
private const ARGUMENTS_AS_INTEGER = [
28+
'x-delay',
29+
'x-expires',
30+
'x-max-length',
31+
'x-max-length-bytes',
32+
'x-max-priority',
33+
'x-message-ttl',
34+
];
35+
2736
private $connectionCredentials;
2837
private $exchangeConfiguration;
2938
private $queueConfiguration;
@@ -89,12 +98,32 @@ public static function fromDsn(string $dsn, array $options = [], bool $debug = f
8998

9099
$exchangeOptions = $amqpOptions['exchange'];
91100
$queueOptions = $amqpOptions['queue'];
92-
93101
unset($amqpOptions['queue'], $amqpOptions['exchange']);
94102

103+
if (\is_array($queueOptions['arguments'] ?? false)) {
104+
$queueOptions['arguments'] = self::normalizeQueueArguments($queueOptions['arguments']);
105+
}
106+
95107
return new self($amqpOptions, $exchangeOptions, $queueOptions, $debug, $amqpFactory);
96108
}
97109

110+
private static function normalizeQueueArguments(array $arguments): array
111+
{
112+
foreach (self::ARGUMENTS_AS_INTEGER as $key) {
113+
if (!array_key_exists($key, $arguments)) {
114+
continue;
115+
}
116+
117+
if (!\is_numeric($arguments[$key])) {
118+
throw new InvalidArgumentException(sprintf('Integer expected for queue argument "%s", %s given.', $key, \gettype($arguments[$key])));
119+
}
120+
121+
$arguments[$key] = (int) $arguments[$key];
122+
}
123+
124+
return $arguments;
125+
}
126+
98127
/**
99128
* @throws \AMQPException
100129
*/

0 commit comments

Comments
 (0)