X-Git-Url: https://git.teslayout.com/public/public/public/?a=blobdiff_plain;f=example%2Fdiameter%2Flauncher%2Fmain.cpp;h=35b283cf7494f9ed5b21a45bbd375c018d32e1fa;hb=4a973145aa74bd26cfd15fe4a4782c140716d70d;hp=38a6b1dd3368f2173d99dd92347233a756435c03;hpb=b9cb59210ce2a02d8246f1a9a1acfcfdcd892f3a;p=anna.git diff --git a/example/diameter/launcher/main.cpp b/example/diameter/launcher/main.cpp index 38a6b1d..35b283c 100644 --- a/example/diameter/launcher/main.cpp +++ b/example/diameter/launcher/main.cpp @@ -116,12 +116,34 @@ typedef std::map < int /* message code */, codec_messages_deque* >::const_iterat public: ProgrammedAnswers() {}; - ~ProgrammedAnswers() { + ~ProgrammedAnswers() { clear(); } + + void clear () throw() { for (reacting_answers_const_iterator it = a_deques.begin(); it != a_deques.end(); it++) { anna::diameter::codec::Engine *engine = anna::functions::component (ANNA_FILE_LOCATION); engine->releaseMessage(*(it->second->begin())); delete(it->second); } + a_deques.clear(); + } + + void dump () throw() { + std::string outfilename, xmlString; + for(reacting_answers_const_iterator it = a_deques.begin(); it != a_deques.end(); it++) { + int sequence = 1; + for(codec_messages_deque_const_iterator itm = it->second->begin(); itm != it->second->end(); itm++) { + // programmed_answer.. + outfilename = "programmed_answer."; + outfilename += anna::functions::asString(it->first); + outfilename += "."; + outfilename += anna::functions::asString(sequence++); + outfilename += ".xml"; + std::ofstream outfile(outfilename.c_str(), std::ifstream::out); + xmlString = (*itm)->asXMLString(); + outfile.write(xmlString.c_str(), xmlString.size()); + outfile.close(); + } + } } void addMessage(int code, anna::diameter::codec::Message *message) throw() { @@ -158,10 +180,14 @@ typedef std::map < int /* message code */, codec_messages_deque* >::const_iterat std::string asString() const throw() { std::string result = "No ocurrences found\n\n"; + std::string s_code; if(a_deques.size() != 0) { + result = ""; for(reacting_answers_const_iterator it = a_deques.begin(); it != a_deques.end(); it++) { - result += "Answer code .............................................................. "; - result += anna::functions::asString(it->first); result += "\n"; + + s_code = "Answer code "; + s_code += anna::functions::asString(it->first); + result += anna::functions::highlightJustify(s_code); for(codec_messages_deque_const_iterator itm = it->second->begin(); itm != it->second->end(); itm++) { result += (*itm)->asXMLString(); result += "\n"; @@ -731,7 +757,7 @@ std::string Launcher::help() const throw() { result += "\n establish as minimum), separate statistics analyzer per each resource, automatic CER/CEA and DWR/DWA"; result += "\n generation, expiration control and many more features."; result += "\n"; - result += "\nProcess traces are dump on \"launcher.traces\" and could have any trace level (POSIX levels), usually"; + result += "\nProcess traces are dump on \"launcher.trace\" and could have any trace level (POSIX levels), usually"; result += "\n 'debug' or 'warning'. See ANNA documentation for more details."; result += "\n"; result += "\nAs any other ANNA process, context dump could be retrieved sending SIGUSR1 signal:"; @@ -819,10 +845,17 @@ std::string Launcher::help() const throw() { result += "\nsendxml2e| Sends xml source file (pathfile) through configured entity."; result += "\nsendxml2c| Sends xml source file (pathfile) to client."; result += "\nsendxml| Same as 'sendxml2e'."; - result += "\nanswerxml2e|[source_file] Answer xml source file (pathfile) for corresponding request from entity."; - result += "\nanswerxml2c|[source_file] Answer xml source file (pathfile) for corresponding request from client."; + result += "\nanswerxml2e|[source_file] Answer xml source file (pathfile) for incoming request with same code from entity."; + result += "\n The answer is stored in a FIFO queue for a specific message code, then there are"; + result += "\n as many queues as different message codes have been received."; + result += "\nanswerxml2c|[source_file] Answer xml source file (pathfile) for incoming request with same code from client."; + result += "\n The answer is stored in a FIFO queue for a specific message code, then there are"; + result += "\n as many queues as different message codes have been received."; result += "\nanswerxml|[source_file] Same as 'answerxml2c'."; - result += "\n List programmed answers if no parameter provided."; + result += "\nanswerxml(2e/2c) List programmed answers (to entity/client) if no parameter provided."; + result += "\nanswerxml(2e/2c)|dump Write programmed answers (to entity/client) to file 'programmed_answer..',"; + result += "\n where 'sequence' is the order of the answer in each FIFO code-queue of programmed answers."; + result += "\nanswerxml(2e/2c)|clear Clear programmed answers (to entity/client)."; result += "\n"; result += "\nSend operations are available using hexadecimal content (hex formatted files) which also allow to test"; result += "\nspecial scenarios (protocol errors):"; @@ -832,8 +865,8 @@ std::string Launcher::help() const throw() { result += "\nsendhex| Same as 'sendhex2e'."; result += "\n"; result += "\nAnswer programming in hexadecimal is not really neccessary (you could use send primitives) and also"; - result += "\nis intended to be used with decoded messages in order to replace things like hop by hop, end to end,"; - result += "\nsubscriber id, session id, etc. Anyway you could use 'decode' operation and then program the xml created."; + result += "\n is intended to be used with decoded messages in order to replace things like hop by hop, end to end,"; + result += "\n subscriber id, session id, etc. Anyway you could use 'decode' operation and then program the xml created."; result += "\n"; result += "\nIf a request is received, answer map (built with 'answerxml<[2c] or 2e>' operations) will be"; result += "\n checked to find a corresponding programmed answer to be replied(*). If no ocurrence is found,"; @@ -841,6 +874,11 @@ std::string Launcher::help() const throw() { result += "\n or nothing but trace when no peer at that side is configured. Answer to client have sense when"; result += "\n diameter server socket is configured, answer to entity have sense when entity does."; result += "\n"; + result += "\nIn the most complete situation (process with both client and server side) there are internally"; + result += "\n two maps with N FIFO queues, one for each different message code within programmed answers."; + result += "\nOne map is for answers towards the client, and the other is to react entity requests. Then in"; + result += "\n each one we could program different answers corresponding to different request codes received."; + result += "\n"; result += "\n(*) sequence values (hop-by-hop and end-to-end), Session-Id and Subscription-Id avps, are mirrored"; result += "\n to the peer which sent the request. If user wants to test a specific answer without changing it,"; result += "\n use sendxml/sendhex operations better than programming."; @@ -998,7 +1036,7 @@ using namespace anna::diameter; int main(int argc, const char** argv) { anna::Logger::setLevel(anna::Logger::Warning); - anna::Logger::initialize("launcher", new TraceWriter("launcher.traces", 2048000)); + anna::Logger::initialize("launcher", new TraceWriter("launcher.trace", 2048000)); anna::time::functions::initialize(); // before application instantiation (it have a anna::time object) anna::time::functions::setControlPoint(); // start control point (application lifetime) Launcher app; @@ -1729,7 +1767,7 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons std::string s_help = help(); std::cout << s_help << std::endl; LOGINFORMATION(anna::Logger::information(s_help, ANNA_FILE_LOCATION)); - response_content = "Help dumped on stdout and information-level traces (launcher.traces file)\n"; + response_content = "Help dumped on stdout and information-level traces (launcher.trace file)\n"; return; } @@ -2019,7 +2057,17 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons if(!localServer) throw anna::RuntimeException("Operation not applicable (no own diameter server has been configured)", ANNA_FILE_LOCATION); - if(param1 != "") { + if(param1 == "") { // programmed answers FIFO's to stdout + std::cout << std::endl << std::endl; + std::cout << " ------------- CURRENT PROGRAMMED ANSWERS TO CLIENT -------------\n\n"; + std::cout << G_reactingAnswers2C.asString() << std::endl; + response_content = "Programmed answers dumped on stdout\n"; + return; + } else if (param1 == "clear") { + G_reactingAnswers2C.clear(); + } else if (param1 == "dump") { + G_reactingAnswers2C.dump(); + } else { anna::diameter::codec::Engine *engine = anna::functions::component (ANNA_FILE_LOCATION); anna::diameter::codec::Message *message = engine->createMessage(param1); LOGDEBUG @@ -2031,14 +2079,8 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons throw anna::RuntimeException("Cannot program diameter requests. Answer type must be provided", ANNA_FILE_LOCATION); int code = message->getId().first; - LOGDEBUG(anna::Logger::debug("Adding a new programed 'answer to client' to the deque...", ANNA_FILE_LOCATION)); + LOGDEBUG(anna::Logger::debug("Adding a new programed 'answer to client' to the FIFO queue corresponding to its message code ...", ANNA_FILE_LOCATION)); G_reactingAnswers2C.addMessage(code, message); - } else { // answers query on stdout - std::cout << std::endl << std::endl; - std::cout << " ------------- CURRENT PROGRAMMED ANSWERS TO CLIENT -------------\n\n"; - std::cout << G_reactingAnswers2C.asString() << std::endl; - response_content = "Programmed answers dumped on stdout\n"; - return; } } else if(opType == "answerxml2e") { anna::diameter::comm::Entity *entity = getEntity(); @@ -2046,7 +2088,17 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons if(!entity) throw anna::RuntimeException("Operation not applicable (no diameter entity has been configured)", ANNA_FILE_LOCATION); - if(param1 != "") { + if(param1 == "") { // programmed answers FIFO's to stdout + std::cout << std::endl << std::endl; + std::cout << " ------------- CURRENT PROGRAMMED ANSWERS TO ENTITY -------------\n\n"; + std::cout << G_reactingAnswers2E.asString() << std::endl; + response_content = "Programmed answers dumped on stdout\n"; + return; + } else if (param1 == "clear") { + G_reactingAnswers2E.clear(); + } else if (param1 == "dump") { + G_reactingAnswers2E.dump(); + } else { anna::diameter::codec::Engine *engine = anna::functions::component (ANNA_FILE_LOCATION); anna::diameter::codec::Message *message = engine->createMessage(param1); LOGDEBUG @@ -2058,14 +2110,8 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons throw anna::RuntimeException("Cannot program diameter requests. Answer type must be provided", ANNA_FILE_LOCATION); int code = message->getId().first; - LOGDEBUG(anna::Logger::debug("Adding a new programed 'answer to entity' to the deque...", ANNA_FILE_LOCATION)); + LOGDEBUG(anna::Logger::debug("Adding a new programed 'answer to entity' to the FIFO queue corresponding to its message code ...", ANNA_FILE_LOCATION)); G_reactingAnswers2E.addMessage(code, message); - } else { // answers query on stdout - std::cout << std::endl << std::endl; - std::cout << " ------------- CURRENT PROGRAMMED ANSWERS TO ENTITY -------------\n\n"; - std::cout << G_reactingAnswers2E.asString() << std::endl; - response_content = "Programmed answers dumped on stdout\n"; - return; } } else { LOGWARNING(anna::Logger::warning(help(), ANNA_FILE_LOCATION));