Fix local server for multiple applications
[anna.git] / example / diameter / launcher / EventOperation.cpp
index 8d8a97d..cab0e83 100644 (file)
 // Process
 #include <EventOperation.hpp>
 #include <Launcher.hpp>
+#include <Procedure.hpp>
+#include <MyDiameterEngine.hpp>
+#include <MyLocalServer.hpp>
+#include <anna/testing/TestManager.hpp>
 
-// Project
-#include <anna/diameter.comm/OriginHost.hpp>
-
-
-//// Standard
-//#include <sstream>      // std::istringstream
-//#include <iostream>     // std::cout
+// Standard
 #include <fstream>
-//#include <math.h> // ceil
-//#include <climits>
 #include <unistd.h> // chdir
-//#include <stdio.h>
-//
-//// Project
+
+// Project
+#include <anna/diameter.comm/OriginHost.hpp>
 #include <anna/json/functions.hpp>
 #include <anna/diameter/codec/Message.hpp>
-//#include <anna/timex/Engine.hpp>
-//#include <anna/statistics/Engine.hpp>
-//#include <anna/diameter/codec/functions.hpp>
-//#include <anna/diameter/codec/Engine.hpp>
-//#include <anna/diameter/codec/EngineManager.hpp>
-//#include <anna/http/Transport.hpp>
-//#include <anna/diameter/stack/Engine.hpp>
 #include <anna/diameter/helpers/base/functions.hpp>
 #include <anna/time/functions.hpp>
 #include <anna/core/functions.hpp>
-//#include <anna/diameter.comm/ApplicationMessageOamModule.hpp>
-//#include <anna/testing/defines.hpp>
 #include <anna/xml/xml.hpp>
-//#include <anna/diameter.comm/OriginHost.hpp>
-//#include <anna/diameter.comm/OriginHostManager.hpp>
 #include <anna/diameter.comm/Message.hpp>
-//
-//// Process
-//#include <Launcher.hpp>
-//#include <Procedure.hpp>
-//#include <EventOperation.hpp>
-#include <MyDiameterEngine.hpp>
-#include <MyLocalServer.hpp>
-#include <anna/testing/TestManager.hpp>
-//#include <anna/testing/TestCase.hpp>
 
 
 /////////////////////
@@ -381,7 +357,7 @@ bool EventOperation::sendmsg_hex_2e(std::string &response, const std::string & d
   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() : "<null client session>"; // shouldn't happen
+    std::string detail = usedClientSession ? usedClientSession->asString() : "[null client session]"; // shouldn't happen
     my_app.getOperatedHost()->writeLogFile(codecMsg, (success ? "sent2e" : "send2eError"), detail);
   }
 
@@ -446,7 +422,7 @@ bool EventOperation::sendmsg_hex_2c(std::string &response, const std::string & d
   // Detailed log:
   if(my_app.getOperatedHost()->logEnabled()) {
     anna::diameter::comm::ServerSession *usedServerSession = my_app.getOperatedServer()->getLastUsedResource();
-    std::string detail = usedServerSession ? usedServerSession->asString() : "<null server session>"; // shouldn't happen
+    std::string detail = usedServerSession ? usedServerSession->asString() : "[null server session]"; // shouldn't happen
     my_app.getOperatedHost()->writeLogFile(codecMsg, (success ? "sent2c" : "send2cError"), detail);
   }
 
@@ -489,23 +465,23 @@ bool EventOperation::answermsg_action_2e(std::string &response, const std::strin
     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);
+    my_app.getOperatedHost()->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"));
+      response = anna::functions::encodeBase64(my_app.getOperatedHost()->getReactingAnswers()->asString("ANSWERS TO ENTITY"));
     } else if (diameterJson_or_action == "rotate") {
-      my_app.getOperatedEntity()->getReactingAnswers()->rotate(true);
+      my_app.getOperatedHost()->getReactingAnswers()->rotate(true);
       response = "rotate";
     } else if (diameterJson_or_action == "exhaust") {
-      my_app.getOperatedEntity()->getReactingAnswers()->rotate(false);
+      my_app.getOperatedHost()->getReactingAnswers()->rotate(false);
       response = "exhaust";
     } else if (diameterJson_or_action == "clear") {
-      my_app.getOperatedEntity()->getReactingAnswers()->clear();
+      my_app.getOperatedHost()->getReactingAnswers()->clear();
       response = "clear";
     } else if (diameterJson_or_action == "dump") {
-      my_app.getOperatedEntity()->getReactingAnswers()->dump("programmed_answer");
+      my_app.getOperatedHost()->getReactingAnswers()->dump("programmed_answer");
       response = "dump";
     }
   }
