From a19f893a70c03dee9312e1208301d079409d84ac Mon Sep 17 00:00:00 2001 From: Alex Stancu Date: Fri, 10 Apr 2020 18:19:53 +0300 Subject: [PATCH] Add counters for generated notifications. Add status counters for generated notifications (VES and NETCONF). Issue-ID: SIM-21 Change-Id: I370532efd7bb9d06f3ed81a2f66cdef4e9750a51 Signed-off-by: Alex Stancu --- ntsimulator/deploy/nts-manager/container-tag.yaml | 2 +- .../deploy/o-ran-sc/o-ran-ru/container-tag.yaml | 2 +- ntsimulator/deploy/o-ran/ru-fh/container-tag.yaml | 2 +- ntsimulator/deploy/x-ran/container-tag.yaml | 2 +- ntsimulator/inc/utils/utils.h | 20 + .../src/ntsimulator-manager/ntsimulator-manager.c | 162 ++++- .../src/ntsimulator-manager/simulator-operations.c | 6 + .../src/o-ran-notifications/o-ran-notifications.c | 77 +++ ntsimulator/src/utils/utils.c | 745 ++++++++++++++++++++- .../nts-manager/network-topology-simulator.yang | 73 ++ ntsimulator/yang/sysrepo-configuration-load.sh | 10 - 11 files changed, 1069 insertions(+), 32 deletions(-) diff --git a/ntsimulator/deploy/nts-manager/container-tag.yaml b/ntsimulator/deploy/nts-manager/container-tag.yaml index 5df0816..16a8dcd 100644 --- a/ntsimulator/deploy/nts-manager/container-tag.yaml +++ b/ntsimulator/deploy/nts-manager/container-tag.yaml @@ -1,2 +1,2 @@ --- -tag: 0.1.1 +tag: 0.1.2 diff --git a/ntsimulator/deploy/o-ran-sc/o-ran-ru/container-tag.yaml b/ntsimulator/deploy/o-ran-sc/o-ran-ru/container-tag.yaml index 5df0816..16a8dcd 100644 --- a/ntsimulator/deploy/o-ran-sc/o-ran-ru/container-tag.yaml +++ b/ntsimulator/deploy/o-ran-sc/o-ran-ru/container-tag.yaml @@ -1,2 +1,2 @@ --- -tag: 0.1.1 +tag: 0.1.2 diff --git a/ntsimulator/deploy/o-ran/ru-fh/container-tag.yaml b/ntsimulator/deploy/o-ran/ru-fh/container-tag.yaml index 5df0816..16a8dcd 100644 --- a/ntsimulator/deploy/o-ran/ru-fh/container-tag.yaml +++ b/ntsimulator/deploy/o-ran/ru-fh/container-tag.yaml @@ -1,2 +1,2 @@ --- -tag: 0.1.1 +tag: 0.1.2 diff --git a/ntsimulator/deploy/x-ran/container-tag.yaml b/ntsimulator/deploy/x-ran/container-tag.yaml index 5df0816..16a8dcd 100644 --- a/ntsimulator/deploy/x-ran/container-tag.yaml +++ b/ntsimulator/deploy/x-ran/container-tag.yaml @@ -1,2 +1,2 @@ --- -tag: 0.1.1 +tag: 0.1.2 diff --git a/ntsimulator/inc/utils/utils.h b/ntsimulator/inc/utils/utils.h index c049c66..9ce7e1f 100644 --- a/ntsimulator/inc/utils/utils.h +++ b/ntsimulator/inc/utils/utils.h @@ -45,6 +45,15 @@ num++;\ } +typedef struct +{ + int normal; + int warning; + int minor; + int major; + int critical; +} counterAlarms; + void set_curl_common_info_ves(CURL *curl); long random_at_most(long max); @@ -75,4 +84,15 @@ int getVesAvailableFromConfigJson(void); void generateRandomMacAddress(char *mac_address); +int writeSkeletonStatusFile(void); +char* readStatusFileInString(void); + +int writeStatusNotificationCounters(counterAlarms ves_counter, counterAlarms netconf_counter); +void writeStatusFile(char *status); +int removeDeviceEntryFromStatusFile(char *deviceName); + +cJSON* getDeviceListFromStatusFile(void); +int compute_notifications_count(counterAlarms *ves_counter, counterAlarms *netconf_counter); +int getDeviceCounters(char *containerId, counterAlarms *ves_counter, counterAlarms *netconf_counter); + #endif /* EXAMPLES_NTSIMULATOR_UTILS_H_ */ diff --git a/ntsimulator/src/ntsimulator-manager/ntsimulator-manager.c b/ntsimulator/src/ntsimulator-manager/ntsimulator-manager.c index e5312b1..836fc6f 100644 --- a/ntsimulator/src/ntsimulator-manager/ntsimulator-manager.c +++ b/ntsimulator/src/ntsimulator-manager/ntsimulator-manager.c @@ -341,7 +341,14 @@ simulator_status_cb(const char *xpath, sr_val_t **values, size_t *values_cnt, { int rc; - printf("\n\n ========== Called simulator_status_cb for xpath: %s ==========\n\n", xpath); + // printf("\n\n ========== Called simulator_status_cb for xpath: %s ==========\n\n", xpath); + + counterAlarms ves_counter, netconf_counter; + rc = compute_notifications_count(&ves_counter, &netconf_counter); + if (rc != SR_ERR_OK) + { + printf("Could not compute the total number of notification count.\n"); + } if (sr_xpath_node_name_eq(xpath, "simulated-devices-list")) { sr_val_t *v; @@ -366,6 +373,13 @@ simulator_status_cb(const char *xpath, sr_val_t **values, size_t *values_cnt, while (current_device != NULL) { + counterAlarms vesCount, netconfCount; + rc = getDeviceCounters(current_device->device_id, &vesCount, &netconfCount); + if (rc != SR_ERR_OK) + { + printf("Could not get Notification Counters for device with uuid=\"%s\"", current_device->device_id); + } + CREATE_NEW_VALUE(rc, v, current_num_of_values); sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/%s", xpath, current_device->device_id, "device-ip"); @@ -394,6 +408,66 @@ simulator_status_cb(const char *xpath, sr_val_t **values, size_t *values_cnt, sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/%s", xpath, current_device->device_id, "operational-state"); sr_val_build_str_data(&v[current_num_of_values - 1], SR_ENUM_T, "%s", operational_state); + CREATE_NEW_VALUE(rc, v, current_num_of_values); + + sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/notification-count/ves-notifications/%s", xpath, current_device->device_id, "normal"); + v[current_num_of_values - 1].type = SR_UINT32_T; + v[current_num_of_values - 1].data.uint32_val = vesCount.normal; + + CREATE_NEW_VALUE(rc, v, current_num_of_values); + + sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/notification-count/ves-notifications/%s", xpath, current_device->device_id, "warning"); + v[current_num_of_values - 1].type = SR_UINT32_T; + v[current_num_of_values - 1].data.uint32_val = vesCount.warning; + + CREATE_NEW_VALUE(rc, v, current_num_of_values); + + sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/notification-count/ves-notifications/%s", xpath, current_device->device_id, "minor"); + v[current_num_of_values - 1].type = SR_UINT32_T; + v[current_num_of_values - 1].data.uint32_val = vesCount.minor; + + CREATE_NEW_VALUE(rc, v, current_num_of_values); + + sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/notification-count/ves-notifications/%s", xpath, current_device->device_id, "major"); + v[current_num_of_values - 1].type = SR_UINT32_T; + v[current_num_of_values - 1].data.uint32_val = vesCount.major; + + CREATE_NEW_VALUE(rc, v, current_num_of_values); + + sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/notification-count/ves-notifications/%s", xpath, current_device->device_id, "critical"); + v[current_num_of_values - 1].type = SR_UINT32_T; + v[current_num_of_values - 1].data.uint32_val = vesCount.critical; + + CREATE_NEW_VALUE(rc, v, current_num_of_values); + + sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/notification-count/netconf-notifications/%s", xpath, current_device->device_id, "normal"); + v[current_num_of_values - 1].type = SR_UINT32_T; + v[current_num_of_values - 1].data.uint32_val = netconfCount.normal; + + CREATE_NEW_VALUE(rc, v, current_num_of_values); + + sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/notification-count/netconf-notifications/%s", xpath, current_device->device_id, "warning"); + v[current_num_of_values - 1].type = SR_UINT32_T; + v[current_num_of_values - 1].data.uint32_val = netconfCount.warning; + + CREATE_NEW_VALUE(rc, v, current_num_of_values); + + sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/notification-count/netconf-notifications/%s", xpath, current_device->device_id, "minor"); + v[current_num_of_values - 1].type = SR_UINT32_T; + v[current_num_of_values - 1].data.uint32_val = netconfCount.minor; + + CREATE_NEW_VALUE(rc, v, current_num_of_values); + + sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/notification-count/netconf-notifications/%s", xpath, current_device->device_id, "major"); + v[current_num_of_values - 1].type = SR_UINT32_T; + v[current_num_of_values - 1].data.uint32_val = netconfCount.major; + + CREATE_NEW_VALUE(rc, v, current_num_of_values); + + sr_val_build_xpath(&v[current_num_of_values - 1], "%s[uuid='%s']/notification-count/netconf-notifications/%s", xpath, current_device->device_id, "critical"); + v[current_num_of_values - 1].type = SR_UINT32_T; + v[current_num_of_values - 1].data.uint32_val = netconfCount.critical; + current_device = current_device->next; } @@ -453,6 +527,86 @@ simulator_status_cb(const char *xpath, sr_val_t **values, size_t *values_cnt, *values = v; *values_cnt = current_num_of_values; } + else if (sr_xpath_node_name_eq(xpath, "total-ves-notifications")) + { + sr_val_t *v; + /* convenient functions such as this can be found in sysrepo/values.h */ + size_t current_num_of_values= 0; + + CREATE_NEW_VALUE(rc, v, current_num_of_values); + + sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "normal"); + v[current_num_of_values - 1].type = SR_UINT32_T; + v[current_num_of_values - 1].data.uint32_val = ves_counter.normal; + + CREATE_NEW_VALUE(rc, v, current_num_of_values); + + sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "warning"); + v[current_num_of_values - 1].type = SR_UINT32_T; + v[current_num_of_values - 1].data.uint32_val = ves_counter.warning; + + CREATE_NEW_VALUE(rc, v, current_num_of_values); + + sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "minor"); + v[current_num_of_values - 1].type = SR_UINT32_T; + v[current_num_of_values - 1].data.uint32_val = ves_counter.minor; + + CREATE_NEW_VALUE(rc, v, current_num_of_values); + + sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "major"); + v[current_num_of_values - 1].type = SR_UINT32_T; + v[current_num_of_values - 1].data.uint32_val = ves_counter.major; + + CREATE_NEW_VALUE(rc, v, current_num_of_values); + + sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "critical"); + v[current_num_of_values - 1].type = SR_UINT32_T; + v[current_num_of_values - 1].data.uint32_val = ves_counter.critical; + + //return the values that we have just created + *values = v; + *values_cnt = current_num_of_values; + } + else if (sr_xpath_node_name_eq(xpath, "total-netconf-notifications")) + { + sr_val_t *v; + /* convenient functions such as this can be found in sysrepo/values.h */ + size_t current_num_of_values= 0; + + CREATE_NEW_VALUE(rc, v, current_num_of_values); + + sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "normal"); + v[current_num_of_values - 1].type = SR_UINT32_T; + v[current_num_of_values - 1].data.uint32_val = netconf_counter.normal; + + CREATE_NEW_VALUE(rc, v, current_num_of_values); + + sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "warning"); + v[current_num_of_values - 1].type = SR_UINT32_T; + v[current_num_of_values - 1].data.uint32_val = netconf_counter.warning; + + CREATE_NEW_VALUE(rc, v, current_num_of_values); + + sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "minor"); + v[current_num_of_values - 1].type = SR_UINT32_T; + v[current_num_of_values - 1].data.uint32_val = netconf_counter.minor; + + CREATE_NEW_VALUE(rc, v, current_num_of_values); + + sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "major"); + v[current_num_of_values - 1].type = SR_UINT32_T; + v[current_num_of_values - 1].data.uint32_val = netconf_counter.major; + + CREATE_NEW_VALUE(rc, v, current_num_of_values); + + sr_val_build_xpath(&v[current_num_of_values - 1], "%s/%s", xpath, "critical"); + v[current_num_of_values - 1].type = SR_UINT32_T; + v[current_num_of_values - 1].data.uint32_val = netconf_counter.critical; + + //return the values that we have just created + *values = v; + *values_cnt = current_num_of_values; + } return SR_ERR_OK; } @@ -556,6 +710,12 @@ main(int argc, char **argv) printf("\n\n ========== STARTUP CONFIG network-topology-simulator APPLIED AS RUNNING ==========\n\n"); + rc = writeSkeletonStatusFile(); + if (rc != SR_ERR_OK) + { + fprintf(stderr, "Could not initialize status JSON file: %s\n", sr_strerror(rc)); + } + /* loop until ctrl-c is pressed / SIGINT is received */ signal(SIGINT, sigint_handler); signal(SIGTERM, sigint_handler); diff --git a/ntsimulator/src/ntsimulator-manager/simulator-operations.c b/ntsimulator/src/ntsimulator-manager/simulator-operations.c index 2ff4207..5f55f4e 100644 --- a/ntsimulator/src/ntsimulator-manager/simulator-operations.c +++ b/ntsimulator/src/ntsimulator-manager/simulator-operations.c @@ -908,6 +908,12 @@ int stop_device(device_stack_t *theStack) printf("Could not kill and remove docker container with uuid=\"%s\"\n", last_id); } + rc = removeDeviceEntryFromStatusFile(last_id); + if (rc != SR_ERR_OK) + { + printf("Could not remove entry from status file for uuid=\"%s\"\n", last_id); + } + pop_device(theStack); return SR_ERR_OK; diff --git a/ntsimulator/src/o-ran-notifications/o-ran-notifications.c b/ntsimulator/src/o-ran-notifications/o-ran-notifications.c index ad282d1..230fad2 100644 --- a/ntsimulator/src/o-ran-notifications/o-ran-notifications.c +++ b/ntsimulator/src/o-ran-notifications/o-ran-notifications.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "sysrepo.h" #include "sysrepo/values.h" @@ -35,6 +36,21 @@ volatile int exit_application = 0; +static counterAlarms netconf_alarm_counter = { + .normal = 0, + .warning = 0, + .minor = 0, + .major = 0, + .critical = 0 +}; +static counterAlarms ves_alarm_counter= { + .normal = 0, + .warning = 0, + .minor = 0, + .major = 0, + .critical = 0 +}; + struct faultAlarms { int faultId; @@ -259,6 +275,30 @@ static int send_dummy_notif(sr_session_ctx_t *sess) printf("Failed to send notification send_dummy_notif\n"); return SR_ERR_OPERATION_FAILED; } + if (oran_fault_alarms[ran].cleared[random_port]) + { + netconf_alarm_counter.normal++; + } + else + { + if (strcmp(oran_fault_alarms[ran].faultSeverity, "WARNING") == 0) + { + netconf_alarm_counter.warning++; + } + else if (strcmp(oran_fault_alarms[ran].faultSeverity, "MINOR") == 0) + { + netconf_alarm_counter.minor++; + } + else if (strcmp(oran_fault_alarms[ran].faultSeverity, "MAJOR") == 0) + { + netconf_alarm_counter.major++; + } + else if (strcmp(oran_fault_alarms[ran].faultSeverity, "CRITICAL") == 0) + { + netconf_alarm_counter.critical++; + } + } + printf("Successfully sent notification with timestamp=\"%s\"\n", dateAndTime); } if (isVesAvailable) @@ -271,7 +311,36 @@ static int send_dummy_notif(sr_session_ctx_t *sess) { printf("Could not send Fault VES message\n"); } + if (oran_fault_alarms[ran].cleared[random_port]) + { + ves_alarm_counter.normal++; + } + else + { + if (strcmp(oran_fault_alarms[ran].faultSeverity, "WARNING") == 0) + { + ves_alarm_counter.warning++; + } + else if (strcmp(oran_fault_alarms[ran].faultSeverity, "MINOR") == 0) + { + ves_alarm_counter.minor++; + } + else if (strcmp(oran_fault_alarms[ran].faultSeverity, "MAJOR") == 0) + { + ves_alarm_counter.major++; + } + else if (strcmp(oran_fault_alarms[ran].faultSeverity, "CRITICAL") == 0) + { + ves_alarm_counter.critical++; + } + } } + printf("Writing counters to file...\n"); + rc = writeStatusNotificationCounters(ves_alarm_counter, netconf_alarm_counter); + if (rc != SR_ERR_OK) + { + printf("Could not write status to file...\n"); + } sr_free_values(vnotif, current_num_of_values); @@ -333,6 +402,14 @@ main(int argc, char **argv) else { sleep(1); + // reset the counters when the notifciation delay period is switched back to 0 + netconf_alarm_counter.normal = netconf_alarm_counter.warning = \ + netconf_alarm_counter.minor = netconf_alarm_counter.major = \ + netconf_alarm_counter.critical = 0; + + ves_alarm_counter.normal = ves_alarm_counter.warning = \ + ves_alarm_counter.minor = ves_alarm_counter.major = \ + ves_alarm_counter.critical = 0; } } diff --git a/ntsimulator/src/utils/utils.c b/ntsimulator/src/utils/utils.c index 0300ff9..7d1d2a0 100644 --- a/ntsimulator/src/utils/utils.c +++ b/ntsimulator/src/utils/utils.c @@ -74,23 +74,31 @@ void generateRandomMacAddress(char *mac_address) return; } -long random_at_most(long max) { - unsigned long - // max <= RAND_MAX < ULONG_MAX, so this is okay. - num_bins = (unsigned long) max + 1, - num_rand = (unsigned long) RAND_MAX + 1, - bin_size = num_rand / num_bins, - defect = num_rand % num_bins; - - long x; - do { - x = random(); - } - // This is carefully written not to overflow - while (num_rand - defect <= (unsigned long)x); - - // Truncated division is intentional - return x/bin_size; +long random_at_most(long max) +{ + unsigned long + // max <= RAND_MAX < ULONG_MAX, so this is okay. + num_bins = (unsigned long) max + 1, + num_rand = (unsigned long) RAND_MAX + 1, + bin_size = num_rand / num_bins, + defect = num_rand % num_bins; + + unsigned int seed; + FILE* urandom = fopen("/dev/urandom", "r"); + fread(&seed, sizeof(int), 1, urandom); + fclose(urandom); + srandom(seed); + + long x; + do + { + x = random(); + } + // This is carefully written not to overflow + while (num_rand - defect <= (unsigned long)x); + + // Truncated division is intentional + return x/bin_size; } int getSecondsFromLastQuarterInterval(void) @@ -1170,3 +1178,706 @@ cJSON* vesCreateFaultFields(char *alarm_condition, char *alarm_object, char *sev return faultFields; } + +static cJSON* createSeverityCounters(counterAlarms count) +{ + cJSON *severityCounters = cJSON_CreateObject(); + if (severityCounters == NULL) + { + printf("Could not create JSON object: severityCounters\n"); + return NULL; + } + + if (cJSON_AddNumberToObject(severityCounters, "severity-normal", count.normal) == NULL) + { + printf("Could not create JSON object: severity-normal\n"); + return NULL; + } + + if (cJSON_AddNumberToObject(severityCounters, "severity-warning", count.warning) == NULL) + { + printf("Could not create JSON object: severity-warning\n"); + return NULL; + } + + if (cJSON_AddNumberToObject(severityCounters, "severity-minor", count.minor) == NULL) + { + printf("Could not create JSON object: severity-minor\n"); + return NULL; + } + + if (cJSON_AddNumberToObject(severityCounters, "severity-major", count.major) == NULL) + { + printf("Could not create JSON object: severity-major\n"); + return NULL; + } + + if (cJSON_AddNumberToObject(severityCounters, "severity-critical", count.critical) == NULL) + { + printf("Could not create JSON object: severity-critical\n"); + return NULL; + } + + return severityCounters; +} + +void writeStatusFile(char *status) +{ + char status_file[200]; + sprintf(status_file, "%s/status.json", getenv("SCRIPTS_DIR")); + FILE * f = fopen (status_file, "w"); + + if (f) + { + fputs(status, f); + fclose(f); + } + else + { + printf("Could not write status file!\n"); + } +} + +int writeSkeletonStatusFile() +{ + cJSON *statusObject = cJSON_CreateObject(); + if (statusObject == NULL) + { + printf("Could not create JSON object: statusObject\n"); + return SR_ERR_OPERATION_FAILED; + } + + // counterAlarms counter = { + // .normal = 0, + // .warning = 0, + // .minor = 0, + // .major = 0, + // .critical = 0 + // }; + + // cJSON *totalVesNotifications = createSeverityCounters(counter); + // if (totalVesNotifications == NULL) + // { + // printf("Could not create JSON object: totalVesNotifications\n"); + // cJSON_Delete(statusObject); + // return SR_ERR_OPERATION_FAILED; + // } + // cJSON_AddItemToObject(statusObject, "total-ves-notifications-sent", totalVesNotifications); + + // cJSON *totalNetconfNotifications = createSeverityCounters(counter); + // if (totalNetconfNotifications == NULL) + // { + // printf("Could not create JSON object: totalNetconfNotifications\n"); + // cJSON_Delete(statusObject); + // return SR_ERR_OPERATION_FAILED; + // } + // cJSON_AddItemToObject(statusObject, "total-netconf-notifications-sent", totalNetconfNotifications); + + cJSON *deviceList = cJSON_CreateArray(); + if (deviceList == NULL) + { + printf("Could not create JSON object: deviceList\n"); + cJSON_Delete(statusObject); + return SR_ERR_OPERATION_FAILED; + } + cJSON_AddItemToObject(statusObject, "device-list", deviceList); + + char *status_string = NULL; + + status_string = cJSON_PrintUnformatted(statusObject); + + writeStatusFile(status_string); + + return SR_ERR_OK; +} + +/* + * Dynamically allocated memory; + * Caller needs to free the memory after it uses the value. + * +*/ +char* readStatusFileInString(void) +{ + char * buffer = 0; + long length; + char config_file[200]; + sprintf(config_file, "%s/status.json", getenv("SCRIPTS_DIR")); + FILE * f = fopen (config_file, "rb"); + + if (f) + { + fseek (f, 0, SEEK_END); + length = ftell (f); + fseek (f, 0, SEEK_SET); + buffer = malloc (length + 1); + if (buffer) + { + fread (buffer, 1, length, f); + } + fclose (f); + buffer[length] = '\0'; + } + + if (buffer) + { + return buffer; + } + + return NULL; +} + +/* + * Dynamically allocated memory; + * Caller needs to free the memory after it uses the value. + * +*/ +cJSON* getDeviceListFromStatusFile(void) +{ + char *stringStatus = readStatusFileInString(); + + if (stringStatus == NULL) + { + printf("Could not read status file!\n"); + return NULL; + } + + cJSON *jsonStatus = cJSON_Parse(stringStatus); + if (jsonStatus == NULL) + { + free(stringStatus); + const char *error_ptr = cJSON_GetErrorPtr(); + if (error_ptr != NULL) + { + fprintf(stderr, "Could not parse JSON status! Error before: %s\n", error_ptr); + } + return NULL; + } + //we don't need the string anymore + free(stringStatus); + stringStatus = NULL; + + return jsonStatus; +} + +cJSON* createDeviceListEntry(counterAlarms ves_counter, counterAlarms netconf_counter) +{ + cJSON *deviceListEntry = cJSON_CreateObject(); + if (deviceListEntry == NULL) + { + printf("Could not create JSON object: deviceListEntry\n"); + return NULL; + } + + char hostname[100]; + sprintf(hostname, "%s", getenv("HOSTNAME")); + + if (cJSON_AddStringToObject(deviceListEntry, "device-name", hostname) == NULL) + { + printf("Could not create JSON object: device-name\n"); + cJSON_Delete(deviceListEntry); + return NULL; + } + + cJSON *vesNotificationsSent = createSeverityCounters(ves_counter); + if (vesNotificationsSent == NULL) + { + printf("Could not create JSON object: vesNotificationsSent\n"); + cJSON_Delete(deviceListEntry); + return NULL; + } + cJSON_AddItemToObject(deviceListEntry, "ves-notifications-sent", vesNotificationsSent); + + cJSON *netconfNotificationsSent = createSeverityCounters(netconf_counter); + if (netconfNotificationsSent == NULL) + { + printf("Could not create JSON object: netconfNotificationsSent\n"); + cJSON_Delete(deviceListEntry); + return NULL; + } + cJSON_AddItemToObject(deviceListEntry, "netconf-notifications-sent", netconfNotificationsSent); + + return deviceListEntry; +} + +static void modifySeverityCounters(cJSON **severityCounters, counterAlarms count) +{ + cJSON *severity= cJSON_GetObjectItemCaseSensitive(*severityCounters, "severity-normal"); + if (!cJSON_IsNumber(severity)) + { + printf("Status JSON is not as expected: severity-normal is not an number"); + return; + } + //we set the value of the severity-normal object + cJSON_SetNumberValue(severity, count.normal); + + severity= cJSON_GetObjectItemCaseSensitive(*severityCounters, "severity-warning"); + if (!cJSON_IsNumber(severity)) + { + printf("Status JSON is not as expected: severity-warning is not an number"); + return; + } + //we set the value of the severity-warning object + cJSON_SetNumberValue(severity, count.warning); + + severity= cJSON_GetObjectItemCaseSensitive(*severityCounters, "severity-minor"); + if (!cJSON_IsNumber(severity)) + { + printf("Status JSON is not as expected: severity-minor is not an number"); + return; + } + //we set the value of the severity-minor object + cJSON_SetNumberValue(severity, count.minor); + + severity= cJSON_GetObjectItemCaseSensitive(*severityCounters, "severity-major"); + if (!cJSON_IsNumber(severity)) + { + printf("Status JSON is not as expected: severity-major is not an number"); + return; + } + //we set the value of the severity-major object + cJSON_SetNumberValue(severity, count.major); + + severity= cJSON_GetObjectItemCaseSensitive(*severityCounters, "severity-critical"); + if (!cJSON_IsNumber(severity)) + { + printf("Status JSON is not as expected: severity-critical is not an number"); + return; + } + //we set the value of the severity-critical object + cJSON_SetNumberValue(severity, count.critical); + + return; +} + +static void modifyDeviceListEntry(cJSON **deviceListEntry, counterAlarms ves_counter, counterAlarms netconf_counter) +{ + cJSON *vesNotificationsSent= cJSON_GetObjectItemCaseSensitive(*deviceListEntry, "ves-notifications-sent"); + if (!cJSON_IsObject(vesNotificationsSent)) + { + printf("Status JSON is not as expected: ves-notifications-sent is not a object"); + return; + } + + modifySeverityCounters(&vesNotificationsSent, ves_counter); + + cJSON *netconfNotificationsSent= cJSON_GetObjectItemCaseSensitive(*deviceListEntry, "netconf-notifications-sent"); + if (!cJSON_IsObject(netconfNotificationsSent)) + { + printf("Status JSON is not as expected: netconf-notifications-sent is not a object"); + return; + } + + modifySeverityCounters(&netconfNotificationsSent, netconf_counter); +} + +int writeStatusNotificationCounters(counterAlarms ves_counter, counterAlarms netconf_counter) +{ + cJSON *jsonStatus = getDeviceListFromStatusFile(); + + cJSON *deviceList = cJSON_GetObjectItemCaseSensitive(jsonStatus, "device-list"); + if (!cJSON_IsArray(deviceList)) + { + printf("Status JSON is not as expected: device-list is not an object"); + cJSON_Delete(jsonStatus); + return SR_ERR_OPERATION_FAILED; + } + + int array_size = cJSON_GetArraySize(deviceList); + + int found = 0; + for (int i=0; inormal = ves_counter->warning = \ + ves_counter->minor = ves_counter->major = \ + ves_counter->critical = 0; + netconf_counter->normal = netconf_counter->warning = \ + netconf_counter->minor = netconf_counter->major = \ + netconf_counter->critical = 0; + + cJSON *jsonStatus = getDeviceListFromStatusFile(); + + cJSON *deviceList = cJSON_GetObjectItemCaseSensitive(jsonStatus, "device-list"); + if (!cJSON_IsArray(deviceList)) + { + printf("Status JSON is not as expected: device-list is not an object"); + cJSON_Delete(jsonStatus); + return SR_ERR_OPERATION_FAILED; + } + + int array_size = cJSON_GetArraySize(deviceList); + + for (int i=0; ivaluedouble); + ves_counter->normal += counter; + + severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-warning"); + if (!cJSON_IsNumber(severity)) + { + printf("Status JSON is not as expected: severity-warning is not a string."); + cJSON_Delete(jsonStatus); + return SR_ERR_OPERATION_FAILED; + } + counter = (int)(severity->valuedouble); + ves_counter->warning += counter; + + severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-minor"); + if (!cJSON_IsNumber(severity)) + { + printf("Status JSON is not as expected: severity-minor is not a string."); + cJSON_Delete(jsonStatus); + return SR_ERR_OPERATION_FAILED; + } + counter = (int)(severity->valuedouble); + ves_counter->minor += counter; + + severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-major"); + if (!cJSON_IsNumber(severity)) + { + printf("Status JSON is not as expected: severity-major is not a string."); + cJSON_Delete(jsonStatus); + return SR_ERR_OPERATION_FAILED; + } + counter = (int)(severity->valuedouble); + ves_counter->major += counter; + + severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-critical"); + if (!cJSON_IsNumber(severity)) + { + printf("Status JSON is not as expected: severity-critical is not a string."); + cJSON_Delete(jsonStatus); + return SR_ERR_OPERATION_FAILED; + } + counter = (int)(severity->valuedouble); + ves_counter->critical += counter; + + cJSON *netconfNotifications = cJSON_GetObjectItemCaseSensitive(deviceListEntry, "netconf-notifications-sent"); + if (!cJSON_IsObject(netconfNotifications)) + { + printf("Status JSON is not as expected: netconf-notifications-sent is not an object."); + cJSON_Delete(jsonStatus); + return SR_ERR_OPERATION_FAILED; + } + + severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-normal"); + if (!cJSON_IsNumber(severity)) + { + printf("Status JSON is not as expected: severity-normal is not a string."); + cJSON_Delete(jsonStatus); + return SR_ERR_OPERATION_FAILED; + } + + counter = (int)(severity->valuedouble); + netconf_counter->normal += (counter * NETCONF_CONNECTIONS_PER_DEVICE); + + severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-warning"); + if (!cJSON_IsNumber(severity)) + { + printf("Status JSON is not as expected: severity-warning is not a string."); + cJSON_Delete(jsonStatus); + return SR_ERR_OPERATION_FAILED; + } + counter = (int)(severity->valuedouble); + netconf_counter->warning += (counter * NETCONF_CONNECTIONS_PER_DEVICE); + + severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-minor"); + if (!cJSON_IsNumber(severity)) + { + printf("Status JSON is not as expected: severity-minor is not a string."); + cJSON_Delete(jsonStatus); + return SR_ERR_OPERATION_FAILED; + } + counter = (int)(severity->valuedouble); + netconf_counter->minor += (counter * NETCONF_CONNECTIONS_PER_DEVICE); + + severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-major"); + if (!cJSON_IsNumber(severity)) + { + printf("Status JSON is not as expected: severity-major is not a string."); + cJSON_Delete(jsonStatus); + return SR_ERR_OPERATION_FAILED; + } + counter = (int)(severity->valuedouble); + netconf_counter->major += (counter * NETCONF_CONNECTIONS_PER_DEVICE); + + severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-critical"); + if (!cJSON_IsNumber(severity)) + { + printf("Status JSON is not as expected: severity-critical is not a string."); + cJSON_Delete(jsonStatus); + return SR_ERR_OPERATION_FAILED; + } + counter = (int)(severity->valuedouble); + netconf_counter->critical += (counter * NETCONF_CONNECTIONS_PER_DEVICE); + } + + cJSON_Delete(jsonStatus); + + return SR_ERR_OK; +} + +int getDeviceCounters(char *containerId, counterAlarms *ves_counter, counterAlarms *netconf_counter) +{ + cJSON *jsonStatus = getDeviceListFromStatusFile(); + + cJSON *deviceList = cJSON_GetObjectItemCaseSensitive(jsonStatus, "device-list"); + if (!cJSON_IsArray(deviceList)) + { + printf("Status JSON is not as expected: device-list is not an object"); + cJSON_Delete(jsonStatus); + return SR_ERR_OPERATION_FAILED; + } + + int array_size = cJSON_GetArraySize(deviceList); + + for (int i=0; ivaluedouble); + ves_counter->normal = counter; + + severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-warning"); + if (!cJSON_IsNumber(severity)) + { + printf("Status JSON is not as expected: severity-warning is not a string."); + cJSON_Delete(jsonStatus); + return SR_ERR_OPERATION_FAILED; + } + counter = (int)(severity->valuedouble); + ves_counter->warning = counter; + + severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-minor"); + if (!cJSON_IsNumber(severity)) + { + printf("Status JSON is not as expected: severity-minor is not a string."); + cJSON_Delete(jsonStatus); + return SR_ERR_OPERATION_FAILED; + } + counter = (int)(severity->valuedouble); + ves_counter->minor = counter; + + severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-major"); + if (!cJSON_IsNumber(severity)) + { + printf("Status JSON is not as expected: severity-major is not a string."); + cJSON_Delete(jsonStatus); + return SR_ERR_OPERATION_FAILED; + } + counter = (int)(severity->valuedouble); + ves_counter->major = counter; + + severity = cJSON_GetObjectItemCaseSensitive(vesNotifications, "severity-critical"); + if (!cJSON_IsNumber(severity)) + { + printf("Status JSON is not as expected: severity-critical is not a string."); + cJSON_Delete(jsonStatus); + return SR_ERR_OPERATION_FAILED; + } + counter = (int)(severity->valuedouble); + ves_counter->critical = counter; + + cJSON *netconfNotifications = cJSON_GetObjectItemCaseSensitive(deviceListEntry, "netconf-notifications-sent"); + if (!cJSON_IsObject(netconfNotifications)) + { + printf("Status JSON is not as expected: netconf-notifications-sent is not an object."); + cJSON_Delete(jsonStatus); + return SR_ERR_OPERATION_FAILED; + } + + severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-normal"); + if (!cJSON_IsNumber(severity)) + { + printf("Status JSON is not as expected: severity-normal is not a string."); + cJSON_Delete(jsonStatus); + return SR_ERR_OPERATION_FAILED; + } + + counter = (int)(severity->valuedouble); + netconf_counter->normal = (counter * NETCONF_CONNECTIONS_PER_DEVICE); + + severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-warning"); + if (!cJSON_IsNumber(severity)) + { + printf("Status JSON is not as expected: severity-warning is not a string."); + cJSON_Delete(jsonStatus); + return SR_ERR_OPERATION_FAILED; + } + counter = (int)(severity->valuedouble); + netconf_counter->warning = (counter * NETCONF_CONNECTIONS_PER_DEVICE); + + severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-minor"); + if (!cJSON_IsNumber(severity)) + { + printf("Status JSON is not as expected: severity-minor is not a string."); + cJSON_Delete(jsonStatus); + return SR_ERR_OPERATION_FAILED; + } + counter = (int)(severity->valuedouble); + netconf_counter->minor = (counter * NETCONF_CONNECTIONS_PER_DEVICE); + + severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-major"); + if (!cJSON_IsNumber(severity)) + { + printf("Status JSON is not as expected: severity-major is not a string."); + cJSON_Delete(jsonStatus); + return SR_ERR_OPERATION_FAILED; + } + counter = (int)(severity->valuedouble); + netconf_counter->major = (counter * NETCONF_CONNECTIONS_PER_DEVICE); + + severity = cJSON_GetObjectItemCaseSensitive(netconfNotifications, "severity-critical"); + if (!cJSON_IsNumber(severity)) + { + printf("Status JSON is not as expected: severity-critical is not a string."); + cJSON_Delete(jsonStatus); + return SR_ERR_OPERATION_FAILED; + } + counter = (int)(severity->valuedouble); + netconf_counter->critical = (counter * NETCONF_CONNECTIONS_PER_DEVICE); + } + + cJSON_Delete(jsonStatus); + + return SR_ERR_OK; +} \ No newline at end of file diff --git a/ntsimulator/yang/nts-manager/network-topology-simulator.yang b/ntsimulator/yang/nts-manager/network-topology-simulator.yang index ac2cf8d..32570eb 100644 --- a/ntsimulator/yang/nts-manager/network-topology-simulator.yang +++ b/ntsimulator/yang/nts-manager/network-topology-simulator.yang @@ -16,6 +16,13 @@ module network-topology-simulator { description "This module contains a collection of YANG definitions for managing the Network Topology Simulator."; + + revision 2020-04-10 { + description + "Add notification count in status."; + reference + "O-RAN SC SIM project"; + } revision 2019-10-25 { description "Modify notifications. Add VES message configuration options."; @@ -145,6 +152,36 @@ module network-topology-simulator { "none"; } + grouping notification-count-per-severity-g { + leaf normal { + type uint32; + description + "The number of normal notifications."; + } + leaf warning { + type uint32; + description + "The number of warning notifications."; + } + leaf minor { + type uint32; + description + "The number of minor notifications."; + } + leaf major { + type uint32; + description + "The number of major notifications."; + } + leaf critical { + type uint32; + description + "The number of normal notifications."; + } + description + "none"; + } + container simulator-config { description "Configuration container of the simulator."; @@ -274,10 +311,46 @@ module network-topology-simulator { description "The details about the simulation, including resources consumed."; } + container notification-count { + config false; + container total-ves-notifications { + config false; + uses notification-count-per-severity-g; + description + "The total number of VES notifications that were sent by all the simulated devices managed by this NTS Manager instance."; + } + container total-netconf-notifications { + config false; + uses notification-count-per-severity-g; + description + "The total number of NETCONF notifications that were sent by all the simulated devices managed by this NTS Manager instance."; + } + description + "The total number of notifications sent by the devices managed by this NTS Manager instance."; + + } list simulated-devices-list { key "uuid"; config false; uses simulated-devices-type-g; + container notification-count { + config false; + container ves-notifications { + config false; + uses notification-count-per-severity-g; + description + "The total number of VES notifications that were sent by this simulated device."; + } + container netconf-notifications { + config false; + uses notification-count-per-severity-g; + description + "The total number of NETCONF notifications that were sent by this simulated device."; + } + description + "The total number of notifications sent by this simulated device."; + + } description "The list of the devices that are currently simulated."; } diff --git a/ntsimulator/yang/sysrepo-configuration-load.sh b/ntsimulator/yang/sysrepo-configuration-load.sh index 8c41b40..71ba5d4 100755 --- a/ntsimulator/yang/sysrepo-configuration-load.sh +++ b/ntsimulator/yang/sysrepo-configuration-load.sh @@ -20,16 +20,6 @@ sleep 20 echo "Loading data into sysrepo..." -#SSH_PUB_KEY="$(cat /home/netconf/.ssh/id_dsa.pub| awk '{print $2}')" - -#echo 'netconfssh_keyssh-dss' >> load_auth_pubkey.xml -#echo ''"$SSH_PUB_KEY"'' >> load_auth_pubkey.xml - -#sysrepocfg --merge=load_auth_pubkey.xml --format=xml ietf-system -#rm load_auth_pubkey.xml -# -#ssh-keyscan -p 830 localhost >> ~/.ssh/known_hosts - pyang -f sample-xml-skeleton --sample-xml-list-entries 2 *.yang result=$(netopeer2-cli <<-END -- 2.16.6