1 | <?php |
||
2 | |||
3 | namespace BiffBangPow\SSMonitor\Server\Task; |
||
4 | |||
5 | use BiffBangPow\SSMonitor\Server\Helper\ClientHelper; |
||
6 | use BiffBangPow\SSMonitor\Server\Helper\CommsHelper; |
||
7 | use BiffBangPow\SSMonitor\Server\Helper\EncryptionHelper; |
||
8 | use BiffBangPow\SSMonitor\Server\Model\Client; |
||
9 | use Psr\Log\LoggerInterface; |
||
10 | use SilverStripe\Core\Config\Configurable; |
||
11 | use SilverStripe\Core\Environment; |
||
12 | use SilverStripe\Core\Extensible; |
||
13 | use SilverStripe\Core\Injector\Injector; |
||
14 | use SilverStripe\ORM\FieldType\DBDatetime; |
||
15 | use Symbiote\QueuedJobs\Services\AbstractQueuedJob; |
||
16 | use Symbiote\QueuedJobs\Services\QueuedJobService; |
||
17 | |||
18 | |||
19 | class PollClientsTask extends AbstractQueuedJob |
||
20 | { |
||
21 | use Configurable; |
||
22 | use Extensible; |
||
23 | |||
24 | /** |
||
25 | * @config |
||
26 | * @var int |
||
27 | */ |
||
28 | private static $requeue_delay = 180; |
||
0 ignored issues
–
show
introduced
by
![]() |
|||
29 | |||
30 | public function __construct() |
||
31 | { |
||
32 | |||
33 | } |
||
34 | |||
35 | public function getTitle() |
||
36 | { |
||
37 | return "BBP Monitoring - Collect data"; |
||
38 | } |
||
39 | |||
40 | public function process() |
||
41 | { |
||
42 | $helper = new CommsHelper(); |
||
43 | $res = $helper->process(); |
||
44 | |||
45 | if (is_array($res)) { |
||
46 | $this->updateClients($res); |
||
47 | } else { |
||
48 | $this->addMessage($res); |
||
49 | } |
||
50 | |||
51 | $this->isComplete = true; |
||
52 | $this->addMessage('Done'); |
||
53 | } |
||
54 | |||
55 | /** |
||
56 | * @param array $res |
||
57 | * @return string |
||
58 | */ |
||
59 | private function updateClients($res) |
||
60 | { |
||
61 | foreach ($res as $clientData) { |
||
62 | $clientID = $clientData['client']; |
||
63 | $httpStatus = $clientData['status']; |
||
64 | $body = $clientData['body']; |
||
65 | |||
66 | if ((is_int($httpStatus)) && ($httpStatus < 300)) { |
||
67 | //We have a response |
||
68 | $this->updateClientData($clientID, $body); |
||
69 | } else if ((is_int($httpStatus)) && ($httpStatus < 500)) { |
||
70 | //404 error - log it and fail it |
||
71 | $this->failClient( |
||
72 | $clientID, |
||
73 | _t(__CLASS__ . '.40xerror', 'The client failed to respond. Please ensure the client module is installed and the API keys are set up correctly') |
||
74 | ); |
||
75 | } else { |
||
76 | $this->failClient( |
||
77 | $clientID, |
||
78 | _t(__CLASS__ . '.50xerror', 'The client failed to respond. Please check it is online and configured properly.') |
||
79 | ); |
||
80 | } |
||
81 | } |
||
82 | } |
||
83 | |||
84 | |||
85 | private function updateClientData($clientID, $data) |
||
86 | { |
||
87 | $client = Client::getByUUID($clientID); |
||
88 | $clientHelper = new ClientHelper($client); |
||
89 | if ($client) { |
||
0 ignored issues
–
show
|
|||
90 | $clientSecret = $clientHelper->getEncryptionSecret(); |
||
91 | $clientSalt = $clientHelper->getEncryptionSalt(); |
||
92 | |||
93 | $encHelper = new EncryptionHelper($clientSecret, $clientSalt); |
||
94 | $clientData = $encHelper->decrypt($data); |
||
95 | |||
96 | if (!$clientData) { |
||
97 | $this->failClient($clientID, "Error decrypting response data"); |
||
98 | return; |
||
99 | } |
||
100 | |||
101 | $clientDataArray = unserialize($clientData); |
||
102 | |||
103 | if ((!isset($clientDataArray['clientid'])) || ($clientDataArray['clientid'] !== $clientID)) { |
||
104 | $this->failClient($clientID, "UUID from client either not set, or incorrect"); |
||
105 | return; |
||
106 | } |
||
107 | |||
108 | $client->update([ |
||
109 | 'LastFetch' => DBDatetime::now()->format('y-MM-dd HH:mm:ss'), |
||
110 | 'ErrorMessage' => '', |
||
111 | 'FetchError' => false, |
||
112 | 'ClientData' => $data, |
||
113 | 'Notified' => false |
||
114 | ]); |
||
115 | $client->write(); |
||
116 | $this->extend('OnAfterClientUpdate', $client); |
||
117 | return; |
||
118 | |||
119 | } else { |
||
120 | $this->failClient($clientID, 'Unknown UUID'); |
||
121 | return; |
||
122 | } |
||
123 | $this->failClient($clientID, 'An unknown error occurred'); |
||
0 ignored issues
–
show
$this->failClient($clien...nknown error occurred') is not reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last ![]() |
|||
124 | } |
||
125 | |||
126 | |||
127 | /** |
||
128 | * @param string $clientID |
||
129 | * @return void |
||
130 | * @throws \SilverStripe\ORM\ValidationException |
||
131 | */ |
||
132 | private function failClient(string $clientID, $message) |
||
133 | { |
||
134 | $client = Client::getByUUID($clientID); |
||
135 | if ($client) { |
||
0 ignored issues
–
show
|
|||
136 | $client->FetchError = true; |
||
137 | $client->ErrorMessage = $message; |
||
138 | $client->write(); |
||
139 | $clientMessage = 'Client: ' . $clientID . ' (' . $client->Title . ') ' . ' : ' . $message; |
||
140 | $this->addMessage($clientMessage); |
||
141 | $this->notifySlack($client, $clientMessage); |
||
142 | $this->extend('OnAfterClientFail', $clientID); |
||
143 | } else { |
||
144 | $this->addMessage('Cannot find client with ID ' . $clientID); |
||
145 | } |
||
146 | } |
||
147 | |||
148 | /** |
||
149 | * @param Client $client |
||
150 | * @param $message |
||
151 | * @return void |
||
152 | * @throws \Psr\Container\NotFoundExceptionInterface |
||
153 | */ |
||
154 | private function notifySlack($client, $message = null) |
||
155 | { |
||
156 | $webhook = Environment::getEnv('SLACK_WEBHOOK'); |
||
157 | $channel = Environment::getEnv('SLACK_CHANNEL'); |
||
158 | if ($channel && $webhook && $client->Notified == 0) { |
||
159 | Injector::inst()->get(LoggerInterface::class . '.SlackLogger') |
||
160 | ->error($message); |
||
161 | $client->update([ |
||
162 | 'Notified' => true |
||
163 | ]); |
||
164 | $client->write(); |
||
165 | } |
||
166 | } |
||
167 | |||
168 | public function afterComplete() |
||
169 | { |
||
170 | $requeue_delay = $this->config()->get('requeue_delay'); |
||
171 | Injector::inst()->get(LoggerInterface::class)->info("Client job finished. Requeuing in " . $requeue_delay . " seconds"); |
||
172 | |||
173 | $newJob = new PollClientsTask(); |
||
174 | if ($requeue_delay > 0) { |
||
175 | singleton(QueuedJobService::class) |
||
176 | ->queueJob( |
||
177 | $newJob, |
||
178 | date( |
||
179 | 'Y-m-d H:i:s', |
||
180 | strtotime('+' . $requeue_delay . ' seconds') |
||
181 | ) |
||
182 | ); |
||
183 | } else { |
||
184 | singleton(QueuedJobService::class)->queueJob($newJob); |
||
185 | } |
||
186 | |||
187 | parent::afterComplete(); |
||
188 | } |
||
189 | |||
190 | } |
||
191 |