bug #26816 [Messenger][FrameworkBundle] Move collector, command into the component & minor tweaks (ogizanagi)

This PR was squashed before being merged into the 4.1-dev branch (closes #26816).

Discussion
----------

[Messenger][FrameworkBundle] Move collector, command into the component & minor tweaks

| Q             | A
| ------------- | ---
| Branch?       | master <!-- see below -->
| Bug fix?      | no
| New feature?  | no <!-- don't forget to update src/**/CHANGELOG.md files -->
| BC breaks?    | no     <!-- see https://symfony.com/bc -->
| Deprecations? | no <!-- don't forget to update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tests pass?   | yes    <!-- please add some, will be required by reviewers -->
| Fixed tickets | N/A   <!-- #-prefixed issue number(s), if any -->
| License       | MIT
| Doc PR        | N/A

Some suggestions more aligned with most of the core practices, mainly:

- Move the command & collector to the component itself. They are not dependent of the Fwb in any way and are useful out of the fwb usage.
- Add an exception in FrameworkExtension if the `framework.messenger` key is enabled, but the component isn't installed.

Commits
-------

6aec62bad3 [FrameworkBundle] Minor messenger component tweaks
f9c9ca0514 [Messenger] Move data collector & command into the component
This commit is contained in:
Fabien Potencier 2018-04-06 07:28:47 +02:00
commit 3a37e41bfb
15 changed files with 196 additions and 17 deletions

View File

@ -61,6 +61,7 @@ use Symfony\Component\Lock\LockInterface;
use Symfony\Component\Lock\Store\StoreFactory;
use Symfony\Component\Lock\StoreInterface;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Messenger\Transport\ReceiverInterface;
use Symfony\Component\Messenger\Transport\SenderInterface;
use Symfony\Component\PropertyAccess\PropertyAccessor;
@ -1441,6 +1442,10 @@ class FrameworkExtension extends Extension
private function registerMessengerConfiguration(array $config, ContainerBuilder $container, XmlFileLoader $loader)
{
if (!interface_exists(MessageBusInterface::class)) {
throw new LogicException('Messenger support cannot be enabled as the Messenger component is not installed.');
}
$loader->load('messenger.xml');
$senderLocatorMapping = array();

View File

@ -69,7 +69,7 @@
<tag name="console.command" command="debug:event-dispatcher" />
</service>
<service id="console.command.messenger_consume_messages" class="Symfony\Bundle\FrameworkBundle\Command\MessengerConsumeMessagesCommand">
<service id="console.command.messenger_consume_messages" class="Symfony\Component\Messenger\Command\ConsumeMessagesCommand">
<argument type="service" id="message_bus" />
<argument type="service" id="messenger.receiver_locator" />

View File

@ -58,7 +58,7 @@
<tag name="monolog.logger" channel="messenger" />
</service>
<service id="data_collector.messenger" class="Symfony\Bundle\FrameworkBundle\DataCollector\MessengerDataCollector">
<service id="data_collector.messenger" class="Symfony\Component\Messenger\DataCollector\MessengerDataCollector">
<tag name="data_collector" template="@WebProfiler/Collector/messenger.html.twig" id="messenger" priority="100" />
<tag name="message_bus_middleware" />
</service>

View File

@ -0,0 +1,12 @@
<?php
$container->loadFromExtension('framework', array(
'validation' => array('enabled' => true),
'messenger' => array(
'middlewares' => array(
'validation' => array(
'enabled' => true,
),
),
),
));

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:framework="http://symfony.com/schema/dic/symfony"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
<framework:config>
<framework:validation enabled="true"/>
<framework:messenger>
<framework:middlewares>
<framework:validation enabled="true"/>
</framework:middlewares>
</framework:messenger>
</framework:config>
</container>

View File

@ -0,0 +1,7 @@
framework:
validation:
enabled: true
messenger:
middlewares:
validation:
enabled: true

View File

@ -520,13 +520,15 @@ abstract class FrameworkExtensionTest extends TestCase
$this->assertFalse($container->hasDefinition('messenger.middleware.doctrine_transaction'));
}
public function testMessengerValidationEnabled()
{
$container = $this->createContainerFromFile('messenger_validation_enabled');
$this->assertTrue($definition = $container->hasDefinition('messenger.middleware.validator'));
}
public function testMessengerValidationDisabled()
{
if (!class_exists(Validation::class)) {
self::markTestSkipped('Skipping tests since Validator component is not installed');
}
$container = $this->createContainerFromFile('messenger_validation');
$container = $this->createContainerFromFile('messenger_validation_disabled');
$this->assertFalse($container->hasDefinition('messenger.middleware.validator'));
}

View File

@ -41,6 +41,7 @@
"symfony/security": "~3.4|~4.0",
"symfony/form": "^4.1",
"symfony/expression-language": "~3.4|~4.0",
"symfony/messenger": "^4.1",
"symfony/process": "~3.4|~4.0",
"symfony/security-core": "~3.4|~4.0",
"symfony/security-csrf": "~3.4|~4.0",

View File

@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Command;
namespace Symfony\Component\Messenger\Command;
use Psr\Container\ContainerInterface;
use Symfony\Component\Console\Command\Command;
@ -24,8 +24,10 @@ use Symfony\Component\Messenger\Worker;
/**
* @author Samuel Roze <samuel.roze@gmail.com>
*
* @experimental in 4.1
*/
class MessengerConsumeMessagesCommand extends Command
class ConsumeMessagesCommand extends Command
{
protected static $defaultName = 'messenger:consume-messages';

View File

@ -9,7 +9,7 @@
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\DataCollector;
namespace Symfony\Component\Messenger\DataCollector;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@ -18,6 +18,8 @@ use Symfony\Component\Messenger\MiddlewareInterface;
/**
* @author Samuel Roze <samuel.roze@gmail.com>
*
* @experimental in 4.1
*/
class MessengerDataCollector extends DataCollector implements MiddlewareInterface
{
@ -26,7 +28,7 @@ class MessengerDataCollector extends DataCollector implements MiddlewareInterfac
*/
public function collect(Request $request, Response $response, \Exception $exception = null)
{
return $this->data;
// noop
}
/**
@ -61,25 +63,25 @@ class MessengerDataCollector extends DataCollector implements MiddlewareInterfac
try {
$result = $next($message);
if (is_object($result)) {
if (\is_object($result)) {
$debugRepresentation['result'] = array(
'type' => get_class($result),
'type' => \get_class($result),
'object' => $this->cloneVar($result),
);
} elseif (is_array($result)) {
} elseif (\is_array($result)) {
$debugRepresentation['result'] = array(
'type' => 'array',
'object' => $this->cloneVar($result),
);
} else {
$debugRepresentation['result'] = array(
'type' => gettype($result),
'type' => \gettype($result),
'value' => $result,
);
}
} catch (\Throwable $exception) {
$debugRepresentation['exception'] = array(
'type' => get_class($exception),
'type' => \get_class($exception),
'message' => $exception->getMessage(),
);
}

View File

@ -0,0 +1,130 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Messenger\Tests\DataCollector;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Messenger\DataCollector\MessengerDataCollector;
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
use Symfony\Component\VarDumper\Test\VarDumperTestTrait;
/**
* @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
*/
class MessengerDataCollectorTest extends TestCase
{
use VarDumperTestTrait;
/**
* @dataProvider getHandleTestData
*/
public function testHandle($returnedValue, $expected)
{
$collector = new MessengerDataCollector();
$message = new DummyMessage('dummy message');
$next = $this->createPartialMock(\stdClass::class, array('__invoke'));
$next->expects($this->once())->method('__invoke')->with($message)->willReturn($returnedValue);
$this->assertSame($returnedValue, $collector->handle($message, $next));
$messages = $collector->getMessages();
$this->assertCount(1, $messages);
$this->assertDumpMatchesFormat($expected, $messages[0]);
}
public function getHandleTestData()
{
$messageDump = <<<DUMP
"message" => array:2 [
"type" => "Symfony\Component\Messenger\Tests\Fixtures\DummyMessage"
"object" => Symfony\Component\VarDumper\Cloner\Data {%A
%A+class: "Symfony\Component\Messenger\Tests\Fixtures\DummyMessage"%A
}
]
DUMP;
yield 'no returned value' => array(
null,
<<<DUMP
array:2 [
$messageDump
"result" => array:2 [
"type" => "NULL"
"value" => null
]
]
DUMP
);
yield 'scalar returned value' => array(
'returned value',
<<<DUMP
array:2 [
$messageDump
"result" => array:2 [
"type" => "string"
"value" => "returned value"
]
]
DUMP
);
yield 'array returned value' => array(
array('returned value'),
<<<DUMP
array:2 [
$messageDump
"result" => array:2 [
"type" => "array"
"object" => Symfony\Component\VarDumper\Cloner\Data {%A
]
]
DUMP
);
}
public function testHandleWithException()
{
$collector = new MessengerDataCollector();
$message = new DummyMessage('dummy message');
$expectedException = new \RuntimeException('foo');
$next = $this->createPartialMock(\stdClass::class, array('__invoke'));
$next->expects($this->once())->method('__invoke')->with($message)->willThrowException($expectedException);
try {
$collector->handle($message, $next);
} catch (\Throwable $actualException) {
$this->assertSame($expectedException, $actualException);
}
$messages = $collector->getMessages();
$this->assertCount(1, $messages);
$this->assertDumpMatchesFormat(<<<DUMP
array:2 [
"message" => array:2 [
"type" => "Symfony\Component\Messenger\Tests\Fixtures\DummyMessage"
"object" => Symfony\Component\VarDumper\Cloner\Data {%A
%A+class: "Symfony\Component\Messenger\Tests\Fixtures\DummyMessage"%A
}
]
"exception" => array:2 [
"type" => "RuntimeException"
"message" => "foo"
]
]
DUMP
, $messages[0]);
}
}

View File

@ -21,7 +21,9 @@
"require-dev": {
"symfony/serializer": "~3.4|~4.0",
"symfony/dependency-injection": "~3.4.6|~4.0",
"symfony/property-access": "~3.4|~4.0"
"symfony/http-kernel": "~3.4|~4.0",
"symfony/property-access": "~3.4|~4.0",
"symfony/var-dumper": "~3.4|~4.0"
},
"suggest": {
"sroze/enqueue-bridge": "For using the php-enqueue library as an adapter."