Fix local server for multiple applications
[anna.git] / include / anna / diameter.comm / LocalServer.hpp
index fff7912..6a63a7c 100644 (file)
@@ -1,37 +1,9 @@
-// ANNA - Anna is Not Nothingness Anymore
-//
-// (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
-//
-// http://redmine.teslayout.com/projects/anna-suite
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     *  Neither the name of the copyright holder nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Authors: eduardo.ramos.testillano@gmail.com
-//          cisco.tierra@gmail.com
+// ANNA - Anna is Not Nothingness Anymore                                                         //
+//                                                                                                //
+// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
+//                                                                                                //
+// See project site at http://redmine.teslayout.com/projects/anna-suite                           //
+// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
 
 
 #ifndef anna_diameter_comm_LocalServer_hpp
 // STL
 #include <string>
 #include <vector>
+#include <map>
 
+// Project
 #include <anna/config/defines.hpp>
-#include <anna/statistics/Accumulator.hpp>
 #include <anna/diameter.comm/ServerSession.hpp>
+#include <anna/diameter/defines.hpp>
+#include <anna/diameter.comm/MessageStatistics.hpp>
 
 
 namespace anna {
@@ -68,10 +43,10 @@ namespace diameter {
 
 namespace comm {
 
-class Engine;
 class Response;
 class ServerSocket;
 class Message;
+class Engine;
 
 
 /**
@@ -90,58 +65,56 @@ class LocalServer {
   bool a_lock;
 
   // Engine
-  Engine *a_engine;
+  Engine *a_engine; // only for refresh availability
 
   // Statistics
-  int a_processing_time__StatisticConceptId; // request from local server (dpr's, etc.)
-  int a_received_message_size__StatisticConceptId;
-  anna::statistics::Accumulator a_statisticsAccumulator;
-  void initializeStatisticConcepts() throw();
-  void resetStatistics() throw();
+  MessageStatistics a_messageStatistics;
+  void initializeStatisticResources() ;
+  void resetStatistics() ;
 
-//   void eraseServerSession(const anna::comm::ClientSocket& clientSocket) throw();
-//   void eraseServerSession(const serverSession_iterator &it) throw();
-  void lostConnection() throw();
-  void newConnection() throw(anna::RuntimeException);
+//   void eraseServerSession(const anna::comm::ClientSocket& clientSocket) ;
+//   void eraseServerSession(const serverSession_iterator &it) ;
+  void lostConnection() ;
+  void newConnection() noexcept(false);
 
   // Activity
   anna::Millisecond a_lastIncomingActivityTime;   // last unix timestamp (in milliseconds) when message reception was managed over this entity
   anna::Millisecond a_lastOutgoingActivityTime;   // last unix timestamp (in milliseconds) when message sending was managed over this entity
-  void updateIncomingActivityTime() throw();
-  void updateOutgoingActivityTime() throw();
+  void updateIncomingActivityTime() ;
+  void updateOutgoingActivityTime() ;
 
   // Availability
   bool a_available; // any of the server-sessions must be bound
-  void availabilityLost() throw();
-  void availabilityRecovered() throw();
-  bool refreshAvailability() throw(); // return true if change
+  void availabilityLost() ;
+  void availabilityRecovered() ;
+  bool refreshAvailability() ; // return true if change
 
-  void attach() throw(); // attach server socket to the communicator
-  void attachPlanning() throw(); // used when attach fails (socket already in use, etc.)
+  void attach() ; // attach server socket to the communicator
+  void attachPlanning() ; // used when attach fails (socket already in use, etc.)
 
   typedef int serverSession_key;
-  serverSession_key getServerSessionKey(const anna::comm::ClientSocket&) const throw(); // hash for Client Socket INetAddress serialization
+  serverSession_key getServerSessionKey(const anna::comm::ClientSocket&) const ; // hash for Client Socket INetAddress serialization
   typedef std::map <serverSession_key, ServerSession*> serverSession_container;
   typedef serverSession_container::value_type serverSession_value_type;
   typedef serverSession_container::iterator serverSession_iterator;
   typedef serverSession_container::const_iterator const_serverSession_iterator;
   serverSession_container a_serverSessions;
   anna::Recycler<ServerSession> a_serverSessionsRecycler;
-  serverSession_iterator serverSession_find(const serverSession_key&) throw();
-  serverSession_iterator serverSession_begin() throw() { return a_serverSessions.begin(); }
-  serverSession_iterator serverSession_end() throw() { return a_serverSessions.end(); }
-  static ServerSession* serverSession(serverSession_iterator ii) throw() { return ii->second; }
-  const_serverSession_iterator serverSession_begin() const throw() { return a_serverSessions.begin(); }
-  const_serverSession_iterator serverSession_end() const throw() { return a_serverSessions.end(); }
-  static const ServerSession* serverSession(const_serverSession_iterator ii) throw() { return ii->second; }
+  serverSession_iterator serverSession_find(const serverSession_key&) ;
+  serverSession_iterator serverSession_begin() { return a_serverSessions.begin(); }
+  serverSession_iterator serverSession_end() { return a_serverSessions.end(); }
+  static ServerSession* serverSession(serverSession_iterator ii) { return ii->second; }
+  const_serverSession_iterator serverSession_begin() const { return a_serverSessions.begin(); }
+  const_serverSession_iterator serverSession_end() const { return a_serverSessions.end(); }
+  static const ServerSession* serverSession(const_serverSession_iterator ii) { return ii->second; }
 
   // INTERNAL CREATORS AND CLOSE METHODS
-  ServerSession *createServerSession(const anna::comm::ClientSocket&) throw(anna::RuntimeException);
-  void closeServerSession(ServerSession*) throw(anna::RuntimeException);
+  ServerSession *createServerSession(const anna::comm::ClientSocket&) noexcept(false);
+  void closeServerSession(ServerSession*) noexcept(false);
 
   // INTERNAL ALLOCATORS
-  ServerSession* allocateServerSession() throw();
-  void releaseServerSession(ServerSession*) throw();
+  ServerSession* allocateServerSession() ;
+  void releaseServerSession(ServerSession*) ;
 
   // Auxiliary
   serverSession_iterator a_deliveryIterator;
@@ -162,22 +135,30 @@ public:
   * Sets the local server key
   * @param LocalServer key
   */
-  void setKey(const socket_t &key) throw() { a_key = key; }
+  void setKey(const socket_t &key) { a_key = key; }
 
   /**
      Sets the server socket optional description
 
      @param description Server socket description
   */
-  void setDescription(const std::string description) throw() { a_description = description; }
+  void setDescription(const std::string description) { a_description = description; }
 
+  /**
+     Set timeout to consider failed a request.
+     \param v Requests class code.
+     \param millisecond Milliseconds wait before considering the requests failed.
+
+     Timers are internally managed and automatically activated.
+  */
+  void setClassCodeTimeout(const ClassCode::_v v, const anna::Millisecond & millisecond) ;
 
   /**
      Sets the server socket optional category
 
      @param description Server socket category
   */
-  void setCategory(int category) throw() { a_category = category; }
+  void setCategory(int category) { a_category = category; }
 
   /**
      Sets the maximum supported connections.
@@ -187,7 +168,7 @@ public:
 
      @param maxConnections Number of maximum connections allowed
   */
-  void setMaxConnections(int maxConnections) throw(anna::RuntimeException);
+  void setMaxConnections(int maxConnections) noexcept(false);
 
   /**
      Sets the maximum allowed inactivity time on server sessions born over the local server before being reset.
@@ -195,14 +176,13 @@ public:
 
      @param allowedInactivityTime Inactivity time allowed
   */
-  void setAllowedInactivityTime(const anna::Millisecond & allowedInactivityTime) throw() { a_allowedInactivityTime = allowedInactivityTime; }
+  void setAllowedInactivityTime(const anna::Millisecond & allowedInactivityTime) { a_allowedInactivityTime = allowedInactivityTime; }
 
   /**
   * Sets the diameter::comm::Engine
   * @param e Diameter::comm::Engine
   */
-  void setEngine(Engine *e) throw() { a_engine = e; }
-
+  void setEngine(Engine *e) { a_engine = e; }
 
   // getters
 
@@ -210,29 +190,29 @@ public:
   * Gets the local server key
   * @return LocalServer key
   */
-  const socket_t & getKey() const throw() { return a_key; }
+  const socket_t & getKey() const { return a_key; }
 
   /**
      Gets the number of maximum accepted connections that server socket is configured to handle
   */
-  int getMaxConnections() const throw() { return a_maxConnections; }
+  int getMaxConnections() const { return a_maxConnections; }
 
   /**
      Gets the number of current connections being established through server socket
   */
-  int getCurrentConnections() const throw() { return a_currentConnections; }
+  int getCurrentConnections() const { return a_currentConnections; }
 
   /**
      Gets the maximum allowed inactivity time on server sessions born over the local server before being reset
 
      @return Inactivity time allowed
   */
-  const anna::Millisecond & getAllowedInactivityTime() const throw() { return a_allowedInactivityTime; }
+  const anna::Millisecond & getAllowedInactivityTime() const { return a_allowedInactivityTime; }
 
   /**
      Returns true when any of the server-sessions is Bound. False when all not-bound.
   */
-  bool isAvailable() const throw() { return a_available; }
+  bool isAvailable() const { return a_available; }
 
   // helpers
 
@@ -243,38 +223,38 @@ public:
      @param lock Locks disabled state (make it permanent even if new connections margin is reached).
      Used during diameter agent isolation (lost of service, maintenance, etc.)
   */
-  void disable(bool lock = false) throw(anna::RuntimeException);
+  void disable(bool lock = false) noexcept(false);
 
   /** Enables local server socket (listener)
 
      @param unlock Unlocks permanent disabled states
   */
-  void enable(bool unlock = false) throw(anna::RuntimeException);
+  void enable(bool unlock = false) noexcept(false);
 
   /**
      Gets the number of requests messages over-the-air.
 
      @return OTA messages.
   */
-  int getOTARequests() const throw();
+  int getOTARequests() const ;
 
   /**
      Returns idle state (no pending answers).
 
      @return Idle state.
   */
-  bool idle() const throw() { return (getOTARequests() == 0); }
+  bool idle() const { return (getOTARequests() == 0); }
 
   /**
      Close the local server means two things: close the server socket and close all the server sessions born
      from this local server freeing such server sessions resources.
   */
-  void close() throw(anna::RuntimeException);
+  void close() noexcept(false);
 
   /**
      Performs coherent server socket close procedure zeroing margin between current established connections and maximum allowed.
   */
-  void resetConnectionsMargin() throw(anna::RuntimeException) { setMaxConnections(a_currentConnections); }
+  void resetConnectionsMargin() noexcept(false) { setMaxConnections(a_currentConnections); }
 
 
   /**
@@ -287,7 +267,7 @@ public:
    *
    * \warning If no server-session found, an exception is launched by default.
    */
-  ServerSession* findServerSession(const anna::comm::ClientSocket &clientSocket, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException);
+  ServerSession* findServerSession(const anna::comm::ClientSocket &clientSocket, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) noexcept(false);
 
   /**
    * Returns server-session instance identified by socket id provided (hash over serialized client socket information).
@@ -299,7 +279,7 @@ public:
    *
    * \warning If no server-session found, an exception is launched by default.
    */
-  ServerSession* findServerSession(int socketId, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) throw(anna::RuntimeException);
+  ServerSession* findServerSession(int socketId, anna::Exception::Mode::_v emode = anna::Exception::Mode::Throw) noexcept(false);
 
 
   /**
@@ -316,14 +296,14 @@ public:
      the resources in spite of any fail. If a specific socket id is provided, only this socket is used without trying any other
      and returning false if fails.
   */
-  bool send(const Message*, int socketId = -1 /* default uses readSocketId() */) throw(anna::RuntimeException);
-  bool send(const Message& message, int socketId = -1 /* default uses readSocketId() */) throw(anna::RuntimeException) { return send(&message, socketId); }
+  bool send(const Message*, int socketId = -1 /* default uses readSocketId() */) noexcept(false);
+  bool send(const Message& message, int socketId = -1 /* default uses readSocketId() */) noexcept(false) { return send(&message, socketId); }
 
   /**
      Gets the last used resource (server session) during sending.
      Broadcast doesn't updates this information.
   */
-  ServerSession *getLastUsedResource() const throw() { return (a_lastUsedResource); }
+  ServerSession *getLastUsedResource() const { return (a_lastUsedResource); }
 
   /**
      Before sending a message over each local server, socketId could be specified to select
@@ -337,7 +317,7 @@ public:
      @return Socket-id (hash over serialized client socket information). Value '-1' if round-robin is desired.
      If socket-id is unkonwn, send procedure will throw an exception.
   */
-  virtual int readSocketId(const Message *message) const throw() { return -1; }
+  virtual int readSocketId(const Message *message) const { return -1; }
 
   /**
      Sent a message to all the server sessions.
@@ -348,28 +328,28 @@ public:
      @return Returns true (success) only when broadcast is success over all the entity servers. If any server fails,
      then false is returned.
   */
-  bool broadcast(const Message *message) throw(anna::RuntimeException);
-  bool broadcast(const Message &message) throw(anna::RuntimeException) { return broadcast(&message); }
+  bool broadcast(const Message *message) noexcept(false);
+  bool broadcast(const Message &message) noexcept(false) { return broadcast(&message); }
 
 
   /**
      Class string representation
      \return String with relevant information for this instance.
   */
-  std::string asString() const throw();
+  std::string asString() const ;
 
   /**
      Class xml representation
      \param parent Parent XML node on which hold this instance information.
      \return XML document with relevant information for this instance.
   */
-  anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
+  anna::xml::Node* asXML(anna::xml::Node* parent) const ;
 
   // Statistics
-  void updateProcessingTimeStatisticConcept(const double &value) throw();
-  void updateReceivedMessageSizeStatisticConcept(const double &value) throw();
-  int getProcessingTimeStatisticConcept() const throw() { return a_processing_time__StatisticConceptId; }
-  int getReceivedMessageSizeStatisticConcept() const throw() { return a_received_message_size__StatisticConceptId; }
+  void updateProcessingTimeStatisticConcept(const double &value, const anna::diameter::CommandId &cid) ;
+  void updateReceivedMessageSizeStatisticConcept(const double &value, const anna::diameter::CommandId &cid) ;
+//  int getProcessingTimeStatisticConcept() const { return a_processing_time__StatisticConceptId; }
+//  int getReceivedMessageSizeStatisticConcept() const { return a_received_message_size__StatisticConceptId; }
 
 protected:
 
@@ -380,31 +360,51 @@ protected:
      Default implementation traces warning event
      \param serverSession ServerSession from which shutdown has been received
   */
-  virtual void eventPeerShutdown(const ServerSession* serverSession) throw();
+  virtual void eventPeerShutdown(const ServerSession* serverSession) ;
+
+  /**
+     Handler about a request retransmission over the server-session.
+     Default implementation traces warning event
+     \param serverSession ServerSession from which retransmission happened
+     \param request Retransmitted request message
+  */
+  virtual void eventRequestRetransmission(const ServerSession* serverSession, Message *request) ;
 
   /**
      Handler for diameter client responses
 
      \param response Answer container object for corresponding diameter request
+     \param myNode Own origin host
   */
-  virtual void eventResponse(const Response& response) throw(anna::RuntimeException) = 0;
+  virtual void eventResponse(const Response& response, const anna::diameter::comm::OriginHost *myNode) noexcept(false) = 0;
 
   /**
      Handler for diameter client requests
 
      \param serverSession ServerSession from which request has been received
      \param request Request data block object for corresponding diameter reception
+     \param myNode Own origin host
   */
-  virtual void eventRequest(ServerSession* serverSession, const anna::DataBlock& request) throw(anna::RuntimeException) = 0;
-  //void eventRequest(ServerSession* serverSession, const Message& request) throw(anna::RuntimeException);
+  virtual void eventRequest(ServerSession* serverSession, const anna::DataBlock& request, const anna::diameter::comm::OriginHost *myNode) noexcept(false) = 0;
+  //void eventRequest(ServerSession* serverSession, const Message& request) noexcept(false);
 
   /**
      Handler for diameter client responses out of context
 
      \param serverSession ServerSession from which request has been received
      \param response Answer data block object without context match
+     \param myNode Own origin host
+  */
+  virtual void eventUnknownResponse(ServerSession* serverSession, const anna::DataBlock& response, const anna::diameter::comm::OriginHost *myNode) noexcept(false) = 0;
+
+  /**
+     Handler for diameter client Disconnect-Peer-Answer messages
+
+     \param serverSession ServerSession from which request has been received
+     \param response Answer data block object without context match
+     \param myNode Own origin host
   */
-  virtual void eventUnknownResponse(ServerSession* serverSession, const anna::DataBlock& response) throw(anna::RuntimeException) = 0;
+  virtual void eventDPA(ServerSession* serverSession, const anna::DataBlock& response, const anna::diameter::comm::OriginHost *myNode) noexcept(false) = 0;
 
 
   friend class anna::diameter::comm::Timer;
@@ -419,4 +419,3 @@ protected:
 }
 
 #endif
-