7d370b5961861abfdffdadc6f54d5d47a005dd22
[anna.git] / include / anna / comm / Server.hpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite                           //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
7
8
9 #ifndef anna_comm_Server_hpp
10 #define anna_comm_Server_hpp
11
12 #include <vector>
13 #include <algorithm>
14
15 #include <anna/config/defines.hpp>
16
17 #include <anna/comm/Resource.hpp>
18
19 namespace anna {
20
21 namespace xml {
22 class Node;
23 }
24
25 namespace comm {
26
27 class Host;
28 class TransportFactory;
29 class Service;
30 class Message;
31 class INetAddress;
32 class ClientSocket;
33 class ServerAllocator;
34 class ReceiverFactory;
35
36 /**
37    Clase que modela los procesos servidores. Cada maquina (ver Host) contiene un numero indeterminado de
38    procesos servidores a los que puede enviar peticiones, bien directamente, o bien a traves del
39    sistema de reparto de carga.
40
41    Para facilitar el diseo de soluciones HA cada servidor puede tener un numero indeterminado por donde
42    recibe/envia peticiones, es por esto que cada servidor puede tener asociado un numero indeterminado
43    de instancias de la clase RemoteConnection.
44
45    La instanciacion de procesos servidores se hara mediante la invocacion al metodo Host::createServer.
46
47    \warning Este metodo no hace que nuestro proceso se convierta en un servidor, sino que conecta
48    nuestra aplicacion a un servidor remoto.
49
50    @see Host::createServer
51    @see Service
52 */
53 class Server : public Resource {
54 public:
55   typedef std::vector <Service*> Services;
56   typedef Services::iterator iterator;
57   typedef Services::const_iterator const_iterator;
58
59   /**
60      Destructor.
61   */
62   virtual ~Server();
63
64   /**
65      Devuelve la instancia del Host indicada en el constructor.
66      \return la instancia del Host indicada en el constructor.
67   */
68   const Host* getHost() const throw() { return &a_host; }
69
70   /**
71      Devuelve la instancia de ClientSocket asociada a este servidor. Puede ser NULL.
72      \return la instancia de ClientSocket asociada a este servidor.
73   */
74   const ClientSocket* getClientSocket() const throw() { return a_clientSocket; }
75
76   /**
77      Devuelve el puerto remoto donde establece las conexiones este proceso servidor.
78      \return El puerto remoto donde establece las conexiones este proceso servidor.
79   */
80   int getRemotePort() const throw() { return a_remotePort; }
81
82   /**
83      Devuelve el estado del indicador de recuperacin automatica. En caso de perder la conexin, por defecto,
84      siempre se intentara reconectar con el servidor.
85      \return El estado del indicador de recuperacin automatica.
86   */
87   bool autoRecovery() const throw() { return a_autoRecovery; }
88
89   /**
90      Configura el estado del indicador de recuperacin automatica. En caso de perder la conexin, por defecto,
91      siempre se intentara reconectar con el servidor.
92      \param autoRecovery Indicador de recuperacin automatica.
93   */
94   void setAutoRecovery(bool autoRecovery = true) throw();
95
96   /**
97      Devuelve el estado activo o inactivo de este proceso servidor. Un proceso servidor estara
98      activo si ha conseguido establecer el socket con el proceso remoto que representa por alguno
99      de los sockets cliente establecidos.
100
101      @return \em true si el proceso servidor esta preparado para enviar peticiones o \em false
102      en otro caso.
103   */
104   bool isAvailable() const throw(RuntimeException);
105
106   /**
107      Devuelve la factoria de transporte indicada en el constructor.
108      \return la factoria de transporte indicada en el constructor.
109   */
110   TransportFactory* getTransportFactory() throw() { return a_transportFactory; }
111
112   /**
113      Devuelve el numero maximo de milisegundos esperados para obtener conexion al invocar
114      al metodo #connect.
115      \return el numero maximo de milisegundos esperados para obtener conexion al invocar
116      al metodo #connect.
117   */
118   const Millisecond &getMaxConnectionDelay() const throw() { return a_msMaxConnectionDelay; }
119
120   /**
121      Devuelve el numero maximo de milisegundos que queda bloqueado el proceso/thread a la espera
122      de escribir en un socket cuyo buffer de salida esta lleno.
123      \return Devuelve el numero maximo de milisegundos que queda bloqueado el proceso/thread a la espera
124      de escribir en un socket cuyo buffer de salida esta lleno.
125   */
126   const Millisecond &getMaxWriteDelay() const throw() { return a_msMaxWriteDelay; }
127
128   /**
129      Devuelve la factoria de receptores usada por este servidor.
130      \return la factoria de receptores usada por este servidor.
131   */
132   ReceiverFactory* getReceiverFactory() throw() { return a_receiverFactory; }
133
134   /**
135      Establece el numero maximo de milisegundos esperados para obtener la conexion al
136      invocar al metodo #connect.
137      \param msMaxConnectionDelay Numero de milisegundos esperados para obtener conexion.
138   */
139   void setMaxConnectionDelay(const Millisecond &msMaxConnectionDelay)
140   throw() {
141     a_msMaxConnectionDelay = msMaxConnectionDelay;
142   }
143
144   /**
145      Establece el numero maximo de milisegundos que queda bloqueado el proceso/thread a la espera
146      de escribir en un socket cuyo buffer de salida esta lleno.
147
148      \param msMaxWriteDelay Numero de milisegundos esperados en caso de que el buffer del socket se llene.
149   */
150   void setMaxWriteDelay(const Millisecond &msMaxWriteDelay) throw() { a_msMaxWriteDelay = msMaxWriteDelay; }
151
152   /**
153      Establece la factoria de receptores usada por este socket.
154      \param receiverFactory Factoria de receptores desde la que obtener el receptor asociado al
155      comm::ClientSocket usado por este servidor.
156   */
157   void setReceiverFactory(ReceiverFactory& receiverFactory) throw();
158
159   /**
160    * Devuelve \em true si el indicador que ignora los mensajes entrantes está activo, o \em false en otro caso.
161    * \return \em true si el indicador que ignora los mensajes entrantes está activo, o \em false en otro caso.
162    */
163   bool getIgnoreIncomingMessages() const throw() { return a_ignoreIncomingMessages; }
164
165   /**
166    * Establece el indicador que provoca ignorar los mensajes entrantes.
167    * \param ignoreIncomingMessages \em true si el indicador que ignora los mensajes entrantes está activo, o \em false en otro caso.
168    */
169   void setIgnoreIncomingMessages(const bool ignoreIncomingMessages) throw() { a_ignoreIncomingMessages = ignoreIncomingMessages; }
170
171   /**
172      Asocia este servidor con un servicio de reparto.
173      \param service Servicio de reparto al que vamos a relacionar este servicio.
174      \warning se invoca automatica desde
175   */
176   void attach(Service* service)
177   throw(RuntimeException) {
178     if(std::find(begin(), end(), service) == end())
179       a_services.push_back(service);
180   }
181
182   /**
183      Crea una conexion al servidor mediante algunas de las conexiones que deberian estar
184      disponibles en la maquina asociada a este servidor.
185   */
186   void connect() throw(RuntimeException);
187
188   /**
189      Envia el mensaje recibido como parametro. El bloque de datos recibido se codifica segun las
190      reglas establecidas por el protocolo asociado en el contructor.
191
192      \param message Mensaje vamos codificar para enviar a la capa de transporte.
193
194      \return La instancia del ClientSocket usada para enviar el mensaje.
195   */
196   ClientSocket* send(Message& message) throw(RuntimeException);
197
198   /**
199      Envia el mensaje recibido como parametro. El bloque de datos recibido se codifica segun las
200      reglas establecidas por el protocolo asociado en el contructor.
201
202      \param message Mensaje vamos codificar para enviar a la capa de transporte.
203
204      \return La instancia del ClientSocket usada para enviar el mensaje.
205   */
206   ClientSocket* send(Message* message) throw(RuntimeException);
207
208   /**
209      Libera el RemoteConnection asociado a esta instancia. Se invoca automaticamente
210      cuando el extremo remoto cierra la conexion.
211   */
212   void reset() throw(RuntimeException);
213
214   /**
215      Devuelve un iterador al comienzo de la lista de RemoteConnections asociados a este proceso servidor.
216      \return Un iterador al comienzo de la lista de RemoteConnections asociados a este proceso servidor.
217   */
218   const_iterator begin() const throw() { return a_services.begin(); }
219
220   /**
221      Devuelve un iterador al final de la lista de RemoteConnections asociados a este proceso servidor.
222      \return Un iterador al final de la lista de RemoteConnections asociados a este proceso servidor.
223   */
224   const_iterator end() const throw() { return a_services.end(); }
225
226   /**
227      Devuelve un iterador al comienzo de la lista de RemoteConnections asociados a este proceso servidor.
228      \return Un iterador al comienzo de la lista de RemoteConnections asociados a este proceso servidor.
229   */
230   iterator begin() throw() { return a_services.begin(); }
231
232   /**
233      Devuelve un iterador al final de la lista de RemoteConnections asociados a este proceso servidor.
234      \return Un iterador al final de la lista de RemoteConnections asociados a este proceso servidor.
235   */
236   iterator end() throw() { return a_services.end(); }
237
238   /**
239      Devuelve una cadena con la informacion referente a este proceso servidor.
240      @return Una cadena con la informacion referente a este proceso servidor.
241   */
242   std::string asString() const throw();
243
244   /**
245      Devuelve un nodo XML con la informacion referente a este objeto.
246      \param parent Nodo XML a partir del cual introducir la informacion.
247      \return Un nodo XML con la informacion referente a este objeto.
248   */
249   xml::Node* asXML(xml::Node* parent) const throw(RuntimeException);
250
251   /**
252      Devuelve la instancia del RemoteConnection sobre el que esta posicionado el iterador recibido
253      como parametro.
254      \param ii Iterador que debera estar comprendido entre begin y end.
255      \return La instancia del RemoteConnection sobre el que esta posicionado el iterador recibido
256   */
257   static Service* service(iterator& ii) throw() { return *ii; }
258
259   /**
260      Devuelve la instancia del RemoteConnection sobre el que esta posicionado el iterador recibido
261      como parametro.
262      \param ii Iterador que debera estar comprendido entre begin y end.
263      \return La instancia del RemoteConnection sobre el que esta posicionado el iterador recibido
264   */
265   static const Service* service(const_iterator& ii) throw() { return *ii; }
266
267   /**
268      Devuelve el nombre logico de esta clase.
269      \return el nombre logico de esta clase.
270   */
271   static const char* className() throw() { return "anna::comm::Server"; }
272
273 protected:
274   /**
275      Constructor.
276
277      \param name Nombre logico del servidor.
278      \param host Instancia de la maquina sobre la que esta atendiento peticiones.
279      \param remotePort Puerto sobre el que atiende peticiones.
280      \param autoRecovery Indica si en caso de caida se debe intenrar la recuperacion
281      automatica de la conexion.
282      \param transportFactory Factoria de protocolos de transporte usada por los ClientSocket asociados a este
283      proceso servidor.
284   */
285   Server(const std::string& name, const Host& host, const int remotePort, const bool autoRecovery, TransportFactory* transportFactory);
286
287 private:
288   const Host& a_host;
289   const int a_remotePort;
290   const bool a_autoRecovery;
291   Services a_services;
292   TransportFactory* a_transportFactory;
293   ClientSocket* a_clientSocket;
294   Millisecond a_msMaxConnectionDelay;
295   Millisecond a_msMaxWriteDelay;
296   ReceiverFactory* a_receiverFactory;
297   bool a_ignoreIncomingMessages;
298   int a_sequence;
299
300   virtual ClientSocket* allocateClientSocket(const INetAddress&, TransportFactory*) const throw();
301
302   friend class Host;
303   friend class ServerAllocator;
304 };
305
306 }
307 }
308
309 #endif