/**
Special OAM module which tracks a replica for a set of counter types for each different application message managed by the
- communication layer in a specific stack id. For example, if one process is managing CCR/A, RAR/A for Gx and AAR/A, RAR/A for Rx,
- then two counter scopes should be registered (one for Gx, another for Rx). Each scope will store counters sets for each diameter
- message. Having N counters within each scope (for example N=14), the total capacity is N/(number of counter types) different
- message codes:
+ communication layer and result code in case of answer, in a specific stack id. For example, if one process is managing CCR/A,
+ RAR/A for Gx and AAR/A, RAR/A for Rx, then two counter scopes should be registered (one for Gx, another for Rx). Each scope
+ will store counters sets for each diameter event (message and optionally result code description). Having N counters within
+ each scope (for example N=14), the total capacity is N/(number of counter types) different events:
<pre>
Scope for Gx:
Re-Auth-Request_Received_AsServer
Re-Auth-Answer_Received_AsServer
Re-Auth-Answer_UnknownReceived_AsServer
+
+ Note: all other combinations including the result code for answers
+ may be dynamically created.
+
</pre>
*/
class ApplicationMessageOamModule : public anna::oam::Module, public anna::Singleton <ApplicationMessageOamModule> {
- std::map<int /* message code */, int /* base offset */> a_messageMap;
+ std::map<std::string /* event id */, int /* base offset */> a_eventMap;
std::map<unsigned int /* stack id */, int /* scope id */> a_stackMap;
int a_counter_types;
void createStackCounterScope(int /* scope id */, unsigned int /* stack id */) throw(anna::RuntimeException);
// translate message code into offset and invoke parent class count method. The message applicationId will be used as stack id
- void count (int messageCode, unsigned int stackId, const int & type, const int & amount = 1) throw(anna::RuntimeException);
+ // resultCode shall be -1 for non-answers
+ void count (int messageCode, int resultCode, unsigned int stackId, const int & type, const int & amount = 1) throw(anna::RuntimeException);
// Number of different counter types for each message
int getCounterTypes() const throw() { return a_counter_types; }
+ // -1 if multistack
+ int monoStackScopeId() const throw() {
+ return ((a_stackMap.size() != 1) ? -1 : a_stackMap.begin()->second);
+ }
+
private:
// private constructor
a_stackMap[stackId] = scopeId;
}
-void anna::diameter::comm::ApplicationMessageOamModule::count (int messageCode, unsigned int stackId, const int & type, const int & amount) throw(anna::RuntimeException) {
+void anna::diameter::comm::ApplicationMessageOamModule::count (int messageCode, int resultCode, unsigned int stackId, const int & type, const int & amount) throw(anna::RuntimeException) {
// Optimization:
// Checkings
anna::Guard guard(a_mutex, "ApplicationMessageOamModule::count"); // counter scope switch
- std::map<unsigned int /* stack id */, int /* scope id */>::const_iterator stackMap_it = a_stackMap.find(stackId);
+ int scopeId = monoStackScopeId();
+ if (scopeId == -1) {
+ std::map<unsigned int /* stack id */, int /* scope id */>::const_iterator stackMap_it = a_stackMap.find(stackId);
- if (stackMap_it == a_stackMap.end()) {
- LOGDEBUG(anna::Logger::debug(anna::functions::asString("Unregistered stack id %lu", stackId), ANNA_FILE_LOCATION));
- return;
+ if (stackMap_it == a_stackMap.end()) {
+ LOGDEBUG(anna::Logger::debug(anna::functions::asString("Unregistered stack id %lu", stackId), ANNA_FILE_LOCATION));
+ return;
+ }
+
+ scopeId = stackMap_it->second;
}
// Select counter scope
- setActiveCounterScope(stackMap_it->second);
-
- std::map<int /* message code */, int /* base offset */>::const_iterator messageMap_it = a_messageMap.find(messageCode);
- int baseOffset = messageMap_it->second;
+ setActiveCounterScope(scopeId);
+
+ // Build event id: <message code>_<result code>
+ std::string eventId = anna::functions::asString("%d%d", messageCode, resultCode);
+
+ std::map<std::string /* event id */, int /* base offset */>::const_iterator eventMap_it = a_eventMap.find(eventId);
+ int baseOffset = eventMap_it->second;
- if (messageMap_it == a_messageMap.end()) {
+ if (eventMap_it == a_eventMap.end()) {
int capacity = anna::oam::CounterScope::MaxCounter / getCounterTypes();
- if (a_messageMap.size() > capacity) {
+ if (a_eventMap.size() > capacity) {
LOGDEBUG(anna::Logger::debug(anna::functions::asString("No more holes to register new application message counters in the scope (up to %d message codes)", capacity), ANNA_FILE_LOCATION));
return;
}
- baseOffset = getCounterTypes() * a_messageMap.size(); // N counter types for each message code
- a_messageMap[messageCode] = baseOffset;
+ baseOffset = getCounterTypes() * a_eventMap.size(); // N counter types for each message code
+ a_eventMap[eventId] = baseOffset;
// Counter name:
std::string counterNamePrefix = anna::functions::asString("ApplicationMessageCode_%d", messageCode); // default
}
if (counterNamePrefix[counterNamePrefix.size() - 1] != '-') counterNamePrefix += "-";
- for (int offset = 0; offset < getCounterTypes(); offset++)
- registerCounter(baseOffset + offset, counterNamePrefix + getDefaultInternalCounterDescription(offset), baseOffset + offset);
+ std::string counterName;
+ // register only count event:
+ //for (int offset = 0; offset < getCounterTypes(); offset++) {
+ int offset = baseOffset + type;
+ counterName = counterNamePrefix + getDefaultInternalCounterDescription(offset);
+ if (resultCode != -1) counterName += anna::functions::asString("-ResultCode_%d", resultCode);
+ registerCounter(baseOffset + offset, counterName, baseOffset + offset);
+ //}
}
// Count
try {
// application message counters
- ApplicationMessageOamModule::instantiate().count(cid.first, anna::diameter::codec::functions::getApplicationId(db), ApplicationMessageOamModule::Counter::Request_Received_AsClient);
+ ApplicationMessageOamModule::instantiate().count(cid.first, -1 /* no result code */, anna::diameter::codec::functions::getApplicationId(db), ApplicationMessageOamModule::Counter::Request_Received_AsClient);
eventRequest(db);
} catch(anna::RuntimeException& ex) {
oamModule.activateAlarm(OamModule::Alarm::AnswerReceivedOnClientSessionUnknown);
// application message counters
- ApplicationMessageOamModule::instantiate().count(cid.first, anna::diameter::codec::functions::getApplicationId(db), ApplicationMessageOamModule::Counter::Answer_UnknownReceived_AsClient);
+ ApplicationMessageOamModule::instantiate().count(cid.first, resultCode, anna::diameter::codec::functions::getApplicationId(db), ApplicationMessageOamModule::Counter::Answer_UnknownReceived_AsClient);
eventUnknownResponse(db);
string msg(asString());
// application message counters
if(cid != helpers::base::COMMANDID__Capabilities_Exchange_Answer)
- ApplicationMessageOamModule::instantiate().count(cid.first, anna::diameter::codec::functions::getApplicationId(db), ApplicationMessageOamModule::Counter::Answer_Received_AsClient);
+ ApplicationMessageOamModule::instantiate().count(cid.first, resultCode, anna::diameter::codec::functions::getApplicationId(db), ApplicationMessageOamModule::Counter::Answer_Received_AsClient);
eventResponse(*response);
} catch(anna::RuntimeException& ex) {
else if(cid == helpers::base::COMMANDID__Disconnect_Peer_Answer) oamModule.count(OamModule::Counter::DPASentOK);
// Application messages:
else {
- appMsgOamModule.count(cid.first, aid, isRequest ? ApplicationMessageOamModule::Counter::Request_SentOK_AsClient : ApplicationMessageOamModule::Counter::Answer_SentOK_AsClient);
+ appMsgOamModule.count(cid.first, -1 /* no result code */, aid, isRequest ? ApplicationMessageOamModule::Counter::Request_SentOK_AsClient : ApplicationMessageOamModule::Counter::Answer_SentOK_AsClient);
}
} else {
// Main counters:
else if(cid == helpers::base::COMMANDID__Disconnect_Peer_Answer) oamModule.count(OamModule::Counter::DPASentNOK);
// Application messages:
else {
- appMsgOamModule.count(cid.first, aid, isRequest ? ApplicationMessageOamModule::Counter::Request_SentNOK_AsClient : ApplicationMessageOamModule::Counter::Answer_SentNOK_AsClient);
+ appMsgOamModule.count(cid.first, -1 /* no result code */, aid, isRequest ? ApplicationMessageOamModule::Counter::Request_SentNOK_AsClient : ApplicationMessageOamModule::Counter::Answer_SentNOK_AsClient);
}
}
}
try {
// application message counters
- ApplicationMessageOamModule::instantiate().count(cid.first, anna::diameter::codec::functions::getApplicationId(db), ApplicationMessageOamModule::Counter::Request_Received_AsServer);
+ ApplicationMessageOamModule::instantiate().count(cid.first, -1 /* no result code */, anna::diameter::codec::functions::getApplicationId(db), ApplicationMessageOamModule::Counter::Request_Received_AsServer);
eventRequest(db);
} catch(anna::RuntimeException& ex) {
oamModule.activateAlarm(OamModule::Alarm::AnswerReceivedOnServerSessionUnknown);
// application message counters
- ApplicationMessageOamModule::instantiate().count(cid.first, anna::diameter::codec::functions::getApplicationId(db), ApplicationMessageOamModule::Counter::Answer_UnknownReceived_AsServer);
+ ApplicationMessageOamModule::instantiate().count(cid.first, resultCode, anna::diameter::codec::functions::getApplicationId(db), ApplicationMessageOamModule::Counter::Answer_UnknownReceived_AsServer);
eventUnknownResponse(db);
diameter::codec::functions::setEndToEnd((anna::DataBlock&)db, response->getRequest()->getRequestEndToEnd());
// application message counters
- ApplicationMessageOamModule::instantiate().count(cid.first, anna::diameter::codec::functions::getApplicationId(db), ApplicationMessageOamModule::Counter::Answer_Received_AsServer);
+ ApplicationMessageOamModule::instantiate().count(cid.first, resultCode, anna::diameter::codec::functions::getApplicationId(db), ApplicationMessageOamModule::Counter::Answer_Received_AsServer);
eventResponse(*response);
else if(cid == helpers::base::COMMANDID__Disconnect_Peer_Request) oamModule.count(OamModule::Counter::DPRSentOK);
// Application messages:
else {
- appMsgOamModule.count(cid.first, aid, isRequest ? ApplicationMessageOamModule::Counter::Request_SentOK_AsServer : ApplicationMessageOamModule::Counter::Answer_SentOK_AsServer);
+ appMsgOamModule.count(cid.first, -1 /* no result code */, aid, isRequest ? ApplicationMessageOamModule::Counter::Request_SentOK_AsServer : ApplicationMessageOamModule::Counter::Answer_SentOK_AsServer);
}
} else {
// Main counters:
else if(cid == helpers::base::COMMANDID__Disconnect_Peer_Request) oamModule.count(OamModule::Counter::DPRSentNOK);
// Application messages:
else {
- appMsgOamModule.count(cid.first, aid, isRequest ? ApplicationMessageOamModule::Counter::Request_SentNOK_AsServer : ApplicationMessageOamModule::Counter::Answer_SentNOK_AsServer);
+ appMsgOamModule.count(cid.first, -1 /* no result code */, aid, isRequest ? ApplicationMessageOamModule::Counter::Request_SentNOK_AsServer : ApplicationMessageOamModule::Counter::Answer_SentNOK_AsServer);
}
}
}