Remove dynamic exceptions
[anna.git] / example / http / kClient / main.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 /*
10    Establece un manejador externo para controlar el teclado, recoge los parametros de la operacion
11    por este y envia la peticion al servidor que devolvera el resultado de aplicar la operacion
12    sobre los parametros recogidos.
13
14    El cliente de esta aplicacion es: http_server.p => Transporte: http::Transport.
15 */
16 #include <iostream>
17
18 #include <string.h>
19
20 #include <anna/core/core.hpp>
21 #include <anna/comm/comm.hpp>
22
23 #include <anna/http/Request.hpp>
24 #include <anna/http/Response.hpp>
25 #include <anna/http/Handler.hpp>
26 #include <anna/http/Transport.hpp>
27 #include <anna/http/functions.hpp>
28
29 #include <anna/test/Menu.hpp>
30 #include <anna/test/Request.hpp>
31 #include <anna/test/Response.hpp>
32
33 class MyHandler : public http::Handler {
34 public:
35    MyHandler () : http::Handler ("http_kclient::MyHandler") {;}
36
37 private:
38    http::Response a_httpResponse;
39    test::Response a_testResponse;
40
41    void evRequest (ClientSocket&, const http::Request&) noexcept(false) {;}
42    void evResponse (ClientSocket&, const http::Response&) noexcept(false);
43 };
44
45 class MyCommunicator : public Communicator {
46 public:
47    MyCommunicator () : Communicator ()
48    {
49       a_httpRequest.setMethod (http::Method::Type::Post);
50       a_httpRequest.setURI ("HTTPKClient");
51    }
52
53 private:
54    MyHandler a_httpHandler;
55    http::Request a_httpRequest;
56    test::Request a_testRequest;
57
58    void eventReceiveMessage (ClientSocket &, const Message&) noexcept(false);
59    void eventUser (const char* id, const void* context) ;
60 };
61
62 class HTTPKClient : public anna::comm::Application {
63 public:
64    HTTPKClient ();
65
66    Server* getServer () const { return a_server; }
67    const test::Menu& getMenu () const { return a_menu; }
68
69 private:
70    MyCommunicator a_communicator;
71    test::Menu a_menu;
72    Server* a_server;
73
74    void initialize () noexcept(false);
75    void run () noexcept(false);
76 };
77
78 using namespace std;
79 using namespace test;
80
81 int main (int argc, const char** argv)
82 {
83    CommandLine& commandLine (CommandLine::instantiate ());
84    HTTPKClient app;
85
86    http::functions::initialize ();
87
88    try {
89       commandLine.initialize (argv, argc);
90       commandLine.verify ();
91
92       Logger::setLevel (Logger::Debug);
93       Logger::initialize ("http_kclient", new TraceWriter ("file.trace", 4096000));
94
95       app.start ();
96    }
97    catch (Exception& ex) {
98       cout << ex.asString () << endl;
99    }
100
101    return 0;
102 }
103
104 HTTPKClient::HTTPKClient () :
105    Application ("kclient", "HTTPKClient", "1.0.0"),
106    a_menu (&a_communicator)
107 {
108    CommandLine& commandLine (CommandLine::instantiate ());
109
110    commandLine.add ("p", CommandLine::Argument::Mandatory, "Puerto en el que el servidor atiende respuestas.");
111    commandLine.add ("a", CommandLine::Argument::Mandatory, "Direccin IP Puerto en el que el servidor atiende respuestas.");
112 }
113
114 void HTTPKClient::initialize () 
115    noexcept(false)
116 {
117    CommandLine& cl (CommandLine::instantiate ());
118
119    Network& network = Network::instantiate ();
120
121    Host* host = network.find_host ("host000");
122    host->assign (network.find (Device::asAddress (cl.getValue ("a"))));
123    a_server = host->createServer ("http_server", cl.getIntegerValue ("p"), true, &http::Transport::getFactory ());
124
125    a_communicator.attach (&a_menu);
126 }
127
128 void HTTPKClient::run ()
129    noexcept(false)
130 {
131    a_menu.paint ();
132    a_communicator.accept ();
133 }
134
135 void MyCommunicator::eventReceiveMessage (ClientSocket& clientSocket, const Message& message)
136    noexcept(false)
137 {
138    LOGMETHOD (TraceMethod tm ("MyCommunicator", "eventReceiveMessage", ANNA_FILE_LOCATION));
139
140    if (clientSocket.support (http::Transport::className ()) == false)
141       return;
142
143    a_httpHandler.apply (clientSocket, message);
144 }
145
146 //-----------------------------------------------------------------------------------------
147 // Cuando el Menu tiene disponibles todos los datos necesarios para la peticin se lo
148 // notifica al comunicador mediante un evento de usuario.
149 //-----------------------------------------------------------------------------------------
150 void MyCommunicator::eventUser (const char* id, const void* context)
151    
152 {
153    LOGMETHOD (TraceMethod tm ("MyCommunicator", "eventUser", ANNA_FILE_LOCATION));
154
155    if (anna_strcmp (id, Menu::EventData) == 0) {
156       const Menu::Data* data (reinterpret_cast <const Menu::Data*>  (context));
157
158       a_testRequest.op = data->a_operation;
159       a_testRequest.x = data->a_op1;
160       a_testRequest.y = data->a_op2;
161       a_testRequest.initTime = anna::functions::millisecond ();
162
163       Server* server = static_cast <HTTPKClient&> (anna::comm::functions::getApp ()).getServer ();
164
165       try {
166          a_httpRequest.setBody (a_testRequest.code ());
167          server->send (a_httpRequest);
168       }
169       catch (RuntimeException& ex) {
170          ex.trace ();
171       }
172    } 
173 }
174
175 void MyHandler::evResponse (ClientSocket& clientSocket, const http::Response& response)
176    noexcept(false)
177 {
178    if (response.getStatusCode () == 200) {
179       a_testResponse.decode (response.getBody ());
180       
181       const Millisecond responseTime = anna::functions::millisecond () - a_testResponse.initTime;  
182       cout << endl << "ResponseTime: " << responseTime << " ms" << endl;
183       cout << endl << "Resultado de la peticion: " << a_testResponse.x << (char) a_testResponse.op << a_testResponse.y  << " = " << a_testResponse.result << endl << endl;
184    }
185    else 
186       cout << endl << "Error en la peticion: " << response.getStatusCode () << " (" << response.getReasonPhrase () << ")" << endl << endl;
187    
188    static_cast <HTTPKClient&> (anna::comm::functions::getApp ()).getMenu ().paint ();
189 }
190