Initial VES for DANOS vRouter
[demo.git] / vnfs / VESreporting_vFW5.0_DANOS / evel / evel-library / code / evel_library / evel_threshold_cross.c
1 /*************************************************************************//**
2  *
3  * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
4  *
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
10  *
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  ****************************************************************************/
18 /**************************************************************************//**
19  * @file
20  * Implementation of EVEL functions relating to the Threshold Cross Alerts.
21  *
22  *****************************************************************************/
23 #include <string.h>
24 #include <assert.h>
25 #include <stdlib.h>
26 #include "evel.h"       
27 #include "evel_internal.h"      
28 #include "evel_throttle.h"      
29
30
31 /**************************************************************************//**
32  * Create a new Threshold Crossing Alert event.
33  *
34  * @note    The mandatory fields on the TCA must be supplied to this factory
35  *          function and are immutable once set.  Optional fields have explicit
36  *          setter functions, but again values may only be set once so that the
37  *          TCA has immutable properties.
38  *
39  * @param event_name  Unique Event Name confirming Domain AsdcVnfModel Description
40  * @param event_id    A universal identifier of the event for: troubleshooting correlation, analysis, etc
41  * @param char* tcriticality   Performance Counter Criticality MAJ MIN,
42  * @param char* tname          Performance Counter Threshold name
43  * @param char* tthresholdCrossed  Counter Threshold crossed value
44  * @param char* tvalue             Counter actual value
45  * @param EVEL_EVENT_ACTION talertAction   Alert set continue or clear
46  * @param char*  talertDescription
47  * @param EVEL_ALERT_TYPE     talertType    Kind of anamoly
48  * @param unsigned long long  tcollectionTimestamp time at which alert was collected
49  * @param EVEL_SEVERITIES     teventSeverity  Severity of Alert
50  * @param unsigned long long  teventStartTimestamp Time when this alert started
51  *
52  * @returns pointer to the newly manufactured ::EVENT_THRESHOLD_CROSS.  If the
53  *          event is not used it must be released using
54  *          ::evel_free_threshold_cross
55  * @retval  NULL  Failed to create the event.
56  *****************************************************************************/
57 EVENT_THRESHOLD_CROSS * evel_new_threshold_cross(const char * ev_name, const char * ev_id,
58                            char *  tcriticality,
59                            char *  tname,
60                            char *  tthresholdCrossed,
61                            char *  tvalue,
62                            EVEL_EVENT_ACTION  talertAction,
63                            char *             talertDescription, 
64                            EVEL_ALERT_TYPE    talertType,
65                            unsigned long long  tcollectionTimestamp, 
66                            EVEL_SEVERITIES     teventSeverity,
67                            unsigned long long  teventStartTimestamp )
68 {
69         EVENT_THRESHOLD_CROSS * event = NULL;
70         EVEL_ENTER();
71
72         assert( tcriticality!= NULL );
73         assert( tname!= NULL );
74         assert( tthresholdCrossed != NULL );
75         assert( tvalue!= NULL );
76         assert( talertDescription != NULL );
77                 
78
79         /***************************************************************************/
80         /* Allocate the Threshold crossing event.                                  */
81         /***************************************************************************/
82         event = malloc(sizeof(EVENT_THRESHOLD_CROSS));
83         if (event == NULL)
84         {
85             log_error_state("Out of memory");
86             goto exit_label;
87         }
88         memset(event, 0, sizeof(EVENT_THRESHOLD_CROSS));
89         EVEL_DEBUG("New Threshold Cross event is at %lp", event);
90
91   /***************************************************************************/
92   /* Initialize the header & the threshold crossing fields.                  */
93   /***************************************************************************/
94   evel_init_header_nameid(&event->header,ev_name,ev_id);
95   event->header.event_domain = EVEL_DOMAIN_THRESHOLD_CROSS;
96   event->major_version = EVEL_THRESHOLD_CROSS_MAJOR_VERSION;
97   event->minor_version = EVEL_THRESHOLD_CROSS_MINOR_VERSION;
98
99
100   event->additionalParameters.criticality = strdup(tcriticality);
101   event->additionalParameters.name = strdup(tname);
102   event->additionalParameters.thresholdCrossed = strdup(tthresholdCrossed);
103   event->additionalParameters.value = strdup(tvalue);
104   event->alertAction      =  talertAction;
105   event->alertDescription =  strdup(talertDescription); 
106   event->alertType        =  talertType;
107   event->collectionTimestamp =   tcollectionTimestamp; 
108   event->eventSeverity       =   teventSeverity;
109   event->eventStartTimestamp =   teventStartTimestamp;
110
111   evel_init_option_string(&event->alertValue);
112   evel_init_option_string(&event->dataCollector);
113   evel_init_option_string(&event->elementType);
114   evel_init_option_string(&event->interfaceName);
115   evel_init_option_string(&event->networkService);
116   evel_init_option_string(&event->possibleRootCause);
117   dlist_initialize(&event->additional_info);
118   dlist_initialize(&event->alertidList);
119
120 exit_label:
121
122   EVEL_EXIT();
123   return event;
124
125 }
126
127
128 /**************************************************************************//**
129  * Set the Event Type property of the TC Alert.
130  *
131  * @note  The property is treated as immutable: it is only valid to call
132  *        the setter once.  However, we don't assert if the caller tries to
133  *        overwrite, just ignoring the update instead.
134  *
135  * @param type        The Event Type to be set. ASCIIZ string. The caller
136  *                    does not need to preserve the value once the function
137  *                    returns.
138  *****************************************************************************/
139 void evel_threshold_cross_type_set(EVENT_THRESHOLD_CROSS * const event,char *  type)
140 {
141   EVEL_ENTER();
142
143   /***************************************************************************/
144   /* Check preconditions and call evel_header_type_set.                      */
145   /***************************************************************************/
146   assert(type!=NULL);
147   assert(event->header.event_domain == EVEL_DOMAIN_THRESHOLD_CROSS);
148   evel_header_type_set(&event->header, type);
149
150   EVEL_EXIT();
151 }
152
153 /**************************************************************************//**
154  * Add an optional additional alertid value to Alert.
155  *
156  *****************************************************************************/
157 void evel_threshold_cross_alertid_add(EVENT_THRESHOLD_CROSS * const event,char *  alertid)
158 {
159   char *alid=NULL;
160   EVEL_ENTER();
161
162   /***************************************************************************/
163   /* Check preconditions.                                                    */
164   /***************************************************************************/
165   assert(event != NULL);
166   assert(event->header.event_domain == EVEL_DOMAIN_THRESHOLD_CROSS);
167   assert(alertid != NULL);
168
169   EVEL_DEBUG("Adding AlertId=%s", alertid);
170   alid = strdup(alertid);
171   assert(alid != NULL);
172
173   dlist_push_last(&event->alertidList, alid);
174
175   EVEL_EXIT();
176 }
177         
178 /**************************************************************************//**
179  * Add an optional additional value name/value pair to the Alert.
180  *
181  * The name and value are NULL delimited ASCII strings.  The library takes
182  * a copy so the caller does not have to preserve values after the function
183  * returns.
184  * @param name      ASCIIZ string with the attribute's name.  The caller
185  *                  does not need to preserve the value once the function
186  *                  returns.
187  * @param value     ASCIIZ string with the attribute's value.  The caller
188  *                  does not need to preserve the value once the function
189  *                  returns.
190  *****************************************************************************/
191 void evel_threshold_cross_addl_info_add(EVENT_THRESHOLD_CROSS * const event, const char *  name, const char *  value)
192 {
193   OTHER_FIELD * nv_pair = NULL;
194
195   EVEL_ENTER();
196
197   /***************************************************************************/
198   /* Check preconditions.                                                    */
199   /***************************************************************************/
200   assert(event != NULL);
201   assert(event->header.event_domain == EVEL_DOMAIN_THRESHOLD_CROSS);
202   assert(name != NULL);
203   assert(value != NULL);
204
205   EVEL_DEBUG("Adding name=%s value=%s", name, value);
206   nv_pair = malloc(sizeof(OTHER_FIELD));
207   assert(nv_pair != NULL);
208   nv_pair->name = strdup(name);
209   nv_pair->value = strdup(value);
210   assert(nv_pair->name != NULL);
211   assert(nv_pair->value != NULL);
212
213   dlist_push_last(&event->additional_info, nv_pair);
214
215   EVEL_EXIT();
216 }
217
218
219 /**************************************************************************//**
220  * Free a Signaling event.
221  *
222  * Free off the event supplied.  Will free all the contained allocated memory.
223  *
224  * @note It does not free the event itself, since that may be part of a larger
225  * structure.
226  *****************************************************************************/
227 void evel_free_threshold_cross(EVENT_THRESHOLD_CROSS * const event)
228 {
229   OTHER_FIELD * addl_info = NULL;
230   char *ptr;
231   EVEL_ENTER();
232
233   /***************************************************************************/
234   /* Check preconditions.  As an internal API we don't allow freeing NULL    */
235   /* events as we do on the API.                                      */
236   /***************************************************************************/
237   assert(event != NULL);
238   assert(event->header.event_domain == EVEL_DOMAIN_THRESHOLD_CROSS);
239
240   /***************************************************************************/
241   /* Free all internal strings then the header itself.                       */
242   /***************************************************************************/
243   addl_info = dlist_pop_last(&event->additional_info);
244   while (addl_info != NULL)
245   {
246     EVEL_DEBUG("Freeing Additional Info (%s, %s)",
247                addl_info->name,
248                addl_info->value);
249     free(addl_info->name);
250     free(addl_info->value);
251     free(addl_info);
252     addl_info = dlist_pop_last(&event->additional_info);
253   }
254   ptr = dlist_pop_last(&event->alertidList);
255   while (ptr != NULL)
256   {
257     free(ptr);
258     ptr = dlist_pop_last(&event->alertidList);
259   }
260
261   free(event->additionalParameters.criticality);
262   free(event->additionalParameters.name);
263   free(event->additionalParameters.thresholdCrossed);
264   free(event->additionalParameters.value);
265   free(event->alertDescription); 
266
267   evel_free_option_string(&event->alertValue);
268   evel_free_option_string(&event->dataCollector);
269   evel_free_option_string(&event->elementType);
270   evel_free_option_string(&event->interfaceName);
271   evel_free_option_string(&event->networkService);
272   evel_free_option_string(&event->possibleRootCause);
273   evel_free_header(&event->header);
274
275   EVEL_EXIT();
276 }
277
278   /**************************************************************************//**
279    * Set the TCA probable Root cause.
280    *
281    * @param sheader     Possible root cause to Threshold
282    *****************************************************************************/
283   void evel_threshold_cross_possible_rootcause_set(EVENT_THRESHOLD_CROSS * const event, char *  sheader)
284   {
285     EVEL_ENTER();
286
287     /***************************************************************************/
288     /* Check preconditions.                                                    */
289     /***************************************************************************/
290     assert(event->header.event_domain == EVEL_DOMAIN_THRESHOLD_CROSS);
291     assert(sheader != NULL);
292
293     evel_set_option_string(&event->possibleRootCause,
294                          sheader,
295                          "Rootcause value");
296
297     EVEL_EXIT();
298   }
299     
300   /**************************************************************************//**
301    * Set the TCA networking cause.
302    *
303    * @param sheader     Possible networking service value to Threshold
304    *****************************************************************************/
305   void evel_threshold_cross_networkservice_set(EVENT_THRESHOLD_CROSS * const event, char *  sheader)
306   {
307             EVEL_ENTER();
308
309     /***************************************************************************/
310     /* Check preconditions.                                                    */
311     /***************************************************************************/
312     assert(event->header.event_domain == EVEL_DOMAIN_THRESHOLD_CROSS);
313     assert(sheader != NULL);
314
315     evel_set_option_string(&event->networkService,
316                          sheader,
317                          "Networking service value");
318
319             EVEL_EXIT();
320   }
321     
322   /**************************************************************************//**
323    * Set the TCA Interface name.
324    *
325    * @param sheader     Interface name to threshold
326    *****************************************************************************/
327   void evel_threshold_cross_interfacename_set(EVENT_THRESHOLD_CROSS * const event,char *  sheader)
328   {
329             EVEL_ENTER();
330
331             /***************************************************************************/
332             /* Check preconditions.                                                    */
333             /***************************************************************************/
334             assert(event->header.event_domain == EVEL_DOMAIN_THRESHOLD_CROSS);
335             assert(sheader != NULL);
336
337             evel_set_option_string(&event->interfaceName,
338                                    sheader,
339                                    "TCA Interface name");
340             EVEL_EXIT();
341   }
342     
343   /**************************************************************************//**
344    * Set the TCA Data element type.
345    *
346    * @param sheader     element type of Threshold
347    *****************************************************************************/
348   void evel_threshold_cross_data_elementtype_set(EVENT_THRESHOLD_CROSS * const event,char *  sheader)
349   {
350             EVEL_ENTER();
351
352             /***************************************************************************/
353             /* Check preconditions.                                                    */
354             /***************************************************************************/
355             assert(event->header.event_domain == EVEL_DOMAIN_THRESHOLD_CROSS);
356             assert(sheader != NULL);
357
358             evel_set_option_string(&event->elementType,
359                                    sheader,
360                                    "TCA Element type value");
361             EVEL_EXIT();
362   }
363
364   /**************************************************************************//**
365    * Set the TCA Data collector value.
366    *
367    * @param sheader     Data collector value
368    *****************************************************************************/
369   void evel_threshold_cross_data_collector_set(EVENT_THRESHOLD_CROSS * const event,char *  sheader)
370   {
371             EVEL_ENTER();
372
373             /***************************************************************************/
374             /* Check preconditions.                                                    */
375             /***************************************************************************/
376             assert(event->header.event_domain == EVEL_DOMAIN_THRESHOLD_CROSS);
377             assert(sheader != NULL);
378
379             evel_set_option_string(&event->dataCollector,
380                                    sheader,
381                                    "Datacollector value");
382             EVEL_EXIT();
383   }
384     
385     
386     
387   /**************************************************************************//**
388    * Set the TCA alert value.
389    *
390    * @param sheader     Possible alert value
391    *****************************************************************************/
392   void evel_threshold_cross_alertvalue_set(EVENT_THRESHOLD_CROSS * const event,char *  sheader)
393   {
394             EVEL_ENTER();
395
396             /***************************************************************************/
397             /* Check preconditions.                                                    */
398             /***************************************************************************/
399             assert(event->header.event_domain == EVEL_DOMAIN_THRESHOLD_CROSS);
400             assert(sheader != NULL);
401
402             evel_set_option_string(&event->alertValue,
403                                    sheader,
404                                    "Alert value");
405             EVEL_EXIT();
406   }
407
408 /**************************************************************************//**
409  * Encode the Mobile Flow GTP Per Flow Metrics as a JSON object.
410  *
411  * @param jbuf          Pointer to working ::EVEL_JSON_BUFFER.
412  * @param metrics       Pointer to the ::EVENT_MOBILE_FLOW to encode.
413  * @returns Number of bytes actually written.
414  *****************************************************************************/
415 void evel_json_encode_perf_counter( EVEL_JSON_BUFFER * jbuf, PERF_COUNTER *pcounter)
416 {
417   EVEL_ENTER();
418
419   /***************************************************************************/
420   /* Check preconditions.                                                    */
421   /***************************************************************************/
422   assert(jbuf != NULL);
423   assert(pcounter != NULL);
424
425   evel_json_open_named_object(jbuf, "additionalParameters");
426
427   /***************************************************************************/
428   /* Mandatory parameters.                                                   */
429   /***************************************************************************/
430   evel_enc_kv_string(jbuf, "criticality", pcounter->criticality);
431   evel_enc_kv_string(jbuf, "name", pcounter->name);
432   evel_enc_kv_string(jbuf, "thresholdCrossed", pcounter->name);
433   evel_enc_kv_string(jbuf, "value", pcounter->value);
434
435   evel_json_close_object(jbuf);
436
437   EVEL_EXIT();
438 }
439
440 /**************************************************************************//**
441  * Encode the Signaling in JSON according to AT&T's schema for the
442  * event type.
443  *
444  * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
445  * @param event         Pointer to the ::EVENT_HEADER to encode.
446  *****************************************************************************/
447 void evel_json_encode_threshold_cross(EVEL_JSON_BUFFER * const jbuf,
448                                 EVENT_THRESHOLD_CROSS * const event)
449 {
450   OTHER_FIELD * nv_pair = NULL;
451   DLIST_ITEM * dlist_item = NULL;
452
453   EVEL_ENTER();
454
455   /***************************************************************************/
456   /* Check preconditions.                                                    */
457   /***************************************************************************/
458   assert(event != NULL);
459   assert(event->header.event_domain == EVEL_DOMAIN_THRESHOLD_CROSS);
460
461   evel_json_encode_header(jbuf, &event->header);
462   evel_json_open_named_object(jbuf, "thresholdCrossingAlert");
463
464   /***************************************************************************/
465   /* Mandatory fields                                                        */
466   /***************************************************************************/
467   evel_json_encode_perf_counter(jbuf, &event->additionalParameters);
468   evel_enc_kv_int(jbuf, "alertAction", event->alertAction);
469   evel_enc_kv_string(jbuf, "alertDescription", event->alertDescription);
470   evel_enc_kv_int(jbuf, "alertType", event->alertType);
471   evel_enc_kv_ull(
472     jbuf, "collectionTimestamp", event->collectionTimestamp);
473   evel_enc_kv_int(jbuf, "eventSeverity", event->eventSeverity);
474   evel_enc_kv_ull(
475     jbuf, "eventStartTimestamp", event->eventStartTimestamp);
476
477   /***************************************************************************/
478   /* Optional fields                                                         */
479   /***************************************************************************/
480   evel_enc_kv_opt_string(jbuf, "alertValue", &event->alertValue);
481   evel_enc_kv_opt_string(jbuf, "dataCollector", &event->dataCollector);
482   evel_enc_kv_opt_string(jbuf, "elementType", &event->elementType);
483   evel_enc_kv_opt_string(jbuf, "interfaceName", &event->interfaceName);
484   evel_enc_kv_opt_string(jbuf, "networkService", &event->networkService);
485   evel_enc_kv_opt_string(jbuf, "possibleRootCause", &event->possibleRootCause);
486
487   /***************************************************************************/
488   /* Checkpoint, so that we can wind back if all fields are suppressed.      */
489   /***************************************************************************/
490   evel_json_checkpoint(jbuf);
491   if (evel_json_open_opt_named_list(jbuf, "additionalFields"))
492   {
493     bool added = false;
494
495     dlist_item = dlist_get_first(&event->additional_info);
496     while (dlist_item != NULL)
497     {
498       nv_pair = (OTHER_FIELD *) dlist_item->item;
499       assert(nv_pair != NULL);
500
501       if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
502                                           "additionalFields",
503                                           nv_pair->name))
504       {
505         evel_json_open_object(jbuf);
506         evel_enc_kv_string(jbuf, "name", nv_pair->name);
507         evel_enc_kv_string(jbuf, "value", nv_pair->value);
508         evel_json_close_object(jbuf);
509         added = true;
510       }
511       dlist_item = dlist_get_next(dlist_item);
512     }
513     evel_json_close_list(jbuf);
514
515     /*************************************************************************/
516     /* If we've not written anything, rewind to before we opened the list.   */
517     /*************************************************************************/
518     if (!added)
519     {
520       evel_json_rewind(jbuf);
521     }
522   }
523   evel_enc_version(jbuf,
524                    "thresholdCrossingFieldsVersion",
525                    event->major_version,
526                    event->minor_version);
527
528   evel_json_close_object(jbuf);
529
530   EVEL_EXIT();
531 }
532