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
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;
56 /**************************************************************************//**
57 * Create a new heartbeat event.
59 * @note that the heartbeat is just a "naked" commonEventHeader!
61 * @returns pointer to the newly manufactured ::EVENT_HEADER. If the event is
62 * not used it must be released using ::evel_free_event
63 * @retval NULL Failed to create the event.
64 *****************************************************************************/
65 EVENT_HEADER * evel_new_heartbeat()
67 EVENT_HEADER * heartbeat = NULL;
70 /***************************************************************************/
71 /* Allocate the header. */
72 /***************************************************************************/
73 heartbeat = malloc(sizeof(EVENT_HEADER));
74 if (heartbeat == NULL)
76 log_error_state("Out of memory");
79 memset(heartbeat, 0, sizeof(EVENT_HEADER));
81 /***************************************************************************/
82 /* Initialize the header. Get a new event sequence number. Note that if */
83 /* any memory allocation fails in here we will fail gracefully because */
84 /* everything downstream can cope with NULLs. */
85 /***************************************************************************/
86 evel_init_header(heartbeat,"Heartbeat");
87 evel_force_option_string(&heartbeat->event_type, "Autonomous heartbeat");
94 /**************************************************************************//**
95 * Initialize a newly created event header.
97 * @param header Pointer to the header being initialized.
98 *****************************************************************************/
99 void evel_init_header(EVENT_HEADER * const header,const char *const eventname)
101 char scratchpad[EVEL_MAX_STRING_LEN + 1] = {0};
106 assert(header != NULL);
108 gettimeofday(&tv, NULL);
110 /***************************************************************************/
111 /* Initialize the header. Get a new event sequence number. Note that if */
112 /* any memory allocation fails in here we will fail gracefully because */
113 /* everything downstream can cope with NULLs. */
114 /***************************************************************************/
115 header->event_domain = EVEL_DOMAIN_HEARTBEAT;
116 snprintf(scratchpad, EVEL_MAX_STRING_LEN, "%d", event_sequence);
117 header->event_id = strdup(scratchpad);
118 if( eventname == NULL )
119 header->event_name = strdup(functional_role);
121 header->event_name = strdup(eventname);
122 header->last_epoch_microsec = tv.tv_usec + 1000000 * tv.tv_sec;
123 header->priority = EVEL_PRIORITY_NORMAL;
124 header->reporting_entity_name = strdup(openstack_vm_name());
125 header->source_name = strdup(openstack_vm_name());
126 header->sequence = event_sequence;
127 header->start_epoch_microsec = header->last_epoch_microsec;
128 header->major_version = EVEL_HEADER_MAJOR_VERSION;
129 header->minor_version = EVEL_HEADER_MINOR_VERSION;
132 /***************************************************************************/
133 /* Optional parameters. */
134 /***************************************************************************/
135 evel_init_option_string(&header->event_type);
136 evel_init_option_string(&header->nfcnaming_code);
137 evel_init_option_string(&header->nfnaming_code);
138 evel_force_option_string(&header->reporting_entity_id, openstack_vm_uuid());
139 evel_force_option_string(&header->source_id, openstack_vm_uuid());
140 evel_init_option_intheader(&header->internal_field);
145 /**************************************************************************//**
146 * Set the Event Type property of the event header.
148 * @note The property is treated as immutable: it is only valid to call
149 * the setter once. However, we don't assert if the caller tries to
150 * overwrite, just ignoring the update instead.
152 * @param header Pointer to the ::EVENT_HEADER.
153 * @param type The Event Type to be set. ASCIIZ string. The caller
154 * does not need to preserve the value once the function
156 *****************************************************************************/
157 void evel_header_type_set(EVENT_HEADER * const header,
158 const char * const type)
162 /***************************************************************************/
163 /* Check preconditions. */
164 /***************************************************************************/
165 assert(header != NULL);
166 assert(type != NULL);
168 evel_set_option_string(&header->event_type, type, "Event Type");
173 /**************************************************************************//**
174 * Set the Start Epoch property of the event header.
176 * @note The Start Epoch defaults to the time of event creation.
178 * @param header Pointer to the ::EVENT_HEADER.
179 * @param start_epoch_microsec
180 * The start epoch to set, in microseconds.
181 *****************************************************************************/
182 void evel_start_epoch_set(EVENT_HEADER * const header,
183 const unsigned long long start_epoch_microsec)
187 /***************************************************************************/
188 /* Check preconditions and assign the new value. */
189 /***************************************************************************/
190 assert(header != NULL);
191 header->start_epoch_microsec = start_epoch_microsec;
196 /**************************************************************************//**
197 * Set the Last Epoch property of the event header.
199 * @note The Last Epoch defaults to the time of event creation.
201 * @param header Pointer to the ::EVENT_HEADER.
202 * @param last_epoch_microsec
203 * The last epoch to set, in microseconds.
204 *****************************************************************************/
205 void evel_last_epoch_set(EVENT_HEADER * const header,
206 const unsigned long long last_epoch_microsec)
210 /***************************************************************************/
211 /* Check preconditions and assign the new value. */
212 /***************************************************************************/
213 assert(header != NULL);
214 header->last_epoch_microsec = last_epoch_microsec;
219 /**************************************************************************//**
220 * Set the NFC Naming code property of the event header.
222 * @param header Pointer to the ::EVENT_HEADER.
223 * @param nfcnamingcode String
224 *****************************************************************************/
225 void evel_nfcnamingcode_set(EVENT_HEADER * const header,
226 const char * const nfcnam)
230 /***************************************************************************/
231 /* Check preconditions and assign the new value. */
232 /***************************************************************************/
233 assert(header != NULL);
234 assert(nfcnam != NULL);
235 evel_set_option_string(&header->nfcnaming_code, nfcnam, "NFC Naming Code");
240 /**************************************************************************//**
241 * Set the NF Naming code property of the event header.
243 * @param header Pointer to the ::EVENT_HEADER.
244 * @param nfnamingcode String
245 *****************************************************************************/
246 void evel_nfnamingcode_set(EVENT_HEADER * const header,
247 const char * const nfnam)
251 /***************************************************************************/
252 /* Check preconditions and assign the new value. */
253 /***************************************************************************/
254 assert(header != NULL);
255 assert(nfnam != NULL);
256 evel_set_option_string(&header->nfnaming_code, nfnam, "NF Naming Code");
262 /**************************************************************************//**
263 * Set the Reporting Entity Name property of the event header.
265 * @note The Reporting Entity Name defaults to the OpenStack VM Name.
267 * @param header Pointer to the ::EVENT_HEADER.
268 * @param entity_name The entity name to set.
269 *****************************************************************************/
270 void evel_reporting_entity_name_set(EVENT_HEADER * const header,
271 const char * const entity_name)
275 /***************************************************************************/
276 /* Check preconditions and assign the new value. */
277 /***************************************************************************/
278 assert(header != NULL);
279 assert(entity_name != NULL);
280 assert(header->reporting_entity_name != NULL);
282 /***************************************************************************/
283 /* Free the previously allocated memory and replace it with a copy of the */
285 /***************************************************************************/
286 free(header->reporting_entity_name);
287 header->reporting_entity_name = strdup(entity_name);
292 /**************************************************************************//**
293 * Set the Reporting Entity Id property of the event header.
295 * @note The Reporting Entity Id defaults to the OpenStack VM UUID.
297 * @param header Pointer to the ::EVENT_HEADER.
298 * @param entity_id The entity id to set.
299 *****************************************************************************/
300 void evel_reporting_entity_id_set(EVENT_HEADER * const header,
301 const char * const entity_id)
305 /***************************************************************************/
306 /* Check preconditions and assign the new value. */
307 /***************************************************************************/
308 assert(header != NULL);
309 assert(entity_id != NULL);
311 /***************************************************************************/
312 /* Free the previously allocated memory and replace it with a copy of the */
313 /* provided one. Note that evel_force_option_string strdups entity_id. */
314 /***************************************************************************/
315 evel_free_option_string(&header->reporting_entity_id);
316 evel_force_option_string(&header->reporting_entity_id, entity_id);
321 /**************************************************************************//**
322 * Encode the event as a JSON event object according to AT&T's schema.
324 * @param jbuf Pointer to the ::EVEL_JSON_BUFFER to encode into.
325 * @param event Pointer to the ::EVENT_HEADER to encode.
326 *****************************************************************************/
327 void evel_json_encode_header(EVEL_JSON_BUFFER * jbuf,
328 EVENT_HEADER * event)
335 /***************************************************************************/
336 /* Check preconditions. */
337 /***************************************************************************/
338 assert(jbuf != NULL);
339 assert(jbuf->json != NULL);
340 assert(jbuf->max_size > 0);
341 assert(event != NULL);
343 domain = evel_event_domain(event->event_domain);
344 priority = evel_event_priority(event->priority);
345 evel_json_open_named_object(jbuf, "commonEventHeader");
347 /***************************************************************************/
348 /* Mandatory fields. */
349 /***************************************************************************/
350 evel_enc_kv_string(jbuf, "domain", domain);
351 evel_enc_kv_string(jbuf, "eventId", event->event_id);
352 evel_enc_kv_string(jbuf, "eventName", event->event_name);
353 evel_enc_kv_ull(jbuf, "lastEpochMicrosec", event->last_epoch_microsec);
354 evel_enc_kv_string(jbuf, "priority", priority);
356 jbuf, "reportingEntityName", event->reporting_entity_name);
357 evel_enc_kv_int(jbuf, "sequence", event->sequence);
358 evel_enc_kv_string(jbuf, "sourceName", event->source_name);
359 evel_enc_kv_ull(jbuf, "startEpochMicrosec", event->start_epoch_microsec);
361 jbuf, "version", event->major_version, event->minor_version);
363 /***************************************************************************/
364 /* Optional fields. */
365 /***************************************************************************/
366 evel_enc_kv_opt_string(jbuf, "eventType", &event->event_type);
367 evel_enc_kv_opt_string(
368 jbuf, "reportingEntityId", &event->reporting_entity_id);
369 evel_enc_kv_opt_string(jbuf, "sourceId", &event->source_id);
370 evel_enc_kv_opt_string(jbuf, "nfcNamingCode", &event->nfcnaming_code);
371 evel_enc_kv_opt_string(jbuf, "nfNamingCode", &event->nfnaming_code);
373 evel_json_close_object(jbuf);
378 /**************************************************************************//**
379 * Free an event header.
381 * Free off the event header supplied. Will free all the contained allocated
384 * @note It does not free the header itself, since that may be part of a
386 *****************************************************************************/
387 void evel_free_header(EVENT_HEADER * const event)
391 /***************************************************************************/
392 /* Check preconditions. As an internal API we don't allow freeing NULL */
393 /* events as we do on the public API. */
394 /***************************************************************************/
395 assert(event != NULL);
397 /***************************************************************************/
398 /* Free all internal strings. */
399 /***************************************************************************/
400 free(event->event_id);
401 evel_free_option_string(&event->event_type);
402 free(event->event_name);
403 evel_free_option_string(&event->reporting_entity_id);
404 free(event->reporting_entity_name);
405 evel_free_option_string(&event->source_id);
406 evel_free_option_string(&event->nfcnaming_code);
407 evel_free_option_string(&event->nfnaming_code);
408 evel_free_option_intheader(&event->internal_field);
409 free(event->source_name);
414 /**************************************************************************//**
415 * Encode the event as a JSON event object according to AT&T's schema.
417 * @param json Pointer to where to store the JSON encoded data.
418 * @param max_size Size of storage available in json_body.
419 * @param event Pointer to the ::EVENT_HEADER to encode.
420 * @returns Number of bytes actually written.
421 *****************************************************************************/
422 int evel_json_encode_event(char * json,
424 EVENT_HEADER * event)
426 EVEL_JSON_BUFFER json_buffer;
427 EVEL_JSON_BUFFER * jbuf = &json_buffer;
428 EVEL_THROTTLE_SPEC * throttle_spec;
432 /***************************************************************************/
433 /* Get the latest throttle specification for the domain. */
434 /***************************************************************************/
435 throttle_spec = evel_get_throttle_spec(event->event_domain);
437 /***************************************************************************/
438 /* Initialize the JSON_BUFFER and open the top-level objects. */
439 /***************************************************************************/
440 evel_json_buffer_init(jbuf, json, max_size, throttle_spec);
441 evel_json_open_object(jbuf);
442 evel_json_open_named_object(jbuf, "event");
444 switch (event->event_domain)
446 case EVEL_DOMAIN_HEARTBEAT:
447 evel_json_encode_header(jbuf, event);
450 case EVEL_DOMAIN_FAULT:
451 evel_json_encode_fault(jbuf, (EVENT_FAULT *)event);
454 case EVEL_DOMAIN_MEASUREMENT:
455 evel_json_encode_measurement(jbuf, (EVENT_MEASUREMENT *)event);
458 case EVEL_DOMAIN_MOBILE_FLOW:
459 evel_json_encode_mobile_flow(jbuf, (EVENT_MOBILE_FLOW *)event);
462 case EVEL_DOMAIN_REPORT:
463 evel_json_encode_report(jbuf, (EVENT_REPORT *)event);
466 case EVEL_DOMAIN_HEARTBEAT_FIELD:
467 evel_json_encode_hrtbt_field(jbuf, (EVENT_HEARTBEAT_FIELD *)event);
470 case EVEL_DOMAIN_SIPSIGNALING:
471 evel_json_encode_signaling(jbuf, (EVENT_SIGNALING *)event);
474 case EVEL_DOMAIN_STATE_CHANGE:
475 evel_json_encode_state_change(jbuf, (EVENT_STATE_CHANGE *)event);
478 case EVEL_DOMAIN_SYSLOG:
479 evel_json_encode_syslog(jbuf, (EVENT_SYSLOG *)event);
482 case EVEL_DOMAIN_OTHER:
483 evel_json_encode_other(jbuf, (EVENT_OTHER *)event);
486 case EVEL_DOMAIN_VOICE_QUALITY:
487 evel_json_encode_other(jbuf, (EVENT_VOICE_QUALITY *)event);
490 case EVEL_DOMAIN_INTERNAL:
492 EVEL_ERROR("Unexpected domain %d", event->event_domain);
496 evel_json_close_object(jbuf);
497 evel_json_close_object(jbuf);
499 /***************************************************************************/
501 /***************************************************************************/
502 assert(jbuf->depth == 0);
510 /**************************************************************************//**
511 * Initialize an event instance id.
513 * @param vfield Pointer to the event vnfname field being initialized.
514 * @param vendor_id The vendor id to encode in the event instance id.
515 * @param event_id The event id to encode in the event instance id.
516 *****************************************************************************/
517 void evel_init_vendor_field(VENDOR_VNFNAME_FIELD * const vfield,
518 const char * const vendor_name)
522 /***************************************************************************/
523 /* Check preconditions. */
524 /***************************************************************************/
525 assert(vfield != NULL);
526 assert(vendor_name != NULL);
528 /***************************************************************************/
529 /* Store the mandatory parts. */
530 /***************************************************************************/
531 vfield->vendorname = strdup(vendor_name);
532 evel_init_option_string(&vfield->vfmodule);
533 evel_init_option_string(&vfield->vnfname);
535 /***************************************************************************/
536 /* Initialize the optional parts. */
537 /***************************************************************************/
542 /**************************************************************************//**
543 * Set the Vendor module property of the Vendor.
545 * @note The property is treated as immutable: it is only valid to call
546 * the setter once. However, we don't assert if the caller tries to
547 * overwrite, just ignoring the update instead.
549 * @param vfield Pointer to the Vendor field.
550 * @param module_name The module name to be set. ASCIIZ string. The caller
551 * does not need to preserve the value once the function
553 *****************************************************************************/
554 void evel_vendor_field_module_set(VENDOR_VNFNAME_FIELD * const vfield,
555 const char * const module_name)
559 /***************************************************************************/
560 /* Check preconditions. */
561 /***************************************************************************/
562 assert(vfield != NULL);
563 assert(module_name != NULL);
565 evel_set_option_string(&vfield->vfmodule, module_name, "Module name set");
570 /**************************************************************************//**
571 * Set the Vendor module property of the Vendor.
573 * @note The property is treated as immutable: it is only valid to call
574 * the setter once. However, we don't assert if the caller tries to
575 * overwrite, just ignoring the update instead.
577 * @param vfield Pointer to the Vendor field.
578 * @param module_name The module name to be set. ASCIIZ string. The caller
579 * does not need to preserve the value once the function
581 *****************************************************************************/
582 void evel_vendor_field_vnfname_set(VENDOR_VNFNAME_FIELD * const vfield,
583 const char * const vnfname)
587 /***************************************************************************/
588 /* Check preconditions. */
589 /***************************************************************************/
590 assert(vfield != NULL);
591 assert(vnfname != NULL);
593 evel_set_option_string(&vfield->vnfname, vnfname, "Virtual Network Function name set");
598 /**************************************************************************//**
599 * Free an event instance id.
601 * @param vfield Pointer to the event vnfname_field being freed.
602 *****************************************************************************/
603 void evel_free_event_vendor_field(VENDOR_VNFNAME_FIELD * const vfield)
607 /***************************************************************************/
608 /* Check preconditions. */
609 /***************************************************************************/
610 assert(vfield->vendorname != NULL);
612 /***************************************************************************/
613 /* Free everything. */
614 /***************************************************************************/
615 evel_free_option_string(&vfield->vfmodule);
616 evel_free_option_string(&vfield->vnfname);
617 free(vfield->vendorname);
622 /**************************************************************************//**
623 * Encode the instance id as a JSON object according to AT&T's schema.
625 * @param jbuf Pointer to the ::EVEL_JSON_BUFFER to encode into.
626 * @param vfield Pointer to the ::VENDOR_VNFNAME_FIELD to encode.
627 *****************************************************************************/
628 void evel_json_encode_vendor_field(EVEL_JSON_BUFFER * jbuf,
629 VENDOR_VNFNAME_FIELD * vfield)
633 /***************************************************************************/
634 /* Check preconditions. */
635 /***************************************************************************/
636 assert(jbuf != NULL);
637 assert(jbuf->json != NULL);
638 assert(jbuf->max_size > 0);
639 assert(vfield != NULL);
640 assert(vfield->vendorname != NULL);
642 evel_json_open_named_object(jbuf, "vendorVnfNamedFields");
644 /***************************************************************************/
645 /* Mandatory fields. */
646 /***************************************************************************/
647 evel_enc_kv_string(jbuf, "vendorName", vfield->vendorname);
648 evel_enc_kv_opt_string(jbuf, "vfModuleName", &vfield->vfmodule);
649 evel_enc_kv_opt_string(jbuf, "vnfName", &vfield->vnfname);
651 /***************************************************************************/
652 /* Optional fields. */
653 /***************************************************************************/
655 evel_json_close_object(jbuf);