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;
55 /**************************************************************************//**
56 * Create a new heartbeat event.
58 * @note that the heartbeat is just a "naked" commonEventHeader!
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()
66 EVENT_HEADER * heartbeat = NULL;
69 /***************************************************************************/
70 /* Allocate the header. */
71 /***************************************************************************/
72 heartbeat = malloc(sizeof(EVENT_HEADER));
73 if (heartbeat == NULL)
75 log_error_state("Out of memory");
78 memset(heartbeat, 0, sizeof(EVENT_HEADER));
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");
93 /**************************************************************************//**
94 * Initialize a newly created event header.
96 * @param header Pointer to the header being initialized.
97 *****************************************************************************/
98 void evel_init_header(EVENT_HEADER * const header,const char *const eventname)
100 char scratchpad[EVEL_MAX_STRING_LEN + 1] = {0};
105 assert(header != NULL);
107 gettimeofday(&tv, NULL);
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);
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;
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);
144 /**************************************************************************//**
145 * Set the Event Type property of the event header.
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.
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
155 *****************************************************************************/
156 void evel_header_type_set(EVENT_HEADER * const header,
157 const char * const type)
161 /***************************************************************************/
162 /* Check preconditions. */
163 /***************************************************************************/
164 assert(header != NULL);
165 assert(type != NULL);
167 evel_set_option_string(&header->event_type, type, "Event Type");
172 /**************************************************************************//**
173 * Set the Start Epoch property of the event header.
175 * @note The Start Epoch defaults to the time of event creation.
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)
186 /***************************************************************************/
187 /* Check preconditions and assign the new value. */
188 /***************************************************************************/
189 assert(header != NULL);
190 header->start_epoch_microsec = start_epoch_microsec;
195 /**************************************************************************//**
196 * Set the Last Epoch property of the event header.
198 * @note The Last Epoch defaults to the time of event creation.
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)
209 /***************************************************************************/
210 /* Check preconditions and assign the new value. */
211 /***************************************************************************/
212 assert(header != NULL);
213 header->last_epoch_microsec = last_epoch_microsec;
218 /**************************************************************************//**
219 * Set the NFC Naming code property of the event header.
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)
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");
239 /**************************************************************************//**
240 * Set the NF Naming code property of the event header.
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)
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");
261 /**************************************************************************//**
262 * Set the Reporting Entity Name property of the event header.
264 * @note The Reporting Entity Name defaults to the OpenStack VM Name.
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)
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);
281 /***************************************************************************/
282 /* Free the previously allocated memory and replace it with a copy of the */
284 /***************************************************************************/
285 free(header->reporting_entity_name);
286 header->reporting_entity_name = strdup(entity_name);
291 /**************************************************************************//**
292 * Set the Reporting Entity Id property of the event header.
294 * @note The Reporting Entity Id defaults to the OpenStack VM UUID.
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)
304 /***************************************************************************/
305 /* Check preconditions and assign the new value. */
306 /***************************************************************************/
307 assert(header != NULL);
308 assert(entity_id != NULL);
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);
320 /**************************************************************************//**
321 * Encode the event as a JSON event object according to AT&T's schema.
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)
334 /***************************************************************************/
335 /* Check preconditions. */
336 /***************************************************************************/
337 assert(jbuf != NULL);
338 assert(jbuf->json != NULL);
339 assert(jbuf->max_size > 0);
340 assert(event != NULL);
342 domain = evel_event_domain(event->event_domain);
343 priority = evel_event_priority(event->priority);
344 evel_json_open_named_object(jbuf, "commonEventHeader");
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);
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);
360 jbuf, "version", event->major_version, event->minor_version);
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);
372 evel_json_close_object(jbuf);
377 /**************************************************************************//**
378 * Free an event header.
380 * Free off the event header supplied. Will free all the contained allocated
383 * @note It does not free the header itself, since that may be part of a
385 *****************************************************************************/
386 void evel_free_header(EVENT_HEADER * const event)
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);
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);
413 /**************************************************************************//**
414 * Encode the event as a JSON event object according to AT&T's schema.
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,
423 EVENT_HEADER * event)
425 EVEL_JSON_BUFFER json_buffer;
426 EVEL_JSON_BUFFER * jbuf = &json_buffer;
427 EVEL_THROTTLE_SPEC * throttle_spec;
431 /***************************************************************************/
432 /* Get the latest throttle specification for the domain. */
433 /***************************************************************************/
434 throttle_spec = evel_get_throttle_spec(event->event_domain);
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");
443 switch (event->event_domain)
445 case EVEL_DOMAIN_HEARTBEAT:
446 evel_json_encode_header(jbuf, event);
449 case EVEL_DOMAIN_FAULT:
450 evel_json_encode_fault(jbuf, (EVENT_FAULT *)event);
453 case EVEL_DOMAIN_MEASUREMENT:
454 evel_json_encode_measurement(jbuf, (EVENT_MEASUREMENT *)event);
457 case EVEL_DOMAIN_MOBILE_FLOW:
458 evel_json_encode_mobile_flow(jbuf, (EVENT_MOBILE_FLOW *)event);
461 case EVEL_DOMAIN_REPORT:
462 evel_json_encode_report(jbuf, (EVENT_REPORT *)event);
465 case EVEL_DOMAIN_HEARTBEAT_FIELD:
466 evel_json_encode_hrtbt_field(jbuf, (EVENT_HEARTBEAT_FIELD *)event);
469 case EVEL_DOMAIN_SIPSIGNALING:
470 evel_json_encode_signaling(jbuf, (EVENT_SIGNALING *)event);
473 case EVEL_DOMAIN_STATE_CHANGE:
474 evel_json_encode_state_change(jbuf, (EVENT_STATE_CHANGE *)event);
477 case EVEL_DOMAIN_SYSLOG:
478 evel_json_encode_syslog(jbuf, (EVENT_SYSLOG *)event);
481 case EVEL_DOMAIN_OTHER:
482 evel_json_encode_other(jbuf, (EVENT_OTHER *)event);
485 case EVEL_DOMAIN_VOICE_QUALITY:
486 evel_json_encode_voice_quality(jbuf, (EVENT_VOICE_QUALITY *)event);
489 case EVEL_DOMAIN_THRESHOLD_CROSS:
490 evel_json_encode_threshold_cross(jbuf, (EVENT_THRESHOLD_CROSS *)event);
493 case EVEL_DOMAIN_INTERNAL:
495 EVEL_ERROR("Unexpected domain %d", event->event_domain);
499 evel_json_close_object(jbuf);
500 evel_json_close_object(jbuf);
502 /***************************************************************************/
504 /***************************************************************************/
505 assert(jbuf->depth == 0);
513 /**************************************************************************//**
514 * Initialize an event instance id.
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)
525 /***************************************************************************/
526 /* Check preconditions. */
527 /***************************************************************************/
528 assert(vfield != NULL);
529 assert(vendor_name != NULL);
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);
538 /***************************************************************************/
539 /* Initialize the optional parts. */
540 /***************************************************************************/
545 /**************************************************************************//**
546 * Set the Vendor module property of the Vendor.
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.
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
556 *****************************************************************************/
557 void evel_vendor_field_module_set(VENDOR_VNFNAME_FIELD * const vfield,
558 const char * const module_name)
562 /***************************************************************************/
563 /* Check preconditions. */
564 /***************************************************************************/
565 assert(vfield != NULL);
566 assert(module_name != NULL);
568 evel_set_option_string(&vfield->vfmodule, module_name, "Module name set");
573 /**************************************************************************//**
574 * Set the Vendor module property of the Vendor.
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.
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
584 *****************************************************************************/
585 void evel_vendor_field_vnfname_set(VENDOR_VNFNAME_FIELD * const vfield,
586 const char * const vnfname)
590 /***************************************************************************/
591 /* Check preconditions. */
592 /***************************************************************************/
593 assert(vfield != NULL);
594 assert(vnfname != NULL);
596 evel_set_option_string(&vfield->vnfname, vnfname, "Virtual Network Function name set");
601 /**************************************************************************//**
602 * Free an event instance id.
604 * @param vfield Pointer to the event vnfname_field being freed.
605 *****************************************************************************/
606 void evel_free_event_vendor_field(VENDOR_VNFNAME_FIELD * const vfield)
610 /***************************************************************************/
611 /* Check preconditions. */
612 /***************************************************************************/
613 assert(vfield->vendorname != NULL);
615 /***************************************************************************/
616 /* Free everything. */
617 /***************************************************************************/
618 evel_free_option_string(&vfield->vfmodule);
619 evel_free_option_string(&vfield->vnfname);
620 free(vfield->vendorname);
625 /**************************************************************************//**
626 * Encode the instance id as a JSON object according to AT&T's schema.
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)
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);
645 evel_json_open_named_object(jbuf, "vendorVnfNameFields");
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);
654 /***************************************************************************/
655 /* Optional fields. */
656 /***************************************************************************/
658 evel_json_close_object(jbuf);