Modified hardcoded eventname id to user defined
[demo.git] / vnfs / VES5.0 / evel / evel-library / code / evel_library / evel_other.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 Other.
21  *
22  ****************************************************************************/
23
24 #include <string.h>
25 #include <assert.h>
26 #include <stdlib.h>
27
28 #include "evel.h"
29 #include "evel_internal.h"
30
31 /**************************************************************************//**
32  * Create a new Other event.
33  *
34  * @note    The mandatory fields on the Other 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  *          Other has immutable properties.
38  * @returns pointer to the newly manufactured ::EVENT_OTHER.  If the event is
39  *          not used (i.e. posted) it must be released using ::evel_free_other.
40  * @retval  NULL  Failed to create the event.
41  *****************************************************************************/
42 EVENT_OTHER * evel_new_other(const char *ev_name, const char *ev_id)
43 {
44   EVENT_OTHER * other = NULL;
45   EVEL_ENTER();
46
47   /***************************************************************************/
48   /* Check preconditions.                                                    */
49   /***************************************************************************/
50
51   /***************************************************************************/
52   /* Allocate the Other.                                                     */
53   /***************************************************************************/
54   other = malloc(sizeof(EVENT_OTHER));
55   if (other == NULL)
56   {
57     log_error_state("Out of memory");
58     goto exit_label;
59   }
60   memset(other, 0, sizeof(EVENT_OTHER));
61   EVEL_DEBUG("New Other is at %lp", other);
62
63   /***************************************************************************/
64   /* Initialize the header & the Other fields.  Optional string values are   */
65   /* uninitialized (NULL).                                                   */
66   /***************************************************************************/
67   evel_init_header_nameid(&other->header,ev_name,ev_id);
68   other->header.event_domain = EVEL_DOMAIN_OTHER;
69   other->major_version = EVEL_OTHER_EVENT_MAJOR_VERSION;
70   other->minor_version = EVEL_OTHER_EVENT_MINOR_VERSION;
71
72   other->namedarrays = NULL;
73   dlist_initialize(&other->jsonobjects);
74   dlist_initialize(&other->namedvalues);
75
76 exit_label:
77   EVEL_EXIT();
78   return other;
79 }
80
81 /**************************************************************************//**
82  * Set the Event Type property of the Other.
83  *
84  * @note  The property is treated as immutable: it is only valid to call
85  *        the setter once.  However, we don't assert if the caller tries to
86  *        overwrite, just ignoring the update instead.
87  *
88  * @param other       Pointer to the Other.
89  * @param type        The Event Type to be set. ASCIIZ string. The caller
90  *                    does not need to preserve the value once the function
91  *                    returns.
92  *****************************************************************************/
93 void evel_other_type_set(EVENT_OTHER * other,
94                          const char * const type)
95 {
96   EVEL_ENTER();
97
98   /***************************************************************************/
99   /* Check preconditions and call evel_header_type_set.                      */
100   /***************************************************************************/
101   assert(other != NULL);
102   assert(other->header.event_domain == EVEL_DOMAIN_OTHER);
103   evel_header_type_set(&other->header, type);
104
105   EVEL_EXIT();
106 }
107
108 /**************************************************************************//**
109  * Add a json object to jsonObject list.
110  *
111  * The name and value are null delimited ASCII strings.  The library takes
112  * a copy so the caller does not have to preserve values after the function
113  * returns.
114  *
115  * @param other         Pointer to the Other.
116  * @param size          size of hashtable
117  *****************************************************************************/
118 void evel_other_field_set_namedarraysize(EVENT_OTHER * other, const int size)
119 {
120   OTHER_FIELD * other_field = NULL;
121   EVEL_ENTER();
122
123   /***************************************************************************/
124   /* Check preconditions.                                                    */
125   /***************************************************************************/
126   assert(other != NULL);
127   assert(other->header.event_domain == EVEL_DOMAIN_OTHER);
128   assert(other->namedarrays == NULL);
129   assert(size > 0);
130
131   EVEL_DEBUG("Adding Named array");
132
133   other->namedarrays =  ht_create(size);
134
135   EVEL_EXIT();
136 }
137
138
139 /**************************************************************************//**
140  * Add a json object to jsonObject list.
141  *
142  * The name and value are null delimited ASCII strings.  The library takes
143  * a copy so the caller does not have to preserve values after the function
144  * returns.
145  *
146  * @param other         Pointer to the Other.
147  * @param size          size of hashtable
148  *****************************************************************************/
149 void evel_other_field_add_namedarray(EVENT_OTHER * other, const char *hashname,  char * name, char *value)
150 {
151   OTHER_FIELD * other_field = NULL;
152   DLIST *list = NULL;
153   EVEL_ENTER();
154
155   /***************************************************************************/
156   /* Check preconditions.                                                    */
157   /***************************************************************************/
158   assert(other != NULL);
159   assert(other->header.event_domain == EVEL_DOMAIN_OTHER);
160   assert(other->namedarrays != NULL);
161
162   EVEL_DEBUG("Adding values to Named array");
163       
164   EVEL_DEBUG("Adding name=%s value=%s", name, value);
165   other_field = malloc(sizeof(OTHER_FIELD));
166   assert(other_field != NULL);
167   memset(other_field, 0, sizeof(OTHER_FIELD));
168   other_field->name = strdup(name);
169   other_field->value = strdup(value);
170   assert(other_field->name != NULL);
171   assert(other_field->value != NULL);
172
173
174   list = ht_get(other->namedarrays, hashname);
175   if( list == NULL )
176   {
177      DLIST * nlist = malloc(sizeof(DLIST));
178      dlist_initialize(nlist);
179      dlist_push_last(nlist, other_field);
180      ht_set(other->namedarrays, hashname, nlist);
181      EVEL_DEBUG("Created to new table table");
182   }
183   else
184   {
185      dlist_push_last(list, other_field);
186      EVEL_DEBUG("Adding to existing table");
187   }
188
189   EVEL_EXIT();
190 }
191
192
193 /**************************************************************************//**
194  * Add a json object to jsonObject list.
195  *
196  * The name and value are null delimited ASCII strings.  The library takes
197  * a copy so the caller does not have to preserve values after the function
198  * returns.
199  *
200  * @param other     Pointer to the Other.
201  * @param jsonobj   Pointer to json object
202  *****************************************************************************/
203 void evel_other_field_add_jsonobj(EVENT_OTHER * other, EVEL_JSON_OBJECT *jsonobj)
204 {
205   OTHER_FIELD * other_field = NULL;
206   EVEL_ENTER();
207
208   /***************************************************************************/
209   /* Check preconditions.                                                    */
210   /***************************************************************************/
211   assert(other != NULL);
212   assert(other->header.event_domain == EVEL_DOMAIN_OTHER);
213   assert(jsonobj != NULL);
214
215   EVEL_DEBUG("Adding jsonObject");
216
217   dlist_push_last(&other->jsonobjects, jsonobj);
218
219   EVEL_EXIT();
220 }
221
222 /**************************************************************************//**
223  * Add a field name/value pair to the Other.
224  *
225  * The name and value are null delimited ASCII strings.  The library takes
226  * a copy so the caller does not have to preserve values after the function
227  * returns.
228  *
229  * @param other     Pointer to the Other.
230  * @param name      ASCIIZ string with the field's name.  The caller does not
231  *                  need to preserve the value once the function returns.
232  * @param value     ASCIIZ string with the field's value.  The caller does not
233  *                  need to preserve the value once the function returns.
234  *****************************************************************************/
235 void evel_other_field_add(EVENT_OTHER * other, char * name, char * value)
236 {
237   OTHER_FIELD * other_field = NULL;
238   EVEL_ENTER();
239
240   /***************************************************************************/
241   /* Check preconditions.                                                    */
242   /***************************************************************************/
243   assert(other != NULL);
244   assert(other->header.event_domain == EVEL_DOMAIN_OTHER);
245   assert(name != NULL);
246   assert(value != NULL);
247
248   EVEL_DEBUG("Adding name=%s value=%s", name, value);
249   other_field = malloc(sizeof(OTHER_FIELD));
250   assert(other_field != NULL);
251   memset(other_field, 0, sizeof(OTHER_FIELD));
252   other_field->name = strdup(name);
253   other_field->value = strdup(value);
254   assert(other_field->name != NULL);
255   assert(other_field->value != NULL);
256
257   dlist_push_last(&other->namedvalues, other_field);
258
259   EVEL_EXIT();
260 }
261
262 /**************************************************************************//**
263  * Encode the Other in JSON according to AT&T's schema for the event type.
264  *
265  * @param jbuf          Pointer to the ::EVEL_JSON_BUFFER to encode into.
266  * @param event         Pointer to the ::EVENT_HEADER to encode.
267  *****************************************************************************/
268 void evel_json_encode_other(EVEL_JSON_BUFFER * jbuf,
269                             EVENT_OTHER * event)
270 {
271   OTHER_FIELD * other_field = NULL;
272   EVEL_JSON_OBJECT * jsonobjp = NULL;
273   DLIST_ITEM * other_field_item = NULL;
274   EVEL_JSON_OBJECT_INSTANCE * jsonobjinst = NULL;
275   DLIST_ITEM * jsobj_field_item = NULL;
276   EVEL_INTERNAL_KEY * keyinst = NULL;
277   DLIST_ITEM * keyinst_field_item = NULL;
278   HASHTABLE_T *ht = NULL;
279   int i;
280   bool itm_added = false;
281   DLIST *itm_list = NULL;
282
283   EVEL_ENTER();
284
285   /***************************************************************************/
286   /* Check preconditions.                                                    */
287   /***************************************************************************/
288   assert(event != NULL);
289   assert(event->header.event_domain == EVEL_DOMAIN_OTHER);
290
291   evel_json_encode_header(jbuf, &event->header);
292   evel_json_open_named_object(jbuf, "otherFields");
293
294 // iterate through hashtable and print DLIST for each entry
295
296    ht = event->namedarrays;
297    if( ht != NULL )
298    {
299      if( ht->size > 0)
300      {
301         for( i = 0; i < ht->size; i++ ) {
302              if( ht->table[i] != NULL)
303              {
304                 itm_added = true;
305              }
306         }
307         if( itm_added == true)
308         {
309
310   if (evel_json_open_opt_named_list(jbuf, "hashOfNameValuePairArrays"))
311   {
312        for( i = 0; i < ht->size; i++ ) {
313              if( ht->table[i] != NULL)
314              {
315                 itm_list = ht->table[i];
316
317   if(evel_json_open_opt_named_list(jbuf, ht->table[i]->key))
318   {
319     other_field_item = dlist_get_first(&itm_list);
320     while (other_field_item != NULL)
321     {
322      other_field = (OTHER_FIELD *) other_field_item->item;
323      if(other_field != NULL){
324        evel_json_open_object(jbuf);
325        evel_enc_kv_string(jbuf, "name", other_field->name);
326        evel_enc_kv_string(jbuf, "value", other_field->value);
327        evel_json_close_object(jbuf);
328        other_field_item = dlist_get_next(other_field_item);
329      }
330     }
331     evel_json_close_list(jbuf);
332   }
333
334              }
335        }
336
337        evel_json_close_list(jbuf);
338   }
339
340
341         }
342      }
343    }
344
345   evel_json_checkpoint(jbuf);
346   if(evel_json_open_opt_named_list(jbuf, "jsonObjects"))
347   {
348   bool item_added = false;
349   other_field_item = dlist_get_first(&event->jsonobjects);
350   while (other_field_item != NULL)
351   {
352     jsonobjp = (EVEL_JSON_OBJECT *) other_field_item->item;
353     if(jsonobjp != NULL);
354     {
355      evel_json_open_object(jbuf);
356
357        if( evel_json_open_opt_named_list(jbuf, "objectInstances"))
358        {
359         bool item_added2 = false;
360         jsobj_field_item = dlist_get_first(&jsonobjp->jsonobjectinstances);
361         while (jsobj_field_item != NULL)
362         {
363            jsonobjinst = (EVEL_JSON_OBJECT_INSTANCE *) jsobj_field_item->item;
364            if( jsonobjinst != NULL )
365            {
366               evel_json_open_object(jbuf);
367               evel_enc_kv_object(jbuf, "objectInstance", jsonobjinst->jsonstring);
368               evel_enc_kv_ull(jbuf, "objectInstanceEpochMicrosec", jsonobjinst->objinst_epoch_microsec);
369   //evel_json_checkpoint(jbuf);
370   if (evel_json_open_opt_named_list(jbuf, "objectKeys"))
371   {
372     bool item_added3 = false;
373
374     keyinst_field_item = dlist_get_first(&jsonobjinst->object_keys);
375     while (keyinst_field_item != NULL)
376     {
377       keyinst = (EVEL_INTERNAL_KEY *)keyinst_field_item->item;
378       if(keyinst != NULL)
379       {
380         evel_json_open_object(jbuf);
381         evel_enc_kv_string(jbuf, "keyName", keyinst->keyname);
382         evel_enc_kv_opt_int(jbuf, "keyOrder", &keyinst->keyorder);
383         evel_enc_kv_opt_string(jbuf, "keyValue", &keyinst->keyvalue);
384         evel_json_close_object(jbuf);
385         item_added3 = false;
386       }
387       keyinst_field_item = dlist_get_next(keyinst_field_item);
388     }
389     evel_json_close_list(jbuf);
390
391     /*************************************************************************/
392     /* If we've not written anything, rewind to before we opened the list.   */
393     /*************************************************************************/
394     //if (!item_added3)
395     //{
396     //  evel_json_rewind(jbuf);
397     //}
398   }
399                evel_json_close_object(jbuf);
400             }
401             item_added2 = true;
402             jsobj_field_item = dlist_get_next(jsobj_field_item);
403         }
404         evel_json_close_list(jbuf);
405         if( !item_added2 )
406         {
407           evel_json_rewind(jbuf);
408         }
409        }
410
411     evel_enc_kv_string(jbuf, "objectName", jsonobjp->object_name);
412     evel_enc_kv_opt_string(jbuf, "objectSchema", &jsonobjp->objectschema);
413     evel_enc_kv_opt_string(jbuf, "objectSchemaUrl", &jsonobjp->objectschemaurl);
414     evel_enc_kv_opt_string(jbuf, "nfSubscribedObjectName", &jsonobjp->nfsubscribedobjname);
415     evel_enc_kv_opt_string(jbuf, "nfSubscriptionId", &jsonobjp->nfsubscriptionid);
416     evel_json_close_object(jbuf);
417     item_added = true;
418   }
419   other_field_item = dlist_get_next(other_field_item);
420   }
421   evel_json_close_list(jbuf);
422
423   if (!item_added)
424   {
425      evel_json_rewind(jbuf);
426   }
427
428   }
429
430   if( evel_json_open_opt_named_list(jbuf, "nameValuePairs"))
431   {
432   other_field_item = dlist_get_first(&event->namedvalues);
433   while (other_field_item != NULL)
434   {
435     other_field = (OTHER_FIELD *) other_field_item->item;
436     assert(other_field != NULL);
437
438     evel_json_open_object(jbuf);
439     evel_enc_kv_string(jbuf, "name", other_field->name);
440     evel_enc_kv_string(jbuf, "value", other_field->value);
441     evel_json_close_object(jbuf);
442     other_field_item = dlist_get_next(other_field_item);
443   }
444   }
445   evel_json_close_list(jbuf);
446
447   evel_enc_version(jbuf, "otherFieldsVersion", event->major_version,event->minor_version);
448
449   evel_json_close_object(jbuf);
450
451   EVEL_EXIT();
452 }
453
454 /**************************************************************************//**
455  * Free an Other.
456  *
457  * Free off the Other supplied.  Will free all the contained allocated memory.
458  *
459  * @note It does not free the Other itself, since that may be part of a
460  * larger structure.
461  *****************************************************************************/
462 void evel_free_other(EVENT_OTHER * event)
463 {
464   OTHER_FIELD * other_field = NULL;
465
466   EVEL_ENTER();
467
468   /***************************************************************************/
469   /* Check preconditions.  As an internal API we don't allow freeing NULL    */
470   /* events as we do on the public API.                                      */
471   /***************************************************************************/
472   assert(event != NULL);
473   assert(event->header.event_domain == EVEL_DOMAIN_OTHER);
474
475   /***************************************************************************/
476   /* Free all internal strings then the header itself.                       */
477   /***************************************************************************/
478   other_field = dlist_pop_last(&event->namedvalues);
479   while (other_field != NULL)
480   {
481     EVEL_DEBUG("Freeing Other Field (%s, %s)",
482                other_field->name,
483                other_field->value);
484     free(other_field->name);
485     free(other_field->value);
486     free(other_field);
487     other_field = dlist_pop_last(&event->namedvalues);
488   }
489   evel_free_header(&event->header);
490
491   EVEL_EXIT();
492 }