Line data Source code
1 : /* SPDX-License-Identifier: Apache-2.0 */
2 : /**
3 : * Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
4 : *
5 : * @file ml-api-service-agent-client.c
6 : * @date 20 Jul 2022
7 : * @brief agent (dbus) implementation of NNStreamer/Service C-API
8 : * @see https://github.com/nnstreamer/nnstreamer
9 : * @author Yongjoo Ahn <yongjoo1.ahn@samsung.com>
10 : * @bug No known bugs except for NYI items
11 : */
12 :
13 : #include <glib/gstdio.h>
14 : #include <json-glib/json-glib.h>
15 :
16 : #include "ml-api-internal.h"
17 : #include "ml-api-service-private.h"
18 : #include "ml-api-service.h"
19 :
20 : #define WARN_MSG_DPTR_SET_OVER "The memory blocks pointed by pipeline_desc will be set over with a new one.\n" \
21 : "It is highly suggested that `%s` before it is set."
22 :
23 : #if defined(__TIZEN__)
24 : #include <app_common.h>
25 :
26 : /**
27 : * @brief Get Tizen application info. It should be a json string.
28 : */
29 : static gchar *
30 14 : _get_app_info (void)
31 : {
32 14 : g_autofree gchar *app_id = NULL;
33 14 : g_autoptr (JsonBuilder) builder = NULL;
34 14 : g_autoptr (JsonGenerator) gen = NULL;
35 : int ret;
36 :
37 14 : ret = app_get_id (&app_id);
38 14 : if (ret == APP_ERROR_INVALID_CONTEXT) {
39 : /* Not a Tizen APP context, e.g. gbs build test */
40 14 : _ml_logi ("Not an APP context, skip creating app_info.");
41 14 : return NULL;
42 : }
43 :
44 : /**
45 : * @todo Check whether the given path is in the app's resource directory.
46 : * Below is sample code for this (unfortunately, TCT get error with it):
47 : * g_autofree gchar *app_resource_path = NULL;
48 : * g_autofree gchar *app_shared_resource_path = NULL;
49 : * app_resource_path = app_get_resource_path ();
50 : * app_shared_resource_path = app_get_shared_resource_path ();
51 : * if (!app_resource_path || !app_shared_resource_path) {
52 : * _ml_error_report_return (ML_ERROR_PERMISSION_DENIED,
53 : * "Failed to get the app resource path of the caller.");
54 : * }
55 : * if (!g_str_has_prefix (path, app_resource_path) &&
56 : * !g_str_has_prefix (path, app_shared_resource_path)) {
57 : * _ml_error_report_return (ML_ERROR_PERMISSION_DENIED,
58 : * "The model file '%s' is not in the app's resource directory.", path);
59 : * }
60 : */
61 0 : builder = json_builder_new ();
62 0 : json_builder_begin_object (builder);
63 :
64 0 : json_builder_set_member_name (builder, "is_rpk");
65 0 : json_builder_add_string_value (builder, "F");
66 :
67 0 : json_builder_set_member_name (builder, "app_id");
68 0 : json_builder_add_string_value (builder, app_id);
69 :
70 0 : json_builder_end_object (builder);
71 :
72 0 : gen = json_generator_new ();
73 0 : json_generator_set_root (gen, json_builder_get_root (builder));
74 0 : json_generator_set_pretty (gen, TRUE);
75 :
76 0 : return json_generator_to_data (gen, NULL);
77 : }
78 : #else
79 : #define _get_app_info(...) (NULL)
80 : #endif
81 :
82 : /**
83 : * @brief Build ml_information_h from json cstring.
84 : */
85 : static gint
86 11 : _build_ml_info_from_json_cstr (const gchar * jcstring, void **handle)
87 : {
88 11 : g_autoptr (GError) err = NULL;
89 11 : g_autoptr (JsonParser) parser = NULL;
90 11 : g_autoptr (GList) members = NULL;
91 11 : ml_information_list_h _info_list = NULL;
92 11 : ml_information_h _info = NULL;
93 11 : JsonNode *rnode = NULL;
94 11 : JsonArray *array = NULL;
95 11 : JsonObject *jobj = NULL;
96 : GList *l;
97 11 : gint ret = ML_ERROR_NONE;
98 : guint i, n;
99 :
100 11 : if (!handle) {
101 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
102 : "The argument for ml-information should not be NULL.");
103 : }
104 :
105 11 : if (NULL != *handle) {
106 0 : _ml_logw (WARN_MSG_DPTR_SET_OVER, "info");
107 0 : *handle = NULL;
108 : }
109 :
110 11 : parser = json_parser_new ();
111 11 : if (!parser) {
112 0 : _ml_error_report_return (ML_ERROR_OUT_OF_MEMORY,
113 : "Failed to allocate memory for JsonParser. Out of memory?");
114 : }
115 :
116 11 : if (!json_parser_load_from_data (parser, jcstring, -1, &err)) {
117 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
118 : "Failed to parse the json string (%s).",
119 : err ? err->message : "Unknown error");
120 : }
121 :
122 11 : rnode = json_parser_get_root (parser);
123 11 : if (!rnode) {
124 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
125 : "Failed to get the root node of json string.");
126 : }
127 :
128 11 : if (JSON_NODE_HOLDS_ARRAY (rnode)) {
129 3 : array = json_node_get_array (rnode);
130 3 : n = (array) ? json_array_get_length (array) : 0U;
131 : } else {
132 8 : n = 1U;
133 : }
134 :
135 11 : if (n == 0U) {
136 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
137 : "Failed to retrieve the length of the json array.");
138 : }
139 :
140 11 : if (array)
141 3 : ret = _ml_information_list_create (&_info_list);
142 : else
143 8 : ret = _ml_information_create (&_info);
144 11 : if (ML_ERROR_NONE != ret) {
145 0 : _ml_error_report ("Failed to parse app_info, cannot create info handle.");
146 0 : goto done;
147 : }
148 :
149 24 : for (i = 0; i < n; i++) {
150 13 : if (array) {
151 5 : jobj = json_array_get_object_element (array, i);
152 5 : ret = _ml_information_create (&_info);
153 5 : if (ML_ERROR_NONE != ret) {
154 0 : _ml_error_report
155 : ("Failed to parse app_info, cannot create info handle.");
156 0 : goto done;
157 : }
158 :
159 5 : _ml_information_list_add (_info_list, _info);
160 : } else {
161 8 : jobj = json_node_get_object (rnode);
162 : }
163 :
164 13 : members = json_object_get_members (jobj);
165 74 : for (l = members; l != NULL; l = l->next) {
166 61 : const gchar *key = l->data;
167 61 : const gchar *val = _ml_service_get_json_string_member (jobj, key);
168 :
169 : /* Prevent empty string case. */
170 61 : if (STR_IS_VALID (key) && STR_IS_VALID (val)) {
171 46 : ret = _ml_information_set (_info, key, g_strdup (val), g_free);
172 46 : if (ret != ML_ERROR_NONE) {
173 0 : _ml_error_report ("Failed to append app info to the info handle.");
174 0 : goto done;
175 : }
176 : }
177 : }
178 : }
179 :
180 11 : done:
181 11 : if (ret == ML_ERROR_NONE) {
182 11 : *handle = (array) ? _info_list : _info;
183 : } else {
184 0 : if (_info_list)
185 0 : ml_information_list_destroy (_info_list);
186 0 : else if (_info)
187 0 : ml_information_destroy (_info);
188 : }
189 :
190 11 : return ret;
191 : }
192 :
193 : /**
194 : * @brief Internal function to check the path of model or resource.
195 : */
196 : static int
197 18 : _ml_service_check_path (const char *path)
198 : {
199 : int ret;
200 18 : g_autofree gchar *dir_name = NULL;
201 : GStatBuf statbuf;
202 :
203 18 : if (!path) {
204 2 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
205 : "The parameter, 'path' is NULL. It should be a valid string.");
206 : }
207 :
208 16 : if (g_file_test (path, G_FILE_TEST_IS_DIR))
209 0 : dir_name = g_strdup (path);
210 : else
211 16 : dir_name = g_path_get_dirname (path);
212 :
213 16 : ret = g_stat (dir_name, &statbuf);
214 16 : if (ret != 0) {
215 0 : _ml_error_report_return (ML_ERROR_PERMISSION_DENIED,
216 : "Failed to get the information of given path '%s'.", path);
217 : }
218 :
219 16 : if (!g_path_is_absolute (path)
220 16 : || !g_file_test (path, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
221 14 : || g_file_test (path, G_FILE_TEST_IS_SYMLINK)) {
222 2 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
223 : "Given path '%s' is not a regular.", path);
224 : }
225 :
226 14 : return ML_ERROR_NONE;
227 : }
228 :
229 : /**
230 : * @brief Set the pipeline description with a given name.
231 : */
232 : int
233 22 : ml_service_pipeline_set (const char *name, const char *pipeline_desc)
234 : {
235 22 : int ret = ML_ERROR_NONE;
236 :
237 22 : check_feature_state (ML_FEATURE_SERVICE);
238 :
239 22 : if (!name) {
240 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
241 : "The parameter, 'name' is NULL. It should be a valid string.");
242 : }
243 :
244 21 : if (!pipeline_desc) {
245 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
246 : "The parameter, 'pipeline_desc' is NULL. It should be a valid string.");
247 : }
248 :
249 20 : ret = ml_agent_pipeline_set_description (name, pipeline_desc);
250 20 : if (ret < 0) {
251 1 : _ml_error_report ("Failed to invoke the method set_pipeline.");
252 : }
253 :
254 20 : return ret;
255 : }
256 :
257 : /**
258 : * @brief Get the pipeline description with a given name.
259 : */
260 : int
261 15 : ml_service_pipeline_get (const char *name, char **pipeline_desc)
262 : {
263 15 : int ret = ML_ERROR_NONE;
264 :
265 15 : check_feature_state (ML_FEATURE_SERVICE);
266 :
267 15 : if (!name) {
268 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
269 : "The parameter, 'name' is NULL, It should be a valid string.");
270 : }
271 :
272 14 : if (pipeline_desc == NULL) {
273 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
274 : "The argument for 'pipeline_desc' should not be NULL.");
275 : }
276 :
277 13 : if (*pipeline_desc != NULL) {
278 7 : _ml_logw (WARN_MSG_DPTR_SET_OVER, "char *pipeline_desc = NULL");
279 7 : *pipeline_desc = NULL;
280 : }
281 :
282 13 : ret = ml_agent_pipeline_get_description (name, pipeline_desc);
283 13 : if (ret < 0) {
284 4 : _ml_error_report ("Failed to invoke the method get_pipeline.");
285 : }
286 :
287 13 : return ret;
288 : }
289 :
290 : /**
291 : * @brief Delete the pipeline description with a given name.
292 : */
293 : int
294 22 : ml_service_pipeline_delete (const char *name)
295 : {
296 22 : int ret = ML_ERROR_NONE;
297 :
298 22 : check_feature_state (ML_FEATURE_SERVICE);
299 :
300 22 : if (!name) {
301 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
302 : "The parameter, 'name' is NULL, It should be a valid string.");
303 : }
304 :
305 21 : ret = ml_agent_pipeline_delete (name);
306 21 : if (ret < 0) {
307 3 : _ml_error_report ("Failed to invoke the method delete_pipeline.");
308 : }
309 :
310 21 : return ret;
311 : }
312 :
313 : /**
314 : * @brief Launch the pipeline of given service.
315 : */
316 : int
317 16 : ml_service_pipeline_launch (const char *name, ml_service_h * handle)
318 : {
319 16 : int ret = ML_ERROR_NONE;
320 : ml_service_s *mls;
321 : _ml_service_server_s *server;
322 :
323 16 : check_feature_state (ML_FEATURE_SERVICE);
324 :
325 16 : if (handle == NULL) {
326 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
327 : "The argument for 'handle' should not be NULL.");
328 : }
329 :
330 15 : if (*handle != NULL) {
331 10 : _ml_logw (WARN_MSG_DPTR_SET_OVER, "ml_service_h *handle = NULL");
332 : }
333 15 : *handle = NULL;
334 :
335 15 : mls = _ml_service_create_internal (ML_SERVICE_TYPE_SERVER_PIPELINE);
336 15 : if (mls == NULL) {
337 0 : _ml_error_report_return (ML_ERROR_OUT_OF_MEMORY,
338 : "Failed to allocate memory for the service handle. Out of memory?");
339 : }
340 :
341 15 : mls->priv = server = g_try_new0 (_ml_service_server_s, 1);
342 15 : if (server == NULL) {
343 0 : _ml_service_destroy_internal (mls);
344 0 : _ml_error_report_return (ML_ERROR_OUT_OF_MEMORY,
345 : "Failed to allocate memory for the service handle's private data. Out of memory?");
346 : }
347 :
348 15 : ret = ml_agent_pipeline_launch (name, &(server->id));
349 15 : if (ret < 0) {
350 5 : _ml_service_destroy_internal (mls);
351 5 : _ml_error_report_return (ret,
352 : "Failed to invoke the method launch_pipeline.");
353 : }
354 :
355 10 : server->service_name = g_strdup (name);
356 10 : *handle = mls;
357 :
358 10 : return ML_ERROR_NONE;
359 : }
360 :
361 : /**
362 : * @brief Return state of given ml_service_h
363 : */
364 : int
365 13 : ml_service_pipeline_get_state (ml_service_h handle, ml_pipeline_state_e * state)
366 : {
367 13 : int ret = ML_ERROR_NONE;
368 13 : gint _state = ML_PIPELINE_STATE_UNKNOWN;
369 13 : ml_service_s *mls = (ml_service_s *) handle;
370 : _ml_service_server_s *server;
371 :
372 26 : check_feature_state (ML_FEATURE_SERVICE);
373 :
374 13 : if (NULL == state) {
375 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
376 : "The parameter 'state' should not be NULL.");
377 : }
378 12 : *state = ML_PIPELINE_STATE_UNKNOWN;
379 :
380 12 : if (!_ml_service_handle_is_valid (mls)) {
381 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
382 : "The parameter, 'handle' (ml_service_h), is invalid. It should be a valid ml_service_h instance.");
383 : }
384 :
385 11 : server = (_ml_service_server_s *) mls->priv;
386 11 : ret = ml_agent_pipeline_get_state (server->id, &_state);
387 11 : if (ret < 0) {
388 2 : _ml_error_report ("Failed to invoke the method get_state.");
389 : }
390 :
391 11 : *state = (ml_pipeline_state_e) _state;
392 11 : return ret;
393 : }
394 :
395 : /**
396 : * @brief Internal function to release ml-service pipeline data.
397 : */
398 : int
399 18 : _ml_service_pipeline_release_internal (ml_service_s * mls)
400 : {
401 18 : _ml_service_server_s *server = (_ml_service_server_s *) mls->priv;
402 : int ret;
403 :
404 : /* Supposed internal function call to release handle. */
405 18 : if (!server)
406 0 : return ML_ERROR_NONE;
407 :
408 18 : if (server->id > 0) {
409 13 : ret = ml_agent_pipeline_destroy (server->id);
410 13 : if (ret < 0) {
411 3 : _ml_error_report_return (ret,
412 : "Failed to invoke the method destroy_pipeline.");
413 : }
414 : }
415 :
416 15 : g_free (server->service_name);
417 15 : g_free (server);
418 15 : mls->priv = NULL;
419 :
420 15 : return ML_ERROR_NONE;
421 : }
422 :
423 : /**
424 : * @brief Registers new information of a neural network model.
425 : */
426 : int
427 16 : ml_service_model_register (const char *name, const char *path,
428 : const bool activate, const char *description, unsigned int *version)
429 : {
430 16 : int ret = ML_ERROR_NONE;
431 16 : g_autofree gchar *app_info = NULL;
432 16 : g_autofree gchar *converted = NULL;
433 :
434 16 : check_feature_state (ML_FEATURE_SERVICE);
435 :
436 16 : if (!name) {
437 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
438 : "The parameter, 'name' is NULL. It should be a valid string.");
439 : }
440 :
441 15 : if (NULL == version) {
442 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
443 : "The parameter 'version' should not be NULL.");
444 : }
445 14 : *version = 0U;
446 :
447 14 : converted = _ml_convert_predefined_entity (path);
448 14 : ret = _ml_service_check_path (converted);
449 14 : if (ret != ML_ERROR_NONE)
450 2 : return ret;
451 :
452 12 : app_info = _get_app_info ();
453 :
454 12 : ret = ml_agent_model_register (name, converted, activate,
455 12 : description ? description : "", app_info ? app_info : "", version);
456 12 : if (ret < 0) {
457 1 : _ml_error_report ("Failed to invoke the method model_register.");
458 : }
459 :
460 12 : return ret;
461 : }
462 :
463 : /**
464 : * @brief Updates the description of neural network model with given @a name and @a version.
465 : */
466 : int
467 7 : ml_service_model_update_description (const char *name,
468 : const unsigned int version, const char *description)
469 : {
470 7 : int ret = ML_ERROR_NONE;
471 :
472 7 : check_feature_state (ML_FEATURE_SERVICE);
473 :
474 7 : if (!name) {
475 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
476 : "The parameter, 'name' is NULL. It should be a valid string.");
477 : }
478 :
479 6 : if (version == 0U) {
480 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
481 : "The parameter, 'version' is 0. It should be a valid unsigned int.");
482 : }
483 :
484 5 : if (!description) {
485 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
486 : "The parameter, 'description' is NULL. It should be a valid string.");
487 : }
488 :
489 4 : ret = ml_agent_model_update_description (name, version, description);
490 4 : if (ret < 0) {
491 3 : _ml_error_report ("Failed to invoke the method model_update_description.");
492 : }
493 :
494 4 : return ret;
495 : }
496 :
497 : /**
498 : * @brief Activates a neural network model with given @a name and @a version.
499 : */
500 : int
501 6 : ml_service_model_activate (const char *name, const unsigned int version)
502 : {
503 6 : int ret = ML_ERROR_NONE;
504 :
505 6 : check_feature_state (ML_FEATURE_SERVICE);
506 :
507 6 : if (!name) {
508 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
509 : "The parameter, 'name' is NULL. It should be a valid string.");
510 : }
511 :
512 5 : if (version == 0U) {
513 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
514 : "The parameter, 'version' is 0. It should be a valid unsigned int.");
515 : }
516 :
517 4 : ret = ml_agent_model_activate (name, version);
518 4 : if (ret < 0) {
519 3 : _ml_error_report ("Failed to invoke the method model_activate.");
520 : }
521 :
522 4 : return ret;
523 : }
524 :
525 : /**
526 : * @brief Gets the information of neural network model with given @a name and @a version.
527 : */
528 : int
529 7 : ml_service_model_get (const char *name, const unsigned int version,
530 : ml_information_h * info)
531 : {
532 7 : int ret = ML_ERROR_NONE;
533 7 : ml_information_h _info = NULL;
534 7 : g_autofree gchar *description = NULL;
535 :
536 7 : check_feature_state (ML_FEATURE_SERVICE);
537 :
538 7 : if (!name) {
539 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
540 : "The parameter, 'name' is NULL. It should be a valid string.");
541 : }
542 :
543 6 : if (info == NULL) {
544 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
545 : "The argument for 'info' should not be NULL.");
546 : }
547 :
548 5 : if (*info != NULL) {
549 3 : _ml_logw (WARN_MSG_DPTR_SET_OVER, "ml_information_h info = NULL");
550 : }
551 5 : *info = NULL;
552 :
553 5 : ret = ml_agent_model_get (name, version, &description);
554 5 : if (ML_ERROR_NONE != ret || !description) {
555 3 : _ml_error_report ("Failed to invoke the method model_get.");
556 3 : return ret;
557 : }
558 :
559 2 : ret = _build_ml_info_from_json_cstr (description, &_info);
560 2 : if (ML_ERROR_NONE != ret)
561 0 : _ml_error_report ("Failed to convert json string to ml-information.");
562 : else
563 2 : *info = _info;
564 :
565 2 : return ret;
566 : }
567 :
568 : /**
569 : * @brief Gets the information of activated neural network model with given @a name.
570 : */
571 : int
572 10 : ml_service_model_get_activated (const char *name, ml_information_h * info)
573 : {
574 10 : int ret = ML_ERROR_NONE;
575 :
576 10 : ml_information_h _info = NULL;
577 10 : g_autofree gchar *description = NULL;
578 :
579 10 : check_feature_state (ML_FEATURE_SERVICE);
580 :
581 10 : if (!name) {
582 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
583 : "The parameter, 'name' is NULL. It should be a valid string.");
584 : }
585 :
586 9 : if (info == NULL) {
587 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
588 : "The argument for 'info' should not be NULL.");
589 : }
590 :
591 8 : if (*info != NULL) {
592 7 : _ml_logw (WARN_MSG_DPTR_SET_OVER, "ml_information_h info = NULL");
593 : }
594 8 : *info = NULL;
595 :
596 8 : ret = ml_agent_model_get_activated (name, &description);
597 8 : if (ML_ERROR_NONE != ret || !description) {
598 2 : _ml_error_report ("Failed to invoke the method model_get_activated.");
599 2 : return ret;
600 : }
601 :
602 6 : ret = _build_ml_info_from_json_cstr (description, &_info);
603 6 : if (ML_ERROR_NONE != ret)
604 0 : _ml_error_report ("Failed to convert json string to ml_information_h.");
605 : else
606 6 : *info = _info;
607 :
608 6 : return ret;
609 : }
610 :
611 : /**
612 : * @brief Gets the list of neural network model with given @a name.
613 : */
614 : int
615 6 : ml_service_model_get_all (const char *name, ml_information_list_h * info_list)
616 : {
617 6 : g_autofree gchar *description = NULL;
618 6 : ml_information_list_h _info_list = NULL;
619 6 : int ret = ML_ERROR_NONE;
620 :
621 6 : check_feature_state (ML_FEATURE_SERVICE);
622 :
623 6 : if (!name) {
624 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
625 : "The parameter, 'name' is NULL. It should be a valid string.");
626 : }
627 :
628 5 : if (NULL == info_list) {
629 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
630 : "The parameter 'info_list' should not be NULL.");
631 : }
632 4 : *info_list = NULL;
633 :
634 4 : ret = ml_agent_model_get_all (name, &description);
635 4 : if (ML_ERROR_NONE != ret || !description) {
636 2 : _ml_error_report_return (ret, "Failed to invoke the method model_get_all.");
637 : }
638 :
639 2 : ret = _build_ml_info_from_json_cstr (description, &_info_list);
640 2 : if (ML_ERROR_NONE != ret)
641 0 : _ml_error_report ("Failed to convert json string to ml-information list.");
642 : else
643 2 : *info_list = _info_list;
644 :
645 2 : return ret;
646 : }
647 :
648 : /**
649 : * @brief Deletes a model information with given @a name and @a version from machine learning service.
650 : */
651 : int
652 18 : ml_service_model_delete (const char *name, const unsigned int version)
653 : {
654 18 : int ret = ML_ERROR_NONE;
655 :
656 18 : check_feature_state (ML_FEATURE_SERVICE);
657 :
658 18 : if (!name) {
659 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
660 : "The parameter, 'name' is NULL. It should be a valid string.");
661 : }
662 :
663 17 : ret = ml_agent_model_delete (name, version, FALSE);
664 17 : if (ret < 0) {
665 10 : _ml_error_report ("Failed to invoke the method model_delete.");
666 : }
667 :
668 17 : return ret;
669 : }
670 :
671 : /**
672 : * @brief Adds new information of machine learning resources.
673 : */
674 : int
675 5 : ml_service_resource_add (const char *name, const char *path,
676 : const char *description)
677 : {
678 5 : int ret = ML_ERROR_NONE;
679 5 : g_autofree gchar *app_info = NULL;
680 5 : g_autofree gchar *converted = NULL;
681 :
682 5 : check_feature_state (ML_FEATURE_SERVICE);
683 :
684 5 : if (!name) {
685 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
686 : "The parameter, 'name' is NULL. It should be a valid string.");
687 : }
688 :
689 4 : converted = _ml_convert_predefined_entity (path);
690 4 : ret = _ml_service_check_path (converted);
691 4 : if (ret != ML_ERROR_NONE)
692 2 : return ret;
693 :
694 2 : app_info = _get_app_info ();
695 :
696 2 : ret = ml_agent_resource_add (name, converted, description ? description : "",
697 2 : app_info ? app_info : "");
698 2 : if (ret < 0) {
699 0 : _ml_error_report ("Failed to invoke the method resource_add.");
700 : }
701 :
702 2 : return ret;
703 : }
704 :
705 : /**
706 : * @brief Deletes the information of the resources from machine learning service.
707 : */
708 : int
709 2 : ml_service_resource_delete (const char *name)
710 : {
711 2 : int ret = ML_ERROR_NONE;
712 :
713 2 : check_feature_state (ML_FEATURE_SERVICE);
714 :
715 2 : if (!name) {
716 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
717 : "The parameter, 'name' is NULL. It should be a valid string.");
718 : }
719 :
720 1 : ret = ml_agent_resource_delete (name);
721 1 : if (ret < 0) {
722 1 : _ml_error_report ("Failed to invoke the method resource_delete.");
723 : }
724 :
725 1 : return ret;
726 : }
727 :
728 : /**
729 : * @brief Gets the information of the resources from machine learning service.
730 : */
731 : int
732 3 : ml_service_resource_get (const char *name, ml_information_list_h * res)
733 : {
734 3 : int ret = ML_ERROR_NONE;
735 3 : ml_information_list_h _info_list = NULL;
736 3 : g_autofree gchar *res_info = NULL;
737 :
738 3 : check_feature_state (ML_FEATURE_SERVICE);
739 :
740 3 : if (!name) {
741 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
742 : "The parameter, 'name' is NULL. It should be a valid string.");
743 : }
744 :
745 2 : if (res == NULL) {
746 1 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
747 : "The argument for 'res' should not be NULL.");
748 : }
749 :
750 1 : if (*res != NULL) {
751 1 : _ml_logw (WARN_MSG_DPTR_SET_OVER, "ml_information_list_h res = NULL");
752 : }
753 1 : *res = NULL;
754 :
755 1 : ret = ml_agent_resource_get (name, &res_info);
756 1 : if (ML_ERROR_NONE != ret || !res_info) {
757 0 : _ml_error_report_return (ret, "Failed to invoke the method resource_get.");
758 : }
759 :
760 1 : ret = _build_ml_info_from_json_cstr (res_info, &_info_list);
761 1 : if (ML_ERROR_NONE != ret)
762 0 : _ml_error_report ("Failed to convert json string to ml-information list.");
763 : else
764 1 : *res = _info_list;
765 :
766 1 : return ret;
767 : }
|