X-Git-Url: https://git.teslayout.com/public/public/public/?a=blobdiff_plain;f=example%2Fdiameter%2Flauncher%2FLauncher.cpp;h=f377e91e15ebea1a50e77175b5bddf1c416a46f5;hb=21d58fc1611bb292fdff8b31628ad88d552ce52b;hp=e4ea4ca347d1309e31c678940946b94ccbcafdc0;hpb=5f094136b1817b5c4d14dbcc33c9819a8569cd1e;p=anna.git diff --git a/example/diameter/launcher/Launcher.cpp b/example/diameter/launcher/Launcher.cpp index e4ea4ca..f377e91 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" @@ -359,13 +360,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: + 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; + } + /////////////////////////////// // 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 // ///////////////// @@ -463,6 +536,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 // @@ -470,77 +555,10 @@ 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': @@ -911,9 +929,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) { @@ -1001,21 +1019,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"; @@ -1041,9 +1059,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]"; @@ -1272,6 +1294,13 @@ 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") { codecMsg.loadXML(param1); std::string hexString = anna::functions::asHexString(codecMsg.code()); @@ -1698,6 +1727,7 @@ throw() { (anna::functions::component (ANNA_FILE_LOCATION))->asXML(result); // 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);