o Bumped up the LDAP API reference to 2.0.2-SNAPSHOT
o Fix for DIRSERVER-2308
diff --git a/core-integ/src/test/java/org/apache/directory/server/core/operations/move/MoveIT.java b/core-integ/src/test/java/org/apache/directory/server/core/operations/move/MoveIT.java
index a20f000..13f75d4 100644
--- a/core-integ/src/test/java/org/apache/directory/server/core/operations/move/MoveIT.java
+++ b/core-integ/src/test/java/org/apache/directory/server/core/operations/move/MoveIT.java
@@ -21,6 +21,7 @@
import org.apache.directory.api.ldap.model.entry.DefaultEntry;
import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.exception.LdapEntryAlreadyExistsException;
import org.apache.directory.api.ldap.model.exception.LdapOperationErrorException;
import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
import org.apache.directory.api.ldap.model.name.Dn;
@@ -67,8 +68,7 @@
@CreateIndex(attribute = "sn"),
@CreateIndex(attribute = "cn")
})
- },
- enableChangeLog = false)
+ })
public class MoveIT extends AbstractLdapTestUnit
{
/**
@@ -201,4 +201,53 @@
connection.close();
}
+
+
+ /**
+ * Test a move operation on an existing location:
+ * cn=test,ou=system will be moved to cn=test,ou=users,ou=system, which already exists
+ */
+ @Test
+ public void testMoveExistingTarget() throws Exception
+ {
+ LdapConnection connection = IntegrationUtils.getAdminConnection( getService() );
+
+ String oldDn = "cn=test,ou=system";
+ String newDn = "cn=test,ou=users,ou=system";
+ String newSuperior = "ou=users,ou=system";
+ String targetDnStr = "cn=test,ou=users,ou=system";
+
+ Dn dn = new Dn( oldDn );
+ Entry entry = new DefaultEntry( getService().getSchemaManager(), dn,
+ "ObjectClass: top",
+ "ObjectClass: person",
+ "sn: TEST",
+ "cn: test" );
+
+ connection.add( entry );
+
+ Dn targetDn = new Dn( targetDnStr );
+ Entry target = new DefaultEntry( getService().getSchemaManager(), targetDn,
+ "ObjectClass: top",
+ "ObjectClass: person",
+ "sn: TEST",
+ "cn: test" );
+
+ connection.add( target );
+
+ assertNotNull( connection.lookup( oldDn ) );
+
+ try
+ {
+ connection.move( oldDn, newSuperior );
+ fail();
+ }
+ catch ( LdapEntryAlreadyExistsException leaee )
+ {
+ assertNotNull( connection.lookup( newDn ) );
+ assertNotNull( connection.lookup( oldDn ) );
+ }
+
+ connection.close();
+ }
}
diff --git a/core-integ/src/test/java/org/apache/directory/server/core/operations/moveAndRename/MoveAndRenameIT.java b/core-integ/src/test/java/org/apache/directory/server/core/operations/moveAndRename/MoveAndRenameIT.java
index ac41f82..2af0261 100644
--- a/core-integ/src/test/java/org/apache/directory/server/core/operations/moveAndRename/MoveAndRenameIT.java
+++ b/core-integ/src/test/java/org/apache/directory/server/core/operations/moveAndRename/MoveAndRenameIT.java
@@ -23,11 +23,15 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertEquals;
import org.apache.directory.api.ldap.model.entry.Attribute;
+import org.apache.directory.api.ldap.model.entry.DefaultEntry;
import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.exception.LdapEntryAlreadyExistsException;
+import org.apache.directory.api.ldap.model.name.Dn;
import org.apache.directory.ldap.client.api.LdapConnection;
import org.apache.directory.server.core.annotations.ApplyLdifs;
import org.apache.directory.server.core.annotations.ContextEntry;
@@ -316,4 +320,63 @@
connection.close();
}
+
+
+ /**
+ * Check that when doing a rename, with a SV RDN, we don't have the previous RDN in the entry,
+ * if the deleteOldrdn flag is set to true
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testRenameSVAttributeDeleteOldRdnExistingEntry() throws Exception
+ {
+ LdapConnection connection = IntegrationUtils.getAdminConnection( getService() );
+
+ String frDnStr = "c=FR,ou=system";
+ String deDnStr = "c=DE,ou=system";
+
+ // Create an entry that will collide with the rename
+ Dn deDn = new Dn( deDnStr );
+ Entry deEntry = new DefaultEntry( getService().getSchemaManager(), deDn,
+ "ObjectClass: top",
+ "ObjectClass: country",
+ "c: DE" );
+
+ connection.add( deEntry );
+
+ // Create the entry that will be renamed
+ Dn frDn = new Dn( frDnStr );
+ Entry frEntry = new DefaultEntry( getService().getSchemaManager(), frDn,
+ "ObjectClass: top",
+ "ObjectClass: country",
+ "c: FR" );
+
+ connection.add( frEntry );
+
+ Entry original = connection.lookup( frDn );
+
+ assertNotNull( original );
+
+ // rename the FR entry to DE entry : should fail as DE entry already exists
+ try
+ {
+ connection.moveAndRename( frDnStr, deDnStr, true );
+ fail();
+ }
+ catch ( LdapEntryAlreadyExistsException leaee )
+ {
+ Entry originalFr = connection.lookup( frDn );
+ assertNotNull( originalFr );
+ assertEquals( frDnStr, originalFr.getDn().toString() );
+ assertTrue( originalFr.get( "c" ).contains( "FR" ) );
+ assertFalse( originalFr.get( "c" ).contains( "DE" ) );
+
+ Entry originalDe = connection.lookup( deDn );
+ assertNotNull( originalDe );
+ assertEquals( deDnStr, originalDe.getDn().toString() );
+ assertTrue( originalDe.get( "c" ).contains( "DE" ) );
+ assertFalse( originalDe.get( "c" ).contains( "FR" ) );
+ }
+ }
}
diff --git a/core-integ/src/test/java/org/apache/directory/server/core/operations/rename/RenameIT.java b/core-integ/src/test/java/org/apache/directory/server/core/operations/rename/RenameIT.java
index 2a61fe6..a93d904 100644
--- a/core-integ/src/test/java/org/apache/directory/server/core/operations/rename/RenameIT.java
+++ b/core-integ/src/test/java/org/apache/directory/server/core/operations/rename/RenameIT.java
@@ -22,6 +22,7 @@
import org.apache.directory.api.ldap.model.entry.Attribute;
import org.apache.directory.api.ldap.model.entry.DefaultEntry;
import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.exception.LdapEntryAlreadyExistsException;
import org.apache.directory.api.ldap.model.name.Dn;
import org.apache.directory.ldap.client.api.LdapConnection;
import org.apache.directory.server.core.annotations.ContextEntry;
@@ -38,6 +39,7 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import static org.junit.Assert.assertFalse;
/**
@@ -267,6 +269,65 @@
/**
+ * Check that when doing a rename, with a SV RDN, we don't have the previous RDN in the entry,
+ * if the deleteOldrdn flag is set to true
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testRenameSVAttributeDeleteOldRdnExistingEntry() throws Exception
+ {
+ LdapConnection connection = IntegrationUtils.getAdminConnection( getService() );
+
+ String frDnStr = "c=FR,ou=system";
+ String deDnStr = "c=DE,ou=system";
+
+ // Create an entry that will collide with the rename
+ Dn deDn = new Dn( deDnStr );
+ Entry deEntry = new DefaultEntry( getService().getSchemaManager(), deDn,
+ "ObjectClass: top",
+ "ObjectClass: country",
+ "c: DE" );
+
+ connection.add( deEntry );
+
+ // Create the entry that will be renamed
+ Dn frDn = new Dn( frDnStr );
+ Entry frEntry = new DefaultEntry( getService().getSchemaManager(), frDn,
+ "ObjectClass: top",
+ "ObjectClass: country",
+ "c: FR" );
+
+ connection.add( frEntry );
+
+ Entry original = connection.lookup( frDn );
+
+ assertNotNull( original );
+
+ // rename the FR entry to DE entry : should fail as DE entry already exists
+ try
+ {
+ connection.rename( frDnStr, "c=DE", true );
+ fail();
+ }
+ catch ( LdapEntryAlreadyExistsException leaee )
+ {
+ Entry originalFr = connection.lookup( frDn );
+ assertNotNull( originalFr );
+ assertEquals( frDnStr, originalFr.getDn().toString() );
+ assertTrue( originalFr.get( "c" ).contains( "FR" ) );
+ assertFalse( originalFr.get( "c" ).contains( "DE" ) );
+
+ Entry originalDe = connection.lookup( deDn );
+ assertNotNull( originalDe );
+ assertEquals( deDnStr, originalDe.getDn().toString() );
+ assertTrue( originalDe.get( "c" ).contains( "DE" ) );
+ assertFalse( originalDe.get( "c" ).contains( "FR" ) );
+ }
+ }
+
+
+ /**
* Check that when doing a rename, with a SV RDN, we get an error if the deleteOldRdn flag is
* set to false
*
diff --git a/interceptors/exception/src/main/java/org/apache/directory/server/core/exception/ExceptionInterceptor.java b/interceptors/exception/src/main/java/org/apache/directory/server/core/exception/ExceptionInterceptor.java
index c9b848d..ed9ff13 100644
--- a/interceptors/exception/src/main/java/org/apache/directory/server/core/exception/ExceptionInterceptor.java
+++ b/interceptors/exception/src/main/java/org/apache/directory/server/core/exception/ExceptionInterceptor.java
@@ -250,6 +250,26 @@
next( modifyContext );
}
+
+
+ private void checkExistingTarget( OperationContext operationContext, Dn newDn, Dn oldDn ) throws LdapException
+ {
+ // check to see if target entry exists
+ HasEntryOperationContext hasEntryContext = new HasEntryOperationContext( operationContext.getSession(), newDn );
+ hasEntryContext.setPartition( operationContext.getPartition() );
+ hasEntryContext.setTransaction( operationContext.getTransaction() );
+
+ if ( nexus.hasEntry( hasEntryContext ) )
+ {
+ // Ok, the target entry already exists.
+ // If the target entry has the same name than the modified entry, it's a rename on itself,
+ // we want to allow this.
+ if ( !newDn.equals( oldDn ) )
+ {
+ throw new LdapEntryAlreadyExistsException( I18n.err( I18n.ERR_250_ENTRY_ALREADY_EXISTS, newDn.getName() ) );
+ }
+ }
+ }
/**
@@ -265,6 +285,9 @@
throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, I18n.err( I18n.ERR_258,
subschemSubentryDn, subschemSubentryDn ) );
}
+
+ // check to see if target entry exists
+ checkExistingTarget( moveContext, moveContext.getNewDn(), oriChildName );
next( moveContext );
@@ -293,6 +316,9 @@
throw new LdapUnwillingToPerformException( ResultCodeEnum.UNWILLING_TO_PERFORM, I18n.err( I18n.ERR_258,
subschemSubentryDn, subschemSubentryDn ) );
}
+
+ // check to see if target entry exists
+ checkExistingTarget( moveAndRenameContext, moveAndRenameContext.getNewDn(), oldDn );
// Remove the original entry from the NotAlias cache, if needed
synchronized ( notAliasCache )
@@ -322,22 +348,7 @@
}
// check to see if target entry exists
- Dn newDn = renameContext.getNewDn();
-
- HasEntryOperationContext hasEntryContext = new HasEntryOperationContext( renameContext.getSession(), newDn );
- hasEntryContext.setPartition( renameContext.getPartition() );
- hasEntryContext.setTransaction( renameContext.getTransaction() );
-
- if ( nexus.hasEntry( hasEntryContext ) )
- {
- // Ok, the target entry already exists.
- // If the target entry has the same name than the modified entry, it's a rename on itself,
- // we want to allow this.
- if ( !newDn.equals( dn ) )
- {
- throw new LdapEntryAlreadyExistsException( I18n.err( I18n.ERR_250_ENTRY_ALREADY_EXISTS, newDn.getName() ) );
- }
- }
+ checkExistingTarget( renameContext, renameContext.getNewDn(), dn );
// Remove the previous entry from the notAnAlias cache
synchronized ( notAliasCache )
diff --git a/pom.xml b/pom.xml
index 5edadd9..014d7b0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -46,7 +46,7 @@
<doclint>none</doclint>
<!-- Set versions for depending projects -->
- <org.apache.directory.api.version>2.0.1</org.apache.directory.api.version>
+ <org.apache.directory.api.version>2.0.2-SNAPSHOT</org.apache.directory.api.version>
<org.apache.directory.mavibot.version>1.0.0-M8</org.apache.directory.mavibot.version>
<org.apache.directory.checkstyle-configuration.version>2.0.1-SNAPSHOT</org.apache.directory.checkstyle-configuration.version>
<org.apache.directory.junit.junit-addons.version>2.0.0</org.apache.directory.junit.junit-addons.version>