1 // ANNA - Anna is Not Nothingness Anymore
3 // (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo
5 // http://redmine.teslayout.com/projects/anna-suite
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
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
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.
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.
33 // Authors: eduardo.ramos.testillano@gmail.com
34 // cisco.tierra@gmail.com
39 #include <anna/core/core.hpp>
41 #include <anna/comm/Application.hpp>
42 #include <anna/comm/Communicator.hpp>
44 #include <anna/app/functions.hpp>
46 #include <anna/timex/timex.hpp>
48 #include <anna/ldap/Engine.hpp>
49 #include <anna/ldap/Session.hpp>
50 #include <anna/ldap/Search.hpp>
51 #include <anna/ldap/Response.hpp>
52 #include <anna/ldap/Attribute.hpp>
54 class MySession : public ldap::Session {
55 void eventResponse (const ldap::Response&) throw (RuntimeException);
58 class MyEngine : public ldap::Engine {
63 Recycler<MySession> a_sessions;
65 ldap::Session* allocateSession (const int category) throw () { return a_sessions.create (); }
67 void releaseSession (ldap::Session* session) throw () {
68 MySession* aux = static_cast <MySession*> (session);
69 a_sessions.release (aux);
73 //-----------------------------------------------------------------------------------------
74 // Define el comunicador de nuestra aplicación.
76 // Las peticiones y respuestas van codificadas mediante un RawCodec pero podriamos
77 // haber utilizado cualquier otro medio de codificación ya que la capa de transporte
78 // es totalmente independiente del contenido del mensaje.
80 // De cara a la capa de transporte lo único que importa es el cliente y el servidor
81 // codifiquen/decodifiquen de la misma forma (RawCodec, EnhancedCodec ....)
82 //-----------------------------------------------------------------------------------------
83 class MyCommunicator : public comm::Communicator {
85 MyCommunicator () : comm::Communicator () { ;}
88 void eventReceiveMessage (comm::ClientSocket &, const comm::Message&) throw (RuntimeException) {;}
91 class Buddy : public Clock {
93 Buddy () : Clock ("buddy", (Millisecond)2000) {;}
95 void setLDAPEngine (ldap::Engine& ldapEngine) throw () { a_ldapEngine = &ldapEngine; }
98 ldap::Engine* a_ldapEngine;
99 ldap::Search a_ldapSearch;
101 bool tick () throw (RuntimeException);
104 class Stopper : public Timer {
106 Stopper () : Timer ("stopper", (Millisecond)0) {;}
107 void expire (Engine*) throw (RuntimeException);
110 class LDAPClient : public anna::comm::Application {
115 MyCommunicator a_communicator;
116 anna::timex::Engine a_timeController;
117 MyEngine a_ldapEngine;
121 void run () throw (RuntimeException);
125 using namespace anna::comm;
127 int main (int argc, const char** argv)
129 CommandLine& commandLine (CommandLine::instantiate ());
133 commandLine.initialize (argv, argc);
134 commandLine.verify ();
136 Logger::setLevel (Logger::Debug);
137 Logger::initialize ("ldap_tsearch", new TraceWriter ("file.trace", 2048000));
141 catch (Exception& ex) {
142 cout << ex.asString () << endl;
148 LDAPClient::LDAPClient () :
149 Application ("ldap_tsearch", "Client LDAP", "1.0"),
151 a_timeController ((Millisecond)120000, (Millisecond)1000)
153 CommandLine& cl = CommandLine::instantiate ();
155 cl.add ("url", CommandLine::Argument::Mandatory, "URL del host");
156 cl.add ("base", CommandLine::Argument::Mandatory, "Base");
157 cl.add ("t", CommandLine::Argument::Mandatory, "Segundos que deber estar en ejecucion este cliente");
158 cl.add ("filter", CommandLine::Argument::Optional, "Filtro");
159 cl.add ("scope", CommandLine::Argument::Optional, "Ambito");
160 cl.add ("user", CommandLine::Argument::Optional, "Usuario");
161 cl.add ("password", CommandLine::Argument::Optional, "Password");
162 cl.add ("d", CommandLine::Argument::Optional, "Nivel de depuracion (all = activa todo)");
165 //-----------------------------------------------------------------------------------------
166 // Atiende las peticiones.
167 // Cuando hay un nuevo mensaje invocará a Communicator::eventReceiveMessage
169 // (1) Para evitar la ejecucion de la aplicacion en caso de indicar un valor no valido.
170 //-----------------------------------------------------------------------------------------
171 void LDAPClient::run ()
172 throw (RuntimeException)
174 LOGMETHOD (TraceMethod tm ("LDAPClient", "run", ANNA_FILE_LOCATION));
176 CommandLine& cl (CommandLine::instantiate ());
178 if (cl.exists ("scope"))
179 ldap::Scope::asEnum (cl.getValue ("scope")); // (1)
181 if (cl.exists ("d")) {
182 if (anna_strcmp (cl.getValue ("d"), "all") == 0)
183 ldap::Engine::setDebugLevel (ldap::Engine::DebugLevel::All);
185 ldap::Engine::setDebugLevel (cl.getIntegerValue ("d"));
188 a_buddy.setLDAPEngine (a_ldapEngine);
190 a_stopper.setTimeout ((Millisecond)(CommandLine::instantiate ().getIntegerValue ("t") * 1000));
192 a_timeController.activate (a_buddy);
193 a_timeController.activate (a_stopper);
195 a_communicator.accept ();
198 void MySession::eventResponse (const ldap::Response& response)
199 throw (RuntimeException)
201 cout << "LDAP Response: " << response.asString () << endl;
202 cout << " Name: " << response.getName () << endl;
204 ldap::Response::const_attribute_iterator ii, maxii;
205 ldap::Attribute::const_value_iterator vv, maxvv;
206 const ldap::Attribute* attr;
208 for (ii = response.attribute_begin (), maxii = response.attribute_end (); ii != maxii; ii ++) {
209 attr = ldap::Response::attribute (ii);
211 cout << " Attribute: " << attr->getName () << " -> ";
212 for (vv = attr->value_begin (), maxvv = attr->value_end (); vv != maxvv; vv ++)
213 cout << ldap::Attribute::value (vv) << " ";
217 ldap::Response::const_referral_iterator jj, maxjj;
218 for (jj = response.referral_begin (), maxjj = response.referral_end (); jj != maxjj; jj ++)
219 cout << " Referral: " << ldap::Response::referral (jj) << endl;
225 throw (RuntimeException)
227 CommandLine& cl = CommandLine::instantiate ();
229 ldap::Session* session;
231 if (cl.exists ("user") && cl.exists ("password"))
232 session = a_ldapEngine->createSession (cl.getValue ("url"), cl.getValue ("user"), cl.getValue ("password"));
234 session = a_ldapEngine->createSession (cl.getValue ("url"));
236 if (session->isBound ()) {
237 a_ldapSearch.clear ();
238 a_ldapSearch.setBase (cl.getValue ("base"));
239 if (cl.exists ("filter"))
240 a_ldapSearch.setFilter (cl.getValue ("filter"));
241 if (cl.exists ("scope"))
242 a_ldapSearch.setScope (cl.getValue ("scope"));
243 session->setTimeout (ldap::ClassCode::Search, (Millisecond)5000);
244 session->send (a_ldapSearch);
252 void Stopper::expire (Engine*)
253 throw (RuntimeException)
255 LOGMETHOD (TraceMethod tm ("Stopper", "expire", ANNA_FILE_LOCATION));
257 MyCommunicator* communicator = anna::app::functions::component <MyCommunicator> (ANNA_FILE_LOCATION);
259 communicator->requestStop ();