Completed
Pull Request — master (#12)
by Timo
03:14
created

ClientSessionStub   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 273
Duplicated Lines 16.85 %

Coupling/Cohesion

Components 5
Dependencies 6

Importance

Changes 7
Bugs 0 Features 4
Metric Value
wmc 20
c 7
b 0
f 4
lcom 5
cbo 6
dl 46
loc 273
rs 10

14 Methods

Rating   Name   Duplication   Size   Complexity  
A subscribe() 0 10 1
A completeSubscription() 13 13 2
A publish() 0 8 1
A confirmPublication() 11 11 2
A register() 0 13 1
A confirmRegistration() 0 11 2
A callRegistration() 0 10 2
A unregister() 0 11 1
A confirmUnregistration() 11 11 2
A call() 0 10 1
A respondToCall() 11 11 2
A setSessionId() 0 4 1
A getSessionId() 0 4 1
A getUniqueId() 0 8 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
namespace Tidal\WampWatch\Stub;
3
4
5
/*
6
 * Copyright 2016 Timo Michna.
7
 *
8
 * For the full copyright and license information, please view the LICENSE file
9
 * that was distributed with this source code.
10
 */
11
12
use Thruway\Message\SubscribedMessage;
13
use Thruway\Message\PublishedMessage;
14
use Thruway\Message\RegisteredMessage;
15
use Thruway\Message\UnregisteredMessage;
16
use Evenement\EventEmitterInterface;
17
use Evenement\EventEmitterTrait;
18
use React\Promise\Deferred;
19
20
use Tidal\WampWatch\ClientSessionInterface;
21
22
/**
23
 * Class ClientSessionStub
24
 *
25
 * @package Tidal\WampWatch\Stub
26
 *
27
 * !!! WARNING !!!!
28
 * This Class should only be used for testing or demos.
29
 * It allows for testing client method calls but behaves differently to
30
 * real client session implementation in that it only stores one (the last)
31
 * subscription, registration etc. for a specific topic/procedure.
32
 *
33
 */
34
class ClientSessionStub implements ClientSessionInterface, EventEmitterInterface
35
{
36
37
    use EventEmitterTrait;
38
39
    protected $sessionId;
40
41
    protected $subscriptions = [];
42
43
    protected $publications = [];
44
45
    protected $registrations = [];
46
47
    protected $unregistrations = [];
48
49
    protected $calls = [];
50
51
    protected $procedures = [];
52
53
54
55
    /**
56
     * Subscribe.
57
     *
58
     * @param string   $topicName
59
     * @param callable $callback
60
     * @param          $options array
61
     * @return \React\Promise\Promise
62
     */
63
    public function subscribe($topicName, callable $callback, $options = null)
64
    {
65
        $this->on($topicName, $callback);
66
67
        $futureResult = new Deferred();
68
69
        $this->subscriptions[$topicName] = $futureResult;
70
71
        return $futureResult->promise();
72
    }
73
74
    /**
75
     * Trigger a SUBSCRIBED message for given topic.
76
     *
77
     * @param $topicName
78
     * @param $requestId
79
     * @param $sessionId
80
     * @throws \RuntimeException if the topic is unknown.
81
     */
82 View Code Duplication
    public function completeSubscription($topicName, $requestId = 1, $sessionId = 1)
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...
83
    {
84
        if (!isset($this->subscriptions[$topicName])) {
85
            throw new \RuntimeException("No subscription to topic '$topicName' initiated.");
86
        }
87
88
        /* @var $futureResult Deferred */
89
        $futureResult = $this->subscriptions[$topicName];
90
        $result = new SubscribedMessage($requestId, $sessionId);
91
92
        $futureResult->resolve($result);
93
94
    }
95
96
97
    /**
98
     * Publish.
99
     *
100
     * @param string      $topicName
101
     * @param array|mixed $arguments
102
     * @param array|mixed $argumentsKw
103
     * @param array|mixed $options
104
     * @return \React\Promise\Promise
105
     */
106
    public function publish($topicName, $arguments = null, $argumentsKw = null, $options = null)
107
    {
108
        $futureResult = new Deferred();
109
110
        $this->publications[$topicName] = $futureResult;
111
112
        return $futureResult->promise();
113
    }
114
115
    /**
116
     * Trigger a PUBLISHED message for given topic.
117
     *
118
     * @param string $topicName
119
     * @param int    $requestId
120
     * @param int    $publicationId
121
     * @throws \RuntimeException if the topic is unknown.
122
     */
123 View Code Duplication
    public function confirmPublication($topicName, $requestId = 1, $publicationId = 1)
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...
124
    {
125
        if (!isset($this->publications[$topicName])) {
126
            throw new \RuntimeException("No publication to topic '$topicName' initiated.");
127
        }
128
129
        $futureResult = $this->publications[$topicName];
130
        $result = new PublishedMessage($requestId, $publicationId);
131
132
        $futureResult->resolve($result);
133
    }
134
135
136
    /**
137
     * Register.
138
     *
139
     * @param string      $procedureName
140
     * @param callable    $callback
141
     * @param array|mixed $options
142
     * @return \React\Promise\Promise
143
     */
144
    public function register($procedureName, callable $callback, $options = null)
145
    {
146
147
        $this->procedures[$procedureName] = $callback;
148
149
        $futureResult = new Deferred();
150
151
        $this->registrations[$procedureName] = $futureResult;
152
153
154
        return $futureResult->promise();
155
156
    }
157
158
    /**
159
     * Trigger a REGISTERED message for given procedure.
160
     *
161
     * @param string $procedureName
162
     * @param int    $requestId
163
     * @param int    $registrationId
164
     * @throws \RuntimeException if the procedure is unknown.
165
     */
166
    public function confirmRegistration($procedureName, $requestId = 1, $registrationId = 1)
167
    {
168
        if (!isset($this->registrations[$procedureName])) {
169
            throw new \RuntimeException("No registration to procedure '$procedureName' initiated.");
170
        }
171
172
        $futureResult = $this->registrations[$procedureName];
173
        $result = new RegisteredMessage($requestId, $registrationId);
174
175
        $futureResult->resolve($result);
176
    }
177
178
    /**
179
     * Triggers a call to a registered procedure and returns its result.
180
     *
181
     * @param string $procedureName
182
     * @param array  $args
183
     * @return mixed    the procedure result
184
     * @throws \RuntimeException if the procedure is unknown.
185
     */
186
    public function callRegistration($procedureName, array $args = [])
187
    {
188
        if (!isset($this->procedures[$procedureName])) {
189
            throw new \RuntimeException("No registration for procedure '$procedureName'.");
190
        }
191
192
        $procedure = $this->procedures[$procedureName];
193
194
        return $procedure($args);
195
    }
196
197
198
    /**
199
     * Unregister.
200
     *
201
     * @param string $procedureName
202
     *
203
     * @return \React\Promise\Promise|false
204
     */
205
    public function unregister($procedureName)
206
    {
207
208
        $futureResult = new Deferred();
209
210
        $this->unregistrations[$procedureName] = $futureResult;
211
212
213
        return $futureResult->promise();
214
215
    }
216
217
    /**
218
     * Triggers a UNREGISTERED message for given procedure.
219
     *
220
     * @param string $procedureName
221
     * @param int    $requestId
222
     */
223 View Code Duplication
    public function confirmUnregistration($procedureName, $requestId = 1)
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...
224
    {
225
        if (!isset($this->unregistrations[$procedureName])) {
226
            throw new \RuntimeException("No registration to procedure '$procedureName' initiated.");
227
        }
228
229
        $futureResult = $this->unregistrations[$procedureName];
230
        $result = new UnregisteredMessage($requestId);
231
232
        $futureResult->resolve($result);
233
    }
234
235
    /**
236
     * Call.
237
     *
238
     * @param string      $procedureName
239
     * @param array|mixed $arguments
240
     * @param array|mixed $argumentsKw
241
     * @param array|mixed $options
242
     * @return \React\Promise\Promise
243
     */
244
    public function call($procedureName, $arguments = null, $argumentsKw = null, $options = null)
245
    {
246
247
        $futureResult = new Deferred();
248
249
        $this->calls[$procedureName] = $futureResult;
250
251
        return $futureResult->promise();
252
253
    }
254
255
256
    /**
257
     * Process ResultMessage
258
     *
259
     * @param string    $procedureName
260
     * @param \stdClass $result
261
     */
262 View Code Duplication
    public function respondToCall($procedureName, $result)
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...
263
    {
264
        if (!isset($this->calls[$procedureName])) {
265
            throw new \RuntimeException("No call to topic '$procedureName' initiated.");
266
        }
267
268
        /* @var $futureResult Deferred */
269
        $futureResult = $this->calls[$procedureName];
270
271
        $futureResult->resolve($result);
272
    }
273
274
275
    /**
276
     * @param int $sessionId
277
     */
278
    public function setSessionId($sessionId)
279
    {
280
        $this->sessionId = $sessionId;
281
    }
282
283
    /**
284
     * @return int the Session Id
285
     */
286
    public function getSessionId()
287
    {
288
        return $this->sessionId;
289
    }
290
291
    /**
292
     * Generate a unique id for sessions and requests
293
     *
294
     * @return mixed
295
     */
296
    public static function getUniqueId()
297
    {
298
        $filter = 0x1fffffffffffff; // 53 bits
299
        $randomBytes = openssl_random_pseudo_bytes(8);
300
        list($high, $low) = array_values(unpack("N2", $randomBytes));
301
302
        return abs(($high << 32 | $low) & $filter);
303
    }
304
305
306
}