Update INFO.yaml with new PTL
[demo.git] / vnfs / VESreporting_vFW5.0_DANOS / vpp-measurement-reporter-danos.c
1 /*************************************************************************//**
2  *
3  * Copyright © 2020 AT&T Intellectual Property. All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and 
14  * limitations under the License.
15  *
16  ****************************************************************************/
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <unistd.h>
21 #include <string.h>
22 #include <sys/time.h>
23
24 #include <jansson.h>
25
26 #include <vyatta-cfg/client/rpc.h>
27 #include <vyatta-cfg/client/error.h>
28 #include <vyatta-cfg/client/connect.h>
29 #include <vyatta-cfg/client/node.h>
30
31 #include <evel.h>
32
33 #define BUFSIZE 128
34 #define READ_INTERVAL 10
35
36 typedef struct dummy_vpp_metrics_struct {
37   int bytes_in;
38   int bytes_out;
39   int packets_in;
40   int packets_out;
41 } vpp_metrics_struct;
42
43
44 void read_vpp_metrics_danos(vpp_metrics_struct *, char *);
45
46 int main(int argc, char** argv)
47 {
48   EVEL_ERR_CODES evel_rc = EVEL_SUCCESS;
49   EVENT_MEASUREMENT* vpp_m = NULL;
50   EVENT_HEADER* vpp_m_header = NULL;
51   EVENT_HEADER* batch_header = NULL;
52   MEASUREMENT_VNIC_PERFORMANCE * vnic_performance = NULL;
53   int bytes_in_this_round;
54   int bytes_out_this_round;
55   int packets_in_this_round;
56   int packets_out_this_round;
57   vpp_metrics_struct* last_vpp_metrics = malloc(sizeof(vpp_metrics_struct));
58   vpp_metrics_struct* curr_vpp_metrics = malloc(sizeof(vpp_metrics_struct));
59   struct timeval time_val;
60   time_t start_epoch;
61   time_t last_epoch;
62   char hostname[BUFSIZE];
63   char eventName[BUFSIZE];
64   char eventId[BUFSIZE];
65   char* fqdn2 = NULL;
66   int port2 = 0;
67   char * vnic = NULL;
68   memset(eventName, 0, BUFSIZE);
69   memset(eventId, 0, BUFSIZE);
70   memset(hostname, 0, BUFSIZE);
71
72   strcpy(eventName, "vFirewallBroadcastPackets");
73   strcpy(eventId, "mvfs00000001");
74
75   char* fqdn = argv[1];
76   int port = atoi(argv[2]);
77   char* caFile = "/opt/VES/config/onap-ca.crt";
78   char* userName = "sample1";
79   char* passWord = "sample1";
80
81   if(argc == 6)
82   {
83      fqdn2 = argv[3];
84      port2 = atoi(argv[4]);
85      vnic = argv[5];
86   }
87   else
88      vnic = argv[3];
89
90
91
92
93
94   printf("\nVector Packet Processing (VPP) measurement collection\n");
95   fflush(stdout);
96
97   if (!((argc == 4) || (argc == 6)))
98   {
99     fprintf(stderr, "Usage: %s <FQDN>|<IP address> <port> <FQDN>|<IP address> <port> <interface> \n", argv[0]);
100     fprintf(stderr, "OR\n");
101     fprintf(stderr, "Usage: %s <FQDN>|<IP address> <port> <interface>\n", argv[0]);
102     exit(-1);
103   }
104
105   /**************************************************************************/
106   /* Initialize                                                             */
107   /**************************************************************************/
108   if(evel_initialize(fqdn,                         /* FQDN                  */
109                      port,                         /* Port                  */
110                      fqdn2,                        /* Backup FQDN           */
111                      port2,                        /* Backup port           */
112                      NULL,                         /* optional path         */
113                      NULL,                         /* optional topic        */
114                      100,                          /* Ring Buffer size      */
115                      1,                            /* HTTPS?                */
116                      NULL,                         /* cert file             */
117                      NULL,                         /* key  file             */
118                      caFile,                       /* ca   file             */
119                      NULL,                         /* ca   directory        */
120                      0,                            /* verify peer           */
121                      0,                            /* verify host           */
122                      userName,                     /* Username              */
123                      passWord,                     /* Password              */
124                      "sample1",                    /* Username2             */
125                      "sample1",                    /* Password2             */
126                      NULL,                         /* Source ip             */
127                      NULL,                         /* Source ip2            */
128                      EVEL_SOURCE_VIRTUAL_MACHINE,  /* Source type           */
129                      "vFirewall",                  /* Role                  */
130                      1))                           /* Verbosity             */
131
132   {
133     fprintf(stderr, "\nFailed to initialize the EVEL library!!!\n");
134     exit(-1);
135   }
136   else
137   {
138     printf("\nInitialization completed\n");
139   }
140
141
142   gethostname(hostname, BUFSIZE);
143   memset(last_vpp_metrics, 0, sizeof(vpp_metrics_struct));
144   read_vpp_metrics_danos(last_vpp_metrics, vnic);
145   gettimeofday(&time_val, NULL);
146   start_epoch = time_val.tv_sec * 1000000 + time_val.tv_usec;
147   sleep(READ_INTERVAL);
148
149   /***************************************************************************/
150   /* Collect metrics from the VNIC                                           */
151   /***************************************************************************/
152   while(1) {
153     memset(curr_vpp_metrics, 0, sizeof(vpp_metrics_struct));
154     read_vpp_metrics_danos(curr_vpp_metrics, vnic );
155
156     if(curr_vpp_metrics->bytes_in - last_vpp_metrics->bytes_in > 0) {
157       bytes_in_this_round = curr_vpp_metrics->bytes_in - last_vpp_metrics->bytes_in;
158     }
159     else {
160       bytes_in_this_round = 0;
161     }
162     if(curr_vpp_metrics->bytes_out - last_vpp_metrics->bytes_out > 0) {
163       bytes_out_this_round = curr_vpp_metrics->bytes_out - last_vpp_metrics->bytes_out;
164     }
165     else {
166       bytes_out_this_round = 0;
167     }
168     if(curr_vpp_metrics->packets_in - last_vpp_metrics->packets_in > 0) {
169       packets_in_this_round = curr_vpp_metrics->packets_in - last_vpp_metrics->packets_in;
170     }
171     else {
172       packets_in_this_round = 0;
173     }
174     if(curr_vpp_metrics->packets_out - last_vpp_metrics->packets_out > 0) {
175       packets_out_this_round = curr_vpp_metrics->packets_out - last_vpp_metrics->packets_out;
176     }
177     else {
178       packets_out_this_round = 0;
179     }
180
181     vpp_m = evel_new_measurement(READ_INTERVAL, eventName, eventId);
182
183     if(vpp_m != NULL) {
184       printf("New measurement report created...\n");
185       vnic_performance = (MEASUREMENT_VNIC_PERFORMANCE *)evel_measurement_new_vnic_performance(vnic, "true");
186       evel_meas_vnic_performance_add(vpp_m, vnic_performance);
187       evel_vnic_performance_rx_total_pkt_delta_set(vnic_performance, packets_in_this_round);
188       evel_vnic_performance_tx_total_pkt_delta_set(vnic_performance, packets_out_this_round);
189
190       evel_vnic_performance_rx_octets_delta_set(vnic_performance, bytes_in_this_round);
191       evel_vnic_performance_tx_octets_delta_set(vnic_performance, bytes_out_this_round);
192
193       /***************************************************************************/
194       /* Set parameters in the MEASUREMENT header packet                         */
195       /***************************************************************************/
196       last_epoch = start_epoch + READ_INTERVAL * 1000000;
197       vpp_m_header = (EVENT_HEADER *)vpp_m;
198       vpp_m_header->start_epoch_microsec = start_epoch;
199       vpp_m_header->last_epoch_microsec = last_epoch;
200       evel_reporting_entity_id_set(vpp_m_header, "No UUID available");
201       evel_reporting_entity_name_set(vpp_m_header, hostname);
202       batch_header = evel_new_batch("batch_event_name", "bevent_id");
203       evel_batch_add_event(batch_header, vpp_m_header);
204       evel_rc = evel_post_event(batch_header);
205
206       if(evel_rc == EVEL_SUCCESS) {
207         printf("Measurement report correctly sent to the collector!\n");
208       }
209       else {
210         printf("Post report failed %d (%s)\n", evel_rc, evel_error_string());
211       }
212     }
213     else {
214       printf("New measurement report failed (%s)\n", evel_error_string());
215     }
216
217     last_vpp_metrics->bytes_in = curr_vpp_metrics->bytes_in;
218     last_vpp_metrics->bytes_out = curr_vpp_metrics->bytes_out;
219     last_vpp_metrics->packets_in = curr_vpp_metrics->packets_in;
220     last_vpp_metrics->packets_out = curr_vpp_metrics->packets_out;
221     gettimeofday(&time_val, NULL);
222     start_epoch = time_val.tv_sec * 1000000 + time_val.tv_usec;
223
224     sleep(READ_INTERVAL);
225   }
226
227   /***************************************************************************/
228   /* Terminate                                                               */
229   /***************************************************************************/
230   sleep(1);
231   free(last_vpp_metrics);
232   free(curr_vpp_metrics);
233   evel_terminate();
234   printf("Terminated\n");
235
236   return 0;
237 }
238
239 void read_vpp_metrics_danos(vpp_metrics_struct *vpp_metrics, char *vnic) {
240
241      // structures for the DANOS stats
242      struct configd_conn conn;
243      struct configd_error err;
244      // will open and close the connection on each call for statistics
245      configd_open_connection(&conn);
246
247      //   /interfaces/statistics/interface/dp0s4
248      char xpath[50];
249      strcpy(xpath, "/interfaces/statistics/interface/");
250      strcat(xpath, vnic);
251      char * data = configd_tree_get_full_encoding(&conn, RUNNING, xpath, "rfc7951", &err);
252
253      if (data == NULL) {
254          printf("failed to get data: %s %s\n", err.source, err.text);
255          exit(1);
256      }
257      printf("%s\n", data);
258
259     // Do something with the RFC7951 encoded JSON data.
260     // Store metrics read from the vNIC in the struct passed from the main function
261     //
262     // "vyatta-interfaces-v1:statistics": {
263     //          "interface": [{
264     //                                  "name": "dp0s3",
265     //
266     //
267     //  bytes_in : interface[i].receive-statistics.bytes
268     //  packets_in : interface[i].receive-statistics.packets
269     //  bytes_out : interface[i].transmit-statistics.bytes
270     //  packets_in : interface[i].transmit-statistics.packets
271     //
272
273     json_t *receive , *receive_bytes, *receive_packets;
274     json_t *transmit, *transmit_bytes , *transmit_packets;
275
276     json_error_t error;
277     json_t *node= json_loads(data,0,&error);
278     if(!node){
279           fprintf(stderr, "node not found error: on line %d: %s\n", error.line, error.text);
280           exit(1);
281     }
282
283     receive = json_object_get(node, "vyatta-interfaces-v1:receive-statistics");
284     if(!receive){
285           fprintf(stderr, "receive not found error: on line %d: %s\n", error.line, error.text);
286           exit(1);
287     }
288
289     receive_bytes= json_object_get(receive,"bytes");
290     if(!receive_bytes){
291           fprintf(stderr, "error: on line %d: %s\n", error.line, error.text);
292           exit(1);
293     }
294
295     receive_packets= json_object_get(receive,"packets");
296     if(!receive_packets){
297           fprintf(stderr, "error: on line %d: %s\n", error.line, error.text);
298           exit(1);
299     }
300
301     transmit = json_object_get(node, "vyatta-interfaces-v1:transmit-statistics");
302     if(!transmit){
303           fprintf(stderr, "error: on line %d: %s\n", error.line, error.text);
304           exit(1);
305     }
306
307     transmit_bytes= json_object_get(transmit,"bytes");
308     if(!transmit_bytes){
309           fprintf(stderr, "error: on line %d: %s\n", error.line, error.text);
310           exit(1);
311     }
312     transmit_packets= json_object_get(transmit,"packets");
313     if(!transmit_packets){
314           fprintf(stderr, "error: on line %d: %s\n", error.line, error.text);
315           exit(1);
316     }
317
318     fprintf(stdout, "Starting to convert json_integer_values\n") ;
319     fprintf(stdout, "receive_bytes %" JSON_INTEGER_FORMAT "\n", receive_bytes) ; 
320
321     const char *receive_bytes_string;
322     receive_bytes_string=  json_string_value(receive_bytes);
323     fprintf(stdout, "receive_bytes_string %s \n", receive_bytes_string) ; 
324
325     const char *receive_packets_string;
326     receive_packets_string=  json_string_value(receive_packets);
327     fprintf(stdout, "receive_packets_string %s \n", receive_packets_string) ; 
328
329     const char *transmit_bytes_string;
330     transmit_bytes_string=  json_string_value(transmit_bytes);
331     fprintf(stdout, "transmit_bytes_string %s \n", transmit_bytes_string) ; 
332
333     const char *transmit_packets_string;
334     transmit_packets_string=  json_string_value(transmit_packets);
335     fprintf(stdout, "transmit_packets_string %s \n", transmit_packets_string) ; 
336
337     vpp_metrics->bytes_in = atoi(receive_bytes_string);
338     vpp_metrics->packets_in = atoi(receive_packets_string);
339     vpp_metrics->bytes_out = atoi(transmit_bytes_string);
340     vpp_metrics->packets_out = atoi(transmit_packets_string);
341     
342     configd_close_connection(&conn);
343 }