AT&T ECOMP Vendor Event Listener library  0.1
quickstart.md
Go to the documentation of this file.
1 # Quick Start Guide {#quickstart}
2 
3 # Introduction {#qs_intro}
4 
5 This Quick-Start section describes how to:
6 
7  * Install and compile the supplied library code
8  * Integrate an existing project to use the EVEL library
9 
10 # Installation {#qs_install}
11 
12 The library is supplied as a source-code compressed-tar file. It is
13 straightforward to install and build to integrate with an existing or new
14 development project.
15 
16 ## Unpack the Source Code {#qs_unpack}
17 
18 The file should unpacked into your development environment:
19 ```
20 $ mkdir evel
21 $ cd evel
22 $ tar zxvf evel-library-package.tgz
23 ```
24 ### Satisfy Dependencies {#qs_depend}
25 
26 Note that all commands in this section are based on CentOS package management
27 tools and you may need to substitute the appropriate tools/packages for your
28 distribution, for example `apt-get` for Ubuntu.
29 
30 Ensure that GCC development tools are available.
31 
32 ```
33 $ sudo yum install gcc
34 ```
35 Additionally, the library has a dependency on the cURL library, so you'll need
36 the development tools for libCurl installed. (At runtime, only the runtime
37 library is required, of course.)
38 
39 ```
40 $ sudo yum install libcurl-devel
41 ```
42 If you wish to make the project documentation, then Doxygen and Graphviz are
43 required. (Again, this is only in the development environment, not the runtime
44 environment!)
45 
46 ```
47 $ sudo yum install doxygen graphviz
48 ```
49 
50 Note that some distributions have quite old versions of Doxygen by default and
51 it may be necessary to install a later version to use all the features.
52 
53 If you want to build PDFs from the LaTeX you will need a texlive install.
54 
55 ```
56 $ sudo yum install texlive
57 ```
58 
59 ### Test Build {#qs_build}
60 Make sure that the library makes cleanly:
61 
62 ```
63 $ cd bldjobs
64 $ make
65 Making dependency file evel_unit.d for evel_unit.c
66 Making dependency file evel_test_control.d for evel_test_control.c
67 Making dependency file evel_demo.d for evel_demo.c
68 Making dependency file jsmn.d for jsmn.c
69 Making dependency file evel_logging.d for evel_logging.c
70 Making dependency file evel_event_mgr.d for evel_event_mgr.c
71 Making dependency file evel_internal_event.d for evel_internal_event.c
72 Making dependency file evel_throttle.d for evel_throttle.c
73 Making dependency file evel_syslog.d for evel_syslog.c
74 Making dependency file evel_strings.d for evel_strings.c
75 Making dependency file evel_state_change.d for evel_state_change.c
76 Making dependency file evel_scaling_measurement.d for evel_scaling_measurement.c
77 Making dependency file evel_signaling.d for evel_signaling.c
78 Making dependency file evel_service.d for evel_service.c
79 Making dependency file evel_reporting_measurement.d for evel_reporting_measurement.c
80 Making dependency file evel_json_buffer.d for evel_json_buffer.c
81 Making dependency file evel_other.d for evel_other.c
82 Making dependency file evel_option.d for evel_option.c
83 Making dependency file evel_mobile_flow.d for evel_mobile_flow.c
84 Making dependency file evel_fault.d for evel_fault.c
85 Making dependency file evel_event.d for evel_event.c
86 Making dependency file double_list.d for double_list.c
87 Making dependency file ring_buffer.d for ring_buffer.c
88 Making dependency file metadata.d for metadata.c
89 Making dependency file evel.d for evel.c
90 Making evel.o from evel.c
91 Making metadata.o from metadata.c
92 Making ring_buffer.o from ring_buffer.c
93 Making double_list.o from double_list.c
94 Making evel_event.o from evel_event.c
95 Making evel_fault.o from evel_fault.c
96 Making evel_mobile_flow.o from evel_mobile_flow.c
97 Making evel_option.o from evel_option.c
98 Making evel_other.o from evel_other.c
99 Making evel_json_buffer.o from evel_json_buffer.c
100 Making evel_reporting_measurement.o from evel_reporting_measurement.c
101 Making evel_service.o from evel_service.c
102 Making evel_signaling.o from evel_signaling.c
103 Making evel_scaling_measurement.o from evel_scaling_measurement.c
104 Making evel_state_change.o from evel_state_change.c
105 Making evel_strings.o from evel_strings.c
106 Making evel_syslog.o from evel_syslog.c
107 Making evel_throttle.o from evel_throttle.c
108 Making evel_internal_event.o from evel_internal_event.c
109 Making evel_event_mgr.o from evel_event_mgr.c
110 Making evel_logging.o from evel_logging.c
111 Making jsmn.o from jsmn.c
112 Linking API Shared Library
113 Linking API Static Library
114 Making evel_demo.o from evel_demo.c
115 Making evel_test_control.o from evel_test_control.c
116 Linking EVEL demo
117 Making EVEL training
118 $
119 ```
120 You should now be able to run the demo CLI application. Since it will want to
121 dynamically link to the library that you've just made, you will need to set
122 your `LD_LIBRARY_PATH` appropriately first. Make sure that you specify
123 your actual directory paths correctly in the following:
124 
125 ```
126 $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/centos/evel/libs/x86_64
127 $ ../output/x86_64/evel_demo
128 evel_demo [--help]
129  --fqdn <domain>
130  --port <port_number>
131  [--path <path>]
132  [--topic <topic>]
133  [--username <username>]
134  [--password <password>]
135  [--https]
136  [--cycles <cycles>]
137  [--nothrott]
138 
139 Demonstrate use of the ECOMP Vendor Event Listener API.
140 
141  -h Display this usage message.
142  --help
143 
144  -f The FQDN or IP address to the RESTful API.
145  --fqdn
146 
147  -n The port number the RESTful API.
148  --port
149 
150  -p The optional path prefix to the RESTful API.
151  --path
152 
153  -t The optional topic part of the RESTful API.
154  --topic
155 
156  -u The optional username for basic authentication of requests.
157  --username
158 
159  -w The optional password for basic authentication of requests.
160  --password
161 
162  -s Use HTTPS rather than HTTP for the transport.
163  --https
164 
165  -c Loop <cycles> times round the main loop. Default = 1.
166  --cycles
167 
168  -v Generate much chattier logs.
169  --verbose
170 
171  -x Exclude throttling commands from demonstration.
172  --nothrott
173 
174 $
175 ```
176 Assuming that all worked as expected, you are ready to start integrating with
177 your application. It probably makes sense to make the LD_LIBRARY_PATH change
178 above permanent by incorporating it into your `.bash_profile` file.
179 
180 ### Project Documentation {#qs_build_docs}
181 
182 The source comes with its own documentation included. The documentation can be
183 built using the `docs` target in the Makefile. By default this builds HTML
184 and LaTeX documentation, the latter being used to prepare PDFs.
185 
186 To make the documentation:
187 ```
188 $ cd bldjobs
189 $ make docs
190 Cleaning docs...
191 Making Doxygen documentation
192 $
193 ```
194 
195 There is a make target that is intended to install the documentation on a
196 "team server" - it will need adaptation for your team's environment - see the
197 `docs_install` target in the Makefile:
198 
199 ```
200 $ make docs_install
201 Cleaning docs...
202 Making Doxygen documentation
203 Copying docs to team web-server...
204 Enter passphrase for key '/data/home/.ssh/id_rsa':
205 annotated.html 100% 8088 7.9KB/s 00:00
206 arrowdown.png 100% 246 0.2KB/s 00:00
207 arrowright.png 100% 229 0.2KB/s 00:00
208  ...
209 $
210 ```
211 
212 # Project Integration {#qs_integrate}
213 
214 There are two key steps to the integration which have to be undertaken:
215 
216  * Initialization/Termination of the library.
217  * Creation & posting of individual events.
218 
219 Additionally, it may be necessary to consider changes to the EVEL library's
220 source code if assumptions made by the library are either not satisfied or
221 inconvenient. In particular:
222 
223  * If the project already uses libcurl then the global initialization of the
224  library should be removed from the _EVEL Library_.
225  * The _EVEL Library_ uses `syslog` for event logging. If the project uses a
226  different event logging process, then EVEL's event logging macros should be
227  rewritten appropriately.
228 
229 These steps are considered in the [Normal Use](@ref qs_normal_use) and
230 [EVEL Adaptation](@ref qs_adaptation) sections below.
231 
232 ## Normal Use {#qs_normal_use}
233 
234 The _EVEL Library_ should be integrated with your project at a per-process
235 level: each process is an independent client of the ECOMP Vendor Event Listener
236 API.
237 
238 ### Initialization {#qs_initialize}
239 
240 The _EVEL Library_ should be initialized before the process becomes
241 multi-threaded. This constraint arises from the use of libcurl which imposes
242 the constraint that initialization occurs before the system is multi-threaded.
243 This is described in more detail in the libcurl documentation for the
244 [curl_global_init](https://curl.haxx.se/libcurl/c/curl_global_init.html)
245 function.
246 
247 Initialization stores configuration of the Vendor Event Listener API's details,
248 such as the FQDN or IP address of the service, so the initializing process must
249 have either extracted this information from its configuration or have this
250 information "hard-wired" into the application, so that it is available at the
251 point the `evel_initialize()` function is called:
252 
253 ```C
254  #include "evel.h"
255  ...
256  if (evel_initialize(api_fqdn,
257  api_port,
258  api_path,
259  api_topic,
260  api_secure,
261  "Alice",
262  "This isn't very secure!",
263  EVEL_SOURCE_VIRTUAL_MACHINE,
264  "EVEL demo client",
265  verbose_mode))
266  {
267  fprintf(stderr, "Failed to initialize the EVEL library!!!");
268  exit(-1);
269  }
270  ...
271 ```
272 Once initialization has occurred successfully, the application may raise events
273 and may also use the logging functions such as EVEL_INFO().
274 
275 Initialization is entirely local (there is no interaction with the service) so
276 it is very unlikely to fail, unless the application environment is seriously
277 degraded.
278 
279 ### Event Generation {#qs_generate}
280 
281 Generating events is a two stage process:
282 
283  1. Firstly, the _EVEL Library_ is called to allocate an event of the correct
284  type.
285  * If this is successful, the caller is given a pointer to the event.
286  * All mandatory fields on the event are provided to this factory function
287  and are thereafter immutable.
288  * The application may add any necessary optional fields to the event, using
289  the pointer previously returned.
290  2. The event is sent to the JSON API using the evel_post_event() function.
291  * At this point, the application relinquishes all responsibility for the
292  event:
293  * It will be posted to the JSON API, if possible.
294  * Whether or not the posting is successful, the memory used will be
295  freed.
296 
297 In practice this looks like:
298 
299 ```C
300  #include "evel.h"
301  ...
302 
303  /***************************************************************************/
304  /* Create a new Fault object, setting mandatory fields as we do so... */
305  /***************************************************************************/
306  fault = evel_new_fault("My alarm condition",
307  "It broke very badly",
308  EVEL_PRIORITY_NORMAL,
309  EVEL_SEVERITY_MAJOR);
310  if (fault != NULL)
311  {
312  /*************************************************************************/
313  /* We have a Fault object - add some optional fields to it... */
314  /*************************************************************************/
315  evel_fault_type_set(fault, "Bad things happen...");
316  evel_fault_interface_set(fault, "My Interface Card");
317  evel_fault_addl_info_add(fault, "name1", "value1");
318  evel_fault_addl_info_add(fault, "name2", "value2");
319 
320  /*************************************************************************/
321  /* Finally, post the Fault. In practice this will only ever fail if */
322  /* local ring-buffer is full because of event overload. */
323  /*************************************************************************/
324  evel_rc = evel_post_event((EVENT_HEADER *)fault);
325  if (evel_rc != EVEL_SUCCESS)
326  {
327  EVEL_ERROR("Post failed %d (%s)", evel_rc, evel_error_string());
328  }
329  }
330  ...
331 ```
332 ### Event Types {#qs_event_types}
333 
334 The _EVEL Library_ supports the following types of events:
335 
336  1. Faults
337 
338  These represent the **fault** domain in the event schema.
339 
340  2. Measurements
341 
342  These represent the **measurementsForVfScaling** domain in the event
343  schema.
344 
345  3. Reports
346 
347  This is an experimental type, designed to allow VNFs to report
348  application-level statistics unencumbered with platform measurements.
349  The formal AT&T schema has been updated to include this experimental
350  type as **measurementsForVfReporting**.
351 
352  4. Mobile Flow
353 
354  These represent the **mobileFlow** domain in the event schema.
355 
356  5. Other
357 
358  These represent the **other** domain in the event schema.
359 
360  6. Service Events
361 
362  These represent the **serviceEvents** domain in the event schema.
363 
364  7. Signaling
365 
366  These represent the **signaling** domain in the event schema.
367 
368  8. State Change
369 
370  These represent the **stateChange** domain in the event schema.
371 
372  9. Syslog
373 
374  These represent the **syslog** domain in the event schema.
375 
376 ### Throttling {#qs_throttling}
377 
378 The _EVEL library_ supports the following command types as defined in the JSON API:
379 
380  1. commandType: throttlingSpecification
381 
382  This is handled internally by the EVEL library, which stores the provided
383  throttling specification internally and applies it to all subsequent events.
384 
385  2. commandType: provideThrottlingState
386 
387  This is handled internally by the EVEL library, which returns the current
388  throttling specification for each domain.
389 
390  3. commandType: measurementIntervalChange
391 
392  This is handled by the EVEL library, which makes the latest measurement
393  interval available via the ::evel_get_measurement_interval function.
394  The application is responsible for checking and adhering to the latest
395  provided interval.
396 
397 ### Termination {#qs_termination}
398 
399 Termination of the _EVEL Library_ is swift and brutal! Events in the buffer
400 at the time are "dropped on the floor" rather than waiting for the buffer to
401 deplete first.
402 
403 ```C
404  #include "evel.h"
405  ...
406 
407  /***************************************************************************/
408  /* Shutdown the library. */
409  /***************************************************************************/
410  evel_terminate();
411 
412  ...
413 ```
414 
415 ## EVEL Adaptation {#qs_adaptation}
416 
417 The _EVEL Library_ is relatively simple and should be easy to adapt into other
418 project environments.
419 
420 ### LibcURL Lifecycle
421 
422 There are two circumstances where initialization of libcurl may be required:
423 
424  1. If libcurl is used by the project already, and therefore already takes
425  responsibility of its initialization, then the libcurl initialization and
426  termination functions should be removed from evel_initialize() and
427  evel_terminate() respectively.
428  2. If the project is unable to satisfy the constraint that libcurl
429  initialization takes place in a single-threaded environment at the point
430  that the _EVEL Library_ can be initialized (for example, if MT code is
431  necessary to read the configuration parameters required for
432  _EVEL Library_ initialization) then it may be necessary to extract the
433  libcurl functions and call them separately, earlier in the program's
434  operation.
435 
436 ### Event Logging
437 
438 The _EVEL Library_ uses `syslog` for logging. If this is inappropriate then
439 the log_debug() and log_initialize() functions should be rewritten accordingly.
440 
441 **Note**: it would be a really bad idea to use the _EVEL Library_ itself for this
442 logging function.
443 [Turtles all the way down...](https://en.wikipedia.org/wiki/Turtles_all_the_way_down)
444 
445