Passed
Push — master ( de28ef...ff0ea2 )
by Tilita
02:12
created

ExchangeEntity::reconnect()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 3
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
1
<?php
2
namespace NeedleProject\LaravelRabbitMq\Entity;
3
4
use NeedleProject\LaravelRabbitMq\AMQPConnection;
5
use NeedleProject\LaravelRabbitMq\PublisherInterface;
6
use PhpAmqpLib\Channel\AMQPChannel;
7
use PhpAmqpLib\Exception\AMQPProtocolChannelException;
8
use PhpAmqpLib\Message\AMQPMessage;
9
10
/**
11
 * Class ExchangeEntity
12
 *
13
 * @package NeedleProject\LaravelRabbitMq\Entity
14
 * @author  Adrian Tilita <[email protected]>
15
 */
16
class ExchangeEntity implements PublisherInterface, AMQPEntityInterface
17
{
18
    /**
19
     * @const array Default connections parameters
20
     */
21
    const DEFAULTS = [
22
        'exchange_type'                => 'topic',
23
        // Whether to check if it exists or to verify existance using argument types (Throws PRECONDITION_FAILED)
24
        'passive'                      => false,
25
        // Entities with durable will be re-created uppon server restart
26
        'durable'                      => false,
27
        // Whether to delete it when no queues ar bind to it
28
        'auto_delete'                  => false,
29
        // Whether the exchange can be used by a publisher or block it (declared just for internal "wiring")
30
        'internal'                     => false,
31
        // Whether to receive a Declare confirmation
32
        'nowait'                       => false,
33
        // Whether to auto create the entity before publishing/consuming it
34
        'auto_create'                  => false,
35
        // whether to "hide" the exception on re-declare.
36
        // if the `passive` filter is set true, this is redundant
37
        'throw_exception_on_redeclare' => true,
38
        // whether to throw on exception when trying to
39
        // bind to an in-existent queue/exchange
40
        'throw_exception_on_bind_fail' => true,
41
    ];
42
43
    /**
44
     * @var AMQPConnection
45
     */
46
    protected $connection;
47
48
    /**
49
     * @var string
50
     */
51
    protected $aliasName;
52
53
    /**
54
     * @var array
55
     */
56
    protected $attributes;
57
58
    /**
59
     * ExchangeEntity constructor.
60
     *
61
     * @param AMQPConnection $connection
62
     * @param string $aliasName
63
     * @param array $attributes
64
     */
65 13
    public function __construct(AMQPConnection $connection, string $aliasName, array $attributes = [])
66
    {
67 13
        $this->connection = $connection;
68 13
        $this->aliasName  = $aliasName;
69 13
        $this->attributes = $attributes;
70 13
    }
71
72
    /**
73
     * @param AMQPConnection $connection
74
     * @param string $aliasName
75
     * @param array $exchangeDetails
76
     * @return ExchangeEntity
77
     */
78 13
    public static function createExchange(AMQPConnection $connection, string $aliasName, array $exchangeDetails)
79
    {
80 13
        return new static(
81
            $connection,
82
            $aliasName,
83 13
            array_merge(self::DEFAULTS, $exchangeDetails)
84
        );
85
    }
86
87
    /**
88
     * @return string
89
     */
90 2
    public function getAliasName(): string
91
    {
92 2
        return $this->aliasName;
93
    }
94
95
    /**
96
     * @return AMQPConnection
97
     */
98 8
    protected function getConnection(): AMQPConnection
99
    {
100 8
        return $this->connection;
101
    }
102
103
    /**
104
     * @return AMQPChannel
105
     */
106 8
    protected function getChannel(): AMQPChannel
107
    {
108 8
        return $this->getConnection()->getChannel();
109
    }
110
111
    /**
112
     * Create the Queue
113
     */
114 4 View Code Duplication
    public function create()
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...
115
    {
116
        try {
117 4
            $this->getChannel()
118 4
                ->exchange_declare(
119 4
                    $this->attributes['name'],
120 4
                    $this->attributes['exchange_type'],
121 4
                    $this->attributes['passive'],
122 4
                    $this->attributes['durable'],
123 4
                    $this->attributes['auto_delete'],
124 4
                    $this->attributes['internal'],
125 4
                    $this->attributes['nowait']
126
                );
127 2
        } catch (AMQPProtocolChannelException $e) {
128
            // 406 is a soft error triggered for precondition failure (when redeclaring with different parameters)
129 2
            if (true === $this->attributes['throw_exception_on_redeclare'] || $e->amqp_reply_code !== 406) {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison !== seems to always evaluate to true as the types of $e->amqp_reply_code (string) and 406 (integer) can never be identical. Maybe you want to use a loose comparison != instead?
Loading history...
130 1
                throw $e;
131
            }
132
            // a failure trigger channels closing process
133 1
            $this->getConnection()->reconnect();
134
        }
135 3
    }
136
137
    /**
138
     * @throws AMQPProtocolChannelException
139
     */
140 3 View Code Duplication
    public function bind()
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...
141
    {
142 3
        if (!isset($this->attributes['bind']) || empty($this->attributes['bind'])) {
143 1
            return;
144
        }
145 2
        foreach ($this->attributes['bind'] as $bindItem) {
146
            try {
147 2
                $this->getChannel()
148 2
                    ->queue_bind(
149 2
                        $bindItem['queue'],
150 2
                        $this->attributes['name'],
151 2
                        $bindItem['routing_key']
152
                    );
153
            } catch (AMQPProtocolChannelException $e) {
154
                // 404 is the code for trying to bind to an non-existing entity
155
                if (true === $this->attributes['throw_exception_on_bind_fail'] || $e->amqp_reply_code !== 404) {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison !== seems to always evaluate to true as the types of $e->amqp_reply_code (string) and 404 (integer) can never be identical. Maybe you want to use a loose comparison != instead?
Loading history...
156
                    throw $e;
157
                }
158 2
                $this->getConnection()->reconnect();
159
            }
160
        }
161 2
    }
162
163
    /**
164
     * Delete the queue
165
     */
166 1
    public function delete()
167
    {
168 1
        $this->getChannel()->exchange_delete($this->attributes['name']);
169 1
    }
170
171
    /**
172
     * {@inheritdoc}
173
     */
174
    public function reconnect()
175
    {
176
        $this->getConnection()->reconnect();
177
    }
178
179
    /**
180
     * Publish a message
181
     *
182
     * @param string $message
183
     * @param string $routingKey
184
     * @return mixed|void
185
     * @throws AMQPProtocolChannelException
186
     */
187 3 View Code Duplication
    public function publish(string $message, string $routingKey = '')
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...
188
    {
189 3
        if ($this->attributes['auto_create'] === true) {
190 1
            $this->create();
191 1
            $this->bind();
192
        }
193 3
        $this->getChannel()->basic_publish(
194 3
            new AMQPMessage($message),
195 3
            $this->attributes['name'],
196
            $routingKey,
197 3
            true
198
        );
199 3
    }
200
}
201