@@ -547,24 +523,24 @@ bool EventOperation::answermsg_action_2c(std::string &response, const std::strin
 
     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);
+    my_app.getOperatedHost()->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"));
+      response = anna::functions::encodeBase64(my_app.getOperatedHost()->getReactingAnswers()->asString("ANSWERS TO CLIENT"));
     } else if (diameterJson_or_action == "rotate") {
-      my_app.getOperatedServer()->getReactingAnswers()->rotate(true);
+      my_app.getOperatedHost()->getReactingAnswers()->rotate(true);
       response = "rotate";
     } else if (diameterJson_or_action == "exhaust") {
-      my_app.getOperatedServer()->getReactingAnswers()->rotate(false);
+      my_app.getOperatedHost()->getReactingAnswers()->rotate(false);
       response = "exhaust";
     } else if (diameterJson_or_action == "clear") {
-      my_app.getOperatedServer()->getReactingAnswers()->clear();
+      my_app.getOperatedHost()->getReactingAnswers()->clear();
       response = "clear";
     } else if (diameterJson_or_action == "dump") {
-      my_app.getOperatedServer()->getReactingAnswers()->dump("programmed_answer");
+      my_app.getOperatedHost()->getReactingAnswers()->dump("programmed_answer");
       response = "dump";
     }
   }
