#include <TestCase.hpp>
-#define SIGUSR2_TASKS_INPUT_FILENAME "./sigusr2.tasks.input"
-#define SIGUSR2_TASKS_OUTPUT_FILENAME "./sigusr2.tasks.output"
+#define SIGUSR2_TASKS_INPUT_FILENAME "./sigusr2.in"
+#define SIGUSR2_TASKS_OUTPUT_FILENAME "./sigusr2.out"
<!--\n\
Stack record\n\
\n\
- id: Normally the id corresponds to the Application-Id for which the dictionary provided is designed.\n\
+ id: Normally the id corresponds to the Application-Id for which the dictionary provided is designed\n\
(in multistack applications, it shall be mandatory respect such association to know the stack used\n\
for processed messages).\n\
dictionary: Path to the dictionary file\n\
-->\n\
\n\
<!ELEMENT node EMPTY>\n\
-<!ATTLIST node originRealm CDATA #REQUIRED applicationId CDATA #REQUIRED originHost CDATA #IMPLIED cer CDATA #IMPLIED dwr CDATA #IMPLIED allowedInactivityTime CDATA #IMPLIED tcpConnectDelay CDATA #IMPLIED answersTimeout CDATA #IMPLIED ceaTimeout CDATA #IMPLIED watchdogPeriod CDATA #IMPLIED entity CDATA #IMPLIED entityServerSessions CDATA #IMPLIED diameterServer CDATA #IMPLIED diameterServerSessions CDATA #IMPLIED balance (yes | no) #IMPLIED sessionBasedModelsClientSocketSelection (SessionIdLowPart | SessionIdHighPart | SessionIdOptionalPart | RoundRobin) #IMPLIED retries CDATA #IMPLIED log CDATA #IMPLIED splitLog (yes | no) #IMPLIED detailedLog (yes | no) #IMPLIED dumpLog (yes | no) #IMPLIED burstLog (yes | no) #IMPLIED>\n\
+<!ATTLIST node originRealm CDATA #REQUIRED originHost CDATA #IMPLIED cer CDATA #IMPLIED dwr CDATA #IMPLIED allowedInactivityTime CDATA #IMPLIED tcpConnectDelay CDATA #IMPLIED answersTimeout CDATA #IMPLIED ceaTimeout CDATA #IMPLIED watchdogPeriod CDATA #IMPLIED entity CDATA #IMPLIED entityServerSessions CDATA #IMPLIED diameterServer CDATA #IMPLIED diameterServerSessions CDATA #IMPLIED balance (yes | no) #IMPLIED sessionBasedModelsClientSocketSelection (SessionIdLowPart | SessionIdHighPart | SessionIdOptionalPart | RoundRobin) #IMPLIED retries CDATA #IMPLIED log CDATA #IMPLIED splitLog (yes | no) #IMPLIED detailedLog (yes | no) #IMPLIED dumpLog (yes | no) #IMPLIED burstLog (yes | no) #IMPLIED>\n\
<!--\n\
Node record\n\
\n\
originRealm: Node identifier (Origin-Realm name).\n\
- applicationId: The Application-Id provided must exists as a registered 'stack id'.\n\
originHost: Diameter application host name (system name). If missing, process sets o.s. hostname\n\
Note that if you have two or more realms, the names must be different.\n\
cer: User defined CER path file to be encoded to establish diameter connections.\n\
Launcher::Launcher() : anna::comm::Application("launcher", "DiameterLauncher", "1.1"), a_communicator(NULL) {
a_codecEngine = new anna::diameter::codec::Engine("MyCodecEngine");
+ a_baseProtocolDictionary = NULL;
a_timeEngine = NULL;
a_counterRecorder = NULL;
a_admlMinResolution = 2 * anna::timex::Engine::minResolution; // 2*10 = 20 ms; 1000/20 = 50 ticks per second;
//<!ATTLIST stack id CDATA #REQUIRED dictionary CDATA #REQUIRED>
const anna::xml::Attribute *id, *dictionary;
- // <!ATTLIST node originRealm CDATA #REQUIRED applicationId CDATA #REQUIRED originHost CDATA #IMPLIED cer CDATA #IMPLIED dwr CDATA #IMPLIED allowedInactivityTime CDATA #IMPLIED tcpConnectDelay CDATA #IMPLIED answersTimeout CDATA #IMPLIED ceaTimeout CDATA #IMPLIED watchdogPeriod CDATA #IMPLIED entity CDATA #IMPLIED entityServerSessions CDATA #IMPLIED diameterServer CDATA #IMPLIED diameterServerSessions CDATA #IMPLIED balance (yes | no) #IMPLIED sessionBasedModelsClientSocketSelection (SessionIdLowPart | SessionIdHighPart | SessionIdOptionalPart | RoundRobin) #IMPLIED retries CDATA #IMPLIED log CDATA #IMPLIED splitLog (yes | no) #IMPLIED detailedLog (yes | no) #IMPLIED dumpLog (yes | no) #IMPLIED burstLog (yes | no) #IMPLIED>
- const anna::xml::Attribute *originRealm, *appId, *originHost, *cer, *dwr, *allowedInactivityTime, *tcpConnectDelay,
+ // <!ATTLIST node originRealm CDATA #REQUIRED originHost CDATA #IMPLIED cer CDATA #IMPLIED dwr CDATA #IMPLIED allowedInactivityTime CDATA #IMPLIED tcpConnectDelay CDATA #IMPLIED answersTimeout CDATA #IMPLIED ceaTimeout CDATA #IMPLIED watchdogPeriod CDATA #IMPLIED entity CDATA #IMPLIED entityServerSessions CDATA #IMPLIED diameterServer CDATA #IMPLIED diameterServerSessions CDATA #IMPLIED balance (yes | no) #IMPLIED sessionBasedModelsClientSocketSelection (SessionIdLowPart | SessionIdHighPart | SessionIdOptionalPart | RoundRobin) #IMPLIED retries CDATA #IMPLIED log CDATA #IMPLIED splitLog (yes | no) #IMPLIED detailedLog (yes | no) #IMPLIED dumpLog (yes | no) #IMPLIED burstLog (yes | no) #IMPLIED>
+ const anna::xml::Attribute *originRealm, *originHost, *cer, *dwr, *allowedInactivityTime, *tcpConnectDelay,
*answersTimeout, *ceaTimeout, *watchdogPeriod, *entity, *entityServerSessions,
*diameterServer, *diameterServerSessions, *balance, *sessionBasedModelsClientSocketSelection,
*retries, *log, *splitLog, *detailedLog, *dumpLog, *burstLog;
anna::diameter::comm::ApplicationMessageOamModule & appMsgOamModule = anna::diameter::comm::ApplicationMessageOamModule::instantiate();
appMsgOamModule.enableCounters(); // this special module is disabled by default (the only)
static int scope_id = 3;
+ bool id_0_registered = false;
+ unsigned int id_value;
for(anna::xml::Node::const_child_iterator it = servicesNode->child_begin(); it != servicesNode->child_end(); it++) {
std::string nodeName = (*it)->getName();
// Input data:
id = (*it)->getAttribute("id");
dictionary = (*it)->getAttribute("dictionary");
+ id_value = id->getIntegerValue();
try {
- d = stackEngine.createDictionary(id->getIntegerValue(), dictionary->getValue());
+ d = stackEngine.createDictionary(id_value, dictionary->getValue());
getCodecEngine()->setDictionary(d);
// OAM module for counters:
- appMsgOamModule.createStackCounterScope(scope_id, id->getIntegerValue() /* application-id */);
+ appMsgOamModule.createStackCounterScope(scope_id, id_value /* application-id */);
scope_id++;
} catch(anna::RuntimeException &ex) {
//_exit(ex.asString());
throw ex;
}
+
+ if (id_value == 0)
+ id_0_registered = true;
+ a_baseProtocolDictionary = d;
}
}
// Show loaded stacks:
std::cout << "Stacks currently loaded:" << std::endl;
- std::cout << anna::functions::tab(stackEngine.asString(false /* light */));
- std::cout << std::endl;
+ std::cout << anna::functions::tab(stackEngine.asString(false /* light */)) << std::endl;
// Codec engine adjustments:
// Auto stack selection based on Application-ID:
bool multistack = (stackEngine.stack_size() > 1);
- if (multistack) getCodecEngine()->selectStackWithApplicationId(true);
+ if (multistack) {
+ getCodecEngine()->selectStackWithApplicationId(true);
+ // In multistack, id = 0 MUST be registered:
+ if (!id_0_registered)
+ throw anna::RuntimeException("In multistack applications is mandatory register a stack id = 0 using a dictionary which contains the needed elements to build base protocol messages (CER/A, DWR/A, DPR/A, STR/A, etc.)", ANNA_FILE_LOCATION);
+ }
+ else {
+ a_baseProtocolDictionary = d;
+ }
for(anna::xml::Node::const_child_iterator it = servicesNode->child_begin(); it != servicesNode->child_end(); it++) {
std::string nodeName = (*it)->getName();
if(nodeName == "node") {
// Input data:
originRealm = (*it)->getAttribute("originRealm");
- appId = (*it)->getAttribute("applicationId");
originHost = (*it)->getAttribute("originHost", false /* no exception */);
cer = (*it)->getAttribute("cer", false /* no exception */);
dwr = (*it)->getAttribute("dwr", false /* no exception */);
burstLog = (*it)->getAttribute("burstLog", false /* no exception */); // (yes | no)
// Basic checkings:
- if (stackEngine.getDictionary(appId->getIntegerValue()) == NULL) {
- std::string msg = "Cannot found a registered stack id with the value of applicationId provided: "; msg += appId->getValue();
- throw anna::RuntimeException(msg, ANNA_FILE_LOCATION);
- }
realm_nodes_it nodeIt = a_nodes.find(originRealm->getValue());
if (nodeIt != a_nodes.end()) {
std::string msg = "Already registered node name (Origin-Realm): "; msg += originRealm->getValue();
}
// Create new Node instance /////////////////////////////////////////////////////////////////
- a_workingNode = new RealmNode(originRealm->getValue(), appId->getIntegerValue(), a_codecEngine);
+ a_workingNode = new RealmNode(originRealm->getValue(), a_codecEngine, a_baseProtocolDictionary);
MyDiameterEngine *commEngine = a_workingNode->getMyDiameterEngine();
/////////////////////////////////////////////////////////////////////////////////////////////
msg += "')";
anna::Logger::notice(msg, ANNA_FILE_LOCATION);
);
+
// Operation:
std::string line;
std::string response_content;
ex.trace();
}
- out_file << response_content;
+ out_file << response_content << "\n";
}
in_file.close();
result += "\n";
result += "\nStart the launcher process without arguments in order to see all the startup configuration";
result += "\n posibilities, many of which could be modified on the air through the management interface";
- result += "\n (we will talk later about this great feature). Some of the more common parameters are:";
+ result += "\n (we will talk later about this great feature). There is only one mandatory parameter which";
+ result += "\n is the services definition: --services <services xml file>. You must follow the dtd schema";
+ result += "\n to build a valid services xml file. Some basic examples are:";
+ result += "\n";
+ result += "\nClient configuration:";
+ result += "\n";
+ result += "\n<services>";
+ result += "\n <!-- Stacks -->";
+ result += "\n <stack id=\"0\" dictionary=\"dictionary.xml\"/>";
result += "\n";
- result += "\nAs mandatory, the stacks enabled given through the applicationId and the xml dictionary:";
- result += "\n --stacks <appid1,dictionary1#appid2,dictionary2#...#appidN,dictionaryN>";
+ result += "\n <!-- Nodes -->";
+ result += "\n <node originRealm=\"ADML-client\" entity=\"localhost:3868\"/>";
+ result += "\n</services>";
result += "\n";
- result += "\nActing as a diameter server (accepting i.e. 10 connections), you would have:";
- result += "\n --diameterServer localhost:3868 --diameterServerSessions 10 --entityServerSessions 0";
+ result += "\nServer configuration:";
result += "\n";
- result += "\nActing as a diameter client (launching i.e. 10 connections to each entity server), you would have:";
- result += "\n --entity 192.168.12.11:3868,192.168.12.21:3868 --entityServerSessions 10 --diameterServerSessions 0";
+ result += "\n<services>";
+ result += "\n <!-- Stacks -->";
+ result += "\n <stack id=\"0\" dictionary=\"dictionary.xml\"/>";
+ result += "\n";
+ result += "\n <!-- Nodes -->";
+ result += "\n <node originRealm=\"ADML-server\" diameterServer=\"localhost:3868\"/>";
+ result += "\n</services>";
result += "\n";
result += "\nIf you act as a proxy or a translation agent, you need to combine both former setups, and probably";
result += "\n will need to program the answers to be replied through the operations interface. To balance the";
result += "\n traffic at your client side you shall use '--balance' and '--sessionBasedModelsClientSocketSelection'";
- result += "\n arguments in order to define the balancing behaviour.";
+ result += "\n arguments in order to define the balancing behaviour. To make hybrid setups you only must mix the realms:";
result += "\n";
- result += "\nThe process builds automatically CER and DWR messages as a client, but you could specify your own";
- result += "\n customized ones using '--cer <xml message file>' and '--dwr <xml message file>'.";
- result += "\nThe process builds automatically CEA and DWA messages as a server, but you could program your own";
- result += "\n customized ones using operations interface.";
+ result += "\nClient and server configuration:";
+ result += "\n";
+ result += "\n<services>";
+ result += "\n <!-- Stacks -->";
+ result += "\n <stack id=\"16777236\" dictionary=\"dictionary_Rx.xml\"/>";
+ result += "\n <stack id=\"16777238\" dictionary=\"dictionary_Gx.xml\"/>";
+ result += "\n <stack id=\"0\" dictionary=\"dictionary_base.xml\"/>";
result += "\n";
+ result += "\n <!-- Nodes -->";
+ result += "\n <node originRealm=\"ADML-Rx-client\" entity=\"localhost:3868\" cer=\"cer_Rx.xml\"/>";
+ result += "\n <node originRealm=\"ADML-Gx-client\" entity=\"localhost:3868\" cer=\"cer_Gx.xml\"/>";
+ result += "\n</services>";
+ result += "\n";
+ result += "\n";
+ result += "\nThe process builds automatically CER and DWR messages as a client, but you could specify your own";
+ result += "\n as shown in the hybrid former example. Note that the base protocol stack must be registered because";
+ result += "\n the configuration corresponds to a multistack process which change the stack using the application-id";
+ result += "\n processed (0 in the case of base protocol messages: CER, CEA, DWR, DWA, DPR, DPA).";
result += "\n";
result += "\nDYNAMIC OPERATIONS";
result += "\n------------------";
result += "\n";
result += "\n--------------------------------------------------------------------------------------- General purpose";
result += "\n";
- result += "\nhelp This help. Startup information-level traces also dump this help.";
+ result += "\nhelp This help.";
result += "\n";
result += "\n---------------------------------------------------------------------------------------- Node selection";
result += "\n";
result += "\nnode[|<name>] Select current working node by mean the registered name.";
result += "\n All the subsequent operations will be referred to this node.";
- result += "\n Without argument, the current node is dumped on stdout.";
+ result += "\n Without argument, the current node information is retrieved.";
result += "\n";
result += "\n------------------------------------------------------------------------------------ Parsing operations";
result += "\n";
result += "\n interface.";
result += "\n";
result += "\n";
+
return result;
}
void Launcher::eventOperation(const std::string &operation, std::string &response_content) throw(anna::RuntimeException) {
LOGMETHOD(anna::TraceMethod tm("Launcher", "eventOperation", ANNA_FILE_LOCATION));
+ if (operation == "") return; // ignore
+
CommandLine& cl(anna::CommandLine::instantiate());
TestManager &testManager = TestManager::instantiate();
LOGDEBUG(anna::Logger::debug(operation, ANNA_FILE_LOCATION));
// Default response:
response_content = "Operation processed with exception (see traces): ";
response_content += operation;
- response_content += "\n";
- std::string result_msg = "";
- anna::DataBlock db_aux(true);
+ std::string opt_response_content = ""; // aditional response content
+ anna::DataBlock db_aux(true);
///////////////////////////////////////////////////////////////////
// Simple operations without arguments:
// Help:
if(operation == "help") {
- std::string s_help = help();
- std::cout << s_help << std::endl;
- LOGINFORMATION(anna::Logger::information(s_help, ANNA_FILE_LOCATION));
- response_content = "Help dumped on stdout and information-level traces\n";
+ response_content = help();
return;
}
if(operation == "collect") {
resetCounters();
resetStatistics();
- response_content = "All process counters & statistic information have been reset\n";
+ response_content = "All process counters & statistic information have been reset";
return;
}
// Counters dump on demand:
if(operation == "forceCountersRecord") {
forceCountersRecord();
- response_content = "Current counters have been dump to disk\n";
+ response_content = "Current counters have been dump to disk";
return;
}
if(opType == "context") {
std::string contextFile = ((numParams == 1) ? param1 : anna::functions::asString("/var/tmp/anna.context.%05d", getPid()));
writeContext(contextFile);
- response_content = anna::functions::asString("Context dumped on file '%s'\n", contextFile.c_str());
+ response_content = anna::functions::asString("Context dumped on file '%s'", contextFile.c_str());
return;
}
}
catch(anna::RuntimeException &ex) {
ex.trace();
- response_content = anna::functions::asString("Loaded services from file '%s' with some problems (ignored ones)\n", servicesFile.c_str());
+ response_content = anna::functions::asString("Loaded services from file '%s' with some problems (ignored ones)", servicesFile.c_str());
return;
}
- response_content = anna::functions::asString("Loaded services from file '%s'\n", servicesFile.c_str());
+ response_content = anna::functions::asString("Loaded services from file '%s'", servicesFile.c_str());
return;
}
// Realm switch:
if(opType == "node") {
if (param1 != "") {
- if (setWorkingNode(param1)) response_content = anna::functions::asString("Current node is now '%s'\n", param1.c_str());
+ if (setWorkingNode(param1)) response_content = anna::functions::asString("Current node is now '%s'", param1.c_str());
}
else {
- std::cout << getWorkingNode()->asXMLString() << std::endl;
+ response_content = getWorkingNode()->asXMLString();
}
return;
}
if(opType == "show") commEngine->findClientSession(key)->show();
- if(opType == "hidden") result_msg = commEngine->findClientSession(key)->hidden() ? "true" : "false";
+ if(opType == "hidden") opt_response_content = commEngine->findClientSession(key)->hidden() ? "true" : "false";
- if(opType == "shown") result_msg = commEngine->findClientSession(key)->shown() ? "true" : "false";
+ if(opType == "shown") opt_response_content = commEngine->findClientSession(key)->shown() ? "true" : "false";
} else {
std::string address;
int port;
if(opType == "show") commEngine->findServer(address, port)->show();
- if(opType == "hidden") result_msg = commEngine->findServer(address, port)->hidden() ? "true" : "false";
+ if(opType == "hidden") opt_response_content = commEngine->findServer(address, port)->hidden() ? "true" : "false";
- if(opType == "shown") result_msg = commEngine->findServer(address, port)->shown() ? "true" : "false";
+ if(opType == "shown") opt_response_content = commEngine->findServer(address, port)->shown() ? "true" : "false";
}
} else {
if(opType == "hide") entity->hide();
if(opType == "show") entity->show();
- if(opType == "hidden") result_msg = entity->hidden() ? "true" : "false";
+ if(opType == "hidden") opt_response_content = entity->hidden() ? "true" : "false";
- if(opType == "shown") result_msg = entity->shown() ? "true" : "false";
+ if(opType == "shown") opt_response_content = entity->shown() ? "true" : "false";
}
} else if((opType == "sendxml") || (opType == "sendxml2e") || (opType == "sendhex") || (opType == "sendhex2e")) {
if(!entity) throw anna::RuntimeException("No entity configured to send the message", ANNA_FILE_LOCATION);
// burst|look|<order> Show programmed burst message for order provided, current when missing.
if(param1 == "clear") {
- result_msg = "removed ";
- result_msg += anna::functions::asString(getWorkingNode()->clearBurst());
- result_msg += " elements";
+ opt_response_content = "removed ";
+ opt_response_content += anna::functions::asString(getWorkingNode()->clearBurst());
+ opt_response_content += " elements";
} else if(param1 == "load") {
if(param2 == "") throw anna::RuntimeException("Missing xml path file for burst load operation", ANNA_FILE_LOCATION);
try { codecMsg.valid(); } catch(anna::RuntimeException &ex) { ex.trace(); } // at least we need to see validation errors although it will continue loading (see validation mode configured in launcher)
int position = getWorkingNode()->loadBurstMessage(codecMsg.code());
- result_msg = "loaded '";
- result_msg += param2;
- result_msg += "' file into burst list position ";
- result_msg += anna::functions::asString(position);
+ opt_response_content = "loaded '";
+ opt_response_content += param2;
+ opt_response_content += "' file into burst list position ";
+ opt_response_content += anna::functions::asString(position);
} else if(param1 == "start") {
if(param2 == "") throw anna::RuntimeException("Missing initial load for burst start operation", ANNA_FILE_LOCATION);
int processed = getWorkingNode()->startBurst(initialLoad);
if(processed > 0) {
- result_msg = "initial load completed for ";
- result_msg += anna::functions::entriesAsString(processed, "message");
+ opt_response_content = "initial load completed for ";
+ opt_response_content += anna::functions::entriesAsString(processed, "message");
}
} else if(param1 == "push") {
if(param2 == "") throw anna::RuntimeException("Missing load amount for burst push operation", ANNA_FILE_LOCATION);
int pushed = getWorkingNode()->pushBurst(atoi(param2.c_str()));
if(pushed > 0) {
- result_msg = "pushed ";
- result_msg += anna::functions::entriesAsString(pushed, "message");
+ opt_response_content = "pushed ";
+ opt_response_content += anna::functions::entriesAsString(pushed, "message");
}
} else if(param1 == "pop") {
if(param2 == "") throw anna::RuntimeException("Missing amount for burst pop operation", ANNA_FILE_LOCATION);
int popped = getWorkingNode()->popBurst(releaseLoad);
if(popped > 0) {
- result_msg = "burst popped for ";
- result_msg += anna::functions::entriesAsString(popped, "message");
+ opt_response_content = "burst popped for ";
+ opt_response_content += anna::functions::entriesAsString(popped, "message");
}
} else if(param1 == "stop") {
int left = getWorkingNode()->stopBurst();
if(left != -1) {
- result_msg += anna::functions::entriesAsString(left, "message");
- result_msg += " left to the end of the cycle";
+ opt_response_content += anna::functions::entriesAsString(left, "message");
+ opt_response_content += " left to the end of the cycle";
}
} else if(param1 == "repeat") {
if(param2 == "") param2 = "yes";
bool repeat = (param2 == "yes");
getWorkingNode()->repeatBurst(repeat);
- result_msg += (repeat ? "repeat enabled" : "repeat disabled");
+ opt_response_content += (repeat ? "repeat enabled" : "repeat disabled");
} else if(param1 == "send") {
if(param2 == "") throw anna::RuntimeException("Missing amount for burst send operation", ANNA_FILE_LOCATION);
int sent = getWorkingNode()->sendBurst(atoi(param2.c_str()));
if(sent > 0) {
- result_msg = "sent ";
- result_msg += anna::functions::entriesAsString(sent, "message");
+ opt_response_content = "sent ";
+ opt_response_content += anna::functions::entriesAsString(sent, "message");
}
} else if(param1 == "goto") {
if(param2 == "") throw anna::RuntimeException("Missing order position for burst goto operation", ANNA_FILE_LOCATION);
- result_msg = getWorkingNode()->gotoBurst(atoi(param2.c_str()));
+ opt_response_content = getWorkingNode()->gotoBurst(atoi(param2.c_str()));
} else if(param1 == "look") {
int order = ((param2 != "") ? atoi(param2.c_str()) : -1);
- result_msg = "\n\n";
- result_msg += getWorkingNode()->lookBurst(order);
+ opt_response_content = "\n\n";
+ opt_response_content += getWorkingNode()->lookBurst(order);
} else {
throw anna::RuntimeException("Wrong body content format on HTTP Request for 'burst' operation (unexpected action parameter). See help", ANNA_FILE_LOCATION);
}
bool success = ((param2 != "") ? testManager.configureTTPS(atoi(param2.c_str())) : false);
if (success) {
- result_msg = "assigned new test launch rate to ";
- result_msg += anna::functions::asString(atoi(param2.c_str()));
- result_msg += " events per second";
+ opt_response_content = "assigned new test launch rate to ";
+ opt_response_content += anna::functions::asString(atoi(param2.c_str()));
+ opt_response_content += " events per second";
}
else {
- result_msg += "unable to configure the test rate provided";
+ opt_response_content += "unable to configure the test rate provided";
}
}
else if(param1 == "ip-limit") {
if (param2 != "") {
limit = atoi(param2.c_str());
testManager.setInProgressLimit(limit);
- result_msg = "new in-progress limit: ";
- result_msg += (limit != UINT_MAX) ? anna::functions::asString(limit) : "<no limit>";
+ opt_response_content = "new in-progress limit: ";
+ opt_response_content += (limit != UINT_MAX) ? anna::functions::asString(limit) : "<no limit>";
}
else {
- result_msg = "in-progress limit amount: ";
+ opt_response_content = "in-progress limit amount: ";
limit = testManager.getInProgressLimit();
- result_msg += (limit != UINT_MAX) ? anna::functions::asString(limit) : "<no limit>";
- result_msg += "; currently there are ";
- result_msg += anna::functions::asString(testManager.getInProgressCount());
- result_msg += " test cases running";
+ opt_response_content += (limit != UINT_MAX) ? anna::functions::asString(limit) : "<no limit>";
+ opt_response_content += "; currently there are ";
+ opt_response_content += anna::functions::asString(testManager.getInProgressCount());
+ opt_response_content += " test cases running";
}
}
else if(param1 == "repeat") {
if(param2 == "") param2 = "yes";
testManager.setPoolRepeat((param2 == "yes"));
- result_msg += (testManager.getPoolRepeat() ? "repeat enabled" : "repeat disabled");
+ opt_response_content += (testManager.getPoolRepeat() ? "repeat enabled" : "repeat disabled");
}
else if(param1 == "report") {
if (numParams > 2)
if(param2 == "") param2 = "yes";
testManager.setDumpReports((param2 == "yes"));
- result_msg += (testManager.getDumpReports() ? "report enabled" : "report disabled");
+ opt_response_content += (testManager.getDumpReports() ? "report enabled" : "report disabled");
}
else if(param1 == "goto") {
if (numParams > 2)
if(param2 == "") throw anna::RuntimeException("Missing id for test goto operation", ANNA_FILE_LOCATION);
int id = atoi(param2.c_str());
if (testManager.gotoTestCase(id)) {
- result_msg = "position updated for id provided (";
+ opt_response_content = "position updated for id provided (";
}
else {
- result_msg = "cannot found test id (";
+ opt_response_content = "cannot found test id (";
}
- result_msg += anna::functions::asString(id);
- result_msg += ")";
+ opt_response_content += anna::functions::asString(id);
+ opt_response_content += ")";
}
else if(param1 == "look") {
if (numParams > 2)
TestCase *testCase = testManager.findTestCase(id);
if (testCase) {
- result_msg = "\n\n";
- result_msg += testCase->asXMLString();
+ response_content = testCase->asXMLString();
+ return;
}
else {
if (id == -1) {
- result_msg = "no current test case detected (testing started ?)";
+ opt_response_content = "no current test case detected (testing started ?)";
}
else {
- result_msg = "cannot found test id (";
- result_msg += anna::functions::asString(id);
- result_msg += ")";
+ opt_response_content = "cannot found test id (";
+ opt_response_content += anna::functions::asString(id);
+ opt_response_content += ")";
}
}
}
if (testCase) {
bool done = testCase->reset((param2 == "hard") ? true:false);
- result_msg = "test ";
- result_msg += param2;
- result_msg += " reset for id ";
- result_msg += anna::functions::asString(id);
- result_msg += done ? ": done": ": not done";
+ opt_response_content = "test ";
+ opt_response_content += param2;
+ opt_response_content += " reset for id ";
+ opt_response_content += anna::functions::asString(id);
+ opt_response_content += done ? ": done": ": not done";
}
else {
if (id == -1) {
bool anyReset = testManager.resetPool((param2 == "hard") ? true:false);
- result_msg = "reset have been sent to all programmed tests: "; result_msg += anyReset ? "some/all was actually reset" : "nothing was reset";
+ opt_response_content = "reset have been sent to all programmed tests: "; opt_response_content += anyReset ? "some/all was actually reset" : "nothing was reset";
}
else {
- result_msg = "cannot found test id (";
- result_msg += anna::functions::asString(id);
- result_msg += ")";
+ opt_response_content = "cannot found test id (";
+ opt_response_content += anna::functions::asString(id);
+ opt_response_content += ")";
}
}
}
throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
if (testManager.clearPool()) {
- result_msg = "all the programmed test cases have been dropped";
+ opt_response_content = "all the programmed test cases have been dropped";
}
else {
- result_msg = "there are not programmed test cases to be removed";
+ opt_response_content = "there are not programmed test cases to be removed";
}
}
else {
else {
throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
}
-
- result_msg = "new step added to test id ";
- result_msg += anna::functions::asString(id);
}
} else if((opType == "sendxml2c") || (opType == "sendhex2c")) {
}
} else if(opType == "loadxml") {
codecMsg.loadXML(param1);
- std::string xmlString = codecMsg.asXMLString();
- std::cout << xmlString << std::endl;
+ response_content = codecMsg.asXMLString();
+ return;
} else if(opType == "diameterServerSessions") {
int diameterServerSessions = atoi(param1.c_str());
throw anna::RuntimeException("Operation not applicable (no own diameter server has been configured)", ANNA_FILE_LOCATION);
if(param1 == "") { // programmed answers FIFO's to stdout
- std::cout << localServer->getReactingAnswers()->asString("ANSWERS TO CLIENT") << std::endl;
- response_content = "Programmed answers dumped on stdout\n";
+ response_content = localServer->getReactingAnswers()->asString("ANSWERS TO CLIENT");
return;
} else if (param1 == "rotate") {
localServer->getReactingAnswers()->rotate(true);
throw anna::RuntimeException("Operation not applicable (no diameter entity has been configured)", ANNA_FILE_LOCATION);
if(param1 == "") { // programmed answers FIFO's to stdout
- std::cout << entity->getReactingAnswers()->asString("ANSWERS TO ENTITY") << std::endl;
- response_content = "Programmed answers dumped on stdout\n";
+ response_content = entity->getReactingAnswers()->asString("ANSWERS TO ENTITY");
return;
} else if (param1 == "rotate") {
entity->getReactingAnswers()->rotate(true);
}
// HTTP response
- response_content = "Operation correctly processed: "; response_content += operation; response_content += " => ";
- response_content += result_msg;
+ response_content = "Operation correctly processed: "; response_content += operation;
+ if (opt_response_content != "") {
+ response_content += " => ";
+ response_content += opt_response_content;
+ }
}
anna::xml::Node* Launcher::asXML(anna::xml::Node* parent) const