1 /*************************************************************************//**
3 * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
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
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.
16 ****************************************************************************/
18 /**************************************************************************//**
20 * Implementation of EVEL functions relating to Event Headers - since
21 * Heartbeats only contain the Event Header, the Heartbeat factory function is
23 *****************************************************************************/
31 #include "evel_internal.h"
32 #include "evel_throttle.h"
35 /**************************************************************************//**
36 * Unique sequence number for events from this VNF.
37 *****************************************************************************/
38 static int event_sequence = 1;
40 /**************************************************************************//**
41 * Set the next event_sequence to use.
43 * @param sequence The next sequence number to use.
44 *****************************************************************************/
45 void evel_set_next_event_sequence(const int sequence)
49 EVEL_INFO("Setting event sequence to %d, was %d ", sequence, event_sequence);
50 event_sequence = sequence;
56 /**************************************************************************//**
57 * Create a new heartbeat event of given name and type.
59 * @note that the heartbeat is just a "naked" commonEventHeader!
61 * @param event_name Unique Event Name: in format
62 * {DomainAbbreviation}_{AsdcModel or ApplicationPlatform}_{DescriptionOfInfoBeingConveyed}
63 * @param event_id Uniquely identify event for correlation and analysis
65 * @returns pointer to the newly manufactured ::EVENT_HEADER. If the event is
66 * not used it must be released using ::evel_free_event
67 * @retval NULL Failed to create the event.
68 *****************************************************************************/
69 EVENT_HEADER * evel_new_heartbeat_nameid(const char* ev_name, const char *ev_id)
71 EVENT_HEADER * heartbeat = NULL;
74 assert(ev_name != NULL);
75 assert(ev_id != NULL);
77 /***************************************************************************/
78 /* Allocate the header. */
79 /***************************************************************************/
80 heartbeat = malloc(sizeof(EVENT_HEADER));
81 if (heartbeat == NULL)
83 log_error_state("Out of memory");
86 memset(heartbeat, 0, sizeof(EVENT_HEADER));
88 /***************************************************************************/
89 /* Initialize the header. Get a new event sequence number. Note that if */
90 /* any memory allocation fails in here we will fail gracefully because */
91 /* everything downstream can cope with NULLs. */
92 /***************************************************************************/
93 evel_init_header_nameid(heartbeat,ev_name,ev_id);
100 /**************************************************************************//**
101 * Create a new heartbeat event.
103 * @note that the heartbeat is just a "naked" commonEventHeader!
105 * @returns pointer to the newly manufactured ::EVENT_HEADER. If the event is
106 * not used it must be released using ::evel_free_event
107 * @retval NULL Failed to create the event.
108 *****************************************************************************/
109 EVENT_HEADER * evel_new_heartbeat()
111 EVENT_HEADER * heartbeat = NULL;
114 /***************************************************************************/
115 /* Allocate the header. */
116 /***************************************************************************/
117 heartbeat = malloc(sizeof(EVENT_HEADER));
118 if (heartbeat == NULL)
120 log_error_state("Out of memory");
123 memset(heartbeat, 0, sizeof(EVENT_HEADER));
125 /***************************************************************************/
126 /* Initialize the header. Get a new event sequence number. Note that if */
127 /* any memory allocation fails in here we will fail gracefully because */
128 /* everything downstream can cope with NULLs. */
129 /***************************************************************************/
130 evel_init_header(heartbeat,"Heartbeat");
131 evel_force_option_string(&heartbeat->event_type, "Autonomous heartbeat");
138 /**************************************************************************//**
139 * Initialize a newly created event header.
141 * @param header Pointer to the header being initialized.
142 *****************************************************************************/
143 void evel_init_header(EVENT_HEADER * const header,const char *const eventname)
145 char scratchpad[EVEL_MAX_STRING_LEN + 1] = {0};
150 assert(header != NULL);
152 gettimeofday(&tv, NULL);
154 /***************************************************************************/
155 /* Initialize the header. Get a new event sequence number. Note that if */
156 /* any memory allocation fails in here we will fail gracefully because */
157 /* everything downstream can cope with NULLs. */
158 /***************************************************************************/
159 header->event_domain = EVEL_DOMAIN_HEARTBEAT;
160 snprintf(scratchpad, EVEL_MAX_STRING_LEN, "%d", event_sequence);
161 header->event_id = strdup(scratchpad);
162 if( eventname == NULL )
163 header->event_name = strdup(functional_role);
165 header->event_name = strdup(eventname);
166 header->last_epoch_microsec = tv.tv_usec + 1000000 * tv.tv_sec;
167 header->priority = EVEL_PRIORITY_NORMAL;
168 header->reporting_entity_name = strdup(openstack_vm_name());
169 header->source_name = strdup(openstack_vm_name());
170 header->sequence = event_sequence;
171 header->start_epoch_microsec = header->last_epoch_microsec;
172 header->major_version = EVEL_HEADER_MAJOR_VERSION;
173 header->minor_version = EVEL_HEADER_MINOR_VERSION;
176 /***************************************************************************/
177 /* Optional parameters. */
178 /***************************************************************************/
179 evel_init_option_string(&header->event_type);
180 evel_init_option_string(&header->nfcnaming_code);
181 evel_init_option_string(&header->nfnaming_code);
182 evel_force_option_string(&header->reporting_entity_id, openstack_vm_uuid());
183 evel_force_option_string(&header->source_id, openstack_vm_uuid());
184 evel_init_option_intheader(&header->internal_field);
190 /**************************************************************************//**
191 * Initialize a newly created event header.
193 * @param header Pointer to the header being initialized.
194 *****************************************************************************/
195 void evel_init_header_nameid(EVENT_HEADER * const header,const char *const eventname, const char *eventid)
201 assert(header != NULL);
202 assert(eventname != NULL);
203 assert(eventid != NULL);
205 gettimeofday(&tv, NULL);
207 /***************************************************************************/
208 /* Initialize the header. Get a new event sequence number. Note that if */
209 /* any memory allocation fails in here we will fail gracefully because */
210 /* everything downstream can cope with NULLs. */
211 /***************************************************************************/
212 header->event_domain = EVEL_DOMAIN_HEARTBEAT;
213 header->event_id = strdup(eventid);
214 header->event_name = strdup(eventname);
215 header->last_epoch_microsec = tv.tv_usec + 1000000 * tv.tv_sec;
216 header->priority = EVEL_PRIORITY_NORMAL;
217 header->reporting_entity_name = strdup(openstack_vm_name());
218 header->source_name = strdup(openstack_vm_name());
219 header->sequence = event_sequence;
220 header->start_epoch_microsec = header->last_epoch_microsec;
221 header->major_version = EVEL_HEADER_MAJOR_VERSION;
222 header->minor_version = EVEL_HEADER_MINOR_VERSION;
225 /***************************************************************************/
226 /* Optional parameters. */
227 /***************************************************************************/
228 evel_init_option_string(&header->event_type);
229 evel_init_option_string(&header->nfcnaming_code);
230 evel_init_option_string(&header->nfnaming_code);
231 evel_force_option_string(&header->reporting_entity_id, openstack_vm_uuid());
232 evel_force_option_string(&header->source_id, openstack_vm_uuid());
233 evel_init_option_intheader(&header->internal_field);
238 /**************************************************************************//**
239 * Set the Event Type property of the event header.
241 * @note The property is treated as immutable: it is only valid to call
242 * the setter once. However, we don't assert if the caller tries to
243 * overwrite, just ignoring the update instead.
245 * @param header Pointer to the ::EVENT_HEADER.
246 * @param type The Event Type to be set. ASCIIZ string. The caller
247 * does not need to preserve the value once the function
249 *****************************************************************************/
250 void evel_header_type_set(EVENT_HEADER * const header,
251 const char * const type)
255 /***************************************************************************/
256 /* Check preconditions. */
257 /***************************************************************************/
258 assert(header != NULL);
259 assert(type != NULL);
261 evel_set_option_string(&header->event_type, type, "Event Type");
266 /**************************************************************************//**
267 * Set the Start Epoch property of the event header.
269 * @note The Start Epoch defaults to the time of event creation.
271 * @param header Pointer to the ::EVENT_HEADER.
272 * @param start_epoch_microsec
273 * The start epoch to set, in microseconds.
274 *****************************************************************************/
275 void evel_start_epoch_set(EVENT_HEADER * const header,
276 const unsigned long long start_epoch_microsec)
280 /***************************************************************************/
281 /* Check preconditions and assign the new value. */
282 /***************************************************************************/
283 assert(header != NULL);
284 header->start_epoch_microsec = start_epoch_microsec;
289 /**************************************************************************//**
290 * Set the Last Epoch property of the event header.
292 * @note The Last Epoch defaults to the time of event creation.
294 * @param header Pointer to the ::EVENT_HEADER.
295 * @param last_epoch_microsec
296 * The last epoch to set, in microseconds.
297 *****************************************************************************/
298 void evel_last_epoch_set(EVENT_HEADER * const header,
299 const unsigned long long last_epoch_microsec)
303 /***************************************************************************/
304 /* Check preconditions and assign the new value. */
305 /***************************************************************************/
306 assert(header != NULL);
307 header->last_epoch_microsec = last_epoch_microsec;
312 /**************************************************************************//**
313 * Set the NFC Naming code property of the event header.
315 * @param header Pointer to the ::EVENT_HEADER.
316 * @param nfcnamingcode String
317 *****************************************************************************/
318 void evel_nfcnamingcode_set(EVENT_HEADER * const header,
319 const char * const nfcnam)
323 /***************************************************************************/
324 /* Check preconditions and assign the new value. */
325 /***************************************************************************/
326 assert(header != NULL);
327 assert(nfcnam != NULL);
328 evel_set_option_string(&header->nfcnaming_code, nfcnam, "NFC Naming Code");
333 /**************************************************************************//**
334 * Set the NF Naming code property of the event header.
336 * @param header Pointer to the ::EVENT_HEADER.
337 * @param nfnamingcode String
338 *****************************************************************************/
339 void evel_nfnamingcode_set(EVENT_HEADER * const header,
340 const char * const nfnam)
344 /***************************************************************************/
345 /* Check preconditions and assign the new value. */
346 /***************************************************************************/
347 assert(header != NULL);
348 assert(nfnam != NULL);
349 evel_set_option_string(&header->nfnaming_code, nfnam, "NF Naming Code");
355 /**************************************************************************//**
356 * Set the Reporting Entity Name property of the event header.
358 * @note The Reporting Entity Name defaults to the OpenStack VM Name.
360 * @param header Pointer to the ::EVENT_HEADER.
361 * @param entity_name The entity name to set.
362 *****************************************************************************/
363 void evel_reporting_entity_name_set(EVENT_HEADER * const header,
364 const char * const entity_name)
368 /***************************************************************************/
369 /* Check preconditions and assign the new value. */
370 /***************************************************************************/
371 assert(header != NULL);
372 assert(entity_name != NULL);
373 assert(header->reporting_entity_name != NULL);
375 /***************************************************************************/
376 /* Free the previously allocated memory and replace it with a copy of the */
378 /***************************************************************************/
379 free(header->reporting_entity_name);
380 header->reporting_entity_name = strdup(entity_name);
385 /**************************************************************************//**
386 * Set the Reporting Entity Id property of the event header.
388 * @note The Reporting Entity Id defaults to the OpenStack VM UUID.
390 * @param header Pointer to the ::EVENT_HEADER.
391 * @param entity_id The entity id to set.
392 *****************************************************************************/
393 void evel_reporting_entity_id_set(EVENT_HEADER * const header,
394 const char * const entity_id)
398 /***************************************************************************/
399 /* Check preconditions and assign the new value. */
400 /***************************************************************************/
401 assert(header != NULL);
402 assert(entity_id != NULL);
404 /***************************************************************************/
405 /* Free the previously allocated memory and replace it with a copy of the */
406 /* provided one. Note that evel_force_option_string strdups entity_id. */
407 /***************************************************************************/
408 evel_free_option_string(&header->reporting_entity_id);
409 evel_force_option_string(&header->reporting_entity_id, entity_id);
414 /**************************************************************************//**
415 * Encode the event as a JSON event object according to AT&T's schema.
417 * @param jbuf Pointer to the ::EVEL_JSON_BUFFER to encode into.
418 * @param event Pointer to the ::EVENT_HEADER to encode.
419 *****************************************************************************/
420 void evel_json_encode_header(EVEL_JSON_BUFFER * jbuf,
421 EVENT_HEADER * event)
428 /***************************************************************************/
429 /* Check preconditions. */
430 /***************************************************************************/
431 assert(jbuf != NULL);
432 assert(jbuf->json != NULL);
433 assert(jbuf->max_size > 0);
434 assert(event != NULL);
436 domain = evel_event_domain(event->event_domain);
437 priority = evel_event_priority(event->priority);
438 evel_json_open_named_object(jbuf, "commonEventHeader");
440 /***************************************************************************/
441 /* Mandatory fields. */
442 /***************************************************************************/
443 evel_enc_kv_string(jbuf, "domain", domain);
444 evel_enc_kv_string(jbuf, "eventId", event->event_id);
445 evel_enc_kv_string(jbuf, "eventName", event->event_name);
446 evel_enc_kv_ull(jbuf, "lastEpochMicrosec", event->last_epoch_microsec);
447 evel_enc_kv_string(jbuf, "priority", priority);
449 jbuf, "reportingEntityName", event->reporting_entity_name);
450 evel_enc_kv_int(jbuf, "sequence", event->sequence);
451 evel_enc_kv_string(jbuf, "sourceName", event->source_name);
452 evel_enc_kv_ull(jbuf, "startEpochMicrosec", event->start_epoch_microsec);
454 jbuf, "version", event->major_version, event->minor_version);
456 /***************************************************************************/
457 /* Optional fields. */
458 /***************************************************************************/
459 evel_enc_kv_opt_string(jbuf, "eventType", &event->event_type);
460 evel_enc_kv_opt_string(
461 jbuf, "reportingEntityId", &event->reporting_entity_id);
462 evel_enc_kv_opt_string(jbuf, "sourceId", &event->source_id);
463 evel_enc_kv_opt_string(jbuf, "nfcNamingCode", &event->nfcnaming_code);
464 evel_enc_kv_opt_string(jbuf, "nfNamingCode", &event->nfnaming_code);
466 evel_json_close_object(jbuf);
471 /**************************************************************************//**
472 * Free an event header.
474 * Free off the event header supplied. Will free all the contained allocated
477 * @note It does not free the header itself, since that may be part of a
479 *****************************************************************************/
480 void evel_free_header(EVENT_HEADER * const event)
484 /***************************************************************************/
485 /* Check preconditions. As an internal API we don't allow freeing NULL */
486 /* events as we do on the public API. */
487 /***************************************************************************/
488 assert(event != NULL);
490 /***************************************************************************/
491 /* Free all internal strings. */
492 /***************************************************************************/
493 free(event->event_id);
494 evel_free_option_string(&event->event_type);
495 free(event->event_name);
496 evel_free_option_string(&event->reporting_entity_id);
497 free(event->reporting_entity_name);
498 evel_free_option_string(&event->source_id);
499 evel_free_option_string(&event->nfcnaming_code);
500 evel_free_option_string(&event->nfnaming_code);
501 evel_free_option_intheader(&event->internal_field);
502 free(event->source_name);
507 /**************************************************************************//**
508 * Encode the event as a JSON event object according to AT&T's schema.
510 * @param json Pointer to where to store the JSON encoded data.
511 * @param max_size Size of storage available in json_body.
512 * @param event Pointer to the ::EVENT_HEADER to encode.
513 * @returns Number of bytes actually written.
514 *****************************************************************************/
515 int evel_json_encode_event(char * json,
517 EVENT_HEADER * event)
519 EVEL_JSON_BUFFER json_buffer;
520 EVEL_JSON_BUFFER * jbuf = &json_buffer;
521 EVEL_THROTTLE_SPEC * throttle_spec;
525 /***************************************************************************/
526 /* Get the latest throttle specification for the domain. */
527 /***************************************************************************/
528 throttle_spec = evel_get_throttle_spec(event->event_domain);
530 /***************************************************************************/
531 /* Initialize the JSON_BUFFER and open the top-level objects. */
532 /***************************************************************************/
533 evel_json_buffer_init(jbuf, json, max_size, throttle_spec);
534 evel_json_open_object(jbuf);
535 evel_json_open_named_object(jbuf, "event");
537 switch (event->event_domain)
539 case EVEL_DOMAIN_HEARTBEAT:
540 evel_json_encode_header(jbuf, event);
543 case EVEL_DOMAIN_FAULT:
544 evel_json_encode_fault(jbuf, (EVENT_FAULT *)event);
547 case EVEL_DOMAIN_MEASUREMENT:
548 evel_json_encode_measurement(jbuf, (EVENT_MEASUREMENT *)event);
551 case EVEL_DOMAIN_MOBILE_FLOW:
552 evel_json_encode_mobile_flow(jbuf, (EVENT_MOBILE_FLOW *)event);
555 case EVEL_DOMAIN_REPORT:
556 evel_json_encode_report(jbuf, (EVENT_REPORT *)event);
559 case EVEL_DOMAIN_HEARTBEAT_FIELD:
560 evel_json_encode_hrtbt_field(jbuf, (EVENT_HEARTBEAT_FIELD *)event);
563 case EVEL_DOMAIN_SIPSIGNALING:
564 evel_json_encode_signaling(jbuf, (EVENT_SIGNALING *)event);
567 case EVEL_DOMAIN_STATE_CHANGE:
568 evel_json_encode_state_change(jbuf, (EVENT_STATE_CHANGE *)event);
571 case EVEL_DOMAIN_SYSLOG:
572 evel_json_encode_syslog(jbuf, (EVENT_SYSLOG *)event);
575 case EVEL_DOMAIN_OTHER:
576 evel_json_encode_other(jbuf, (EVENT_OTHER *)event);
579 case EVEL_DOMAIN_VOICE_QUALITY:
580 evel_json_encode_voice_quality(jbuf, (EVENT_VOICE_QUALITY *)event);
583 case EVEL_DOMAIN_THRESHOLD_CROSS:
584 evel_json_encode_threshold_cross(jbuf, (EVENT_THRESHOLD_CROSS *)event);
587 case EVEL_DOMAIN_INTERNAL:
589 EVEL_ERROR("Unexpected domain %d", event->event_domain);
593 evel_json_close_object(jbuf);
594 evel_json_close_object(jbuf);
596 /***************************************************************************/
598 /***************************************************************************/
599 assert(jbuf->depth == 0);
607 /**************************************************************************//**
608 * Initialize an event instance id.
610 * @param vfield Pointer to the event vnfname field being initialized.
611 * @param vendor_id The vendor id to encode in the event instance id.
612 * @param event_id The event id to encode in the event instance id.
613 *****************************************************************************/
614 void evel_init_vendor_field(VENDOR_VNFNAME_FIELD * const vfield,
615 const char * const vendor_name)
619 /***************************************************************************/
620 /* Check preconditions. */
621 /***************************************************************************/
622 assert(vfield != NULL);
623 assert(vendor_name != NULL);
625 /***************************************************************************/
626 /* Store the mandatory parts. */
627 /***************************************************************************/
628 vfield->vendorname = strdup(vendor_name);
629 evel_init_option_string(&vfield->vfmodule);
630 evel_init_option_string(&vfield->vnfname);
632 /***************************************************************************/
633 /* Initialize the optional parts. */
634 /***************************************************************************/
639 /**************************************************************************//**
640 * Set the Vendor module property of the Vendor.
642 * @note The property is treated as immutable: it is only valid to call
643 * the setter once. However, we don't assert if the caller tries to
644 * overwrite, just ignoring the update instead.
646 * @param vfield Pointer to the Vendor field.
647 * @param module_name The module name to be set. ASCIIZ string. The caller
648 * does not need to preserve the value once the function
650 *****************************************************************************/
651 void evel_vendor_field_module_set(VENDOR_VNFNAME_FIELD * const vfield,
652 const char * const module_name)
656 /***************************************************************************/
657 /* Check preconditions. */
658 /***************************************************************************/
659 assert(vfield != NULL);
660 assert(module_name != NULL);
662 evel_set_option_string(&vfield->vfmodule, module_name, "Module name set");
667 /**************************************************************************//**
668 * Set the Vendor module property of the Vendor.
670 * @note The property is treated as immutable: it is only valid to call
671 * the setter once. However, we don't assert if the caller tries to
672 * overwrite, just ignoring the update instead.
674 * @param vfield Pointer to the Vendor field.
675 * @param module_name The module name to be set. ASCIIZ string. The caller
676 * does not need to preserve the value once the function
678 *****************************************************************************/
679 void evel_vendor_field_vnfname_set(VENDOR_VNFNAME_FIELD * const vfield,
680 const char * const vnfname)
684 /***************************************************************************/
685 /* Check preconditions. */
686 /***************************************************************************/
687 assert(vfield != NULL);
688 assert(vnfname != NULL);
690 evel_set_option_string(&vfield->vnfname, vnfname, "Virtual Network Function name set");
695 /**************************************************************************//**
696 * Free an event instance id.
698 * @param vfield Pointer to the event vnfname_field being freed.
699 *****************************************************************************/
700 void evel_free_event_vendor_field(VENDOR_VNFNAME_FIELD * const vfield)
704 /***************************************************************************/
705 /* Check preconditions. */
706 /***************************************************************************/
707 assert(vfield->vendorname != NULL);
709 /***************************************************************************/
710 /* Free everything. */
711 /***************************************************************************/
712 evel_free_option_string(&vfield->vfmodule);
713 evel_free_option_string(&vfield->vnfname);
714 free(vfield->vendorname);
719 /**************************************************************************//**
720 * Encode the instance id as a JSON object according to AT&T's schema.
722 * @param jbuf Pointer to the ::EVEL_JSON_BUFFER to encode into.
723 * @param vfield Pointer to the ::VENDOR_VNFNAME_FIELD to encode.
724 *****************************************************************************/
725 void evel_json_encode_vendor_field(EVEL_JSON_BUFFER * jbuf,
726 VENDOR_VNFNAME_FIELD * vfield)
730 /***************************************************************************/
731 /* Check preconditions. */
732 /***************************************************************************/
733 assert(jbuf != NULL);
734 assert(jbuf->json != NULL);
735 assert(jbuf->max_size > 0);
736 assert(vfield != NULL);
737 assert(vfield->vendorname != NULL);
739 evel_json_open_named_object(jbuf, "vendorVnfNameFields");
741 /***************************************************************************/
742 /* Mandatory fields. */
743 /***************************************************************************/
744 evel_enc_kv_string(jbuf, "vendorName", vfield->vendorname);
745 evel_enc_kv_opt_string(jbuf, "vfModuleName", &vfield->vfmodule);
746 evel_enc_kv_opt_string(jbuf, "vnfName", &vfield->vnfname);
748 /***************************************************************************/
749 /* Optional fields. */
750 /***************************************************************************/
752 evel_json_close_object(jbuf);