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