Add VES stndDefined PM and subscription for O-DU.
[sim/o1-interface.git] / ntsimulator / ntsim-ng / core / datastore / populate_validation.c
1 /*************************************************************************
2 *
3 * Copyright 2021 highstreet technologies GmbH and others
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 ***************************************************************************/
17 #define _GNU_SOURCE
18
19 #include "populate_internal.h"
20 #include "utils/log_utils.h"
21 #include "utils/rand_utils.h"
22 #include "utils/type_utils.h"
23
24 #include "core/datastore/schema.h"
25 #include "core/framework.h"
26 #include "core/session.h"
27
28 #include <sysrepo.h>
29 #include <libyang/libyang.h>
30
31 #include <stdlib.h>
32 #include <assert.h>
33
34
35 int populate_validate(populate_instance_t *instance, int count) {
36     assert(instance);
37
38     int rc = 0;
39     int commit_ok = NTS_ERR_OK;
40
41     for(int i = 0; i < count; i++) {
42         if(instance[i].operational) {
43             log_add_verbose(2, "available modules:");
44             for(int j = 0; j < instance[i].mod_count; j++) {
45                 log_add(2, " %s", instance[i].modules[j]->name);
46             }
47             log_add(2, "\n");
48             log_add_verbose(1, "validating OPERATIONAL for [%d] : %s... ", i, instance[i].xpath);
49
50             int solved_instance_errors = 1;
51             int solved_errors = 0;
52             bool success = false;
53             while(instance[i].operational && solved_instance_errors) {
54                 solved_instance_errors = 0;
55                 rc = lyd_validate_modules(&instance[i].operational, instance[i].modules, instance[i].mod_count, LYD_OPT_DATA, 0);
56                 if(rc == 0) {
57                     log_add(1, LOG_COLOR_BOLD_GREEN"success (%d)\n"LOG_COLOR_RESET, solved_errors);
58                     success = true;
59                     break;
60                 }
61                 else {
62                     log_add(2, "\n");
63
64                     struct ly_err_item *err = ly_err_first(session_context);
65                     while(err) {
66                         if((err->vecode == LYVE_NOWHEN) || (err->vecode == LYVE_NOMUST) || (err->vecode == LYVE_NOCONSTR) || (err->vecode == LYVE_NOLEAFREF) || (err->vecode == LYVE_NOMIN) || (err->vecode == LYVE_INVAL)) {
67                             struct ly_set *set = lyd_find_path(instance[i].operational, err->path);
68                             if(set && set->number) {
69                                 log_add_verbose(2, "operational error code %d on path %s with msg %s\n", err->vecode, err->path, err->msg);
70                                 log_add_verbose(2, LOG_COLOR_BOLD_RED"  [WHEN-DELETE O]"LOG_COLOR_RESET" %s ... ", err->path);
71
72                                 bool mandatory = false;
73                                 if((set->set.d[0]->schema->flags & LYS_MAND_TRUE) != 0) {
74                                     mandatory = true;
75                                 }
76
77                                 if((set->set.d[0]->schema->parent) && (set->set.d[0]->schema->parent->nodetype == LYS_CASE)) {
78                                     if((set->set.d[0]->schema->parent->flags & LYS_MAND_TRUE) != 0) {
79                                         mandatory = true;
80                                     }
81                                 }
82
83                                 if((set->set.d[0]->dflt != 0) || (lys_is_key((const struct lys_node_leaf *)set->set.d[0]->schema, 0)) || (mandatory) || (err->vecode == LYVE_NOMIN)) {
84                                     //delete whole parent
85                                     log_add(2, "deleted parent : %s\n", lyd_path(set->set.d[0]->parent));
86                                     struct lyd_node *p = set->set.d[0]->parent;
87                                     lyd_free_withsiblings(set->set.d[0]);
88                                     lyd_free(p);
89                                     if(p == instance[i].operational) {
90                                         log_add_verbose(1, "instance became empty "LOG_COLOR_BOLD_GREEN"success\n"LOG_COLOR_RESET);
91                                         success = true;
92                                         instance[i].operational = 0;
93                                         break;
94                                     }
95                                 }
96                                 else {
97                                     //delete THIS node only
98                                     lyd_free(set->set.d[0]);
99                                     log_add(2, "deleted\n");
100                                     if(set->set.d[0] == instance[i].operational) {
101                                         log_add_verbose(1, "instance became empty "LOG_COLOR_BOLD_GREEN"success\n"LOG_COLOR_RESET);
102                                         success = true;
103                                         instance[i].operational = 0;
104                                         break;
105                                     }
106                                 }
107                                 solved_instance_errors++;
108
109                                 ly_set_free(set);
110                             }
111                         }
112                         else if((err->vecode != 0) && (err->vecode != 29)) {
113                             log_add_verbose(2, "operational error code %d on path %s with msg %s\n", err->vecode, err->path, err->msg);
114                         }
115
116                         err = err->next;
117                     }
118                     ly_err_clean(session_context, 0);
119                 }
120
121                 solved_errors += solved_instance_errors;
122             }
123
124             if(!success) {
125                 if(!solved_errors) {
126                     log_add(1, LOG_COLOR_BOLD_YELLOW"failed"LOG_COLOR_RESET"\n%s\n", ly_errmsg(session_context));
127                 }
128                 else {
129                     log_add(1, LOG_COLOR_BOLD_YELLOW"partially solved (%d)"LOG_COLOR_RESET"\n", solved_errors);
130                 }
131             }
132         }
133
134         if(instance[i].running) {
135             log_add_verbose(1, "validating RUNNING... for [%d] : %s... ", i, instance[i].xpath);
136
137             int solved_instance_errors = 1;
138             int solved_errors = 0;
139             bool success = false;
140             while(instance[i].running && solved_instance_errors) {
141                 solved_instance_errors = 0;
142                 rc = lyd_validate_modules(&instance[i].running, instance[i].modules, instance[i].mod_count, LYD_OPT_CONFIG, 0);
143                 if(rc == 0) {
144                     log_add(1, LOG_COLOR_BOLD_GREEN"success (%d)\n"LOG_COLOR_RESET, solved_errors);
145                     success = true;
146                     break;
147                 }
148                 else {
149                     log_add(2, "\n");
150
151                     struct ly_err_item *err = ly_err_first(session_context);
152                     while(err) {
153                         if((err->vecode == LYVE_NOWHEN) || (err->vecode == LYVE_NOMUST) || (err->vecode == LYVE_NOCONSTR) || (err->vecode == LYVE_NOLEAFREF) || (err->vecode == LYVE_NOMIN) || (err->vecode == LYVE_INVAL)) {
154                             struct ly_set *set = lyd_find_path(instance[i].running, err->path);
155                             if(set && set->number) {
156                                 log_add_verbose(2, "running error code %d on path %s with msg %s\n", err->vecode, err->path, err->msg);
157                                 log_add_verbose(2, LOG_COLOR_BOLD_RED"  [WHEN-DELETE R]"LOG_COLOR_RESET" %s ... ", err->path);
158
159                                 bool mandatory = false;
160                                 if((set->set.d[0]->schema->flags & LYS_MAND_TRUE) != 0) {
161                                     mandatory = true;
162                                 }
163
164                                 if((set->set.d[0]->schema->parent) && (set->set.d[0]->schema->parent->nodetype == LYS_CASE)) {
165                                     if((set->set.d[0]->schema->parent->flags & LYS_MAND_TRUE) != 0) {
166                                         mandatory = true;
167                                     }
168                                 }
169
170                                 if((set->set.d[0]->dflt != 0) || (lys_is_key((const struct lys_node_leaf *)set->set.d[0]->schema, 0)) || (mandatory) || (err->vecode == LYVE_NOMIN))  {
171                                     //delete whole parent
172                                     log_add(2, "deleted parent : %s\n", lyd_path(set->set.d[0]->parent));
173                                     struct lyd_node *p = set->set.d[0]->parent;
174                                     lyd_free_withsiblings(set->set.d[0]);
175                                     lyd_free(p);
176
177                                     if(p == instance[i].running) {
178                                         log_add_verbose(1, "instance became empty "LOG_COLOR_BOLD_GREEN"success\n"LOG_COLOR_RESET);
179                                         success = true;
180                                         instance[i].running = 0;
181                                         break;
182                                     }
183                                 }
184                                 else {
185                                     //delete THIS node only
186                                     lyd_free(set->set.d[0]);
187                                     log_add(2, "deleted\n");
188                                     if(set->set.d[0] == instance[i].running) {
189                                         log_add_verbose(1, "instance became empty "LOG_COLOR_BOLD_GREEN"success\n"LOG_COLOR_RESET);
190                                         success = true;
191                                         instance[i].running = 0;
192                                         break;
193                                     }
194                                 }
195                                 solved_instance_errors++;
196
197                                 ly_set_free(set);
198                             }
199                         }
200                         else if((err->vecode != 0) && (err->vecode != 29)) {
201                             log_add_verbose(2, "running error code %d on path %s with msg %s\n", err->vecode, err->path, err->msg);
202                         }
203
204                         err = err->next;
205                     }
206                     ly_err_clean(session_context, 0);
207                 }
208
209                 solved_errors += solved_instance_errors;
210             }
211
212             if(!success) {
213                 if(!solved_errors) {
214                     log_add(1, LOG_COLOR_BOLD_YELLOW"failed"LOG_COLOR_RESET"\n%s\n", ly_errmsg(session_context));
215                 }
216                 else {
217                     log_add(1, LOG_COLOR_BOLD_YELLOW"partially solved (%d)"LOG_COLOR_RESET"\n", solved_errors);
218                 }
219             }
220         }
221     }
222
223     return commit_ok;
224 }