Skip to content

Commit 38de8a9

Browse files
authored
feat: Allow to define the serializer from connection DSN (#8)
1 parent 6693501 commit 38de8a9

9 files changed

Lines changed: 157 additions & 7 deletions

File tree

ConnectionFactory/Configuration.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ public static function createConfiguration(string $name, array $options): self
6666

6767
if (isset($options['url'])) {
6868
$preparedConfig = ResolverConnectionDriverFactory::parseDsn($options['url']);
69+
70+
if (isset($preparedConfig['serializer'])) {
71+
$preparedConfig['url_serializer'] = $preparedConfig['serializer'];
72+
unset($preparedConfig['serializer']);
73+
}
6974
}
7075
if (!empty($options['options'])) {
7176
$options = array_merge($options, $options['options']);

ConnectionFactory/ConnectionDriverFactory.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,26 @@ public function createDriver(Configuration $config, SerializerInterface $seriali
106106
return $this->configureKnownDriver($config, $serializer);
107107
}
108108

109+
/**
110+
* Create the connection driver instance, and resolve the serializer from the URL option "serializer".
111+
*
112+
* @param Configuration $config The driver configuration
113+
* @param \Closure():SerializerInterface $defaultSerializerResolver The default serializer resolver. Used when the serializer is not set in the configuration.
114+
*
115+
* @return ConnectionDriverInterface
116+
*
117+
* @internal
118+
*/
119+
public function createDriverAndResolveSerializerFromUrl(Configuration $config, \Closure $defaultSerializerResolver)
120+
{
121+
$serializer = $config->has('url_serializer')
122+
? $this->container->get('bdf_queue.serializer.'.$config->get('url_serializer'))
123+
: $defaultSerializerResolver()
124+
;
125+
126+
return $this->createDriver($config, $serializer);
127+
}
128+
109129
/**
110130
* Create the known driver instance.
111131
*

DependencyInjection/BdfQueueExtension.php

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Bdf\QueueBundle\DependencyInjection\Compiler\RegisterReceiverFactoryPass;
2020
use Bdf\QueueBundle\DependencyInjection\Failer\FailerDriverConfiguratorInterface;
2121
use Symfony\Component\Config\FileLocator;
22+
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
2223
use Symfony\Component\DependencyInjection\ContainerBuilder;
2324
use Symfony\Component\DependencyInjection\Extension\Extension;
2425
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
@@ -56,13 +57,22 @@ public function configureConnections(array $config, ContainerBuilder $container)
5657
->setFactory([DriverConfiguration::class, 'createConfiguration'])
5758
->setArguments([$name, $options]);
5859

59-
$container->register('bdf_queue.connection_definition.'.$name, ConnectionDriverInterface::class)
60+
$driverDefinition = $container->register('bdf_queue.connection_definition.'.$name, ConnectionDriverInterface::class)
6061
->setPublic(true)
61-
->setFactory($options['connection_factory'] ?? [new Reference(ConnectionDriverFactory::class), 'createDriver'])
62-
->setArguments([
63-
new Reference('bdf_queue.config_definition.'.$name),
64-
new Reference($this->configureSerializer($options['serializer'], $config['default_serializer'])),
65-
]);
62+
->setArgument(0, new Reference('bdf_queue.config_definition.'.$name))
63+
;
64+
65+
if (empty($options['serializer']['from_url'])) {
66+
$driverDefinition
67+
->setFactory($options['connection_factory'] ?? [new Reference(ConnectionDriverFactory::class), 'createDriver'])
68+
->setArgument(1, new Reference($this->configureSerializer($options['serializer'], $config['default_serializer'])))
69+
;
70+
} else {
71+
$driverDefinition
72+
->setFactory($options['connection_factory'] ?? [new Reference(ConnectionDriverFactory::class), 'createDriverAndResolveSerializerFromUrl'])
73+
->setArgument(1, new ServiceClosureArgument(new Reference($this->configureSerializer($options['serializer'], $config['default_serializer']))))
74+
;
75+
}
6676
}
6777

6878
$container->registerForAutoconfiguration(ConnectionDriverConfiguratorInterface::class)

DependencyInjection/Configuration.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ private function getConnectionsNode()
8888
->scalarNode('service')
8989
->info('The serializer service ID.')
9090
->end()
91+
->booleanNode('from_url')
92+
->info('Use the URL option "serializer=" to configure the serializer. The value should be the serializer ID.')
93+
->defaultFalse()
94+
->end()
9195
->end()
9296
->end()
9397
->arrayNode('options')

Resources/config/queue.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,16 +65,20 @@ services:
6565
#Serializer
6666
bdf_queue.serializer.native:
6767
class: 'Bdf\Queue\Serializer\Serializer'
68+
public: true
6869

6970
bdf_queue.serializer.bdf:
7071
class: 'Bdf\Queue\Serializer\BdfSerializer'
72+
public: true
7173
arguments: ['@?bdf_serializer']
7274

7375
bdf_queue.serializer.json:
7476
class: 'Bdf\Queue\Serializer\JsonSerializer'
77+
public: true
7578

7679
bdf_queue.serializer.bdf_json:
7780
class: 'Bdf\Queue\Serializer\BdfSerializer'
81+
public: true
7882
arguments:
7983
- '@?bdf_serializer'
8084
- 'json'

Tests/BdfQueueBundleTest.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
require_once __DIR__.'/TestKernel.php';
66

7+
use Bdf\Queue\Connection\ConnectionDriverInterface;
78
use Bdf\Queue\Connection\Prime\PrimeConnection;
89
use Bdf\Queue\Console\Command\BindCommand;
910
use Bdf\Queue\Console\Command\ConsumeCommand;
@@ -25,11 +26,14 @@
2526
use Bdf\Queue\Failer\MemoryFailedJobRepository;
2627
use Bdf\Queue\Message\Message;
2728
use Bdf\Queue\Message\QueuedMessage;
29+
use Bdf\Queue\Serializer\JsonSerializer;
30+
use Bdf\Queue\Serializer\Serializer;
2831
use Bdf\Queue\Testing\QueueHelper;
2932
use Bdf\QueueBundle\BdfQueueBundle;
3033
use Bdf\QueueBundle\Consumption\ReceiverLoader;
3134
use Bdf\QueueBundle\Tests\Fixtures\Bar;
3235
use Bdf\QueueBundle\Tests\Fixtures\Foo;
36+
use Bdf\QueueBundle\Tests\Fixtures\GetConnection;
3337
use Bdf\QueueBundle\Tests\Fixtures\GetDestinationFactory;
3438
use Bdf\QueueBundle\Tests\Fixtures\TestHandler;
3539
use PHPUnit\Framework\TestCase;
@@ -154,7 +158,7 @@ public function testConnectionOptions()
154158
'gearman' => [
155159
'driver' => null,
156160
'host' => null,
157-
'serializer' => ['id' => 'native'],
161+
'serializer' => ['id' => 'native', 'from_url' => false],
158162
'queue' => null,
159163
'url' => 'gearman://127.0.0.1',
160164
'options' => ['client_timeout' => 1],
@@ -254,6 +258,20 @@ public function testPrimeConnection()
254258
$destinations->queue('prime', 'queue_name');
255259
}
256260

261+
public function testWithSerializerFromUrl()
262+
{
263+
$kernel = new \TestKernel(__DIR__.'/Fixtures/conf_with_serializer_from_dsn.yaml');
264+
$kernel->boot();
265+
266+
/** @var ConnectionDriverInterface $connection */
267+
$connection = $kernel->getContainer()->get(GetConnection::class)->get('queue');
268+
$this->assertInstanceOf(JsonSerializer::class, $connection->serializer());
269+
270+
/** @var ConnectionDriverInterface $connection */
271+
$connection = $kernel->getContainer()->get(GetConnection::class)->get('no_defined');
272+
$this->assertInstanceOf(Serializer::class, $connection->serializer());
273+
}
274+
257275
public function testDestinationFactoryInstance()
258276
{
259277
$kernel = new \TestKernel();

Tests/Fixtures/GetConnection.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace Bdf\QueueBundle\Tests\Fixtures;
4+
5+
use Bdf\Queue\Connection\ConnectionDriverInterface;
6+
use Bdf\Queue\Connection\Factory\ConnectionDriverFactoryInterface;
7+
8+
class GetConnection
9+
{
10+
private ConnectionDriverFactoryInterface $factory;
11+
12+
public function __construct(ConnectionDriverFactoryInterface $factory)
13+
{
14+
$this->factory = $factory;
15+
}
16+
17+
public function get(string $name): ConnectionDriverInterface
18+
{
19+
return $this->factory->create($name);
20+
}
21+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
bdf_queue:
2+
default_connection: 'gearman'
3+
default_serializer: 'native'
4+
connections:
5+
queue:
6+
url: 'gearman://127.0.0.1?serializer=json'
7+
serializer:
8+
from_url: true
9+
options:
10+
client-timeout: 1
11+
12+
no_defined:
13+
url: 'gearman://127.0.0.1'
14+
serializer:
15+
from_url: true
16+
17+
prime:
18+
default_connection: 'my_connection'
19+
connections:
20+
my_connection: 'sqlite::memory:'
21+
22+
migration:
23+
connection: 'my_connection'
24+
path: '%kernel.project_dir%/src/Migration'
25+
26+
services:
27+
Bdf\QueueBundle\Tests\Fixtures\GetConnection:
28+
class: Bdf\QueueBundle\Tests\Fixtures\GetConnection
29+
public: true
30+
autowire: true
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
bdf_queue:
2+
default_connection: 'gearman'
3+
default_serializer: 'native'
4+
connections:
5+
memory:
6+
url: 'memory:'
7+
serializer:
8+
id: 'native'
9+
destinations:
10+
b2p_bus:
11+
url: 'queue://memory/b2p_bus'
12+
consumer:
13+
handler: 'var_dump'
14+
middlewares:
15+
- 'test_receiver'
16+
17+
prime:
18+
default_connection: 'my_connection'
19+
connections:
20+
my_connection: 'sqlite::memory:'
21+
22+
migration:
23+
connection: 'my_connection'
24+
path: '%kernel.project_dir%/src/Migration'
25+
26+
services:
27+
_defaults:
28+
autowire: true
29+
autoconfigure: true
30+
31+
Bdf\QueueBundle\Tests\Fixtures\GetDestinationFactory:
32+
public: true
33+
class: Bdf\QueueBundle\Tests\Fixtures\GetDestinationFactory
34+
35+
test_receiver:
36+
class: Bdf\QueueBundle\Tests\Fixtures\FooReceiver
37+
arguments:
38+
- {'foo': 'bar'}

0 commit comments

Comments
 (0)