Changed LICENSE. Now referenced to web site and file on project root directory
[anna.git] / include / anna / diameter.comm / Engine.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_diameter_comm_Engine_hpp
10 #define anna_diameter_comm_Engine_hpp
11
12
13 // STL
14 #include <map>
15 #include <string>
16 #include <algorithm>
17
18 #include <anna/app/Component.hpp>
19 #include <anna/core/util/Recycler.hpp>
20
21 #include <anna/diameter.comm/Server.hpp>
22 #include <anna/diameter.comm/ServerSession.hpp>
23 #include <anna/config/defines.hpp>
24 #include <anna/diameter.comm/ClientSession.hpp>
25 #include <anna/diameter.comm/ServerSession.hpp>
26
27 // Standard
28 #include <time.h>
29
30
31 //------------------------------------------------------------------------------
32 //---------------------------------------------------------------------- #define
33 //------------------------------------------------------------------------------
34
35 namespace anna {
36 class DataBlock;
37 class Millisecond;
38 }
39
40
41
42 namespace anna {
43
44 namespace diameter {
45
46 namespace codec {
47 class Engine;
48 }
49
50 namespace comm {
51
52
53 class Entity;
54 class Server;
55 class LocalServer;
56
57 /**
58  *  General manager for connections to several diameter servers and from diameter clients.
59  *
60  *  Optimizes creation, finding and releasing of established client-sessions to a certain number of
61  *  diameter servers through entities.
62  *  Optimizes creation, finding and releasing of established server-sessions from a certain number of
63  *  diameter clients through local servers.
64  *
65  *  Implementation example:
66  *
67  *  \code
68  *
69  *     class MyEngine : public diameter::comm::Engine {
70  *     public:
71  *        MyEngine () {;}
72  *
73  *     private:
74  *        anna::Recycler<MyEntity> a_entities;
75  *
76  *        anna::diameter::comm::Entity* allocateEntity () throw () { return a_entities.create (); }
77  *
78  *        void releaseEntity (anna::diameter::comm::Entity* entity) throw () {
79  *           MyEntity* aux = static_cast <MyEntity*> (entity);
80  *           a_entities.release (aux);
81  *        }
82  *
83  *
84  *        anna::diameter::comm::LocalServer* allocateLocalServer () throw () { return a_localServers.create (); }
85  *
86  *        void releaseLocalServer (anna::diameter::comm::LocalServer* localServer) throw () {
87  *           MyLocalServer* aux = static_cast <MyLocalServer*> (localServer);
88  *           a_localServers.release (aux);
89  *        }
90  *     };
91  *
92  *  \endcode
93  */
94 class Engine : public anna::app::Component {
95 public:
96
97   /**
98      Logical name for this anna::app::Component.
99      \return Logical name for this anna::app::Component.
100   */
101   static const char* getClassName() throw() { return "anna::diameter::comm::Engine"; }
102
103   /**
104      Diameter application node realm name (used to be the site domain name).
105
106      @param name Diameter application node realm name. Used in order to configure the Origin-Realm for outgoing messages.
107      If not configured or empty string provided, host domainname will be set.
108   */
109   void setRealm(const std::string & name) throw();
110
111
112   /**
113      Gets the configured diameter application node realm name.
114
115      @return Diameter application node realm name.
116   */
117   const std::string & getRealm() const throw() { return a_realm; }
118
119
120   /**
121      Diameter application host name as solved by #anna::functions::getHostname()
122
123      @param name Host name. Used in order to configure the Origin-Host for outgoing messages.
124      If not configured or empty string provided, hostname (system name) will be set.
125   */
126   void setHost(const std::string & name) throw();
127
128
129   /**
130      Gets the configured diameter application host name.
131
132      @return Diameter application host name.
133   */
134   const std::string & getHost() const throw() { return a_host; }
135
136
137   /**
138    * Propagate auto recovery configuration to entities within engine. Recovery period is configured at
139    * #anna::comm::Communicator::setRecoveryTime. All the client client-sessions created throught #createEntity,
140    * will be created based on the engine auto-recovery value (enable by default). But you could access entities,
141    * servers or client-sessions independently to change this behaviour.
142    *
143    * @param autoRecovery Auto recovery indicator. True by default.
144    */
145   void raiseAutoRecovery(bool autoRecovery = true) throw(anna::RuntimeException);
146
147   /**
148    * Returns automatic bind indicator for client-sessions. By default \em true will be used.
149    * \return Value for automatic connection bind.
150    */
151   bool getAutoBind() const throw() { return a_autoBind; }
152
153   /**
154    * Sets automatic connection bind indicator for client-sessions. If not asigned, it will be \em true.
155    * \param autoBind Value for automatic connection bind.
156    *
157    * In order to change bind timer, first client-session must be created without autobind, modify time
158    * parameter and then invoking bind.
159    */
160   void setAutoBind(const bool autoBind) throw() { a_autoBind = autoBind; }
161
162   /**
163      Sets the milliseconds wait to achieve a client connection to server by mean connect primitive.
164      This is a general value for born client-sessions over engine. Particular configuration could be done
165      through #ClientSession::setMaxConnectionDelay.
166
167      \param maxConnectionDelay Milliseconds wait to get connection
168   */
169   void setMaxConnectionDelay(const anna::Millisecond & maxConnectionDelay) throw() { a_maxConnectionDelay = maxConnectionDelay; }
170
171   /**
172      Gets the milliseconds wait to achieve a client connection to server by mean connect primitive.
173      Returns the global engine value, but it could be overwritten through each client session (#ClientSession::setMaxConnectionDelay).
174      Default value is 'anna::comm::ClientSocket::DefaultMaxConnectionDelay'.
175
176      \return Milliseconds wait to get connection
177   */
178   const anna::Millisecond & getMaxConnectionDelay() throw() { return a_maxConnectionDelay; }
179
180   /**
181    * Binds engine entities.
182    *
183    * @return Returns true if all client-session were successfully bound
184    */
185   bool bind() throw(anna::RuntimeException);
186
187   /**
188    * Sets CER and DWR diameter messages to be used over created client-sessions.
189    * Its recommended to set this global configuration although it is possible to configure each client-session separately.
190    *
191    * @param cer Capabilities-Exchange-Request message (encoded) for the client-sessions bind.
192    * @param dwr Device-Watchdog-Request message (encoded) for the client-sessions keep-alive.
193    */
194   void setCERandDWR(const anna::DataBlock & cer, const anna::DataBlock & dwr) throw(anna::RuntimeException);
195
196
197   /**
198    * Sets the watchdog period (DWR) for client-sessions.
199    * Its recommended to set this global configuration although it is possible to configure each client-session separately.
200    *
201    * @param wp Watchdog period.
202    */
203   void setWatchdogPeriod(const anna::Millisecond & wp) throw(anna::RuntimeException);
204
205   /**
206    * Gets the number of client-sessions per server.
207    * \return numberOfClientSessionsPerServer Number of client-sessions per server.
208    */
209   int getNumberOfClientSessionsPerServer() const throw() { return a_numberOfClientSessionsPerServer; }
210
211   /**
212    * Sets the number of client-sessions per server.
213    * Its recommended to set this global configuration although it is possible to configure each client-session separately.
214    * \param numberOfClientSessionsPerServer Number of client-sessions per server.
215    */
216   void setNumberOfClientSessionsPerServer(int numberOfClientSessionsPerServer) throw() { a_numberOfClientSessionsPerServer = numberOfClientSessionsPerServer; }
217
218   /**
219    * Gets true when end-to-end sequence is freezed on requests sendings.
220    * Engine starts with false value, sequencing end-to-end as hop-by-hop does.
221    * \return Freeze end-to-end indicator.
222    */
223   bool getFreezeEndToEndOnSending() const throw() { return a_freezeEndToEndOnSending; }
224
225   /**
226    * Freeze end-to-end indicator on requests sendings.
227    * \param freezeEndToEndOnSending Freeze end-to-end indicator.
228    */
229   void setFreezeEndToEndOnSending(bool freezeEndToEndOnSending = true) throw() { a_freezeEndToEndOnSending = freezeEndToEndOnSending; }
230
231   /**
232    * Returns client-session instance identified by (address, port, socketId) provided.
233    *
234    * \param addr Diameter server address (ip or hostname).
235    * \param port Diameter server port.
236    * @param socketId Diameter server socket id.
237    * \param emode Action when no client-session is found with provided parameters (Throw/Ignore).
238    *
239    * \return The client-session instance identified by (address, port, socketId) provided.
240    *
241    * \warning If no client-session found, an exception is launched by default.
242    */
243   ClientSession* findClientSession(const std::string & addr, int port, int socketId, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException);
244
245
246   /**
247    * Same as #findClientSession, but providing client session key (<address>:<port>|<socket id>)
248    */
249   ClientSession* findClientSession(const std::string & key, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException);
250
251
252   /**
253    * Returns server instance identified by pair (address, port) provided.
254    *
255    * \param addr Diameter server address (ip or hostname).
256    * \param port Diameter server port.
257    * \param emode Action when no client-session is found with provided parameters (Throw/Ignore).
258    *
259    * \return The server instance identified by pair (address, port) provided.
260    *
261    * \warning If no server found, an exception is launched by default.
262    */
263   Server* findServer(const std::string & addr, int port, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException);
264
265   /**
266    * Returns entity instance identified by internal index.
267    *
268    * \param socketList Diameter entity servers list.
269    * \param emode Action when no client-session is found with provided parameters (Throw/Ignore).
270    *
271    * \return The entity instance identified by id provided.
272    *
273    * \warning If no entity found, an exception is launched by default.
274    */
275   Entity* findEntity(const socket_v & socketList, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException);
276
277   /**
278    * Returns entity instance identified by internal index.
279    *
280    * \param addr1 Diameter primary server address (ip or hostname).
281    * \param port1 Diameter primary server port.
282    * \param addr2 Diameter secondary server address (ip or hostname).
283    * \param port2 Diameter secondary server port.
284    * \param emode Action when no client-session is found with provided parameters (Throw/Ignore).
285    *
286    * \return The entity instance identified by id provided.
287    *
288    * \warning If no entity found, an exception is launched by default.
289    */
290   Entity* findEntity(const std::string & addr1, int port1, const std::string & addr2, int port2, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException);
291
292   /**
293    * Creates a diameter entity with provided parameters.
294    *
295    * Depending on auto-bind configuration, capabilities exchange request will be or won't be performed over the entity client-sessions.
296    *
297    * \param socketList Diameter server priority list (priority-ordered) in order to define whole entity.
298    * @param description Optional entity description (empty by default)
299    *
300    * \return The entity created or exception when any server (address/port) already exists for another entity.
301    *
302    * \warning The entity won't be almost operative until a notification by mean 'ClientSession::eventResponse'
303    * indicates that 'ClassCode::Bind' has been correctly performed for any included client-session.
304    */
305   Entity* createEntity(const socket_v & socketList, const std::string & description = "")
306   throw(anna::RuntimeException);
307
308   /**
309    * Creates a standard (dual) diameter entity with provided parameters.
310    *
311    * Depending on auto-bind configuration, capabilities exchange request will be or won't be performed over the entity client-sessions.
312    *
313    * \param addr1 Diameter primary server address (ip or hostname).
314    * \param port1 Diameter primary server port.
315    * \param addr2 Diameter secondary server address (ip or hostname).
316    * \param port2 Diameter secondary server port.
317    * @param description Optional entity description (empty by default)
318    *
319    * \return The standard entity created or exception when any server (address/port) already exists for another entity.
320    *
321    * \warning The entity won't be almost operative until a notification by mean 'ClientSession::eventResponse'
322    * indicates that 'ClassCode::Bind' has been correctly performed for any included client-session.
323    */
324   Entity* createEntity(const std::string & addr1, int port1, const std::string & addr2, int port2, const std::string & description = "")
325   throw(anna::RuntimeException);
326
327
328   /**
329    * Returns local server instance identified by pair (address, port) provided.
330    *
331    * @param addr Diameter server socket address (ip or hostname).
332    * @param port Diameter server socket port.
333    * \param emode Action when no local server is found with provided parameters (Throw/Ignore).
334    *
335    * \return The local server instance identified by pair (address, port) provided.
336    *
337    * \warning If no local server found, an exception is launched by default.
338    */
339   LocalServer* findLocalServer(const std::string & addr, int port, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException);
340
341   /**
342    * Returns server-session instance identified by INetAddress serialization provided.
343    *
344    * @param socketId Hash for Client Socket INetAddress serialization
345    * \param emode Action when no server-session is found with provided parameters (Throw/Ignore).
346    *
347    * \return The server-session instance identified by global unique socketId provided.
348    *
349    * \warning If no server-session found, an exception is launched by default.
350    */
351   ServerSession* findServerSession(int socketId, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException);
352
353   /**
354    * Creates a diameter local server with provided parameters.
355    *
356    * Server socket address could be an IPv4 or hostname. Default port will be standard 3868 for diameter agents,
357    * but any other could be configured. Socket server could be created with any max accepted connections: zero
358    * value means temporarily disabled and negative values assume no limit (shared bind) for incomming connections.
359    *
360    * @param addr Diameter server socket address (ip or hostname).
361    * @param port Diameter server socket port (standard 3868 by default).
362    * @param maxConnections Diameter server max sessions allowed (no limit by default).
363    * @param allowedInactivityTime Max inactivity time for server sessions over the local server before being reset.
364    * @param category Optional socket server category (1 by default).
365    * @param description Optional socket server description (empty by default).
366    *
367    * \return The local server created or exception when is already created.
368    */
369   LocalServer *createLocalServer(const std::string & addr, int port = Session::DefaultPort, int maxConnections = -1, const anna::Millisecond & allowedInactivityTime = ServerSession::DefaultAllowedInactivityTime, int category = 1, const std::string & description = "")
370   throw(anna::RuntimeException);
371
372
373   /**
374      Close all the engine resources (entities and local servers)
375      Optionally all resources may be freed passing true
376
377      @param destroy Free all engine entity resources
378   */
379   void close(bool destroy = false) throw(anna::RuntimeException) { closeEntities(destroy); closeLocalServers(destroy); }
380
381
382   /**
383      Close all the engine entities (close servers, then close client-sessions within them). Depending on client-session configuration
384      ('OnDisconnect' behaviour), pending answers will be wait (graceful) or ignored (immediate-abrupt close).
385      Optionally all entities resources may be freed passing true; in this case, close is immediately performed:
386      @param destroy Free all engine entity resources
387   */
388   void closeEntities(bool destroy = false) throw(anna::RuntimeException);
389
390
391   /**
392    * Close entity servers (then, client-sessions included) and optionally free resources including entity itself.
393    * If entity is null, this operation has no effect.
394    *
395    * \param entity Diameter entity to be closed.
396    * \param destroy Deletes entity over the engine and all its resources.
397    */
398   void closeEntity(Entity* entity, bool destroy = false) throw(anna::RuntimeException);
399
400
401   /**
402      Close all the engine local server sockets including their children server sessions.
403      Optionally all local server resources may be freed passing true.
404
405      @param destroy Free all engine local servers resources and server sessions within them.
406   */
407   void closeLocalServers(bool destroy = false) throw(anna::RuntimeException);
408
409   /**
410    * Close local server socket and its children server sessions.
411    * This is useful when detecting service lost. When service is ready to handle traffic, a new server socket would
412    * be created by mean #LocalServer::enable() and new connections could be accepted.
413    * Optionally local server resources may be freed passing true.
414    *
415    * \param localServer Local server to be closed.
416    * \param destroy Deletes local server over engine and all its resources (server sessions within it).
417    */
418   void closeLocalServer(LocalServer * localServer, bool destroy = false) throw(anna::RuntimeException);
419
420   /**
421      Gets the number of requests messages over-the-air for entities.
422
423      @return OTA messages.
424   */
425   int getOTARequestsForEntities() const throw();
426
427   /**
428      Gets the number of requests messages over-the-air for local servers.
429
430      @return OTA messages.
431   */
432   int getOTARequestsForLocalServers() const throw();
433
434   /**
435      Gets the number of requests messages over-the-air for entities plus local servers.
436
437      @return OTA messages.
438   */
439   int getOTARequests() const throw() { return (getOTARequestsForEntities() + getOTARequestsForLocalServers()); }
440
441   /**
442      Returns idle state (no pending answers) for entities.
443
444      @return Idle state.
445   */
446   bool idleForEntities() const throw() { return (getOTARequestsForEntities() == 0); }
447
448   /**
449      Returns idle state (no pending answers).
450
451      @return Idle state.
452   */
453   bool idleForLocalServers() const throw() { return (getOTARequestsForLocalServers() == 0); }
454
455   /**
456      Returns idle state (no pending answers for entities or local servers).
457
458      @return Idle state.
459   */
460   bool idle() const throw() { return (getOTARequests() == 0); }
461
462   /**
463      Sent a message to all the engine entities.
464      It is used, i.e., in Disconnect-Peer-Request procedure over the engine.
465
466      \param message Message which is being sent.
467
468      @return Returns true (success) only when broadcast is success over all the engine entities. If any entity fails,
469      then false is returned. Broadcast try to send all over the resources in spite of any fail.
470   */
471   bool broadcastEntities(const Message*message) throw(anna::RuntimeException);
472   bool broadcastEntities(const Message& message) throw(anna::RuntimeException) { return broadcastEntities(&message); }
473
474   /**
475      Sent a message through all the engine local servers.
476      It is used, i.e., in Disconnect-Peer-Request procedure over the engine.
477
478      \param message Message which is being sent.
479
480      @return Returns true (success) only when broadcast is success over all the engine local servers. If any local server fails,
481      then false is returned. Broadcast try to send all over the resources in spite of any fail.
482   */
483   bool broadcastLocalServers(const Message*message) throw(anna::RuntimeException);
484   bool broadcastLocalServers(const Message& message) throw(anna::RuntimeException) { return broadcastLocalServers(&message); }
485
486   /**
487   * Class string representation
488   *
489   * @return String with class content
490   */
491   virtual std::string asString(void) const throw();
492
493   /**
494      Class XML representation.
495      \param parent XML node over which we will put instance information.
496      \return XML documentcon with class content.
497   */
498   virtual anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
499
500
501   /**
502      When there is not bound server session over the engine, this virtual method will be invoked.
503      Applications must decide to do any other tasks at this idle/isolated situation.
504      Default implementation do nothing.
505   */
506   virtual void availabilityLostForLocalServers(Engine *) const throw() {;}
507
508   /**
509      When there is any bound server session over the engine, this virtual method will be invoked.
510      Applications must decide to do be ready for incoming traffic.
511      Default implementation do nothing.
512   */
513   virtual void availabilityRecoveredForLocalServers(Engine *) const throw() {;}
514
515   /**
516      When there is not bound entity over the engine, this virtual method will be invoked.
517      Many applications must change communicator status to Unavailable when no engines are available.
518      Default implementation do nothing.
519   */
520   virtual void availabilityLostForEntities(Engine *) const throw() {;}
521
522   /**
523      When there is any bound entity over the engine, this virtual method will be invoked.
524      Many applications must recover communicator status to Available when any engine are available.
525      Default implementation do nothing.
526   */
527   virtual void availabilityRecoveredForEntities(Engine *) const throw() {;}
528
529   /**
530      When there is not bound server-session over the local server, this virtual method will be invoked.
531      Default implementation do nothing.
532   */
533   virtual void availabilityLost(LocalServer *) const throw() {;}
534
535   /**
536      When there is any bound server-session over the local server, this virtual method will be invoked.
537      Default implementation do nothing.
538   */
539   virtual void availabilityRecovered(LocalServer *) const throw() {;}
540
541   /**
542      When there is not bound server over the entity, this virtual method will be invoked.
543      Default implementation do nothing.
544   */
545   virtual void availabilityLost(Entity *) const throw() {;}
546
547   /**
548      When there is any bound server over the entity, this virtual method will be invoked.
549      Default implementation do nothing.
550   */
551   virtual void availabilityRecovered(Entity *) const throw() {;}
552
553   /**
554      When there is not bound client-session over the server, this virtual method will be invoked.
555      Default implementation do nothing.
556   */
557   virtual void availabilityLost(Server *) const throw() {;}
558
559   /**
560      When there is any bound client-session over the server, this virtual method will be invoked.
561      Default implementation do nothing.
562   */
563   virtual void availabilityRecovered(Server *) const throw() {;}
564
565   /**
566      When a subyacent client session is going to be bound, this method is invoked before.
567      Default implementation do nothing.
568   */
569   virtual void bindingClientSession(const ClientSession *) const throw() {;}
570
571   /**
572    * Class user should implement this method in order to define Disconnect-Peer-Answer for last received DPR.
573    * Origin-Host and Origin-Realm are configured at comm::Engine with hostname and FQDN (Fully Qualified Domain Name).
574    * Default implementation imply DPA with DIAMETER_SUCCESS Result-Code, allowing remote disconnection.
575    * Any other implementation is responsible to build a valid DPA diameter message.
576    * DPR/DPA procedure is disabled with empty definition of this method: no DPA will be sent when DPR is received.
577    *
578    * @param dpa DPA datablock passed as reference
579    * @param dpr Corresponding DPR received (sequence values must be taken into account in order to build DPA)
580   */
581   virtual void readDPA(anna::DataBlock &dpa, const anna::DataBlock & dpr) throw();
582
583   /**
584    * Class user should implement this method in order to define Capabilities-Exchange-Answer for received CER over server socket.
585    * Origin-Host and Origin-Realm are configured at comm::Engine with hostname and FQDN (Fully Qualified Domain Name).
586    * Default implementation imply CEA with DIAMETER_SUCCESS Result-Code, and own domain node parameters, but application should
587    * analyze the CER message in order to accept it or not (with apropiate non-success Result-Code).
588    * Any other implementation is responsible to build a valid CEA diameter message:
589    *
590    * If one peer sends a CER message to another Peer and receiver does not have support for
591    *
592    *  1) any common application then it must return the CEA with Result-Code Avp set to DIAMETER_NO_COMMON_APPLICATION
593    *     and should disconnect the transport layer connection (automatically done by diameter::comm module).
594    *  2) no common security mechanism then it must return the CEA with Result-Code Avp set to DIAMETER_NO_COMMON_SECURITY
595    *     and should disconnect the transport layer connection (automatically done by diameter::comm module).
596    *  3) if CER is received from any unknown peer then receiver should discard the message, or send the CEA with the
597    *     Result-Code Avp set to DIAMETER_UNKNOWN_PEER.
598    *
599    *  If the local implementation policy permits to receive CER from unknown hosts, a successful CEA MAY be returned,
600    *  and the life time of the peer entry in PEER-Table is equal to the lifetime of the transport connection.
601    *  If in any case transport connection fails then all the pending transactions destined to the unknown peer can be discarded.
602    *
603    *  The CER and CEA messages MUST NOT be proxied, redirected or relayed. Since CER/CEA messages can not be proxied, but still
604    *  it is possible that proxy will receive a CER message and proxy does not have any peer to handle the application requested
605    *  in CER, in this case proxy set the E bit in CEA and set the Result-Code Avp to DIAMETER_UNABLE_TO_DELIVER, sends back to
606    *  CER generator peer.
607    *
608    * @param cea CEA datablock passed as reference. Empty cea implies to discard CER received.
609    * @param cer Corresponding CER received (sequence values must be taken into account in order to build CEA)
610   */
611   virtual void readCEA(anna::DataBlock &cea, const anna::DataBlock & cer) throw();
612
613   /**
614    * Class user should implement this method in order to define Device-Watchdog-Answer for received DWR over server socket.
615    * Origin-Host and Origin-Realm are configured at comm::Engine with hostname and FQDN (Fully Qualified Domain Name).
616    * Default implementation imply DWA with DIAMETER_SUCCESS Result-Code, and own domain node parameters.
617    * Any other implementation is responsible to build a valid DWA diameter message.
618    *
619    * @param dwa DWA datablock passed as reference
620    * @param dwr Corresponding DWR received (sequence values must be taken into account in order to build DWA)
621   */
622   virtual void readDWA(anna::DataBlock &dwa, const anna::DataBlock & dwr) throw();
623
624   /**
625      Reset engine statistics.
626      At the moment, only diameter servers processing time is observed.
627   */
628   void resetStatistics() throw();
629
630
631 protected:
632   /**
633      Constructor.
634   */
635   Engine();
636
637
638   // INTERNAL CREATORS AND CLOSE METHODS
639   Server *createServer(Entity*, const socket_t&) throw(anna::RuntimeException);
640   void closeServer(Server*, bool) throw(anna::RuntimeException);
641   ClientSession *createClientSession(Server*, int) throw(anna::RuntimeException);
642   void closeClientSession(ClientSession*, bool) throw(anna::RuntimeException);
643
644   // INTERNAL ALLOCATORS
645   Server* allocateServer() throw();
646   void releaseServer(Server*) throw();
647   ClientSession* allocateClientSession() throw();
648   void releaseClientSession(ClientSession*) throw();
649
650
651   /**
652      Entity allocator method.
653
654      It is recommended to use anna::Recycler for entities creation/releasing.
655
656      \see anna::Recycler
657   */
658   virtual Entity* allocateEntity() throw() { return NULL; }
659
660
661   /**
662      Invoked to free entities.
663      \see anna::Recycler
664   */
665   virtual void releaseEntity(Entity*) throw() {;}
666
667
668   /**
669      Local server allocator method.
670
671      It is recommended to use anna::Recycler for entities creation/releasing.
672
673      \see anna::Recycler
674   */
675   virtual LocalServer* allocateLocalServer() throw() { return NULL; }
676
677
678   /**
679      Invoked to free local servers.
680      \see anna::Recycler
681   */
682   virtual void releaseLocalServer(LocalServer*) throw() {;}
683
684
685
686 private:
687
688   std::string a_realm;
689   std::string a_host;
690   bool a_autoBind;
691   int a_numberOfClientSessionsPerServer;
692   bool a_freezeEndToEndOnSending;
693
694
695   // ClientSessions messages:
696   anna::DataBlock a_cer;
697   anna::DataBlock a_dwr;
698   anna::Millisecond a_watchdogPeriod;
699
700 //   // ServerSessions messages:
701 //   anna::DataBlock a_cea;
702 //   anna::DataBlock a_dwa;
703
704   // Client connectivity
705   anna::Millisecond a_maxConnectionDelay;
706
707
708   // Availability
709   bool a_availableForEntities; // any of the entities must be bound
710   void availabilityLostForEntities() throw();
711   void availabilityRecoveredForEntities() throw();
712   bool refreshAvailabilityForEntities() throw(); // return true if change
713
714   bool a_availableForLocalServers; // any of the local servers must be bound
715   void availabilityLostForLocalServers() throw();
716   void availabilityRecoveredForLocalServers() throw();
717   bool refreshAvailabilityForLocalServers() throw(); // return true if change
718
719   void eraseDeprecatedIdleEntities() throw();
720
721   // Component:
722   void do_initialize() throw() {;}
723   void do_stop() throw();
724
725   // Integrity:
726   void checkEntityCollision(const socket_v &) throw(anna::RuntimeException);
727
728
729   //////////////////////////
730   // CLIENT FUNCTIONALITY //
731   //////////////////////////
732
733   //typedef int clientSession_key; // exclusiveHash('ADDR:PORT|id')
734   typedef std::string clientSession_key; // 'ADDR:PORT|id'
735   typedef std::map <clientSession_key, ClientSession*> clientSession_container;
736   typedef clientSession_container::value_type clientSession_value_type;
737   typedef clientSession_container::iterator clientSession_iterator;
738   typedef clientSession_container::const_iterator const_clientSession_iterator;
739   clientSession_container a_clientSessions;
740   anna::Recycler<ClientSession> a_clientSessionsRecycler;
741   clientSession_iterator clientSession_find(const clientSession_key&) throw();
742   clientSession_iterator clientSession_begin() throw() { return a_clientSessions.begin(); }
743   clientSession_iterator clientSession_end() throw() { return a_clientSessions.end(); }
744   static ClientSession* clientSession(clientSession_iterator ii) throw() { return ii->second; }
745   const_clientSession_iterator clientSession_begin() const throw() { return a_clientSessions.begin(); }
746   const_clientSession_iterator clientSession_end() const throw() { return a_clientSessions.end(); }
747   static const ClientSession* clientSession(const_clientSession_iterator ii) throw() { return ii->second; }
748
749   typedef socket_t server_key;
750   server_key getServerKey(const std::string & addr, int port) const throw();
751   typedef std::map <server_key, Server*> server_container;
752   typedef server_container::value_type server_value_type;
753   typedef server_container::iterator server_iterator;
754   typedef server_container::const_iterator const_server_iterator;
755   server_container a_servers;
756   anna::Recycler<Server> a_serversRecycler;
757   server_iterator server_find(const server_key&) throw();
758   server_iterator server_begin() throw() { return a_servers.begin(); }
759   server_iterator server_end() throw() { return a_servers.end(); }
760   static Server* server(server_iterator ii) throw() { return ii->second; }
761   const_server_iterator server_begin() const throw() { return a_servers.begin(); }
762   const_server_iterator server_end() const throw() { return a_servers.end(); }
763   static const Server* server(const_server_iterator ii) throw() { return ii->second; }
764
765   //typedef int entity_key; // exclusiveHash('IP1:PORT1 IP2:PORT2 IP3:PORT3 ...')
766   typedef std::string entity_key; // 'ADDR1:PORT1 ADDR2:PORT2 ADDR3:PORT3 ...'
767   entity_key getEntityKey(const socket_v &) const throw();
768   entity_key getEntityKey(const std::string & addr1, int port1, const std::string & addr2, int port2) const throw();
769   typedef std::map <entity_key, Entity*> entity_container;
770   typedef entity_container::value_type entity_value_type;
771   typedef entity_container::iterator entity_iterator;
772   typedef entity_container::const_iterator const_entity_iterator;
773   entity_container a_entities;
774   entity_iterator entity_find(const entity_key&) throw();
775   entity_iterator entity_begin() throw() { return a_entities.begin(); }
776   entity_iterator entity_end() throw() { return a_entities.end(); }
777   static Entity* entity(entity_iterator ii) throw() { return ii->second; }
778   const_entity_iterator entity_begin() const throw() { return a_entities.begin(); }
779   const_entity_iterator entity_end() const throw() { return a_entities.end(); }
780   static const Entity* entity(const_entity_iterator ii) throw() { return ii->second; }
781
782
783   //////////////////////////
784   // SERVER FUNCTIONALITY //
785   //////////////////////////
786
787   // Local servers
788   typedef std::map <socket_t, LocalServer*> localServer_container;
789   typedef localServer_container::value_type localServer_value_type;
790   typedef localServer_container::iterator localServer_iterator;
791   typedef localServer_container::const_iterator const_localServer_iterator;
792   localServer_container a_localServers;
793   localServer_iterator localServer_find(const socket_t&) throw();
794   localServer_iterator localServer_begin() throw() { return a_localServers.begin(); }
795   localServer_iterator localServer_end() throw() { return a_localServers.end(); }
796   static LocalServer* localServer(localServer_iterator ii) throw() { return ii->second; }
797   const_localServer_iterator localServer_begin() const throw() { return a_localServers.begin(); }
798   const_localServer_iterator localServer_end() const throw() { return a_localServers.end(); }
799   static const LocalServer* localServer(const_localServer_iterator ii) throw() { return ii->second; }
800
801   // Server sessions are managed within LocalServer (not at engine) due to dynamic cration nature
802
803
804   friend class Session;
805   friend class ServerSession;
806   friend class ServerSocket;
807   friend class Server;
808   friend class Entity;
809   friend class LocalServer;
810   //friend class Message;
811 };
812
813 }
814 }
815 }
816
817 #endif
818