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