1 // ANNA - Anna is Not 'N' Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // https://bitbucket.org/testillano/anna
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
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
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.
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.
33 // Authors: eduardo.ramos.testillano@gmail.com
34 // cisco.tierra@gmail.com
37 #ifndef anna_diameter_comm_Server_hpp
38 #define anna_diameter_comm_Server_hpp
45 #include <anna/core/util/Millisecond.hpp>
46 #include <anna/core/RuntimeException.hpp>
48 #include <anna/diameter/defines.hpp>
49 #include <anna/config/defines.hpp>
50 #include <anna/diameter.comm/ClassCode.hpp>
51 #include <anna/statistics/Accumulator.hpp>
76 Diameter server with 1..N connections.
83 // Main server attributes
87 std::vector<ClientSession*> a_clientSessions;
88 int a_maxClientSessions; // -1 means "no limit to add client-sessions" (sockets per server)
89 std::vector<ClientSession*>::iterator a_deliveryIterator;
90 ClientSession *a_lastUsedResource;
93 anna::Millisecond a_lastIncomingActivityTime; // last unix timestamp (in milliseconds) when message reception was managed over this server
94 anna::Millisecond a_lastOutgoingActivityTime; // last unix timestamp (in milliseconds) when message sending was managed over this server
95 void updateIncomingActivityTime() throw();
96 void updateOutgoingActivityTime() throw();
102 int a_processing_time__StatisticConceptId;
103 int a_received_message_size__StatisticConceptId;
104 anna::statistics::Accumulator a_statisticsAccumulator;
105 void initializeStatisticConcepts() throw();
106 void resetStatistics() throw();
109 bool a_available; // any of the client-sessions must be bound
110 void availabilityLost() throw();
111 void availabilityRecovered() throw();
112 bool refreshAvailability() throw(); // return true if change
113 void assertReady() throw(anna::RuntimeException);
114 void initialize() throw();
115 void childIdle() const throw();
117 // Private close/destroy method
118 void close(bool destroy) throw(anna::RuntimeException);
125 * Default constructor.
126 * @param maxClientSessions Maximum number of client-sessions managed by the server. Default is 1 (monoconnection server).
127 * The value -1, means no limit to add client-sessions.
129 Server(int maxClientSessions = 1) : a_maxClientSessions(maxClientSessions) { initialize(); }
133 * Add a server to the entity and create all the client-sessions configured at #setSocketsPerDiameterServer within that server.
135 * \param socketId Diameter socket identifier within the server.
137 void addClientSession(int socketId) throw(anna::RuntimeException);
140 Set timeout to consider failed a request.
141 \param v Requests class code.
142 \param millisecond Milliseconds wait before considering the requests failed.
144 Timers are internally managed and automatically activated.
146 void setClassCodeTimeout(const ClassCode::_v v, const anna::Millisecond & millisecond) throw();
149 * Binds server client-sessions.
151 * @return Returns true if all client-session were successfully bound
153 bool bind() throw(anna::RuntimeException);
156 * Propagate auto recovery configuration to client-sessions within server
158 * @param autoRecovery Auto recovery indicator. True by default.
160 void raiseAutoRecovery(bool autoRecovery = true) throw(anna::RuntimeException);
163 // Sent a message to the server using a certain client-session by mean round-robin between socketId's for
164 // multiple client client-sessions functionality. If a specific socketId is provided, then uses such specific client-session.
165 // Last used delivery resource could be known through #getLastUsedResource().
166 bool send(const Message*, int socketId = -1 /* client-sessions round-robin */) throw(anna::RuntimeException);
167 bool send(const Message& message, int socketId = -1 /* client-sessions round-robin */) throw(anna::RuntimeException) { return send(&message, socketId); }
170 Gets the last used resource (client session) during sending.
171 Broadcast doesn't updates this information.
173 ClientSession *getLastUsedResource() const throw() { return (a_lastUsedResource); }
176 Sent a message to all the server client-sessions (socketId's) for multiple client client-sessions functionality.
177 It is used, i.e., in Disconnect-Peer-Request procedure over a certain server.
178 Returns true (success) only when broadcast is success over all the server client-sessions. If any client-session fails,
179 then false is returned. Broadcast try to send all over the resources in spite of any fail.
181 bool broadcast(const Message*) throw(anna::RuntimeException);
182 bool broadcast(const Message& message) throw(anna::RuntimeException) { return broadcast(&message); }
185 Close all the server client-sessions. Depending on client-session configuration ('OnDisconnect' behaviour),
186 pending answers will be wait (graceful) or ignored (immediate-abrupt close).
187 Resources are not destroyed.
189 void close() throw(anna::RuntimeException) { close(false /* no destroy */); }
193 Diameter parent entity.
194 \return Diameter parent entity.
196 const Entity *getParent() const throw() { return a_parent; }
199 Returns true when any of the server client-sessions is Bound. False when all not-bound.
201 bool isAvailable() const throw() { return a_available; }
204 std::vector<ClientSession*>::iterator begin() throw() { return a_clientSessions.begin(); }
205 std::vector<ClientSession*>::iterator end() throw() { return a_clientSessions.end(); }
206 std::vector<ClientSession*>::const_iterator begin() const throw() { return a_clientSessions.begin(); }
207 std::vector<ClientSession*>::const_iterator end() const throw() { return a_clientSessions.end(); }
209 int getNumberOfClientSessions() const throw() { return a_clientSessions.size(); }
210 int getMaxClientSessions() const throw() { return a_maxClientSessions; }
211 void setMaxClientSessions(int maxClientSessions) throw() { a_maxClientSessions = maxClientSessions; }
214 Diameter server address (IP or hostname)
215 \return Diameter server address.
217 const std::string& getAddress() const throw() { return a_socket.first; }
220 Diameter server port.
221 \return Diameter server port.
223 int getPort() const throw() { return a_socket.second; }
226 /** Server presentation as 'ADDRESS:PORT' */
227 std::string socketAsString() const throw();
231 Gets the timestamp for last incoming activity over the server.
233 @return Last incoming activity timestamp.
235 const anna::Millisecond & getLastIncomingActivityTime() const throw() { return a_lastIncomingActivityTime; }
238 Gets the timestamp for last outgoing activity over the server.
240 @return Last outgoing activity timestamp.
242 const anna::Millisecond & getLastOutgoingActivityTime() const throw() { return a_lastOutgoingActivityTime; }
246 Gets the number of requests messages over-the-air.
248 @return OTA messages.
250 int getOTARequests() const throw();
253 Returns idle state (no pending answers).
257 bool idle() const throw() { return (getOTARequests() == 0); }
261 Deny resources for delivery restriction.
262 Deny all its client sessions
267 Allow resource for delivery permission.
268 Allow all its client sessions
273 Returns true when all its client session resources are hidden for application messages delivery
275 bool hidden() const throw();
278 Returns true when all its client session resources are shown for application messages delivery
280 bool shown() const throw();
284 Class string representation
285 \return String with relevant information for this instance.
287 std::string asString() const throw();
290 Class xml representation
291 \param parent Parent XML node on which hold this instance information.
292 \return XML document with relevant information for this instance.
294 anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
298 void updateProcessingTimeStatisticConcept(const double &value) throw();
299 void updateReceivedMessageSizeStatisticConcept(const double &value) throw();
300 int getProcessingTimeStatisticConcept() const throw() { return a_processing_time__StatisticConceptId; }
301 int getReceivedMessageSizeStatisticConcept() const throw() { return a_received_message_size__StatisticConceptId; }
306 Handler about event break connection from diameter server (client-session) over this entity.
308 When notified, ANNA.diameter.comm generates an diameter::comm::Entity::eventResponse for every request with pending answers.
310 virtual void eventPeerShutdown(const ClientSession*) throw();
313 Handler for diameter server (client-session) responses
315 \param response Answer container object for corresponding diameter request
317 virtual void eventResponse(const Response & response) throw(anna::RuntimeException);
320 Handler for diameter server (client-session) requests
322 \param clientSession ClientSession from which request has been received
323 \param request Diameter request message received
325 virtual void eventRequest(ClientSession *clientSession, const anna::DataBlock &request) throw(anna::RuntimeException);
326 //virtual void eventRequest(ClientSession *clientSession, const Message & request) throw(anna::RuntimeException);
329 Handler for diameter server (client-session) responses out of context
331 \param clientSession ClientSession from which request has been received
332 \param response Answer data block object without context match
334 virtual void eventUnknownResponse(ClientSession *clientSession, const anna::DataBlock& response) throw(anna::RuntimeException);
338 friend class ClientSession;