Completed
Pull Request — master (#362)
by Maxence
01:50
created

GSUpstreamService::getInstances()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 27
rs 9.488
c 0
b 0
f 0
cc 3
nc 3
nop 1
1
<?php declare(strict_types=1);
2
3
4
/**
5
 * Circles - Bring cloud-users closer together.
6
 *
7
 * This file is licensed under the Affero General Public License version 3 or
8
 * later. See the COPYING file.
9
 *
10
 * @author Maxence Lange <[email protected]>
11
 * @copyright 2017
12
 * @license GNU AGPL version 3 or any later version
13
 *
14
 * This program is free software: you can redistribute it and/or modify
15
 * it under the terms of the GNU Affero General Public License as
16
 * published by the Free Software Foundation, either version 3 of the
17
 * License, or (at your option) any later version.
18
 *
19
 * This program is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 * GNU Affero General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU Affero General Public License
25
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
26
 *
27
 */
28
29
30
namespace OCA\Circles\Service;
31
32
33
use daita\MySmallPhpTools\Exceptions\RequestContentException;
34
use daita\MySmallPhpTools\Exceptions\RequestNetworkException;
35
use daita\MySmallPhpTools\Exceptions\RequestResultNotJsonException;
36
use daita\MySmallPhpTools\Exceptions\RequestResultSizeException;
37
use daita\MySmallPhpTools\Exceptions\RequestServerException;
38
use daita\MySmallPhpTools\Model\Request;
39
use daita\MySmallPhpTools\Traits\TArrayTools;
40
use daita\MySmallPhpTools\Traits\TRequest;
41
use Exception;
42
use OCA\Circles\Db\CirclesRequest;
43
use OCA\Circles\Db\GSEventsRequest;
44
use OCA\Circles\Exceptions\GlobalScaleEventException;
45
use OCA\Circles\Exceptions\GSStatusException;
46
use OCA\Circles\Exceptions\JsonException;
47
use OCA\Circles\Exceptions\ModelException;
48
use OCA\Circles\Exceptions\TokenDoesNotExistException;
49
use OCA\Circles\Model\GlobalScale\GSEvent;
50
use OCA\Circles\Model\GlobalScale\GSWrapper;
51
use OCP\IURLGenerator;
52
53
54
/**
55
 * Class GSUpstreamService
56
 *
57
 * @package OCA\Circles\Service
58
 */
59
class GSUpstreamService {
60
61
62
	use TRequest;
63
	use TArrayTools;
64
65
66
	/** @var string */
67
	private $userId = '';
68
69
	/** @var IURLGenerator */
70
	private $urlGenerator;
71
72
	/** @var GSEventsRequest */
73
	private $gsEventsRequest;
74
75
	/** @var CirclesRequest */
76
	private $circlesRequest;
77
78
	/** @var GlobalScaleService */
79
	private $globalScaleService;
80
81
	/** @var ConfigService */
82
	private $configService;
83
84
	/** @var MiscService */
85
	private $miscService;
86
87
88
	/**
89
	 * GSUpstreamService constructor.
90
	 *
91
	 * @param $userId
92
	 * @param IURLGenerator $urlGenerator
93
	 * @param GSEventsRequest $gsEventsRequest
94
	 * @param CirclesRequest $circlesRequest
95
	 * @param GlobalScaleService $globalScaleService
96
	 * @param ConfigService $configService
97
	 * @param MiscService $miscService
98
	 */
99
	public function __construct(
100
		$userId,
101
		IURLGenerator $urlGenerator,
102
		GSEventsRequest $gsEventsRequest,
103
		CirclesRequest $circlesRequest,
104
		GlobalScaleService $globalScaleService,
105
		ConfigService $configService,
106
		MiscService $miscService
107
	) {
108
		$this->userId = $userId;
109
		$this->urlGenerator = $urlGenerator;
110
		$this->gsEventsRequest = $gsEventsRequest;
111
		$this->circlesRequest = $circlesRequest;
112
		$this->globalScaleService = $globalScaleService;
113
		$this->configService = $configService;
114
		$this->miscService = $miscService;
115
	}
116
117
118
	/**
119
	 * @param GSEvent $event
120
	 *
121
	 * @throws Exception
122
	 */
123
	public function newEvent(GSEvent $event) {
124
		try {
125
			$gs = $this->globalScaleService->getGlobalScaleEvent($event);
126
//		if (!$this->configService->getGSStatus(ConfigService::GS_ENABLED)) {
127
//			return true;
128
//		}
129
130
			$this->fillEvent($event);
131
			if ($this->isLocalEvent($event)) {
132
				$gs->verify($event, true);
133
				$gs->manage($event);
134
135
				$this->globalScaleService->asyncBroadcast($event);
136
			} else {
137
				$gs->verify($event);
138
				$this->confirmEvent($event);
139
				$gs->manage($event);
140
			}
141
		} catch (Exception $e) {
142
			$this->miscService->log(
143
				get_class($e) . ' on new event: ' . $e->getMessage() . ' - ' . json_encode($event), 1
144
			);
145
			throw $e;
146
		}
147
	}
148
149
150
	/**
151
	 * @param string $protocol
152
	 * @param GSEvent $event
153
	 *
154
	 * @throws GSStatusException
155
	 */
156
	public function broadcastEvent(string $protocol, GSEvent $event): void {
157
		$this->signEvent($event);
158
159
		$path = $this->urlGenerator->linkToRoute('circles.GlobalScale.broadcast');
160
		$request = new Request($path, Request::TYPE_POST);
161
		$request->setProtocol($protocol);
162
		$request->setDataSerialize($event);
163
164
		foreach ($this->getInstances() as $instance) {
165
			$request->setAddress($instance);
166
167
			try {
168
				$this->doRequest($request);
169
			} catch (RequestContentException | RequestNetworkException | RequestResultSizeException | RequestServerException $e) {
170
				// TODO: queue request
171
			}
172
		}
173
174
	}
175
176
177
	/**
178
	 * @param GSEvent $event
179
	 *
180
	 * @throws RequestContentException
181
	 * @throws RequestNetworkException
182
	 * @throws RequestResultSizeException
183
	 * @throws RequestServerException
184
	 * @throws RequestResultNotJsonException
185
	 * @throws GlobalScaleEventException
186
	 */
187
	public function confirmEvent(GSEvent $event): void {
188
		$this->signEvent($event);
189
190
		$circle = $event->getCircle();
191
		$owner = $circle->getOwner();
192
//$instance = $this->configService->getLocalCloudId();
193
//$instance = $owner->getInstance();
194
//$instance = ($instance === '') ?
195
		$path = $this->urlGenerator->linkToRoute('circles.GlobalScale.event');
196
197
		$request = new Request($path, Request::TYPE_POST);
198
		$request->setProtocol($_SERVER['REQUEST_SCHEME']);
199
		$request->setAddressFromUrl($owner->getInstance());
200
		$request->setDataSerialize($event);
201
202
		$result = $this->retrieveJson($request);
203
		$this->miscService->log('result ' . json_encode($result));
204
		if ($this->getInt('status', $result) === 0) {
205
			throw new GlobalScaleEventException($this->get('error', $result));
206
		}
207
	}
208
209
210
	/**
211
	 * @param GSEvent $event
212
	 *
213
	 * @throws GSStatusException
214
	 */
215
	private function fillEvent(GSEvent $event): void {
216
		if (!$this->configService->getGSStatus(ConfigService::GS_ENABLED)) {
217
			return;
218
		}
219
220
		$event->setSource($this->configService->getLocalCloudId());
221
	}
222
223
	/**
224
	 * @param string $protocol
0 ignored issues
show
Bug introduced by
There is no parameter named $protocol. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
225
	 * @param bool $all
226
	 *
227
	 * @return array
228
	 * @throws GSStatusException
229
	 */
230
	public function getInstances(bool $all = false): array {
231
		/** @var string $lookup */
232
		$lookup = $this->configService->getGSStatus(ConfigService::GS_LOOKUP);
233
234
		$request = new Request('/instances', Request::TYPE_GET);
235
		$request->setAddressFromUrl($lookup);
236
237
		try {
238
			$instances = $this->retrieveJson($request);
239
		} catch (
240
		RequestContentException |
241
		RequestNetworkException |
242
		RequestResultSizeException |
243
		RequestServerException |
244
		RequestResultNotJsonException $e
245
		) {
246
			$this->miscService->log('Issue while retrieving instances from lookup: ' . $e->getMessage());
247
248
			return [];
249
		}
250
251
		if ($all) {
252
			return $instances;
253
		}
254
255
		return array_diff($instances, $this->configService->getTrustedDomains());
256
	}
257
258
259
	/**
260
	 * @param GSEvent $event
261
	 */
262
	private function signEvent(GSevent $event) {
263
		$event->setKey($this->globalScaleService->getKey());
264
	}
265
266
267
	/**
268
	 * @param GSEvent $event
269
	 *asyncBroadcast
270
	 *
271
	 * @return bool
272
	 */
273
	private function isLocalEvent(GSEvent $event): bool {
274
		if ($event->isLocal()) {
275
			return true;
276
		}
277
278
		$circle = $event->getCircle();
279
		$owner = $circle->getOwner();
280
		if ($owner->getInstance() === ''
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return $owner->getInstan...->getTrustedDomains());.
Loading history...
281
			|| in_array(
282
				$owner->getInstance(), $this->configService->getTrustedDomains()
283
			)) {
284
			return true;
285
		}
286
287
		return false;
288
	}
289
290
291
	/**
292
	 * @param string $token
293
	 *
294
	 * @return GSWrapper
295
	 * @throws JsonException
296
	 * @throws ModelException
297
	 * @throws TokenDoesNotExistException
298
	 */
299
	public function getEventByToken(string $token): GSWrapper {
300
		return $this->gsEventsRequest->getByToken($token);
301
	}
302
303
}
304
305