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