First commit
[anna.git] / source / core / oam / Module.cpp
1 // ANNA - Anna is Not 'N' Anymore
2 //
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
4 //
5 // https://bitbucket.org/testillano/anna
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
9 // are met:
10 //
11 //     * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 //     * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 //     * Neither the name of Google Inc. nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
33 // Authors: eduardo.ramos.testillano@gmail.com
34 //          cisco.tierra@gmail.com
35
36
37 // Local
38 #include <anna/core/oam/Module.hpp>
39 #include <anna/core/functions.hpp>
40 #include <anna/core/oam/Configuration.hpp>
41
42 #include <anna/core/tracing/Logger.hpp>
43 #include <anna/core/tracing/TraceWriter.hpp>
44 #include <anna/core/tracing/TraceMethod.hpp>
45 #include <anna/core/functions.hpp>
46 #include <anna/xml/xml.hpp>
47 #include <anna/core/oam/CounterManager.hpp>
48
49 // Standard
50 #include <stdarg.h>
51
52
53 #define UNDEFINED_EVENT_DESCRIPTION "<undefined>"
54
55
56 //******************************************************************************
57 //----------------------------------------------------------------------- Module
58 //******************************************************************************
59
60 //------------------------------------------------------------------------------
61 //----------------------------------------------------------- Module::getScope()
62 //------------------------------------------------------------------------------
63 anna::oam::CounterScope *anna::oam::Module::getScope(const int &id) throw() {
64   scope_iterator it = scope_find(id);
65   return ((it != scope_end()) ? scope(it) : NULL);
66 }
67
68 ////------------------------------------------------------------------------------
69 ////------------------------------------------------------- Module::alarm_remove()
70 ////------------------------------------------------------------------------------
71 //bool anna::oam::Module::alarm_remove(const int &key) throw() {
72 //   alarm_iterator it = alarm_find(key);
73 //   if (it != alarm_end()) {
74 //      a_alarms.erase(key);
75 //      return true;
76 //   }
77 //
78 //   return false;
79 //}
80 //
81 ////------------------------------------------------------------------------------
82 ////----------------------------------------------------- Module::counter_remove()
83 ////------------------------------------------------------------------------------
84 //bool anna::oam::Module::counter_remove(const int &key) throw() {
85 //   counter_iterator it = counter_find(key);
86 //   if (it != counter_end()) {
87 //      a_counters.erase(key);
88 //      return true;
89 //   }
90 //
91 //   return false;
92 //}
93
94
95 // public:
96
97
98 //------------------------------------------------------------------------------
99 //----------------------------------------------------- Module::enableCounters()
100 //------------------------------------------------------------------------------
101 void anna::oam::Module::enableCounters(void) throw() {
102   a_counters_enabled = true;
103   LOGDEBUG(anna::Logger::debug("Scoped counters ENABLED", ANNA_FILE_LOCATION));
104 }
105
106
107 //------------------------------------------------------------------------------
108 //---------------------------------------------------- Module::disableCounters()
109 //------------------------------------------------------------------------------
110 void anna::oam::Module::disableCounters(void) throw() {
111   a_counters_enabled = false;
112   LOGDEBUG(anna::Logger::debug("Scoped counters DISABLED", ANNA_FILE_LOCATION));
113 }
114
115
116 //------------------------------------------------------------------------------
117 //------------------------------------------------------- Module::enableAlarms()
118 //------------------------------------------------------------------------------
119 void anna::oam::Module::enableAlarms(void) throw() {
120   a_alarms_enabled = true;
121   LOGDEBUG(anna::Logger::debug("Scoped alarms ENABLED", ANNA_FILE_LOCATION));
122 }
123
124
125 //------------------------------------------------------------------------------
126 //------------------------------------------------------ Module::disableAlarms()
127 //------------------------------------------------------------------------------
128 void anna::oam::Module::disableAlarms(void) throw() {
129   a_alarms_enabled = false;
130   LOGDEBUG(anna::Logger::debug("Scoped alarms DISABLED", ANNA_FILE_LOCATION));
131 }
132
133
134 //------------------------------------------------------------------------------
135 //------------------------------------------------ Module::enableAlarmsPreffix()
136 //------------------------------------------------------------------------------
137 void anna::oam::Module::enableAlarmsPreffix(void) throw() {
138   a_alarms_preffix_enabled = true;
139   LOGDEBUG(anna::Logger::debug("Alarm preffix module components SHOWN", ANNA_FILE_LOCATION));
140 }
141
142
143 //------------------------------------------------------------------------------
144 //------------------------------------------------- Module::enableAlarmsSuffix()
145 //------------------------------------------------------------------------------
146 void anna::oam::Module::enableAlarmsSuffix(void) throw() {
147   a_alarms_suffix_enabled = true;
148   LOGDEBUG(anna::Logger::debug("Alarm suffix module components SHOWN", ANNA_FILE_LOCATION));
149 }
150
151
152 //------------------------------------------------------------------------------
153 //----------------------------------------------- Module::disableAlarmsPreffix()
154 //------------------------------------------------------------------------------
155 void anna::oam::Module::disableAlarmsPreffix(void) throw() {
156   a_alarms_preffix_enabled = false;
157   LOGDEBUG(anna::Logger::debug("Alarm preffix module components HIDDEN", ANNA_FILE_LOCATION));
158 }
159
160
161 //------------------------------------------------------------------------------
162 //------------------------------------------------ Module::disableAlarmsSuffix()
163 //------------------------------------------------------------------------------
164 void anna::oam::Module::disableAlarmsSuffix(void) throw() {
165   a_alarms_suffix_enabled = false;
166   LOGDEBUG(anna::Logger::debug("Alarm suffix module components HIDDEN", ANNA_FILE_LOCATION));
167 }
168
169
170 //------------------------------------------------------------------------------
171 //--------------------------------- Module::getDefaultInternalAlarmDescription()
172 //------------------------------------------------------------------------------
173 std::string anna::oam::Module::getDefaultInternalAlarmDescription(const int & type) const throw() {
174   return UNDEFINED_EVENT_DESCRIPTION;
175 }
176
177
178 //------------------------------------------------------------------------------
179 //------------------------------- Module::getDefaultInternalCounterDescription()
180 //------------------------------------------------------------------------------
181 std::string anna::oam::Module::getDefaultInternalCounterDescription(const int & type) const throw() {
182   return UNDEFINED_EVENT_DESCRIPTION;
183 }
184
185
186 //------------------------------------------------------------------------------
187 //---------------------------------------------- Module::alarmComponentsToText()
188 //------------------------------------------------------------------------------
189 std::string anna::oam::Module::alarmComponentsToText(const std::vector<std::string> & components, const std::string & psL, const std::string & psS, const std::string & psR) const throw() {
190   if(components.size() == 0) return ("");
191
192   std::vector<std::string>::const_iterator it_min(components.begin());
193   std::vector<std::string>::const_iterator it_max(components.end());
194   std::vector<std::string>::const_iterator it, it_last = it_max - 1;
195   std::string result = psL;
196
197   for(it = it_min; it != it_last; it++) { result += (*it); result += psS; }
198
199   result += (*it_last);
200   result += psR;
201   return (result);
202 }
203
204
205 //------------------------------------------------------------------------------
206 //------------------------------ Module::getAlarmPreffixSuffixAndZoneSeparator()
207 //------------------------------------------------------------------------------
208 void anna::oam::Module::getAlarmPreffixSuffixAndZoneSeparator(std::string & preffix, std::string & suffix, char & zS) const throw() {
209   Configuration &conf = Configuration::instantiate();
210   const std::vector<std::string> * globalPreffixComponents = conf.getAlarmPreffixComponents();
211   const std::vector<std::string> * globalSuffixComponents = conf.getAlarmSuffixComponents();
212   std::vector<std::string> preffixComponents, suffixComponents, compsAux;
213
214   if(globalPreffixComponents) preffixComponents = *globalPreffixComponents;
215
216   if(globalSuffixComponents) suffixComponents = *globalSuffixComponents;
217
218   if(a_alarms_preffix_enabled) {
219     // Read from virtual and append to global configuration ones:
220     readAlarmPreffixComponents(compsAux);
221
222     if(compsAux.size() != 0) preffixComponents.insert(preffixComponents.begin(), compsAux.begin(), compsAux.end());
223   }
224
225   if(a_alarms_suffix_enabled) {
226     // Read from virtual and append to global configuration ones:
227     compsAux.clear();
228     readAlarmSuffixComponents(compsAux);
229
230     if(compsAux.size() != 0) suffixComponents.insert(suffixComponents.begin(), compsAux.begin(), compsAux.end());
231   }
232
233   // Build final preffix and suffix from its components:
234   std::string psL, psS, psR;
235   conf.getAlarmTextDelimiters(zS, psL, psS, psR);
236   preffix = alarmComponentsToText(preffixComponents, psL, psS, psR);
237   suffix = alarmComponentsToText(suffixComponents, psL, psS, psR);
238 }
239
240
241
242
243 //------------------------------------------------------------------------------
244 //--------------------------------------------- Module::initializeCounterScope()
245 //------------------------------------------------------------------------------
246 void anna::oam::Module::initializeCounterScope(const int & scopeId, const std::string & description) throw(anna::RuntimeException) {
247   LOGMETHOD(anna::TraceMethod tttm("anna::oam::Module", "initializeCounterScope", ANNA_FILE_LOCATION));
248
249   // Order of use:
250   if(a_counters.size() != 0)  // any counter have been registered
251     throw anna::RuntimeException("After use of counter registration can't initialize more scope ids!. Do initializations firstly", ANNA_FILE_LOCATION);
252
253   // Scope range: 0 - 99
254   if(scopeId < 0 || scopeId >= anna::oam::CounterManager::MaxScope) {
255     std::string msg = "Scope Id must be in range [0 - ";
256     msg += anna::functions::asString(anna::oam::CounterManager::MaxScope - 1); // 99
257     msg += "]";
258     throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
259   }
260
261   // Check module scopes:
262   if(getScope(scopeId)) {
263     std::string msg = "Scope Id '";
264     msg += anna::functions::asString(scopeId);
265     msg += "' has already been registered in this module!";
266     throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
267   }
268
269   // Create scope:
270   bool missingScopeDescription = (description == "");
271   LOGWARNING(
272
273   if(missingScopeDescription && a_scopes.size() != 0) {
274   anna::Logger::warning("This is not the first initialized scope. Perhaps you should provide specific description better than general module name ...", ANNA_FILE_LOCATION);
275   }
276   );
277   const char * c_description = (missingScopeDescription ? getClassName() : description.c_str());
278   a_active_counter_scope = &(anna::oam::CounterManager::instantiate().create(scopeId, c_description, true /* reuses */));
279   a_scopes[scopeId] = a_active_counter_scope;
280 }
281
282
283 //------------------------------------------------------------------------------
284 //---------------------------------------------- Module::setActiveCounterScope()
285 //------------------------------------------------------------------------------
286 void anna::oam::Module::setActiveCounterScope(const int & scopeId) throw() {
287   anna::oam::CounterScope *scope = getScope(scopeId);
288
289   if(!scope) {
290     anna::Logger::error(anna::functions::asString("Provided scope id '%d' can't be activated, because you must initialize it first", scopeId), ANNA_FILE_LOCATION);
291     return;
292   }
293
294   a_active_counter_scope = scope;
295 }
296
297
298 //------------------------------------------------------------------------------
299 //---------------------------------------------------- Module::registerCounter()
300 //------------------------------------------------------------------------------
301 void anna::oam::Module::registerCounter(const int & type, const std::string & description, const int & offset) throw(anna::RuntimeException) {
302   // Handler-specific
303   a_handler->registerCounter(this, type, description, offset);
304
305   // Order of use:
306   if(a_scopes.size() == 0)  // at least one scope must be initialized
307     throw anna::RuntimeException("Before counter registration, at least one counter scope must be initialized at oam module", ANNA_FILE_LOCATION);
308
309   // Check type existence:
310   const_counter_iterator counter_it = counter_find(type);
311
312   if(counter_it != counter_end()) {
313     std::string msg = "There is a former counter registered with enum value (counter type) = ";
314     msg += anna::functions::asString(type);
315     throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
316   }
317
318   // If description is empty, get the default defined
319   std::string _description = ((description != "") ? description : getDefaultInternalCounterDescription(type));
320   counter_data_t aux;
321   aux.Offset = offset;
322   aux.Description = _description;
323   // Register for all initialized scopes:
324
325   for(scope_iterator scope_it = scope_begin(); scope_it != scope_end(); scope_it++) {
326     int scopeId = (*scope_it).first;
327     anna::oam::CounterScope * counterScope = scope(scope_it);
328     counterScope->create(offset, _description.c_str());
329     LOGDEBUG
330     (
331       std::string msg = "Added counter '";
332       msg += _description;
333       msg += "' over scope '";
334       msg += counterScope->getName();
335       msg += "': ScopeId/Offset [RealCounterId] = ";
336       msg += anna::functions::asString(scopeId); msg += "/";
337       msg += anna::functions::asString(offset); msg += " [";
338       msg += anna::functions::asString((scopeId * anna::oam::CounterScope::MaxCounter) + offset); msg += "]";
339       anna::Logger::debug(msg, ANNA_FILE_LOCATION);
340     );
341   }
342
343   a_counters[type] = aux;
344 }
345
346
347
348 //------------------------------------------------------------------------------
349 //------------------------------------------------------ Module::registerAlarm()
350 //------------------------------------------------------------------------------
351 void anna::oam::Module::registerAlarm(const int & type, const std::string &description, const int & externalId, const std::string & dynamicVariablesCSL, const int & activationId, const int & cancellationId) throw(anna::RuntimeException) {
352   // Handler-specific
353   a_handler->registerAlarm(this, type, description, externalId, dynamicVariablesCSL, activationId, cancellationId);
354   // Check type existence:
355   const_alarm_iterator alarm_it = alarm_find(type);
356
357   if(alarm_it != alarm_end()) {
358     std::string msg = "There is a former alarm registered with enum value (alarm type) = ";
359     msg += anna::functions::asString(type);
360     throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
361   }
362
363   // If description is empty, get the default defined
364   std::string _description = ((description != "") ? description : getDefaultInternalAlarmDescription(type));
365   alarm_data_t aux;
366   aux.ExternalId = externalId;
367   aux.DynamicVariablesCSL = dynamicVariablesCSL;
368   aux.ActivationId = activationId;
369   aux.CancellationId = cancellationId;
370   aux.Description = _description;
371   a_alarms[type] = aux;
372   LOGDEBUG
373   (
374     std::string msg = "Added alarm '";
375     msg += _description;
376     msg += "': externalId[dynamicVariablesCSL]/activationId";
377
378     if(cancellationId != -1) msg += "/cancellationId";
379     msg += " = ";
380     msg += anna::functions::asString(externalId); msg += "[";
381     msg += anna::functions::asString(dynamicVariablesCSL); msg += "]/";
382     msg += anna::functions::asString(activationId);
383   if(cancellationId != -1) {
384     msg += "/";
385     msg += anna::functions::asString(cancellationId);
386     }
387   anna::Logger::debug(msg, ANNA_FILE_LOCATION);
388   );
389 }
390
391
392 //------------------------------------------------------------------------------
393 //------------------------------------------------------ Module::activateAlarm()
394 //------------------------------------------------------------------------------
395 void anna::oam::Module::alarmEvent(bool activation, const int & type, va_list argList) const throw() {
396   // Preffix/Suffix and separator:
397   std::string userPreffix, userSuffix; char separator;
398   getAlarmPreffixSuffixAndZoneSeparator(userPreffix, userSuffix, separator);
399   const char *preffix = ((userPreffix != "") ? userPreffix.c_str() : NULL);
400   const char *suffix = ((userSuffix != "") ? userSuffix.c_str() : NULL);
401   va_list ap;
402   va_copy(ap, argList); // http://julipedia.meroh.net/2011/09/using-vacopy-to-safely-pass-ap.html
403   a_handler->alarmEvent(this, preffix, suffix, separator, activation, type, ap);
404   va_end(ap);
405 }
406
407
408 //------------------------------------------------------------------------------
409 //------------------------------------------------------ Module::activateAlarm()
410 //------------------------------------------------------------------------------
411 void anna::oam::Module::activateAlarm(const int & type, ...) const throw(anna::RuntimeException) {
412 //   LOGMETHOD(anna::TraceMethod tttm("anna::oam::Module", "activateAlarm", ANNA_FILE_LOCATION));
413
414   // Checkings
415   if(!a_alarms_enabled) {
416     LOGDEBUG
417     (
418       std::string msg = "Alarm activation ignored over module '";
419       msg += getClassName();
420       msg += "': alarms are disabled";
421       anna::Logger::debug(msg, ANNA_FILE_LOCATION);
422     );
423     return;
424   }
425
426   // User alarm event
427   va_list argList;
428   va_start(argList, type);
429   alarmEvent(true, type, argList);
430   va_end(argList);
431 }
432
433
434 //------------------------------------------------------------------------------
435 //-------------------------------------------------------- Module::cancelAlarm()
436 //------------------------------------------------------------------------------
437 void anna::oam::Module::cancelAlarm(const int & type, ...) const throw(anna::RuntimeException) {
438 //   LOGMETHOD(anna::TraceMethod tttm("anna::oam::Module", "cancelAlarm", ANNA_FILE_LOCATION));
439
440   // Checkings
441   if(!a_alarms_enabled) {
442     LOGDEBUG
443     (
444       std::string msg = "Alarm cancellation ignored over module '";
445       msg += getClassName();
446       msg += "': alarms are disabled";
447       anna::Logger::debug(msg, ANNA_FILE_LOCATION);
448     );
449     return;
450   }
451
452   // User alarm event
453   va_list argList;
454   va_start(argList, type);
455   alarmEvent(false, type, argList);
456   va_end(argList);
457 }
458
459
460 //------------------------------------------------------------------------------
461 //-------------------------------------------------------------- Module::count()
462 //------------------------------------------------------------------------------
463 void anna::oam::Module::count(const int & type, const int & amount) throw(anna::RuntimeException) {
464 //   LOGMETHOD(anna::TraceMethod tttm("anna::oam::Module", "count", ANNA_FILE_LOCATION));
465
466   // Checkings
467   if(!a_counters_enabled) {
468     LOGDEBUG
469     (
470       std::string msg = "Count operation ignored over module '";
471       msg += getClassName();
472       msg += "': counters are disabled";
473       anna::Logger::debug(msg, ANNA_FILE_LOCATION);
474     );
475     return;
476   }
477
478   a_handler->counterEvent(this, type, amount);
479 }
480
481
482 //------------------------------------------------------------------------------
483 //------------------------------------------------------ Module::resetCounters()
484 //------------------------------------------------------------------------------
485 int anna::oam::Module::resetCounters(const int & scopeId) throw() {
486   LOGMETHOD(anna::TraceMethod tttm("anna::oam::Module", "resetCounters", ANNA_FILE_LOCATION));
487   int result = 0; // affected number
488
489   for(scope_iterator scope_it = scope_begin(); scope_it != scope_end(); scope_it++)
490     result += scope(scope_it)->resetAccValues();
491
492   return result;
493 }
494
495
496 //------------------------------------------------------------------------------
497 //----------------------------------------------------------- Module::asString()
498 //------------------------------------------------------------------------------
499 std::string anna::oam::Module::asString(void) const throw() {
500   std::string trace;
501   trace = "Module name: '";
502   trace += getClassName();
503   trace += "'";
504   trace += "\n\nCOUNTERS"; trace += "\n--------";
505   trace += "\nScoped counters "; trace += a_counters_enabled ? "Enabled" : "Disabled";
506   trace += "\nCounter Scopes: "; trace += anna::functions::asString(a_scopes.size());
507
508   for(const_scope_iterator scope_it = scope_begin(); scope_it != scope_end(); scope_it++) {
509     trace += "\n\nCounter Scope:";
510     int scopeId = (*scope_it).first;
511     trace += " Id: "; trace += anna::functions::asString(scopeId);
512     trace += " | Description: '"; trace += scope(scope_it)->getName(); trace += "'";
513     trace += "\nRegistered counters:\n";
514     counter_data_t * ptrCounterData;
515
516     for(const_counter_iterator cnt_it = counter_begin(); cnt_it != counter_end(); cnt_it++) {
517       ptrCounterData = (counter_data_t *) & ((*cnt_it).second);
518       // Counter:
519       trace += "\n\tType: "; trace += anna::functions::asString((*cnt_it).first);
520       trace += " | Description: '"; trace += ptrCounterData->Description; trace += "'";
521       int offset = ptrCounterData->Offset;
522       int realId = (1000 * scopeId) + offset;
523       trace += " | ScopeId/Offset: "; trace += anna::functions::asString(scopeId); trace += "/"; trace += anna::functions::asString(offset);
524       trace += " | RealId: "; trace += anna::functions::asString(realId);
525       unsigned long long int accValue = scope(scope_it)->getAccValue(offset);
526
527       if(accValue != 0ULL) {
528         trace += " | AccumulatedAmount: ";
529         trace += anna::functions::asString("%llu", accValue);
530       }
531     }
532   }
533
534   trace += "\n\nALARMS"; trace += "\n------";
535   trace += "\nScoped alarms "; trace += a_alarms_enabled ? "Enabled" : "Disabled";
536   trace += "\nPreffix alarm components: "; trace += a_alarms_preffix_enabled ? "Shown" : "Hidden";
537   trace += "\nSuffix alarm components: "; trace += a_alarms_suffix_enabled ? "Shown" : "Hidden";
538   trace += "\nRegistered alarms:\n";
539
540   for(const_alarm_iterator alrm_it = alarm_begin(); alrm_it != alarm_end(); alrm_it++) {
541     int cancellationId = (*alrm_it).second.CancellationId;
542     bool transferable = (cancellationId != -1);
543     trace += "\n\tType: "; trace += anna::functions::asString((*alrm_it).first);
544     trace += " | Description: '"; trace += (*alrm_it).second.Description;
545     trace += transferable ? "' [transferable alarm]" : "'";
546     trace += " | DatabaseId: "; trace += anna::functions::asString((*alrm_it).second.ExternalId);
547     trace += " | dynamicVariablesCSL: "; trace += (*alrm_it).second.DynamicVariablesCSL;
548     trace += " | ActivationId: "; trace += anna::functions::asString((*alrm_it).second.ActivationId);
549
550     if(transferable) { trace += " | CancellationId: "; trace += anna::functions::asString(cancellationId); }
551   }
552
553   return (trace);
554 }
555
556
557
558 //------------------------------------------------------------------------------
559 //-------------------------------------------------------------- Module::asXML()
560 //------------------------------------------------------------------------------
561 anna::xml::Node* anna::oam::Module::asXML(anna::xml::Node* parent) const throw() {
562   anna::xml::Node* result = parent->createChild("oam.Module");
563   result->createAttribute("Name", getClassName());
564   result->createAttribute("Counters", a_counters_enabled ? "Enabled" : "Disabled");
565   anna::xml::Node* registeredCounterScopes = result->createChild("RegisteredCounterScopes");
566
567   for(const_scope_iterator scope_it = scope_begin(); scope_it != scope_end(); scope_it++) {
568     // Scope:
569     anna::xml::Node* scopeNode = registeredCounterScopes->createChild("Scope");
570     int scopeId = (*scope_it).first;
571     scopeNode->createAttribute("Id", anna::functions::asString(scopeId));
572     scopeNode->createAttribute("Description", scope(scope_it)->getName());
573     // Counters:
574     anna::xml::Node* registeredCounters = scopeNode->createChild("RegisteredCounters");
575     counter_data_t * ptrCounterData;
576
577     for(const_counter_iterator cnt_it = counter_begin(); cnt_it != counter_end(); cnt_it++) {
578       ptrCounterData = (counter_data_t *) & ((*cnt_it).second);
579       // Counter:
580       anna::xml::Node* counter = registeredCounters->createChild("Counter");
581       counter->createAttribute("Type", anna::functions::asString((*cnt_it).first));
582       counter->createAttribute("Description", ptrCounterData->Description);
583       int offset = ptrCounterData->Offset;
584       int realId = (1000 * scopeId) + offset;
585       counter->createAttribute("ScopeId", anna::functions::asString(scopeId));
586       counter->createAttribute("Offset", anna::functions::asString(offset));
587       counter->createAttribute("RealId", anna::functions::asString(realId));
588       unsigned long long int accValue = scope(scope_it)->getAccValue(offset);
589
590       if(accValue != 0ULL)
591         counter->createAttribute("AccumulatedAmount", anna::functions::asString("%llu", accValue));
592     }
593   }
594
595   result->createAttribute("Alarms", a_alarms_enabled ? "Enabled" : "Disabled");
596   result->createAttribute("PreffixAlarmComponents", a_alarms_preffix_enabled ? "Shown" : "Hidden");
597   result->createAttribute("SuffixAlarmComponents", a_alarms_suffix_enabled ? "Shown" : "Hidden");
598   anna::xml::Node* registeredAlarms = result->createChild("RegisteredAlarms");
599
600   for(const_alarm_iterator alrm_it = alarm_begin(); alrm_it != alarm_end(); alrm_it++) {
601     anna::xml::Node* alarm;
602     int cancellationId = (*alrm_it).second.CancellationId;
603     bool transferable = (cancellationId != -1);
604     alarm  = registeredAlarms->createChild("Alarm");
605     alarm->createAttribute("Type", anna::functions::asString((*alrm_it).first));
606     std::string desc = (*alrm_it).second.Description; desc += " ["; desc += transferable ? "transferable]" : "non transferable]";
607     alarm->createAttribute("Description", desc);
608     alarm->createAttribute("DatabaseId", anna::functions::asString((*alrm_it).second.ExternalId));
609     alarm->createAttribute("DynamicVariablesCSL", (*alrm_it).second.DynamicVariablesCSL);
610     alarm->createAttribute("ActivationId", anna::functions::asString((*alrm_it).second.ActivationId));
611
612     if(transferable) alarm->createAttribute("CancellationId", anna::functions::asString(cancellationId));
613   }
614
615   return result;
616 }
617