directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From akaras...@apache.org
Subject svn commit: r682296 - in /directory/apacheds/branches/bigbang: protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/NewCompareHandler.java server-integ/src/test/java/org/apache/directory/server/operations/compare/CompareIT.java
Date Mon, 04 Aug 2008 08:58:39 GMT
Author: akarasulu
Date: Mon Aug  4 01:58:38 2008
New Revision: 682296

URL: http://svn.apache.org/viewvc?rev=682296&view=rev
Log:
finishing off last peice of referral handling for compare operations

Modified:
    directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/NewCompareHandler.java
    directory/apacheds/branches/bigbang/server-integ/src/test/java/org/apache/directory/server/operations/compare/CompareIT.java

Modified: directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/NewCompareHandler.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/NewCompareHandler.java?rev=682296&r1=682295&r2=682296&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/NewCompareHandler.java
(original)
+++ directory/apacheds/branches/bigbang/protocol-newldap/src/main/java/org/apache/directory/server/newldap/handlers/NewCompareHandler.java
Mon Aug  4 01:58:38 2008
@@ -25,8 +25,8 @@
 import javax.naming.NamingException;
 
 import org.apache.directory.server.core.entry.ClonedServerEntry;
+import org.apache.directory.server.core.entry.ServerAttribute;
 import org.apache.directory.server.newldap.LdapSession;
-import org.apache.directory.shared.ldap.NotImplementedException;
 import org.apache.directory.shared.ldap.constants.SchemaConstants;
 import org.apache.directory.shared.ldap.entry.EntryAttribute;
 import org.apache.directory.shared.ldap.entry.Value;
@@ -34,10 +34,13 @@
 import org.apache.directory.shared.ldap.message.CompareRequest;
 import org.apache.directory.shared.ldap.message.LdapResult;
 import org.apache.directory.shared.ldap.message.ManageDsaITControl;
+import org.apache.directory.shared.ldap.message.Referral;
 import org.apache.directory.shared.ldap.message.ReferralImpl;
 import org.apache.directory.shared.ldap.message.ResultCodeEnum;
 import org.apache.directory.shared.ldap.name.LdapDN;
 import org.apache.directory.shared.ldap.util.ExceptionUtils;
