Merge "removed vFW vLB extra executables"
[demo.git] / VES5.0 / evel / evel-library / code / evel_library / evel_heartbeat_fields.c
1 /**************************************************************************//**
2  * @file
3  * Implementation of EVEL functions relating to Heartbeat fields.
4  *
5  * License
6  * -------
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice,
12  *    this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  *    this list of conditions and the following disclaimer in the documentation
15  *    and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:  This product includes
18  *    software developed by the AT&T.
19  * 4. Neither the name of AT&T nor the names of its contributors may be used to
20  *    endorse or promote products derived from this software without specific
21  *    prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY AT&T INTELLECTUAL PROPERTY ''AS IS'' AND ANY
24  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED. IN NO EVENT SHALL AT&T INTELLECTUAL PROPERTY BE LIABLE FOR ANY
27  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *****************************************************************************/
34
35 #include <string.h>
36 #include <assert.h>
37 #include <stdlib.h>
38
39 #include "evel.h"
40 #include "evel_throttle.h"
41
42 /**************************************************************************//**
43  * Create a new Heartbeat fields event.
44  *
45  * @note    The mandatory fields on the Heartbeat fields must be supplied to
46  *          this factory function and are immutable once set.  Optional fields
47  *          have explicit setter functions, but again values may only be set
48  *          once so that the event has immutable properties.
49  * @param vendor_id     The vendor id to encode in the event instance id.
50  * @param event_id      The vendor event id to encode in the event instance id.
51  * @returns pointer to the newly manufactured ::EVENT_HEARTBEAT_FIELD.  If the event
52  *          is not used (i.e. posted) it must be released using
53  *          ::evel_free_hrtbt_field.
54  * @retval  NULL  Failed to create the event.
55  *****************************************************************************/
56 EVENT_HEARTBEAT_FIELD * evel_new_heartbeat_field(int interval)
57 {
58   EVENT_HEARTBEAT_FIELD * event = NULL;
59
60   EVEL_ENTER();
61
62   /***************************************************************************/
63   /* Check preconditions.                                                    */
64   /***************************************************************************/
65   assert(interval > 0);
66
67   /***************************************************************************/
68   /* Allocate the Heartbeat fields event.                                           */
69   /***************************************************************************/
70   event = malloc(sizeof(EVENT_HEARTBEAT_FIELD));
71   if (event == NULL)
72   {
73     log_error_state("Out of memory");
74     goto exit_label;
75   }
76   memset(event, 0, sizeof(EVENT_HEARTBEAT_FIELD));
77   EVEL_DEBUG("New Heartbeat fields event is at %lp", event);
78
79   /***************************************************************************/
80   /* Initialize the header & the Heartbeat fields fields.                           */
81   /***************************************************************************/
82   evel_init_header(&event->header,"HeartbeatFields");
83   event->header.event_domain = EVEL_DOMAIN_HEARTBEAT_FIELD;
84   event->major_version = EVEL_HEARTBEAT_FIELD_MAJOR_VERSION;
85   event->minor_version = EVEL_HEARTBEAT_FIELD_MINOR_VERSION;
86
87   event->heartbeat_interval = interval;
88   dlist_initialize(&event->additional_info);
89
90 exit_label:
91
92   EVEL_EXIT();
93   return event;
94 }
95
96 /**************************************************************************//**
97  * Add a name/value pair to the Heartbeat fields, under the additionalFields array.
98  *
99  * The name and value are null delimited ASCII strings.  The library takes
100  * a copy so the caller does not have to preserve values after the function
101  * returns.
102  *
103  * @param event     Pointer to the Heartbeat fields event.
104  * @param name      ASCIIZ string with the field's name.  The caller does not
105  *                  need to preserve the value once the function returns.
106  * @param value     ASCIIZ string with the field's value.  The caller does not
107  *                  need to preserve the value once the function returns.
108  *****************************************************************************/
109 void evel_hrtbt_field_addl_field_add(EVENT_HEARTBEAT_FIELD * const event,
110                                  const char * const name,
111                                  const char * const value)
112 {
113   OTHER_FIELD * nv_pair = NULL;
114
115   EVEL_ENTER();
116
117   /***************************************************************************/
118   /* Check preconditions.                                                    */
119   /***************************************************************************/
120   assert(event != NULL);
121   assert(event->header.event_domain == EVEL_DOMAIN_HEARTBEAT_FIELD);
122   assert(name != NULL);
123   assert(value != NULL);
124
125   EVEL_DEBUG("Adding name=%s value=%s", name, value);
126   nv_pair = malloc(sizeof(OTHER_FIELD));
127   assert(nv_pair != NULL);
128   nv_pair->name = strdup(name);
129   nv_pair->value = strdup(value);
130   assert(nv_pair->name != NULL);
131   assert(nv_pair->value != NULL);
132
133   dlist_push_last(&event->additional_info, nv_pair);
134
135   EVEL_EXIT();
136 }
137
138 /**************************************************************************//**
139  * Set the Interval property of the Heartbeat fields event.
140  *
141  * @note  The property is treated as immutable: it is only valid to call
142  *        the setter once.  However, we don't assert if the caller tries to
143  *        overwrite, just ignoring the update instead.
144  *
145  * @param event         Pointer to the Heartbeat fields event.
146  * @param product_id    The vendor product id to be set. ASCIIZ string. The
147  *                      caller does not need to preserve the value once the
148  *                      function returns.
149  *****************************************************************************/
150 void evel_hrtbt_interval_set(EVENT_HEARTBEAT_FIELD * const event,
151                                  const int interval)
152 {
153   EVEL_ENTER();
154
155   /***************************************************************************/
156   /* Check preconditions and call evel_set_option_string.                    */
157   /***************************************************************************/
158   assert(event != NULL);
159   assert(event->header.event_domain == EVEL_DOMAIN_HEARTBEAT_FIELD);
160   assert(interval > 0);
161
162   event->heartbeat_interval = interval;
163   EVEL_EXIT();
164 }
165
166
167 /**************************************************************************//**
168  * Encode the Heartbeat fields in JSON according to AT&T's schema for the
169  * event type.
170  *
171  * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
172  * @param event         Pointer to the ::EVENT_HEADER to encode.
173  *****************************************************************************/
174 void evel_json_encode_hrtbt_field(EVEL_JSON_BUFFER * const jbuf,
175                                 EVENT_HEARTBEAT_FIELD * const event)
176 {
177   OTHER_FIELD * nv_pair = NULL;
178   DLIST_ITEM * dlist_item = NULL;
179
180   EVEL_ENTER();
181
182   /***************************************************************************/
183   /* Check preconditions.                                                    */
184   /***************************************************************************/
185   assert(event != NULL);
186   assert(event->header.event_domain == EVEL_DOMAIN_HEARTBEAT_FIELD);
187
188   evel_json_encode_header(jbuf, &event->header);
189   evel_json_open_named_object(jbuf, "heartbeatField");
190
191   /***************************************************************************/
192   /* Mandatory fields                                                        */
193   /***************************************************************************/
194   evel_enc_version(jbuf, "heartbeatFieldsVersion", event->major_version,event->minor_version);
195   evel_enc_kv_int(jbuf, "heartbeatInterval", event->heartbeat_interval);
196
197   /***************************************************************************/
198   /* Optional fields                                                         */
199   /***************************************************************************/
200
201   /***************************************************************************/
202   /* Checkpoint, so that we can wind back if all fields are suppressed.      */
203   /***************************************************************************/
204   evel_json_checkpoint(jbuf);
205   if (evel_json_open_opt_named_list(jbuf, "additionalFields"))
206   {
207     bool added = false;
208
209     dlist_item = dlist_get_first(&event->additional_info);
210     while (dlist_item != NULL)
211     {
212       nv_pair = (OTHER_FIELD *) dlist_item->item;
213       assert(nv_pair != NULL);
214
215       if (!evel_throttle_suppress_nv_pair(jbuf->throttle_spec,
216                                           "additionalFields",
217                                           nv_pair->name))
218       {
219         evel_json_open_object(jbuf);
220         evel_enc_kv_string(jbuf, "name", nv_pair->name);
221         evel_enc_kv_string(jbuf, "value", nv_pair->value);
222         evel_json_close_object(jbuf);
223         added = true;
224       }
225       dlist_item = dlist_get_next(dlist_item);
226     }
227     evel_json_close_list(jbuf);
228
229     /*************************************************************************/
230     /* If we've not written anything, rewind to before we opened the list.   */
231     /*************************************************************************/
232     if (!added)
233     {
234       evel_json_rewind(jbuf);
235     }
236   }
237
238   evel_json_close_object(jbuf);
239
240   EVEL_EXIT();
241 }
242
243 /**************************************************************************//**
244  * Free a Heartbeat fields event.
245  *
246  * Free off the event supplied.  Will free all the contained allocated memory.
247  *
248  * @note It does not free the event itself, since that may be part of a larger
249  * structure.
250  *****************************************************************************/
251 void evel_free_hrtbt_field(EVENT_HEARTBEAT_FIELD * const event)
252 {
253   OTHER_FIELD * nv_pair = NULL;
254
255   EVEL_ENTER();
256
257   /***************************************************************************/
258   /* Check preconditions.                                                    */
259   /***************************************************************************/
260   assert(event != NULL);
261   assert(event->header.event_domain == EVEL_DOMAIN_HEARTBEAT_FIELD);
262
263   /***************************************************************************/
264   /* Free all internal strings then the header itself.                       */
265   /***************************************************************************/
266   nv_pair = dlist_pop_last(&event->additional_info);
267   while (nv_pair != NULL)
268   {
269     EVEL_DEBUG("Freeing Other Field (%s, %s)", nv_pair->name, nv_pair->value);
270     free(nv_pair->name);
271     free(nv_pair->value);
272     free(nv_pair);
273     nv_pair = dlist_pop_last(&event->additional_info);
274   }
275   evel_free_header(&event->header);
276
277   EVEL_EXIT();
278 }