Hi Benoit,

I don't kn ow the exact test your are doing, and I'm interested to get the specifics.

I have added a unit test that shows the nbChildren and nbSubordinates attributes are correctly updated (and they are single valued), in the M-27 branch. It is possible that the same test fails in M-26, I have to check.

Here is the unit test:

package org.apache.directory.server.operations.modifydn;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import org.apache.directory.api.ldap.model.entry.DefaultEntry;
import org.apache.directory.api.ldap.model.entry.Entry;
import org.apache.directory.ldap.client.api.LdapConnection;
import org.apache.directory.server.annotations.CreateLdapServer;
import org.apache.directory.server.annotations.CreateTransport;
import org.apache.directory.server.core.annotations.ContextEntry;
import org.apache.directory.server.core.annotations.CreateDS;
import org.apache.directory.server.core.annotations.CreateIndex;
import org.apache.directory.server.core.annotations.CreatePartition;
import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
import org.apache.directory.server.core.integ.ApacheDSTestExtension;
import org.apache.directory.server.integ.ServerIntegrationUtils;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

@ExtendWith( { ApacheDSTestExtension.class } )
@CreateDS(name = "ModifyRdnIT-class", enableChangeLog = false,
    partitions =
        {
            @CreatePartition(
                name = "example",
                suffix = "dc=example,dc=com",
                contextEntry = @ContextEntry(
                    entryLdif = "dn: dc=example,dc=com\n" +
                        "objectClass: domain\n" +
                        "objectClass: top\n" +
                        "dc: example\n\n"
                ),
                indexes = {
                    @CreateIndex( attribute = "uid" )
                }
            )
    })
@CreateLdapServer(
    transports =
        {
            @CreateTransport(protocol = "LDAP")
    })
public class MoveDescendantIT extends AbstractLdapTestUnit
{
    private static final String BASE = "dc=example,dc=com";


    /**
     * Modify Rdn of an entry, delete its old rdn value.
     */
    @Test
    public void testMoveDescendant() throws Exception
    {
LdapConnection connection = ServerIntegrationUtils.getAdminConnection( getLdapServer() );
        connection.loadSchema();

        // Create a users root
        Entry entry = new DefaultEntry( "cn=users," + BASE,
            "objectClass: top",
            "objectClass: person",
            "cn", "users",
            "sn: users",
            "description", "The users root" );

        connection.add( entry );

        // Create a person root
        entry = new DefaultEntry( "cn=persons," + BASE,
            "objectClass: top",
            "objectClass: person",
            "cn", "persons",
            "sn: persons",
            "description", "The persons root" );

        connection.add( entry );

        // Create a person, cn value is rdn
        String cn = "Myra Ellen Amos";
        String rdn = "cn=" + cn;
        String dn = rdn + ", " + "cn=users," + BASE;

        entry = new DefaultEntry( dn,
            "objectClass: top",
            "objectClass: person",
            "cn", cn,
            "sn: Amos",
            "description", cn + " is a person." );

        connection.add( entry );

        // Get the top entry
        Entry tori = connection.lookup( dn, "+", "*" );

        assertNotNull( tori );
        assertTrue( tori.contains( "cn", "Myra Ellen Amos" ) );

        // Get the users root
        Entry users = connection.lookup( "cn=users," + BASE, "+", "*" );

        assertTrue( users.contains( "nbSubordinates", "1" ) );
        assertTrue( users.contains( "nbChildren", "1" ) );

        // Get the persons root
Entry persons = connection.lookup( "cn=persons," + BASE, "+", "*" );

        assertTrue( persons.contains( "nbSubordinates", "0" ) );
        assertTrue( persons.contains( "nbChildren", "0" ) );

        // move the top entry
        connection.move( dn, "cn=persons," + BASE );


        // Get the users root
        users = connection.lookup( "cn=users," + BASE, "+", "*" );

        assertTrue( users.contains( "nbSubordinates", "0" ) );
        assertTrue( users.contains( "nbChildren", "0" ) );

        // Get the persons root
        persons = connection.lookup( "cn=persons," + BASE, "+", "*" );

        assertTrue( persons.contains( "nbSubordinates", "1" ) );
        assertTrue( persons.contains( "nbChildren", "1" ) );
    }
}


On 08/11/2021 17:01, Benoît Dissert wrote:
Hello Emmanuel,

Did you find some time to check this ?

Is there some input I could provide to help ?

Benoît

--

Benoît Dissert

Le 2021-02-12T11:05:07.000+01:00, Emmanuel Lécharny <[email protected]> a écrit :

    Hi,

    this is clearly a bug. The attribute should be unique.


    I have to check that...


    Note that this feature is unique to ApacheDS, so this is why you don't
    have a lot of info on internet about it...

    On 12/02/2021 09:25, Benoît Dissert wrote:

        Hello,

        I suspect a bug which is rather blocking for my usage and found not
        ressource about it on Internet.

        Here is the observed behaviour :
        In my DIT, I have some branches of o nodes unders roots of ou type.
        When I move a o node in the DIT (ie changing the dn of this
        entry, but
        not its final rdn) the orginal parent of the
        node has now two values for the nbChildren attribute (the old
        one and the
        new one, which is the old value minus
        one, since there is one children less).

        Consequence :
        since the nbChildren attribute is supposed to be monovalued,
        most of the
        operations on this parent are no longer possibles.

        I was able to reproduce the behaviour with a virgin ADS
        2.0.0-M26 with the
        sevenSeas data in the specific partition
        (o=sevenSeas) but not under the system partition.

        Do you know something about this ?

        Is there a way to set the node in a correct way ? Other than :
        - ldif export the complete DIT
        - ldif import it in a new ADS instance

        Regards,

        Benoît Dissert


    ---------------------------------------------------------------------
    To unsubscribe, e-mail: [email protected]
    <mailto:[email protected]>
    For additional commands, e-mail: [email protected]
    <mailto:[email protected]>



--
*Emmanuel Lécharny - CTO* 205 Promenade des Anglais – 06200 NICE
T. +33 (0)4 89 97 36 50
P. +33 (0)6 08 33 32 61
[email protected] https://www.busit.com/

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to