Line data Source code
1 : /* SPDX-License-Identifier: Apache-2.0 */
2 : /**
3 : * @file mlops-agent-interface.c
4 : * @date 5 April 2023
5 : * @brief A set of exported ml-agent interfaces for managing pipelines, models, and other service.
6 : * @see https://github.com/nnstreamer/deviceMLOps.MLAgent
7 : * @author Wook Song <wook16.song@samsung.com>
8 : * @bug No known bugs except for NYI items
9 : */
10 :
11 : #include <errno.h>
12 : #include <glib.h>
13 : #include <stdint.h>
14 : #include <json-glib/json-glib.h>
15 :
16 : #include "log.h"
17 : #include "include/mlops-agent-interface.h"
18 : #include "dbus-interface.h"
19 : #include "model-dbus.h"
20 : #include "pipeline-dbus.h"
21 : #include "resource-dbus.h"
22 :
23 : #if defined(__TIZEN__)
24 : #include <app_common.h>
25 :
26 : static char *
27 0 : _resolve_rpk_path_in_json (const char *json_str)
28 : {
29 0 : JsonNode *node = NULL;
30 0 : JsonArray *array = NULL;
31 0 : JsonObject *object = NULL;
32 0 : JsonNode *app_info_node = NULL;
33 0 : JsonObject *app_info_object = NULL;
34 0 : gchar *ret_json_str = NULL;
35 : const gchar *app_info;
36 :
37 : guint i, n;
38 :
39 0 : g_autofree gchar *app_id = NULL;
40 0 : if (app_get_id (&app_id) == APP_ERROR_INVALID_CONTEXT) {
41 0 : ml_logi ("Not an Tizen APP context.");
42 0 : return g_strdup (json_str);
43 : }
44 :
45 0 : node = json_from_string (json_str, NULL);
46 0 : if (!node) {
47 0 : ml_loge ("Failed to parse given json string.");
48 0 : return NULL;
49 : }
50 :
51 0 : if (JSON_NODE_HOLDS_ARRAY (node)) {
52 0 : array = json_node_get_array (node);
53 0 : n = (array) ? json_array_get_length (array) : 0U;
54 : } else {
55 0 : n = 1;
56 : }
57 :
58 0 : if (n == 0U) {
59 0 : ml_loge ("No data found in the given json string.");
60 0 : return NULL;
61 : }
62 :
63 0 : for (i = 0; i < n; ++i) {
64 0 : if (array) {
65 0 : object = json_array_get_object_element (array, i);
66 : } else {
67 0 : object = json_node_get_object (node);
68 : }
69 :
70 0 : if (!object) {
71 0 : ml_loge ("Failed to parse given json string.");
72 0 : return NULL;
73 : }
74 :
75 0 : app_info = json_object_get_string_member (object, "app_info");
76 0 : if (!app_info) {
77 0 : ml_loge ("Failed to get `app_info` from the given json string.");
78 0 : goto done;
79 : }
80 :
81 0 : app_info_node = json_from_string (app_info, NULL);
82 0 : if (!app_info_node) {
83 0 : ml_loge ("Failed to parse `app_info` from the given json string.");
84 0 : goto done;
85 : }
86 :
87 0 : app_info_object = json_node_get_object (app_info_node);
88 0 : if (!app_info_object) {
89 0 : ml_loge ("Failed to get `app_info` object.");
90 0 : json_node_free (app_info_node);
91 0 : goto done;
92 : }
93 :
94 0 : if (g_strcmp0 (json_object_get_string_member (app_info_object, "is_rpk"), "T") == 0) {
95 : gchar *new_path;
96 0 : g_autofree gchar *global_resource_path;
97 : const gchar *res_type =
98 0 : json_object_get_string_member (app_info_object, "res_type");
99 :
100 0 : const gchar *ori_path = json_object_get_string_member (object, "path");
101 :
102 0 : if (app_get_res_control_global_resource_path (res_type,
103 : &global_resource_path) != APP_ERROR_NONE) {
104 0 : ml_loge ("failed to get global resource path.");
105 0 : json_node_free (app_info_node);
106 0 : goto done;
107 : }
108 :
109 0 : new_path = g_strdup_printf ("%s/%s", global_resource_path, ori_path);
110 0 : json_object_set_string_member (object, "path", new_path);
111 0 : g_free (new_path);
112 : }
113 :
114 0 : json_node_free (app_info_node);
115 : }
116 :
117 0 : done:
118 0 : ret_json_str = json_to_string (node, TRUE);
119 0 : json_node_free (node);
120 :
121 0 : return ret_json_str;
122 : }
123 : #else
124 : static char *
125 : _resolve_rpk_path_in_json (const char *json_str)
126 : {
127 : return g_strdup (json_str);
128 : }
129 : #endif
130 :
131 : #define STR_IS_VALID(s) ((s) && (s)[0] != '\0')
132 :
133 : typedef enum
134 : {
135 : ML_AGENT_SERVICE_PIPELINE = 0,
136 : ML_AGENT_SERVICE_MODEL,
137 : ML_AGENT_SERVICE_RESOURCE,
138 : ML_AGENT_SERVICE_END
139 : } ml_agent_service_type_e;
140 :
141 : typedef gpointer ml_agent_proxy_h;
142 :
143 : /**
144 : * @brief An internal helper to get the dbus proxy
145 : */
146 : static ml_agent_proxy_h
147 0 : _get_proxy_new_for_bus_sync (ml_agent_service_type_e type)
148 : {
149 : static const GBusType bus_types[] = { G_BUS_TYPE_SYSTEM, G_BUS_TYPE_SESSION };
150 : static const size_t num_bus_types =
151 : sizeof (bus_types) / sizeof (bus_types[0]);
152 0 : ml_agent_proxy_h proxy = NULL;
153 : size_t i;
154 :
155 0 : switch (type) {
156 0 : case ML_AGENT_SERVICE_PIPELINE:
157 : {
158 : MachinelearningServicePipeline *mlsp;
159 :
160 0 : for (i = 0; i < num_bus_types; ++i) {
161 0 : mlsp = machinelearning_service_pipeline_proxy_new_for_bus_sync
162 : (bus_types[i], G_DBUS_PROXY_FLAGS_NONE, DBUS_ML_BUS_NAME,
163 : DBUS_PIPELINE_PATH, NULL, NULL);
164 0 : if (mlsp) {
165 0 : break;
166 : }
167 : }
168 0 : proxy = (ml_agent_proxy_h) mlsp;
169 0 : break;
170 : }
171 0 : case ML_AGENT_SERVICE_MODEL:
172 : {
173 : MachinelearningServiceModel *mlsm;
174 :
175 0 : for (i = 0; i < num_bus_types; ++i) {
176 0 : mlsm = machinelearning_service_model_proxy_new_for_bus_sync
177 : (bus_types[i], G_DBUS_PROXY_FLAGS_NONE, DBUS_ML_BUS_NAME,
178 : DBUS_MODEL_PATH, NULL, NULL);
179 0 : if (mlsm)
180 0 : break;
181 : }
182 0 : proxy = (ml_agent_proxy_h) mlsm;
183 0 : break;
184 : }
185 0 : case ML_AGENT_SERVICE_RESOURCE:
186 : {
187 : MachinelearningServiceResource *mlsr;
188 :
189 0 : for (i = 0; i < num_bus_types; ++i) {
190 0 : mlsr = machinelearning_service_resource_proxy_new_for_bus_sync
191 : (bus_types[i], G_DBUS_PROXY_FLAGS_NONE, DBUS_ML_BUS_NAME,
192 : DBUS_RESOURCE_PATH, NULL, NULL);
193 0 : if (mlsr)
194 0 : break;
195 : }
196 0 : proxy = (ml_agent_proxy_h) mlsr;
197 0 : break;
198 : }
199 0 : default:
200 0 : break;
201 : }
202 :
203 0 : return proxy;
204 : }
205 :
206 : /**
207 : * @brief An interface exported for setting the description of a pipeline.
208 : */
209 : int
210 0 : ml_agent_pipeline_set_description (const char *name, const char *pipeline_desc)
211 : {
212 : MachinelearningServicePipeline *mlsp;
213 : gboolean result;
214 :
215 0 : if (!STR_IS_VALID (name) || !STR_IS_VALID (pipeline_desc)) {
216 0 : g_return_val_if_reached (-EINVAL);
217 : }
218 :
219 0 : mlsp = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_PIPELINE);
220 0 : if (!mlsp) {
221 0 : g_return_val_if_reached (-EIO);
222 : }
223 :
224 0 : result = machinelearning_service_pipeline_call_set_pipeline_sync (mlsp,
225 : name, pipeline_desc, NULL, NULL, NULL);
226 0 : g_object_unref (mlsp);
227 :
228 0 : g_return_val_if_fail (result, -EIO);
229 0 : return 0;
230 : }
231 :
232 : /**
233 : * @brief An interface exported for getting the pipeline's description corresponding to the given @a name.
234 : */
235 : int
236 0 : ml_agent_pipeline_get_description (const char *name, char **pipeline_desc)
237 : {
238 : MachinelearningServicePipeline *mlsp;
239 : gboolean result;
240 : gint ret;
241 :
242 0 : if (!STR_IS_VALID (name) || !pipeline_desc) {
243 0 : g_return_val_if_reached (-EINVAL);
244 : }
245 :
246 0 : mlsp = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_PIPELINE);
247 0 : if (!mlsp) {
248 0 : g_return_val_if_reached (-EIO);
249 : }
250 :
251 0 : result = machinelearning_service_pipeline_call_get_pipeline_sync (mlsp,
252 : name, &ret, pipeline_desc, NULL, NULL);
253 0 : g_object_unref (mlsp);
254 :
255 0 : g_return_val_if_fail (ret == 0 && result, ret);
256 0 : return 0;
257 : }
258 :
259 : /**
260 : * @brief An interface exported for deletion of the pipeline's description corresponding to the given @a name.
261 : */
262 : int
263 0 : ml_agent_pipeline_delete (const char *name)
264 : {
265 : MachinelearningServicePipeline *mlsp;
266 : gboolean result;
267 : gint ret;
268 :
269 0 : if (!STR_IS_VALID (name)) {
270 0 : g_return_val_if_reached (-EINVAL);
271 : }
272 :
273 0 : mlsp = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_PIPELINE);
274 0 : if (!mlsp) {
275 0 : g_return_val_if_reached (-EIO);
276 : }
277 :
278 0 : result = machinelearning_service_pipeline_call_delete_pipeline_sync (mlsp,
279 : name, &ret, NULL, NULL);
280 0 : g_object_unref (mlsp);
281 :
282 0 : g_return_val_if_fail (ret == 0 && result, ret);
283 0 : return 0;
284 : }
285 :
286 : /**
287 : * @brief An interface exported for launching the pipeline's description corresponding to the given @a name.
288 : */
289 : int
290 0 : ml_agent_pipeline_launch (const char *name, int64_t * id)
291 : {
292 : MachinelearningServicePipeline *mlsp;
293 : gboolean result;
294 : gint ret;
295 :
296 0 : if (!STR_IS_VALID (name) || !id) {
297 0 : g_return_val_if_reached (-EINVAL);
298 : }
299 :
300 0 : mlsp = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_PIPELINE);
301 0 : if (!mlsp) {
302 0 : g_return_val_if_reached (-EIO);
303 : }
304 :
305 0 : result = machinelearning_service_pipeline_call_launch_pipeline_sync (mlsp,
306 : name, &ret, id, NULL, NULL);
307 0 : g_object_unref (mlsp);
308 :
309 0 : g_return_val_if_fail (ret == 0 && result, ret);
310 0 : return 0;
311 : }
312 :
313 : /**
314 : * @brief An interface exported for changing the pipeline's state of the given @a id to start.
315 : */
316 : int
317 0 : ml_agent_pipeline_start (const int64_t id)
318 : {
319 : MachinelearningServicePipeline *mlsp;
320 : gboolean result;
321 : gint ret;
322 :
323 0 : mlsp = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_PIPELINE);
324 0 : if (!mlsp) {
325 0 : g_return_val_if_reached (-EIO);
326 : }
327 :
328 0 : result = machinelearning_service_pipeline_call_start_pipeline_sync (mlsp,
329 : id, &ret, NULL, NULL);
330 0 : g_object_unref (mlsp);
331 :
332 0 : g_return_val_if_fail (ret == 0 && result, ret);
333 0 : return 0;
334 : }
335 :
336 : /**
337 : * @brief An interface exported for changing the pipeline's state of the given @a id to stop.
338 : */
339 : int
340 0 : ml_agent_pipeline_stop (const int64_t id)
341 : {
342 : MachinelearningServicePipeline *mlsp;
343 : gboolean result;
344 : gint ret;
345 :
346 0 : mlsp = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_PIPELINE);
347 0 : if (!mlsp) {
348 0 : g_return_val_if_reached (-EIO);
349 : }
350 :
351 0 : result = machinelearning_service_pipeline_call_stop_pipeline_sync (mlsp,
352 : id, &ret, NULL, NULL);
353 0 : g_object_unref (mlsp);
354 :
355 0 : g_return_val_if_fail (ret == 0 && result, ret);
356 0 : return 0;
357 : }
358 :
359 : /**
360 : * @brief An interface exported for destroying a launched pipeline corresponding to the given @a id.
361 : */
362 : int
363 0 : ml_agent_pipeline_destroy (const int64_t id)
364 : {
365 : MachinelearningServicePipeline *mlsp;
366 : gboolean result;
367 : gint ret;
368 :
369 0 : mlsp = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_PIPELINE);
370 0 : if (!mlsp) {
371 0 : g_return_val_if_reached (-EIO);
372 : }
373 :
374 0 : result = machinelearning_service_pipeline_call_destroy_pipeline_sync (mlsp,
375 : id, &ret, NULL, NULL);
376 0 : g_object_unref (mlsp);
377 :
378 0 : g_return_val_if_fail (ret == 0 && result, ret);
379 0 : return 0;
380 : }
381 :
382 : /**
383 : * @brief An interface exported for getting the pipeline's state of the given @a id.
384 : */
385 : int
386 0 : ml_agent_pipeline_get_state (const int64_t id, int *state)
387 : {
388 : MachinelearningServicePipeline *mlsp;
389 : gboolean result;
390 : gint ret;
391 :
392 0 : if (!state) {
393 0 : g_return_val_if_reached (-EINVAL);
394 : }
395 :
396 0 : mlsp = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_PIPELINE);
397 0 : if (!mlsp) {
398 0 : g_return_val_if_reached (-EIO);
399 : }
400 :
401 0 : result = machinelearning_service_pipeline_call_get_state_sync (mlsp,
402 : id, &ret, state, NULL, NULL);
403 0 : g_object_unref (mlsp);
404 :
405 0 : g_return_val_if_fail (ret == 0 && result, ret);
406 0 : return 0;
407 : }
408 :
409 : /**
410 : * @brief An interface exported for registering a model.
411 : */
412 : int
413 0 : ml_agent_model_register (const char *name, const char *path,
414 : const int activate, const char *description, const char *app_info,
415 : uint32_t * version)
416 : {
417 : MachinelearningServiceModel *mlsm;
418 : gboolean result;
419 : gint ret;
420 :
421 0 : if (!STR_IS_VALID (name) || !STR_IS_VALID (path) || !version) {
422 0 : g_return_val_if_reached (-EINVAL);
423 : }
424 :
425 0 : mlsm = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_MODEL);
426 0 : if (!mlsm) {
427 0 : g_return_val_if_reached (-EIO);
428 : }
429 :
430 0 : result = machinelearning_service_model_call_register_sync (mlsm, name, path,
431 : activate, description ? description : "", app_info ? app_info : "",
432 : version, &ret, NULL, NULL);
433 0 : g_object_unref (mlsm);
434 :
435 0 : g_return_val_if_fail (ret == 0 && result, ret);
436 0 : return 0;
437 : }
438 :
439 : /**
440 : * @brief An interface exported for updating the description of the model with @a name and @a version.
441 : */
442 : int
443 0 : ml_agent_model_update_description (const char *name,
444 : const uint32_t version, const char *description)
445 : {
446 : MachinelearningServiceModel *mlsm;
447 : gboolean result;
448 : gint ret;
449 :
450 0 : if (!STR_IS_VALID (name) || !STR_IS_VALID (description) || version == 0U) {
451 0 : g_return_val_if_reached (-EINVAL);
452 : }
453 :
454 0 : mlsm = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_MODEL);
455 0 : if (!mlsm) {
456 0 : g_return_val_if_reached (-EIO);
457 : }
458 :
459 0 : result = machinelearning_service_model_call_update_description_sync (mlsm,
460 : name, version, description, &ret, NULL, NULL);
461 0 : g_object_unref (mlsm);
462 :
463 0 : g_return_val_if_fail (ret == 0 && result, ret);
464 0 : return 0;
465 : }
466 :
467 : /**
468 : * @brief An interface exported for activating the model with @a name and @a version.
469 : */
470 : int
471 0 : ml_agent_model_activate (const char *name, const uint32_t version)
472 : {
473 : MachinelearningServiceModel *mlsm;
474 : gboolean result;
475 : gint ret;
476 :
477 0 : if (!STR_IS_VALID (name) || version == 0U) {
478 0 : g_return_val_if_reached (-EINVAL);
479 : }
480 :
481 0 : mlsm = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_MODEL);
482 0 : if (!mlsm) {
483 0 : g_return_val_if_reached (-EIO);
484 : }
485 :
486 0 : result = machinelearning_service_model_call_activate_sync (mlsm,
487 : name, version, &ret, NULL, NULL);
488 0 : g_object_unref (mlsm);
489 :
490 0 : g_return_val_if_fail (ret == 0 && result, ret);
491 0 : return 0;
492 : }
493 :
494 : /**
495 : * @brief An interface exported for getting the information of the model with @a name and @a version.
496 : */
497 : int
498 0 : ml_agent_model_get (const char *name, const uint32_t version, char **model_info)
499 : {
500 : MachinelearningServiceModel *mlsm;
501 : gboolean result;
502 : gint ret;
503 : gchar *ret_json;
504 :
505 0 : if (!STR_IS_VALID (name) || !model_info || version == 0U) {
506 0 : g_return_val_if_reached (-EINVAL);
507 : }
508 :
509 0 : mlsm = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_MODEL);
510 0 : if (!mlsm) {
511 0 : g_return_val_if_reached (-EIO);
512 : }
513 :
514 0 : result = machinelearning_service_model_call_get_sync (mlsm,
515 : name, version, &ret_json, &ret, NULL, NULL);
516 0 : g_object_unref (mlsm);
517 :
518 0 : g_return_val_if_fail (ret == 0 && result, ret);
519 :
520 0 : *model_info = _resolve_rpk_path_in_json (ret_json);
521 0 : g_free (ret_json);
522 :
523 0 : return 0;
524 : }
525 :
526 : /**
527 : * @brief An interface exported for getting the information of the activated model with @a name.
528 : */
529 : int
530 0 : ml_agent_model_get_activated (const char *name, char **model_info)
531 : {
532 : MachinelearningServiceModel *mlsm;
533 : gboolean result;
534 : gint ret;
535 : gchar *ret_json;
536 :
537 0 : if (!STR_IS_VALID (name) || !model_info) {
538 0 : g_return_val_if_reached (-EINVAL);
539 : }
540 :
541 0 : mlsm = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_MODEL);
542 0 : if (!mlsm) {
543 0 : g_return_val_if_reached (-EIO);
544 : }
545 :
546 0 : result = machinelearning_service_model_call_get_activated_sync (mlsm,
547 : name, &ret_json, &ret, NULL, NULL);
548 0 : g_object_unref (mlsm);
549 :
550 0 : g_return_val_if_fail (ret == 0 && result, ret);
551 :
552 0 : *model_info = _resolve_rpk_path_in_json (ret_json);
553 0 : g_free (ret_json);
554 :
555 0 : return 0;
556 : }
557 :
558 : /**
559 : * @brief An interface exported for getting the information of all the models corresponding to the given @a name.
560 : */
561 : int
562 0 : ml_agent_model_get_all (const char *name, char **model_info)
563 : {
564 : MachinelearningServiceModel *mlsm;
565 : gboolean result;
566 : gint ret;
567 : gchar *ret_json;
568 :
569 0 : if (!STR_IS_VALID (name) || !model_info) {
570 0 : g_return_val_if_reached (-EINVAL);
571 : }
572 :
573 0 : mlsm = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_MODEL);
574 0 : if (!mlsm) {
575 0 : g_return_val_if_reached (-EIO);
576 : }
577 :
578 0 : result = machinelearning_service_model_call_get_all_sync (mlsm,
579 : name, &ret_json, &ret, NULL, NULL);
580 0 : g_object_unref (mlsm);
581 :
582 0 : g_return_val_if_fail (ret == 0 && result, ret);
583 :
584 0 : *model_info = _resolve_rpk_path_in_json (ret_json);
585 0 : g_free (ret_json);
586 :
587 0 : return 0;
588 : }
589 :
590 : /**
591 : * @brief An interface exported for removing the model of @a name and @a version.
592 : * @details If @a force is true, this will delete the model even if it is activated.
593 : */
594 : int
595 0 : ml_agent_model_delete (const char *name, const uint32_t version,
596 : const int force)
597 : {
598 : MachinelearningServiceModel *mlsm;
599 : gboolean result;
600 : gint ret;
601 :
602 0 : if (!STR_IS_VALID (name)) {
603 0 : g_return_val_if_reached (-EINVAL);
604 : }
605 :
606 0 : mlsm = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_MODEL);
607 0 : if (!mlsm) {
608 0 : g_return_val_if_reached (-EIO);
609 : }
610 :
611 0 : result = machinelearning_service_model_call_delete_sync (mlsm,
612 : name, version, force, &ret, NULL, NULL);
613 0 : g_object_unref (mlsm);
614 :
615 0 : g_return_val_if_fail (ret == 0 && result, ret);
616 0 : return 0;
617 : }
618 :
619 : /**
620 : * @brief An interface exported for adding the resource.
621 : */
622 : int
623 0 : ml_agent_resource_add (const char *name, const char *path,
624 : const char *description, const char *app_info)
625 : {
626 : MachinelearningServiceResource *mlsr;
627 : gboolean result;
628 : gint ret;
629 :
630 0 : if (!STR_IS_VALID (name) || !STR_IS_VALID (path)) {
631 0 : g_return_val_if_reached (-EINVAL);
632 : }
633 :
634 0 : mlsr = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_RESOURCE);
635 0 : if (!mlsr) {
636 0 : g_return_val_if_reached (-EIO);
637 : }
638 :
639 0 : result = machinelearning_service_resource_call_add_sync (mlsr, name, path,
640 : description ? description : "", app_info ? app_info : "",
641 : &ret, NULL, NULL);
642 0 : g_object_unref (mlsr);
643 :
644 0 : g_return_val_if_fail (ret == 0 && result, ret);
645 0 : return 0;
646 : }
647 :
648 : /**
649 : * @brief An interface exported for removing the resource with @a name.
650 : */
651 : int
652 0 : ml_agent_resource_delete (const char *name)
653 : {
654 : MachinelearningServiceResource *mlsr;
655 : gboolean result;
656 : gint ret;
657 :
658 0 : if (!STR_IS_VALID (name)) {
659 0 : g_return_val_if_reached (-EINVAL);
660 : }
661 :
662 0 : mlsr = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_RESOURCE);
663 0 : if (!mlsr) {
664 0 : g_return_val_if_reached (-EIO);
665 : }
666 :
667 0 : result = machinelearning_service_resource_call_delete_sync (mlsr,
668 : name, &ret, NULL, NULL);
669 0 : g_object_unref (mlsr);
670 :
671 0 : g_return_val_if_fail (ret == 0 && result, ret);
672 0 : return 0;
673 : }
674 :
675 : /**
676 : * @brief An interface exported for getting the description of the resource with @a name.
677 : */
678 : int
679 0 : ml_agent_resource_get (const char *name, char **res_info)
680 : {
681 : MachinelearningServiceResource *mlsr;
682 : gboolean result;
683 : gint ret;
684 : gchar *ret_json;
685 :
686 0 : if (!STR_IS_VALID (name) || !res_info) {
687 0 : g_return_val_if_reached (-EINVAL);
688 : }
689 :
690 0 : mlsr = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_RESOURCE);
691 0 : if (!mlsr) {
692 0 : g_return_val_if_reached (-EIO);
693 : }
694 :
695 0 : result = machinelearning_service_resource_call_get_sync (mlsr,
696 : name, &ret_json, &ret, NULL, NULL);
697 0 : g_object_unref (mlsr);
698 :
699 0 : g_return_val_if_fail (ret == 0 && result, ret);
700 :
701 0 : *res_info = _resolve_rpk_path_in_json (ret_json);
702 0 : g_free (ret_json);
703 :
704 0 : return 0;
705 : }
|