6735e5f2a18e2296fecc409782d4d6b1122a920f
[anna.git] / include / anna / diameter.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_diameter_comm_Server_hpp
10 #define anna_diameter_comm_Server_hpp
11
12
13 // STL
14 #include <string>
15 #include <vector>
16 #include <map>
17
18 // Project
19 #include <anna/core/util/Millisecond.hpp>
20 #include <anna/core/RuntimeException.hpp>
21 #include <anna/diameter/defines.hpp>
22 #include <anna/config/defines.hpp>
23 #include <anna/diameter.comm/ClassCode.hpp>
24 #include <anna/diameter.comm/MessageStatistics.hpp>
25
26
27
28
29 namespace anna {
30 class DataBlock;
31 namespace timex {
32 class Engine;
33 }
34 }
35
36
37 namespace anna {
38
39 namespace diameter {
40
41 namespace comm {
42
43 class Engine;
44 class Entity;
45 class ClientSession;
46 class Response;
47 class Message;
48
49
50 /**
51    Diameter server with 1..N connections.
52 */
53 class Server {
54
55   // Parent information
56   Entity *a_parent;
57
58   // Main server attributes
59   socket_t a_socket;
60
61   // ClientSessions
62   std::vector<ClientSession*> a_clientSessions;
63   int a_maxClientSessions; // -1 means "no limit to add client-sessions" (sockets per server)
64   std::vector<ClientSession*>::iterator a_deliveryIterator;
65   ClientSession *a_lastUsedResource;
66
67   // Activity
68   anna::Millisecond a_lastIncomingActivityTime;   // last unix timestamp (in milliseconds) when message reception was managed over this server
69   anna::Millisecond a_lastOutgoingActivityTime;   // last unix timestamp (in milliseconds) when message sending was managed over this server
70   void updateIncomingActivityTime() throw();
71   void updateOutgoingActivityTime() throw();
72
73   // Engine
74   Engine *a_engine;
75
76   // Statistics
77   MessageStatistics a_messageStatistics;
78   void initializeStatisticResources() throw();
79   void resetStatistics() throw();
80
81   // Availability
82   bool a_available; // any of the client-sessions must be bound
83   void availabilityLost() throw();
84   void availabilityRecovered() throw();
85   bool refreshAvailability() throw(); // return true if change
86   void assertReady() throw(anna::RuntimeException);
87   void initialize() throw();
88   void childIdle() const throw();
89
90   // Private close/destroy method
91   void close(bool destroy) throw(anna::RuntimeException);
92
93
94 public:
95
96
97   /**
98    * Default constructor.
99    * @param maxClientSessions Maximum number of client-sessions managed by the server. Default is 1 (monoconnection server).
100    * The value -1, means no limit to add client-sessions.
101    */
102   Server(int maxClientSessions = 1) : a_maxClientSessions(maxClientSessions) { initialize(); }
103
104
105   /**
106   * Add a server to the entity and create all the client-sessions configured at #setSocketsPerDiameterServer within that server.
107   *
108   * \param socketId Diameter socket identifier within the server.
109   */
110   void addClientSession(int socketId) throw(anna::RuntimeException);
111
112   /**
113      Set timeout to consider failed a request.
114      \param v Requests class code.
115      \param millisecond Milliseconds wait before considering the requests failed.
116
117      Timers are internally managed and automatically activated.
118   */
119   void setClassCodeTimeout(const ClassCode::_v v, const anna::Millisecond & millisecond) throw();
120
121   /**
122    * Binds server client-sessions.
123    *
124    * @return Returns true if all client-session were successfully bound
125    */
126   bool bind() throw(anna::RuntimeException);
127
128   /**
129    * Propagate auto recovery configuration to client-sessions within server
130    *
131    * @param autoRecovery Auto recovery indicator. True by default.
132    */
133   void raiseAutoRecovery(bool autoRecovery = true) throw(anna::RuntimeException);
134
135
136 // Sent a message to the server using a certain client-session by mean round-robin between socketId's for
137 //  multiple client client-sessions functionality. If a specific socketId is provided, then uses such specific client-session.
138 // Last used delivery resource could be known through #getLastUsedResource().
139   bool send(const Message*, int socketId = -1 /* client-sessions round-robin */) throw(anna::RuntimeException);
140   bool send(const Message& message, int socketId = -1 /* client-sessions round-robin */) throw(anna::RuntimeException) { return send(&message, socketId); }
141
142   /**
143      Gets the last used resource (client session) during sending.
144      Broadcast doesn't updates this information.
145   */
146   ClientSession *getLastUsedResource() const throw() { return (a_lastUsedResource); }
147
148   /**
149      Sent a message to all the server client-sessions (socketId's) for multiple client client-sessions functionality.
150      It is used, i.e., in Disconnect-Peer-Request procedure over a certain server.
151      Returns true (success) only when broadcast is success over all the server client-sessions. If any client-session fails,
152      then false is returned. Broadcast try to send all over the resources in spite of any fail.
153   */
154   bool broadcast(const Message*) throw(anna::RuntimeException);
155   bool broadcast(const Message& message) throw(anna::RuntimeException) { return broadcast(&message); }
156
157   /**
158      Close all the server client-sessions. Depending on client-session configuration ('OnDisconnect' behaviour),
159      pending answers will be wait (graceful) or ignored (immediate-abrupt close).
160      Resources are not destroyed.
161   */
162   void close() throw(anna::RuntimeException) { close(false /* no destroy */); }
163
164
165   /**
166      Diameter parent entity.
167      \return Diameter parent entity.
168   */
169   const Entity *getParent() const throw() { return a_parent; }
170
171   /**
172      Returns true when any of the server client-sessions is Bound. False when all not-bound.
173   */
174   bool isAvailable() const throw() { return a_available; }
175
176
177   std::vector<ClientSession*>::iterator begin() throw() { return a_clientSessions.begin(); }
178   std::vector<ClientSession*>::iterator end() throw() { return a_clientSessions.end(); }
179   std::vector<ClientSession*>::const_iterator begin() const throw() { return a_clientSessions.begin(); }
180   std::vector<ClientSession*>::const_iterator end() const throw() { return a_clientSessions.end(); }
181
182   int getNumberOfClientSessions() const throw() { return a_clientSessions.size(); }
183   int getMaxClientSessions() const throw() { return a_maxClientSessions; }
184   void setMaxClientSessions(int maxClientSessions) throw() { a_maxClientSessions = maxClientSessions; }
185
186   /**
187      Diameter server  address (IP or hostname)
188      \return Diameter server address.
189   */
190   const std::string& getAddress() const throw() { return a_socket.first; }
191
192   /**
193      Diameter server port.
194      \return Diameter server port.
195   */
196   int getPort() const throw() { return a_socket.second; }
197
198
199   /** Server presentation as 'ADDRESS:PORT' */
200   std::string socketAsString() const throw();
201
202
203   /**
204      Gets the timestamp for last incoming activity over the server.
205
206      @return Last incoming activity timestamp.
207   */
208   const anna::Millisecond & getLastIncomingActivityTime() const throw() { return a_lastIncomingActivityTime; }
209
210   /**
211      Gets the timestamp for last outgoing activity over the server.
212
213      @return Last outgoing activity timestamp.
214   */
215   const anna::Millisecond & getLastOutgoingActivityTime() const throw() { return a_lastOutgoingActivityTime; }
216
217
218   /**
219      Gets the number of requests messages over-the-air.
220
221      @return OTA messages.
222   */
223   int getOTARequests() const throw();
224
225   /**
226      Returns idle state (no pending answers).
227
228      @return Idle state.
229   */
230   bool idle() const throw() { return (getOTARequests() == 0); }
231
232
233   /**
234      Deny resources for delivery restriction.
235      Deny all its client sessions
236   */
237   void hide() throw();
238
239   /**
240      Allow resource for delivery permission.
241      Allow all its client sessions
242   */
243   void show() throw();
244
245   /**
246      Returns true when all its client session resources are hidden for application messages delivery
247   */
248   bool hidden() const throw();
249
250   /**
251      Returns true when all its client session resources are shown for application messages delivery
252   */
253   bool shown() const throw();
254
255
256   /**
257      Class string representation
258      \return String with relevant information for this instance.
259   */
260   std::string asString() const throw();
261
262   /**
263      Class xml representation
264      \param parent Parent XML node on which hold this instance information.
265      \return XML document with relevant information for this instance.
266   */
267   anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
268
269
270   // Statistics
271   void updateProcessingTimeStatisticConcept(const double &value, const anna::diameter::CommandId &cid) throw();
272   void updateReceivedMessageSizeStatisticConcept(const double &value, const anna::diameter::CommandId &cid) throw();
273 //  int getProcessingTimeStatisticConcept() const throw() { return a_processing_time__StatisticConceptId; }
274 //  int getReceivedMessageSizeStatisticConcept() const throw() { return a_received_message_size__StatisticConceptId; }
275
276 protected:
277
278   /**
279      Handler about event break connection from diameter server (client-session) over this entity.
280
281      When notified, ANNA.diameter.comm generates an diameter::comm::Entity::eventResponse for every request with pending answers.
282   */
283   virtual void eventPeerShutdown(const ClientSession*) throw();
284
285   /**
286      Handler about a request retransmission over the session.
287
288      \param request Message retransmitted
289   */
290   virtual void eventRequestRetransmission(const ClientSession*, Message *request) throw();
291
292   /**
293      Handler for diameter server (client-session) responses
294
295      \param response Answer container object for corresponding diameter request
296   */
297   virtual void eventResponse(const Response & response) throw(anna::RuntimeException);
298
299   /**
300      Handler for diameter server (client-session) requests
301
302      \param clientSession ClientSession from which request has been received
303      \param request Diameter request message received
304   */
305   virtual void eventRequest(ClientSession *clientSession, const anna::DataBlock &request) throw(anna::RuntimeException);
306   //virtual void eventRequest(ClientSession *clientSession, const Message & request) throw(anna::RuntimeException);
307
308   /**
309      Handler for diameter server (client-session) responses out of context
310
311      \param clientSession ClientSession from which request has been received
312      \param response Answer data block object without context match
313   */
314   virtual void eventUnknownResponse(ClientSession *clientSession, const anna::DataBlock& response) throw(anna::RuntimeException);
315
316   /**
317      Handler for diameter server (client-session) Disconnect-Peer-Answer messages
318
319      \param clientSession ClientSession from which request has been received
320      \param response Answer data block object without context match
321   */
322   virtual void eventDPA(ClientSession *clientSession, const anna::DataBlock& response) throw(anna::RuntimeException);
323
324
325
326   friend class Engine;
327   friend class ClientSession;
328 };
329
330 }
331 }
332 }
333
334 #endif