Cleanup code and correct License
[demo.git] / vnfs / VES5.0 / evel / evel-library / code / evel_library / evel_event.c
1 /*************************************************************************//**
2  *
3  * Copyright © 2017 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 /**************************************************************************//**
19  * @file
20  * Implementation of EVEL functions relating to Event Headers - since
21  * Heartbeats only contain the Event Header, the Heartbeat factory function is
22  * here too.
23  *
24  ****************************************************************************/
25
26 #include <string.h>
27 #include <assert.h>
28 #include <stdlib.h>
29 #include <sys/time.h>
30
31 #include "evel.h"
32 #include "evel_internal.h"
33 #include "evel_throttle.h"
34 #include "metadata.h"
35
36 /**************************************************************************//**
37  * Unique sequence number for events from this VNF.
38  *****************************************************************************/
39 static int event_sequence = 1;
40
41 /**************************************************************************//**
42  * Set the next event_sequence to use.
43  *
44  * @param sequence      The next sequence number to use.
45  *****************************************************************************/
46 void evel_set_next_event_sequence(const int sequence)
47 {
48   EVEL_ENTER();
49
50   EVEL_INFO("Setting event sequence to %d, was %d ", sequence, event_sequence);
51   event_sequence = sequence;
52
53   EVEL_EXIT();
54 }
55
56 /**************************************************************************//**
57  * Create a new heartbeat event.
58  *
59  * @note that the heartbeat is just a "naked" commonEventHeader!
60  *
61  * @returns pointer to the newly manufactured ::EVENT_HEADER.  If the event is
62  *          not used it must be released using ::evel_free_event
63  * @retval  NULL  Failed to create the event.
64  *****************************************************************************/
65 EVENT_HEADER * evel_new_heartbeat()
66 {
67   EVENT_HEADER * heartbeat = NULL;
68   EVEL_ENTER();
69
70   /***************************************************************************/
71   /* Allocate the header.                                                    */
72   /***************************************************************************/
73   heartbeat = malloc(sizeof(EVENT_HEADER));
74   if (heartbeat == NULL)
75   {
76     log_error_state("Out of memory");
77     goto exit_label;
78   }
79   memset(heartbeat, 0, sizeof(EVENT_HEADER));
80
81   /***************************************************************************/
82   /* Initialize the header.  Get a new event sequence number.  Note that if  */
83   /* any memory allocation fails in here we will fail gracefully because     */
84   /* everything downstream can cope with NULLs.                              */
85   /***************************************************************************/
86   evel_init_header(heartbeat,"Heartbeat");
87   evel_force_option_string(&heartbeat->event_type, "Autonomous heartbeat");
88
89 exit_label:
90   EVEL_EXIT();
91   return heartbeat;
92 }
93
94 /**************************************************************************//**
95  * Initialize a newly created event header.
96  *
97  * @param header  Pointer to the header being initialized.
98  *****************************************************************************/
99 void evel_init_header(EVENT_HEADER * const header,const char *const eventname)
100 {
101   char scratchpad[EVEL_MAX_STRING_LEN + 1] = {0};
102   struct timeval tv;
103
104   EVEL_ENTER();
105
106   assert(header != NULL);
107
108   gettimeofday(&tv, NULL);
109
110   /***************************************************************************/
111   /* Initialize the header.  Get a new event sequence number.  Note that if  */
112   /* any memory allocation fails in here we will fail gracefully because     */
113   /* everything downstream can cope with NULLs.                              */
114   /***************************************************************************/
115   header->event_domain = EVEL_DOMAIN_HEARTBEAT;
116   snprintf(scratchpad, EVEL_MAX_STRING_LEN, "%d", event_sequence);
117   header->event_id = strdup(scratchpad);
118   if( eventname == NULL )
119      header->event_name = strdup(functional_role);
120   else
121      header->event_name = strdup(eventname);
122   header->last_epoch_microsec = tv.tv_usec + 1000000 * tv.tv_sec;
123   header->priority = EVEL_PRIORITY_NORMAL;
124   header->reporting_entity_name = strdup(openstack_vm_name());
125   header->source_name = strdup(openstack_vm_name());
126   header->sequence = event_sequence;
127   header->start_epoch_microsec = header->last_epoch_microsec;
128   header->major_version = EVEL_HEADER_MAJOR_VERSION;
129   header->minor_version = EVEL_HEADER_MINOR_VERSION;
130   event_sequence++;
131
132   /***************************************************************************/
133   /* Optional parameters.                                                    */
134   /***************************************************************************/
135   evel_init_option_string(&header->event_type);
136   evel_init_option_string(&header->nfcnaming_code);
137   evel_init_option_string(&header->nfnaming_code);
138   evel_force_option_string(&header->reporting_entity_id, openstack_vm_uuid());
139   evel_force_option_string(&header->source_id, openstack_vm_uuid());
140   evel_init_option_intheader(&header->internal_field);
141
142   EVEL_EXIT();
143 }
144
145 /**************************************************************************//**
146  * Set the Event Type property of the event header.
147  *
148  * @note  The property is treated as immutable: it is only valid to call
149  *        the setter once.  However, we don't assert if the caller tries to
150  *        overwrite, just ignoring the update instead.
151  *
152  * @param header        Pointer to the ::EVENT_HEADER.
153  * @param type          The Event Type to be set. ASCIIZ string. The caller
154  *                      does not need to preserve the value once the function
155  *                      returns.
156  *****************************************************************************/
157 void evel_header_type_set(EVENT_HEADER * const header,
158                           const char * const type)
159 {
160   EVEL_ENTER();
161
162   /***************************************************************************/
163   /* Check preconditions.                                                    */
164   /***************************************************************************/
165   assert(header != NULL);
166   assert(type != NULL);
167
168   evel_set_option_string(&header->event_type, type, "Event Type");
169
170   EVEL_EXIT();
171 }
172
173 /**************************************************************************//**
174  * Set the Start Epoch property of the event header.
175  *
176  * @note The Start Epoch defaults to the time of event creation.
177  *
178  * @param header        Pointer to the ::EVENT_HEADER.
179  * @param start_epoch_microsec
180  *                      The start epoch to set, in microseconds.
181  *****************************************************************************/
182 void evel_start_epoch_set(EVENT_HEADER * const header,
183                           const unsigned long long start_epoch_microsec)
184 {
185   EVEL_ENTER();
186
187   /***************************************************************************/
188   /* Check preconditions and assign the new value.                           */
189   /***************************************************************************/
190   assert(header != NULL);
191   header->start_epoch_microsec = start_epoch_microsec;
192
193   EVEL_EXIT();
194 }
195
196 /**************************************************************************//**
197  * Set the Last Epoch property of the event header.
198  *
199  * @note The Last Epoch defaults to the time of event creation.
200  *
201  * @param header        Pointer to the ::EVENT_HEADER.
202  * @param last_epoch_microsec
203  *                      The last epoch to set, in microseconds.
204  *****************************************************************************/
205 void evel_last_epoch_set(EVENT_HEADER * const header,
206                          const unsigned long long last_epoch_microsec)
207 {
208   EVEL_ENTER();
209
210   /***************************************************************************/
211   /* Check preconditions and assign the new value.                           */
212   /***************************************************************************/
213   assert(header != NULL);
214   header->last_epoch_microsec = last_epoch_microsec;
215
216   EVEL_EXIT();
217 }
218
219 /**************************************************************************//**
220  * Set the NFC Naming code property of the event header.
221  *
222  * @param header        Pointer to the ::EVENT_HEADER.
223  * @param nfcnamingcode String
224  *****************************************************************************/
225 void evel_nfcnamingcode_set(EVENT_HEADER * const header,
226                          const char * const nfcnam)
227 {
228   EVEL_ENTER();
229
230   /***************************************************************************/
231   /* Check preconditions and assign the new value.                           */
232   /***************************************************************************/
233   assert(header != NULL);
234   assert(nfcnam != NULL);
235   evel_set_option_string(&header->nfcnaming_code, nfcnam, "NFC Naming Code");
236
237   EVEL_EXIT();
238 }
239
240 /**************************************************************************//**
241  * Set the NF Naming code property of the event header.
242  *
243  * @param header        Pointer to the ::EVENT_HEADER.
244  * @param nfnamingcode String
245  *****************************************************************************/
246 void evel_nfnamingcode_set(EVENT_HEADER * const header,
247                          const char * const nfnam)
248 {
249   EVEL_ENTER();
250
251   /***************************************************************************/
252   /* Check preconditions and assign the new value.                           */
253   /***************************************************************************/
254   assert(header != NULL);
255   assert(nfnam != NULL);
256   evel_set_option_string(&header->nfnaming_code, nfnam, "NF Naming Code");
257
258   EVEL_EXIT();
259 }
260
261
262 /**************************************************************************//**
263  * Set the Reporting Entity Name property of the event header.
264  *
265  * @note The Reporting Entity Name defaults to the OpenStack VM Name.
266  *
267  * @param header        Pointer to the ::EVENT_HEADER.
268  * @param entity_name   The entity name to set.
269  *****************************************************************************/
270 void evel_reporting_entity_name_set(EVENT_HEADER * const header,
271                                     const char * const entity_name)
272 {
273   EVEL_ENTER();
274
275   /***************************************************************************/
276   /* Check preconditions and assign the new value.                           */
277   /***************************************************************************/
278   assert(header != NULL);
279   assert(entity_name != NULL);
280   assert(header->reporting_entity_name != NULL);
281
282   /***************************************************************************/
283   /* Free the previously allocated memory and replace it with a copy of the  */
284   /* provided one.                                                           */
285   /***************************************************************************/
286   free(header->reporting_entity_name);
287   header->reporting_entity_name = strdup(entity_name);
288
289   EVEL_EXIT();
290 }
291
292 /**************************************************************************//**
293  * Set the Reporting Entity Id property of the event header.
294  *
295  * @note The Reporting Entity Id defaults to the OpenStack VM UUID.
296  *
297  * @param header        Pointer to the ::EVENT_HEADER.
298  * @param entity_id     The entity id to set.
299  *****************************************************************************/
300 void evel_reporting_entity_id_set(EVENT_HEADER * const header,
301                                   const char * const entity_id)
302 {
303   EVEL_ENTER();
304
305   /***************************************************************************/
306   /* Check preconditions and assign the new value.                           */
307   /***************************************************************************/
308   assert(header != NULL);
309   assert(entity_id != NULL);
310
311   /***************************************************************************/
312   /* Free the previously allocated memory and replace it with a copy of the  */
313   /* provided one.  Note that evel_force_option_string strdups entity_id.    */
314   /***************************************************************************/
315   evel_free_option_string(&header->reporting_entity_id);
316   evel_force_option_string(&header->reporting_entity_id, entity_id);
317
318   EVEL_EXIT();
319 }
320
321 /**************************************************************************//**
322  * Encode the event as a JSON event object according to AT&T's schema.
323  *
324  * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
325  * @param event         Pointer to the ::EVENT_HEADER to encode.
326  *****************************************************************************/
327 void evel_json_encode_header(EVEL_JSON_BUFFER * jbuf,
328                              EVENT_HEADER * event)
329 {
330   char * domain;
331   char * priority;
332
333   EVEL_ENTER();
334
335   /***************************************************************************/
336   /* Check preconditions.                                                    */
337   /***************************************************************************/
338   assert(jbuf != NULL);
339   assert(jbuf->json != NULL);
340   assert(jbuf->max_size > 0);
341   assert(event != NULL);
342
343   domain = evel_event_domain(event->event_domain);
344   priority = evel_event_priority(event->priority);
345   evel_json_open_named_object(jbuf, "commonEventHeader");
346
347   /***************************************************************************/
348   /* Mandatory fields.                                                       */
349   /***************************************************************************/
350   evel_enc_kv_string(jbuf, "domain", domain);
351   evel_enc_kv_string(jbuf, "eventId", event->event_id);
352   evel_enc_kv_string(jbuf, "eventName", event->event_name);
353   evel_enc_kv_ull(jbuf, "lastEpochMicrosec", event->last_epoch_microsec);
354   evel_enc_kv_string(jbuf, "priority", priority);
355   evel_enc_kv_string(
356     jbuf, "reportingEntityName", event->reporting_entity_name);
357   evel_enc_kv_int(jbuf, "sequence", event->sequence);
358   evel_enc_kv_string(jbuf, "sourceName", event->source_name);
359   evel_enc_kv_ull(jbuf, "startEpochMicrosec", event->start_epoch_microsec);
360   evel_enc_version(
361     jbuf, "version", event->major_version, event->minor_version);
362
363   /***************************************************************************/
364   /* Optional fields.                                                        */
365   /***************************************************************************/
366   evel_enc_kv_opt_string(jbuf, "eventType", &event->event_type);
367   evel_enc_kv_opt_string(
368     jbuf, "reportingEntityId", &event->reporting_entity_id);
369   evel_enc_kv_opt_string(jbuf, "sourceId", &event->source_id);
370   evel_enc_kv_opt_string(jbuf, "nfcNamingCode", &event->nfcnaming_code);
371   evel_enc_kv_opt_string(jbuf, "nfNamingCode", &event->nfnaming_code);
372
373   evel_json_close_object(jbuf);
374
375   EVEL_EXIT();
376 }
377
378 /**************************************************************************//**
379  * Free an event header.
380  *
381  * Free off the event header supplied.  Will free all the contained allocated
382  * memory.
383  *
384  * @note It does not free the header itself, since that may be part of a
385  * larger structure.
386  *****************************************************************************/
387 void evel_free_header(EVENT_HEADER * const event)
388 {
389   EVEL_ENTER();
390
391   /***************************************************************************/
392   /* Check preconditions.  As an internal API we don't allow freeing NULL    */
393   /* events as we do on the public API.                                      */
394   /***************************************************************************/
395   assert(event != NULL);
396
397   /***************************************************************************/
398   /* Free all internal strings.                                              */
399   /***************************************************************************/
400   free(event->event_id);
401   evel_free_option_string(&event->event_type);
402   free(event->event_name);
403   evel_free_option_string(&event->reporting_entity_id);
404   free(event->reporting_entity_name);
405   evel_free_option_string(&event->source_id);
406   evel_free_option_string(&event->nfcnaming_code);
407   evel_free_option_string(&event->nfnaming_code);
408   evel_free_option_intheader(&event->internal_field);
409   free(event->source_name);
410
411   EVEL_EXIT();
412 }
413
414 /**************************************************************************//**
415  * Encode the event as a JSON event object according to AT&T's schema.
416  *
417  * @param json      Pointer to where to store the JSON encoded data.
418  * @param max_size  Size of storage available in json_body.
419  * @param event     Pointer to the ::EVENT_HEADER to encode.
420  * @returns Number of bytes actually written.
421  *****************************************************************************/
422 int evel_json_encode_event(char * json,
423                            int max_size,
424                            EVENT_HEADER * event)
425 {
426   EVEL_JSON_BUFFER json_buffer;
427   EVEL_JSON_BUFFER * jbuf = &json_buffer;
428   EVEL_THROTTLE_SPEC * throttle_spec;
429
430   EVEL_ENTER();
431
432   /***************************************************************************/
433   /* Get the latest throttle specification for the domain.                   */
434   /***************************************************************************/
435   throttle_spec = evel_get_throttle_spec(event->event_domain);
436
437   /***************************************************************************/
438   /* Initialize the JSON_BUFFER and open the top-level objects.              */
439   /***************************************************************************/
440   evel_json_buffer_init(jbuf, json, max_size, throttle_spec);
441   evel_json_open_object(jbuf);
442   evel_json_open_named_object(jbuf, "event");
443
444   switch (event->event_domain)
445   {
446     case EVEL_DOMAIN_HEARTBEAT:
447       evel_json_encode_header(jbuf, event);
448       break;
449
450     case EVEL_DOMAIN_FAULT:
451       evel_json_encode_fault(jbuf, (EVENT_FAULT *)event);
452       break;
453
454     case EVEL_DOMAIN_MEASUREMENT:
455       evel_json_encode_measurement(jbuf, (EVENT_MEASUREMENT *)event);
456       break;
457
458     case EVEL_DOMAIN_MOBILE_FLOW:
459       evel_json_encode_mobile_flow(jbuf, (EVENT_MOBILE_FLOW *)event);
460       break;
461
462     case EVEL_DOMAIN_REPORT:
463       evel_json_encode_report(jbuf, (EVENT_REPORT *)event);
464       break;
465
466     case EVEL_DOMAIN_HEARTBEAT_FIELD:
467       evel_json_encode_hrtbt_field(jbuf, (EVENT_HEARTBEAT_FIELD *)event);
468       break;
469
470     case EVEL_DOMAIN_SIPSIGNALING:
471       evel_json_encode_signaling(jbuf, (EVENT_SIGNALING *)event);
472       break;
473
474     case EVEL_DOMAIN_STATE_CHANGE:
475       evel_json_encode_state_change(jbuf, (EVENT_STATE_CHANGE *)event);
476       break;
477
478     case EVEL_DOMAIN_SYSLOG:
479       evel_json_encode_syslog(jbuf, (EVENT_SYSLOG *)event);
480       break;
481
482     case EVEL_DOMAIN_OTHER:
483       evel_json_encode_other(jbuf, (EVENT_OTHER *)event);
484       break;
485
486     case EVEL_DOMAIN_VOICE_QUALITY:
487       evel_json_encode_other(jbuf, (EVENT_VOICE_QUALITY *)event);
488       break;
489
490     case EVEL_DOMAIN_INTERNAL:
491     default:
492       EVEL_ERROR("Unexpected domain %d", event->event_domain);
493       assert(0);
494   }
495
496   evel_json_close_object(jbuf);
497   evel_json_close_object(jbuf);
498
499   /***************************************************************************/
500   /* Sanity check.                                                           */
501   /***************************************************************************/
502   assert(jbuf->depth == 0);
503
504   EVEL_EXIT();
505
506   return jbuf->offset;
507 }
508
509
510 /**************************************************************************//**
511  * Initialize an event instance id.
512  *
513  * @param vfield        Pointer to the event vnfname field being initialized.
514  * @param vendor_id     The vendor id to encode in the event instance id.
515  * @param event_id      The event id to encode in the event instance id.
516  *****************************************************************************/
517 void evel_init_vendor_field(VENDOR_VNFNAME_FIELD * const vfield,
518                                  const char * const vendor_name)
519 {
520   EVEL_ENTER();
521
522   /***************************************************************************/
523   /* Check preconditions.                                                    */
524   /***************************************************************************/
525   assert(vfield != NULL);
526   assert(vendor_name != NULL);
527
528   /***************************************************************************/
529   /* Store the mandatory parts.                                              */
530   /***************************************************************************/
531   vfield->vendorname = strdup(vendor_name);
532   evel_init_option_string(&vfield->vfmodule);
533   evel_init_option_string(&vfield->vnfname);
534
535   /***************************************************************************/
536   /* Initialize the optional parts.                                          */
537   /***************************************************************************/
538
539   EVEL_EXIT();
540 }
541
542 /**************************************************************************//**
543  * Set the Vendor module property of the Vendor.
544  *
545  * @note  The property is treated as immutable: it is only valid to call
546  *        the setter once.  However, we don't assert if the caller tries to
547  *        overwrite, just ignoring the update instead.
548  *
549  * @param vfield        Pointer to the Vendor field.
550  * @param module_name   The module name to be set. ASCIIZ string. The caller
551  *                      does not need to preserve the value once the function
552  *                      returns.
553  *****************************************************************************/
554 void evel_vendor_field_module_set(VENDOR_VNFNAME_FIELD * const vfield,
555                                     const char * const module_name)
556 {
557   EVEL_ENTER();
558
559   /***************************************************************************/
560   /* Check preconditions.                                                    */
561   /***************************************************************************/
562   assert(vfield != NULL);
563   assert(module_name != NULL);
564
565   evel_set_option_string(&vfield->vfmodule, module_name, "Module name set");
566
567   EVEL_EXIT();
568 }
569
570 /**************************************************************************//**
571  * Set the Vendor module property of the Vendor.
572  *
573  * @note  The property is treated as immutable: it is only valid to call
574  *        the setter once.  However, we don't assert if the caller tries to
575  *        overwrite, just ignoring the update instead.
576  *
577  * @param vfield        Pointer to the Vendor field.
578  * @param module_name   The module name to be set. ASCIIZ string. The caller
579  *                      does not need to preserve the value once the function
580  *                      returns.
581  *****************************************************************************/
582 void evel_vendor_field_vnfname_set(VENDOR_VNFNAME_FIELD * const vfield,
583                                     const char * const vnfname)
584 {
585   EVEL_ENTER();
586
587   /***************************************************************************/
588   /* Check preconditions.                                                    */
589   /***************************************************************************/
590   assert(vfield != NULL);
591   assert(vnfname != NULL);
592
593   evel_set_option_string(&vfield->vnfname, vnfname, "Virtual Network Function name set");
594
595   EVEL_EXIT();
596 }
597
598 /**************************************************************************//**
599  * Free an event instance id.
600  *
601  * @param vfield   Pointer to the event vnfname_field being freed.
602  *****************************************************************************/
603 void evel_free_event_vendor_field(VENDOR_VNFNAME_FIELD * const vfield)
604 {
605   EVEL_ENTER();
606
607   /***************************************************************************/
608   /* Check preconditions.                                                    */
609   /***************************************************************************/
610   assert(vfield->vendorname != NULL);
611
612   /***************************************************************************/
613   /* Free everything.                                                        */
614   /***************************************************************************/
615   evel_free_option_string(&vfield->vfmodule);
616   evel_free_option_string(&vfield->vnfname);
617   free(vfield->vendorname);
618
619   EVEL_EXIT();
620 }
621
622 /**************************************************************************//**
623  * Encode the instance id as a JSON object according to AT&T's schema.
624  *
625  * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
626  * @param vfield        Pointer to the ::VENDOR_VNFNAME_FIELD to encode.
627  *****************************************************************************/
628 void evel_json_encode_vendor_field(EVEL_JSON_BUFFER * jbuf,
629                                   VENDOR_VNFNAME_FIELD * vfield)
630 {
631   EVEL_ENTER();
632
633   /***************************************************************************/
634   /* Check preconditions.                                                    */
635   /***************************************************************************/
636   assert(jbuf != NULL);
637   assert(jbuf->json != NULL);
638   assert(jbuf->max_size > 0);
639   assert(vfield != NULL);
640   assert(vfield->vendorname != NULL);
641
642   evel_json_open_named_object(jbuf, "vendorVnfNamedFields");
643
644   /***************************************************************************/
645   /* Mandatory fields.                                                       */
646   /***************************************************************************/
647   evel_enc_kv_string(jbuf, "vendorName", vfield->vendorname);
648   evel_enc_kv_opt_string(jbuf, "vfModuleName", &vfield->vfmodule);
649   evel_enc_kv_opt_string(jbuf, "vnfName", &vfield->vnfname);
650
651   /***************************************************************************/
652   /* Optional fields.                                                        */
653   /***************************************************************************/
654
655   evel_json_close_object(jbuf);
656
657   EVEL_EXIT();
658 }