Skip to content

Commit

Permalink
Merge pull request #67 from jderusse/compiler-pass
Browse files Browse the repository at this point in the history
Move Provider logic in a compilerpass
  • Loading branch information
odolbeau committed Oct 15, 2015
2 parents 4e7cfb7 + cc6db6f commit 8220702
Show file tree
Hide file tree
Showing 7 changed files with 435 additions and 26 deletions.
56 changes: 56 additions & 0 deletions DependencyInjection/Compiler/ProviderCompilerPass.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

namespace Swarrot\SwarrotBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class ProviderCompilerPass implements CompilerPassInterface
{
/** {@inheritDoc} */
public function process(ContainerBuilder $container)
{
if ($container->has('swarrot.factory.default') || !$container->hasParameter('swarrot.provider_config')) {
return;
}

$providersIds = [];

foreach ($container->findTaggedServiceIds('swarrot.provider_factory') as $id => $tags) {
foreach ($tags as $tag) {
if (!isset($tag['alias'])) {
throw new \InvalidArgumentException(
sprintf('The provider\'s alias is no defined for the service "%s"', $id)
);
}
$providersIds[$tag['alias']] = $id;
}
}

list($provider, $connections) = $container->getParameter('swarrot.provider_config');

if (!isset($providersIds[$provider])) {
throw new \InvalidArgumentException(sprintf('Invalid provider "%s"', $provider));
}

$id = $providersIds[$provider];
$definition = $container->getDefinition($id);
$className = $container->getParameterBag()->resolveValue($definition->getClass());

$reflection = new \ReflectionClass($className);

if (!$reflection->implementsInterface('Swarrot\\SwarrotBundle\\Broker\\FactoryInterface')) {
throw new \InvalidArgumentException(sprintf('The provider "%s" is not valid', $provider));
}

foreach ($connections as $name => $connectionConfig) {
$definition->addMethodCall('addConnection', [
$name,
$connectionConfig
]);
}

$container->setAlias('swarrot.factory.default', $id);
$container->getParameterBag()->remove('swarrot.provider_config');
}
}
16 changes: 1 addition & 15 deletions DependencyInjection/SwarrotExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,12 @@ public function load(array $configs, ContainerBuilder $container)
$loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
$loader->load('swarrot.xml');

$id = 'swarrot.factory.'.$config['provider'];
if (!$container->has($id)) {
throw new \InvalidArgumentException('Unsupported provider');
}

$definition = $container->getDefinition($id);

foreach ($config['connections'] as $name => $connectionConfig) {
$definition->addMethodCall('addConnection', array(
$name,
$connectionConfig
));
}

if (null === $config['default_connection']) {
reset($config['connections']);
$config['default_connection'] = key($config['connections']);
}

$container->setAlias('swarrot.factory.default', $id);
$container->setParameter('swarrot.provider_config', [$config['provider'], $config['connections']]);

$commands = array();
foreach ($config['consumers'] as $name => $consumerConfig) {
Expand Down
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,38 @@ You can also use options of the commande line:

Default values will be override by your `config.yml` and use of options will override defaut|config values.

## Implementing your own Provider
If you want to implement your own provider (like Redis). First, you have to implements the `Swarrot\SwarrotBundle\Broker\FactoryInterface`.
Then, you can register it with along the others services and tag it with `swarrot.provider_factory`.

```yaml
services:
app.swarrot.custom_provider_factory:
class: AppBundle\Provider\CustomFactory
tags:
- {name: swarrot.provider_factory}
app.swarrot.redis_provider_factory:
class: AppBundle\Provider\RedisFactory
tags:
- {name: swarrot.provider_factory, alias: redis}
```
Now you can tell to swarrot to use it in the `config.yml` file.

```yaml
swarrot:
provider: app.swarrot.custom_provider_factory
...
```

or with the alias

```yaml
swarrot:
provider: redis
...
```

## Running your tests without publishing
If you use Swarrot you may not want to realy publish messages like in test environment for example. You can use the `BlackholePublisher` to achieve this.

Expand Down
8 changes: 6 additions & 2 deletions Resources/config/swarrot.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@
</parameters>

<services>
<service id="swarrot.factory.pecl" class="%swarrot.factory.pecl.class%" />
<service id="swarrot.factory.amqp_lib" class="%swarrot.factory.amqp_lib.class%" />
<service id="swarrot.factory.pecl" class="%swarrot.factory.pecl.class%">
<tag name="swarrot.provider_factory" alias="pecl"/>
</service>
<service id="swarrot.factory.amqp_lib" class="%swarrot.factory.amqp_lib.class%">
<tag name="swarrot.provider_factory" alias="amqp_lib"/>
</service>

<service id="swarrot.command.base" class="%swarrot.command.base.class%" abstract="true">
<argument /> <!-- name -->
Expand Down
11 changes: 10 additions & 1 deletion SwarrotBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,20 @@

namespace Swarrot\SwarrotBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;
use Swarrot\SwarrotBundle\DependencyInjection\Compiler\ProviderCompilerPass;
use Symfony\Component\Console\Application;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;

class SwarrotBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);

$container->addCompilerPass(new ProviderCompilerPass());
}

public function registerCommands(Application $application)
{
$container = $application->getKernel()->getContainer();
Expand Down
Loading

0 comments on commit 8220702

Please sign in to comment.