@@ -582,8 +558,9 @@ bool EventOperation::test_id__description(std::string &response, unsigned int id
   anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
 
   try {
-    testManager.getTestCase(id)->setDescription(description); // creates / reuses
-    response = "Done";
+    anna::testing::TestCase *tc = testManager.getTestCase(id); // creates / reuses
+    tc->setDescription(description);
+    response = std::to_string(tc->getId());
   }
   catch(anna::RuntimeException &ex) {
     ex.trace();
@@ -600,8 +577,9 @@ bool EventOperation::test_id__ip_limit(std::string &response, unsigned int id, i
   anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
 
   try {
-    testManager.getTestCase(id)->addIpLimit(amount); // creates / reuses
-    response = "Done";
+    anna::testing::TestCase *tc = testManager.getTestCase(id); // creates / reuses
+    tc->addIpLimit(amount);
+    response = std::to_string(tc->getId());
   }
   catch(anna::RuntimeException &ex) {
     ex.trace();
@@ -619,8 +597,9 @@ bool EventOperation::test_id__timeout(std::string &response, unsigned int id, in
 
   try {
     anna::Millisecond timeout = my_app.checkTimeMeasure("Test case timeout", anna::functions::asString(msecs));
-    testManager.getTestCase(id)->addTimeout(timeout); // creates / reuses
-    response = "Done";
+    anna::testing::TestCase *tc = testManager.getTestCase(id); // creates / reuses
+    tc->addTimeout(timeout);
+    response = std::to_string(tc->getId());
   }
   catch(anna::RuntimeException &ex) {
     ex.trace();
@@ -651,13 +630,14 @@ bool EventOperation::test_id__sendmsg2e_2c(std::string &response, unsigned int i
   );
 
   try {
+    anna::testing::TestCase *tc = testManager.getTestCase(id); // creates / reuses
     my_app.updateOperatedOriginHostWithMessage(codecMsg);
     if (_2e_or_2c)
-      testManager.getTestCase(id)->addSendDiameterXml2e(codecMsg.code(), my_app.getOperatedHost(), stepNumber); // creates / reuses
+      tc->addSendDiameterXml2e(codecMsg.code(), my_app.getOperatedHost(), stepNumber);
     else
-      testManager.getTestCase(id)->addSendDiameterXml2c(codecMsg.code(), my_app.getOperatedHost(), stepNumber); // creates / reuses
+      tc->addSendDiameterXml2c(codecMsg.code(), my_app.getOperatedHost(), stepNumber);
 
-    response = "Done";
+    response = std::to_string(tc->getId());
   }
   catch(anna::RuntimeException &ex) {
     ex.trace();
@@ -674,9 +654,10 @@ bool EventOperation::test_id__delay(std::string &response, unsigned int id, int
   anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
 
   try {
+    anna::testing::TestCase *tc = testManager.getTestCase(id); // creates / reuses
     anna::Millisecond delay = ((msecs == 0 /* special case */) ? (anna::Millisecond)0 : my_app.checkTimeMeasure("Test case delay step", anna::functions::asString(msecs)));
-    testManager.getTestCase(id)->addDelay(delay); // creates / reuses
-    response = "Done";
+    tc->addDelay(delay); // creates / reuses
+    response = std::to_string(tc->getId());
   }
   catch(anna::RuntimeException &ex) {
     ex.trace();
@@ -693,8 +674,9 @@ bool EventOperation::test_id__sh_command(std::string &response, unsigned int id,
   anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
 
   try {
-    testManager.getTestCase(id)->addCommand(script); // creates / reuses
-    response = "Done";
+    anna::testing::TestCase *tc = testManager.getTestCase(id); // creates / reuses
+    tc->addCommand(script); // creates / reuses
+    response = std::to_string(tc->getId());
   }
   catch(anna::RuntimeException &ex) {
     ex.trace();
@@ -742,8 +724,9 @@ bool EventOperation::test_id__waitfefc_hex(std::string &response, unsigned int i
   }
 
   try {
-    testManager.getTestCase(id)->addWaitDiameterRegexpHex(fe_or_fc, regexp);
-    response = "Done";
+    anna::testing::TestCase *tc = testManager.getTestCase(id); // creates / reuses
+    tc->addWaitDiameterRegexpHex(fe_or_fc, regexp);
+    response = std::to_string(tc->getId());
   }
   catch(anna::RuntimeException &ex) {
     ex.trace();
@@ -778,18 +761,22 @@ bool EventOperation::test_id__waitfefc_msg(std::string &response, unsigned int i
       std::string::size_type pos, pos_1, pos_2;
 
       pos = regexp.find("end-to-end-id=", 0u);
-      pos = regexp.find("\"", pos);
-      pos_1 = pos;
-      pos = regexp.find("\"", pos+1);
-      pos_2 = pos;
-      regexp.replace(pos_1 + 1, pos_2 - pos_1 - 1, "[0-9]+");
+      if (pos != std::string::npos) {
+        pos = regexp.find("\"", pos);
+        pos_1 = pos;
+        pos = regexp.find("\"", pos+1);
+        pos_2 = pos;
+        regexp.replace(pos_1 + 1, pos_2 - pos_1 - 1, "[0-9]+");
+      }
 
       pos = regexp.find("hop-by-hop-id=", 0u);
-      pos = regexp.find("\"", pos);
-      pos_1 = pos;
-      pos = regexp.find("\"", pos+1);
-      pos_2 = pos;
-      regexp.replace(pos_1 + 1, pos_2 - pos_1 - 1, "[0-9]+");
+      if (pos != std::string::npos) {
+        pos = regexp.find("\"", pos);
+        pos_1 = pos;
+        pos = regexp.find("\"", pos+1);
+        pos_2 = pos;
+        regexp.replace(pos_1 + 1, pos_2 - pos_1 - 1, "[0-9]+");
+      }
 
       // For this representation: <avp name="Origin-State-Id" data="1428633668"/>
       //pos = regexp.find("Origin-State-Id", 0u);
@@ -801,20 +788,23 @@ bool EventOperation::test_id__waitfefc_msg(std::string &response, unsigned int i
       //regexp.replace(pos_1 + 1, pos_2 - pos_1 - 1, "[0-9]+");
       // But we have this one: <avp data="1428633668" name="Origin-State-Id"/>
       pos = regexp.find("Origin-State-Id", 0u);
-      pos = regexp.rfind("\"", pos);
-      pos = regexp.rfind("\"", pos-1);
-      pos = regexp.rfind("\"", pos-1);
-      pos_1 = pos;
-      pos = regexp.find("\"", pos+1);
-      pos_2 = pos;
-      regexp.replace(pos_1 + 1, pos_2 - pos_1 - 1, "[0-9]+");
+      if (pos != std::string::npos) {
+        pos = regexp.rfind("\"", pos);
+        pos = regexp.rfind("\"", pos-1);
+        pos = regexp.rfind("\"", pos-1);
+        pos_1 = pos;
+        pos = regexp.find("\"", pos+1);
+        pos_2 = pos;
+        regexp.replace(pos_1 + 1, pos_2 - pos_1 - 1, "[0-9]+");
+      }
 
       //regexp.insert(0, "^");
       //regexp += "$";
     }
 
-    testManager.getTestCase(id)->addWaitDiameterRegexpXml(fe_or_fc, regexp);
-    response = "Done";
+    anna::testing::TestCase *tc = testManager.getTestCase(id); // creates / reuses
+    tc->addWaitDiameterRegexpXml(fe_or_fc, regexp);
+    response = std::to_string(tc->getId());
   }
   catch(anna::RuntimeException &ex) {
     ex.trace();
@@ -840,8 +830,9 @@ bool EventOperation::test_id__waitfefc(std::string &response, unsigned int id, b
   anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
 
   try { // [code]|[bitR]|[hopByHop]|[applicationId]|[sessionId]|[resultCode]|[msisdn]|[imsi]|[serviceContextId]
-    testManager.getTestCase(id)->addWaitDiameter(fe_or_fc, code, bitR, hopByHop, applicationId, sessionId, resultCode, msisdn, imsi, serviceContextId);
-    response = "Done";
+    anna::testing::TestCase *tc = testManager.getTestCase(id); // creates / reuses
+    tc->addWaitDiameter(fe_or_fc, code, bitR, hopByHop, applicationId, sessionId, resultCode, msisdn, imsi, serviceContextId);
+    response = std::to_string(tc->getId());
   }
   catch(anna::RuntimeException &ex) {
     ex.trace();
@@ -901,12 +892,12 @@ bool EventOperation::test__ip_limit(std::string &response, int amount) {
   if (amount > -2) {
     testManager.setInProgressLimit(amount);
     response = "New in-progress limit: ";
-    response += (amount != -1) ? anna::functions::asString(amount) : "<no limit>";
+    response += (amount != -1) ? anna::functions::asString(amount) : "[no limit]";
   }
   else {
     response = "In-progress limit amount: ";
     int limit = testManager.getInProgressLimit();
-    response += (limit != -1) ? anna::functions::asString(limit) : "<no limit>";
+    response += (limit != -1) ? anna::functions::asString(limit) : "[no limit]";
     response += "; currently there are ";
     response += anna::functions::asString(testManager.getInProgressCount());
     response += " test cases running";
@@ -1114,12 +1105,23 @@ bool EventOperation::test__finished(std::string &response) {
   return true; // OK
 }
 
-bool EventOperation::test__clear(std::string &response) {
+bool EventOperation::test__clear(std::string &response, int id) {
 
   Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
   anna::testing::TestManager &testManager = anna::testing::TestManager::instantiate();
 
-  return testManager.clearPool(response);
+  if (id == -1) {
+     return testManager.clearPool(response);
+  }
+
+  if (!testManager.findTestCase(id)) {
+      response += "cannot found test id (";
+      response += anna::functions::asString(id);
+      response += ")";
+      return false;
+  }
+
+  return testManager.clearTestCase(response, id);
 }
 
 bool EventOperation::test__junit(std::string &response, const std::string & targetFile) {
@@ -1236,3 +1238,21 @@ bool EventOperation::test__dump_stdout(std::string &response, bool enable) {
   return true; // OK
 }
 
+bool EventOperation::test__dynamic(std::string &response, const nlohmann::json &arguments) {
+
+  Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
+
+  Procedure p(&my_app);
+  try {
+    p.execute(arguments, response);
+  }
+  catch(anna::RuntimeException &ex) {
+    ex.trace();
+    response += ex.asString();
+    return false;
+  }
+
+  return true; // OK
+}
+
+