Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update deps and fix deprecation from AMQP lib #147

Merged
merged 1 commit into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com), and this project adheres to [Semantic Versioning](https://semver.org).

## [Unreleased]
### Added
* *Nothing*

### Changed
* Update dependencies

### Deprecated
* *Nothing*

### Removed
* *Nothing*

### Fixed
* *Nothing*


## [6.1.0] - 2024-04-14
### Added
* Allow current request ID to be set and read in `RequestIdMiddleware`.
Expand Down
44 changes: 22 additions & 22 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,43 +14,43 @@
"require": {
"php": "^8.2",
"ext-fileinfo": "*",
"akrabat/ip-address-middleware": "^2.1",
"cakephp/chronos": "^3.0.2",
"doctrine/orm": "^3.0",
"endroid/qr-code": "^5.0 || ^4.8",
"akrabat/ip-address-middleware": "^2.3",
"cakephp/chronos": "^3.1",
"doctrine/orm": "^3.2",
"endroid/qr-code": "^5.0",
"fig/http-message-util": "^1.1",
"guzzlehttp/guzzle": "^7.8",
"guzzlehttp/guzzle": "^7.9",
"laminas/laminas-config": "^3.9",
"laminas/laminas-diactoros": "^3.3",
"laminas/laminas-inputfilter": "^2.29",
"laminas/laminas-inputfilter": "^2.30",
"laminas/laminas-servicemanager": "^3.22",
"lcobucci/jwt": "^5.2",
"monolog/monolog": "^3.5",
"php-amqplib/php-amqplib": "^3.6",
"lcobucci/jwt": "^5.3",
"monolog/monolog": "^3.7",
"php-amqplib/php-amqplib": "^3.7",
"predis/predis": "^2.2",
"psr/http-server-middleware": "^1.0",
"ramsey/uuid": "^4.7",
"shlinkio/shlink-config": "^3.0 || ^2.5",
"shlinkio/shlink-config": "^3.1",
"shlinkio/shlink-json": "^1.1",
"symfony/cache": "^7.0 || ^6.4",
"symfony/lock": "^7.0 || ^6.4",
"symfony/cache": "^7.1",
"symfony/lock": "^7.1",
"symfony/mercure": "^0.6",
"symfony/string": "^7.0 || ^6.4",
"symfony/translation-contracts": "^3.4 || ^2.5",
"symfony/var-exporter": "^7.0 || ^6.4"
"symfony/string": "^7.1",
"symfony/translation-contracts": "^3.5",
"symfony/var-exporter": "^7.1"
},
"require-dev": {
"devster/ubench": "^2.1",
"laminas/laminas-stratigility": "^3.11",
"mezzio/mezzio-problem-details": "^1.12",
"laminas/laminas-stratigility": "^3.12",
"mezzio/mezzio-problem-details": "^1.14",
"pagerfanta/core": "^3.8",
"phpstan/phpstan": "^1.10",
"phpstan/phpstan-phpunit": "^1.3",
"phpunit/phpunit": "^11.0",
"psr/simple-cache": "^3.0 || ^2.0",
"phpstan/phpstan": "^1.11",
"phpstan/phpstan-phpunit": "^1.4",
"phpunit/phpunit": "^11.2",
"psr/simple-cache": "^3.0",
"roave/security-advisories": "dev-master",
"shlinkio/php-coding-standard": "~2.3.0",
"symfony/var-dumper": "^7.0 || ^6.4"
"symfony/var-dumper": "^7.1"
},
"suggest": {
"mezzio/mezzio-problem-details": "To log ProblemDetailsMiddleware errors using the ErrorLogger",
Expand Down
2 changes: 2 additions & 0 deletions config/rabbit.config.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Laminas\ServiceManager\AbstractFactory\ConfigAbstractFactory;
use Laminas\ServiceManager\Proxy\LazyServiceFactory;
use PhpAmqpLib\Connection\AMQPConnectionConfig;
use PhpAmqpLib\Connection\AMQPStreamConnection;

return [
Expand All @@ -17,6 +18,7 @@
'dependencies' => [
'factories' => [
AMQPStreamConnection::class => RabbitMq\AMQPConnectionFactory::class,
AMQPConnectionConfig::class => RabbitMq\AMQPConfigFactory::class,
RabbitMq\RabbitMqPublishingHelper::class => ConfigAbstractFactory::class,
],
'delegators' => [
Expand Down
2 changes: 0 additions & 2 deletions docker-compose.override.yml.dist
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
version: '3'

services:
shlink_common_php:
user: 1000:1000
Expand Down
2 changes: 0 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
version: '3'

services:
shlink_common_php:
container_name: shlink_common_php
Expand Down
5 changes: 3 additions & 2 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@ includes:
- vendor/phpstan/phpstan-phpunit/extension.neon
- vendor/phpstan/phpstan-phpunit/rules.neon
parameters:
checkMissingIterableValueType: false
checkGenericClassInNonGenericObjectType: false
ignoreErrors:
- identifier: missingType.iterableValue
- identifier: missingType.generics
2 changes: 2 additions & 0 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
bootstrap="./vendor/autoload.php"
colors="true"
cacheDirectory="build/.phpunit.cache"
displayDetailsOnTestsThatTriggerWarnings="true"
displayDetailsOnTestsThatTriggerDeprecations="true"
>
<testsuites>
<testsuite name="Common">
Expand Down
29 changes: 29 additions & 0 deletions src/RabbitMq/AMQPConfigFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace Shlinkio\Shlink\Common\RabbitMq;

use PhpAmqpLib\Connection\AMQPConnectionConfig;
use Psr\Container\ContainerInterface;

class AMQPConfigFactory
{
public function __invoke(ContainerInterface $container): AMQPConnectionConfig
{
$rabbitMqConfig = $container->get('config')['rabbitmq'] ?? [];

$config = new AMQPConnectionConfig();
$config->setHost($rabbitMqConfig['host']);
$config->setPort($rabbitMqConfig['port']);
$config->setUser($rabbitMqConfig['user']);
$config->setPassword($rabbitMqConfig['password']);
$config->setVhost($rabbitMqConfig['vhost']);
$config->setIsSecure($rabbitMqConfig['use_ssl'] ?? false);

// Make sure we do not try to connect until the first time we need to access the server
$config->setIsLazy(true);

return $config;
}
}
43 changes: 5 additions & 38 deletions src/RabbitMq/AMQPConnectionFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,49 +4,16 @@

namespace Shlinkio\Shlink\Common\RabbitMq;

use PhpAmqpLib\Connection\AbstractConnection;
use PhpAmqpLib\Connection\AMQPConnectionConfig;
use PhpAmqpLib\Connection\AMQPSSLConnection;
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Connection\AMQPConnectionFactory as ConnFactory;
use Psr\Container\ContainerInterface;
use Shlinkio\Shlink\Common\Util\SSL;

class AMQPConnectionFactory
{
public function __invoke(ContainerInterface $container): AMQPStreamConnection
public function __invoke(ContainerInterface $container): AbstractConnection
{
$rabbitMqConfig = $container->get('config')['rabbitmq'] ?? [];
$useSsl = $rabbitMqConfig['use_ssl'] ?? false;
$connectionConfig = $this->connectionConfig();

return $useSsl
? new AMQPSSLConnection(
host: $rabbitMqConfig['host'],
port: $rabbitMqConfig['port'],
user: $rabbitMqConfig['user'],
password: $rabbitMqConfig['password'],
vhost: $rabbitMqConfig['vhost'],
ssl_options: SSL::OPTIONS,
config: $connectionConfig,
)
: new AMQPStreamConnection(
host: $rabbitMqConfig['host'],
port: $rabbitMqConfig['port'],
user: $rabbitMqConfig['user'],
password: $rabbitMqConfig['password'],
vhost: $rabbitMqConfig['vhost'],
// We have to pass the config as the ssl_protocol to avoid an internal deprecation warning
// When the ssl_protocol is a config instance, it is internally set as config.
// See https://github.com/php-amqplib/php-amqplib/blob/b4ade54ebe4685873f6316f9a05fc2c77a9e28f9/PhpAmqpLib/Connection/AMQPStreamConnection.php#L48-L55
ssl_protocol: $connectionConfig,
);
}

private function connectionConfig(): AMQPConnectionConfig
{
$config = new AMQPConnectionConfig();
// Make sure we do not try to connect until the first time we need to access the server
$config->setIsLazy(true);

return $config;
$connectionConfig = $container->get(AMQPConnectionConfig::class);
return ConnFactory::create($connectionConfig);
}
}
55 changes: 55 additions & 0 deletions test/RabbitMq/AMQPConfigFactoryTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

declare(strict_types=1);

namespace ShlinkioTest\Shlink\Common\RabbitMq;

use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Container\ContainerInterface;
use Shlinkio\Shlink\Common\RabbitMq\AMQPConfigFactory;

class AMQPConfigFactoryTest extends TestCase
{
private AMQPConfigFactory $factory;
private MockObject & ContainerInterface $container;

protected function setUp(): void
{
$this->factory = new AMQPConfigFactory();
$this->container = $this->createMock(ContainerInterface::class);
}

#[Test, DataProvider('provideSsl')]
public function properConnectionObjectIsCreated(array $useSsl): void
{
$this->container->expects($this->once())->method('get')->with('config')->willReturn([
'rabbitmq' => [
...$useSsl,
'host' => 'host',
'port' => 1111,
'user' => 'user',
'password' => 'password',
'vhost' => 'vhost',
],
]);

$config = ($this->factory)($this->container);

self::assertEquals($useSsl['use_ssl'] ?? false, $config->isSecure());
self::assertEquals('host', $config->getHost());
self::assertEquals(1111, $config->getPort());
self::assertEquals('user', $config->getUser());
self::assertEquals('password', $config->getPassword());
self::assertEquals('vhost', $config->getVhost());
}

public static function provideSsl(): iterable
{
yield 'no ssl set' => [[]];
yield 'no ssl' => [['use_ssl' => false]];
yield 'ssl' => [['use_ssl' => true]];
}
}
33 changes: 8 additions & 25 deletions test/RabbitMq/AMQPConnectionFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@

namespace ShlinkioTest\Shlink\Common\RabbitMq;

use PhpAmqpLib\Connection\AMQPSSLConnection;
use PHPUnit\Framework\Attributes\DataProvider;
use PhpAmqpLib\Connection\AMQPConnectionConfig;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
Expand All @@ -17,35 +16,19 @@ class AMQPConnectionFactoryTest extends TestCase
private AMQPConnectionFactory $factory;
private MockObject & ContainerInterface $container;

protected function setUp(): void
public function setUp(): void
{
$this->factory = new AMQPConnectionFactory();
$this->container = $this->createMock(ContainerInterface::class);
}

#[Test, DataProvider('provideSsl')]
public function properConnectionObjectIsCreated(array $useSsl): void
#[Test]
public function connectionIsCreatedWithConfig(): void
{
$this->container->expects($this->once())->method('get')->with('config')->willReturn([
'rabbitmq' => [
...$useSsl,
'host' => 'host',
'port' => 1111,
'user' => 'user',
'password' => 'password',
'vhost' => 'vhost',
],
]);
$expectedConfig = new AMQPConnectionConfig();
$expectedConfig->setIsLazy(true); // Avoid connection to be attempted

$connection = ($this->factory)($this->container);

self::assertEquals($useSsl['use_ssl'] ?? false, $connection instanceof AMQPSSLConnection);
}

public static function provideSsl(): iterable
{
yield 'no ssl set' => [[]];
yield 'no ssl' => [['use_ssl' => false]];
yield 'ssl' => [['use_ssl' => true]];
$this->container->expects($this->once())->method('get')->willReturn($expectedConfig);
($this->factory)($this->container);
}
}