Improvements from anna fork
[anna.git] / example / diameter / launcher / Launcher.cpp
index 1633e5c..2175263 100644 (file)
 #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 <Procedure.hpp>
 
 // Process
 #include <Launcher.hpp>
 #include <MyDiameterEngine.hpp>
-#include <anna/diameter.comm/OriginHost.hpp>
 #include <anna/testing/TestManager.hpp>
 #include <anna/testing/TestCase.hpp>
 
@@ -141,7 +142,6 @@ Launcher::Launcher() : anna::comm::Application("launcher", "DiameterLauncher", "
   //a_admlMinResolution = (anna::Millisecond)100;
   a_counterRecorderClock = NULL;
 
-  // a_originHosts.clear();
   a_workingNode = NULL;
 
   a_httpServerSocket = NULL;
@@ -302,8 +302,9 @@ void Launcher::servicesFromXML(const anna::xml::Node* servicesNode, bool eventOp
       burstLog = (*it)->getAttribute("burstLog", false /* no exception */); // (yes | no)
 
       // Basic checkings:
-      origin_hosts_it nodeIt = a_originHosts.find(originHost->getValue());
-      if (nodeIt != a_originHosts.end()) {
+      anna::diameter::comm::OriginHostManager &ohm = anna::diameter::comm::OriginHostManager::instantiate();
+      anna::diameter::comm::OriginHost *oh = ohm.getOriginHost(originHost->getValue());
+      if (oh) {
         std::string msg = "Already registered such Origin-Host: "; msg += originHost->getValue();
         throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
       }
@@ -416,7 +417,7 @@ void Launcher::servicesFromXML(const anna::xml::Node* servicesNode, bool eventOp
       if (eventOperation) commEngine->lazyInitialize();
 
       // Node and Codec Engine registration ///////////////////////////////////////////////////////
-      a_originHosts[originHost->getValue()] = a_workingNode;
+      ohm.registerOriginHost(originHost->getValue(), a_workingNode);
       /////////////////////////////////////////////////////////////////////////////////////////////
     }
   }
@@ -515,25 +516,25 @@ anna::Millisecond Launcher::checkTimeMeasure(const std::string &parameter, const
 bool Launcher::setWorkingNode(const std::string &name) throw() {
   bool result = false;
 
-  origin_hosts_it nodeIt = a_originHosts.find(name);
-  if (nodeIt == a_originHosts.end()) {
-    LOGWARNING(
-        std::string msg = "Unknown node with name '"; msg += name; msg += "'. Ignoring ...";
-    anna::Logger::warning(msg, ANNA_FILE_LOCATION);
-    );
-  }
-  else {
-    a_workingNode = const_cast<anna::diameter::comm::OriginHost*>(nodeIt->second);
+  anna::diameter::comm::OriginHostManager &ohm = anna::diameter::comm::OriginHostManager::instantiate();
+  anna::diameter::comm::OriginHost *oh = ohm.getOriginHost(name);
+
+  if (oh) {
+    a_workingNode = const_cast<anna::diameter::comm::OriginHost*>(oh);
     result = true;
   }
 
   return result;
 }
 
-anna::diameter::comm::OriginHost *Launcher::getOriginHost(const std::string &oh) const throw(anna::RuntimeException) {
-  origin_hosts_it it = a_originHosts.find(oh);
-  if (it != a_originHosts.end()) return it->second;
-  throw anna::RuntimeException(anna::functions::asString("There is no origin host registered as '%s' (set Origin-Host avp correctly or force a specific host with 'node' operation)", oh.c_str()), ANNA_FILE_LOCATION);
+anna::diameter::comm::OriginHost *Launcher::getOriginHost(const std::string &name) const throw(anna::RuntimeException) {
+  anna::diameter::comm::OriginHostManager &ohm = anna::diameter::comm::OriginHostManager::instantiate();
+  anna::diameter::comm::OriginHost *result = ohm.getOriginHost(name);
+
+  if (!result)
+  throw anna::RuntimeException(anna::functions::asString("There is no origin host registered as '%s' (set Origin-Host avp correctly or force a specific host with 'node' operation)", name.c_str()), ANNA_FILE_LOCATION);
+
+  return result;
 }
 
 anna::diameter::comm::OriginHost *Launcher::getOriginHost(const anna::diameter::codec::Message &message) const throw(anna::RuntimeException) {
@@ -541,6 +542,12 @@ anna::diameter::comm::OriginHost *Launcher::getOriginHost(const anna::diameter::
   return (getOriginHost(originHost));
 }
 
+bool Launcher::uniqueOriginHost() const throw() {
+  anna::diameter::comm::OriginHostManager &ohm = anna::diameter::comm::OriginHostManager::instantiate();
+  return (ohm.size() == 1);
+}
+
+
 void Launcher::updateOperatedOriginHostWithMessage(const anna::diameter::codec::Message &message) throw(anna::RuntimeException) {
   if (!a_operatedHost) // priority for working node by mean 'node' operation
     a_operatedHost = getOriginHost(message);
@@ -589,7 +596,14 @@ throw(anna::RuntimeException) {
 
   // Counters record procedure:
   const char *varname = "cntRecordPeriod";
-  anna::Millisecond cntRecordPeriod = (cl.exists(varname)) ? checkTimeMeasure(varname, cl.getValue(varname)) : (anna::Millisecond)300000;
+  anna::Millisecond cntRecordPeriod;
+  try {
+    cntRecordPeriod = (cl.exists(varname)) ? checkTimeMeasure(varname, cl.getValue(varname)) : (anna::Millisecond)300000;
+  }
+  catch(anna::RuntimeException &ex) {
+    if (cntRecordPeriod != 0) throw ex;
+  }
+
   if(cntRecordPeriod != 0) {
     a_counterRecorderClock = new MyCounterRecorderClock("Counters record procedure clock", cntRecordPeriod); // clock
     std::string cntDir = ".";
@@ -614,7 +628,7 @@ void Launcher::run()
 throw(anna::RuntimeException) {
   LOGMETHOD(anna::TraceMethod tm("Launcher", "run", ANNA_FILE_LOCATION));
   CommandLine& cl(anna::CommandLine::instantiate());
-  anna::diameter::stack::Engine &stackEngine = anna::diameter::stack::Engine::instantiate();
+  anna::diameter::stack::Engine::instantiate();
 
   // Start time:
   a_start_time.setNow();
@@ -779,7 +793,8 @@ throw(anna::RuntimeException) {
 
   // Start client connections //////////////////////////////////////////////////////////////////////////////////
   MyDiameterEntity *entity;
-  for (origin_hosts_it it = a_originHosts.begin(); it != a_originHosts.end(); it++) {
+  anna::diameter::comm::OriginHostManager &ohm = anna::diameter::comm::OriginHostManager::instantiate();
+  for (diameter::comm::origin_hosts_it it = ohm.begin(); it != ohm.end(); it++) {
     entity = (MyDiameterEntity *)(it->second->getEntity());
     if (entity) entity->bind();
   }
@@ -839,7 +854,8 @@ void Launcher::resetStatistics() throw() {
     a_workingNode->getCommEngine()->resetStatistics();
   }
   else {
-    for (origin_hosts_it it = a_originHosts.begin(); it != a_originHosts.end(); it++) {
+    anna::diameter::comm::OriginHostManager &ohm = anna::diameter::comm::OriginHostManager::instantiate();
+    for (diameter::comm::origin_hosts_it it = ohm.begin(); it != ohm.end(); it++) {
       it->second->getCommEngine()->resetStatistics();
     }
   }
@@ -851,6 +867,15 @@ void Launcher::resetCounters() throw() {
   anna::diameter::codec::OamModule::instantiate().resetCounters();
 }
 
+void Launcher::signalTerminate() throw(anna::RuntimeException) {
+  LOGMETHOD(anna::TraceMethod tm("Launcher", "signalTerminate", ANNA_FILE_LOCATION));
+
+  forceCountersRecord();
+
+  a_communicator->terminate ();
+  comm::Application::signalTerminate ();
+}
+
 void Launcher::signalUSR2() throw(anna::RuntimeException) {
 
   std::string inputFile = getSignalUSR2InputFile();
@@ -1204,7 +1229,17 @@ std::string Launcher::help() const throw() {
   result += "\n                                 values (Session-Id, Subscriber-Id, etc.).";
   result += "\n";
   result += "\n                           <command>: commands to be executed for the test id provided. Each command programmed";
-  result += "\n                                      constitutes a test case 'step', numbered from 1 to N.";
+  result += "\n                                      constitutes a test case 'step', numbered from 1 to N, with an exception for";
+  result += "\n                                      'description' which is used to describe the test case:";
+  result += "\n";
+  result += "\n                              description|<description>  Sets a test case description. Test cases by default are";
+  result += "\n                                                          constructed with description 'Testcase_<id>'.";
+  result += "\n";
+  result += "\n                              ip-limit[|amount]          In-progress limit of test cases controlled from this test.";
+  result += "\n                                                         No new test cases will be launched over this value (test";
+  result += "\n                                                         manager tick work will be ignored). Zero-value is equivalent";
+  result += "\n                                                         to stop the clock tick, -1 is used to specify 'no limit' which";
+  result += "\n                                                         is the default. For missing amount, value of 1 is applied.";
   result += "\n";
   result += "\n                              timeout|<msecs>            Sets an asynchronous timer to restrict the maximum timeout";
   result += "\n                                                          until last test step. Normally, this command is invoked";
@@ -1272,7 +1307,8 @@ std::string Launcher::help() const throw() {
   result += "\n                                                          source file (xml representation). Fix mode must be enabled to avoid";
   result += "\n                                                          unexpected matching behaviour. If you need a strict matching you";
   result += "\n                                                          must add parameter 'strict', if not, regexp is built ignoring sequence";
-  result += "\n                                                          information (hop-by-hop-id=\"[0-9]+\" end-to-end-id=\"[0-9]+\").";
+  result += "\n                                                          information (hop-by-hop-id=\"[0-9]+\" end-to-end-id=\"[0-9]+\") and";
+  result += "\n                                                          Origin-State-Id value.";
   result += "\n                                                          All LF codes will be internally removed when comparison is executed";
   result += "\n                                                          in order to ease xml content configuration.";
   result += "\n";
@@ -1416,10 +1452,10 @@ std::string Launcher::help() const throw() {
   result += "\n                                 next programmed test cases (1 by default). This event works regardless the timer tick";
   result += "\n                                 function, but it is normally used with the test manager tick stopped.";
   result += "\n";
-  result += "\n   test|ip-limit[|amount]        In-progress limit of test cases. No new test cases will be launched over this value";
-  result += "\n                                 (test Manager tick work will be ignored). Zero-value is equivalent to stop the clock.";
-  result += "\n                                 tick, -1 is used to specify 'no limit' which is the default. If missing amount, the";
-  result += "\n                                 limit and current amount of in-progress test cases will be shown.";
+  result += "\n   test|ip-limit[|amount]        In-progress limit of test cases established from global context. This value will be";
+  result += "\n                                 overwritten if used at test case level when the corresponding test step is executed.";
+  result += "\n                                 Anyway, the meaning is the same in both contexts. But now, when the amount is missing,";
+  result += "\n                                 the limit and current amount of in-progress test cases will be shown.";
   result += "\n";
   result += "\n   test|goto|<id>                Updates current test pointer position.";
   result += "\n";
@@ -1427,13 +1463,14 @@ std::string Launcher::help() const throw() {
   result += "\n                                 Test cases reports are not dumped on process context (too many information in general).";
   result += "\n                                 The report contains context information in every moment: this operation acts as a snapshot.";
   result += "\n";
-  result += "\n   test|interact|amount|id       Makes interactive a specific test case id. The amount is the margin of execution steps";
-  result += "\n                                 to be done. Normally, we will execute 'test|interact|0|<test case id>', which means that";
+  result += "\n   test|interact|amount[|id]     Makes interactive a specific test case id. The amount is the margin of execution steps";
+  result += "\n                                 to be done. Normally, we will execute 'test|interact|0[|<test case id>]', which means that";
   result += "\n                                 the test case is selected to be interactive, but no step is executed. Then you have to";
   result += "\n                                 interact with positive amounts (usually 1), executing the provided number of steps if";
   result += "\n                                 they are ready and fulfill the needed conditions. The value of 0, implies no execution";
   result += "\n                                 steps margin, which could be useful to 'freeze' a test in the middle of its execution.";
   result += "\n                                 You could also provide -1 to make it non-interactive resuming it from the current step.";
+  result += "\n                                 By default, current test case id is selected for interaction.";
   result += "\n";
   result += "\n   test|reset|<[soft]/hard>[|id] Reset the test case for id provided, all the tests when missing. It could be hard/soft:";
   result += "\n                                 - hard: you probably may need to stop the load rate before. This operation initializes";
@@ -1447,8 +1484,23 @@ std::string Launcher::help() const throw() {
   result += "\n                                 been done before. Test cases state & data will be reset (when achieved again), but general";
   result += "\n                                 statistics and counters will continue measuring until reset with 'collect' operation.";
   result += "\n";
+  result += "\n   test|auto-reset|<soft|hard>   When cycling, current test cases can be soft (default) or hard reset. If no timeout has";
+  result += "\n                                 been configured for the test case, hard reset could prevent stuck on the next cycle for";
+  result += "\n                                 those test cases still in progress.";
+  result += "\n";
+  result += "\n   test|initialized              Shows the number of initialized test cases. Zero-value means that everything was processed";
+  result += "                                   or not initiated yet.\n";
+  result += "\n";
+  result += "\n   test|finished                 Shows the number of finished (successful or failed) test cases.";
+  result += "\n";
   result += "\n   test|clear                    Clears all the programmed test cases and stop testing (if in progress).";
   result += "\n";
+  result += "\n   test|junit                    Shows the junit report in the moment of execution.";
+  result += "\n";
+  result += "\n   test|summary-counts           Test manager counts report. Counts by state and prints total verdict.";
+  result += "\n";
+  result += "\n   test|summary-states           Test manager states report.";
+  result += "\n";
   result += "\n   test|summary                  Test manager general report (number of test cases, counts by state, global configuration,";
   result += "\n                                 forced in-progress limitation, reports visibility, etc.). Be careful when you have reports";
   result += "\n                                 enabled because the programmed test cases dumps could be heavy (anyway you could enable the";
@@ -1471,6 +1523,8 @@ std::string Launcher::help() const throw() {
   result += "\n";
   result += "\n   test|report-hex[|[yes]|no]    Reports could include the diameter messages in hexadecimal format. Disabled by default.";
   result += "\n";
+  result += "\n   test|dump-stdout[|[yes]|no]   Test manager information is dumped into stdout.";
+  result += "\n";
   result += "\n";
   result += "\n------------------------------------------------------------------------------------- Dynamic procedure";
   result += "\n";
@@ -1592,7 +1646,7 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
     if (args == "" && op_size != 7)
       throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
     try {
-      p.execute(args, response_content, getWorkingNode());
+      p.execute(args, response_content);
     }
     catch(anna::RuntimeException &ex) {
       ex.trace();
@@ -1968,6 +2022,7 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
     // test|look[|id]                           Show programmed test case for id provided, current when missing ...
     // test|interact|amount|id                  Makes interactive a specific test case id. The amount is the margin of execution steps ...
     // test|reset|<[soft]/hard>[|id]            Reset the test case for id provided, all the tests when missing ...
+    // test|auto-reset|<soft|hard>              When cycling, current test cases can be soft (default) or hard reset ...
     // test|clear                               Clears all the programmed test cases.
     // test|summary                             Test manager general report (number of test cases, counts by state ...
 
@@ -2072,6 +2127,14 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
       testManager.setDumpHex((param2 == "yes"));
       opt_response_content += (testManager.getDumpHex() ? "report includes hexadecimal messages" : "report excludes hexadecimal messages");
     }
+    else if(param1 == "dump-stdout") {
+      if (numParams > 2)
+        throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
+
+      if(param2 == "") param2 = "yes";
+      testManager.setDumpStdout((param2 == "yes"));
+      opt_response_content += (testManager.getDumpHex() ? "test manager dumps progress into stdout" : "test manager does not dump progress into stdout");
+    }
     else if(param1 == "goto") {
       if (numParams > 2)
         throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
@@ -2110,14 +2173,14 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
       }
     }
     else if (param1 == "interact") {
-      if (numParams != 3)
+      if (numParams != 2)
         throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
 
       int amount = atoi(param2.c_str());
       if (amount < -1)
         throw anna::RuntimeException("Interactive amount must be -1 (to disable interactive mode) or a positive number.", ANNA_FILE_LOCATION);
 
-      int id = atoi(param3.c_str());
+      int id = ((param3 != "") ? atoi(param3.c_str()) : -1);
       anna::testing::TestCase *testCase = testManager.findTestCase(id);
       if (testCase) {
         if (amount == -1) {
@@ -2152,7 +2215,7 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
       anna::testing::TestCase *testCase = ((id != -1) ? testManager.findTestCase(id) : NULL);
 
       if (testCase) {
-        bool done = testCase->reset((param2 == "hard") ? true:false);
+        bool done = testCase->reset(param2 == "hard");
         opt_response_content = "test ";
         opt_response_content += param2;
         opt_response_content += " reset for id ";
@@ -2161,7 +2224,7 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
       }
       else {
         if (id == -1) {
-          bool anyReset = testManager.resetPool((param2 == "hard") ? true:false);
+          bool anyReset = testManager.resetPool(param2 == "hard");
           opt_response_content = param2; opt_response_content += " reset have been sent to all programmed tests: "; opt_response_content += anyReset ? "some/all have been reset" : "nothing was reset";
         }
         else {
@@ -2171,6 +2234,28 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
         }
       }
     }
+    else if(param1 == "auto-reset") {
+      if (numParams != 2)
+        throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
+
+      if (param2 != "soft" && param2 != "hard")
+        throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
+
+      testManager.setAutoResetHard(param2 == "hard");
+      opt_response_content += anna::functions::asString("Auto-reset configured to '%s'", param2.c_str());
+    }
+    else if(param1 == "initialized") {
+      if (numParams > 1)
+        throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
+
+      opt_response_content = anna::functions::asString("%lu", testManager.getInitializedCount());
+    }
+    else if(param1 == "finished") {
+      if (numParams > 1)
+        throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
+
+      opt_response_content = anna::functions::asString("%lu", testManager.getFinishedCount());
+    }
     else if(param1 == "clear") {
       if (numParams > 1)
         throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
@@ -2182,6 +2267,18 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
         opt_response_content = "there are not programmed test cases to be removed";
       }
     }
+    else if(param1 == "junit") {
+      response_content = testManager.junitAsXMLString();
+      return;
+    }
+    else if(param1 == "summary-counts") {
+      response_content = testManager.summaryCounts();
+      return;
+    }
+    else if(param1 == "summary-states") {
+      response_content = testManager.summaryStates();
+      return;
+    }
     else if(param1 == "summary") {
       response_content = testManager.asXMLString();
       return;
@@ -2193,6 +2290,8 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
 
       // PARAM: 1     2            3      4          5           6             7           8          9       10         11
       // test|<id>|<command>
+      //             description|<description>
+      //             ip-limit[|<iplimit>]
       //             timeout|    <msecs>
       //             sendxml2e|  <file>[|<step number>]
       //             sendxml2c|  <file>[|<step number>]
@@ -2204,7 +2303,19 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
       if(param2 == "") throw anna::RuntimeException("Missing command for test id operation", ANNA_FILE_LOCATION);
 
       // Commands:
-      if (param2 == "timeout") {
+      if (param2 == "description") {
+        if (numParams > 3)
+          throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
+        if(param3 == "") throw anna::RuntimeException("Missing description for test case", ANNA_FILE_LOCATION);
+        testManager.getTestCase(id)->setDescription(param3); // creates / reuses
+      }
+      else if (param2 == "ip-limit") {
+        if (numParams > 3)
+          throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
+        unsigned int limit = (param3 == "") ? 1 : atoi(param3.c_str());
+        testManager.getTestCase(id)->addIpLimit(limit); // creates / reuses
+      }
+      else if (param2 == "timeout") {
         if (numParams > 3)
           throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
         if(param3 == "") throw anna::RuntimeException("Missing milliseconds for 'timeout' command in test id operation", ANNA_FILE_LOCATION);
@@ -2225,9 +2336,9 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
         int stepNumber = ((param4 != "") ? atoi(param4.c_str()):-1);
 
         if (param2 == "sendxml2e")
-          testManager.getTestCase(id)->addSendxml2e(codecMsg.code(), getOperatedHost(), stepNumber); // creates / reuses
+          testManager.getTestCase(id)->addSendDiameterXml2e(codecMsg.code(), getOperatedHost(), stepNumber); // creates / reuses
         else
-          testManager.getTestCase(id)->addSendxml2c(codecMsg.code(), getOperatedHost(), stepNumber); // creates / reuses
+          testManager.getTestCase(id)->addSendDiameterXml2c(codecMsg.code(), getOperatedHost(), stepNumber); // creates / reuses
       }
       else if (param2 == "delay") {
         if (numParams > 3)
@@ -2241,7 +2352,7 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
           throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
         if (param3 != "" || param4 != "" || param5 != "" || param6 != "" || param7 != "" || param8 != "" || param9 != "" || param10 != "" || param11 != "") {
           bool fromEntity = (param2.substr(4,2) == "fe");
-          testManager.getTestCase(id)->addWait(fromEntity, param3, param4, param5, param6, param7, param8, param9, param10, param11);
+          testManager.getTestCase(id)->addWaitDiameter(fromEntity, param3, param4, param5, param6, param7, param8, param9, param10, param11);
         }
         else {
           throw anna::RuntimeException(anna::functions::asString("Missing condition for '%s' command in test id operation", param2.c_str()), ANNA_FILE_LOCATION);
@@ -2270,7 +2381,7 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
         }
 
         bool fromEntity = (param2.substr(4,2) == "fe");
-        testManager.getTestCase(id)->addWaitRegexpHex(fromEntity, regexp);
+        testManager.getTestCase(id)->addWaitDiameterRegexpHex(fromEntity, regexp);
       }
       else if ((param2 == "waitfe-xml")||(param2 == "waitfc-xml")) {
         if (numParams > 4)
@@ -2289,13 +2400,17 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
 /*
           std::string s_from = "hop-by-hop-id=\"[0-9]+\" end-to-end-id=\"[0-9]+\"";
           std::string s_to = s_from;
+          std::string s_from2 = "avp name=\"Origin-State-Id\" data=\"[0-9]+\"";
+          std::string s_to2 = s_from2;
 
           try {
             regexp = std::regex_replace (regexp, std::regex(s_from), s_to);
+            regexp = std::regex_replace (regexp, std::regex(s_from2), s_to2);
           }
           catch (const std::regex_error& e) {
             throw anna::RuntimeException(e.what(), ANNA_FILE_LOCATION);
           }
+
 */
           std::string::size_type pos, pos_1, pos_2;
 
@@ -2313,12 +2428,20 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
           pos_2 = pos;
           regexp.replace(pos_1 + 1, pos_2 - pos_1 - 1, "[0-9]+");
 
+          pos = regexp.find("Origin-State-Id", 0u);
+          pos = regexp.find("\"", pos);
+          pos = regexp.find("\"", 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 += "$";
         }
 
         bool fromEntity = (param2.substr(4,2) == "fe");
-        testManager.getTestCase(id)->addWaitRegexpXml(fromEntity, regexp);
+        testManager.getTestCase(id)->addWaitDiameterRegexpXml(fromEntity, regexp);
       }
       else if (param2 == "sh-command") {
         // Allow pipes in command:
@@ -2442,7 +2565,8 @@ throw() {
   result->createAttribute("InitialWorkingDirectory", a_initialWorkingDirectory);
   result->createAttribute("SecondsLifeTime", anna::time::functions::lapsedMilliseconds() / 1000);
   // Diameter:
-  for (origin_hosts_it it = a_originHosts.begin(); it != a_originHosts.end(); it++) {
+  anna::diameter::comm::OriginHostManager &ohm = anna::diameter::comm::OriginHostManager::instantiate();
+  for (diameter::comm::origin_hosts_it it = ohm.begin(); it != ohm.end(); it++) {
     it->second->asXML(result);
   }