From 5f094136b1817b5c4d14dbcc33c9819a8569cd1e Mon Sep 17 00:00:00 2001 From: Eduardo Ramos Testillano Date: Mon, 18 May 2015 03:38:17 +0200 Subject: [PATCH] Remove global variables. Factory for comm/codec messages in application class (Launcher) --- example/diameter/launcher/Launcher.cpp | 93 +++++++++++-------- example/diameter/launcher/Launcher.hpp | 11 +++ .../diameter/launcher/MyDiameterEntity.cpp | 32 +++---- example/diameter/launcher/MyLocalServer.cpp | 39 ++++---- 4 files changed, 100 insertions(+), 75 deletions(-) diff --git a/example/diameter/launcher/Launcher.cpp b/example/diameter/launcher/Launcher.cpp index 7e16c90..e4ea4ca 100644 --- a/example/diameter/launcher/Launcher.cpp +++ b/example/diameter/launcher/Launcher.cpp @@ -23,12 +23,6 @@ #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 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 // ::= < 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::const_iterator it_min(a_burstMessages.begin()); std::map::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() : ""; // 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() : ""; // 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()); diff --git a/example/diameter/launcher/Launcher.hpp b/example/diameter/launcher/Launcher.hpp index 9a61627..d550ceb 100644 --- a/example/diameter/launcher/Launcher.hpp +++ b/example/diameter/launcher/Launcher.hpp @@ -15,6 +15,7 @@ #include // Project +#include #include #include #include @@ -61,6 +62,10 @@ class Launcher : public anna::comm::Application { int a_otaRequest; int a_burstPopCounter; + // comm Messages factory: + anna::Recycler a_commMessages; + anna::Recycler 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(); diff --git a/example/diameter/launcher/MyDiameterEntity.cpp b/example/diameter/launcher/MyDiameterEntity.cpp index c69290d..0535160 100644 --- a/example/diameter/launcher/MyDiameterEntity.cpp +++ b/example/diameter/launcher/MyDiameterEntity.cpp @@ -16,11 +16,6 @@ #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 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() : ""; // 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(); diff --git a/example/diameter/launcher/MyLocalServer.cpp b/example/diameter/launcher/MyLocalServer.cpp index dab87d1..5e3ca1f 100644 --- a/example/diameter/launcher/MyLocalServer.cpp +++ b/example/diameter/launcher/MyLocalServer.cpp @@ -17,11 +17,6 @@ #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 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() : ""; // 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) { -- 2.20.1