Skip to content

Commit adbf105

Browse files
committed
[DAPS-1515] Enhance endpoints with repository type system integration
- Implement repository type checks for data operations. - Replace allocation create/delete logic with RepositoryOps. - Add support for metadata-only repositories and relevant error handling. - Ensure API response compatibility is preserved.
1 parent b872681 commit adbf105

File tree

4 files changed

+166
-16
lines changed

4 files changed

+166
-16
lines changed

core/database/foxx/api/data_router.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ const g_lib = require("./support");
88
const g_proc = require("./process");
99
const g_tasks = require("./tasks");
1010
const { UserToken } = require("./lib/user_token");
11+
const { RepositoryOps } = require("./repository/operations");
12+
const { RepositoryType } = require("./repository/types");
1113

1214
module.exports = router;
1315

@@ -90,6 +92,24 @@ function recordCreate(client, record, result) {
9092

9193
if (!repo_alloc) throw [g_lib.ERR_NO_ALLOCATION, "No allocation available"];
9294

95+
// Check if repository supports data operations
96+
var findResult = RepositoryOps.find(repo_alloc._to);
97+
if (findResult.ok) {
98+
var repository = findResult.value;
99+
var dataOpsResult = RepositoryOps.supportsDataOperations(repository);
100+
101+
if (dataOpsResult.ok && !dataOpsResult.value) {
102+
throw [
103+
g_lib.ERR_INVALID_OPERATION,
104+
"Data uploads not supported for metadata-only repository",
105+
{
106+
repo_type: repository.type,
107+
repo_id: repository.data._id
108+
}
109+
];
110+
}
111+
}
112+
93113
// Extension setting only apply to managed data
94114
if (record.ext) {
95115
obj.ext_auto = false;

core/database/foxx/api/repo_router.js

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ const g_db = require("@arangodb").db;
88
const g_lib = require("./support");
99
const g_tasks = require("./tasks");
1010
const { validateGlobusConfig, validatePartialGlobusConfig } = require("./repository/validation");
11+
const { RepositoryOps } = require("./repository/operations");
12+
const { RepositoryType } = require("./repository/types");
1113

1214
module.exports = router;
1315

@@ -677,15 +679,33 @@ router
677679
subject_id = req.queryParams.subject;
678680
else subject_id = g_lib.getUserFromClientID(req.queryParams.subject)._id;
679681

680-
var result = g_tasks.taskInitAllocCreate(
681-
client,
682-
req.queryParams.repo,
683-
subject_id,
684-
req.queryParams.data_limit,
685-
req.queryParams.rec_limit,
686-
);
682+
// Find the repository using the new type system
683+
var findResult = RepositoryOps.find(req.queryParams.repo);
684+
if (!findResult.ok) {
685+
throw [findResult.error.code, findResult.error.message];
686+
}
687+
688+
var repository = findResult.value;
689+
690+
// Check permissions
691+
var permResult = RepositoryOps.checkPermission(repository, client._id, "admin");
692+
if (!permResult.ok || !permResult.value) {
693+
throw g_lib.ERR_PERM_DENIED;
694+
}
695+
696+
// Create allocation using the new system
697+
var allocResult = RepositoryOps.createAllocation(repository, {
698+
subject: subject_id,
699+
size: req.queryParams.data_limit,
700+
rec_limit: req.queryParams.rec_limit,
701+
});
702+
703+
if (!allocResult.ok) {
704+
throw [allocResult.error.code, allocResult.error.message];
705+
}
687706

688-
res.send(result);
707+
// Return the new response format
708+
res.send(allocResult.value);
689709
},
690710
});
691711
} catch (e) {
@@ -707,7 +727,7 @@ router
707727
)
708728
.summary("Create user/project repo allocation")
709729
.description(
710-
"Create user repo/project allocation. Only repo admin can set allocations. Returns a task document.",
730+
"Create user repo/project allocation. Only repo admin can set allocations. Returns either a task (for Globus repos) or direct result (for metadata-only repos).",
711731
);
712732

713733
router
@@ -727,13 +747,29 @@ router
727747
subject_id = req.queryParams.subject;
728748
else subject_id = g_lib.getUserFromClientID(req.queryParams.subject)._id;
729749

730-
var result = g_tasks.taskInitAllocDelete(
731-
client,
732-
req.queryParams.repo,
733-
subject_id,
734-
);
750+
// Find the repository using the new type system
751+
var findResult = RepositoryOps.find(req.queryParams.repo);
752+
if (!findResult.ok) {
753+
throw [findResult.error.code, findResult.error.message];
754+
}
755+
756+
var repository = findResult.value;
757+
758+
// Check permissions
759+
var permResult = RepositoryOps.checkPermission(repository, client._id, "admin");
760+
if (!permResult.ok || !permResult.value) {
761+
throw g_lib.ERR_PERM_DENIED;
762+
}
763+
764+
// Delete allocation using the new system
765+
var deleteResult = RepositoryOps.deleteAllocation(repository, subject_id);
766+
767+
if (!deleteResult.ok) {
768+
throw [deleteResult.error.code, deleteResult.error.message];
769+
}
735770

