diff --git a/include/HostPool.h b/include/HostPool.h index 0ace0c3789..4dcf149bbe 100644 --- a/include/HostPool.h +++ b/include/HostPool.h @@ -67,7 +67,19 @@ public: { return static_cast(PoolSQL::get(oid,lock)); }; - + + /** + * Function to get a Host from the pool, if the object is not in memory + * it is loaded from the DB + * @param hostname + * @param lock locks the Host mutex + * @return a pointer to the Host, 0 if the Host could not be loaded + */ + Host * get(string name, bool lock) + { + return static_cast(PoolSQL::get(name,-1,lock)); + }; + /** * Bootstraps the database table(s) associated to the Host pool */ diff --git a/include/PoolSQL.h b/include/PoolSQL.h index 080dd30dcc..fef4fee546 100644 --- a/include/PoolSQL.h +++ b/include/PoolSQL.h @@ -201,11 +201,6 @@ private: */ map name_pool; - /** - * If set to true the objects of the pool will be indexed by its name also - */ - bool use_index; - /** * Factory method, must return an ObjectSQL pointer to an allocated pool * specific object. diff --git a/src/cluster/ClusterPool.cc b/src/cluster/ClusterPool.cc index a5846b2486..ef1280e8ef 100644 --- a/src/cluster/ClusterPool.cc +++ b/src/cluster/ClusterPool.cc @@ -57,30 +57,41 @@ ClusterPool::ClusterPool(SqlDB * db):PoolSQL(db, Cluster::table) int ClusterPool::allocate(int * oid, string name, string& error_str) { - Cluster * cluster; - Cluster * cluster_aux; + Cluster * cluster; + ostringstream oss; + + if ( name.empty() ) + { + goto error_name; + } // Check for duplicates - cluster_aux = get(name, false); + cluster = get(name, false); - if( cluster_aux != 0 ) + if( cluster != 0 ) { - ostringstream oss; - - oss << "NAME is already taken by CLUSTER " - << cluster_aux->get_oid() << "."; - error_str = oss.str(); - - *oid = -1; + goto error_duplicated; } - else - { - // Build a new Cluster object - cluster = new Cluster(-1, name); - // Insert the Object in the pool - *oid = PoolSQL::allocate(cluster, error_str); - } + // Build a new Cluster object + cluster = new Cluster(-1, name); + + // Insert the Object in the pool + *oid = PoolSQL::allocate(cluster, error_str); + + return *oid; + + +error_name: + oss << "NAME cannot be empty."; + goto error_common; + +error_duplicated: + oss << "NAME is already taken by CLUSTER " << cluster->get_oid() << "."; + +error_common: + *oid = -1; + error_str = oss.str(); return *oid; } diff --git a/src/cluster/test/ClusterPoolTest.cc b/src/cluster/test/ClusterPoolTest.cc index 42bf799e87..bdb102dd05 100644 --- a/src/cluster/test/ClusterPoolTest.cc +++ b/src/cluster/test/ClusterPoolTest.cc @@ -80,6 +80,8 @@ class ClusterPoolTest : public PoolTest CPPUNIT_TEST (wrong_get); CPPUNIT_TEST (drop_and_get); + CPPUNIT_TEST (name_pool); + CPPUNIT_TEST (duplicates); CPPUNIT_TEST (set_cluster); CPPUNIT_TEST (remove_cluster); @@ -193,6 +195,53 @@ public: /* ********************************************************************* */ /* ********************************************************************* */ + // Test intended to check the PoolSQL name index functionallity + void name_pool() + { + Cluster * cluster; + int oid; + string err; + + + // Allocate some clusters + cpool->allocate(&oid, "name_1", err); + CPPUNIT_ASSERT( oid == 1 ); + + cpool->allocate(&oid, "name_2", err); + CPPUNIT_ASSERT( oid == 2 ); + + cpool->allocate(&oid, "name_3", err); + CPPUNIT_ASSERT( oid == 3 ); + + // Clean the cache + cpool->clean(); + + cpool->allocate(&oid, "name_4", err); + CPPUNIT_ASSERT( oid == 4 ); + + cpool->allocate(&oid, "name_5", err); + CPPUNIT_ASSERT( oid == 5 ); + + // Cluster names 0-3 should be unknown, and 4-5 cached + // Ask for a cached object + cluster = cpool->get("name_5", false); + CPPUNIT_ASSERT( cluster != 0 ); + CPPUNIT_ASSERT( cluster->get_oid() == 5 ); + CPPUNIT_ASSERT( cluster->get_name() == "name_5" ); + + // Ask for non-cached object + cluster = cpool->get("name_2", false); + CPPUNIT_ASSERT( cluster != 0 ); + CPPUNIT_ASSERT( cluster->get_oid() == 2 ); + CPPUNIT_ASSERT( cluster->get_name() == "name_2" ); + + // Ask for non-existing object + cluster = cpool->get("name_X", false); + CPPUNIT_ASSERT( cluster == 0 ); + }; + + /* ********************************************************************* */ + void duplicates() { int rc, oid; diff --git a/src/host/HostPool.cc b/src/host/HostPool.cc index 867c6f153d..621660aab9 100644 --- a/src/host/HostPool.cc +++ b/src/host/HostPool.cc @@ -144,18 +144,32 @@ int HostPool::allocate ( { Host * host; - // Build a new Host object + host = get(hostname,false); - host = new Host(-1, - hostname, - im_mad_name, - vmm_mad_name, - tm_mad_name, - ClusterPool::DEFAULT_CLUSTER_NAME); + if ( host !=0) + { + ostringstream oss; - // Insert the Object in the pool + oss << "NAME is already taken by HOST " << host->get_oid() << "."; + error_str = oss.str(); - *oid = PoolSQL::allocate(host, error_str); + *oid = -1; + } + else + { + // Build a new Host object + + host = new Host(-1, + hostname, + im_mad_name, + vmm_mad_name, + tm_mad_name, + ClusterPool::DEFAULT_CLUSTER_NAME); + + // Insert the Object in the pool + + *oid = PoolSQL::allocate(host, error_str); + } return *oid; } diff --git a/src/um/UserPool.cc b/src/um/UserPool.cc index 5758d723e3..1351b55cce 100644 --- a/src/um/UserPool.cc +++ b/src/um/UserPool.cc @@ -120,26 +120,39 @@ int UserPool::allocate ( string& error_str) { User * user; + ostringstream oss; + + if ( username.empty() ) + { + goto error_name; + } user = get(username,false); - if ( user !=0) + if ( user !=0 ) { - ostringstream oss; - - oss << "NAME is already taken by USER " << user->get_oid() << "."; - error_str = oss.str(); - - *oid = -1; + goto error_duplicated; } - else - { - // Build a new User object - user = new User(-1, username, password, enabled); - // Insert the Object in the pool - *oid = PoolSQL::allocate(user, error_str); - } + // Build a new User object + user = new User(-1, username, password, enabled); + + // Insert the Object in the pool + *oid = PoolSQL::allocate(user, error_str); + + return *oid; + + +error_name: + oss << "NAME cannot be empty."; + goto error_common; + +error_duplicated: + oss << "NAME is already taken by USER " << user->get_oid() << "."; + +error_common: + *oid = -1; + error_str = oss.str(); return *oid; } diff --git a/src/vnm/VirtualNetwork.cc b/src/vnm/VirtualNetwork.cc index a448e03995..8d885b670f 100644 --- a/src/vnm/VirtualNetwork.cc +++ b/src/vnm/VirtualNetwork.cc @@ -228,9 +228,13 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str) { type = VirtualNetwork::FIXED; } + else if ( s_type.empty() ) + { + goto error_type_defined; + } else { - goto error_type; + goto error_wrong_type; } // ------------ NAME ---------------------- @@ -343,32 +347,34 @@ int VirtualNetwork::insert(SqlDB * db, string& error_str) return 0; -error_type: - ose << "Wrong type in template for Virtual Network, id: "; +error_type_defined: + ose << "No TYPE in template for Virtual Network."; + goto error_common; + +error_wrong_type: + ose << "Wrong type \""<< s_type <<"\" in template for Virtual Network."; goto error_common; error_name: - ose << "No NAME in template for Virtual Network, id: "; + ose << "No NAME in template for Virtual Network."; goto error_common; error_bridge: - ose << "No BRIDGE in template for Virtual Network, id: "; + ose << "No BRIDGE in template for Virtual Network."; goto error_common; error_update: - ose << "Can not update Virtual Network, id: "; + ose << "Can not update Virtual Network."; goto error_common; error_addr: - ose << "Network address is not defined, id: "; + ose << "No NETWORK_ADDRESS in template for Virtual Network."; goto error_common; error_null_leases: - ose << "Error getting Virtual Network leases, id: "; + ose << "Error getting Virtual Network leases."; error_common: - ose << oid << "."; - error_str = ose.str(); NebulaLog::log("VNM", Log::ERROR, ose); return -1; diff --git a/src/vnm/test/VirtualNetworkPoolTest.cc b/src/vnm/test/VirtualNetworkPoolTest.cc index 6162934dc8..c059dd1213 100644 --- a/src/vnm/test/VirtualNetworkPoolTest.cc +++ b/src/vnm/test/VirtualNetworkPoolTest.cc @@ -409,12 +409,12 @@ public: CPPUNIT_ASSERT( rc == oid_0 ); CPPUNIT_ASSERT( rc == 0 ); - // Allocate the same vnet twice, with the same user ID + // Allocate the same vnet twice, with the same user ID. Should fail rc = vnpool->allocate(uids[0], user_names[0], templates[0], &oid_1); CPPUNIT_ASSERT( rc == oid_1 ); CPPUNIT_ASSERT( rc == -1 ); - // Same VNet, with different user ID + // Same VNet, with different user ID. Should succeed rc = vnpool->allocate(uids[1], user_names[1], templates[0], &oid_2); CPPUNIT_ASSERT( rc == oid_2 ); CPPUNIT_ASSERT( rc == 1 ); @@ -425,7 +425,7 @@ public: CPPUNIT_ASSERT( rc == 2 ); - // Make sure the table contains only one vnet with name[0] + // Make sure the table contains two vnets with name[0] vector results; int ret; const char * table = "network_pool";