Skip to content

Commit 898009b

Browse files
Introduce api endpoint channels
1 parent cc77780 commit 898009b

File tree

2 files changed

+149
-0
lines changed

2 files changed

+149
-0
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
<?php
2+
3+
/* Icinga Notifications Web | (c) 2024 Icinga GmbH | GPLv2 */
4+
5+
namespace Icinga\Module\Notifications\Controllers;
6+
7+
use Icinga\Module\Notifications\Common\Database;
8+
use Icinga\Util\Environment;
9+
use Icinga\Util\Json;
10+
use ipl\Sql\Compat\FilterProcessor;
11+
use ipl\Sql\Select;
12+
use ipl\Stdlib\Filter;
13+
use ipl\Web\Compat\CompatController;
14+
use ipl\Web\Filter\QueryString;
15+
use ipl\Web\Url;
16+
use Ramsey\Uuid\Uuid;
17+
use stdClass;
18+
19+
class ApiV1ChannelsController extends CompatController
20+
{
21+
public function indexAction(): void
22+
{
23+
$this->assertPermission('notifications/api/v1');
24+
25+
$request = $this->getRequest();
26+
if (! $request->isApiRequest()) {
27+
$this->httpBadRequest('No API request');
28+
}
29+
30+
$method = $request->getMethod();
31+
if ($method !== 'GET') {
32+
$this->httpBadRequest('Only GET method supported');
33+
}
34+
35+
$db = Database::get();
36+
37+
/** @var ?string $identifier */
38+
$identifier = $request->getParam('identifier');
39+
40+
if ($identifier && ! Uuid::isValid($identifier)) {
41+
$this->httpBadRequest('The given identifier is not a valid UUID');
42+
}
43+
44+
$filter = FilterProcessor::assembleFilter(
45+
QueryString::fromString(rawurldecode(Url::fromRequest()->getQueryString()))
46+
->on(
47+
QueryString::ON_CONDITION,
48+
function (Filter\Condition $condition) {
49+
$column = $condition->getColumn();
50+
if (! in_array($column, ['id', 'name', 'type'])) {
51+
$this->httpBadRequest(sprintf(
52+
'Invalid filter column %s given, only id, name and type are allowed',
53+
$column
54+
));
55+
}
56+
57+
if ($column === 'id') {
58+
if (! Uuid::isValid($condition->getValue())) {
59+
$this->httpBadRequest('The given filter id is not a valid UUID');
60+
}
61+
62+
$condition->setColumn('external_uuid');
63+
}
64+
}
65+
)->parse()
66+
);
67+
68+
$stmt = (new Select())
69+
->distinct()
70+
->from('channel ch')
71+
->columns([
72+
'channel_id' => 'ch.id',
73+
'id' => 'ch.external_uuid',
74+
'name',
75+
'type',
76+
'config'
77+
]);
78+
79+
if ($identifier !== null) {
80+
$stmt->where(['external_uuid = ?' => $identifier]);
81+
82+
/** @var stdClass|false $result */
83+
$result = $db->fetchOne($stmt);
84+
85+
if ($result === false) {
86+
$this->httpNotFound('Channel not found');
87+
}
88+
89+
unset($result->channel_id);
90+
91+
$this->getResponse()
92+
->setHttpResponseCode(200)
93+
->json()
94+
->setSuccessData((array) $result)
95+
->sendResponse();
96+
} else {
97+
if ($filter !== null) {
98+
$stmt->where($filter);
99+
}
100+
101+
$stmt->limit(500);
102+
$offset = 0;
103+
104+
ob_end_clean();
105+
Environment::raiseExecutionTime();
106+
107+
$this->getResponse()
108+
->setHeader('Content-Type', 'application/json')
109+
->setHeader('Cache-Control', 'no-store')
110+
->sendResponse();
111+
112+
echo '[';
113+
114+
$res = $db->select($stmt->offset($offset));
115+
do {
116+
/** @var stdClass $row */
117+
foreach ($res as $i => $row) {
118+
if ($i > 0 || $offset !== 0) {
119+
echo ",\n";
120+
}
121+
122+
unset($row->channel_id);
123+
124+
echo Json::sanitize($row);
125+
}
126+
127+
$offset += 500;
128+
$res = $db->select($stmt->offset($offset));
129+
} while ($res->rowCount());
130+
131+
echo ']';
132+
}
133+
134+
exit;
135+
}
136+
}

run.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,16 @@
4747
1 => 'identifier'
4848
]
4949
));
50+
51+
$this->addRoute('notifications/api-v1-channels', new Zend_Controller_Router_Route_Regex(
52+
'notifications/api/v1/channels(?:\/(.+)|\?(.+))?',
53+
[
54+
'controller' => 'api-v1-channels',
55+
'action' => 'index',
56+
'module' => 'notifications',
57+
'identifier' => null
58+
],
59+
[
60+
1 => 'identifier'
61+
]
62+
));

0 commit comments

Comments
 (0)