1 // ANNA - Anna is Not Nothingness Anymore //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
13 #include <EventOperation.hpp>
14 #include <Launcher.hpp>
17 #include <anna/diameter.comm/OriginHost.hpp>
21 //#include <sstream> // std::istringstream
22 //#include <iostream> // std::cout
24 //#include <math.h> // ceil
26 #include <unistd.h> // chdir
30 #include <anna/json/functions.hpp>
31 #include <anna/diameter/codec/Message.hpp>
32 //#include <anna/timex/Engine.hpp>
33 //#include <anna/statistics/Engine.hpp>
34 //#include <anna/diameter/codec/functions.hpp>
35 //#include <anna/diameter/codec/Engine.hpp>
36 //#include <anna/diameter/codec/EngineManager.hpp>
37 //#include <anna/http/Transport.hpp>
38 //#include <anna/diameter/stack/Engine.hpp>
39 #include <anna/diameter/helpers/base/functions.hpp>
40 #include <anna/time/functions.hpp>
41 #include <anna/core/functions.hpp>
42 //#include <anna/diameter.comm/ApplicationMessageOamModule.hpp>
43 //#include <anna/testing/defines.hpp>
44 #include <anna/xml/xml.hpp>
45 //#include <anna/diameter.comm/OriginHost.hpp>
46 //#include <anna/diameter.comm/OriginHostManager.hpp>
47 #include <anna/diameter.comm/Message.hpp>
50 //#include <Launcher.hpp>
51 //#include <Procedure.hpp>
52 //#include <EventOperation.hpp>
53 #include <MyDiameterEngine.hpp>
54 #include <MyLocalServer.hpp>
55 #include <anna/testing/TestManager.hpp>
56 //#include <anna/testing/TestCase.hpp>
62 bool EventOperation::node(std::string &response, const std::string & name) {
64 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
66 anna::diameter::comm::OriginHost *workingNode;
67 try { workingNode = my_app.getWorkingNode(); } catch(anna::RuntimeException &ex) { ex.trace(); }
70 if (my_app.setWorkingNode(name)) {
71 response = anna::functions::asString("Forced node is now '%s'", name.c_str());
72 my_app.setOperatedHost(my_app.getWorkingNode()); // now is the new one
75 response = anna::functions::asString("Node '%s' invalid. Nothing done", name.c_str());
81 response = anna::functions::encodeBase64(workingNode->asXMLString());
84 response = workingNode->asXMLString();
88 response = "Working node is automatic";
94 bool EventOperation::node_auto(std::string &response) {
96 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
99 response = "Working node has been set to automatic";
104 ////////////////////////
105 // Parsing operations //
106 ////////////////////////
107 bool EventOperation::code(std::string &response, const std::string & diameterJson) {
110 std::string diameterXml = anna::json::functions::json2xml(diameterJson, success);
112 response += "json to xml failed, unable to encode !";
115 anna::diameter::codec::Message codecMsg; // auxiliary codec message
116 codecMsg.loadXMLString(diameterXml);
117 response = anna::functions::asHexString(codecMsg.code());
122 bool EventOperation::decode(std::string &response, const std::string & diameterHex) {
124 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
126 anna::DataBlock db_aux(true);
127 anna::functions::fromHexString(diameterHex, db_aux);
128 anna::diameter::codec::Message codecMsg; // auxiliary codec message
130 codecMsg.decode(db_aux);
131 std::string xmlString = codecMsg.asXMLString();
132 response = anna::functions::encodeBase64(xmlString);
134 catch(anna::RuntimeException &ex) { ex.trace(); }
139 bool EventOperation::loadmsg(std::string &response, const std::string & diameterJson) {
142 std::string diameterXml = anna::json::functions::json2xml(diameterJson, success);
144 response += "json to xml failed, unable to load message !";
147 anna::diameter::codec::Message codecMsg; // auxiliary codec message
148 codecMsg.loadXMLString(diameterXml);
149 response = anna::functions::encodeBase64(codecMsg.asXMLString());
157 bool EventOperation::services(std::string &response, const std::string & servicesJson) {
159 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
162 std::string servicesXml = anna::json::functions::json2xml(servicesJson, success);
164 response += "json to xml failed, unable to load services !";
169 my_app.loadServicesFromXMLString(servicesXml, true /* bind entities */);
171 catch(anna::RuntimeException &ex) {
173 response += "loaded services with errors";
176 response = "loaded services correctly";
181 bool EventOperation::diameterServerSessions(std::string &response, int sessions) {
183 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
186 my_app.getOperatedServer()->setMaxConnections(sessions);
188 catch(anna::RuntimeException &ex) {
190 response += "fail to operate the server";
193 response = "new sessions successfully established on operated diameter server";
198 bool EventOperation::change_dir(std::string &response, const std::string & directory) {
200 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
202 std::string dir = directory;
203 if (dir == "") dir = my_app.getInitialWorkingDirectory();
204 bool result = (chdir(dir.c_str()) == 0);
207 response = "New execution directory configured: ";
209 response = "Cannot assign provided execution directory: ";
215 ////////////////////////////////
216 // Client sessions visibility //
217 ////////////////////////////////
218 bool EventOperation::visibility(std::string &response, const std::string & action, const std::string &addressPort, int socket) {
220 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
224 if(addressPort != "") {
226 std::string key = addressPort;
228 key += anna::functions::asString(socket);
230 if(action == "hide") my_app.getOperatedEngine()->findClientSession(key)->hide();
231 if(action == "show") my_app.getOperatedEngine()->findClientSession(key)->show();
232 if(action == "hidden") response = my_app.getOperatedEngine()->findClientSession(key)->hidden() ? "true" : "false";
233 if(action == "shown") response = my_app.getOperatedEngine()->findClientSession(key)->shown() ? "true" : "false";
237 anna::functions::getAddressAndPortFromSocketLiteral(addressPort, address, port);
239 if(action == "hide") my_app.getOperatedEngine()->findServer(address, port)->hide();
240 if(action == "show") my_app.getOperatedEngine()->findServer(address, port)->show();
241 if(action == "hidden") response = my_app.getOperatedEngine()->findServer(address, port)->hidden() ? "true" : "false";
242 if(action == "shown") response = my_app.getOperatedEngine()->findServer(address, port)->shown() ? "true" : "false";
245 if(action == "hide") my_app.getOperatedEntity()->hide();
246 if(action == "show") my_app.getOperatedEntity()->show();
247 if(action == "hidden") response = my_app.getOperatedEntity()->hidden() ? "true" : "false";
248 if(action == "shown") response = my_app.getOperatedEntity()->shown() ? "true" : "false";
258 bool EventOperation::collect(std::string &response) {
260 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
262 my_app.resetCounters();
263 my_app.resetStatistics();
264 response = "All process counters & statistic information have been reset";
269 bool EventOperation::context(std::string &response, const std::string & targetFile) {
271 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
273 std::string contextFile = (targetFile != "") ? targetFile : anna::functions::asString("/var/tmp/anna.context.%05d", my_app.getPid());
274 my_app.writeContext(contextFile);
275 response = anna::functions::asString("Context dumped on file '%s'", contextFile.c_str());
280 bool EventOperation::forceCountersRecord(std::string &response) {
282 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
284 my_app.forceCountersRecord();
285 response = "Current counters have been dump to disk";
290 bool EventOperation::log_statistics_samples(std::string &response, const std::string & list) {
292 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
294 my_app.logStatisticsSamples(list);
295 response = anna::functions::asString("Log statistics samples for '%s' concepts", list.c_str());
300 bool EventOperation::show_oam(std::string &response) {
302 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
304 anna::xml::Node root("root");
305 response = anna::xml::Compiler().apply(my_app.oamAsXML(&root));
307 response = anna::functions::encodeBase64(response);
312 bool EventOperation::show_stats(std::string &response) {
314 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
316 anna::xml::Node root("root");
317 response = anna::xml::Compiler().apply(my_app.statsAsXML(&root));
319 response = anna::functions::encodeBase64(response);
324 /////////////////////
325 // Flow operations //
326 /////////////////////
327 bool EventOperation::sendmsg_hex_2e(std::string &response, const std::string & diameterJson_or_Hex, bool msg_or_hex) {
329 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
330 anna::diameter::codec::Message codecMsg; // auxiliary codec message
332 anna::diameter::comm::Message *msg;
335 std::string diameterXml = anna::json::functions::json2xml(diameterJson_or_Hex, success);
337 response += "json to xml failed, unable to send message !";
340 codecMsg.loadXMLString(diameterXml);
342 my_app.updateOperatedOriginHostWithMessage(codecMsg);
343 msg = my_app.getOperatedHost()->createCommMessage();
346 catch(anna::RuntimeException &ex) {
348 response += "invalid operated host";
351 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)
352 msg->setBody(codecMsg.code());
354 // Get DataBlock from hex content:
355 anna::DataBlock db_aux(true);
356 std::string hexString = diameterJson_or_Hex;
357 hexString.erase(std::remove(hexString.begin(), hexString.end(), ':'), hexString.end());
359 std::string msg = "Hex string (remove colons if exists): ";
361 anna::Logger::debug(msg, ANNA_FILE_LOCATION);
363 anna::functions::fromHexString(hexString, db_aux); // could launch exception
365 my_app.updateOperatedOriginHostWithMessage(db_aux);
366 msg = my_app.getOperatedHost()->createCommMessage();
368 catch(anna::RuntimeException &ex) {
370 response += "invalid operated host";
373 msg->setBody(db_aux);
374 try { if(my_app.getOperatedHost()->logEnabled()) codecMsg.decode(db_aux); } catch(anna::RuntimeException &ex) { ex.trace(); }
377 success = my_app.getOperatedEntity()->send(msg);
378 my_app.getOperatedHost()->releaseCommMessage(msg);
381 if(my_app.getOperatedHost()->logEnabled()) {
382 anna::diameter::comm::Server *usedServer = my_app.getOperatedEntity()->getLastUsedResource();
383 anna::diameter::comm::ClientSession *usedClientSession = usedServer ? usedServer->getLastUsedResource() : NULL;
384 std::string detail = usedClientSession ? usedClientSession->asString() : "<null client session>"; // shouldn't happen
385 my_app.getOperatedHost()->writeLogFile(codecMsg, (success ? "sent2e" : "send2eError"), detail);
389 response = "Operation processed"; // could be failed
393 bool EventOperation::sendmsg_hex_2c(std::string &response, const std::string & diameterJson_or_Hex, bool msg_or_hex) {
395 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
396 anna::diameter::codec::Message codecMsg; // auxiliary codec message
398 anna::diameter::comm::Message *msg;
401 std::string diameterXml = anna::json::functions::json2xml(diameterJson_or_Hex, success);
403 response += "json to xml failed, unable to send message !";
406 codecMsg.loadXMLString(diameterXml);
408 my_app.updateOperatedOriginHostWithMessage(codecMsg);
409 msg = my_app.getOperatedHost()->createCommMessage();
412 catch(anna::RuntimeException &ex) {
414 response += "invalid operated host";
417 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)
418 msg->setBody(codecMsg.code());
420 // Get DataBlock from hex content:
421 anna::DataBlock db_aux(true);
422 std::string hexString = diameterJson_or_Hex;
423 hexString.erase(std::remove(hexString.begin(), hexString.end(), ':'), hexString.end());
425 std::string msg = "Hex string (remove colons if exists): ";
427 anna::Logger::debug(msg, ANNA_FILE_LOCATION);
429 anna::functions::fromHexString(hexString, db_aux); // could launch exception
431 my_app.updateOperatedOriginHostWithMessage(db_aux);
432 msg = my_app.getOperatedHost()->createCommMessage();
434 catch(anna::RuntimeException &ex) {
436 response += "invalid operated host";
439 msg->setBody(db_aux);
440 try { if(my_app.getOperatedHost()->logEnabled()) codecMsg.decode(db_aux); } catch(anna::RuntimeException &ex) { ex.trace(); }
443 success = my_app.getOperatedServer()->send(msg);
444 my_app.getOperatedHost()->releaseCommMessage(msg);
447 if(my_app.getOperatedHost()->logEnabled()) {
448 anna::diameter::comm::ServerSession *usedServerSession = my_app.getOperatedServer()->getLastUsedResource();
449 std::string detail = usedServerSession ? usedServerSession->asString() : "<null server session>"; // shouldn't happen
450 my_app.getOperatedHost()->writeLogFile(codecMsg, (success ? "sent2c" : "send2cError"), detail);
454 response = "Operation processed"; // could be failed
458 bool EventOperation::answermsg_action_2e(std::string &response, const std::string & diameterJson_or_action, bool msg_or_action) {
460 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
461 anna::diameter::codec::Message codecMsg; // auxiliary codec message
462 anna::diameter::codec::Message *message;
467 std::string diameterXml = anna::json::functions::json2xml(diameterJson_or_action, success);
469 response += "json to xml failed, unable to send message !";
472 codecMsg.loadXMLString(diameterXml);
474 my_app.updateOperatedOriginHostWithMessage(codecMsg);
475 message = my_app.getOperatedHost()->getCodecEngine()->createMessage(diameterXml, false /* is xml string */); // loads xml again, lesser of two evils
476 LOGDEBUG(anna::Logger::debug(message->asXMLString(), ANNA_FILE_LOCATION));
478 catch(anna::RuntimeException &ex) {
480 response += "invalid operated host";
484 if(message->isRequest()) {
485 response += "cannot program diameter requests. Answer type must be provided";
489 int code = message->getId().first;
490 LOGDEBUG(anna::Logger::debug("Adding a new programed 'answer to entity' to the FIFO queue corresponding to its message code ...", ANNA_FILE_LOCATION));
491 response = "Added 'answer to entity' to the FIFO queue corresponding to its message code";
492 my_app.getOperatedEntity()->getReactingAnswers()->addMessage(code, message);
496 if(diameterJson_or_action == "list") { // programmed answers FIFO's to stdout
497 response = anna::functions::encodeBase64(my_app.getOperatedEntity()->getReactingAnswers()->asString("ANSWERS TO ENTITY"));
498 } else if (diameterJson_or_action == "rotate") {
499 my_app.getOperatedEntity()->getReactingAnswers()->rotate(true);
501 } else if (diameterJson_or_action == "exhaust") {
502 my_app.getOperatedEntity()->getReactingAnswers()->rotate(false);
503 response = "exhaust";
504 } else if (diameterJson_or_action == "clear") {
505 my_app.getOperatedEntity()->getReactingAnswers()->clear();
507 } else if (diameterJson_or_action == "dump") {
508 my_app.getOperatedEntity()->getReactingAnswers()->dump("programmed_answer");
517 bool EventOperation::answermsg_action_2c(std::string &response, const std::string & diameterJson_or_action, bool msg_or_action) {
519 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
520 anna::diameter::codec::Message codecMsg; // auxiliary codec message
521 anna::diameter::codec::Message *message;
526 std::string diameterXml = anna::json::functions::json2xml(diameterJson_or_action, success);
528 response += "json to xml failed, unable to send message !";
531 codecMsg.loadXMLString(diameterXml);
533 my_app.updateOperatedOriginHostWithMessage(codecMsg);
534 message = my_app.getOperatedHost()->getCodecEngine()->createMessage(diameterXml, false /* is xml string */); // loads xml again, lesser of two evils
535 LOGDEBUG(anna::Logger::debug(message->asXMLString(), ANNA_FILE_LOCATION));
537 catch(anna::RuntimeException &ex) {
539 response += "invalid operated host";
543 if(message->isRequest()) {
544 response += "cannot program diameter requests. Answer type must be provided";
548 int code = message->getId().first;
549 LOGDEBUG(anna::Logger::debug("Adding a new programed 'answer to client' to the FIFO queue corresponding to its message code ...", ANNA_FILE_LOCATION));
550 my_app.getOperatedServer()->getReactingAnswers()->addMessage(code, message);
551 response = "Added 'answer to client' to the FIFO queue corresponding to its message code";
555 if(diameterJson_or_action == "list") { // programmed answers FIFO's to stdout
556 response = anna::functions::encodeBase64(my_app.getOperatedServer()->getReactingAnswers()->asString("ANSWERS TO CLIENT"));
557 } else if (diameterJson_or_action == "rotate") {
558 my_app.getOperatedServer()->getReactingAnswers()->rotate(true);
560 } else if (diameterJson_or_action == "exhaust") {
561 my_app.getOperatedServer()->getReactingAnswers()->rotate(false);
562 response = "exhaust";
563 } else if (diameterJson_or_action == "clear") {
564 my_app.getOperatedServer()->getReactingAnswers()->clear();
566 } else if (diameterJson_or_action == "dump") {
567 my_app.getOperatedServer()->getReactingAnswers()->dump("programmed_answer");
579 bool EventOperation::test_id__description(std::string &response, unsigned int id, const std::string & description) {
581 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
582 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
585 testManager.getTestCase(id)->setDescription(description); // creates / reuses
588 catch(anna::RuntimeException &ex) {
590 response += "invalid ip-limit";
597 bool EventOperation::test_id__ip_limit(std::string &response, unsigned int id, int amount) {
599 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
600 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
603 testManager.getTestCase(id)->addIpLimit(amount); // creates / reuses
606 catch(anna::RuntimeException &ex) {
608 response += "invalid ip-limit";
615 bool EventOperation::test_id__timeout(std::string &response, unsigned int id, int msecs) {
617 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
618 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
621 anna::Millisecond timeout = my_app.checkTimeMeasure("Test case timeout", anna::functions::asString(msecs));
622 testManager.getTestCase(id)->addTimeout(timeout); // creates / reuses
625 catch(anna::RuntimeException &ex) {
627 response += "invalid timeout";
634 bool EventOperation::test_id__sendmsg2e_2c(std::string &response, unsigned int id, bool _2e_or_2c, const std::string & diameterJson, int stepNumber) {
636 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
637 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
640 std::string diameterXml = anna::json::functions::json2xml(diameterJson, success);
642 response += "json to xml failed, unable to load message !";
645 anna::diameter::codec::Message codecMsg; // auxiliary codec message
646 codecMsg.loadXMLString(diameterXml);
649 if (!codecMsg.isRequest() && (stepNumber == -1))
650 anna::Logger::warning("Step number has not been provided. Take into account that this answer message will be sent 'as is' and sequence information could be wrong at the remote peer", ANNA_FILE_LOCATION);
654 my_app.updateOperatedOriginHostWithMessage(codecMsg);
656 testManager.getTestCase(id)->addSendDiameterXml2e(codecMsg.code(), my_app.getOperatedHost(), stepNumber); // creates / reuses
658 testManager.getTestCase(id)->addSendDiameterXml2c(codecMsg.code(), my_app.getOperatedHost(), stepNumber); // creates / reuses
662 catch(anna::RuntimeException &ex) {
664 response += "failed";
671 bool EventOperation::test_id__delay(std::string &response, unsigned int id, int msecs) {
673 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
674 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
677 anna::Millisecond delay = ((msecs == 0 /* special case */) ? (anna::Millisecond)0 : my_app.checkTimeMeasure("Test case delay step", anna::functions::asString(msecs)));
678 testManager.getTestCase(id)->addDelay(delay); // creates / reuses
681 catch(anna::RuntimeException &ex) {
683 response += "invalid delay";
690 bool EventOperation::test_id__sh_command(std::string &response, unsigned int id, const std::string & script) {
692 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
693 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
696 testManager.getTestCase(id)->addCommand(script); // creates / reuses
699 catch(anna::RuntimeException &ex) {
701 response += "failed";
708 bool EventOperation::test_id__waitfefc_hex(std::string &response, unsigned int id, bool fe_or_fc, const std::string & hex, bool strict) {
710 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
711 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
713 // Get DataBlock from hex content:
714 anna::DataBlock db_aux(true);
715 std::string hexString = hex;
716 hexString.erase(std::remove(hexString.begin(), hexString.end(), ':'), hexString.end());
718 std::string msg = "Hex string (remove colons if exists): ";
720 anna::Logger::debug(msg, ANNA_FILE_LOCATION);
725 anna::functions::fromHexString(hexString, db_aux); // could launch exception
726 regexp = anna::functions::asHexString(db_aux);
728 catch(anna::RuntimeException &ex) {
730 response += "failed";
736 //// If request, we will ignore sequence data:
737 //if (anna::diameter::codec::functions::requestBit(db_aux))
738 regexp.replace (24, 16, "[0-9A-Fa-f]{16}");
740 regexp.insert(0, "^");
745 testManager.getTestCase(id)->addWaitDiameterRegexpHex(fe_or_fc, regexp);
748 catch(anna::RuntimeException &ex) {
750 response += "failed";
757 bool EventOperation::test_id__waitfefc_msg(std::string &response, unsigned int id, bool fe_or_fc, const std::string & diameterJson, bool strict) {
759 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
760 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
763 std::string diameterXml = anna::json::functions::json2xml(diameterJson, success);
765 response += "json to xml failed, unable to load message !";
770 anna::diameter::codec::Message codecMsg; // auxiliary codec message
771 codecMsg.loadXMLString(diameterXml);
772 std::string regexp = codecMsg.asXMLString(true /* normalization */);
774 // Now we must insert regular expressions in hop-by-hop, end-to-end and Origin-State-Id:
778 std::string::size_type pos, pos_1, pos_2;
780 pos = regexp.find("end-to-end-id=", 0u);
781 pos = regexp.find("\"", pos);
783 pos = regexp.find("\"", pos+1);
785 regexp.replace(pos_1 + 1, pos_2 - pos_1 - 1, "[0-9]+");
787 pos = regexp.find("hop-by-hop-id=", 0u);
788 pos = regexp.find("\"", pos);
790 pos = regexp.find("\"", pos+1);
792 regexp.replace(pos_1 + 1, pos_2 - pos_1 - 1, "[0-9]+");
794 // For this representation: <avp name="Origin-State-Id" data="1428633668"/>
795 //pos = regexp.find("Origin-State-Id", 0u);
796 //pos = regexp.find("\"", pos);
797 //pos = regexp.find("\"", pos+1);
799 //pos = regexp.find("\"", pos+1);
801 //regexp.replace(pos_1 + 1, pos_2 - pos_1 - 1, "[0-9]+");
802 // But we have this one: <avp data="1428633668" name="Origin-State-Id"/>
803 pos = regexp.find("Origin-State-Id", 0u);
804 pos = regexp.rfind("\"", pos);
805 pos = regexp.rfind("\"", pos-1);
806 pos = regexp.rfind("\"", pos-1);
808 pos = regexp.find("\"", pos+1);
810 regexp.replace(pos_1 + 1, pos_2 - pos_1 - 1, "[0-9]+");
812 //regexp.insert(0, "^");
816 testManager.getTestCase(id)->addWaitDiameterRegexpXml(fe_or_fc, regexp);
819 catch(anna::RuntimeException &ex) {
821 response += "failed";
828 bool EventOperation::test_id__waitfefc(std::string &response, unsigned int id, bool fe_or_fc,
829 const std::string & code,
830 const std::string & bitR,
831 const std::string & hopByHop,
832 const std::string & applicationId,
833 const std::string & sessionId,
834 const std::string & resultCode,
835 const std::string & msisdn,
836 const std::string & imsi,
837 const std::string & serviceContextId) {
839 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
840 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
842 try { // [code]|[bitR]|[hopByHop]|[applicationId]|[sessionId]|[resultCode]|[msisdn]|[imsi]|[serviceContextId]
843 testManager.getTestCase(id)->addWaitDiameter(fe_or_fc, code, bitR, hopByHop, applicationId, sessionId, resultCode, msisdn, imsi, serviceContextId);
846 catch(anna::RuntimeException &ex) {
848 response += "failed";
855 /////////////////////////
856 // Testcases execution //
857 /////////////////////////
858 bool EventOperation::test__ttps(std::string &response, int amount) {
860 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
861 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
863 bool success = testManager.configureTTPS(amount);
865 response = "Assigned new test launch rate to ";
866 response += anna::functions::asString(amount);
867 response += " events per second";
870 response += "unable to configure the test rate provided";
873 return success; // OK
876 bool EventOperation::test__next(std::string &response, int syncAmount) {
878 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
879 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
881 if (syncAmount < 1) {
882 response += "the parameter 'sync-amount' must be a positive integer value";
886 bool success = testManager.execTestCases(syncAmount);
888 response = (success ? "P" : "Not completely p" /* completed cycle and no repeats, rare case */);
889 response += "rocessed ";
890 response += anna::functions::asString(syncAmount);
891 response += ((syncAmount > 1) ? " test cases synchronously" : " test case");
896 bool EventOperation::test__ip_limit(std::string &response, int amount) {
898 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
899 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
902 testManager.setInProgressLimit(amount);
903 response = "New in-progress limit: ";
904 response += (amount != -1) ? anna::functions::asString(amount) : "<no limit>";
907 response = "In-progress limit amount: ";
908 int limit = testManager.getInProgressLimit();
909 response += (limit != -1) ? anna::functions::asString(limit) : "<no limit>";
910 response += "; currently there are ";
911 response += anna::functions::asString(testManager.getInProgressCount());
912 response += " test cases running";
918 bool EventOperation::test__goto(std::string &response, int id) {
920 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
921 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
923 bool success = testManager.gotoTestCase(id);
926 response = "Position updated for id provided (";
929 response += "cannot found test id (";
931 response += anna::functions::asString(id);
937 bool EventOperation::test__run(std::string &response, int id) {
939 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
940 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
942 bool success = testManager.runTestCase(id);
945 response = "Test executed for id provided (";
948 response += "cannot found test id (";
950 response += anna::functions::asString(id);
956 bool EventOperation::test__look(std::string &response, int id) {
958 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
959 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
961 anna::testing::TestCase *testCase = testManager.findTestCase(id);
964 response += "no current test case detected (testing started ?)";
967 response += "cannot found test id (";
968 response += anna::functions::asString(id);
976 response = anna::functions::encodeBase64(testCase->asXMLString());
978 response = testCase->asXMLString();
983 bool EventOperation::test__state(std::string &response, int id) {
985 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
986 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
988 anna::testing::TestCase *testCase = testManager.findTestCase(id);
991 response += "no current test case detected (testing started ?)";
994 response += "cannot found test id (";
995 response += anna::functions::asString(id);
1002 response = anna::testing::TestCase::asText(testCase->getState());
1003 return testCase->isSuccess();
1006 bool EventOperation::test__interact(std::string &response, int amount, unsigned int id) {
1008 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
1009 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
1012 response += "interactive amount must be -1 (to disable interactive mode) or a positive number.";
1016 anna::testing::TestCase *testCase = testManager.findTestCase(id);
1019 testCase->makeInteractive(false);
1020 response = "Interactive mode disabled";
1023 testCase->addInteractiveAmount(amount);
1024 response = "Added interactive amount of ";
1025 response += anna::functions::asString(amount);
1026 response += " units";
1027 if (amount == 0) response += " (0: freezing a non-interactive testcase, no effect on already interactive)";
1029 response += " for test case id ";
1030 response += anna::functions::asString(id);
1033 response += "cannot found test id (";
1034 response += anna::functions::asString(id);
1042 bool EventOperation::test__reset(std::string &response, bool soft_hard, int id) {
1044 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
1045 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
1047 anna::testing::TestCase *testCase = ((id != -1) ? testManager.findTestCase(id) : NULL);
1049 bool done = testCase->reset(!soft_hard);
1051 response += (soft_hard ? "soft":"hard");
1052 response += " reset for id ";
1053 response += anna::functions::asString(id);
1054 response += done ? ": done": ": not done";
1058 bool anyReset = testManager.resetPool(!soft_hard);
1059 response = (soft_hard ? "Soft":"Hard");
1060 response += " reset have been sent to all programmed tests: "; response += anyReset ? "some/all have been reset" : "nothing was reset";
1063 response += "cannot found test id (";
1064 response += anna::functions::asString(id);
1073 bool EventOperation::test__repeats(std::string &response, int amount) {
1075 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
1076 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
1078 if (amount < 0) amount = -1;
1079 testManager.setPoolRepeats(amount);
1080 std::string nolimit = (amount != -1) ? "":" [no limit]";
1081 response = anna::functions::asString("Pool repeats: %d%s (current cycle: %d)", amount, nolimit.c_str(), testManager.getPoolCycle());
1086 bool EventOperation::test__auto_reset(std::string &response, bool soft_hard) {
1088 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
1089 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
1091 testManager.setAutoResetHard(!soft_hard);
1092 response = anna::functions::asString("Auto-reset configured to '%s'", (soft_hard ? "soft":"hard"));
1097 bool EventOperation::test__initialized(std::string &response) {
1099 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
1100 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
1102 response = anna::functions::asString("%lu", testManager.getInitializedCount());
1107 bool EventOperation::test__finished(std::string &response) {
1109 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
1110 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
1112 response = anna::functions::asString("%lu", testManager.getFinishedCount());
1117 bool EventOperation::test__clear(std::string &response) {
1119 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
1120 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
1122 return testManager.clearPool(response);
1125 bool EventOperation::test__junit(std::string &response, const std::string & targetFile) {
1127 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
1128 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
1131 out.open(targetFile.c_str());
1133 if(out.is_open() == false) {
1134 response += "error opening '";
1135 response += targetFile;
1140 out << testManager.junitAsXMLString() << std::endl;
1143 response = "Junit report written on '";
1144 response += targetFile;
1150 bool EventOperation::test__summary_counts(std::string &response) {
1152 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
1153 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
1155 response = anna::functions::encodeBase64(testManager.summaryCounts());
1160 bool EventOperation::test__summary_states(std::string &response) {
1162 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
1163 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
1165 response = anna::functions::encodeBase64(testManager.summaryStates());
1170 bool EventOperation::test__summary(std::string &response) {
1172 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
1173 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
1175 response = anna::functions::encodeBase64(testManager.asXMLString());
1180 bool EventOperation::test__report(std::string &response, const std::string & state, bool enable) {
1182 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
1183 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
1185 std::string _state = state;
1187 if(_state == "initialized")
1188 testManager.setDumpInitializedReports(enable);
1189 else if(_state == "in-progress")
1190 testManager.setDumpInProgressReports(enable);
1191 else if(_state == "failed")
1192 testManager.setDumpFailedReports(enable);
1193 else if(_state == "success")
1194 testManager.setDumpSuccessReports(enable);
1195 else if(_state == "all") {
1197 testManager.setDumpAllReports(enable);
1199 else if(_state == "none") {
1202 testManager.setDumpAllReports(enable);
1205 response += "invalid state (allowed: initialized|in-progress|failed|success|[all]|none)";
1209 response = (enable ? "Report enabled " : "Report disabled ");
1210 response += "for tests in '";
1212 response += "' state";
1217 bool EventOperation::test__report_hex(std::string &response, bool enable) {
1219 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
1220 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
1222 testManager.setDumpHex(enable);
1223 response = (testManager.getDumpHex() ? "Report includes hexadecimal messages" : "Report excludes hexadecimal messages");
1228 bool EventOperation::test__dump_stdout(std::string &response, bool enable) {
1230 Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
1231 anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
1233 testManager.setDumpStdout(enable);
1234 response = (testManager.getDumpStdout() ? "Test manager dumps progress into stdout" : "Test manager does not dump progress into stdout");