AT&T ECOMP Vendor Event Listener library  0.1
evel.c
Go to the documentation of this file.
1 /**************************************************************************/
44 #include <string.h>
45 #include <assert.h>
46 #include <stdlib.h>
47 #include <sys/time.h>
48 #include <curl/curl.h>
49 
50 #include "evel.h"
51 #include "evel_internal.h"
52 #include "evel_throttle.h"
53 #include "metadata.h"
54 
55 /**************************************************************************/
59 
60 /**************************************************************************/
63 char *functional_role = NULL;
64 
65 /**************************************************************************/
93 EVEL_ERR_CODES evel_initialize(const char * const fqdn,
94  int port,
95  const char * const path,
96  const char * const topic,
97  int secure,
98  const char * const username,
99  const char * const password,
100  EVEL_SOURCE_TYPES source_type,
101  const char * const role,
102  int verbosity
103  )
104 {
106  char base_api_url[EVEL_MAX_URL_LEN + 1] = {0};
107  char event_api_url[EVEL_MAX_URL_LEN + 1] = {0};
108  char throt_api_url[EVEL_MAX_URL_LEN + 1] = {0};
109  char path_url[EVEL_MAX_URL_LEN + 1] = {0};
110  char topic_url[EVEL_MAX_URL_LEN + 1] = {0};
111  char version_string[10] = {0};
112  int offset;
113 
114  /***************************************************************************/
115  /* Check assumptions. */
116  /***************************************************************************/
117  assert(fqdn != NULL);
118  assert(port > 0 && port <= 65535);
119  assert(source_type < EVEL_MAX_SOURCE_TYPES);
120  assert(role != NULL);
121 
122  /***************************************************************************/
123  /* Start logging so we can report on progress. */
124  /***************************************************************************/
125  log_initialize(verbosity == 0 ? EVEL_LOG_INFO : EVEL_LOG_DEBUG, "EVEL");
126  EVEL_INFO("EVEL started");
127  EVEL_INFO("API server is: %s", fqdn);
128  EVEL_INFO("API port is: %d", port);
129 
130  if (path != NULL)
131  {
132  EVEL_INFO("API path is: %s", path);
133  }
134  else
135  {
136  EVEL_INFO("No API path");
137  }
138 
139  if (topic != NULL)
140  {
141  EVEL_INFO("API topic is: %s", topic);
142  }
143  else
144  {
145  EVEL_INFO("No API topic");
146  }
147 
148  EVEL_INFO("API transport is: %s", secure ? "HTTPS" : "HTTP");
149  EVEL_INFO("Event Source Type is: %d", source_type);
150  EVEL_INFO("Functional Role is: %s", role);
151  EVEL_INFO("Log verbosity is: %d", verbosity);
152 
153  /***************************************************************************/
154  /* Initialize event throttling to the default state. */
155  /***************************************************************************/
157 
158  /***************************************************************************/
159  /* Save values we will need during operation. */
160  /***************************************************************************/
161  event_source_type = source_type;
162  functional_role = strdup(role);
163 
164  /***************************************************************************/
165  /* Ensure there are no trailing zeroes and unnecessary decimal points in */
166  /* the version. */
167  /***************************************************************************/
168  offset = sprintf(version_string, "%d", EVEL_API_MAJOR_VERSION);
169 
170  if (EVEL_API_MINOR_VERSION != 0)
171  {
172  sprintf(version_string + offset, ".%d", EVEL_API_MINOR_VERSION);
173  }
174 
175  /***************************************************************************/
176  /* Build a common base of the API URLs. */
177  /***************************************************************************/
178  strcpy(path_url, "/");
179  snprintf(base_api_url,
181  "%s://%s:%d%s/eventListener/v%s",
182  secure ? "https" : "http",
183  fqdn,
184  port,
185  (((path != NULL) && (strlen(path) > 0)) ?
186  strncat(path_url, path, EVEL_MAX_URL_LEN) : ""),
187  version_string);
188 
189  /***************************************************************************/
190  /* Build the URL to the event API. */
191  /***************************************************************************/
192  strcpy(topic_url, "/");
193  snprintf(event_api_url,
195  "%s%s",
196  base_api_url,
197  (((topic != NULL) && (strlen(topic) > 0)) ?
198  strncat(topic_url, topic, EVEL_MAX_URL_LEN) : ""));
199  EVEL_INFO("Vendor Event Listener API is located at: %s", event_api_url);
200 
201  /***************************************************************************/
202  /* Build the URL to the throttling API. */
203  /***************************************************************************/
204  snprintf(throt_api_url,
206  "%s/clientThrottlingState",
207  base_api_url);
208  EVEL_INFO("Vendor Event Throttling API is located at: %s", throt_api_url);
209 
210  /***************************************************************************/
211  /* Spin-up the event-handler, which gets cURL readied for use. */
212  /***************************************************************************/
213  rc = event_handler_initialize(event_api_url,
214  throt_api_url,
215  username,
216  password,
217  verbosity);
218  if (rc != EVEL_SUCCESS)
219  {
220  log_error_state("Failed to initialize event handler (including cURL)");
221  goto exit_label;
222  }
223 
224  /***************************************************************************/
225  /* Extract the metadata from OpenStack. If we fail to extract it, we */
226  /* record that in the logs, but carry on, assuming we're in a test */
227  /* without a metadata service. */
228  /***************************************************************************/
229  rc = openstack_metadata(verbosity);
230  if (rc != EVEL_SUCCESS)
231  {
232  EVEL_INFO("Failed to load OpenStack metadata - assuming test environment");
233  rc = EVEL_SUCCESS;
234  }
235 
236  /***************************************************************************/
237  /* Start the event handler thread. */
238  /***************************************************************************/
239  rc = event_handler_run();
240  if (rc != EVEL_SUCCESS)
241  {
242  log_error_state("Failed to start event handler thread. "
243  "Error code=%d", rc);
244  goto exit_label;
245  }
246 
247 exit_label:
248  return(rc);
249 }
250 
251 /**************************************************************************/
261 {
262  int rc = EVEL_SUCCESS;
263 
264  /***************************************************************************/
265  /* First terminate any pending transactions in the event-posting thread. */
266  /***************************************************************************/
268  if (rc != EVEL_SUCCESS)
269  {
270  log_error_state("Failed to terminate EVEL library cleanly!");
271  }
272 
273  /***************************************************************************/
274  /* Shut down the Event Handler library in a tidy manner. */
275  /***************************************************************************/
276  curl_global_cleanup();
277 
278  /***************************************************************************/
279  /* Clean up allocated memory. */
280  /***************************************************************************/
281  free(functional_role);
282 
283  /***************************************************************************/
284  /* Clean up event throttling. */
285  /***************************************************************************/
287 
288  EVEL_INFO("EVEL stopped");
289  return(rc);
290 }
291 
292 /**************************************************************************/
299 void evel_free_event(void * event)
300 {
301  EVENT_HEADER * evt_ptr = event;
302  EVEL_ENTER();
303 
304  if (event != NULL)
305  {
306  /*************************************************************************/
307  /* Work out what kind of event we're dealing with so we can cast it */
308  /* appropriately. */
309  /*************************************************************************/
310  switch (evt_ptr->event_domain)
311  {
313  EVEL_DEBUG("Event is an Internal event at %lp", evt_ptr);
315  memset(evt_ptr, 0, sizeof(EVENT_INTERNAL));
316  free(evt_ptr);
317  break;
318 
320  EVEL_DEBUG("Event is a Heartbeat at %lp", evt_ptr);
321  evel_free_header(evt_ptr);
322  memset(evt_ptr, 0, sizeof(EVENT_HEADER));
323  free(evt_ptr);
324  break;
325 
326  case EVEL_DOMAIN_FAULT:
327  EVEL_DEBUG("Event is a Fault at %lp", evt_ptr);
328  evel_free_fault((EVENT_FAULT *)evt_ptr);
329  memset(evt_ptr, 0, sizeof(EVENT_FAULT));
330  free(evt_ptr);
331  break;
332 
334  EVEL_DEBUG("Event is a Measurement at %lp", evt_ptr);
336  memset(evt_ptr, 0, sizeof(EVENT_MEASUREMENT));
337  free(evt_ptr);
338  break;
339 
341  EVEL_DEBUG("Event is a Mobile Flow at %lp", evt_ptr);
343  memset(evt_ptr, 0, sizeof(EVENT_MOBILE_FLOW));
344  free(evt_ptr);
345  break;
346 
347  case EVEL_DOMAIN_REPORT:
348  EVEL_DEBUG("Event is a Report at %lp", evt_ptr);
349  evel_free_report((EVENT_REPORT *)evt_ptr);
350  memset(evt_ptr, 0, sizeof(EVENT_REPORT));
351  free(evt_ptr);
352  break;
353 
354  case EVEL_DOMAIN_SERVICE:
355  EVEL_DEBUG("Event is a Service Event at %lp", evt_ptr);
356  evel_free_service((EVENT_SERVICE *)evt_ptr);
357  memset(evt_ptr, 0, sizeof(EVENT_SERVICE));
358  free(evt_ptr);
359  break;
360 
362  EVEL_DEBUG("Event is a Signaling at %lp", evt_ptr);
364  memset(evt_ptr, 0, sizeof(EVENT_SIGNALING));
365  free(evt_ptr);
366  break;
367 
369  EVEL_DEBUG("Event is a State Change at %lp", evt_ptr);
371  memset(evt_ptr, 0, sizeof(EVENT_STATE_CHANGE));
372  free(evt_ptr);
373  break;
374 
375  case EVEL_DOMAIN_SYSLOG:
376  EVEL_DEBUG("Event is a Syslog at %lp", evt_ptr);
377  evel_free_syslog((EVENT_SYSLOG *)evt_ptr);
378  memset(evt_ptr, 0, sizeof(EVENT_SYSLOG));
379  free(evt_ptr);
380  break;
381 
382  case EVEL_DOMAIN_OTHER:
383  EVEL_DEBUG("Event is an Other at %lp", evt_ptr);
384  evel_free_other((EVENT_OTHER *)evt_ptr);
385  memset(evt_ptr, 0, sizeof(EVENT_OTHER));
386  free(evt_ptr);
387  break;
388 
389  default:
390  EVEL_ERROR("Unexpected event domain (%d)", evt_ptr->event_domain);
391  assert(0);
392  }
393  }
394  EVEL_EXIT();
395 }
void evel_free_state_change(EVENT_STATE_CHANGE *const state_change)
Free a State Change.
#define EVEL_DEBUG(FMT,...)
Definition: evel.h:3621
#define EVEL_MAX_URL_LEN
Definition: evel.h:103
void log_initialize(EVEL_LOG_LEVELS level, const char *ident)
Initialize logging.
Definition: evel_logging.c:68
void evel_throttle_terminate()
Clean up event throttling.
void evel_free_signaling(EVENT_SIGNALING *const event)
Free a Signaling event.
void evel_throttle_initialize()
Initialize event throttling to the default state.
Report.
Definition: evel.h:650
EVEL_SOURCE_TYPES event_source_type
The type of equipment represented by this VNF.
Definition: evel.c:58
EVEL_ERR_CODES evel_terminate(void)
Clean up the EVEL library.
Definition: evel.c:260
#define EVEL_INFO(FMT,...)
Definition: evel.h:3622
void evel_free_syslog(EVENT_SYSLOG *event)
Free a Syslog.
Definition: evel_syslog.c:464
void evel_free_event(void *event)
Free an event.
Definition: evel.c:299
Internal event.
void evel_free_measurement(EVENT_MEASUREMENT *event)
Free a Measurement.
Measurement.
Definition: evel.h:504
void evel_free_report(EVENT_REPORT *event)
Free a Report.
Wrap the OpenStack metadata service.
void evel_free_mobile_flow(EVENT_MOBILE_FLOW *event)
Free a Mobile Flow.
A Fault event.
Definition: evel.h:134
void evel_free_fault(EVENT_FAULT *event)
Free a Fault.
Definition: evel_fault.c:304
#define EVEL_EXIT()
Definition: evel.h:3631
#define EVEL_ENTER()
Definition: evel.h:3626
A Measurement for VF Reporting event.
Definition: evel.h:137
Header for EVEL library.
State Change.
Definition: evel.h:952
Syslog.
Definition: evel.h:993
EVEL_ERR_CODES openstack_metadata(int verbosity)
Download metadata from the OpenStack metadata service.
Definition: metadata.c:105
A Syslog event.
Definition: evel.h:141
EVEL_ERR_CODES evel_initialize(const char *const fqdn, int port, const char *const path, const char *const topic, int secure, const char *const username, const char *const password, EVEL_SOURCE_TYPES source_type, const char *const role, int verbosity)
Library initialization.
Definition: evel.c:93
void evel_free_service(EVENT_SERVICE *const event)
Free a Service Events event.
char * functional_role
The Functional Role of the equipment represented by this VNF.
Definition: evel.c:63
#define EVEL_ERROR(FMT,...)
Definition: evel.h:3624
EVEL_SOURCE_TYPES
Fault source types.
Definition: evel.h:174
A Signaling event.
Definition: evel.h:139
EVEL_ERR_CODES
Error codes.
Definition: evel.h:68
EVEL_ERR_CODES event_handler_initialize(const char *const event_api_url, const char *const throt_api_url, const char *const username, const char *const password, int verbosity)
Initialize the event handler.
A Mobile Flow event.
Definition: evel.h:136
void evel_free_internal_event(EVENT_INTERNAL *event)
Free an internal event.
EVEL_ERR_CODES event_handler_terminate()
Terminate the event handler.
Mobile Flow.
Definition: evel.h:740
EVEL_EVENT_DOMAINS event_domain
Definition: evel.h:420
#define EVEL_API_MAJOR_VERSION
Definition: evel.h:60
void evel_free_header(EVENT_HEADER *const event)
Free an event header.
Definition: evel_event.c:349
Service Events.
Definition: evel.h:839
A Heartbeat event (event header only).
Definition: evel.h:133
void log_error_state(char *format,...)
Definition: evel_logging.c:98
A State Change event.
Definition: evel.h:140
Other.
Definition: evel.h:793
void evel_free_other(EVENT_OTHER *event)
Free an Other.
Definition: evel_other.c:201
A Measurement for VF Scaling event.
Definition: evel.h:135
#define EVEL_API_MINOR_VERSION
Definition: evel.h:61
Event header.
Definition: evel.h:410
Internal event, not for external routing.
Definition: evel.h:132
Signaling.
Definition: evel.h:916
EVEL_ERR_CODES event_handler_run()
Run the event handler.
EVEL throttle definitions.
EVEL internal definitions.
A Service event.
Definition: evel.h:138
Fault.
Definition: evel.h:449