diff options
author | Gao Weitao <victor.gao@huawei.com> | 2019-02-27 01:28:41 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@onap.org> | 2019-02-27 01:28:41 +0000 |
commit | 35299e097671269087f1c737cf9b08a88baf447e (patch) | |
tree | 32786eb83aee8193e75cb4d23ff25683f4554b03 /veslibrary/ves_clibrary | |
parent | 28b6e97d3929f94f91c4bf57f1d0273d8c8a73e0 (diff) | |
parent | 2273dead6fd4da2b3b88b22c64172ec4d889e633 (diff) |
Merge "VES5.4.1 EVEL Library enhancements" into beijing
Diffstat (limited to 'veslibrary/ves_clibrary')
89 files changed, 9104 insertions, 398 deletions
diff --git a/veslibrary/ves_clibrary/VESreporting_vFW/Makefile b/veslibrary/ves_clibrary/VESreporting_vFW/Makefile index e7ac57b..c9776e0 100644 --- a/veslibrary/ves_clibrary/VESreporting_vFW/Makefile +++ b/veslibrary/ves_clibrary/VESreporting_vFW/Makefile @@ -16,9 +16,9 @@ ############################################################################# CC=gcc + ARCH=$(shell getconf LONG_BIT) -#CODE_ROOT=$(CURDIR)/../../.. -CODE_ROOT=../VES5.0/evel/evel-library +CODE_ROOT=$(CURDIR)/../.. LIBS_DIR=$(CODE_ROOT)/libs/x86_$(ARCH) INCLUDE_DIR=$(CODE_ROOT)/code/evel_library diff --git a/veslibrary/ves_clibrary/VESreporting_vFW/README.md b/veslibrary/ves_clibrary/VESreporting_vFW/README.md index 598b207..e9bbc2d 100644 --- a/veslibrary/ves_clibrary/VESreporting_vFW/README.md +++ b/veslibrary/ves_clibrary/VESreporting_vFW/README.md @@ -1,6 +1,5 @@ PROJECT DESCRIPTION - --- This project contains the source code and scripts for the periodic generation of network measurement reports. The folder contains: @@ -22,5 +21,6 @@ To run the vpp_measurement_reporter, please execute the following steps: - Make the go-client.sh script executable chmod +x go-client.sh - - Run the go-client.sh script + - Run one of the scripts based on one collector or 2 collector ./go-client.sh + ./go-client_2_collector.sh diff --git a/veslibrary/ves_clibrary/VESreporting_vFW/go-client_2_collector.sh b/veslibrary/ves_clibrary/VESreporting_vFW/go-client_2_collector.sh new file mode 100755 index 0000000..3fe872e --- /dev/null +++ b/veslibrary/ves_clibrary/VESreporting_vFW/go-client_2_collector.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +export LD_LIBRARY_PATH="/opt/VES/libs/x86_64/" +DCAE_COLLECTOR_IP=$(cat /opt/config/dcae_collector_ip.txt) +DCAE_COLLECTOR_PORT=$(cat /opt/config/dcae_collector_port.txt) +DCAE_COLLECTOR_IP2=$(cat /opt/config/dcae_collector_ip2.txt) +DCAE_COLLECTOR_PORT2=$(cat /opt/config/dcae_collector_port2.txt) +./vpp_measurement_reporter $DCAE_COLLECTOR_IP $DCAE_COLLECTOR_PORT $DCAE_COLLECTOR_IP2 $DCAE_COLLECTOR_PORT2 eth1 diff --git a/veslibrary/ves_clibrary/VESreporting_vFW/vpp_measurement_reporter.c b/veslibrary/ves_clibrary/VESreporting_vFW/vpp_measurement_reporter.c index 4b7d6bd..371f3d9 100644 --- a/veslibrary/ves_clibrary/VESreporting_vFW/vpp_measurement_reporter.c +++ b/veslibrary/ves_clibrary/VESreporting_vFW/vpp_measurement_reporter.c @@ -1,9 +1,8 @@ /*************************************************************************//** * - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. * - * Unless otherwise specified, all software contained herein is * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -37,128 +36,13 @@ typedef struct dummy_vpp_metrics_struct { void read_vpp_metrics(vpp_metrics_struct *, char *); -unsigned long long epoch_start = 0; - -#ifdef DOCKER -int measure_traffic() -{ - - EVEL_ERR_CODES evel_rc = EVEL_SUCCESS; - FILE *fp; - int status; - char count[10]; - time_t rawtime; - struct tm * timeinfo; - char period [21]; - char cmd [100]; - int concurrent_sessions = 0; - int configured_entities = 0; - double mean_request_latency = 0; - double measurement_interval = 1; - double memory_configured = 0; - double memory_used = 0; - int request_rate=0; - char secs [3]; - int sec; - double loadavg; - - printf("Checking app traffic\n"); - time (&rawtime); - timeinfo = localtime (&rawtime); - strftime(period,21,"%d/%b/%Y:%H:%M:",timeinfo); - strftime(secs,3,"%S",timeinfo); - sec = atoi(secs); - if (sec == 0) sec = 59; - sprintf(secs, "%02d", sec); - strncat(period, secs, 21); - // ....x....1....x....2. - // 15/Oct/2016:17:51:19 - strcpy(cmd, "sudo docker logs vHello | grep -c "); - strncat(cmd, period, 100); - - fp = popen(cmd, "r"); - if (fp == NULL) { - EVEL_ERROR("popen failed to execute command"); - } - - if (fgets(count, 10, fp) != NULL) { - request_rate = atoi(count); - printf("Reporting request rate for second: %s as %d\n", period, request_rate); - - } - else { - EVEL_ERROR("New Measurement failed"); - } - printf("Processed measurement\n"); - - status = pclose(fp); - if (status == -1) { - EVEL_ERROR("pclose returned an error"); - } - return request_rate; -} - -#endif - - - -/**************************************************************************//** - * tap live cpu stats - *****************************************************************************/ -void evel_get_cpu_stats(EVENT_MEASUREMENT * measurement) -{ - FILE *fp; - char path[1024]; - double usage=0.0; - double idle; - double intrpt; - double nice; - double softirq; - double steal; - double sys; - double user; - double wait; - MEASUREMENT_CPU_USE *cpu_use = NULL; - - /* Open the command for reading. */ - //fp = popen("/bin/ls /etc/", "r"); - fp = popen("/usr/bin/top -bn 2 -d 0.01 | grep '^%Cpu' | tail -n 1 ", "r"); - if (fp == NULL) { - printf("Failed to run command\n" ); - exit(1); - } - - /* Read the output a line at a time - output it. */ - while (fgets(path, sizeof(path)-1, fp) != NULL) { - printf("%s", path+10); - sscanf(path+10," %lf us, %lf sy, %lf ni, %lf id, %lf wa, %lf hi, %lf si, %lf st", - &user,&sys,&nice,&idle,&wait,&intrpt,&softirq,&steal); - } - - /* close */ - pclose(fp); - - cpu_use = evel_measurement_new_cpu_use_add(measurement, "cpu1", usage); - if( cpu_use != NULL ){ - evel_measurement_cpu_use_idle_set(cpu_use,idle); - //evel_measurement_cpu_use_interrupt_set(cpu_use,intrpt); - //evel_measurement_cpu_use_nice_set(cpu_use,nice); - //evel_measurement_cpu_use_softirq_set(cpu_use,softirq); - //evel_measurement_cpu_use_steal_set(cpu_use,steal); - evel_measurement_cpu_use_system_set(cpu_use,sys); - evel_measurement_cpu_use_usageuser_set(cpu_use,user); - //evel_measurement_cpu_use_wait_set(cpu_use,wait); - //evel_measurement_cpu_use_add(measurement, "cpu2", usage,idle,intrpt,nice,softirq,steal,sys,user,wait); - } -} - - - int main(int argc, char** argv) { EVEL_ERR_CODES evel_rc = EVEL_SUCCESS; EVENT_MEASUREMENT* vpp_m = NULL; EVENT_HEADER* vpp_m_header = NULL; + EVENT_HEADER* batch_header = NULL; + MEASUREMENT_VNIC_PERFORMANCE * vnic_performance = NULL; int bytes_in_this_round; int bytes_out_this_round; int packets_in_this_round; @@ -166,38 +50,70 @@ int main(int argc, char** argv) vpp_metrics_struct* last_vpp_metrics = malloc(sizeof(vpp_metrics_struct)); vpp_metrics_struct* curr_vpp_metrics = malloc(sizeof(vpp_metrics_struct)); struct timeval time_val; - //time_t start_epoch; - //time_t last_epoch; + time_t start_epoch; + time_t last_epoch; char hostname[BUFSIZE]; + char eventName[BUFSIZE]; + char eventId[BUFSIZE]; + char* fqdn2 = NULL; + int port2 = 0; + char * vnic = NULL; + memset(eventName, 0, BUFSIZE); + memset(eventId, 0, BUFSIZE); + memset(hostname, 0, BUFSIZE); + + strcpy(eventName, "measurement_vFirewall-Att-Linkdownerr"); + strcpy(eventId, "mvfs00000001"); + char* fqdn = argv[1]; int port = atoi(argv[2]); - char* vnic = argv[3]; - MEASUREMENT_VNIC_PERFORMANCE * vnic_performance = NULL; - //struct timeval tv_start; + if(argc == 6) + { + fqdn2 = argv[3]; + port2 = atoi(argv[4]); + vnic = argv[5]; + } + else + vnic = argv[3]; printf("\nVector Packet Processing (VPP) measurement collection\n"); fflush(stdout); - if (argc != 4) + if (!((argc == 4) || (argc == 6))) { + fprintf(stderr, "Usage: %s <FQDN>|<IP address> <port> <FQDN>|<IP address> <port> <interface> \n", argv[0]); + fprintf(stderr, "OR\n"); fprintf(stderr, "Usage: %s <FQDN>|<IP address> <port> <interface>\n", argv[0]); exit(-1); } - srand(time(NULL)); /**************************************************************************/ /* Initialize */ /**************************************************************************/ if(evel_initialize(fqdn, /* FQDN */ port, /* Port */ + fqdn2, /* Backup FQDN */ + port2, /* Backup port */ NULL, /* optional path */ NULL, /* optional topic */ + 100, /* Ring Buffer size */ 0, /* HTTPS? */ - "", /* Username */ - "", /* Password */ + NULL, /* cert file */ + NULL, /* key file */ + NULL, /* ca info */ + NULL, /* ca file */ + 0, /* verify peer */ + 0, /* verify host */ + "sample1", /* Username */ + "sample1", /* Password */ + "sample1", /* Username2 */ + "sample1", /* Password2 */ + NULL, /* Source ip */ + NULL, /* Source ip2 */ EVEL_SOURCE_VIRTUAL_MACHINE, /* Source type */ "vFirewall", /* Role */ 1)) /* Verbosity */ + { fprintf(stderr, "\nFailed to initialize the EVEL library!!!\n"); exit(-1); @@ -211,7 +127,7 @@ int main(int argc, char** argv) memset(last_vpp_metrics, 0, sizeof(vpp_metrics_struct)); read_vpp_metrics(last_vpp_metrics, vnic); gettimeofday(&time_val, NULL); - epoch_start = time_val.tv_sec * 1000000 + time_val.tv_usec; + start_epoch = time_val.tv_sec * 1000000 + time_val.tv_usec; sleep(READ_INTERVAL); /***************************************************************************/ @@ -246,45 +162,33 @@ int main(int argc, char** argv) packets_out_this_round = 0; } - vpp_m = evel_new_measurement(READ_INTERVAL,"Measurement_vVNF","TrafficStats_1.2.3.4"); - vnic_performance = (MEASUREMENT_VNIC_PERFORMANCE *)evel_measurement_new_vnic_performance("eth0", "true"); - evel_meas_vnic_performance_add(vpp_m, vnic_performance); + vpp_m = evel_new_measurement(READ_INTERVAL, eventName, eventId); if(vpp_m != NULL) { printf("New measurement report created...\n"); - - evel_measurement_type_set(vpp_m, "HTTP request rate"); - evel_measurement_request_rate_set(vpp_m, rand()%10000); - + vnic_performance = (MEASUREMENT_VNIC_PERFORMANCE *)evel_measurement_new_vnic_performance(vnic, "true"); + evel_meas_vnic_performance_add(vpp_m, vnic_performance); evel_vnic_performance_rx_total_pkt_delta_set(vnic_performance, packets_in_this_round); evel_vnic_performance_tx_total_pkt_delta_set(vnic_performance, packets_out_this_round); evel_vnic_performance_rx_octets_delta_set(vnic_performance, bytes_in_this_round); evel_vnic_performance_tx_octets_delta_set(vnic_performance, bytes_out_this_round); - evel_get_cpu_stats(vpp_m); /***************************************************************************/ /* Set parameters in the MEASUREMENT header packet */ /***************************************************************************/ - struct timeval tv_now; - gettimeofday(&tv_now, NULL); - unsigned long long epoch_now = tv_now.tv_usec + 1000000 * tv_now.tv_sec; - - //last_epoch = start_epoch + READ_INTERVAL * 1000000; + last_epoch = start_epoch + READ_INTERVAL * 1000000; vpp_m_header = (EVENT_HEADER *)vpp_m; - //vpp_m_header->start_epoch_microsec = start_epoch; - //vpp_m_header->last_epoch_microsec = last_epoch; - evel_start_epoch_set(&vpp_m->header, epoch_start); - evel_last_epoch_set(&vpp_m->header, epoch_now); - epoch_start = epoch_now; - - evel_nfcnamingcode_set(&vpp_m->header, "vVNF"); - evel_nfnamingcode_set(&vpp_m->header, "vVNF"); - //strcpy(vpp_m_header->reporting_entity_id.value, "No UUID available"); - //strcpy(vpp_m_header->reporting_entity_name, hostname); - evel_reporting_entity_name_set(&vpp_m->header, "fwll"); - evel_reporting_entity_id_set(&vpp_m->header, "No UUID available"); - evel_rc = evel_post_event(vpp_m_header); + vpp_m_header->start_epoch_microsec = start_epoch; + vpp_m_header->last_epoch_microsec = last_epoch; + evel_reporting_entity_id_set(vpp_m_header, "No UUID available"); +printf("1111\n"); + evel_reporting_entity_name_set(vpp_m_header, hostname); +printf("1111\n"); + // evel_rc = evel_post_event(vpp_m_header); + batch_header = evel_new_batch("batch_event_name", "bevent_id"); + evel_batch_add_event(batch_header, vpp_m_header); + evel_rc = evel_post_event(batch_header); if(evel_rc == EVEL_SUCCESS) { printf("Measurement report correctly sent to the collector!\n"); @@ -301,8 +205,8 @@ int main(int argc, char** argv) last_vpp_metrics->bytes_out = curr_vpp_metrics->bytes_out; last_vpp_metrics->packets_in = curr_vpp_metrics->packets_in; last_vpp_metrics->packets_out = curr_vpp_metrics->packets_out; - //gettimeofday(&time_val, NULL); - //start_epoch = time_val.tv_sec * 1000000 + time_val.tv_usec; + gettimeofday(&time_val, NULL); + start_epoch = time_val.tv_sec * 1000000 + time_val.tv_usec; sleep(READ_INTERVAL); } diff --git a/veslibrary/ves_clibrary/VESreporting_vLB/Makefile b/veslibrary/ves_clibrary/VESreporting_vLB/Makefile index faf004c..a9eb05e 100644 --- a/veslibrary/ves_clibrary/VESreporting_vLB/Makefile +++ b/veslibrary/ves_clibrary/VESreporting_vLB/Makefile @@ -1,4 +1,3 @@ - ############################################################################# # # Copyright © 2017 AT&T Intellectual Property. All rights reserved. @@ -17,9 +16,9 @@ ############################################################################# CC=gcc + ARCH=$(shell getconf LONG_BIT) -#CODE_ROOT=$(CURDIR)/../../.. -CODE_ROOT=../VES5.0/evel/evel-library +CODE_ROOT=$(CURDIR)/../.. LIBS_DIR=$(CODE_ROOT)/libs/x86_$(ARCH) INCLUDE_DIR=$(CODE_ROOT)/code/evel_library @@ -38,4 +37,10 @@ vpp_measurement_reporter: vpp_measurement_reporter.c $(CC) $(CPPFLAGS) $(CFLAGS) -o vpp_measurement_reporter \ -L $(LIBS_DIR) \ -I $(INCLUDE_DIR) \ - vpp_measurement_reporter.c -lm -lpthread -level -lcurl + vpp_measurement_reporter.c \ + -lpthread \ + -level \ + -lm \ + -lcurl + + diff --git a/veslibrary/ves_clibrary/VESreporting_vLB/README.md b/veslibrary/ves_clibrary/VESreporting_vLB/README.md index 598b207..1b3dd48 100644 --- a/veslibrary/ves_clibrary/VESreporting_vLB/README.md +++ b/veslibrary/ves_clibrary/VESreporting_vLB/README.md @@ -22,5 +22,6 @@ To run the vpp_measurement_reporter, please execute the following steps: - Make the go-client.sh script executable chmod +x go-client.sh - - Run the go-client.sh script + - Run one of the scripts based on one collector or 2 collectors ./go-client.sh + ./go-client_2_collector.sh diff --git a/veslibrary/ves_clibrary/VESreporting_vLB/go-client.sh b/veslibrary/ves_clibrary/VESreporting_vLB/go-client.sh index 3d1b159..623c86e 100755 --- a/veslibrary/ves_clibrary/VESreporting_vLB/go-client.sh +++ b/veslibrary/ves_clibrary/VESreporting_vLB/go-client.sh @@ -1,6 +1,8 @@ #!/bin/bash -export LD_LIBRARY_PATH="/opt/VES/libs/x86_64/" +export LD_LIBRARY_PATH="/opt/VES/evel/evel-library/libs/x86_64/" DCAE_COLLECTOR_IP=$(cat /opt/config/dcae_collector_ip.txt) DCAE_COLLECTOR_PORT=$(cat /opt/config/dcae_collector_port.txt) ./vpp_measurement_reporter $DCAE_COLLECTOR_IP $DCAE_COLLECTOR_PORT eth1 + + diff --git a/veslibrary/ves_clibrary/VESreporting_vLB/go-client_2_collector.sh b/veslibrary/ves_clibrary/VESreporting_vLB/go-client_2_collector.sh new file mode 100755 index 0000000..3fe872e --- /dev/null +++ b/veslibrary/ves_clibrary/VESreporting_vLB/go-client_2_collector.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +export LD_LIBRARY_PATH="/opt/VES/libs/x86_64/" +DCAE_COLLECTOR_IP=$(cat /opt/config/dcae_collector_ip.txt) +DCAE_COLLECTOR_PORT=$(cat /opt/config/dcae_collector_port.txt) +DCAE_COLLECTOR_IP2=$(cat /opt/config/dcae_collector_ip2.txt) +DCAE_COLLECTOR_PORT2=$(cat /opt/config/dcae_collector_port2.txt) +./vpp_measurement_reporter $DCAE_COLLECTOR_IP $DCAE_COLLECTOR_PORT $DCAE_COLLECTOR_IP2 $DCAE_COLLECTOR_PORT2 eth1 diff --git a/veslibrary/ves_clibrary/VESreporting_vLB/vpp_measurement_reporter.c b/veslibrary/ves_clibrary/VESreporting_vLB/vpp_measurement_reporter.c index c0c6e01..d641f95 100644 --- a/veslibrary/ves_clibrary/VESreporting_vLB/vpp_measurement_reporter.c +++ b/veslibrary/ves_clibrary/VESreporting_vLB/vpp_measurement_reporter.c @@ -3,7 +3,6 @@ * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. * - * Unless otherwise specified, all software contained herein is * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -121,31 +120,59 @@ int main(int argc, char** argv) char* fqdn = argv[1]; int port = atoi(argv[2]); char* vnic = argv[3]; + char* fqdn2 = NULL; + int port2 = 0; + + if(argc == 6) + { + fqdn2 = argv[3]; + port2 = atoi(argv[4]); + vnic = argv[5]; + } + else + vnic = argv[3]; + MEASUREMENT_VNIC_PERFORMANCE * vnic_performance = NULL; printf("\nVector Packet Processing (VPP) measurement collection\n"); fflush(stdout); - if (argc != 4) + if (!((argc == 6) || (argc == 4))) { - fprintf(stderr, "Usage: %s <FQDN>|<IP address> <port> <interface>\n", argv[0]); + fprintf(stderr, "Usage: %s <FQDN>|<IP address> <port> <FQDN>|<IP address> <port> <interface> \n", argv[0]); + fprintf(stderr, "OR\n"); + fprintf(stderr, "Usage: %s <FQDN>|<IP address> <port> <interface> \n", argv[0]); exit(-1); } + srand(time(NULL)); /**************************************************************************/ /* Initialize */ /**************************************************************************/ if(evel_initialize(fqdn, /* FQDN */ - port, /* Port */ - NULL, /* optional path */ - NULL, /* optional topic */ - 0, /* HTTPS? */ - "", /* Username */ - "", /* Password */ - EVEL_SOURCE_VIRTUAL_MACHINE, /* Source type */ - "vLoadBalancer", /* Role */ - 1)) /* Verbosity */ + port, /* Port */ + fqdn2, /* Backup FQDN */ + port2, /* Backup port */ + NULL, /* optional path */ + NULL, /* optional topic */ + 100, /* Ring Buffer size */ + 0, /* HTTPS? */ + NULL, /* cert file */ + NULL, /* key file */ + NULL, /* ca info */ + NULL, /* ca file */ + 0, /* verify peer */ + 0, /* verify host */ + "sample1", /* Username */ + "sample1", /* Password */ + "sample1", /* Username2 */ + "sample1", /* Password2 */ + NULL, /* Source ip */ + NULL, /* Backup Source IP */ + EVEL_SOURCE_VIRTUAL_MACHINE, /* Source type */ + "vLoadBalancer", /* Role */ + 1)) /* Verbosity */ { fprintf(stderr, "\nFailed to initialize the EVEL library!!!\n"); exit(-1); @@ -207,8 +234,8 @@ int main(int argc, char** argv) packets_out_this_round = 0; } - vpp_m = evel_new_measurement(READ_INTERVAL,"Measurement_vVNF","TrafficStats_1.2.3.4"); - vnic_performance = (MEASUREMENT_VNIC_PERFORMANCE *)evel_measurement_new_vnic_performance("eth0", "true"); + vpp_m = evel_new_measurement(READ_INTERVAL,"vLoadBalancer","TrafficStats_1.2.3.4"); + vnic_performance = (MEASUREMENT_VNIC_PERFORMANCE *)evel_measurement_new_vnic_performance(vnic, "true"); evel_meas_vnic_performance_add(vpp_m, vnic_performance); if(vpp_m != NULL) { diff --git a/veslibrary/ves_clibrary/evel/evel-library/bldjobs/Makefile b/veslibrary/ves_clibrary/evel/evel-library/bldjobs/Makefile index 5a3a111..134d0be 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/bldjobs/Makefile +++ b/veslibrary/ves_clibrary/evel/evel-library/bldjobs/Makefile @@ -146,6 +146,7 @@ API_SOURCES=$(EVELLIB_ROOT)/evel.c \ $(EVELLIB_ROOT)/evel_threshold_cross.c \ $(EVELLIB_ROOT)/evel_voicequality.c \ $(EVELLIB_ROOT)/evel_logging.c \ + $(EVELLIB_ROOT)/evel_batch.c \ $(EVELLIB_ROOT)/jsmn.c API_OBJECTS=$(API_SOURCES:.c=.o) -include $(API_SOURCES:.c=.d) diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/LICENSE.TXT b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/LICENSE.TXT new file mode 100644 index 0000000..16285cd --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/LICENSE.TXT @@ -0,0 +1,22 @@ +/* + * ============LICENSE_START========================================== + * =================================================================== + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Unless otherwise specified, all software contained herein is + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + * + * ECOMP is trademark and service mark of AT&T Intellectual Property. + * + */ diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/Makefile b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/Makefile new file mode 100644 index 0000000..e007759 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/Makefile @@ -0,0 +1,52 @@ +############################################################################# +# +# Copyright © 2018 AT&T Intellectual Property. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +############################################################################# + +CC=gcc +ARCH=$(shell getconf LONG_BIT) +CODE_ROOT=$(CURDIR)/../.. +#CODE_ROOT=../code/evel-library +LIBS_DIR=$(CODE_ROOT)/libs/x86_$(ARCH) +#LIBS_DIR=/usr/lib +INCLUDE_DIR= -I $(CODE_ROOT)/code/evel_library -I . + +#****************************************************************************** +# Standard compiler flags. * +#****************************************************************************** +CPPFLAGS= +CFLAGS=-Wall -g -fPIC +FILEOBJLIST= jsmn.o ves_heartbeat_reporter.o + +all: ves_heartbeat_reporter + +clean: + rm -f *.o ves_heartbeat_reporter + +%.o: %.c + $(CC) $(CPPFLAGS) $(CFLAGS) $(INCLUDE_DIR) -c $< -o $@ + +jsmn.o: jsmn.c jsmn.h +ves_heartbeat_reporter.o: ves_heartbeat_reporter.c + +ves_heartbeat_reporter: $(FILEOBJLIST) + $(CC) $(CPPFLAGS) $(CFLAGS) -o ves_heartbeat_reporter \ + -L $(LIBS_DIR) \ + $(FILEOBJLIST) \ + -lpthread \ + -level \ + -lcurl + + diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/README.md b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/README.md new file mode 100644 index 0000000..a0d8e76 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/README.md @@ -0,0 +1,37 @@ + +PROJECT DESCRIPTION + +--- +This project contains the source code and scripts for the periodic generation of heartbeat events. The folder contains: + + - README.md: this file. + + - LICENSE.TXT: the license text. + + - ves_heartbeat_reporter.c and other .c files: source code that uses the ECOMP Vendor Event Listener Library (VES) to generate the periodic hertbeat events. It reads hb_config.json file for parameter values and poppulate the heartbeat event. If eventName parameter value is not given, the application terminates. If reportingEntityName and sourceName parameter values are not given, then it gets the hostname and poppulates it. If heartbeatInterval is not given, it defaults to 60 seconds. + + - Makefile: makefile that compiles ves_heartbeat_reporter.c and generates ves_heartbeat_reporter binary. + + - go-client.sh/go-client_2_collectors.sh: bash script that starts up the ves_heartbeat_reporter. It reads input parameters like DCAE IP address and port from configuration files contained in /opt/config. Based on the collector configuration, use go-client.sh for single collector configuration, or use go-client_2_collectors.sh for 2 collectors configuration. + + +USAGE +----- + +Update the configuration files with proper parameters values so that events generated would contain those values + +To run the ves_heartbeat_reporter in single collector configuration, please execute the following steps: + + - Make the go-client.sh script executable + chmod +x go-client.sh + + - Run the go-client.sh script + ./go-client.sh + +For 2 collectors configuration, please execute following steps: + + - Make the go-client.sh script executable + chmod +x go-client_2_collectors.sh + + - Run the go-client_2_collectors.sh script + ./go-client_2_collectors.sh diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/dep.xml b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/dep.xml new file mode 100644 index 0000000..fc18229 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/dep.xml @@ -0,0 +1,25 @@ +<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd"> + <id>demo</id> + <formats> + <format>tar.gz</format> + </formats> + <fileSets> + + <fileSet> + <directory>.</directory> + <outputDirectory>/</outputDirectory> + <includes> + <include>*.sh</include> + <include>*.md</include> + <include>*.TXT</include> + <include>*.c</include> + <include>Makefile</include> + </includes> + </fileSet> + + </fileSets> +</assembly> + + diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/go-client.sh b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/go-client.sh new file mode 100755 index 0000000..22b930d --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/go-client.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +export LD_LIBRARY_PATH="/opt/VES/evel/evel-library/libs/x86_64/" +DCAE_COLLECTOR_IP=$(cat /opt/config/dcae_collector_ip.txt) +DCAE_COLLECTOR_PORT=$(cat /opt/config/dcae_collector_port.txt) +./ves_heartbeat_reporter $DCAE_COLLECTOR_IP $DCAE_COLLECTOR_PORT diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/go-client_2_collectors.sh b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/go-client_2_collectors.sh new file mode 100755 index 0000000..b3747e2 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/go-client_2_collectors.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +export LD_LIBRARY_PATH="/opt/VES/evel/evel-library/libs/x86_64/" + +#Usage for 2 collectors: +#./ves_heartbeat_reporter <FQDN>|<IP address> <port> <FQDN>|<IP address> <port> + +DCAE_COLLECTOR_IP=$(cat /opt/config/dcae_collector_ip.txt) +DCAE_COLLECTOR_PORT=$(cat /opt/config/dcae_collector_port.txt) +DCAE_COLLECTOR_IP2=$(cat /opt/config/dcae_collector_ip2.txt) +DCAE_COLLECTOR_PORT2=$(cat /opt/config/dcae_collector_port2.txt) +./ves_heartbeat_reporter $DCAE_COLLECTOR_IP $DCAE_COLLECTOR_PORT $DCAE_COLLECTOR_IP2 $DCAE_COLLECTOR_PORT2 diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/hb_config.json b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/hb_config.json new file mode 100644 index 0000000..db32d2d --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/hb_config.json @@ -0,0 +1,13 @@ +{ + "tmp_directParameters": { + "eventType": "platform", + "eventName": "Heartbeat_VNF-AT&T_heartbeat", + "nfcNamingCode": "ssc", + "nfNamingCode": "scfx", + "reportingEntityId": "cc305d54-75b4-431b-adb2-eb6b9e541234", + "reportingEntityName": "ibcx0001vm002oam001", + "sourceId": "de305d54-75b4-431b-adb2-eb6b9e546014", + "sourceName": "scfx0001vm002cap001", + "heartbeatInterval": 10 + } +} diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/jsmn.c b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/jsmn.c new file mode 100644 index 0000000..f663403 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/jsmn.c @@ -0,0 +1,615 @@ +/*************************************************************************//** + * + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * + * Unless otherwise specified, all software contained herein is + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + ****************************************************************************/ +#include<stdio.h> +#include<stdlib.h> +#include<string.h> +#include "jsmn.h" + +/** + * Allocates a fresh unused token from the token pull. + */ +static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser, + jsmntok_t *tokens, size_t num_tokens) { + jsmntok_t *tok; + if (parser->toknext >= num_tokens) { + return NULL; + } + tok = &tokens[parser->toknext++]; + tok->start = tok->end = -1; + tok->size = 0; +//#ifdef JSMN_PARENT_LINKS + tok->parent = -1; +//#endif + return tok; +} + +/** + * Fills token type and boundaries. + */ +static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type, + int start, int end) { +//printf("jsmn_fill_token:: start-%d, end-%d\n", start, end); + token->type = type; + token->start = start; + token->end = end; + token->size = 0; +} + +/** + * Fills next available token with JSON primitive. + */ +static int jsmn_parse_primitive(jsmn_parser *parser, const char *js, + size_t len, jsmntok_t *tokens, size_t num_tokens) { + jsmntok_t *token; + int start; + + start = parser->pos; + + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { +//printf("jsmn_parse_primitive:: the char is - %c\n", js[parser->pos]); + switch (js[parser->pos]) { +#ifndef JSMN_STRICT + /* In strict mode primitive must be followed by "," or "}" or "]" */ + case ':': +#endif + case '\t' : case '\r' : case '\n' : case ' ' : + case ',' : case ']' : case '}' : + goto found; + } + if (js[parser->pos] < 32 || js[parser->pos] >= 127) { + parser->pos = start; + return JSMN_ERROR_INVAL; + } + } +#ifdef JSMN_STRICT + /* In strict mode primitive must be followed by a comma/object/array */ + parser->pos = start; + return JSMN_ERROR_PART; +#endif + +found: + if (tokens == NULL) { + parser->pos--; + return 0; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); + if (token == NULL) { + parser->pos = start; + return JSMN_ERROR_NOMEM; + } + jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos); +//#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +//#endif + parser->pos--; + return 0; +} + +/** + * Fills next token with JSON string. + */ +static int jsmn_parse_string(jsmn_parser *parser, const char *js, + size_t len, jsmntok_t *tokens, size_t num_tokens) { + jsmntok_t *token; + + int start = parser->pos; + + parser->pos++; + + /* Skip starting quote */ + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { + char c = js[parser->pos]; + char d = js[parser->pos + 1]; +// char e = js[parser->pos + 2]; +//printf("jsmn_parse_string: value-%c, pos-%d\n", c,parser->pos); + + /* Quote: end of string */ +// if (c == '\"') { + if (d == '\"') { +// if ((d == '\"')&&((e == ' ')||(e == ','))) { +parser->pos++; +//printf("jsmn_parse_string: end of string\n"); + if (tokens == NULL) { +//printf("jsmn_parse_string: end tokens is NULL\n"); + return 0; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); +//printf("jsmn_parse_string: Allocated tokens \n"); + if (token == NULL) { +//printf("jsmn_parse_string: Allocated tokens is NULL\n"); + parser->pos = start; + return JSMN_ERROR_NOMEM; + } + jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos); +//printf("jsmn_parse_string: Allocated tokens is filled\n"); +//#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +//#endif + return 0; + } + + /* Backslash: Quoted symbol expected */ + if (c == '\\' && parser->pos + 1 < len) { + int i; + parser->pos++; +//printf("jsmn_parse_string: value - %c, POS-%3d \n",c, js[parser->pos]); + switch (js[parser->pos]) { + /* Allowed escaped symbols */ + case '\"': case '/' : case '\\' : case 'b' : + case 'f' : case 'r' : case 'n' : case 't' : + break; + /* Allows escaped symbol \uXXXX */ + case 'u': + parser->pos++; + for(i = 0; i < 4 && parser->pos < len && js[parser->pos] != '\0'; i++) { + /* If it isn't a hex character we have an error */ + if(!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */ + (js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */ + (js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */ + parser->pos = start; + return JSMN_ERROR_INVAL; + } + parser->pos++; + } + parser->pos--; + break; + /* Unexpected symbol */ + default: + parser->pos = start; + return JSMN_ERROR_INVAL; + } + } + } + parser->pos = start; +printf("jsmn_parse_string: exiting with ERROR_PART, pos-%d", parser->pos); + return JSMN_ERROR_PART; +} + +/** + * Parse JSON string and fill tokens. + */ +int jsmn_parse(jsmn_parser *parser, const char *js, size_t len, + jsmntok_t *tokens, unsigned int num_tokens) { + int r; + int i; + jsmntok_t *token; + int count = parser->toknext; + + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { + char c; + jsmntype_t type; + + c = js[parser->pos]; +//printf("jsmn_parse: value of c - %c\n",c); + switch (c) { + case '{': case '[': + count++; + if (tokens == NULL) { + break; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); + if (token == NULL) + return JSMN_ERROR_NOMEM; + if (parser->toksuper != -1) { + tokens[parser->toksuper].size++; +//#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +//#endif + } + token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY); + token->start = parser->pos; + parser->toksuper = parser->toknext - 1; + break; + case '}': case ']': + if (tokens == NULL) + break; + type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY); +//#ifdef JSMN_PARENT_LINKS + if (parser->toknext < 1) { + return JSMN_ERROR_INVAL; + } + token = &tokens[parser->toknext - 1]; + for (;;) { + if (token->start != -1 && token->end == -1) { + if (token->type != type) { + return JSMN_ERROR_INVAL; + } + token->end = parser->pos + 1; + parser->toksuper = token->parent; + break; + } + if (token->parent == -1) { + break; + } + token = &tokens[token->parent]; + } +//#else +// for (i = parser->toknext - 1; i >= 0; i--) { +// token = &tokens[i]; +// if (token->start != -1 && token->end == -1) { +// if (token->type != type) { +// return JSMN_ERROR_INVAL; +// } +// parser->toksuper = -1; +// token->end = parser->pos + 1; +// break; +// } +// } +// /* Error if unmatched closing bracket */ +// if (i == -1) return JSMN_ERROR_INVAL; +// for (; i >= 0; i--) { +// token = &tokens[i]; +// if (token->start != -1 && token->end == -1) { +// parser->toksuper = i; +// break; +// } +// } +//#endif + break; + case '\"': + r = jsmn_parse_string(parser, js, len, tokens, num_tokens); + if (r < 0) return r; + count++; + if (parser->toksuper != -1 && tokens != NULL) + tokens[parser->toksuper].size++; + break; + case '\t' : case '\r' : case '\n' : case ' ': + break; + case ':': + parser->toksuper = parser->toknext - 1; +//printf("jsmn_parse: value of c is :: - %c\n",c); + break; + case ',': + if (tokens != NULL && parser->toksuper != -1 && + tokens[parser->toksuper].type != JSMN_ARRAY && + tokens[parser->toksuper].type != JSMN_OBJECT) { +//#ifdef JSMN_PARENT_LINKS + parser->toksuper = tokens[parser->toksuper].parent; +//#else +// for (i = parser->toknext - 1; i >= 0; i--) { +// if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) { +// if (tokens[i].start != -1 && tokens[i].end == -1) { +// parser->toksuper = i; +// break; +// } +// } +// } +//#endif + } + break; +#ifdef JSMN_STRICT + /* In strict mode primitives are: numbers and booleans */ + case '-': case '0': case '1' : case '2': case '3' : case '4': + case '5': case '6': case '7' : case '8': case '9': + case 't': case 'f': case 'n' : + /* And they must not be keys of the object */ + if (tokens != NULL && parser->toksuper != -1) { + jsmntok_t *t = &tokens[parser->toksuper]; + if (t->type == JSMN_OBJECT || + (t->type == JSMN_STRING && t->size != 0)) { + return JSMN_ERROR_INVAL; + } + } +#else + /* In non-strict mode every unquoted value is a primitive */ + default: +#endif + r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens); + if (r < 0) return r; + count++; + if (parser->toksuper != -1 && tokens != NULL) + tokens[parser->toksuper].size++; + break; + +#ifdef JSMN_STRICT + /* Unexpected char in strict mode */ + default: + return JSMN_ERROR_INVAL; +#endif + } + } + + if (tokens != NULL) { + for (i = parser->toknext - 1; i >= 0; i--) { +//printf("index -%2d, start is %3d, end is %3d\n", i, tokens[i].start, tokens[i].end); + /* Unmatched opened object or array */ + if (tokens[i].start != -1 && tokens[i].end == -1) { + return JSMN_ERROR_PART; + } + } + } + + return count; +} + +/** + * Creates a new parser based over a given buffer with an array of tokens + * available. + */ +void jsmn_init(jsmn_parser *parser) { + parser->pos = 0; + parser->toknext = 0; + parser->toksuper = -1; +} + +int jsoneq(const char *json, jsmntok_t *tok, const char *s) +{ + if (tok->type == JSMN_STRING && (int) strlen(s) == tok->end - tok->start && + strncmp(json + tok->start, s, tok->end - tok->start) == 0) { + return 0; + } + return -1; +} + +void printToken(char * js, jsmntok_t * tokens, int numToken) +{ + for (int i = 1; i < numToken; i++) + { + printf("Token number-%2d, parent-%2d, type-%d size-%2d, parameter -", i, tokens[i].parent, tokens[i].type, tokens[i].size); + if (tokens[i].type == JSMN_STRING || tokens[i].type == JSMN_PRIMITIVE) { + printf("%.*s\n", tokens[i].end - tokens[i].start, js + tokens[i].start); + } else if (tokens[i].type == JSMN_ARRAY) { + printf("[%d elems]\n", tokens[i].size); + } else if (tokens[i].type == JSMN_OBJECT) { + printf("{%d elems}\n", tokens[i].size); + } else { + printf("value?? - "); + TOKEN_PRINT(tokens[i]); + } + } +} + +int getStringToken(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, char * value, int maxValueSize) +{ + int i = 0; + int dpToken = 0; + + memset(value, 0, maxValueSize); + + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], pParam) == 0) + break; + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 1; //Parent token not seen + } + for (i=1; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { + if(jsoneq(js, &tokens[i], param) != 0) + continue; + TOKEN_COPY(js, tokens[i+1], value); + + return 0; //Success + } + } + printf("The parameter %s is not present in JSON file\n", param); + return 2; //parameter not found +} + +int getIntToken(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, int * value) +{ + int i = 0; + int dpToken = 0; + char val[128]; + + memset(val, 0, 128); + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], pParam) == 0) + break; + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 1; //Parent token not seen + } + for (i=1; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { + if(jsoneq(js, &tokens[i], param) != 0) + { + continue; + } + + if(tokens[i+1].type != JSMN_PRIMITIVE) + return 3; //Wrong parameter type + +// printf("INT parameter / Value - %s", param); + TOKEN_COPY(js, tokens[i+1], val); + *value = atoi(val); +// printf(" - %d\n", *value); + + return 0; //success + } + } + printf("The parameter %s is not present in JSON file\n", param); + return 2; //parameter not found +} + +void parseDirectParameters(char * js, jsmntok_t * tokens, int numToken) +{ + int i = 0; + int dpToken = 0; + char param[128]; + char value[128]; + + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], "directParameters") == 0) + break; + } + + if (i < numToken) + { + dpToken = ++i; + } + + for (int i = 1; i < numToken; i++) + { + memset(param, 0, 128); + memset(value, 0, 128); + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { + TOKEN_COPY(js, tokens[i], param); +// printf("parameter / Value - %s", param); + TOKEN_COPY(js, tokens[i+1], value); +// printf(" - %s\n", value); + } + } +} + +int getArrayTokens(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, ARRAYVAL * arrayValue, int * numElements) +{ + int i = 0; + int dpToken = 0; + + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], pParam) == 0) + break; + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 1; //Parent token not seen + } + for (i=1; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { +// printf("value of token %d\n", i); + if(jsoneq(js, &tokens[i], param) != 0) + continue; + + if (tokens[i+1].type == JSMN_ARRAY) + { + *numElements = tokens[i+1].size; +// printf("[%d elems]\n", *numElements); + + for (int k = 0; k < *numElements; k++) + { + TOKEN_COPY(js, tokens[i+2+k], arrayValue[k].arrayString); +// printf(" - %s\n", arrayValue[k].arrayString); + } + return 0; //Success + } + } + } + printf("The parameter %s is not present in JSON file\n", param); + return 2; //parameter not found +} + +int isTokenPresent(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam) +{ + int i = 0; + int dpToken = 0; + char val[128]; + + memset(val, 0, 128); + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], pParam) == 0) + break; + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 1; //Parent token not seen + } + for (i=1; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING) + { + if(jsoneq(js, &tokens[i], param) != 0) + { + return 0; //Token present + } + } + } + printf("The parameter %s is not present in JSON file\n", param); + return 2; //Token Not present +} + +int read_keyVal_params(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, KEYVALRESULT * keyValueResultList, int * numElements) +{ + int i = 0; + int dpToken = 0; + + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], pParam) == 0) + break; + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 1; //Parent token not seen + } + for (i=1; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { +// printf("value of token %d\n", i); + if(jsoneq(js, &tokens[i], param) != 0) + continue; + + if (tokens[i+1].type == JSMN_OBJECT) + { + *numElements = tokens[i+1].size; +// printf("{%d elems}\n", *numElements); + + for (int k = 0; k < *numElements; k++) + { + TOKEN_COPY(js, tokens[i+2+k*2], keyValueResultList[k].keyStr); +// printf("Key - %s", keyValueResultList[k].keyStr); + TOKEN_COPY(js, tokens[i+3+k*2], keyValueResultList[k].valStr); +// printf("Value - %s\n", keyValueResultList[k].valStr); + } + return 0; //Success + } + } + } + printf("The parameter %s is not present in JSON file\n", param); + return 2; //parameter not found +} diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/jsmn.h b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/jsmn.h new file mode 100644 index 0000000..6703494 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/jsmn.h @@ -0,0 +1,134 @@ +/*************************************************************************//** + * + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ + +#ifndef __JSMN_H_ +#define __JSMN_H_ + +#include <stddef.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * JSON type identifier. Basic types are: + * o Object + * o Array + * o String + * o Other primitive: number, boolean (true/false) or null + */ +typedef enum { + JSMN_UNDEFINED = 0, + JSMN_OBJECT = 1, + JSMN_ARRAY = 2, + JSMN_STRING = 3, + JSMN_PRIMITIVE = 4 +} jsmntype_t; + +enum jsmnerr { + /* Not enough tokens were provided */ + JSMN_ERROR_NOMEM = -1, + /* Invalid character inside JSON string */ + JSMN_ERROR_INVAL = -2, + /* The string is not a full JSON packet, more bytes expected */ + JSMN_ERROR_PART = -3 +}; + +typedef struct arrayValues { + char arrayString[32]; +} ARRAYVAL; + +typedef struct keyValResult { + char keyStr[80]; + char valStr[250]; + char resultStr[80]; +} KEYVALRESULT; + +/** + * JSON token description. + * @param type type (object, array, string etc.) + * @param start start position in JSON data string + * @param end end position in JSON data string + */ +typedef struct { + jsmntype_t type; + int start; + int end; + int size; +//#ifdef JSMN_PARENT_LINKS + int parent; +//#endif +} jsmntok_t; + +/** + * JSON parser. Contains an array of token blocks available. Also stores + * the string being parsed now and current position in that string + */ +typedef struct { + unsigned int pos; /* offset in the JSON string */ + unsigned int toknext; /* next token to allocate */ + int toksuper; /* superior token node, e.g parent object or array */ +} jsmn_parser; + +#define TOKEN_EQ(t, tok_start, tok_end, tok_type) \ + ((t).start == tok_start \ + && (t).end == tok_end \ + && (t).type == (tok_type)) + +#define TOKEN_STRING(js, t, s) \ + (strncmp(js+(t).start, s, (t).end - (t).start) == 0 \ + && strlen(s) == (t).end - (t).start) + +#define TOKEN_COPY(js, t, s) \ + strncpy(s, js+(t).start, (t).end - (t).start) + +#define TOKEN_PRINT(t) \ + printf("start: %d, end: %d, type: %d, size: %d\n", \ + (t).start, (t).end, (t).type, (t).size) + + +/** + * Create JSON parser over an array of tokens + */ +void jsmn_init(jsmn_parser *parser); + +/** + * Run JSON parser. It parses a JSON data string into and array of tokens, each describing + * a single JSON object. + */ +int jsmn_parse(jsmn_parser *parser, const char *js, size_t len, + jsmntok_t *tokens, unsigned int num_tokens); + +int jsoneq(const char *json, jsmntok_t *tok, const char *s); + +void printToken(char * js, jsmntok_t * tokens, int numToken); + +int getStringToken(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, char * value, int maxValueSize); + +int getIntToken(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, int * value); + +int getArrayTokens(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, ARRAYVAL * arrayValue, int * numElements); + +int isTokenPresent(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam); + +int read_keyVal_params(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, KEYVALRESULT * keyValueResultList, int * numElements); + +#ifdef __cplusplus +} +#endif + +#endif /* __JSMN_H_ */ diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/pom.xml b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/pom.xml new file mode 100644 index 0000000..f9f42eb --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/pom.xml @@ -0,0 +1,83 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START========================================== + =================================================================== + Copyright © 2017 AT&T Intellectual Property. All rights reserved. + =================================================================== + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ============LICENSE_END============================================ + + ECOMP and OpenECOMP are trademarks + and service marks of AT&T Intellectual Property. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + +<parent> + <groupId>org.onap.demo.vnf</groupId> + <artifactId>demo-aggregator</artifactId> + <version>1.2.0-SNAPSHOT</version> + <relativePath>../../pom.xml</relativePath> + </parent> + + <modelVersion>4.0.0</modelVersion> + <groupId>org.onap.demo.vnf.ves5</groupId> + <artifactId>ves_vfw_reporting</artifactId> + + <build> + <plugins> + + <plugin> + <artifactId>maven-jar-plugin</artifactId> + <version>2.3.2</version> + <executions> + <execution> + <id>default-jar</id> + <phase>never</phase> + </execution> + </executions> + </plugin> + + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <version>2.5.3</version> + <configuration> + <descriptor>dep.xml</descriptor> + </configuration> + <executions> + <execution> + <id>create-archive</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>exec-maven-plugin</artifactId> + <executions> + <execution> + <phase>none</phase> + </execution> + </executions> + <configuration> + <skip>true</skip> + </configuration> + </plugin> + + </plugins> + </build> + +</project> diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/sample_heartbeat_events.txt b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/sample_heartbeat_events.txt new file mode 100644 index 0000000..f318fa7 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/sample_heartbeat_events.txt @@ -0,0 +1,26 @@ +{ + "event": { + "commonEventHeader": { + "domain": "heartbeat", + "eventId": "heartbeat000000001", + "eventName": "Heartbeat_VNF-AT&T_heartbeat", + "eventType": "platform", + "lastEpochMicrosec": 1548490889528042, + "nfNamingCode": "scfx", + "nfcNamingCode": "ssc", + "priority": "Normal", + "reportingEntityId": "cc305d54-75b4-431b-adb2-eb6b9e541234", + "reportingEntityName": "ibcx0001vm002oam001", + "sequence": 0, + "sourceId": "de305d54-75b4-431b-adb2-eb6b9e546014", + "sourceName": "scfx0001vm002cap001", + "startEpochMicrosec": 1548490879514800, + "version": 3.0 + }, + "heartbeatField": { + "heartbeatFieldsVersion": 1.0, + "heartbeatInterval": 10 + } + } +} + diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/ves_heartbeat_reporter.c b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/ves_heartbeat_reporter.c new file mode 100644 index 0000000..7077925 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_HB/ves_heartbeat_reporter.c @@ -0,0 +1,255 @@ +/*************************************************************************//** + * + * Copyright © 2018 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <pthread.h> +#include <string.h> +#include <netdb.h> +#include <sys/time.h> +#include <sys/stat.h> +#include "jsmn.h" +#include "evel.h" + +#define BUFSIZE 128 +#define MAX_BUFFER_SIZE 4096 +#define MAX_TOKENS 1000 + +void *HeartbeatThread(void *threadarg); + +unsigned long long epoch_start = 0; + +int main(int argc, char** argv) +{ + char* fqdn = argv[1]; + int port = atoi(argv[2]); + int i=0; + int rc; + pthread_attr_t attr; + pthread_t hb_thread; + char* fqdn2 = NULL; + int port2 = 0; + + if(argc == 5) + { + fqdn2 = argv[3]; + port2 = atoi(argv[4]); + } + + if (!((argc == 3) || (argc == 5))) + { + fprintf(stderr, "Usage: %s <FQDN>|<IP address> <port> <FQDN>|<IP address> <port> \n", argv[0]); + fprintf(stderr, "OR\n"); + fprintf(stderr, "Usage: %s <FQDN>|<IP address> <port> \n", argv[0]); + exit(-1); + } + + /**************************************************************************/ + /* Initialize */ + /**************************************************************************/ + if(evel_initialize(fqdn, /* FQDN */ + port, /* Port */ + fqdn2, /* Backup FQDN */ + port2, /* Backup port */ + NULL, /* optional path */ + NULL, /* optional topic */ + 100, /* Ring Buffer size */ + 0, /* HTTPS? */ + NULL, /* cert file */ + NULL, /* key file */ + NULL, /* ca info */ + NULL, /* ca file */ + 0, /* verify peer */ + 0, /* verify host */ + "sample1", /* Username */ + "sample1", /* Password */ + "sample1", /* Username2 */ + "sample1", /* Password2 */ + NULL, /* Source ip */ + NULL, /* Source ip2 */ + EVEL_SOURCE_VIRTUAL_MACHINE, /* Source type */ + "vHeartbeat", /* Role */ + 1)) /* Verbosity */ + { + fprintf(stderr, "\nFailed to initialize the EVEL library!!!\n"); + exit(-1); + } + else + { + printf("\nInitialization completed\n"); + } + + /* Initialize and set thread detached attribute */ + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + printf("Main:Creating thread \n"); + rc = pthread_create(&hb_thread, NULL, HeartbeatThread, &i); + if (rc) + { + printf("ERROR; return code from pthread_create() is %d\n", rc); + exit(-1); + } + printf("Main:Created HB thread \n"); + + pthread_join(hb_thread, NULL); + + evel_terminate(); + printf("Terminated\n"); + return 0; +} + +void *HeartbeatThread(void *threadarg) +{ + + EVENT_HEARTBEAT_FIELD * event = NULL; + EVENT_HEADER* hb_header = NULL; + EVEL_ERR_CODES evel_rc = EVEL_SUCCESS; + + int numToken; + jsmntok_t tokens[MAX_TOKENS]; + char js[MAX_BUFFER_SIZE]; + + jsmn_parser p; + char ch[BUFSIZE]; + int ret = 0; + char stringVal[BUFSIZE]; + char eName[BUFSIZE]; + int hb_interval; + + char event_id1[10] = "heartbeat"; + char event_id2[15] = {0}; + int event_id3 = 0; + char event_id[BUFSIZE] = {0}; + + sleep(1); + printf("Running HB thread \n"); + fflush(stdout); + + while(1) + { + + FILE * file = fopen("hb_config.json", "r"); + + memset(js, 0, MAX_BUFFER_SIZE); + memset(ch, 0, BUFSIZE); + + while((fgets(ch, (BUFSIZE-1), file)) !=NULL) + { + strcat(js, ch); + memset(ch, 0, BUFSIZE); + } +// printf("the file content is \n %s \n", js); + + jsmn_init(&p); + numToken = jsmn_parse(&p, js, strlen(js), tokens, MAX_TOKENS); + printf("Token count-%d\n", numToken); + +// printToken(js,tokens, numToken); + + ret = getStringToken(js, tokens, numToken, "eventName", "tmp_directParameters", eName, BUFSIZE); + if (ret != 0) + { + printf("Missing mandatory parameters - eventName is not there in tmp_directParameters. Exiting...\n"); + exit(1); + } + + ret = getIntToken(js, tokens, numToken, "heartbeatInterval", "tmp_directParameters", &hb_interval); + if (ret != 0) + { + printf("The parameter heartbeatInterval is not defined, defaulted to 60 seconds\n"); + hb_interval = 60; + } + + /***************************************************************************/ + /* Heartbeat */ + /***************************************************************************/ + memset(event_id, 0, BUFSIZE); + memset(event_id2, 0, 15); + sprintf(event_id2, "%09d", event_id3++); + strcat(event_id, event_id1); + strcat(event_id, event_id2); + + event = evel_new_heartbeat_field(hb_interval, eName, event_id); + if (event != NULL) + { + hb_header = (EVENT_HEADER *)event; + + ret = getStringToken(js, tokens, numToken, "eventType", "tmp_directParameters", stringVal, BUFSIZE); + if (ret == 0) + { + evel_header_type_set(&event->header, stringVal); + } + + struct timeval tv_now; + gettimeofday(&tv_now, NULL); + unsigned long long epoch_now = tv_now.tv_usec + 1000000 * tv_now.tv_sec; + + evel_start_epoch_set(&event->header, epoch_start); + evel_last_epoch_set(&event->header, epoch_now); + epoch_start = epoch_now; + + ret = getStringToken(js, tokens, numToken, "nfcNamingCode", "tmp_directParameters", stringVal, BUFSIZE); + if (ret == 0) + evel_nfcnamingcode_set(&event->header, stringVal); + + ret = getStringToken(js, tokens, numToken, "nfNamingCode", "tmp_directParameters", stringVal, BUFSIZE); + if (ret == 0) + evel_nfnamingcode_set(&event->header, stringVal); + + ret = getStringToken(js, tokens, numToken, "reportingEntityName", "tmp_directParameters", stringVal, BUFSIZE); + if (ret == 0) + evel_reporting_entity_name_set(&event->header, stringVal); + else + { + printf("Missing mandatory parameters - reportingEntityName is not there in tmp_directParameters\n"); + printf("Defaulting reportingEntityName to hostname\n"); + } + + ret = getStringToken(js, tokens, numToken, "reportingEntityId", "tmp_directParameters", stringVal, BUFSIZE); + if (ret == 0) + evel_reporting_entity_id_set(&event->header, stringVal); + + ret = getStringToken(js, tokens, numToken, "sourceId", "tmp_directParameters", stringVal, BUFSIZE); + if (ret == 0) + evel_source_id_set(&event->header, stringVal); + + ret = getStringToken(js, tokens, numToken, "sourceName", "tmp_directParameters", stringVal, BUFSIZE); + if (ret == 0) + evel_source_name_set(&event->header, stringVal); + else + { + printf("Missing mandatory parameters - sourceName is not there in tmp_directParameters\n"); + printf("Defaulting sourceName to hostname\n"); + } + + evel_rc = evel_post_event(hb_header); + if (evel_rc != EVEL_SUCCESS) + { + EVEL_ERROR("Post failed %d (%s)", evel_rc, evel_error_string()); + } + } + else + { + EVEL_ERROR("New Heartbeat failed"); + } + printf(" Processed Heartbeat\n"); + + sleep(hb_interval); + } +} diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/LICENSE.TXT b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/LICENSE.TXT new file mode 100644 index 0000000..16285cd --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/LICENSE.TXT @@ -0,0 +1,22 @@ +/* + * ============LICENSE_START========================================== + * =================================================================== + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Unless otherwise specified, all software contained herein is + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + * + * ECOMP is trademark and service mark of AT&T Intellectual Property. + * + */ diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/Makefile b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/Makefile new file mode 100644 index 0000000..4837c7d --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/Makefile @@ -0,0 +1,52 @@ +############################################################################# +# +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +############################################################################# + +CC=gcc +ARCH=$(shell getconf LONG_BIT) +CODE_ROOT=$(CURDIR)/../.. +#CODE_ROOT=../code/evel-library +LIBS_DIR=$(CODE_ROOT)/libs/x86_$(ARCH) +#LIBS_DIR=/usr/lib +INCLUDE_DIR= -I $(CODE_ROOT)/code/evel_library -I . + +#****************************************************************************** +# Standard compiler flags. * +#****************************************************************************** +CPPFLAGS= +CFLAGS=-Wall -g -fPIC +FILEOBJLIST= jsmn.o ves_fault_reporter.o + +all: ves_fault_reporter + +clean: + rm -f *.o ves_fault_reporter + +%.o: %.c + $(CC) $(CPPFLAGS) $(CFLAGS) $(INCLUDE_DIR) -c $< -o $@ + +jsmn.o: jsmn.c jsmn.h +ves_fault_reporter.o: ves_fault_reporter.c + +ves_fault_reporter: $(FILEOBJLIST) + $(CC) $(CPPFLAGS) $(CFLAGS) -o ves_fault_reporter \ + -L $(LIBS_DIR) \ + $(FILEOBJLIST) \ + -lpthread \ + -level \ + -lcurl + + diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/README.md b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/README.md new file mode 100644 index 0000000..5a7ea41 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/README.md @@ -0,0 +1,37 @@ + +PROJECT DESCRIPTION + +--- +This project contains the source code and scripts for the generation of fault events. The folder contains: + + - README.md: this file. + + - LICENSE.TXT: the license text. + + - ves_fault_reporter.c and other .c files: source code that uses the ECOMP Vendor Event Listener Library (VES) to generate the fault events. Fault is generated based on the link status. If number of bytes transmitted/received is less than the low water mark, the fault is generated. The application reads flt_config.json file for parameter values and poppulate the fault event. If eventName, eventSourceType, vfStatus, specificProblem or alarmCondition parameter value is not given, the application terminates. If reportingEntityName and sourceName parameter values are not given, then it gets the hostname and poppulates it. If tmp_faultCheckInterval is not given, it defaults to 60 seconds. + + - Makefile: makefile that compiles ves_fault_reporter.c and generates ves_fault_reporter binary. + + - go-client.sh/go-client_2_collectors.sh: bash script that starts up the ves_fault_reporter. It reads input parameters like DCAE IP address and port from configuration files contained in /opt/config. Based on the collector configuration, use go-client.sh for single collector configuration, or use go-client_2_collectors.sh for 2 collectors configuration. + + +USAGE +----- + +Update the configuration files with proper parameters values so that events generated would contain those values + +To run the ves_fault_reporter in single collector configuration, please execute the following steps: + + - Make the go-client.sh script executable + chmod +x go-client.sh + + - Run the go-client.sh script + ./go-client.sh + +For 2 collectors configuration, please execute following steps: + + - Make the go-client.sh script executable + chmod +x go-client_2_collectors.sh + + - Run the go-client_2_collectors.sh script + ./go-client_2_collectors.sh diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/dep.xml b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/dep.xml new file mode 100644 index 0000000..fc18229 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/dep.xml @@ -0,0 +1,25 @@ +<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd"> + <id>demo</id> + <formats> + <format>tar.gz</format> + </formats> + <fileSets> + + <fileSet> + <directory>.</directory> + <outputDirectory>/</outputDirectory> + <includes> + <include>*.sh</include> + <include>*.md</include> + <include>*.TXT</include> + <include>*.c</include> + <include>Makefile</include> + </includes> + </fileSet> + + </fileSets> +</assembly> + + diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/flt_config.json b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/flt_config.json new file mode 100644 index 0000000..90654ef --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/flt_config.json @@ -0,0 +1,71 @@ +{ + "tmp_directParameters": { + "eventType": "applicationVnf", + "nfcNamingCode": "AFX", + "nfNamingCode": "AFX", + "priority": "Low", + "reportingEntityId": "cc305d54-75b4-431b-adb2-eb6b9e541234", + "reportingEntityName": "ibcx0001vm002oam001", + "sourceId": "de305d54-75b4-431b-adb2-eb6b9e546014", + "sourceName": "scfx0001vm002cap001", + "vfStatus": "Idle", + "tmp_device": ["lo", "enp0s3", "docker0"] + + }, + "tmp_indirectParameters": [ + "tmp_faultInstance01": { + "eventName": "Fault_vFirewall-AT&T_linkDownError", + "eventCategory": "link", + "eventSourceType": "router", + "tmp_init":{ + "tmp_t0BytesIn": "sudo cat /proc/net/dev | grep $tmp_device | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f2", + "tmp_t0BytesOut": "sudo cat /proc/net/dev | grep $tmp_device | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f10", + "tmp_t0PacketsIn": "sudo cat /proc/net/dev | grep $tmp_device | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f3", + "tmp_t0PacketsOut": "sudo cat /proc/net/dev | grep $tmp_device | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f11" + }, + "alarmInterfaceA": "$tmp_device", + "tmp_faultCheckInterval": 20, + "tmp_lowWaterMark": 100, + "tmp_command": { + "tmp_t1BytesIn": "sudo cat /proc/net/dev | grep $tmp_device | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f2", + "tmp_t1BytesOut": "sudo cat /proc/net/dev | grep $tmp_device | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f10", + "tmp_t1PacketsIn": "sudo cat /proc/net/dev | grep $tmp_device | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f3", + "tmp_t1PacketsOut": "sudo cat /proc/net/dev | grep $tmp_device | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f11" + }, + "tmp_BytesIn": "$(tmp_t1BytesIn - tmp_t0BytesIn)", + "tmp_PacketsIn": "$(tmp_t1PacketsIn - tmp_t0PacketsIn)", + "tmp_BytesOut": "$(tmp_t1BytesOut - tmp_t0BytesOut)", + "tmp_PacketsOut": "$(tmp_t1PacketsOut - tmp_t0PacketsOut)", + "tmp_alarmSetParameters": { + "specificProblem": "physical or logical connection to a remote router is down", + "eventSeverity": "MAJOR", + "alarmCondition": "link down trap_alarm" + }, + "tmp_alarmClearParameters": { + "specificProblem": "physical or logical connection to a remote router is up", + "eventSeverity": "NORMAL", + "alarmCondition": "link up trap_alarm" + } + }, + "tmp_faultInstance02": { + "eventName": "Fault_vFirewall-AT&T_serviceDownError", + "alarmInterfaceA": "afx@input.service", + "eventCategory": "other", + "eventSourceType": "virtualMachine", + "tmp_faultCheckInterval": 10, + "tmp_command": { + "tmp_cmd1": "/bin/systemctl is-active afx@input* |grep -E 'inactive|failed' | wc -l" + }, + "tmp_alarmSetParameters": { + "specificProblem": "service is down", + "eventSeverity": "MAJOR", + "alarmCondition": "service down trap_alarm" + }, + "tmp_alarmClearParameters": { + "specificProblem": "service is up", + "eventSeverity": "NORMAL", + "alarmCondition": "service up trap_alarm" + } + } + ] +} diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/go-client.sh b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/go-client.sh new file mode 100755 index 0000000..5a59882 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/go-client.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +export LD_LIBRARY_PATH="/opt/VES/evel/evel-library/libs/x86_64/" +DCAE_COLLECTOR_IP=$(cat /opt/config/dcae_collector_ip.txt) +DCAE_COLLECTOR_PORT=$(cat /opt/config/dcae_collector_port.txt) +./ves_fault_reporter $DCAE_COLLECTOR_IP $DCAE_COLLECTOR_PORT diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/go-client_2_collectors.sh b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/go-client_2_collectors.sh new file mode 100755 index 0000000..09d65f0 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/go-client_2_collectors.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +export LD_LIBRARY_PATH="/opt/VES/evel/evel-library/libs/x86_64/" + +#Usage for 2 collectors: +#./ves_fault_reporter <FQDN>|<IP address> <port> <FQDN>|<IP address> <port> + +DCAE_COLLECTOR_IP=$(cat /opt/config/dcae_collector_ip.txt) +DCAE_COLLECTOR_PORT=$(cat /opt/config/dcae_collector_port.txt) +DCAE_COLLECTOR_IP2=$(cat /opt/config/dcae_collector_ip2.txt) +DCAE_COLLECTOR_PORT2=$(cat /opt/config/dcae_collector_port2.txt) +./ves_fault_reporter $DCAE_COLLECTOR_IP $DCAE_COLLECTOR_PORT $DCAE_COLLECTOR_IP2 $DCAE_COLLECTOR_PORT2 diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/jsmn.c b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/jsmn.c new file mode 100644 index 0000000..1d72ba4 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/jsmn.c @@ -0,0 +1,672 @@ +/*************************************************************************//** + * + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * + * Unless otherwise specified, all software contained herein is + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + ****************************************************************************/ +#include<stdio.h> +#include<stdlib.h> +#include<string.h> +#include "jsmn.h" + +/** + * Allocates a fresh unused token from the token pull. + */ +static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser, + jsmntok_t *tokens, size_t num_tokens) { + jsmntok_t *tok; + if (parser->toknext >= num_tokens) { + return NULL; + } + tok = &tokens[parser->toknext++]; + tok->start = tok->end = -1; + tok->size = 0; +//#ifdef JSMN_PARENT_LINKS + tok->parent = -1; +//#endif + return tok; +} + +/** + * Fills token type and boundaries. + */ +static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type, + int start, int end) { +//printf("jsmn_fill_token:: start-%d, end-%d\n", start, end); + token->type = type; + token->start = start; + token->end = end; + token->size = 0; +} + +/** + * Fills next available token with JSON primitive. + */ +static int jsmn_parse_primitive(jsmn_parser *parser, const char *js, + size_t len, jsmntok_t *tokens, size_t num_tokens) { + jsmntok_t *token; + int start; + + start = parser->pos; + + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { +//printf("jsmn_parse_primitive:: the char is - %c\n", js[parser->pos]); + switch (js[parser->pos]) { +#ifndef JSMN_STRICT + /* In strict mode primitive must be followed by "," or "}" or "]" */ + case ':': +#endif + case '\t' : case '\r' : case '\n' : case ' ' : + case ',' : case ']' : case '}' : + goto found; + } + if (js[parser->pos] < 32 || js[parser->pos] >= 127) { + parser->pos = start; + return JSMN_ERROR_INVAL; + } + } +#ifdef JSMN_STRICT + /* In strict mode primitive must be followed by a comma/object/array */ + parser->pos = start; + return JSMN_ERROR_PART; +#endif + +found: + if (tokens == NULL) { + parser->pos--; + return 0; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); + if (token == NULL) { + parser->pos = start; + return JSMN_ERROR_NOMEM; + } + jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos); +//#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +//#endif + parser->pos--; + return 0; +} + +/** + * Fills next token with JSON string. + */ +static int jsmn_parse_string(jsmn_parser *parser, const char *js, + size_t len, jsmntok_t *tokens, size_t num_tokens) { + jsmntok_t *token; + + int start = parser->pos; + + parser->pos++; + + /* Skip starting quote */ + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { + char c = js[parser->pos]; + char d = js[parser->pos + 1]; +// char e = js[parser->pos + 2]; +//printf("jsmn_parse_string: value-%c, pos-%d\n", c,parser->pos); + + /* Quote: end of string */ +// if (c == '\"') { + if (d == '\"') { +// if ((d == '\"')&&((e == ' ')||(e == ','))) { +parser->pos++; +//printf("jsmn_parse_string: end of string\n"); + if (tokens == NULL) { +//printf("jsmn_parse_string: end tokens is NULL\n"); + return 0; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); +//printf("jsmn_parse_string: Allocated tokens \n"); + if (token == NULL) { +//printf("jsmn_parse_string: Allocated tokens is NULL\n"); + parser->pos = start; + return JSMN_ERROR_NOMEM; + } + jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos); +//printf("jsmn_parse_string: Allocated tokens is filled\n"); +//#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +//#endif + return 0; + } + + /* Backslash: Quoted symbol expected */ + if (c == '\\' && parser->pos + 1 < len) { + int i; + parser->pos++; +//printf("jsmn_parse_string: value - %c, POS-%3d \n",c, js[parser->pos]); + switch (js[parser->pos]) { + /* Allowed escaped symbols */ + case '\"': case '/' : case '\\' : case 'b' : + case 'f' : case 'r' : case 'n' : case 't' : + break; + /* Allows escaped symbol \uXXXX */ + case 'u': + parser->pos++; + for(i = 0; i < 4 && parser->pos < len && js[parser->pos] != '\0'; i++) { + /* If it isn't a hex character we have an error */ + if(!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */ + (js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */ + (js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */ + parser->pos = start; + return JSMN_ERROR_INVAL; + } + parser->pos++; + } + parser->pos--; + break; + /* Unexpected symbol */ + default: + parser->pos = start; + return JSMN_ERROR_INVAL; + } + } + } + parser->pos = start; +printf("jsmn_parse_string: exiting with ERROR_PART, pos-%d", parser->pos); + return JSMN_ERROR_PART; +} + +/** + * Parse JSON string and fill tokens. + */ +int jsmn_parse(jsmn_parser *parser, const char *js, size_t len, + jsmntok_t *tokens, unsigned int num_tokens) { + int r; + int i; + jsmntok_t *token; + int count = parser->toknext; + + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { + char c; + jsmntype_t type; + + c = js[parser->pos]; +//printf("jsmn_parse: value of c - %c\n",c); + switch (c) { + case '{': case '[': + count++; + if (tokens == NULL) { + break; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); + if (token == NULL) + return JSMN_ERROR_NOMEM; + if (parser->toksuper != -1) { + tokens[parser->toksuper].size++; +//#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +//#endif + } + token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY); + token->start = parser->pos; + parser->toksuper = parser->toknext - 1; + break; + case '}': case ']': + if (tokens == NULL) + break; + type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY); +//#ifdef JSMN_PARENT_LINKS + if (parser->toknext < 1) { + return JSMN_ERROR_INVAL; + } + token = &tokens[parser->toknext - 1]; + for (;;) { + if (token->start != -1 && token->end == -1) { + if (token->type != type) { + return JSMN_ERROR_INVAL; + } + token->end = parser->pos + 1; + parser->toksuper = token->parent; + break; + } + if (token->parent == -1) { + break; + } + token = &tokens[token->parent]; + } +//#else +// for (i = parser->toknext - 1; i >= 0; i--) { +// token = &tokens[i]; +// if (token->start != -1 && token->end == -1) { +// if (token->type != type) { +// return JSMN_ERROR_INVAL; +// } +// parser->toksuper = -1; +// token->end = parser->pos + 1; +// break; +// } +// } +// /* Error if unmatched closing bracket */ +// if (i == -1) return JSMN_ERROR_INVAL; +// for (; i >= 0; i--) { +// token = &tokens[i]; +// if (token->start != -1 && token->end == -1) { +// parser->toksuper = i; +// break; +// } +// } +//#endif + break; + case '\"': + r = jsmn_parse_string(parser, js, len, tokens, num_tokens); + if (r < 0) return r; + count++; + if (parser->toksuper != -1 && tokens != NULL) + tokens[parser->toksuper].size++; + break; + case '\t' : case '\r' : case '\n' : case ' ': + break; + case ':': + parser->toksuper = parser->toknext - 1; +//printf("jsmn_parse: value of c is :: - %c\n",c); + break; + case ',': + if (tokens != NULL && parser->toksuper != -1 && + tokens[parser->toksuper].type != JSMN_ARRAY && + tokens[parser->toksuper].type != JSMN_OBJECT) { +//#ifdef JSMN_PARENT_LINKS + parser->toksuper = tokens[parser->toksuper].parent; +//#else +// for (i = parser->toknext - 1; i >= 0; i--) { +// if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) { +// if (tokens[i].start != -1 && tokens[i].end == -1) { +// parser->toksuper = i; +// break; +// } +// } +// } +//#endif + } + break; +#ifdef JSMN_STRICT + /* In strict mode primitives are: numbers and booleans */ + case '-': case '0': case '1' : case '2': case '3' : case '4': + case '5': case '6': case '7' : case '8': case '9': + case 't': case 'f': case 'n' : + /* And they must not be keys of the object */ + if (tokens != NULL && parser->toksuper != -1) { + jsmntok_t *t = &tokens[parser->toksuper]; + if (t->type == JSMN_OBJECT || + (t->type == JSMN_STRING && t->size != 0)) { + return JSMN_ERROR_INVAL; + } + } +#else + /* In non-strict mode every unquoted value is a primitive */ + default: +#endif + r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens); + if (r < 0) return r; + count++; + if (parser->toksuper != -1 && tokens != NULL) + tokens[parser->toksuper].size++; + break; + +#ifdef JSMN_STRICT + /* Unexpected char in strict mode */ + default: + return JSMN_ERROR_INVAL; +#endif + } + } + + if (tokens != NULL) { + for (i = parser->toknext - 1; i >= 0; i--) { +//printf("index -%2d, start is %3d, end is %3d\n", i, tokens[i].start, tokens[i].end); + /* Unmatched opened object or array */ + if (tokens[i].start != -1 && tokens[i].end == -1) { + return JSMN_ERROR_PART; + } + } + } + + return count; +} + +/** + * Creates a new parser based over a given buffer with an array of tokens + * available. + */ +void jsmn_init(jsmn_parser *parser) { + parser->pos = 0; + parser->toknext = 0; + parser->toksuper = -1; +} + +int jsoneq(const char *json, jsmntok_t *tok, const char *s) +{ + if (tok->type == JSMN_STRING && (int) strlen(s) == tok->end - tok->start && + strncmp(json + tok->start, s, tok->end - tok->start) == 0) { + return 0; + } + return -1; +} + +void printToken(char * js, jsmntok_t * tokens, int numToken) +{ + for (int i = 1; i < numToken; i++) + { + printf("Token number-%2d, parent-%2d, type-%d size-%2d, parameter -", i, tokens[i].parent, tokens[i].type, tokens[i].size); + if (tokens[i].type == JSMN_STRING || tokens[i].type == JSMN_PRIMITIVE) { + printf("%.*s\n", tokens[i].end - tokens[i].start, js + tokens[i].start); + } else if (tokens[i].type == JSMN_ARRAY) { + printf("[%d elems]\n", tokens[i].size); + } else if (tokens[i].type == JSMN_OBJECT) { + printf("{%d elems}\n", tokens[i].size); + } else { + printf("value?? - "); + TOKEN_PRINT(tokens[i]); + } + } +} + +int getStringToken(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, char * value, int maxValueSize) +{ + int i = 0; + int dpToken = 0; + + memset(value, 0, maxValueSize); + + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], pParam) == 0) + break; + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 1; //Parent token not seen + } + for (i=1; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { + if(jsoneq(js, &tokens[i], param) != 0) + continue; + TOKEN_COPY(js, tokens[i+1], value); + + return 0; //Success + } + } + printf("The parameter %s is not present in JSON file\n", param); + return 2; //parameter not found +} + + +int getStringTokenV2(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, char * gParam,char * value, int maxValueSize) +{ + int i = 0; + int dpToken = 0; + + memset(value, 0, maxValueSize); + + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], gParam) == 0) + break; + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 1; //Grand Parent token not seen + } + + for (i=dpToken; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { + if(jsoneq(js, &tokens[i], pParam) == 0) + break; + } + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 2; //Parent token not seen + } + + for (i=dpToken; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { + if(jsoneq(js, &tokens[i], param) != 0) + continue; + TOKEN_COPY(js, tokens[i+1], value); + + return 0; //Success + } + } + + printf("The parameter %s is not present in JSON file\n", param); + return 2; //parameter not found +} + +int getIntToken(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, int * value) +{ + int i = 0; + int dpToken = 0; + char val[128]; + + memset(val, 0, 128); + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], pParam) == 0) + break; + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 1; //Parent token not seen + } + for (i=1; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { + if(jsoneq(js, &tokens[i], param) != 0) + { + continue; + } + + if(tokens[i+1].type != JSMN_PRIMITIVE) + return 3; //Wrong parameter type + +// printf("INT parameter / Value - %s", param); + TOKEN_COPY(js, tokens[i+1], val); + *value = atoi(val); +// printf(" - %d\n", *value); + + return 0; //success + } + } + printf("The parameter %s is not present in JSON file\n", param); + return 2; //parameter not found +} + +void parseDirectParameters(char * js, jsmntok_t * tokens, int numToken) +{ + int i = 0; + int dpToken = 0; + char param[128]; + char value[128]; + + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], "directParameters") == 0) + break; + } + + if (i < numToken) + { + dpToken = ++i; + } + + for (int i = 1; i < numToken; i++) + { + memset(param, 0, 128); + memset(value, 0, 128); + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { + TOKEN_COPY(js, tokens[i], param); +// printf("parameter / Value - %s", param); + TOKEN_COPY(js, tokens[i+1], value); +// printf(" - %s\n", value); + } + } +} + +int getArrayTokens(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, ARRAYVAL * arrayValue, int * numElements) +{ + int i = 0; + int dpToken = 0; + + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], pParam) == 0) + break; + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 1; //Parent token not seen + } + for (i=1; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { +// printf("value of token %d\n", i); + if(jsoneq(js, &tokens[i], param) != 0) + continue; + + if (tokens[i+1].type == JSMN_ARRAY) + { + *numElements = tokens[i+1].size; +// printf("[%d elems]\n", *numElements); + + for (int k = 0; k < *numElements; k++) + { + TOKEN_COPY(js, tokens[i+2+k], arrayValue[k].arrayString); +// printf(" - %s\n", arrayValue[k].arrayString); + } + return 0; //Success + } + } + } + printf("The parameter %s is not present in JSON file\n", param); + return 2; //parameter not found +} + +int isTokenPresent(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam) +{ + int i = 0; + int dpToken = 0; + char val[128]; + + memset(val, 0, 128); + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], pParam) == 0) + break; + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 1; //Parent token not seen + } + for (i=1; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING) + { + if(jsoneq(js, &tokens[i], param) == 0) + { + return 0; //Token present + } + } + } + printf("The parameter %s is not present in JSON file\n", param); + return 2; //Token Not present +} + +int read_keyVal_params(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, KEYVALRESULT * keyValueResultList, int * numElements) +{ + int i = 0; + int dpToken = 0; + + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], pParam) == 0) + break; + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 1; //Parent token not seen + } + for (i=1; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { +// printf("value of token %d\n", i); + if(jsoneq(js, &tokens[i], param) != 0) + continue; + + if (tokens[i+1].type == JSMN_OBJECT) + { + *numElements = tokens[i+1].size; +// printf("{%d elems}\n", *numElements); + + for (int k = 0; k < *numElements; k++) + { + TOKEN_COPY(js, tokens[i+2+k*2], keyValueResultList[k].keyStr); +// printf("Key - %s", keyValueResultList[k].keyStr); + TOKEN_COPY(js, tokens[i+3+k*2], keyValueResultList[k].valStr); +// printf("Value - %s\n", keyValueResultList[k].valStr); + } + return 0; //Success + } + } + } + printf("The parameter %s is not present in JSON file\n", param); + return 2; //parameter not found +} diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/jsmn.h b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/jsmn.h new file mode 100644 index 0000000..f9d838b --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/jsmn.h @@ -0,0 +1,136 @@ +/*************************************************************************//** + * + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ + +#ifndef __JSMN_H_ +#define __JSMN_H_ + +#include <stddef.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * JSON type identifier. Basic types are: + * o Object + * o Array + * o String + * o Other primitive: number, boolean (true/false) or null + */ +typedef enum { + JSMN_UNDEFINED = 0, + JSMN_OBJECT = 1, + JSMN_ARRAY = 2, + JSMN_STRING = 3, + JSMN_PRIMITIVE = 4 +} jsmntype_t; + +enum jsmnerr { + /* Not enough tokens were provided */ + JSMN_ERROR_NOMEM = -1, + /* Invalid character inside JSON string */ + JSMN_ERROR_INVAL = -2, + /* The string is not a full JSON packet, more bytes expected */ + JSMN_ERROR_PART = -3 +}; + +typedef struct arrayValues { + char arrayString[32]; +} ARRAYVAL; + +typedef struct keyValResult { + char keyStr[80]; + char valStr[250]; + char resultStr[80]; +} KEYVALRESULT; + +/** + * JSON token description. + * @param type type (object, array, string etc.) + * @param start start position in JSON data string + * @param end end position in JSON data string + */ +typedef struct { + jsmntype_t type; + int start; + int end; + int size; +//#ifdef JSMN_PARENT_LINKS + int parent; +//#endif +} jsmntok_t; + +/** + * JSON parser. Contains an array of token blocks available. Also stores + * the string being parsed now and current position in that string + */ +typedef struct { + unsigned int pos; /* offset in the JSON string */ + unsigned int toknext; /* next token to allocate */ + int toksuper; /* superior token node, e.g parent object or array */ +} jsmn_parser; + +#define TOKEN_EQ(t, tok_start, tok_end, tok_type) \ + ((t).start == tok_start \ + && (t).end == tok_end \ + && (t).type == (tok_type)) + +#define TOKEN_STRING(js, t, s) \ + (strncmp(js+(t).start, s, (t).end - (t).start) == 0 \ + && strlen(s) == (t).end - (t).start) + +#define TOKEN_COPY(js, t, s) \ + strncpy(s, js+(t).start, (t).end - (t).start) + +#define TOKEN_PRINT(t) \ + printf("start: %d, end: %d, type: %d, size: %d\n", \ + (t).start, (t).end, (t).type, (t).size) + + +/** + * Create JSON parser over an array of tokens + */ +void jsmn_init(jsmn_parser *parser); + +/** + * Run JSON parser. It parses a JSON data string into and array of tokens, each describing + * a single JSON object. + */ +int jsmn_parse(jsmn_parser *parser, const char *js, size_t len, + jsmntok_t *tokens, unsigned int num_tokens); + +int jsoneq(const char *json, jsmntok_t *tok, const char *s); + +void printToken(char * js, jsmntok_t * tokens, int numToken); + +int getStringToken(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, char * value, int maxValueSize); + +int getIntToken(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, int * value); + +int getArrayTokens(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, ARRAYVAL * arrayValue, int * numElements); + +int isTokenPresent(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam); + +int read_keyVal_params(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, KEYVALRESULT * keyValueResultList, int * numElements); + +int getStringTokenV2(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, char *gParam, char * value, int maxValueSize); + +#ifdef __cplusplus +} +#endif + +#endif /* __JSMN_H_ */ diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/pom.xml b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/pom.xml new file mode 100644 index 0000000..f9f42eb --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/pom.xml @@ -0,0 +1,83 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START========================================== + =================================================================== + Copyright © 2017 AT&T Intellectual Property. All rights reserved. + =================================================================== + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ============LICENSE_END============================================ + + ECOMP and OpenECOMP are trademarks + and service marks of AT&T Intellectual Property. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + +<parent> + <groupId>org.onap.demo.vnf</groupId> + <artifactId>demo-aggregator</artifactId> + <version>1.2.0-SNAPSHOT</version> + <relativePath>../../pom.xml</relativePath> + </parent> + + <modelVersion>4.0.0</modelVersion> + <groupId>org.onap.demo.vnf.ves5</groupId> + <artifactId>ves_vfw_reporting</artifactId> + + <build> + <plugins> + + <plugin> + <artifactId>maven-jar-plugin</artifactId> + <version>2.3.2</version> + <executions> + <execution> + <id>default-jar</id> + <phase>never</phase> + </execution> + </executions> + </plugin> + + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <version>2.5.3</version> + <configuration> + <descriptor>dep.xml</descriptor> + </configuration> + <executions> + <execution> + <id>create-archive</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>exec-maven-plugin</artifactId> + <executions> + <execution> + <phase>none</phase> + </execution> + </executions> + <configuration> + <skip>true</skip> + </configuration> + </plugin> + + </plugins> + </build> + +</project> diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/sample_fault_events.txt b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/sample_fault_events.txt new file mode 100644 index 0000000..516d101 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/sample_fault_events.txt @@ -0,0 +1,98 @@ +{ + "event": { + "commonEventHeader": { + "domain": "fault", + "eventId": "fault000000001", + "eventName": "Fault_vFirewall-AT&T_linkDownError", + "eventType": "applicationVnf", + "lastEpochMicrosec": 1548491713599115, + "nfNamingCode": "AFX", + "nfcNamingCode": "AFX", + "priority": "Low", + "reportingEntityId": "cc305d54-75b4-431b-adb2-eb6b9e541234", + "reportingEntityName": "ibcx0001vm002oam001", + "sequence": 1, + "sourceId": "de305d54-75b4-431b-adb2-eb6b9e546014", + "sourceName": "scfx0001vm002cap001", + "startEpochMicrosec": 1548491713599115, + "version": 3.0 + }, + "faultFields": { + "alarmCondition": "link down trap_alarm", + "alarmInterfaceA": "docker0", + "eventCategory": "link", + "eventSeverity": "MAJOR", + "eventSourceType": "router", + "faultFieldsVersion": 2.0, + "specificProblem": "physical or logical connection to a remote router is down", + "vfStatus": "Idle" + } + } +} +=================================== + +{ + "event": { + "commonEventHeader": { + "domain": "fault", + "eventId": "fault000000001", + "eventName": "Fault_vFirewall-AT&T_serviceDownError", + "eventType": "applicationVnf", + "lastEpochMicrosec": 1548491702433326, + "nfNamingCode": "AFX", + "nfcNamingCode": "AFX", + "priority": "Low", + "reportingEntityId": "cc305d54-75b4-431b-adb2-eb6b9e541234", + "reportingEntityName": "ibcx0001vm002oam001", + "sequence": 1, + "sourceId": "de305d54-75b4-431b-adb2-eb6b9e546014", + "sourceName": "scfx0001vm002cap001", + "startEpochMicrosec": 1548491702433326, + "version": 3.0 + }, + "faultFields": { + "alarmCondition": "service down trap_alarm", + "alarmInterfaceA": "afx@input.service", + "eventCategory": "other", + "eventSeverity": "MAJOR", + "eventSourceType": "virtualMachine", + "faultFieldsVersion": 2.0, + "specificProblem": "service is down", + "vfStatus": "Idle" + } + } +} + +========================== +{ + "event": { + "commonEventHeader": { + "domain": "fault", + "eventId": "fault000000001", + "eventName": "Fault_vFirewall-AT&T_linkDownError", + "eventType": "applicationVnf", + "lastEpochMicrosec": 1548491569186353, + "nfNamingCode": "AFX", + "nfcNamingCode": "AFX", + "priority": "Low", + "reportingEntityId": "cc305d54-75b4-431b-adb2-eb6b9e541234", + "reportingEntityName": "ibcx0001vm002oam001", + "sequence": 0, + "sourceId": "de305d54-75b4-431b-adb2-eb6b9e546014", + "sourceName": "scfx0001vm002cap001", + "startEpochMicrosec": 1548491548714540, + "version": 3.0 + }, + "faultFields": { + "alarmCondition": "link up trap_alarm", + "alarmInterfaceA": "lo", + "eventCategory": "link", + "eventSeverity": "NORMAL", + "eventSourceType": "router", + "faultFieldsVersion": 2.0, + "specificProblem": "physical or logical connection to a remote router is up", + "vfStatus": "Idle" + } + } +} + diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/ves_fault_reporter.c b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/ves_fault_reporter.c new file mode 100644 index 0000000..3757d17 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_fault/ves_fault_reporter.c @@ -0,0 +1,1328 @@ +/*************************************************************************//** + * + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <pthread.h> +#include <string.h> +#include <netdb.h> +#include <sys/time.h> +#include <sys/stat.h> +#include "jsmn.h" +#include "evel.h" + +#define BUFSIZE 128 +#define MAX_BUFFER_SIZE 4096 +#define MAX_TOKENS 1000 +#define MAX_INTERFACES 40 + +void *FaultThread(void *threadarg); +void *FaultThread01(void *threadarg); +void *FaultThread02(void *threadarg); +void *FaultThread03(void *threadarg); + +typedef struct dummy_vpp_metrics_struct { + int curr_bytes_in; + int curr_bytes_out; + int curr_packets_in; + int curr_packets_out; + int last_bytes_in; + int last_bytes_out; + int last_packets_in; + int last_packets_out; +} vpp_metrics_struct; + +typedef struct linkstat { + + char linkname[32]; + char linkdescr[64]; + char linkmode[64]; + int speedmbps; + int fault_raised; + unsigned long long last_epoch; + +}LINKSTAT; + +//vpp_metrics_struct meas_intfstat[MAX_INTERFACES]; +//LINKSTAT meas_linkstat[MAX_INTERFACES]; +//int request_rate=0; +vpp_metrics_struct fault_intfstat[MAX_INTERFACES]; +LINKSTAT fault_linkstat[MAX_INTERFACES]; + +unsigned long long epoch_start = 0; + +int format_val_params(KEYVALRESULT * keyValArray, int numElements, const char *replace, const char *search) +{ + char *sp; + int i =0; + int search_len; + int replace_len; + int tail_len; + + for (i=0; i<numElements; i++) + { + if ((sp = strstr(keyValArray[i].valStr, search)) == NULL) { + printf("\n String not found\n"); + return 1; //Error search string not found + } + + search_len = strlen(search); + replace_len = strlen(replace); + tail_len = strlen(sp+search_len); + memmove(sp+replace_len,sp+search_len,tail_len+1); + memcpy(sp, replace, replace_len); +// printf("\n Changed value for i=%d is %s", i, keyValArray[i].valStr); + } + return 0; //search and replace is successful +} + +void runCommands(KEYVALRESULT * commandArray, int numCommands) +{ + + char buf[BUFSIZE]; /* buffer used to store VPP metrics */ + FILE *fp; /* file descriptor to pipe cmd to shell */ + int i; + + for(i = 0; i < numCommands; i++) + { + memset(buf, 0, BUFSIZE); + + // Open a pipe and read VPP values + if ((fp = popen(commandArray[i].valStr, "r")) == NULL) { + printf("Error opening pipe!\n"); + return; + } + + while (fgets(buf, BUFSIZE, fp) != NULL); + // printf("\n the vpp value is %d\n", atoi(buf)); + strcpy(commandArray[i].resultStr, buf); + + if(pclose(fp)) { + printf("Command not found or exited with error status\n"); + return; + } + } + //for(i = 0; i < numCommands; i++) + // printf("\n commandArray[%d].resultStr is- %s\n", i, commandArray[i].resultStr); +} + + +void copy_vpp_metic_data(vpp_metrics_struct *intfstats, KEYVALRESULT * cmdArray, int numCmds, int linkNum) +{ + int i; + + // Store the current metric in the last metric + intfstats[linkNum].last_bytes_in = intfstats[linkNum].curr_bytes_in; + intfstats[linkNum].last_bytes_out = intfstats[linkNum].curr_bytes_out; + intfstats[linkNum].last_packets_in = intfstats[linkNum].curr_packets_in; + intfstats[linkNum].last_packets_out = intfstats[linkNum].curr_packets_out; + + // Store metrics read from the vNIC in the current + for(i=0; i<numCmds; i++) + { + if((strcmp(cmdArray[i].keyStr, "tmp_t0BytesIn") == 0) || + (strcmp(cmdArray[i].keyStr, "tmp_t1BytesIn") == 0)) + intfstats[linkNum].curr_bytes_in = atoi(cmdArray[i].resultStr); + + if((strcmp(cmdArray[i].keyStr, "tmp_t0BytesOut") == 0) || + (strcmp(cmdArray[i].keyStr, "tmp_t1BytesOut") == 0)) + intfstats[linkNum].curr_bytes_out = atoi(cmdArray[i].resultStr); + + if((strcmp(cmdArray[i].keyStr, "tmp_t0PacketsIn") == 0) || + (strcmp(cmdArray[i].keyStr, "tmp_t1PacketsIn") == 0)) + intfstats[linkNum].curr_packets_in = atoi(cmdArray[i].resultStr); + + if((strcmp(cmdArray[i].keyStr, "tmp_t0PacketsOut") == 0) || + (strcmp(cmdArray[i].keyStr, "tmp_t1PacketsOut") == 0)) + intfstats[linkNum].curr_packets_out = atoi(cmdArray[i].resultStr); + } + // printf("intfstats[%d].curr_bytes_in = %d\n", linkNum, intfstats[linkNum].curr_bytes_in); + // printf("intfstats[%d].curr_bytes_out = %d\n", linkNum, intfstats[linkNum].curr_bytes_out); + // printf("intfstats[%d].curr_packets_in = %d\n", linkNum, intfstats[linkNum].curr_packets_in); + // printf("intfstats[%d].curr_packets_out = %d\n", linkNum, intfstats[linkNum].curr_packets_out); +} + +int get_severity(char * inStr) +{ + int result = -1; + + if(strcmp(inStr, "CRITICAL") == 0) + result = EVEL_SEVERITY_CRITICAL; + else if(strcmp(inStr, "MAJOR") == 0) + result = EVEL_SEVERITY_MAJOR; + else if(strcmp(inStr, "MINOR") == 0) + result = EVEL_SEVERITY_MINOR; + else if(strcmp(inStr, "WARNING") == 0) + result = EVEL_SEVERITY_WARNING; + else if(strcmp(inStr, "NORMAL") == 0) + result = EVEL_SEVERITY_NORMAL; + + return result; +} + +int get_priority(char * inStr) +{ + int result = -1; + + if(strcmp(inStr, "High") == 0) + result = EVEL_PRIORITY_HIGH; + else if(strcmp(inStr, "Medium") == 0) + result = EVEL_PRIORITY_MEDIUM; + else if(strcmp(inStr, "Normal") == 0) + result = EVEL_PRIORITY_NORMAL; + else if(strcmp(inStr, "Low") == 0) + result = EVEL_PRIORITY_LOW; + + return result; +} + +int get_source(char * inStr) +{ + int result = -1; + + if(strcmp(inStr, "other") == 0) + result = EVEL_SOURCE_OTHER; + else if(strcmp(inStr, "router") == 0) + result = EVEL_SOURCE_ROUTER; + else if(strcmp(inStr, "switch") == 0) + result = EVEL_SOURCE_SWITCH; + else if(strcmp(inStr, "host") == 0) + result = EVEL_SOURCE_HOST; + else if(strcmp(inStr, "card") == 0) + result = EVEL_SOURCE_CARD; + else if(strcmp(inStr, "port") == 0) + result = EVEL_SOURCE_PORT; + else if(strcmp(inStr, "slotThreshold") == 0) + result = EVEL_SOURCE_SLOT_THRESHOLD; + else if(strcmp(inStr, "portThreshold") == 0) + result = EVEL_SOURCE_PORT_THRESHOLD; + else if(strcmp(inStr, "virtualMachine") == 0) + result = EVEL_SOURCE_VIRTUAL_MACHINE; + else if(strcmp(inStr, "virtualNetworkFunction") == 0) + result = EVEL_SOURCE_VIRTUAL_NETWORK_FUNCTION; + + return result; +} + +int get_vf_status(char * inStr) +{ + int result = -1; + + if(strcmp(inStr, "Active") == 0) + result = EVEL_VF_STATUS_ACTIVE; + else if(strcmp(inStr, "Idle") == 0) + result = EVEL_VF_STATUS_IDLE; + else if(strcmp(inStr, "Preparing to terminate") == 0) + result = EVEL_VF_STATUS_PREP_TERMINATE; + else if(strcmp(inStr, "Ready to terminate") == 0) + result = EVEL_VF_STATUS_READY_TERMINATE; + else if(strcmp(inStr, "Requesting termination") == 0) + result = EVEL_VF_STATUS_REQ_TERMINATE; + + return result; +} + +int main(int argc, char** argv) +{ + char* fqdn = argv[1]; + int port = atoi(argv[2]); + int i=0; + int rc; + pthread_attr_t attr; + pthread_t flt_thread; + char* fqdn2 = NULL; + int port2 = 0; + + if(argc == 5) + { + fqdn2 = argv[3]; + port2 = atoi(argv[4]); + } + + if (!((argc == 3) || (argc == 5))) + { + fprintf(stderr, "Usage: %s <FQDN>|<IP address> <port> <FQDN>|<IP address> <port> \n", argv[0]); + fprintf(stderr, "OR\n"); + fprintf(stderr, "Usage: %s <FQDN>|<IP address> <port> \n", argv[0]); + exit(-1); + } + + /**************************************************************************/ + /* Initialize */ + /**************************************************************************/ + if(evel_initialize(fqdn, /* FQDN */ + port, /* Port */ + fqdn2, /* Backup FQDN */ + port2, /* Backup port */ + NULL, /* optional path */ + NULL, /* optional topic */ + 100, /* Ring Buffer size */ + 0, /* HTTPS? */ + NULL, /* cert file */ + NULL, /* key file */ + NULL, /* ca info */ + NULL, /* ca file */ + 0, /* verify peer */ + 0, /* verify host */ + "sample1", /* Username */ + "sample1", /* Password */ + "sample1", /* Username2 */ + "sample1", /* Password2 */ + NULL, /* Source ip */ + NULL, /* Source ip2 */ + EVEL_SOURCE_VIRTUAL_MACHINE, /* Source type */ + "vFault", /* Role */ + 1)) /* Verbosity */ + { + fprintf(stderr, "\nFailed to initialize the EVEL library!!!\n"); + exit(-1); + } + else + { + printf("\nInitialization completed\n"); + } + + /* Initialize and set thread detached attribute */ + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + printf("Main:Creating thread \n"); + rc = pthread_create(&flt_thread, NULL, FaultThread, &i); + if (rc) + { + printf("ERROR; return code from pthread_create() is %d\n", rc); + exit(-1); + } + printf("Main:Created Fault thread \n"); + + pthread_join(flt_thread, NULL); + + evel_terminate(); + printf("Terminated\n"); + return 0; +} + +void *FaultThread(void *mainFault) +{ + + pthread_attr_t attr; + pthread_t flt_thread01; + pthread_t flt_thread02; + pthread_t flt_thread03; + int faultInstance01 = 0; + int faultInstance02 = 0; + int faultInstance03 = 0; + int rc; + + int numToken; + jsmntok_t tokens[MAX_TOKENS]; + char js[MAX_BUFFER_SIZE]; + + jsmn_parser p; + char ch[BUFSIZE]; + int ret = 0; + + memset(js, 0, MAX_BUFFER_SIZE); + memset(ch, 0, BUFSIZE); + + sleep(1); + printf("Running Main Fault thread \n"); + fflush(stdout); + + /* Initialize and set thread detached attribute */ + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + FILE * file = fopen("flt_config.json", "r"); + + while((fgets(ch, (BUFSIZE-1), file)) !=NULL) + { + strcat(js, ch); + memset(ch, 0, BUFSIZE); + } + //printf("MainFaulThread::the file content is \n %s \n", js); + //printf("\n MainFaulThread::MMMMMMMMMMMMMMM\n"); + + jsmn_init(&p); + numToken = jsmn_parse(&p, js, strlen(js), tokens, MAX_TOKENS); + //printf("count-%d\n", numToken); + + //printToken(js,tokens, numToken); + + printf("Main Fault Thread: Creating other fault threads\n"); + + ret = isTokenPresent(js, tokens, numToken, "tmp_faultInstance01", "tmp_indirectParameters"); + if (ret == 0) + { +// rc = pthread_create(&flt_thread01, NULL, FaultThread01, "tmp_faultInstance01"); + rc = pthread_create(&flt_thread01, NULL, FaultThread01, &ret); + if (rc) + { + printf("Main Fault Thread::ERROR; return code from pthread_create() is %d\n", rc); + exit(-1); + } + faultInstance01 = 1; + } + + ret = isTokenPresent(js, tokens, numToken, "tmp_faultInstance02", "tmp_indirectParameters"); + if (ret == 0) + { +// rc = pthread_create(&flt_thread02, NULL, FaultThread02, "tmp_faultInstance02"); + rc = pthread_create(&flt_thread02, NULL, FaultThread02, &ret); + if (rc) + { + printf("Main Fault Thread::ERROR; return code from pthread_create() is %d\n", rc); + exit(-1); + } + faultInstance02 = 1; + } + + ret = isTokenPresent(js, tokens, numToken, "tmp_faultInstance03", "tmp_indirectParameters"); + if (ret == 0) + { + rc = pthread_create(&flt_thread03, NULL, FaultThread03, &ret); + if (rc) + { + printf("Main Fault Thread::ERROR; return code from pthread_create() is %d\n", rc); + exit(-1); + } + faultInstance03 = 1; + } + + if (faultInstance01 == 1) + { + pthread_join(flt_thread01, NULL); + } + + if (faultInstance02 == 1) + { + pthread_join(flt_thread02, NULL); + } + + if (faultInstance03 == 1) + { + pthread_join(flt_thread03, NULL); + } + + while(1) + { + sleep(100); + } +} + +void *FaultThread01(void *faultInstanceTag) +{ + EVEL_ERR_CODES evel_rc = EVEL_SUCCESS; + EVENT_FAULT * fault = NULL; + EVENT_HEADER* fault_header = NULL; + int bytes_in; + int bytes_out; + int packets_in; + int packets_out; + unsigned long long epoch_now; + int lowWaterMark; + + struct timeval time_val; + char event_id1[10] = "fault"; + char event_id2[15] = {0}; + char event_id[BUFSIZE] = {0}; + int fault_event_id = 0; + + int numToken; + jsmntok_t tokens[MAX_TOKENS]; + char js[MAX_BUFFER_SIZE]; + + jsmn_parser p; + char ch[BUFSIZE]; + int ret = 0; + char eName[BUFSIZE]; + char eType[BUFSIZE]; + char nfcCode[BUFSIZE]; + char nfCode[BUFSIZE]; + char prio[BUFSIZE]; + char reportEId[BUFSIZE]; + char reportEName[BUFSIZE]; + char srcId[BUFSIZE]; + char srcName[BUFSIZE]; + char eCategory[BUFSIZE]; + char eventSrcTyp[BUFSIZE]; + char specProb[BUFSIZE]; + char alarmCondn[BUFSIZE]; + char eventSev[BUFSIZE]; + char vfStatus[BUFSIZE]; + + int priority; + int srcTyp; + int vfStat; + int eSev; + + char hostname[BUFSIZE]; + + int flt_interval; + ARRAYVAL intfArray[MAX_INTERFACES]; + KEYVALRESULT keyValResultArray[32]; + KEYVALRESULT commandArray[32]; + int numInitCommands = 0; + int numCommands = 0; + int linkCount = 0; + int i = 0; + + memset(hostname, 0, BUFSIZE); + gethostname(hostname, BUFSIZE); + printf("FAULT01::The hostname is %s\n", hostname); + + sleep(1); + printf("FAULT01::Running Fault thread \n"); + fflush(stdout); + + memset(&intfArray[0],0,(sizeof(ARRAYVAL) * MAX_INTERFACES)); + memset(&keyValResultArray[0],0,(sizeof(KEYVALRESULT) * 32)); + + memset(js, 0, MAX_BUFFER_SIZE); + memset(ch, 0, BUFSIZE); + memset(&fault_intfstat[0],0,(sizeof(vpp_metrics_struct)* MAX_INTERFACES)); + memset(&fault_linkstat[0],0,(sizeof(LINKSTAT) * MAX_INTERFACES)); + + FILE * file = fopen("flt_config.json", "r"); + + while((fgets(ch, (BUFSIZE-1), file)) !=NULL) + { + strcat(js, ch); + memset(ch, 0, BUFSIZE); + } +// printf("FAULT01::the file content is \n %s \n", js); + + jsmn_init(&p); + numToken = jsmn_parse(&p, js, strlen(js), tokens, MAX_TOKENS); + printf("FAULT01::count-%d\n", numToken); + +// printToken(js,tokens, numToken); + + + ret = getIntToken(js, tokens, numToken, "tmp_faultCheckInterval", "tmp_faultInstance01", &flt_interval); + if (ret != 0) + { + printf("FAULT01::The parameter tmp_faultCheckInterval is not defined, defaulted to 60 seconds\n"); + flt_interval = 60; + } + + ret = getIntToken(js, tokens, numToken, "tmp_lowWaterMark", "tmp_faultInstance01", &lowWaterMark); + if (ret != 0) + { + printf("FAULT01::The parameter tmp_lowWaterMark is not defined, defaulted to 100\n"); + lowWaterMark = 100; + } + + ret = getArrayTokens(js, tokens, numToken, "tmp_device", "tmp_directParameters", intfArray, &linkCount); + + printf("FAULT01::Array link count is %d\n", linkCount); + + /* Copy the link information */ + for(i=0;i<linkCount;i++) + { + strcpy(fault_linkstat[i].linkname, &intfArray[i]); +// printf("FAULT01::Link name %s\n", fault_linkstat[i].linkname); + } + + //read_fault_config_file(); + + read_keyVal_params(js, tokens, numToken, "tmp_init", "tmp_faultInstance01", keyValResultArray, &numInitCommands); + + for(i=0;i<linkCount;i++) + { + memset(&commandArray[0],0,(sizeof(KEYVALRESULT) * 32)); + memcpy(commandArray, keyValResultArray, (sizeof(KEYVALRESULT) * 32)); + format_val_params(commandArray, numInitCommands, fault_linkstat[i].linkname, "$tmp_device"); + runCommands(commandArray, numInitCommands); + copy_vpp_metic_data(fault_intfstat, commandArray, numInitCommands, i); + } + + gettimeofday(&time_val, NULL); + + sleep(flt_interval); + + /***************************************************************************/ + /* Collect metrics from the VNIC */ + /***************************************************************************/ + while(1) + { + + ret = getIntToken(js, tokens, numToken, "tmp_faultCheckInterval", "tmp_faultInstance01", &flt_interval); + if (ret != 0) + { + flt_interval = 60; + } + + ret = getIntToken(js, tokens, numToken, "tmp_lowWaterMark", "tmp_faultInstance01", &lowWaterMark); + if (ret != 0) + { + lowWaterMark = 100; + } + + ret = getStringToken(js, tokens, numToken, "eventName", "tmp_faultInstance01", eName, BUFSIZE); + if (ret != 0) + { + printf("FAULT01::Missing mandatory parameters - eventName is not there in tmp_faultInstance01. Exiting...\n"); + exit(1); + } + + ret = getStringToken(js, tokens, numToken, "eventType", "tmp_directParameters", eType, BUFSIZE); + ret = getStringToken(js, tokens, numToken, "nfcNamingCode", "tmp_directParameters", nfcCode, BUFSIZE); + ret = getStringToken(js, tokens, numToken, "nfNamingCode", "tmp_directParameters", nfCode, BUFSIZE); + ret = getStringToken(js, tokens, numToken, "reportingEntityId", "tmp_directParameters", reportEId, BUFSIZE); + ret = getStringToken(js, tokens, numToken, "sourceId", "tmp_directParameters", srcId, BUFSIZE); + ret = getStringToken(js, tokens, numToken, "eventCategory", "tmp_faultInstance01", eCategory, BUFSIZE); + + ret = getStringToken(js, tokens, numToken, "eventSourceType", "tmp_faultInstance01", eventSrcTyp, BUFSIZE); + if (ret != 0) + { + printf("FAULT01::Missing mandatory parameters - eventSourceType is not there in tmp_directParameters, exiting..\n"); + exit(1); + } + srcTyp = get_source(eventSrcTyp); + if(srcTyp == -1) + { + printf("FAULT01::Fault eventSourceType value is not matching, eventSourceType-%s \n", eventSrcTyp); + exit(1); + } + + ret = getStringToken(js, tokens, numToken, "vfStatus", "tmp_directParameters", vfStatus, BUFSIZE); + if (ret != 0) + { + printf("FAULT01::Missing mandatory parameters - vfStatus is not there in tmp_directParameters, exiting..\n"); + exit(1); + } + vfStat = get_vf_status(vfStatus); + if(vfStat == -1) + { + printf("FAULT01::Fault vfStatus value is not matching, vfStatus-%s \n", vfStatus); + exit(1); + } + + read_keyVal_params(js, tokens, numToken, "tmp_command", "tmp_faultInstance01", keyValResultArray, &numCommands); + + for(i=0;i<linkCount;i++) + { + memset(&commandArray[0],0,(sizeof(KEYVALRESULT) * 32)); + memcpy(commandArray, keyValResultArray, (sizeof(KEYVALRESULT) * 32)); + format_val_params(commandArray, numCommands, fault_linkstat[i].linkname, "$tmp_device"); + runCommands(commandArray, numCommands); + copy_vpp_metic_data(fault_intfstat, commandArray, numInitCommands, i); + } + + for (int i = 0; i < linkCount; i++) + { + if(fault_intfstat[i].curr_bytes_in - fault_intfstat[i].last_bytes_in > 0) { + bytes_in = fault_intfstat[i].curr_bytes_in - fault_intfstat[i].last_bytes_in; + } + else { + bytes_in = 0; + } + if(fault_intfstat[i].curr_bytes_out - fault_intfstat[i].last_bytes_out > 0) { + bytes_out = fault_intfstat[i].curr_bytes_out - fault_intfstat[i].last_bytes_out; + } + else { + bytes_out = 0; + } + if(fault_intfstat[i].curr_packets_in - fault_intfstat[i].last_packets_in > 0) { + packets_in = fault_intfstat[i].curr_packets_in - fault_intfstat[i].last_packets_in; + } + else { + packets_in = 0; + } + if(fault_intfstat[i].curr_packets_out - fault_intfstat[i].last_packets_out > 0) { + packets_out = fault_intfstat[i].curr_packets_out - fault_intfstat[i].last_packets_out; + } + else { + packets_out = 0; + } + if (((bytes_in < lowWaterMark) || (bytes_out < lowWaterMark) || + (packets_in < lowWaterMark) || (packets_out < lowWaterMark)) && + (fault_linkstat[i].fault_raised == 0)) + { + printf("\n%d - bytes in %d, ouot %d, packets in %d, out %d", i, bytes_in, bytes_out, packets_in, packets_out); + printf("\nFAULT01::Raising fault\n"); + memset(event_id, 0, BUFSIZE); + fault_event_id = fault_event_id+1; + sprintf(event_id2, "%09d", fault_event_id); + strcat(event_id, event_id1); + strcat(event_id, event_id2); + + ret = getIntToken(js, tokens, numToken, "tmp_faultCheckInterval", "tmp_faultInstance01", &flt_interval); + if (ret != 0) + { + printf("FAULT01::The parameter tmp_faultCheckInterval is not defined, defaulted to 60 seconds\n"); + flt_interval = 60; + } + + ret = getIntToken(js, tokens, numToken, "tmp_lowWaterMark", "tmp_faultInstance01", &lowWaterMark); + if (ret != 0) + { + printf("FAULT01::The parameter tmp_lowWaterMark is not defined, defaulted to 100\n"); + lowWaterMark = 100; + } + ret = getStringToken(js, tokens, numToken, "reportingEntityName", "tmp_directParameters", reportEName, BUFSIZE); + if (ret != 0) + { + printf("FAULT01::Missing mandatory parameters - reportingEntityName is not there in tmp_directParameters\n"); + printf("FAULT01::Defaulting reportingEntityName to hostname\n"); + strcpy(reportEName, hostname); + } + ret = getStringToken(js, tokens, numToken, "sourceName", "tmp_directParameters", srcName, BUFSIZE); + if (ret != 0) + { + printf("FAULT01::Missing mandatory parameters - sourceName is not there in tmp_directParameters\n"); + printf("FAULT01::Defaulting sourceName to hostname\n"); + strcpy(srcName, hostname); + } + + ret = getStringToken(js, tokens, numToken, "priority", "tmp_directParameters", prio, BUFSIZE); + if (ret != 0) + { + printf("FAULT01::Missing mandatory parameters - priority is not there in tmp_directParameters\nDefaulting priority to Low\n"); + strcpy(prio, "Medium"); + } + priority = get_priority(prio); + if(priority == -1) + { + printf("FAULT01::Fault priority value is not matching, prioirty-%s \n", prio); + exit(1); + } + + ret = getStringTokenV2(js, tokens, numToken, "specificProblem", "tmp_alarmSetParameters", "tmp_faultInstance01", specProb, BUFSIZE); + if (ret != 0) + { + printf("FAULT01::Missing mandatory parameters - specificProblem is not there in tmp_alarmSetParameters, exiting ...\n"); + exit(1); + } + ret = getStringTokenV2(js, tokens, numToken, "alarmCondition", "tmp_alarmSetParameters", "tmp_faultInstance01", alarmCondn, BUFSIZE); + if (ret != 0) + { + printf("FAULT01::Missing mandatory parameters - alarmCondition is not there in tmp_alarmSetParameters, exiting ...\n"); + exit(1); + } + ret = getStringTokenV2(js, tokens, numToken, "eventSeverity", "tmp_alarmSetParameters", "tmp_faultInstance01", eventSev, BUFSIZE); + if (ret != 0) + { + printf("FAULT01::Missing mandatory parameters - eventSeverity is not there in tmp_alarmSetParameters\n"); + printf("FAULT01::Defaulting eventSeverity to MAJOR\n"); + strcpy(eventSev, "MAJOR"); + } + eSev = get_severity(eventSev); + if(eSev == -1) + { + printf("FAULT01::Fault eventSeverity value is not matching, eventSeverity-%s \n", eventSev); + exit(1); + } + + fault = evel_new_fault(eName, event_id, alarmCondn, + specProb, priority, eSev, srcTyp,vfStat); + if (fault != NULL) + { + fault_linkstat[i].fault_raised = 1; + + struct timeval tv_now; + gettimeofday(&tv_now, NULL); + epoch_now = tv_now.tv_usec + 1000000 * tv_now.tv_sec; + fault_linkstat[i].last_epoch = epoch_now; + + fault_header = (EVENT_HEADER *)fault; + + evel_fault_category_set(fault, eCategory); + evel_fault_interface_set(fault, fault_linkstat[i].linkname); + + if (eType != NULL) + evel_fault_type_set(fault, eType); + + evel_start_epoch_set(&fault->header, epoch_now); + evel_last_epoch_set(&fault->header, epoch_now); + if(nfcCode != NULL) + evel_nfcnamingcode_set(&fault->header, nfcCode); + if(nfCode != NULL) + evel_nfnamingcode_set(&fault->header, nfCode); + evel_reporting_entity_name_set(&fault->header, reportEName); + if(reportEId != NULL) + evel_reporting_entity_id_set(&fault->header, reportEId); + if(srcId != NULL ) + evel_source_id_set(&fault->header, srcId); + if(srcName!= NULL ) + evel_source_name_set(&fault->header, srcName); + + evel_rc = evel_post_event(fault_header); + + if(evel_rc == EVEL_SUCCESS) + printf("FAULT01::Fault event is correctly sent to the collector!\n"); + else + printf("FAULT01::Post failed %d (%s)\n", evel_rc, evel_error_string()); + } + else + { + printf("FAULT01::New new fault failed (%s)\n", evel_error_string()); + } + } + else if (((bytes_in > lowWaterMark) && (bytes_out > lowWaterMark) && + (packets_in > lowWaterMark) && (packets_out > lowWaterMark)) && + (fault_linkstat[i].fault_raised == 1)) + { + printf("\nFAULT01:: Clearing fault\n"); + memset(event_id, 0, BUFSIZE); + sprintf(event_id2, "%09d", (i+1)); + strcat(event_id, event_id1); + strcat(event_id, event_id2); + + ret = getIntToken(js, tokens, numToken, "tmp_faultCheckInterval", "tmp_faultInstance01", &flt_interval); + if (ret != 0) + { + printf("FAULT01::The parameter tmp_faultCheckInterval is not defined, defaulted to 60 seconds\n"); + flt_interval = 60; + } + + ret = getIntToken(js, tokens, numToken, "tmp_lowWaterMark", "tmp_faultInstance01", &lowWaterMark); + if (ret != 0) + { + printf("FAULT01::The parameter tmp_lowWaterMark is not defined, defaulted to 100\n"); + lowWaterMark = 100; + } + ret = getStringToken(js, tokens, numToken, "reportingEntityName", "tmp_directParameters", reportEName, BUFSIZE); + if (ret != 0) + { + printf("FAULT01::Missing mandatory parameters - reportingEntityName is not there in tmp_directParameters\n"); + printf("FAULT01::Defaulting reportingEntityName to hostname\n"); + strcpy(reportEName, hostname); + } + ret = getStringToken(js, tokens, numToken, "sourceName", "tmp_directParameters", srcName, BUFSIZE); + if (ret != 0) + { + printf("FAULT01::Missing mandatory parameters - sourceName is not there in tmp_directParameters\n"); + printf("FAULT01::Defaulting sourceName to hostname\n"); + strcpy(srcName, hostname); + } + + ret = getStringToken(js, tokens, numToken, "priority", "tmp_directParameters", prio, BUFSIZE); + if (ret != 0) + { + printf("FAULT01::Missing mandatory parameters - priority is not there in tmp_directParameters\nDefaulting priority to Low\n"); + strcpy(prio, "Medium"); + } + priority = get_priority(prio); + if(priority == -1) + { + printf("FAULT01::Fault priority value is not matching, prioirty-%s \n", prio); + exit(1); + } + + ret = getStringTokenV2(js, tokens, numToken, "specificProblem", "tmp_alarmClearParameters", "tmp_faultInstance01", specProb, BUFSIZE); + if (ret != 0) + { + printf("FAULT01::Missing mandatory parameters - specificProblem is not there in tmp_alarmClearParameters, exiting ...\n"); + exit(1); + } + + ret = getStringTokenV2(js, tokens, numToken, "alarmCondition", "tmp_alarmClearParameters", "tmp_faultInstance01", alarmCondn, BUFSIZE); + if (ret != 0) + { + printf("FAULT01::Missing mandatory parameters - alarmCondition is not there in tmp_alarmClearParameters, exiting ...\n"); + exit(1); + } + + ret = getStringTokenV2(js, tokens, numToken, "eventSeverity", "tmp_alarmClearParameters", "tmp_faultInstance01", eventSev, BUFSIZE); + if (ret != 0) + { + printf("FAULT01::Missing mandatory parameters - eventSeverity is not there in tmp_alarmClearParameters\n"); + printf("FAULT01::Defaulting eventSeverity to MAJOR\n"); + strcpy(eventSev, "NORMAL"); + } + eSev = get_severity(eventSev); + if(eSev == -1) + { + printf("FAULT01::Fault eventSeverity value is not matching, eventSeverity-%s \n", eventSev); + exit(1); + } + + fault = evel_new_fault(eName, event_id, alarmCondn, + specProb, priority, eSev, srcTyp,vfStat); + if (fault != NULL) + { + fault_linkstat[i].fault_raised = 0; + + struct timeval tv_now; + gettimeofday(&tv_now, NULL); + epoch_now = tv_now.tv_usec + 1000000 * tv_now.tv_sec; + + fault_header = (EVENT_HEADER *)fault; + evel_fault_category_set(fault, eCategory); + evel_fault_interface_set(fault, fault_linkstat[i].linkname); + + if (eType != NULL) + evel_fault_type_set(fault, eType); + + evel_start_epoch_set(&fault->header, fault_linkstat[i].last_epoch); + evel_last_epoch_set(&fault->header, epoch_now); + fault_linkstat[i].last_epoch = 0; + + if(nfcCode != NULL) + evel_nfcnamingcode_set(&fault->header, nfcCode); + if(nfCode != NULL) + evel_nfnamingcode_set(&fault->header, nfCode); + evel_reporting_entity_name_set(&fault->header, reportEName); + if(reportEId != NULL) + evel_reporting_entity_id_set(&fault->header, reportEId); + if(srcId != NULL ) + evel_source_id_set(&fault->header, srcId); + if(srcName!= NULL ) + evel_source_name_set(&fault->header, srcName); + + evel_rc = evel_post_event(fault_header); + + if(evel_rc == EVEL_SUCCESS) + printf("FAULT01::Fault event is correctly sent to the collector!\n"); + else + printf("FAULT01::Post failed %d (%s)\n", evel_rc, evel_error_string()); + } + else + printf("FAULT01::New fault failed (%s)\n", evel_error_string()); + } + } + + sleep(flt_interval); + } + + /***************************************************************************/ + /* Terminate */ + /***************************************************************************/ + sleep(1); +} + +void *FaultThread02(void *faultInstanceTag) +{ + EVEL_ERR_CODES evel_rc = EVEL_SUCCESS; + EVENT_FAULT * fault = NULL; + EVENT_HEADER* fault_header = NULL; + unsigned long long epoch_now; + unsigned long long last_epoch; + + struct timeval time_val; + char event_id1[10] = "fault"; + char event_id2[15] = {0}; + char event_id[BUFSIZE] = {0}; + int fault_event_id = 0; + int i=0; + + int numToken; + jsmntok_t tokens[MAX_TOKENS]; + char js[MAX_BUFFER_SIZE]; + + jsmn_parser p; + char ch[BUFSIZE]; + int ret = 0; + char eName[BUFSIZE]; + char eType[BUFSIZE]; + char aInterface[BUFSIZE]; + char nfcCode[BUFSIZE]; + char nfCode[BUFSIZE]; + char prio[BUFSIZE]; + char reportEId[BUFSIZE]; + char reportEName[BUFSIZE]; + char srcId[BUFSIZE]; + char srcName[BUFSIZE]; + char eCategory[BUFSIZE]; + char eventSrcTyp[BUFSIZE]; + char specProb[BUFSIZE]; + char alarmCondn[BUFSIZE]; + char eventSev[BUFSIZE]; + char vfStatus[BUFSIZE]; + + int priority; + int srcTyp; + int vfStat; + int eSev; + + char hostname[BUFSIZE]; + + int flt_interval; + KEYVALRESULT keyValResultArray[32]; + KEYVALRESULT commandArray[32]; + int numInitCommands = 0; + int numCommands = 0; + int fault_raised = 0; + + memset(hostname, 0, BUFSIZE); + gethostname(hostname, BUFSIZE); + printf("FAULT02::The hostname is %s\n", hostname); + + sleep(1); + printf("FAULT02::Running Fault thread \n"); + fflush(stdout); + + memset(&keyValResultArray[0],0,(sizeof(KEYVALRESULT) * 32)); + + memset(js, 0, MAX_BUFFER_SIZE); + memset(ch, 0, BUFSIZE); + + FILE * file = fopen("flt_config.json", "r"); + + while((fgets(ch, (BUFSIZE-1), file)) !=NULL) + { + strcat(js, ch); + memset(ch, 0, BUFSIZE); + } +// printf("FAULT02::the file content is \n %s \n", js); + + jsmn_init(&p); + numToken = jsmn_parse(&p, js, strlen(js), tokens, MAX_TOKENS); + printf("FAULT02::count-%d\n", numToken); + +// printToken(js,tokens, numToken); + + ret = getIntToken(js, tokens, numToken, "tmp_faultCheckInterval", "tmp_faultInstance02", &flt_interval); + if (ret != 0) + { + printf("FAULT02::The parameter tmp_faultCheckInterval is not defined, defaulted to 60 seconds\n"); + flt_interval = 60; + } + + + read_keyVal_params(js, tokens, numToken, "tmp_init", "tmp_faultInstance02", keyValResultArray, &numInitCommands); + + memset(&commandArray[0],0,(sizeof(KEYVALRESULT) * 32)); + memcpy(commandArray, keyValResultArray, (sizeof(KEYVALRESULT) * 32)); + runCommands(commandArray, numInitCommands); + + gettimeofday(&time_val, NULL); + + sleep(flt_interval); + + /***************************************************************************/ + /* Collect metrics from the VNIC */ + /***************************************************************************/ + while(1) { + + ret = getIntToken(js, tokens, numToken, "tmp_faultCheckInterval", "tmp_faultInstance02", &flt_interval); + if (ret != 0) + { + flt_interval = 60; + } + + ret = getStringToken(js, tokens, numToken, "eventName", "tmp_faultInstance02", eName, BUFSIZE); + if (ret != 0) + { + printf("FAULT02::Missing mandatory parameters - eventName is not there in tmp_faultInstance02. Exiting...\n"); + exit(1); + } + + ret = getStringToken(js, tokens, numToken, "eventType", "tmp_directParameters", eType, BUFSIZE); + ret = getStringToken(js, tokens, numToken, "nfcNamingCode", "tmp_directParameters", nfcCode, BUFSIZE); + ret = getStringToken(js, tokens, numToken, "nfNamingCode", "tmp_directParameters", nfCode, BUFSIZE); + ret = getStringToken(js, tokens, numToken, "reportingEntityId", "tmp_directParameters", reportEId, BUFSIZE); + ret = getStringToken(js, tokens, numToken, "sourceId", "tmp_directParameters", srcId, BUFSIZE); + ret = getStringToken(js, tokens, numToken, "eventCategory", "tmp_faultInstance02", eCategory, BUFSIZE); + ret = getStringToken(js, tokens, numToken, "alarmInterfaceA", "tmp_faultInstance02", aInterface, BUFSIZE); + + ret = getStringToken(js, tokens, numToken, "eventSourceType", "tmp_faultInstance02", eventSrcTyp, BUFSIZE); + if (ret != 0) + { + printf("FAULT02::Missing mandatory parameters - eventSourceType is not there in tmp_directParameters, exiting..\n"); + exit(1); + } + srcTyp = get_source(eventSrcTyp); + if(srcTyp == -1) + { + printf("FAULT02::Fault eventSourceType value is not matching, eventSourceType-%s \n", eventSrcTyp); + exit(1); + } + + ret = getStringToken(js, tokens, numToken, "vfStatus", "tmp_directParameters", vfStatus, BUFSIZE); + if (ret != 0) + { + printf("FAULT02::Missing mandatory parameters - vfStatus is not there in tmp_directParameters, exiting..\n"); + exit(1); + } + vfStat = get_vf_status(vfStatus); + if(vfStat == -1) + { + printf("FAULT02::Fault vfStatus value is not matching, vfStatus-%s \n", vfStatus); + exit(1); + } + + read_keyVal_params(js, tokens, numToken, "tmp_command", "tmp_faultInstance02", keyValResultArray, &numCommands); + + memset(&commandArray[0],0,(sizeof(KEYVALRESULT) * 32)); + memcpy(commandArray, keyValResultArray, (sizeof(KEYVALRESULT) * 32)); + runCommands(commandArray, numCommands); + + /******************************************************************************** + * Put the condition to set the fault here + *******************************************************************************/ + if ((atoi(commandArray[0].resultStr) == 1) && (fault_raised == 0)) + { + printf("\nFAULT02::Raising fault\n"); + memset(event_id, 0, BUFSIZE); + fault_event_id = fault_event_id+1; + sprintf(event_id2, "%09d", fault_event_id); + strcat(event_id, event_id1); + strcat(event_id, event_id2); + + ret = getIntToken(js, tokens, numToken, "tmp_faultCheckInterval", "tmp_faultInstance02", &flt_interval); + if (ret != 0) + { + printf("FAULT02::The parameter tmp_faultCheckInterval is not defined, defaulted to 60 seconds\n"); + flt_interval = 60; + } + + ret = getStringToken(js, tokens, numToken, "reportingEntityName", "tmp_directParameters", reportEName, BUFSIZE); + if (ret != 0) + { + printf("FAULT02::Missing mandatory parameters - reportingEntityName is not there in tmp_directParameters\n"); + printf("FAULT02::Defaulting reportingEntityName to hostname\n"); + strcpy(reportEName, hostname); + } + ret = getStringToken(js, tokens, numToken, "sourceName", "tmp_directParameters", srcName, BUFSIZE); + if (ret != 0) + { + printf("FAULT02::Missing mandatory parameters - sourceName is not there in tmp_directParameters\n"); + printf("FAULT02::Defaulting sourceName to hostname\n"); + strcpy(srcName, hostname); + } + + ret = getStringToken(js, tokens, numToken, "priority", "tmp_directParameters", prio, BUFSIZE); + if (ret != 0) + { + printf("FAULT02::Missing mandatory parameters - priority is not there in tmp_directParameters\nDefaulting priority to Low\n"); + strcpy(prio, "Medium"); + } + priority = get_priority(prio); + if(priority == -1) + { + printf("FAULT02::Fault priority value is not matching, prioirty-%s \n", prio); + exit(1); + } + + ret = getStringTokenV2(js, tokens, numToken, "specificProblem", "tmp_alarmSetParameters", "tmp_faultInstance02", specProb, BUFSIZE); + if (ret != 0) + { + printf("FAULT02::Missing mandatory parameters - specificProblem is not there in tmp_alarmSetParameters, exiting ...\n"); + exit(1); + } + ret = getStringTokenV2(js, tokens, numToken, "alarmCondition", "tmp_alarmSetParameters", "tmp_faultInstance02", alarmCondn, BUFSIZE); + if (ret != 0) + { + printf("FAULT02::Missing mandatory parameters - alarmCondition is not there in tmp_alarmSetParameters, exiting ...\n"); + exit(1); + } + ret = getStringTokenV2(js, tokens, numToken, "eventSeverity", "tmp_alarmSetParameters", "tmp_faultInstance02", eventSev, BUFSIZE); + if (ret != 0) + { + printf("FAULT02::Missing mandatory parameters - eventSeverity is not there in tmp_alarmSetParameters\n"); + printf("FAULT02::Defaulting eventSeverity to MAJOR\n"); + strcpy(eventSev, "MAJOR"); + } + eSev = get_severity(eventSev); + if(eSev == -1) + { + printf("FAULT02::Fault eventSeverity value is not matching, eventSeverity-%s \n", eventSev); + exit(1); + } + + fault = evel_new_fault(eName, event_id, alarmCondn, + specProb, priority, eSev, srcTyp,vfStat); + if (fault != NULL) + { + fault_raised = 1; + + struct timeval tv_now; + gettimeofday(&tv_now, NULL); + epoch_now = tv_now.tv_usec + 1000000 * tv_now.tv_sec; + last_epoch = epoch_now; + + fault_header = (EVENT_HEADER *)fault; + + evel_fault_category_set(fault, eCategory); + if (aInterface != NULL) + evel_fault_interface_set(fault, aInterface); + + if (eType != NULL) + evel_fault_type_set(fault, eType); + + evel_start_epoch_set(&fault->header, epoch_now); + evel_last_epoch_set(&fault->header, epoch_now); + if(nfcCode != NULL) + evel_nfcnamingcode_set(&fault->header, nfcCode); + if(nfCode != NULL) + evel_nfnamingcode_set(&fault->header, nfCode); + evel_reporting_entity_name_set(&fault->header, reportEName); + if(reportEId != NULL) + evel_reporting_entity_id_set(&fault->header, reportEId); + if(srcId != NULL ) + evel_source_id_set(&fault->header, srcId); + if(srcName!= NULL ) + evel_source_name_set(&fault->header, srcName); + + evel_rc = evel_post_event(fault_header); + + if(evel_rc == EVEL_SUCCESS) { + printf("FAULT02::Fault event is correctly sent to the collector!\n"); + } + else { + printf("FAULT02::Post failed %d (%s)\n", evel_rc, evel_error_string()); + } + } + else { + printf("FAULT02::New new fault failed (%s)\n", evel_error_string()); + } + } + /******************************************************************************** + * Put the condition to clear the fault here + *******************************************************************************/ + else if ((atoi(commandArray[0].resultStr) == 0) && (fault_raised == 1)) + { + printf("\nFAULT02:: Clearing fault\n"); + memset(event_id, 0, BUFSIZE); + sprintf(event_id2, "%09d", (i+1)); + strcat(event_id, event_id1); + strcat(event_id, event_id2); + + ret = getIntToken(js, tokens, numToken, "tmp_faultCheckInterval", "tmp_faultInstance02", &flt_interval); + if (ret != 0) + { + printf("FAULT02::The parameter tmp_faultCheckInterval is not defined, defaulted to 60 seconds\n"); + flt_interval = 60; + } + + ret = getStringToken(js, tokens, numToken, "reportingEntityName", "tmp_directParameters", reportEName, BUFSIZE); + if (ret != 0) + { + printf("FAULT02::Missing mandatory parameters - reportingEntityName is not there in tmp_directParameters\n"); + printf("FAULT02::Defaulting reportingEntityName to hostname\n"); + strcpy(reportEName, hostname); + } + ret = getStringToken(js, tokens, numToken, "sourceName", "tmp_directParameters", srcName, BUFSIZE); + if (ret != 0) + { + printf("FAULT02::Missing mandatory parameters - sourceName is not there in tmp_directParameters\n"); + printf("FAULT02::Defaulting sourceName to hostname\n"); + strcpy(srcName, hostname); + } + + ret = getStringToken(js, tokens, numToken, "priority", "tmp_directParameters", prio, BUFSIZE); + if (ret != 0) + { + printf("FAULT02::Missing mandatory parameters - priority is not there in tmp_directParameters\nDefaulting priority to Low\n"); + strcpy(prio, "Medium"); + } + priority = get_priority(prio); + if(priority == -1) + { + printf("FAULT02::Fault priority value is not matching, prioirty-%s \n", prio); + exit(1); + } + + ret = getStringTokenV2(js, tokens, numToken, "specificProblem", "tmp_alarmClearParameters", "tmp_faultInstance02", specProb, BUFSIZE); + if (ret != 0) + { + printf("FAULT02::Missing mandatory parameters - specificProblem is not there in tmp_alarmClearParameters, exiting ...\n"); + exit(1); + } + + ret = getStringTokenV2(js, tokens, numToken, "alarmCondition", "tmp_alarmClearParameters", "tmp_faultInstance02", alarmCondn, BUFSIZE); + if (ret != 0) + { + printf("FAULT02::Missing mandatory parameters - alarmCondition is not there in tmp_alarmClearParameters, exiting ...\n"); + exit(1); + } + + ret = getStringTokenV2(js, tokens, numToken, "eventSeverity", "tmp_alarmClearParameters", "tmp_faultInstance02", eventSev, BUFSIZE); + if (ret != 0) + { + printf("FAULT02::Missing mandatory parameters - eventSeverity is not there in tmp_alarmClearParameters\n"); + printf("FAULT02::Defaulting eventSeverity to MAJOR\n"); + strcpy(eventSev, "NORMAL"); + } + eSev = get_severity(eventSev); + if(eSev == -1) + { + printf("FAULT02::Fault eventSeverity value is not matching, eventSeverity-%s \n", eventSev); + exit(1); + } + + fault = evel_new_fault(eName, event_id, alarmCondn, + specProb, priority, eSev, srcTyp,vfStat); + if (fault != NULL) + { + fault_raised = 0; + + struct timeval tv_now; + gettimeofday(&tv_now, NULL); + epoch_now = tv_now.tv_usec + 1000000 * tv_now.tv_sec; + + fault_header = (EVENT_HEADER *)fault; + evel_fault_category_set(fault, eCategory); + if (aInterface != NULL) + evel_fault_interface_set(fault, aInterface); + + if (eType != NULL) + evel_fault_type_set(fault, eType); + + evel_start_epoch_set(&fault->header, last_epoch); + evel_last_epoch_set(&fault->header, epoch_now); + last_epoch = 0; + + if(nfcCode != NULL) + evel_nfcnamingcode_set(&fault->header, nfcCode); + if(nfCode != NULL) + evel_nfnamingcode_set(&fault->header, nfCode); + evel_reporting_entity_name_set(&fault->header, reportEName); + if(reportEId != NULL) + evel_reporting_entity_id_set(&fault->header, reportEId); + if(srcId != NULL ) + evel_source_id_set(&fault->header, srcId); + if(srcName!= NULL ) + evel_source_name_set(&fault->header, srcName); + + evel_rc = evel_post_event(fault_header); + + if(evel_rc == EVEL_SUCCESS) { + printf("FAULT02::Fault event is correctly sent to the collector!\n"); + } + else { + printf("FAULT02::Post failed %d (%s)\n", evel_rc, evel_error_string()); + } + } + else { + printf("FAULT02::New fault failed (%s)\n", evel_error_string()); + } + + } + + sleep(flt_interval); + } + + /***************************************************************************/ + /* Terminate */ + /***************************************************************************/ + sleep(1); +} + +void *FaultThread03(void *faultInstanceTag) +{ + sleep(4); + printf("FAULT03::thread created\n"); + fflush(stdout); + while (1) + { sleep (100); } +} + diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/LICENSE.TXT b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/LICENSE.TXT new file mode 100644 index 0000000..16285cd --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/LICENSE.TXT @@ -0,0 +1,22 @@ +/* + * ============LICENSE_START========================================== + * =================================================================== + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Unless otherwise specified, all software contained herein is + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + * + * ECOMP is trademark and service mark of AT&T Intellectual Property. + * + */ diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/Makefile b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/Makefile new file mode 100644 index 0000000..4b0fd85 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/Makefile @@ -0,0 +1,52 @@ +############################################################################# +# +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +############################################################################# + +CC=gcc +ARCH=$(shell getconf LONG_BIT) +CODE_ROOT=$(CURDIR)/../.. +#CODE_ROOT=../code/evel-library +LIBS_DIR=$(CODE_ROOT)/libs/x86_$(ARCH) +#LIBS_DIR=/usr/lib +INCLUDE_DIR= -I $(CODE_ROOT)/code/evel_library -I . + +#****************************************************************************** +# Standard compiler flags. * +#****************************************************************************** +CPPFLAGS= +CFLAGS=-Wall -g -fPIC +FILEOBJLIST= jsmn.o ves_syslog_reporter.o + +all: ves_syslog_reporter + +clean: + rm -f *.o ves_syslog_reporter + +%.o: %.c + $(CC) $(CPPFLAGS) $(CFLAGS) $(INCLUDE_DIR) -c $< -o $@ + +jsmn.o: jsmn.c jsmn.h +ves_syslog_reporter.o: ves_syslog_reporter.c + +ves_syslog_reporter: $(FILEOBJLIST) + $(CC) $(CPPFLAGS) $(CFLAGS) -o ves_syslog_reporter \ + -L $(LIBS_DIR) \ + $(FILEOBJLIST) \ + -lpthread \ + -level \ + -lcurl + + diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/README.md b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/README.md new file mode 100644 index 0000000..9aecc2a --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/README.md @@ -0,0 +1,37 @@ + +PROJECT DESCRIPTION + +--- +This project contains the source code and scripts for the generation of syslog events. The folder contains: + + - README.md: this file. + + - LICENSE.TXT: the license text. + + - ves_syslog_reporter.c and other .c files: source code that uses the ECOMP Vendor Event Listener Library (VES) to generate the syslog events. Syslog events are generated based on /var/log/syslog entries. If a specific pattern is observed in the syslog file, then it generates the syslog event. The application reads syslog_config.json file for parameter values and poppulate the syslog event. If eventName, eventSourceType, syslogTag and tmp_syslogFile parameter value is not given, the application terminates. If reportingEntityName and/or sourceName parameter values are not given, then it gets the hostname and poppulates it. + + - Makefile: makefile that compiles ves_syslog_reporter.c and generates ves_syslog_reporter binary. + + - go-client.sh/go-client_2_collectors.sh: bash script that starts up the ves_syslog_reporter. It reads input parameters like DCAE IP address and port from configuration files contained in /opt/config. Based on the collector configuration, use go-client.sh for single collector configuration, or use go-client_2_collectors.sh for 2 collectors configuration. + + +USAGE +----- + +Update the configuration files with proper parameters values so that events generated would contain those values + +To run the ves_syslog_reporter in single collector configuration, please execute the following steps: + + - Make the go-client.sh script executable + chmod +x go-client.sh + + - Run the go-client.sh script + ./go-client.sh + +For 2 collectors configuration, please execute following steps: + + - Make the go-client.sh script executable + chmod +x go-client_2_collectors.sh + + - Run the go-client_2_collectors.sh script + ./go-client_2_collectors.sh diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/dep.xml b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/dep.xml new file mode 100644 index 0000000..fc18229 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/dep.xml @@ -0,0 +1,25 @@ +<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd"> + <id>demo</id> + <formats> + <format>tar.gz</format> + </formats> + <fileSets> + + <fileSet> + <directory>.</directory> + <outputDirectory>/</outputDirectory> + <includes> + <include>*.sh</include> + <include>*.md</include> + <include>*.TXT</include> + <include>*.c</include> + <include>Makefile</include> + </includes> + </fileSet> + + </fileSets> +</assembly> + + diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/go-client.sh b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/go-client.sh new file mode 100755 index 0000000..0701456 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/go-client.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +export LD_LIBRARY_PATH="/opt/VES/evel/evel-library/libs/x86_64/" +DCAE_COLLECTOR_IP=$(cat /opt/config/dcae_collector_ip.txt) +DCAE_COLLECTOR_PORT=$(cat /opt/config/dcae_collector_port.txt) +./ves_syslog_reporter $DCAE_COLLECTOR_IP $DCAE_COLLECTOR_PORT diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/go-client_2_collectors.sh b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/go-client_2_collectors.sh new file mode 100755 index 0000000..492d76d --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/go-client_2_collectors.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +export LD_LIBRARY_PATH="/opt/VES/evel/evel-library/libs/x86_64/" + +#Usage for 2 collectors: +#./ves_syslog_reporter <FQDN>|<IP address> <port> <FQDN>|<IP address> <port> + +DCAE_COLLECTOR_IP=$(cat /opt/config/dcae_collector_ip.txt) +DCAE_COLLECTOR_PORT=$(cat /opt/config/dcae_collector_port.txt) +DCAE_COLLECTOR_IP2=$(cat /opt/config/dcae_collector_ip2.txt) +DCAE_COLLECTOR_PORT2=$(cat /opt/config/dcae_collector_port2.txt) +./ves_syslog_reporter $DCAE_COLLECTOR_IP $DCAE_COLLECTOR_PORT $DCAE_COLLECTOR_IP2 $DCAE_COLLECTOR_PORT2 diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/jsmn.c b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/jsmn.c new file mode 100644 index 0000000..1d72ba4 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/jsmn.c @@ -0,0 +1,672 @@ +/*************************************************************************//** + * + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * + * Unless otherwise specified, all software contained herein is + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + ****************************************************************************/ +#include<stdio.h> +#include<stdlib.h> +#include<string.h> +#include "jsmn.h" + +/** + * Allocates a fresh unused token from the token pull. + */ +static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser, + jsmntok_t *tokens, size_t num_tokens) { + jsmntok_t *tok; + if (parser->toknext >= num_tokens) { + return NULL; + } + tok = &tokens[parser->toknext++]; + tok->start = tok->end = -1; + tok->size = 0; +//#ifdef JSMN_PARENT_LINKS + tok->parent = -1; +//#endif + return tok; +} + +/** + * Fills token type and boundaries. + */ +static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type, + int start, int end) { +//printf("jsmn_fill_token:: start-%d, end-%d\n", start, end); + token->type = type; + token->start = start; + token->end = end; + token->size = 0; +} + +/** + * Fills next available token with JSON primitive. + */ +static int jsmn_parse_primitive(jsmn_parser *parser, const char *js, + size_t len, jsmntok_t *tokens, size_t num_tokens) { + jsmntok_t *token; + int start; + + start = parser->pos; + + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { +//printf("jsmn_parse_primitive:: the char is - %c\n", js[parser->pos]); + switch (js[parser->pos]) { +#ifndef JSMN_STRICT + /* In strict mode primitive must be followed by "," or "}" or "]" */ + case ':': +#endif + case '\t' : case '\r' : case '\n' : case ' ' : + case ',' : case ']' : case '}' : + goto found; + } + if (js[parser->pos] < 32 || js[parser->pos] >= 127) { + parser->pos = start; + return JSMN_ERROR_INVAL; + } + } +#ifdef JSMN_STRICT + /* In strict mode primitive must be followed by a comma/object/array */ + parser->pos = start; + return JSMN_ERROR_PART; +#endif + +found: + if (tokens == NULL) { + parser->pos--; + return 0; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); + if (token == NULL) { + parser->pos = start; + return JSMN_ERROR_NOMEM; + } + jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos); +//#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +//#endif + parser->pos--; + return 0; +} + +/** + * Fills next token with JSON string. + */ +static int jsmn_parse_string(jsmn_parser *parser, const char *js, + size_t len, jsmntok_t *tokens, size_t num_tokens) { + jsmntok_t *token; + + int start = parser->pos; + + parser->pos++; + + /* Skip starting quote */ + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { + char c = js[parser->pos]; + char d = js[parser->pos + 1]; +// char e = js[parser->pos + 2]; +//printf("jsmn_parse_string: value-%c, pos-%d\n", c,parser->pos); + + /* Quote: end of string */ +// if (c == '\"') { + if (d == '\"') { +// if ((d == '\"')&&((e == ' ')||(e == ','))) { +parser->pos++; +//printf("jsmn_parse_string: end of string\n"); + if (tokens == NULL) { +//printf("jsmn_parse_string: end tokens is NULL\n"); + return 0; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); +//printf("jsmn_parse_string: Allocated tokens \n"); + if (token == NULL) { +//printf("jsmn_parse_string: Allocated tokens is NULL\n"); + parser->pos = start; + return JSMN_ERROR_NOMEM; + } + jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos); +//printf("jsmn_parse_string: Allocated tokens is filled\n"); +//#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +//#endif + return 0; + } + + /* Backslash: Quoted symbol expected */ + if (c == '\\' && parser->pos + 1 < len) { + int i; + parser->pos++; +//printf("jsmn_parse_string: value - %c, POS-%3d \n",c, js[parser->pos]); + switch (js[parser->pos]) { + /* Allowed escaped symbols */ + case '\"': case '/' : case '\\' : case 'b' : + case 'f' : case 'r' : case 'n' : case 't' : + break; + /* Allows escaped symbol \uXXXX */ + case 'u': + parser->pos++; + for(i = 0; i < 4 && parser->pos < len && js[parser->pos] != '\0'; i++) { + /* If it isn't a hex character we have an error */ + if(!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */ + (js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */ + (js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */ + parser->pos = start; + return JSMN_ERROR_INVAL; + } + parser->pos++; + } + parser->pos--; + break; + /* Unexpected symbol */ + default: + parser->pos = start; + return JSMN_ERROR_INVAL; + } + } + } + parser->pos = start; +printf("jsmn_parse_string: exiting with ERROR_PART, pos-%d", parser->pos); + return JSMN_ERROR_PART; +} + +/** + * Parse JSON string and fill tokens. + */ +int jsmn_parse(jsmn_parser *parser, const char *js, size_t len, + jsmntok_t *tokens, unsigned int num_tokens) { + int r; + int i; + jsmntok_t *token; + int count = parser->toknext; + + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { + char c; + jsmntype_t type; + + c = js[parser->pos]; +//printf("jsmn_parse: value of c - %c\n",c); + switch (c) { + case '{': case '[': + count++; + if (tokens == NULL) { + break; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); + if (token == NULL) + return JSMN_ERROR_NOMEM; + if (parser->toksuper != -1) { + tokens[parser->toksuper].size++; +//#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +//#endif + } + token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY); + token->start = parser->pos; + parser->toksuper = parser->toknext - 1; + break; + case '}': case ']': + if (tokens == NULL) + break; + type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY); +//#ifdef JSMN_PARENT_LINKS + if (parser->toknext < 1) { + return JSMN_ERROR_INVAL; + } + token = &tokens[parser->toknext - 1]; + for (;;) { + if (token->start != -1 && token->end == -1) { + if (token->type != type) { + return JSMN_ERROR_INVAL; + } + token->end = parser->pos + 1; + parser->toksuper = token->parent; + break; + } + if (token->parent == -1) { + break; + } + token = &tokens[token->parent]; + } +//#else +// for (i = parser->toknext - 1; i >= 0; i--) { +// token = &tokens[i]; +// if (token->start != -1 && token->end == -1) { +// if (token->type != type) { +// return JSMN_ERROR_INVAL; +// } +// parser->toksuper = -1; +// token->end = parser->pos + 1; +// break; +// } +// } +// /* Error if unmatched closing bracket */ +// if (i == -1) return JSMN_ERROR_INVAL; +// for (; i >= 0; i--) { +// token = &tokens[i]; +// if (token->start != -1 && token->end == -1) { +// parser->toksuper = i; +// break; +// } +// } +//#endif + break; + case '\"': + r = jsmn_parse_string(parser, js, len, tokens, num_tokens); + if (r < 0) return r; + count++; + if (parser->toksuper != -1 && tokens != NULL) + tokens[parser->toksuper].size++; + break; + case '\t' : case '\r' : case '\n' : case ' ': + break; + case ':': + parser->toksuper = parser->toknext - 1; +//printf("jsmn_parse: value of c is :: - %c\n",c); + break; + case ',': + if (tokens != NULL && parser->toksuper != -1 && + tokens[parser->toksuper].type != JSMN_ARRAY && + tokens[parser->toksuper].type != JSMN_OBJECT) { +//#ifdef JSMN_PARENT_LINKS + parser->toksuper = tokens[parser->toksuper].parent; +//#else +// for (i = parser->toknext - 1; i >= 0; i--) { +// if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) { +// if (tokens[i].start != -1 && tokens[i].end == -1) { +// parser->toksuper = i; +// break; +// } +// } +// } +//#endif + } + break; +#ifdef JSMN_STRICT + /* In strict mode primitives are: numbers and booleans */ + case '-': case '0': case '1' : case '2': case '3' : case '4': + case '5': case '6': case '7' : case '8': case '9': + case 't': case 'f': case 'n' : + /* And they must not be keys of the object */ + if (tokens != NULL && parser->toksuper != -1) { + jsmntok_t *t = &tokens[parser->toksuper]; + if (t->type == JSMN_OBJECT || + (t->type == JSMN_STRING && t->size != 0)) { + return JSMN_ERROR_INVAL; + } + } +#else + /* In non-strict mode every unquoted value is a primitive */ + default: +#endif + r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens); + if (r < 0) return r; + count++; + if (parser->toksuper != -1 && tokens != NULL) + tokens[parser->toksuper].size++; + break; + +#ifdef JSMN_STRICT + /* Unexpected char in strict mode */ + default: + return JSMN_ERROR_INVAL; +#endif + } + } + + if (tokens != NULL) { + for (i = parser->toknext - 1; i >= 0; i--) { +//printf("index -%2d, start is %3d, end is %3d\n", i, tokens[i].start, tokens[i].end); + /* Unmatched opened object or array */ + if (tokens[i].start != -1 && tokens[i].end == -1) { + return JSMN_ERROR_PART; + } + } + } + + return count; +} + +/** + * Creates a new parser based over a given buffer with an array of tokens + * available. + */ +void jsmn_init(jsmn_parser *parser) { + parser->pos = 0; + parser->toknext = 0; + parser->toksuper = -1; +} + +int jsoneq(const char *json, jsmntok_t *tok, const char *s) +{ + if (tok->type == JSMN_STRING && (int) strlen(s) == tok->end - tok->start && + strncmp(json + tok->start, s, tok->end - tok->start) == 0) { + return 0; + } + return -1; +} + +void printToken(char * js, jsmntok_t * tokens, int numToken) +{ + for (int i = 1; i < numToken; i++) + { + printf("Token number-%2d, parent-%2d, type-%d size-%2d, parameter -", i, tokens[i].parent, tokens[i].type, tokens[i].size); + if (tokens[i].type == JSMN_STRING || tokens[i].type == JSMN_PRIMITIVE) { + printf("%.*s\n", tokens[i].end - tokens[i].start, js + tokens[i].start); + } else if (tokens[i].type == JSMN_ARRAY) { + printf("[%d elems]\n", tokens[i].size); + } else if (tokens[i].type == JSMN_OBJECT) { + printf("{%d elems}\n", tokens[i].size); + } else { + printf("value?? - "); + TOKEN_PRINT(tokens[i]); + } + } +} + +int getStringToken(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, char * value, int maxValueSize) +{ + int i = 0; + int dpToken = 0; + + memset(value, 0, maxValueSize); + + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], pParam) == 0) + break; + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 1; //Parent token not seen + } + for (i=1; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { + if(jsoneq(js, &tokens[i], param) != 0) + continue; + TOKEN_COPY(js, tokens[i+1], value); + + return 0; //Success + } + } + printf("The parameter %s is not present in JSON file\n", param); + return 2; //parameter not found +} + + +int getStringTokenV2(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, char * gParam,char * value, int maxValueSize) +{ + int i = 0; + int dpToken = 0; + + memset(value, 0, maxValueSize); + + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], gParam) == 0) + break; + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 1; //Grand Parent token not seen + } + + for (i=dpToken; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { + if(jsoneq(js, &tokens[i], pParam) == 0) + break; + } + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 2; //Parent token not seen + } + + for (i=dpToken; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { + if(jsoneq(js, &tokens[i], param) != 0) + continue; + TOKEN_COPY(js, tokens[i+1], value); + + return 0; //Success + } + } + + printf("The parameter %s is not present in JSON file\n", param); + return 2; //parameter not found +} + +int getIntToken(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, int * value) +{ + int i = 0; + int dpToken = 0; + char val[128]; + + memset(val, 0, 128); + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], pParam) == 0) + break; + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 1; //Parent token not seen + } + for (i=1; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { + if(jsoneq(js, &tokens[i], param) != 0) + { + continue; + } + + if(tokens[i+1].type != JSMN_PRIMITIVE) + return 3; //Wrong parameter type + +// printf("INT parameter / Value - %s", param); + TOKEN_COPY(js, tokens[i+1], val); + *value = atoi(val); +// printf(" - %d\n", *value); + + return 0; //success + } + } + printf("The parameter %s is not present in JSON file\n", param); + return 2; //parameter not found +} + +void parseDirectParameters(char * js, jsmntok_t * tokens, int numToken) +{ + int i = 0; + int dpToken = 0; + char param[128]; + char value[128]; + + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], "directParameters") == 0) + break; + } + + if (i < numToken) + { + dpToken = ++i; + } + + for (int i = 1; i < numToken; i++) + { + memset(param, 0, 128); + memset(value, 0, 128); + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { + TOKEN_COPY(js, tokens[i], param); +// printf("parameter / Value - %s", param); + TOKEN_COPY(js, tokens[i+1], value); +// printf(" - %s\n", value); + } + } +} + +int getArrayTokens(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, ARRAYVAL * arrayValue, int * numElements) +{ + int i = 0; + int dpToken = 0; + + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], pParam) == 0) + break; + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 1; //Parent token not seen + } + for (i=1; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { +// printf("value of token %d\n", i); + if(jsoneq(js, &tokens[i], param) != 0) + continue; + + if (tokens[i+1].type == JSMN_ARRAY) + { + *numElements = tokens[i+1].size; +// printf("[%d elems]\n", *numElements); + + for (int k = 0; k < *numElements; k++) + { + TOKEN_COPY(js, tokens[i+2+k], arrayValue[k].arrayString); +// printf(" - %s\n", arrayValue[k].arrayString); + } + return 0; //Success + } + } + } + printf("The parameter %s is not present in JSON file\n", param); + return 2; //parameter not found +} + +int isTokenPresent(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam) +{ + int i = 0; + int dpToken = 0; + char val[128]; + + memset(val, 0, 128); + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], pParam) == 0) + break; + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 1; //Parent token not seen + } + for (i=1; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING) + { + if(jsoneq(js, &tokens[i], param) == 0) + { + return 0; //Token present + } + } + } + printf("The parameter %s is not present in JSON file\n", param); + return 2; //Token Not present +} + +int read_keyVal_params(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, KEYVALRESULT * keyValueResultList, int * numElements) +{ + int i = 0; + int dpToken = 0; + + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], pParam) == 0) + break; + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 1; //Parent token not seen + } + for (i=1; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { +// printf("value of token %d\n", i); + if(jsoneq(js, &tokens[i], param) != 0) + continue; + + if (tokens[i+1].type == JSMN_OBJECT) + { + *numElements = tokens[i+1].size; +// printf("{%d elems}\n", *numElements); + + for (int k = 0; k < *numElements; k++) + { + TOKEN_COPY(js, tokens[i+2+k*2], keyValueResultList[k].keyStr); +// printf("Key - %s", keyValueResultList[k].keyStr); + TOKEN_COPY(js, tokens[i+3+k*2], keyValueResultList[k].valStr); +// printf("Value - %s\n", keyValueResultList[k].valStr); + } + return 0; //Success + } + } + } + printf("The parameter %s is not present in JSON file\n", param); + return 2; //parameter not found +} diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/jsmn.h b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/jsmn.h new file mode 100644 index 0000000..f9d838b --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/jsmn.h @@ -0,0 +1,136 @@ +/*************************************************************************//** + * + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ + +#ifndef __JSMN_H_ +#define __JSMN_H_ + +#include <stddef.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * JSON type identifier. Basic types are: + * o Object + * o Array + * o String + * o Other primitive: number, boolean (true/false) or null + */ +typedef enum { + JSMN_UNDEFINED = 0, + JSMN_OBJECT = 1, + JSMN_ARRAY = 2, + JSMN_STRING = 3, + JSMN_PRIMITIVE = 4 +} jsmntype_t; + +enum jsmnerr { + /* Not enough tokens were provided */ + JSMN_ERROR_NOMEM = -1, + /* Invalid character inside JSON string */ + JSMN_ERROR_INVAL = -2, + /* The string is not a full JSON packet, more bytes expected */ + JSMN_ERROR_PART = -3 +}; + +typedef struct arrayValues { + char arrayString[32]; +} ARRAYVAL; + +typedef struct keyValResult { + char keyStr[80]; + char valStr[250]; + char resultStr[80]; +} KEYVALRESULT; + +/** + * JSON token description. + * @param type type (object, array, string etc.) + * @param start start position in JSON data string + * @param end end position in JSON data string + */ +typedef struct { + jsmntype_t type; + int start; + int end; + int size; +//#ifdef JSMN_PARENT_LINKS + int parent; +//#endif +} jsmntok_t; + +/** + * JSON parser. Contains an array of token blocks available. Also stores + * the string being parsed now and current position in that string + */ +typedef struct { + unsigned int pos; /* offset in the JSON string */ + unsigned int toknext; /* next token to allocate */ + int toksuper; /* superior token node, e.g parent object or array */ +} jsmn_parser; + +#define TOKEN_EQ(t, tok_start, tok_end, tok_type) \ + ((t).start == tok_start \ + && (t).end == tok_end \ + && (t).type == (tok_type)) + +#define TOKEN_STRING(js, t, s) \ + (strncmp(js+(t).start, s, (t).end - (t).start) == 0 \ + && strlen(s) == (t).end - (t).start) + +#define TOKEN_COPY(js, t, s) \ + strncpy(s, js+(t).start, (t).end - (t).start) + +#define TOKEN_PRINT(t) \ + printf("start: %d, end: %d, type: %d, size: %d\n", \ + (t).start, (t).end, (t).type, (t).size) + + +/** + * Create JSON parser over an array of tokens + */ +void jsmn_init(jsmn_parser *parser); + +/** + * Run JSON parser. It parses a JSON data string into and array of tokens, each describing + * a single JSON object. + */ +int jsmn_parse(jsmn_parser *parser, const char *js, size_t len, + jsmntok_t *tokens, unsigned int num_tokens); + +int jsoneq(const char *json, jsmntok_t *tok, const char *s); + +void printToken(char * js, jsmntok_t * tokens, int numToken); + +int getStringToken(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, char * value, int maxValueSize); + +int getIntToken(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, int * value); + +int getArrayTokens(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, ARRAYVAL * arrayValue, int * numElements); + +int isTokenPresent(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam); + +int read_keyVal_params(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, KEYVALRESULT * keyValueResultList, int * numElements); + +int getStringTokenV2(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, char *gParam, char * value, int maxValueSize); + +#ifdef __cplusplus +} +#endif + +#endif /* __JSMN_H_ */ diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/pom.xml b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/pom.xml new file mode 100644 index 0000000..f9f42eb --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/pom.xml @@ -0,0 +1,83 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START========================================== + =================================================================== + Copyright © 2017 AT&T Intellectual Property. All rights reserved. + =================================================================== + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ============LICENSE_END============================================ + + ECOMP and OpenECOMP are trademarks + and service marks of AT&T Intellectual Property. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + +<parent> + <groupId>org.onap.demo.vnf</groupId> + <artifactId>demo-aggregator</artifactId> + <version>1.2.0-SNAPSHOT</version> + <relativePath>../../pom.xml</relativePath> + </parent> + + <modelVersion>4.0.0</modelVersion> + <groupId>org.onap.demo.vnf.ves5</groupId> + <artifactId>ves_vfw_reporting</artifactId> + + <build> + <plugins> + + <plugin> + <artifactId>maven-jar-plugin</artifactId> + <version>2.3.2</version> + <executions> + <execution> + <id>default-jar</id> + <phase>never</phase> + </execution> + </executions> + </plugin> + + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <version>2.5.3</version> + <configuration> + <descriptor>dep.xml</descriptor> + </configuration> + <executions> + <execution> + <id>create-archive</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>exec-maven-plugin</artifactId> + <executions> + <execution> + <phase>none</phase> + </execution> + </executions> + <configuration> + <skip>true</skip> + </configuration> + </plugin> + + </plugins> + </build> + +</project> diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/sample_syslog_event.txt b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/sample_syslog_event.txt new file mode 100644 index 0000000..3a6ec91 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/sample_syslog_event.txt @@ -0,0 +1,30 @@ +{ + "event": { + "commonEventHeader": { + "domain": "syslog", + "eventId": "syslog000000000", + "eventName": "syslog_vFirewall-AT&T_connectionReset", + "eventType": "applicationVnf", + "lastEpochMicrosec": 1548493308853168, + "nfNamingCode": "AFX", + "nfcNamingCode": "AFX", + "priority": "Normal", + "reportingEntityId": "cc305d54-75b4-431b-adb2-eb6b9e541234", + "reportingEntityName": "ibcx0001vm002oam001", + "sequence": 0, + "sourceId": "de305d54-75b4-431b-adb2-eb6b9e546014", + "sourceName": "scfx0001vm002cap001", + "startEpochMicrosec": 1548493278782875, + "version": 3.0 + }, + "syslogFields": { + "eventSourceType": "virtualMachine", + "syslogFacility": 16, + "syslogFieldsVersion": 3.0, + "syslogMsg": "Jan 26 14:31:46 prakash-VirtualBox prakash: peer reset qwerty", + "syslogProc": "vSyslog", + "syslogTag": "peer reset" + } + } +} + diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/syslog_config.json b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/syslog_config.json new file mode 100644 index 0000000..6a434e4 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/syslog_config.json @@ -0,0 +1,20 @@ +{ + "tmp_directParameters": { + "eventName": "syslog_vFirewall-AT&T_connectionReset", + "eventType": "applicationVnf", + "nfcNamingCode": "AFX", + "nfNamingCode": "AFX", + "nfVendorName": "AT&T", + "reportingEntityId": "cc305d54-75b4-431b-adb2-eb6b9e541234", + "reportingEntityName": "ibcx0001vm002oam001", + "sourceId": "de305d54-75b4-431b-adb2-eb6b9e546014", + "sourceName": "scfx0001vm002cap001", + "timeZoneOffset": "UTC-05:30", + "eventSourceType": "virtualMachine", + "syslogProc": "vSyslog", + "syslogTag": "peer reset" + }, + "tmp_indirectParameters": { + "tmp_syslogFile": "/var/log/syslog" + } +} diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/ves_syslog_reporter.c b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/ves_syslog_reporter.c new file mode 100644 index 0000000..b7226e7 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_syslog/ves_syslog_reporter.c @@ -0,0 +1,375 @@ +/*************************************************************************//** + * + * Copyright © 2018 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <pthread.h> +#include <string.h> +#include <netdb.h> +#include <sys/time.h> +#include <sys/stat.h> +#include "jsmn.h" +#include "evel.h" + +#define BUFSIZE 128 +#define MAX_BUFFER_SIZE 4096 +#define MAX_TOKENS 1000 + +void *SyslogThread(void *threadarg); + +unsigned long long epoch_start = 0; + +void report_syslog(char * js, jsmntok_t * tokens, int numToken, char * syslog_tag, char * eName, int srcTyp, char * syslog_msg) +{ + EVENT_HEARTBEAT_FIELD * event = NULL; + EVENT_HEADER* syslog_header = NULL; + EVEL_ERR_CODES evel_rc = EVEL_SUCCESS; + char stringVal[BUFSIZE]; + + char event_id1[10] = "syslog"; + char event_id2[15] = {0}; + int event_id3 = 0; + char event_id[BUFSIZE] = {0}; + + int ret = 0; + /***************************************************************************/ + /* Syslog */ + /***************************************************************************/ + memset(event_id, 0, BUFSIZE); + memset(event_id2, 0, 15); + sprintf(event_id2, "%09d", event_id3++); + strcat(event_id, event_id1); + strcat(event_id, event_id2); + + + event = evel_new_syslog(eName, event_id, srcTyp, syslog_msg, syslog_tag); + + if (event != NULL) + { + syslog_header = (EVENT_HEADER *)event; + + ret = getStringToken(js, tokens, numToken, "syslogProc", "tmp_directParameters", stringVal, BUFSIZE); + if (ret == 0) + evel_syslog_proc_set(event, stringVal); + evel_syslog_facility_set(event, EVEL_SYSLOG_FACILITY_LOCAL0); + ret = getStringToken(js, tokens, numToken, "eventType", "tmp_directParameters", stringVal, BUFSIZE); + if (ret == 0) + evel_header_type_set(&event->header, stringVal); + + struct timeval tv_now; + gettimeofday(&tv_now, NULL); + unsigned long long epoch_now = tv_now.tv_usec + 1000000 * tv_now.tv_sec; + + evel_start_epoch_set(&event->header, epoch_start); + evel_last_epoch_set(&event->header, epoch_now); + epoch_start = epoch_now; + + ret = getStringToken(js, tokens, numToken, "nfcNamingCode", "tmp_directParameters", stringVal, BUFSIZE); + if (ret == 0) + evel_nfcnamingcode_set(&event->header, stringVal); + + ret = getStringToken(js, tokens, numToken, "nfNamingCode", "tmp_directParameters", stringVal, BUFSIZE); + if (ret == 0) + evel_nfnamingcode_set(&event->header, stringVal); + + ret = getStringToken(js, tokens, numToken, "reportingEntityName", "tmp_directParameters", stringVal, BUFSIZE); + if (ret == 0) + evel_reporting_entity_name_set(&event->header, stringVal); + else + { + printf("Missing mandatory parameters - reportingEntityName is not there in tmp_directParameters\n"); + printf("Defaulting reportingEntityName to hostname\n"); + } + + ret = getStringToken(js, tokens, numToken, "reportingEntityId", "tmp_directParameters", stringVal, BUFSIZE); + if (ret == 0) + evel_reporting_entity_id_set(&event->header, stringVal); + + ret = getStringToken(js, tokens, numToken, "sourceId", "tmp_directParameters", stringVal, BUFSIZE); + if (ret == 0) + evel_source_id_set(&event->header, stringVal); + + ret = getStringToken(js, tokens, numToken, "sourceName", "tmp_directParameters", stringVal, BUFSIZE); + if (ret == 0) + evel_source_name_set(&event->header, stringVal); + else + { + printf("Missing mandatory parameters - sourceName is not there in tmp_directParameters\n"); + printf("Defaulting sourceName to hostname\n"); + } + + evel_rc = evel_post_event(syslog_header); + if (evel_rc != EVEL_SUCCESS) + { + EVEL_ERROR("Post failed %d (%s)", evel_rc, evel_error_string()); + } + } + else + { + EVEL_ERROR("New Syslog failed"); + } + printf(" Processed Syslog\n"); +} + +int get_source(char * inStr) +{ + int result = -1; + + if(strcmp(inStr, "other") == 0) + result = EVEL_SOURCE_OTHER; + else if(strcmp(inStr, "router") == 0) + result = EVEL_SOURCE_ROUTER; + else if(strcmp(inStr, "switch") == 0) + result = EVEL_SOURCE_SWITCH; + else if(strcmp(inStr, "host") == 0) + result = EVEL_SOURCE_HOST; + else if(strcmp(inStr, "card") == 0) + result = EVEL_SOURCE_CARD; + else if(strcmp(inStr, "port") == 0) + result = EVEL_SOURCE_PORT; + else if(strcmp(inStr, "slotThreshold") == 0) + result = EVEL_SOURCE_SLOT_THRESHOLD; + else if(strcmp(inStr, "portThreshold") == 0) + result = EVEL_SOURCE_PORT_THRESHOLD; + else if(strcmp(inStr, "virtualMachine") == 0) + result = EVEL_SOURCE_VIRTUAL_MACHINE; + else if(strcmp(inStr, "virtualNetworkFunction") == 0) + result = EVEL_SOURCE_VIRTUAL_NETWORK_FUNCTION; + + return result; +} + + +int main(int argc, char** argv) +{ + char* fqdn = argv[1]; + int port = atoi(argv[2]); + int i=0; + int rc; + pthread_attr_t attr; + pthread_t syslog_thread; + char* fqdn2 = NULL; + int port2 = 0; + + if(argc == 5) + { + fqdn2 = argv[3]; + port2 = atoi(argv[4]); + } + + if (!((argc == 3) || (argc == 5))) + { + fprintf(stderr, "Usage: %s <FQDN>|<IP address> <port> <FQDN>|<IP address> <port> \n", argv[0]); + fprintf(stderr, "OR\n"); + fprintf(stderr, "Usage: %s <FQDN>|<IP address> <port> \n", argv[0]); + exit(-1); + } + + /**************************************************************************/ + /* Initialize */ + /**************************************************************************/ + if(evel_initialize(fqdn, /* FQDN */ + port, /* Port */ + fqdn2, /* Backup FQDN */ + port2, /* Backup port */ + NULL, /* optional path */ + NULL, /* optional topic */ + 100, /* Ring Buffer size */ + 0, /* HTTPS? */ + NULL, /* cert file */ + NULL, /* key file */ + NULL, /* ca info */ + NULL, /* ca file */ + 0, /* verify peer */ + 0, /* verify host */ + "sample1", /* Username */ + "sample1", /* Password */ + "sample1", /* Username2 */ + "sample1", /* Password2 */ + NULL, /* Source ip */ + NULL, /* Source ip2 */ + EVEL_SOURCE_VIRTUAL_MACHINE, /* Source type */ + "vSyslog", /* Role */ + 1)) /* Verbosity */ + { + fprintf(stderr, "\nFailed to initialize the EVEL library!!!\n"); + exit(-1); + } + else + { + printf("\nInitialization completed\n"); + } + + /* Initialize and set thread detached attribute */ + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + printf("Main:Creating thread \n"); + rc = pthread_create(&syslog_thread, NULL, SyslogThread, &i); + if (rc) + { + printf("ERROR; return code from pthread_create() is %d\n", rc); + exit(-1); + } + printf("Main:Created Syslog thread \n"); + + pthread_join(syslog_thread, NULL); + + evel_terminate(); + printf("Terminated\n"); + return 0; +} + +void *SyslogThread(void *threadarg) +{ + + int numToken; + jsmntok_t tokens[MAX_TOKENS]; + char js[MAX_BUFFER_SIZE]; + FILE * fp; + jsmn_parser p; + char ch[BUFSIZE]; + int ret = 0; + char eName[BUFSIZE]; + char eventSrcTyp[BUFSIZE]; + char syslog_tag[BUFSIZE]; + char syslog_msg[8*BUFSIZE]; + char str[8*BUFSIZE]; + char syslog_file[BUFSIZE]; + int srcTyp = 0; + int count = 0; + unsigned long long pos; + unsigned long long prevpos = 0; + + sleep(1); + printf("Running Syslog thread \n"); + fflush(stdout); + + while(1) + { + + FILE * file = fopen("syslog_config.json", "r"); + + memset(js, 0, MAX_BUFFER_SIZE); + memset(ch, 0, BUFSIZE); + + while((fgets(ch, (BUFSIZE-1), file)) !=NULL) + { + strcat(js, ch); + memset(ch, 0, BUFSIZE); + } +// printf("the file content is \n %s \n", js); + + jsmn_init(&p); + numToken = jsmn_parse(&p, js, strlen(js), tokens, MAX_TOKENS); +// printf("Token count-%d\n", numToken); + +// printToken(js,tokens, numToken); + + ret = getStringToken(js, tokens, numToken, "tmp_syslogFile", "tmp_indirectParameters", syslog_file, BUFSIZE); + if (ret != 0) + { + printf("Missing mandatory parameters - tmp_syslogFile is not there in tmp_indirectParameters. Exiting...\n"); + exit(1); + } + + ret = getStringToken(js, tokens, numToken, "syslogTag", "tmp_directParameters", syslog_tag, BUFSIZE); + if (ret != 0) + { + printf("Missing mandatory parameters - syslogTag is not there in tmp_directParameters, exiting..\n"); + exit(1); + } + + ret = getStringToken(js, tokens, numToken, "eventName", "tmp_directParameters", eName, BUFSIZE); + if (ret != 0) + { + printf("Missing mandatory parameters - eventName is not there in tmp_directParameters. Exiting...\n"); + exit(1); + } + + ret = getStringToken(js, tokens, numToken, "eventSourceType", "tmp_directParameters", eventSrcTyp, BUFSIZE); + if (ret != 0) + { + printf("Missing mandatory parameters - eventSourceType is not there in tmp_directParameters, exiting..\n"); + exit(1); + } + srcTyp = get_source(eventSrcTyp); + if(srcTyp == -1) + { + printf("Fault eventSourceType value is not matching, eventSourceType-%s \n", eventSrcTyp); + exit(1); + } + + // Open file in read mode + fp = fopen(syslog_file, "r"); + if (fp == NULL) + { + printf("Error while opening file"); + exit(EXIT_FAILURE); + } + + memset(str, 0, 8*BUFSIZE); + if (fseek(fp, 0, SEEK_END)) + perror("fseek() failed"); + else + { + // pos will contain no. of chars in input file. + int n = 8; + pos = ftell(fp); + + // search for '\n' characters + while (pos>prevpos) + { + // Move 'pos' away from end of file. + if (!fseek(fp, --pos, SEEK_SET)) + { + if (fgetc(fp) == '\n') + + // stop reading when n newlines is found + if (count++ == n) + break; + } + else + perror("fseek() failed"); + } + //printf("pos %d prevpos %d\n",pos,prevpos); + + // print last n lines + prevpos = pos; + + while (fgets(str, sizeof(str), fp)) + { + char * position; + // printf("str is - %s\n", str); + if ((position=strchr(str, '\n')) != NULL) + *position = '\0'; + if(strstr(str, syslog_tag) && !strstr(str,"EVEL") && !strstr(str,"commonEventHeader") && !strstr(str,"syslogMsg") && !strstr(str,"syslogTag")) + { + memset(syslog_msg, 0, 8*BUFSIZE); + memcpy(syslog_msg, str, 8*BUFSIZE); + report_syslog(js, tokens, numToken, syslog_tag, eName, srcTyp, syslog_msg); + } + + prevpos += strlen(str); + //printf("new prevpos is %d, size of str is %d\n", prevpos, strlen(str)); + } + } + sleep(3); + } +} + diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/LICENSE.TXT b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/LICENSE.TXT new file mode 100644 index 0000000..16285cd --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/LICENSE.TXT @@ -0,0 +1,22 @@ +/* + * ============LICENSE_START========================================== + * =================================================================== + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * =================================================================== + * Unless otherwise specified, all software contained herein is + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END============================================ + * + * ECOMP is trademark and service mark of AT&T Intellectual Property. + * + */ diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/Makefile b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/Makefile new file mode 100644 index 0000000..9d1812f --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/Makefile @@ -0,0 +1,52 @@ +############################################################################# +# +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +############################################################################# + +CC=gcc +ARCH=$(shell getconf LONG_BIT) +CODE_ROOT=$(CURDIR)/../.. +#CODE_ROOT=../code/evel-library +LIBS_DIR=$(CODE_ROOT)/libs/x86_$(ARCH) +#LIBS_DIR=/usr/lib +INCLUDE_DIR= -I $(CODE_ROOT)/code/evel_library -I . + +#****************************************************************************** +# Standard compiler flags. * +#****************************************************************************** +CPPFLAGS= +CFLAGS=-Wall -g -fPIC +FILEOBJLIST= jsmn.o vpp_measurement_reporter.o + +all: vpp_measurement_reporter + +clean: + rm -f *.o vpp_measurement_reporter + +%.o: %.c + $(CC) $(CPPFLAGS) $(CFLAGS) $(INCLUDE_DIR) -c $< -o $@ + +jsmn.o: jsmn.c jsmn.h +vpp_measurement_reporter.o: vpp_measurement_reporter.c + +vpp_measurement_reporter: $(FILEOBJLIST) + $(CC) $(CPPFLAGS) $(CFLAGS) -o vpp_measurement_reporter \ + -L $(LIBS_DIR) \ + $(FILEOBJLIST) \ + -lpthread \ + -level \ + -lcurl + + diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/README.md b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/README.md new file mode 100644 index 0000000..6921cdc --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/README.md @@ -0,0 +1,37 @@ + +PROJECT DESCRIPTION + +--- +This project contains the source code and scripts for the periodic generation of measurement events. The folder contains: + + - README.md: this file. + + - LICENSE.TXT: the license text. + + - vpp_measurement_reporter.c and other .c files: source code that uses the ECOMP Vendor Event Listener Library (VES) to generate the measurement events. Measurement event is generated periodically on each of the interfaces. It gives the number of bytes/packets that transmitted/received. The application reads meas_config.json file for parameter values and poppulate the measurement event. If eventName parameter value is not given, the application terminates. If reportingEntityName and sourceName parameter values are not given, then it gets the hostname and poppulates it. If measurementInterval is not given, it defaults to 60 seconds. + + - Makefile: makefile that compiles vpp_measurement_reporter.c and generates vpp_measurement_reporter binary. + + - go-client.sh/go-client_2_collectors.sh: bash script that starts up the vpp_measurement_reporter. It reads input parameters like DCAE IP address and port from configuration files contained in /opt/config. Based on the collector configuration, use go-client.sh for single collector configuration, or use go-client_2_collectors.sh for 2 collectors configuration. + + +USAGE +----- + +Update the configuration files with proper parameters values so that events generated would contain those values + +To run the vpp_measurement_reporter in single collector configuration, please execute the following steps: + + - Make the go-client.sh script executable + chmod +x go-client.sh + + - Run the go-client.sh script + ./go-client.sh + +For 2 collectors configuration, please execute following steps: + + - Make the go-client.sh script executable + chmod +x go-client_2_collectors.sh + + - Run the go-client_2_collectors.sh script + ./go-client_2_collectors.sh diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/dep.xml b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/dep.xml new file mode 100644 index 0000000..fc18229 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/dep.xml @@ -0,0 +1,25 @@ +<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd"> + <id>demo</id> + <formats> + <format>tar.gz</format> + </formats> + <fileSets> + + <fileSet> + <directory>.</directory> + <outputDirectory>/</outputDirectory> + <includes> + <include>*.sh</include> + <include>*.md</include> + <include>*.TXT</include> + <include>*.c</include> + <include>Makefile</include> + </includes> + </fileSet> + + </fileSets> +</assembly> + + diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/go-client.sh b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/go-client.sh new file mode 100755 index 0000000..b2b3a08 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/go-client.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +export LD_LIBRARY_PATH="/opt/VES/evel/evel-library/libs/x86_64/" +DCAE_COLLECTOR_IP=$(cat /opt/config/dcae_collector_ip.txt) +DCAE_COLLECTOR_PORT=$(cat /opt/config/dcae_collector_port.txt) +./vpp_measurement_reporter $DCAE_COLLECTOR_IP $DCAE_COLLECTOR_PORT diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/go-client_2_collectors.sh b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/go-client_2_collectors.sh new file mode 100755 index 0000000..65f7126 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/go-client_2_collectors.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +export LD_LIBRARY_PATH="/opt/VES/evel/evel-library/libs/x86_64/" + +#Usage for 2 collectors: +#./vpp_measurement_reporter <FQDN>|<IP address> <port> <FQDN>|<IP address> <port> + +DCAE_COLLECTOR_IP=$(cat /opt/config/dcae_collector_ip.txt) +DCAE_COLLECTOR_PORT=$(cat /opt/config/dcae_collector_port.txt) +DCAE_COLLECTOR_IP2=$(cat /opt/config/dcae_collector_ip2.txt) +DCAE_COLLECTOR_PORT2=$(cat /opt/config/dcae_collector_port2.txt) +./vpp_measurement_reporter $DCAE_COLLECTOR_IP $DCAE_COLLECTOR_PORT $DCAE_COLLECTOR_IP2 $DCAE_COLLECTOR_PORT2 diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/jsmn.c b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/jsmn.c new file mode 100644 index 0000000..1d72ba4 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/jsmn.c @@ -0,0 +1,672 @@ +/*************************************************************************//** + * + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * + * Unless otherwise specified, all software contained herein is + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + ****************************************************************************/ +#include<stdio.h> +#include<stdlib.h> +#include<string.h> +#include "jsmn.h" + +/** + * Allocates a fresh unused token from the token pull. + */ +static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser, + jsmntok_t *tokens, size_t num_tokens) { + jsmntok_t *tok; + if (parser->toknext >= num_tokens) { + return NULL; + } + tok = &tokens[parser->toknext++]; + tok->start = tok->end = -1; + tok->size = 0; +//#ifdef JSMN_PARENT_LINKS + tok->parent = -1; +//#endif + return tok; +} + +/** + * Fills token type and boundaries. + */ +static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type, + int start, int end) { +//printf("jsmn_fill_token:: start-%d, end-%d\n", start, end); + token->type = type; + token->start = start; + token->end = end; + token->size = 0; +} + +/** + * Fills next available token with JSON primitive. + */ +static int jsmn_parse_primitive(jsmn_parser *parser, const char *js, + size_t len, jsmntok_t *tokens, size_t num_tokens) { + jsmntok_t *token; + int start; + + start = parser->pos; + + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { +//printf("jsmn_parse_primitive:: the char is - %c\n", js[parser->pos]); + switch (js[parser->pos]) { +#ifndef JSMN_STRICT + /* In strict mode primitive must be followed by "," or "}" or "]" */ + case ':': +#endif + case '\t' : case '\r' : case '\n' : case ' ' : + case ',' : case ']' : case '}' : + goto found; + } + if (js[parser->pos] < 32 || js[parser->pos] >= 127) { + parser->pos = start; + return JSMN_ERROR_INVAL; + } + } +#ifdef JSMN_STRICT + /* In strict mode primitive must be followed by a comma/object/array */ + parser->pos = start; + return JSMN_ERROR_PART; +#endif + +found: + if (tokens == NULL) { + parser->pos--; + return 0; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); + if (token == NULL) { + parser->pos = start; + return JSMN_ERROR_NOMEM; + } + jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos); +//#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +//#endif + parser->pos--; + return 0; +} + +/** + * Fills next token with JSON string. + */ +static int jsmn_parse_string(jsmn_parser *parser, const char *js, + size_t len, jsmntok_t *tokens, size_t num_tokens) { + jsmntok_t *token; + + int start = parser->pos; + + parser->pos++; + + /* Skip starting quote */ + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { + char c = js[parser->pos]; + char d = js[parser->pos + 1]; +// char e = js[parser->pos + 2]; +//printf("jsmn_parse_string: value-%c, pos-%d\n", c,parser->pos); + + /* Quote: end of string */ +// if (c == '\"') { + if (d == '\"') { +// if ((d == '\"')&&((e == ' ')||(e == ','))) { +parser->pos++; +//printf("jsmn_parse_string: end of string\n"); + if (tokens == NULL) { +//printf("jsmn_parse_string: end tokens is NULL\n"); + return 0; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); +//printf("jsmn_parse_string: Allocated tokens \n"); + if (token == NULL) { +//printf("jsmn_parse_string: Allocated tokens is NULL\n"); + parser->pos = start; + return JSMN_ERROR_NOMEM; + } + jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos); +//printf("jsmn_parse_string: Allocated tokens is filled\n"); +//#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +//#endif + return 0; + } + + /* Backslash: Quoted symbol expected */ + if (c == '\\' && parser->pos + 1 < len) { + int i; + parser->pos++; +//printf("jsmn_parse_string: value - %c, POS-%3d \n",c, js[parser->pos]); + switch (js[parser->pos]) { + /* Allowed escaped symbols */ + case '\"': case '/' : case '\\' : case 'b' : + case 'f' : case 'r' : case 'n' : case 't' : + break; + /* Allows escaped symbol \uXXXX */ + case 'u': + parser->pos++; + for(i = 0; i < 4 && parser->pos < len && js[parser->pos] != '\0'; i++) { + /* If it isn't a hex character we have an error */ + if(!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */ + (js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */ + (js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */ + parser->pos = start; + return JSMN_ERROR_INVAL; + } + parser->pos++; + } + parser->pos--; + break; + /* Unexpected symbol */ + default: + parser->pos = start; + return JSMN_ERROR_INVAL; + } + } + } + parser->pos = start; +printf("jsmn_parse_string: exiting with ERROR_PART, pos-%d", parser->pos); + return JSMN_ERROR_PART; +} + +/** + * Parse JSON string and fill tokens. + */ +int jsmn_parse(jsmn_parser *parser, const char *js, size_t len, + jsmntok_t *tokens, unsigned int num_tokens) { + int r; + int i; + jsmntok_t *token; + int count = parser->toknext; + + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { + char c; + jsmntype_t type; + + c = js[parser->pos]; +//printf("jsmn_parse: value of c - %c\n",c); + switch (c) { + case '{': case '[': + count++; + if (tokens == NULL) { + break; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); + if (token == NULL) + return JSMN_ERROR_NOMEM; + if (parser->toksuper != -1) { + tokens[parser->toksuper].size++; +//#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +//#endif + } + token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY); + token->start = parser->pos; + parser->toksuper = parser->toknext - 1; + break; + case '}': case ']': + if (tokens == NULL) + break; + type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY); +//#ifdef JSMN_PARENT_LINKS + if (parser->toknext < 1) { + return JSMN_ERROR_INVAL; + } + token = &tokens[parser->toknext - 1]; + for (;;) { + if (token->start != -1 && token->end == -1) { + if (token->type != type) { + return JSMN_ERROR_INVAL; + } + token->end = parser->pos + 1; + parser->toksuper = token->parent; + break; + } + if (token->parent == -1) { + break; + } + token = &tokens[token->parent]; + } +//#else +// for (i = parser->toknext - 1; i >= 0; i--) { +// token = &tokens[i]; +// if (token->start != -1 && token->end == -1) { +// if (token->type != type) { +// return JSMN_ERROR_INVAL; +// } +// parser->toksuper = -1; +// token->end = parser->pos + 1; +// break; +// } +// } +// /* Error if unmatched closing bracket */ +// if (i == -1) return JSMN_ERROR_INVAL; +// for (; i >= 0; i--) { +// token = &tokens[i]; +// if (token->start != -1 && token->end == -1) { +// parser->toksuper = i; +// break; +// } +// } +//#endif + break; + case '\"': + r = jsmn_parse_string(parser, js, len, tokens, num_tokens); + if (r < 0) return r; + count++; + if (parser->toksuper != -1 && tokens != NULL) + tokens[parser->toksuper].size++; + break; + case '\t' : case '\r' : case '\n' : case ' ': + break; + case ':': + parser->toksuper = parser->toknext - 1; +//printf("jsmn_parse: value of c is :: - %c\n",c); + break; + case ',': + if (tokens != NULL && parser->toksuper != -1 && + tokens[parser->toksuper].type != JSMN_ARRAY && + tokens[parser->toksuper].type != JSMN_OBJECT) { +//#ifdef JSMN_PARENT_LINKS + parser->toksuper = tokens[parser->toksuper].parent; +//#else +// for (i = parser->toknext - 1; i >= 0; i--) { +// if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) { +// if (tokens[i].start != -1 && tokens[i].end == -1) { +// parser->toksuper = i; +// break; +// } +// } +// } +//#endif + } + break; +#ifdef JSMN_STRICT + /* In strict mode primitives are: numbers and booleans */ + case '-': case '0': case '1' : case '2': case '3' : case '4': + case '5': case '6': case '7' : case '8': case '9': + case 't': case 'f': case 'n' : + /* And they must not be keys of the object */ + if (tokens != NULL && parser->toksuper != -1) { + jsmntok_t *t = &tokens[parser->toksuper]; + if (t->type == JSMN_OBJECT || + (t->type == JSMN_STRING && t->size != 0)) { + return JSMN_ERROR_INVAL; + } + } +#else + /* In non-strict mode every unquoted value is a primitive */ + default: +#endif + r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens); + if (r < 0) return r; + count++; + if (parser->toksuper != -1 && tokens != NULL) + tokens[parser->toksuper].size++; + break; + +#ifdef JSMN_STRICT + /* Unexpected char in strict mode */ + default: + return JSMN_ERROR_INVAL; +#endif + } + } + + if (tokens != NULL) { + for (i = parser->toknext - 1; i >= 0; i--) { +//printf("index -%2d, start is %3d, end is %3d\n", i, tokens[i].start, tokens[i].end); + /* Unmatched opened object or array */ + if (tokens[i].start != -1 && tokens[i].end == -1) { + return JSMN_ERROR_PART; + } + } + } + + return count; +} + +/** + * Creates a new parser based over a given buffer with an array of tokens + * available. + */ +void jsmn_init(jsmn_parser *parser) { + parser->pos = 0; + parser->toknext = 0; + parser->toksuper = -1; +} + +int jsoneq(const char *json, jsmntok_t *tok, const char *s) +{ + if (tok->type == JSMN_STRING && (int) strlen(s) == tok->end - tok->start && + strncmp(json + tok->start, s, tok->end - tok->start) == 0) { + return 0; + } + return -1; +} + +void printToken(char * js, jsmntok_t * tokens, int numToken) +{ + for (int i = 1; i < numToken; i++) + { + printf("Token number-%2d, parent-%2d, type-%d size-%2d, parameter -", i, tokens[i].parent, tokens[i].type, tokens[i].size); + if (tokens[i].type == JSMN_STRING || tokens[i].type == JSMN_PRIMITIVE) { + printf("%.*s\n", tokens[i].end - tokens[i].start, js + tokens[i].start); + } else if (tokens[i].type == JSMN_ARRAY) { + printf("[%d elems]\n", tokens[i].size); + } else if (tokens[i].type == JSMN_OBJECT) { + printf("{%d elems}\n", tokens[i].size); + } else { + printf("value?? - "); + TOKEN_PRINT(tokens[i]); + } + } +} + +int getStringToken(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, char * value, int maxValueSize) +{ + int i = 0; + int dpToken = 0; + + memset(value, 0, maxValueSize); + + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], pParam) == 0) + break; + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 1; //Parent token not seen + } + for (i=1; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { + if(jsoneq(js, &tokens[i], param) != 0) + continue; + TOKEN_COPY(js, tokens[i+1], value); + + return 0; //Success + } + } + printf("The parameter %s is not present in JSON file\n", param); + return 2; //parameter not found +} + + +int getStringTokenV2(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, char * gParam,char * value, int maxValueSize) +{ + int i = 0; + int dpToken = 0; + + memset(value, 0, maxValueSize); + + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], gParam) == 0) + break; + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 1; //Grand Parent token not seen + } + + for (i=dpToken; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { + if(jsoneq(js, &tokens[i], pParam) == 0) + break; + } + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 2; //Parent token not seen + } + + for (i=dpToken; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { + if(jsoneq(js, &tokens[i], param) != 0) + continue; + TOKEN_COPY(js, tokens[i+1], value); + + return 0; //Success + } + } + + printf("The parameter %s is not present in JSON file\n", param); + return 2; //parameter not found +} + +int getIntToken(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, int * value) +{ + int i = 0; + int dpToken = 0; + char val[128]; + + memset(val, 0, 128); + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], pParam) == 0) + break; + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 1; //Parent token not seen + } + for (i=1; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { + if(jsoneq(js, &tokens[i], param) != 0) + { + continue; + } + + if(tokens[i+1].type != JSMN_PRIMITIVE) + return 3; //Wrong parameter type + +// printf("INT parameter / Value - %s", param); + TOKEN_COPY(js, tokens[i+1], val); + *value = atoi(val); +// printf(" - %d\n", *value); + + return 0; //success + } + } + printf("The parameter %s is not present in JSON file\n", param); + return 2; //parameter not found +} + +void parseDirectParameters(char * js, jsmntok_t * tokens, int numToken) +{ + int i = 0; + int dpToken = 0; + char param[128]; + char value[128]; + + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], "directParameters") == 0) + break; + } + + if (i < numToken) + { + dpToken = ++i; + } + + for (int i = 1; i < numToken; i++) + { + memset(param, 0, 128); + memset(value, 0, 128); + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { + TOKEN_COPY(js, tokens[i], param); +// printf("parameter / Value - %s", param); + TOKEN_COPY(js, tokens[i+1], value); +// printf(" - %s\n", value); + } + } +} + +int getArrayTokens(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, ARRAYVAL * arrayValue, int * numElements) +{ + int i = 0; + int dpToken = 0; + + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], pParam) == 0) + break; + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 1; //Parent token not seen + } + for (i=1; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { +// printf("value of token %d\n", i); + if(jsoneq(js, &tokens[i], param) != 0) + continue; + + if (tokens[i+1].type == JSMN_ARRAY) + { + *numElements = tokens[i+1].size; +// printf("[%d elems]\n", *numElements); + + for (int k = 0; k < *numElements; k++) + { + TOKEN_COPY(js, tokens[i+2+k], arrayValue[k].arrayString); +// printf(" - %s\n", arrayValue[k].arrayString); + } + return 0; //Success + } + } + } + printf("The parameter %s is not present in JSON file\n", param); + return 2; //parameter not found +} + +int isTokenPresent(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam) +{ + int i = 0; + int dpToken = 0; + char val[128]; + + memset(val, 0, 128); + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], pParam) == 0) + break; + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 1; //Parent token not seen + } + for (i=1; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING) + { + if(jsoneq(js, &tokens[i], param) == 0) + { + return 0; //Token present + } + } + } + printf("The parameter %s is not present in JSON file\n", param); + return 2; //Token Not present +} + +int read_keyVal_params(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, KEYVALRESULT * keyValueResultList, int * numElements) +{ + int i = 0; + int dpToken = 0; + + for (i = 1; i < numToken; i++) + { + if(jsoneq(js, &tokens[i], pParam) == 0) + break; + } + if (i < numToken) + { + dpToken = ++i; + } + else + { + printf("The parameter %s is not present in JSON file\n", pParam); + return 1; //Parent token not seen + } + for (i=1; i < numToken; i++) + { + if (tokens[i].parent == dpToken && tokens[i].type == JSMN_STRING && tokens[i].size == 1) + { +// printf("value of token %d\n", i); + if(jsoneq(js, &tokens[i], param) != 0) + continue; + + if (tokens[i+1].type == JSMN_OBJECT) + { + *numElements = tokens[i+1].size; +// printf("{%d elems}\n", *numElements); + + for (int k = 0; k < *numElements; k++) + { + TOKEN_COPY(js, tokens[i+2+k*2], keyValueResultList[k].keyStr); +// printf("Key - %s", keyValueResultList[k].keyStr); + TOKEN_COPY(js, tokens[i+3+k*2], keyValueResultList[k].valStr); +// printf("Value - %s\n", keyValueResultList[k].valStr); + } + return 0; //Success + } + } + } + printf("The parameter %s is not present in JSON file\n", param); + return 2; //parameter not found +} diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/jsmn.h b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/jsmn.h new file mode 100644 index 0000000..f9d838b --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/jsmn.h @@ -0,0 +1,136 @@ +/*************************************************************************//** + * + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ + +#ifndef __JSMN_H_ +#define __JSMN_H_ + +#include <stddef.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * JSON type identifier. Basic types are: + * o Object + * o Array + * o String + * o Other primitive: number, boolean (true/false) or null + */ +typedef enum { + JSMN_UNDEFINED = 0, + JSMN_OBJECT = 1, + JSMN_ARRAY = 2, + JSMN_STRING = 3, + JSMN_PRIMITIVE = 4 +} jsmntype_t; + +enum jsmnerr { + /* Not enough tokens were provided */ + JSMN_ERROR_NOMEM = -1, + /* Invalid character inside JSON string */ + JSMN_ERROR_INVAL = -2, + /* The string is not a full JSON packet, more bytes expected */ + JSMN_ERROR_PART = -3 +}; + +typedef struct arrayValues { + char arrayString[32]; +} ARRAYVAL; + +typedef struct keyValResult { + char keyStr[80]; + char valStr[250]; + char resultStr[80]; +} KEYVALRESULT; + +/** + * JSON token description. + * @param type type (object, array, string etc.) + * @param start start position in JSON data string + * @param end end position in JSON data string + */ +typedef struct { + jsmntype_t type; + int start; + int end; + int size; +//#ifdef JSMN_PARENT_LINKS + int parent; +//#endif +} jsmntok_t; + +/** + * JSON parser. Contains an array of token blocks available. Also stores + * the string being parsed now and current position in that string + */ +typedef struct { + unsigned int pos; /* offset in the JSON string */ + unsigned int toknext; /* next token to allocate */ + int toksuper; /* superior token node, e.g parent object or array */ +} jsmn_parser; + +#define TOKEN_EQ(t, tok_start, tok_end, tok_type) \ + ((t).start == tok_start \ + && (t).end == tok_end \ + && (t).type == (tok_type)) + +#define TOKEN_STRING(js, t, s) \ + (strncmp(js+(t).start, s, (t).end - (t).start) == 0 \ + && strlen(s) == (t).end - (t).start) + +#define TOKEN_COPY(js, t, s) \ + strncpy(s, js+(t).start, (t).end - (t).start) + +#define TOKEN_PRINT(t) \ + printf("start: %d, end: %d, type: %d, size: %d\n", \ + (t).start, (t).end, (t).type, (t).size) + + +/** + * Create JSON parser over an array of tokens + */ +void jsmn_init(jsmn_parser *parser); + +/** + * Run JSON parser. It parses a JSON data string into and array of tokens, each describing + * a single JSON object. + */ +int jsmn_parse(jsmn_parser *parser, const char *js, size_t len, + jsmntok_t *tokens, unsigned int num_tokens); + +int jsoneq(const char *json, jsmntok_t *tok, const char *s); + +void printToken(char * js, jsmntok_t * tokens, int numToken); + +int getStringToken(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, char * value, int maxValueSize); + +int getIntToken(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, int * value); + +int getArrayTokens(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, ARRAYVAL * arrayValue, int * numElements); + +int isTokenPresent(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam); + +int read_keyVal_params(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, KEYVALRESULT * keyValueResultList, int * numElements); + +int getStringTokenV2(char * js, jsmntok_t * tokens, int numToken, char * param, char * pParam, char *gParam, char * value, int maxValueSize); + +#ifdef __cplusplus +} +#endif + +#endif /* __JSMN_H_ */ diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/meas_config.json b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/meas_config.json new file mode 100644 index 0000000..bbd3e45 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/meas_config.json @@ -0,0 +1,50 @@ +{ + "tmp_directParameters": { + "eventName": "Measurement_vFirewall-AT&T_nicPerformance", + "eventType": "applicationVnf", + "nfcNamingCode": "AFX", + "nfNamingCode": "AFX", + "priority": "Low", + "reportingEntityId": "cc305d54-75b4-431b-adb2-eb6b9e541234", + "reportingEntityName": "ibcx0001vm002oam001", + "sourceId": "de305d54-75b4-431b-adb2-eb6b9e546014", + "sourceName": "scfx0001vm002cap001", + "measurementInterval": 20, + "tmp_device": ["lo", "enp0s3", "docker0"] + + }, + "tmp_indirectParameters": { + "tmp_init":{ + "tmp_t0BytesIn": "sudo cat /proc/net/dev | grep $tmp_device | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f2", + "tmp_t0BytesOut": "sudo cat /proc/net/dev | grep $tmp_device | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f10", + "tmp_t0PacketsIn": "sudo cat /proc/net/dev | grep $tmp_device | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f3", + "tmp_t0PacketsOut": "sudo cat /proc/net/dev | grep $tmp_device | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f11" + }, + "vNicPerformance": { + "tmp_vnic_command": { + "tmp_t1BytesIn": "sudo cat /proc/net/dev | grep $tmp_device | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f2", + "tmp_t1BytesOut": "sudo cat /proc/net/dev | grep $tmp_device | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f10", + "tmp_t1PacketsIn": "sudo cat /proc/net/dev | grep $tmp_device | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f3", + "tmp_t1PacketsOut": "sudo cat /proc/net/dev | grep $tmp_device | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f11" + }, + "receivedOctetsDelta": "$(tmp_t1BytesIn - tmp_t0BytesIn)", + "receivedTotalPacketsDelta": "$(tmp_t1PacketsIn - tmp_t0PacketsIn)", + "transmittedOctetsDelta": "$(tmp_t1BytesOut - tmp_t0BytesOut)", + "transmittedTotalPacketsDelta": "$(tmp_t1PacketsOut - tmp_t0PacketsOut)", + "valuesAreSuspect": "true", + "vNicIdentifier": "$tmp_device" + } + "cpuUsage": { + "tmp_cpuuse_command": { + "tmp_cpuUseCmd": "/usr/bin/top -bn 2 -d 0.01 | grep '^%Cpu' | tail -n 1 | cut -d ':' -f2", + "tmp_cpuIdle": "/usr/bin/top -bn 2 -d 0.01 | grep '^%Cpu' | tail -n 1 |cut -d ':' -f2 | cut -d ',' -f4 | cut -b 1-5", + "tmp_cpuUsageSystem": "/usr/bin/top -bn 2 -d 0.01 | grep '^%Cpu' | tail -n 1 |cut -d ':' -f2 | cut -d ',' -f2 | cut -b 1-5", + "tmp_cpuUsageUser": "/usr/bin/top -bn 2 -d 0.01 | grep '^%Cpu' | tail -n 1 |cut -d ':' -f2 | cut -d ',' -f1 | cut -b 1-5" + }, + "cpuIdentifier": "Cpu1", + "cpuIdle": "$tmp_cpuIdle", + "cpuUsageSystem": "$tmp_cpuUsageSystem", + "cpuUsageUser": "$tmp_cpuUsageUser" + } + } +} diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/pom.xml b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/pom.xml new file mode 100644 index 0000000..f9f42eb --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/pom.xml @@ -0,0 +1,83 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ============LICENSE_START========================================== + =================================================================== + Copyright © 2017 AT&T Intellectual Property. All rights reserved. + =================================================================== + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ============LICENSE_END============================================ + + ECOMP and OpenECOMP are trademarks + and service marks of AT&T Intellectual Property. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + +<parent> + <groupId>org.onap.demo.vnf</groupId> + <artifactId>demo-aggregator</artifactId> + <version>1.2.0-SNAPSHOT</version> + <relativePath>../../pom.xml</relativePath> + </parent> + + <modelVersion>4.0.0</modelVersion> + <groupId>org.onap.demo.vnf.ves5</groupId> + <artifactId>ves_vfw_reporting</artifactId> + + <build> + <plugins> + + <plugin> + <artifactId>maven-jar-plugin</artifactId> + <version>2.3.2</version> + <executions> + <execution> + <id>default-jar</id> + <phase>never</phase> + </execution> + </executions> + </plugin> + + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <version>2.5.3</version> + <configuration> + <descriptor>dep.xml</descriptor> + </configuration> + <executions> + <execution> + <id>create-archive</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>exec-maven-plugin</artifactId> + <executions> + <execution> + <phase>none</phase> + </execution> + </executions> + <configuration> + <skip>true</skip> + </configuration> + </plugin> + + </plugins> + </build> + +</project> diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/sample_measurement_event.txt b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/sample_measurement_event.txt new file mode 100644 index 0000000..e66fa19 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/sample_measurement_event.txt @@ -0,0 +1,62 @@ +{ + "event": { + "commonEventHeader": { + "domain": "measurementsForVfScaling", + "eventId": "mvfs000000002", + "eventName": "Measurement_vFirewall-AT&T_nicPerformance", + "eventType": "applicationVnf", + "lastEpochMicrosec": 1548492802113484, + "nfNamingCode": "AFX", + "nfcNamingCode": "AFX", + "priority": "Normal", + "reportingEntityId": "cc305d54-75b4-431b-adb2-eb6b9e541234", + "reportingEntityName": "ibcx0001vm002oam001", + "sequence": 0, + "sourceId": "de305d54-75b4-431b-adb2-eb6b9e546014", + "sourceName": "scfx0001vm002cap001", + "startEpochMicrosec": 1548492780026901, + "version": 3.0 + }, + "measurementsForVfScalingFields": { + "cpuUsageArray": [ + { + "cpuIdentifier": "Cpu1", + "cpuIdle": 33.3, + "cpuUsageSystem": 0.0, + "cpuUsageUser": 66.7, + "percentUsage": 0.0 + } + ], + "measurementInterval": 20, + "measurementsForVfScalingVersion": 2.0, + "requestRate": 0, + "vNicPerformanceArray": [ + { + "receivedOctetsDelta": 2721.0, + "receivedTotalPacketsDelta": 18.0, + "transmittedOctetsDelta": 2721.0, + "transmittedTotalPacketsDelta": 18.0, + "vNicIdentifier": "lo", + "valuesAreSuspect": "true" + }, + { + "receivedOctetsDelta": 531.0, + "receivedTotalPacketsDelta": 6.0, + "transmittedOctetsDelta": 525.0, + "transmittedTotalPacketsDelta": 6.0, + "vNicIdentifier": "enp0s3", + "valuesAreSuspect": "true" + }, + { + "receivedOctetsDelta": 0.0, + "receivedTotalPacketsDelta": 0.0, + "transmittedOctetsDelta": 0.0, + "transmittedTotalPacketsDelta": 0.0, + "vNicIdentifier": "docker0", + "valuesAreSuspect": "true" + } + ] + } + } +} + diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/vpp_measurement_reporter.c b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/vpp_measurement_reporter.c new file mode 100644 index 0000000..15b20d1 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/VESreporting_vFW/vpp_measurement_reporter.c @@ -0,0 +1,685 @@ +/*************************************************************************//** + * + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <pthread.h> +#include <string.h> +#include <netdb.h> +#include <sys/time.h> +#include <sys/stat.h> +#include "jsmn.h" +#include "evel.h" + +#define BUFSIZE 128 +#define MAX_BUFFER_SIZE 4096 +#define MAX_TOKENS 1000 +#define MAX_INTERFACES 40 + +void *MeasThread(void *threadarg); + +typedef struct dummy_vpp_metrics_struct { + int curr_bytes_in; + int curr_bytes_out; + int curr_packets_in; + int curr_packets_out; + int last_bytes_in; + int last_bytes_out; + int last_packets_in; + int last_packets_out; +} vpp_metrics_struct; + +typedef struct linkstat { + + char linkname[32]; + char linkdescr[64]; + char linkmode[64]; + int speedmbps; + +}LINKSTAT; + +vpp_metrics_struct meas_intfstat[MAX_INTERFACES]; +LINKSTAT meas_linkstat[MAX_INTERFACES]; + +unsigned long long epoch_start = 0; + +int format_val_params(KEYVALRESULT * keyValArray, int numElements, const char *replace, const char *search) +{ + char *sp; + int i =0; + int search_len; + int replace_len; + int tail_len; + + for (i=0; i<numElements; i++) + { + if ((sp = strstr(keyValArray[i].valStr, search)) == NULL) { + printf("\n String not found\n"); + return 1; //Error search string not found + } + + search_len = strlen(search); + replace_len = strlen(replace); + tail_len = strlen(sp+search_len); + memmove(sp+replace_len,sp+search_len,tail_len+1); + memcpy(sp, replace, replace_len); +// printf("\n Changed value for i=%d is %s", i, keyValArray[i].valStr); + } + return 0; //search and replace is successful +} + +void runCommands(KEYVALRESULT * commandArray, int numCommands) +{ + + char buf[BUFSIZE]; /* buffer used to store VPP metrics */ + FILE *fp; /* file descriptor to pipe cmd to shell */ + int i; + + for(i = 0; i < numCommands; i++) + { + memset(buf, 0, BUFSIZE); + + // Open a pipe and read VPP values + if ((fp = popen(commandArray[i].valStr, "r")) == NULL) { + printf("Error opening pipe!\n"); + return; + } + + while (fgets(buf, BUFSIZE, fp) != NULL); + strcpy(commandArray[i].resultStr, buf); + + if(pclose(fp)) { + printf("Command not found or exited with error status\n"); + return; + } + } + //for(i = 0; i < numCommands; i++) + // printf("-%d-valstr and resultStr is- %s - %s\n", i, commandArray[i].valStr, commandArray[i].resultStr); + printf("%d - %d - %d - %d\n", atoi(commandArray[0].resultStr), atoi(commandArray[1].resultStr), atoi(commandArray[2].resultStr), atoi(commandArray[3].resultStr)); +} + + +void copy_vpp_metic_data(vpp_metrics_struct *intfstats, KEYVALRESULT * cmdArray, int numCmds, int linkNum) +{ + int i; + + // Store the current metric in the last metric + intfstats[linkNum].last_bytes_in = intfstats[linkNum].curr_bytes_in; + intfstats[linkNum].last_bytes_out = intfstats[linkNum].curr_bytes_out; + intfstats[linkNum].last_packets_in = intfstats[linkNum].curr_packets_in; + intfstats[linkNum].last_packets_out = intfstats[linkNum].curr_packets_out; + + // Store metrics read from the vNIC in the current + for(i=0; i<numCmds; i++) + { + if((strcmp(cmdArray[i].keyStr, "tmp_t0BytesIn") == 0) || + (strcmp(cmdArray[i].keyStr, "tmp_t1BytesIn") == 0)) + intfstats[linkNum].curr_bytes_in = atoi(cmdArray[i].resultStr); + + if((strcmp(cmdArray[i].keyStr, "tmp_t0BytesOut") == 0) || + (strcmp(cmdArray[i].keyStr, "tmp_t1BytesOut") == 0)) + intfstats[linkNum].curr_bytes_out = atoi(cmdArray[i].resultStr); + + if((strcmp(cmdArray[i].keyStr, "tmp_t0PacketsIn") == 0) || + (strcmp(cmdArray[i].keyStr, "tmp_t1PacketsIn") == 0)) + intfstats[linkNum].curr_packets_in = atoi(cmdArray[i].resultStr); + + if((strcmp(cmdArray[i].keyStr, "tmp_t0PacketsOut") == 0) || + (strcmp(cmdArray[i].keyStr, "tmp_t1PacketsOut") == 0)) + intfstats[linkNum].curr_packets_out = atoi(cmdArray[i].resultStr); + } + // printf("intfstats[%d].curr_bytes_in = %d\n", linkNum, intfstats[linkNum].curr_bytes_in); + // printf("intfstats[%d].curr_bytes_out = %d\n", linkNum, intfstats[linkNum].curr_bytes_out); + // printf("intfstats[%d].curr_packets_in = %d\n", linkNum, intfstats[linkNum].curr_packets_in); + // printf("intfstats[%d].curr_packets_out = %d\n", linkNum, intfstats[linkNum].curr_packets_out); +} + +int get_priority(char * inStr) +{ + int result = -1; + + if(strcmp(inStr, "High") == 0) + result = EVEL_PRIORITY_HIGH; + else if(strcmp(inStr, "Medium") == 0) + result = EVEL_PRIORITY_MEDIUM; + else if(strcmp(inStr, "Normal") == 0) + result = EVEL_PRIORITY_NORMAL; + else if(strcmp(inStr, "Low") == 0) + result = EVEL_PRIORITY_LOW; + + return result; +} + +/**************************************************************************//** + * tap live cpu stats + *****************************************************************************/ +void evel_get_cpu_stats(EVENT_MEASUREMENT * measurement) +{ + FILE *fp; + char path[1024]; + double usage=0.0; + double idle; + double intrpt; + double nice; + double softirq; + double steal; + double sys; + double user; + double wait; + MEASUREMENT_CPU_USE *cpu_use = NULL; + + /* Open the command for reading. */ + //fp = popen("/bin/ls /etc/", "r"); + fp = popen("/usr/bin/top -bn 2 -d 0.01 | grep '^%Cpu' | tail -n 1 ", "r"); + if (fp == NULL) { + printf("Failed to run command\n" ); + exit(1); + } + + /* Read the output a line at a time - output it. */ + while (fgets(path, sizeof(path)-1, fp) != NULL) { + printf("%s", path+10); + sscanf(path+10," %lf us, %lf sy, %lf ni, %lf id, %lf wa, %lf hi, %lf si, %lf st", + &user,&sys,&nice,&idle,&wait,&intrpt,&softirq,&steal); + } + + /* close */ + pclose(fp); + + cpu_use = evel_measurement_new_cpu_use_add(measurement, "cpu1", usage); + if( cpu_use != NULL ){ + + evel_measurement_cpu_use_idle_set(cpu_use,idle); + //evel_measurement_cpu_use_interrupt_set(cpu_use,intrpt); + //evel_measurement_cpu_use_nice_set(cpu_use,nice); + //evel_measurement_cpu_use_softirq_set(cpu_use,softirq); + //evel_measurement_cpu_use_steal_set(cpu_use,steal); + evel_measurement_cpu_use_system_set(cpu_use,sys); + evel_measurement_cpu_use_usageuser_set(cpu_use,user); + //evel_measurement_cpu_use_wait_set(cpu_use,wait); + //evel_measurement_cpu_use_add(measurement, "cpu2", usage,idle,intrpt,nice,softirq,steal,sys,user,wait); + } +} + +int measure_traffic() +{ + + FILE *fp; + int status; + char count[10]; + time_t rawtime; + struct tm * timeinfo; + char period [21]; + char cmd [100]; + char secs [3]; + int sec; + int request_rate=0; + + printf("Checking app traffic\n"); + time (&rawtime); + timeinfo = localtime (&rawtime); + strftime(period,21,"%d/%b/%Y:%H:%M:",timeinfo); + strftime(secs,3,"%S",timeinfo); + sec = atoi(secs); + if (sec == 0) sec = 59; + sprintf(secs, "%02d", sec); + strncat(period, secs, 21); + // ....x....1....x....2. + // 15/Oct/2016:17:51:19 + strcpy(cmd, "sudo docker logs vHello | grep -c "); + strncat(cmd, period, 100); + fp = popen(cmd, "r"); + if (fp == NULL) { + EVEL_ERROR("popen failed to execute command"); + } + + if (fgets(count, 10, fp) != NULL) { + request_rate = atoi(count); + printf("Reporting request rate for second: %s as %d\n", period, request_rate); + + } + else { + EVEL_ERROR("New Measurement failed"); + } + printf("Processed measurement\n"); + + status = pclose(fp); + if (status == -1) { + EVEL_ERROR("pclose returned an error"); + } + return request_rate; +} + + + +int main(int argc, char** argv) +{ + char* fqdn = argv[1]; + int port = atoi(argv[2]); + int i=0; + int rc; + pthread_attr_t attr; + pthread_t meas_thread; + char* fqdn2 = NULL; + int port2 = 0; + + if(argc == 5) + { + fqdn2 = argv[3]; + port2 = atoi(argv[4]); + } + + if (!((argc == 3) || (argc == 5))) + { + fprintf(stderr, "Usage: %s <FQDN>|<IP address> <port> <FQDN>|<IP address> <port> \n", argv[0]); + fprintf(stderr, "OR\n"); + fprintf(stderr, "Usage: %s <FQDN>|<IP address> <port> \n", argv[0]); + exit(-1); + } + + /**************************************************************************/ + /* Initialize */ + /**************************************************************************/ + if(evel_initialize(fqdn, /* FQDN */ + port, /* Port */ + fqdn2, /* Backup FQDN */ + port2, /* Backup port */ + NULL, /* optional path */ + NULL, /* optional topic */ + 100, /* Ring Buffer size */ + 0, /* HTTPS? */ + NULL, /* cert file */ + NULL, /* key file */ + NULL, /* ca info */ + NULL, /* ca file */ + 0, /* verify peer */ + 0, /* verify host */ + "sample1", /* Username */ + "sample1", /* Password */ + "sample1", /* Username2 */ + "sample1", /* Password2 */ + NULL, /* Source ip */ + NULL, /* Source ip2 */ + EVEL_SOURCE_VIRTUAL_MACHINE, /* Source type */ + "vFirewall", /* Role */ + 1)) /* Verbosity */ + { + fprintf(stderr, "\nFailed to initialize the EVEL library!!!\n"); + exit(-1); + } + else + { + printf("\nInitialization completed\n"); + } + + /* Initialize and set thread detached attribute */ + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + printf("Main:Creating thread \n"); + rc = pthread_create(&meas_thread, NULL, MeasThread, &i); + if (rc) + { + printf("ERROR; return code from pthread_create() is %d\n", rc); + exit(-1); + } + printf("Main:Created Meas thread \n"); + + pthread_join(meas_thread, NULL); + + evel_terminate(); + printf("Terminated\n"); + return 0; +} + +void *MeasThread(void *mainMeas) +{ + EVEL_ERR_CODES evel_rc = EVEL_SUCCESS; + EVENT_MEASUREMENT * vpp_m = NULL; + MEASUREMENT_CPU_USE *cpu_use = NULL; + EVENT_HEADER* vpp_m_header = NULL; + int bytes_in; + int bytes_out; + int packets_in; + int packets_out; + unsigned long long epoch_now; + int request_rate = 0; + + struct timeval time_val; + MEASUREMENT_VNIC_PERFORMANCE * vnic_performance = NULL; + char event_id1[10] = "mvfs"; + char event_id2[15] = {0}; + char event_id[BUFSIZE] = {0}; + int meas_event_id = 0; + + int numToken; + jsmntok_t tokens[MAX_TOKENS]; + char js[MAX_BUFFER_SIZE]; + + jsmn_parser p; + char ch[BUFSIZE]; + int ret = 0; + char eName[BUFSIZE]; + char eType[BUFSIZE]; + char nfcCode[BUFSIZE]; + char nfCode[BUFSIZE]; + char prio[BUFSIZE]; + char reportEId[BUFSIZE]; + char reportEName[BUFSIZE]; + char srcId[BUFSIZE]; + char srcName[BUFSIZE]; + char cpuId[BUFSIZE]; + + int priority; + + char hostname[BUFSIZE]; + + int meas_interval; + ARRAYVAL intfArray[MAX_INTERFACES]; + KEYVALRESULT keyValResultArray[32]; + KEYVALRESULT keyValResultArray2[32]; + KEYVALRESULT vnicCommandArray[32]; + KEYVALRESULT cpuUsageCommandArray[32]; + int numInitCommands = 0; + int numVnicCommands = 0; + int numCpuUsageCommands = 0; + int linkCount = 0; + double usage=0.0; + double cpuIdle=0.0; + double cpuSystem=0.0; + double cpuUser=0.0; + double intrpt; + double nice; + double softirq; + double steal; + double wait; + + int i = 0; + + memset(hostname, 0, BUFSIZE); + gethostname(hostname, BUFSIZE); + printf("MeasThread::The hostname is %s\n", hostname); + + sleep(1); + printf("MeasThread::Running Meas thread \n"); + fflush(stdout); + + memset(&intfArray[0],0,(sizeof(ARRAYVAL) * MAX_INTERFACES)); + memset(&keyValResultArray[0],0,(sizeof(KEYVALRESULT) * 32)); + + memset(js, 0, MAX_BUFFER_SIZE); + memset(ch, 0, BUFSIZE); + memset(&meas_intfstat[0],0,(sizeof(vpp_metrics_struct)* MAX_INTERFACES)); + memset(&meas_linkstat[0],0,(sizeof(LINKSTAT) * MAX_INTERFACES)); + + FILE * file = fopen("meas_config.json", "r"); + + while((fgets(ch, (BUFSIZE-1), file)) !=NULL) + { + strcat(js, ch); + memset(ch, 0, BUFSIZE); + } +// printf("MeasThread::the file content is \n %s \n", js); + + jsmn_init(&p); + numToken = jsmn_parse(&p, js, strlen(js), tokens, MAX_TOKENS); + printf("MeasThread::count-%d\n", numToken); + +// printToken(js,tokens, numToken); + + + ret = getIntToken(js, tokens, numToken, "measurementInterval", "tmp_directParameters", &meas_interval); + if (ret != 0) + { + printf("MeasThread::The parameter measurementInterval is not defined, defaulted to 60 seconds\n"); + meas_interval = 60; + } + + ret = getArrayTokens(js, tokens, numToken, "tmp_device", "tmp_directParameters", intfArray, &linkCount); + + printf("MeasThread::Array link count is %d\n", linkCount); + + /* Copy the link information */ + for(i=0;i<linkCount;i++) + { + strcpy(meas_linkstat[i].linkname, &intfArray[i]); +// printf("MeasThread::Link name %s\n", meas_linkstat[i].linkname); + } + + + read_keyVal_params(js, tokens, numToken, "tmp_init", "tmp_indirectParameters", keyValResultArray, &numInitCommands); + + for(i=0;i<linkCount;i++) + { + memset(&vnicCommandArray[0],0,(sizeof(KEYVALRESULT) * 32)); + memcpy(vnicCommandArray, keyValResultArray, (sizeof(KEYVALRESULT) * 32)); + format_val_params(vnicCommandArray, numInitCommands, meas_linkstat[i].linkname, "$tmp_device"); + runCommands(vnicCommandArray, numInitCommands); + copy_vpp_metic_data(meas_intfstat, vnicCommandArray, numInitCommands, i); + } + + gettimeofday(&time_val, NULL); + + sleep(meas_interval); + + /***************************************************************************/ + /* Collect metrics from the VNIC */ + /***************************************************************************/ + while(1) + { + + ret = getIntToken(js, tokens, numToken, "measurementInterval", "tmp_directParameters", &meas_interval); + if (ret != 0) + { + meas_interval = 60; + } + + ret = getStringToken(js, tokens, numToken, "eventName", "tmp_directParameters", eName, BUFSIZE); + if (ret != 0) + { + printf("MeasThread::Missing mandatory parameters - eventName is not there in tmp_directParameters. Exiting...\n"); + exit(1); + } + + ret = getStringToken(js, tokens, numToken, "eventType", "tmp_directParameters", eType, BUFSIZE); + ret = getStringToken(js, tokens, numToken, "nfcNamingCode", "tmp_directParameters", nfcCode, BUFSIZE); + ret = getStringToken(js, tokens, numToken, "nfNamingCode", "tmp_directParameters", nfCode, BUFSIZE); + ret = getStringToken(js, tokens, numToken, "reportingEntityId", "tmp_directParameters", reportEId, BUFSIZE); + ret = getStringToken(js, tokens, numToken, "sourceId", "tmp_directParameters", srcId, BUFSIZE); + ret = getStringToken(js, tokens, numToken, "reportingEntityName", "tmp_directParameters", reportEName, BUFSIZE); + if (ret != 0) + { + printf("MeasThread::Missing mandatory parameters - reportingEntityName is not there in tmp_directParameters\n"); + printf("MeasThread::Defaulting reportingEntityName to hostname\n"); + strcpy(reportEName, hostname); + } + ret = getStringToken(js, tokens, numToken, "sourceName", "tmp_directParameters", srcName, BUFSIZE); + if (ret != 0) + { + printf("MeasThread::Missing mandatory parameters - sourceName is not there in tmp_directParameters\n"); + printf("MeasThread::Defaulting sourceName to hostname\n"); + strcpy(srcName, hostname); + } + + ret = getStringToken(js, tokens, numToken, "priority", "tmp_directParameters", prio, BUFSIZE); + if (ret != 0) + { + printf("MeasThread::Missing mandatory parameters - priority is not there in tmp_directParameters\nDefaulting priority to Low\n"); + strcpy(prio, "Medium"); + } + priority = get_priority(prio); + if(priority == -1) + { + printf("MeasThread::Meas priority value is not matching, prioirty-%s \n", prio); + exit(1); + } + + read_keyVal_params(js, tokens, numToken, "tmp_vnic_command", "vNicPerformance", keyValResultArray, &numVnicCommands); + + for(i=0;i<linkCount;i++) + { + memset(&vnicCommandArray[0],0,(sizeof(KEYVALRESULT) * 32)); + memcpy(vnicCommandArray, keyValResultArray, (sizeof(KEYVALRESULT) * 32)); + format_val_params(vnicCommandArray, numVnicCommands, meas_linkstat[i].linkname, "$tmp_device"); + runCommands(vnicCommandArray, numVnicCommands); + copy_vpp_metic_data(meas_intfstat, vnicCommandArray, numVnicCommands, i); + } + + memset(event_id, 0, BUFSIZE); + meas_event_id = meas_event_id+1; + sprintf(event_id2, "%09d", meas_event_id); + strcat(event_id, event_id1); + strcat(event_id, event_id2); + + vpp_m = evel_new_measurement(meas_interval, eName,event_id); + + if(vpp_m != NULL) + { + printf("New measurement report created...\n"); + + for (int i = 0; i < linkCount; i++) + { + if(meas_intfstat[i].curr_bytes_in - meas_intfstat[i].last_bytes_in > 0) { + bytes_in = meas_intfstat[i].curr_bytes_in - meas_intfstat[i].last_bytes_in; + } + else { + bytes_in = 0; + } + if(meas_intfstat[i].curr_bytes_out - meas_intfstat[i].last_bytes_out > 0) { + bytes_out = meas_intfstat[i].curr_bytes_out - meas_intfstat[i].last_bytes_out; + } + else { + bytes_out = 0; + } + if(meas_intfstat[i].curr_packets_in - meas_intfstat[i].last_packets_in > 0) { + packets_in = meas_intfstat[i].curr_packets_in - meas_intfstat[i].last_packets_in; + } + else { + packets_in = 0; + } + if(meas_intfstat[i].curr_packets_out - meas_intfstat[i].last_packets_out > 0) { + packets_out = meas_intfstat[i].curr_packets_out - meas_intfstat[i].last_packets_out; + } + else { + packets_out = 0; + } + vnic_performance = (MEASUREMENT_VNIC_PERFORMANCE *)evel_measurement_new_vnic_performance(meas_linkstat[i].linkname, "true"); + evel_meas_vnic_performance_add(vpp_m, vnic_performance); + evel_vnic_performance_rx_total_pkt_delta_set(vnic_performance, packets_in); + evel_vnic_performance_tx_total_pkt_delta_set(vnic_performance, packets_out); + + evel_vnic_performance_rx_octets_delta_set(vnic_performance, bytes_in); + evel_vnic_performance_tx_octets_delta_set(vnic_performance, bytes_out); + + if (strcmp(meas_linkstat[i].linkname, "docker") == 0) + { + request_rate = measure_traffic(); + } + } + + evel_measurement_request_rate_set(vpp_m, request_rate); + + //evel_get_cpu_stats(vpp_m); + memset(&keyValResultArray2[0],0,(sizeof(KEYVALRESULT) * 32)); + memset(&cpuUsageCommandArray[0],0,(sizeof(KEYVALRESULT) * 32)); + + ret = getStringToken(js, tokens, numToken, "cpuIdentifier", "cpuUsage", cpuId, BUFSIZE); + if (ret != 0) + { + printf("MeasThread::Missing parameters - cpuIdentifier is not there in cpuUsage, default to Cpu1\n"); + strcpy(cpuId, "Cpu1"); + } + read_keyVal_params(js, tokens, numToken, "tmp_cpuuse_command", "cpuUsage", keyValResultArray2, &numCpuUsageCommands); + memcpy(cpuUsageCommandArray, keyValResultArray2, (sizeof(KEYVALRESULT) * 32)); + runCommands(cpuUsageCommandArray, numCpuUsageCommands); + + cpu_use = evel_measurement_new_cpu_use_add(vpp_m, cpuId, usage); + if( cpu_use != NULL ) + { +/**************************** + for(i=0; i<numCpuUsageCommands; i++) + { + if(strcmp(cpuUsageCommandArray[i].keyStr, "tmp_cpuIdle") == 0) + { + cpuIdle = atof(cpuUsageCommandArray[i].resultStr); + } + if(strcmp(cpuUsageCommandArray[i].keyStr, "tmp_cpuUsageSystem") == 0) + { + cpuSystem = atof(cpuUsageCommandArray[i].resultStr); + } + if(strcmp(cpuUsageCommandArray[i].keyStr, "tmp_cpuUsageUser") == 0) + { + cpuUser = atof(cpuUsageCommandArray[i].resultStr); + } + } **********************/ + printf("%s", cpuUsageCommandArray[0].resultStr); + sscanf(cpuUsageCommandArray[0].resultStr, " %lf us, %lf sy, %lf ni, %lf id, %lf wa, %lf hi, %lf si, %lf st", &cpuUser,&cpuSystem,&nice,&cpuIdle,&wait,&intrpt,&softirq,&steal); +printf("user - %f, system - %f, idle - %f\n", cpuUser, cpuSystem, cpuIdle); + + evel_measurement_cpu_use_idle_set(cpu_use, cpuIdle); + evel_measurement_cpu_use_system_set(cpu_use, cpuSystem); + evel_measurement_cpu_use_usageuser_set(cpu_use, cpuUser); + } + + struct timeval tv_now; + gettimeofday(&tv_now, NULL); + epoch_now = tv_now.tv_usec + 1000000 * tv_now.tv_sec; + + vpp_m_header = (EVENT_HEADER *)vpp_m; + + + if (eType != NULL) + evel_measurement_type_set(vpp_m, eType); + + evel_start_epoch_set(&vpp_m->header, epoch_start); + evel_last_epoch_set(&vpp_m->header, epoch_now); + epoch_start= epoch_now; + + if(nfcCode != NULL) + evel_nfcnamingcode_set(&vpp_m->header, nfcCode); + if(nfCode != NULL) + evel_nfnamingcode_set(&vpp_m->header, nfCode); + evel_reporting_entity_name_set(&vpp_m->header, reportEName); + if(reportEId != NULL) + evel_reporting_entity_id_set(&vpp_m->header, reportEId); + if(srcId != NULL ) + evel_source_id_set(&vpp_m->header, srcId); + if(srcName!= NULL ) + evel_source_name_set(&vpp_m->header, srcName); + + evel_rc = evel_post_event(vpp_m_header); + + if(evel_rc == EVEL_SUCCESS) + printf("MeasThread::Meas event is correctly sent to the collector!\n"); + else + printf("MeasThread::Post failed %d (%s)\n", evel_rc, evel_error_string()); + } + else + { + printf("MeasThread::Measurement event creation failed (%s)\n", evel_error_string()); + } + + sleep(meas_interval); + } + + /***************************************************************************/ + /* Terminate */ + /***************************************************************************/ + sleep(1); +} + diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/double_list.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/double_list.c index 3106074..cd171bc 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/double_list.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/double_list.c @@ -14,6 +14,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * ECOMP is a trademark and service mark of AT&T Intellectual Property. * ****************************************************************************/ diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel.c index dbaf58a..fbe3de4 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel.c @@ -64,11 +64,24 @@ char *functional_role = NULL; * * @param fqdn The API's FQDN or IP address. * @param port The API's port. + * @param bakup_fqdn The API's Backup FQDN or IP address. + * @param bakup_port The API's Backup port. * @param path The optional path (may be NULL). * @param topic The optional topic part of the URL (may be NULL). + * @param ring buf size Ring buffer size * @param secure Whether to use HTTPS (0=HTTP, 1=HTTPS) + * @param cert_file_path Path to client certificate file + * @param key_file_path Path to client key file + * @param ca_info Path to CA cert file + * @param ca_file_path Path to CA cert files + * @param verify_peer SSL verification of peer 0 or 1 + * @param verify_host SSL verification of host 0 or 1 * @param username Username for Basic Authentication of requests. * @param password Password for Basic Authentication of requests. + * @param bakup_username Username for Basic Authentication of Bakup FQDN. + * @param bakup_password Password for Basic Authentication of Bakup FQDN. + * @param source_ip The ip of node we represent.(NULL for default ip) + * @param bakup_source_ip The ip bakup fqdn interface.(NULL for default ip) * @param source_type The kind of node we represent. * @param role The role this node undertakes. * @param verbosity 0 for normal operation, positive values for chattier @@ -80,11 +93,24 @@ char *functional_role = NULL; *****************************************************************************/ EVEL_ERR_CODES evel_initialize(const char * const fqdn, int port, + const char * const bakup_fqdn, + int bakup_port, const char * const path, const char * const topic, + int ring_buf_size, int secure, + const char * const cert_file_path, + const char * const key_file_path, + const char * const ca_info, + const char * const ca_file_path, + long verify_peer, + long verify_host, const char * const username, const char * const password, + const char * const bakup_username, + const char * const bakup_password, + const char * const source_ip, + const char * const bakup_source_ip, EVEL_SOURCE_TYPES source_type, const char * const role, int verbosity @@ -93,11 +119,13 @@ EVEL_ERR_CODES evel_initialize(const char * const fqdn, EVEL_ERR_CODES rc = EVEL_SUCCESS; char base_api_url[EVEL_MAX_URL_LEN + 1] = {0}; char event_api_url[EVEL_MAX_URL_LEN + 1] = {0}; + char bakup_api_url[EVEL_MAX_URL_LEN + 1] = {0}; char throt_api_url[EVEL_MAX_URL_LEN + 1] = {0}; char path_url[EVEL_MAX_URL_LEN + 1] = {0}; char topic_url[EVEL_MAX_URL_LEN + 1] = {0}; char version_string[10] = {0}; int offset; + char * bakup_coll = NULL; /***************************************************************************/ /* Check assumptions. */ @@ -107,10 +135,17 @@ EVEL_ERR_CODES evel_initialize(const char * const fqdn, assert(source_type < EVEL_MAX_SOURCE_TYPES); assert(role != NULL); + if( bakup_fqdn != NULL ) { + assert(bakup_port > 0 && bakup_port <= 65535); + } + /***************************************************************************/ /* Start logging so we can report on progress. */ /***************************************************************************/ - log_initialize(verbosity == 0 ? EVEL_LOG_INFO : EVEL_LOG_DEBUG, "EVEL"); + if( verbosity >= EVEL_LOG_MIN && verbosity <= EVEL_LOG_MAX) + log_initialize(verbosity, "EVEL"); + else + log_initialize(EVEL_LOG_MIN, "EVEL"); EVEL_INFO("EVEL started"); EVEL_INFO("API server is: %s", fqdn); EVEL_INFO("API port is: %d", port); @@ -134,6 +169,42 @@ EVEL_ERR_CODES evel_initialize(const char * const fqdn, } EVEL_INFO("API transport is: %s", secure ? "HTTPS" : "HTTP"); + if( secure ) { + assert( verify_peer >= 0 ); + assert( verify_host >= 0 ); + if (cert_file_path != NULL) + { + EVEL_INFO("Client cert is: %s", cert_file_path); + } + else + { + EVEL_INFO("No Client cert"); + } + if (key_file_path != NULL) + { + EVEL_INFO("Key file is: %s", key_file_path); + } + else + { + EVEL_INFO("No Key file"); + } + if (ca_file_path != NULL) + { + EVEL_INFO("Client CA certs path is: %s", ca_file_path); + } + else + { + EVEL_INFO("No CA certs path"); + } + if (ca_info != NULL) + { + EVEL_INFO("Client CA cert file is: %s", ca_info); + } + else + { + EVEL_INFO("No CA cert file"); + } + } EVEL_INFO("Event Source Type is: %d", source_type); EVEL_INFO("Functional Role is: %s", role); EVEL_INFO("Log verbosity is: %d", verbosity); @@ -187,6 +258,36 @@ EVEL_ERR_CODES evel_initialize(const char * const fqdn, EVEL_INFO("Vendor Event Listener API is located at: %s", event_api_url); /***************************************************************************/ + /* Build a common base of the Backup API URLs. */ + /***************************************************************************/ + if( bakup_fqdn != NULL ) + { + strcpy(path_url, "/"); + snprintf(base_api_url, + EVEL_MAX_URL_LEN, + "%s://%s:%d%s/eventListener/v%s", + secure ? "https" : "http", + bakup_fqdn, + bakup_port, + (((path != NULL) && (strlen(path) > 0)) ? + strncat(path_url, path, EVEL_MAX_URL_LEN) : ""), + version_string); + + /***************************************************************************/ + /* Build the URL to the event API. */ + /***************************************************************************/ + strcpy(topic_url, "/"); + snprintf(bakup_api_url, + EVEL_MAX_URL_LEN, + "%s%s", + base_api_url, + (((topic != NULL) && (strlen(topic) > 0)) ? + strncat(topic_url, topic, EVEL_MAX_URL_LEN) : "")); + EVEL_INFO("Vendor Backup Event Listener API is located at: %s", bakup_api_url); + bakup_coll = bakup_api_url; + } + + /***************************************************************************/ /* Build the URL to the throttling API. */ /***************************************************************************/ snprintf(throt_api_url, @@ -199,9 +300,22 @@ EVEL_ERR_CODES evel_initialize(const char * const fqdn, /* Spin-up the event-handler, which gets cURL readied for use. */ /***************************************************************************/ rc = event_handler_initialize(event_api_url, + bakup_coll, throt_api_url, + source_ip, + bakup_source_ip, + ring_buf_size, + secure, + cert_file_path, + key_file_path, + ca_info, + ca_file_path, + verify_peer, + verify_host, username, password, + bakup_username, + bakup_password, verbosity); if (rc != EVEL_SUCCESS) { @@ -388,6 +502,13 @@ void evel_free_event(void * event) free(evt_ptr); break; + case EVEL_DOMAIN_BATCH: + EVEL_DEBUG("Event is a Batch at %lp", evt_ptr); + evel_free_batch((EVENT_HEADER *)evt_ptr); + memset(evt_ptr, 0, sizeof(EVENT_HEADER)); + free(evt_ptr); + break; + default: EVEL_ERROR("Unexpected event domain (%d)", evt_ptr->event_domain); assert(0); diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel.h b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel.h index 0ae1713..8cdc4b5 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel.h +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel.h @@ -1,5 +1,3 @@ -#ifndef EVEL_INCLUDED -#define EVEL_INCLUDED /*************************************************************************//** * * Copyright © 2017 AT&T Intellectual Property. All rights reserved. @@ -29,6 +27,9 @@ * be one of ::EVEL_ERR_CODES. *****************************************************************************/ +#ifndef EVEL_INCLUDED +#define EVEL_INCLUDED + #ifdef __cplusplus extern "C" { #endif @@ -86,7 +87,7 @@ typedef enum { /* Maximum string lengths. */ /*****************************************************************************/ #define EVEL_MAX_STRING_LEN 4096 -#define EVEL_MAX_JSON_BODY 16000 +#define EVEL_MAX_JSON_BODY 524288 #define EVEL_MAX_ERROR_STRING_LEN 255 #define EVEL_MAX_URL_LEN 511 @@ -117,6 +118,7 @@ static const int EVEL_EVENT_BUFFER_DEPTH = 100; *****************************************************************************/ typedef enum { EVEL_DOMAIN_INTERNAL, /** Internal event, not for external routing. */ + EVEL_DOMAIN_BATCH, /** Batch event, composite event. */ EVEL_DOMAIN_HEARTBEAT, /** A Heartbeat event (event header only). */ EVEL_DOMAIN_FAULT, /** A Fault event. */ EVEL_DOMAIN_MEASUREMENT, /** A Measurement for VF Scaling event. */ @@ -400,9 +402,11 @@ typedef struct internal_header_fields /*****************************************************************************/ /* Supported Common Event Header version. */ /*****************************************************************************/ -#define EVEL_HEADER_MAJOR_VERSION 1 -#define EVEL_HEADER_MINOR_VERSION 2 +#define EVEL_HEADER_MAJOR_VERSION 3 +#define EVEL_HEADER_MINOR_VERSION 0 +#define EVEL_BATCH_MAJOR_VERSION 1 +#define EVEL_BATCH_MINOR_VERSION 0 /**************************************************************************//** * Event header. * JSON equivalent field: commonEventHeader @@ -436,14 +440,62 @@ typedef struct event_header { EVEL_OPTION_INTHEADER_FIELDS internal_field; EVEL_OPTION_STRING nfcnaming_code; EVEL_OPTION_STRING nfnaming_code; + DLIST batch_events; } EVENT_HEADER; +/**************************************************************************//** + * Initialize a newly created event header. + * + * @param header Pointer to the header being initialized. + * @param eventname Eventname string + * @param eventid Event id : unique id for classification and analysis + * @param header Pointer to the header being initialized. + *****************************************************************************/ +void evel_init_header_nameid(EVENT_HEADER * const header,const char *const eventname, const char *eventid); + +/**************************************************************************//** + * Create a new Batch event. + * + * @note The mandatory fields on the Batch must be supplied to this factory + * function and are immutable once set. Optional fields have explicit + * setter functions, but again values may only be set once so that the + * Batch has immutable properties. At this time evename and eventid + * for batch events are set but not used in json encoding + * @returns pointer to the newly manufactured ::EVENT_HEADER. If the event is + * not used (i.e. posted) it must be released using ::evel_free_batch. + * @retval NULL Failed to create the event. + *****************************************************************************/ +EVENT_HEADER * evel_new_batch(const char* ev_name, const char *ev_id); + + +/**************************************************************************//** + * Add an Event into Batch Event + * + * The name and value are null delimited ASCII strings. The library takes + * a copy so the caller does not have to preserve values after the function + * returns. + * + * @param other Pointer to the Batch Event. + * @param jsonobj Pointer to additional Event + *****************************************************************************/ +void evel_batch_add_event(EVENT_HEADER * batchev, EVENT_HEADER *child); + +/**************************************************************************//** + * Free an Batch. + * + * Free off the Batch supplied. Will free all the contained allocated memory. + * + * @note It does not free the Batch itself, since that may be part of a + * larger structure. + *****************************************************************************/ +void evel_free_batch(EVENT_HEADER * event); + /*****************************************************************************/ /* Supported Fault version. */ /*****************************************************************************/ #define EVEL_FAULT_MAJOR_VERSION 2 -#define EVEL_FAULT_MINOR_VERSION 1 +#define EVEL_FAULT_MINOR_VERSION 0 /**************************************************************************//** * Fault. @@ -529,7 +581,7 @@ typedef struct json_object_instance { char *jsonstring; - unsigned long long objinst_epoch_microsec; + EVEL_OPTION_ULL objinst_epoch_microsec; DLIST object_keys; /*EVEL_INTERNAL_KEY list */ } EVEL_JSON_OBJECT_INSTANCE; @@ -597,7 +649,7 @@ void evel_free_jsonobject(EVEL_JSON_OBJECT * jsobj); /* Supported Measurement version. */ /*****************************************************************************/ #define EVEL_MEASUREMENT_MAJOR_VERSION 2 -#define EVEL_MEASUREMENT_MINOR_VERSION 1 +#define EVEL_MEASUREMENT_MINOR_VERSION 0 /**************************************************************************//** * Errors. @@ -651,6 +703,37 @@ typedef struct event_measurement { } EVENT_MEASUREMENT; + + +/**************************************************************************//** + * Add an additional value name/value pair to the Measurement. + * + * The name and value are null delimited ASCII strings. The library takes + * a copy so the caller does not have to preserve values after the function + * returns. + * + * @param measurement Pointer to the measurement. + * @param name ASCIIZ string with the attribute's name. The caller + * does not need to preserve the value once the function + * returns. + * @param value ASCIIZ string with the attribute's value. The caller + * does not need to preserve the value once the function + * returns. + *****************************************************************************/ +void evel_measurement_addl_info_add(EVENT_MEASUREMENT * measurement, char * name, char * value); + +/**************************************************************************//** + * Add a json object to jsonObject list. + * + * The name and value are null delimited ASCII strings. The library takes + * a copy so the caller does not have to preserve values after the function + * returns. + * + * @param measurement Pointer to the ScalingMeasurement + * @param jsonobj Pointer to json object + *****************************************************************************/ +void evel_measurement_addl_object_add(EVENT_MEASUREMENT * measurement, EVEL_JSON_OBJECT *jsonobj); + /**************************************************************************//** * CPU Usage. * JSON equivalent field: cpuUsage @@ -990,7 +1073,7 @@ typedef struct custom_measurement { /* Supported Report version. */ /*****************************************************************************/ #define EVEL_REPORT_MAJOR_VERSION 1 -#define EVEL_REPORT_MINOR_VERSION 1 +#define EVEL_REPORT_MINOR_VERSION 0 /**************************************************************************//** * Report. @@ -1082,8 +1165,8 @@ typedef struct mobile_gtp_per_flow_metrics { /*****************************************************************************/ /* Supported Mobile Flow version. */ /*****************************************************************************/ -#define EVEL_MOBILE_FLOW_MAJOR_VERSION 1 -#define EVEL_MOBILE_FLOW_MINOR_VERSION 2 +#define EVEL_MOBILE_FLOW_MAJOR_VERSION 2 +#define EVEL_MOBILE_FLOW_MINOR_VERSION 0 /**************************************************************************//** * Mobile Flow. @@ -1143,7 +1226,7 @@ typedef struct event_mobile_flow { /* Supported Other field version. */ /*****************************************************************************/ #define EVEL_OTHER_EVENT_MAJOR_VERSION 1 -#define EVEL_OTHER_EVENT_MINOR_VERSION 1 +#define EVEL_OTHER_EVENT_MINOR_VERSION 0 /**************************************************************************//** * Other. @@ -1173,14 +1256,14 @@ typedef struct other_field { /* Supported Service Events version. */ /*****************************************************************************/ #define EVEL_HEARTBEAT_FIELD_MAJOR_VERSION 1 -#define EVEL_HEARTBEAT_FIELD_MINOR_VERSION 1 +#define EVEL_HEARTBEAT_FIELD_MINOR_VERSION 0 /*****************************************************************************/ /* Supported Signaling version. */ /*****************************************************************************/ -#define EVEL_SIGNALING_MAJOR_VERSION 2 -#define EVEL_SIGNALING_MINOR_VERSION 1 +#define EVEL_SIGNALING_MAJOR_VERSION 1 +#define EVEL_SIGNALING_MINOR_VERSION 0 /**************************************************************************//** * Vendor VNF Name fields. @@ -1235,8 +1318,8 @@ typedef struct signaling_additional_field { /*****************************************************************************/ /* Supported State Change version. */ /*****************************************************************************/ -#define EVEL_STATE_CHANGE_MAJOR_VERSION 1 -#define EVEL_STATE_CHANGE_MINOR_VERSION 2 +#define EVEL_STATE_CHANGE_MAJOR_VERSION 2 +#define EVEL_STATE_CHANGE_MINOR_VERSION 0 /**************************************************************************//** * State Change. @@ -1277,8 +1360,8 @@ typedef struct state_change_additional_field { /*****************************************************************************/ /* Supported Syslog version. */ /*****************************************************************************/ -#define EVEL_SYSLOG_MAJOR_VERSION 1 -#define EVEL_SYSLOG_MINOR_VERSION 2 +#define EVEL_SYSLOG_MAJOR_VERSION 3 +#define EVEL_SYSLOG_MINOR_VERSION 0 /**************************************************************************//** * Syslog. @@ -1346,11 +1429,24 @@ typedef struct copyright { * * @param fqdn The API's FQDN or IP address. * @param port The API's port. + * @param bakup_fqdn The API's FQDN or IP address. + * @param bakup_port The API's port. * @param path The optional path (may be NULL). * @param topic The optional topic part of the URL (may be NULL). + * @param ring_buf_size Ring buffer size (>=100) ~ Avg Messages in 1hr * @param secure Whether to use HTTPS (0=HTTP, 1=HTTPS). + * @param cert_file_path Path to client certificate file + * @param key_file_path Path to client key file + * @param ca_info Path to CA info + * @param ca_file_path Path to CA file + * @param verify_peer SSL verification of peer 0 or 1 + * @param verify_host SSL verification of host 0 or 1 * @param username Username for Basic Authentication of requests. * @param password Password for Basic Authentication of requests. + * @param bakup_username Username for Basic Authentication of Bakup FQDN. + * @param bakup_password Password for Basic Authentication of Bakup FQDN. + * @param source_ip The ip of node we represent.(NULL for default ip) + * @param bakup_source_ip The ip bakup fqdn interface.(NULL for default ip) * @param source_type The kind of node we represent. * @param role The role this node undertakes. * @param verbosity 0 for normal operation, positive values for chattier @@ -1362,17 +1458,41 @@ typedef struct copyright { *****************************************************************************/ EVEL_ERR_CODES evel_initialize(const char * const fqdn, int port, + const char * const bakup_fqdn, + int bakup_port, const char * const path, const char * const topic, + int ring_buf_size, int secure, + const char * const cert_file_path, + const char * const key_file_path, + const char * const ca_info, + const char * const ca_file_path, + long verify_peer, + long verify_host, const char * const username, const char * const password, + const char * const bakup_username, + const char * const bakup_password, + const char * const source_ip, + const char * const bakup_source_ip, EVEL_SOURCE_TYPES source_type, const char * const role, int verbosity ); /**************************************************************************//** + * Initialize value for vm_name for all coming events + * @param source_name Source name string. + * Must confirm with EVEL source name standard + * @returns Status code + * @retval EVEL_SUCCESS On success + * @retval ::EVEL_ERR_CODES On failure. + *****************************************************************************/ +EVEL_ERR_CODES evel_set_source_name(char * src_name); + + +/**************************************************************************//** * Clean up the EVEL library. * * @note that at present don't expect Init/Term cycling not to leak memory! @@ -1400,6 +1520,7 @@ void evel_free_event(void * event); * Encode the event as a JSON event object according to AT&T's schema. * * @param json Pointer to where to store the JSON encoded data. + * @param mode Event mode or Batch mode * @param max_size Size of storage available in json_body. * @param event Pointer to the ::EVENT_HEADER to encode. * @returns Number of bytes actually written. @@ -1407,7 +1528,9 @@ void evel_free_event(void * event); int evel_json_encode_event(char * json, int max_size, EVENT_HEADER * event); - +int evel_json_encode_batch_event(char * json, + int max_size, + EVENT_HEADER * event); /**************************************************************************//** * Initialize an event instance id. * @@ -1490,8 +1613,8 @@ EVENT_HEADER * evel_new_heartbeat(void); * * @note that the heartbeat is just a "naked" commonEventHeader! * - * @param event_name Unique Event Name confirming Domain AsdcModel Description - * @param event_id A universal identifier of the event for: troubleshooting correlation, analysis, etc + * @param event_name Unique Event Name: {DomainAbbreviation}_{AsdcModel or ApplicationPlatform}_{DescriptionOfInfoBeingConveyed} + * @param event_id A universal identifier of the event for: troubleshooting, cross-referencing of alarms for alarm correlation, offline log analysis, etc * * @returns pointer to the newly manufactured ::EVENT_HEADER. If the event is * not used it must be released using ::evel_free_event @@ -1499,6 +1622,22 @@ EVENT_HEADER * evel_new_heartbeat(void); *****************************************************************************/ EVENT_HEADER * evel_new_heartbeat_nameid(const char* ev_name, const char *ev_id); +/**************************************************************************//** + * Create a new Heartbeat fields event. + * + * @note The mandatory fields on the Heartbeat fields must be supplied to + * this factory function and are immutable once set. Optional fields + * have explicit setter functions, but again values may only be set + * once so that the event has immutable properties. + * @param ev_name Unique Event Name confirming Domain AsdcModel Description + * @param ev_id A universal identifier of the event for: troubleshooting correlation, analysis, etc + * @param interval heartbeat interval + * @returns pointer to the newly manufactured ::EVENT_HEARTBEAT_FIELD. If the event + * is not used (i.e. posted) it must be released using + * ::evel_free_hrtbt_field. + * @retval NULL Failed to create the event. + *****************************************************************************/ +EVENT_HEARTBEAT_FIELD * evel_new_heartbeat_field(int interval,const char* ev_name, const char *ev_id); /**************************************************************************//** * Free an event header. @@ -1530,6 +1669,24 @@ void evel_header_type_set(EVENT_HEADER * const header, const char * const type); /**************************************************************************//** + * Set the next event_sequence to use. + * + * @param sequence The next sequence number to use. + *****************************************************************************/ +void evel_set_global_event_sequence(const int sequence); + +/**************************************************************************//** + * Set the Event Sequence property of the event header. + * + * @note This is mainly for tracking fault event sequence numbers + * + * @param header Pointer to the ::EVENT_HEADER. + * @param sequence_number + * + *****************************************************************************/ +void evel_event_sequence_set(EVENT_HEADER * const header,const int sequence_number); + +/**************************************************************************//** * Set the Start Epoch property of the event header. * * @note The Start Epoch defaults to the time of event creation. @@ -1565,6 +1722,17 @@ void evel_reporting_entity_name_set(EVENT_HEADER * const header, const char * const entity_name); /**************************************************************************//** + * Set the Source Name property of the event header. + * + * @note The Source Name defaults to the OpenStack VM Name. + * + * @param header Pointer to the ::EVENT_HEADER. + * @param entity_name The source name to set. + *****************************************************************************/ +void evel_source_name_set(EVENT_HEADER * const header, + const char * const source_name); + +/**************************************************************************//** * Set the Reporting Entity Id property of the event header. * * @note The Reporting Entity Id defaults to the OpenStack VM UUID. @@ -1576,6 +1744,17 @@ void evel_reporting_entity_id_set(EVENT_HEADER * const header, const char * const entity_id); /**************************************************************************//** + * Set the Source Id property of the event header. + * + * @note The Source Id defaults to the OpenStack VM UUID. + * + * @param header Pointer to the ::EVENT_HEADER. + * @param entity_id The Source id to set. + *****************************************************************************/ +void evel_source_id_set(EVENT_HEADER * const header, + const char * const source_id); + +/**************************************************************************//** * Set the NFC Naming code property of the event header. * * @param header Pointer to the ::EVENT_HEADER. @@ -3955,7 +4134,7 @@ int evel_get_measurement_interval(); /* Supported Report version. */ /*****************************************************************************/ #define EVEL_VOICEQ_MAJOR_VERSION 1 -#define EVEL_VOICEQ_MINOR_VERSION 1 +#define EVEL_VOICEQ_MINOR_VERSION 0 /**************************************************************************//** * End of Call Voice Quality Metrices @@ -4255,8 +4434,8 @@ typedef struct perf_counter { /*****************************************************************************/ /* Supported Threshold Crossing version. */ /*****************************************************************************/ -#define EVEL_THRESHOLD_CROSS_MAJOR_VERSION 1 -#define EVEL_THRESHOLD_CROSS_MINOR_VERSION 1 +#define EVEL_THRESHOLD_CROSS_MAJOR_VERSION 2 +#define EVEL_THRESHOLD_CROSS_MINOR_VERSION 0 /**************************************************************************//** * Threshold Crossing. diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_batch.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_batch.c new file mode 100644 index 0000000..a33e5e1 --- /dev/null +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_batch.c @@ -0,0 +1,150 @@ +/*************************************************************************//** + * + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * + * Unless otherwise specified, all software contained herein is + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************/ + +/**************************************************************************//** + * @file + * Source module implementing EVEL Batch API. + * + * This file implements the EVEL Batch API which is intended to provide a + * simple wrapper around packaging multiple EVEL messages into single HTTP(S) package + * This is implemented per VES 5.3 standards. Currently max size of package is 160K + * + ****************************************************************************/ + +#include <string.h> +#include <assert.h> +#include <stdlib.h> + +#include "evel.h" +#include "evel_internal.h" + +/**************************************************************************//** + * Create a new empty Batch event. + * + * @note The mandatory fields on the Batch must be supplied to this factory + * function and are immutable once set. Optional fields have explicit + * setter functions, but again values may only be set once so that the + * Batch has immutable properties. + * @params Event name and Event id are dummy strings. Not encoded into JSON + * @returns pointer to the newly manufactured ::EVENT_HEADER. If the event is + * not used (i.e. posted) it must be released using ::evel_free_batch. + * @retval NULL Failed to create the event. + *****************************************************************************/ +EVENT_HEADER * evel_new_batch(const char* ev_name, const char *ev_id) +{ + EVENT_HEADER * other = NULL; + EVEL_ENTER(); + + /***************************************************************************/ + /* Check preconditions. */ + /***************************************************************************/ + + /***************************************************************************/ + /* Allocate the Batch. */ + /***************************************************************************/ + other = malloc(sizeof(EVENT_HEADER)); + if (other == NULL) + { + log_error_state("Out of memory"); + goto exit_label; + } + memset(other, 0, sizeof(EVENT_HEADER)); + EVEL_DEBUG("New Batch is at %lp", other); + + /***************************************************************************/ + /* Initialize the header & the Batch fields. Optional string values are */ + /* uninitialized (NULL). */ + /***************************************************************************/ + evel_init_header_nameid(other,ev_name,ev_id); + other->event_domain = EVEL_DOMAIN_BATCH; + other->major_version = EVEL_BATCH_MAJOR_VERSION; + other->minor_version = EVEL_BATCH_MINOR_VERSION; + + dlist_initialize(&other->batch_events); + +exit_label: + EVEL_EXIT(); + return other; +} + + +/**************************************************************************//** + * Add an additional VES Message into Batch Event + * + * The function may be called as many times without reaching 160K max json size + * limit. + * The max limit is only checked at encoding time and error generated + * + * @param batchev Pointer to already created new Batch Event. + * @param child Pointer to additional VES Event + *****************************************************************************/ +void evel_batch_add_event(EVENT_HEADER * batchev, EVENT_HEADER *child) +{ + EVEL_ENTER(); + + /***************************************************************************/ + /* Check preconditions. */ + /***************************************************************************/ + assert(batchev != NULL); + assert(batchev->event_domain == EVEL_DOMAIN_BATCH); + assert(child != NULL); + + EVEL_DEBUG("Adding Batch event"); + + dlist_push_last(&batchev->batch_events, child); + + EVEL_EXIT(); +} + + +/**************************************************************************//** + * Free a Batch Event. + * + * Free off the Batch supplied. Will free all the contained VES message memory. + * + * @note It does not free the Batch itself, since that may be part of a + * larger structure. + *****************************************************************************/ +void evel_free_batch(EVENT_HEADER * event) +{ + EVENT_HEADER * batch_field = NULL; + + EVEL_ENTER(); + + /***************************************************************************/ + /* Check preconditions. As an internal API we don't allow freeing NULL */ + /* events as we do on the public API. */ + /***************************************************************************/ + assert(event != NULL); + assert(event->event_domain == EVEL_DOMAIN_BATCH); + + /***************************************************************************/ + /* Free all internal strings then the header itself. */ + /***************************************************************************/ + batch_field = dlist_pop_last(&event->batch_events); + while (batch_field != NULL) + { + EVEL_DEBUG("Freeing Batch Event (%s, %s)", + batch_field->event_name, + batch_field->event_id); + evel_free_event(batch_field); + batch_field = dlist_pop_last(&event->batch_events); + } + + EVEL_EXIT(); +} diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_event.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_event.c index 9ccadb2..89c5c15 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_event.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_event.c @@ -13,7 +13,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. ****************************************************************************/ /**************************************************************************//** @@ -43,7 +43,7 @@ static int event_sequence = 1; * * @param sequence The next sequence number to use. *****************************************************************************/ -void evel_set_next_event_sequence(const int sequence) +void evel_set_global_event_sequence(const int sequence) { EVEL_ENTER(); @@ -168,7 +168,7 @@ void evel_init_header(EVENT_HEADER * const header,const char *const eventname) header->priority = EVEL_PRIORITY_NORMAL; header->reporting_entity_name = strdup(openstack_vm_name()); header->source_name = strdup(openstack_vm_name()); - header->sequence = event_sequence; + header->sequence = 0; header->start_epoch_microsec = header->last_epoch_microsec; header->major_version = EVEL_HEADER_MAJOR_VERSION; header->minor_version = EVEL_HEADER_MINOR_VERSION; @@ -180,9 +180,10 @@ void evel_init_header(EVENT_HEADER * const header,const char *const eventname) evel_init_option_string(&header->event_type); evel_init_option_string(&header->nfcnaming_code); evel_init_option_string(&header->nfnaming_code); - evel_force_option_string(&header->reporting_entity_id, openstack_vm_uuid()); - evel_force_option_string(&header->source_id, openstack_vm_uuid()); + evel_init_option_string(&header->reporting_entity_id); + evel_init_option_string(&header->source_id); evel_init_option_intheader(&header->internal_field); + dlist_initialize(&header->batch_events); EVEL_EXIT(); } @@ -192,6 +193,9 @@ void evel_init_header(EVENT_HEADER * const header,const char *const eventname) * Initialize a newly created event header. * * @param header Pointer to the header being initialized. + * @param eventname Eventname string + * @param eventid Event id : unique id for classification and analysis + * @param header Pointer to the header being initialized. *****************************************************************************/ void evel_init_header_nameid(EVENT_HEADER * const header,const char *const eventname, const char *eventid) { @@ -206,7 +210,7 @@ void evel_init_header_nameid(EVENT_HEADER * const header,const char *const event gettimeofday(&tv, NULL); /***************************************************************************/ - /* Initialize the header. Get a new event sequence number. Note that if */ + /* Initialize the header. Reset event sequence number. Note that if */ /* any memory allocation fails in here we will fail gracefully because */ /* everything downstream can cope with NULLs. */ /***************************************************************************/ @@ -217,11 +221,10 @@ void evel_init_header_nameid(EVENT_HEADER * const header,const char *const event header->priority = EVEL_PRIORITY_NORMAL; header->reporting_entity_name = strdup(openstack_vm_name()); header->source_name = strdup(openstack_vm_name()); - header->sequence = event_sequence; + header->sequence = 0; header->start_epoch_microsec = header->last_epoch_microsec; header->major_version = EVEL_HEADER_MAJOR_VERSION; header->minor_version = EVEL_HEADER_MINOR_VERSION; - event_sequence++; /***************************************************************************/ /* Optional parameters. */ @@ -229,9 +232,10 @@ void evel_init_header_nameid(EVENT_HEADER * const header,const char *const event evel_init_option_string(&header->event_type); evel_init_option_string(&header->nfcnaming_code); evel_init_option_string(&header->nfnaming_code); - evel_force_option_string(&header->reporting_entity_id, openstack_vm_uuid()); - evel_force_option_string(&header->source_id, openstack_vm_uuid()); + evel_init_option_string(&header->reporting_entity_id); + evel_init_option_string(&header->source_id); evel_init_option_intheader(&header->internal_field); + dlist_initialize(&header->batch_events); EVEL_EXIT(); } @@ -265,6 +269,29 @@ void evel_header_type_set(EVENT_HEADER * const header, } /**************************************************************************//** + * Set the Event Sequence property of the event header. + * + * @note The Start Epoch defaults to the time of event creation. + * + * @param header Pointer to the ::EVENT_HEADER. + * @param start_epoch_microsec + * The start epoch to set, in microseconds. + *****************************************************************************/ +void evel_event_sequence_set(EVENT_HEADER * const header,const int sequence_number) +{ + EVEL_ENTER(); + + /***************************************************************************/ + /* Check preconditions and assign the new value. */ + /***************************************************************************/ + assert(header != NULL); + header->sequence = sequence_number; + + EVEL_EXIT(); +} + + +/**************************************************************************//** * Set the Start Epoch property of the event header. * * @note The Start Epoch defaults to the time of event creation. @@ -384,6 +411,35 @@ void evel_reporting_entity_name_set(EVENT_HEADER * const header, } /**************************************************************************//** + * Set the Source Name property of the event header. + * + * @note The Source Name defaults to the OpenStack VM Name. + * + * @param header Pointer to the ::EVENT_HEADER. + * @param entity_name The source name to set. + *****************************************************************************/ +void evel_source_name_set(EVENT_HEADER * const header, + const char * const source_name) +{ + EVEL_ENTER(); + + /***************************************************************************/ + /* Check preconditions and assign the new value. */ + /***************************************************************************/ + assert(header != NULL); + assert(source_name != NULL); + + /***************************************************************************/ + /* Free the previously allocated memory and replace it with a copy of the */ + /* provided one. */ + /***************************************************************************/ + free(header->source_name); + header->source_name = strdup(source_name); + + EVEL_EXIT(); +} + +/**************************************************************************//** * Set the Reporting Entity Id property of the event header. * * @note The Reporting Entity Id defaults to the OpenStack VM UUID. @@ -413,6 +469,35 @@ void evel_reporting_entity_id_set(EVENT_HEADER * const header, } /**************************************************************************//** + * Set the Source Id property of the event header. + * + * @note The Source Id defaults to the OpenStack VM UUID. + * + * @param header Pointer to the ::EVENT_HEADER. + * @param entity_id The Source id to set. + *****************************************************************************/ +void evel_source_id_set(EVENT_HEADER * const header, + const char * const source_id) +{ + EVEL_ENTER(); + + /***************************************************************************/ + /* Check preconditions and assign the new value. */ + /***************************************************************************/ + assert(header != NULL); + assert(source_id != NULL); + + /***************************************************************************/ + /* Free the previously allocated memory and replace it with a copy of the */ + /* provided one. Note that evel_force_option_string strdups entity_id. */ + /***************************************************************************/ + evel_free_option_string(&header->source_id); + evel_force_option_string(&header->source_id, source_id); + + EVEL_EXIT(); +} + +/**************************************************************************//** * Encode the event as a JSON event object according to AT&T's schema. * * @param jbuf Pointer to the ::EVEL_JSON_BUFFER to encode into. @@ -505,6 +590,78 @@ void evel_free_header(EVENT_HEADER * const event) EVEL_EXIT(); } + +/**************************************************************************//** + * Encode the event as a JSON event object according to AT&T's schema. + * + * @param json Pointer to where to store the JSON encoded data. + * @param max_size Size of storage available in json_body. + * @param event Pointer to the ::EVENT_HEADER to encode. + * @returns Number of bytes actually written. + *****************************************************************************/ +void evel_json_encode_eventtype( + EVEL_JSON_BUFFER * jbuf, + EVENT_HEADER * event) +{ + switch (event->event_domain) + { + case EVEL_DOMAIN_HEARTBEAT: + evel_json_encode_header(jbuf, event); + break; + + case EVEL_DOMAIN_FAULT: + evel_json_encode_fault(jbuf, (EVENT_FAULT *)event); + break; + + case EVEL_DOMAIN_MEASUREMENT: + evel_json_encode_measurement(jbuf, (EVENT_MEASUREMENT *)event); + break; + + case EVEL_DOMAIN_MOBILE_FLOW: + evel_json_encode_mobile_flow(jbuf, (EVENT_MOBILE_FLOW *)event); + break; + + case EVEL_DOMAIN_REPORT: + evel_json_encode_report(jbuf, (EVENT_REPORT *)event); + break; + + case EVEL_DOMAIN_HEARTBEAT_FIELD: + evel_json_encode_hrtbt_field(jbuf, (EVENT_HEARTBEAT_FIELD *)event); + break; + + case EVEL_DOMAIN_SIPSIGNALING: + evel_json_encode_signaling(jbuf, (EVENT_SIGNALING *)event); + break; + + case EVEL_DOMAIN_STATE_CHANGE: + evel_json_encode_state_change(jbuf, (EVENT_STATE_CHANGE *)event); + break; + + case EVEL_DOMAIN_SYSLOG: + evel_json_encode_syslog(jbuf, (EVENT_SYSLOG *)event); + break; + + case EVEL_DOMAIN_OTHER: + evel_json_encode_other(jbuf, (EVENT_OTHER *)event); + break; + + case EVEL_DOMAIN_VOICE_QUALITY: + evel_json_encode_voice_quality(jbuf, (EVENT_VOICE_QUALITY *)event); + break; + + case EVEL_DOMAIN_THRESHOLD_CROSS: + evel_json_encode_threshold_cross(jbuf, (EVENT_THRESHOLD_CROSS *)event); + break; + + case EVEL_DOMAIN_INTERNAL: + default: + EVEL_ERROR("Unexpected domain %d", event->event_domain); + assert(0); + } +} + + + /**************************************************************************//** * Encode the event as a JSON event object according to AT&T's schema. * @@ -535,61 +692,7 @@ int evel_json_encode_event(char * json, evel_json_open_object(jbuf); evel_json_open_named_object(jbuf, "event"); - switch (event->event_domain) - { - case EVEL_DOMAIN_HEARTBEAT: - evel_json_encode_header(jbuf, event); - break; - - case EVEL_DOMAIN_FAULT: - evel_json_encode_fault(jbuf, (EVENT_FAULT *)event); - break; - - case EVEL_DOMAIN_MEASUREMENT: - evel_json_encode_measurement(jbuf, (EVENT_MEASUREMENT *)event); - break; - - case EVEL_DOMAIN_MOBILE_FLOW: - evel_json_encode_mobile_flow(jbuf, (EVENT_MOBILE_FLOW *)event); - break; - - case EVEL_DOMAIN_REPORT: - evel_json_encode_report(jbuf, (EVENT_REPORT *)event); - break; - - case EVEL_DOMAIN_HEARTBEAT_FIELD: - evel_json_encode_hrtbt_field(jbuf, (EVENT_HEARTBEAT_FIELD *)event); - break; - - case EVEL_DOMAIN_SIPSIGNALING: - evel_json_encode_signaling(jbuf, (EVENT_SIGNALING *)event); - break; - - case EVEL_DOMAIN_STATE_CHANGE: - evel_json_encode_state_change(jbuf, (EVENT_STATE_CHANGE *)event); - break; - - case EVEL_DOMAIN_SYSLOG: - evel_json_encode_syslog(jbuf, (EVENT_SYSLOG *)event); - break; - - case EVEL_DOMAIN_OTHER: - evel_json_encode_other(jbuf, (EVENT_OTHER *)event); - break; - - case EVEL_DOMAIN_VOICE_QUALITY: - evel_json_encode_voice_quality(jbuf, (EVENT_VOICE_QUALITY *)event); - break; - - case EVEL_DOMAIN_THRESHOLD_CROSS: - evel_json_encode_threshold_cross(jbuf, (EVENT_THRESHOLD_CROSS *)event); - break; - - case EVEL_DOMAIN_INTERNAL: - default: - EVEL_ERROR("Unexpected domain %d", event->event_domain); - assert(0); - } + evel_json_encode_eventtype(jbuf, event); evel_json_close_object(jbuf); evel_json_close_object(jbuf); @@ -598,6 +701,79 @@ int evel_json_encode_event(char * json, /* Sanity check. */ /***************************************************************************/ assert(jbuf->depth == 0); + if( jbuf->offset >= max_size ){ + EVEL_ERROR("Event exceeded size limit %d", max_size); + assert(0); + } + + EVEL_EXIT(); + + return jbuf->offset; +} +/**************************************************************************//** + * Encode the event as a JSON event object according to AT&T's schema. + * + * @param json Pointer to where to store the JSON encoded data. + * @param max_size Size of storage available in json_body. + * @param event Pointer to the ::EVENT_HEADER to encode. + * @returns Number of bytes actually written. + *****************************************************************************/ +int evel_json_encode_batch_event(char * json, + int max_size, + EVENT_HEADER * event) +{ + EVEL_JSON_BUFFER json_buffer; + EVEL_JSON_BUFFER *jbuf = &json_buffer; + EVEL_THROTTLE_SPEC * throttle_spec; + int tot_size = 0; + EVENT_HEADER * batch_field = NULL; + DLIST_ITEM * batch_field_item = NULL; + + EVEL_ENTER(); + + /***************************************************************************/ + /* Get the latest throttle specification for the domain. */ + /***************************************************************************/ + throttle_spec = evel_get_throttle_spec(event->event_domain); + + /***************************************************************************/ + /* Initialize the JSON_BUFFER and open the top-level objects. */ + /***************************************************************************/ + if (event->event_domain == EVEL_DOMAIN_BATCH){ + evel_json_buffer_init(jbuf, json, max_size, throttle_spec); + + if(dlist_count(&event->batch_events) > 0) + { + evel_json_open_object(jbuf); + evel_json_open_named_list(jbuf, "eventList"); + batch_field_item = dlist_get_first(&event->batch_events); + while (batch_field_item != NULL) + { + batch_field = (EVENT_HEADER *) batch_field_item->item; + if(batch_field != NULL){ + EVEL_DEBUG("Batch Event %p %p added curr fsize %d offset %d depth %d check %d", batch_field_item->item, batch_field, tot_size,jbuf->offset,jbuf->depth,jbuf->checkpoint); + evel_json_open_object(jbuf); + evel_json_encode_eventtype(jbuf, batch_field); + evel_json_close_object(jbuf); + + tot_size += jbuf->offset; + EVEL_DEBUG("Batch Event result size %d offset %d depth %d check %d", tot_size,jbuf->offset,jbuf->depth,jbuf->checkpoint); + if( tot_size >= max_size ){ + EVEL_ERROR("Batch Event exceeded size limit %d", tot_size); + assert(0); + } + batch_field_item = dlist_get_next(batch_field_item); + } + } + evel_json_close_list(jbuf); + evel_json_close_object(jbuf); + } + + } + /***************************************************************************/ + /* Sanity check. */ + /***************************************************************************/ + //assert(jbuf->depth == 0); EVEL_EXIT(); diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_event_mgr.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_event_mgr.c index 89242e3..cc676a6 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_event_mgr.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_event_mgr.c @@ -13,7 +13,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. ****************************************************************************/ /**************************************************************************//** @@ -43,6 +43,11 @@ *****************************************************************************/ static const int EVEL_API_TIMEOUT = 5; +/**************************************************************************//** + * Wait time if both the collectors are not responding + *****************************************************************************/ +static const int EVEL_COLLECTOR_RECONNECTION_WAIT_TIME = 120; + /*****************************************************************************/ /* Prototypes of locally scoped functions. */ /*****************************************************************************/ @@ -58,6 +63,8 @@ static bool evel_tokens_match_command_list(const MEMORY_CHUNK * const chunk, static bool evel_token_equals_string(const MEMORY_CHUNK * const chunk, const jsmntok_t * const json_token, const char * check_string); +static EVEL_ERR_CODES evel_setup_curl(); +static EVEL_ERR_CODES evel_send_to_another_collector(const EVEL_EVENT_DOMAINS evel_domain, char * json_body, size_t json_size); /**************************************************************************//** * Buffers for error strings from libcurl. @@ -68,6 +75,7 @@ static char curl_err_string[CURL_ERROR_SIZE] = "<NULL>"; * Handle for the API into libcurl. *****************************************************************************/ static CURL * curl_handle = NULL; +int curr_global_handles = 0; /**************************************************************************//** * Special headers that we send. @@ -102,7 +110,34 @@ static EVT_HANDLER_STATE evt_handler_state = EVT_HANDLER_UNINITIALIZED; *****************************************************************************/ static char * evel_event_api_url; static char * evel_throt_api_url; +static char * evel_batch_api_url; +static char * evel_bevent_api_url; +static char * evel_bthrot_api_url; +static char * evel_bbatch_api_url; + +/**************************************************************************//** + * Storage for other CURL related parameters + *****************************************************************************/ +int evel_secure = -1; +int evel_verbosity = -1; + +long evel_verify_peer = 0; +long evel_verify_host = 0; + +static char * evel_source_ip = NULL; +static char * evel_source_ip_bakup = NULL; +static char * evel_cert_file_path = NULL; +static char * evel_key_file_path = NULL; +static char * evel_ca_info = NULL; +static char * evel_ca_file_path = NULL; +static char * evel_username = NULL; +static char * evel_password = NULL; +static char * evel_username2 = NULL; +static char * evel_password2 = NULL; + +static long http_response_code = 0; +static int evel_collector_id = 1; /**************************************************************************//** * Initialize the event handler. * @@ -113,19 +148,41 @@ static char * evel_throt_api_url; * to be. * @param[in] throt_api_url * The URL where the Throttling API is expected to be. + * @param[in] source_ip Source IP of VES Agent + * @param[in] ring_buf_size Initial size of ring buffer + * @param[in] secure Whether Using http or https + * @param[in] cert_file_path Path to Client Certificate file + * @param[in] key_file_path Path to Client key file + * @param[in] ca_info Path to CA info file + * @param[in] ca_file_path Path to CA file + * @param[in] verify_peer Using peer verification or not 0 or 1 + * @param[in] verify_host Using host verification or not 0 or 1 * @param[in] username The username for the Basic Authentication of requests. * @param[in] password The password for the Basic Authentication of requests. * @param verbosity 0 for normal operation, positive values for chattier * logs. *****************************************************************************/ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, + const char * const bakup_api_url, const char * const throt_api_url, + const char * const source_ip, + const char * const source_ip_bakup, + int ring_buf_size, + int secure, + const char * const cert_file_path, + const char * const key_file_path, + const char * const ca_info, + const char * const ca_file_path, + long verify_peer, + long verify_host, const char * const username, const char * const password, + const char * const username2, + const char * const password2, int verbosity) { int rc = EVEL_SUCCESS; - CURLcode curl_rc = CURLE_OK; + char batch_api_url[EVEL_MAX_URL_LEN + 1] = {0}; EVEL_ENTER(); @@ -136,15 +193,115 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, assert(throt_api_url != NULL); assert(username != NULL); assert(password != NULL); + if( bakup_api_url != NULL ) + { + assert(username2 != NULL); + assert(password2 != NULL); + } /***************************************************************************/ /* Store the API URLs. */ /***************************************************************************/ evel_event_api_url = strdup(event_api_url); assert(evel_event_api_url != NULL); + sprintf(batch_api_url,"%s/eventBatch",event_api_url); + evel_batch_api_url = strdup(batch_api_url); + assert(evel_batch_api_url != NULL); evel_throt_api_url = strdup(throt_api_url); assert(evel_throt_api_url != NULL); + curr_global_handles = 1; + + if( bakup_api_url != NULL ) + { + evel_bevent_api_url = strdup(bakup_api_url); + assert(evel_bevent_api_url != NULL); + sprintf(batch_api_url,"%s/eventBatch",bakup_api_url); + evel_bbatch_api_url = strdup(batch_api_url); + assert(evel_bbatch_api_url != NULL); + evel_bthrot_api_url = strdup(throt_api_url); + assert(evel_bthrot_api_url != NULL); + curr_global_handles = 2; + } + + /***************************************************************************/ + /* Store other parameters */ + /***************************************************************************/ + evel_secure = secure; + evel_verbosity = verbosity; + + evel_verify_peer = verify_peer; + evel_verify_host = verify_host; + + evel_source_ip = NULL; + if (source_ip != NULL) + { + evel_source_ip = strdup(source_ip); + assert(evel_source_ip != NULL); + } + + evel_source_ip_bakup = NULL; + if (source_ip_bakup != NULL) + { + evel_source_ip_bakup = strdup(source_ip_bakup); + assert(evel_source_ip_bakup != NULL); + } + + evel_cert_file_path = NULL; + if (cert_file_path != NULL) + { + evel_cert_file_path = strdup(cert_file_path); + assert(evel_cert_file_path != NULL); + } + + evel_key_file_path = NULL; + if (key_file_path != NULL) + { + evel_key_file_path = strdup(key_file_path); + assert(evel_key_file_path != NULL); + } + + evel_ca_info = NULL; + if (ca_info != NULL) + { + evel_ca_info = strdup(ca_info); + assert(evel_ca_info != NULL); + } + + evel_ca_file_path = NULL; + if (ca_file_path != NULL) + { + evel_ca_file_path = strdup(ca_file_path); + assert(evel_ca_file_path != NULL); + } + + evel_username = NULL; + if (username != NULL) + { + evel_username = strdup(username); + assert(evel_username != NULL); + } + + evel_password = NULL; + if (password != NULL) + { + evel_password = strdup(password); + assert(evel_password != NULL); + } + + evel_username2 = NULL; + if (username2 != NULL) + { + evel_username2 = strdup(username2); + assert(evel_username2 != NULL); + } + + evel_password2 = NULL; + if (password2 != NULL) + { + evel_password2 = strdup(password2); + assert(evel_password2 != NULL); + } curl_version_info_data *d = curl_version_info(CURLVERSION_NOW); /* compare with the 24 bit hex number in 8 bit fields */ @@ -155,6 +312,83 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, else { EVEL_INFO("Old Curl version."); } + + /***************************************************************************/ + /* Initialize a message ring-buffer to be used between the foreground and */ + /* the thread which sends the messages. This can't fail. */ + /***************************************************************************/ + if( ring_buf_size < EVEL_EVENT_BUFFER_DEPTH ) + { + log_error_state("Warning: Failed to initialize Ring buffer size to %d. ", + ring_buf_size); + goto exit_label; + } + ring_buffer_initialize(&event_buffer, EVEL_EVENT_BUFFER_DEPTH); + +exit_label: + + EVEL_EXIT(); + + return rc; + +} +/**************************************************************************//** + * Setup the curl connection to collector + * + * Primarily responsible for getting CURL ready to send message. Also it would + * be used to swithch over to other collector + *****************************************************************************/ +static EVEL_ERR_CODES evel_setup_curl() +{ + int rc = EVEL_SUCCESS; + CURLcode curl_rc = CURLE_OK; + char local_address[64]; + char * api_url = NULL; + char * username = NULL; + char * password = NULL; + char * source_ip = NULL; + + EVEL_ENTER(); + + if (evel_collector_id > 2) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Wrong evel_collector- value > 2"); + goto exit_label; + } + + /***************************************************************************/ + /* Initialize the local variable with proper global variables that are */ + /* required to setup the connection */ + /***************************************************************************/ + if (evel_collector_id == 1) + { + api_url = evel_event_api_url; + source_ip = evel_source_ip; + username = evel_username; + password = evel_password; + } + else if (evel_collector_id == 2) + { + api_url = evel_bevent_api_url; + source_ip = evel_source_ip_bakup; + username = evel_username2; + password = evel_password2; + } + /***************************************************************************/ + /* Clean-up the cURL library. */ + /***************************************************************************/ + if (curl_handle != NULL) + { + curl_easy_cleanup(curl_handle); + curl_handle = NULL; + } + if (hdr_chunk != NULL) + { + curl_slist_free_all(hdr_chunk); + hdr_chunk = NULL; + } + /***************************************************************************/ /* Start the CURL library. Note that this initialization is not threadsafe */ /* which imposes a constraint that the EVEL library is initialized before */ @@ -196,7 +430,7 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, /***************************************************************************/ /* If running in verbose mode generate more output. */ /***************************************************************************/ - if (verbosity > 0) + if (evel_verbosity > 0) { curl_rc = curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 1L); if (curl_rc != CURLE_OK) @@ -211,7 +445,7 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, /***************************************************************************/ /* Set the URL for the API. */ /***************************************************************************/ - curl_rc = curl_easy_setopt(curl_handle, CURLOPT_URL, event_api_url); + curl_rc = curl_easy_setopt(curl_handle, CURLOPT_URL, api_url); if (curl_rc != CURLE_OK) { rc = EVEL_CURL_LIBRARY_FAIL; @@ -219,7 +453,7 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, "Error code=%d (%s)", curl_rc, curl_err_string); goto exit_label; } - EVEL_INFO("Initializing CURL to send events to: %s", event_api_url); + EVEL_INFO("Initializing CURL to send events to: %s", api_url); /***************************************************************************/ /* send all data to this function. */ @@ -236,6 +470,114 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, } /***************************************************************************/ + /* configure local ip address if provided */ + /* Default ip if NULL */ + /***************************************************************************/ + if( source_ip != NULL ) + { + snprintf(local_address,sizeof(local_address),source_ip); + if( local_address[0] != '\0' ) + { + curl_rc = curl_easy_setopt(curl_handle, + CURLOPT_INTERFACE, + local_address); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with the local address. " + "Error code=%d (%s)", curl_rc, curl_err_string); + goto exit_label; + } + } + } + + /***************************************************************************/ + /* configure SSL options for HTTPS transfers */ + /***************************************************************************/ + if( evel_secure ) + { + if( evel_cert_file_path != NULL ) + { + curl_rc = curl_easy_setopt(curl_handle, + CURLOPT_SSLCERT, + evel_cert_file_path); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with the client cert. " + "Error code=%d (%s)", curl_rc, curl_err_string); + goto exit_label; + } + } + + if( evel_key_file_path != NULL ) + { + curl_rc = curl_easy_setopt(curl_handle, + CURLOPT_SSLKEY, + evel_key_file_path); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with the client key. " + "Error code=%d (%s)", curl_rc, curl_err_string); + goto exit_label; + } + } + + if( evel_ca_info != NULL ) + { + curl_rc = curl_easy_setopt(curl_handle, + CURLOPT_CAINFO, + evel_ca_info); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with the CA cert file. " + "Error code=%d (%s)", curl_rc, curl_err_string); + goto exit_label; + } + } + + if( evel_ca_file_path != NULL ) + { + curl_rc = curl_easy_setopt(curl_handle, + CURLOPT_CAPATH, + evel_ca_file_path); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with the CA cert path. " + "Error code=%d (%s)", curl_rc, curl_err_string); + goto exit_label; + } + } + + curl_rc = curl_easy_setopt(curl_handle, + CURLOPT_SSL_VERIFYPEER, + evel_verify_peer); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with SSL Server verification. " + "Error code=%d (%s)", curl_rc, curl_err_string); + goto exit_label; + } + curl_rc = curl_easy_setopt(curl_handle, + CURLOPT_SSL_VERIFYHOST, + evel_verify_host); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with Client host verification. " + "Error code=%d (%s)", curl_rc, curl_err_string); + goto exit_label; + } + + } + + + + /***************************************************************************/ /* some servers don't like requests that are made without a user-agent */ /* field, so we provide one. */ /***************************************************************************/ @@ -340,12 +682,6 @@ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, } /***************************************************************************/ - /* Initialize a message ring-buffer to be used between the foreground and */ - /* the thread which sends the messages. This can't fail. */ - /***************************************************************************/ - ring_buffer_initialize(&event_buffer, EVEL_EVENT_BUFFER_DEPTH); - - /***************************************************************************/ /* Initialize the priority post buffer to empty. */ /***************************************************************************/ priority_post.memory = NULL; @@ -469,6 +805,11 @@ EVEL_ERR_CODES event_handler_terminate() free(evel_event_api_url); evel_event_api_url = NULL; } + if (evel_batch_api_url != NULL) + { + free(evel_batch_api_url); + evel_batch_api_url = NULL; + } if (evel_throt_api_url != NULL) { free(evel_throt_api_url); @@ -546,7 +887,6 @@ static EVEL_ERR_CODES evel_post_api(char * msg, size_t size) CURLcode curl_rc = CURLE_OK; MEMORY_CHUNK rx_chunk; MEMORY_CHUNK tx_chunk; - int http_response_code = 0; EVEL_ENTER(); @@ -609,6 +949,8 @@ static EVEL_ERR_CODES evel_post_api(char * msg, size_t size) /***************************************************************************/ /* Now run off and do what you've been told! */ /***************************************************************************/ + http_response_code = 0; + curl_rc = curl_easy_perform(curl_handle); if (curl_rc != CURLE_OK) { @@ -665,6 +1007,57 @@ exit_label: } /**************************************************************************//** + * Send event to another collector + * + * Identify the next collector and try sending the event to that collector + ****************************************************************************/ +static EVEL_ERR_CODES evel_send_to_another_collector( + const EVEL_EVENT_DOMAINS evel_domain, + char * json_body, + size_t json_size) +{ + int rc = EVEL_SUCCESS; + CURLcode curl_rc; + + EVEL_ENTER(); + + if ((evel_collector_id == 1) && (curr_global_handles == 2)) + { + evel_collector_id =2; + } + else if (evel_collector_id == 2) + { + evel_collector_id =1; + } + + rc = evel_setup_curl(); + + if ( rc == EVEL_SUCCESS) + { + if (evel_collector_id == 1) + { + if (evel_domain == EVEL_DOMAIN_BATCH) + curl_rc = curl_easy_setopt(curl_handle, CURLOPT_URL, evel_batch_api_url); + else + curl_rc = curl_easy_setopt(curl_handle, CURLOPT_URL, evel_event_api_url); + } + else if (evel_collector_id == 2) + { + if (evel_domain == EVEL_DOMAIN_BATCH) + curl_rc = curl_easy_setopt(curl_handle, CURLOPT_URL, evel_bbatch_api_url); + else + curl_rc = curl_easy_setopt(curl_handle, CURLOPT_URL, evel_bevent_api_url); + } + + rc = evel_post_api(json_body, json_size); + } + + EVEL_EXIT(); + + return rc; +} + +/**************************************************************************//** * Callback function to provide data to send. * * Copy data into the supplied buffer, read_callback::ptr, checking size @@ -755,6 +1148,8 @@ static void * event_handler(void * arg __attribute__ ((unused))) char json_body[EVEL_MAX_JSON_BODY]; int rc = EVEL_SUCCESS; CURLcode curl_rc; + int collector_down_count = 0; + int switch_coll = 0; EVEL_INFO("Event handler thread started"); @@ -777,6 +1172,50 @@ static void * event_handler(void * arg __attribute__ ((unused))) EVEL_ERROR("Event Handler State was not INACTIVE at start-up - " "Handler will exit immediately!"); } + /***************************************************************************/ + /* Set the connection to collector */ + /***************************************************************************/ + while (true) + { + evel_collector_id = 1; + rc = evel_setup_curl(); + + if ( rc != EVEL_SUCCESS) + { + EVEL_ERROR("Failed to setup the first collector. Error code=%d", rc); + if (curr_global_handles == 2) + { + EVEL_DEBUG("Switching to other collector"); + + evel_collector_id = 2; + + rc = evel_setup_curl(); + if ( rc != EVEL_SUCCESS) + { + EVEL_ERROR("Failed to setup the connection to second collector also, Error code%d", rc); + sleep(EVEL_COLLECTOR_RECONNECTION_WAIT_TIME); + collector_down_count = collector_down_count + 1; + EVEL_ERROR("Collectors setup issue- retry count=%d", collector_down_count); + } + else + { + collector_down_count = 0; + break; + } + } + else + { + sleep(EVEL_COLLECTOR_RECONNECTION_WAIT_TIME); + collector_down_count = collector_down_count + 1; + EVEL_ERROR("Collector setup issue-retry count=%d", collector_down_count); + } + } + else + { + collector_down_count = 0; + break; + } + } while (evt_handler_state == EVT_HANDLER_ACTIVE) { @@ -790,7 +1229,106 @@ static void * event_handler(void * arg __attribute__ ((unused))) /* Internal events get special treatment while regular events get posted */ /* to the far side. */ /*************************************************************************/ - if (msg->event_domain != EVEL_DOMAIN_INTERNAL) + if (msg->event_domain == EVEL_DOMAIN_BATCH ) + { + EVEL_DEBUG("Batch event received"); + + /***********************************************************************/ + /* Encode the event in JSON. */ + /***********************************************************************/ + json_size = evel_json_encode_batch_event(json_body, EVEL_MAX_JSON_BODY, msg); + + /***************************************************************************/ + /* Set the URL for the API. */ + /***************************************************************************/ + if (evel_collector_id == 1) + { + curl_rc = curl_easy_setopt(curl_handle, CURLOPT_URL, evel_batch_api_url); + } + else + { + curl_rc = curl_easy_setopt(curl_handle, CURLOPT_URL, evel_bbatch_api_url); + } + + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with the Batch API URL. " + "Error code=%d (%s)", curl_rc, curl_err_string); + } + + /***********************************************************************/ + /* Send the JSON across the API. */ + /***********************************************************************/ + EVEL_DEBUG("Sending Batch JSON of size %d is: %s", json_size, json_body); + rc = evel_post_api(json_body, json_size); + + switch_coll = 0; + if ((rc == EVEL_SUCCESS) && ((http_response_code / 100) != 2)) + { + switch_coll = 1; + if (http_response_code == 400) // 400 - Bad JSON related return code + switch_coll = 0; + } + + if ((rc != EVEL_SUCCESS) || (switch_coll == 1)) + { + EVEL_ERROR("Failed to transfer the data. Error code=%d", rc); + EVEL_DEBUG("Switching to other collector if any"); + + while (true) + { + if (curr_global_handles == 2) + { + rc = evel_send_to_another_collector(msg->event_domain, json_body, json_size); + + switch_coll = 0; + if ((rc == EVEL_SUCCESS) && ((http_response_code / 100) != 2)) + { + switch_coll = 1; + if (http_response_code == 400) // 400 - Bad JSON related return code + switch_coll = 0; + } + if ((rc != EVEL_SUCCESS) || (switch_coll == 1)) + { + sleep(EVEL_COLLECTOR_RECONNECTION_WAIT_TIME); + collector_down_count = collector_down_count + 1; + EVEL_ERROR("Collector setup issue-retry count=%d", collector_down_count); + } + else + { + break; + } + } + else + { + sleep(EVEL_COLLECTOR_RECONNECTION_WAIT_TIME); + collector_down_count = collector_down_count + 1; + EVEL_ERROR("Collector setup issue-retry count=%d", collector_down_count); + } + + rc = evel_send_to_another_collector(msg->event_domain, json_body, json_size); + + switch_coll = 0; + if ((rc == EVEL_SUCCESS) && ((http_response_code / 100) != 2)) + { + switch_coll = 1; + if (http_response_code == 400) // 400 - Bad JSON related return code + switch_coll = 0; + } + if ((rc != EVEL_SUCCESS) || (switch_coll == 1)) + { + collector_down_count = collector_down_count + 1; + EVEL_ERROR("Collector setup issue-retry count=%d", collector_down_count); + } + else + { + break; + } + } + } + } + else if (msg->event_domain != EVEL_DOMAIN_INTERNAL ) { EVEL_DEBUG("External event received"); @@ -799,14 +1337,89 @@ static void * event_handler(void * arg __attribute__ ((unused))) /***********************************************************************/ json_size = evel_json_encode_event(json_body, EVEL_MAX_JSON_BODY, msg); + /***************************************************************************/ + /* Set the URL for the API. */ + /***************************************************************************/ + if (evel_collector_id == 1) + curl_rc = curl_easy_setopt(curl_handle, CURLOPT_URL, evel_event_api_url); + else + curl_rc = curl_easy_setopt(curl_handle, CURLOPT_URL, evel_bevent_api_url); + if (curl_rc != CURLE_OK) + { + rc = EVEL_CURL_LIBRARY_FAIL; + log_error_state("Failed to initialize libCURL with the API URL. " + "Error code=%d (%s)", curl_rc, curl_err_string); + } + /***********************************************************************/ /* Send the JSON across the API. */ /***********************************************************************/ EVEL_DEBUG("Sending JSON of size %d is: %s", json_size, json_body); rc = evel_post_api(json_body, json_size); - if (rc != EVEL_SUCCESS) + + switch_coll = 0; + if ((rc == EVEL_SUCCESS) && ((http_response_code / 100) != 2)) + { + switch_coll = 1; + if (http_response_code == 400) // 400 - Bad JSON related return code + switch_coll = 0; + } + + if ((rc != EVEL_SUCCESS) || (switch_coll == 1)) { EVEL_ERROR("Failed to transfer the data. Error code=%d", rc); + EVEL_DEBUG("Switching to other collector if any"); + + while (true) + { + if (curr_global_handles == 2) + { + rc = evel_send_to_another_collector(msg->event_domain, json_body, json_size); + + switch_coll = 0; + if ((rc == EVEL_SUCCESS) && ((http_response_code / 100) != 2)) + { + switch_coll = 1; + if (http_response_code == 400) // 400 - Bad JSON related return code + switch_coll = 0; + } + if ((rc != EVEL_SUCCESS) || (switch_coll == 1)) + { + sleep(EVEL_COLLECTOR_RECONNECTION_WAIT_TIME); + collector_down_count = collector_down_count + 1; + EVEL_ERROR("Collector setup issue-retry count=%d", collector_down_count); + } + else + { + break; + } + } + else + { + sleep(EVEL_COLLECTOR_RECONNECTION_WAIT_TIME); + collector_down_count = collector_down_count + 1; + EVEL_ERROR("Collector setup issue-retry count=%d", collector_down_count); + } + + rc = evel_send_to_another_collector(msg->event_domain, json_body, json_size); + + switch_coll = 0; + if ((rc == EVEL_SUCCESS) && ((http_response_code / 100) != 2)) + { + switch_coll = 1; + if (http_response_code == 400) // 400 - Bad JSON related return code + switch_coll = 0; + } + if ((rc != EVEL_SUCCESS) || (switch_coll == 1)) + { + collector_down_count = collector_down_count + 1; + EVEL_ERROR("Collector setup issue-retry count=%d", collector_down_count); + } + else + { + break; + } + } } } else @@ -962,7 +1575,7 @@ bool evel_handle_response_tokens(const MEMORY_CHUNK * const chunk, const int num_tokens, MEMORY_CHUNK * const post) { - bool json_ok = false; + bool json_ok = true; EVEL_ENTER(); diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_fault.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_fault.c index 321d354..401e4ad 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_fault.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_fault.c @@ -13,7 +13,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. ****************************************************************************/ /**************************************************************************//** @@ -92,6 +92,10 @@ EVENT_FAULT * evel_new_fault(const char * ev_name, fault->major_version = EVEL_FAULT_MAJOR_VERSION; fault->minor_version = EVEL_FAULT_MINOR_VERSION; fault->event_severity = severity; + if( severity == EVEL_SEVERITY_NORMAL ) + evel_event_sequence_set(&fault->header,0); + else + evel_event_sequence_set(&fault->header,1); fault->event_source_type = ev_source_type; fault->vf_status = status; fault->alarm_condition = strdup(condition); diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_heartbeat_fields.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_heartbeat_fields.c index 899f1d7..be8527c 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_heartbeat_fields.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_heartbeat_fields.c @@ -13,7 +13,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. ****************************************************************************/ /**************************************************************************//** @@ -36,10 +36,9 @@ * this factory function and are immutable once set. Optional fields * have explicit setter functions, but again values may only be set * once so that the event has immutable properties. - * @param event_name Unique Event Name confirming Domain AsdcModel Description - * @param event_id A universal identifier of the event for: troubleshooting correlation, analysis, etc - * @param vendor_id The vendor id to encode in the event instance id. - * @param event_id The vendor event id to encode in the event instance id. + * @param ev_name Unique Event Name confirming Domain AsdcModel Description + * @param ev_id A universal identifier of the event for: troubleshooting correlation, analysis, etc + * @param interval heartbeat interval * @returns pointer to the newly manufactured ::EVENT_HEARTBEAT_FIELD. If the event * is not used (i.e. posted) it must be released using * ::evel_free_hrtbt_field. diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_internal.h b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_internal.h index 46f71af..14d224d 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_internal.h +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_internal.h @@ -172,17 +172,45 @@ typedef struct evel_throttle_spec { * @param[in] event_api_url * The URL where the Vendor Event Listener API is expected * to be. + * @param[in] bakup_api_url + * The BakupURL where the Vendor Backup Listener is expected + * to be. * @param[in] throt_api_url * The URL where the Throttling API is expected to be. + * @param[in] source_ip Source IP of VES Agent + * @param[in] bakup_source_ip Backup Source IP of VES Agent + * @param[in] ring_buf_size Initialization size of Ring Buffer + * @param[in] secure Whether Using http or https + * @param[in] cert_file_path Path to Client Certificate file + * @param[in] key_file_path Path to Client key file + * @param[in] ca_info Path to CA info file + * @param[in] ca_file_path Path to CA file + * @param[in] verify_peer Using peer verification or not + * @param[in] verify_host Using host verification or not * @param[in] username The username for the Basic Authentication of requests. * @param[in] password The password for the Basic Authentication of requests. + * @param[in] username2 The username for the Bakup requests. + * @param[in] password2 The password for the Bakup requests. * @param verbosity 0 for normal operation, positive values for chattier * logs. *****************************************************************************/ EVEL_ERR_CODES event_handler_initialize(const char * const event_api_url, + const char * const bakup_api_url, const char * const throt_api_url, + const char * const source_ip, + const char * const bakup_source_ip, + int ring_buf_size, + int secure, + const char * const cert_file_path, + const char * const key_file_path, + const char * const ca_info, + const char * const ca_file_path, + long verify_peer, + long verify_host, const char * const username, const char * const password, + const char * const username2, + const char * const password2, int verbosity); /**************************************************************************//** diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_internal_event.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_internal_event.c index 73546c5..dff2bae 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_internal_event.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_internal_event.c @@ -13,7 +13,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. ****************************************************************************/ /**************************************************************************//** diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_json_buffer.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_json_buffer.c index 5467595..cf1323d 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_json_buffer.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_json_buffer.c @@ -13,7 +13,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. ****************************************************************************/ /**************************************************************************//** @@ -521,6 +521,7 @@ void evel_enc_version(EVEL_JSON_BUFFER * jbuf, const int major_version, const int minor_version) { + float ver; EVEL_ENTER(); /***************************************************************************/ @@ -529,14 +530,14 @@ void evel_enc_version(EVEL_JSON_BUFFER * jbuf, assert(jbuf != NULL); assert(key != NULL); - evel_enc_kv_int(jbuf, key, major_version); - if (minor_version != 0) - { + ver = (float)major_version + (float)minor_version/10.0; + jbuf->offset += snprintf(jbuf->json + jbuf->offset, - jbuf->max_size - jbuf->offset, - ".%d", - minor_version); - } + jbuf->max_size - jbuf->offset, + "%s\"%s\": %.1f", + evel_json_kv_comma(jbuf), + key, + ver); EVEL_EXIT(); } diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_jsonobject.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_jsonobject.c index 57e6839..df0b03c 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_jsonobject.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_jsonobject.c @@ -13,7 +13,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. ****************************************************************************/ /**************************************************************************//** @@ -113,7 +113,7 @@ EVEL_JSON_OBJECT_INSTANCE * evel_new_jsonobjinstance(const char *const yourjson) assert(len > 0); /***************************************************************************/ - /* Validate JSON for json object + /* Validate JSON for json object */ /***************************************************************************/ jsmn_init(&p); resultCode = jsmn_parse(&p, yourjson, len, tokens, sizeof(tokens)/sizeof(tokens[0])); @@ -298,7 +298,7 @@ void evel_jsonobject_nfsubscriptionid_set(EVEL_JSON_OBJECT * pinst, const char * void evel_epoch_microsec_set(EVEL_JSON_OBJECT_INSTANCE * pinst, const unsigned long long epmicrosec) { assert(epmicrosec != 0 ); - pinst->objinst_epoch_microsec = epmicrosec; + evel_set_option_ull(&pinst->objinst_epoch_microsec , epmicrosec, "Json object instance microsec set"); } /**************************************************************************//** @@ -321,7 +321,7 @@ void evel_jsonobject_add_jsoninstance(EVEL_JSON_OBJECT * pobj, EVEL_JSON_OBJECT_ assert(pobj != NULL); assert(jinst != NULL); - EVEL_DEBUG("Adding json object instance"); + EVEL_DEBUG("Adding json object instance %p",jinst); dlist_push_last(&pobj->jsonobjectinstances, jinst); @@ -375,6 +375,7 @@ void evel_free_internal_key(EVEL_INTERNAL_KEY * keyp) free(keyp->keyname); evel_free_option_string(&keyp->keyvalue); + free(keyp); EVEL_EXIT(); } @@ -397,7 +398,7 @@ void evel_free_jsonobjinst(EVEL_JSON_OBJECT_INSTANCE * objinst) free(objinst->jsonstring); /***************************************************************************/ - /* Free all internal internal keys + /* Free all internal internal keys */ /***************************************************************************/ other_field = dlist_pop_last(&objinst->object_keys); while (other_field != NULL) @@ -407,6 +408,7 @@ void evel_free_jsonobjinst(EVEL_JSON_OBJECT_INSTANCE * objinst) evel_free_internal_key(other_field); other_field = dlist_pop_last(&objinst->object_keys); } + free(objinst); EVEL_EXIT(); } @@ -425,6 +427,7 @@ void evel_free_jsonobject(EVEL_JSON_OBJECT * jsobj) EVEL_ENTER(); assert(jsobj != NULL); + EVEL_DEBUG("Freeing Json Object (%s)", jsobj->object_name); free(jsobj->object_name); evel_free_option_string(&jsobj->objectschema); evel_free_option_string(&jsobj->objectschemaurl); @@ -437,11 +440,12 @@ void evel_free_jsonobject(EVEL_JSON_OBJECT * jsobj) other_field = dlist_pop_last(&jsobj->jsonobjectinstances); while (other_field != NULL) { - EVEL_DEBUG("Freeing Object Instance Field (%s)", - other_field->jsonstring); + EVEL_DEBUG("Freeing jsonObject Instance Field %p (%s)", + other_field,other_field->jsonstring); evel_free_jsonobjinst(other_field); other_field = dlist_pop_last(&jsobj->jsonobjectinstances); } + free(jsobj); EVEL_EXIT(); } diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_logging.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_logging.c index f26e487..cb07396 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_logging.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_logging.c @@ -13,7 +13,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. ****************************************************************************/ /**************************************************************************//** * @file diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_mobile_flow.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_mobile_flow.c index 093cb13..90b1a44 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_mobile_flow.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_mobile_flow.c @@ -13,7 +13,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. ****************************************************************************/ /**************************************************************************//** * @file diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_option.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_option.c index dc2e347..7818fe1 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_option.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_option.c @@ -13,7 +13,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. ****************************************************************************/ /**************************************************************************//** * @file diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_other.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_other.c index d68f815..5f59c1d 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_other.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_other.c @@ -18,9 +18,9 @@ /**************************************************************************//** * @file - * Implementation of EVEL functions relating to Other. + * Implementation of EVEL functions relating to Other domain. * - ****************************************************************************/ + *****************************************************************************/ #include <string.h> #include <assert.h> @@ -40,7 +40,7 @@ * not used (i.e. posted) it must be released using ::evel_free_other. * @retval NULL Failed to create the event. *****************************************************************************/ -EVENT_OTHER * evel_new_other(const char *ev_name, const char *ev_id) +EVENT_OTHER * evel_new_other(const char* ev_name, const char *ev_id) { EVENT_OTHER * other = NULL; EVEL_ENTER(); @@ -107,18 +107,15 @@ void evel_other_type_set(EVENT_OTHER * other, } /**************************************************************************//** - * Add a json object to jsonObject list. + * Set size of Named arrays hash table * - * The name and value are null delimited ASCII strings. The library takes - * a copy so the caller does not have to preserve values after the function - * returns. + * The max size of hash table is passed * * @param other Pointer to the Other. * @param size size of hashtable *****************************************************************************/ void evel_other_field_set_namedarraysize(EVENT_OTHER * other, const int size) { - OTHER_FIELD * other_field = NULL; EVEL_ENTER(); /***************************************************************************/ @@ -172,19 +169,19 @@ void evel_other_field_add_namedarray(EVENT_OTHER * other, const char *hashname, assert(other_field->value != NULL); - list = ht_get(other->namedarrays, hashname); + list = (DLIST *)ht_get(other->namedarrays, hashname); if( list == NULL ) { DLIST * nlist = malloc(sizeof(DLIST)); dlist_initialize(nlist); dlist_push_last(nlist, other_field); - ht_set(other->namedarrays, hashname, nlist); - EVEL_DEBUG("Created to new table table"); + ht_set(other->namedarrays, hashname,(void*)nlist); + EVEL_DEBUG("Created to new namedarray table %p",nlist); } else { dlist_push_last(list, other_field); - EVEL_DEBUG("Adding to existing table"); + EVEL_DEBUG("Adding to existing table %p",list); } EVEL_EXIT(); @@ -203,7 +200,6 @@ void evel_other_field_add_namedarray(EVENT_OTHER * other, const char *hashname, *****************************************************************************/ void evel_other_field_add_jsonobj(EVENT_OTHER * other, EVEL_JSON_OBJECT *jsonobj) { - OTHER_FIELD * other_field = NULL; EVEL_ENTER(); /***************************************************************************/ @@ -277,9 +273,10 @@ void evel_json_encode_other(EVEL_JSON_BUFFER * jbuf, EVEL_INTERNAL_KEY * keyinst = NULL; DLIST_ITEM * keyinst_field_item = NULL; HASHTABLE_T *ht = NULL; - int i; + int idx; bool itm_added = false; DLIST *itm_list = NULL; + ENTRY_T *entry = NULL; EVEL_ENTER(); @@ -294,33 +291,31 @@ void evel_json_encode_other(EVEL_JSON_BUFFER * jbuf, // iterate through hashtable and print DLIST for each entry + evel_json_checkpoint(jbuf); ht = event->namedarrays; if( ht != NULL ) { if( ht->size > 0) { - for( i = 0; i < ht->size; i++ ) { - if( ht->table[i] != NULL) - { - itm_added = true; - } - } - if( itm_added == true) - { - if (evel_json_open_opt_named_list(jbuf, "hashOfNameValuePairArrays")) - { - for( i = 0; i < ht->size; i++ ) { - if( ht->table[i] != NULL) + evel_json_open_opt_named_list(jbuf, "hashOfNameValuePairArrays"); + for( idx = 0; idx < ht->size; idx++ ) { + if( ht->table[idx] != NULL) { - itm_list = ht->table[i]; + entry = ht->table[idx]; + EVEL_DEBUG("Encoding other %s %p",(char *) (entry->key), entry->value); - if(evel_json_open_opt_named_list(jbuf, ht->table[i]->key)) - { - other_field_item = dlist_get_first(&itm_list); + evel_json_open_object(jbuf); + evel_enc_kv_string(jbuf, "name", entry->key); + + itm_list = (DLIST*)(entry->value); + evel_json_open_opt_named_list(jbuf, "arrayOfFields"); + + other_field_item = dlist_get_first(itm_list); while (other_field_item != NULL) { other_field = (OTHER_FIELD *) other_field_item->item; + EVEL_DEBUG("Encoding other %s %s",(char *)other_field->name,(char*)other_field->value); if(other_field != NULL){ evel_json_open_object(jbuf); evel_enc_kv_string(jbuf, "name", other_field->name); @@ -329,17 +324,15 @@ void evel_json_encode_other(EVEL_JSON_BUFFER * jbuf, other_field_item = dlist_get_next(other_field_item); } } - evel_json_close_list(jbuf); - } + evel_json_close_list(jbuf); + evel_json_close_object(jbuf); } - } - - evel_json_close_list(jbuf); - } - - } + evel_json_close_list(jbuf); + + } else { + evel_json_rewind(jbuf); } } @@ -366,7 +359,7 @@ void evel_json_encode_other(EVEL_JSON_BUFFER * jbuf, { evel_json_open_object(jbuf); evel_enc_kv_object(jbuf, "objectInstance", jsonobjinst->jsonstring); - evel_enc_kv_ull(jbuf, "objectInstanceEpochMicrosec", jsonobjinst->objinst_epoch_microsec); + evel_enc_kv_opt_ull(jbuf, "objectInstanceEpochMicrosec", &jsonobjinst->objinst_epoch_microsec); //evel_json_checkpoint(jbuf); if (evel_json_open_opt_named_list(jbuf, "objectKeys")) { @@ -428,23 +421,37 @@ void evel_json_encode_other(EVEL_JSON_BUFFER * jbuf, } + evel_json_checkpoint(jbuf); if( evel_json_open_opt_named_list(jbuf, "nameValuePairs")) { + bool item_added = false; + other_field_item = dlist_get_first(&event->namedvalues); while (other_field_item != NULL) { other_field = (OTHER_FIELD *) other_field_item->item; - assert(other_field != NULL); - - evel_json_open_object(jbuf); - evel_enc_kv_string(jbuf, "name", other_field->name); - evel_enc_kv_string(jbuf, "value", other_field->value); - evel_json_close_object(jbuf); + if(other_field != NULL) + { + evel_json_open_object(jbuf); + evel_enc_kv_string(jbuf, "name", other_field->name); + evel_enc_kv_string(jbuf, "value", other_field->value); + evel_json_close_object(jbuf); + item_added = true; + } other_field_item = dlist_get_next(other_field_item); } - } evel_json_close_list(jbuf); + /*************************************************************************/ + /* If we've not written anything, rewind to before we opened the list. */ + /*************************************************************************/ + if (!item_added) + { + evel_json_rewind(jbuf); + } + + } + evel_enc_version(jbuf, "otherFieldsVersion", event->major_version,event->minor_version); evel_json_close_object(jbuf); @@ -463,6 +470,8 @@ void evel_json_encode_other(EVEL_JSON_BUFFER * jbuf, void evel_free_other(EVENT_OTHER * event) { OTHER_FIELD * other_field = NULL; + EVEL_JSON_OBJECT * jsonobjp = NULL; + DLIST_ITEM * other_field_item = NULL; EVEL_ENTER(); @@ -487,6 +496,15 @@ void evel_free_other(EVENT_OTHER * event) free(other_field); other_field = dlist_pop_last(&event->namedvalues); } + + jsonobjp = dlist_pop_last(&event->jsonobjects); + while (jsonobjp != NULL) + { + evel_free_jsonobject( jsonobjp ); + + jsonobjp = dlist_pop_last(&event->jsonobjects); + } + evel_free_header(&event->header); EVEL_EXIT(); diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_reporting_measurement.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_reporting_measurement.c index 60fbad7..0f30372 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_reporting_measurement.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_reporting_measurement.c @@ -13,7 +13,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. ****************************************************************************/ /**************************************************************************//** diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_scaling_measurement.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_scaling_measurement.c index ef4537b..04bed57 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_scaling_measurement.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_scaling_measurement.c @@ -13,7 +13,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. ****************************************************************************/ /**************************************************************************//** * @file @@ -170,6 +170,35 @@ void evel_measurement_addl_info_add(EVENT_MEASUREMENT * measurement, char * name } /**************************************************************************//** + * Add a json object to jsonObject list. + * + * The name and value are null delimited ASCII strings. The library takes + * a copy so the caller does not have to preserve values after the function + * returns. + * + * @param measurement Pointer to the ScalingMeasurement + * @param jsonobj Pointer to json object + *****************************************************************************/ +void evel_measurement_addl_object_add(EVENT_MEASUREMENT * measurement, EVEL_JSON_OBJECT *jsonobj) +{ + EVEL_ENTER(); + + /***************************************************************************/ + /* Check preconditions. */ + /***************************************************************************/ + assert(measurement != NULL); + assert(measurement->header.event_domain == EVEL_DOMAIN_MEASUREMENT); + assert(jsonobj != NULL); + + EVEL_DEBUG("Adding jsonObject %p",jsonobj); + + dlist_push_last(&measurement->additional_objects, jsonobj); + + EVEL_EXIT(); +} + + +/**************************************************************************//** * Set the Concurrent Sessions property of the Measurement. * * @note The property is treated as immutable: it is only valid to call @@ -984,6 +1013,25 @@ void evel_measurement_disk_use_mergewritemax_set(MEASUREMENT_DISK_USE * const di /**************************************************************************//** * Set number of logical write operations that were merged into physical read * operations, e.g., two logical writes were served by one physical disk access; + * provide the average measurement within the measurement interval + * + * @note The property is treated as immutable: it is only valid to call + * the setter once. However, we don't assert if the caller tries to + * overwrite, just ignoring the update instead. + * + * @param disk_use Pointer to the Disk Use. + * @param val double + *****************************************************************************/ +void evel_measurement_disk_use_mergewriteavg_set(MEASUREMENT_DISK_USE * const disk_use, + const double val) +{ + EVEL_ENTER(); + evel_set_option_double(&disk_use->mergewriteavg, val, "Disk writeavg set"); + EVEL_EXIT(); +} +/**************************************************************************//** + * Set number of logical write operations that were merged into physical read + * operations, e.g., two logical writes were served by one physical disk access; * provide the maximum measurement within the measurement interval * * @note The property is treated as immutable: it is only valid to call @@ -2801,17 +2849,17 @@ void evel_vnic_performance_tx_total_pkt_delta_set(MEASUREMENT_VNIC_PERFORMANCE * * @param tx_ucast_packets_acc *****************************************************************************/ void evel_vnic_performance_tx_ucast_pkt_acc_set(MEASUREMENT_VNIC_PERFORMANCE * const vnic_performance, - const double tx_ucast_packets_acc) + const double mtx_ucast_packets_acc) { EVEL_ENTER(); /***************************************************************************/ /* Check preconditions. */ /***************************************************************************/ - assert(tx_ucast_packets_acc >= 0.0); + assert(mtx_ucast_packets_acc >= 0.0); evel_set_option_double(&vnic_performance->tx_ucast_packets_acc, - tx_ucast_packets_acc, + mtx_ucast_packets_acc, "Transmitted Unicast Packets accumulated"); EVEL_EXIT(); @@ -3004,6 +3052,13 @@ void evel_json_encode_measurement(EVEL_JSON_BUFFER * jbuf, DLIST_ITEM * nested_item = NULL; DLIST_ITEM * addl_info_item = NULL; OTHER_FIELD *addl_info = NULL; + DLIST_ITEM * other_field_item = NULL; + EVEL_JSON_OBJECT_INSTANCE * jsonobjinst = NULL; + EVEL_JSON_OBJECT * jsonobjp = NULL; + DLIST_ITEM * jsobj_field_item = NULL; + EVEL_INTERNAL_KEY * keyinst = NULL; + DLIST_ITEM * keyinst_field_item = NULL; + EVEL_ENTER(); @@ -3059,6 +3114,92 @@ void evel_json_encode_measurement(EVEL_JSON_BUFFER * jbuf, } } + + evel_json_checkpoint(jbuf); + if(evel_json_open_opt_named_list(jbuf, "additionalObjects")) + { + bool item_added = false; + other_field_item = dlist_get_first(&event->additional_objects); + while (other_field_item != NULL) + { + jsonobjp = (EVEL_JSON_OBJECT *) other_field_item->item; + if(jsonobjp != NULL) + { + evel_json_open_object(jbuf); + + if( evel_json_open_opt_named_list(jbuf, "objectInstances")) + { + bool item_added2 = false; + jsobj_field_item = dlist_get_first(&jsonobjp->jsonobjectinstances); + while (jsobj_field_item != NULL) + { + jsonobjinst = (EVEL_JSON_OBJECT_INSTANCE *) jsobj_field_item->item; + if( jsonobjinst != NULL ) + { + evel_json_open_object(jbuf); + evel_enc_kv_object(jbuf, "objectInstance", jsonobjinst->jsonstring); + evel_enc_kv_opt_ull(jbuf, "objectInstanceEpochMicrosec", &jsonobjinst->objinst_epoch_microsec); + //evel_json_checkpoint(jbuf); + if (evel_json_open_opt_named_list(jbuf, "objectKeys")) + { + bool item_added3 = false; + + keyinst_field_item = dlist_get_first(&jsonobjinst->object_keys); + while (keyinst_field_item != NULL) + { + keyinst = (EVEL_INTERNAL_KEY *)keyinst_field_item->item; + if(keyinst != NULL) + { + evel_json_open_object(jbuf); + evel_enc_kv_string(jbuf, "keyName", keyinst->keyname); + evel_enc_kv_opt_int(jbuf, "keyOrder", &keyinst->keyorder); + evel_enc_kv_opt_string(jbuf, "keyValue", &keyinst->keyvalue); + evel_json_close_object(jbuf); + item_added3 = true; + } + keyinst_field_item = dlist_get_next(keyinst_field_item); + } + evel_json_close_list(jbuf); + + /*************************************************************************/ + /* If we've not written anything, rewind to before we opened the list. */ + /*************************************************************************/ + //if (!item_added3) + //{ + // evel_json_rewind(jbuf); + //} + } + evel_json_close_object(jbuf); + } + item_added2 = true; + jsobj_field_item = dlist_get_next(jsobj_field_item); + } + evel_json_close_list(jbuf); + if( !item_added2 ) + { + evel_json_rewind(jbuf); + } + } + + evel_enc_kv_string(jbuf, "objectName", jsonobjp->object_name); + evel_enc_kv_opt_string(jbuf, "objectSchema", &jsonobjp->objectschema); + evel_enc_kv_opt_string(jbuf, "objectSchemaUrl", &jsonobjp->objectschemaurl); + evel_enc_kv_opt_string(jbuf, "nfSubscribedObjectName", &jsonobjp->nfsubscribedobjname); + evel_enc_kv_opt_string(jbuf, "nfSubscriptionId", &jsonobjp->nfsubscriptionid); + evel_json_close_object(jbuf); + item_added = true; + } + other_field_item = dlist_get_next(other_field_item); + } + evel_json_close_list(jbuf); + + if (!item_added) + { + evel_json_rewind(jbuf); + } + } + + // TBD additional json objects evel_enc_kv_opt_int(jbuf, "concurrentSessions", &event->concurrent_sessions); evel_enc_kv_opt_int(jbuf, "configuredEntities", &event->configured_entities); @@ -3261,7 +3402,7 @@ void evel_json_encode_measurement(EVEL_JSON_BUFFER * jbuf, /* vNIC Usage TBD Performance array */ /***************************************************************************/ evel_json_checkpoint(jbuf); - if (evel_json_open_opt_named_list(jbuf, "vNicUsageArray")) + if (evel_json_open_opt_named_list(jbuf, "vNicPerformanceArray")) { bool item_added = false; @@ -3588,6 +3729,7 @@ void evel_free_measurement(EVENT_MEASUREMENT * event) MEASUREMENT_GROUP * measurement_group = NULL; CUSTOM_MEASUREMENT * measurement = NULL; OTHER_FIELD *addl_info = NULL; + EVEL_JSON_OBJECT * jsonobjp = NULL; EVEL_ENTER(); @@ -3613,7 +3755,13 @@ void evel_free_measurement(EVENT_MEASUREMENT * event) addl_info = dlist_pop_last(&event->additional_info); } - + jsonobjp = dlist_pop_last(&event->additional_objects); + while (jsonobjp != NULL) + { + EVEL_DEBUG("Freeing jsonObject %p",jsonobjp); + evel_free_jsonobject( jsonobjp ); + jsonobjp = dlist_pop_last(&event->additional_objects); + } cpu_use = dlist_pop_last(&event->cpu_usage); while (cpu_use != NULL) diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_sipsignaling.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_sipsignaling.c index 6d4d5df..efc62db 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_sipsignaling.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_sipsignaling.c @@ -14,6 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. ****************************************************************************/ /**************************************************************************//** * @file diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_strings.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_strings.c index 912537e..3f0e7a4 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_strings.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_strings.c @@ -13,7 +13,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. ****************************************************************************/ /**************************************************************************//** * @file diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_syslog.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_syslog.c index c768e74..06d8163 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_syslog.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_syslog.c @@ -13,7 +13,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. ****************************************************************************/ /**************************************************************************//** * @file diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_threshold_cross.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_threshold_cross.c index ecc4a65..c66b08c 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_threshold_cross.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_threshold_cross.c @@ -13,7 +13,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. ****************************************************************************/ /**************************************************************************//** * @file diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_throttle.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_throttle.c index d6a366d..ac664a1 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_throttle.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_throttle.c @@ -13,7 +13,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. ****************************************************************************/ /**************************************************************************//** @@ -125,6 +125,7 @@ static const char * const evel_json_token_strings[JSON_TOKEN_TYPES] = { /*****************************************************************************/ static const char * evel_domain_strings[EVEL_MAX_DOMAINS] = { "internal", + "batch", "heartbeat", "fault", "measurementsForVfScaling", @@ -134,7 +135,7 @@ static const char * evel_domain_strings[EVEL_MAX_DOMAINS] = { "signaling", "stateChange", "syslog", - "other" + "other", "voiceQuality", "maxDomain" }; diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_voicequality.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_voicequality.c index 4f37138..04238d1 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_voicequality.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/evel_voicequality.c @@ -13,7 +13,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. ****************************************************************************/ /**************************************************************************//** * @file @@ -467,7 +467,6 @@ void evel_json_encode_voice_quality(EVEL_JSON_BUFFER * jbuf, DLIST_ITEM * addlInfoItem = NULL; END_OF_CALL_VOICE_QUALITY_METRICS * vQMetrics = NULL; - DLIST_ITEM * vQMetricsItem = NULL; EVEL_ENTER(); diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/hashtable.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/hashtable.c index 3ad0a78..d0017c9 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/hashtable.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/hashtable.c @@ -14,6 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. ****************************************************************************/ /**************************************************************************//** * @file diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/jsmn.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/jsmn.c index bd3cf42..ae08569 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/jsmn.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/jsmn.c @@ -13,7 +13,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. ****************************************************************************/ #include "jsmn.h" diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/metadata.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/metadata.c index 460815b..b865074 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/metadata.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/metadata.c @@ -13,7 +13,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. ****************************************************************************/ /**************************************************************************//** * @file @@ -23,6 +23,7 @@ #include <string.h> #include <assert.h> #include <malloc.h> +#include <unistd.h> #include <curl/curl.h> @@ -308,17 +309,59 @@ exit_label: return rc; } + /**************************************************************************//** * Initialize default values for vm_name and vm_uuid - for testing purposes. *****************************************************************************/ void openstack_metadata_initialize() { + char hostname[MAX_METADATA_STRING]; + + FILE * f = fopen ("/proc/sys/kernel/random/uuid", "r"); + strncpy(vm_uuid, "Dummy VM UUID - No Metadata available", MAX_METADATA_STRING); strncpy(vm_name, "Dummy VM name - No Metadata available", MAX_METADATA_STRING); + + if( gethostname(hostname, 1024) != -1 ) + strcpy(vm_name,hostname); + + if (f) + { + if (fgets(vm_uuid,MAX_METADATA_STRING, f)!=NULL) + { + vm_uuid[strlen( vm_uuid ) - 1 ] = '\0'; + EVEL_DEBUG("VM UUID: %s", vm_uuid); + } + fclose (f); + } + +} + +/**************************************************************************//** + * Initialize value for vm_name for all coming events + * @param source_name Source name string. + * Must confirm with EVEL source name standard + * @returns Status code + * @retval EVEL_SUCCESS On success + * @retval ::EVEL_ERR_CODES On failure. + *****************************************************************************/ +EVEL_ERR_CODES evel_set_source_name(char * src_name) +{ + if( src_name && src_name[0] ) + { + if( strlen(src_name) < MAX_METADATA_STRING ){ + strcpy(vm_name,src_name); + return EVEL_SUCCESS; + } else + EVEL_DEBUG("Event Source Name too long"); + } + else + EVEL_DEBUG("Invalid Event Source Name string"); + return EVEL_ERR_GEN_FAIL; } /**************************************************************************//** diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/readme.md b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/readme.md index 3cf5708..2033cfc 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/readme.md +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/readme.md @@ -76,17 +76,30 @@ The following fragment illustrates the above usage: ```C - if (evel_initialize(api_fqdn, - api_port, - api_path, - api_topic, - api_secure, - "Alice", - "This isn't very secure!", - EVEL_SOURCE_VIRTUAL_MACHINE, - "EVEL demo client", - verbose_mode)) - { +EVEL_ERR_CODES evel_initialize(const char * const fqdn, + int port, + const char * const bakup_fqdn, + int bakup_port, + const char * const path, + const char * const topic, + int ring_buf_size, + int secure, + const char * const cert_file_path, + const char * const key_file_path, + const char * const ca_info, + const char * const ca_file_path, + long verify_peer, + long verify_host, + const char * const username, + const char * const password, + const char * const bakup_username, + const char * const bakup_password, + const char * const source_ip, + const char * const bakup_source_ip, + EVEL_SOURCE_TYPES source_type, + const char * const role, + int verbosity + ) { fprintf(stderr, "Failed to initialize the EVEL library!!!"); exit(-1); } diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/ring_buffer.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/ring_buffer.c index db50a40..248baf2 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/ring_buffer.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_library/ring_buffer.c @@ -13,7 +13,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. ****************************************************************************/ /**************************************************************************//** * @file @@ -101,9 +101,9 @@ void * ring_buffer_read(ring_buffer * buffer) msg = (buffer->ring)[buffer->next_read]; buffer->ring[buffer->next_read] = NULL; buffer->next_read = (buffer->next_read + 1) % buffer->size; - EVEL_DEBUG("RBR: next read location is %d", buffer->next_read); pthread_mutex_unlock(&buffer->ring_mutex); - break; + EVEL_DEBUG("RBR: next read location is %d data %lp", buffer->next_read,msg); + return msg; } else { @@ -112,7 +112,7 @@ void * ring_buffer_read(ring_buffer * buffer) EVEL_DEBUG("RBR: Condition variable wait completed"); } } - EVEL_DEBUG("RBR: Ring buffer read returning data at %lp", msg); + pthread_mutex_unlock(&buffer->ring_mutex); return msg; } diff --git a/veslibrary/ves_clibrary/evel/evel-library/code/evel_unit/evel_unit.c b/veslibrary/ves_clibrary/evel/evel-library/code/evel_unit/evel_unit.c index 8fd00e6..3cfb66b 100644 --- a/veslibrary/ves_clibrary/evel/evel-library/code/evel_unit/evel_unit.c +++ b/veslibrary/ves_clibrary/evel/evel-library/code/evel_unit/evel_unit.c @@ -14,6 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. ****************************************************************************/ /**************************************************************************//** * @file diff --git a/veslibrary/ves_clibrary/readme.md b/veslibrary/ves_clibrary/readme.md index 784fade..85ff942 100644 --- a/veslibrary/ves_clibrary/readme.md +++ b/veslibrary/ves_clibrary/readme.md @@ -1,6 +1,5 @@ # ECOMP Vendor Event Listener Library -“The content of this directory is currently under development and, at this stage, is not intended for demonstration and/or testing.” This project contains a C library that supports interfacing to AT&T's ECOMP Vendor Event Listener. For an overview of ECOMP, see the @@ -16,15 +15,131 @@ Current Maintainers: * Paul Potochniak (https://github.com/pp8491) * Gayathri Patrachari(https://github.com/gp2421) -# Installation +#The description about important directories are given here -For installation instructions, clone this repo and load the -[installation guide](./docs/source/evel/html/quickstart.html) in your web browser. + evel - This contains the code for VES library for VES5.4.1, sample agents -Full source-code documentation is included with the code and can be built from -the included Makefile. See the [readme file](./code/evel_library/readme.md). + VESreporting_vFW - This is the sample virtual firewall agent -# Use + VESreporting_vLB - This is the sample virtual load balancer agent + + evel/evel-library/code/evel_library - Code for VES library 'evel' + + evel/evel-library/code/VESreporting_HB - Sample json based heartbeat event generated periodically + + evel/evel-library/code/VESreporting_fault - Sample json based fault event based on low byte/packet count on interface. + + evel/evel-library/code/VESreporting_syslog - Sample json based syslog event based on pattern being logged into any file + + evel/evel-library/code/VESreporting_vFW - Sample json based Firewall application that generates measurement event periodically. + +# Info on evel Library +This library supports following events. The corresponding factory functions to generate that event is also mentioned against it +- Faults - ::evel_new_fault +- Heartbeat - ::evel_new_heartbeat +- Measurements - ::evel_new_measurement +- State Change - ::evel_new_state_change +- Syslog - ::evel_new_syslog +- Other - ::evel_new_other +- Mobile Flow - ::evel_new_mobile_flow +- Sipsingnaling - ::evel_new_signaling +- Threshold Crossing Alert - ::evel_new_threshold_cross +- Voice Quality - ::evel_new_voice_quality + +# Setting the environment +Install gcc, libcurl3-dev packages as below + + sudo apt-get install gcc + sudo apt-get install libcurl3-dev + +Clone the code from demo repository + +#Compile VES library + Go to evel/evel-library/bldjobs directory and run the below commands + make all ==> to create the VES library + make package ==> to create the VES package if needed + + FYI - 'make install' can also be given to make a package and install the package in another machine - see evel/evel-library/bldjobs/Makefile for more details + + After compilation VES libraries are generated and are available at below location + evel/evel-library/libs/x86_64 + +#Loading VES the library + Go to evel/evel-library/libs/x86_64 directory and run below commands + sudo cp libevel.so /usr/lib + sudo ldconfig + +#Compiling agent code + After successful compiling of VES library and loading the library, go to agent directory and run 'make all' +For json heartbeat agent + > cd evel/evel-library/VESreporting_HB + > make all + +For all other jason based agents (VESreporting_fault, VESreporting_syslog and VESreporting_vFW) also, the compilation to be carried out in the same manner as mentioned above. + +But for agents in VESreporting_vFW5.0 and VESreporting_vLB5.0, special care to be taken as below + - Copy the contents of the directory into evel/evel-library/VESreporting directory + - run 'make all' to create an executable (alternatively, this agent gets compiled during compilation of evel library when VESreporting directory has the agent code. + +#Run the agent + - run the application using go-client.sh command in the agent directory as below + > sudo chmod +x go-client.sh + > sudo ./go-client.sh + +# Agent building guide + +Each application that wants to send events would call evel_initialize() function to initialize the parameter with evel library. For more details about the parameters passed, see the evel/evel-library/code/evel_library/evel.h file. The public APIs to the library are defined in evel.h + +EVEL_ERR_CODES evel_initialize(const char * const fqdn, + int port, + const char * const bakup_fqdn, + int bakup_port, + const char * const path, + const char * const topic, + int ring_buf_size, + int secure, + const char * const cert_file_path, + const char * const key_file_path, + const char * const ca_info, + const char * const ca_file_path, + long verify_peer, + long verify_host, + const char * const username, + const char * const password, + const char * const bakup_username, + const char * const bakup_password, + const char * const source_ip, + const char * const bakup_source_ip, + EVEL_SOURCE_TYPES source_type, + const char * const role, + int verbosity + ) { + fprintf(stderr, "Failed to initialize the EVEL library!!!"); + exit(-1); + } + +After successful running of evel_initialize() API, call the APIs to generate the events. + +For fault event generation, below APIs would be called. For other events see the APIs listed in evel/evel-library/code/evel_library/evel.h + + EVENT_FAULT * fault = evel_new_fault("Fault_vFW-ATT-LinkdownError", + "fault0001", + "My alarm condition", + "It broke very badly", + EVEL_PRIORITY_NORMAL, + EVEL_SEVERITY_MAJOR, + EVEL_SOURCE_HOST, + EVEL_VF_STATUS_PREP_TERMINATE); + if (fault != NULL) + { + evel_fault_type_set(fault, "Bad things happen..."); + evel_fault_interface_set(fault, "My Interface Card"); + evel_fault_addl_info_add(fault, "name1", "value1"); + evel_fault_addl_info_add(fault, "name2", "value2"); + evel_rc = evel_post_event((EVENT_HEADER *)fault); + if (evel_rc != EVEL_SUCCESS) + { + EVEL_ERROR("Post failed %d (%s)", evel_rc, evel_error_string()); + } + } -Clone this repo and load the [user guide](./docs/source/evel/html/index.html) -in your web browser. |