+import org.apache.directory.shared.ldap.codec.util.LdapURL;
+import org.apache.directory.shared.ldap.codec.util.LdapURLEncodingException;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -99,10 +102,12 @@
         try
         {
             entry = session.getCoreSession().lookup( req.getName() );
+            LOG.debug( "Entry for {} was found: ", req.getName(), entry );
         }
         catch ( NameNotFoundException e )
         {
             /* ignore */
+            LOG.debug( "Entry for {} not found.", req.getName() );
         }
         catch ( Exception e )
         {
@@ -172,19 +177,16 @@
             
             while ( ! dn.isEmpty() )
             {
+                LOG.debug( "Walking ancestors of {} to find referrals.", dn );
+                
                 try
                 {
-                    referralAncestor = session.getCoreSession().lookup( dn );
-                    EntryAttribute oc = referralAncestor.getOriginalEntry().get( SchemaConstants.OBJECT_CLASS_AT
);
+                    entry = session.getCoreSession().lookup( dn );
+                    EntryAttribute oc = entry.getOriginalEntry().get( SchemaConstants.OBJECT_CLASS_AT
);
                     
-                    // make sure referral ancestor is really a referral if not
-                    // then we null it out so the proper handling can occur 
-                    // down below - the reason for this is because we want the
-                    // farthest ancestor, not the closest one.
-                    
-                    if ( ! oc.contains( SchemaConstants.REFERRAL_OC ) )
+                    if ( oc.contains( SchemaConstants.REFERRAL_OC ) )
                     {
-                        referralAncestor = null;
+                        referralAncestor = entry;
                     }
 
                     // set last matched DN only if not set yet because we want 
@@ -195,13 +197,17 @@
                     {
                         lastMatchedDn = ( LdapDN ) dn.clone();
                     }
+
+                    dn.remove( dn.size() - 1 );
                 }
                 catch ( NameNotFoundException e )
                 {
+                    LOG.debug( "Entry for {} not found.", dn );
+
                     // update the DN as we strip last component 
                     try
                     {
-                        dn = ( LdapDN ) dn.remove( dn.size() - 1 );
+                        dn.remove( dn.size() - 1 );
                     }
                     catch ( InvalidNameException e1 )
                     {
@@ -224,7 +230,7 @@
             }
               
             // if we get here then we have a valid referral ancestor
-            handleReferralOnAncestor( session, req, referralAncestor );
+            handleReferralOnAncestor( session, req, referralAncestor, lastMatchedDn );
         }
     }
 
@@ -237,9 +243,106 @@
      * @param referralAncestor the farthest referral ancestor of the missing 
      * entry  
      */
-    public void handleReferralOnAncestor( LdapSession session, CompareRequest req, ClonedServerEntry
referralAncestor )
+    public void handleReferralOnAncestor( LdapSession session, CompareRequest req, 
+        ClonedServerEntry referralAncestor, LdapDN lastMatchedDn )
     {
-        throw new NotImplementedException();
+        LOG.debug( "Inside handleReferralOnAncestor()" );
+        
+        try
+        {
+            ServerAttribute refAttr = ( ServerAttribute ) referralAncestor.getOriginalEntry()
+                .get( SchemaConstants.REF_AT );
+            Referral referral = new ReferralImpl();
+
+            for ( Value<?> value : refAttr )
+            {
+                String ref = ( String ) value.get();
+
+                LOG.debug( "Calculating LdapURL for referrence value {}", ref );
+
+                // need to add non-ldap URLs as-is
+                if ( ! ref.startsWith( "ldap" ) )
+                {
+                    referral.addLdapUrl( ref );
+                    continue;
+                }
+                
+                // parse the ref value and normalize the DN  
+                LdapURL ldapUrl = new LdapURL();
+                try
+                {
+                    ldapUrl.parse( ref.toCharArray() );
+                }
+                catch ( LdapURLEncodingException e )
+                {
+                    LOG.error( "Bad URL ({}) for ref in {}.  Reference will be ignored.",
ref, referralAncestor );
+                }
+                
+                LdapDN urlDn = new LdapDN( ldapUrl.getDn().getUpName() );
+                urlDn.normalize( session.getCoreSession().getDirectoryService().getRegistries()
+                    .getAttributeTypeRegistry().getNormalizerMapping() ); 
+                
+                if ( urlDn.getNormName().equals( referralAncestor.getDn().getNormName() )
)
+                {
+                    // according to the protocol there is no need for the dn since it is
the same as this request
+                    StringBuilder buf = new StringBuilder();
+                    buf.append( ldapUrl.getScheme() );
+                    buf.append( ldapUrl.getHost() );
+
+                    if ( ldapUrl.getPort() > 0 )
+                    {
+                        buf.append( ":" );
+                        buf.append( ldapUrl.getPort() );
+                    }
+
+                    referral.addLdapUrl( buf.toString() );
+                    continue;
+                }
+                
+                /*
+                 * If we get here then the DN of the referral was not the same as the 
+                 * DN of the ref LDAP URL.  We must calculate the remaining (difference)
+                 * name past the farthest referral DN which the target name extends.
+                 */
+                int diff = req.getName().size() - referralAncestor.getDn().size();
+                LdapDN extra = new LdapDN();
+    
+                // TODO - fix this by access unormalized RDN values
+                // seems we have to do this because get returns normalized rdns
+                LdapDN reqUnnormalizedDn = new LdapDN( req.getName().getUpName() );
+                for ( int jj = 0; jj < diff; jj++ )
+                {
+                    extra.add( reqUnnormalizedDn.get( referralAncestor.getDn().size() + jj
) );
+                }
+    
+                urlDn.addAll( extra );
+    
+                StringBuilder buf = new StringBuilder();
+                buf.append( ldapUrl.getScheme() );
+                buf.append( ldapUrl.getHost() );
+    
+                if ( ldapUrl.getPort() > 0 )
+                {
+                    buf.append( ":" );
+                    buf.append( ldapUrl.getPort() );
+                }
+    
+                buf.append( "/" );
+                buf.append( LdapURL.urlEncode( urlDn.getUpName(), false ) );
+                referral.addLdapUrl( buf.toString() );
+            }
+            
+            LdapResult result = req.getResultResponse().getLdapResult();
+            result.setMatchedDn( lastMatchedDn );
+            result.setResultCode( ResultCodeEnum.REFERRAL );
+            result.setReferral( referral );
+            
+            session.getIoSession().write( req.getResultResponse() );
+        }
+        catch ( Exception e )
+        {
+            handleException( session, req, e );
+        }
     }
     
     

Modified: directory/apacheds/branches/bigbang/server-integ/src/test/java/org/apache/directory/server/operations/compare/CompareIT.java
URL: http://svn.apache.org/viewvc/directory/apacheds/branches/bigbang/server-integ/src/test/java/org/apache/directory/server/operations/compare/CompareIT.java?rev=682296&r1=682295&r2=682296&view=diff
==============================================================================
--- directory/apacheds/branches/bigbang/server-integ/src/test/java/org/apache/directory/server/operations/compare/CompareIT.java
(original)
+++ directory/apacheds/branches/bigbang/server-integ/src/test/java/org/apache/directory/server/operations/compare/CompareIT.java
Mon Aug  4 01:58:38 2008
@@ -27,9 +27,11 @@
 import javax.naming.ldap.LdapContext;
 
 import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPAttributeSet;
 import netscape.ldap.LDAPConnection;
 import netscape.ldap.LDAPConstraints;
 import netscape.ldap.LDAPControl;
+import netscape.ldap.LDAPEntry;
 import netscape.ldap.LDAPException;
 import netscape.ldap.LDAPResponse;
 import netscape.ldap.LDAPResponseListener;
@@ -72,6 +74,13 @@
     "cn: Alex Karasulu\n" +
     "sn: karasulu\n\n" + 
     // Entry # 2
+    "dn: ou=Computers,uid=akarasulu,ou=users,ou=system\n" +
+    "objectClass: organizationalUnit\n" +
+    "objectClass: top\n" +
+    "ou: computers\n" +
+    "description: Computers for Alex\n" +
+    "seeAlso: ou=Machines,uid=akarasulu,ou=users,ou=system\n\n" + 
+    // Entry # 3
     "dn: uid=akarasuluref,ou=users,ou=system\n" +
     "objectClass: uidObject\n" +
     "objectClass: referral\n" +
@@ -275,4 +284,33 @@
         answer.close();
         ctx.close();
     }
