Completed
Push — master ( 1c4593...ca959b )
by Tomasz
09:01
created

PoolsPass   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 118
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 63.46%

Importance

Changes 0
Metric Value
wmc 17
lcom 1
cbo 3
dl 0
loc 118
ccs 33
cts 52
cp 0.6346
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A process() 0 18 4
B setupPools() 0 26 5
B setupSingleQueueManager() 0 22 4
B setupMultipleQueueManager() 0 22 4
1
<?php
2
3
/*
4
 * This file is part of the Symfony package.
5
 *
6
 * (c) Fabien Potencier <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Gendoria\CommandQueueBundle\DependencyInjection\Pass;
13
14
use Gendoria\CommandQueue\QueueManager\MultipleQueueManagerInterface;
15
use Gendoria\CommandQueue\QueueManager\SingleQueueManagerInterface;
16
use Gendoria\CommandQueue\SendDriver\SendDriverInterface;
17
use InvalidArgumentException;
18
use ReflectionClass;
19
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
20
use Symfony\Component\DependencyInjection\ContainerBuilder;
21
use Symfony\Component\DependencyInjection\Definition;
22
use Symfony\Component\DependencyInjection\Reference;
23
24
/**
25
 * Compiler pass to register tagged services for an event dispatcher.
26
 */
27
class PoolsPass implements CompilerPassInterface
28
{
29
30
    /**
31
     * Queue manager tag name.
32
     *
33
     * @var string
34
     */
35
    const QUEUE_MANAGER_TAG = 'gendoria_command_queue.send_manager';
36
37
    /**
38
     * Prepares command queue pools based on bundle configuration.
39
     *
40
     * Function also attaches specific pools to services tagged with {@link QUEUE_MANAGER_TAG} tag.
41
     *
42
     * @param ContainerBuilder $container
43
     *
44
     * @throws InvalidArgumentException
45
     */
46 11
    public function process(ContainerBuilder $container)
47
    {
48 3
        $this->setupPools($container);
49
        
50
        $pools = $container->getParameter('gendoria_command_queue.pools');
51
52 11
        foreach ($container->findTaggedServiceIds(self::QUEUE_MANAGER_TAG) as $id => $tags) {
53
            $def = $container->getDefinition($id);
54
            $reflection = new ReflectionClass($def->getClass());
55
            if ($reflection->implementsInterface(MultipleQueueManagerInterface::class)) {
56 1
                $this->setupMultipleQueueManager($id, $def, $tags, $pools);
57
            } elseif ($reflection->implementsInterface(SingleQueueManagerInterface::class)) {
58 2
                $this->setupSingleQueueManager($id, $def, $tags, $pools);
59
            } else {
60
                throw new InvalidArgumentException(sprintf('Service "%s" does not implement one of required interfaces.', $id));
61 5
            }
62 4
        }
63 3
    }
64
    
65
    /**
66
     * Setup pools.
67
     * 
68
     * @param ContainerBuilder $container
69
     * @throws InvalidArgumentException
70
     * @return void
71
     */
72 14
    private function setupPools(ContainerBuilder $container)
73
    {
74
        $pools = $container->getParameter('gendoria_command_queue.pools');
75 14
        $usedServiceIds = array();
76
        foreach ($pools as $poolData) {
77
            $sendServiceId = substr($poolData['send_driver'], 1);
78
            if (in_array($sendServiceId, $usedServiceIds)) {
79
                throw new InvalidArgumentException(sprintf(
80 1
                    'Each pool has to have unique send service - duplicate service id "%s" found.',
81
                    $sendServiceId
82
                ));
83
            }
84
            if (!$container->hasDefinition($sendServiceId)) {
85
                throw new InvalidArgumentException('Non existing send driver service provided: ' . $poolData['send_driver'].'.');
86
            }
87
            $sendDriverReflection = new ReflectionClass($container->getDefinition($sendServiceId)->getClass());
88
            if (!$sendDriverReflection->implementsInterface(SendDriverInterface::class)) {
89
                throw new InvalidArgumentException(sprintf(
90 1
                    'Service "%s" does not implement interface "%s".',
91
                    $sendServiceId,
92 1
                    SendDriverInterface::class
93
                ));
94
            }
95 9
            $usedServiceIds[] = $sendServiceId;
96 2
        }
97
    }
98
99 5
    private function setupSingleQueueManager($id, Definition $def, array $tags, array $pools)
100
    {
101
        if (count($tags) > 1) {
102
            throw new InvalidArgumentException('Only single ' . self::QUEUE_MANAGER_TAG . ' tag possible on service ' . $id.'.');
103
        }
104 5
        if (!empty($tags[0]['pool'])) {
105 4
            $poolName = $tags[0]['pool'];
106
        } else {
107 1
            $poolName = 'default';
108 4
        }
109 5
        if (empty($pools[$poolName])) {
110
            throw new InvalidArgumentException(sprintf(
111 1
                'Service "%s" requests non existing queue pool "%s".',
112
                $id,
113
                $poolName
114
            ));
115
        }
116
        $def->addMethodCall(
117 4
            'setSendDriver',
118
            array(new Reference(substr($pools[$poolName]['send_driver'], 1)))
119
        );
120 2
    }
121
122 5
    private function setupMultipleQueueManager($id, Definition $def, array $tags, array $pools)
123
    {
124
        foreach ($tags as $tag) {
125 3
            if (!empty($tag['pool'])) {
126 5
                $poolName = $tag['pool'];
127
            } else {
128 4
                $poolName = 'default';
129 5
            }
130 3
            $isDefault = !empty($tag['default']);
131 3
            if (empty($pools[$poolName])) {
132
                throw new InvalidArgumentException(sprintf(
133 1
                    'Service "%s" requests non existing queue pool "%s".',
134
                    $id,
135
                    $poolName
136
                ));
137
            }
138
            $def->addMethodCall(
139 4
                'addSendDriver',
140
                array($poolName, new Reference(substr($pools[$poolName]['send_driver'], 1)), $isDefault)
141
            );
142
        }
143
    }
144
}
145