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