1
0
mirror of https://github.com/OpenNebula/one.git synced 2024-12-22 13:33:52 +03:00

feature #1288: Managers can now execute synchronous actions

This commit is contained in:
Ruben S. Montero 2012-05-31 18:38:14 +02:00
parent e192b6348b
commit 9361376e90
6 changed files with 170 additions and 268 deletions

View File

@ -40,16 +40,11 @@ class AuthManager : public MadManager, public ActionListener
public:
AuthManager(
time_t timer,
time_t __time_out,
vector<const Attribute*>& _mads):
time_t timer,
vector<const Attribute*>& _mads):
MadManager(_mads), timer_period(timer)
{
_time_out = __time_out;
am.addListener(this);
pthread_mutex_init(&mutex,0);
};
~AuthManager(){};
@ -96,32 +91,6 @@ public:
return authm_thread;
};
/**
* Notify the result of an auth request
*/
void notify_request(int auth_id, bool result, const string& message);
/**
* Discards a pending request. Call this before freeing not notified or
* timeout requests.
*/
void discard_request(int auth_id)
{
lock();
auth_requests.erase(auth_id);
unlock();
}
/**
* Gets default timeout for Auth requests
*/
static time_t time_out()
{
return _time_out;
}
/**
* Returns true if there is an authorization driver enabled
*
@ -143,21 +112,6 @@ private:
*/
ActionManager am;
/**
* List of pending requests
*/
map<int, AuthRequest *> auth_requests;
/**
* Mutex to access the auth_requests
*/
pthread_mutex_t mutex;
/**
* Default timeout for Auth requests
*/
static time_t _time_out;
/**
* Timer for the Manager (periocally triggers timer action)
*/
@ -227,41 +181,6 @@ private:
* This function authorizes a user request
*/
void authorize_action(AuthRequest * ar);
/**
* This function is periodically executed to check time_outs on requests
*/
void timer_action();
/**
* Function to lock the pool
*/
void lock()
{
pthread_mutex_lock(&mutex);
};
/**
* Function to unlock the pool
*/
void unlock()
{
pthread_mutex_unlock(&mutex);
};
/**
* Add a new request to the Request map
* @param ar pointer to the AuthRequest
* @return the id for the request
*/
int add_request(AuthRequest *ar);
/**
* Gets request from the Request map
* @param id for the request
* @return pointer to the AuthRequest
*/
AuthRequest * get_request(int id);
};
#endif /*AUTH_MANAGER_H*/

View File

@ -24,6 +24,8 @@
#include "SSLTools.h"
#include "AuthManager.h"
#include "SyncRequest.h"
using namespace std;
/**
@ -31,19 +33,10 @@ using namespace std;
* request to the AuthManager. The result of the request will be stored
* in the result and message attributes of this class.
*/
class AuthRequest : public ActionListener
class AuthRequest : public SyncRequest
{
public:
AuthRequest(int _uid, int _gid):
result(false),
timeout(false),
uid(_uid),
gid(_gid),
time_out(0),
self_authorize(true)
{
am.addListener(this);
};
AuthRequest(int _uid, int _gid): uid(_uid),gid(_gid),self_authorize(true){};
~AuthRequest(){};
@ -143,24 +136,6 @@ public:
return oss.str();
};
/**
* Notify client that we have an answer for the request
*/
void notify()
{
am.trigger(ActionListener::ACTION_FINALIZE,0);
};
/**
* Wait for the AuthRequest to be completed
*/
void wait()
{
time_out = time(0) + AuthManager::time_out();
am.loop(0,0);
};
bool core_authorize()
{
return ( uid == 0 || self_authorize );
@ -173,35 +148,10 @@ public:
return (password == sha1_session);
}
/**
* The result of the request, true if authorized or authenticated
*/
bool result;
/**
* Error message for negative results
*/
string message;
/**
* Time out
*/
bool timeout;
/**
* Identification of this request
*/
int id;
private:
friend class AuthManager;
/**
* The ActionManager that will be notify when the request is ready.
*/
ActionManager am;
/**
* The user id for this request
*/
@ -212,11 +162,6 @@ private:
*/
int gid;
/**
* Timeout for this request
*/
time_t time_out;
/**
* Username to authenticate the user
*/
@ -247,11 +192,6 @@ private:
*/
bool self_authorize;
/**
* No actions defined for the Auth request, just FINALIZE when done
*/
void do_action(const string &name, void *args){};
/**
* Adds a new authorization item to this request, with a template for
* a new object

View File

@ -30,6 +30,8 @@
using namespace std;
class SyncRequest;
extern "C" void * mad_manager_listener(void * _mm);
/**
@ -55,6 +57,11 @@ public:
*/
virtual void load_mads(int uid) = 0;
/**
* Notify the result of an auth request
*/
void notify_request(int id, bool result, const string& message);
protected:
MadManager(vector<const Attribute *>& _mads);
@ -94,6 +101,40 @@ protected:
*/
int add(Mad *mad);
/**
* This function can be periodically executed to check time_outs on
* request. It will fail requests with an expired timeout and will notify
* the clients.
*/
void check_time_outs_action();
/**
* Add a new request to the Request map
* @param ar pointer to the request
* @return the id for the request
*/
int add_request(SyncRequest *ar);
/**
* Gets request from the Request map
* @param id for the request
* @return pointer to the Request
*/
SyncRequest * get_request(int id);
/**
* Discards a pending request. Call this before freeing not notified or
* timeout requests.
*/
void discard_request(int id)
{
lock();
sync_requests.erase(id);
unlock();
}
private:
/**
* Function to lock the Manager
@ -156,6 +197,11 @@ private:
*/
ostringstream buffer;
/**
* List of pending requests
*/
map<int, SyncRequest *> sync_requests;
/**
* Listener thread implementation.
*/

