0d5b49be30c712875fe8df6480cf6d82b605bbe4
[anna.git] / example / http / wims20Client / 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    Envia una peticion de interseccion sobre HTTP/XML para ihttp_server
11
12    El cliente de esta aplicacion es: ihttp_server.p => Transporte: http::Transport.
13 */
14 #include <iostream>
15
16 #include <string.h>
17
18 #include <anna/core/core.hpp>
19 #include <anna/comm/comm.hpp>
20
21 #include <anna/app/functions.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/http/wims20/ClientSide.hpp>
30
31 class MyHandler : public http::Handler {
32 public:
33    MyHandler () : http::Handler ("ihttp_client::MyHandler") {;}
34
35 private:
36    http::Response a_httpResponse;
37
38    void evRequest (ClientSocket&, const http::Request&) throw (RuntimeException) {;}
39    void evResponse (ClientSocket&, const http::Response&) throw (RuntimeException);
40 };
41
42 class MyCommunicator : public Communicator {
43 public:
44    MyCommunicator () : Communicator (), a_httpRequest ()
45    {
46       a_httpRequest.setMethod (http::Method::Type::Get);
47       a_httpRequest.setURI ("ihttp_client");
48    }
49
50 private:
51    MyHandler a_httpHandler;
52    http::Request a_httpRequest;
53
54    void eventReceiveMessage (ClientSocket &, const Message&) throw (RuntimeException);
55    void eventStartup () throw (RuntimeException);
56 };
57
58 class IHTTPClient : public anna::comm::Application {
59 public:
60    IHTTPClient ();
61
62    Server* getServer () const throw () { return a_server; }
63
64 private:
65    MyCommunicator a_communicator;
66    Server* a_server;
67
68    void initialize () throw (RuntimeException);
69    void run () throw (RuntimeException);
70 };
71
72 using namespace std;
73
74 int main (int argc, const char** argv)
75 {
76    CommandLine& commandLine (CommandLine::instantiate ());
77    IHTTPClient app;
78
79    http::functions::initialize ();
80
81    try {
82       commandLine.initialize (argv, argc);
83       commandLine.verify ();
84
85       Logger::setLevel (Logger::Debug);
86       Logger::initialize ("ihttp_client", new TraceWriter ("file.trace", 4096000));
87
88       app.start ();
89    }
90    catch (Exception& ex) {
91       cout << ex.asString () << endl;
92    }
93
94    return 0;
95 }
96
97 IHTTPClient::IHTTPClient () :
98    Application ("wims20_client", "IHTTPClient", "2.0.0")
99 {
100    CommandLine& commandLine (CommandLine::instantiate ());
101
102    commandLine.add ("p", CommandLine::Argument::Mandatory, "Port to attend the answers.");
103    commandLine.add ("a", CommandLine::Argument::Mandatory, "Direccion IP Puerto en el que el servidor atiende respuestas.");
104    commandLine.add ("domain", CommandLine::Argument::Mandatory, "Domain indicado en la peticion WIMS 2.0");
105    commandLine.add ("op", CommandLine::Argument::Mandatory, "operacion a realizar (sum,sub,mul,div)");
106    commandLine.add ("x", CommandLine::Argument::Mandatory, "Primer operador");
107    commandLine.add ("y", CommandLine::Argument::Mandatory, "Segundo operador");
108    commandLine.add ("op", CommandLine::Argument::Mandatory, "operacion a realizar (sum,sub,mul,div)");
109    commandLine.add ("trace", CommandLine::Argument::Optional, "Nivel de trazas (debug,warning, error,...)");
110    commandLine.add ("path", CommandLine::Argument::Optional, "Path indicado en la peticion WIMS 2.0");
111    commandLine.add ("m", CommandLine::Argument::Optional, "Metodo HTTP a usar");
112 }
113
114 void IHTTPClient::initialize () 
115    throw (RuntimeException)
116 {
117    CommandLine& cl (CommandLine::instantiate ());
118
119    Network& network = Network::instantiate ();
120
121    if (cl.exists ("trace"))
122       Logger::setLevel (Logger::asLevel (cl.getValue ("trace")));
123
124    Host* host = network.find_host("host000");
125    host->assign (network.find (Device::asAddress (cl.getValue ("a"))));
126    a_server = host->createServer ("http_server", cl.getIntegerValue ("p"), true, &http::Transport::getFactory ());
127 }
128
129 void IHTTPClient::run ()
130    throw (RuntimeException)
131 {
132    a_communicator.accept ();
133 }
134
135 void MyCommunicator::eventStartup ()
136    throw (RuntimeException)
137 {
138    CommandLine& cl (CommandLine::instantiate ());
139
140    string domain = cl.getValue ("domain");
141
142    http::wims20::ClientSide* wims20Request = NULL;
143
144    if (cl.exists ("path")) {
145       string path = cl.getValue ("path");
146       wims20Request = new http::wims20::ClientSide (domain, path);
147    }
148    else
149       wims20Request = new http::wims20::ClientSide (domain);
150
151    wims20Request->setServiceID ("math");
152    wims20Request->setGUID ("user@tid.es");
153    wims20Request->addOtherLevel (cl.getValue ("op"));
154    wims20Request->setParameter ("X", cl.getIntegerValue ("x"));
155    wims20Request->setParameter ("Y", cl.getIntegerValue ("y"));
156
157    http::Header* header = a_httpRequest.createHeader (http::Header::Type::Connection);
158    header->setValue ("   Keep-Alive    ");
159
160    if (cl.exists ("m")) {
161       http::Method::Type::_v type = http::Method::Type::asEnumEx (cl.getValue ("m"));
162       a_httpRequest.setMethod (type);
163    }
164
165    wims20Request->codeOn (a_httpRequest);
166
167    static_cast <IHTTPClient&> (anna::comm::functions::getApp ()).getServer ()->send (a_httpRequest);
168 }
169
170 void MyCommunicator::eventReceiveMessage (ClientSocket& clientSocket, const Message& message)
171    throw (RuntimeException)
172 {
173    LOGMETHOD (TraceMethod tm ("MyCommunicator", "eventReceiveMessage", ANNA_FILE_LOCATION));
174
175    if (clientSocket.support (http::Transport::className ()) == false)
176       return;
177
178    a_httpHandler.apply (clientSocket, message);
179 }
180
181 void MyHandler::evResponse (ClientSocket& clientSocket, const http::Response& response)
182    throw (RuntimeException)
183 {
184    cout << "HTTP StatusCode: " << response.getStatusCode () << endl;
185    cout << "HTTP Text: " << response.getReasonPhrase () << endl;
186
187    app::functions::component <Communicator> (ANNA_FILE_LOCATION)->requestStop ();
188 }
189