+    
+    
+    /**
+     * Tests referral handling when an ancestor is a referral.
+     */
+    @Test 
+    public void testAncestorReferral() throws Exception
+    {
+        LOG.debug( "" );
+
+        LDAPConnection conn = getWiredConnection( ldapServer );
+        LDAPConstraints constraints = new LDAPConstraints();
+        conn.setConstraints( constraints );
+
+        // referrals failure
+        LDAPAttribute attribute = new LDAPAttribute( "ou", "Computers" );
+        LDAPResponseListener listener = null;
+        LDAPResponse response = null;
+
+        listener = conn.compare( "ou=Computers,uid=akarasuluref,ou=users,ou=system", attribute,
null, constraints );
+        response = listener.getResponse();
+        assertEquals( ResultCodeEnum.REFERRAL.getValue(), response.getResultCode() );
+
+        assertEquals( "ldap://localhost:10389/ou=Computers,uid=akarasulu,ou=users,ou=system",
response.getReferrals()[0] );
+        assertEquals( "ldap://foo:10389/ou=Computers,uid=akarasulu,ou=users,ou=system", response.getReferrals()[1]
);
+        assertEquals( "ldap://bar:10389/ou=Computers,uid=akarasulu,ou=users,ou=system", response.getReferrals()[2]
);
+
+        conn.disconnect();
+    }
 }



Mime
View raw message