Skip to content

Commit 108c819

Browse files
committed
added upstream data related methods.
1 parent 05f5473 commit 108c819

File tree

1 file changed

+64
-97
lines changed

1 file changed

+64
-97
lines changed

glued/Controllers/IfController.php

Lines changed: 64 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
namespace Glued\Controllers;
66

77
use Glued\Lib\Sql;
8+
use Glued\Lib\TsSql;
89
use Psr\Http\Message\ResponseInterface as Response;
910
use Psr\Http\Message\ServerRequestInterface as Request;
1011
use Glued\Lib\Controllers\AbstractService;
12+
use Selective\Transformer\ArrayTransformer;
1113

1214
class IfController extends AbstractService
1315
{
@@ -97,107 +99,72 @@ public function getActions(Request $request, Response $response, array $args = [
9799
return $response->withJson($data);
98100
}
99101

100-
}
101-
102-
103-
/*
104-
public function runs_r1(Request $request, Response $response, array $args = []): Response
105-
{
106-
$rp = $this->utils->getQueryParams($request) ?? [];
107-
$qs = (new \Glued\Lib\IfSql())->q['json:runs:all'];
108-
$qs = (new \Glued\Lib\QueryBuilder())->select($qs);
109-
$qs = $this->utils->mysqlQueryFromRequest($qs, $rp, 'c_data');
110-
$r = $this->mysqli->execute_query($qs,array_values($rp));
111-
$res['status'] = 'ok';
112-
foreach ($r as $i) {
113-
$res['data'][] = $i;
114-
}
115-
return $response->withJson($res);
116-
}
117-
118-
public function hello_r1(Request $request, Response $response, array $args = []): Response
102+
/**
103+
* Abstract method to get data from upstream (must be implemented in child classes).
104+
* @return array
105+
*
106+
* @example Example implementation:
107+
* ```php
108+
* $data = logic_getting_upstream_data();
109+
* return $data;
110+
* ```
111+
*/
112+
abstract protected function getUpstream(): array;
113+
114+
/**
115+
* Abstract method to save raw and transformed upstream data (must be implemented in child classes).
116+
*
117+
* @param array $upstreamData The upstream data to save.
118+
* @return bool True if saving succeeded, false otherwise.
119+
*
120+
* @example Example implementation:
121+
* ```php
122+
* $xf = new ArrayTransformer();
123+
* $xf->registerFilter("prefix", function ($value) { return "{$this->uuids['if:deployment']}/$value"; });
124+
* $xf->map("uuid", "uuid")
125+
* ->map("key1", "key2");
126+
* $tsdb = new TsSql($this->pg, "some_table_tsdb", "external_unique_id");
127+
* return $tsdb->CommonCreateBatch($upstreamData, $xf);
128+
* ```
129+
*/
130+
abstract protected function saveUpstream(array $upstreamData): bool;
131+
132+
/**
133+
* Syncs upstream data if the last sync occurred more than the specified TTL (time-to-live).
134+
*
135+
* This method checks the cache for the last sync timestamp using the provided cache key.
136+
* If the last sync occurred more than `syncedTtl` seconds ago, it will attempt to sync upstream data.
137+
* After a successful sync, the cache is updated with the current timestamp.
138+
* The method returns an HTTP-like status code based on the result of the sync.
139+
*
140+
* @param string $cacheKey The key used to retrieve and store the sync timestamp in the cache.
141+
* @param int $syncedTtl The time-to-live (in seconds) for considering the upstream sync as fresh. Defaults to 60 seconds.
142+
* @param int $staleTreshold The threshold (in seconds) for considering the upstream sync as stale. Defaults to 3600 seconds (1 hour).
143+
*
144+
* @return int Returns an HTTP-like status code:
145+
* - 200 if the upstream sync was successful.
146+
* - 203 if the sync was not performed (data from cache is returned).
147+
* - 502 if the sync failed and the last successful sync is older than the stale threshold.
148+
*/
149+
public function syncUpstream(string $cacheKey, int $syncedTtl = 60, int $staleTreshold = 3600): int
119150
{
120-
$payload['help']['get'] = 'List all IF v1 compliant service providers (A `"provides": "docs"` route is present).';
121-
$payload['help']['post'] = 'Post a json according to `service docs` to this interface as a request body to add a service coupler.';
122-
$routes = array_filter($this->settings['routes'], function ($key) {
123-
// return strpos($key, 'be_if_') === 0 &&
124-
return strpos($key, 'be_if_svc') === 0;
125-
}, ARRAY_FILTER_USE_KEY);
126-
foreach ($routes as $route) {
127-
$f['txt'] = trim($route['label']. " / " . $route['dscr']);
128-
$f['uri'] = $this->settings['glued']['protocol'] . $this->settings['glued']['hostname'] . $route['path'];
129-
$payload['links'][] = $f;
151+
$cacheTtl = 86400; // 24 hours in seconds
152+
$syncedResult = null;
153+
$now = time();
154+
155+
// Check if the last sync was more than 60 seconds ago, sync if yes
156+
$syncedAt = $this->memcache->get($cacheKey, 0);
157+
if (($now - $syncedAt) > $syncedTtl) {
158+
$syncedResult = $this->saveUpstream($this->getUpstream());
159+
if ($syncedResult === false) { $this->logger->error('Upstream sync failed.', ['cacheKey' => $cacheKey]); }
160+
else { $this->memcache->set($cacheKey, $now, $cacheTtl); }
130161
}
131-
$payload['status'] = 'Ok';
132-
return $response->withJson($payload);
133-
}
134-
135-
public function services_r1(Request $request, Response $response, array $args = []): Response
136-
{
137-
$base = $this->settings['glued']['protocol'] . $this->settings['glued']['hostname'];
138-
$svcs = [];
139-
foreach ($this->getServices() as $key => $value) {
140-
$svcs[$key]['name'] = $value;
141-
$svcs[$key]['links'] = "{$base}/{$this->settings['routes']['be_if_deployments_v1']['path']}/$value/deployments";
142-
}
143-
$payload['status'] = 'Ok';
144-
$payload['data'] = $svcs;
145-
return $response->withJson($payload);
146-
}
147-
148-
149-
public function queue_r1(Request $request, Response $response, array $args = []): Response
150-
{
151-
$rp = $this->utils->getQueryParams($request) ?? [];
152-
$override = [ [ 'next_in', '<', '0' ], [ 'row_num', '=', '1' ] ];
153-
$qs = (new \Glued\Lib\IfSql())->q['json:runs:latest'];;
154-
$qs = (new \Glued\Lib\QueryBuilder())->select($qs);
155-
$qs = $this->utils->mysqlQueryFromRequest($qs, $rp, 'svc_data', override: $override);
156-
$r = $this->mysqli->execute_query($qs,array_values($rp));
157-
$res['status'] = 'ok';
158-
foreach ($r as $i) {
159-
$i['run'] = $this->settings['glued']['protocol'] . $this->settings['glued']['hostname'] . '/api/if/v1/svc/' . $i['svc_type'] . '/act/' . $i['act_uuid'];
160-
$i['run'] = $this->settings['glued']['protocol'] . $this->settings['glued']['hostname'] . '/api/if/v1/runs/' . $i['act_uuid'];
161-
$res['data'][] = $i;
162-
}
163-
return $response->withJson($res);
164-
}
165-
166-
public function deployments_r1(Request $request, Response $response, array $args = []): Response
167-
{
168-
169-
$data = [];
170-
$rp = $this->utils->getQueryParams($request) ?? [];
171-
$qs = (new \Glued\Lib\IfSql())->q['json:runs:latest'];
172-
if ($args['svc'] ?? false) { $data[] = $args['svc']; $qs.= " and subquery.service = ?"; }
173-
$data = array_values($rp) + $data;
174-
$res = $this->mysqli->execute_query($qs, $data);
175-
foreach ($res as $row) {
176-
$data = json_decode($row['json_result'], true); break; }
177-
$fin['status'] = 'ok';
178-
$base = "{$this->settings['glued']['protocol']}{$this->settings['glued']['hostname']}/api/if";
179-
foreach ($data as $k => &$i) {
180-
$data[$k]['links']['start'] = "{$base}/svc/{$i['service']}/v1/act/{$i['action']['uuid']}";
181-
//$i['run'] = $this->settings['glued']['protocol'] . $this->settings['glued']['hostname'] . '/api/if/v1/runs/' . $i['act_uuid'];
182-
}
183-
$fin['data'] = $data;
184-
185-
//$res['data'][] = $i;
186-
return $response->withJson($fin);
187-
}
188-
189-
public function stats_r1(Request $request, Response $response, array $args = []): Response
190-
{
191-
$res = ['status' => 'ok', 'message' => 'This endpoint is under development.'];
192-
return $response->withJson($res);
162+
$status = ($syncedResult === false)
163+
? (($now - $syncedAt) > $staleTreshold ? 502 : 203) // 502 if sync failed for >1 hour, else 203
164+
: ($syncedResult === null ? 203 : 200); // 203 if cached, 200 if sync successful
165+
return $status;
193166
}
194167

195168

196169
}
197170

198-
199-
// {"svc":{"type":"Caretag","name":"NEMCB Prod","host":"https:\/\/caretag-api.nemocnice.local","note": "Production environment ([email protected])","freq":3600,"auth":{"UserName":"[email protected]","Password":"Administrator1!"}},"act":[{"type":"Assets","freq":3600},{"type":"AssetDefinition","freq":36000}]}
200-
// toalety - wc
201-
//
202-
203-
*/

0 commit comments

Comments
 (0)