Updated license
[anna.git] / source / core / oam / Module.cpp
1 // ANNA - Anna is Not Nothingness 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 #include <anna/core/oam/CounterScope.hpp>
42 #include <anna/core/oam/CounterRecorder.hpp>
43
44 #include <anna/core/tracing/Logger.hpp>
45 #include <anna/core/tracing/TraceWriter.hpp>
46 #include <anna/core/tracing/TraceMethod.hpp>
47 #include <anna/core/functions.hpp>
48 #include <anna/xml/xml.hpp>
49
50 // Standard
51 #include <cstdarg>
52
53
54 #define UNDEFINED_EVENT_DESCRIPTION "<undefined>"
55
56
57 //******************************************************************************
58 //----------------------------------------------------------------------- Module
59 //******************************************************************************
60
61 //------------------------------------------------------------------------------
62 //-------------------------------------------------------------- Module::~Module
63 //------------------------------------------------------------------------------
64 anna::oam::Module::~Module() {
65   for(scope_iterator scope_it = scope_begin(); scope_it != scope_end(); scope_it++)
66     delete (scope(scope_it));
67 }
68
69
70 //------------------------------------------------------------------------------
71 //----------------------------------------------------------- Module::getScope()
72 //------------------------------------------------------------------------------
73 anna::oam::CounterScope *anna::oam::Module::getScope(const int &id) throw() {
74   scope_iterator it = scope_find(id);
75   return ((it != scope_end()) ? scope(it) : NULL);
76 }
77
78 ////------------------------------------------------------------------------------
79 ////------------------------------------------------------- Module::alarm_remove()
80 ////------------------------------------------------------------------------------
81 //bool anna::oam::Module::alarm_remove(const int &key) throw() {
82 //   alarm_iterator it = alarm_find(key);
83 //   if (it != alarm_end()) {
84 //      a_alarms.erase(key);
85 //      return true;
86 //   }
87 //
88 //   return false;
89 //}
90 //
91 ////------------------------------------------------------------------------------
92 ////----------------------------------------------------- Module::counter_remove()
93 ////------------------------------------------------------------------------------
94 //bool anna::oam::Module::counter_remove(const int &key) throw() {
95 //   counter_iterator it = counter_find(key);
96 //   if (it != counter_end()) {
97 //      a_counters.erase(key);
98 //      return true;
99 //   }
100 //
101 //   return false;
102 //}
103
104
105 // public:
106
107
108 //------------------------------------------------------------------------------
109 //----------------------------------------------------- Module::enableCounters()
110 //------------------------------------------------------------------------------
111 void anna::oam::Module::enableCounters(void) throw() {
112   a_counters_enabled = true;
113   LOGDEBUG(anna::Logger::debug("Scoped counters ENABLED", ANNA_FILE_LOCATION));
114 }
115
116
117 //------------------------------------------------------------------------------
118 //---------------------------------------------------- Module::disableCounters()
119 //------------------------------------------------------------------------------
120 void anna::oam::Module::disableCounters(void) throw() {
121   a_counters_enabled = false;
122   LOGDEBUG(anna::Logger::debug("Scoped counters DISABLED", ANNA_FILE_LOCATION));
123 }
124
125
126 //------------------------------------------------------------------------------
127 //------------------------------------------------------- Module::enableAlarms()
128 //------------------------------------------------------------------------------
129 void anna::oam::Module::enableAlarms(void) throw() {
130   a_alarms_enabled = true;
131   LOGDEBUG(anna::Logger::debug("Scoped alarms ENABLED", ANNA_FILE_LOCATION));
132 }
133
134
135 //------------------------------------------------------------------------------
136 //------------------------------------------------------ Module::disableAlarms()
137 //------------------------------------------------------------------------------
138 void anna::oam::Module::disableAlarms(void) throw() {
139   a_alarms_enabled = false;
140   LOGDEBUG(anna::Logger::debug("Scoped alarms DISABLED", ANNA_FILE_LOCATION));
141 }
142
143
144 //------------------------------------------------------------------------------
145 //------------------------------------------------ Module::enableAlarmsPreffix()
146 //------------------------------------------------------------------------------
147 void anna::oam::Module::enableAlarmsPreffix(void) throw() {
148   a_alarms_preffix_enabled = true;
149   LOGDEBUG(anna::Logger::debug("Alarm preffix module components SHOWN", ANNA_FILE_LOCATION));
150 }
151
152
153 //------------------------------------------------------------------------------
154 //------------------------------------------------- Module::enableAlarmsSuffix()
155 //------------------------------------------------------------------------------
156 void anna::oam::Module::enableAlarmsSuffix(void) throw() {
157   a_alarms_suffix_enabled = true;
158   LOGDEBUG(anna::Logger::debug("Alarm suffix module components SHOWN", ANNA_FILE_LOCATION));
159 }
160
161
162 //------------------------------------------------------------------------------
163 //----------------------------------------------- Module::disableAlarmsPreffix()
164 //------------------------------------------------------------------------------
165 void anna::oam::Module::disableAlarmsPreffix(void) throw() {
166   a_alarms_preffix_enabled = false;
167   LOGDEBUG(anna::Logger::debug("Alarm preffix module components HIDDEN", ANNA_FILE_LOCATION));
168 }
169
170
171 //------------------------------------------------------------------------------
172 //------------------------------------------------ Module::disableAlarmsSuffix()
173 //------------------------------------------------------------------------------
174 void anna::oam::Module::disableAlarmsSuffix(void) throw() {
175   a_alarms_suffix_enabled = false;
176   LOGDEBUG(anna::Logger::debug("Alarm suffix module components HIDDEN", ANNA_FILE_LOCATION));
177 }
178
179
180 //------------------------------------------------------------------------------
181 //--------------------------------- Module::getDefaultInternalAlarmDescription()
182 //------------------------------------------------------------------------------
183 std::string anna::oam::Module::getDefaultInternalAlarmDescription(const int & type) const throw() {
184   return UNDEFINED_EVENT_DESCRIPTION;
185 }
186
187
188 //------------------------------------------------------------------------------
189 //------------------------------- Module::getDefaultInternalCounterDescription()
190 //------------------------------------------------------------------------------
191 std::string anna::oam::Module::getDefaultInternalCounterDescription(const int & type) const throw() {
192   return UNDEFINED_EVENT_DESCRIPTION;
193 }
194
195
196 //------------------------------------------------------------------------------
197 //---------------------------------------------- Module::alarmComponentsToText()
198 //------------------------------------------------------------------------------
199 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() {
200   if(components.size() == 0) return ("");
201
202   std::vector<std::string>::const_iterator it_min(components.begin());
203   std::vector<std::string>::const_iterator it_max(components.end());
204   std::vector<std::string>::const_iterator it, it_last = it_max - 1;
205   std::string result = psL;
206
207   for(it = it_min; it != it_last; it++) { result += (*it); result += psS; }
208
209   result += (*it_last);
210   result += psR;
211   return (result);
212 }
213
214
215 //------------------------------------------------------------------------------
216 //------------------------------ Module::getAlarmPreffixSuffixAndZoneSeparator()
217 //------------------------------------------------------------------------------
218 void anna::oam::Module::getAlarmPreffixSuffixAndZoneSeparator(std::string & preffix, std::string & suffix, char & zS) const throw() {
219   Configuration &conf = Configuration::instantiate();
220   const std::vector<std::string> * globalPreffixComponents = conf.getAlarmPreffixComponents();
221   const std::vector<std::string> * globalSuffixComponents = conf.getAlarmSuffixComponents();
222   std::vector<std::string> preffixComponents, suffixComponents, compsAux;
223
224   if(globalPreffixComponents) preffixComponents = *globalPreffixComponents;
225
226   if(globalSuffixComponents) suffixComponents = *globalSuffixComponents;
227
228   if(a_alarms_preffix_enabled) {
229     // Read from virtual and append to global configuration ones:
230     readAlarmPreffixComponents(compsAux);
231
232     if(compsAux.size() != 0) preffixComponents.insert(preffixComponents.begin(), compsAux.begin(), compsAux.end());
233   }
234
235   if(a_alarms_suffix_enabled) {
236     // Read from virtual and append to global configuration ones:
237     compsAux.clear();
238     readAlarmSuffixComponents(compsAux);
239
240     if(compsAux.size() != 0) suffixComponents.insert(suffixComponents.begin(), compsAux.begin(), compsAux.end());
241   }
242
243   // Build final preffix and suffix from its components:
244   std::string psL, psS, psR;
245   conf.getAlarmTextDelimiters(zS, psL, psS, psR);
246   preffix = alarmComponentsToText(preffixComponents, psL, psS, psR);
247   suffix = alarmComponentsToText(suffixComponents, psL, psS, psR);
248 }
249
250
251
252
253 //------------------------------------------------------------------------------
254 //--------------------------------------------- Module::initializeCounterScope()
255 //------------------------------------------------------------------------------
256 void anna::oam::Module::initializeCounterScope(const int & scopeId, const std::string & description) throw(anna::RuntimeException) {
257   LOGMETHOD(anna::TraceMethod tttm("anna::oam::Module", "initializeCounterScope", ANNA_FILE_LOCATION));
258
259   // Order of use:
260   if(a_counters.size() != 0)  // any counter have been registered
261     throw anna::RuntimeException("After use of counter registration can't initialize more scope ids!. Do initializations firstly", ANNA_FILE_LOCATION);
262
263   // Scope range: 0 - 99
264   if(scopeId < 0 || scopeId >= MaxScope) {
265     std::string msg = "Scope Id must be in range [0 - ";
266     msg += anna::functions::asString(MaxScope - 1); // 99
267     msg += "]";
268     throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
269   }
270
271   // Check module scopes:
272   if(getScope(scopeId)) {
273     std::string msg = "Scope Id '";
274     msg += anna::functions::asString(scopeId);
275     msg += "' has already been registered in this module!";
276     throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
277   }
278
279   // Create scope:
280   bool missingScopeDescription = (description == "");
281   LOGWARNING(
282
283   if(missingScopeDescription && a_scopes.size() != 0) {
284   anna::Logger::warning("This is not the first initialized scope. Perhaps you should provide specific description better than general module name ...", ANNA_FILE_LOCATION);
285   }
286   );
287   const char * c_description = (missingScopeDescription ? getClassName() : description.c_str());
288   a_active_counter_scope = new CounterScope(scopeId, c_description);
289   a_scopes[scopeId] = a_active_counter_scope;
290 }
291
292
293 //------------------------------------------------------------------------------
294 //---------------------------------------------- Module::setActiveCounterScope()
295 //------------------------------------------------------------------------------
296 void anna::oam::Module::setActiveCounterScope(const int & scopeId) throw() {
297   anna::oam::CounterScope *scope = getScope(scopeId);
298
299   if(!scope) {
300     anna::Logger::error(anna::functions::asString("Provided scope id '%d' can't be activated, because you must initialize it first", scopeId), ANNA_FILE_LOCATION);
301     return;
302   }
303
304   a_active_counter_scope = scope;
305 }
306
307
308 //------------------------------------------------------------------------------
309 //---------------------------------------------------- Module::registerCounter()
310 //------------------------------------------------------------------------------
311 void anna::oam::Module::registerCounter(const int & type, const std::string & description, const int & offset) throw(anna::RuntimeException) {
312   // Handler-specific
313   a_handler->registerCounter(this, type, description, offset);
314
315   // Order of use:
316   if(a_scopes.size() == 0)  // at least one scope must be initialized
317     throw anna::RuntimeException("Before counter registration, at least one counter scope must be initialized at oam module", ANNA_FILE_LOCATION);
318
319   // Check type existence:
320   const_counter_iterator counter_it = counter_find(type);
321
322   if(counter_it != counter_end()) {
323     std::string msg = "There is a former counter registered with enum value (counter type) = ";
324     msg += anna::functions::asString(type);
325     throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
326   }
327
328   // If description is empty, get the default defined
329   std::string _description = ((description != "") ? description : getDefaultInternalCounterDescription(type));
330   counter_data_t aux;
331   aux.Offset = offset;
332   aux.Description = _description;
333   // Register for all initialized scopes:
334
335   for(scope_iterator scope_it = scope_begin(); scope_it != scope_end(); scope_it++) {
336     int scopeId = (*scope_it).first;
337     anna::oam::CounterScope * counterScope = scope(scope_it);
338     counterScope->create(offset, _description.c_str());
339     LOGDEBUG
340     (
341       std::string msg = "Added counter '";
342       msg += _description;
343       msg += "' over scope '";
344       msg += counterScope->getName();
345       msg += "': ScopeId/Offset [RealCounterId] = ";
346       msg += anna::functions::asString(scopeId); msg += "/";
347       msg += anna::functions::asString(offset); msg += " [";
348       msg += anna::functions::asString((scopeId * anna::oam::CounterScope::MaxCounter) + offset); msg += "]";
349       anna::Logger::debug(msg, ANNA_FILE_LOCATION);
350     );
351   }
352
353   a_counters[type] = aux;
354 }
355
356
357
358 //------------------------------------------------------------------------------
359 //------------------------------------------------------ Module::registerAlarm()
360 //------------------------------------------------------------------------------
361 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) {
362   // Handler-specific
363   a_handler->registerAlarm(this, type, description, externalId, dynamicVariablesCSL, activationId, cancellationId);
364   // Check type existence:
365   const_alarm_iterator alarm_it = alarm_find(type);
366
367   if(alarm_it != alarm_end()) {
368     std::string msg = "There is a former alarm registered with enum value (alarm type) = ";
369     msg += anna::functions::asString(type);
370     throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
371   }
372
373   // If description is empty, get the default defined
374   std::string _description = ((description != "") ? description : getDefaultInternalAlarmDescription(type));
375   alarm_data_t aux;
376   aux.ExternalId = externalId;
377   aux.DynamicVariablesCSL = dynamicVariablesCSL;
378   aux.ActivationId = activationId;
379   aux.CancellationId = cancellationId;
380   aux.Description = _description;
381   a_alarms[type] = aux;
382   LOGDEBUG
383   (
384     std::string msg = "Added alarm '";
385     msg += _description;
386     msg += "': externalId[dynamicVariablesCSL]/activationId";
387
388     if(cancellationId != -1) msg += "/cancellationId";
389     msg += " = ";
390     msg += anna::functions::asString(externalId); msg += "[";
391     msg += anna::functions::asString(dynamicVariablesCSL); msg += "]/";
392     msg += anna::functions::asString(activationId);
393   if(cancellationId != -1) {
394     msg += "/";
395     msg += anna::functions::asString(cancellationId);
396     }
397   anna::Logger::debug(msg, ANNA_FILE_LOCATION);
398   );
399 }
400
401
402 //------------------------------------------------------------------------------
403 //------------------------------------------------------ Module::activateAlarm()
404 //------------------------------------------------------------------------------
405 void anna::oam::Module::alarmEvent(bool activation, const int & type, va_list argList) const throw() {
406   // Preffix/Suffix and separator:
407   std::string userPreffix, userSuffix; char separator;
408   getAlarmPreffixSuffixAndZoneSeparator(userPreffix, userSuffix, separator);
409   const char *preffix = ((userPreffix != "") ? userPreffix.c_str() : NULL);
410   const char *suffix = ((userSuffix != "") ? userSuffix.c_str() : NULL);
411   va_list ap;
412   va_copy(ap, argList); // http://julipedia.meroh.net/2011/09/using-vacopy-to-safely-pass-ap.html
413   a_handler->alarmEvent(this, preffix, suffix, separator, activation, type, ap);
414   va_end(ap);
415 }
416
417
418 //------------------------------------------------------------------------------
419 //------------------------------------------------------ Module::activateAlarm()
420 //------------------------------------------------------------------------------
421 void anna::oam::Module::activateAlarm(const int & type, ...) const throw(anna::RuntimeException) {
422 //   LOGMETHOD(anna::TraceMethod tttm("anna::oam::Module", "activateAlarm", ANNA_FILE_LOCATION));
423
424   // Checkings
425   if(!a_alarms_enabled) {
426     LOGDEBUG
427     (
428       std::string msg = "Alarm activation ignored over module '";
429       msg += getClassName();
430       msg += "': alarms are disabled";
431       anna::Logger::debug(msg, ANNA_FILE_LOCATION);
432     );
433     return;
434   }
435
436   // User alarm event
437   va_list argList;
438   va_start(argList, type);
439   alarmEvent(true, type, argList);
440   va_end(argList);
441 }
442
443
444 //------------------------------------------------------------------------------
445 //-------------------------------------------------------- Module::cancelAlarm()
446 //------------------------------------------------------------------------------
447 void anna::oam::Module::cancelAlarm(const int & type, ...) const throw(anna::RuntimeException) {
448 //   LOGMETHOD(anna::TraceMethod tttm("anna::oam::Module", "cancelAlarm", ANNA_FILE_LOCATION));
449
450   // Checkings
451   if(!a_alarms_enabled) {
452     LOGDEBUG
453     (
454       std::string msg = "Alarm cancellation ignored over module '";
455       msg += getClassName();
456       msg += "': alarms are disabled";
457       anna::Logger::debug(msg, ANNA_FILE_LOCATION);
458     );
459     return;
460   }
461
462   // User alarm event
463   va_list argList;
464   va_start(argList, type);
465   alarmEvent(false, type, argList);
466   va_end(argList);
467 }
468
469
470 //------------------------------------------------------------------------------
471 //-------------------------------------------------------------- Module::count()
472 //------------------------------------------------------------------------------
473 void anna::oam::Module::count(const int & type, const int & amount) throw(anna::RuntimeException) {
474 //   LOGMETHOD(anna::TraceMethod tttm("anna::oam::Module", "count", ANNA_FILE_LOCATION));
475
476   // Checkings
477   if(!a_counters_enabled) {
478     LOGDEBUG
479     (
480       std::string msg = "Count operation ignored over module '";
481       msg += getClassName();
482       msg += "': counters are disabled";
483       anna::Logger::debug(msg, ANNA_FILE_LOCATION);
484     );
485     return;
486   }
487
488   a_handler->counterEvent(this, type, amount);
489 }
490
491
492 //------------------------------------------------------------------------------
493 //------------------------------------------------------ Module::resetCounters()
494 //------------------------------------------------------------------------------
495 int anna::oam::Module::resetCounters(const int & scopeId) throw() {
496   LOGMETHOD(anna::TraceMethod tttm("anna::oam::Module", "resetCounters", ANNA_FILE_LOCATION));
497   int result = 0; // affected number
498
499   for(scope_iterator scope_it = scope_begin(); scope_it != scope_end(); scope_it++)
500     result += scope(scope_it)->resetAccValues();
501
502   return result;
503 }
504
505
506 //------------------------------------------------------------------------------
507 //------------------------------------- Module::RecordingGuard::RecordingGuard()
508 //------------------------------------------------------------------------------
509 anna::oam::Module::RecordingGuard::RecordingGuard(anna::oam::Module* module) :
510   a_module(module) {                                                
511   module->a_counterRecording = true;                                               
512 }                                                                                   
513                                                                                     
514
515 //------------------------------------------------------------------------------
516 //------------------------------------ Module::RecordingGuard::~RecordingGuard()
517 //------------------------------------------------------------------------------
518 anna::oam::Module::RecordingGuard::~RecordingGuard() {                            
519   a_module->a_counterRecording = false;                                            
520 }                                                                                   
521
522
523 //------------------------------------------------------------------------------
524 //----------------------------------------------------- Module::recordCounters()
525 //------------------------------------------------------------------------------
526 void anna::oam::Module::recordCounters() throw(anna::RuntimeException) {
527   LOGMETHOD(anna::TraceMethod tttm("anna::oam::Module", "recordCounters", ANNA_FILE_LOCATION));
528
529   if(a_counterRecorder == NULL)
530     throw RuntimeException("anna::oam::Module has no counter recorder associated", ANNA_FILE_LOCATION);
531
532   LOGDEBUG(
533     std::string msg("Recording counters | ");
534     msg += a_counterRecorder->asString();
535     anna::Logger::write(Logger::Debug, msg, ANNA_FILE_LOCATION)
536   );
537   RecordingGuard guard(this);
538
539   a_counterRecorder->open();
540   Counter* counter = NULL;
541   CounterScope* cscope = NULL;
542
543   try {
544     for(scope_iterator scope_it = scope_begin(); scope_it != scope_end(); scope_it++) {
545       cscope = scope(scope_it);
546       if(cscope == NULL) continue;
547
548       Guard csGuard(cscope, "oam::CounterScope from oam::Module::record");
549
550       for(register int icounter = 0; icounter < CounterScope::MaxCounter; icounter ++) {
551         Counter* counter = cscope->a_counters [icounter];
552
553         if(counter == NULL)
554           continue;
555
556         if(counter->getValue() == 0)
557           continue;
558
559         a_counterRecorder->apply(*counter);
560         counter->reset();
561       }
562     }
563
564     a_counterRecorder->close();
565   } catch(anna::RuntimeException&) {
566     a_counterRecorder->close();
567     throw;
568   }
569 }
570
571 //------------------------------------------------------------------------------
572 //----------------------------------------------------------- Module::asString()
573 //------------------------------------------------------------------------------
574 std::string anna::oam::Module::asString(void) const throw() {
575   std::string trace;
576   trace = "Module name: '";
577   trace += getClassName();
578   trace += "'";
579   trace += "\n\nCOUNTERS"; trace += "\n--------";
580   trace += "\nScoped counters "; trace += a_counters_enabled ? "Enabled" : "Disabled";
581   trace += "\nCounter Scopes: "; trace += anna::functions::asString(a_scopes.size());
582
583   for(const_scope_iterator scope_it = scope_begin(); scope_it != scope_end(); scope_it++) {
584     trace += "\n\nCounter Scope:";
585     int scopeId = (*scope_it).first;
586     trace += " Id: "; trace += anna::functions::asString(scopeId);
587     trace += " | Description: '"; trace += scope(scope_it)->getName(); trace += "'";
588     trace += "\nRegistered counters:\n";
589     counter_data_t * ptrCounterData;
590
591     for(const_counter_iterator cnt_it = counter_begin(); cnt_it != counter_end(); cnt_it++) {
592       ptrCounterData = (counter_data_t *) & ((*cnt_it).second);
593       // Counter:
594       trace += "\n\tType: "; trace += anna::functions::asString((*cnt_it).first);
595       trace += " | Description: '"; trace += ptrCounterData->Description; trace += "'";
596       int offset = ptrCounterData->Offset;
597       int realId = (1000 * scopeId) + offset;
598       trace += " | ScopeId/Offset: "; trace += anna::functions::asString(scopeId); trace += "/"; trace += anna::functions::asString(offset);
599       trace += " | RealId: "; trace += anna::functions::asString(realId);
600       unsigned long long int accValue = scope(scope_it)->getAccValue(offset);
601
602       if(accValue != 0ULL) {
603         trace += " | AccumulatedAmount: ";
604         trace += anna::functions::asString("%llu", accValue);
605       }
606     }
607   }
608
609   trace += "\n\nALARMS"; trace += "\n------";
610   trace += "\nScoped alarms "; trace += a_alarms_enabled ? "Enabled" : "Disabled";
611   trace += "\nPreffix alarm components: "; trace += a_alarms_preffix_enabled ? "Shown" : "Hidden";
612   trace += "\nSuffix alarm components: "; trace += a_alarms_suffix_enabled ? "Shown" : "Hidden";
613   trace += "\nRegistered alarms:\n";
614
615   for(const_alarm_iterator alrm_it = alarm_begin(); alrm_it != alarm_end(); alrm_it++) {
616     int cancellationId = (*alrm_it).second.CancellationId;
617     bool transferable = (cancellationId != -1);
618     trace += "\n\tType: "; trace += anna::functions::asString((*alrm_it).first);
619     trace += " | Description: '"; trace += (*alrm_it).second.Description;
620     trace += transferable ? "' [transferable alarm]" : "'";
621     trace += " | DatabaseId: "; trace += anna::functions::asString((*alrm_it).second.ExternalId);
622     trace += " | dynamicVariablesCSL: "; trace += (*alrm_it).second.DynamicVariablesCSL;
623     trace += " | ActivationId: "; trace += anna::functions::asString((*alrm_it).second.ActivationId);
624
625     if(transferable) { trace += " | CancellationId: "; trace += anna::functions::asString(cancellationId); }
626   }
627
628   return (trace);
629 }
630
631
632
633 //------------------------------------------------------------------------------
634 //-------------------------------------------------------------- Module::asXML()
635 //------------------------------------------------------------------------------
636 anna::xml::Node* anna::oam::Module::asXML(anna::xml::Node* parent) const throw() {
637   anna::xml::Node* result = parent->createChild("oam.Module");
638   result->createAttribute("Name", getClassName());
639   result->createAttribute("Counters", a_counters_enabled ? "Enabled" : "Disabled");
640   anna::xml::Node* registeredCounterScopes = result->createChild("RegisteredCounterScopes");
641
642   for(const_scope_iterator scope_it = scope_begin(); scope_it != scope_end(); scope_it++) {
643     // Scope:
644     anna::xml::Node* scopeNode = registeredCounterScopes->createChild("Scope");
645     int scopeId = (*scope_it).first;
646     scopeNode->createAttribute("Id", anna::functions::asString(scopeId));
647     scopeNode->createAttribute("Description", scope(scope_it)->getName());
648     // Counters:
649     anna::xml::Node* registeredCounters = scopeNode->createChild("RegisteredCounters");
650     counter_data_t * ptrCounterData;
651
652     for(const_counter_iterator cnt_it = counter_begin(); cnt_it != counter_end(); cnt_it++) {
653       ptrCounterData = (counter_data_t *) & ((*cnt_it).second);
654       // Counter:
655       anna::xml::Node* counter = registeredCounters->createChild("Counter");
656       counter->createAttribute("Type", anna::functions::asString((*cnt_it).first));
657       counter->createAttribute("Description", ptrCounterData->Description);
658       int offset = ptrCounterData->Offset;
659       int realId = (1000 * scopeId) + offset;
660       counter->createAttribute("ScopeId", anna::functions::asString(scopeId));
661       counter->createAttribute("Offset", anna::functions::asString(offset));
662       counter->createAttribute("RealId", anna::functions::asString(realId));
663       unsigned long long int accValue = scope(scope_it)->getAccValue(offset);
664
665       if(accValue != 0ULL)
666         counter->createAttribute("AccumulatedAmount", anna::functions::asString("%llu", accValue));
667     }
668   }
669
670   result->createAttribute("Alarms", a_alarms_enabled ? "Enabled" : "Disabled");
671   result->createAttribute("PreffixAlarmComponents", a_alarms_preffix_enabled ? "Shown" : "Hidden");
672   result->createAttribute("SuffixAlarmComponents", a_alarms_suffix_enabled ? "Shown" : "Hidden");
673   anna::xml::Node* registeredAlarms = result->createChild("RegisteredAlarms");
674
675   for(const_alarm_iterator alrm_it = alarm_begin(); alrm_it != alarm_end(); alrm_it++) {
676     anna::xml::Node* alarm;
677     int cancellationId = (*alrm_it).second.CancellationId;
678     bool transferable = (cancellationId != -1);
679     alarm  = registeredAlarms->createChild("Alarm");
680     alarm->createAttribute("Type", anna::functions::asString((*alrm_it).first));
681     std::string desc = (*alrm_it).second.Description; desc += " ["; desc += transferable ? "transferable]" : "non transferable]";
682     alarm->createAttribute("Description", desc);
683     alarm->createAttribute("DatabaseId", anna::functions::asString((*alrm_it).second.ExternalId));
684     alarm->createAttribute("DynamicVariablesCSL", (*alrm_it).second.DynamicVariablesCSL);
685     alarm->createAttribute("ActivationId", anna::functions::asString((*alrm_it).second.ActivationId));
686
687     if(transferable) alarm->createAttribute("CancellationId", anna::functions::asString(cancellationId));
688   }
689
690   return result;
691 }
692