X-Git-Url: https://git.teslayout.com/public/public/public/?a=blobdiff_plain;f=example%2Fdiameter%2Flauncher%2FEventOperation.cpp;h=935940db56d8a0f6c18db729db1c026a496f981e;hb=c56124ff93e8bceec159748dfe5ba8d56c62e3de;hp=be0c1683f14e0df49f6752c0cea552c8f169340f;hpb=220eecc7d53ddb85f72d94d5053738519fd8d27e;p=anna.git diff --git a/example/diameter/launcher/EventOperation.cpp b/example/diameter/launcher/EventOperation.cpp index be0c168..935940d 100644 --- a/example/diameter/launcher/EventOperation.cpp +++ b/example/diameter/launcher/EventOperation.cpp @@ -35,13 +35,14 @@ //#include //#include //#include -//#include +#include //#include //#include //#include #include //#include //#include +#include // //// Process //#include @@ -321,79 +322,255 @@ bool EventOperation::show_stats(std::string &response) { ///////////////////// // Flow operations // ///////////////////// -bool EventOperation::sendmsg2e(std::string &response, const std::string & diameterJson) { +bool EventOperation::sendmsg_hex_2e(std::string &response, const std::string & diameterJson_or_Hex, bool msg_or_hex) { Launcher& my_app = static_cast (anna::app::functions::getApp()); + anna::diameter::codec::Message codecMsg; // auxiliary codec message + bool success; + anna::diameter::comm::Message *msg; + if(msg_or_hex) { + std::string diameterXml = anna::json::functions::json2xml(diameterJson_or_Hex, success); + if (!success) { + response += "json to xml failed, unable to send message !"; + return false; + } + codecMsg.loadXMLString(diameterXml); + try { + my_app.updateOperatedOriginHostWithMessage(codecMsg); + msg = my_app.getOperatedHost()->createCommMessage(); + msg->clearBody(); + } + catch(anna::RuntimeException &ex) { + ex.trace(); + response += "invalid operated host"; + return false; + } + 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) + msg->setBody(codecMsg.code()); + } else { + // Get DataBlock from hex content: + anna::DataBlock db_aux(true); + std::string hexString = diameterJson_or_Hex; + hexString.erase(std::remove(hexString.begin(), hexString.end(), ':'), hexString.end()); + LOGDEBUG( + std::string msg = "Hex string (remove colons if exists): "; + msg += hexString; + anna::Logger::debug(msg, ANNA_FILE_LOCATION); + ); + anna::functions::fromHexString(hexString, db_aux); // could launch exception + try { + my_app.updateOperatedOriginHostWithMessage(db_aux); + msg = my_app.getOperatedHost()->createCommMessage(); + } + catch(anna::RuntimeException &ex) { + ex.trace(); + response += "invalid operated host"; + return false; + } + msg->setBody(db_aux); + try { if(my_app.getOperatedHost()->logEnabled()) codecMsg.decode(db_aux); } catch(anna::RuntimeException &ex) { ex.trace(); } + } + success = my_app.getOperatedEntity()->send(msg); + my_app.getOperatedHost()->releaseCommMessage(msg); - return true; // OK -} - -bool EventOperation::sendmsg2c(std::string &response, const std::string & diameterJson) { - - Launcher& my_app = static_cast (anna::app::functions::getApp()); - + // Detailed log: + if(my_app.getOperatedHost()->logEnabled()) { + anna::diameter::comm::Server *usedServer = my_app.getOperatedEntity()->getLastUsedResource(); + anna::diameter::comm::ClientSession *usedClientSession = usedServer ? usedServer->getLastUsedResource() : NULL; + std::string detail = usedClientSession ? usedClientSession->asString() : ""; // shouldn't happen + my_app.getOperatedHost()->writeLogFile(codecMsg, (success ? "sent2e" : "send2eError"), detail); + } - return true; // OK + response = "Operation processed"; // could be failed + return success; } -bool EventOperation::answermsg2e(std::string &response, const std::string & diameterJson) { +bool EventOperation::sendmsg_hex_2c(std::string &response, const std::string & diameterJson_or_Hex, bool msg_or_hex) { Launcher& my_app = static_cast (anna::app::functions::getApp()); + anna::diameter::codec::Message codecMsg; // auxiliary codec message + bool success; + anna::diameter::comm::Message *msg; + if(msg_or_hex) { + std::string diameterXml = anna::json::functions::json2xml(diameterJson_or_Hex, success); + if (!success) { + response += "json to xml failed, unable to send message !"; + return false; + } + codecMsg.loadXMLString(diameterXml); + try { + my_app.updateOperatedOriginHostWithMessage(codecMsg); + msg = my_app.getOperatedHost()->createCommMessage(); + msg->clearBody(); + } + catch(anna::RuntimeException &ex) { + ex.trace(); + response += "invalid operated host"; + return false; + } + 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) + msg->setBody(codecMsg.code()); + } else { + // Get DataBlock from hex content: + anna::DataBlock db_aux(true); + std::string hexString = diameterJson_or_Hex; + hexString.erase(std::remove(hexString.begin(), hexString.end(), ':'), hexString.end()); + LOGDEBUG( + std::string msg = "Hex string (remove colons if exists): "; + msg += hexString; + anna::Logger::debug(msg, ANNA_FILE_LOCATION); + ); + anna::functions::fromHexString(hexString, db_aux); // could launch exception + try { + my_app.updateOperatedOriginHostWithMessage(db_aux); + msg = my_app.getOperatedHost()->createCommMessage(); + } + catch(anna::RuntimeException &ex) { + ex.trace(); + response += "invalid operated host"; + return false; + } + msg->setBody(db_aux); + try { if(my_app.getOperatedHost()->logEnabled()) codecMsg.decode(db_aux); } catch(anna::RuntimeException &ex) { ex.trace(); } + } + success = my_app.getOperatedServer()->send(msg); + my_app.getOperatedHost()->releaseCommMessage(msg); - return true; // OK -} - -bool EventOperation::answermsg2c(std::string &response, const std::string & diameterJson) { - - Launcher& my_app = static_cast (anna::app::functions::getApp()); - + // Detailed log: + if(my_app.getOperatedHost()->logEnabled()) { + anna::diameter::comm::ServerSession *usedServerSession = my_app.getOperatedServer()->getLastUsedResource(); + std::string detail = usedServerSession ? usedServerSession->asString() : ""; // shouldn't happen + my_app.getOperatedHost()->writeLogFile(codecMsg, (success ? "sent2c" : "send2cError"), detail); + } - return true; // OK + response = "Operation processed"; // could be failed + return success; } -bool EventOperation::answermsg2e_action(std::string &response, const std::string & action) { +bool EventOperation::answermsg_action_2e(std::string &response, const std::string & diameterJson_or_action, bool msg_or_action) { Launcher& my_app = static_cast (anna::app::functions::getApp()); + anna::diameter::codec::Message codecMsg; // auxiliary codec message + anna::diameter::codec::Message *message; + bool success; + if (msg_or_action) { + std::string diameterXml = anna::json::functions::json2xml(diameterJson_or_action, success); + if (!success) { + response += "json to xml failed, unable to send message !"; + return false; + } + codecMsg.loadXMLString(diameterXml); + try { + my_app.updateOperatedOriginHostWithMessage(codecMsg); + message = my_app.getOperatedHost()->getCodecEngine()->createMessage(diameterXml, false /* is xml string */); // loads xml again, lesser of two evils + LOGDEBUG(anna::Logger::debug(message->asXMLString(), ANNA_FILE_LOCATION)); + } + catch(anna::RuntimeException &ex) { + ex.trace(); + response += "invalid operated host"; + return false; + } - return true; // OK -} - -bool EventOperation::answermsg2c_action(std::string &response, const std::string & action) { - - Launcher& my_app = static_cast (anna::app::functions::getApp()); + if(message->isRequest()) { + response += "cannot program diameter requests. Answer type must be provided"; + return false; + } + int code = message->getId().first; + LOGDEBUG(anna::Logger::debug("Adding a new programed 'answer to entity' to the FIFO queue corresponding to its message code ...", ANNA_FILE_LOCATION)); + response = "Added 'answer to entity' to the FIFO queue corresponding to its message code"; + my_app.getOperatedEntity()->getReactingAnswers()->addMessage(code, message); + } + else { // action + + if(diameterJson_or_action == "list") { // programmed answers FIFO's to stdout + response = anna::functions::encodeBase64(my_app.getOperatedEntity()->getReactingAnswers()->asString("ANSWERS TO ENTITY")); + } else if (diameterJson_or_action == "rotate") { + my_app.getOperatedEntity()->getReactingAnswers()->rotate(true); + response = "rotate"; + } else if (diameterJson_or_action == "exhaust") { + my_app.getOperatedEntity()->getReactingAnswers()->rotate(false); + response = "exhaust"; + } else if (diameterJson_or_action == "clear") { + my_app.getOperatedEntity()->getReactingAnswers()->clear(); + response = "clear"; + } else if (diameterJson_or_action == "dump") { + my_app.getOperatedEntity()->getReactingAnswers()->dump("programmed_answer"); + response = "dump"; + } + } return true; // OK } -bool EventOperation::sendhex2e(std::string &response, const std::string & diameterHex) { +bool EventOperation::answermsg_action_2c(std::string &response, const std::string & diameterJson_or_action, bool msg_or_action) { Launcher& my_app = static_cast (anna::app::functions::getApp()); + anna::diameter::codec::Message codecMsg; // auxiliary codec message + anna::diameter::codec::Message *message; + bool success; + if (msg_or_action) { + std::string diameterXml = anna::json::functions::json2xml(diameterJson_or_action, success); + if (!success) { + response += "json to xml failed, unable to send message !"; + return false; + } + codecMsg.loadXMLString(diameterXml); + try { + my_app.updateOperatedOriginHostWithMessage(codecMsg); + message = my_app.getOperatedHost()->getCodecEngine()->createMessage(diameterXml, false /* is xml string */); // loads xml again, lesser of two evils + LOGDEBUG(anna::Logger::debug(message->asXMLString(), ANNA_FILE_LOCATION)); + } + catch(anna::RuntimeException &ex) { + ex.trace(); + response += "invalid operated host"; + return false; + } - return true; // OK -} - -bool EventOperation::sendhex2c(std::string &response, const std::string & diameterHex) { - - Launcher& my_app = static_cast (anna::app::functions::getApp()); + if(message->isRequest()) { + response += "cannot program diameter requests. Answer type must be provided"; + return false; + } + int code = message->getId().first; + LOGDEBUG(anna::Logger::debug("Adding a new programed 'answer to client' to the FIFO queue corresponding to its message code ...", ANNA_FILE_LOCATION)); + my_app.getOperatedServer()->getReactingAnswers()->addMessage(code, message); + response = "Added 'answer to client' to the FIFO queue corresponding to its message code"; + } + else { // action + + if(diameterJson_or_action == "list") { // programmed answers FIFO's to stdout + response = anna::functions::encodeBase64(my_app.getOperatedServer()->getReactingAnswers()->asString("ANSWERS TO CLIENT")); + } else if (diameterJson_or_action == "rotate") { + my_app.getOperatedServer()->getReactingAnswers()->rotate(true); + response = "rotate"; + } else if (diameterJson_or_action == "exhaust") { + my_app.getOperatedServer()->getReactingAnswers()->rotate(false); + response = "exhaust"; + } else if (diameterJson_or_action == "clear") { + my_app.getOperatedServer()->getReactingAnswers()->clear(); + response = "clear"; + } else if (diameterJson_or_action == "dump") { + my_app.getOperatedServer()->getReactingAnswers()->dump("programmed_answer"); + response = "dump"; + } + } return true; // OK } - ///////////////// // FSM testing // /////////////////