Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Mercure] Add the component #28877

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

Closed
wants to merge 13 commits into from
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\Lock\Lock;
use Symfony\Component\Lock\Store\SemaphoreStore;
use Symfony\Component\Mercure\Update;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\PropertyInfo\PropertyInfoExtractorInterface;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
Expand All @@ -35,6 +36,7 @@
*
* @author Jeremy Mikola <[email protected]>
* @author Grégoire Pineau <[email protected]>
* @author Kévin Dunglas <[email protected]>
*/
class Configuration implements ConfigurationInterface
{
Expand Down Expand Up @@ -106,6 +108,7 @@ public function getConfigTreeBuilder()
$this->addWebLinkSection($rootNode);
$this->addLockSection($rootNode);
$this->addMessengerSection($rootNode);
$this->addMercureSection($rootNode);

return $treeBuilder;
}
Expand Down Expand Up @@ -1132,4 +1135,36 @@ function ($a) {
->end()
;
}

private function addMercureSection(ArrayNodeDefinition $rootNode)
{
$rootNode
->children()
->arrayNode('mercure')
->info('Mercure configuration')
->{!class_exists(FullStack::class) && class_exists(Update::class) ? 'canBeDisabled' : 'canBeEnabled'}()
->fixXmlConfig('hub')
->children()
->arrayNode('hubs')
->useAttributeAsKey('name')
->normalizeKeys(false)
->arrayPrototype()
->children()
->scalarNode('url')->info('URL of the hub\'s publish endpoint')->example('https://demo.mercure.rocks/hub')->end()
->scalarNode('jwt')->info('JSON Web Token to use to publish to this hub.')->end()
->scalarNode('jwt_provider')->info('The ID of a service to call to generate the JSON Web Token.')->end()
->scalarNode('bus')->info('Name of the Messenger bus where the handler for this hub must be registered. Default to the default bus if Messenger is enabled.')->end()
->end()
->validate()
->ifTrue(function ($v) { return isset($v['jwt']) && isset($v['jwt_provider']); })
->thenInvalid('"jwt" and "jwt_provider" cannot be used together.')
->end()
->end()
->end()
->scalarNode('default_hub')->end()
->end()
->end()
->end()
;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@
use Symfony\Component\Lock\Store\FlockStore;
use Symfony\Component\Lock\Store\StoreFactory;
use Symfony\Component\Lock\StoreInterface;
use Symfony\Component\Mercure\Jwt\StaticJwtProvider;
use Symfony\Component\Mercure\Publisher;
use Symfony\Component\Mercure\Update;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
use Symfony\Component\Messenger\MessageBus;
use Symfony\Component\Messenger\MessageBusInterface;
Expand Down Expand Up @@ -289,6 +292,10 @@ public function load(array $configs, ContainerBuilder $container)
$this->registerLockConfiguration($config['lock'], $container, $loader);
}

if ($this->isConfigEnabled($container, $config['mercure'])) {
$this->registerMercureConfiguration($config['mercure'], $container);
}

