1 // ANNA - Anna is Not Nothingness Anymore //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
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 //
9 #ifndef anna_diameter_comm_LocalServer_hpp
10 #define anna_diameter_comm_LocalServer_hpp
13 #include <anna/core/RuntimeException.hpp>
14 #include <anna/core/util/Millisecond.hpp>
15 #include <anna/core/util/Recycler.hpp>
23 #include <anna/config/defines.hpp>
24 #include <anna/diameter.comm/ServerSession.hpp>
25 #include <anna/diameter/defines.hpp>
26 #include <anna/diameter.comm/MessageStatistics.hpp>
35 //class LocalConnection;
53 Diameter server socket
59 std::string a_description;
61 int a_currentConnections; // deberia coincidir en todo momento con el numero de local connections del server socket
62 anna::Millisecond a_allowedInactivityTime;
63 ServerSocket *a_serverSocket;
68 Engine *a_engine; // only for refresh availability
71 MessageStatistics a_messageStatistics;
72 void initializeStatisticResources() ;
73 void resetStatistics() ;
75 // void eraseServerSession(const anna::comm::ClientSocket& clientSocket) ;
76 // void eraseServerSession(const serverSession_iterator &it) ;
77 void lostConnection() ;
78 void newConnection() noexcept(false);
81 anna::Millisecond a_lastIncomingActivityTime; // last unix timestamp (in milliseconds) when message reception was managed over this entity
82 anna::Millisecond a_lastOutgoingActivityTime; // last unix timestamp (in milliseconds) when message sending was managed over this entity
83 void updateIncomingActivityTime() ;
84 void updateOutgoingActivityTime() ;
87 bool a_available; // any of the server-sessions must be bound
88 void availabilityLost() ;
89 void availabilityRecovered() ;
90 bool refreshAvailability() ; // return true if change
92 void attach() ; // attach server socket to the communicator
93 void attachPlanning() ; // used when attach fails (socket already in use, etc.)
95 typedef int serverSession_key;
96 serverSession_key getServerSessionKey(const anna::comm::ClientSocket&) const ; // hash for Client Socket INetAddress serialization
97 typedef std::map <serverSession_key, ServerSession*> serverSession_container;
98 typedef serverSession_container::value_type serverSession_value_type;
99 typedef serverSession_container::iterator serverSession_iterator;
100 typedef serverSession_container::const_iterator const_serverSession_iterator;
101 serverSession_container a_serverSessions;
102 anna::Recycler<ServerSession> a_serverSessionsRecycler;
103 serverSession_iterator serverSession_find(const serverSession_key&) ;
104 serverSession_iterator serverSession_begin() { return a_serverSessions.begin(); }
105 serverSession_iterator serverSession_end() { return a_serverSessions.end(); }
106 static ServerSession* serverSession(serverSession_iterator ii) { return ii->second; }
107 const_serverSession_iterator serverSession_begin() const { return a_serverSessions.begin(); }
108 const_serverSession_iterator serverSession_end() const { return a_serverSessions.end(); }
109 static const ServerSession* serverSession(const_serverSession_iterator ii) { return ii->second; }
111 // INTERNAL CREATORS AND CLOSE METHODS
112 ServerSession *createServerSession(const anna::comm::ClientSocket&) noexcept(false);
113 void closeServerSession(ServerSession*) noexcept(false);
115 // INTERNAL ALLOCATORS
116 ServerSession* allocateServerSession() ;
117 void releaseServerSession(ServerSession*) ;
120 serverSession_iterator a_deliveryIterator;
121 ServerSession *a_lastUsedResource;
129 ~LocalServer() { close(); }
135 * Sets the local server key
136 * @param LocalServer key
138 void setKey(const socket_t &key) { a_key = key; }
141 Sets the server socket optional description
143 @param description Server socket description
145 void setDescription(const std::string description) { a_description = description; }
148 Set timeout to consider failed a request.
149 \param v Requests class code.
150 \param millisecond Milliseconds wait before considering the requests failed.
152 Timers are internally managed and automatically activated.
154 void setClassCodeTimeout(const ClassCode::_v v, const anna::Millisecond & millisecond) ;
157 Sets the server socket optional category
159 @param description Server socket category
161 void setCategory(int category) { a_category = category; }
164 Sets the maximum supported connections.
165 If provided value is negative or lesser than the number of current connections, an exception will be launched.
166 If all the connections was established, a new maximum will open the listen port.
167 when margin is zeroed (maximum configured is equal to current connections), listen port will be closed.
169 @param maxConnections Number of maximum connections allowed
171 void setMaxConnections(int maxConnections) noexcept(false);
174 Sets the maximum allowed inactivity time on server sessions born over the local server before being reset.
175 Communication engine assign a default value of 90000 msecs.
177 @param allowedInactivityTime Inactivity time allowed
179 void setAllowedInactivityTime(const anna::Millisecond & allowedInactivityTime) { a_allowedInactivityTime = allowedInactivityTime; }
182 * Sets the diameter::comm::Engine
183 * @param e Diameter::comm::Engine
185 void setEngine(Engine *e) { a_engine = e; }
190 * Gets the local server key
191 * @return LocalServer key
193 const socket_t & getKey() const { return a_key; }
196 Gets the number of maximum accepted connections that server socket is configured to handle
198 int getMaxConnections() const { return a_maxConnections; }
201 Gets the number of current connections being established through server socket
203 int getCurrentConnections() const { return a_currentConnections; }
206 Gets the maximum allowed inactivity time on server sessions born over the local server before being reset
208 @return Inactivity time allowed
210 const anna::Millisecond & getAllowedInactivityTime() const { return a_allowedInactivityTime; }
213 Returns true when any of the server-sessions is Bound. False when all not-bound.
215 bool isAvailable() const { return a_available; }
220 Disables local server socket (listener) keeping current server sessions alive.
221 Note that applications should not close the listen port directly to keep coherence (see #resetConnectionsMargin)
223 @param lock Locks disabled state (make it permanent even if new connections margin is reached).
224 Used during diameter agent isolation (lost of service, maintenance, etc.)
226 void disable(bool lock = false) noexcept(false);
228 /** Enables local server socket (listener)
230 @param unlock Unlocks permanent disabled states
232 void enable(bool unlock = false) noexcept(false);
235 Gets the number of requests messages over-the-air.
237 @return OTA messages.
239 int getOTARequests() const ;
242 Returns idle state (no pending answers).
246 bool idle() const { return (getOTARequests() == 0); }
249 Close the local server means two things: close the server socket and close all the server sessions born
250 from this local server freeing such server sessions resources.
252 void close() noexcept(false);
255 Performs coherent server socket close procedure zeroing margin between current established connections and maximum allowed.
257 void resetConnectionsMargin() noexcept(false) { setMaxConnections(a_currentConnections); }
261 * Returns server-session instance identified by client socket provided.
263 * \param clientSocket Client socket associated to the server session
264 * \param emode Action when no client-session is found with provided parameters (Throw/Ignore).
266 * \return The server-session instance identified by client socket provided.
268 * \warning If no server-session found, an exception is launched by default.
270 ServerSession* findServerSession(const anna::comm::ClientSocket &clientSocket, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) noexcept(false);
273 * Returns server-session instance identified by socket id provided (hash over serialized client socket information).
275 * \param socketId Socket id which is key for the server session
276 * \param emode Action when no client-session is found with provided parameters (Throw/Ignore).
278 * \return The server-session instance identified by client socket provided.
280 * \warning If no server-session found, an exception is launched by default.
282 ServerSession* findServerSession(int socketId, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) noexcept(false);
286 Sent a message to the client using a certain server-session provided or defined by #readSocketId if not.
287 When the message is a request, a timer will be set automatically to control the response time.
288 If expires, the ResultCode Timeout will be finally notified on #LocalServer::eventResponse. This
289 timeout value will be configured at #setClassCodeTimeout.
291 \param message Message sent.
292 \param socketId Server session socket id INetAddress serialization. By default, #readSocketId is invoked to get the socket id used (which uses round-robin if not re-implemented)
294 @return Boolean about success in send operation. True when any of the server sessions could send the message.
295 False, when neither of the server sessions was available or fail to send the message. Broadcast try to send all over
296 the resources in spite of any fail. If a specific socket id is provided, only this socket is used without trying any other
297 and returning false if fails.
299 bool send(const Message*, int socketId = -1 /* default uses readSocketId() */) noexcept(false);
300 bool send(const Message& message, int socketId = -1 /* default uses readSocketId() */) noexcept(false) { return send(&message, socketId); }
303 Gets the last used resource (server session) during sending.
304 Broadcast doesn't updates this information.
306 ServerSession *getLastUsedResource() const { return (a_lastUsedResource); }
309 Before sending a message over each local server, socketId could be specified to select
310 which session within such server will manage the message.
312 Default implementation performs round-robin (value '-1' for socketId) but any other kind of
313 application could re-implement this method and change the behaviour.
315 \param message Message which is being sent.
317 @return Socket-id (hash over serialized client socket information). Value '-1' if round-robin is desired.
318 If socket-id is unkonwn, send procedure will throw an exception.
320 virtual int readSocketId(const Message *message) const { return -1; }
323 Sent a message to all the server sessions.
324 It is used, i.e., in Disconnect-Peer-Request procedure over a certain entity.
326 \param message Message which is being sent.
328 @return Returns true (success) only when broadcast is success over all the entity servers. If any server fails,
329 then false is returned.
331 bool broadcast(const Message *message) noexcept(false);
332 bool broadcast(const Message &message) noexcept(false) { return broadcast(&message); }
336 Class string representation
337 \return String with relevant information for this instance.
339 std::string asString() const ;
342 Class xml representation
343 \param parent Parent XML node on which hold this instance information.
344 \return XML document with relevant information for this instance.
346 anna::xml::Node* asXML(anna::xml::Node* parent) const ;
349 void updateProcessingTimeStatisticConcept(const double &value, const anna::diameter::CommandId &cid) ;
350 void updateReceivedMessageSizeStatisticConcept(const double &value, const anna::diameter::CommandId &cid) ;
351 // int getProcessingTimeStatisticConcept() const { return a_processing_time__StatisticConceptId; }
352 // int getReceivedMessageSizeStatisticConcept() const { return a_received_message_size__StatisticConceptId; }
358 Handler about event break connection from diameter client over this server-session.
359 When notified, ANNA.diameter.comm generates an diameter::comm::ServerSession::eventResponse for every request with pending answers.
360 Default implementation traces warning event
361 \param serverSession ServerSession from which shutdown has been received
363 virtual void eventPeerShutdown(const ServerSession* serverSession) ;
366 Handler about a request retransmission over the server-session.
367 Default implementation traces warning event
368 \param serverSession ServerSession from which retransmission happened
369 \param request Retransmitted request message
371 virtual void eventRequestRetransmission(const ServerSession* serverSession, Message *request) ;
374 Handler for diameter client responses
376 \param response Answer container object for corresponding diameter request
377 \param myNode Own origin host
379 virtual void eventResponse(const Response& response, const anna::diameter::comm::OriginHost *myNode) noexcept(false) = 0;
382 Handler for diameter client requests
384 \param serverSession ServerSession from which request has been received
385 \param request Request data block object for corresponding diameter reception
386 \param myNode Own origin host
388 virtual void eventRequest(ServerSession* serverSession, const anna::DataBlock& request, const anna::diameter::comm::OriginHost *myNode) noexcept(false) = 0;
389 //void eventRequest(ServerSession* serverSession, const Message& request) noexcept(false);
392 Handler for diameter client responses out of context
394 \param serverSession ServerSession from which request has been received
395 \param response Answer data block object without context match
396 \param myNode Own origin host
398 virtual void eventUnknownResponse(ServerSession* serverSession, const anna::DataBlock& response, const anna::diameter::comm::OriginHost *myNode) noexcept(false) = 0;
401 Handler for diameter client Disconnect-Peer-Answer messages
403 \param serverSession ServerSession from which request has been received
404 \param response Answer data block object without context match
405 \param myNode Own origin host
407 virtual void eventDPA(ServerSession* serverSession, const anna::DataBlock& response, const anna::diameter::comm::OriginHost *myNode) noexcept(false) = 0;
410 friend class anna::diameter::comm::Timer;
412 friend class ServerSocket;
413 friend class ServerSession;
414 friend class ServerSessionReceiver;