Completed
Push — master ( f58be8...855521 )
by Tilita
03:07
created

SetupCommand::createEntity()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 28
ccs 0
cts 27
cp 0
rs 9.472
c 0
b 0
f 0
cc 4
nc 2
nop 4
crap 20
1
<?php
2
namespace NeedleProject\LaravelRabbitMq\Command;
3
4
use Illuminate\Console\Command;
5
use NeedleProject\LaravelRabbitMq\ConsumerInterface;
6
use NeedleProject\LaravelRabbitMq\Container;
7
use NeedleProject\LaravelRabbitMq\Entity\AMQPEntityInterface;
8
use NeedleProject\LaravelRabbitMq\Entity\ExchangeEntity;
9
use NeedleProject\LaravelRabbitMq\Entity\QueueEntity;
10
use PhpAmqpLib\Exception\AMQPProtocolChannelException;
11
12
/**
13
 * Class SetupCommand
14
 *
15
 * @package NeedleProject\LaravelRabbitMq\Commad
16
 * @author  Adrian Tilita <[email protected]>
17
 */
18
class SetupCommand extends Command
19
{
20
    /**
21
     * The name and signature of the console command.
22
     *
23
     * @var string
24
     */
25
    protected $signature = 'rabbitmq:setup {--force}';
26
27
    /**
28
     * The console command description.
29
     *
30
     * @var string
31
     */
32
    protected $description = 'Create all queues, exchanges and binds that are defined in entities AND referenced to' .
33
        ' either a publisher or a consumer';
34
35
    /**
36
     * @var Container
37
     */
38
    private $container;
39
40
    /**
41
     * CreateEntitiesCommand constructor.
42
     *
43
     * @param Container $container
44
     */
45
    public function __construct(Container $container)
46
    {
47
        $this->container = $container;
48
        parent::__construct();
49
    }
50
51
    /**
52
     * @param AMQPEntityInterface $entity
53
     * @param string $type
54
     * @param string $resourceName
55
     * @param bool $forceRecreate
56
     */
57
    private function createEntity(
58
        AMQPEntityInterface $entity,
59
        string $type,
60
        string $resourceName,
61
        bool $forceRecreate = false
62
    ) {
63
        if (true === $forceRecreate) {
64
            $this->output->writeln(
65
                sprintf(
66
                    "Deleting <info>%s</info> <fg=yellow>%s</>",
67
                    (string)($entity instanceof QueueEntity) ? 'QUEUE' : 'EXCHANGE',
68
                    (string)$entity->getAliasName()
69
                )
70
            );
71
            $entity->delete();
72
        }
73
74
        $entity->create();
75
        $this->output->writeln(
76
            sprintf(
77
                "Created <info>%s</info> <fg=yellow>%s</> for %s [<fg=yellow>%s</>]",
78
                (string)($entity instanceof QueueEntity) ? 'QUEUE' : 'EXCHANGE',
79
                (string)$entity->getAliasName(),
80
                (string)$type,
81
                (string)$resourceName
82
            )
83
        );
84
    }
85
86
    /**
87
     * Execute the console command.
88
     */
89
    public function handle()
90
    {
91
        $forceRecreate = $this->input->getOption('force');
92
93
        $hasErrors = false;
94
        /** @var QueueEntity|ExchangeEntity $entity */
95 View Code Duplication
        foreach ($this->container->getPublishers() as $publisherName => $entity) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
96
            try {
97
                $this->createEntity($entity, 'publisher', $publisherName, $forceRecreate);
98
            } catch (AMQPProtocolChannelException $e) {
99
                $hasErrors = true;
100
                $this->output->error(
101
                    sprintf(
102
                        "Could not create entity %s for publisher [%s], got:\n%s",
103
                        (string)$entity->getAliasName(),
104
                        (string)$publisherName,
105
                        (string)$e->getMessage()
106
                    )
107
                );
108
                // @todo Fix type mismatch
109
                $entity->getConnection()->reconnect();
110
            }
111
        }
112
113
        /** @var QueueEntity|ExchangeEntity $entity */
114 View Code Duplication
        foreach ($this->container->getConsumers() as $publisherName => $entity) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
115
            try {
116
                $this->createEntity($entity, 'consumer', $publisherName, $forceRecreate);
117
            } catch (AMQPProtocolChannelException $e) {
118
                $hasErrors = true;
119
                $this->output->error(
120
                    sprintf(
121
                        "Could not create entity %s for consumer [%s], got:\n%s",
122
                        (string)$entity->getAliasName(),
123
                        (string)$publisherName,
124
                        (string)$e->getMessage()
125
                    )
126
                );
127
                // @todo Fix type mismatch
128
                $entity->getConnection()->reconnect();
129
            }
130
        }
131
132
        $this->output->block("Create binds");
133
        /** @var PublisherInterface $entity */
134
        foreach ($this->container->getPublishers() as $publisherName => $entity) {
135
            try {
136
                $entity->bind();
137
                $this->output->writeln(
138
                    sprintf(
139
                        "Created bind <info>%s</info> for publisher [<fg=yellow>%s</>]",
140
                        (string)$entity->getAliasName(),
141
                        (string)$publisherName
142
                    )
143
                );
144
            } catch (\Exception $e) {
145
                $hasErrors = true;
146
                $this->output->error(
147
                    sprintf(
148
                        "Could not bind entity %s for publisher [%s], got:\n%s",
149
                        (string)$entity->getAliasName(),
150
                        (string)$publisherName,
151
                        (string)$e->getMessage()
152
                    )
153
                );
154
            }
155
        }
156
157
        /** @var ConsumerInterface $entity */
158 View Code Duplication
        foreach ($this->container->getConsumers() as $consumerAliasName => $entity) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
159
            try {
160
                $entity->bind();
161
                $this->output->writeln(
162
                    sprintf(
163
                        "Bind entity <info>%s</info> for consumer [<fg=yellow>%s</>]",
164
                        (string)$entity->getAliasName(),
165
                        (string)$consumerAliasName
166
                    )
167
                );
168
            } catch (\Exception $e) {
169
                $hasErrors = true;
170
                $this->output->error(
171
                    sprintf(
172
                        "Could not create bind %s for consumer [%s], got:\n%s",
173
                        (string)$entity->getAliasName(),
174
                        (string)$consumerAliasName,
175
                        (string)$e->getMessage()
176
                    )
177
                );
178
            }
179
        }
180
        return (int)$hasErrors;
181
    }
182
}
183