You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2016/03/07 13:39:58 UTC

svn commit: r1733917 - in /directory/apacheds/trunk: core-integ/src/test/java/org/apache/directory/server/core/operations/lookup/ core-shared/src/main/java/org/apache/directory/server/core/shared/partition/ interceptors/operational/src/main/java/org/ap...

Author: elecharny
Date: Mon Mar  7 12:39:58 2016
New Revision: 1733917

URL: http://svn.apache.org/viewvc?rev=1733917&view=rev
Log:
o Added the support of subordinates for the Lookup operation (DIRSERVER-2129)

Modified:
    directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/operations/lookup/LookupIT.java
    directory/apacheds/trunk/core-shared/src/main/java/org/apache/directory/server/core/shared/partition/DefaultPartitionNexus.java
    directory/apacheds/trunk/interceptors/operational/src/main/java/org/apache/directory/server/core/operational/OperationalAttributeInterceptor.java
    directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/replication/consumer/ReplicationConsumerImpl.java
    directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java

Modified: directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/operations/lookup/LookupIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/operations/lookup/LookupIT.java?rev=1733917&r1=1733916&r2=1733917&view=diff
==============================================================================
--- directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/operations/lookup/LookupIT.java (original)
+++ directory/apacheds/trunk/core-integ/src/test/java/org/apache/directory/server/core/operations/lookup/LookupIT.java Mon Mar  7 12:39:58 2016
@@ -27,7 +27,9 @@ import static org.junit.Assert.assertNul
 import static org.junit.Assert.assertTrue;
 
 import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.exception.LdapException;
 import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.server.constants.ApacheSchemaConstants;
 import org.apache.directory.server.core.annotations.ApplyLdifs;
 import org.apache.directory.server.core.annotations.CreateDS;
 import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
@@ -104,7 +106,7 @@ public class LookupIT extends AbstractLd
         assertNotNull( entry );
         
         // We should have 6 attributes
-        assertEquals( 6, entry.size() );
+        assertEquals( 8, entry.size() );
 
         // Check that all the user attributes are absent
         assertNull( entry.get( "cn" ) );
@@ -126,6 +128,8 @@ public class LookupIT extends AbstractLd
         assertNotNull( entry.get( "entryUUID" ).getString() );
         assertNotNull( entry.get( "entryParentId" ).getString() );
         assertNotNull( entry.get( "entryDn" ));
+        assertNotNull( entry.get( "nbChildren" ));
+        assertNotNull( entry.get( "nbSubordinates" ));
         assertEquals( "cn=test,ou=system", entry.get( "entryDn" ).getString() );
     }
 
@@ -252,4 +256,71 @@ public class LookupIT extends AbstractLd
         // We should have 0 attributes
         assertEquals( 0, entry.size() );
     }
+    
+    
+    @Test
+    public void testLookupSubordinates() throws LdapException
+    {
+        Entry entry = connection.lookup( "cn=test,ou=system", "*", "+" );
+        
+        assertNotNull( entry );
+
+        // We should have 11 attributes
+        assertEquals( 11, entry.size() );
+        assertTrue( entry.containsAttribute( "nbChildren", "nbSubordinates" ) );
+        assertEquals( 0L, Long.parseLong( entry.get( "nbChildren" ).getString() ) );
+        assertEquals( 0L, Long.parseLong( entry.get( "nbSubordinates" ).getString() ) );
+        
+        // Now lookup for the "ou=system"
+        entry = connection.lookup( "ou=system", "*", "+" );
+        
+        assertNotNull( entry );
+
+        // We should have 11 attributes
+        assertEquals( 11, entry.size() );
+        assertTrue( entry.containsAttribute( "nbChildren", "nbSubordinates" ) );
+
+        // we will have 6 children :
+        // - ou=configuration
+        // - ou=consumer
+        // - ou = groups
+        // - ou=users
+        // - ou=prefNodeNames
+        // - uid=admin
+        // and 10 subordinates, as we have 3 children under ou=configuration and one under ou=groups
+        assertEquals( 6L, Long.parseLong( entry.get( "nbChildren" ).getString() ) );
+        assertEquals( 10L, Long.parseLong( entry.get( "nbSubordinates" ).getString() ) );
+        
+        // Check with only one of the two attributes 
+        entry = connection.lookup( "ou=system", "nbChildren" );
+        
+        assertNotNull( entry );
+
+        // We should have 1 attributes
+        assertEquals( 1, entry.size() );
+        assertTrue( entry.containsAttribute( "nbChildren" ) );
+        assertFalse( entry.containsAttribute( "nbSubordinates" ) );
+
+        // we will have 6 children :
+        // - ou=configuration
+        // - ou=consumer
+        // - ou = groups
+        // - ou=users
+        // - ou=prefNodeNames
+        // - uid=admin
+        assertEquals( 6L, Long.parseLong( entry.get( "nbChildren" ).getString() ) );
+        
+        // And teh subordinates
+        entry = connection.lookup( "ou=system", "nbSubordinates" );
+        
+        assertNotNull( entry );
+
+        // We should have 1 attributes
+        assertEquals( 1, entry.size() );
+        assertFalse( entry.containsAttribute( "nbChildren" ) );
+        assertTrue( entry.containsAttribute( "nbSubordinates" ) );
+
+        // we will have 10 subordinates
+        assertEquals( 10L, Long.parseLong( entry.get( "nbSubordinates" ).getString() ) );
+    }
 }

