From 75bf275e3f6cf6b13625330694d6c080bfd786bf Mon Sep 17 00:00:00 2001 From: "Francois @fanf42 Armand" Date: Mon, 13 Jan 2014 18:41:34 +0100 Subject: [PATCH] Fixes #4149: Restore cat. with same name and different parents --- .../ldap/LDAPSwapGroupLibrary.scala | 25 +++++++++--------- .../ldap/LDAPSwapPolicyLibrary.scala | 26 ++++++++++--------- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/rudder-core/src/main/scala/com/normation/rudder/repository/ldap/LDAPSwapGroupLibrary.scala b/rudder-core/src/main/scala/com/normation/rudder/repository/ldap/LDAPSwapGroupLibrary.scala index 5d7b3425947..db3759aa25d 100644 --- a/rudder-core/src/main/scala/com/normation/rudder/repository/ldap/LDAPSwapGroupLibrary.scala +++ b/rudder-core/src/main/scala/com/normation/rudder/repository/ldap/LDAPSwapGroupLibrary.scala @@ -256,7 +256,7 @@ class ImportGroupLibraryImpl( /** * Check that the user lib match our global rules: * - two NodeGroup can't referenced the same PT (arbitrary skip the second one) - * - two categories can not have the same name (arbitrary skip the second one) + * - two categories WITH THE SAME PARENT can not have the same name (arbitrary skip the second one) * - all ids must be uniques * + remove system library if we don't want them */ @@ -265,7 +265,8 @@ class ImportGroupLibraryImpl( val nodeGroupIds = Set[NodeGroupId]() val nodeGroupNames = Map[String, NodeGroupId]() val categoryIds = Set[NodeGroupCategoryId]() - val categoryNames = Map[String, NodeGroupCategoryId]() + // for a name, all Category already containing a child with that name. + val categoryNamesByParent = Map[String, List[NodeGroupCategoryId]]() def sanitizeNodeGroup(nodeGroup:NodeGroup) : Option[NodeGroup] = { @@ -284,7 +285,7 @@ class ImportGroupLibraryImpl( } } - def recSanitizeCategory(content:NodeGroupCategoryContent, isRoot:Boolean = false) : Option[NodeGroupCategoryContent] = { + def recSanitizeCategory(content:NodeGroupCategoryContent, parent: NodeGroupCategory, isRoot:Boolean = false) : Option[NodeGroupCategoryContent] = { val cat = content.category if( !isRoot && content.category.isSystem && includeSystem == false) None else if(categoryIds.contains(cat.id)) { @@ -293,17 +294,17 @@ class ImportGroupLibraryImpl( } else if(cat.name == null || cat.name.size < 1) { logger.error("Ignoring Active Technique Category because its name is empty: " + cat) None - } else categoryNames.get(cat.name) match { //name is mandatory - case Some(id) => - logger.error("Ignoring Active Technique Categor with ID '%s' because its name is '%s' already referenced by category with ID '%s'".format( - cat.id.value, cat.name, id.value + } else categoryNamesByParent.get(cat.name) match { //name is mandatory + case Some(list) if list.contains(parent.id) => + logger.error("Ignoring Active Technique Categor with ID '%s' because its name is '%s' already referenced by category '%s' with ID '%s'".format( + cat.id.value, cat.name, parent.name, parent.id.value )) None - case None => //OK, process PT and sub categories ! + case _ => //OK, process PT and sub categories ! categoryIds += cat.id - categoryNames += (cat.name -> cat.id) + categoryNamesByParent += (cat.name -> (parent.id :: categoryNamesByParent.getOrElse(cat.name, Nil))) - val subCategories = content.categories.flatMap( recSanitizeCategory(_) ).toSet + val subCategories = content.categories.flatMap(c => recSanitizeCategory(c, cat) ).toSet val subNodeGroups = content.groups.flatMap( sanitizeNodeGroup(_) ).toSet //remove from sub cat groups that where not correct @@ -325,7 +326,7 @@ class ImportGroupLibraryImpl( } } - Box(recSanitizeCategory(userLib, true)) ?~! "Error when trying to sanitize serialised user library for consistency errors" + Box(recSanitizeCategory(userLib, userLib.category, true)) ?~! "Error when trying to sanitize serialised user library for consistency errors" } //all the logic for a library swap. @@ -349,4 +350,4 @@ class ImportGroupLibraryImpl( } } -} \ No newline at end of file +} diff --git a/rudder-core/src/main/scala/com/normation/rudder/repository/ldap/LDAPSwapPolicyLibrary.scala b/rudder-core/src/main/scala/com/normation/rudder/repository/ldap/LDAPSwapPolicyLibrary.scala index 7a64e4387a2..edf612e15e1 100644 --- a/rudder-core/src/main/scala/com/normation/rudder/repository/ldap/LDAPSwapPolicyLibrary.scala +++ b/rudder-core/src/main/scala/com/normation/rudder/repository/ldap/LDAPSwapPolicyLibrary.scala @@ -62,6 +62,7 @@ import com.normation.ldap.sdk.LDAPConnectionProvider import com.normation.utils.ScalaReadWriteLock import com.unboundid.ldap.sdk.DN import com.normation.rudder.domain.policies.ActiveTechniqueCategoryId +import com.normation.rudder.domain.policies.ActiveTechniqueCategory import com.normation.cfclerk.domain.TechniqueName import com.normation.ldap.sdk.RwLDAPConnection import org.joda.time.DateTime @@ -183,7 +184,7 @@ class ImportTechniqueLibraryImpl( /** * Check that the user lib match our global rules: * - two UPT can't referenced the same PT (arbitrary skip the second one) - * - two categories can not have the same name (arbitrary skip the second one) + * - two categories WITH THE SAME PARENT can not have the same name (arbitrary skip the second one) * - all ids must be uniques * + remove system library if we don't want them */ @@ -193,7 +194,8 @@ class ImportTechniqueLibraryImpl( val ptNames = Map[TechniqueName,ActiveTechniqueId]() val uactiveTechniqueIds = Set[ActiveTechniqueId]() val categoryIds = Set[ActiveTechniqueCategoryId]() - val categoryNames = Map[String, ActiveTechniqueCategoryId]() + // for a name, all Category already containing a child with that name. + val categoryNamesByParent = Map[String, List[ActiveTechniqueCategoryId]]() def sanitizeUPT(uptContent:ActiveTechniqueContent) : Option[ActiveTechniqueContent] = { val activeTechnique = uptContent.activeTechnique @@ -226,7 +228,7 @@ class ImportTechniqueLibraryImpl( } } - def recSanitizeCategory(content:ActiveTechniqueCategoryContent, isRoot:Boolean = false) : Option[ActiveTechniqueCategoryContent] = { + def recSanitizeCategory(content:ActiveTechniqueCategoryContent, parent: ActiveTechniqueCategory, isRoot:Boolean = false) : Option[ActiveTechniqueCategoryContent] = { val cat = content.category if( !isRoot && content.category.isSystem && includeSystem == false) None else if(categoryIds.contains(cat.id)) { @@ -235,17 +237,17 @@ class ImportTechniqueLibraryImpl( } else if(cat.name == null || cat.name.size < 1) { logger.error("Ignoring Active Technique Category because its name is empty: " + cat) None - } else categoryNames.get(cat.name) match { //name is mandatory - case Some(id) => - logger.error("Ignoring Active Technique Categor with ID '%s' because its name is '%s' already referenced by category with ID '%s'".format( - cat.id.value, cat.name, id.value + } else categoryNamesByParent.get(cat.name) match { //name is mandatory + case Some(list) if(list.contains(parent.id))=> + logger.error("Ignoring Active Technique Categor with ID '%s' because its name is '%s' already referenced by category '%s' with ID '%s'".format( + cat.id.value, cat.name, parent.name, parent.id.value )) None - case None => //OK, process PT and sub categories ! + case _ => //OK, process PT and sub categories ! categoryIds += cat.id - categoryNames += (cat.name -> cat.id) + categoryNamesByParent += (cat.name -> (parent.id :: categoryNamesByParent.getOrElse(cat.name, Nil))) - val subCategories = content.categories.flatMap( recSanitizeCategory(_) ) + val subCategories = content.categories.flatMap(c => recSanitizeCategory(c, cat)) val subUPTs = content.templates.flatMap( sanitizeUPT(_) ) Some(content.copy( @@ -259,7 +261,7 @@ class ImportTechniqueLibraryImpl( } } - Box(recSanitizeCategory(userLib, true)) ?~! "Error when trying to sanitize serialised user library for consistency errors" + Box(recSanitizeCategory(userLib, userLib.category, true)) ?~! "Error when trying to sanitize serialised user library for consistency errors" } //all the logic for a library swap. @@ -283,4 +285,4 @@ class ImportTechniqueLibraryImpl( } } -} \ No newline at end of file +}