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(); $httpClient = $this->getMockBuilder(HttpClientInterface::class)->getMock();
$this->assertEquals( $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) 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 = new Connection(['queue_name' => 'queue', 'account' => 123, 'auto_setup' => false], $client);
$connection->get(); $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 */ /** @var string|null */
private $queueUrl; 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->configuration = array_replace_recursive(self::DEFAULT_OPTIONS, $configuration);
$this->client = $client ?? new SqsClient([]); $this->client = $client ?? new SqsClient([]);
$this->queueUrl = $queueUrl;
} }
public function __destruct() public function __destruct()
@ -140,7 +141,18 @@ class Connection
} }
$configuration['account'] = 2 === \count($parsedPath) ? $parsedPath[0] : $options['account'] ?? self::DEFAULT_OPTIONS['account']; $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 public function get(): ?array