Modified: directory/apacheds/trunk/core-shared/src/main/java/org/apache/directory/server/core/shared/partition/DefaultPartitionNexus.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/core-shared/src/main/java/org/apache/directory/server/core/shared/partition/DefaultPartitionNexus.java?rev=1733917&r1=1733916&r2=1733917&view=diff
==============================================================================
--- directory/apacheds/trunk/core-shared/src/main/java/org/apache/directory/server/core/shared/partition/DefaultPartitionNexus.java (original)
+++ directory/apacheds/trunk/core-shared/src/main/java/org/apache/directory/server/core/shared/partition/DefaultPartitionNexus.java Mon Mar  7 12:39:58 2016
@@ -81,6 +81,7 @@ import org.apache.directory.server.core.
 import org.apache.directory.server.core.api.partition.AbstractPartition;
 import org.apache.directory.server.core.api.partition.Partition;
 import org.apache.directory.server.core.api.partition.PartitionNexus;
+import org.apache.directory.server.core.api.partition.Subordinates;
 import org.apache.directory.server.i18n.I18n;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -1042,8 +1043,8 @@ public class DefaultPartitionNexus exten
 
         mods.add( timeStampMod );
     }
-
-
+    
+    
     @Override
     public String getContextCsn()
     {
@@ -1056,4 +1057,17 @@ public class DefaultPartitionNexus exten
     public void saveContextCsn() throws Exception
     {
     }
+    
+    
+    /**
+     * Return the number of children and subordinates for a given entry
+     *
+     * @param dn The entry's DN
+     * @return The Subordinate instance that contains the values.
+     * @throws LdapException If we had an issue while processing the request
+     */
+    public Subordinates getSubordinates( Entry entry ) throws LdapException
+    {
+        return new Subordinates();
+    }
 }

Modified: directory/apacheds/trunk/interceptors/operational/src/main/java/org/apache/directory/server/core/operational/OperationalAttributeInterceptor.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/interceptors/operational/src/main/java/org/apache/directory/server/core/operational/OperationalAttributeInterceptor.java?rev=1733917&r1=1733916&r2=1733917&view=diff
==============================================================================
--- directory/apacheds/trunk/interceptors/operational/src/main/java/org/apache/directory/server/core/operational/OperationalAttributeInterceptor.java (original)
+++ directory/apacheds/trunk/interceptors/operational/src/main/java/org/apache/directory/server/core/operational/OperationalAttributeInterceptor.java Mon Mar  7 12:39:58 2016
@@ -38,6 +38,7 @@ import org.apache.directory.api.ldap.mod
 import org.apache.directory.api.ldap.model.name.Dn;
 import org.apache.directory.api.ldap.model.name.Rdn;
 import org.apache.directory.api.ldap.model.schema.AttributeType;
+import org.apache.directory.api.ldap.model.schema.AttributeTypeOptions;
 import org.apache.directory.api.util.DateUtils;
 import org.apache.directory.server.constants.ApacheSchemaConstants;
 import org.apache.directory.server.constants.ServerDNConstants;
@@ -55,6 +56,8 @@ import org.apache.directory.server.core.
 import org.apache.directory.server.core.api.interceptor.context.MoveOperationContext;
 import org.apache.directory.server.core.api.interceptor.context.RenameOperationContext;
 import org.apache.directory.server.core.api.interceptor.context.SearchOperationContext;
+import org.apache.directory.server.core.api.partition.Partition;
+import org.apache.directory.server.core.api.partition.Subordinates;
 import org.apache.directory.server.core.shared.SchemaService;
 import org.apache.directory.server.i18n.I18n;
 import org.slf4j.Logger;
@@ -117,6 +120,7 @@ public class OperationalAttributeInterce
         }
     }
 
+    
     /**
      * the search result filter to use for the addition of mandatory operational attributes
      */
@@ -155,7 +159,7 @@ public class OperationalAttributeInterce
         }
     }
 
-
+    
     /**
      * Creates the operational attribute management service interceptor.
      */
@@ -294,6 +298,47 @@ public class OperationalAttributeInterce
         Entry result = next( lookupContext );
 
         denormalizeEntryOpAttrs( result );
