Skip to content

Commit a12b06c

Browse files
authored
Merge pull request #335 from php-enqueue/bundle-better-dx-when-transport-is-missing
[bundle][dx] Add a message that suggest installing a pkg to use the transport.
2 parents 6558467 + 58f62cf commit a12b06c

File tree

4 files changed

+210
-7
lines changed

4 files changed

+210
-7
lines changed

pkg/enqueue-bundle/EnqueueBundle.php

+25-7
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
use Enqueue\Stomp\Symfony\RabbitMqStompTransportFactory;
3030
use Enqueue\Stomp\Symfony\StompTransportFactory;
3131
use Enqueue\Symfony\AmqpTransportFactory;
32+
use Enqueue\Symfony\MissingTransportFactory;
3233
use Enqueue\Symfony\RabbitMqAmqpTransportFactory;
3334
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
3435
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -53,8 +54,11 @@ public function build(ContainerBuilder $container)
5354
$extension = $container->getExtension('enqueue');
5455

5556
if (class_exists(StompConnectionFactory::class)) {
56-
$extension->addTransportFactory(new StompTransportFactory());
57-
$extension->addTransportFactory(new RabbitMqStompTransportFactory());
57+
$extension->addTransportFactory(new StompTransportFactory('stomp'));
58+
$extension->addTransportFactory(new RabbitMqStompTransportFactory('rabbitmq_stomp'));
59+
} else {
60+
$extension->addTransportFactory(new MissingTransportFactory('stomp', ['enqueue/stomp']));
61+
$extension->addTransportFactory(new MissingTransportFactory('rabbitmq_stomp', ['enqueue/stomp']));
5862
}
5963

6064
if (
@@ -64,26 +68,40 @@ class_exists(AmqpLibConnectionFactory::class)
6468
) {
6569
$extension->addTransportFactory(new AmqpTransportFactory('amqp'));
6670
$extension->addTransportFactory(new RabbitMqAmqpTransportFactory('rabbitmq_amqp'));
71+
} else {
72+
$amppPackages = ['enqueue/amqp-ext', 'enqueue/amqp-bunny', 'enqueue/amqp-lib'];
73+
$extension->addTransportFactory(new MissingTransportFactory('amqp', $amppPackages));
74+
$extension->addTransportFactory(new MissingTransportFactory('rabbitmq_amqp', $amppPackages));
6775
}
6876

6977
if (class_exists(FsConnectionFactory::class)) {
70-
$extension->addTransportFactory(new FsTransportFactory());
78+
$extension->addTransportFactory(new FsTransportFactory('fs'));
79+
} else {
80+
$extension->addTransportFactory(new MissingTransportFactory('fs', ['enqueue/fs']));
7181
}
7282

7383
if (class_exists(RedisConnectionFactory::class)) {
74-
$extension->addTransportFactory(new RedisTransportFactory());
84+
$extension->addTransportFactory(new RedisTransportFactory('redis'));
85+
} else {
86+
$extension->addTransportFactory(new MissingTransportFactory('redis', ['enqueue/redis']));
7587
}
7688

7789
if (class_exists(DbalConnectionFactory::class)) {
78-
$extension->addTransportFactory(new DbalTransportFactory());
90+
$extension->addTransportFactory(new DbalTransportFactory('dbal'));
91+
} else {
92+
$extension->addTransportFactory(new MissingTransportFactory('dbal', ['enqueue/dbal']));
7993
}
8094

8195
if (class_exists(SqsConnectionFactory::class)) {
82-
$extension->addTransportFactory(new SqsTransportFactory());
96+
$extension->addTransportFactory(new SqsTransportFactory('sqs'));
97+
} else {
98+
$extension->addTransportFactory(new MissingTransportFactory('sqs', ['enqueue/sqs']));
8399
}
84100

85101
if (class_exists(GpsConnectionFactory::class)) {
86-
$extension->addTransportFactory(new GpsTransportFactory());
102+
$extension->addTransportFactory(new GpsTransportFactory('gps'));
103+
} else {
104+
$extension->addTransportFactory(new MissingTransportFactory('gps', ['enqueue/gps']));
87105
}
88106

89107
$container->addCompilerPass(new AsyncEventsPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 100);

pkg/enqueue-bundle/Tests/Unit/DependencyInjection/EnqueueExtensionTest.php

