X-Git-Url: https://git.teslayout.com/public/public/public/?a=blobdiff_plain;f=example%2Fdiameter%2Flauncher%2FLauncher.cpp;h=59f5202beeed5c2e61c00268b44bb46a1e10a7d4;hb=a8cde75abebb30020be4d9cb10d898f8986e124c;hp=7e16c90c5f9bc4f0dbab0dc2fc0514d78212d14d;hpb=752438861433c3789eb1b0d9f2c15e15037595e6;p=anna.git diff --git a/example/diameter/launcher/Launcher.cpp b/example/diameter/launcher/Launcher.cpp index 7e16c90..59f5202 100644 --- a/example/diameter/launcher/Launcher.cpp +++ b/example/diameter/launcher/Launcher.cpp @@ -14,6 +14,7 @@ #include #include #include +#include // Process #include "Launcher.hpp" @@ -21,13 +22,7 @@ #define SIGUSR2_TASKS_INPUT_FILENAME "./sigusr2.tasks.input" #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 - +#define DIAMETER_CODEC_ENGINE_NAME_PREFIX "MyCodecEngine" Launcher::Launcher() : anna::comm::Application("launcher", "DiameterLauncher", "1.1"), a_communicator(NULL) { a_myDiameterEngine = new MyDiameterEngine(); @@ -55,7 +50,22 @@ Launcher::Launcher() : anna::comm::Application("launcher", "DiameterLauncher", " a_burstPopCounter = 0; } -void Launcher::baseProtocolSetupAsClient(void) throw(anna::RuntimeException) { +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); +} + +void Launcher::baseProtocolSetupAsClient() throw(anna::RuntimeException) { + + anna::diameter::codec::Engine *codecEngine; + + codecEngine = getCodecEngine(); + // XXXXXXXXXXXXXXXXXXXX codecEngine = a_myDiameterEngine->getBaseProtocolCodecEngine(); + + // Build CER // ::= < Diameter Header: 257, REQ > // { Origin-Host } 264 diameterIdentity @@ -67,7 +77,7 @@ void Launcher::baseProtocolSetupAsClient(void) throw(anna::RuntimeException) { // * [ Supported-Vendor-Id ] 265 Unsigned32 // * [ Auth-Application-Id ] 258 Unsigned32 // * [Acct-Application-Id] 259 Unsigned32 - anna::diameter::codec::Message diameterCER; + anna::diameter::codec::Message diameterCER(codecEngine); int applicationId = 0 /*anna::diameter::helpers::APPID__3GPP_Rx*/; // Unsigned32 std::string OH = a_myDiameterEngine->getHost(); std::string OR = a_myDiameterEngine->getRealm(); @@ -99,7 +109,7 @@ void Launcher::baseProtocolSetupAsClient(void) throw(anna::RuntimeException) { // ::= < Diameter Header: 280, REQ > // { Origin-Host } // { Origin-Realm } - anna::diameter::codec::Message diameterDWR; + anna::diameter::codec::Message diameterDWR(codecEngine); loadingError = false; try { @@ -117,81 +127,17 @@ void Launcher::baseProtocolSetupAsClient(void) throw(anna::RuntimeException) { diameterDWR.addAvp(anna::diameter::helpers::base::AVPID__Origin_Realm)->getDiameterIdentity()->setValue(OR); } -////////////////////////// -// IDEM FOR CEA AND DWA // -////////////////////////// -// // Build CER -// // ::= < Diameter Header: 257, REQ > -// // { Origin-Host } 264 diameterIdentity -// // { Origin-Realm } 296 idem -// // 1* { Host-IP-Address } 257, address -// // { Vendor-Id } 266 Unsigned32 -// // { Product-Name } 269 UTF8String -// // [Origin-State-Id] 278 Unsigned32 -// // * [ Supported-Vendor-Id ] 265 Unsigned32 -// // * [ Auth-Application-Id ] 258 Unsigned32 -// // * [Acct-Application-Id] 259 Unsigned32 -// anna::diameter::codec::Message diameterCER; -// int applicationId = 0 /*anna::diameter::helpers::APPID__3GPP_Rx*/; // Unsigned32 -// std::string OH = a_myDiameterEngine->getHost(); -// std::string OR = a_myDiameterEngine->getRealm(); -// std::string hostIP = anna::functions::getHostnameIP(); // Address -// int vendorId = anna::diameter::helpers::VENDORID__tgpp; // Unsigned32 -// std::string productName = "ANNA Diameter Launcher"; // UTF8String -// bool loadingError = false; -// -// try { -// diameterCER.loadXML("cer.xml"); -// } catch (anna::RuntimeException &ex) { -// ex.trace(); -// loadingError = true; -// } -// -// if (loadingError) { -// LOGWARNING(anna::Logger::warning("CER file not found. Get harcoded.", ANNA_FILE_LOCATION)); -// diameterCER.setId(anna::diameter::helpers::base::COMMANDID__Capabilities_Exchange_Request); -// diameterCER.setApplicationId(applicationId); -// diameterCER.addAvp(anna::diameter::helpers::base::AVPID__Origin_Host)->getDiameterIdentity()->setValue(OH); -// diameterCER.addAvp(anna::diameter::helpers::base::AVPID__Origin_Realm)->getDiameterIdentity()->setValue(OR); -// diameterCER.addAvp(anna::diameter::helpers::base::AVPID__Host_IP_Address)->getAddress()->fromPrintableString(hostIP.c_str()); // supported by Address class, anyway is better to provide "1|" -// diameterCER.addAvp(anna::diameter::helpers::base::AVPID__Vendor_Id)->getUnsigned32()->setValue(vendorId); -// diameterCER.addAvp(anna::diameter::helpers::base::AVPID__Product_Name)->getUTF8String()->setValue(productName); -// diameterCER.addAvp(anna::diameter::helpers::base::AVPID__Auth_Application_Id)->getUnsigned32()->setValue(applicationId); -// } -// -// // Build DWR -// // ::= < Diameter Header: 280, REQ > -// // { Origin-Host } -// // { Origin-Realm } -// anna::diameter::codec::Message diameterDWR; -// loadingError = false; -// -// try { -// diameterDWR.loadXML("dwr.xml"); -// } catch (anna::RuntimeException &ex) { -// ex.trace(); -// loadingError = true; -// } -// -// if (loadingError) { -// LOGWARNING(anna::Logger::warning("DWR file not found. Get harcoded.", ANNA_FILE_LOCATION)); -// diameterDWR.setId(anna::diameter::helpers::base::COMMANDID__Device_Watchdog_Request); -// diameterDWR.setApplicationId(applicationId); -// diameterDWR.addAvp(anna::diameter::helpers::base::AVPID__Origin_Host)->getDiameterIdentity()->setValue(OH); -// diameterDWR.addAvp(anna::diameter::helpers::base::AVPID__Origin_Realm)->getDiameterIdentity()->setValue(OR); -// } // Assignment for CER/DWR and CEA/DWA: a_myDiameterEngine->setCERandDWR(diameterCER.code(), diameterDWR.code()); //a_myDiameterEngine->setCEAandDWA(diameterCEA.code(), diameterDWA.code()); } -void Launcher::writeLogFile(const anna::DataBlock & db, const std::string &logExtension, const std::string &detail) const throw() { +void Launcher::writeLogFile(const anna::DataBlock & db, const std::string &logExtension, const std::string &detail, anna::diameter::codec::Engine *codecEngine) const throw() { // if (!logEnabled()) return; + anna::diameter::codec::Message codecMsg(codecEngine); + 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: @@ -271,7 +217,7 @@ void Launcher::checkTimeMeasure(const char * commandLineParameter, bool optional if(anna::functions::isLike("^[0-9]+$", parameter)) { // para incluir numeros decimales: ^[0-9]+(.[0-9]+)?$ int msecs = cl.getIntegerValue(commandLineParameter); - if(msecs > a_timeEngine->getMaxTimeout()) { + if(msecs > a_timeEngine->getMaxTimeout()) { // 600000 ms std::string msg = "Commandline parameter '"; msg += commandLineParameter; msg += "' is greater than allowed max timeout for timming engine: "; @@ -279,6 +225,13 @@ void Launcher::checkTimeMeasure(const char * commandLineParameter, bool optional throw RuntimeException(msg, ANNA_FILE_LOCATION); } + if(msecs > 300000) { + std::string msg = "Commandline parameter '"; + msg += commandLineParameter; + msg += "' is perhaps very big (over 5 minutes). Take into account memory consumption issues."; + LOGWARNING(anna::Logger::warning(msg, ANNA_FILE_LOCATION)); + } + if(msecs <= a_timeEngine->getResolution()) { std::string msg = "Commandline parameter '"; msg += commandLineParameter; @@ -309,6 +262,7 @@ void Launcher::startDiameterServer(int diameterServerSessions) throw(anna::Runti //ServerSocket *createServerSocket(const std::string & addr, int port = Session::DefaultPort, int maxConnections = -1, int category = 1, const std::string & description = "") a_diameterLocalServer = (MyLocalServer*)(a_myDiameterEngine->createLocalServer(address, port, diameterServerSessions)); a_diameterLocalServer->setDescription("Launcher diameter local server"); + a_diameterLocalServer->setCodecEngine(getCodecEngine()); // this is for automatic answers (failed-avp) XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX el del nodo correspondiente int allowedInactivityTime = 90000; // ms if(cl.exists("allowedInactivityTime")) allowedInactivityTime = cl.getIntegerValue("allowedInactivityTime"); @@ -324,7 +278,8 @@ throw(anna::RuntimeException) { // if (cl.exists ("clone")) // workMode = anna::comm::Communicator::WorkMode::Clone; a_communicator = new MyCommunicator(workMode); - a_timeEngine = new anna::timex::Engine((anna::Millisecond)300000, (anna::Millisecond)150); + //a_timeEngine = new anna::timex::Engine((anna::Millisecond)600000, anna::timex::Engine::minResolution); + a_timeEngine = new anna::timex::Engine((anna::Millisecond)600000, (anna::Millisecond)100); // puedo bajar hasta 10 // Counters record procedure: anna::Millisecond cntRecordPeriod = (anna::Millisecond)300000; // ms @@ -349,13 +304,85 @@ throw(anna::RuntimeException) { a_start_time.setNow(); // Statistics: anna::statistics::Engine::instantiate().enable(); + + // Checking command line parameters + if(cl.exists("sessionBasedModelsClientSocketSelection")) { + std::string type = cl.getValue("sessionBasedModelsClientSocketSelection"); + + if((type != "SessionIdHighPart") && (type != "SessionIdOptionalPart") && (type != "RoundRobin")) { + throw anna::RuntimeException("Commandline option '-sessionBasedModelsClientSocketSelection' only accepts 'SessionIdHighPart'/'SessionIdOptionalPart'/'RoundRobin' as parameter values", ANNA_FILE_LOCATION); + } + } + + // Tracing: + if(cl.exists("trace")) + anna::Logger::setLevel(anna::Logger::asLevel(cl.getValue("trace"))); + + LOGINFORMATION( + // Help on startup traces: + anna::Logger::information(help(), ANNA_FILE_LOCATION); + // Test messages dtd: + std::string msg = "\n ------------- TESTMESSAGES DTD -------------\n"; + msg += anna::diameter::codec::MessageDTD; + anna::Logger::information(msg, ANNA_FILE_LOCATION); + ); + + // HTTP Server: + if(cl.exists("httpServer")) { + anna::comm::Network& network = anna::comm::Network::instantiate(); + std::string address; + int port; + anna::functions::getAddressAndPortFromSocketLiteral(cl.getValue("httpServer"), address, port); + //const anna::comm::Device* device = network.find(Device::asAddress(address)); // here provide IP + const anna::comm::Device* device = *((network.resolve(address)->device_begin())); // trick to solve + a_httpServerSocket = new anna::comm::ServerSocket(anna::comm::INetAddress(device, port), cl.exists("httpServerShared") /* shared bind */, &anna::http::Transport::getFactory()); + } + + // Stack: + a_codecEngine = new anna::diameter::codec::Engine(DIAMETER_CODEC_ENGINE_NAME_PREFIX); + anna::diameter::stack::Engine &stackEngine = anna::diameter::stack::Engine::instantiate(); + anna::diameter::stack::Dictionary * d = stackEngine.createDictionary(0 /* stack id; its value don't mind, is not used (ADL is monostack) */); + // Analyze comma-separated list: + anna::Tokenizer lst; + std::string dictionaryParameter = cl.getValue("dictionary"); + lst.apply(dictionaryParameter, ","); + + if(lst.size() >= 1) { // always true (at least one, because --dictionary is mandatory) + anna::Tokenizer::const_iterator tok_min(lst.begin()); + anna::Tokenizer::const_iterator tok_max(lst.end()); + anna::Tokenizer::const_iterator tok_iter; + std::string pathFile; + d->allowUpdates(); + + for(tok_iter = tok_min; tok_iter != tok_max; tok_iter++) { + pathFile = anna::Tokenizer::data(tok_iter); + d->load(pathFile); + } + } + + getCodecEngine()->setDictionary(d); // XXXX esto cambiara... + LOGDEBUG(anna::Logger::debug(getCodecEngine()->asString(), ANNA_FILE_LOCATION)); + + if(lst.size() > 1) { + std::string all_in_one = "./dictionary-all-in-one.xml"; + std::ofstream out(all_in_one.c_str(), std::ifstream::out); + std::string buffer = d->asXMLString(); + out.write(buffer.c_str(), buffer.size()); + out.close(); + std::cout << "Written accumulated '" << all_in_one << "' (provide it next time to be more comfortable)." << std::endl; + } + /////////////////////////////// // Diameter library COUNTERS // /////////////////////////////// anna::diameter::comm::OamModule & oamDiameterComm = anna::diameter::comm::OamModule::instantiate(); oamDiameterComm.initializeCounterScope(1); // 1000 - 1999 + oamDiameterComm.enableCounters(); + oamDiameterComm.enableAlarms(); anna::diameter::codec::OamModule & oamDiameterCodec = anna::diameter::codec::OamModule::instantiate(); oamDiameterCodec.initializeCounterScope(2); // 2000 - 2999 + oamDiameterCodec.enableCounters(); + oamDiameterCodec.enableAlarms(); ///////////////// // COMM MODULE // ///////////////// @@ -453,6 +480,18 @@ throw(anna::RuntimeException) { oamDiameterCodec.registerCounter(anna::diameter::codec::OamModule::Counter::LevelValidation__FailedRuleForCardinalityMoreThanNeeded, "", 17 /*2017*/); oamDiameterCodec.registerCounter(anna::diameter::codec::OamModule::Counter::LevelValidation__FailedGenericAvpRuleForCardinalityFoundDisregardedItem, "", 18 /*2018*/); oamDiameterCodec.registerCounter(anna::diameter::codec::OamModule::Counter::LevelValidation__FoundDisregardedItemsAndGenericAVPWasNotSpecified, "", 19 /*2019*/); + /////////////////////////////////////////// + // APPLICATION MESSAGE OAM MODULE SCOPES // + /////////////////////////////////////////// + // We will register a scope per stack id registered. The counters will be dynamically registered at count method. + anna::diameter::comm::ApplicationMessageOamModule & appMsgOamModule = anna::diameter::comm::ApplicationMessageOamModule::instantiate(); + int scope_id = 3; + for (anna::diameter::stack::Engine::const_stack_iterator it = stackEngine.stack_begin(); it != stackEngine.stack_end(); it++) { + appMsgOamModule.createStackCounterScope(scope_id, it->first); + scope_id++; + } + appMsgOamModule.enableCounters(); // this special module is disabled by default (the only) + ///////////////////////////////// // Counter recorder associated // @@ -460,83 +499,16 @@ throw(anna::RuntimeException) { if(a_counterRecorderClock) { oamDiameterComm.setCounterRecorder(a_counterRecorder); oamDiameterCodec.setCounterRecorder(a_counterRecorder); + appMsgOamModule.setCounterRecorder(a_counterRecorder); a_timeEngine->activate(a_counterRecorderClock); // start clock } - // Checking command line parameters - if(cl.exists("sessionBasedModelsClientSocketSelection")) { - std::string type = cl.getValue("sessionBasedModelsClientSocketSelection"); - - if((type != "SessionIdHighPart") && (type != "SessionIdOptionalPart") && (type != "RoundRobin")) { - throw anna::RuntimeException("Commandline option '-sessionBasedModelsClientSocketSelection' only accepts 'SessionIdHighPart'/'SessionIdOptionalPart'/'RoundRobin' as parameter values", ANNA_FILE_LOCATION); - } - } - - // Tracing: - if(cl.exists("trace")) - anna::Logger::setLevel(anna::Logger::asLevel(cl.getValue("trace"))); - - LOGINFORMATION( - // Help on startup traces: - anna::Logger::information(help(), ANNA_FILE_LOCATION); - // Test messages dtd: - std::string msg = "\n ------------- TESTMESSAGES DTD -------------\n"; - msg += anna::diameter::codec::MessageDTD; - anna::Logger::information(msg, ANNA_FILE_LOCATION); - ); - - // HTTP Server: - if(cl.exists("httpServer")) { - anna::comm::Network& network = anna::comm::Network::instantiate(); - std::string address; - int port; - anna::functions::getAddressAndPortFromSocketLiteral(cl.getValue("httpServer"), address, port); - //const anna::comm::Device* device = network.find(Device::asAddress(address)); // here provide IP - const anna::comm::Device* device = *((network.resolve(address)->device_begin())); // trick to solve - a_httpServerSocket = new anna::comm::ServerSocket(anna::comm::INetAddress(device, port), cl.exists("httpServerShared") /* shared bind */, &anna::http::Transport::getFactory()); - } - - // Stack: - anna::diameter::codec::Engine *codecEngine = new anna::diameter::codec::Engine(); - anna::diameter::stack::Engine &stackEngine = anna::diameter::stack::Engine::instantiate(); - anna::diameter::stack::Dictionary * d = stackEngine.createDictionary(0 /* stack id; its value don't mind, is not used (ADL is monostack) */); - // Analyze comma-separated list: - anna::Tokenizer lst; - std::string dictionaryParameter = cl.getValue("dictionary"); - lst.apply(dictionaryParameter, ","); - - if(lst.size() >= 1) { // always true (at least one, because -dictionary is mandatory) - anna::Tokenizer::const_iterator tok_min(lst.begin()); - anna::Tokenizer::const_iterator tok_max(lst.end()); - anna::Tokenizer::const_iterator tok_iter; - std::string pathFile; - d->allowUpdates(); - - for(tok_iter = tok_min; tok_iter != tok_max; tok_iter++) { - pathFile = anna::Tokenizer::data(tok_iter); - d->load(pathFile); - } - } - - codecEngine->setDictionary(d); - LOGDEBUG(anna::Logger::debug(codecEngine->asString(), ANNA_FILE_LOCATION)); - - if(lst.size() > 1) { - std::string all_in_one = "./dictionary-all-in-one.xml"; - std::ofstream out(all_in_one.c_str(), std::ifstream::out); - std::string buffer = d->asXMLString(); - out.write(buffer.c_str(), buffer.size()); - out.close(); - std::cout << "Written accumulated '" << all_in_one << "' (provide it next time to be more comfortable)." << std::endl; - } - - // Integration (validation 'Complete' for receiving messages) and debugging (validation also before encoding: 'Always'). // If missing 'integrationAndDebugging', default behaviour at engine is: mode 'AfterDecoding', depth 'FirstError': if(cl.exists("integrationAndDebugging")) { - codecEngine->setValidationMode(anna::diameter::codec::Engine::ValidationMode::Always); - codecEngine->setValidationDepth(anna::diameter::codec::Engine::ValidationDepth::Complete); + getCodecEngine()->setValidationMode(anna::diameter::codec::Engine::ValidationMode::Always); // XXXXXXXXXXXXXXXXXXXXXXXXX + getCodecEngine()->setValidationDepth(anna::diameter::codec::Engine::ValidationDepth::Complete); } // Fix mode @@ -548,10 +520,14 @@ throw(anna::RuntimeException) { else if (fixMode == "Always") fm = anna::diameter::codec::Engine::FixMode::Always; else if (fixMode == "Never") fm = anna::diameter::codec::Engine::FixMode::Never; else LOGINFORMATION(anna::Logger::information("Unreconized command-line fix mode. Assumed default 'BeforeEncoding'", ANNA_FILE_LOCATION)); - codecEngine->setFixMode(fm); + getCodecEngine()->setFixMode(fm); // XXXXXXXXXXXXXXXXXXXXXXX } - codecEngine->ignoreFlagsOnValidation(cl.exists("ignoreFlags")); + getCodecEngine()->ignoreFlagsOnValidation(cl.exists("ignoreFlags")); // XXXXXXXXXXXXXXXXXXXXXXX + + // Base protocol for internal use (CEA, DWA, DPA and tracing: + a_myDiameterEngine->setBaseProtocolCodecEngine(getCodecEngine()); + // Diameter Server: if(cl.exists("diameterServer")) @@ -602,12 +578,13 @@ throw(anna::RuntimeException) { int entityServerSessions = cl.exists("entityServerSessions") ? cl.getIntegerValue("entityServerSessions") : 1; if(entityServerSessions > 0) { - baseProtocolSetupAsClient(); // Same CER/CEA, DWR/DWA for all diameter servers + baseProtocolSetupAsClient(); anna::socket_v servers = anna::functions::getSocketVectorFromString(cl.getValue("entity")); a_myDiameterEngine->setNumberOfClientSessionsPerServer(entityServerSessions); a_entity = (MyDiameterEntity*)(a_myDiameterEngine->createEntity(servers, "Launcher diameter entity")); a_entity->setClassCodeTimeout(anna::diameter::comm::ClassCode::Bind, ceaTimeout); a_entity->setClassCodeTimeout(anna::diameter::comm::ClassCode::ApplicationMessage, answersTimeout); + a_entity->setCodecEngine(getCodecEngine()); // XXXXXXXXXXXXXXXXXXXXXXX a_entity->bind(); } } @@ -690,7 +667,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 +683,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); @@ -864,7 +841,7 @@ bool Launcher::sendBurstMessage(bool anyway) throw() { anna::diameter::comm::Server *usedServer = a_entity->getLastUsedResource(); anna::diameter::comm::ClientSession *usedClientSession = usedServer ? usedServer->getLastUsedResource() : NULL; std::string detail = usedClientSession ? usedClientSession->asString() : ""; // esto no deberia ocurrir - writeLogFile(msg->getBody(), (result ? "sent2e" : "send2eError"), detail); + writeLogFile(msg->getBody(), (result ? "sent2e" : "send2eError"), detail, getCodecEngine()); // el del nodo de trabajo } return result; @@ -878,9 +855,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(getCodecEngine()); // XXXXXXXXXXXXXXXX el del nodo de trabajo + try { codecMsg.decode((*it).second->getBody()); } catch(anna::RuntimeException &ex) { ex.trace(); } + result = codecMsg.asXMLString(); } return result; @@ -901,9 +878,9 @@ std::string Launcher::gotoBurst(int order) throw() { } void Launcher::resetCounters() throw() { - // Diameter::comm module: - anna::diameter::comm::OamModule & oamDiameterComm = anna::diameter::comm::OamModule::instantiate(); - oamDiameterComm.resetCounters(); + anna::diameter::comm::OamModule::instantiate().resetCounters(); + anna::diameter::comm::ApplicationMessageOamModule::instantiate().resetCounters(); + anna::diameter::codec::OamModule::instantiate().resetCounters(); } void Launcher::signalUSR2() throw(anna::RuntimeException) { @@ -991,21 +968,21 @@ std::string Launcher::help() const throw() { result += "\n (we will talk later about this great feature). Some of the more common parameters are:"; result += "\n"; result += "\nAs mandatory, the stack definition given through the xml dictionary:"; - result += "\n -dictionary "; + result += "\n --dictionary "; result += "\n"; result += "\nActing as a diameter server (accepting i.e. 10 connections), you would have:"; - result += "\n -diameterServer localhost:3868 -diameterServerSessions 10 -entityServerSessions 0"; + result += "\n --diameterServer localhost:3868 --diameterServerSessions 10 --entityServerSessions 0"; result += "\n"; result += "\nActing as a diameter client (launching i.e. 10 connections to each entity server), you would have:"; - result += "\n -entity 192.168.12.11:3868,192.168.12.21:3868 -entityServerSessions 10 -diameterServerSessions 0"; + result += "\n --entity 192.168.12.11:3868,192.168.12.21:3868 --entityServerSessions 10 --diameterServerSessions 0"; result += "\n"; result += "\nIf you act as a proxy or a translation agent, you need to combine both former setups, and probably"; result += "\n will need to program the answers to be replied through the operations interface. To balance the"; - result += "\n traffic at your client side you shall use '-balance' and '-sessionBasedModelsClientSocketSelection'"; + result += "\n traffic at your client side you shall use '--balance' and '--sessionBasedModelsClientSocketSelection'"; result += "\n arguments in order to define the balancing behaviour."; result += "\n"; result += "\nThe process builds automatically CER and DWR messages as a client, but you could specify your own"; - result += "\n customized ones using '-cer ' and '-dwr '."; + result += "\n customized ones using '--cer ' and '--dwr '."; result += "\nThe process builds automatically CEA and DWA messages as a server, but you could program your own"; result += "\n customized ones using operations interface."; result += "\n"; @@ -1031,9 +1008,13 @@ std::string Launcher::help() const throw() { result += "\n"; result += "\ndiameterServerSessions| Updates the maximum number of accepted connections to diameter"; result += "\n server socket."; + result += "\ncontext|[target file] Application context could also be written by mean this operation,"; + result += "\n and not only through SIGUSR1. If optional path file is missing,"; + result += "\n default '/var/tmp/anna.context.' will be used."; result += "\ncollect Reset statistics and counters to start a new test stage of"; - result += "\n performance measurement. Context data is written at"; - result += "\n '/var/tmp/anna.context.' by mean 'kill -10 '."; + result += "\n performance measurement. Context data can be written at"; + result += "\n '/var/tmp/anna.context.' by mean 'kill -10 '"; + result += "\n or sending operation 'context|[target file]'."; result += "\nforceCountersRecord Forces dump to file the current counters of the process."; result += "\n"; result += "\n|[
:]|[socket id]"; @@ -1116,6 +1097,7 @@ std::string Launcher::help() const throw() { result += "\n has been logged)"; result += "\n [recvfe-ans-unknown] Reception from entity of an unknown answer (probably former [req2e-expired]"; result += "\n has been logged)"; + result += "\n [retry] Request retransmission"; result += "\n"; result += "\n-------------------------------------------------------------------------------------------- Load tests"; result += "\n"; @@ -1191,6 +1173,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(getCodecEngine()); // XXXXXXXXXXXXXX el del nodo de trabajo /////////////////////////////////////////////////////////////////// // Simple operations without arguments: @@ -1261,9 +1244,16 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons if(numParams == 2) { tok_iter++; param2 = Tokenizer::data(tok_iter); } // Operations: + if(opType == "context") { + std::string contextFile = ((numParams == 1) ? param1 : anna::functions::asString("/var/tmp/anna.context.%05d", getPid())); + writeContext(contextFile); + response_content = anna::functions::asString("Context dumped on file '%s'\n", contextFile.c_str()); + return; + } + 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 +1264,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 +1315,33 @@ 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(); + //msg->setRetries(4); + //msg->setOnExpiry(anna::diameter::comm::Message::OnExpiry::Retransmit); 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 +1368,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 +1451,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()); @@ -1510,8 +1506,7 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons } else if (param1 == "dump") { localServer->getReactingAnswers()->dump(); } else { - anna::diameter::codec::Engine *engine = anna::functions::component (ANNA_FILE_LOCATION); - anna::diameter::codec::Message *message = engine->createMessage(param1); + anna::diameter::codec::Message *message = getCodecEngine()->createMessage(param1); // // XXXXXXXXXXXXXX el del nodo de trabajo LOGDEBUG ( anna::Logger::debug(message->asXMLString(), ANNA_FILE_LOCATION); @@ -1543,8 +1538,7 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons } else if (param1 == "dump") { entity->getReactingAnswers()->dump(); } else { - anna::diameter::codec::Engine *engine = anna::functions::component (ANNA_FILE_LOCATION); - anna::diameter::codec::Message *message = engine->createMessage(param1); + anna::diameter::codec::Message *message = getCodecEngine()->createMessage(param1); // XXXXXXXXXXXXXX el del nodo de trabajo LOGDEBUG ( anna::Logger::debug(message->asXMLString(), ANNA_FILE_LOCATION); @@ -1656,10 +1650,12 @@ int MyDiameterEntity::readSocketId(const anna::diameter::comm::Message* message, if(sessionBasedModelsType == "SessionIdOptionalPart") return (atoi(optional.c_str()) % maxClientSessions); } - //case anna::diameter::helpers::dcca::ChargingContext::SMS: - //case anna::diameter::helpers::dcca::ChargingContext::MMS: - //default: - // return -1; // IEC model and Unknown traffic types + + case anna::diameter::helpers::dcca::ChargingContext::SMS: + case anna::diameter::helpers::dcca::ChargingContext::MMS: + case anna::diameter::helpers::dcca::ChargingContext::Unknown: + default: + return -1; } } catch(anna::RuntimeException &ex) { LOGDEBUG( @@ -1680,9 +1676,10 @@ throw() { result->createAttribute("StartTime", a_start_time.asString()); result->createAttribute("SecondsLifeTime", anna::time::functions::lapsedMilliseconds() / 1000); // Diameter: - (anna::functions::component (ANNA_FILE_LOCATION))->asXML(result); + getCodecEngine()->asXML(result); // XXXXXXXXXXXXXXX todos los nodos ... // OAM: anna::diameter::comm::OamModule::instantiate().asXML(result); + anna::diameter::comm::ApplicationMessageOamModule::instantiate().asXML(result); anna::diameter::codec::OamModule::instantiate().asXML(result); // Statistics: anna::statistics::Engine::instantiate().asXML(result);