+        
+       // Bypass the rootDSE : we won't get the nbChildren and nbSubordiantes for this special entry
+        if ( Dn.isNullOrEmpty( result.getDn() ) )
+        {
+            return result;
+        }
+
+        // Add the Subordinates AttributeType if it's requested
+        AttributeType nbChildrenAt = directoryService.getAtProvider().getNbChildren();
+        AttributeTypeOptions nbChildrenAto = new AttributeTypeOptions( nbChildrenAt );
+        AttributeType nbSubordinatesAt = directoryService.getAtProvider().getNbSubordinates();
+        AttributeTypeOptions nbSubordinatesAto = new AttributeTypeOptions( nbSubordinatesAt );
+        
+        if ( lookupContext.getReturningAttributes() != null )
+        {
+            boolean nbChildrenRequested = lookupContext.getReturningAttributes().contains( nbChildrenAto ) 
+                | lookupContext.isAllOperationalAttributes();
+            boolean nbSubordinatesRequested = lookupContext.getReturningAttributes().contains( nbSubordinatesAto )
+                | lookupContext.isAllOperationalAttributes();
+
+            if ( nbChildrenRequested || nbSubordinatesRequested )
+            {
+                Partition partition = directoryService.getPartitionNexus().getPartition( result.getDn() );
+                Subordinates subordinates = partition.getSubordinates( result );
+                
+                long nbChildren = subordinates.getNbChildren();
+                long nbSubordinates = subordinates.getNbSubordinates();
+                
+                if ( nbChildrenRequested )
+                {
+                    result.add( new DefaultAttribute( nbChildrenAt, 
+                        Long.toString( nbChildren ) ) );
+                }
+    
+                if ( nbSubordinatesRequested )
+                { 
+                    result.add( new DefaultAttribute( nbSubordinatesAt,
+                        Long.toString( nbSubordinates ) ) );
+                }
+            }
+        }
 
         return result;
     }

Modified: directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/replication/consumer/ReplicationConsumerImpl.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/replication/consumer/ReplicationConsumerImpl.java?rev=1733917&r1=1733916&r2=1733917&view=diff
==============================================================================
--- directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/replication/consumer/ReplicationConsumerImpl.java (original)
+++ directory/apacheds/trunk/protocol-ldap/src/main/java/org/apache/directory/server/ldap/replication/consumer/ReplicationConsumerImpl.java Mon Mar  7 12:39:58 2016
@@ -140,7 +140,9 @@ public class ReplicationConsumerImpl imp
             SchemaConstants.CREATORS_NAME_AT,
             ApacheSchemaConstants.ENTRY_PARENT_ID_AT,
             SchemaConstants.COLLECTIVE_ATTRIBUTE_SUBENTRIES_AT,
-            SchemaConstants.CONTEXT_CSN_AT
+            SchemaConstants.CONTEXT_CSN_AT,
+            ApacheSchemaConstants.NB_CHILDREN_AT,
+            ApacheSchemaConstants.NB_SUBORDINATES_AT
     };
 
     /** the cookie that was saved last time */

Modified: directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java?rev=1733917&r1=1733916&r2=1733917&view=diff
==============================================================================
--- directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java (original)
+++ directory/apacheds/trunk/xdbm-partition/src/main/java/org/apache/directory/server/core/partition/impl/btree/AbstractBTreePartition.java Mon Mar  7 12:39:58 2016
@@ -83,6 +83,7 @@ import org.apache.directory.server.core.
 import org.apache.directory.server.core.api.interceptor.context.UnbindOperationContext;
 import org.apache.directory.server.core.api.partition.AbstractPartition;
 import org.apache.directory.server.core.api.partition.Partition;
+import org.apache.directory.server.core.api.partition.Subordinates;
 import org.apache.directory.server.i18n.I18n;
 import org.apache.directory.server.xdbm.Index;
 import org.apache.directory.server.xdbm.IndexEntry;
@@ -3419,4 +3420,40 @@ public abstract class AbstractBTreeParti
             throw new LdapOperationErrorException( e.getMessage(), e );
         }
     }
+    
+    
+    /**
+     * Return the number of children and subordinates for a given entry
+     *
+     * @param dn The entry's DN
+     * @return The Subordinate instance that contains the values.
+     * @throws LdapException If we had an issue while processing the request
+     */
+    public Subordinates getSubordinates( Entry entry ) throws LdapException
+    {
+        Subordinates subordinates = new Subordinates();
+        
+        try
+        {
+            // Check into the Rdn index, starting with the partition Suffix
+            try
+            {
+                rwLock.readLock().lock();
+                ParentIdAndRdn parentIdAndRdn = rdnIdx.reverseLookup( entry.get( SchemaConstants.ENTRY_UUID_AT ).getString() );
+
+                subordinates.setNbChildren( parentIdAndRdn.getNbChildren() );
+                subordinates.setNbSubordinates( parentIdAndRdn.getNbDescendants() );
+            }
+            finally
+            {
+                rwLock.readLock().unlock();
+            }
+        }
+        catch ( Exception e )
+        {
+            throw new LdapException( e.getMessage(), e );
+        }
+
+        return subordinates;
+    }
 }