6f0bba0d899882916e5bfd1b82ae91abe8ce4b70
[anna.git] / source / testing / TestCondition.cpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
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 //
7
8
9 // Standard
10 #include <algorithm>
11
12 // Project
13 #include <anna/testing/TestDiameterCondition.hpp>
14
15 #include <anna/xml/Node.hpp>
16 #include <anna/xml/Compiler.hpp>
17 #include <anna/diameter/defines.hpp>
18 #include <anna/diameter/codec/functions.hpp>
19 #include <anna/diameter/codec/Message.hpp>
20 #include <anna/diameter/helpers/base/functions.hpp>
21
22 #include <anna/diameter/helpers/dcca/defines.hpp>
23 #include <anna/diameter/helpers/dcca/functions.hpp>
24 #include <anna/core/util/defines.hpp>
25 #include <anna/core/util/RegularExpression.hpp>
26
27
28 using namespace anna::testing;
29
30
31 const char* TestDiameterCondition::asText(const Type::_v type)
32 throw() {
33   static const char* text [] = { "RegexpXml", "RegexpHex", "Fields" };
34   return text [type];
35 }
36
37 bool TestDiameterCondition::exists() const throw() {
38   if (a_type != Type::Fields) return (getRegexp() != "");
39
40   return (a_code != "" || a_bitR != "" || a_hopByHop != "" || a_applicationId != "" || a_sessionId != "" || a_resultCode != "" || a_msisdn != "" || a_imsi != "" || a_serviceContextId != "");
41 }
42
43 bool TestDiameterCondition::comply(const anna::DataBlock &message) const throw() {
44
45   if (a_type == Type::RegexpXml) {
46     anna::diameter::codec::Message codecMsg;
47     try { codecMsg.decode(message); } catch (anna::RuntimeException &ex) { ex.trace(); }
48
49     //return codecMsg.isLike(getRegexp());
50     // We will remove LF from both sides to ease regexp management:
51     std::string regexp = getRegexp();
52     regexp.erase(std::remove(regexp.begin(), regexp.end(), '\n'), regexp.end());
53     anna::RegularExpression re(regexp);
54
55     std::string msgString = codecMsg.asXMLString();
56     msgString.erase(std::remove(msgString.begin(), msgString.end(), '\n'), msgString.end());
57
58     return re.isLike(msgString);
59   }
60   else if (a_type == Type::RegexpHex) {
61     anna::RegularExpression re(getRegexp());
62     return re.isLike(anna::functions::asHexString(message));
63   }
64
65   // Basic
66   std::string compare;
67   anna::diameter::CommandId cid;
68
69   if (a_code != "" || a_bitR != "") {
70     try {
71       cid = anna::diameter::codec::functions::getCommandId(message);
72     }
73     catch (anna::RuntimeException &) { return false; }
74   }
75
76   if (a_code != "") {
77     compare = anna::functions::asString(cid.first);
78     if (a_code != compare) return false;
79   }
80
81   if (a_bitR != "") {
82     compare = (cid.second ? "1":"0");
83     if (a_bitR != compare) return false;
84   }
85
86   if (a_hopByHop != "") {
87     try {
88       anna::diameter::HopByHop h = anna::diameter::codec::functions::getHopByHop(message);
89       compare = anna::functions::asString(h);
90     }
91     catch (anna::RuntimeException &) { return false; }
92     if (a_hopByHop != compare) return false;
93   }
94
95   if (a_applicationId != "") {
96     try {
97       anna::diameter::ApplicationId a = anna::diameter::codec::functions::getApplicationId(message);
98       compare = anna::functions::asString(a);
99     }
100     catch (anna::RuntimeException &) { return false; }
101     if (a_applicationId != compare) return false;
102   }
103
104   //if (matchSessionId) {
105   if (a_sessionId != "") {
106     try {
107       compare = anna::diameter::helpers::base::functions::getSessionId(message);
108     }
109     catch (anna::RuntimeException &) { return false; }
110     if (a_sessionId != compare) return false;
111   }
112   //}
113
114   if (a_resultCode != "") {
115     try {
116       anna::U32 rc = anna::diameter::helpers::base::functions::getResultCode(message);
117       compare = anna::functions::asString(rc);
118     }
119     catch (anna::RuntimeException &) { return false; }
120     if (a_resultCode != compare) return false;
121   }
122
123   if (a_msisdn != "") {
124     try {
125       compare = anna::diameter::helpers::dcca::functions::getSubscriptionIdData(message, anna::diameter::helpers::dcca::AVPVALUES__Subscription_Id_Type::END_USER_E164);
126     }
127     catch (anna::RuntimeException &) { return false; }
128     if (a_msisdn != compare) return false;
129   }
130
131   if (a_imsi != "") {
132     try {
133       compare = anna::diameter::helpers::dcca::functions::getSubscriptionIdData(message, anna::diameter::helpers::dcca::AVPVALUES__Subscription_Id_Type::END_USER_IMSI);
134     }
135     catch (anna::RuntimeException &) { return false; }
136     if (a_imsi != compare) return false;
137   }
138
139   if (a_serviceContextId != "") {
140     try {
141       compare = anna::diameter::helpers::dcca::functions::getServiceContextId(message);
142     }
143     catch (anna::RuntimeException &) { return false; }
144     if (a_serviceContextId != compare) return false;
145   }
146
147   return true;
148 }
149
150 anna::xml::Node* TestDiameterCondition::asXML(anna::xml::Node* parent) const
151 throw() {
152   anna::xml::Node* result = parent->createChild("TestDiameterCondition");
153   if (!exists()) return result;
154
155   if (a_type == Type::RegexpXml) {
156     if (getRegexp() != "") result->createAttribute("RegexpXml", getRegexp());
157   }
158   else if (a_type == Type::RegexpHex) {
159     if (getRegexp() != "") result->createAttribute("RegexpHex", getRegexp());
160   }
161   else {
162     if (a_code != "") result->createAttribute("Code", atoi(a_code.c_str()));
163     if (a_bitR != "") result->createAttribute("BitR", ((a_bitR == "1") ? "yes":"no"));
164     if (a_hopByHop != "") result->createAttribute("HopByHop", atoll(a_hopByHop.c_str()));
165     if (a_applicationId != "") result->createAttribute("ApplicationId", atoll(a_applicationId.c_str()));
166     if (a_sessionId != "") result->createAttribute("SessionId", a_sessionId);
167     if (a_resultCode != "") result->createAttribute("ResultCode", atoi(a_resultCode.c_str()));
168     if (a_msisdn != "") result->createAttribute("Msisdn", a_msisdn);
169     if (a_imsi != "") result->createAttribute("Imsi", a_imsi);
170     if (a_serviceContextId != "") result->createAttribute("ServiceContextId", a_serviceContextId);
171   }
172
173   result->createAttribute("ExpectedSource", a_rcvFromEntity ? "entity":"client");
174
175   return result;
176 }