Skip to content

Commit 5eafe60

Browse files
authored
Merge pull request #1715 from hashtopolis/1152-implement-fetching-sparse-fieldsets
Implemented sparse fieldsets support on the backend #1152
2 parents ee0994a + cf0e5c9 commit 5eafe60

File tree

5 files changed

+76
-42
lines changed

5 files changed

+76
-42
lines changed

src/inc/apiv2/common/AbstractBaseAPI.class.php

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ protected function getUpdateHandlers($id, $current_user): array {
160160
* Implementations should use $includedData to collect related resources that should be included
161161
* in the API response, such as related entities or additional data.
162162
*/
163-
public static function aggregateData(object $object, array &$includedData=[]): array
163+
public static function aggregateData(object $object, array &$includedData = [], array $aggregateFieldsets = null): array
164164
{
165165
return [];
166166
}
@@ -561,7 +561,7 @@ protected function obj2Array(object $obj): array {
561561
* @throws NotFoundExceptionInterface
562562
* @throws ContainerExceptionInterface
563563
*/
564-
protected function obj2Resource(object $obj, array &$expandResult = []): array {
564+
protected function obj2Resource(object $obj, array &$expandResult = [], array $sparseFieldsets = null, array $aggregateFieldsets = null): array {
565565
// Convert values to JSON supported types
566566
$features = $obj->getFeatures();
567567
$kv = $obj->getKeyValueDict();
@@ -571,6 +571,11 @@ protected function obj2Resource(object $obj, array &$expandResult = []): array {
571571

572572
$attributes = [];
573573
$relationships = [];
574+
575+
$sparseFieldsetsForObj = null;
576+
if (is_array($sparseFieldsets) && array_key_exists($this->getObjectTypeName($obj), $sparseFieldsets)) {
577+
$sparseFieldsetsForObj = explode(",", $sparseFieldsets[$this->getObjectTypeName($obj)]);
578+
}
574579

575580
/* Collect attributes */
576581
foreach ($features as $name => $feature) {
@@ -579,6 +584,12 @@ protected function obj2Resource(object $obj, array &$expandResult = []): array {
579584
if ($feature['private'] === true) {
580585
continue;
581586
}
587+
588+
// If sparse fieldsets (https://jsonapi.org/format/#fetching-sparse-fieldsets) is used, return only the requested data
589+
if (is_array($sparseFieldsetsForObj) && !in_array($feature['alias'], $sparseFieldsetsForObj)) {
590+
continue;
591+
}
592+
582593
// Hide the primaryKey from the attributes since this is used as indentifier (id) in response
583594
if ($feature['pk'] === true) {
584595
continue;
@@ -590,9 +601,8 @@ protected function obj2Resource(object $obj, array &$expandResult = []): array {
590601

591602
$attributes[$feature['alias']] = $apiClass::db2json($feature, $kv[$name]);
592603
}
593-
594-
//TODO: only aggregate data when it has been included
595-
$aggregatedData = $apiClass::aggregateData($obj, $expandResult);
604+
605+
$aggregatedData = $apiClass::aggregateData($obj, $expandResult, $aggregateFieldsets);
596606
$attributes = array_merge($attributes, $aggregatedData);
597607

598608
/* Build JSON::API relationship resource */
@@ -1187,7 +1197,9 @@ protected function processExpands(
11871197
array $expands,
11881198
object $object,
11891199
array $expandResult,
1190-
array $includedResources
1200+
array $includedResources,
1201+
array $sparseFieldsets = null,
1202+
array $aggregateFieldsets = null
11911203
): array {
11921204

11931205
// Add missing expands to expands in case they have been added in aggregateData()
@@ -1204,14 +1216,16 @@ protected function processExpands(
12041216

12051217
if (is_array($expandResultObject)) {
12061218
foreach ($expandResultObject as $expandObject) {
1207-
$includedResources = self::addToRelatedResources($includedResources, $apiClass->obj2Resource($expandObject));
1219+
$noFurtherExpands = [];
1220+
$includedResources = self::addToRelatedResources($includedResources, $apiClass->obj2Resource($expandObject, $noFurtherExpands, $sparseFieldsets, $aggregateFieldsets));
12081221
}
12091222
} else {
12101223
if ($expandResultObject === null) {
12111224
// to-only relation which is nullable
12121225
continue;
12131226
}
1214-
$includedResources = self::addToRelatedResources($includedResources, $apiClass->obj2Resource($expandResultObject));
1227+
$noFurtherExpands = [];
1228+
$includedResources = self::addToRelatedResources($includedResources, $apiClass->obj2Resource($expandResultObject, $noFurtherExpands, $sparseFieldsets, $aggregateFieldsets));
12151229
}
12161230
}
12171231

@@ -1493,8 +1507,8 @@ protected static function getOneResource(object $apiClass, object $object, Reque
14931507
// Convert objects to data resources
14941508
foreach ($objects as $object) {
14951509
// Create object
1496-
$newObject = $apiClass->obj2Resource($object, $expandResult);
1497-
$includedResources = $apiClass->processExpands($apiClass, $expands, $object, $expandResult, $includedResources);
1510+
$newObject = $apiClass->obj2Resource($object, $expandResult, $request->getQueryParams()['fields'] ?? null, $request->getQueryParams()['aggregate'] ?? null);
1511+
$includedResources = $apiClass->processExpands($apiClass, $expands, $object, $expandResult, $includedResources, $request->getQueryParams()['fields'] ?? null, $request->getQueryParams()['aggregate'] ?? null);
14981512

14991513
// Add to result output
15001514
$dataResources[] = $newObject;

src/inc/apiv2/common/AbstractModelAPI.class.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -731,12 +731,13 @@ public static function getManyResources(object $apiClass, Request $request, Resp
731731
// Convert objects to data resources
732732
foreach ($objects as $object) {
733733
// Create object
734-
$newObject = $apiClass->obj2Resource($object, $expandResult);
735-
$includedResources = $apiClass->processExpands($apiClass, $expands, $object, $expandResult, $includedResources);
734+
$newObject = $apiClass->obj2Resource($object, $expandResult, $request->getQueryParams()['fields'] ?? null, $request->getQueryParams()['aggregate'] ?? null);
735+
$includedResources = $apiClass->processExpands($apiClass, $expands, $object, $expandResult, $includedResources, $request->getQueryParams()['fields'] ?? null, $request->getQueryParams()['aggregate'] ?? null);
736736

737737
// Add to result output
738738
$dataResources[] = $newObject;
739739
}
740+
740741
$baseUrl = Util::buildServerUrl();
741742
//build last link
742743
$lastParams = $request->getQueryParams();

src/inc/apiv2/helper/getTaskProgressImage.routes.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ public function getParamsSwagger(): array {
7979
*/
8080
public function handleGet(Request $request, Response $response): Response {
8181
$this->preCommon($request);
82-
$task_id = $request->getQueryParams()['task'];
83-
$supertask_id = $request->getQueryParams()['supertask'];
82+
$task_id = $request->getQueryParams()['task'] ?? null;
83+
$supertask_id = $request->getQueryParams()['supertask'] ?? null;
8484

8585
//check if task exists and get information
8686
if ($task_id) {

src/inc/apiv2/model/agents.routes.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ protected function getUpdateHandlers($id, $current_user): array {
4646
* @param array &$includedData
4747
* @return array not used here
4848
*/
49-
static function aggregateData(object $object, array &$included_data = []): array {
49+
static function aggregateData(object $object, array &$included_data = [], array $aggregateFieldsets = null): array {
5050
$agentId = $object->getId();
5151
$qFs = [];
5252
$qFs[] = new QueryFilter(Chunk::AGENT_ID, $agentId, "=");

src/inc/apiv2/model/tasks.routes.php

Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -162,38 +162,57 @@ protected function createObject(array $data): int {
162162
}
163163

164164
//TODO make aggregate data queryable and not included by default
165-
static function aggregateData(object $object, array &$included_data = []): array {
166-
$qF = new QueryFilter(Assignment::TASK_ID, $object->getId(), "=");
167-
$activeAgents = Factory::getAssignmentFactory()->countFilter([Factory::FILTER => $qF]);
168-
$aggregatedData["activeAgents"] = $activeAgents;
169-
170-
$keyspace = $object->getKeyspace();
171-
$keyspaceProgress = $object->getKeyspaceProgress();
165+
static function aggregateData(object $object, array &$included_data = [], array $aggregateFieldsets = null): array {
166+
$aggregatedData = [];
172167

173-
$qF1 = new QueryFilter(Chunk::TASK_ID, $object->getId(), "=");
174-
$agg1 = new Aggregation(Chunk::CHECKPOINT, Aggregation::SUM);
175-
$agg2 = new Aggregation(Chunk::SKIP, Aggregation::SUM);
176-
$agg3 = new Aggregation(Chunk::DISPATCH_TIME, Aggregation::MAX);
177-
$agg4 = new Aggregation(Chunk::SOLVE_TIME, Aggregation::MAX);
178-
$results = Factory::getChunkFactory()->multicolAggregationFilter([Factory::FILTER => $qF1], [$agg1, $agg2, $agg3, $agg4]);
168+
if (is_null($aggregateFieldsets) || (is_array($aggregateFieldsets) && array_key_exists('task', $aggregateFieldsets))) {
169+
if (!is_null($aggregateFieldsets)) {
170+
$aggregateFieldsets['task'] = explode(",", $aggregateFieldsets['task']);
171+
}
172+
173+
$activeAgents = [];
174+
if (is_null($aggregateFieldsets) || in_array("activeAgents", $aggregateFieldsets['task'])) {
175+
$qF = new QueryFilter(Assignment::TASK_ID, $object->getId(), "=");
176+
$activeAgents = Factory::getAssignmentFactory()->countFilter([Factory::FILTER => $qF]);
177+
$aggregatedData["activeAgents"] = $activeAgents;
178+
}
179179

180-
$progress = $results[$agg1->getName()] - $results[$agg2->getName()];
181-
$maxTime = max($results[$agg3->getName()], $results[$agg4->getName()]);
180+
$keyspace = $object->getKeyspace();
181+
$keyspaceProgress = $object->getKeyspaceProgress();
182+
183+
if (is_null($aggregateFieldsets) || in_array("dispatched", $aggregateFieldsets['task'])) {
184+
$aggregatedData["dispatched"] = Util::showperc($keyspaceProgress, $keyspace);
185+
}
182186

183-
//status 1 is running, 2 is idle and 3 is completed
184-
$status = 2;
185-
if (time() - $maxTime < SConfig::getInstance()->getVal(DConfig::CHUNK_TIMEOUT) && ($progress < $object->getKeyspace() || $object->getUsePreprocessor() && $object->getKeyspace() == DPrince::PRINCE_KEYSPACE)) {
186-
$status = 1;
187-
}
188-
$aggregatedData["dispatched"] = Util::showperc($keyspaceProgress, $keyspace);
189-
$aggregatedData["searched"] = Util::showperc(TaskUtils::getTaskProgress($object), $keyspace);
190-
191-
if ($keyspaceProgress >= $keyspace && $keyspaceProgress > 0) {
192-
$status = 3;
187+
if (is_null($aggregateFieldsets) || in_array("searched", $aggregateFieldsets['task'])) {
188+
$aggregatedData["searched"] = Util::showperc(TaskUtils::getTaskProgress($object), $keyspace);
189+
}
190+
191+
if (is_null($aggregateFieldsets) || in_array("status", $aggregateFieldsets['task'])) {
192+
$qF1 = new QueryFilter(Chunk::TASK_ID, $object->getId(), "=");
193+
$agg1 = new Aggregation(Chunk::CHECKPOINT, Aggregation::SUM);
194+
$agg2 = new Aggregation(Chunk::SKIP, Aggregation::SUM);
195+
$agg3 = new Aggregation(Chunk::DISPATCH_TIME, Aggregation::MAX);
196+
$agg4 = new Aggregation(Chunk::SOLVE_TIME, Aggregation::MAX);
197+
$results = Factory::getChunkFactory()->multicolAggregationFilter([Factory::FILTER => $qF1], [$agg1, $agg2, $agg3, $agg4]);
198+
199+
$progress = $results[$agg1->getName()] - $results[$agg2->getName()];
200+
$maxTime = max($results[$agg3->getName()], $results[$agg4->getName()]);
201+
202+
//status 1 is running, 2 is idle and 3 is completed
203+
$status = 2;
204+
if (time() - $maxTime < SConfig::getInstance()->getVal(DConfig::CHUNK_TIMEOUT) && ($progress < $keyspace || $object->getUsePreprocessor() && $keyspace == DPrince::PRINCE_KEYSPACE)) {
205+
$status = 1;
206+
}
207+
208+
if ($keyspaceProgress >= $keyspace && $keyspaceProgress > 0) {
209+
$status = 3;
210+
}
211+
212+
$aggregatedData["status"] = $status;
213+
}
193214
}
194215

195-
$aggregatedData["status"] = $status;
196-
197216
return $aggregatedData;
198217
}
199218

0 commit comments

Comments
 (0)