1 /*************************************************************************//**
3 * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
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
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 ****************************************************************************/
19 /**************************************************************************//**
21 * Implementation of EVEL functions relating to Other.
23 ****************************************************************************/
30 #include "evel_internal.h"
32 /**************************************************************************//**
33 * Create a new Other event.
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)
45 EVENT_OTHER * other = NULL;
48 /***************************************************************************/
49 /* Check preconditions. */
50 /***************************************************************************/
52 /***************************************************************************/
53 /* Allocate the Other. */
54 /***************************************************************************/
55 other = malloc(sizeof(EVENT_OTHER));
58 log_error_state("Out of memory");
61 memset(other, 0, sizeof(EVENT_OTHER));
62 EVEL_DEBUG("New Other is at %lp", other);
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;
73 other->namedarrays = NULL;
74 dlist_initialize(&other->jsonobjects);
75 dlist_initialize(&other->namedvalues);
82 /**************************************************************************//**
83 * Set the Event Type property of the Other.
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.
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
93 *****************************************************************************/
94 void evel_other_type_set(EVENT_OTHER * other,
95 const char * const type)
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);
109 /**************************************************************************//**
110 * Add a json object to jsonObject list.
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
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)
121 OTHER_FIELD * other_field = NULL;
124 /***************************************************************************/
125 /* Check preconditions. */
126 /***************************************************************************/
127 assert(other != NULL);
128 assert(other->header.event_domain == EVEL_DOMAIN_OTHER);
129 assert(other->namedarrays == NULL);
132 EVEL_DEBUG("Adding Named array");
134 other->namedarrays = ht_create(size);
140 /**************************************************************************//**
141 * Add a json object to jsonObject list.
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
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)
152 OTHER_FIELD * other_field = NULL;
156 /***************************************************************************/
157 /* Check preconditions. */
158 /***************************************************************************/
159 assert(other != NULL);
160 assert(other->header.event_domain == EVEL_DOMAIN_OTHER);
161 assert(other->namedarrays != NULL);
163 EVEL_DEBUG("Adding values to Named array");
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);
175 list = ht_get(other->namedarrays, hashname);
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");
186 dlist_push_last(list, other_field);
187 EVEL_DEBUG("Adding to existing table");
194 /**************************************************************************//**
195 * Add a json object to jsonObject list.
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
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)
206 OTHER_FIELD * other_field = NULL;
209 /***************************************************************************/
210 /* Check preconditions. */
211 /***************************************************************************/
212 assert(other != NULL);
213 assert(other->header.event_domain == EVEL_DOMAIN_OTHER);
214 assert(jsonobj != NULL);
216 EVEL_DEBUG("Adding jsonObject");
218 dlist_push_last(&other->jsonobjects, jsonobj);
223 /**************************************************************************//**
224 * Add a field name/value pair to the Other.
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
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)
238 OTHER_FIELD * other_field = NULL;
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);
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);
258 dlist_push_last(&other->namedvalues, other_field);
263 /**************************************************************************//**
264 * Encode the Other in JSON according to AT&T's schema for the event type.
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,
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;
281 bool itm_added = false;
282 DLIST *itm_list = NULL;
286 /***************************************************************************/
287 /* Check preconditions. */
288 /***************************************************************************/
289 assert(event != NULL);
290 assert(event->header.event_domain == EVEL_DOMAIN_OTHER);
292 evel_json_encode_header(jbuf, &event->header);
293 evel_json_open_named_object(jbuf, "otherFields");
295 // iterate through hashtable and print DLIST for each entry
297 ht = event->namedarrays;
302 for( i = 0; i < ht->size; i++ ) {
303 if( ht->table[i] != NULL)
308 if( itm_added == true)
311 if (evel_json_open_opt_named_list(jbuf, "hashOfNameValuePairArrays"))
313 for( i = 0; i < ht->size; i++ ) {
314 if( ht->table[i] != NULL)
316 itm_list = ht->table[i];
318 if(evel_json_open_opt_named_list(jbuf, ht->table[i]->key))
320 other_field_item = dlist_get_first(&itm_list);
321 while (other_field_item != NULL)
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);
332 evel_json_close_list(jbuf);
338 evel_json_close_list(jbuf);
346 evel_json_checkpoint(jbuf);
347 if(evel_json_open_opt_named_list(jbuf, "jsonObjects"))
349 bool item_added = false;
350 other_field_item = dlist_get_first(&event->jsonobjects);
351 while (other_field_item != NULL)
353 jsonobjp = (EVEL_JSON_OBJECT *) other_field_item->item;
354 if(jsonobjp != NULL);
356 evel_json_open_object(jbuf);
358 if( evel_json_open_opt_named_list(jbuf, "objectInstances"))
360 bool item_added2 = false;
361 jsobj_field_item = dlist_get_first(&jsonobjp->jsonobjectinstances);
362 while (jsobj_field_item != NULL)
364 jsonobjinst = (EVEL_JSON_OBJECT_INSTANCE *) jsobj_field_item->item;
365 if( jsonobjinst != NULL )
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"))
373 bool item_added3 = false;
375 keyinst_field_item = dlist_get_first(&jsonobjinst->object_keys);
376 while (keyinst_field_item != NULL)
378 keyinst = (EVEL_INTERNAL_KEY *)keyinst_field_item->item;
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);
388 keyinst_field_item = dlist_get_next(keyinst_field_item);
390 evel_json_close_list(jbuf);
392 /*************************************************************************/
393 /* If we've not written anything, rewind to before we opened the list. */
394 /*************************************************************************/
397 // evel_json_rewind(jbuf);
400 evel_json_close_object(jbuf);
403 jsobj_field_item = dlist_get_next(jsobj_field_item);
405 evel_json_close_list(jbuf);
408 evel_json_rewind(jbuf);
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);
420 other_field_item = dlist_get_next(other_field_item);
422 evel_json_close_list(jbuf);
426 evel_json_rewind(jbuf);
431 if( evel_json_open_opt_named_list(jbuf, "nameValuePairs"))
433 other_field_item = dlist_get_first(&event->namedvalues);
434 while (other_field_item != NULL)
436 other_field = (OTHER_FIELD *) other_field_item->item;
437 assert(other_field != NULL);
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);
446 evel_json_close_list(jbuf);
448 evel_enc_version(jbuf, "otherFieldsVersion", event->major_version,event->minor_version);
450 evel_json_close_object(jbuf);
455 /**************************************************************************//**
458 * Free off the Other supplied. Will free all the contained allocated memory.
460 * @note It does not free the Other itself, since that may be part of a
462 *****************************************************************************/
463 void evel_free_other(EVENT_OTHER * event)
465 OTHER_FIELD * other_field = NULL;
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);
476 /***************************************************************************/
477 /* Free all internal strings then the header itself. */
478 /***************************************************************************/
479 other_field = dlist_pop_last(&event->namedvalues);
480 while (other_field != NULL)
482 EVEL_DEBUG("Freeing Other Field (%s, %s)",
485 free(other_field->name);
486 free(other_field->value);
488 other_field = dlist_pop_last(&event->namedvalues);
490 evel_free_header(&event->header);