Remove dynamic exceptions
[anna.git] / include / anna / diameter.comm / Entity.hpp
index e8e1b95..b8ade9b 100644 (file)
@@ -1,37 +1,9 @@
-// ANNA - Anna is Not 'N' Anymore
-//
-// (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
-//
-// https://bitbucket.org/testillano/anna
-//
-// 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 Google Inc. 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_Entity_hpp
@@ -47,6 +19,8 @@
 #include <anna/core/RuntimeException.hpp>
 #include <anna/core/util/Millisecond.hpp>
 
+#include <anna/diameter.comm/ClassCode.hpp>
+
 
 namespace anna {
 class DataBlock;
@@ -67,6 +41,7 @@ class Engine;
 class Server;
 class Response;
 class Message;
+class ClientSession;
 
 
 /**
@@ -74,6 +49,16 @@ class Message;
 */
 class Entity {
 
+public:
+
+  /**
+   * Sessions based models type
+   */
+  struct SessionBasedModelsType { enum _v { RoundRobin, SessionIdOptionalPart, SessionIdHighPart, SessionIdLowPart /* default */ }; };
+
+private:
+
+
   std::vector<Server*> a_servers;
   int a_maxServers; // -1 means "no limit to add servers"
   std::string a_description;
@@ -84,14 +69,18 @@ class Entity {
   // Engine
   Engine *a_engine;
 
+  // Balance and socket selection:
+  bool a_balance;
+  SessionBasedModelsType::_v a_sessionBasedModelsType;
+
   // Availability
   bool a_available; // any of the servers must be bound
-  void availabilityLost() throw();
-  void availabilityRecovered() throw();
-  bool refreshAvailability() throw(); // return true if change
-  void assertReady() throw(anna::RuntimeException);
-  void initialize() throw();
-  void childIdle() const throw();
+  void availabilityLost() ;
+  void availabilityRecovered() ;
+  bool refreshAvailability() ; // return true if change
+  void assertReady() noexcept(false);
+  void initialize() ;
+  void childIdle() const ;
 
   // Selected for remove
   bool a_deprecated; // entity has been selected as deprecated (will be removed when idle)
@@ -105,12 +94,14 @@ class Entity {
   // 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() ;
 
   // Private close/destroy method
-  void close(bool destroy) throw(anna::RuntimeException);
+  void close(bool destroy) noexcept(false);
 
+  // helpers
+  static const char* asText(const SessionBasedModelsType::_v) ;
 
 public:
 
@@ -128,14 +119,14 @@ public:
    *
    * @param maxServers Maximum number of servers managed by the entity.
    */
-  void setMaxServers(int maxServers) throw() { a_maxServers = maxServers; }
+  void setMaxServers(int maxServers) { a_maxServers = maxServers; }
 
   /**
    * Gets the maximum number of servers managed by the entity.
    *
    * @return Maximum number of servers managed by the entity.
    */
-  int getMaxServers() const throw() { return a_maxServers; }
+  int getMaxServers() const { return a_maxServers; }
 
 
   /**
@@ -143,22 +134,27 @@ public:
    *
    * @param description Entity description. Empty by default.
    */
-  void setDescription(const std::string &description) throw() { a_description = description; }
+  void setDescription(const std::string &description) { a_description = description; }
 
   /**
    * Gets the entity description.
    *
    * @return Entity description.
    */
-  const std::string & getDescription() const throw() { return a_description; }
+  const std::string & getDescription() const { return a_description; }
 
 
   /**
   * 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; }
 
+  /**
+  * Gets the diameter::comm::Engine
+  * @return Diameter::comm::Engine
+  */
+  Engine *getEngine() const { return a_engine; }
 
   /**
   * Add a server to the entity and create all the servers configured at #setSocketsPerDiameterServer within that server.
@@ -167,21 +163,21 @@ public:
   *
   * @return Returns success on send operation over any server within the entity
   */
-  void addServer(const socket_t & serverId) throw(anna::RuntimeException);
+  void addServer(const socket_t & serverId) noexcept(false);
 
   /**
    * Binds entity servers.
    *
    * @return Returns true if all client-session were successfully bound
    */
-  bool bind() throw(anna::RuntimeException);
+  bool bind() noexcept(false);
 
   /**
    * Propagate auto recovery configuration to servers within entity
    *
    * @param autoRecovery Auto recovery indicator. True by default.
    */
-  void raiseAutoRecovery(bool autoRecovery = true) throw(anna::RuntimeException);
+  void raiseAutoRecovery(bool autoRecovery = true) noexcept(false);
 
   /**
      Sets timeout for wait responses for any class code request for all entity servers
@@ -189,28 +185,43 @@ public:
      \param v Diameter request type.
      \param millisecond Milliseconds for timeout
   */
-  void setClassCodeTimeout(const ClassCode::_v v, const anna::Millisecond & millisecond) throw();
+  void setClassCodeTimeout(const ClassCode::_v v, const anna::Millisecond & millisecond) ;
 
   /**
      Sets entity category. Used by application in order to categorize or clasify.
 
      @param category Entity category
   */
-  void setCategory(int category) throw() { a_category = category; }
+  void setCategory(int category) { a_category = category; }
 
   /**
      Gets entity category. Used by application in order to categorize or clasify.
 
      @return Entity category
   */
-  int getCategory() const throw() { return a_category; }
+  int getCategory() const { return a_category; }
 
   /**
      Gets the last used resource (server) during sending.
      Broadcast doesn't updates this information.
   */
-  Server *getLastUsedResource() const throw() { return (a_lastUsedResource); }
+  Server *getLastUsedResource() const { return (a_lastUsedResource); }
+
+
+  /**
+   * Balance over entity servers or use standard behaviour (first primary, secondary if fails, etc.).
+   * New created entities have balance disabled.
+   *
+   * @param balance True or false to enable or disable.
+   */
+   void setBalance (bool balance) { a_balance = balance; }
 
+  /**
+   * Gets the balance mode
+   *
+   * @return True if balance over entity servers is enabled, false if standard behaviour is configured (default).
+   */
+   bool getBalance() const { return a_balance; }
 
 
 // SIMPLE BALANCE or STANDARD documentation version
@@ -236,15 +247,15 @@ public:
 //   */
 
 // OJO: en el caso estandard, no se prueban todas las sessiones de un servidor si tiene mas de una, luego la alarma
-//      generada en caso de error, presupone que las sessiones no usadas, también darían error, lo cual no tiene porque
+//      generada en caso de error, presupone que las sessiones no usadas, tambi�n dar�an error, lo cual no tiene porque
 //      ser cierto. En condiciones normales, los servidores tienen una session, con lo que lo anterior es cierto y el
 //      la practica es lo mas normal.
 
   /**
      Sent a message to the entity. First uses primary server, secondary if fails and so on to the
      last defined resource (server) within entity. Another sending algorithm (non standard) could
-     be enabled (balance boolean parameter): it consist in round-robin server selection to set the
-     first resource in a complete cycle (standard behaviour tries all servers from FIRST defined).
+     be enabled (@setBalance): it consist in round-robin server selection to set the first resource
+     in a complete cycle (standard behaviour tries all servers from FIRST defined).
      Anyway, last used delivery resource could be known through #getLastUsedResource().
 
      When the message is a request, a timer will be set automatically to control the response time.
@@ -252,15 +263,26 @@ public:
      timeout value will be configured at #setClassCodeTimeout.
 
      \param message Message sent.
-     \param balance False by default (standard beaviour), but useful to balance over servers within entity.
 
      @return Boolean about success in send operation. Implies true result when any of the entity servers could
      send the message, and false when neither of the servers was available or fail to send the message (an alarm
      and error counter will be generated in this case). Broadcast try to send all over the resources in spite of
      any fail.
   */
-  bool send(const Message *message, bool balance = false) throw(anna::RuntimeException);
-  bool send(const Message &message, bool balance = false) throw(anna::RuntimeException) { return send(&message, balance); }
+  bool send(const Message *message) noexcept(false);
+  bool send(const Message &message) noexcept(false) { return send(&message); }
+
+  /**
+   * Sets sessions based models type.
+   * \param sessionBasedModelsType Session based models type: RoundRobin, SessionIdLowPart (default), SessionIdHighPart or SessionIdOptionalPart.
+   */
+  void setSessionBasedModelsType(const SessionBasedModelsType::_v sessionBasedModelsType)  { a_sessionBasedModelsType = sessionBasedModelsType; }
+
+  /**
+   * Returns sessions based models type.
+   * \return Session based models type: RoundRobin, SessionIdLowPart, SessionIdHighPart or SessionIdOptionalPart.
+   */
+  SessionBasedModelsType::_v getSessionBasedModelsType() const { return a_sessionBasedModelsType; }
 
 
   /**
@@ -306,7 +328,7 @@ public:
      subscriber and service aware contextual load balancing strategies. By default, Session-Id avp
      is used to select the resource. Session-Id is split into 4 sections: diameter identity, high
      part, low part and optional part. Default implementation analizes 'low' part, returning its
-     value as reference for socket selection.
+     value as reference for socket selection. Use @setSessionBasedModelsType to change this behaviour.
      </pre>
 
      When server is configured as single client session (max client sessions equal to 1), entity will ignore
@@ -318,7 +340,7 @@ public:
      @return Socket-id used within range [0,maxClientSessions-1]. Value '-1' if round-robin is desired.
      If socket-id is return out of range, send procedure will throw an exception.
   */
-  virtual int readSocketId(const Message *message, int maxClientSessions) const throw();
+  virtual int readSocketId(const Message *message, int maxClientSessions) const ;
 
 
   /**
@@ -330,24 +352,24 @@ 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); }
 
 
   /**
      Returns true when any of the entity servers is Bound. False when all not-bound.
   */
-  bool isAvailable() const throw() { return a_available; }
+  bool isAvailable() const { return a_available; }
 
   /**
      Returns true when the entity has been selected as deprecated
   */
-  bool isDeprecated() const throw() { return a_deprecated; }
+  bool isDeprecated() const { return a_deprecated; }
 
   /**
      Sets the entity deprecated state
   */
-  void setDeprecated(bool deprecated = true) throw() { a_deprecated = deprecated; }
+  void setDeprecated(bool deprecated = true) { a_deprecated = deprecated; }
 
 
   /**
@@ -355,81 +377,81 @@ public:
 
      @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); }
 
 
-  std::vector<Server*>::iterator begin() throw() { return a_servers.begin(); }
-  std::vector<Server*>::iterator end() throw() { return a_servers.end(); }
-  std::vector<Server*>::const_iterator begin() const throw() { return a_servers.begin(); }
-  std::vector<Server*>::const_iterator end() const throw() { return a_servers.end(); }
+  std::vector<Server*>::iterator begin() { return a_servers.begin(); }
+  std::vector<Server*>::iterator end() { return a_servers.end(); }
+  std::vector<Server*>::const_iterator begin() const { return a_servers.begin(); }
+  std::vector<Server*>::const_iterator end() const { return a_servers.end(); }
 
   /**
      Close all the entity servers (close client-sessions within them). Depending on client-session configuration ('OnDisconnect' behaviour),
      pending answers will be wait (graceful) or ignored (immediate-abrupt close).
      Resources are not destroyed.
   */
-  void close() throw(anna::RuntimeException) { close(false /* no destroy */); }
+  void close() noexcept(false) { close(false /* no destroy */); }
 
   // helpers
 
   /**
      Number of currently configured servers
   */
-  int getNumberOfServers() const throw() { return a_servers.size(); }
+  int getNumberOfServers() const { return a_servers.size(); }
 
   /**
      Number of maximum allowed servers
   */
-  int getMaxServerss() const throw() { return a_maxServers; }
+  int getMaxServerss() const { return a_maxServers; }
 
   /**
      List of (address,port) pairs defining entity servers
   */
-  socket_v getAddressPortList() const throw();
+  socket_v getAddressPortList() const ;
 
 
   /**
      Deny resources for delivery restriction.
      Deny all its servers
   */
-  void hide() throw();
+  void hide() ;
 
   /**
      Allow resource for delivery permission.
      Allow all its servers
   */
-  void show() throw();
+  void show() ;
 
   /**
      Returns true when all its servers resources are hidden for application messages delivery
   */
-  bool hidden() const throw();
+  bool hidden() const ;
 
   /**
      Returns true when all its servers resources are shown for application messages delivery
   */
-  bool shown() const throw();
+  bool shown() const ;
 
 
   /**
      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 ;
 
 protected:
 
@@ -439,14 +461,22 @@ protected:
      Default implementation traces warning event
      \param clientSession ClientSession from which shutdown has been received
   */
-  virtual void eventPeerShutdown(const ClientSession* clientSession) throw();
+  virtual void eventPeerShutdown(const ClientSession* clientSession) ;
+
+  /**
+     Handler about a request retransmission over the session.
+     Default implementation traces warning event
+     \param clientSession ClientSession from which retransmission happened
+     \param request Retransmitted request message
+  */
+  virtual void eventRequestRetransmission(const ClientSession* clientSession, Message *request) ;
 
   /**
      Handler for diameter server (server) responses
 
      \param response Answer container object for corresponding diameter request
   */
-  virtual void eventResponse(const Response& response) throw(anna::RuntimeException) = 0;
+  virtual void eventResponse(const Response& response) noexcept(false) = 0;
 
   /**
      Handler for diameter server (server) requests
@@ -454,8 +484,8 @@ protected:
      \param clientSession ClientSession from which request has been received
      \param request Diameter request message received
   */
-  virtual void eventRequest(ClientSession* clientSession, const anna::DataBlock &request) throw(anna::RuntimeException) = 0;
-  //virtual void eventRequest(ClientSession* clientSession, const Message& request) throw(anna::RuntimeException) = 0;
+  virtual void eventRequest(ClientSession* clientSession, const anna::DataBlock &request) noexcept(false) = 0;
+  //virtual void eventRequest(ClientSession* clientSession, const Message& request) noexcept(false) = 0;
 
   /**
      Handler for diameter session responses out of context
@@ -463,7 +493,17 @@ protected:
      \param clientSession ClientSession from which request has been received
      \param response Answer data block object without context match
   */
-  virtual void eventUnknownResponse(ClientSession *clientSession, const anna::DataBlock& response) throw(anna::RuntimeException) = 0;
+  virtual void eventUnknownResponse(ClientSession *clientSession, const anna::DataBlock& response) noexcept(false) = 0;
+
+  /**
+     Handler for diameter session Disconnect-Peer-Answer messages
+
+     \param clientSession ClientSession from which request has been received
+     \param response Answer data block object without context match
+  */
+  virtual void eventDPA(ClientSession *clientSession, const anna::DataBlock& response) noexcept(false) = 0;
+
+
 
 
   friend class Engine;