736-
res.send(result);
771+
// Return the new response format
772+
res.send(deleteResult.value);
737773
},
738774
});
739775
} catch (e) {
@@ -745,7 +781,7 @@ router
745781
.queryParam("repo", joi.string().required(), "Repo ID")
746782
.summary("Delete user/project repo allocation")
747783
.description(
748-
"Delete user repo/project allocation. Only repo admin can set allocations. Returns a task document.",
784+
"Delete user repo/project allocation. Only repo admin can set allocations. Returns either a task (for Globus repos) or direct result (for metadata-only repos).",
749785
);
750786

751787
router

core/database/foxx/api/support.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ module.exports = (function () {
77

88
obj.db = require("@arangodb").db;
99
obj.graph = require("@arangodb/general-graph")._graph("sdmsg");
10+
11+
// Import repository type system
12+
const { RepositoryOps } = require("./repository/operations");
13+
const { RepositoryType } = require("./repository/types");
1014

1115
obj.PERM_RD_REC = 0x0001; // Read record info (description, keywords, details)
1216
obj.PERM_RD_META = 0x0002; // Read structured metadata
@@ -164,6 +168,8 @@ module.exports = (function () {
164168
obj.ERR_INFO.push([400, "No allocation available"]);
165169
obj.ERR_ALLOCATION_EXCEEDED = obj.ERR_COUNT++;
166170
obj.ERR_INFO.push([400, "Storage allocation exceeded"]);
171+
obj.ERR_INVALID_OPERATION = obj.ERR_COUNT++;
172+
obj.ERR_INFO.push([400, "Invalid operation"]);
167173

168174
obj.CHARSET_ID = 0;
169175
obj.CHARSET_ALIAS = 1;
@@ -910,6 +916,18 @@ module.exports = (function () {
910916
alloc = allocs[i];
911917

912918
if (alloc.data_size < alloc.data_limit && alloc.rec_count < alloc.rec_limit) {
919+
// Check if repository supports data operations
920+
var findResult = RepositoryOps.find(alloc._to);
921+
if (findResult.ok) {
922+
var repository = findResult.value;
923+
var dataOpsResult = RepositoryOps.supportsDataOperations(repository);
924+
925+
// Skip metadata-only repositories
926+
if (dataOpsResult.ok && !dataOpsResult.value) {
927+
continue;
928+
}
929+
}
930+
913931
return alloc;
914932
}
915933
}
@@ -936,6 +954,24 @@ module.exports = (function () {
936954
"Allocation record count exceeded (max: " + alloc.rec_limit + ")",
937955
];
938956

957+
// Check if repository supports data operations
958+
var findResult = RepositoryOps.find(a_repo_id);
959+
if (findResult.ok) {
960+
var repository = findResult.value;
961+
var dataOpsResult = RepositoryOps.supportsDataOperations(repository);
962+
963+
if (dataOpsResult.ok && !dataOpsResult.value) {
964+
throw [
965+
obj.ERR_INVALID_OPERATION,
966+
"Data operations not supported for metadata-only repository",
967+
{
968+
repo_type: repository.type,
969+
repo_id: repository.data._id
970+
}
971+
];
972+
}
973+
}
974+
939975
return alloc;
940976
};
941977

core/database/foxx/api/tasks.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// local imports
44
const g_lib = require("./support");
55
const { UserToken } = require("./lib/user_token");
6+
const { RepositoryOps } = require("./repository/operations");
7+
const { RepositoryType } = require("./repository/types");
68

79
const g_db = require("@arangodb").db;
810
const g_graph = require("@arangodb/general-graph")._graph("sdmsg");
@@ -308,6 +310,34 @@ var tasks_func = (function () {
308310

309311
var result = g_proc.preprocessItems(a_client, null, a_res_ids, g_lib.TT_DATA_GET);
310312

313+
// Check repository types for all Globus data items
314+
if (result.glob_data.length > 0) {
315+
for (var i = 0; i < result.glob_data.length; i++) {
316+
var data = result.glob_data[i];
317+
// Get repository from data location
318+
var loc = g_db.loc.firstExample({ _from: data.id });
319+
if (loc) {
320+
var findResult = RepositoryOps.find(loc._to);
321+
if (findResult.ok) {
322+
var repository = findResult.value;
323+
var dataOpsResult = RepositoryOps.supportsDataOperations(repository);
324+
325+
if (dataOpsResult.ok && !dataOpsResult.value) {
326+
throw [
327+
g_lib.ERR_INVALID_OPERATION,
328+
"Data transfers not supported for metadata-only repository",
329+
{
330+
repo_type: repository.type,
331+
repo_id: repository.data._id,
332+
data_id: data.id
333+
}
334+
];
335+
}
336+
}
337+
}
338+
}
339+
}
340+
311341
if (result.glob_data.length + result.ext_data.length > 0 && !a_check) {
312342
var idx = a_path.indexOf("/");
313343
if (idx == -1)
@@ -492,6 +522,34 @@ var tasks_func = (function () {
492522

493523
var result = g_proc.preprocessItems(a_client, null, a_res_ids, g_lib.TT_DATA_PUT);
494524

525+
// Check repository types for all Globus data items
526+
if (result.glob_data.length > 0) {
527+
for (var i = 0; i < result.glob_data.length; i++) {
528+
var data = result.glob_data[i];
529+
// Get repository from data location
530+
var loc = g_db.loc.firstExample({ _from: data.id });
531+
if (loc) {
532+
var findResult = RepositoryOps.find(loc._to);
533+
if (findResult.ok) {
534+
var repository = findResult.value;
535+
var dataOpsResult = RepositoryOps.supportsDataOperations(repository);
536+
537+
if (dataOpsResult.ok && !dataOpsResult.value) {
538+
throw [
539+
g_lib.ERR_INVALID_OPERATION,
540+
"Data transfers not supported for metadata-only repository",
541+
{
542+
repo_type: repository.type,
543+
repo_id: repository.data._id,
544+
data_id: data.id
545+
}
546+
];
547+
}
548+
}
549+
}
550+
}
551+
}
552+
495553
if (result.glob_data.length > 0 && !a_check) {
496554
var idx = a_path.indexOf("/");
497555
if (idx == -1)

0 commit comments

Comments
 (0)