Completed
Push — master ( 9b5563...bf775b )
by Timo
04:56 queued 01:35
created

ClientSessionStub::respondToCall()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 11
Ratio 100 %

Importance

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