if ($this->isConfigEnabled($container, $config['web_link'])) {
if (!class_exists(HttpHeaderSerializer::class)) {
throw new LogicException('WebLink support cannot be enabled as the WebLink component is not installed.');
Expand Down Expand Up @@ -1668,6 +1675,50 @@ private function registerCacheConfiguration(array $config, ContainerBuilder $con
}
}

private function registerMercureConfiguration(array $config, ContainerBuilder $container)
{
if (!class_exists(Update::class)) {
throw new LogicException('Mercure support cannot be enabled as the Mercure component is not installed. Try running "composer require symfony/mercure".');
}

if (!$config['hubs']) {
return;
}

$defaultHub = $config['default_hub'] ?? null;
$hubUrls = array();
$defaultHubUrl = null;
foreach ($config['hubs'] as $name => $hub) {
if (isset($hub['jwt'])) {
$jwtProvider = sprintf('mercure.hub.%s.jwt_provider', $name);
$container->register($jwtProvider, StaticJwtProvider::class)->addArgument($hub['jwt']);
} else {
$jwtProvider = $hub['jwt_provider'];
}

$hubUrls[$name] = $hub['url'];
$hubId = sprintf('mercure.hub.%s.publisher', $name);
if (!$defaultHub) {
$defaultHubUrl = $hub['url'];
$defaultHub = $hubId;
}

$publisherDefinition = $container->register($hubId, Publisher::class)
->addArgument($hub['url'])
->addArgument(new Reference($jwtProvider));

$bus = $hub['bus'] ?? null;
if ($this->messengerConfigEnabled && false !== $bus) {
$attributes = null === $bus ? array() : array('bus' => $hub['bus']);
$publisherDefinition->addTag('messenger.message_handler', $attributes);
}
}

$container->setAlias(Publisher::class, $defaultHub);
$container->setParameter('mercure.hubs', $hubUrls);
$container->setParameter('mercure.default_hub', $defaultHubUrl);
}

/**
* Returns the base path for the XSD files.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<xsd:element name="php-errors" type="php-errors" minOccurs="0" maxOccurs="1" />
<xsd:element name="lock" type="lock" minOccurs="0" maxOccurs="1" />
<xsd:element name="messenger" type="messenger" minOccurs="0" maxOccurs="1" />
<xsd:element name="mercure" type="mercure" minOccurs="0" maxOccurs="1" />
</xsd:choice>

<xsd:attribute name="http-method-override" type="xsd:boolean" />
Expand Down Expand Up @@ -417,4 +418,20 @@
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" use="required"/>
</xsd:complexType>

<xsd:complexType name="mercure">
<xsd:sequence>
<xsd:element name="hub" type="mercure_hub" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="default-hub" type="xsd:string" />
<xsd:attribute name="enabled" type="xsd:boolean" />
</xsd:complexType>

<xsd:complexType name="mercure_hub">
<xsd:attribute name="name" type="xsd:string" use="required" />
<xsd:attribute name="url" type="xsd:string" />
<xsd:attribute name="jwt" type="xsd:string" />
<xsd:attribute name="jwt_provider" type="xsd:string" />
<xsd:attribute name="bus" type="xsd:string" />
</xsd:complexType>
</xsd:schema>
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,10 @@ class_exists(SemaphoreStore::class) && SemaphoreStore::isSupported() ? 'semaphor
'default_bus' => null,
'buses' => array('messenger.bus.default' => array('default_middleware' => true, 'middleware' => array())),
),
'mercure' => array(
'enabled' => !class_exists(FullStack::class) && class_exists(Update::class),
'hubs' => array(),
),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

$container->loadFromExtension('framework', array(
'mercure' => array(
'hubs' => array(
array(
'name' => 'default',
'url' => 'https://demo.mercure.rocks/hub',
'jwt' => 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.HB0k08BaV8KlLZ3EafCRlTDGbkd9qdznCzJQ_l8ELTU',
),
),
),
));
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?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:mercure>
<framework:hub name="default" url="https://demo.mercure.rocks/hub" jwt="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.HB0k08BaV8KlLZ3EafCRlTDGbkd9qdznCzJQ_l8ELTU" />
</framework:mercure>
</framework:config>
</container>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
framework:
mercure:
hubs:
default:
url: https://demo.mercure.rocks/hub
jwt: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.HB0k08BaV8KlLZ3EafCRlTDGbkd9qdznCzJQ_l8ELTU
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpKernel\DependencyInjection\LoggerPass;
use Symfony\Component\Mercure\Update;
use Symfony\Component\Messenger\Tests\Fixtures\DummyMessage;
use Symfony\Component\Messenger\Tests\Fixtures\SecondMessage;
use Symfony\Component\Messenger\Transport\TransportFactory;
Expand Down Expand Up @@ -1239,6 +1240,21 @@ public function testSessionCookieSecureAuto()
$this->assertEquals($expected, array_keys($container->getDefinition('session_listener')->getArgument(0)->getValues()));
}

public function testMercure()
{
if (!class_exists(Update::class)) {
$this->markTestSkipped('The Mercure Component has been introduced in Symfony 4.2.');
}

$container = $this->createContainerFromFile('mercure');
$this->assertTrue($container->hasDefinition('mercure.hub.default.jwt_provider'));
$this->assertTrue($container->hasDefinition('mercure.hub.default.publisher'));
$this->assertSame('https://demo.mercure.rocks/hub', $container->getDefinition('mercure.hub.default.publisher')->getArgument(0));
$this->assertSame('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.HB0k08BaV8KlLZ3EafCRlTDGbkd9qdznCzJQ_l8ELTU', $container->getDefinition('mercure.hub.default.jwt_provider')->getArgument(0));
$this->assertSame(array('default' => 'https://demo.mercure.rocks/hub'), $container->getParameter('mercure.hubs'));
$this->assertSame('https://demo.mercure.rocks/hub', $container->getParameter('mercure.default_hub'));
}

protected function createContainer(array $data = array())
{
return new ContainerBuilder(new ParameterBag(array_merge(array(
Expand Down
7 changes: 7 additions & 0 deletions src/Symfony/Component/Mercure/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CHANGELOG
=========

4.2.0
-----

* Introduced the component as experimental
36 changes: 36 additions & 0 deletions src/Symfony/Component/Mercure/Jwt/StaticJwtProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Symfony\Component\Mercure\Jwt;

/**
* Provides a JWT passed as a configuration parameter.
*
* @author Kévin Dunglas <[email protected]>
*
* @experimental
*/
final class StaticJwtProvider
{
private $jwt;

public function __construct(string $jwt)
{
$this->jwt = $jwt;
}

public function __invoke(): string
{
return $this->jwt;
}
}
19 changes: 19 additions & 0 deletions src/Symfony/Component/Mercure/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Copyright (c) 2018 Fabien Potencier

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Loading