diff --git a/include/FixedLeases.h b/include/FixedLeases.h index 69d8a014f6..b83bb92e6a 100644 --- a/include/FixedLeases.h +++ b/include/FixedLeases.h @@ -150,6 +150,13 @@ private: * @return 0 if success */ int unset(const string& ip); + + /** + * Updates the DB entry for this lease + * @param lease Lease to be updated + * @return 0 if success + */ + int update_lease(Lease * lease); }; #endif /*FIXED_LEASES_H_*/ diff --git a/include/Leases.h b/include/Leases.h index 55e5811a84..34047e4bb5 100644 --- a/include/Leases.h +++ b/include/Leases.h @@ -18,6 +18,7 @@ #define LEASES_H_ #include "ObjectSQL.h" +#include "ObjectXML.h" #include "Attribute.h" #include @@ -40,7 +41,8 @@ public: * @param _size the max number of leases */ Leases(SqlDB * _db, int _oid, unsigned long _size): - oid(_oid), size(_size), db(_db){}; + ObjectSQL(), + oid(_oid), size(_size), n_used(0), db(_db){}; virtual ~Leases() { @@ -108,7 +110,7 @@ protected: * The Lease class, it represents a pair of IP and MAC assigned to * a Virtual Machine */ - class Lease + class Lease : public ObjectXML { public: /** @@ -129,13 +131,19 @@ protected: * @param _used, the lease is in use */ Lease(unsigned int _ip, unsigned int _mac[], int _vid, bool _used=true) - :ip(_ip), vid(_vid), used(_used) + :ObjectXML(),ip(_ip), vid(_vid), used(_used) { // TODO check size mac[PREFIX]=_mac[PREFIX]; mac[SUFFIX]=_mac[SUFFIX]; }; + /** + * Creates a new empty lease. Method from_xml should be called right + * after this constructor. + */ + Lease():ObjectXML(){}; + ~Lease(){}; /** @@ -172,14 +180,6 @@ protected: */ friend ostream& operator<<(ostream& os, Lease& _lease); - /** - * Function to print the Lease object into a string in - * plain text - * @param str the resulting string - * @return a reference to the generated string - */ - string& to_str(string& str) const; - /** * Function to print the Lease object into a string in * XML format @@ -188,6 +188,23 @@ protected: */ string& to_xml(string& xml) const; + /** + * Function to print the Lease object into a string in + * XML format. The output contains all the internal attributes, + * to be saved in the DB as a blob + * @param xml the resulting XML string + * @return a reference to the generated string + */ + string& to_xml_db(string& xml) const; + + /** + * Rebuilds the object from an xml formatted string + * @param xml_str The xml-formatted string + * + * @return 0 on success, -1 otherwise + */ + int from_xml(const string &xml_str); + /** * Constants to access the array storing the MAC address */ @@ -227,6 +244,11 @@ protected: */ map leases; + /** + * Number of used leases + */ + int n_used; + // ------------------------------------------------------------------------- // DataBase implementation variables // ------------------------------------------------------------------------- @@ -235,17 +257,6 @@ protected: */ SqlDB * db; - enum ColNames - { - OID = 0, - IP = 1, - MAC_PREFIX = 2, - MAC_SUFFIX = 3, - VID = 4, - USED = 5, - LIMIT = 6 - }; - static const char * table; static const char * db_names; @@ -274,14 +285,6 @@ protected: friend ostream& operator<<(ostream& os, Lease& _lease); - /** - * Function to print the Leases object into a string in - * plain text - * @param str the resulting string - * @return a reference to the generated string - */ - string& to_str(string& str) const; - /** * Function to print the Leases object into a string in * XML format diff --git a/include/ObjectXML.h b/include/ObjectXML.h index 857b8d316c..c492fdf78b 100644 --- a/include/ObjectXML.h +++ b/include/ObjectXML.h @@ -82,6 +82,18 @@ public: */ int xpath(int& value, const char * xpath_expr, const int& def); + /** + * Gets and sets a xpath attribute, if the attribute is not found a default + * is used + * @param value to set + * @param xpath_expr of the xml element + * @param def default value if the element is not found + * + * @return -1 if default was set + */ + int xpath(unsigned int& value, const char * xpath_expr, + const unsigned int& def); + /** * Gets and sets a xpath attribute, if the attribute is not found a default * is used diff --git a/include/VirtualNetwork.h b/include/VirtualNetwork.h index 46fb6e03ca..2591a01531 100644 --- a/include/VirtualNetwork.h +++ b/include/VirtualNetwork.h @@ -175,14 +175,6 @@ public: */ friend ostream& operator<<(ostream& os, VirtualNetwork& vn); - /** - * Function to print the VirtualNetwork object into a string in - * plain text - * @param str the resulting string - * @return a reference to the generated string - */ - string& to_str(string& str) const; - /** * Function to print the VirtualNetwork object into a string in * XML format @@ -283,6 +275,11 @@ private: */ int uid; + /** + * Owner's name + */ + string user_name; + // ------------------------------------------------------------------------- // Binded physical attributes // ------------------------------------------------------------------------- @@ -350,11 +347,21 @@ private: int select_cb(void * nil, int num, char **values, char **names); /** - * Function to drop VN entry in vn_pool - * @return 0 on success + * Function to print the VirtualNetwork object into a string in + * XML format + * @param xml the resulting XML string + * @param extended If true, leases are included + * @return a reference to the generated string */ - int vn_drop(SqlDB * db); + string& to_xml_extended(string& xml, bool extended) const; + /** + * Rebuilds the object from an xml formatted string + * @param xml_str The xml-formatted string + * + * @return 0 on success, -1 otherwise + */ + int from_xml(const string &xml_str); protected: @@ -362,7 +369,7 @@ protected: // Constructor //************************************************************************** - VirtualNetwork(VirtualNetworkTemplate * _vn_template = 0); + VirtualNetwork(string _user_name,VirtualNetworkTemplate * _vn_template = 0); ~VirtualNetwork(); @@ -370,18 +377,6 @@ protected: // DataBase implementation // ************************************************************************* - enum ColNames - { - OID = 0, - UID = 1, - NAME = 2, - TYPE = 3, - BRIDGE = 4, - PUBLIC = 5, - TEMPLATE = 6, - LIMIT = 7 - }; - static const char * table; static const char * db_names; @@ -418,27 +413,7 @@ protected: * @param db pointer to the db * @return 0 on success */ - int drop(SqlDB * db) - { - int rc; - - rc = leases->drop(db); - - rc += vn_drop(db); - - return rc; - } - - /** - * Dumps the contect of a VirtualNetwork object in the given stream using - * XML format - * @param oss the output stream - * @param num the number of columns read from the DB - * @param names the column names - * @param vaues the column values - * @return 0 on success - */ - static int dump(ostringstream& oss, int num, char **values, char **names); + int drop(SqlDB * db); }; #endif /*VIRTUAL_NETWORK_H_*/ diff --git a/include/VirtualNetworkPool.h b/include/VirtualNetworkPool.h index 7286c8d88b..0a4faae146 100644 --- a/include/VirtualNetworkPool.h +++ b/include/VirtualNetworkPool.h @@ -48,6 +48,7 @@ public: */ int allocate ( int uid, + string user_name, VirtualNetworkTemplate * vn_template, int * oid, string& error_str); @@ -150,7 +151,7 @@ private: */ PoolObjectSQL * create() { - return new VirtualNetwork(); + return new VirtualNetwork("", 0); }; /** diff --git a/src/rm/RequestManagerVirtualNetworkAllocate.cc b/src/rm/RequestManagerVirtualNetworkAllocate.cc index 75082ce8eb..812daf5111 100644 --- a/src/rm/RequestManagerVirtualNetworkAllocate.cc +++ b/src/rm/RequestManagerVirtualNetworkAllocate.cc @@ -28,10 +28,12 @@ void RequestManager::VirtualNetworkAllocate::execute( { string session; string name; + string user_name; string str_template; string error_str; VirtualNetworkTemplate * vn_template; + User * user; int nid; int uid; @@ -96,10 +98,25 @@ void RequestManager::VirtualNetworkAllocate::execute( } } + //-------------------------------------------------------------------------- + // Get the User Name + //-------------------------------------------------------------------------- + + user = VirtualNetworkAllocate::upool->get(uid,true); + + if ( user == 0 ) + { + goto error_user_get; + } + + user_name = user->get_username(); + + user->unlock(); + //-------------------------------------------------------------------------- // Allocate the Virtual Network //-------------------------------------------------------------------------- - rc = vnpool->allocate(uid,vn_template,&nid,error_str); + rc = vnpool->allocate(uid,user_name,vn_template,&nid,error_str); if ( rc < 0 ) { @@ -118,6 +135,12 @@ void RequestManager::VirtualNetworkAllocate::execute( return; +error_user_get: + oss.str(get_error(method_name, "USER", uid)); + + delete vn_template; + goto error_common; + error_authenticate: oss.str(authenticate_error(method_name)); goto error_common; diff --git a/src/vnm/FixedLeases.cc b/src/vnm/FixedLeases.cc index ca5d87e28c..da4d13b0f0 100644 --- a/src/vnm/FixedLeases.cc +++ b/src/vnm/FixedLeases.cc @@ -62,6 +62,10 @@ int FixedLeases::add(const string& ip, const string& mac, int vid, unsigned int _ip; unsigned int _mac [2]; + Lease * lease; + string xml_body; + char * sql_xml; + int rc; if ( Leases::Lease::ip_to_number(ip,_ip) ) @@ -84,13 +88,19 @@ int FixedLeases::add(const string& ip, const string& mac, int vid, goto error_mac; } - oss << "INSERT INTO " << table << " ("<< db_names <<") VALUES (" << - oid << "," << - _ip << "," << - _mac[Lease::PREFIX] << "," << - _mac[Lease::SUFFIX] << "," << - vid << "," << - used << ")"; + lease = new Lease(_ip,_mac,vid,used); + + sql_xml = db->escape_str(lease->to_xml_db(xml_body).c_str()); + + if ( sql_xml == 0 ) + { + goto error_body; + } + + oss << "INSERT INTO " << table << " ("<< db_names <<") VALUES (" + << oid << "," + << _ip << "," + << "'" << sql_xml << "')"; rc = db->exec(oss); @@ -99,10 +109,21 @@ int FixedLeases::add(const string& ip, const string& mac, int vid, goto error_db; } - leases.insert(make_pair(_ip,new Lease(_ip,_mac,vid,used))); + leases.insert( make_pair(_ip,lease) ); + + if(lease->used) + { + n_used++; + } + return rc; +error_body: + oss.str(""); + oss << "Error inserting lease, marshall error"; + goto error_common; + error_ip: oss.str(""); oss << "Error inserting lease, malformed IP = " << ip; @@ -202,7 +223,6 @@ error_common: int FixedLeases::unset(const string& ip) { unsigned int _ip; - ostringstream oss; map::iterator it_ip; @@ -219,14 +239,11 @@ int FixedLeases::unset(const string& ip) } // Flip used flag to false - it_ip->second->used = false; it_ip->second->vid = -1; - oss << "UPDATE " << table << " SET used='0', vid='-1' " - << " WHERE oid=" << oid << " AND ip='" << _ip <<"'"; - - return db->exec(oss); + // Update the lease + return update_lease(it_ip->second); } /* -------------------------------------------------------------------------- */ @@ -234,7 +251,7 @@ int FixedLeases::unset(const string& ip) int FixedLeases::get(int vid, string& ip, string& mac) { - int rc = -1; + int rc = -1; if (leases.empty()) { @@ -252,22 +269,14 @@ int FixedLeases::get(int vid, string& ip, string& mac) { ostringstream oss; - oss << "UPDATE " << table << " SET used='1', vid='" << vid - << "' WHERE oid=" << oid - << " AND ip='" << current->second->ip <<"'"; + current->second->used = true; + current->second->vid = vid; - rc = db->exec(oss); + rc = update_lease(current->second); - if ( rc == 0 ) - { - current->second->used = true; - current->second->vid = vid; - - current->second->to_string(ip,mac); - - current++; - } + current->second->to_string(ip,mac); + current++; break; } } @@ -282,7 +291,6 @@ int FixedLeases::set(int vid, const string& ip, string& mac) { map::iterator it; - ostringstream oss; unsigned int num_ip; int rc; @@ -304,22 +312,43 @@ int FixedLeases::set(int vid, const string& ip, string& mac) return -1; } - oss << "UPDATE " << table << " SET used='1', vid='" << vid << "'" - << " WHERE oid=" << oid << " AND ip='" << it->second->ip <<"'"; - - rc = db->exec(oss); - - if ( rc != 0 ) - { - return -1; - } - it->second->used = true; it->second->vid = vid; Leases::Lease::mac_to_string(it->second->mac,mac); - return 0; + return update_lease(it->second); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int FixedLeases::update_lease(Lease * lease) +{ + ostringstream oss; + string xml_body; + char * sql_xml; + + sql_xml = db->escape_str(lease->to_xml_db(xml_body).c_str()); + + if ( sql_xml == 0 ) + { + return -1; + } + + if( lease->used ) + { + n_used++; + } + else + { + n_used--; + } + + oss << "UPDATE " << table << " SET body='" << sql_xml << "'" + << " WHERE oid=" << oid << " AND ip='" << lease->ip <<"'"; + + return db->exec(oss); } /* -------------------------------------------------------------------------- */ diff --git a/src/vnm/Leases.cc b/src/vnm/Leases.cc index 4fb52351d1..5933470477 100644 --- a/src/vnm/Leases.cc +++ b/src/vnm/Leases.cc @@ -181,6 +181,8 @@ void Leases::Lease::mac_to_string(const unsigned int i_mac[], string& mac) mac = oss.str(); } +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ ostream& operator<<(ostream& os, Leases::Lease& _lease) { @@ -191,32 +193,8 @@ ostream& operator<<(ostream& os, Leases::Lease& _lease) return os; } -string& Leases::Lease::to_str(string& str) const -{ - string ip; - string mac; - - ostringstream os; - - to_string(ip,mac); - - ip = "IP = " + ip; - mac = "MAC = " + mac; - - os.width(20); - os << left << ip; - - os.width(24); - os << left << mac; - - os << left << " USED = " << used; - os << left << " VID = " << vid; - - str = os.str(); - - return str; -} - +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ string& Leases::Lease::to_xml(string& str) const { @@ -229,10 +207,10 @@ string& Leases::Lease::to_xml(string& str) const os << "" << - ""<< ip << "" << - "" << mac << "" << - "" << used << "" << - "" << vid << "" << + "" << ip << "" << + "" << mac << "" << + ""<< used << ""<< + "" << vid << "" << ""; str = os.str(); @@ -240,6 +218,54 @@ string& Leases::Lease::to_xml(string& str) const return str; } +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +string& Leases::Lease::to_xml_db(string& str) const +{ + ostringstream os; + + os << + "" << + "" << ip << "" << + "" << mac[Lease::PREFIX] << "" << + "" << mac[Lease::SUFFIX] << "" << + "" << used << ""<< + "" << vid << "" << + ""; + + str = os.str(); + + return str; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +int Leases::Lease::from_xml(const string &xml_str) +{ + int rc = 0; + int int_used; + + // Initialize the internal XML object + update_from_str(xml_str); + + rc += xpath(ip , "/LEASE/IP" , 0); + rc += xpath(mac[Lease::PREFIX], "/LEASE/MAC_PREFIX" , 0); + rc += xpath(mac[Lease::SUFFIX], "/LEASE/MAC_SUFFIX" , 0); + rc += xpath(int_used , "/LEASE/USED" , 0); + rc += xpath(vid , "/LEASE/VID" , 0); + + used = static_cast(int_used); + + if (rc != 0) + { + return -1; + } + + return 0; +} + /* ************************************************************************** */ /* ************************************************************************** */ /* Leases class */ @@ -248,55 +274,38 @@ string& Leases::Lease::to_xml(string& str) const const char * Leases::table = "leases"; -const char * Leases::db_names = "oid,ip,mac_prefix,mac_suffix,vid,used"; +const char * Leases::db_names = "oid, ip, body"; const char * Leases::db_bootstrap = "CREATE TABLE IF NOT EXISTS leases (" - "oid INTEGER, ip BIGINT, mac_prefix BIGINT, mac_suffix BIGINT," - "vid INTEGER, used INTEGER, PRIMARY KEY(oid,ip))"; + "oid INTEGER, ip BIGINT, body TEXT, PRIMARY KEY(oid,ip))"; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ int Leases::select_cb(void *nil, int num, char **values, char **names) { - if ( (values[OID] == 0) || - (values[IP] == 0) || - (values[MAC_PREFIX] == 0) || - (values[MAC_SUFFIX] == 0) || - (values[VID] == 0) || - (values[USED]== 0) || - (num != LIMIT )) + Lease * lease; + int rc; + + if ( (!values[0]) || (num != 1) ) { return -1; } - unsigned int mac[2]; - unsigned int ip; - int vid; - bool used; + lease = new Lease(); + rc = lease->from_xml(values[0]); - istringstream iss; + if (rc != 0) + { + return -1; + } - iss.str(values[IP]); - iss >> ip; + leases.insert(make_pair(lease->ip, lease)); - iss.clear(); - iss.str(values[MAC_PREFIX]); - iss >> mac[Lease::PREFIX]; - - iss.clear(); - iss.str(values[MAC_SUFFIX]); - iss >> mac[Lease::SUFFIX]; - - iss.clear(); - iss.str(values[VID]); - iss >> vid; - - iss.clear(); - iss.str(values[USED]); - iss >> used; - - leases.insert(make_pair(ip,new Lease(ip,mac,vid,used))); + if(lease->used) + { + n_used++; + } return 0; } @@ -308,9 +317,12 @@ int Leases::select(SqlDB * db) ostringstream oss; int rc; + // Reset the used leases counter + n_used = 0; + set_callback(static_cast(&Leases::select_cb)); - oss << "SELECT " << db_names << " FROM " << table << " WHERE oid = " << oid; + oss << "SELECT body FROM " << table << " WHERE oid = " << oid; rc = db->exec(oss,this); @@ -434,25 +446,6 @@ string& Leases::to_xml(string& xml) const /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -string& Leases::to_str(string& str) const -{ - map::const_iterator it; - ostringstream os; - string lease_str; - - for(it=leases.begin();it!=leases.end();it++) - { - os << it->second->to_str(lease_str) << endl; - } - - str = os.str(); - - return str; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - ostream& operator<<(ostream& os, Leases& _leases) { string xml; diff --git a/src/vnm/RangedLeases.cc b/src/vnm/RangedLeases.cc index ef76145e96..8b07a02f24 100644 --- a/src/vnm/RangedLeases.cc +++ b/src/vnm/RangedLeases.cc @@ -132,26 +132,54 @@ int RangedLeases::add( int vid, bool used) { - ostringstream oss; - int rc; + ostringstream oss; - //Insert the lease in the database - oss << "INSERT INTO " << table << " ("<< db_names <<") VALUES ("<< - oid << "," << - ip << "," << - mac[Lease::PREFIX] << "," << - mac[Lease::SUFFIX] << "," << - vid << "," << - used << ")"; + Lease * lease; + string xml_body; + char * sql_xml; + + int rc; + + lease = new Lease(ip,mac,vid,used); + + sql_xml = db->escape_str(lease->to_xml_db(xml_body).c_str()); + + if ( sql_xml == 0 ) + { + goto error_body; + } + + oss << "INSERT INTO " << table << " ("<< db_names <<") VALUES (" + << oid << "," + << ip << "," + << "'" << sql_xml << "')"; rc = db->exec(oss); - if ( rc == 0 ) + if ( rc != 0 ) { - leases.insert(make_pair(ip,new Lease(ip,mac,vid,used))); + goto error_db; } + leases.insert( make_pair(ip,lease) ); + + n_used++; + return rc; + + +error_body: + oss.str(""); + oss << "Error inserting lease, marshall error"; + goto error_common; + +error_db: + oss.str(""); + oss << "Error inserting lease in database."; + +error_common: + NebulaLog::log("VNM", Log::ERROR, oss); + return -1; } /* -------------------------------------------------------------------------- */ @@ -187,6 +215,8 @@ int RangedLeases::del(const string& ip) if ( rc == 0 ) { + n_used--; + delete it_ip->second; leases.erase(it_ip); diff --git a/src/vnm/VirtualNetwork.cc b/src/vnm/VirtualNetwork.cc index d838ea1067..00731c01f6 100644 --- a/src/vnm/VirtualNetwork.cc +++ b/src/vnm/VirtualNetwork.cc @@ -29,10 +29,12 @@ /* Virtual Network :: Constructor/Destructor */ /* ************************************************************************** */ -VirtualNetwork::VirtualNetwork(VirtualNetworkTemplate *_vn_template): - PoolObjectSQL(-1), +VirtualNetwork::VirtualNetwork(string _user_name, + VirtualNetworkTemplate *_vn_template): + PoolObjectSQL(-1, table), name(""), uid(-1), + user_name(_user_name), bridge(""), type(UNINITIALIZED), leases(0) @@ -69,51 +71,11 @@ VirtualNetwork::~VirtualNetwork() const char * VirtualNetwork::table = "network_pool"; -const char * VirtualNetwork::db_names = - "oid,uid,name,type,bridge,public,template"; - -const char * VirtualNetwork::extended_db_names = - "network_pool.oid, network_pool.uid, network_pool.name, network_pool.type, " - "network_pool.bridge, network_pool.public, network_pool.template"; +const char * VirtualNetwork::db_names = "oid, name, body"; const char * VirtualNetwork::db_bootstrap = "CREATE TABLE IF NOT EXISTS" - " network_pool (" - "oid INTEGER PRIMARY KEY, uid INTEGER, name VARCHAR(256), type INTEGER, " - "bridge TEXT, public INTEGER, template TEXT, UNIQUE(name))"; - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - -int VirtualNetwork::select_cb(void * nil, int num, char **values, char **names) -{ - if ((!values[OID]) || - (!values[UID]) || - (!values[NAME]) || - (!values[TYPE]) || - (!values[BRIDGE]) || - (!values[PUBLIC]) || - (!values[TEMPLATE]) || - (num != LIMIT )) - { - return -1; - } - - oid = atoi(values[OID]); - uid = atoi(values[UID]); - - name = values[NAME]; - - type = (NetworkType)atoi(values[TYPE]); - - bridge = values[BRIDGE]; - - public_vnet = atoi(values[PUBLIC]); - - // Virtual Network template - vn_template->from_xml(values[TEMPLATE]); - - return 0; -} + " network_pool " + "(oid INTEGER PRIMARY KEY, name VARCHAR(256), body TEXT, UNIQUE(name))"; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ @@ -124,28 +86,19 @@ int VirtualNetwork::select(SqlDB * db) ostringstream ose; int rc; - int boid; string network_address; unsigned int default_size = VirtualNetworkPool::default_size(); unsigned int mac_prefix = VirtualNetworkPool::mac_prefix(); - set_callback( - static_cast(&VirtualNetwork::select_cb)); - oss << "SELECT " << db_names << " FROM " << table << " WHERE oid = " << oid; + // Rebuld the VirtualNetwork object + rc = PoolObjectSQL::select(db); - boid = oid; - oid = -1; - - rc = db->exec(oss, this); - - unset_callback(); - - if ((rc != 0) || (oid != boid )) + if( rc != 0 ) { - goto error_id; + return rc; } //Get the leases @@ -207,9 +160,6 @@ int VirtualNetwork::select(SqlDB * db) return leases->select(db); -error_id: - ose << "Error getting Virtual Network nid: " << oid; - goto error_common; error_leases: ose << "Error getting Virtual Network leases nid: " << oid; @@ -230,43 +180,6 @@ error_common: /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int VirtualNetwork::dump(ostringstream& oss, - int num, - char ** values, - char ** names) -{ - if ((!values[OID]) || - (!values[UID]) || - (!values[NAME]) || - (!values[TYPE]) || - (!values[BRIDGE]) || - (!values[PUBLIC]) || - (!values[TEMPLATE]) || - (!values[LIMIT]) || - (num != LIMIT + 2 )) - { - return -1; - } - - oss << - "" << - "" << values[OID] << "" << - "" << values[UID] << "" << - "" << values[LIMIT+1] << "" << - "" << values[NAME] << "" << - "" << values[TYPE] << "" << - "" << values[BRIDGE] << "" << - "" << values[PUBLIC] << "" << - ""<< values[LIMIT] << "" - << values[TEMPLATE] << - ""; - - return 0; -} - -/* -------------------------------------------------------------------------- */ -/* -------------------------------------------------------------------------- */ - int VirtualNetwork::insert(SqlDB * db, string& error_str) { ostringstream ose; @@ -444,23 +357,24 @@ error_common: /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ - int VirtualNetwork::update(SqlDB * db) { return insert_replace(db, true); } +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int VirtualNetwork::insert_replace(SqlDB *db, bool replace) { ostringstream oss; int rc; - string xml_template; + string xml_body; char * sql_name; - char * sql_bridge; - char * sql_template; + char * sql_xml; sql_name = db->escape_str(name.c_str()); @@ -470,22 +384,13 @@ int VirtualNetwork::insert_replace(SqlDB *db, bool replace) goto error_name; } - sql_bridge = db->escape_str(bridge.c_str()); + sql_xml = db->escape_str(to_xml(xml_body).c_str()); - if ( sql_bridge == 0 ) + if ( sql_xml == 0 ) { - goto error_bridge; + goto error_body; } - vn_template->to_xml(xml_template); - sql_template = db->escape_str(xml_template.c_str()); - - if ( sql_template == 0 ) - { - goto error_template; - } - - // Construct the SQL statement to Insert or Replace if(replace) { @@ -498,24 +403,18 @@ int VirtualNetwork::insert_replace(SqlDB *db, bool replace) oss << " INTO " << table << " (" << db_names << ") VALUES (" << oid << "," - << uid << "," << "'" << sql_name << "'," - << type << "," - << "'" << sql_bridge << "'," - << public_vnet << "," - << "'" << sql_template<< "')"; + << "'" << sql_xml << "')"; rc = db->exec(oss); db->free_str(sql_name); - db->free_str(sql_bridge); - db->free_str(sql_template); + db->free_str(sql_xml); return rc; -error_template: - db->free_str(sql_bridge); -error_bridge: + +error_body: db->free_str(sql_name); error_name: return -1; @@ -524,30 +423,20 @@ error_name: /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int VirtualNetwork::vn_drop(SqlDB * db) +int VirtualNetwork::drop(SqlDB * db) { - ostringstream oss; - int rc; + int rc; - if ( leases != 0 ) + rc = PoolObjectSQL::drop(db); + + if ( rc == 0 && leases != 0 ) { - leases->drop(db); - } - - oss << "DELETE FROM " << table << " WHERE OID=" << oid; - - rc = db->exec(oss); - - if ( rc == 0 ) - { - set_valid(false); + rc += leases->drop(db); } return rc; } - - /* ************************************************************************** */ /* Virtual Network :: Misc */ /* ************************************************************************** */ @@ -556,7 +445,7 @@ ostream& operator<<(ostream& os, VirtualNetwork& vn) { string vnet_xml; - os << vn.to_xml(vnet_xml); + os << vn.to_xml_extended(vnet_xml, true); return os; }; @@ -565,25 +454,45 @@ ostream& operator<<(ostream& os, VirtualNetwork& vn) /* -------------------------------------------------------------------------- */ string& VirtualNetwork::to_xml(string& xml) const +{ + return to_xml_extended(xml, false); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +string& VirtualNetwork::to_xml_extended(string& xml, bool extended) const { ostringstream os; string template_xml; string leases_xml; + // Total leases is the number of used leases. + int total_leases = 0; + + if (leases != 0) + { + total_leases = leases->n_used; + } + os << "" << - "" << oid << "" << - "" << uid << "" << - "" << name << "" << - "" << type << "" << - "" << bridge << "" << - "" << public_vnet << "" << + "" << oid << "" << + "" << uid << "" << + "" << user_name << "" << + "" << name << "" << + "" << type << "" << + "" << bridge << "" << + "" << public_vnet << "" << + ""<< total_leases << ""<< vn_template->to_xml(template_xml); - if (leases) + + if (extended && leases != 0) { os << leases->to_xml(leases_xml); } + os << ""; xml = os.str(); @@ -594,40 +503,44 @@ string& VirtualNetwork::to_xml(string& xml) const /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -string& VirtualNetwork::to_str(string& str) const +int VirtualNetwork::from_xml(const string &xml_str) { - ostringstream os; + vector content; - string template_str; - string leases_str; + int rc = 0; + int int_type; - os << "ID : " << oid << endl; - os << "UID : " << uid << endl; - os << "NAME : " << name << endl; - os << "Type : "; - if ( type==VirtualNetwork::RANGED ) + // Initialize the internal XML object + update_from_str(xml_str); + + // Get class base attributes + rc += xpath(oid, "/VNET/ID", -1); + rc += xpath(uid, "/VNET/UID", -1); + rc += xpath(user_name, "/VNET/USERNAME", "not_found"); + rc += xpath(name, "/VNET/NAME", "not_found"); + rc += xpath(int_type, "/VNET/TYPE", -1); + rc += xpath(bridge, "/VNET/BRIDGE", "not_found"); + rc += xpath(public_vnet,"/VNET/PUBLIC", 0); + + type = static_cast( int_type ); + + // Get associated classes + ObjectXML::get_nodes("/VNET/TEMPLATE", content); + + if( content.size() < 1 ) { - os << "Ranged" << endl; - } - else - { - os << "Fixed" << endl; + return -1; } - os << "Bridge : " << bridge << endl; - os << "Public : " << public_vnet << endl << endl; + // Virtual Network template + rc += vn_template->from_xml_node( content[0] ); - os << "....: Template :...." << vn_template->to_str(template_str) << endl << -endl; - - if (leases) + if (rc != 0) { - os << "....: Leases :...." << endl << leases->to_str(leases_str) << endl; + return -1; } - str = os.str(); - - return str; + return 0; } /* -------------------------------------------------------------------------- */ diff --git a/src/vnm/VirtualNetworkPool.cc b/src/vnm/VirtualNetworkPool.cc index 19c8a7513e..c75ff4ea50 100644 --- a/src/vnm/VirtualNetworkPool.cc +++ b/src/vnm/VirtualNetworkPool.cc @@ -71,13 +71,14 @@ VirtualNetworkPool::VirtualNetworkPool(SqlDB * db, int VirtualNetworkPool::allocate ( int uid, + string user_name, VirtualNetworkTemplate * vn_template, int * oid, string& error_str) { VirtualNetwork * vn; - vn = new VirtualNetwork(vn_template); + vn = new VirtualNetwork(user_name, vn_template); vn->uid = uid; @@ -171,23 +172,13 @@ int VirtualNetworkPool::dump(ostringstream& oss, const string& where) static_cast(&VirtualNetworkPool::dump_cb), static_cast(&oss)); - cmd << "SELECT " << VirtualNetwork::extended_db_names << ",COUNT(" - << Leases::table << ".used), user_pool.user_name FROM " - << VirtualNetwork::table - << " LEFT OUTER JOIN " << Leases::table << " ON " - << VirtualNetwork::table << ".oid = " << Leases::table << ".oid" - << " AND " << Leases::table << ".used = 1" - << " LEFT OUTER JOIN (SELECT oid,user_name FROM user_pool) " - << " AS user_pool ON "<< VirtualNetwork::table - << ".uid = user_pool.oid"; + cmd << "SELECT body FROM " << VirtualNetwork::table; if ( !where.empty() ) { cmd << " WHERE " << where; } - cmd << " GROUP BY " << VirtualNetwork::table << ".oid"; - rc = db->exec(cmd,this); oss << ""; diff --git a/src/vnm/test/VirtualNetworkPoolTest.cc b/src/vnm/test/VirtualNetworkPoolTest.cc index 248d5d94c6..5249e68736 100644 --- a/src/vnm/test/VirtualNetworkPoolTest.cc +++ b/src/vnm/test/VirtualNetworkPoolTest.cc @@ -20,6 +20,7 @@ #include "VirtualNetworkPool.h" #include "PoolTest.h" +#include "ObjectXML.h" using namespace std; @@ -27,6 +28,7 @@ using namespace std; /* ************************************************************************* */ const int uids[] = {123, 261, 133}; +const string user_names[] = {"A user","B user","C user"}; const string names[] = {"Net number one", "A virtual network","Net number two"}; @@ -69,11 +71,11 @@ const string templates[] = const string xmls[] = { - "0123Net number one1br10130.10.0.150:20:20:20:20:200-1", + "0123A userNet number one1br100130.10.0.150:20:20:20:20:200-1", - "1261A virtual network0br01", + "1261B userA virtual network0br010", - "0133Net number two1br10130.10.2.150:20:20:20:20:200-1" + "0133C userNet number two1br100130.10.2.150:20:20:20:20:200-1" }; const string xml_dump = @@ -97,7 +99,8 @@ public: {}; - int allocate(const int& uid, const std::string& stemplate, int* oid) + int allocate(const int& uid, const std::string& user_name, + const std::string& stemplate, int* oid) { VirtualNetworkTemplate * vn_template; char * error_msg = 0; @@ -109,7 +112,8 @@ public: if( rc == 0 ) { - return VirtualNetworkPool::allocate(uid, vn_template, oid, err); + return VirtualNetworkPool::allocate(uid, user_name, + vn_template, oid, err); } else { @@ -182,41 +186,33 @@ protected: int allocate(int index) { int oid; - return ((VirtualNetworkPoolFriend*)pool)->allocate(uids[index], - templates[index], &oid); + return ((VirtualNetworkPoolFriend*)pool)->allocate( + uids[index],user_names[index],templates[index], &oid); }; void check(int index, PoolObjectSQL* obj) { CPPUNIT_ASSERT( obj != 0 ); - string xml_str = ""; + string xml_str; + ostringstream oss; + + ((VirtualNetwork*)obj)->to_xml(xml_str); + oss << * ((VirtualNetwork*)obj); + + xml_str = oss.str(); +/* + if( xml_str != xmls[index] ) + { + cout << endl << xml_str << endl << "========" + << endl << xmls[index] << endl << "--------"; + } +//*/ CPPUNIT_ASSERT( ((VirtualNetwork*)obj)->get_uid() == uids[index] ); - CPPUNIT_ASSERT( ((VirtualNetwork*)obj)->to_xml(xml_str) == xmls[index] ); + CPPUNIT_ASSERT( xml_str == xmls[index] ); }; - void set_up_user_pool() - { - string err; - - UserPool::bootstrap(db); - UserPool * user_pool = new UserPool(db); - int uid_1, uid_2; - - string username_1 = "A user"; - string username_2 = "B user"; - - string pass_1 = "A pass"; - string pass_2 = "B pass"; - - user_pool->allocate(&uid_1, username_1, pass_1, true, err); - user_pool->allocate(&uid_2, username_2, pass_2, true, err); - - delete user_pool; - }; - - public: VirtualNetworkPoolTest(){xmlInitParser();}; @@ -380,7 +376,7 @@ public: for (int i = 0 ; i < 7 ; i++) { - rc = vnpool->allocate(uids[0], templ[i], &oid[i]); + rc = vnpool->allocate(uids[0], user_names[0], templ[i], &oid[i]); CPPUNIT_ASSERT( rc >= 0 ); vnet = vnpool->get(oid[i], false); @@ -409,22 +405,22 @@ public: VirtualNetwork * vnet; // Allocate a vnet - rc = vnpool->allocate(uids[0], templates[0], &oid_0); + rc = vnpool->allocate(uids[0], user_names[0], templates[0], &oid_0); CPPUNIT_ASSERT( rc == oid_0 ); CPPUNIT_ASSERT( rc == 0 ); // Allocate the same vnet twice, with the same user ID - rc = vnpool->allocate(uids[0], templates[0], &oid_1); + rc = vnpool->allocate(uids[0], user_names[0], templates[0], &oid_1); CPPUNIT_ASSERT( rc == oid_1 ); CPPUNIT_ASSERT( rc == -1 ); // With different user ID - rc = vnpool->allocate(uids[1], templates[0], &oid_1); + rc = vnpool->allocate(uids[1], user_names[1], templates[0], &oid_1); CPPUNIT_ASSERT( rc == oid_1 ); CPPUNIT_ASSERT( rc == -1 ); // Insert a different template, with the same user ID - rc = vnpool->allocate(uids[1], templates[1], &oid_1); + rc = vnpool->allocate(uids[1], user_names[1], templates[1], &oid_1); CPPUNIT_ASSERT( rc == oid_1 ); CPPUNIT_ASSERT( rc == 1 ); @@ -456,16 +452,23 @@ public: int oid, rc; ostringstream oss; - set_up_user_pool(); - - vnpool->allocate(1, templates[0], &oid); - vnpool->allocate(2, templates[1], &oid); + vnpool->allocate(1, user_names[0], templates[0], &oid); + vnpool->allocate(2, user_names[1], templates[1], &oid); rc = pool->dump(oss, ""); CPPUNIT_ASSERT(rc == 0); string result = oss.str(); + +/* + if( result != xml_dump ) + { + cout << endl << result << endl << "========" + << endl << xml_dump << endl << "--------"; + } +//*/ + CPPUNIT_ASSERT( result == xml_dump ); }; @@ -479,17 +482,24 @@ public: int oid, rc; ostringstream oss; - set_up_user_pool(); + vnpool->allocate(1, user_names[0], templates[0], &oid); + vnpool->allocate(2, user_names[1], templates[1], &oid); - vnpool->allocate(1, templates[0], &oid); - vnpool->allocate(2, templates[1], &oid); - - string where = "uid > 1"; + string where = "name LIKE '%virtual%'"; rc = pool->dump(oss, where); CPPUNIT_ASSERT(rc == 0); string result = oss.str(); + +/* + if( result != xml_dump_where ) + { + cout << endl << result << endl << "========" + << endl << xml_dump_where << endl << "--------"; + } +//*/ + CPPUNIT_ASSERT( result == xml_dump_where ); }; @@ -594,7 +604,7 @@ public: "NETWORK_ADDRESS = 192.168.50.0\n"; - vnpool->allocate(45, tmpl, &oid); + vnpool->allocate(45, user_names[0], tmpl, &oid); CPPUNIT_ASSERT( oid != -1 ); vn = vnpool->get(oid, false); @@ -811,15 +821,18 @@ public: string mac = ""; string bridge = ""; + ostringstream oss; + string xpath; + vector results; // First VNet template - vnpool->allocate(13, tmpl_A, &oid_0); + vnpool->allocate(13, user_names[0], tmpl_A, &oid_0); CPPUNIT_ASSERT( oid_0 != -1 ); // Second VNet - vnpool->allocate(45, tmpl_B, &oid_new); + vnpool->allocate(45, user_names[0], tmpl_B, &oid_new); CPPUNIT_ASSERT( oid_new != -1 ); // Get this second VNet @@ -833,15 +846,31 @@ public: CPPUNIT_ASSERT( rc == 0 ); - + // --------------------------------------------------------------------- // The IP ...1 should be tagged as used only in the second Vnet - const char * table = "leases"; - string where = "used = 1 AND vid = 1234"; + // Clean the cache, forcing the pool to read the objects from the DB + pool->clean(); - rc = pool->search(results, table, where); - CPPUNIT_ASSERT(rc == 0); - CPPUNIT_ASSERT(results.size() == 1); + // First VNet + vn = vnpool->get(oid_0, false); + CPPUNIT_ASSERT( vn != 0 ); + oss << *vn; + + // 0 Used leases + ObjectXML::xpath_value(xpath, oss.str().c_str(), "/VNET/TOTAL_LEASES" ); + CPPUNIT_ASSERT( xpath == "0" ); + + // Second VNet + vn = vnpool->get(oid_new, false); + CPPUNIT_ASSERT( vn != 0 ); + oss.str(""); + oss << *vn; + + // 1 Used leases + ObjectXML::xpath_value(xpath, oss.str().c_str(), "/VNET/TOTAL_LEASES" ); + CPPUNIT_ASSERT( xpath == "1" ); + // --------------------------------------------------------------------- // Now check that the first VNet has that IP available @@ -872,13 +901,32 @@ public: CPPUNIT_ASSERT( rc != 0 ); + // --------------------------------------------------------------------- // Check that in the DB, only one lease is used - where = "used = 1"; - // Clean the reults - results.resize(0); - rc = pool->search(results, table, where); - CPPUNIT_ASSERT(rc == 0); - CPPUNIT_ASSERT(results.size() == 1); + + // Clean the cache, forcing the pool to read the objects from the DB + pool->clean(); + + // First VNet + vn = vnpool->get(oid_0, false); + CPPUNIT_ASSERT( vn != 0 ); + oss.str(""); + oss << *vn; + + // 0 Used leases + ObjectXML::xpath_value(xpath, oss.str().c_str(), "/VNET/TOTAL_LEASES" ); + CPPUNIT_ASSERT( xpath == "0" ); + + // Second VNet + vn = vnpool->get(oid_new, false); + CPPUNIT_ASSERT( vn != 0 ); + oss.str(""); + oss << *vn; + + // 1 Used leases + ObjectXML::xpath_value(xpath, oss.str().c_str(), "/VNET/TOTAL_LEASES" ); + CPPUNIT_ASSERT( xpath == "1" ); + // --------------------------------------------------------------------- } /* -------------------------------------------------------------------------- */ @@ -1000,7 +1048,7 @@ public: while( templates[i] != "END" ) { - vnp->allocate(0, templates[i], &oid); + vnp->allocate(0, user_names[0], templates[i], &oid); CPPUNIT_ASSERT( oid >= 0 ); @@ -1039,10 +1087,10 @@ public: "LEASES = [IP=130.10.0.5, MAC=50:20:20:20:20:25]"; - vnp->allocate(0, template_0, &oid_0); + vnp->allocate(0, user_names[0], template_0, &oid_0); CPPUNIT_ASSERT( oid_0 == 0 ); - vnp->allocate(0, template_1, &oid_1); + vnp->allocate(0, user_names[0], template_1, &oid_1); CPPUNIT_ASSERT( oid_1 == 1 ); @@ -1530,7 +1578,5 @@ public: int main(int argc, char ** argv) { - OneUnitTest::set_one_auth(); - return PoolTest::main(argc, argv, VirtualNetworkPoolTest::suite()); } diff --git a/src/xml/ObjectXML.cc b/src/xml/ObjectXML.cc index 7ec2ed0f01..a922c7ae21 100644 --- a/src/xml/ObjectXML.cc +++ b/src/xml/ObjectXML.cc @@ -188,6 +188,40 @@ int ObjectXML::xpath(int& value, const char * xpath_expr, const int& def) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +int ObjectXML::xpath(unsigned int& value, const char * xpath_expr, + const unsigned int& def) +{ + vector values; + int rc = 0; + + values = (*this)[xpath_expr]; + + if (values.empty() == true) + { + value = def; + rc = -1; + } + else + { + istringstream iss; + + iss.str(values[0]); + + iss >> dec >> value; + + if (iss.fail() == true) + { + value = def; + rc = -1; + } + } + + return rc; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int ObjectXML::xpath(time_t& value, const char * xpath_expr, const time_t& def) { int int_val;