Remove global variables. Factory for comm/codec messages in application class (Launcher)
authorEduardo Ramos Testillano <eduardo.ramos.testillano@ericsson.com>
Mon, 18 May 2015 01:38:17 +0000 (03:38 +0200)
committerEduardo Ramos Testillano <eduardo.ramos.testillano@ericsson.com>
Mon, 18 May 2015 01:38:17 +0000 (03:38 +0200)
example/diameter/launcher/Launcher.cpp
example/diameter/launcher/Launcher.hpp
example/diameter/launcher/MyDiameterEntity.cpp
example/diameter/launcher/MyLocalServer.cpp

index 7e16c90..e4ea4ca 100644 (file)
 #define SIGUSR2_TASKS_OUTPUT_FILENAME "./sigusr2.tasks.output"
 
 
-// Auxiliary message for sendings
-anna::diameter::comm::Message G_commMsgSent2c, G_commMsgSent2e, G_commMsgFwd2c, G_commMsgFwd2e;
-anna::diameter::codec::Message G_codecMsg, G_codecAnsMsg;
-anna::Recycler<anna::diameter::comm::Message> G_commMessages; // create on requests forwards without programmed answer / release in answers forward
-
-
 Launcher::Launcher() : anna::comm::Application("launcher", "DiameterLauncher", "1.1"), a_communicator(NULL) {
   a_myDiameterEngine = new MyDiameterEngine();
   a_myDiameterEngine->setRealm("ADL.ericsson.com");
@@ -55,6 +49,23 @@ Launcher::Launcher() : anna::comm::Application("launcher", "DiameterLauncher", "
   a_burstPopCounter = 0;
 }
 
+anna::diameter::comm::Message *Launcher::createCommMessage() throw(anna::RuntimeException) {
+  return a_commMessages.create();
+}
+
+void Launcher::releaseCommMessage(anna::diameter::comm::Message *msg) throw() {
+  a_commMessages.release(msg);
+}
+
+anna::diameter::codec::Message *Launcher::createCodecMessage() throw(anna::RuntimeException) {
+  return a_codecMessages.create();
+}
+
+void Launcher::releaseCodecMessage(anna::diameter::codec::Message *msg) throw() {
+  a_codecMessages.release(msg);
+}
+
+
 void Launcher::baseProtocolSetupAsClient(void) throw(anna::RuntimeException) {
   // Build CER
   //   <CER> ::= < Diameter Header: 257, REQ >
@@ -187,11 +198,10 @@ void Launcher::baseProtocolSetupAsClient(void) throw(anna::RuntimeException) {
 
 void Launcher::writeLogFile(const anna::DataBlock & db, const std::string &logExtension, const std::string &detail) const throw() {
 //   if (!logEnabled()) return;
+  anna::diameter::codec::Message codecMsg;
+  try { codecMsg.decode(db); } catch(anna::RuntimeException &ex) { ex.trace(); }
+  writeLogFile(codecMsg, logExtension, detail);
 
-  // Decode
-  try { G_codecMsg.decode(db); } catch(anna::RuntimeException &ex) { ex.trace(); }
-
-  writeLogFile(G_codecMsg, logExtension, detail);
 }
 
 // Si ya lo tengo decodificado:
@@ -690,7 +700,7 @@ int Launcher::clearBurst() throw() {
     std::map<int, anna::diameter::comm::Message*>::const_iterator it_min(a_burstMessages.begin());
     std::map<int, anna::diameter::comm::Message*>::const_iterator it_max(a_burstMessages.end());
 
-    for(it = it_min; it != it_max; it++) G_commMessages.release((*it).second);
+    for(it = it_min; it != it_max; it++) releaseCommMessage((*it).second);
 
     a_burstMessages.clear();
   } else {
@@ -706,7 +716,7 @@ int Launcher::clearBurst() throw() {
 }
 
 int Launcher::loadBurstMessage(const anna::DataBlock & db) throw(anna::RuntimeException) {
-  anna::diameter::comm::Message *msg = G_commMessages.create();
+  anna::diameter::comm::Message *msg = createCommMessage();
   msg->setBody(db);
   a_burstMessages[a_burstLoadIndx++] = msg;
   return (a_burstLoadIndx - 1);
@@ -878,9 +888,9 @@ std::string Launcher::lookBurst(int order) const throw() {
 
   if(it != a_burstMessages.end()) {
     // Decode
-    try { G_codecMsg.decode((*it).second->getBody()); } catch(anna::RuntimeException &ex) { ex.trace(); }
-
-    result = G_codecMsg.asXMLString();
+    anna::diameter::codec::Message codecMsg;
+    try { codecMsg.decode((*it).second->getBody()); } catch(anna::RuntimeException &ex) { ex.trace(); }
+    result = codecMsg.asXMLString();
   }
 
   return result;
@@ -1191,6 +1201,7 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
   response_content = "Operation processed with exception. See traces\n"; // supposed
   std::string result = "";
   anna::DataBlock db_aux(true);
+  anna::diameter::codec::Message codecMsg;
 
   ///////////////////////////////////////////////////////////////////
   // Simple operations without arguments:
@@ -1262,8 +1273,8 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
 
   // Operations:
   if(opType == "code") {
-    G_codecMsg.loadXML(param1);
-    std::string hexString = anna::functions::asHexString(G_codecMsg.code());
+    codecMsg.loadXML(param1);
+    std::string hexString = anna::functions::asHexString(codecMsg.code());
     // write to outfile
     std::ofstream outfile(param2.c_str(), std::ifstream::out);
     outfile.write(hexString.c_str(), hexString.size());
@@ -1274,9 +1285,9 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
       throw anna::RuntimeException("Error reading hex file provided", ANNA_FILE_LOCATION);
 
     // Decode
-    try { G_codecMsg.decode(db_aux); } catch(anna::RuntimeException &ex) { ex.trace(); }
+    try { codecMsg.decode(db_aux); } catch(anna::RuntimeException &ex) { ex.trace(); }
 
-    std::string xmlString = G_codecMsg.asXMLString();
+    std::string xmlString = codecMsg.asXMLString();
     // write to outfile
     std::ofstream outfile(param2.c_str(), std::ifstream::out);
     outfile.write(xmlString.c_str(), xmlString.size());
@@ -1325,29 +1336,31 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
     MyDiameterEntity *entity = getEntity();
 
     if(!entity) throw anna::RuntimeException("No entity configured to send the message", ANNA_FILE_LOCATION);
+    anna::diameter::comm::Message *msg = createCommMessage();
 
     if((opType == "sendxml") || (opType == "sendxml2e")) {
-      G_codecMsg.loadXML(param1);
-      G_commMsgSent2e.clearBody();
-      try { G_codecMsg.valid(); } catch(anna::RuntimeException &ex) { ex.trace(); }  // at least we need to see validation errors although it will continue sending (see validation mode configured in launcher)
+      codecMsg.loadXML(param1);
+      msg->clearBody();
+      try { codecMsg.valid(); } catch(anna::RuntimeException &ex) { ex.trace(); }  // at least we need to see validation errors although it will continue sending (see validation mode configured in launcher)
 
-      G_commMsgSent2e.setBody(G_codecMsg.code());
+      msg->setBody(codecMsg.code());
     } else {
       // Get DataBlock from file with hex content:
       if(!getDataBlockFromHexFile(param1, db_aux))
         throw anna::RuntimeException("Error reading hex file provided", ANNA_FILE_LOCATION);
 
-      G_commMsgSent2e.setBody(db_aux);
+      msg->setBody(db_aux);
     }
 
-    bool success = entity->send(G_commMsgSent2e, cl.exists("balance"));
+    bool success = entity->send(msg, cl.exists("balance"));
+    releaseCommMessage(msg);
 
     // Detailed log:
     if(logEnabled()) {
       anna::diameter::comm::Server *usedServer = entity->getLastUsedResource();
       anna::diameter::comm::ClientSession *usedClientSession = usedServer ? usedServer->getLastUsedResource() : NULL;
       std::string detail = usedClientSession ? usedClientSession->asString() : "<null client session>"; // esto no deberia ocurrir
-      writeLogFile(G_codecMsg, (success ? "sent2e" : "send2eError"), detail);
+      writeLogFile(codecMsg, (success ? "sent2e" : "send2eError"), detail);
     }
   } else if((opType == "burst")) {
     anna::diameter::comm::Entity *entity = getEntity();
@@ -1374,12 +1387,12 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
     } else if(param1 == "load") {
       if(param2 == "") throw anna::RuntimeException("Missing xml path file for burst load operation", ANNA_FILE_LOCATION);
 
-      G_codecMsg.loadXML(param2);
+      codecMsg.loadXML(param2);
 
-      if(G_codecMsg.isAnswer()) throw anna::RuntimeException("Cannot load diameter answers for burst feature", ANNA_FILE_LOCATION);
-      try { G_codecMsg.valid(); } catch(anna::RuntimeException &ex) { ex.trace(); }  // at least we need to see validation errors although it will continue loading (see validation mode configured in launcher)
+      if(codecMsg.isAnswer()) throw anna::RuntimeException("Cannot load diameter answers for burst feature", ANNA_FILE_LOCATION);
+      try { codecMsg.valid(); } catch(anna::RuntimeException &ex) { ex.trace(); }  // at least we need to see validation errors although it will continue loading (see validation mode configured in launcher)
 
-      int position = loadBurstMessage(G_codecMsg.code());
+      int position = loadBurstMessage(codecMsg.code());
       result = "Loaded '";
       result += param2;
       result += "' file into burst list position ";
@@ -1457,32 +1470,34 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
     MyLocalServer *localServer = getDiameterLocalServer();
 
     if(!localServer) throw anna::RuntimeException("No local server configured to send the message", ANNA_FILE_LOCATION);
+    anna::diameter::comm::Message *msg = createCommMessage();
 
     if(opType == "sendxml2c") {
-      G_codecMsg.loadXML(param1);
-      G_commMsgSent2c.clearBody();
-      try { G_codecMsg.valid(); } catch(anna::RuntimeException &ex) { ex.trace(); }  // at least we need to see validation errors although it will continue sending (see validation mode configured in launcher)
+      codecMsg.loadXML(param1);
+      msg->clearBody();
+      try { codecMsg.valid(); } catch(anna::RuntimeException &ex) { ex.trace(); }  // at least we need to see validation errors although it will continue sending (see validation mode configured in launcher)
 
-      G_commMsgSent2c.setBody(G_codecMsg.code());
+      msg->setBody(codecMsg.code());
     } else {
       // Get DataBlock from file with hex content:
       if(!getDataBlockFromHexFile(param1, db_aux))
         throw anna::RuntimeException("Error reading hex file provided", ANNA_FILE_LOCATION);
 
-      G_commMsgSent2c.setBody(db_aux);
+      msg->setBody(db_aux);
     }
 
-    bool success = localServer->send(G_commMsgSent2c);
+    bool success = localServer->send(msg);
+    releaseCommMessage(msg);
 
     // Detailed log:
     if(logEnabled()) {
       anna::diameter::comm::ServerSession *usedServerSession = localServer->getLastUsedResource();
       std::string detail = usedServerSession ? usedServerSession->asString() : "<null server session>"; // esto no deberia ocurrir
-      writeLogFile(G_codecMsg, (success ? "sent2c" : "send2cError"), detail);
+      writeLogFile(codecMsg, (success ? "sent2c" : "send2cError"), detail);
     }
   } else if(opType == "loadxml") {
-    G_codecMsg.loadXML(param1);
-    std::string xmlString = G_codecMsg.asXMLString();
+    codecMsg.loadXML(param1);
+    std::string xmlString = codecMsg.asXMLString();
     std::cout << xmlString << std::endl;
   } else if(opType == "diameterServerSessions") {
     int diameterServerSessions = atoi(param1.c_str());
index 9a61627..d550ceb 100644 (file)
@@ -15,6 +15,7 @@
 #include <fstream>
 
 // Project
+#include <anna/core/core.hpp>
 #include <anna/comm/comm.hpp>
 #include <anna/diameter.comm/Entity.hpp>
 #include <anna/time/Date.hpp>
@@ -61,6 +62,10 @@ class Launcher : public anna::comm::Application {
   int a_otaRequest;
   int a_burstPopCounter;
 
+  // comm Messages factory:
+  anna::Recycler<anna::diameter::comm::Message> a_commMessages;
+  anna::Recycler<anna::diameter::codec::Message> a_codecMessages;
+
   anna::comm::ServerSocket* a_httpServerSocket; // HTTP
   MyLocalServer* a_diameterLocalServer; // DIAMETER
   void checkTimeMeasure(const char * commandLineParameter, bool optional = true) throw(anna::RuntimeException);
@@ -90,6 +95,12 @@ public:
   void signalUSR2() throw(anna::RuntimeException);
   std::string help() const throw();
 
+  // Messages factory:
+  anna::diameter::comm::Message *createCommMessage() throw(anna::RuntimeException);
+  void releaseCommMessage(anna::diameter::comm::Message*) throw();
+  anna::diameter::codec::Message *createCodecMessage() throw(anna::RuntimeException);
+  void releaseCodecMessage(anna::diameter::codec::Message*) throw();
+
   // helpers
   bool getDataBlockFromHexFile(const std::string &pathfile, anna::DataBlock &db) const throw();
 
index c69290d..0535160 100644 (file)
 #include "MyDiameterEntity.hpp"
 #include "Launcher.hpp"
 
-// Auxiliary message for sendings
-extern anna::diameter::comm::Message G_commMsgSent2e, G_commMsgFwd2c;
-extern anna::diameter::codec::Message G_codecMsg, G_codecAnsMsg;
-extern anna::Recycler<anna::diameter::comm::Message> G_commMessages; // create on requests forwards without programmed answer / release in answers forward
-
 
 void MyDiameterEntity::eventRequest(anna::diameter::comm::ClientSession *clientSession, const anna::DataBlock &message)
 throw(anna::RuntimeException) {
@@ -52,8 +47,10 @@ throw(anna::RuntimeException) {
     my_app.getCommunicator()->prepareAnswer(answer_message, message);
 
     try {
-      G_commMsgSent2e.setBody(answer_message->code());
-      /* response = NULL =*/clientSession->send(&G_commMsgSent2e);
+      anna::diameter::comm::Message *msg = my_app.createCommMessage();
+      msg->setBody(answer_message->code());
+      /* response = NULL =*/clientSession->send(msg);
+      my_app.releaseCommMessage(msg);
 
       if(my_app.logEnabled()) my_app.writeLogFile(*answer_message, "sent2e", clientSession->asString());
     } catch(anna::RuntimeException &ex) {
@@ -80,7 +77,7 @@ throw(anna::RuntimeException) {
 
   if(localServer && (cid != anna::diameter::helpers::base::COMMANDID__Capabilities_Exchange_Request) /* don't forward CER */) {
     try {
-      anna::diameter::comm::Message *msg = G_commMessages.create();
+      anna::diameter::comm::Message *msg = my_app.createCommMessage();
       msg->updateEndToEnd(false); // end-to-end will be kept
       msg->setBody(message);
       msg->setRequestClientSessionKey(clientSession->getKey());
@@ -149,12 +146,9 @@ throw(anna::RuntimeException) {
       anna::Logger::debug(msg, ANNA_FILE_LOCATION);
     );
     // Write reception
-    bool alreadyDecodedOnG_codecMsg = false;
-
     if(request_cid != anna::diameter::helpers::base::COMMANDID__Capabilities_Exchange_Request) {  // don't trace CEA
       if(my_app.logEnabled()) {
         my_app.writeLogFile(*message, "recvfe", clientSession->asString());
-        alreadyDecodedOnG_codecMsg = true;
       }
     }
 
@@ -163,19 +157,19 @@ throw(anna::RuntimeException) {
 
     if(localServer && (request_cid != anna::diameter::helpers::base::COMMANDID__Capabilities_Exchange_Request) /* don't forward CEA */) {
       try {
-        G_commMsgFwd2c.updateEndToEnd(false); // end-to-end will be kept
-        G_commMsgFwd2c.setBody(*message);
-        bool success = localServer->send(&G_commMsgFwd2c, request->getRequestServerSessionKey());
-        G_commMessages.release(request);
+        anna::diameter::comm::Message *msg = my_app.createCommMessage();
+        msg->updateEndToEnd(false); // end-to-end will be kept
+        msg->setBody(*message);
+        bool success = localServer->send(msg, request->getRequestServerSessionKey());
+        my_app.releaseCommMessage(msg);
+        my_app.releaseCommMessage(request);
+
         // Detailed log:
         anna::diameter::comm::ServerSession *usedServerSession = my_app.getMyDiameterEngine()->findServerSession(request->getRequestServerSessionKey());
         std::string detail = usedServerSession ? usedServerSession->asString() : "<null server session>"; // esto no deberia ocurrir
 
         if(my_app.logEnabled()) {
-          if(alreadyDecodedOnG_codecMsg)
-            my_app.writeLogFile(G_codecMsg, (success ? "fwd2c" : "fwd2cError"), detail);
-          else
-            my_app.writeLogFile(*message, (success ? "fwd2c" : "fwd2cError"), detail);
+          my_app.writeLogFile(*message, (success ? "fwd2c" : "fwd2cError"), detail);
         }
       } catch(anna::RuntimeException &ex) {
         ex.trace();
index dab87d1..5e3ca1f 100644 (file)
 #include "MyLocalServer.hpp"
 #include "Launcher.hpp"
 
-// Auxiliary message for sendings
-extern anna::diameter::comm::Message G_commMsgSent2c, G_commMsgFwd2e;
-extern anna::diameter::codec::Message G_codecMsg, G_codecAnsMsg;
-extern anna::Recycler<anna::diameter::comm::Message> G_commMessages; // create on requests forwards without programmed answer / release in answers forward
-
 
 void MyLocalServer::eventRequest(anna::diameter::comm::ServerSession *serverSession, const anna::DataBlock &message)
 throw(anna::RuntimeException) {
@@ -52,7 +47,7 @@ throw(anna::RuntimeException) {
 
   anna::diameter::comm::Entity *entity = my_app.getEntity();
   if(!programmed && entity) {  // forward condition (no programmed answer + entity available)
-    anna::diameter::comm::Message *msg = G_commMessages.create();
+    anna::diameter::comm::Message *msg = my_app.createCommMessage();
     msg->updateEndToEnd(false); // end-to-end will be kept
     msg->setBody(message);
     msg->setRequestServerSessionKey(serverSession->getKey());
@@ -72,15 +67,17 @@ throw(anna::RuntimeException) {
   // Error analisys:
   bool analysisOK = true; // by default
   anna::diameter::codec::Message *answer_message = NULL;
+  anna::diameter::codec::Message *codecMsg = my_app.createCodecMessage();
 
   if(!cl.exists("ignoreErrors")) {  // Error analysis
-    answer_message = (anna::diameter::codec::Message*) & G_codecAnsMsg;
+    answer_message = my_app.createCodecMessage();
     answer_message->clear();
 
     // Decode
-    try { G_codecMsg.decode(message, answer_message); } catch(anna::RuntimeException &ex) { ex.trace(); }
+    try { codecMsg->decode(message, answer_message); } catch(anna::RuntimeException &ex) { ex.trace(); }
 
-    answer_message->setStandardToAnswer(G_codecMsg, my_app.getMyDiameterEngine()->getHost(), my_app.getMyDiameterEngine()->getRealm());
+    answer_message->setStandardToAnswer(*codecMsg, my_app.getMyDiameterEngine()->getHost(), my_app.getMyDiameterEngine()->getRealm());
+    my_app.releaseCodecMessage(codecMsg);
     analysisOK = (answer_message->getResultCode() == anna::diameter::helpers::base::AVPVALUES__Result_Code::DIAMETER_SUCCESS);
   }
 
@@ -100,8 +97,10 @@ throw(anna::RuntimeException) {
     codecEngine->setValidationMode(anna::diameter::codec::Engine::ValidationMode::Never);
 
   try {
-    G_commMsgSent2c.setBody(answer_message->code());
-    /* response = NULL =*/serverSession->send(&G_commMsgSent2c);
+    anna::diameter::comm::Message *msg = my_app.createCommMessage();
+    msg->setBody(answer_message->code());
+    /* response = NULL =*/serverSession->send(msg);
+    my_app.releaseCommMessage(msg);
 
     if(my_app.logEnabled()) my_app.writeLogFile(*answer_message, "sent2c", serverSession->asString());
   } catch(anna::RuntimeException &ex) {
@@ -110,6 +109,9 @@ throw(anna::RuntimeException) {
     if(my_app.logEnabled()) my_app.writeLogFile(*answer_message, "send2cError", serverSession->asString());
   }
 
+  // Release auxiliary codec message
+  my_app.releaseCodecMessage(answer_message);
+
   // Restore validation mode
   codecEngine->setValidationMode(backupVM);
 
@@ -181,16 +183,19 @@ throw(anna::RuntimeException) {
       if(my_app.logEnabled()) detail = usedClientSession ? usedClientSession->asString() : "<null client session>";  // esto no deberia ocurrir
 
       try {
-        G_commMsgFwd2e.updateEndToEnd(false); // end-to-end will be kept
-        G_commMsgFwd2e.setBody(*message);
+        anna::diameter::comm::Message *msg = my_app.createCommMessage();
+        msg->updateEndToEnd(false); // end-to-end will be kept
+        msg->setBody(*message);
 
         // Metodo 1:
-        if(usedClientSession) /* response = NULL =*/usedClientSession->send(&G_commMsgFwd2e);
+        if(usedClientSession) /* response = NULL =*/usedClientSession->send(msg);
 
         // Metodo 2:
-        //G_commMsgFwd2e.setRequestClientSessionKey(request->getRequestClientSessionKey());
-        //bool success = entity->send(G_commMsgFwd2e);
-        G_commMessages.release(request);
+        //msg->setRequestClientSessionKey(request->getRequestClientSessionKey());
+        //bool success = entity->send(msg);
+
+        my_app.releaseCommMessage(msg);
+        my_app.releaseCommMessage(request);
 
         if(my_app.logEnabled()) my_app.writeLogFile(*message, "fwd2e", detail);  // forwarded
       } catch(anna::RuntimeException &ex) {