Initial VES for DANOS vRouter
[demo.git] / vnfs / VESreporting_vFW5.0_DANOS / evel / evel-library / code / evel_library / quickstart.md
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