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 <anna/diameter.comm/ApplicationMessageOamModule.hpp>
14 #include <anna/core/mt/Guard.hpp>
15 #include <anna/core/functions.hpp>
16 #include <anna/core/oam/CounterScope.hpp>
17 #include <anna/diameter/stack/Engine.hpp>
20 anna_assign_enum(anna::diameter::comm::ApplicationMessageOamModule::Counter) = { \
21 "Request_SentOK_AsClient", \
22 "Request_SentNOK_AsClient", \
23 "Answer_SentOK_AsClient", \
24 "Answer_SentNOK_AsClient", \
25 "Request_Received_AsClient", \
26 "Answer_Received_AsClient", \
27 "Answer_UnknownReceived_AsClient", \
29 "Request_SentOK_AsServer", \
30 "Request_SentNOK_AsServer", \
31 "Answer_SentOK_AsServer", \
32 "Answer_SentNOK_AsServer", \
33 "Request_Received_AsServer", \
34 "Answer_Received_AsServer", \
35 "Answer_UnknownReceived_AsServer", \
36 NULL /* list end indicator */
39 void anna::diameter::comm::ApplicationMessageOamModule::createStackCounterScope(int scopeId, unsigned int stackId) throw(anna::RuntimeException) {
41 initializeCounterScope(scopeId, anna::functions::asString("Application Message Events for stack id %lu", stackId));
43 // Better to be enabled by application in order to be more conscious of the native disabled nature of this special oam module
44 //if (!countersEnabled()) enableCounters();
45 //enableAlarms(); not yet implemented
47 a_stackMap[stackId] = scopeId;
50 void anna::diameter::comm::ApplicationMessageOamModule::count (int messageCode, int resultCode, unsigned int stackId, const int & type, const int & amount) throw(anna::RuntimeException) {
54 if(!countersEnabled()) {
57 std::string msg = "Count operation ignored over module '";
59 msg += "': counters are disabled";
60 anna::Logger::debug(msg, ANNA_FILE_LOCATION);
65 anna::Guard guard(a_mutex, "ApplicationMessageOamModule::count"); // counter scope switch
67 int scopeId = monoStackScopeId();
69 std::map<unsigned int /* stack id */, int /* scope id */>::const_iterator stackMap_it = a_stackMap.find(stackId);
71 if (stackMap_it == a_stackMap.end()) {
72 LOGDEBUG(anna::Logger::debug(anna::functions::asString("Unregistered stack id %lu", stackId), ANNA_FILE_LOCATION));
76 scopeId = stackMap_it->second;
79 // Select counter scope
80 setActiveCounterScope(scopeId);
82 // Build event id: <message code>_<result code>
83 std::string eventId = anna::functions::asString("%d_%d", messageCode, resultCode);
85 std::map<std::string /* event id */, int /* base offset */>::const_iterator eventMap_it = a_eventMap.find(eventId);
88 if (eventMap_it == a_eventMap.end()) {
89 int capacity = anna::oam::CounterScope::MaxCounter / getCounterTypes();
90 if (a_eventMap.size() > capacity) {
91 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));
94 baseOffset = getCounterTypes() * a_eventMap.size(); // N counter types for each message code / rc
95 a_eventMap[eventId] = baseOffset;
98 std::string counterNamePrefix = anna::functions::asString("ApplicationMessageCode_%d", messageCode); // default
99 anna::diameter::stack::Engine &stackEngine = anna::diameter::stack::Engine::instantiate();
100 const anna::diameter::stack::Dictionary *dictionary = stackEngine.getDictionary(stackId);
102 anna::diameter::CommandId cidR(messageCode, true /* request */);
103 anna::diameter::CommandId cidA(messageCode, false /* answer */);
104 const anna::diameter::stack::Command *commandR = dictionary->getCommand(cidR);
105 const anna::diameter::stack::Command *commandA = dictionary->getCommand(cidA);
106 if (commandR && commandA) {
107 std::string string1 = commandR->getName();
108 std::string string2 = commandA->getName();
109 std::string intersection; // non-standard names will be also intersected: XXR and XXA gives XX
110 std::set_intersection(string1.begin(), string1.end(), string2.begin(), string2.end(), std::back_inserter(intersection));
111 counterNamePrefix = intersection;
113 if (counterNamePrefix == "") counterNamePrefix = string1 + "#" + string2;
117 if (counterNamePrefix[counterNamePrefix.size() - 1] != '-') counterNamePrefix += "-";
118 std::string counterName;
120 for (int offset = 0; offset < getCounterTypes(); offset++) {
121 counterName = counterNamePrefix + getDefaultInternalCounterDescription(offset);
122 if (resultCode != -1) counterName += anna::functions::asString("-ResultCode_%d", resultCode);
123 registerCounter(baseOffset + offset, counterName, baseOffset + offset);
126 // Register only affected one:
127 int offset = baseOffset + type;
128 counterName = counterNamePrefix + getDefaultInternalCounterDescription(type);
129 if (resultCode != -1) counterName += anna::functions::asString("-ResultCode_%d", resultCode);
130 registerCounter(offset, counterName, offset);
134 baseOffset = eventMap_it->second;
138 Module::count(baseOffset + type, amount);