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