Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
82.00% |
82 / 100 |
|
84.62% |
11 / 13 |
CRAP | |
0.00% |
0 / 1 |
RdsDeliveryExecutionService | |
82.00% |
82 / 100 |
|
84.62% |
11 / 13 |
28.65 | |
0.00% |
0 / 1 |
deleteDeliveryExecutionData | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
1 | |||
getExecutionsByDelivery | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
1 | |||
getUserExecutions | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
1 | |||
getDeliveryExecutionsByStatus | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
1 | |||
spawnDeliveryExecution | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
2 | |||
initDeliveryExecution | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
1 | |||
getDeliveryExecution | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
2 | |||
updateDeliveryExecutionState | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
20 | |||
getPersistence | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getNewUri | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getQueryBuilder | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
parseQueryResult | |
100.00% |
16 / 16 |
|
100.00% |
1 / 1 |
8 | |||
getCurrentDateTime | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | |
3 | /** |
4 | * This program is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU General Public License |
6 | * as published by the Free Software Foundation; under version 2 |
7 | * of the License (non-upgradable). |
8 | * |
9 | * This program is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write to the Free Software |
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
17 | * |
18 | * Copyright (c) 2013-2017 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT); |
19 | */ |
20 | |
21 | namespace oat\taoDelivery\model\execution\rds; |
22 | |
23 | use common_persistence_SqlPersistence; |
24 | use core_kernel_classes_Resource; |
25 | use Doctrine\DBAL\Query\QueryBuilder; |
26 | use oat\oatbox\service\ConfigurableService; |
27 | use oat\oatbox\user\User; |
28 | use oat\taoDelivery\model\execution\Delete\DeliveryExecutionDeleteRequest; |
29 | use oat\taoDelivery\model\execution\DeliveryExecution; |
30 | use oat\taoDelivery\model\execution\DeliveryExecutionInterface; |
31 | use oat\taoDelivery\model\execution\DeliveryExecutionServiceInterface; |
32 | use oat\taoDelivery\model\execution\Monitoring; |
33 | |
34 | /** |
35 | * RDS implementation of the Delivery Execution Service |
36 | * |
37 | * @author Péter Halász <peter@taotesting.com> |
38 | */ |
39 | class RdsDeliveryExecutionService extends ConfigurableService implements Monitoring, DeliveryExecutionServiceInterface |
40 | { |
41 | public const ID_PREFIX = "rds_de_"; |
42 | public const TABLE_NAME = "delivery_executions"; |
43 | public const COLUMN_ID = "id"; |
44 | public const COLUMN_DELIVERY_ID = "delivery_id"; |
45 | public const COLUMN_USER_ID = "user_id"; |
46 | public const COLUMN_STATUS = "status"; |
47 | public const COLUMN_FINISHED_AT = "finished_at"; |
48 | public const COLUMN_STARTED_AT = "started_at"; |
49 | public const COLUMN_LABEL = "label"; |
50 | |
51 | /** |
52 | * @param DeliveryExecutionDeleteRequest $request |
53 | * @throws \Exception |
54 | * @return bool |
55 | */ |
56 | public function deleteDeliveryExecutionData(DeliveryExecutionDeleteRequest $request) |
57 | { |
58 | $query = $this->getQueryBuilder() |
59 | ->delete(self::TABLE_NAME) |
60 | ->where(self::COLUMN_ID . " = :id") |
61 | ->setParameter("id", $request->getDeliveryExecution()->getIdentifier()) |
62 | ; |
63 | |
64 | return $query->execute(); |
65 | } |
66 | |
67 | /** |
68 | * Returns the delivery executions for a compiled directory |
69 | * |
70 | * @param core_kernel_classes_Resource $compiled |
71 | * @return DeliveryExecution[] |
72 | */ |
73 | public function getExecutionsByDelivery(core_kernel_classes_Resource $compiled) |
74 | { |
75 | $query = $this->getQueryBuilder() |
76 | ->select("*") |
77 | ->from(self::TABLE_NAME) |
78 | ->where(self::COLUMN_DELIVERY_ID . " = :deliveryId") |
79 | ->setParameter("deliveryId", $compiled->getUri()) |
80 | ; |
81 | |
82 | return array_map(function ($row) { |
83 | return $this->parseQueryResult($row); |
84 | }, $query->execute()->fetchAll()); |
85 | } |
86 | |
87 | /** |
88 | * Returns the executions the user has of a specified assembly |
89 | * |
90 | * @param core_kernel_classes_Resource $assembly |
91 | * @param string $userUri |
92 | * @return DeliveryExecution[] |
93 | */ |
94 | public function getUserExecutions(core_kernel_classes_Resource $assembly, $userUri) |
95 | { |
96 | $query = $this->getQueryBuilder() |
97 | ->select("*") |
98 | ->from(self::TABLE_NAME) |
99 | ->where(self::COLUMN_DELIVERY_ID . " = :deliveryId") |
100 | ->andWhere(self::COLUMN_USER_ID . " = :userId") |
101 | ->setParameter("deliveryId", $assembly->getUri()) |
102 | ->setParameter("userId", $userUri) |
103 | ; |
104 | |
105 | return array_map(function ($row) { |
106 | return $this->parseQueryResult($row); |
107 | }, $query->execute()->fetchAll()); |
108 | } |
109 | |
110 | /** |
111 | * Returns all Delivery Executions of a User with a specific status |
112 | * |
113 | * @param string $userUri |
114 | * @param string $status |
115 | * @return array |
116 | */ |
117 | public function getDeliveryExecutionsByStatus($userUri, $status) |
118 | { |
119 | $query = $this->getQueryBuilder() |
120 | ->select("*") |
121 | ->from(self::TABLE_NAME) |
122 | ->where(self::COLUMN_USER_ID . " = :userId") |
123 | ->andWhere(self::COLUMN_STATUS . " = :status") |
124 | ->setParameter("userId", $userUri) |
125 | ->setParameter("status", $status) |
126 | ; |
127 | |
128 | return array_map(function ($row) { |
129 | return $this->parseQueryResult($row); |
130 | }, $query->execute()->fetchAll()); |
131 | } |
132 | |
133 | /** |
134 | * @param $label |
135 | * @param $deliveryId |
136 | * @param $userId |
137 | * @param $status |
138 | * @param string|null $deliveryExecutionId |
139 | * @return DeliveryExecution |
140 | * @throws \common_exception_Error |
141 | */ |
142 | public function spawnDeliveryExecution($label, $deliveryId, $userId, $status, $deliveryExecutionId = null) |
143 | { |
144 | $deliveryExecutionId = self::ID_PREFIX . ($deliveryExecutionId ?: $this->getNewUri()); |
145 | |
146 | $this->getPersistence()->insert(self::TABLE_NAME, [ |
147 | self::COLUMN_ID => $deliveryExecutionId, |
148 | self::COLUMN_LABEL => $label, |
149 | self::COLUMN_DELIVERY_ID => $deliveryId, |
150 | self::COLUMN_USER_ID => $userId, |
151 | self::COLUMN_STATUS => $status, |
152 | self::COLUMN_STARTED_AT => $this->getCurrentDateTime(), |
153 | ]); |
154 | |
155 | return $this->getDeliveryExecution($deliveryExecutionId); |
156 | } |
157 | |
158 | /** |
159 | * Generate a new delivery execution |
160 | * |
161 | * @deprecated |
162 | * @param core_kernel_classes_Resource $assembly |
163 | * @param User $user |
164 | * @return DeliveryExecution the delivery execution |
165 | * @throws \common_exception_Error |
166 | */ |
167 | public function initDeliveryExecution(core_kernel_classes_Resource $assembly, $user) |
168 | { |
169 | return $this->spawnDeliveryExecution( |
170 | $assembly->getLabel(), |
171 | $assembly->getUri(), |
172 | $user, |
173 | DeliveryExecution::STATE_ACTIVE |
174 | ); |
175 | } |
176 | |
177 | /** |
178 | * Returns the delivery execution instance associated to the implementation |
179 | * |
180 | * @param string $identifier |
181 | * @return DeliveryExecution |
182 | * @throws \common_exception_Error |
183 | */ |
184 | public function getDeliveryExecution($identifier) |
185 | { |
186 | $query = $this->getQueryBuilder() |
187 | ->select("*") |
188 | ->from(self::TABLE_NAME) |
189 | ->where(self::COLUMN_ID . " = :id") |
190 | ->setParameter("id", $identifier) |
191 | ; |
192 | |
193 | $result = $query->execute()->fetch(); |
194 | |
195 | if (!$result) { |
196 | $result = []; |
197 | } |
198 | |
199 | return $this->parseQueryResult($result); |
200 | } |
201 | |
202 | /** |
203 | * Updates the state of the given deliveryexecution |
204 | * |
205 | * @param string $identifier the ID of the delivery execution |
206 | * @param core_kernel_classes_Resource $fromState the original state |
207 | * @param string $toState the desired state |
208 | * @return bool true if the update went well, false otherwise |
209 | */ |
210 | public function updateDeliveryExecutionState($identifier, $fromState, $toState) |
211 | { |
212 | try { |
213 | if ($fromState === $toState) { |
214 | // do nothing, when the state didn't change |
215 | return true; |
216 | } |
217 | |
218 | $query = $this->getQueryBuilder() |
219 | ->update(self::TABLE_NAME) |
220 | ->set(self::COLUMN_STATUS, ":status") |
221 | ->where(self::COLUMN_ID . " = :id") |
222 | ->setParameter("status", $toState) |
223 | ->setParameter("id", $identifier) |
224 | ; |
225 | |
226 | if ($toState === DeliveryExecutionInterface::STATE_FINISHED) { |
227 | $query |
228 | ->set(self::COLUMN_FINISHED_AT, ":finishedAt") |
229 | ->setParameter("finishedAt", $this->getCurrentDateTime()) |
230 | ; |
231 | } |
232 | |
233 | return $query->execute() === 1; |
234 | } catch (\Exception $e) { |
235 | return false; |
236 | } |
237 | } |
238 | |
239 | /** |
240 | * Returns the default SQL persistence |
241 | * |
242 | * @return common_persistence_SqlPersistence |
243 | */ |
244 | public function getPersistence() |
245 | { |
246 | return $this->getServiceLocator()->get(\common_persistence_Manager::SERVICE_ID)->getPersistenceById("default"); |
247 | } |
248 | |
249 | /** |
250 | * Returns a new Uri |
251 | * (moved to a separated function to be able to mock it during unit tests) |
252 | * |
253 | * @return string |
254 | */ |
255 | protected function getNewUri() |
256 | { |
257 | return \common_Utils::getNewUri(); |
258 | } |
259 | |
260 | /** |
261 | * Returns the QueryBuilder |
262 | * |
263 | * @return QueryBuilder |
264 | */ |
265 | private function getQueryBuilder() |
266 | { |
267 | return $this->getPersistence()->getPlatform()->getQueryBuilder(); |
268 | } |
269 | |
270 | /** |
271 | * Parses the query result array and constructs a new DeliveryExecution object from it |
272 | * |
273 | * @param array $result |
274 | * @return DeliveryExecution |
275 | * @throws \common_exception_Error |
276 | */ |
277 | private function parseQueryResult($result = []) |
278 | { |
279 | $rdsDeliveryExecution = new RdsDeliveryExecution($this); |
280 | |
281 | if (array_key_exists(self::COLUMN_ID, $result)) { |
282 | $rdsDeliveryExecution->setIdentifier($result[self::COLUMN_ID]); |
283 | } |
284 | |
285 | if (array_key_exists(self::COLUMN_LABEL, $result)) { |
286 | $rdsDeliveryExecution->setLabel($result[self::COLUMN_LABEL]); |
287 | } |
288 | |
289 | if (array_key_exists(self::COLUMN_DELIVERY_ID, $result)) { |
290 | $rdsDeliveryExecution->setDelivery($result[self::COLUMN_DELIVERY_ID]); |
291 | } |
292 | |
293 | if (array_key_exists(self::COLUMN_STATUS, $result)) { |
294 | $rdsDeliveryExecution->setState($result[self::COLUMN_STATUS]); |
295 | } |
296 | |
297 | if (array_key_exists(self::COLUMN_USER_ID, $result)) { |
298 | $rdsDeliveryExecution->setUserIdentifier($result[self::COLUMN_USER_ID]); |
299 | } |
300 | |
301 | if (array_key_exists(self::COLUMN_STARTED_AT, $result)) { |
302 | $rdsDeliveryExecution->setStartTime(new \DateTime($result[self::COLUMN_STARTED_AT])); |
303 | } |
304 | |
305 | if (array_key_exists(self::COLUMN_FINISHED_AT, $result)) { |
306 | $rdsDeliveryExecution->setFinishTime(new \DateTime($result[self::COLUMN_FINISHED_AT])); |
307 | } |
308 | |
309 | return $this->propagate(new DeliveryExecution($rdsDeliveryExecution)); |
310 | } |
311 | |
312 | /** |
313 | * Returns the current DateTime in a predefined format |
314 | * |
315 | * @return string |
316 | */ |
317 | private function getCurrentDateTime() |
318 | { |
319 | return $this->getPersistence()->getPlatform()->getNowExpression(); |
320 | } |
321 | } |