1 /*************************************************************************//**
3 * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
5 * Unless otherwise specified, all software contained herein is
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
17 ****************************************************************************/
19 /**************************************************************************//**
21 * Implementation of EVEL functions relating to Event Headers - since
22 * Heartbeats only contain the Event Header, the Heartbeat factory function is
24 *****************************************************************************/
32 #include "evel_internal.h"
33 #include "evel_throttle.h"
36 /**************************************************************************//**
37 * Unique sequence number for events from this VNF.
38 *****************************************************************************/
39 static int event_sequence = 1;
41 /**************************************************************************//**
42 * Set the next event_sequence to use.
44 * @param sequence The next sequence number to use.
45 *****************************************************************************/
46 void evel_set_next_event_sequence(const int sequence)
50 EVEL_INFO("Setting event sequence to %d, was %d ", sequence, event_sequence);
51 event_sequence = sequence;
57 /**************************************************************************//**
58 * Create a new heartbeat event of given name and type.
60 * @note that the heartbeat is just a "naked" commonEventHeader!
62 * @param event_name Unique Event Name: in format
63 * {DomainAbbreviation}_{AsdcModel or ApplicationPlatform}_{DescriptionOfInfoBeingConveyed}
64 * @param event_id Uniquely identify event for correlation and analysis
66 * @returns pointer to the newly manufactured ::EVENT_HEADER. If the event is
67 * not used it must be released using ::evel_free_event
68 * @retval NULL Failed to create the event.
69 *****************************************************************************/
70 EVENT_HEADER * evel_new_heartbeat_nameid(const char* ev_name, const char *ev_id)
72 EVENT_HEADER * heartbeat = NULL;
75 assert(ev_name != NULL);
76 assert(ev_id != NULL);
78 /***************************************************************************/
79 /* Allocate the header. */
80 /***************************************************************************/
81 heartbeat = malloc(sizeof(EVENT_HEADER));
82 if (heartbeat == NULL)
84 log_error_state("Out of memory");
87 memset(heartbeat, 0, sizeof(EVENT_HEADER));
89 /***************************************************************************/
90 /* Initialize the header. Get a new event sequence number. Note that if */
91 /* any memory allocation fails in here we will fail gracefully because */
92 /* everything downstream can cope with NULLs. */
93 /***************************************************************************/
94 evel_init_header_nameid(heartbeat,ev_name,ev_id);
101 /**************************************************************************//**
102 * Create a new heartbeat event.
104 * @note that the heartbeat is just a "naked" commonEventHeader!
106 * @returns pointer to the newly manufactured ::EVENT_HEADER. If the event is
107 * not used it must be released using ::evel_free_event
108 * @retval NULL Failed to create the event.
109 *****************************************************************************/
110 EVENT_HEADER * evel_new_heartbeat()
112 EVENT_HEADER * heartbeat = NULL;
115 /***************************************************************************/
116 /* Allocate the header. */
117 /***************************************************************************/
118 heartbeat = malloc(sizeof(EVENT_HEADER));
119 if (heartbeat == NULL)
121 log_error_state("Out of memory");
124 memset(heartbeat, 0, sizeof(EVENT_HEADER));
126 /***************************************************************************/
127 /* Initialize the header. Get a new event sequence number. Note that if */
128 /* any memory allocation fails in here we will fail gracefully because */
129 /* everything downstream can cope with NULLs. */
130 /***************************************************************************/
131 evel_init_header(heartbeat,"Heartbeat");
132 evel_force_option_string(&heartbeat->event_type, "Autonomous heartbeat");
139 /**************************************************************************//**
140 * Initialize a newly created event header.
142 * @param header Pointer to the header being initialized.
143 *****************************************************************************/
144 void evel_init_header(EVENT_HEADER * const header,const char *const eventname)
146 char scratchpad[EVEL_MAX_STRING_LEN + 1] = {0};
151 assert(header != NULL);
153 gettimeofday(&tv, NULL);
155 /***************************************************************************/
156 /* Initialize the header. Get a new event sequence number. Note that if */
157 /* any memory allocation fails in here we will fail gracefully because */
158 /* everything downstream can cope with NULLs. */
159 /***************************************************************************/
160 header->event_domain = EVEL_DOMAIN_HEARTBEAT;
161 snprintf(scratchpad, EVEL_MAX_STRING_LEN, "%d", event_sequence);
162 header->event_id = strdup(scratchpad);
163 if( eventname == NULL )
164 header->event_name = strdup(functional_role);
166 header->event_name = strdup(eventname);
167 header->last_epoch_microsec = tv.tv_usec + 1000000 * tv.tv_sec;
168 header->priority = EVEL_PRIORITY_NORMAL;
169 header->reporting_entity_name = strdup(openstack_vm_name());
170 header->source_name = strdup(openstack_vm_name());
171 header->sequence = event_sequence;
172 header->start_epoch_microsec = header->last_epoch_microsec;
173 header->major_version = EVEL_HEADER_MAJOR_VERSION;
174 header->minor_version = EVEL_HEADER_MINOR_VERSION;
177 /***************************************************************************/
178 /* Optional parameters. */
179 /***************************************************************************/
180 evel_init_option_string(&header->event_type);
181 evel_init_option_string(&header->nfcnaming_code);
182 evel_init_option_string(&header->nfnaming_code);
183 evel_force_option_string(&header->reporting_entity_id, openstack_vm_uuid());
184 evel_force_option_string(&header->source_id, openstack_vm_uuid());
185 evel_init_option_intheader(&header->internal_field);
191 /**************************************************************************//**
192 * Initialize a newly created event header.
194 * @param header Pointer to the header being initialized.
195 *****************************************************************************/
196 void evel_init_header_nameid(EVENT_HEADER * const header,const char *const eventname, const char *eventid)
202 assert(header != NULL);
203 assert(eventname != NULL);
204 assert(eventid != NULL);
206 gettimeofday(&tv, NULL);
208 /***************************************************************************/
209 /* Initialize the header. Get a new event sequence number. Note that if */
210 /* any memory allocation fails in here we will fail gracefully because */
211 /* everything downstream can cope with NULLs. */
212 /***************************************************************************/
213 header->event_domain = EVEL_DOMAIN_HEARTBEAT;
214 header->event_id = strdup(eventid);
215 header->event_name = strdup(eventname);
216 header->last_epoch_microsec = tv.tv_usec + 1000000 * tv.tv_sec;
217 header->priority = EVEL_PRIORITY_NORMAL;
218 header->reporting_entity_name = strdup(openstack_vm_name());
219 header->source_name = strdup(openstack_vm_name());
220 header->sequence = event_sequence;
221 header->start_epoch_microsec = header->last_epoch_microsec;
222 header->major_version = EVEL_HEADER_MAJOR_VERSION;
223 header->minor_version = EVEL_HEADER_MINOR_VERSION;
226 /***************************************************************************/
227 /* Optional parameters. */
228 /***************************************************************************/
229 evel_init_option_string(&header->event_type);
230 evel_init_option_string(&header->nfcnaming_code);
231 evel_init_option_string(&header->nfnaming_code);
232 evel_force_option_string(&header->reporting_entity_id, openstack_vm_uuid());
233 evel_force_option_string(&header->source_id, openstack_vm_uuid());
234 evel_init_option_intheader(&header->internal_field);
239 /**************************************************************************//**
240 * Set the Event Type property of the event header.
242 * @note The property is treated as immutable: it is only valid to call
243 * the setter once. However, we don't assert if the caller tries to
244 * overwrite, just ignoring the update instead.
246 * @param header Pointer to the ::EVENT_HEADER.
247 * @param type The Event Type to be set. ASCIIZ string. The caller
248 * does not need to preserve the value once the function
250 *****************************************************************************/
251 void evel_header_type_set(EVENT_HEADER * const header,
252 const char * const type)
256 /***************************************************************************/
257 /* Check preconditions. */
258 /***************************************************************************/
259 assert(header != NULL);
260 assert(type != NULL);
262 evel_set_option_string(&header->event_type, type, "Event Type");
267 /**************************************************************************//**
268 * Set the Start Epoch property of the event header.
270 * @note The Start Epoch defaults to the time of event creation.
272 * @param header Pointer to the ::EVENT_HEADER.
273 * @param start_epoch_microsec
274 * The start epoch to set, in microseconds.
275 *****************************************************************************/
276 void evel_start_epoch_set(EVENT_HEADER * const header,
277 const unsigned long long start_epoch_microsec)
281 /***************************************************************************/
282 /* Check preconditions and assign the new value. */
283 /***************************************************************************/
284 assert(header != NULL);
285 header->start_epoch_microsec = start_epoch_microsec;
290 /**************************************************************************//**
291 * Set the Last Epoch property of the event header.
293 * @note The Last Epoch defaults to the time of event creation.
295 * @param header Pointer to the ::EVENT_HEADER.
296 * @param last_epoch_microsec
297 * The last epoch to set, in microseconds.
298 *****************************************************************************/
299 void evel_last_epoch_set(EVENT_HEADER * const header,
300 const unsigned long long last_epoch_microsec)
304 /***************************************************************************/
305 /* Check preconditions and assign the new value. */
306 /***************************************************************************/
307 assert(header != NULL);
308 header->last_epoch_microsec = last_epoch_microsec;
313 /**************************************************************************//**
314 * Set the NFC Naming code property of the event header.
316 * @param header Pointer to the ::EVENT_HEADER.
317 * @param nfcnamingcode String
318 *****************************************************************************/
319 void evel_nfcnamingcode_set(EVENT_HEADER * const header,
320 const char * const nfcnam)
324 /***************************************************************************/
325 /* Check preconditions and assign the new value. */
326 /***************************************************************************/
327 assert(header != NULL);
328 assert(nfcnam != NULL);
329 evel_set_option_string(&header->nfcnaming_code, nfcnam, "NFC Naming Code");
334 /**************************************************************************//**
335 * Set the NF Naming code property of the event header.
337 * @param header Pointer to the ::EVENT_HEADER.
338 * @param nfnamingcode String
339 *****************************************************************************/
340 void evel_nfnamingcode_set(EVENT_HEADER * const header,
341 const char * const nfnam)
345 /***************************************************************************/
346 /* Check preconditions and assign the new value. */
347 /***************************************************************************/
348 assert(header != NULL);
349 assert(nfnam != NULL);
350 evel_set_option_string(&header->nfnaming_code, nfnam, "NF Naming Code");
356 /**************************************************************************//**
357 * Set the Reporting Entity Name property of the event header.
359 * @note The Reporting Entity Name defaults to the OpenStack VM Name.
361 * @param header Pointer to the ::EVENT_HEADER.
362 * @param entity_name The entity name to set.
363 *****************************************************************************/
364 void evel_reporting_entity_name_set(EVENT_HEADER * const header,
365 const char * const entity_name)
369 /***************************************************************************/
370 /* Check preconditions and assign the new value. */
371 /***************************************************************************/
372 assert(header != NULL);
373 assert(entity_name != NULL);
374 assert(header->reporting_entity_name != NULL);
376 /***************************************************************************/
377 /* Free the previously allocated memory and replace it with a copy of the */
379 /***************************************************************************/
380 free(header->reporting_entity_name);
381 header->reporting_entity_name = strdup(entity_name);
386 /**************************************************************************//**
387 * Set the Reporting Entity Id property of the event header.
389 * @note The Reporting Entity Id defaults to the OpenStack VM UUID.
391 * @param header Pointer to the ::EVENT_HEADER.
392 * @param entity_id The entity id to set.
393 *****************************************************************************/
394 void evel_reporting_entity_id_set(EVENT_HEADER * const header,
395 const char * const entity_id)
399 /***************************************************************************/
400 /* Check preconditions and assign the new value. */
401 /***************************************************************************/
402 assert(header != NULL);
403 assert(entity_id != NULL);
405 /***************************************************************************/
406 /* Free the previously allocated memory and replace it with a copy of the */
407 /* provided one. Note that evel_force_option_string strdups entity_id. */
408 /***************************************************************************/
409 evel_free_option_string(&header->reporting_entity_id);
410 evel_force_option_string(&header->reporting_entity_id, entity_id);
415 /**************************************************************************//**
416 * Encode the event as a JSON event object according to AT&T's schema.
418 * @param jbuf Pointer to the ::EVEL_JSON_BUFFER to encode into.
419 * @param event Pointer to the ::EVENT_HEADER to encode.
420 *****************************************************************************/
421 void evel_json_encode_header(EVEL_JSON_BUFFER * jbuf,
422 EVENT_HEADER * event)
429 /***************************************************************************/
430 /* Check preconditions. */
431 /***************************************************************************/
432 assert(jbuf != NULL);
433 assert(jbuf->json != NULL);
434 assert(jbuf->max_size > 0);
435 assert(event != NULL);
437 domain = evel_event_domain(event->event_domain);
438 priority = evel_event_priority(event->priority);
439 evel_json_open_named_object(jbuf, "commonEventHeader");
441 /***************************************************************************/
442 /* Mandatory fields. */
443 /***************************************************************************/
444 evel_enc_kv_string(jbuf, "domain", domain);
445 evel_enc_kv_string(jbuf, "eventId", event->event_id);
446 evel_enc_kv_string(jbuf, "eventName", event->event_name);
447 evel_enc_kv_ull(jbuf, "lastEpochMicrosec", event->last_epoch_microsec);
448 evel_enc_kv_string(jbuf, "priority", priority);
450 jbuf, "reportingEntityName", event->reporting_entity_name);
451 evel_enc_kv_int(jbuf, "sequence", event->sequence);
452 evel_enc_kv_string(jbuf, "sourceName", event->source_name);
453 evel_enc_kv_ull(jbuf, "startEpochMicrosec", event->start_epoch_microsec);
455 jbuf, "version", event->major_version, event->minor_version);
457 /***************************************************************************/
458 /* Optional fields. */
459 /***************************************************************************/
460 evel_enc_kv_opt_string(jbuf, "eventType", &event->event_type);
461 evel_enc_kv_opt_string(
462 jbuf, "reportingEntityId", &event->reporting_entity_id);
463 evel_enc_kv_opt_string(jbuf, "sourceId", &event->source_id);
464 evel_enc_kv_opt_string(jbuf, "nfcNamingCode", &event->nfcnaming_code);
465 evel_enc_kv_opt_string(jbuf, "nfNamingCode", &event->nfnaming_code);
467 evel_json_close_object(jbuf);
472 /**************************************************************************//**
473 * Free an event header.
475 * Free off the event header supplied. Will free all the contained allocated
478 * @note It does not free the header itself, since that may be part of a
480 *****************************************************************************/
481 void evel_free_header(EVENT_HEADER * const event)
485 /***************************************************************************/
486 /* Check preconditions. As an internal API we don't allow freeing NULL */
487 /* events as we do on the public API. */
488 /***************************************************************************/
489 assert(event != NULL);
491 /***************************************************************************/
492 /* Free all internal strings. */
493 /***************************************************************************/
494 free(event->event_id);
495 evel_free_option_string(&event->event_type);
496 free(event->event_name);
497 evel_free_option_string(&event->reporting_entity_id);
498 free(event->reporting_entity_name);
499 evel_free_option_string(&event->source_id);
500 evel_free_option_string(&event->nfcnaming_code);
501 evel_free_option_string(&event->nfnaming_code);
502 evel_free_option_intheader(&event->internal_field);
503 free(event->source_name);
508 /**************************************************************************//**
509 * Encode the event as a JSON event object according to AT&T's schema.
511 * @param json Pointer to where to store the JSON encoded data.
512 * @param max_size Size of storage available in json_body.
513 * @param event Pointer to the ::EVENT_HEADER to encode.
514 * @returns Number of bytes actually written.
515 *****************************************************************************/
516 int evel_json_encode_event(char * json,
518 EVENT_HEADER * event)
520 EVEL_JSON_BUFFER json_buffer;
521 EVEL_JSON_BUFFER * jbuf = &json_buffer;
522 EVEL_THROTTLE_SPEC * throttle_spec;
526 /***************************************************************************/
527 /* Get the latest throttle specification for the domain. */
528 /***************************************************************************/
529 throttle_spec = evel_get_throttle_spec(event->event_domain);
531 /***************************************************************************/
532 /* Initialize the JSON_BUFFER and open the top-level objects. */
533 /***************************************************************************/
534 evel_json_buffer_init(jbuf, json, max_size, throttle_spec);
535 evel_json_open_object(jbuf);
536 evel_json_open_named_object(jbuf, "event");
538 switch (event->event_domain)
540 case EVEL_DOMAIN_HEARTBEAT:
541 evel_json_encode_header(jbuf, event);
544 case EVEL_DOMAIN_FAULT:
545 evel_json_encode_fault(jbuf, (EVENT_FAULT *)event);
548 case EVEL_DOMAIN_MEASUREMENT:
549 evel_json_encode_measurement(jbuf, (EVENT_MEASUREMENT *)event);
552 case EVEL_DOMAIN_MOBILE_FLOW:
553 evel_json_encode_mobile_flow(jbuf, (EVENT_MOBILE_FLOW *)event);
556 case EVEL_DOMAIN_REPORT:
557 evel_json_encode_report(jbuf, (EVENT_REPORT *)event);
560 case EVEL_DOMAIN_HEARTBEAT_FIELD:
561 evel_json_encode_hrtbt_field(jbuf, (EVENT_HEARTBEAT_FIELD *)event);
564 case EVEL_DOMAIN_SIPSIGNALING:
565 evel_json_encode_signaling(jbuf, (EVENT_SIGNALING *)event);
568 case EVEL_DOMAIN_STATE_CHANGE:
569 evel_json_encode_state_change(jbuf, (EVENT_STATE_CHANGE *)event);
572 case EVEL_DOMAIN_SYSLOG:
573 evel_json_encode_syslog(jbuf, (EVENT_SYSLOG *)event);
576 case EVEL_DOMAIN_OTHER:
577 evel_json_encode_other(jbuf, (EVENT_OTHER *)event);
580 case EVEL_DOMAIN_VOICE_QUALITY:
581 evel_json_encode_voice_quality(jbuf, (EVENT_VOICE_QUALITY *)event);
584 case EVEL_DOMAIN_THRESHOLD_CROSS:
585 evel_json_encode_threshold_cross(jbuf, (EVENT_THRESHOLD_CROSS *)event);
588 case EVEL_DOMAIN_INTERNAL:
590 EVEL_ERROR("Unexpected domain %d", event->event_domain);
594 evel_json_close_object(jbuf);
595 evel_json_close_object(jbuf);
597 /***************************************************************************/
599 /***************************************************************************/
600 assert(jbuf->depth == 0);
608 /**************************************************************************//**
609 * Initialize an event instance id.
611 * @param vfield Pointer to the event vnfname field being initialized.
612 * @param vendor_id The vendor id to encode in the event instance id.
613 * @param event_id The event id to encode in the event instance id.
614 *****************************************************************************/
615 void evel_init_vendor_field(VENDOR_VNFNAME_FIELD * const vfield,
616 const char * const vendor_name)
620 /***************************************************************************/
621 /* Check preconditions. */
622 /***************************************************************************/
623 assert(vfield != NULL);
624 assert(vendor_name != NULL);
626 /***************************************************************************/
627 /* Store the mandatory parts. */
628 /***************************************************************************/
629 vfield->vendorname = strdup(vendor_name);
630 evel_init_option_string(&vfield->vfmodule);
631 evel_init_option_string(&vfield->vnfname);
633 /***************************************************************************/
634 /* Initialize the optional parts. */
635 /***************************************************************************/
640 /**************************************************************************//**
641 * Set the Vendor module property of the Vendor.
643 * @note The property is treated as immutable: it is only valid to call
644 * the setter once. However, we don't assert if the caller tries to
645 * overwrite, just ignoring the update instead.
647 * @param vfield Pointer to the Vendor field.
648 * @param module_name The module name to be set. ASCIIZ string. The caller
649 * does not need to preserve the value once the function
651 *****************************************************************************/
652 void evel_vendor_field_module_set(VENDOR_VNFNAME_FIELD * const vfield,
653 const char * const module_name)
657 /***************************************************************************/
658 /* Check preconditions. */
659 /***************************************************************************/
660 assert(vfield != NULL);
661 assert(module_name != NULL);
663 evel_set_option_string(&vfield->vfmodule, module_name, "Module name set");
668 /**************************************************************************//**
669 * Set the Vendor module property of the Vendor.
671 * @note The property is treated as immutable: it is only valid to call
672 * the setter once. However, we don't assert if the caller tries to
673 * overwrite, just ignoring the update instead.
675 * @param vfield Pointer to the Vendor field.
676 * @param module_name The module name to be set. ASCIIZ string. The caller
677 * does not need to preserve the value once the function
679 *****************************************************************************/
680 void evel_vendor_field_vnfname_set(VENDOR_VNFNAME_FIELD * const vfield,
681 const char * const vnfname)
685 /***************************************************************************/
686 /* Check preconditions. */
687 /***************************************************************************/
688 assert(vfield != NULL);
689 assert(vnfname != NULL);
691 evel_set_option_string(&vfield->vnfname, vnfname, "Virtual Network Function name set");
696 /**************************************************************************//**
697 * Free an event instance id.
699 * @param vfield Pointer to the event vnfname_field being freed.
700 *****************************************************************************/
701 void evel_free_event_vendor_field(VENDOR_VNFNAME_FIELD * const vfield)
705 /***************************************************************************/
706 /* Check preconditions. */
707 /***************************************************************************/
708 assert(vfield->vendorname != NULL);
710 /***************************************************************************/
711 /* Free everything. */
712 /***************************************************************************/
713 evel_free_option_string(&vfield->vfmodule);
714 evel_free_option_string(&vfield->vnfname);
715 free(vfield->vendorname);
720 /**************************************************************************//**
721 * Encode the instance id as a JSON object according to AT&T's schema.
723 * @param jbuf Pointer to the ::EVEL_JSON_BUFFER to encode into.
724 * @param vfield Pointer to the ::VENDOR_VNFNAME_FIELD to encode.
725 *****************************************************************************/
726 void evel_json_encode_vendor_field(EVEL_JSON_BUFFER * jbuf,
727 VENDOR_VNFNAME_FIELD * vfield)
731 /***************************************************************************/
732 /* Check preconditions. */
733 /***************************************************************************/
734 assert(jbuf != NULL);
735 assert(jbuf->json != NULL);
736 assert(jbuf->max_size > 0);
737 assert(vfield != NULL);
738 assert(vfield->vendorname != NULL);
740 evel_json_open_named_object(jbuf, "vendorVnfNameFields");
742 /***************************************************************************/
743 /* Mandatory fields. */
744 /***************************************************************************/
745 evel_enc_kv_string(jbuf, "vendorName", vfield->vendorname);
746 evel_enc_kv_opt_string(jbuf, "vfModuleName", &vfield->vfmodule);
747 evel_enc_kv_opt_string(jbuf, "vnfName", &vfield->vnfname);
749 /***************************************************************************/
750 /* Optional fields. */
751 /***************************************************************************/
753 evel_json_close_object(jbuf);