// Local
#include "Procedure.hpp"
-void Procedure::execute(const std::string &args, std::string &response, anna::diameter::comm::OriginHost *originHost) throw(anna::RuntimeException) {
+void Procedure::execute(const std::string &args, std::string &response) throw(anna::RuntimeException) {
response = "Empty default implementation. Make dynamic library and reimplement this method.";
if (args != "" ) {
response += " Provided argument(s) ignored: ";
#include <anna/comm/comm.hpp>
-namespace anna {
- namespace diameter {
- namespace comm {
- class OriginHost;
- }
- }
-}
-
class Procedure {
anna::comm::Application *a_app;
public:
Procedure(anna::comm::Application *app) : a_app(app) {;}
- virtual void execute(const std::string &args, std::string &response, anna::diameter::comm::OriginHost *originHost) throw(anna::RuntimeException);
+ virtual void execute(const std::string &args, std::string &response) throw(anna::RuntimeException);
};
#endif
#include <anna/diameter/helpers/dcca/functions.hpp>
#include <anna/diameter/helpers/dcca/functions.hpp>
#include <anna/diameter.comm/OriginHost.hpp>
+#include <anna/diameter.comm/OriginHostManager.hpp>
// Local
#include "Procedure.hpp"
}
}
-void Procedure::execute(const std::string &args, std::string &response, anna::diameter::comm::OriginHost *originHost) throw(anna::RuntimeException) {
+void Procedure::execute(const std::string &args, std::string &response) throw(anna::RuntimeException) {
response = "Dynamic procedure failed to process '"; response += args; response += "': ";
anna::diameter::codec::Message ccri, ccrt;
anna::diameter::codec::Avp *ccri_sessionId, *ccrt_sessionId, *ccri_framedIPAddress, *ccrt_framedIPAddress, *ccri_msisdn, *ccri_imsi;
anna::diameter::codec::Avp *si1, *si2, *sidata1, *sidata2, *sitype1;
+ anna::diameter::codec::Avp *ccri_originHost;
///////// CCR-Initial:
ccri.loadXML(ccr_i);
// Session-Id & Framed-Ip-Address AVPs
ccri_sessionId = ccri.getAvp("Session-Id");
ccri_framedIPAddress = ccri.getAvp("Framed-IP-Address");
+ ccri_originHost = ccri.getAvp("Origin-Host");
// Subscription-Id AVPs
if (ccri.countAvp("Subscription-Id") != 2) {
char cad_framed[16];
anna::testing::TestCase *tc;
+ // Origin host manager:
+ anna::diameter::comm::OriginHostManager &ohm = anna::diameter::comm::OriginHostManager::instantiate();
+ // Assume the oh name from CCR-I (same as CCR-T):
+ std::string originHostName = ccri_originHost->getDiameterIdentity()->getValue();
+ anna::diameter::comm::OriginHost *originHost = ohm.getOriginHost(originHostName);
+
for (ll_index = 0; ll_index < ll_seq_size; ll_index++) {
// Calculate next values ////////////////////////////////////////////////////////////
#include <anna/comm/comm.hpp>
-namespace anna {
- namespace diameter {
- namespace comm {
- class OriginHost;
- }
- }
-}
-
class Procedure {
anna::comm::Application *a_app;
public:
Procedure(anna::comm::Application *app) : a_app(app) {;}
- virtual void execute(const std::string &args, std::string &response, anna::diameter::comm::OriginHost *originHost) throw(anna::RuntimeException);
+ virtual void execute(const std::string &args, std::string &response) throw(anna::RuntimeException);
};
#endif
#include <anna/diameter.comm/ApplicationMessageOamModule.hpp>
#include <anna/testing/defines.hpp>
#include <anna/xml/xml.hpp>
+#include <anna/diameter.comm/OriginHost.hpp>
+#include <anna/diameter.comm/OriginHostManager.hpp>
#include <Procedure.hpp>
// Process
#include <Launcher.hpp>
#include <MyDiameterEngine.hpp>
-#include <anna/diameter.comm/OriginHost.hpp>
#include <anna/testing/TestManager.hpp>
#include <anna/testing/TestCase.hpp>
//a_admlMinResolution = (anna::Millisecond)100;
a_counterRecorderClock = NULL;
- // a_originHosts.clear();
a_workingNode = NULL;
a_httpServerSocket = NULL;
burstLog = (*it)->getAttribute("burstLog", false /* no exception */); // (yes | no)
// Basic checkings:
- origin_hosts_it nodeIt = a_originHosts.find(originHost->getValue());
- if (nodeIt != a_originHosts.end()) {
+ anna::diameter::comm::OriginHostManager &ohm = anna::diameter::comm::OriginHostManager::instantiate();
+ anna::diameter::comm::OriginHost *oh = ohm.getOriginHost(originHost->getValue());
+ if (oh) {
std::string msg = "Already registered such Origin-Host: "; msg += originHost->getValue();
throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
}
if (eventOperation) commEngine->lazyInitialize();
// Node and Codec Engine registration ///////////////////////////////////////////////////////
- a_originHosts[originHost->getValue()] = a_workingNode;
+ ohm.registerOriginHost(originHost->getValue(), a_workingNode);
/////////////////////////////////////////////////////////////////////////////////////////////
}
}
bool Launcher::setWorkingNode(const std::string &name) throw() {
bool result = false;
- origin_hosts_it nodeIt = a_originHosts.find(name);
- if (nodeIt == a_originHosts.end()) {
- LOGWARNING(
- std::string msg = "Unknown node with name '"; msg += name; msg += "'. Ignoring ...";
- anna::Logger::warning(msg, ANNA_FILE_LOCATION);
- );
- }
- else {
- a_workingNode = const_cast<anna::diameter::comm::OriginHost*>(nodeIt->second);
+ anna::diameter::comm::OriginHostManager &ohm = anna::diameter::comm::OriginHostManager::instantiate();
+ anna::diameter::comm::OriginHost *oh = ohm.getOriginHost(name);
+
+ if (oh) {
+ a_workingNode = const_cast<anna::diameter::comm::OriginHost*>(oh);
result = true;
}
return result;
}
-anna::diameter::comm::OriginHost *Launcher::getOriginHost(const std::string &oh) const throw(anna::RuntimeException) {
- origin_hosts_it it = a_originHosts.find(oh);
- if (it != a_originHosts.end()) return it->second;
- throw anna::RuntimeException(anna::functions::asString("There is no origin host registered as '%s' (set Origin-Host avp correctly or force a specific host with 'node' operation)", oh.c_str()), ANNA_FILE_LOCATION);
+anna::diameter::comm::OriginHost *Launcher::getOriginHost(const std::string &name) const throw(anna::RuntimeException) {
+ anna::diameter::comm::OriginHostManager &ohm = anna::diameter::comm::OriginHostManager::instantiate();
+ anna::diameter::comm::OriginHost *result = ohm.getOriginHost(name);
+
+ if (!result)
+ throw anna::RuntimeException(anna::functions::asString("There is no origin host registered as '%s' (set Origin-Host avp correctly or force a specific host with 'node' operation)", name.c_str()), ANNA_FILE_LOCATION);
+
+ return result;
}
anna::diameter::comm::OriginHost *Launcher::getOriginHost(const anna::diameter::codec::Message &message) const throw(anna::RuntimeException) {
return (getOriginHost(originHost));
}
+bool Launcher::uniqueOriginHost() const throw() {
+ anna::diameter::comm::OriginHostManager &ohm = anna::diameter::comm::OriginHostManager::instantiate();
+ return (ohm.size() == 1);
+}
+
+
void Launcher::updateOperatedOriginHostWithMessage(const anna::diameter::codec::Message &message) throw(anna::RuntimeException) {
if (!a_operatedHost) // priority for working node by mean 'node' operation
a_operatedHost = getOriginHost(message);
// Start client connections //////////////////////////////////////////////////////////////////////////////////
MyDiameterEntity *entity;
- for (origin_hosts_it it = a_originHosts.begin(); it != a_originHosts.end(); it++) {
+ anna::diameter::comm::OriginHostManager &ohm = anna::diameter::comm::OriginHostManager::instantiate();
+ for (diameter::comm::origin_hosts_it it = ohm.begin(); it != ohm.end(); it++) {
entity = (MyDiameterEntity *)(it->second->getEntity());
if (entity) entity->bind();
}
a_workingNode->getCommEngine()->resetStatistics();
}
else {
- for (origin_hosts_it it = a_originHosts.begin(); it != a_originHosts.end(); it++) {
+ anna::diameter::comm::OriginHostManager &ohm = anna::diameter::comm::OriginHostManager::instantiate();
+ for (diameter::comm::origin_hosts_it it = ohm.begin(); it != ohm.end(); it++) {
it->second->getCommEngine()->resetStatistics();
}
}
if (args == "" && op_size != 7)
throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
try {
- p.execute(args, response_content, getWorkingNode());
+ p.execute(args, response_content);
}
catch(anna::RuntimeException &ex) {
ex.trace();
result->createAttribute("InitialWorkingDirectory", a_initialWorkingDirectory);
result->createAttribute("SecondsLifeTime", anna::time::functions::lapsedMilliseconds() / 1000);
// Diameter:
- for (origin_hosts_it it = a_originHosts.begin(); it != a_originHosts.end(); it++) {
+ anna::diameter::comm::OriginHostManager &ohm = anna::diameter::comm::OriginHostManager::instantiate();
+ for (diameter::comm::origin_hosts_it it = ohm.begin(); it != ohm.end(); it++) {
it->second->asXML(result);
}
MyCounterRecorderClock *a_counterRecorderClock;
// Nodes deployment:
- origin_hosts_t a_originHosts;
anna::diameter::comm::OriginHost *a_workingNode;
anna::diameter::comm::OriginHost *a_operatedHost; // auxiliary for eventOperation
void startServices() throw(anna::RuntimeException);
bool setWorkingNode(const std::string &name) throw();
- anna::diameter::comm::OriginHost *getOriginHost(const std::string &oh) const throw(anna::RuntimeException);
+ anna::diameter::comm::OriginHost *getOriginHost(const std::string &name) const throw(anna::RuntimeException);
anna::diameter::comm::OriginHost *getOriginHost(const anna::diameter::codec::Message &message) const throw(anna::RuntimeException);
- bool uniqueOriginHost() const throw() { return (a_originHosts.size() == 1); }
+ bool uniqueOriginHost() const throw();
// Operated host for communication resources smart assignment ////////////////////////////////////////////////////////////
void updateOperatedOriginHostWithMessage(const anna::diameter::codec::Message &message) throw(anna::RuntimeException);
--- /dev/null
+// 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_OriginHostManager_hpp
+#define anna_diameter_comm_OriginHostManager_hpp
+
+
+// Project
+#include <anna/core/Singleton.hpp>
+#include <anna/diameter/defines.hpp>
+
+// Standard
+#include <map>
+#include <string>
+
+
+namespace anna {
+
+namespace xml {
+ class Node;
+
+}
+namespace diameter {
+
+namespace comm {
+
+class OriginHost;
+
+typedef std::map<std::string, anna::diameter::comm::OriginHost*> origin_hosts_t;
+typedef std::map<std::string, anna::diameter::comm::OriginHost*>::const_iterator origin_hosts_it;
+typedef std::map<std::string, anna::diameter::comm::OriginHost*>::iterator origin_hosts_nc_it;
+
+
+/**
+ * Helper class to centralize application Origin Host Nodes
+ *
+ */
+class OriginHostManager : public anna::Singleton <OriginHostManager> {
+
+private:
+
+ origin_hosts_t a_origin_hosts;
+
+ // private constructor
+ OriginHostManager() {};
+
+public:
+
+ virtual ~OriginHostManager() {;}
+
+ /**
+ * First element iterator
+ */
+ origin_hosts_it begin() const throw() { return a_origin_hosts.begin(); }
+
+ /**
+ * Last element iterator
+ */
+ origin_hosts_it end() const throw() { return a_origin_hosts.end(); }
+
+ /**
+ * Number of registered origin hosts
+ */
+ int size() const throw() { return a_origin_hosts.size(); }
+
+ /**
+ * Registers a new origin host node (externally allocated) associated to a name.
+ * If the name exists, the new origin host pointer will replace the existing one.
+ *
+ * @param name Origin Host Name
+ * @param originHost Associated Origin Host node
+ */
+ void registerOriginHost(const std::string &name, OriginHost* originHost) throw();
+
+ /**
+ * Get the associated origin host node for a provided name.
+ *
+ * @param name Origin Host Name
+ *
+ * @return Found origin host node, NULL if not found
+ */
+ OriginHost *getOriginHost(const std::string &name) const throw();
+
+ /**
+ Class XML representation.
+ \param parent XML node over which we will put instance information.
+ \return XML with class content.
+ */
+ virtual anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
+
+
+ friend class anna::Singleton <OriginHostManager>;
+};
+
+}
+}
+}
+
+#endif
+
--- /dev/null
+// 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 //
+
+
+// Project
+#include <anna/diameter.comm/OriginHostManager.hpp>
+#include <anna/diameter.comm/OriginHost.hpp>
+#include <anna/core/tracing/Logger.hpp>
+#include <anna/xml/Node.hpp>
+
+
+using namespace anna::diameter::comm;
+
+OriginHost *OriginHostManager::getOriginHost(const std::string &name) const throw() {
+ origin_hosts_it it = a_origin_hosts.find(name);
+ if (it != a_origin_hosts.end())
+ return it->second;
+
+ LOGWARNING(
+ std::string msg = "Unknown origin host node with name '"; msg += name; msg += "'";
+ anna::Logger::warning(msg, ANNA_FILE_LOCATION);
+ );
+
+ return NULL;
+}
+
+void OriginHostManager::registerOriginHost(const std::string &name, OriginHost* originHost) throw() {
+ if (!originHost) return; // nothing done
+ a_origin_hosts[name] = originHost;
+}
+
+anna::xml::Node* OriginHostManager::asXML(anna::xml::Node* parent) const
+throw() {
+ anna::xml::Node* result = parent->createChild("OriginHostManager");
+ origin_hosts_it it_min(a_origin_hosts.begin());
+ origin_hosts_it it_max(a_origin_hosts.end());
+ for (origin_hosts_it it = it_min; it != it_max; it++)
+ it->second->asXML(result);
+
+ return result;
+}
+