Suuports clang compiler
[anna.git] / example / http / wims20Client / main.cpp
1 // ANNA - Anna is Not Nothingness Anymore
2 //
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
4 //
5 // http://redmine.teslayout.com/projects/anna-suite
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
9 // are met:
10 //
11 //     * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 //     * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 //     *  Neither the name of the copyright holder nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 //
33 // Authors: eduardo.ramos.testillano@gmail.com
34 //          cisco.tierra@gmail.com
35
36
37 /*
38    Envia una peticion de interseccion sobre HTTP/XML para ihttp_server
39
40    El cliente de esta aplicacion es: ihttp_server.p => Transporte: http::Transport.
41 */
42 #include <iostream>
43
44 #include <string.h>
45
46 #include <anna/core/core.hpp>
47 #include <anna/comm/comm.hpp>
48
49 #include <anna/app/functions.hpp>
50
51 #include <anna/http/Request.hpp>
52 #include <anna/http/Response.hpp>
53 #include <anna/http/Handler.hpp>
54 #include <anna/http/Transport.hpp>
55 #include <anna/http/functions.hpp>
56
57 #include <anna/http/wims20/ClientSide.hpp>
58
59 class MyHandler : public http::Handler {
60 public:
61    MyHandler () : http::Handler ("ihttp_client::MyHandler") {;}
62
63 private:
64    http::Response a_httpResponse;
65
66    void evRequest (ClientSocket&, const http::Request&) throw (RuntimeException) {;}
67    void evResponse (ClientSocket&, const http::Response&) throw (RuntimeException);
68 };
69
70 class MyCommunicator : public Communicator {
71 public:
72    MyCommunicator () : Communicator (), a_httpRequest ()
73    {
74       a_httpRequest.setMethod (http::Method::Type::Get);
75       a_httpRequest.setURI ("ihttp_client");
76    }
77
78 private:
79    MyHandler a_httpHandler;
80    http::Request a_httpRequest;
81
82    void eventReceiveMessage (ClientSocket &, const Message&) throw (RuntimeException);
83    void eventStartup () throw (RuntimeException);
84 };
85
86 class IHTTPClient : public anna::comm::Application {
87 public:
88    IHTTPClient ();
89
90    Server* getServer () const throw () { return a_server; }
91
92 private:
93    MyCommunicator a_communicator;
94    Server* a_server;
95
96    void initialize () throw (RuntimeException);
97    void run () throw (RuntimeException);
98 };
99
100 using namespace std;
101
102 int main (int argc, const char** argv)
103 {
104    CommandLine& commandLine (CommandLine::instantiate ());
105    IHTTPClient app;
106
107    http::functions::initialize ();
108
109    try {
110       commandLine.initialize (argv, argc);
111       commandLine.verify ();
112
113       Logger::setLevel (Logger::Debug);
114       Logger::initialize ("ihttp_client", new TraceWriter ("file.trace", 4096000));
115
116       app.start ();
117    }
118    catch (Exception& ex) {
119       cout << ex.asString () << endl;
120    }
121
122    return 0;
123 }
124
125 IHTTPClient::IHTTPClient () :
126    Application ("wims20_client", "IHTTPClient", "2.0.0")
127 {
128    CommandLine& commandLine (CommandLine::instantiate ());
129
130    commandLine.add ("p", CommandLine::Argument::Mandatory, "Port to attend the answers.");
131    commandLine.add ("a", CommandLine::Argument::Mandatory, "Direccion IP Puerto en el que el servidor atiende respuestas.");
132    commandLine.add ("domain", CommandLine::Argument::Mandatory, "Domain indicado en la peticion WIMS 2.0");
133    commandLine.add ("op", CommandLine::Argument::Mandatory, "operacion a realizar (sum,sub,mul,div)");
134    commandLine.add ("x", CommandLine::Argument::Mandatory, "Primer operador");
135    commandLine.add ("y", CommandLine::Argument::Mandatory, "Segundo operador");
136    commandLine.add ("op", CommandLine::Argument::Mandatory, "operacion a realizar (sum,sub,mul,div)");
137    commandLine.add ("trace", CommandLine::Argument::Optional, "Nivel de trazas (debug,warning, error,...)");
138    commandLine.add ("path", CommandLine::Argument::Optional, "Path indicado en la peticion WIMS 2.0");
139    commandLine.add ("m", CommandLine::Argument::Optional, "Metodo HTTP a usar");
140 }
141
142 void IHTTPClient::initialize () 
143    throw (RuntimeException)
144 {
145    CommandLine& cl (CommandLine::instantiate ());
146
147    Network& network = Network::instantiate ();
148
149    if (cl.exists ("trace"))
150       Logger::setLevel (Logger::asLevel (cl.getValue ("trace")));
151
152    Host* host = network.find_host("host000");
153    host->assign (network.find (Device::asAddress (cl.getValue ("a"))));
154    a_server = host->createServer ("http_server", cl.getIntegerValue ("p"), true, &http::Transport::getFactory ());
155 }
156
157 void IHTTPClient::run ()
158    throw (RuntimeException)
159 {
160    a_communicator.accept ();
161 }
162
163 void MyCommunicator::eventStartup ()
164    throw (RuntimeException)
165 {
166    CommandLine& cl (CommandLine::instantiate ());
167
168    string domain = cl.getValue ("domain");
169
170    http::wims20::ClientSide* wims20Request = NULL;
171
172    if (cl.exists ("path")) {
173       string path = cl.getValue ("path");
174       wims20Request = new http::wims20::ClientSide (domain, path);
175    }
176    else
177       wims20Request = new http::wims20::ClientSide (domain);
178
179    wims20Request->setServiceID ("math");
180    wims20Request->setGUID ("user@tid.es");
181    wims20Request->addOtherLevel (cl.getValue ("op"));
182    wims20Request->setParameter ("X", cl.getIntegerValue ("x"));
183    wims20Request->setParameter ("Y", cl.getIntegerValue ("y"));
184
185    http::Header* header = a_httpRequest.createHeader (http::Header::Type::Connection);
186    header->setValue ("   Keep-Alive    ");
187
188    if (cl.exists ("m")) {
189       http::Method::Type::_v type = http::Method::Type::asEnumEx (cl.getValue ("m"));
190       a_httpRequest.setMethod (type);
191    }
192
193    wims20Request->codeOn (a_httpRequest);
194
195    static_cast <IHTTPClient&> (anna::comm::functions::getApp ()).getServer ()->send (a_httpRequest);
196 }
197
198 void MyCommunicator::eventReceiveMessage (ClientSocket& clientSocket, const Message& message)
199    throw (RuntimeException)
200 {
201    LOGMETHOD (TraceMethod tm ("MyCommunicator", "eventReceiveMessage", ANNA_FILE_LOCATION));
202
203    if (clientSocket.support (http::Transport::className ()) == false)
204       return;
205
206    a_httpHandler.apply (clientSocket, message);
207 }
208
209 void MyHandler::evResponse (ClientSocket& clientSocket, const http::Response& response)
210    throw (RuntimeException)
211 {
212    cout << "HTTP StatusCode: " << response.getStatusCode () << endl;
213    cout << "HTTP Text: " << response.getReasonPhrase () << endl;
214
215    app::functions::component <Communicator> (ANNA_FILE_LOCATION)->requestStop ();
216 }
217