1 /**************************************************************************//**
3 * Implementation of EVEL functions relating to Event Headers - since
4 * Heartbeats only contain the Event Header, the Heartbeat factory function is
10 * Copyright(c) <2016>, AT&T Intellectual Property. All other rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions are met:
15 * 1. Redistributions of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright notice,
18 * this list of conditions and the following disclaimer in the documentation
19 * and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement: This product includes
22 * software developed by the AT&T.
23 * 4. Neither the name of AT&T nor the names of its contributors may be used to
24 * endorse or promote products derived from this software without specific
25 * prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY AT&T INTELLECTUAL PROPERTY ''AS IS'' AND ANY
28 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
29 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30 * DISCLAIMED. IN NO EVENT SHALL AT&T INTELLECTUAL PROPERTY BE LIABLE FOR ANY
31 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
32 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
33 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
34 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
36 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 *****************************************************************************/
45 #include "evel_internal.h"
46 #include "evel_throttle.h"
49 /**************************************************************************//**
50 * Unique sequence number for events from this VNF.
51 *****************************************************************************/
52 static int event_sequence = 1;
54 /**************************************************************************//**
55 * Set the next event_sequence to use.
57 * @param sequence The next sequence number to use.
58 *****************************************************************************/
59 void evel_set_next_event_sequence(const int sequence)
63 EVEL_INFO("Setting event sequence to %d, was %d ", sequence, event_sequence);
64 event_sequence = sequence;
69 /**************************************************************************//**
70 * Create a new heartbeat event.
72 * @note that the heartbeat is just a "naked" commonEventHeader!
74 * @returns pointer to the newly manufactured ::EVENT_HEADER. If the event is
75 * not used it must be released using ::evel_free_event
76 * @retval NULL Failed to create the event.
77 *****************************************************************************/
78 EVENT_HEADER * evel_new_heartbeat()
80 EVENT_HEADER * heartbeat = NULL;
83 /***************************************************************************/
84 /* Allocate the header. */
85 /***************************************************************************/
86 heartbeat = malloc(sizeof(EVENT_HEADER));
87 if (heartbeat == NULL)
89 log_error_state("Out of memory");
92 memset(heartbeat, 0, sizeof(EVENT_HEADER));
94 /***************************************************************************/
95 /* Initialize the header. Get a new event sequence number. Note that if */
96 /* any memory allocation fails in here we will fail gracefully because */
97 /* everything downstream can cope with NULLs. */
98 /***************************************************************************/
99 evel_init_header(heartbeat,"Heartbeat");
100 evel_force_option_string(&heartbeat->event_type, "Autonomous heartbeat");
107 /**************************************************************************//**
108 * Initialize a newly created event header.
110 * @param header Pointer to the header being initialized.
111 *****************************************************************************/
112 void evel_init_header(EVENT_HEADER * const header,const char *const eventname)
114 char scratchpad[EVEL_MAX_STRING_LEN + 1] = {0};
119 assert(header != NULL);
121 gettimeofday(&tv, NULL);
123 /***************************************************************************/
124 /* Initialize the header. Get a new event sequence number. Note that if */
125 /* any memory allocation fails in here we will fail gracefully because */
126 /* everything downstream can cope with NULLs. */
127 /***************************************************************************/
128 header->event_domain = EVEL_DOMAIN_HEARTBEAT;
129 snprintf(scratchpad, EVEL_MAX_STRING_LEN, "%d", event_sequence);
130 header->event_id = strdup(scratchpad);
131 if( eventname == NULL )
132 header->event_name = strdup(functional_role);
134 header->event_name = strdup(eventname);
135 header->last_epoch_microsec = tv.tv_usec + 1000000 * tv.tv_sec;
136 header->priority = EVEL_PRIORITY_NORMAL;
137 header->reporting_entity_name = strdup(openstack_vm_name());
138 header->source_name = strdup(openstack_vm_name());
139 header->sequence = event_sequence;
140 header->start_epoch_microsec = header->last_epoch_microsec;
141 header->major_version = EVEL_HEADER_MAJOR_VERSION;
142 header->minor_version = EVEL_HEADER_MINOR_VERSION;
145 /***************************************************************************/
146 /* Optional parameters. */
147 /***************************************************************************/
148 evel_init_option_string(&header->event_type);
149 evel_init_option_string(&header->nfcnaming_code);
150 evel_init_option_string(&header->nfnaming_code);
151 evel_force_option_string(&header->reporting_entity_id, openstack_vm_uuid());
152 evel_force_option_string(&header->source_id, openstack_vm_uuid());
153 evel_init_option_intheader(&header->internal_field);
158 /**************************************************************************//**
159 * Set the Event Type property of the event header.
161 * @note The property is treated as immutable: it is only valid to call
162 * the setter once. However, we don't assert if the caller tries to
163 * overwrite, just ignoring the update instead.
165 * @param header Pointer to the ::EVENT_HEADER.
166 * @param type The Event Type to be set. ASCIIZ string. The caller
167 * does not need to preserve the value once the function
169 *****************************************************************************/
170 void evel_header_type_set(EVENT_HEADER * const header,
171 const char * const type)
175 /***************************************************************************/
176 /* Check preconditions. */
177 /***************************************************************************/
178 assert(header != NULL);
179 assert(type != NULL);
181 evel_set_option_string(&header->event_type, type, "Event Type");
186 /**************************************************************************//**
187 * Set the Start Epoch property of the event header.
189 * @note The Start Epoch defaults to the time of event creation.
191 * @param header Pointer to the ::EVENT_HEADER.
192 * @param start_epoch_microsec
193 * The start epoch to set, in microseconds.
194 *****************************************************************************/
195 void evel_start_epoch_set(EVENT_HEADER * const header,
196 const unsigned long long start_epoch_microsec)
200 /***************************************************************************/
201 /* Check preconditions and assign the new value. */
202 /***************************************************************************/
203 assert(header != NULL);
204 header->start_epoch_microsec = start_epoch_microsec;
209 /**************************************************************************//**
210 * Set the Last Epoch property of the event header.
212 * @note The Last Epoch defaults to the time of event creation.
214 * @param header Pointer to the ::EVENT_HEADER.
215 * @param last_epoch_microsec
216 * The last epoch to set, in microseconds.
217 *****************************************************************************/
218 void evel_last_epoch_set(EVENT_HEADER * const header,
219 const unsigned long long last_epoch_microsec)
223 /***************************************************************************/
224 /* Check preconditions and assign the new value. */
225 /***************************************************************************/
226 assert(header != NULL);
227 header->last_epoch_microsec = last_epoch_microsec;
232 /**************************************************************************//**
233 * Set the NFC Naming code property of the event header.
235 * @param header Pointer to the ::EVENT_HEADER.
236 * @param nfcnamingcode String
237 *****************************************************************************/
238 void evel_nfcnamingcode_set(EVENT_HEADER * const header,
239 const char * const nfcnam)
243 /***************************************************************************/
244 /* Check preconditions and assign the new value. */
245 /***************************************************************************/
246 assert(header != NULL);
247 assert(nfcnam != NULL);
248 evel_set_option_string(&header->nfcnaming_code, nfcnam, "NFC Naming Code");
253 /**************************************************************************//**
254 * Set the NF Naming code property of the event header.
256 * @param header Pointer to the ::EVENT_HEADER.
257 * @param nfnamingcode String
258 *****************************************************************************/
259 void evel_nfnamingcode_set(EVENT_HEADER * const header,
260 const char * const nfnam)
264 /***************************************************************************/
265 /* Check preconditions and assign the new value. */
266 /***************************************************************************/
267 assert(header != NULL);
268 assert(nfnam != NULL);
269 evel_set_option_string(&header->nfnaming_code, nfnam, "NF Naming Code");
275 /**************************************************************************//**
276 * Set the Reporting Entity Name property of the event header.
278 * @note The Reporting Entity Name defaults to the OpenStack VM Name.
280 * @param header Pointer to the ::EVENT_HEADER.
281 * @param entity_name The entity name to set.
282 *****************************************************************************/
283 void evel_reporting_entity_name_set(EVENT_HEADER * const header,
284 const char * const entity_name)
288 /***************************************************************************/
289 /* Check preconditions and assign the new value. */
290 /***************************************************************************/
291 assert(header != NULL);
292 assert(entity_name != NULL);
293 assert(header->reporting_entity_name != NULL);
295 /***************************************************************************/
296 /* Free the previously allocated memory and replace it with a copy of the */
298 /***************************************************************************/
299 free(header->reporting_entity_name);
300 header->reporting_entity_name = strdup(entity_name);
305 /**************************************************************************//**
306 * Set the Reporting Entity Id property of the event header.
308 * @note The Reporting Entity Id defaults to the OpenStack VM UUID.
310 * @param header Pointer to the ::EVENT_HEADER.
311 * @param entity_id The entity id to set.
312 *****************************************************************************/
313 void evel_reporting_entity_id_set(EVENT_HEADER * const header,
314 const char * const entity_id)
318 /***************************************************************************/
319 /* Check preconditions and assign the new value. */
320 /***************************************************************************/
321 assert(header != NULL);
322 assert(entity_id != NULL);
324 /***************************************************************************/
325 /* Free the previously allocated memory and replace it with a copy of the */
326 /* provided one. Note that evel_force_option_string strdups entity_id. */
327 /***************************************************************************/
328 evel_free_option_string(&header->reporting_entity_id);
329 evel_force_option_string(&header->reporting_entity_id, entity_id);
334 /**************************************************************************//**
335 * Encode the event as a JSON event object according to AT&T's schema.
337 * @param jbuf Pointer to the ::EVEL_JSON_BUFFER to encode into.
338 * @param event Pointer to the ::EVENT_HEADER to encode.
339 *****************************************************************************/
340 void evel_json_encode_header(EVEL_JSON_BUFFER * jbuf,
341 EVENT_HEADER * event)
348 /***************************************************************************/
349 /* Check preconditions. */
350 /***************************************************************************/
351 assert(jbuf != NULL);
352 assert(jbuf->json != NULL);
353 assert(jbuf->max_size > 0);
354 assert(event != NULL);
356 domain = evel_event_domain(event->event_domain);
357 priority = evel_event_priority(event->priority);
358 evel_json_open_named_object(jbuf, "commonEventHeader");
360 /***************************************************************************/
361 /* Mandatory fields. */
362 /***************************************************************************/
363 evel_enc_kv_string(jbuf, "domain", domain);
364 evel_enc_kv_string(jbuf, "eventId", event->event_id);
365 evel_enc_kv_string(jbuf, "eventName", event->event_name);
366 evel_enc_kv_ull(jbuf, "lastEpochMicrosec", event->last_epoch_microsec);
367 evel_enc_kv_string(jbuf, "priority", priority);
369 jbuf, "reportingEntityName", event->reporting_entity_name);
370 evel_enc_kv_int(jbuf, "sequence", event->sequence);
371 evel_enc_kv_string(jbuf, "sourceName", event->source_name);
372 evel_enc_kv_ull(jbuf, "startEpochMicrosec", event->start_epoch_microsec);
374 jbuf, "version", event->major_version, event->minor_version);
376 /***************************************************************************/
377 /* Optional fields. */
378 /***************************************************************************/
379 evel_enc_kv_opt_string(jbuf, "eventType", &event->event_type);
380 evel_enc_kv_opt_string(
381 jbuf, "reportingEntityId", &event->reporting_entity_id);
382 evel_enc_kv_opt_string(jbuf, "sourceId", &event->source_id);
383 evel_enc_kv_opt_string(jbuf, "nfcNamingCode", &event->nfcnaming_code);
384 evel_enc_kv_opt_string(jbuf, "nfNamingCode", &event->nfnaming_code);
386 evel_json_close_object(jbuf);
391 /**************************************************************************//**
392 * Free an event header.
394 * Free off the event header supplied. Will free all the contained allocated
397 * @note It does not free the header itself, since that may be part of a
399 *****************************************************************************/
400 void evel_free_header(EVENT_HEADER * const event)
404 /***************************************************************************/
405 /* Check preconditions. As an internal API we don't allow freeing NULL */
406 /* events as we do on the public API. */
407 /***************************************************************************/
408 assert(event != NULL);
410 /***************************************************************************/
411 /* Free all internal strings. */
412 /***************************************************************************/
413 free(event->event_id);
414 evel_free_option_string(&event->event_type);
415 free(event->event_name);
416 evel_free_option_string(&event->reporting_entity_id);
417 free(event->reporting_entity_name);
418 evel_free_option_string(&event->source_id);
419 evel_free_option_string(&event->nfcnaming_code);
420 evel_free_option_string(&event->nfnaming_code);
421 evel_free_option_intheader(&event->internal_field);
422 free(event->source_name);
427 /**************************************************************************//**
428 * Encode the event as a JSON event object according to AT&T's schema.
430 * @param json Pointer to where to store the JSON encoded data.
431 * @param max_size Size of storage available in json_body.
432 * @param event Pointer to the ::EVENT_HEADER to encode.
433 * @returns Number of bytes actually written.
434 *****************************************************************************/
435 int evel_json_encode_event(char * json,
437 EVENT_HEADER * event)
439 EVEL_JSON_BUFFER json_buffer;
440 EVEL_JSON_BUFFER * jbuf = &json_buffer;
441 EVEL_THROTTLE_SPEC * throttle_spec;
445 /***************************************************************************/
446 /* Get the latest throttle specification for the domain. */
447 /***************************************************************************/
448 throttle_spec = evel_get_throttle_spec(event->event_domain);
450 /***************************************************************************/
451 /* Initialize the JSON_BUFFER and open the top-level objects. */
452 /***************************************************************************/
453 evel_json_buffer_init(jbuf, json, max_size, throttle_spec);
454 evel_json_open_object(jbuf);
455 evel_json_open_named_object(jbuf, "event");
457 switch (event->event_domain)
459 case EVEL_DOMAIN_HEARTBEAT:
460 evel_json_encode_header(jbuf, event);
463 case EVEL_DOMAIN_FAULT:
464 evel_json_encode_fault(jbuf, (EVENT_FAULT *)event);
467 case EVEL_DOMAIN_MEASUREMENT:
468 evel_json_encode_measurement(jbuf, (EVENT_MEASUREMENT *)event);
471 case EVEL_DOMAIN_MOBILE_FLOW:
472 evel_json_encode_mobile_flow(jbuf, (EVENT_MOBILE_FLOW *)event);
475 case EVEL_DOMAIN_REPORT:
476 evel_json_encode_report(jbuf, (EVENT_REPORT *)event);
479 case EVEL_DOMAIN_HEARTBEAT_FIELD:
480 evel_json_encode_hrtbt_field(jbuf, (EVENT_HEARTBEAT_FIELD *)event);
483 case EVEL_DOMAIN_SIPSIGNALING:
484 evel_json_encode_signaling(jbuf, (EVENT_SIGNALING *)event);
487 case EVEL_DOMAIN_STATE_CHANGE:
488 evel_json_encode_state_change(jbuf, (EVENT_STATE_CHANGE *)event);
491 case EVEL_DOMAIN_SYSLOG:
492 evel_json_encode_syslog(jbuf, (EVENT_SYSLOG *)event);
495 case EVEL_DOMAIN_OTHER:
496 evel_json_encode_other(jbuf, (EVENT_OTHER *)event);
499 case EVEL_DOMAIN_VOICE_QUALITY:
500 evel_json_encode_other(jbuf, (EVENT_VOICE_QUALITY *)event);
503 case EVEL_DOMAIN_INTERNAL:
505 EVEL_ERROR("Unexpected domain %d", event->event_domain);
509 evel_json_close_object(jbuf);
510 evel_json_close_object(jbuf);
512 /***************************************************************************/
514 /***************************************************************************/
515 assert(jbuf->depth == 0);
523 /**************************************************************************//**
524 * Initialize an event instance id.
526 * @param vfield Pointer to the event vnfname field being initialized.
527 * @param vendor_id The vendor id to encode in the event instance id.
528 * @param event_id The event id to encode in the event instance id.
529 *****************************************************************************/
530 void evel_init_vendor_field(VENDOR_VNFNAME_FIELD * const vfield,
531 const char * const vendor_name)
535 /***************************************************************************/
536 /* Check preconditions. */
537 /***************************************************************************/
538 assert(vfield != NULL);
539 assert(vendor_name != NULL);
541 /***************************************************************************/
542 /* Store the mandatory parts. */
543 /***************************************************************************/
544 vfield->vendorname = strdup(vendor_name);
545 evel_init_option_string(&vfield->vfmodule);
546 evel_init_option_string(&vfield->vnfname);
548 /***************************************************************************/
549 /* Initialize the optional parts. */
550 /***************************************************************************/
555 /**************************************************************************//**
556 * Set the Vendor module property of the Vendor.
558 * @note The property is treated as immutable: it is only valid to call
559 * the setter once. However, we don't assert if the caller tries to
560 * overwrite, just ignoring the update instead.
562 * @param vfield Pointer to the Vendor field.
563 * @param module_name The module name to be set. ASCIIZ string. The caller
564 * does not need to preserve the value once the function
566 *****************************************************************************/
567 void evel_vendor_field_module_set(VENDOR_VNFNAME_FIELD * const vfield,
568 const char * const module_name)
572 /***************************************************************************/
573 /* Check preconditions. */
574 /***************************************************************************/
575 assert(vfield != NULL);
576 assert(module_name != NULL);
578 evel_set_option_string(&vfield->vfmodule, module_name, "Module name set");
583 /**************************************************************************//**
584 * Set the Vendor module property of the Vendor.
586 * @note The property is treated as immutable: it is only valid to call
587 * the setter once. However, we don't assert if the caller tries to
588 * overwrite, just ignoring the update instead.
590 * @param vfield Pointer to the Vendor field.
591 * @param module_name The module name to be set. ASCIIZ string. The caller
592 * does not need to preserve the value once the function
594 *****************************************************************************/
595 void evel_vendor_field_vnfname_set(VENDOR_VNFNAME_FIELD * const vfield,
596 const char * const vnfname)
600 /***************************************************************************/
601 /* Check preconditions. */
602 /***************************************************************************/
603 assert(vfield != NULL);
604 assert(vnfname != NULL);
606 evel_set_option_string(&vfield->vnfname, vnfname, "Virtual Network Function name set");
611 /**************************************************************************//**
612 * Free an event instance id.
614 * @param vfield Pointer to the event vnfname_field being freed.
615 *****************************************************************************/
616 void evel_free_event_vendor_field(VENDOR_VNFNAME_FIELD * const vfield)
620 /***************************************************************************/
621 /* Check preconditions. */
622 /***************************************************************************/
623 assert(vfield->vendorname != NULL);
625 /***************************************************************************/
626 /* Free everything. */
627 /***************************************************************************/
628 evel_free_option_string(&vfield->vfmodule);
629 evel_free_option_string(&vfield->vnfname);
630 free(vfield->vendorname);
635 /**************************************************************************//**
636 * Encode the instance id as a JSON object according to AT&T's schema.
638 * @param jbuf Pointer to the ::EVEL_JSON_BUFFER to encode into.
639 * @param vfield Pointer to the ::VENDOR_VNFNAME_FIELD to encode.
640 *****************************************************************************/
641 void evel_json_encode_vendor_field(EVEL_JSON_BUFFER * jbuf,
642 VENDOR_VNFNAME_FIELD * vfield)
646 /***************************************************************************/
647 /* Check preconditions. */
648 /***************************************************************************/
649 assert(jbuf != NULL);
650 assert(jbuf->json != NULL);
651 assert(jbuf->max_size > 0);
652 assert(vfield != NULL);
653 assert(vfield->vendorname != NULL);
655 evel_json_open_named_object(jbuf, "vendorVnfNamedFields");
657 /***************************************************************************/
658 /* Mandatory fields. */
659 /***************************************************************************/
660 evel_enc_kv_string(jbuf, "vendorName", vfield->vendorname);
661 evel_enc_kv_opt_string(jbuf, "vfModuleName", &vfield->vfmodule);
662 evel_enc_kv_opt_string(jbuf, "vnfName", &vfield->vnfname);
664 /***************************************************************************/
665 /* Optional fields. */
666 /***************************************************************************/
668 evel_json_close_object(jbuf);