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_free (server->service_name);
417 0 : g_free (server);
418 0 : mls->priv = NULL;
419 :
420 0 : return ML_ERROR_NONE;
421 : }
422 :
423 : /**
424 : * @brief Registers new information of a neural network model.
425 : */
426 : int
427 0 : ml_service_model_register (const char *name, const char *path,
428 : const bool activate, const char *description, unsigned int *version)
429 : {
430 0 : int ret = ML_ERROR_NONE;
431 0 : g_autofree gchar *app_info = 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 : ret = _ml_service_check_path (path);
447 0 : if (ret != ML_ERROR_NONE)
448 0 : return ret;
449 :
450 0 : app_info = _get_app_info ();
451 :
452 0 : ret = ml_agent_model_register (name, path, activate,
453 0 : description ? description : "", app_info ? app_info : "", version);
454 0 : if (ret < 0) {
455 0 : _ml_error_report ("Failed to invoke the method model_register.");
456 : }
457 :
458 0 : return ret;
459 : }
460 :
461 : /**
462 : * @brief Updates the description of neural network model with given @a name and @a version.
463 : */
464 : int
465 0 : ml_service_model_update_description (const char *name,
466 : const unsigned int version, const char *description)
467 : {
468 0 : int ret = ML_ERROR_NONE;
469 :
470 0 : check_feature_state (ML_FEATURE_SERVICE);
471 :
472 0 : if (!name) {
473 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
474 : "The parameter, 'name' is NULL. It should be a valid string.");
475 : }
476 :
477 0 : if (version == 0U) {
478 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
479 : "The parameter, 'version' is 0. It should be a valid unsigned int.");
480 : }
481 :
482 0 : if (!description) {
483 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
484 : "The parameter, 'description' is NULL. It should be a valid string.");
485 : }
486 :
487 0 : ret = ml_agent_model_update_description (name, version, description);
488 0 : if (ret < 0) {
489 0 : _ml_error_report ("Failed to invoke the method model_update_description.");
490 : }
491 :
492 0 : return ret;
493 : }
494 :
495 : /**
496 : * @brief Activates a neural network model with given @a name and @a version.
497 : */
498 : int
499 0 : ml_service_model_activate (const char *name, const unsigned int version)
500 : {
501 0 : int ret = ML_ERROR_NONE;
502 :
503 0 : check_feature_state (ML_FEATURE_SERVICE);
504 :
505 0 : if (!name) {
506 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
507 : "The parameter, 'name' is NULL. It should be a valid string.");
508 : }
509 :
510 0 : if (version == 0U) {
511 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
512 : "The parameter, 'version' is 0. It should be a valid unsigned int.");
513 : }
514 :
515 0 : ret = ml_agent_model_activate (name, version);
516 0 : if (ret < 0) {
517 0 : _ml_error_report ("Failed to invoke the method model_activate.");
518 : }
519 :
520 0 : return ret;
521 : }
522 :
523 : /**
524 : * @brief Gets the information of neural network model with given @a name and @a version.
525 : */
526 : int
527 0 : ml_service_model_get (const char *name, const unsigned int version,
528 : ml_information_h * info)
529 : {
530 0 : int ret = ML_ERROR_NONE;
531 0 : ml_information_h _info = NULL;
532 0 : g_autofree gchar *description = NULL;
533 :
534 0 : check_feature_state (ML_FEATURE_SERVICE);
535 :
536 0 : if (!name) {
537 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
538 : "The parameter, 'name' is NULL. It should be a valid string.");
539 : }
540 :
541 0 : if (info == NULL) {
542 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
543 : "The argument for 'info' should not be NULL.");
544 : }
545 :
546 0 : if (*info != NULL) {
547 0 : _ml_logw (WARN_MSG_DPTR_SET_OVER, "ml_information_h info = NULL");
548 : }
549 0 : *info = NULL;
550 :
551 0 : ret = ml_agent_model_get (name, version, &description);
552 0 : if (ML_ERROR_NONE != ret || !description) {
553 0 : _ml_error_report ("Failed to invoke the method model_get.");
554 0 : return ret;
555 : }
556 :
557 0 : ret = _build_ml_info_from_json_cstr (description, &_info);
558 0 : if (ML_ERROR_NONE != ret)
559 0 : _ml_error_report ("Failed to convert json string to ml-information.");
560 : else
561 0 : *info = _info;
562 :
563 0 : return ret;
564 : }
565 :
566 : /**
567 : * @brief Gets the information of activated neural network model with given @a name.
568 : */
569 : int
570 0 : ml_service_model_get_activated (const char *name, ml_information_h * info)
571 : {
572 0 : int ret = ML_ERROR_NONE;
573 :
574 0 : ml_information_h _info = NULL;
575 0 : g_autofree gchar *description = NULL;
576 :
577 0 : check_feature_state (ML_FEATURE_SERVICE);
578 :
579 0 : if (!name) {
580 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
581 : "The parameter, 'name' is NULL. It should be a valid string.");
582 : }
583 :
584 0 : if (info == NULL) {
585 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
586 : "The argument for 'info' should not be NULL.");
587 : }
588 :
589 0 : if (*info != NULL) {
590 0 : _ml_logw (WARN_MSG_DPTR_SET_OVER, "ml_information_h info = NULL");
591 : }
592 0 : *info = NULL;
593 :
594 0 : ret = ml_agent_model_get_activated (name, &description);
595 0 : if (ML_ERROR_NONE != ret || !description) {
596 0 : _ml_error_report ("Failed to invoke the method model_get_activated.");
597 0 : return ret;
598 : }
599 :
600 0 : ret = _build_ml_info_from_json_cstr (description, &_info);
601 0 : if (ML_ERROR_NONE != ret)
602 0 : _ml_error_report ("Failed to convert json string to ml_information_h.");
603 : else
604 0 : *info = _info;
605 :
606 0 : return ret;
607 : }
608 :
609 : /**
610 : * @brief Gets the list of neural network model with given @a name.
611 : */
612 : int
613 0 : ml_service_model_get_all (const char *name, ml_information_list_h * info_list)
614 : {
615 0 : g_autofree gchar *description = NULL;
616 0 : ml_information_list_h _info_list = NULL;
617 0 : int ret = ML_ERROR_NONE;
618 :
619 0 : check_feature_state (ML_FEATURE_SERVICE);
620 :
621 0 : if (!name) {
622 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
623 : "The parameter, 'name' is NULL. It should be a valid string.");
624 : }
625 :
626 0 : if (NULL == info_list) {
627 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
628 : "The parameter 'info_list' should not be NULL.");
629 : }
630 0 : *info_list = NULL;
631 :
632 0 : ret = ml_agent_model_get_all (name, &description);
633 0 : if (ML_ERROR_NONE != ret || !description) {
634 0 : _ml_error_report_return (ret, "Failed to invoke the method model_get_all.");
635 : }
636 :
637 0 : ret = _build_ml_info_from_json_cstr (description, &_info_list);
638 0 : if (ML_ERROR_NONE != ret)
639 0 : _ml_error_report ("Failed to convert json string to ml-information list.");
640 : else
641 0 : *info_list = _info_list;
642 :
643 0 : return ret;
644 : }
645 :
646 : /**
647 : * @brief Deletes a model information with given @a name and @a version from machine learning service.
648 : */
649 : int
650 0 : ml_service_model_delete (const char *name, const unsigned int version)
651 : {
652 0 : int ret = ML_ERROR_NONE;
653 :
654 0 : check_feature_state (ML_FEATURE_SERVICE);
655 :
656 0 : if (!name) {
657 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
658 : "The parameter, 'name' is NULL. It should be a valid string.");
659 : }
660 :
661 0 : ret = ml_agent_model_delete (name, version, FALSE);
662 0 : if (ret < 0) {
663 0 : _ml_error_report ("Failed to invoke the method model_delete.");
664 : }
665 :
666 0 : return ret;
667 : }
668 :
669 : /**
670 : * @brief Adds new information of machine learning resources.
671 : */
672 : int
673 0 : ml_service_resource_add (const char *name, const char *path,
674 : const char *description)
675 : {
676 0 : int ret = ML_ERROR_NONE;
677 0 : g_autofree gchar *app_info = NULL;
678 :
679 0 : check_feature_state (ML_FEATURE_SERVICE);
680 :
681 0 : if (!name) {
682 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
683 : "The parameter, 'name' is NULL. It should be a valid string.");
684 : }
685 :
686 0 : ret = _ml_service_check_path (path);
687 0 : if (ret != ML_ERROR_NONE)
688 0 : return ret;
689 :
690 0 : app_info = _get_app_info ();
691 :
692 0 : ret = ml_agent_resource_add (name, path, description ? description : "",
693 0 : app_info ? app_info : "");
694 0 : if (ret < 0) {
695 0 : _ml_error_report ("Failed to invoke the method resource_add.");
696 : }
697 :
698 0 : return ret;
699 : }
700 :
701 : /**
702 : * @brief Deletes the information of the resources from machine learning service.
703 : */
704 : int
705 0 : ml_service_resource_delete (const char *name)
706 : {
707 0 : int ret = ML_ERROR_NONE;
708 :
709 0 : check_feature_state (ML_FEATURE_SERVICE);
710 :
711 0 : if (!name) {
712 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
713 : "The parameter, 'name' is NULL. It should be a valid string.");
714 : }
715 :
716 0 : ret = ml_agent_resource_delete (name);
717 0 : if (ret < 0) {
718 0 : _ml_error_report ("Failed to invoke the method resource_delete.");
719 : }
720 :
721 0 : return ret;
722 : }
723 :
724 : /**
725 : * @brief Gets the information of the resources from machine learning service.
726 : */
727 : int
728 0 : ml_service_resource_get (const char *name, ml_information_list_h * res)
729 : {
730 0 : int ret = ML_ERROR_NONE;
731 0 : ml_information_list_h _info_list = NULL;
732 0 : g_autofree gchar *res_info = NULL;
733 :
734 0 : check_feature_state (ML_FEATURE_SERVICE);
735 :
736 0 : if (!name) {
737 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
738 : "The parameter, 'name' is NULL. It should be a valid string.");
739 : }
740 :
741 0 : if (res == NULL) {
742 0 : _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
743 : "The argument for 'res' should not be NULL.");
744 : }
745 :
746 0 : if (*res != NULL) {
747 0 : _ml_logw (WARN_MSG_DPTR_SET_OVER, "ml_information_list_h res = NULL");
748 : }
749 0 : *res = NULL;
750 :
751 0 : ret = ml_agent_resource_get (name, &res_info);
752 0 : if (ML_ERROR_NONE != ret || !res_info) {
753 0 : _ml_error_report_return (ret, "Failed to invoke the method resource_get.");
754 : }
755 :
756 0 : ret = _build_ml_info_from_json_cstr (res_info, &_info_list);
757 0 : if (ML_ERROR_NONE != ret)
758 0 : _ml_error_report ("Failed to convert json string to ml-information list.");
759 : else
760 0 : *res = _info_list;
761 :
762 0 : return ret;
763 : }
|