Initial VES for DANOS vRouter
[demo.git] / vnfs / VESreporting_vFW5.0_DANOS / evel / evel-library / code / evel_library / evel_heartbeat_fields.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 /**************************************************************************//**
20  * @file
21  * Implementation of EVEL functions relating to Heartbeat fields.
22  *
23  ****************************************************************************/
24
25 #include <string.h>
26 #include <assert.h>
27 #include <stdlib.h>
28
29 #include "evel.h"
30 #include "evel_throttle.h"
31
32 /**************************************************************************//**
33  * Create a new Heartbeat fields event.
34  *
35  * @note    The mandatory fields on the Heartbeat fields must be supplied to
36  *          this factory function and are immutable once set.  Optional fields
37  *          have explicit setter functions, but again values may only be set
38  *          once so that the event has immutable properties.
39  * @param ev_name  Unique Event Name confirming Domain AsdcModel Description
40  * @param ev_id    A universal identifier of the event for: troubleshooting correlation, analysis, etc
41  * @param interval    heartbeat interval
42  * @returns pointer to the newly manufactured ::EVENT_HEARTBEAT_FIELD.  If the event
43  *          is not used (i.e. posted) it must be released using
44  *          ::evel_free_hrtbt_field.
45  * @retval  NULL  Failed to create the event.
46  *****************************************************************************/
47 EVENT_HEARTBEAT_FIELD * evel_new_heartbeat_field(int interval,const char* ev_name, const char *ev_id)
48 {
49   EVENT_HEARTBEAT_FIELD * event = NULL;
50
51   EVEL_ENTER();
52
53   /***************************************************************************/
54   /* Check preconditions.                                                    */
55   /***************************************************************************/
56   assert(interval > 0);
57
58   /***************************************************************************/
59   /* Allocate the Heartbeat fields event.                                           */
60   /***************************************************************************/
61   event = malloc(sizeof(EVENT_HEARTBEAT_FIELD));
62   if (event == NULL)
63   {
64     log_error_state("Out of memory");
65     goto exit_label;
66   }
67   memset(event, 0, sizeof(EVENT_HEARTBEAT_FIELD));
68   EVEL_DEBUG("New Heartbeat fields event is at %lp", event);
69
70   /***************************************************************************/
71   /* Initialize the header & the Heartbeat fields fields.                           */
72   /***************************************************************************/
73   evel_init_header_nameid(&event->header,ev_name,ev_id);
74   event->header.event_domain = EVEL_DOMAIN_HEARTBEAT_FIELD;
75   event->major_version = EVEL_HEARTBEAT_FIELD_MAJOR_VERSION;
76   event->minor_version = EVEL_HEARTBEAT_FIELD_MINOR_VERSION;
77
78   event->heartbeat_interval = interval;
79   dlist_initialize(&event->additional_info);
80
81 exit_label:
82
83   EVEL_EXIT();
84   return event;
85 }
86
87 /**************************************************************************//**
88  * Add a name/value pair to the Heartbeat fields, under the additionalFields array.
89  *
90  * The name and value are null delimited ASCII strings.  The library takes
91  * a copy so the caller does not have to preserve values after the function
92  * returns.
93  *
94  * @param event     Pointer to the Heartbeat fields event.
95  * @param name      ASCIIZ string with the field's name.  The caller does not
96  *                  need to preserve the value once the function returns.
97  * @param value     ASCIIZ string with the field's value.  The caller does not
98  *                  need to preserve the value once the function returns.
99  *****************************************************************************/
100 void evel_hrtbt_field_addl_field_add(EVENT_HEARTBEAT_FIELD * const event,
101                                  const char * const name,
102                                  const char * const value)
103 {
104   OTHER_FIELD * nv_pair = NULL;
105
106   EVEL_ENTER();
107
108   /***************************************************************************/
109   /* Check preconditions.                                                    */
110   /***************************************************************************/
111   assert(event != NULL);
112   assert(event->header.event_domain == EVEL_DOMAIN_HEARTBEAT_FIELD);
113   assert(name != NULL);
114   assert(value != NULL);
115
116   EVEL_DEBUG("Adding name=%s value=%s", name, value);
117   nv_pair = malloc(sizeof(OTHER_FIELD));
118   assert(nv_pair != NULL);
119   nv_pair->name = strdup(name);
120   nv_pair->value = strdup(value);
121   assert(nv_pair->name != NULL);
122   assert(nv_pair->value != NULL);
123
124   dlist_push_last(&event->additional_info, nv_pair);
125
126   EVEL_EXIT();
127 }
128
129 /**************************************************************************//**
130  * Set the Interval property of the Heartbeat fields event.
131  *
132  * @note  The property is treated as immutable: it is only valid to call
133  *        the setter once.  However, we don't assert if the caller tries to
134  *        overwrite, just ignoring the update instead.
135  *
136  * @param event         Pointer to the Heartbeat fields event.
137  * @param product_id    The vendor product id to be set. ASCIIZ string. The
138  *                      caller does not need to preserve the value once the
139  *                      function returns.
140  *****************************************************************************/
141 void evel_hrtbt_interval_set(EVENT_HEARTBEAT_FIELD * const event,
142                                  const int interval)
143 {
144   EVEL_ENTER();
145
146   /***************************************************************************/
147   /* Check preconditions and call evel_set_option_string.                    */
148   /***************************************************************************/
149   assert(event != NULL);
150   assert(event->header.event_domain == EVEL_DOMAIN_HEARTBEAT_FIELD);
151   assert(interval > 0);
152
153   event->heartbeat_interval = interval;
154   EVEL_EXIT();
155 }
156
157
158 /**************************************************************************//**
159  * Encode the Heartbeat fields in JSON according to AT&T's schema for the
160  * event type.
161  *
162  * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
163  * @param event         Pointer to the ::EVENT_HEADER to encode.
164  *****************************************************************************/
165 void evel_json_encode_hrtbt_field(EVEL_JSON_BUFFER * const jbuf,
166                                 EVENT_HEARTBEAT_FIELD * const event)
167 {
168   OTHER_FIELD * nv_pair = NULL;
169   DLIST_ITEM * dlist_item = NULL;
170
171   EVEL_ENTER();
172
173   /***************************************************************************/
174   /* Check preconditions.                                                    */
175   /***************************************************************************/
176   assert(event != NULL);
177   assert(event->header.event_domain == EVEL_DOMAIN_HEARTBEAT_FIELD);
178
179   evel_json_encode_header(jbuf, &event->header);
180   evel_json_open_named_object(jbuf, "heartbeatField");
181
182   /***************************************************************************/
183   /* Mandatory fields                                                        */
184   /***************************************************************************/
185   evel_enc_version(jbuf, "heartbeatFieldsVersion", event->major_version,event->minor_version);
186   evel_enc_kv_int(jbuf, "heartbeatInterval", event->heartbeat_interval);
187
188   /***************************************************************************/
189   /* Optional fields                                                         */
190   /***************************************************************************/
191
192   /***************************************************************************/
193   /* Checkpoint, so that we can wind back if all fields are suppressed.      */
194   /***************************************************************************/
195   evel_json_checkpoint(jbuf);
196   if (evel_json_open_opt_named_list(jbuf, "additionalFields"))
197   {
198     bool added = false;
199
200     dlist_item = dlist_get_first(&event->additional_info);
201     while (dlist_item != NULL)
202     {
203       nv_pair = (OTHER_FIELD *) dlist_item->item;
204       assert(nv_pair != NULL);
205
206       if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
207                                           "additionalFields",
208                                           nv_pair->name))
209       {
210         evel_json_open_object(jbuf);
211         evel_enc_kv_string(jbuf, "name", nv_pair->name);
212         evel_enc_kv_string(jbuf, "value", nv_pair->value);
213         evel_json_close_object(jbuf);
214         added = true;
215       }
216       dlist_item = dlist_get_next(dlist_item);
217     }
218     evel_json_close_list(jbuf);
219
220     /*************************************************************************/
221     /* If we've not written anything, rewind to before we opened the list.   */
222     /*************************************************************************/
223     if (!added)
224     {
225       evel_json_rewind(jbuf);
226     }
227   }
228
229   evel_json_close_object(jbuf);
230
231   EVEL_EXIT();
232 }
233
234 /**************************************************************************//**
235  * Free a Heartbeat fields event.
236  *
237  * Free off the event supplied.  Will free all the contained allocated memory.
238  *
239  * @note It does not free the event itself, since that may be part of a larger
240  * structure.
241  *****************************************************************************/
242 void evel_free_hrtbt_field(EVENT_HEARTBEAT_FIELD * const event)
243 {
244   OTHER_FIELD * nv_pair = NULL;
245
246   EVEL_ENTER();
247
248   /***************************************************************************/
249   /* Check preconditions.                                                    */
250   /***************************************************************************/
251   assert(event != NULL);
252   assert(event->header.event_domain == EVEL_DOMAIN_HEARTBEAT_FIELD);
253
254   /***************************************************************************/
255   /* Free all internal strings then the header itself.                       */
256   /***************************************************************************/
257   nv_pair = dlist_pop_last(&event->additional_info);
258   while (nv_pair != NULL)
259   {
260     EVEL_DEBUG("Freeing Other Field (%s, %s)", nv_pair->name, nv_pair->value);
261     free(nv_pair->name);
262     free(nv_pair->value);
263     free(nv_pair);
264     nv_pair = dlist_pop_last(&event->additional_info);
265   }
266   evel_free_header(&event->header);
267
268   EVEL_EXIT();
269 }