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 0 : _resolve_rpk_path_in_json (const char *json_str)
29 : {
30 0 : JsonNode *node = NULL;
31 0 : JsonArray *array = NULL;
32 0 : JsonObject *object = NULL;
33 0 : JsonNode *app_info_node = NULL;
34 0 : JsonObject *app_info_object = NULL;
35 0 : gchar *ret_json_str = NULL;
36 : const gchar *app_info;
37 :
38 : guint i, n;
39 :
40 0 : g_autofree gchar *app_id = NULL;
41 0 : if (app_get_id (&app_id) == APP_ERROR_INVALID_CONTEXT) {
42 0 : ml_logi ("Not an Tizen APP context.");
43 0 : 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 0 : _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 0 : ml_agent_proxy_h proxy = NULL;
144 : size_t i;
145 :
146 0 : switch (type) {
147 0 : case ML_AGENT_SERVICE_PIPELINE:
148 : {
149 : MachinelearningServicePipeline *mlsp;
150 :
151 0 : for (i = 0; i < num_bus_types; ++i) {
152 0 : mlsp = machinelearning_service_pipeline_proxy_new_for_bus_sync
153 0 : (bus_types[i], G_DBUS_PROXY_FLAGS_NONE, DBUS_ML_BUS_NAME,
154 : DBUS_PIPELINE_PATH, NULL, NULL);
155 0 : if (mlsp) {
156 0 : break;
157 : }
158 : }
159 0 : proxy = (ml_agent_proxy_h) mlsp;
160 0 : break;
161 : }
162 0 : case ML_AGENT_SERVICE_MODEL:
163 : {
164 : MachinelearningServiceModel *mlsm;
165 :
166 0 : for (i = 0; i < num_bus_types; ++i) {
167 0 : mlsm = machinelearning_service_model_proxy_new_for_bus_sync
168 0 : (bus_types[i], G_DBUS_PROXY_FLAGS_NONE, DBUS_ML_BUS_NAME,
169 : DBUS_MODEL_PATH, NULL, NULL);
170 0 : if (mlsm)
171 0 : break;
172 : }
173 0 : proxy = (ml_agent_proxy_h) mlsm;
174 0 : break;
175 : }
176 0 : case ML_AGENT_SERVICE_RESOURCE:
177 : {
178 : MachinelearningServiceResource *mlsr;
179 :
180 0 : for (i = 0; i < num_bus_types; ++i) {
181 0 : mlsr = machinelearning_service_resource_proxy_new_for_bus_sync
182 0 : (bus_types[i], G_DBUS_PROXY_FLAGS_NONE, DBUS_ML_BUS_NAME,
183 : DBUS_RESOURCE_PATH, NULL, NULL);
184 0 : if (mlsr)
185 0 : break;
186 : }
187 0 : proxy = (ml_agent_proxy_h) mlsr;
188 0 : break;
189 : }
190 0 : default:
191 0 : break;
192 : }
193 :
194 0 : return proxy;
195 : }
196 :
197 : /**
198 : * @brief An interface exported for setting the description of a pipeline.
199 : */
200 : int
201 0 : ml_agent_pipeline_set_description (const char *name, const char *pipeline_desc)
202 : {
203 : MachinelearningServicePipeline *mlsp;
204 : gboolean result;
205 : gint ret;
206 :
207 0 : if (!STR_IS_VALID (name) || !STR_IS_VALID (pipeline_desc)) {
208 0 : g_return_val_if_reached (-EINVAL);
209 : }
210 :
211 0 : mlsp = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_PIPELINE);
212 0 : if (!mlsp) {
213 0 : g_return_val_if_reached (-EIO);
214 : }
215 :
216 0 : result = machinelearning_service_pipeline_call_set_pipeline_sync (mlsp,
217 : name, pipeline_desc, &ret, NULL, NULL);
218 0 : g_object_unref (mlsp);
219 :
220 0 : g_return_val_if_fail (ret == 0 && result, ret);
221 0 : 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 0 : ml_agent_pipeline_get_description (const char *name, char **pipeline_desc)
229 : {
230 : MachinelearningServicePipeline *mlsp;
231 : gboolean result;
232 : gint ret;
233 :
234 0 : if (!STR_IS_VALID (name) || !pipeline_desc) {
235 0 : g_return_val_if_reached (-EINVAL);
236 : }
237 :
238 0 : mlsp = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_PIPELINE);
239 0 : if (!mlsp) {
240 0 : g_return_val_if_reached (-EIO);
241 : }
242 :
243 0 : result = machinelearning_service_pipeline_call_get_pipeline_sync (mlsp,
244 : name, &ret, pipeline_desc, NULL, NULL);
245 0 : g_object_unref (mlsp);
246 :
247 0 : g_return_val_if_fail (ret == 0 && result, ret);
248 0 : 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 0 : ml_agent_pipeline_delete (const char *name)
256 : {
257 : MachinelearningServicePipeline *mlsp;
258 : gboolean result;
259 : gint ret;
260 :
261 0 : if (!STR_IS_VALID (name)) {
262 0 : g_return_val_if_reached (-EINVAL);
263 : }
264 :
265 0 : mlsp = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_PIPELINE);
266 0 : if (!mlsp) {
267 0 : g_return_val_if_reached (-EIO);
268 : }
269 :
270 0 : result = machinelearning_service_pipeline_call_delete_pipeline_sync (mlsp,
271 : name, &ret, NULL, NULL);
272 0 : g_object_unref (mlsp);
273 :
274 0 : g_return_val_if_fail (ret == 0 && result, ret);
275 0 : 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 0 : ml_agent_pipeline_launch (const char *name, int64_t * id)
283 : {
284 : MachinelearningServicePipeline *mlsp;
285 : gboolean result;
286 : gint ret;
287 :
288 0 : if (!STR_IS_VALID (name) || !id) {
289 0 : g_return_val_if_reached (-EINVAL);
290 : }
291 :
292 0 : mlsp = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_PIPELINE);
293 0 : if (!mlsp) {
294 0 : g_return_val_if_reached (-EIO);
295 : }
296 :
297 0 : result = machinelearning_service_pipeline_call_launch_pipeline_sync (mlsp,
298 : name, &ret, id, NULL, NULL);
299 0 : g_object_unref (mlsp);
300 :
301 0 : g_return_val_if_fail (ret == 0 && result, ret);
302 0 : 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 0 : ml_agent_pipeline_start (const int64_t id)
310 : {
311 : MachinelearningServicePipeline *mlsp;
312 : gboolean result;
313 : gint ret;
314 :
315 0 : mlsp = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_PIPELINE);
316 0 : if (!mlsp) {
317 0 : g_return_val_if_reached (-EIO);
318 : }
319 :
320 0 : result = machinelearning_service_pipeline_call_start_pipeline_sync (mlsp,
321 : id, &ret, NULL, NULL);
322 0 : g_object_unref (mlsp);
323 :
324 0 : g_return_val_if_fail (ret == 0 && result, ret);
325 0 : 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 0 : ml_agent_pipeline_stop (const int64_t id)
333 : {
334 : MachinelearningServicePipeline *mlsp;
335 : gboolean result;
336 : gint ret;
337 :
338 0 : mlsp = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_PIPELINE);
339 0 : if (!mlsp) {
340 0 : g_return_val_if_reached (-EIO);
341 : }
342 :
343 0 : result = machinelearning_service_pipeline_call_stop_pipeline_sync (mlsp,
344 : id, &ret, NULL, NULL);
345 0 : g_object_unref (mlsp);
346 :
347 0 : g_return_val_if_fail (ret == 0 && result, ret);
348 0 : 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 0 : ml_agent_pipeline_destroy (const int64_t id)
356 : {
357 : MachinelearningServicePipeline *mlsp;
358 : gboolean result;
359 : gint ret;
360 :
361 0 : mlsp = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_PIPELINE);
362 0 : if (!mlsp) {
363 0 : g_return_val_if_reached (-EIO);
364 : }
365 :
366 0 : result = machinelearning_service_pipeline_call_destroy_pipeline_sync (mlsp,
367 : id, &ret, NULL, NULL);
368 0 : g_object_unref (mlsp);
369 :
370 0 : g_return_val_if_fail (ret == 0 && result, ret);
371 0 : 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 0 : ml_agent_pipeline_get_state (const int64_t id, int *state)
379 : {
380 : MachinelearningServicePipeline *mlsp;
381 : gboolean result;
382 : gint ret;
383 :
384 0 : if (!state) {
385 0 : g_return_val_if_reached (-EINVAL);
386 : }
387 :
388 0 : mlsp = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_PIPELINE);
389 0 : if (!mlsp) {
390 0 : g_return_val_if_reached (-EIO);
391 : }
392 :
393 0 : result = machinelearning_service_pipeline_call_get_state_sync (mlsp,
394 : id, &ret, state, NULL, NULL);
395 0 : g_object_unref (mlsp);
396 :
397 0 : g_return_val_if_fail (ret == 0 && result, ret);
398 0 : return 0;
399 : }
400 :
401 : /**
402 : * @brief An interface exported for registering a model.
403 : */
404 : int
405 0 : 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 0 : if (!STR_IS_VALID (name) || !STR_IS_VALID (path) || !version) {
414 0 : g_return_val_if_reached (-EINVAL);
415 : }
416 :
417 0 : mlsm = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_MODEL);
418 0 : if (!mlsm) {
419 0 : g_return_val_if_reached (-EIO);
420 : }
421 :
422 0 : result = machinelearning_service_model_call_register_sync (mlsm, name, path,
423 : activate, description ? description : "", app_info ? app_info : "",
424 : version, &ret, NULL, NULL);
425 0 : g_object_unref (mlsm);
426 :
427 0 : g_return_val_if_fail (ret == 0 && result, ret);
428 0 : 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 0 : 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 0 : if (!STR_IS_VALID (name) || !STR_IS_VALID (description) || version == 0U) {
443 0 : g_return_val_if_reached (-EINVAL);
444 : }
445 :
446 0 : mlsm = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_MODEL);
447 0 : if (!mlsm) {
448 0 : g_return_val_if_reached (-EIO);
449 : }
450 :
451 0 : result = machinelearning_service_model_call_update_description_sync (mlsm,
452 : name, version, description, &ret, NULL, NULL);
453 0 : g_object_unref (mlsm);
454 :
455 0 : g_return_val_if_fail (ret == 0 && result, ret);
456 0 : return 0;
457 : }
458 :
459 : /**
460 : * @brief An interface exported for activating the model with @a name and @a version.
461 : */
462 : int
463 0 : ml_agent_model_activate (const char *name, const uint32_t version)
464 : {
465 : MachinelearningServiceModel *mlsm;
466 : gboolean result;
467 : gint ret;
468 :
469 0 : if (!STR_IS_VALID (name) || version == 0U) {
470 0 : g_return_val_if_reached (-EINVAL);
471 : }
472 :
473 0 : mlsm = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_MODEL);
474 0 : if (!mlsm) {
475 0 : g_return_val_if_reached (-EIO);
476 : }
477 :
478 0 : result = machinelearning_service_model_call_activate_sync (mlsm,
479 : name, version, &ret, NULL, NULL);
480 0 : g_object_unref (mlsm);
481 :
482 0 : g_return_val_if_fail (ret == 0 && result, ret);
483 0 : 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 0 : 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 0 : if (!STR_IS_VALID (name) || !model_info || version == 0U) {
498 0 : g_return_val_if_reached (-EINVAL);
499 : }
500 :
501 0 : mlsm = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_MODEL);
502 0 : if (!mlsm) {
503 0 : g_return_val_if_reached (-EIO);
504 : }
505 :
506 0 : result = machinelearning_service_model_call_get_sync (mlsm,
507 : name, version, &ret_json, &ret, NULL, NULL);
508 0 : g_object_unref (mlsm);
509 :
510 0 : g_return_val_if_fail (ret == 0 && result, ret);
511 :
512 0 : *model_info = _resolve_rpk_path_in_json (ret_json);
513 0 : g_free (ret_json);
514 :
515 0 : 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 0 : 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 0 : if (!STR_IS_VALID (name) || !model_info) {
530 0 : g_return_val_if_reached (-EINVAL);
531 : }
532 :
533 0 : mlsm = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_MODEL);
534 0 : if (!mlsm) {
535 0 : g_return_val_if_reached (-EIO);
536 : }
537 :
538 0 : result = machinelearning_service_model_call_get_activated_sync (mlsm,
539 : name, &ret_json, &ret, NULL, NULL);
540 0 : g_object_unref (mlsm);
541 :
542 0 : g_return_val_if_fail (ret == 0 && result, ret);
543 :
544 0 : *model_info = _resolve_rpk_path_in_json (ret_json);
545 0 : g_free (ret_json);
546 :
547 0 : 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 0 : 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 0 : if (!STR_IS_VALID (name) || !model_info) {
562 0 : g_return_val_if_reached (-EINVAL);
563 : }
564 :
565 0 : mlsm = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_MODEL);
566 0 : if (!mlsm) {
567 0 : g_return_val_if_reached (-EIO);
568 : }
569 :
570 0 : result = machinelearning_service_model_call_get_all_sync (mlsm,
571 : name, &ret_json, &ret, NULL, NULL);
572 0 : g_object_unref (mlsm);
573 :
574 0 : g_return_val_if_fail (ret == 0 && result, ret);
575 :
576 0 : *model_info = _resolve_rpk_path_in_json (ret_json);
577 0 : g_free (ret_json);
578 :
579 0 : 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 0 : 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 0 : if (!STR_IS_VALID (name)) {
595 0 : g_return_val_if_reached (-EINVAL);
596 : }
597 :
598 0 : mlsm = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_MODEL);
599 0 : if (!mlsm) {
600 0 : g_return_val_if_reached (-EIO);
601 : }
602 :
603 0 : result = machinelearning_service_model_call_delete_sync (mlsm,
604 : name, version, force, &ret, NULL, NULL);
605 0 : g_object_unref (mlsm);
606 :
607 0 : g_return_val_if_fail (ret == 0 && result, ret);
608 0 : return 0;
609 : }
610 :
611 : /**
612 : * @brief An interface exported for adding the resource.
613 : */
614 : int
615 0 : 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 0 : if (!STR_IS_VALID (name) || !STR_IS_VALID (path)) {
623 0 : g_return_val_if_reached (-EINVAL);
624 : }
625 :
626 0 : mlsr = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_RESOURCE);
627 0 : if (!mlsr) {
628 0 : g_return_val_if_reached (-EIO);
629 : }
630 :
631 0 : result = machinelearning_service_resource_call_add_sync (mlsr, name, path,
632 : description ? description : "", app_info ? app_info : "",
633 : &ret, NULL, NULL);
634 0 : g_object_unref (mlsr);
635 :
636 0 : g_return_val_if_fail (ret == 0 && result, ret);
637 0 : return 0;
638 : }
639 :
640 : /**
641 : * @brief An interface exported for removing the resource with @a name.
642 : */
643 : int
644 0 : ml_agent_resource_delete (const char *name)
645 : {
646 : MachinelearningServiceResource *mlsr;
647 : gboolean result;
648 : gint ret;
649 :
650 0 : if (!STR_IS_VALID (name)) {
651 0 : g_return_val_if_reached (-EINVAL);
652 : }
653 :
654 0 : mlsr = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_RESOURCE);
655 0 : if (!mlsr) {
656 0 : g_return_val_if_reached (-EIO);
657 : }
658 :
659 0 : result = machinelearning_service_resource_call_delete_sync (mlsr,
660 : name, &ret, NULL, NULL);
661 0 : g_object_unref (mlsr);
662 :
663 0 : g_return_val_if_fail (ret == 0 && result, ret);
664 0 : return 0;
665 : }
666 :
667 : /**
668 : * @brief An interface exported for getting the description of the resource with @a name.
669 : */
670 : int
671 0 : 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 0 : if (!STR_IS_VALID (name) || !res_info) {
679 0 : g_return_val_if_reached (-EINVAL);
680 : }
681 :
682 0 : mlsr = _get_proxy_new_for_bus_sync (ML_AGENT_SERVICE_RESOURCE);
683 0 : if (!mlsr) {
684 0 : g_return_val_if_reached (-EIO);
685 : }
686 :
687 0 : result = machinelearning_service_resource_call_get_sync (mlsr,
688 : name, &ret_json, &ret, NULL, NULL);
689 0 : g_object_unref (mlsr);
690 :
691 0 : g_return_val_if_fail (ret == 0 && result, ret);
692 :
693 0 : *res_info = _resolve_rpk_path_in_json (ret_json);
694 0 : g_free (ret_json);
695 :
696 0 : return 0;
697 : }
|