feature #38850 [Messenger] Do not call getQueueUrl when the url is known in AmazonSqs transport (jderusse)

This PR was merged into the 5.2-dev branch.

Discussion
----------

[Messenger] Do not call getQueueUrl when the url is known in AmazonSqs transport

| Q             | A
| ------------- | ---
| Branch?       | 5.x
| Bug fix?      | no
| New feature?  | yes
| Deprecations? | no
| Tickets       | Fix #38849
| License       | MIT
| Doc PR        | TODO

When user provides a DSN that looks like a queueUrl, we don't need to call the `getQueueUrl` method. This PR inject the known queueUrl and prevent performing a useless call to the API when sending a message

Commits
-------

f1f44d48e0 Do not call getQueueUrl when the url is known
This commit is contained in:
Fabien Potencier 2020-11-04 08:24:27 +01:00
commit 57e39b41b9
2 changed files with 68 additions and 3 deletions

View File

@ -92,7 +92,7 @@ class ConnectionTest extends TestCase
{
$httpClient = $this->getMockBuilder(HttpClientInterface::class)->getMock();
$this->assertEquals(
new Connection(['queue_name' => 'ab1-MyQueue-A2BCDEF3GHI4', 'account' => '123456789012'], new SqsClient(['region' => 'us-east-2', 'endpoint' => 'https://sqs.us-east-2.amazonaws.com', 'accessKeyId' => null, 'accessKeySecret' => null], null, $httpClient)),
new Connection(['queue_name' => 'ab1-MyQueue-A2BCDEF3GHI4', 'account' => '123456789012'], new SqsClient(['region' => 'us-east-2', 'endpoint' => 'https://sqs.us-east-2.amazonaws.com', 'accessKeyId' => null, 'accessKeySecret' => null], null, $httpClient), 'https://sqs.us-east-2.amazonaws.com/123456789012/ab1-MyQueue-A2BCDEF3GHI4'),
Connection::fromDsn('https://sqs.us-east-2.amazonaws.com/123456789012/ab1-MyQueue-A2BCDEF3GHI4', [], $httpClient)
);
}
@ -259,4 +259,57 @@ class ConnectionTest extends TestCase
$connection = new Connection(['queue_name' => 'queue', 'account' => 123, 'auto_setup' => false], $client);
$connection->get();
}
/**
* @dataProvider provideQueueUrl
*/
public function testInjectQueueUrl(string $dsn, string $queueUrl)
{
$connection = Connection::fromDsn($dsn);
$r = new \ReflectionObject($connection);
$queueProperty = $r->getProperty('queueUrl');
$queueProperty->setAccessible(true);
$this->assertSame($queueUrl, $queueProperty->getValue($connection));
}
public function provideQueueUrl()
{
yield ['https://sqs.us-east-2.amazonaws.com/123456/queue', 'https://sqs.us-east-2.amazonaws.com/123456/queue'];
yield ['https://KEY:SECRET@sqs.us-east-2.amazonaws.com/123456/queue', 'https://sqs.us-east-2.amazonaws.com/123456/queue'];
yield ['https://sqs.us-east-2.amazonaws.com/123456/queue?auto_setup=1', 'https://sqs.us-east-2.amazonaws.com/123456/queue'];
}
/**
* @dataProvider provideNotQueueUrl
*/
public function testNotInjectQueueUrl(string $dsn)
{
$connection = Connection::fromDsn($dsn);
$r = new \ReflectionObject($connection);
$queueProperty = $r->getProperty('queueUrl');
$queueProperty->setAccessible(true);
$this->assertNull($queueProperty->getValue($connection));
}
public function provideNotQueueUrl()
{
yield ['https://sqs.us-east-2.amazonaws.com/queue'];
yield ['https://us-east-2/123456/ab1-MyQueue-A2BCDEF3GHI4'];
yield ['sqs://default/queue'];
}
public function testGetQueueUrlNotCalled()
{
$client = $this->getMockBuilder(SqsClient::class)->getMock();
$connection = new Connection(['queue_name' => 'ab1-MyQueue-A2BCDEF3GHI4', 'account' => '123456789012'], $client, 'https://sqs.us-east-2.amazonaws.com/123456789012/ab1-MyQueue-A2BCDEF3GHI4');
$client->expects($this->never())->method('getQueueUrl');
$client->expects($this->once())->method('deleteMessage');
$connection->delete('id');
}
}

View File

@ -57,10 +57,11 @@ class Connection
/** @var string|null */
private $queueUrl;
public function __construct(array $configuration, SqsClient $client = null)
public function __construct(array $configuration, SqsClient $client = null, string $queueUrl = null)
{
$this->configuration = array_replace_recursive(self::DEFAULT_OPTIONS, $configuration);
$this->client = $client ?? new SqsClient([]);
$this->queueUrl = $queueUrl;
}
public function __destruct()
@ -140,7 +141,18 @@ class Connection
}
$configuration['account'] = 2 === \count($parsedPath) ? $parsedPath[0] : $options['account'] ?? self::DEFAULT_OPTIONS['account'];
return new self($configuration, new SqsClient($clientConfiguration, null, $client));
// When the DNS looks like a QueueUrl, we can directly inject it in the connection
// https://sqs.REGION.amazonaws.com/ACCOUNT/QUEUE
$queueUrl = null;
if (
'https' === $parsedUrl['scheme']
&& ($parsedUrl['host'] ?? 'default') === "sqs.{$clientConfiguration['region']}.amazonaws.com"
&& ($parsedUrl['path'] ?? '/') === "/{$configuration['account']}/{$configuration['queue_name']}"
) {
$queueUrl = 'https://'.$parsedUrl['host'].$parsedUrl['path'];
}
return new self($configuration, new SqsClient($clientConfiguration, null, $client), $queueUrl);
}
public function get(): ?array