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 0 : _get_app_info (void)
31 : {
32 0 : g_autofree gchar *app_id = NULL;
33 0 : g_autoptr (JsonBuilder) builder = NULL;
34 0 : g_autoptr (JsonGenerator) gen = NULL;
35 : int ret;
36 :
37 0 : ret = app_get_id (&app_id);
38 0 : if (ret == APP_ERROR_INVALID_CONTEXT) {
39 : /* Not a Tizen APP context, e.g. gbs build test */
40 0 : _ml_logi ("Not an APP context, skip creating app_info.");
41 0 : 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 0 : _build_ml_info_from_json_cstr (const gchar * jcstring, void **handle)
87 : {
88 0 : g_autoptr (GError) err = NULL;
89 0 : g_autoptr (JsonParser) parser = NULL;
90 0 : g_autoptr (GList) members = NULL;
91 0 : ml_information_list_h _info_list = NULL;
92 0 : ml_information_h _info = NULL;
93 0 : JsonNode *rnode = NULL;
94 0 : JsonArray *array = NULL;
95 0 : JsonObject *jobj = NULL;
96 : GList *l;
97 0 : gint ret = ML_ERROR_NONE;
98 : guint i, n;
99 :
100 0 : 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 0 : if (NULL != *handle) {
106 0 : _ml_logw (WARN_MSG_DPTR_SET_OVER, "info");
107 0 : *handle = NULL;
108 : }
109 :
110 0 : parser = json_parser_new ();
111 0 : 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 0 : 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 0 : rnode = json_parser_get_root (parser);
123 0 : 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 0 : if (JSON_NODE_HOLDS_ARRAY (rnode)) {
129 0 : array = json_node_get_array (rnode);
130 0 : n = (array) ? json_array_get_length (array) : 0U;
131 : } else {
132 0 : n = 1U;
133 : }
134 :
135 0 : 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 0 : if (array)
141 0 : ret = _ml_information_list_create (&_info_list);
142 : else
143 0 : ret = _ml_information_create (&_info);
144 0 : 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 0 : for (i = 0; i < n; i++) {
150 0 : if (array) {
151 0 : jobj = json_array_get_object_element (array, i);
152 0 : ret = _ml_information_create (&_info);
153 0 : 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 0 : _ml_information_list_add (_info_list, _info);
160 : } else {
161 0 : jobj = json_node_get_object (rnode);
162 : }
163 :
164 0 : members = json_object_get_members (jobj);
165 0 : for (l = members; l != NULL; l = l->next) {
166 0 : const gchar *key = l->data;
167 0 : const gchar *val = _ml_service_get_json_string_member (jobj, key);
168 :
169 : /* Prevent empty string case. */
170 0 : if (STR_IS_VALID (key) && STR_IS_VALID (val)) {
171 0 : ret = _ml_information_set (_info, key, g_strdup (val), g_free);
172 0 : 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 0 : done:
181 0 : if (ret == ML_ERROR_NONE) {
182 0 : *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 0 : return ret;
191 : }
192 :
193 : /**
194 : * @brief Internal function to check the path of model or resource.
195 : */
196 : static int
197 0 : _ml_service_check_path (const char *path)
198 : {
199 : int ret;
200 0 : g_autofree gchar *dir_name = NULL;
201 : GStatBuf statbuf;
202 :
203 0 : if (!path) {
204 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
205 : "The parameter, 'path' is NULL. It should be a valid string.");
206 : }
207 :
208 0 : if (g_file_test (path, G_FILE_TEST_IS_DIR))
209 0 : dir_name = g_strdup (path);
210 : else
211 0 : dir_name = g_path_get_dirname (path);
212 :
213 0 : ret = g_stat (dir_name, &statbuf);
214 0 : 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 0 : if (!g_path_is_absolute (path)
220 0 : || !g_file_test (path, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))
221 0 : || g_file_test (path, G_FILE_TEST_IS_SYMLINK)) {
222 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
223 : "Given path '%s' is not a regular.", path);
224 : }
225 :
226 0 : return ML_ERROR_NONE;
227 : }
228 :
229 : /**
230 : * @brief Set the pipeline description with a given name.
231 : */
232 : int
233 0 : ml_service_pipeline_set (const char *name, const char *pipeline_desc)
234 : {
235 0 : int ret = ML_ERROR_NONE;
236 :
237 0 : check_feature_state (ML_FEATURE_SERVICE);
238 :
239 0 : if (!name) {
240 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
241 : "The parameter, 'name' is NULL. It should be a valid string.");
242 : }
243 :
244 0 : if (!pipeline_desc) {
245 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
246 : "The parameter, 'pipeline_desc' is NULL. It should be a valid string.");
247 : }
248 :
249 0 : ret = ml_agent_pipeline_set_description (name, pipeline_desc);
250 0 : if (ret < 0) {
251 0 : _ml_error_report ("Failed to invoke the method set_pipeline.");
252 : }
253 :
254 0 : return ret;
255 : }
256 :
257 : /**
258 : * @brief Get the pipeline description with a given name.
259 : */
260 : int
261 0 : ml_service_pipeline_get (const char *name, char **pipeline_desc)
262 : {
263 0 : int ret = ML_ERROR_NONE;
264 :
265 0 : check_feature_state (ML_FEATURE_SERVICE);
266 :
267 0 : if (!name) {
268 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
269 : "The parameter, 'name' is NULL, It should be a valid string.");
270 : }
271 :
272 0 : if (pipeline_desc == NULL) {
273 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
274 : "The argument for 'pipeline_desc' should not be NULL.");
275 : }
276 :
277 0 : if (*pipeline_desc != NULL) {
278 0 : _ml_logw (WARN_MSG_DPTR_SET_OVER, "char *pipeline_desc = NULL");
279 0 : *pipeline_desc = NULL;
280 : }
281 :
282 0 : ret = ml_agent_pipeline_get_description (name, pipeline_desc);
283 0 : if (ret < 0) {
284 0 : _ml_error_report ("Failed to invoke the method get_pipeline.");
285 : }
286 :
287 0 : return ret;
288 : }
289 :
290 : /**
291 : * @brief Delete the pipeline description with a given name.
292 : */
293 : int
294 0 : ml_service_pipeline_delete (const char *name)
295 : {
296 0 : int ret = ML_ERROR_NONE;
297 :
298 0 : check_feature_state (ML_FEATURE_SERVICE);
299 :
300 0 : if (!name) {
301 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
302 : "The parameter, 'name' is NULL, It should be a valid string.");
303 : }
304 :
305 0 : ret = ml_agent_pipeline_delete (name);
306 0 : if (ret < 0) {
307 0 : _ml_error_report ("Failed to invoke the method delete_pipeline.");
308 : }
309 :
310 0 : return ret;
311 : }
312 :
313 : /**
314 : * @brief Launch the pipeline of given service.
315 : */
316 : int
317 0 : ml_service_pipeline_launch (const char *name, ml_service_h * handle)
318 : {
319 0 : int ret = ML_ERROR_NONE;
320 : ml_service_s *mls;
321 : _ml_service_server_s *server;
322 :
323 0 : check_feature_state (ML_FEATURE_SERVICE);
324 :
325 0 : if (handle == NULL) {
326 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
327 : "The argument for 'handle' should not be NULL.");
328 : }
329 :
330 0 : if (*handle != NULL) {
331 0 : _ml_logw (WARN_MSG_DPTR_SET_OVER, "ml_service_h *handle = NULL");
332 : }
333 0 : *handle = NULL;
334 :
335 0 : mls = _ml_service_create_internal (ML_SERVICE_TYPE_SERVER_PIPELINE);
336 0 : 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 0 : mls->priv = server = g_try_new0 (_ml_service_server_s, 1);
342 0 : 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 0 : ret = ml_agent_pipeline_launch (name, &(server->id));
349 0 : if (ret < 0) {
350 0 : _ml_service_destroy_internal (mls);
351 0 : _ml_error_report_return (ret,
352 : "Failed to invoke the method launch_pipeline.");
353 : }
354 :
355 0 : server->service_name = g_strdup (name);
356 0 : *handle = mls;
357 :
358 0 : return ML_ERROR_NONE;
359 : }
360 :
361 : /**
362 : * @brief Return state of given ml_service_h
363 : */
364 : int
365 0 : ml_service_pipeline_get_state (ml_service_h handle, ml_pipeline_state_e * state)
366 : {
367 0 : int ret = ML_ERROR_NONE;
368 0 : gint _state = ML_PIPELINE_STATE_UNKNOWN;
369 0 : ml_service_s *mls = (ml_service_s *) handle;
370 : _ml_service_server_s *server;
371 :
372 0 : check_feature_state (ML_FEATURE_SERVICE);
373 :
374 0 : if (NULL == state) {
375 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
376 : "The parameter 'state' should not be NULL.");
377 : }
378 0 : *state = ML_PIPELINE_STATE_UNKNOWN;
379 :
380 0 : if (!_ml_service_handle_is_valid (mls)) {
381 0 : _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 0 : server = (_ml_service_server_s *) mls->priv;
386 0 : ret = ml_agent_pipeline_get_state (server->id, &_state);
387 0 : if (ret < 0) {
388 0 : _ml_error_report ("Failed to invoke the method get_state.");
389 : }
390 :
391 0 : *state = (ml_pipeline_state_e) _state;
392 0 : return ret;
393 : }
394 :
395 : /**
396 : * @brief Internal function to release ml-service pipeline data.
397 : */
398 : int
399 0 : _ml_service_pipeline_release_internal (ml_service_s * mls)
400 : {
401 0 : _ml_service_server_s *server = (_ml_service_server_s *) mls->priv;
402 : int ret;
403 :
404 : /* Supposed internal function call to release handle. */
405 0 : if (!server)
406 0 : return ML_ERROR_NONE;
407 :
408 0 : if (server->id > 0) {
409 0 : ret = ml_agent_pipeline_destroy (server->id);
410 0 : if (ret < 0) {
411 0 : _ml_error_report_return (ret,
412 : "Failed to invoke the method destroy_pipeline.");
413 : }
414 : }
415 :
416 0 : g_clear_pointer (&server->service_name, g_free);
417 0 : g_clear_pointer (&mls->priv, g_free);
418 :
419 0 : return ML_ERROR_NONE;
420 : }
421 :
422 : /**
423 : * @brief Registers new information of a neural network model.
424 : */
425 : int
426 0 : ml_service_model_register (const char *name, const char *path,
427 : const bool activate, const char *description, unsigned int *version)
428 : {
429 0 : int ret = ML_ERROR_NONE;
430 0 : g_autofree gchar *app_info = NULL;
431 0 : g_autofree gchar *converted = NULL;
432 :
433 0 : check_feature_state (ML_FEATURE_SERVICE);
434 :
435 0 : if (!name) {
436 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
437 : "The parameter, 'name' is NULL. It should be a valid string.");
438 : }
439 :
440 0 : if (NULL == version) {
441 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
442 : "The parameter 'version' should not be NULL.");
443 : }
444 0 : *version = 0U;
445 :
446 0 : converted = _ml_convert_predefined_entity (path);
447 0 : ret = _ml_service_check_path (converted);
448 0 : if (ret != ML_ERROR_NONE)
449 0 : return ret;
450 :
451 0 : app_info = _get_app_info ();
452 :
453 0 : ret = ml_agent_model_register (name, converted, activate,
454 0 : description ? description : "", app_info ? app_info : "", version);
455 0 : if (ret < 0) {
456 0 : _ml_error_report ("Failed to invoke the method model_register.");
457 : }
458 :
459 0 : return ret;
460 : }
461 :
462 : /**
463 : * @brief Updates the description of neural network model with given @a name and @a version.
464 : */
465 : int
466 0 : ml_service_model_update_description (const char *name,
467 : const unsigned int version, const char *description)
468 : {
469 0 : int ret = ML_ERROR_NONE;
470 :
471 0 : check_feature_state (ML_FEATURE_SERVICE);
472 :
473 0 : if (!name) {
474 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
475 : "The parameter, 'name' is NULL. It should be a valid string.");
476 : }
477 :
478 0 : if (version == 0U) {
479 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
480 : "The parameter, 'version' is 0. It should be a valid unsigned int.");
481 : }
482 :
483 0 : if (!description) {
484 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
485 : "The parameter, 'description' is NULL. It should be a valid string.");
486 : }
487 :
488 0 : ret = ml_agent_model_update_description (name, version, description);
489 0 : if (ret < 0) {
490 0 : _ml_error_report ("Failed to invoke the method model_update_description.");
491 : }
492 :
493 0 : return ret;
494 : }
495 :
496 : /**
497 : * @brief Activates a neural network model with given @a name and @a version.
498 : */
499 : int
500 0 : ml_service_model_activate (const char *name, const unsigned int version)
501 : {
502 0 : int ret = ML_ERROR_NONE;
503 :
504 0 : check_feature_state (ML_FEATURE_SERVICE);
505 :
506 0 : if (!name) {
507 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
508 : "The parameter, 'name' is NULL. It should be a valid string.");
509 : }
510 :
511 0 : if (version == 0U) {
512 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
513 : "The parameter, 'version' is 0. It should be a valid unsigned int.");
514 : }
515 :
516 0 : ret = ml_agent_model_activate (name, version);
517 0 : if (ret < 0) {
518 0 : _ml_error_report ("Failed to invoke the method model_activate.");
519 : }
520 :
521 0 : return ret;
522 : }
523 :
524 : /**
525 : * @brief Gets the information of neural network model with given @a name and @a version.
526 : */
527 : int
528 0 : ml_service_model_get (const char *name, const unsigned int version,
529 : ml_information_h * info)
530 : {
531 0 : int ret = ML_ERROR_NONE;
532 0 : ml_information_h _info = NULL;
533 0 : g_autofree gchar *description = NULL;
534 :
535 0 : check_feature_state (ML_FEATURE_SERVICE);
536 :
537 0 : if (!name) {
538 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
539 : "The parameter, 'name' is NULL. It should be a valid string.");
540 : }
541 :
542 0 : if (info == NULL) {
543 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
544 : "The argument for 'info' should not be NULL.");
545 : }
546 :
547 0 : if (*info != NULL) {
548 0 : _ml_logw (WARN_MSG_DPTR_SET_OVER, "ml_information_h info = NULL");
549 : }
550 0 : *info = NULL;
551 :
552 0 : ret = ml_agent_model_get (name, version, &description);
553 0 : if (ML_ERROR_NONE != ret || !description) {
554 0 : _ml_error_report ("Failed to invoke the method model_get.");
555 0 : return ret;
556 : }
557 :
558 0 : ret = _build_ml_info_from_json_cstr (description, &_info);
559 0 : if (ML_ERROR_NONE != ret)
560 0 : _ml_error_report ("Failed to convert json string to ml-information.");
561 : else
562 0 : *info = _info;
563 :
564 0 : return ret;
565 : }
566 :
567 : /**
568 : * @brief Gets the information of activated neural network model with given @a name.
569 : */
570 : int
571 0 : ml_service_model_get_activated (const char *name, ml_information_h * info)
572 : {
573 0 : int ret = ML_ERROR_NONE;
574 :
575 0 : ml_information_h _info = NULL;
576 0 : g_autofree gchar *description = NULL;
577 :
578 0 : check_feature_state (ML_FEATURE_SERVICE);
579 :
580 0 : if (!name) {
581 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
582 : "The parameter, 'name' is NULL. It should be a valid string.");
583 : }
584 :
585 0 : if (info == NULL) {
586 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
587 : "The argument for 'info' should not be NULL.");
588 : }
589 :
590 0 : if (*info != NULL) {
591 0 : _ml_logw (WARN_MSG_DPTR_SET_OVER, "ml_information_h info = NULL");
592 : }
593 0 : *info = NULL;
594 :
595 0 : ret = ml_agent_model_get_activated (name, &description);
596 0 : if (ML_ERROR_NONE != ret || !description) {
597 0 : _ml_error_report ("Failed to invoke the method model_get_activated.");
598 0 : return ret;
599 : }
600 :
601 0 : ret = _build_ml_info_from_json_cstr (description, &_info);
602 0 : if (ML_ERROR_NONE != ret)
603 0 : _ml_error_report ("Failed to convert json string to ml_information_h.");
604 : else
605 0 : *info = _info;
606 :
607 0 : return ret;
608 : }
609 :
610 : /**
611 : * @brief Gets the list of neural network model with given @a name.
612 : */
613 : int
614 0 : ml_service_model_get_all (const char *name, ml_information_list_h * info_list)
615 : {
616 0 : g_autofree gchar *description = NULL;
617 0 : ml_information_list_h _info_list = NULL;
618 0 : int ret = ML_ERROR_NONE;
619 :
620 0 : check_feature_state (ML_FEATURE_SERVICE);
621 :
622 0 : if (!name) {
623 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
624 : "The parameter, 'name' is NULL. It should be a valid string.");
625 : }
626 :
627 0 : if (NULL == info_list) {
628 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
629 : "The parameter 'info_list' should not be NULL.");
630 : }
631 0 : *info_list = NULL;
632 :
633 0 : ret = ml_agent_model_get_all (name, &description);
634 0 : if (ML_ERROR_NONE != ret || !description) {
635 0 : _ml_error_report_return (ret, "Failed to invoke the method model_get_all.");
636 : }
637 :
638 0 : ret = _build_ml_info_from_json_cstr (description, &_info_list);
639 0 : if (ML_ERROR_NONE != ret)
640 0 : _ml_error_report ("Failed to convert json string to ml-information list.");
641 : else
642 0 : *info_list = _info_list;
643 :
644 0 : return ret;
645 : }
646 :
647 : /**
648 : * @brief Deletes a model information with given @a name and @a version from machine learning service.
649 : */
650 : int
651 0 : ml_service_model_delete (const char *name, const unsigned int version)
652 : {
653 0 : int ret = ML_ERROR_NONE;
654 :
655 0 : check_feature_state (ML_FEATURE_SERVICE);
656 :
657 0 : if (!name) {
658 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
659 : "The parameter, 'name' is NULL. It should be a valid string.");
660 : }
661 :
662 0 : ret = ml_agent_model_delete (name, version, FALSE);
663 0 : if (ret < 0) {
664 0 : _ml_error_report ("Failed to invoke the method model_delete.");
665 : }
666 :
667 0 : return ret;
668 : }
669 :
670 : /**
671 : * @brief Adds new information of machine learning resources.
672 : */
673 : int
674 0 : ml_service_resource_add (const char *name, const char *path,
675 : const char *description)
676 : {
677 0 : int ret = ML_ERROR_NONE;
678 0 : g_autofree gchar *app_info = NULL;
679 0 : g_autofree gchar *converted = NULL;
680 :
681 0 : check_feature_state (ML_FEATURE_SERVICE);
682 :
683 0 : if (!name) {
684 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
685 : "The parameter, 'name' is NULL. It should be a valid string.");
686 : }
687 :
688 0 : converted = _ml_convert_predefined_entity (path);
689 0 : ret = _ml_service_check_path (converted);
690 0 : if (ret != ML_ERROR_NONE)
691 0 : return ret;
692 :
693 0 : app_info = _get_app_info ();
694 :
695 0 : ret = ml_agent_resource_add (name, converted, description ? description : "",
696 0 : app_info ? app_info : "");
697 0 : if (ret < 0) {
698 0 : _ml_error_report ("Failed to invoke the method resource_add.");
699 : }
700 :
701 0 : return ret;
702 : }
703 :
704 : /**
705 : * @brief Deletes the information of the resources from machine learning service.
706 : */
707 : int
708 0 : ml_service_resource_delete (const char *name)
709 : {
710 0 : int ret = ML_ERROR_NONE;
711 :
712 0 : check_feature_state (ML_FEATURE_SERVICE);
713 :
714 0 : if (!name) {
715 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
716 : "The parameter, 'name' is NULL. It should be a valid string.");
717 : }
718 :
719 0 : ret = ml_agent_resource_delete (name);
720 0 : if (ret < 0) {
721 0 : _ml_error_report ("Failed to invoke the method resource_delete.");
722 : }
723 :
724 0 : return ret;
725 : }
726 :
727 : /**
728 : * @brief Gets the information of the resources from machine learning service.
729 : */
730 : int
731 0 : ml_service_resource_get (const char *name, ml_information_list_h * res)
732 : {
733 0 : int ret = ML_ERROR_NONE;
734 0 : ml_information_list_h _info_list = NULL;
735 0 : g_autofree gchar *res_info = NULL;
736 :
737 0 : check_feature_state (ML_FEATURE_SERVICE);
738 :
739 0 : if (!name) {
740 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
741 : "The parameter, 'name' is NULL. It should be a valid string.");
742 : }
743 :
744 0 : if (res == NULL) {
745 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
746 : "The argument for 'res' should not be NULL.");
747 : }
748 :
749 0 : if (*res != NULL) {
750 0 : _ml_logw (WARN_MSG_DPTR_SET_OVER, "ml_information_list_h res = NULL");
751 : }
752 0 : *res = NULL;
753 :
754 0 : ret = ml_agent_resource_get (name, &res_info);
755 0 : if (ML_ERROR_NONE != ret || !res_info) {
756 0 : _ml_error_report_return (ret, "Failed to invoke the method resource_get.");
757 : }
758 :
759 0 : ret = _build_ml_info_from_json_cstr (res_info, &_info_list);
760 0 : if (ML_ERROR_NONE != ret)
761 0 : _ml_error_report ("Failed to convert json string to ml-information list.");
762 : else
763 0 : *res = _info_list;
764 :
765 0 : return ret;
766 : }
|