Updated license
[anna.git] / include / anna / comm / Host.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_Host_hpp
38 #define anna_comm_Host_hpp
39
40 #include <algorithm>
41 #include <vector>
42 #include <map>
43 #include <string>
44
45 #include <anna/core/mt/Mutex.hpp>
46 #include <anna/core/util/MultiMap.hpp>
47
48 namespace anna {
49
50 namespace xml {
51 class Node;
52 }
53
54 namespace comm {
55
56 class Communicator;
57 class Server;
58 class TransportFactory;
59 class Device;
60 class Network;
61 class ServerAllocator;
62
63 /**
64    Clase que modela una maquina en la que se ejecutan procesos servidores. Cada maquina contiene
65    un nmero indeterminado de procesos servidores (ver Server) a los que enviar peticiones, bien
66    directamente, o bien a traves del un sistema de reparto de carga.
67
68    Para crear una nueva maquina hay que invocar a Network::find(const char*) o Network::find(const std::string&).
69
70    \see Server
71    \see Service
72    \see Network::find
73 */
74 class Host : public Mutex {
75
76   typedef int Port;
77
78   // Requerido por Forte C++
79 //   struct Comparator;
80 //   friend struct Comparator;
81
82
83   struct SortBy {
84     static int value(const Server* server) throw();
85   };
86
87   std::string a_name;
88
89 public:
90
91   typedef std::vector <const Device*> device_container;
92   typedef device_container::const_iterator const_device_iterator; /**<Iterador para acceder a los dispositivo de red de la maquina */
93
94   typedef MultiMap <Server, SortBy> server_container;
95
96   typedef server_container::iterator server_iterator; /**<Iterador para acceder a los Servidores asociados a cada uno de los puertos en esta maquina. */
97   typedef server_container::const_iterator const_server_iterator; /**<Iterador para acceder a los Servidores asociados a cada uno de los puertos en esta maquina. */
98
99
100   /**
101      Destructor.
102   */
103   virtual ~Host();
104
105   /**
106      Devuelve el nombre logico de esta maquina.
107
108      @return El nombre logico de esta maquina.
109   */
110   const std::string& getName() const throw() { return a_name; }
111
112   /**
113      Crea y registra un nuevo proceso servidor sobre esta maquina (maquina, remotePort) con el nombre indicado.
114
115      @param name Nombre logico del proceso servidor.
116      @param remotePort Puerto remoto en el que atiende peticiones este proceso servidor.
117      \param autoRecovery Indica si en caso de caida se debe intenrar la recuperacion
118      automatica de la conexion.
119      \param transportFactory Factoria de protocolos de transporte usada por los ClientSocket asociados a este
120      proceso servidor.
121      \param ignoreIncomingMessages Indicador de ignorar mensajes entrantes.
122      \param doConnect Indicador de connectar al servidor en el momento de crearlo.
123
124      @return La instancia del nuevo proceso servidor
125   */
126   Server* createServer(const char* name, const int remotePort, const bool autoRecovery, TransportFactory* transportFactory = NULL, const bool ignoreIncomingMessages = false, const bool doConnect = true)
127   throw(RuntimeException) {
128     return createServer(std::string(name), remotePort, autoRecovery, transportFactory, ignoreIncomingMessages, doConnect);
129   }
130
131   /**
132      Crea y registra un nuevo proceso servidor sobre esta maquina (maquina, remotePort) con el nombre indicado.
133
134      @param name Nombre logico del proceso servidor.
135      @param remotePort Puerto remoto en el que atiende peticiones este proceso servidor.
136      \param autoRecovery Indica si en caso de caida se debe intentar la recuperacion
137      automatica de la conexion.
138      \param transportFactory Factoria de protocolos de transporte usada por los ClientSocket asociados a este
139      proceso servidor.
140      \param ignoreIncomingMessages Indicador de ignorar mensajes entrantes.
141      \param doConnect Indicador de connectar al servidor en el momento de crearlo.
142
143      @return La instancia del nuevo proceso servidor
144   */
145   Server* createServer(const std::string& name, const int remotePort, const bool autoRecovery, TransportFactory* transportFactory = NULL, const bool ignoreIncomingMessages = false, const bool doConnect = true)
146   throw(RuntimeException);
147
148   /**
149      Crea y registra un nuevo proceso servidor sobre esta maquina (maquina, remotePort) con el nombre indicado.
150
151      \param serverAllocator Instanciador de Server utilizado para crear la instancia del Server.
152
153      @return La instancia del nuevo proceso servidor
154   */
155   Server* createServer(const ServerAllocator& serverAllocator) throw(RuntimeException);
156
157   /**
158      Devuelve un iterador al comienzo de la lista de servidores asociados a esta maquina.
159      \return Un iterador al comienzo de la lista de servidores asociados a esta maquina.
160   */
161   server_iterator server_begin() throw() { return a_servers.begin(); }
162
163   /**
164      Devuelve un iterador al comienzo de la lista de servidores asociados a esta maquina.
165      \return Un iterador al comienzo de la lista de servidores asociados a esta maquina.
166   */
167   const_server_iterator server_begin() const throw() { return a_servers.begin(); }
168
169   /**
170      Devuelve un iterador al comienzo de la lista de servidores asociados a esta maquina.
171      \return Un iterador al final de la lista de servidores asociados a esta maquina.
172   */
173   server_iterator server_end() throw() { return a_servers.end(); }
174
175   /**
176      Devuelve un iterador al comienzo de la lista de servidores asociados a esta maquina.
177      \return Un iterador al final de la lista de servidores asociados a esta maquina.
178   */
179   const_server_iterator server_end() const throw() { return a_servers.end(); }
180
181   /**
182      Devuelve la instancia del servidor sobre el que esta posicionado el iterador recibido
183      como parametro.
184      \param ii Iterador que debera estar comprendido entre begin y end.
185      \return La instancia del servidor sobre el que esta posicionado el iterador recibido
186   */
187   static Server* server(server_iterator ii) throw() { return server_container::data(ii); }
188
189   /**
190      Devuelve la instancia del servidor sobre el que esta posicionado el iterador recibido
191      como parametro.
192      \param ii Iterador que debera estar comprendido entre begin y end.
193      \return La instancia del servidor sobre el que esta posicionado el iterador recibido
194   */
195   static const Server* server(const_server_iterator ii) throw() { return server_container::data(ii); }
196
197
198   /**
199      Devuelve un iterador al comienzo de la lista de direcciones IPs asociadas a esta maquina.
200      \return Un iterador al comienzo de la lista de direcciones IPs asociadas a esta maquina.
201   */
202   const_device_iterator device_begin() const throw() { return a_devices.begin(); }
203
204   /**
205      Devuelve un iterador al final de la lista de direcciones IPs asociadas a esta maquina.
206      \return Un iterador al final de la lista de direcciones IPs asociadas a esta maquina.
207   */
208   const_device_iterator device_end() const throw() { return a_devices.end(); }
209
210   /**
211      Devuelve la instancia de la IP sobre el que esta posicionado el iterador recibido
212      como parametro.
213      \param ii Iterador que debera estar comprendido entre begin y end.
214      \return La instancia de la sobre el que esta posicionado el iterador recibido
215   */
216   static const Device* device(const_device_iterator ii) throw() { return *ii; }
217
218   /**
219    * Devuelve la instancia del proceso servidor asociado al puerto recibido como parametro. Si
220    * hay más de una conexión sobre el mismo puerto sólo devolverá la primera.
221    *
222    * @param remotePort Puerto remoto en el que atiende peticiones este proceso servidor.
223    *
224    * @return La instancia del proceso servidor asociado al puerto recibido. Puede ser NULL si no
225    * hay ningn proceso servidor asociado con el puerto recibido.
226    *
227    * @see #createServer
228    */
229   const Server* find_server(const int remotePort) const throw();
230
231   /**
232    * Devuelve la instancia del proceso servidor asociado al puerto recibido como parametro. Si
233    * hay más de una conexión sobre el mismo puerto sólo devolverá la primera.
234    *
235    * @param remotePort Puerto remoto en el que atiende peticiones este proceso servidor.
236    *
237    * @return La instancia del proceso servidor asociado al puerto recibido. Puede ser NULL si no
238    * hay ningn proceso servidor asociado con el puerto recibido.
239    *
240    * @see #createServer
241    */
242   Server* find_server(const int remotePort) throw();
243   /**
244      Incorpora un dispositivo de red.
245      \param device Dispositivo de red a incorporar.
246   */
247   void assign(const Device* device) throw(RuntimeException);
248
249   /**
250      Devuelve \em true si el dispositivo de red recibido fue asignado a esta maquina o \em
251      false en otro caso.
252      \param device Dispositivo de red a comprobar.
253      \return \em true si el dispositivo de red recibido fue asignado a esta maquina o \em
254      false en otro caso.
255      \see #assign
256   */
257   bool contains(const Device* device) const
258   throw() {
259     const_device_iterator end = device_end();
260     return (std::find(device_begin(), end, device) != end);
261   }
262
263   /**
264      Devuelve una cadena con la informacin referente a esta maquina.
265      @return Una cadena con la informacin referente a esta maquina.
266   */
267   std::string asString() const throw();
268
269   /**
270      Devuelve un nodo XML con la informacin referente a este objeto.
271      \param parent Nodo XML a partir del cual introducir la informacin.
272      \return Un nodo XML con la informacin referente a este objeto.
273   */
274   xml::Node* asXML(xml::Node* parent) const throw(RuntimeException);
275
276
277 protected:
278   /**
279      Constructor.
280      \param name Nombre logico de esta maquina.
281      \warning Cualquier clase heredada que invoque a este constructor debe evitar el acceso
282      al metodo #createServer.
283   */
284   Host(const char* name) : a_name(name) {}
285
286 private:
287   device_container a_devices;
288   server_container a_servers;
289
290   Server* add(Server*, const int remotePort, const bool doConnect) throw();
291
292   friend class Network;
293 };
294
295 }
296 }
297
298 #endif