Revert "Remove mysql and oracle resources for anna-ericsson project"
[anna.git] / example / diameter / launcher / MyDiameterEntity.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 // Project
10 #include <anna/core/core.hpp>
11 #include <anna/diameter/functions.hpp>
12 #include <anna/time/functions.hpp>
13 #include <anna/diameter.comm/Response.hpp>
14 #include <anna/diameter.comm/ClientSession.hpp>
15 #include <anna/diameter.comm/OriginHost.hpp>
16 #include <anna/diameter/helpers/base/functions.hpp>
17 #include <anna/diameter/helpers/dcca/functions.hpp>
18
19 // Process
20 #include <MyDiameterEngine.hpp>
21 #include <MyDiameterEntity.hpp>
22 #include <MyLocalServer.hpp>
23 #include <Launcher.hpp>
24 #include <anna/testing/TestManager.hpp>
25
26
27 void MyDiameterEntity::eventRequestRetransmission(const anna::diameter::comm::ClientSession* clientSession, anna::diameter::comm::Message *request) throw() {
28
29   LOGMETHOD(anna::TraceMethod tm("launcher::MyDiameterEntity", "eventRequestRetransmission", ANNA_FILE_LOCATION));
30
31   // Base class:
32   Entity::eventRequestRetransmission(clientSession, request); // warning trace
33
34   // Performance stats:
35   Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
36   anna::diameter::comm::OriginHost * my_node = my_app.getOriginHost(getEngine()->getOriginHostName());
37   // CommandId:
38   anna::diameter::CommandId cid = anna::diameter::codec::functions::getCommandId(request->getBody());
39   LOGDEBUG
40   (
41     std::string msg = "Request retransmitted: ";
42     msg += anna::diameter::functions::commandIdAsPairString(cid);
43     msg += " | DiameterServer: ";
44     msg += anna::functions::socketLiteralAsString(clientSession->getAddress(), clientSession->getPort());
45     msg += " | EventTime: ";
46     msg += anna::time::functions::currentTimeAsString();
47     anna::Logger::debug(msg, ANNA_FILE_LOCATION);
48   );
49
50   // Write retransmission
51   if(my_node->logEnabled()) my_node->writeLogFile(request->getBody(), "retry", clientSession->asString());
52 }
53
54
55 void MyDiameterEntity::eventRequest(anna::diameter::comm::ClientSession *clientSession, const anna::DataBlock &message)
56 throw(anna::RuntimeException) {
57   LOGMETHOD(anna::TraceMethod tm("launcher::MyDiameterEntity", "eventRequest", ANNA_FILE_LOCATION));
58   // Performance stats:
59   Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
60   anna::diameter::comm::OriginHost * my_node = my_app.getOriginHost(getEngine()->getOriginHostName());
61
62   // CommandId:
63   anna::diameter::CommandId cid = anna::diameter::codec::functions::getCommandId(message);
64   LOGDEBUG
65   (
66     std::string msg = "Request received: ";
67     msg += anna::diameter::functions::commandIdAsPairString(cid);
68     msg += " | DiameterServer: ";
69     msg += anna::functions::socketLiteralAsString(clientSession->getAddress(), clientSession->getPort());
70     msg += " | EventTime: ";
71     msg += anna::time::functions::currentTimeAsString();
72     anna::Logger::debug(msg, ANNA_FILE_LOCATION);
73   );
74
75   // Write reception
76   if(my_node->logEnabled()) my_node->writeLogFile(message, "recvfe", clientSession->asString());
77
78   // Lookup reacting answers list:
79   int code = cid.first;
80   anna::diameter::codec::Message *answer_message = a_reactingAnswers.getMessage(code);
81   if (answer_message) {
82     // Prepare answer:
83     my_app.getCommunicator()->prepareAnswer(answer_message, message);
84     anna::diameter::comm::Message *msg;
85
86     try {
87       msg = my_node->createCommMessage();
88       msg->setBody(answer_message->code());
89       /* response = NULL =*/clientSession->send(msg);
90
91       if(my_node->logEnabled()) my_node->writeLogFile(*answer_message, "sent2e", clientSession->asString());
92     } catch(anna::RuntimeException &ex) {
93       ex.trace();
94
95       if(my_node->logEnabled()) my_node->writeLogFile(*answer_message, "send2eError", clientSession->asString());
96     }
97
98     // release msg
99     my_node->releaseCommMessage(msg);
100
101     // Pop front the reacting answer:
102     a_reactingAnswers.nextMessage(code);
103     return;
104   }
105
106   LOGDEBUG
107   (
108     std::string msg = "No answers programmed (maybe sold out) for request coming from entity: ";
109     msg += anna::diameter::functions::commandIdAsPairString(cid);
110     anna::Logger::debug(msg, ANNA_FILE_LOCATION);
111   );
112
113   // not found: forward to client (if exists)
114   // Forward to client:
115   MyLocalServer *localServer = (MyLocalServer *)my_node->getDiameterServer();
116
117   if(localServer && (cid != anna::diameter::helpers::base::COMMANDID__Capabilities_Exchange_Request) /* don't forward CER */) {
118     try {
119       anna::diameter::comm::Message *msg = my_node->createCommMessage();
120       msg->forwardEndToEnd(); // end-to-end will be kept
121       msg->setBody(message);
122       msg->setRequestClientSessionKey(clientSession->getKey());
123       bool success = localServer->send(msg);
124
125       // Detailed log:
126       if(my_node->logEnabled()) {
127         anna::diameter::comm::ServerSession *usedServerSession = localServer->getLastUsedResource();
128         std::string detail = usedServerSession ? usedServerSession->asString() : "<null server session>"; // esto no deberia ocurrir
129         my_node->writeLogFile(message, (success ? "fwd2c" : "fwd2cError"), detail);
130       }
131     } catch(anna::RuntimeException &ex) {
132       ex.trace();
133     }
134   }
135
136   // Testing:
137   anna::testing::TestManager::instantiate().receiveDiameterMessage(message, clientSession);
138 }
139
140 void MyDiameterEntity::eventResponse(const anna::diameter::comm::Response &response)
141 throw(anna::RuntimeException) {
142   LOGMETHOD(anna::TraceMethod tm("launcher::MyDiameterEntity", "eventResponse", ANNA_FILE_LOCATION));
143   Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
144   anna::diameter::comm::OriginHost *my_node = my_app.getOriginHost(getEngine()->getOriginHostName());
145   anna::diameter::comm::ClassCode::_v code = response.getClassCode();
146   anna::diameter::comm::Response::ResultCode::_v result = response.getResultCode();
147   anna::diameter::comm::Message* request = const_cast<anna::diameter::comm::Message*>(response.getRequest());
148   const anna::DataBlock* message = response.getMessage();
149   const anna::diameter::comm::ClientSession *clientSession = static_cast<const anna::diameter::comm::ClientSession *>(response.getSession());
150   bool contextExpired = (result == anna::diameter::comm::Response::ResultCode::Timeout);
151   bool isUnavailable = (result == anna::diameter::comm::Response::ResultCode::DiameterUnavailable);
152   bool isOK = (result == anna::diameter::comm::Response::ResultCode::Success);
153
154   // CommandId:
155   anna::diameter::CommandId request_cid = request->getCommandId();
156   LOGDEBUG
157   (
158     std::string msg = "Response received for original diameter request: ";
159     msg += anna::diameter::functions::commandIdAsPairString(request_cid);
160     msg += " | Response: ";
161     msg += response.asString();
162     msg += " | DiameterServer: ";
163     msg += anna::functions::socketLiteralAsString(clientSession->getAddress(), clientSession->getPort());
164     msg += " | EventTime: ";
165     msg += anna::time::functions::currentTimeAsString();
166     anna::Logger::debug(msg, ANNA_FILE_LOCATION);
167   );
168
169   if(isUnavailable) {
170     //if (isApplicationMessage)
171     LOGWARNING(anna::Logger::warning("Diameter entity unavailable for Diameter Request", ANNA_FILE_LOCATION));
172   }
173
174   if(contextExpired) {
175     //if (isApplicationMessage)
176     LOGWARNING(anna::Logger::warning("Context Expired for Diameter Request which was sent to the entity", ANNA_FILE_LOCATION));
177
178     if(request_cid != anna::diameter::helpers::base::COMMANDID__Capabilities_Exchange_Request) {  // don't trace CEA
179       if(my_node->logEnabled()) my_node->writeLogFile(*request, "req2e-expired", clientSession->asString());
180     }
181   }
182
183   if(isOK) {
184     LOGDEBUG(
185       std::string msg = "Received response for diameter message:  ";
186       msg += anna::diameter::functions::commandIdAsPairString(request_cid);
187       anna::Logger::debug(msg, ANNA_FILE_LOCATION);
188     );
189
190     // Write reception
191     if(request_cid != anna::diameter::helpers::base::COMMANDID__Capabilities_Exchange_Request) {  // don't trace CEA
192       if(my_node->logEnabled()) {
193         my_node->writeLogFile(*message, "recvfe", clientSession->asString());
194       }
195     }
196
197     // Forward to client:
198     MyLocalServer *localServer = (MyLocalServer *)my_node->getDiameterServer();
199
200     if(localServer && (request_cid != anna::diameter::helpers::base::COMMANDID__Capabilities_Exchange_Request) /* don't forward CEA */) {
201       anna::diameter::comm::Message *msg;
202
203       try {
204         msg = my_node->createCommMessage();
205         msg->forwardEndToEnd(); // end-to-end will be kept
206         msg->setBody(*message);
207         bool success = localServer->send(msg, request->getRequestServerSessionKey());
208
209         // Detailed log:
210         anna::diameter::comm::ServerSession *usedServerSession = my_node->getCommEngine()->findServerSession(request->getRequestServerSessionKey());
211         std::string detail = usedServerSession ? usedServerSession->asString() : "<null server session>"; // esto no deberia ocurrir
212
213         if(my_node->logEnabled()) {
214           my_node->writeLogFile(*message, (success ? "fwd2c" : "fwd2cError"), detail);
215         }
216       } catch(anna::RuntimeException &ex) {
217         ex.trace();
218       }
219
220       // release msgs
221       my_node->releaseCommMessage(msg);
222       my_node->releaseCommMessage(request);
223     }
224   }
225
226   // Triggering burst:
227   if(isOK || contextExpired) my_node->sendBurstMessage();
228
229   // Testing:
230   if(isOK) anna::testing::TestManager::instantiate().receiveDiameterMessage(*message, clientSession);
231 }
232
233 void MyDiameterEntity::eventUnknownResponse(anna::diameter::comm::ClientSession *clientSession, const anna::DataBlock &message)
234 throw(anna::RuntimeException) {
235   LOGMETHOD(anna::TraceMethod tm("launcher::MyDiameterEntity", "eventUnknownResponse", ANNA_FILE_LOCATION));
236   // Performance stats:
237   Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
238   anna::diameter::comm::OriginHost * my_node = my_app.getOriginHost(getEngine()->getOriginHostName());
239   // CommandId:
240   anna::diameter::CommandId cid = anna::diameter::codec::functions::getCommandId(message);
241   LOGDEBUG
242   (
243     std::string msg = "Out-of-context response received from entity: ";
244     msg += anna::diameter::functions::commandIdAsPairString(cid);
245     msg += " | DiameterServer: ";
246     msg += anna::functions::socketLiteralAsString(clientSession->getAddress(), clientSession->getPort());
247     msg += " | EventTime: ";
248     msg += anna::time::functions::currentTimeAsString();
249     anna::Logger::debug(msg, ANNA_FILE_LOCATION);
250   );
251
252   // Write reception
253   if(my_node->logEnabled()) my_node->writeLogFile(message, "recvfe-ans-unknown", clientSession->asString());
254 }
255
256 void MyDiameterEntity::eventDPA(anna::diameter::comm::ClientSession *clientSession, const anna::DataBlock &message)
257 throw(anna::RuntimeException) {
258   LOGMETHOD(anna::TraceMethod tm("launcher::MyDiameterEntity", "eventDPA", ANNA_FILE_LOCATION));
259   // Performance stats:
260   Launcher& my_app = static_cast <Launcher&>(anna::app::functions::getApp());
261   anna::diameter::comm::OriginHost * my_node = my_app.getOriginHost(getEngine()->getOriginHostName());
262   // CommandId:
263   anna::diameter::CommandId cid = anna::diameter::codec::functions::getCommandId(message);
264   LOGDEBUG
265   (
266     std::string msg = "Disconnect-Peer-Answer received from entity: ";
267     msg += anna::diameter::functions::commandIdAsPairString(cid);
268     msg += " | DiameterServer: ";
269     msg += anna::functions::socketLiteralAsString(clientSession->getAddress(), clientSession->getPort());
270     msg += " | EventTime: ";
271     msg += anna::time::functions::currentTimeAsString();
272     anna::Logger::debug(msg, ANNA_FILE_LOCATION);
273   );
274
275   // Write reception
276   if(my_node->logEnabled()) my_node->writeLogFile(message, "recvfe", clientSession->asString());
277
278   // Testing:
279   anna::testing::TestManager::instantiate().receiveDiameterMessage(message, clientSession);
280 }