1 // ANNA - Anna is Not Nothingness Anymore //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
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 //
11 #include <anna/core/core.hpp>
13 #include <anna/comm/Application.hpp>
14 #include <anna/comm/Communicator.hpp>
16 #include <anna/app/functions.hpp>
18 #include <anna/timex/timex.hpp>
20 #include <anna/ldap/Engine.hpp>
21 #include <anna/ldap/Session.hpp>
22 #include <anna/ldap/Search.hpp>
23 #include <anna/ldap/Response.hpp>
24 #include <anna/ldap/Attribute.hpp>
26 class MySession : public ldap::Session {
27 void eventResponse (const ldap::Response&) noexcept(false);
30 class MyEngine : public ldap::Engine {
35 Recycler<MySession> a_sessions;
37 ldap::Session* allocateSession (const int category) { return a_sessions.create (); }
39 void releaseSession (ldap::Session* session) {
40 MySession* aux = static_cast <MySession*> (session);
41 a_sessions.release (aux);
45 //-----------------------------------------------------------------------------------------
46 // Define el comunicador de nuestra aplicación.
48 // Las peticiones y respuestas van codificadas mediante un RawCodec pero podriamos
49 // haber utilizado cualquier otro medio de codificación ya que la capa de transporte
50 // es totalmente independiente del contenido del mensaje.
52 // De cara a la capa de transporte lo único que importa es el cliente y el servidor
53 // codifiquen/decodifiquen de la misma forma (RawCodec, EnhancedCodec ....)
54 //-----------------------------------------------------------------------------------------
55 class MyCommunicator : public comm::Communicator {
57 MyCommunicator () : comm::Communicator () { ;}
60 void eventReceiveMessage (comm::ClientSocket &, const comm::Message&) noexcept(false) {;}
63 class Buddy : public Clock {
65 Buddy () : Clock ("buddy", (Millisecond)2000) {;}
67 void setLDAPEngine (ldap::Engine& ldapEngine) { a_ldapEngine = &ldapEngine; }
70 ldap::Engine* a_ldapEngine;
71 ldap::Search a_ldapSearch;
73 bool tick () noexcept(false);
76 class Stopper : public Timer {
78 Stopper () : Timer ("stopper", (Millisecond)0) {;}
79 void expire (Engine*) noexcept(false);
82 class LDAPClient : public anna::comm::Application {
87 MyCommunicator a_communicator;
88 anna::timex::Engine a_timeController;
89 MyEngine a_ldapEngine;
93 void run () noexcept(false);
97 using namespace anna::comm;
99 int main (int argc, const char** argv)
101 CommandLine& commandLine (CommandLine::instantiate ());
105 commandLine.initialize (argv, argc);
106 commandLine.verify ();
108 Logger::setLevel (Logger::Debug);
109 Logger::initialize ("ldap_tsearch", new TraceWriter ("file.trace", 2048000));
113 catch (Exception& ex) {
114 cout << ex.asString () << endl;
120 LDAPClient::LDAPClient () :
121 Application ("ldap_tsearch", "Client LDAP", "1.0"),
123 a_timeController ((Millisecond)120000, (Millisecond)1000)
125 CommandLine& cl = CommandLine::instantiate ();
127 cl.add ("url", CommandLine::Argument::Mandatory, "URL del host");
128 cl.add ("base", CommandLine::Argument::Mandatory, "Base");
129 cl.add ("t", CommandLine::Argument::Mandatory, "Segundos que deber estar en ejecucion este cliente");
130 cl.add ("filter", CommandLine::Argument::Optional, "Filtro");
131 cl.add ("scope", CommandLine::Argument::Optional, "Ambito");
132 cl.add ("user", CommandLine::Argument::Optional, "Usuario");
133 cl.add ("password", CommandLine::Argument::Optional, "Password");
134 cl.add ("d", CommandLine::Argument::Optional, "Nivel de depuracion (all = activa todo)");
137 //-----------------------------------------------------------------------------------------
138 // Atiende las peticiones.
139 // Cuando hay un nuevo mensaje invocará a Communicator::eventReceiveMessage
141 // (1) Para evitar la ejecucion de la aplicacion en caso de indicar un valor no valido.
142 //-----------------------------------------------------------------------------------------
143 void LDAPClient::run ()
146 LOGMETHOD (TraceMethod tm ("LDAPClient", "run", ANNA_FILE_LOCATION));
148 CommandLine& cl (CommandLine::instantiate ());
150 if (cl.exists ("scope"))
151 ldap::Scope::asEnum (cl.getValue ("scope")); // (1)
153 if (cl.exists ("d")) {
154 if (anna_strcmp (cl.getValue ("d"), "all") == 0)
155 ldap::Engine::setDebugLevel (ldap::Engine::DebugLevel::All);
157 ldap::Engine::setDebugLevel (cl.getIntegerValue ("d"));
160 a_buddy.setLDAPEngine (a_ldapEngine);
162 a_stopper.setTimeout ((Millisecond)(CommandLine::instantiate ().getIntegerValue ("t") * 1000));
164 a_timeController.activate (a_buddy);
165 a_timeController.activate (a_stopper);
167 a_communicator.accept ();
170 void MySession::eventResponse (const ldap::Response& response)
173 cout << "LDAP Response: " << response.asString () << endl;
174 cout << " Name: " << response.getName () << endl;
176 ldap::Response::const_attribute_iterator ii, maxii;
177 ldap::Attribute::const_value_iterator vv, maxvv;
178 const ldap::Attribute* attr;
180 for (ii = response.attribute_begin (), maxii = response.attribute_end (); ii != maxii; ii ++) {
181 attr = ldap::Response::attribute (ii);
183 cout << " Attribute: " << attr->getName () << " -> ";
184 for (vv = attr->value_begin (), maxvv = attr->value_end (); vv != maxvv; vv ++)
185 cout << ldap::Attribute::value (vv) << " ";
189 ldap::Response::const_referral_iterator jj, maxjj;
190 for (jj = response.referral_begin (), maxjj = response.referral_end (); jj != maxjj; jj ++)
191 cout << " Referral: " << ldap::Response::referral (jj) << endl;
199 CommandLine& cl = CommandLine::instantiate ();
201 ldap::Session* session;
203 if (cl.exists ("user") && cl.exists ("password"))
204 session = a_ldapEngine->createSession (cl.getValue ("url"), cl.getValue ("user"), cl.getValue ("password"));
206 session = a_ldapEngine->createSession (cl.getValue ("url"));
208 if (session->isBound ()) {
209 a_ldapSearch.clear ();
210 a_ldapSearch.setBase (cl.getValue ("base"));
211 if (cl.exists ("filter"))
212 a_ldapSearch.setFilter (cl.getValue ("filter"));
213 if (cl.exists ("scope"))
214 a_ldapSearch.setScope (cl.getValue ("scope"));
215 session->setTimeout (ldap::ClassCode::Search, (Millisecond)5000);
216 session->send (a_ldapSearch);
224 void Stopper::expire (Engine*)
227 LOGMETHOD (TraceMethod tm ("Stopper", "expire", ANNA_FILE_LOCATION));
229 MyCommunicator* communicator = anna::app::functions::component <MyCommunicator> (ANNA_FILE_LOCATION);
231 communicator->requestStop ();