First commit
[anna.git] / include / anna / core / oam / CounterManager.hpp
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 #ifndef anna_core_oam_CounterManager_hpp
38 #define anna_core_oam_CounterManager_hpp
39
40 #include <anna/core/functions.hpp>
41 #include <anna/core/Singleton.hpp>
42
43 #include <anna/timex/Timer.hpp>
44
45 #include <anna/core/oam/Counter.hpp>
46 #include <anna/core/oam/CounterScope.hpp>
47
48 namespace anna {
49
50 namespace xml {
51 class Node;
52 }
53
54 namespace timex {
55 class Engine;
56 }
57
58 namespace oam {
59
60 class CounterScope;
61 class CounterRecorder;
62 class CounterSummarizer;
63 class Counter;
64
65 /**
66    Gestor de contadores.
67
68    Mantiene la lista de ambitos y contadores definidas en nuestra aplicacion. Ademas establece
69    el periodo de grabacion de los contadores modificados.
70
71    El periodo de grabacion se iniciara cada vez que se incremente un contador.
72 */
73 class CounterManager : public Singleton <CounterManager> {
74 public:
75   static const int MaxScope = 100; /**< Numero maximo de ambitos */
76
77   /**
78      Destructor.
79   */
80   virtual ~CounterManager();
81
82   /**
83    * Devuelve el gestor de tiempos asociado al gestor de contadores.
84    * \return   el gestor de tiempos asociado al gestor de contadores.
85    */
86   timex::Engine* getEngine() throw() { return a_timeController; }
87
88   /**
89      Establece el gestor de tiempos usado para establecer el periodo de grabacion
90      de contadores.
91      \param timeController Gestor de tiempos usado para establecer el periodo de
92      grabacion de contadores.
93   */
94   void setEngine(timex::Engine* timeController) throw() { a_timeController = timeController; }
95
96   /**
97      Establece la instancia de la clase encargada de grabar el fichero con la informacion
98      de los contadores.
99      \param  counterRecorder Instancia encargada de grabar los contadores.
100      \warning Sera invocado automaticamente cuando se cumpla el periodo de grabacion indicado en
101      la configuracion de esta clase.
102
103   */
104   void setCounterRecorder(CounterRecorder* counterRecorder) throw() { a_counterRecorder = counterRecorder; }
105
106   /**
107      Establece la instancia de la clase encargada de calcular los contadores acumulados o
108      expresados en funcion de algunos otros.
109      \param  counterSummarizer Instancia encargada de calcular los contadores acumulados o
110      expresados en funcion de algunos otros.
111      \warning Sera invocado automaticamente cuando se cumpla el periodo de grabacion indicado en
112      la configuracion de esta clase.
113
114   */
115   void setCounterSummarizer(CounterSummarizer* counterSummarizer) throw() { a_counterSummarizer = counterSummarizer; }
116
117   /**
118      Establece el periodo de grabacion de los contadores. Por defecto sera 600000 (10 minutos).
119      \param millisecond Periodo de grabacion de contadores expresado en milisegundos.
120   */
121   void setRecordPeriod(const anna::Millisecond & millisecond) throw() { a_timer.setTimeout(millisecond); }
122
123   /**
124      Operador de acceso. El ambito solicitado deberia estar creado mediate #create.
125      \param scope Indica el numero de ambito al que deseamos acceder.
126      \return El ambito de contadores.
127   */
128   CounterScope& operator [](const int scope) throw(RuntimeException) { return find(scope); }
129
130   /**
131      Operador de acceso. El ambito solicitado deberia estar creado mediate #create.
132      \param scope Indica el numero de ambito al que deseamos acceder.
133      \return El ambito de contadores.
134   */
135   const CounterScope& operator [](const int scope) const throw(RuntimeException) { return find(scope); }
136
137   /**
138      Crea un nuevo ambito de contadores.
139      \param scope Índice del ambito. Debera ser menor de MaxScope.
140      \param name Nombre logico del ambito.
141      \param reuse Reusa el ambito si ya fue creado o da excepcion (por defecto).
142   */
143   CounterScope& create(const int scope, const char* name, bool reuse = false) throw(RuntimeException);
144
145   /**
146      Crea un nuevo ambito de contadores. Creara el ambito 0.
147      \param name Nombre logico del ambito.
148   */
149   CounterScope& create(const char* name) throw(RuntimeException) { return create(0, name); }
150
151   /**
152      Devuelve el ambito de contadores asociado al numero recibido como parametro.
153      El ambito solicitado deberia estar creado mediate #create.
154      \param scope Indica el numero de ambito al que deseamos acceder.
155      \return El ambito de contadores.
156   */
157   CounterScope& find(const int scope) throw(RuntimeException);
158
159   /**
160      Devuelve el ambito de contadores asociado al numero recibido como parametro.
161      El ambito solicitado deberia estar creado mediate #create.
162      \param scope Indica el numero de ambito al que deseamos acceder.
163      \return El ambito de contadores.
164   */
165   const CounterScope& find(const int scope) const throw(RuntimeException);
166
167   /**
168     Vuelca los contadores modificados desde la ultima llamada a este metodo.
169
170     \warning Si se ha establecido un anna::timex::Engine valido mediante la invocacion al
171     metodo #setEngine no seria necesario invocar a este metodo, ya que se invocara automaticamente
172     cuando se cumpla el periodo de grabacion establecido por la configuracion.
173   */
174   void record() throw(RuntimeException);
175
176   /**
177    * Devuelve la información relevante de esta instancia en un documento XML.
178    * \return la información relevante de esta instancia en un documento XML.
179    */
180   xml::Node* asXML(xml::Node* parent) const throw(RuntimeException);
181
182   /**
183      Incrementa la cuenta del contador identificador por (scope, counter)
184      El ambito solicitado deberia estar creado mediate #create, ademas el contador debera
185      estar creado mediante CounterScope::create.
186      \param scope Ámbito del contador.
187      \param counter Identificador del contador.
188      \param value Valor con el que incrementar el contador.
189   */
190   static void count(const int scope, const int counter, const oam::Counter::type_t value = 1) throw();
191
192   /**
193      Incrementa la cuenta del contador identificador por (scope = 0, counter)
194      El ambito solicitado deberia estar creado mediate #create, ademas el contador debera
195      estar creado mediante CounterScope::create.
196      \param counter Identificador del contador.
197   */
198   static void count(const int counter) { count(0, counter, 1); }
199
200 private:
201   class Timer : public timex::Timer {
202   public:
203     Timer(CounterManager& counterManager) :
204       timex::Timer("anna::oam:CounterManager::Timer", Millisecond(600000)),
205       a_counterManager(counterManager)
206     {;}
207
208   private:
209     CounterManager& a_counterManager;
210     void expire(timex::Engine *) throw(RuntimeException) { a_counterManager.record(); }
211   };
212
213   class RecordingGuard {
214   public:
215     RecordingGuard(CounterManager*);
216     ~RecordingGuard();
217   private:
218     CounterManager* a_counterManager;
219   };
220
221   CounterScope* a_scopes [MaxScope];
222   Timer a_timer;
223   timex::Engine* a_timeController;
224   CounterRecorder* a_counterRecorder;
225   CounterSummarizer* a_counterSummarizer;
226   bool a_recording;
227
228   CounterManager();
229   CounterManager(const CounterManager&);
230   void activateTimer() throw(RuntimeException);
231
232   friend class Singleton <CounterManager>;
233   friend class Timer;
234
235   friend class CounterScope;
236   // activateTimer
237
238   friend class RecordingGuard;
239 };
240
241 }
242 }
243
244 #endif
245