View File

@ -24,8 +24,6 @@
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
time_t AuthManager::_time_out;
const char * AuthManager::auth_driver_name = "auth_exe";
/* -------------------------------------------------------------------------- */
@ -126,7 +124,7 @@ extern "C" void * authm_action_loop(void *arg)
NebulaLog::log("AuM",Log::INFO,"Authorization Manager started.");
authm->am.loop(authm->timer_period,0);
authm->am.loop(authm->timer_period, 0);
NebulaLog::log("AuM",Log::INFO,"Authorization Manager stopped.");
@ -204,7 +202,7 @@ void AuthManager::do_action(const string &action, void * arg)
}
else if (action == ACTION_TIMER)
{
timer_action();
check_time_outs_action();
}
else if (action == ACTION_FINALIZE)
{
@ -249,7 +247,6 @@ void AuthManager::authenticate_action(AuthRequest * ar)
// Make the request to the driver
// ---- --------------------------------------------------------------------
authm_md->authenticate(ar->id,
ar->uid,
ar->driver,
@ -313,116 +310,6 @@ error:
return;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void AuthManager::timer_action()
{
map<int,AuthRequest *>::iterator it;
time_t the_time = time(0);
lock();
it = auth_requests.begin();
while ( it !=auth_requests.end())
{
if ((it->second->time_out != 0) && (the_time > it->second->time_out))
{
AuthRequest * ar = it->second;
auth_requests.erase(it++);
ar->result = false;
ar->timeout = true;
ar->message = "Auth request timeout";
ar->notify();
}
else
{
++it;
}
}
unlock();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int AuthManager::add_request(AuthRequest *ar)
{
static int auth_id = 0;
int id;
lock();
id = auth_id++;
auth_requests.insert(auth_requests.end(),make_pair(id,ar));
unlock();
return id;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
AuthRequest * AuthManager::get_request(int id)
{
AuthRequest * ar = 0;
map<int,AuthRequest *>::iterator it;
ostringstream oss;
lock();
it=auth_requests.find(id);
if ( it != auth_requests.end())
{
ar = it->second;
auth_requests.erase(it);
}
unlock();
return ar;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void AuthManager::notify_request(int auth_id,bool result,const string& message)
{
AuthRequest * ar;
ar = get_request(auth_id);
if ( ar == 0 )
{
return;
}
ar->result = result;
if ( message != "-" )
{
if ( !ar->message.empty() )
{
ar->message.append("; ");
}
ar->message.append(message);
}
ar->notify();
}
/* ************************************************************************** */
/* MAD Loading */
/* ************************************************************************** */

View File

@ -22,6 +22,7 @@
#include <sstream>
#include "MadManager.h"
#include "SyncRequest.h"
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
@ -336,3 +337,113 @@ void MadManager::listener()
}
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void MadManager::check_time_outs_action()
{
map<int, SyncRequest *>::iterator it;
time_t the_time = time(0);
lock();
it = sync_requests.begin();
while ( it != sync_requests.end())
{
if ((it->second->time_out != 0) && (the_time > it->second->time_out))
{
SyncRequest * ar = it->second;
sync_requests.erase(it++);
ar->result = false;
ar->timeout = true;
ar->message = "Request timeout";
ar->notify();
}
else
{
++it;
}
}
unlock();
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int MadManager::add_request(SyncRequest *ar)
{
static int request_id = 0;
int id;
lock();
id = request_id++;
sync_requests.insert(sync_requests.end(),make_pair(id,ar));
unlock();
return id;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
SyncRequest * MadManager::get_request(int id)
{
SyncRequest * ar = 0;
map<int,SyncRequest *>::iterator it;
ostringstream oss;
lock();
it = sync_requests.find(id);
if ( it != sync_requests.end())
{
ar = it->second;
sync_requests.erase(it);
}
unlock();
return ar;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
void MadManager::notify_request(int id, bool result, const string& message)
{
SyncRequest * ar;
ar = get_request(id);
if ( ar == 0 )
{
return;
}
ar->result = result;
if ( message != "-" )
{
if ( !ar->message.empty() )
{
ar->message.append("; ");
}
ar->message.append(message);
}
ar->notify();
}

View File

@ -500,8 +500,7 @@ void Nebula::start()
if (!auth_mads.empty())
{
//Defaults 60s to timeout auth requests
authm = new AuthManager(timer_period,60,auth_mads);
authm = new AuthManager(timer_period, auth_mads);
}
else
{