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