Passed
Push — staging ( 189a42...513f1d )
by Patrick
02:35
created

SqsFifoQueue::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 5
c 1
b 0
f 0
nc 1
nop 8
dl 0
loc 13
ccs 6
cts 6
cp 1
crap 1
rs 10

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
namespace ShiftOneLabs\LaravelSqsFifoQueue;
4
5
use Aws\Sqs\SqsClient;
6
use BadMethodCallException;
7
use Illuminate\Support\Arr;
8
use InvalidArgumentException;
9
use Illuminate\Queue\SqsQueue;
10
use Illuminate\Mail\SendQueuedMailable;
11
use Illuminate\Notifications\SendQueuedNotifications;
12
use ShiftOneLabs\LaravelSqsFifoQueue\Contracts\Queue\Deduplicator;
13
14
class SqsFifoQueue extends SqsQueue
15
{
16
    /**
17
     * The queue name suffix.
18
     *
19
     * This property was made protected in Laravel 10x. The redefinition
20
     * here can be removed when support for < Laravel 10x is dropped.
21
     *
22
     * @var string
23
     */
24
    protected $suffix;
25
26
    /**
27
     * The message group id of the fifo pipe in the queue.
28
     *
29
     * @var string
30
     */
31
    protected $group;
32
33
    /**
34
     * The driver to generate the deduplication id for the message.
35
     *
36
     * @var string
37
     */
38
    protected $deduplicator;
39
40
    /**
41
     * The flag to check if this queue is setup for delay.
42
     *
43
     * @var bool
44
     */
45
    protected $allowDelay;
46
47
    /**
48
     * Create a new Amazon SQS queue instance.
49
     *
50
     * @param  \Aws\Sqs\SqsClient  $sqs
51
     * @param  string  $default
52
     * @param  string  $prefix
53
     * @param  string  $suffix
54
     * @param  bool  $dispatchAfterCommit
55
     * @param  string  $group
56
     * @param  string  $deduplicator
57
     * @param  bool  $allowDelay
58
     *
59
     * @return void
60
     */
61 215
    public function __construct(SqsClient $sqs, $default, $prefix = '', $suffix = '', $dispatchAfterCommit = false, $group = '', $deduplicator = '', $allowDelay = false)
62
    {
63 215
        parent::__construct($sqs, $default, $prefix, $suffix, $dispatchAfterCommit);
64
65
        /**
66
         * The suffix property on SqsQueue was not made protected until Laravel 10x.
67
         * Since it is private on the parent class, the parent constructor will
68
         * not set the property on this class, so we must do it manually.
69
         */
70 215
        $this->suffix = $suffix;
71 215
        $this->group = $group;
72 215
        $this->deduplicator = $deduplicator;
73 215
        $this->allowDelay = $allowDelay;
74
    }
75
76
    /**
77
     * Set the underlying SQS instance.
78
     *
79
     * @param  \Aws\Sqs\SqsClient  $sqs
80
     *
81
     * @return \ShiftOneLabs\LaravelSqsFifoQueue\SqsFifoQueue
82
     */
83 15
    public function setSqs(SqsClient $sqs)
84
    {
85 15
        $this->sqs = $sqs;
86
87 15
        return $this;
88
    }
89
90
    /**
91
     * Push a raw payload onto the queue.
92
     *
93
     * @param  string  $payload
94
     * @param  string|null  $queue
95
     * @param  array  $options
96
     *
97
     * @return mixed
98
     */
99 95
    public function pushRaw($payload, $queue = null, array $options = [])
100
    {
101 95
        $message = [
102 95
            'QueueUrl' => $this->getQueue($queue), 'MessageBody' => $payload, 'MessageGroupId' => $this->getMeta($payload, 'group', $this->group),
103 95
        ];
104
105 95
        if (($deduplication = $this->getDeduplicationId($payload, $queue)) !== false) {
106 45
            $message['MessageDeduplicationId'] = $deduplication;
107
        }
108
109 85
        $response = $this->sqs->sendMessage($message);
110
111 85
        return $response->get('MessageId');
112
    }
113
114
    /**
115
     * Push a new job onto the queue after (n) seconds.
116
     *
117
     * SQS FIFO queues do not allow per-message delays, but the queue itself
118
     * can be configured to delay the message. If this queue is setup for
119
     * delayed messages, push the job to the queue instead of throwing.
120
     *
121
     * @param  \DateTime|int  $delay
122
     * @param  string  $job
123
     * @param  mixed  $data
124
     * @param  string|null  $queue
125
     *
126
     * @return mixed
127
     *
128
     * @throws BadMethodCallException
129
     */
130 10
    public function later($delay, $job, $data = '', $queue = null)
131
    {
132 10
        if ($this->allowDelay) {
133 5
            return $this->push($job, $data, $queue);
134
        }
135
136 5
        throw new BadMethodCallException('FIFO queues do not support per-message delays.');
137
    }
138
139
    /**
140
     * Get the deduplication id for the given driver.
141
     *
142
     * @param  string  $payload
143
     * @param  string  $queue
144
     *
145
     * @return string|bool
146
     *
147
     * @throws InvalidArgumentException
148
     */
149 95
    protected function getDeduplicationId($payload, $queue)
150
    {
151 95
        $driver = $this->getMeta($payload, 'deduplicator', $this->deduplicator);
152
153 95
        if (empty($driver)) {
154 35
            return false;
155
        }
156
157 60
        if ($this->container->bound($key = 'queue.sqs-fifo.deduplicator.'.$driver)) {
158 55
            $deduplicator = $this->container->make($key);
159
160 55
            if ($deduplicator instanceof Deduplicator) {
161 50
                return $deduplicator->generate($payload, $queue);
162
            }
163
164 5
            throw new InvalidArgumentException(sprintf('Deduplication method [%s] must resolve to a %s implementation.', $driver, Deduplicator::class));
165
        }
166
167 5
        throw new InvalidArgumentException(sprintf('Unsupported deduplication method [%s].', $driver));
168
    }
169
170
    /**
171
     * Create a payload array from the given job and data.
172
     *
173
     * @param  string|object  $job
174
     * @param  string  $queue
175
     * @param  mixed  $data
176
     *
177
     * @return array
178
     */
179 55
    protected function createPayloadArray($job, $queue, $data = '')
180
    {
181 55
        return array_merge(
182 55
            parent::createPayloadArray($job, $queue, $data),
183 55
            $this->getMetaPayload($job)
184 55
        );
185
    }
186
187
    /**
188
     * Get the meta data to add to the payload.
189
     *
190
     * @param  mixed  $job
191
     *
192
     * @return array
193
     */
194 55
    protected function getMetaPayload($job)
195
    {
196 55
        if (!is_object($job)) {
197 15
            return [];
198
        }
199
200 40
        if ($job instanceof SendQueuedNotifications) {
201 10
            $queueable = $job->notification;
202 30
        } elseif ($job instanceof SendQueuedMailable) {
203 10
            $queueable = $job->mailable;
204
        } else {
205 20
            $queueable = $job;
206
        }
207
208 40
        return array_filter(
209 40
            [
210 40
                'group' => isset($queueable->messageGroupId) ? $queueable->messageGroupId : null,
211 40
                'deduplicator' => isset($queueable->deduplicator) ? $queueable->deduplicator : null,
212 40
            ],
213 40
            function ($value) {
214 40
                return $value !== null;
215 40
            }
216 40
        );
217
    }
218
219
    /**
220
     * Get additional meta from a payload string.
221
     *
222
     * @param  string  $payload
223
     * @param  string  $key
224
     * @param  mixed  $default
225
     *
226
     * @return mixed
227
     */
228 95
    protected function getMeta($payload, $key, $default = null)
229
    {
230 95
        $payload = json_decode($payload, true);
231
232 95
        return Arr::get($payload, $key, $default);
233
    }
234
}
235