+18
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313
use Enqueue\Null\NullContext;
1414
use Enqueue\Null\Symfony\NullTransportFactory;
1515
use Enqueue\Symfony\DefaultTransportFactory;
16+
use Enqueue\Symfony\MissingTransportFactory;
1617
use Enqueue\Symfony\TransportFactoryInterface;
1718
use Enqueue\Test\ClassExtensionTrait;
1819
use PHPUnit\Framework\TestCase;
20+
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
1921
use Symfony\Component\DependencyInjection\ContainerBuilder;
2022
use Symfony\Component\DependencyInjection\Reference;
2123
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
@@ -569,4 +571,20 @@ public function testShouldConfigureQueueConsumer()
569571
$this->assertSame(123, $def->getArgument(2));
570572
$this->assertSame(456, $def->getArgument(3));
571573
}
574+
575+
public function testShouldThrowIfPackageShouldBeInstalledToUseTransport()
576+
{
577+
$container = new ContainerBuilder();
578+
579+
$extension = new EnqueueExtension();
580+
$extension->addTransportFactory(new MissingTransportFactory('need_package', ['a_package', 'another_package']));
581+
582+
$this->expectException(InvalidConfigurationException::class);
583+
$this->expectExceptionMessage('In order to use the transport "need_package" install');
584+
$extension->load([[
585+
'transport' => [
586+
'need_package' => true,
587+
],
588+
]], $container);
589+
}
572590
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?php
2+
3+
namespace Enqueue\Symfony;
4+
5+
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
6+
use Symfony\Component\DependencyInjection\ContainerBuilder;
7+
8+
class MissingTransportFactory implements TransportFactoryInterface, DriverFactoryInterface
9+
{
10+
/**
11+
* @var string
12+
*/
13+
private $name;
14+
/**
15+
* @var string[]
16+
*/
17+
private $packages;
18+
19+
/**
20+
* @param string $name
21+
* @param string[] $packages
22+
*/
23+
public function __construct($name, array $packages)
24+
{
25+
$this->name = $name;
26+
$this->packages = $packages;
27+
}
28+
29+
/**
30+
* {@inheritdoc}
31+
*/
32+
public function addConfiguration(ArrayNodeDefinition $builder)
33+
{
34+
if (1 == count($this->packages)) {
35+
$message = sprintf(
36+
'In order to use the transport "%s" install a package "%s"',
37+
$this->getName(),
38+
implode('", "', $this->packages)
39+
);
40+
} else {
41+
$message = sprintf(
42+
'In order to use the transport "%s" install one of the packages "%s"',
43+
$this->getName(),
44+
implode('", "', $this->packages)
45+
);
46+
}
47+
48+
$builder
49+
->info($message)
50+
->beforeNormalization()
51+
->always(function () {
52+
return [];
53+
})
54+
->end()
55+
->validate()
56+
->always(function () use ($message) {
57+
throw new \InvalidArgumentException($message);
58+
})
59+
->end()
60+
;
61+
}
62+
63+
/**
64+
* {@inheritdoc}
65+
*/
66+
public function createConnectionFactory(ContainerBuilder $container, array $config)
67+
{
68+
throw new \LogicException('Should not be called');
69+
}
70+
71+
/**
72+
* {@inheritdoc}
73+
*/
74+
public function createContext(ContainerBuilder $container, array $config)
75+
{
76+
throw new \LogicException('Should not be called');
77+
}
78+
79+
/**
80+
* {@inheritdoc}
81+
*/
82+
public function createDriver(ContainerBuilder $container, array $config)
83+
{
84+
throw new \LogicException('Should not be called');
85+
}
86+
87+
/**
88+
* @return string
89+
*/
90+
public function getName()
91+
{
92+
return $this->name;
93+
}
94+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<?php
2+
3+
namespace Enqueue\Tests\Symfony;
4+
5+
use Enqueue\Symfony\MissingTransportFactory;
6+
use Enqueue\Symfony\TransportFactoryInterface;
7+
use Enqueue\Test\ClassExtensionTrait;
8+
use PHPUnit\Framework\TestCase;
9+
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
10+
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
11+
use Symfony\Component\Config\Definition\Processor;
12+
13+
class MissingTransportFactoryTest extends TestCase
14+
{
15+
use ClassExtensionTrait;
16+
17+
public function testShouldImplementTransportFactoryInterface()
18+
{
19+
$this->assertClassImplements(TransportFactoryInterface::class, MissingTransportFactory::class);
20+
}
21+
22+
public function testCouldBeConstructedWithNameAndPackages()
23+
{
24+
$transport = new MissingTransportFactory('aMissingTransportName', ['aPackage', 'anotherPackage']);
25+
26+
$this->assertEquals('aMissingTransportName', $transport->getName());
27+
}
28+
29+
public function testThrowOnProcessForOnePackageToInstall()
30+
{
31+
$transport = new MissingTransportFactory('aMissingTransportName', ['aFooPackage']);
32+
$tb = new TreeBuilder();
33+
$rootNode = $tb->root('foo');
34+
35+
$transport->addConfiguration($rootNode);
36+
$processor = new Processor();
37+
38+
$this->expectException(InvalidConfigurationException::class);
39+
$this->expectExceptionMessage('Invalid configuration for path "foo": In order to use the transport "aMissingTransportName" install a package "aFooPackage"');
40+
$processor->process($tb->buildTree(), [[]]);
41+
}
42+
43+
public function testThrowOnProcessForSeveralPackagesToInstall()
44+
{
45+
$transport = new MissingTransportFactory('aMissingTransportName', ['aFooPackage', 'aBarPackage']);
46+
$tb = new TreeBuilder();
47+
$rootNode = $tb->root('foo');
48+
49+
$transport->addConfiguration($rootNode);
50+
$processor = new Processor();
51+
52+
$this->expectException(InvalidConfigurationException::class);
53+
$this->expectExceptionMessage('Invalid configuration for path "foo": In order to use the transport "aMissingTransportName" install one of the packages "aFooPackage", "aBarPackage"');
54+
$processor->process($tb->buildTree(), [[]]);
55+
}
56+
57+
public function testThrowEvenIfThereAreSomeOptionsPassed()
58+
{
59+
$transport = new MissingTransportFactory('aMissingTransportName', ['aFooPackage', 'aBarPackage']);
60+
$tb = new TreeBuilder();
61+
$rootNode = $tb->root('foo');
62+
63+
$transport->addConfiguration($rootNode);
64+
$processor = new Processor();
65+
66+
$this->expectException(InvalidConfigurationException::class);
67+
$this->expectExceptionMessage('In order to use the transport "aMissingTransportName"');
68+
$processor->process($tb->buildTree(), [[
69+
'foo' => 'fooVal',
70+
'bar' => 'barVal',
71+
]]);
72+
}
73+
}

0 commit comments

Comments
 (0)