Test Setup Failed
Push — master ( 7cf6c7...109933 )
by Matthew
02:28
created

WorkerCompilerPass::getJobClassArchive()   C

Complexity

Conditions 8
Paths 16

Size

Total Lines 27
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 27
rs 5.3846
c 0
b 0
f 0
cc 8
eloc 17
nc 16
nop 1
1
<?php
2
3
namespace Dtc\QueueBundle\DependencyInjection\Compiler;
4
5
use Dtc\QueueBundle\Model\Job;
6
use Dtc\QueueBundle\Model\Run;
7
use Pheanstalk\Pheanstalk;
8
use Symfony\Component\DependencyInjection\Alias;
9
use Symfony\Component\DependencyInjection\ContainerBuilder;
10
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
11
use Symfony\Component\DependencyInjection\Definition;
12
use Symfony\Component\DependencyInjection\Reference;
13
14
class WorkerCompilerPass implements CompilerPassInterface
15
{
16
    public function process(ContainerBuilder $container)
17
    {
18
        if (false === $container->hasDefinition('dtc_queue.worker_manager')) {
19
            return;
20
        }
21
22
        $defaultManagerType = $container->getParameter('dtc_queue.default_manager');
23
        if (!$container->hasDefinition('dtc_queue.job_manager.'.$defaultManagerType)) {
24
            throw new \Exception("No job manager found for dtc_queue.job_manager.$defaultManagerType");
25
        }
26
27
        $alias = new Alias('dtc_queue.job_manager.'.$defaultManagerType);
28
        $container->setAlias('dtc_queue.job_manager', $alias);
29
30
        // Setup beanstalkd if configuration is present
31
        $this->setupBeanstalkd($container);
32
        $this->setupRabbitMQ($container);
33
34
        $definition = $container->getDefinition('dtc_queue.worker_manager');
35
        $jobManagerRef = array(new Reference('dtc_queue.job_manager'));
36
37
        $jobClass = $this->getJobClass($container);
38
        $jobClassArchive = $this->getJobClassArchive($container);
39
        $container->setParameter('dtc_queue.class_job', $jobClass);
40
        $container->setParameter('dtc_queue.class_job_archive', $jobClassArchive);
41
        $container->setParameter('dtc_queue.class_run', $this->getRunClass($container));
42
        $container->setParameter('dtc_queue.class_run_archive', $this->getRunArchiveClass($container));
43
        // Add each worker to workerManager, make sure each worker has instance to work
44
        foreach ($container->findTaggedServiceIds('dtc_queue.worker') as $id => $attributes) {
45
            $worker = $container->getDefinition($id);
46
            $class = $container->getDefinition($id)->getClass();
47
48
            $refClass = new \ReflectionClass($class);
49
            $workerClass = 'Dtc\QueueBundle\Model\Worker';
50
            if (!$refClass->isSubclassOf($workerClass)) {
51
                throw new \InvalidArgumentException(sprintf('Service "%s" must extend class "%s".', $id, $workerClass));
52
            }
53
54
            // Give each worker access to job manager
55
            $worker->addMethodCall('setJobManager', $jobManagerRef);
56
            $worker->addMethodCall('setJobClass', array($jobClass));
57
58
            $definition->addMethodCall('addWorker', array(new Reference($id)));
59
        }
60
61
        $eventDispatcher = $container->getDefinition('dtc_queue.event_dispatcher');
62
        foreach ($container->findTaggedServiceIds('dtc_queue.event_subscriber') as $id => $attributes) {
63
            $eventSubscriber = $container->getDefinition($id);
64
            $eventDispatcher->addMethodCall('addSubscriber', [$eventSubscriber]);
65
        }
66
        $this->setupDoctrineManagers($container);
67
    }
68
69
    /**
70
     * Sets up beanstalkd instance if appropriate.
71
     *
72
     * @param ContainerBuilder $container
73
     */
74
    public function setupBeanstalkd(ContainerBuilder $container)
75
    {
76
        if ($container->hasParameter('dtc_queue.beanstalkd.host')) {
77
            $definition = new Definition('Pheanstalk\\Pheanstalk', [$container->getParameter('dtc_queue.beanstalkd.host')]);
78
            $container->setDefinition('dtc_queue.beanstalkd', $definition);
79
            $definition = $container->getDefinition('dtc_queue.job_manager.beanstalkd');
80
            $definition->addMethodCall('setBeanstalkd', [new Reference('dtc_queue.beanstalkd')]);
81
            if ($container->hasParameter('dtc_queue.beanstalkd.tube')) {
82
                $definition->addMethodCall('setTube', [$container->getParameter('dtc_queue.beanstalkd.tube')]);
83
            }
84
        }
85
    }
86
87
    public function setupDoctrineManagers(ContainerBuilder $container)
88
    {
89
        $documentManager = $container->getParameter('dtc_queue.document_manager');
90
91
        $odmManager = "doctrine_mongodb.odm.{$documentManager}_document_manager";
92
        if ($container->has($odmManager)) {
93
            $container->setAlias('dtc_queue.document_manager', $odmManager);
94
        }
95
96
        $entityManager = $container->getParameter('dtc_queue.entity_manager');
97
98
        $ormManager = "doctrine.orm.{$entityManager}_entity_manager";
99
        if ($container->has($ormManager)) {
100
            $container->setAlias('dtc_queue.entity_manager', $ormManager);
101
        }
102
    }
103
104
    /**
105
     * Sets up RabbitMQ instance if appropriate.
106
     *
107
     * @param ContainerBuilder $container
108
     */
109
    public function setupRabbitMQ(ContainerBuilder $container)
110
    {
111
        if ($container->hasParameter('dtc_queue.rabbit_mq')) {
112
            $class = 'PhpAmqpLib\\Connection\\AMQPStreamConnection';
113
            $rabbitMqConfig = $container->getParameter('dtc_queue.rabbit_mq');
114
            $arguments = [
115
                $rabbitMqConfig['host'],
116
                $rabbitMqConfig['port'],
117
                $rabbitMqConfig['user'],
118
                $rabbitMqConfig['password'],
119
                $rabbitMqConfig['vhost'],
120
            ];
121
122
            if ($container->hasParameter('dtc_queue.rabbit_mq.ssl') && $container->getParameter('dtc_queue.rabbit_mq.ssl')) {
123
                $class = 'PhpAmqpLib\\Connection\\AMQPSSLConnection';
124
                if ($container->hasParameter('dtc_queue.rabbit_mq.ssl_options')) {
125
                    $arguments[] = $container->getParameter('dtc_queue.rabbit_mq.ssl_options');
126
                } else {
127
                    $arguments[] = [];
128
                }
129
                if ($container->hasParameter('dtc_queue.rabbit_mq.options')) {
130
                    $arguments[] = $container->getParameter('dtc_queue.rabbit_mq.options');
131
                }
132
            } else {
133
                if ($container->hasParameter('dtc_queue.rabbit_mq.options')) {
134
                    $options = $container->getParameter('dtc_queue.rabbit_mq.options');
135
                    $this->setRabbitMqOptions($arguments, $options);
136
                }
137
            }
138
139
            $definition = new Definition($class, $arguments);
140
            $container->setDefinition('dtc_queue.rabbit_mq', $definition);
141
            $definition = $container->getDefinition('dtc_queue.job_manager.rabbit_mq');
142
            $definition->addMethodCall('setAMQPConnection', [new Reference('dtc_queue.rabbit_mq')]);
143
            $definition->addMethodCall('setQueueArgs', array_values($rabbitMqConfig['queue_args']));
144
            $definition->addMethodCall('setExchangeArgs', array_values($rabbitMqConfig['exchange_args']));
145
        }
146
    }
147
148
    public function setRabbitMqOptions(array &$arguments, array $options) {
149
        if (isset($options['insist'])) {
150
            $arguments[] = $options['insist'];
151
        } else {
152
            $arguments[] = false;
153
        }
154
        if (isset($options['login_method'])) {
155
            $arguments[] = $options['login_method'];
156
        } else {
157
            $arguments[] = 'AMQPLAIN';
158
        }
159
        if (isset($options['login_response'])) {
160
            $arguments[] = $options['login_response'];
161
        } else {
162
            $arguments[] = null;
163
        }
164
        if (isset($options['locale'])) {
165
            $arguments[] = $options['locale'];
166
        } else {
167
            $arguments[] = 'en_US';
168
        }
169
        if (isset($options['connection_timeout'])) {
170
            $arguments[] = $options['connection_timeout'];
171
        } else {
172
            $arguments[] = 3.0;
173
        }
174
        if (isset($options['read_write_timeout'])) {
175
            $arguments[] = $options['read_write_timeout'];
176
        } else {
177
            $arguments[] = 3.0;
178
        }
179
        if (isset($options['context'])) {
180
            $arguments[] = $options['context'];
181
        } else {
182
            $arguments[] = null;
183
        }
184
        if (isset($options['keepalive'])) {
185
            $arguments[] = $options['keepalive'];
186
        } else {
187
            $arguments[] = false;
188
        }
189
        if (isset($options['heartbeat'])) {
190
            $arguments[] = $options['heartbeat'];
191
        } else {
192
            $arguments[] = 0;
193
        }
194
    }
195
196
    /**
197
     * Determines the job class based on the queue manager type.
198
     *
199
     * @param ContainerBuilder $container
200
     *
201
     * @return mixed|string
202
     *
203
     * @throws \Exception
204
     */
205
    public function getJobClass(ContainerBuilder $container)
206
    {
207
        $jobClass = $container->getParameter('dtc_queue.class_job');
208
        if (!$jobClass) {
209
            switch ($defaultType = $container->getParameter('dtc_queue.default_manager')) {
210
                case 'mongodb':
211
                    $jobClass = 'Dtc\\QueueBundle\\Document\\Job';
212
                    break;
213
                case 'beanstalkd':
214
                    $jobClass = 'Dtc\\QueueBundle\\Beanstalkd\\Job';
215
                    break;
216
                case 'rabbit_mq':
217
                    $jobClass = 'Dtc\\QueueBundle\\RabbitMQ\\Job';
218
                    break;
219
                case 'orm':
220
                    $jobClass = 'Dtc\\QueueBundle\\Entity\\Job';
221
                    break;
222
                default:
223
                    throw new \Exception("Unknown default_manager type $defaultType - please specify a Job class in the 'class' configuration parameter");
224
            }
225
        }
226
227
        if (!class_exists($jobClass)) {
228
            throw new \Exception("Can't find Job class $jobClass");
229
        }
230
231
        $test = new $jobClass();
232
        if (!$test instanceof Job) {
233
            throw new \Exception("$jobClass must be instance of (or derived from) Dtc\\QueueBundle\\Model\\Job");
234
        }
235
236
        return $jobClass;
237
    }
238
239 View Code Duplication
    public function getRunClass(ContainerBuilder $container)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
240
    {
241
        $runClass = $container->hasParameter('dtc_queue.class_run') ? $container->getParameter('dtc_queue.class_run') : null;
242
        if (!$runClass) {
243
            switch ($defaultType = $container->getParameter('dtc_queue.default_manager')) {
0 ignored issues
show
Unused Code introduced by
$defaultType is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
244
                case 'mongodb':
245
                    $runClass = 'Dtc\\QueueBundle\\Document\\Run';
246
                    break;
247
                case 'orm':
248
                    $runClass = 'Dtc\\QueueBundle\\Entity\\Run';
249
                    break;
250
                default:
251
                    $runClass = 'Dtc\\QueueBundle\\Model\\Run';
252
            }
253
        }
254
255
        if (isset($runClass)) {
256
            if (!class_exists($runClass)) {
257
                throw new \Exception("Can't find Run class $runClass");
258
            }
259
        }
260
261
        $test = new $runClass();
262
        if (!$test instanceof Run) {
263
            throw new \Exception("$runClass must be instance of (or derived from) Dtc\\QueueBundle\\Model\\Run");
264
        }
265
266
        return $runClass;
267
    }
268
269 View Code Duplication
    public function getRunArchiveClass(ContainerBuilder $container)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
270
    {
271
        $runArchiveClass = $container->hasParameter('dtc_queue.class_run_archive') ? $container->getParameter('dtc_queue.class_run_archive') : null;
272
        if (!$runArchiveClass) {
273
            switch ($defaultType = $container->getParameter('dtc_queue.default_manager')) {
0 ignored issues
show
Unused Code introduced by
$defaultType is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
274
                case 'mongodb':
275
                    $runArchiveClass = 'Dtc\\QueueBundle\\Document\\RunArchive';
276
                    break;
277
                case 'orm':
278
                    $runArchiveClass = 'Dtc\\QueueBundle\\Entity\\RunArchive';
279
                    break;
280
                default:
281
                    $runArchiveClass = 'Dtc\\QueueBundle\\Model\\Run';
282
            }
283
        }
284
285
        if (isset($runArchiveClass)) {
286
            if (!class_exists($runArchiveClass)) {
287
                throw new \Exception("Can't find RunArchive class $runArchiveClass");
288
            }
289
        }
290
291
        $test = new $runArchiveClass();
292
        if (!$test instanceof Run) {
293
            throw new \Exception("$runArchiveClass must be instance of (or derived from) Dtc\\QueueBundle\\Model\\Run");
294
        }
295
296
        return $runArchiveClass;
297
    }
298
299
    /**
300
     * Determines the job class based on the queue manager type.
301
     *
302
     * @param ContainerBuilder $container
303
     *
304
     * @return mixed|string
305
     *
306
     * @throws \Exception
307
     */
308
    public function getJobClassArchive(ContainerBuilder $container)
309
    {
310
        $jobArchiveClass = $container->getParameter('dtc_queue.class_job_archive');
311
        if (!$jobArchiveClass) {
312
            switch ($defaultType = $container->getParameter('dtc_queue.default_manager')) {
0 ignored issues
show
Unused Code introduced by
$defaultType is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
313
                case 'mongodb':
314
                    $jobArchiveClass = 'Dtc\\QueueBundle\\Document\\JobArchive';
315
                    break;
316
                case 'orm':
317
                    $jobArchiveClass = 'Dtc\\QueueBundle\\Entity\\JobArchive';
318
                    break;
319
            }
320
        }
321
322
        if ($jobArchiveClass && !class_exists($jobArchiveClass)) {
323
            throw new \Exception("Can't find JobArchive class $jobArchiveClass");
324
        }
325
326
        if ($jobArchiveClass) {
327
            $test = new $jobArchiveClass();
328
            if (!$test instanceof Job) {
329
                throw new \Exception("$jobArchiveClass must be instance of (or derived from) Dtc\\QueueBundle\\Model\\Job");
330
            }
331
        }
332
333
        return $jobArchiveClass;
334
    }
335
}
336